Skip to content
This repository was archived by the owner on Jul 10, 2024. It is now read-only.

Commit 3226cf1

Browse files
versilisVersilis Tyson
authored andcommitted
Add kube secret command
1 parent a06efcf commit 3226cf1

3 files changed

Lines changed: 136 additions & 0 deletions

File tree

cmd/internal/kube/secret.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package kube
2+
3+
import (
4+
"encoding/base64"
5+
"github.com/akitasoftware/akita-cli/cmd/internal/cmderr"
6+
"github.com/pkg/errors"
7+
"github.com/spf13/cobra"
8+
"log"
9+
"os"
10+
"text/template"
11+
)
12+
13+
14+
var (
15+
output string
16+
namespace string
17+
// Store a parsed representation of /template/akita-secret.tmpl
18+
secretTemplate *template.Template
19+
)
20+
21+
var secretCmd = &cobra.Command{
22+
Use: "secret",
23+
Short: "Generate a Kubernetes secret config for Akita",
24+
RunE: func(cmd *cobra.Command, args []string) error {
25+
if namespace == "" {
26+
return cmderr.AkitaErr{Err: errors.New("namespace flag not set")}
27+
}
28+
29+
key, secret, err := cmderr.RequireAPICredentials("Akita API key is required for Kubernetes Secret generation")
30+
if err != nil {
31+
return err
32+
}
33+
34+
return handleSecretGeneration(namespace, key, secret, output)
35+
},
36+
}
37+
38+
// Represents the input used by secretTemplate
39+
type secretTemplateInput struct {
40+
//
41+
Namespace string
42+
APIKey string
43+
APISecret string
44+
}
45+
46+
func handleSecretGeneration(namespace, key, secret, output string) error {
47+
48+
input := secretTemplateInput{
49+
Namespace: namespace,
50+
APIKey: base64.StdEncoding.EncodeToString([]byte(key)),
51+
APISecret: base64.StdEncoding.EncodeToString([]byte(secret)),
52+
}
53+
54+
file, err := os.Create(output)
55+
if err != nil {
56+
return cmderr.AkitaErr{Err: errors.Wrap(err, "failed to create output file")}
57+
}
58+
59+
defer file.Close()
60+
61+
err = secretTemplate.Execute(file, input)
62+
if err != nil {
63+
return cmderr.AkitaErr{Err: errors.Wrap(err, "failed to generate template")}
64+
}
65+
66+
return nil
67+
}
68+
69+
func init() {
70+
var err error
71+
72+
secretTemplate, err = template.ParseFS(templateFS, "template/akita-secret.tmpl")
73+
if err != nil {
74+
log.Fatalf("unable to parse kube secret template: %v", err)
75+
}
76+
77+
// Create a flag on the root subcommand to avoid
78+
secretCmd.Flags().StringVarP(
79+
&namespace,
80+
"namespace",
81+
"n",
82+
"",
83+
"The Kuberenetes namespace the secret should be applied to",
84+
)
85+
86+
secretCmd.Flags().StringVarP(&output, "output", "o", "akita-secret.yml", "File to output the generated secret.")
87+
88+
Cmd.AddCommand(secretCmd)
89+
}

cmd/internal/kube/secret_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package kube
2+
3+
import (
4+
_ "embed"
5+
"github.com/stretchr/testify/assert"
6+
"os"
7+
"path/filepath"
8+
"testing"
9+
)
10+
11+
//go:embed test_resource/akita-secret.yml
12+
var testAkitaSecretYAML []byte
13+
14+
func Test_secretGeneration(t *testing.T) {
15+
// GIVEN
16+
const (
17+
namespace = "default"
18+
key = "api-key"
19+
secret = "api-secret"
20+
)
21+
22+
dir := t.TempDir()
23+
actualOutput := filepath.Join(dir, "akita-secret.yml")
24+
25+
// WHEN
26+
err := handleSecretGeneration(namespace, key, secret, actualOutput)
27+
if err != nil {
28+
t.Errorf("Unexpected error: %s", err)
29+
}
30+
31+
// THEN
32+
actualFile, err := os.ReadFile(actualOutput)
33+
if err != nil {
34+
t.Errorf("Failed to read generated file: %v", err)
35+
}
36+
37+
assert.Equal(t, string(testAkitaSecretYAML), string(actualFile))
38+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: v1
2+
kind: Secret
3+
metadata:
4+
name: akita-secrets
5+
namespace: default
6+
type: Opaque
7+
data:
8+
akita-api-key: YXBpLWtleQ==
9+
akita-api-secret: YXBpLXNlY3JldA==

0 commit comments

Comments
 (0)