Add --json
to pulumi config get
and pulumi config
This supports using `--json` to get configuration information in a structured way. The objects we return have the following schema: ``` { name: string; value: string?; secret: bool; } ``` In the case of `pulumi config` when --show-secrets is not passed, and there are secret values, the `value` property of the object for that configuration value will not be set. This differs from the normal rendering where we show `[secret]`. Contributes To #496
This commit is contained in:
parent
0de4294fc7
commit
5cfd44c73a
|
@ -2,6 +2,8 @@
|
|||
|
||||
### Improvements
|
||||
|
||||
- Add `--JSON` to `pulumi config` and `pulumi config get` to request the output be in JSON.
|
||||
|
||||
## 0.16.11 (Released January 16th, 2019)
|
||||
|
||||
### Improvements
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
@ -38,6 +39,7 @@ import (
|
|||
func newConfigCmd() *cobra.Command {
|
||||
var stack string
|
||||
var showSecrets bool
|
||||
var jsonOut bool
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "config",
|
||||
|
@ -56,13 +58,16 @@ func newConfigCmd() *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
return listConfig(stack, showSecrets)
|
||||
return listConfig(stack, showSecrets, jsonOut)
|
||||
}),
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVar(
|
||||
&showSecrets, "show-secrets", false,
|
||||
"Show secret values when listing config instead of displaying blinded values")
|
||||
cmd.Flags().BoolVarP(
|
||||
&jsonOut, "json", "j", false,
|
||||
"Emit output as JSON")
|
||||
cmd.PersistentFlags().StringVarP(
|
||||
&stack, "stack", "s", "",
|
||||
"The name of the stack to operate on. Defaults to the current stack")
|
||||
|
@ -79,6 +84,8 @@ func newConfigCmd() *cobra.Command {
|
|||
}
|
||||
|
||||
func newConfigGetCmd(stack *string) *cobra.Command {
|
||||
var jsonOut bool
|
||||
|
||||
getCmd := &cobra.Command{
|
||||
Use: "get <key>",
|
||||
Short: "Get a single configuration value",
|
||||
|
@ -98,9 +105,12 @@ func newConfigGetCmd(stack *string) *cobra.Command {
|
|||
return errors.Wrap(err, "invalid configuration key")
|
||||
}
|
||||
|
||||
return getConfig(s, key)
|
||||
return getConfig(s, key, jsonOut)
|
||||
}),
|
||||
}
|
||||
getCmd.Flags().BoolVarP(
|
||||
&jsonOut, "json", "j", false,
|
||||
"Emit output as JSON")
|
||||
|
||||
return getCmd
|
||||
}
|
||||
|
@ -361,7 +371,16 @@ func prettyKeyForProject(k config.Key, proj *workspace.Project) string {
|
|||
return fmt.Sprintf("%s:%s", k.Namespace(), k.Name())
|
||||
}
|
||||
|
||||
func listConfig(stack backend.Stack, showSecrets bool) error {
|
||||
// configValueJSON is the shape of the --json output for a configuration value. While we can add fields to this
|
||||
// structure in the future, we should not change existing fields.
|
||||
type configValueJSON struct {
|
||||
Name string `json:"name"`
|
||||
// When the value is encrypted and --show-secrets was not passed, the value will not be set.
|
||||
Value *string `json:"value,omitempty"`
|
||||
Secret bool `json:"secret"`
|
||||
}
|
||||
|
||||
func listConfig(stack backend.Stack, showSecrets bool, jsonOut bool) error {
|
||||
ps, err := loadProjectStack(stack)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -369,7 +388,7 @@ func listConfig(stack backend.Stack, showSecrets bool) error {
|
|||
|
||||
cfg := ps.Config
|
||||
|
||||
// By default, we will use a blinding decrypter to show '******'. If requested, display secrets in plaintext.
|
||||
// By default, we will use a blinding decrypter to show "[secret]". If requested, display secrets in plaintext.
|
||||
var decrypter config.Decrypter
|
||||
if cfg.HasSecureValue() && showSecrets {
|
||||
decrypter, err = backend.GetStackCrypter(stack)
|
||||
|
@ -388,24 +407,55 @@ func listConfig(stack backend.Stack, showSecrets bool) error {
|
|||
}
|
||||
sort.Sort(keys)
|
||||
|
||||
rows := []cmdutil.TableRow{}
|
||||
for _, key := range keys {
|
||||
decrypted, err := cfg[key].Value(decrypter)
|
||||
if jsonOut {
|
||||
var configValues []configValueJSON
|
||||
for _, key := range keys {
|
||||
entry := configValueJSON{
|
||||
Name: key.String(),
|
||||
Secret: cfg[key].Secure(),
|
||||
}
|
||||
|
||||
decrypted, err := cfg[key].Value(decrypter)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not decrypt configuration value")
|
||||
}
|
||||
entry.Value = &decrypted
|
||||
|
||||
// If the value was a secret value and we aren't showing secrets, then the above would have set value
|
||||
// to "[secret]" which is reasonable when printing for human display, but for our JSON output, we'd rather
|
||||
// just elide the value.
|
||||
if cfg[key].Secure() && !showSecrets {
|
||||
entry.Value = nil
|
||||
}
|
||||
|
||||
configValues = append(configValues, entry)
|
||||
}
|
||||
out, err := json.MarshalIndent(configValues, "", " ")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not decrypt configuration value")
|
||||
return err
|
||||
}
|
||||
fmt.Println(string(out))
|
||||
} else {
|
||||
rows := []cmdutil.TableRow{}
|
||||
for _, key := range keys {
|
||||
decrypted, err := cfg[key].Value(decrypter)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not decrypt configuration value")
|
||||
}
|
||||
|
||||
rows = append(rows, cmdutil.TableRow{Columns: []string{prettyKey(key), decrypted}})
|
||||
}
|
||||
|
||||
rows = append(rows, cmdutil.TableRow{Columns: []string{prettyKey(key), decrypted}})
|
||||
cmdutil.PrintTable(cmdutil.Table{
|
||||
Headers: []string{"KEY", "VALUE"},
|
||||
Rows: rows,
|
||||
})
|
||||
}
|
||||
|
||||
cmdutil.PrintTable(cmdutil.Table{
|
||||
Headers: []string{"KEY", "VALUE"},
|
||||
Rows: rows,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func getConfig(stack backend.Stack, key config.Key) error {
|
||||
func getConfig(stack backend.Stack, key config.Key, jsonOut bool) error {
|
||||
ps, err := loadProjectStack(stack)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -427,7 +477,23 @@ func getConfig(stack backend.Stack, key config.Key) error {
|
|||
if err != nil {
|
||||
return errors.Wrap(err, "could not decrypt configuration value")
|
||||
}
|
||||
fmt.Printf("%v\n", raw)
|
||||
|
||||
if jsonOut {
|
||||
value := configValueJSON{
|
||||
Name: key.String(),
|
||||
Value: &raw,
|
||||
Secret: v.Secure(),
|
||||
}
|
||||
|
||||
out, err := json.MarshalIndent(value, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(string(out))
|
||||
} else {
|
||||
fmt.Printf("%v\n", raw)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ func newLogsCmd() *cobra.Command {
|
|||
&stackConfigFile, "config-file", "",
|
||||
"Use the configuration values in the specified file rather than detecting the file name")
|
||||
logsCmd.PersistentFlags().BoolVarP(
|
||||
&jsonOut, "json", "j", false, "Emit outputs as JSON")
|
||||
&jsonOut, "json", "j", false, "Emit output as JSON")
|
||||
logsCmd.PersistentFlags().BoolVarP(
|
||||
&follow, "follow", "f", false,
|
||||
"Follow the log stream in real time (like tail -f)")
|
||||
|
|
|
@ -87,7 +87,7 @@ func newStackLsCmd() *cobra.Command {
|
|||
}),
|
||||
}
|
||||
cmd.PersistentFlags().BoolVarP(
|
||||
&jsonOut, "json", "j", false, "Emit outputs as JSON")
|
||||
&jsonOut, "json", "j", false, "Emit output as JSON")
|
||||
cmd.PersistentFlags().BoolVarP(
|
||||
&allStacks, "all", "a", false, "List all stacks instead of just stacks for the current project")
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ func newStackOutputCmd() *cobra.Command {
|
|||
}
|
||||
|
||||
cmd.PersistentFlags().BoolVarP(
|
||||
&jsonOut, "json", "j", false, "Emit outputs as JSON")
|
||||
&jsonOut, "json", "j", false, "Emit output as JSON")
|
||||
cmd.PersistentFlags().StringVarP(
|
||||
&stackName, "stack", "s", "", "The name of the stack to operate on. Defaults to the current stack")
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ func newStackTagLsCmd(stack *string) *cobra.Command {
|
|||
}
|
||||
|
||||
cmd.PersistentFlags().BoolVarP(
|
||||
&jsonOut, "json", "j", false, "Emit stack tags as JSON")
|
||||
&jsonOut, "json", "j", false, "Emit output as JSON")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue