Skip to content

Commit

Permalink
feat: support for generated secrets in schemas (#4347)
Browse files Browse the repository at this point in the history
If `"default":"<generated>”` is used on a token or a password then it will default to a generated secret

Signed-off-by: Pete Muir <pmuir@bleepbleep.org.uk>
  • Loading branch information
pmuir committed Jun 20, 2019
1 parent b7e23b3 commit e97868b
Show file tree
Hide file tree
Showing 4 changed files with 544 additions and 595 deletions.
59 changes: 35 additions & 24 deletions pkg/surveyutils/jsonschema.go
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,7 @@ func (o *JSONSchemaOptions) handleBasicProperty(name string, prefixes []string,
return o.handleConst(name, validators, t, output)
}

vaultPath := strings.Join([]string{o.VaultBasePath, strings.Join(prefixes, "-")}, "/")
ask := true
defaultValue := ""
autoAcceptMessage := ""
Expand Down Expand Up @@ -665,16 +666,44 @@ func (o *JSONSchemaOptions) handleBasicProperty(name string, prefixes []string,
validator := survey.ComposeValidators(validators...)
// Ask the question
// Custom format support for passwords
storeAsSecret := false
var err error
dereferencedFormat := strings.TrimSuffix(util.DereferenceString(t.Format), "-passthrough")
if dereferencedFormat == "password" || dereferencedFormat == "token" {
storeAsSecret = true
result, err = handlePasswordProperty(message, help, dereferencedFormat, ask, validator, surveyOpts, defaultValue,
if o.VaultClient != nil {
// the standard existing logic is not used in this case
secret, err := o.VaultClient.Read(vaultPath)
if err == nil {
if !o.AskExisting {
ask = false
}
if value, ok := secret[dereferencedFormat]; ok {
defaultValue = fmt.Sprintf("%v", value)
autoAcceptMessage = "Automatically accepted existing value"
}
} else {
// If there is an error, just continue
log.Logger().Debugf("Error reading %s from vault %v", vaultPath, err)
}
}

secret, err := handlePasswordProperty(message, help, dereferencedFormat, ask, validator, surveyOpts, defaultValue,
autoAcceptMessage, o.Out, t.Type)
if err != nil {
return errors.WithStack(err)
}
value, err := util.AsString(secret)
if err != nil {
return err
}
if secret != nil {
if o.VaultClient != nil {
result = secreturl.ToURI(vaultPath, dereferencedFormat, o.VaultScheme)
o.VaultClient.Write(vaultPath, map[string]interface{}{
dereferencedFormat: value,
})
} else {
log.Logger().Warnf("Need to store a secret for %s but no secret store configured. Value is %s", name, value)
}
}
} else if t.Enum != nil {
var enumResult string
// Support for selects
Expand Down Expand Up @@ -763,25 +792,7 @@ func (o *JSONSchemaOptions) handleBasicProperty(name string, prefixes []string,
return errors.Wrapf(err, "error converting result %s to type %s", answer, t.Type)
}
}

if storeAsSecret && result != nil {
value, err := util.AsString(result)
if err != nil {
return err
}
if o.VaultClient != nil {
dereferencedFormat := util.DereferenceString(t.Format)
path := strings.Join([]string{o.VaultBasePath, strings.Join(prefixes, "-")}, "/")
secretReference := secreturl.ToURI(path, dereferencedFormat, o.VaultScheme)
output.Set(name, secretReference)
o.VaultClient.Write(path, map[string]interface{}{
dereferencedFormat: value,
})
} else {
log.Logger().Warnf("Need to store a secret for %s but no secret store configured", name)
}

} else if result != nil {
if result != nil {
// Write the value to the output
output.Set(name, result)
}
Expand Down Expand Up @@ -816,7 +827,7 @@ func handlePasswordProperty(message string, help string, kind string, ask bool,
}
} else {
answer = defaultValue
msg := fmt.Sprintf("%s %s [%s]\n", message, util.ColorInfo(answer), autoAcceptMessage)
msg := fmt.Sprintf("%s *** [%s]\n", message, autoAcceptMessage)
_, err := fmt.Fprint(terminal.NewAnsiStdout(out), msg)
if err != nil {
return nil, errors.Wrapf(err, "writing %s to console", msg)
Expand Down
Loading

0 comments on commit e97868b

Please sign in to comment.