Skip to content

Commit

Permalink
Merge pull request #3 from devjoes/add-configmap-option
Browse files Browse the repository at this point in the history
added outputAsConfigMap
  • Loading branch information
devjoes authored Mar 2, 2020
2 parents 3bda02a + 0491089 commit 6a4ef70
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 24 deletions.
76 changes: 53 additions & 23 deletions AzureSecrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ const disableAzureAuthValidation = "DISABLE_AZURE_AUTH_VALIDATION"
const offlineTestingMode = "AZURE_SECRETS_OFFLINE_TESTING_MODE"

type innerSecret struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
Keys []string `json:"keys,omitempty" yaml:"keys,omitempty"`
Base64Decode bool `json:"base64decode,omitempty" yaml:"base64decode,omitempty"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
Keys []string `json:"keys,omitempty" yaml:"keys,omitempty"`
Base64Decode bool `json:"base64decode,omitempty" yaml:"base64decode,omitempty"`
OutputAsConfigMap bool `json:"outputAsConfigMap,omitempty" yaml:"outputAsConfigMap,omitempty"`
}

type plugin struct {
Expand Down Expand Up @@ -69,7 +70,7 @@ func (p *plugin) Config(ph *resmap.PluginHelpers, c []byte) (err error) {

func (p *plugin) Generate() (resmap.ResMap, error) {
p.debug("Azure Secrets - generate start")
resmap := resmap.New()
outerResmap := resmap.New()
_, err := getKvClient(p.Vault)
if err != nil {
p.debug("Azure Secrets - generate error")
Expand All @@ -88,15 +89,21 @@ func (p *plugin) Generate() (resmap.ResMap, error) {
}

for _, sec := range p.Secrets {
innerRmap, err := p.generateSecret(sec, secretValues)
var innerResmap resmap.ResMap
var err error
if sec.OutputAsConfigMap {
innerResmap, err = p.outputAsConfigMap(sec, secretValues)
} else {
innerResmap, err = p.generateSecret(sec, secretValues)
}
if err != nil {
p.debug("Azure Secrets - generate error")
return nil, errors.Wrapf(err, "Error generating %v", sec)
}
resmap.AppendAll(innerRmap)
outerResmap.AppendAll(innerResmap)
}
p.debug("Azure Secrets - generate end")
return resmap, nil
return outerResmap, nil
}

func getSecret(valuesChan chan secretValue, name string, vaultName string) {
Expand Down Expand Up @@ -183,20 +190,45 @@ func contains(arr []string, str string) bool {
}

func (p *plugin) generateSecret(secret innerSecret, values map[string]string) (resmap.ResMap, error) {
name, namespace, contents, err := p.generateContents(secret, values)
if err != nil {
return nil, err
}
args := types.SecretArgs{}
args.Name = secret.Name
args.Namespace = secret.Namespace
if args.Name == "" {
args.Name = p.Name
args.Name = name
args.Namespace = namespace
args.LiteralSources = contents
return p.factory.FromSecretArgs(p.loader, nil, args)
}

func (p *plugin) outputAsConfigMap(secret innerSecret, values map[string]string) (resmap.ResMap, error) {
name, namespace, contents, err := p.generateContents(secret, values)
if err != nil {
return nil, err
}
if args.Namespace == "" {
args.Namespace = p.Namespace
args := types.ConfigMapArgs{}
args.Name = name
args.Namespace = namespace
args.LiteralSources = contents
return p.factory.FromConfigMapArgs(p.loader, nil, args)
}

func (p *plugin) generateContents(secret innerSecret, values map[string]string) (string, string, []string, error) {
name := secret.Name
namespace := secret.Namespace
var contents []string

if name == "" {
name = p.Name
}
if args.Name == "" {
return nil, errors.Errorf("Secret is missing name: %v", secret)
if namespace == "" {
namespace = p.Namespace
}
if args.Namespace == "" {
return nil, errors.Errorf("Secret is missing namespace: %v", secret)
if name == "" {
return "", "", nil, errors.Errorf("Secret is missing name: %v", secret)
}
if namespace == "" {
return "", "", nil, errors.Errorf("Secret is missing namespace: %v", secret)
}

for _, key := range secret.Keys {
Expand All @@ -206,17 +238,15 @@ func (p *plugin) generateSecret(secret innerSecret, values map[string]string) (r
if secret.Base64Decode {
data, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return nil, errors.Wrapf(err, "Could not base64 decode '%s'", v)
return "", "", nil, errors.Wrapf(err, "Could not base64 decode '%s'", v)
}
v = string(data)
}
args.LiteralSources = append(
args.LiteralSources, kv[0]+"="+v)
contents = append(contents, kv[0]+"="+v)
}
}
}

return p.factory.FromSecretArgs(p.loader, nil, args)
return name, namespace, contents, nil
}

func (p *plugin) debug(format string, a ...interface{}) {
Expand Down
29 changes: 29 additions & 0 deletions AzureSecrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,35 @@ func TestAzureSecrets_OfflineTesting(t *testing.T) {

}

func TestAzureSecrets_OutputAsConfigMap(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
BuildGoPlugin("devjoes", "v1", "AzureSecrets")
result := th.LoadAndRunGenerator(
`apiVersion: devjoes/v1
kind: AzureSecrets
metadata:
name: default-name
namespace: default-ns
vault: __TESTING_AZURESECRETS__
secrets:
- name: test-secret1
namespace: test-ns
outputAsConfigMap: true
keys:
- FOOKey=RND
- BARKey=RND`)

yamlResult, _ := result.AsYaml()

if !regexp.MustCompile(`ConfigMap`).Match(yamlResult) {
t.Errorf("Could not find Kind: ConfigMap in:\n%s", string(yamlResult))
}

if regexp.MustCompile(`Secret`).Match(yamlResult) {
t.Errorf("Found Kind: Secret in:\n%s", string(yamlResult))
}
}

// func TestAzureSecrets_RunInParallel(t *testing.T) {
// // The test implementation takes ~1000ms to get a secret
// th := kusttest_test.MakeEnhancedHarness(t).
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,17 @@ You can declare the plugin like this:
base64decode: true
keys:
- baz=name_of_baz_secret_in_vault
- name: configmap
namespace: test-ns
outputAsConfigMap: true
keys:
- foo=name_of_foo_secret_in_vault
- bar=name_of_bar_secret_in_vault

This will result in two secrets being generated in the test-ns namespace.
This will result in two secrets and one configmap being generated in the test-ns namespace.
* secret1 will contain the keys foo and bar, assigned to these will be the values of the keyvault secrets 'name_of_foo_secret_in_vault' and 'name_of_bar_secret_in_vault'.
* secret2 will contain the key baz which will have the base64 decoded value of the keyvault secret 'name_of_baz_secret_in_vault'
* configmap will be identical to secret1, except as a ConfigMap

If the name or namespace of a secret is unset then it will default to the name/namespace of the parent AzureSecrets. See the Dockerfile for more examples.

Expand Down

0 comments on commit 6a4ef70

Please sign in to comment.