Skip to content

Commit

Permalink
Add new -token-sink-file flag
Browse files Browse the repository at this point in the history
If this flag is set and -init-type=sync then we will write the acl token
to that file.
  • Loading branch information
lkysow committed Mar 16, 2020
1 parent 19f8701 commit fe59489
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 11 deletions.
35 changes: 24 additions & 11 deletions subcommand/acl-init/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ import (
type Command struct {
UI cli.Ui

flags *flag.FlagSet
k8s *k8sflags.K8SFlags
flagSecretName string
flagInitType string
flagNamespace string
flagACLDir string
flags *flag.FlagSet
k8s *k8sflags.K8SFlags
flagSecretName string
flagInitType string
flagNamespace string
flagACLDir string
flagTokenSinkFile string

k8sClient *kubernetes.Clientset
k8sClient kubernetes.Interface

once sync.Once
help string
Expand All @@ -45,6 +46,8 @@ func (c *Command) init() {
"Name of Kubernetes namespace where the servers are deployed")
c.flags.StringVar(&c.flagACLDir, "acl-dir", "/consul/aclconfig",
"Directory name of shared volume where acl config will be output")
c.flags.StringVar(&c.flagTokenSinkFile, "token-sink-file", "",
"Filepath to write acl token to when -init-type is sync")

c.k8s = &k8sflags.K8SFlags{}
flags.Merge(c.flags, c.k8s.Flags())
Expand All @@ -68,10 +71,12 @@ func (c *Command) Run(args []string) int {
}

// Create the Kubernetes clientset
c.k8sClient, err = kubernetes.NewForConfig(config)
if err != nil {
c.UI.Error(fmt.Sprintf("Error initializing Kubernetes client: %s", err))
return 1
if c.k8sClient == nil {
c.k8sClient, err = kubernetes.NewForConfig(config)
if err != nil {
c.UI.Error(fmt.Sprintf("Error initializing Kubernetes client: %s", err))
return 1
}
}

// Check if the client secret exists yet
Expand Down Expand Up @@ -107,6 +112,14 @@ func (c *Command) Run(args []string) int {
}
}

if c.flagInitType == "sync" && c.flagTokenSinkFile != "" {
err = ioutil.WriteFile(c.flagTokenSinkFile, []byte(secret), 0400)
if err != nil {
c.UI.Error(fmt.Sprintf("Error writing token to file %q: %s", c.flagTokenSinkFile, err))
return 1
}
}

return 0
}

Expand Down
89 changes: 89 additions & 0 deletions subcommand/acl-init/command_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package aclinit

import (
"io/ioutil"
"os"
"path/filepath"
"testing"

"github.com/mitchellh/cli"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
)

// Test that we write the secret data to a file.
func TestRun_TokenSinkFile(t *testing.T) {
t.Parallel()
require := require.New(t)
tmpDir, err := ioutil.TempDir("", "")
require.NoError(err)
defer os.Remove(tmpDir)

// Set up k8s with the secret.
token := "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
k8sNS := "default"
secretName := "secret-name"
k8s := fake.NewSimpleClientset()
k8s.CoreV1().Secrets(k8sNS).Create(&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: secretName,
},
Data: map[string][]byte{
"token": []byte(token),
},
})

sinkFile := filepath.Join(tmpDir, "acl-token")
ui := cli.NewMockUi()
cmd := Command{
UI: ui,
k8sClient: k8s,
}
code := cmd.Run([]string{
"-k8s-namespace", k8sNS,
"-init-type=sync",
"-token-sink-file", sinkFile,
})
require.Equal(0, code, ui.ErrorWriter.String())

bytes, err := ioutil.ReadFile(sinkFile)
require.NoError(err)
require.Equal(token, string(bytes), "exp: %s, got: %s", token, string(bytes))
}

// Test that if there's an error writing the sink file it's returned.
func TestRun_TokenSinkFileErr(t *testing.T) {
t.Parallel()
require := require.New(t)

// Set up k8s with the secret.
token := "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
k8sNS := "default"
secretName := "secret-name"
k8s := fake.NewSimpleClientset()
k8s.CoreV1().Secrets(k8sNS).Create(&v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: secretName,
},
Data: map[string][]byte{
"token": []byte(token),
},
})

ui := cli.NewMockUi()
cmd := Command{
UI: ui,
k8sClient: k8s,
}
code := cmd.Run([]string{
"-k8s-namespace", k8sNS,
"-init-type=sync",
"-token-sink-file", "/this/filepath/does/not/exist",
})
require.Equal(1, code)
require.Contains(ui.ErrorWriter.String(),
`Error writing token to file "/this/filepath/does/not/exist": open /this/filepath/does/not/exist: no such file or directory`,
)
}

0 comments on commit fe59489

Please sign in to comment.