We now encrypt secrets at rest based on a key derived from a user suplied passphrase. The system is designed in a way such that we should be able to have a different decrypter (either using a local key or some remote service in the Pulumi.com case in the future). Care is taken to ensure that we do not leak decrypted secrets into the "info" section of the checkpoint file (since we currently store the config there). In addtion, secrets are "pay for play", a passphrase is only needed when dealing with a value that's encrypted. If secure config values are not used, `pulumi` will never prompt you for a passphrase. Otherwise, we only prompt if we know we are going to need to decrypt the value. For example, `pulumi config <key>` only prompts if `<key>` is encrypted and `pulumi deploy` and friends only prompt if you are targeting a stack that has secure configuration assoicated with it. Secure values show up as unecrypted config values inside the language hosts and providers.
78 lines
2.4 KiB
Go
78 lines
2.4 KiB
Go
// Copyright 2016-2017, Pulumi Corporation. All rights reserved.
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"bufio"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/golang/glog"
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/pulumi/pulumi/pkg/diag/colors"
|
|
"github.com/pulumi/pulumi/pkg/util/cmdutil"
|
|
)
|
|
|
|
// NewPulumiCmd creates a new Pulumi Cmd instance.
|
|
func NewPulumiCmd(version string) *cobra.Command {
|
|
var logFlow bool
|
|
var logToStderr bool
|
|
var verbose int
|
|
var cwd string
|
|
cmd := &cobra.Command{
|
|
Use: "pulumi",
|
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
|
if cwd != "" {
|
|
err := os.Chdir(cwd)
|
|
if err != nil {
|
|
cmdutil.ExitError(err.Error())
|
|
}
|
|
}
|
|
|
|
cmdutil.InitLogging(logToStderr, verbose, logFlow)
|
|
},
|
|
PersistentPostRun: func(cmd *cobra.Command, args []string) {
|
|
glog.Flush()
|
|
},
|
|
}
|
|
|
|
cmd.PersistentFlags().StringVarP(&cwd, "cwd", "C", "", "Run pulumi as if it had been started in another directory")
|
|
cmd.PersistentFlags().BoolVar(&logFlow, "logflow", false, "Flow log settings to child processes (like plugins)")
|
|
cmd.PersistentFlags().BoolVar(&logToStderr, "logtostderr", false, "Log to stderr instead of to files")
|
|
cmd.PersistentFlags().IntVarP(
|
|
&verbose, "verbose", "v", 0, "Enable verbose logging (e.g., v=3); anything >3 is very verbose")
|
|
|
|
cmd.AddCommand(newConfigCmd())
|
|
cmd.AddCommand(newDestroyCmd())
|
|
cmd.AddCommand(newStackCmd())
|
|
cmd.AddCommand(newPreviewCmd())
|
|
cmd.AddCommand(newUpdateCmd())
|
|
cmd.AddCommand(newVersionCmd(version))
|
|
|
|
// Commands specific to the Pulumi Cloud Management Console.
|
|
cmd.AddCommand(newLoginCmd())
|
|
cmd.AddCommand(newLogoutCmd())
|
|
|
|
// Tell flag about -C, so someone can do pulumi -C <working-directory> stack and the call to cmdutil.InitLogging
|
|
// which calls flag.Parse under the hood doesn't yell at you.
|
|
//
|
|
// TODO[pulumi/pulumi#301]: when we move away from using glog, it should be safe to remove this.
|
|
flag.StringVar(&cwd, "C", "", "Run pulumi as if it had been started in another directory")
|
|
|
|
return cmd
|
|
}
|
|
|
|
func confirmPrompt(msg string, name string) bool {
|
|
prompt := fmt.Sprintf(msg, name)
|
|
fmt.Print(
|
|
colors.ColorizeText(fmt.Sprintf("%v%v%v\n", colors.SpecAttention, prompt, colors.Reset)))
|
|
fmt.Printf("Please confirm that this is what you'd like to do by typing (\"%v\"): ", name)
|
|
reader := bufio.NewReader(os.Stdin)
|
|
if line, _ := reader.ReadString('\n'); line != name+"\n" {
|
|
fmt.Fprintf(os.Stderr, "Confirmation declined -- exiting without doing anything\n")
|
|
return false
|
|
}
|
|
return true
|
|
}
|