Skip to content

Commit

Permalink
Add kube secret command
Browse files Browse the repository at this point in the history
  • Loading branch information
versilis committed Mar 15, 2023
1 parent 1a96ac2 commit b7f4f96
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 0 deletions.
89 changes: 89 additions & 0 deletions cmd/internal/kube/secret.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package kube

import (
"encoding/base64"
"github.com/akitasoftware/akita-cli/cmd/internal/cmderr"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"log"
"os"
"text/template"
)


var (
output string
namespace string
// Store a parsed representation of /template/akita-secret.tmpl
secretTemplate *template.Template
)

var secretCmd = &cobra.Command{
Use: "secret",
Short: "Generate a Kubernetes secret config for Akita",
RunE: func(cmd *cobra.Command, args []string) error {
if namespace == "" {
return cmderr.AkitaErr{Err: errors.New("namespace flag not set")}
}

key, secret, err := cmderr.RequireAPICredentials("Akita API key is required for Kubernetes Secret generation")
if err != nil {
return err
}

return handleSecretGeneration(namespace, key, secret, output)
},
}

// Represents the input used by secretTemplate
type secretTemplateInput struct {
//
Namespace string
APIKey string
APISecret string
}

func handleSecretGeneration(namespace, key, secret, output string) error {

input := secretTemplateInput{
Namespace: namespace,
APIKey: base64.StdEncoding.EncodeToString([]byte(key)),
APISecret: base64.StdEncoding.EncodeToString([]byte(secret)),
}

file, err := os.Create(output)
if err != nil {
return cmderr.AkitaErr{Err: errors.Wrap(err, "failed to create output file")}
}

defer file.Close()

err = secretTemplate.Execute(file, input)
if err != nil {
return cmderr.AkitaErr{Err: errors.Wrap(err, "failed to generate template")}
}

return nil
}

func init() {
var err error

secretTemplate, err = template.ParseFS(templateFS, "template/akita-secret.tmpl")
if err != nil {
log.Fatalf("unable to parse kube secret template: %v", err)
}

// Create a flag on the root subcommand to avoid
secretCmd.Flags().StringVarP(
&namespace,
"namespace",
"n",
"",
"The Kuberenetes namespace the secret should be applied to",
)

secretCmd.Flags().StringVarP(&output, "output", "o", "akita-secret.yml", "File to output the generated secret.")

Cmd.AddCommand(secretCmd)
}
38 changes: 38 additions & 0 deletions cmd/internal/kube/secret_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package kube

import (
_ "embed"
"github.com/stretchr/testify/assert"
"os"
"path/filepath"
"testing"
)

//go:embed test_resource/akita-secret.yml
var testAkitaSecretYAML []byte

func Test_secretGeneration(t *testing.T) {
// GIVEN
const (
namespace = "default"
key = "api-key"
secret = "api-secret"
)

dir := t.TempDir()
actualOutput := filepath.Join(dir, "akita-secret.yml")

// WHEN
err := handleSecretGeneration(namespace, key, secret, actualOutput)
if err != nil {
t.Errorf("Unexpected error: %s", err)
}

// THEN
actualFile, err := os.ReadFile(actualOutput)
if err != nil {
t.Errorf("Failed to read generated file: %v", err)
}

assert.Equal(t, string(testAkitaSecretYAML), string(actualFile))
}
9 changes: 9 additions & 0 deletions cmd/internal/kube/test_resource/akita-secret.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v1
kind: Secret
metadata:
name: akita-secrets
namespace: default
type: Opaque
data:
akita-api-key: YXBpLWtleQ==
akita-api-secret: YXBpLXNlY3JldA==

0 comments on commit b7f4f96

Please sign in to comment.