diff --git a/command/ca/bootstrap.go b/command/ca/bootstrap.go index a1c3c7b4..71bab078 100644 --- a/command/ca/bootstrap.go +++ b/command/ca/bootstrap.go @@ -75,14 +75,8 @@ domain name 'certs.example-team.ca.smallstep.com' the value would be 'certs'.`, flags.TeamURL, flags.RedirectURL, flags.Force, - cli.StringFlag{ - Name: "context-name", - Usage: `The that will serve as the key for the context.`, - }, - cli.StringFlag{ - Name: "context-profile", - Usage: `The that will serve as the profile name for the context.`, - }, + flags.ContextName, + flags.ContextProfile, }, } } diff --git a/command/ca/init.go b/command/ca/init.go index a6ed14aa..1450a641 100644 --- a/command/ca/init.go +++ b/command/ca/init.go @@ -7,6 +7,8 @@ import ( "fmt" "io" "os" + "path/filepath" + "regexp" "strings" "time" @@ -15,6 +17,7 @@ import ( "github.com/smallstep/certificates/kms" "github.com/smallstep/certificates/pki" "github.com/smallstep/cli/crypto/pemutil" + "github.com/smallstep/cli/flags" "github.com/smallstep/cli/ui" "github.com/smallstep/cli/utils" "github.com/urfave/cli" @@ -24,6 +27,7 @@ import ( "go.step.sm/cli-utils/command" "go.step.sm/cli-utils/errs" + "go.step.sm/cli-utils/step" ) func initCommand() cli.Command { @@ -36,7 +40,8 @@ func initCommand() cli.Command { [**--helm**] [**--deployment-type**=] [**--name**=] [**--dns**=] [**--address**=
] [**--provisioner**=] [**--provisioner-password-file**=] [**--password-file**=] -[**--with-ca-url**=] [**--ra**=] [**--kms**=] [**--no-db**]`, +[**--ra**=] [**--kms**=] [**--with-ca-url**=] [**--no-db**] +[**--context-name**=] [**--context-profile**=]`, Description: `**step ca init** command initializes a public key infrastructure (PKI) to be used by the Certificate Authority.`, Flags: []cli.Flag{ @@ -163,6 +168,8 @@ Cloud.`, Name: "no-db", Usage: `Generate a CA configuration without the DB stanza. No persistence layer.`, }, + flags.ContextName, + flags.ContextProfile, }, } } @@ -439,6 +446,40 @@ func initAction(ctx *cli.Context) (err error) { IsCreator: true, KeyManager: keyManager, } + + } + + // Set appropriate context. + fi, err := os.Stat(filepath.Join(step.BasePath(), "config")) + configDirExists := !os.IsNotExist(err) && fi.IsDir() + fi, err = os.Stat(filepath.Join(step.BasePath(), "authorities")) + authoritiesDirExists := !os.IsNotExist(err) && fi.IsDir() + + if !configDirExists || authoritiesDirExists { + reg, err := regexp.Compile("[^a-zA-Z0-9]+") + if err != nil { + return err + } + processedName := strings.ToLower(strings.ReplaceAll(reg.ReplaceAllString(name, ""), " ", "-")) + + contextName := ctx.String("context-name") + if contextName == "" { + contextName = processedName + } + contextProfile := ctx.String("context-profile") + if contextProfile == "" { + contextProfile = processedName + } + if err := step.AddContext(&step.Context{ + Name: contextName, + Profile: contextProfile, + Authority: processedName, + }); err != nil { + return err + } + if err := step.SwitchCurrentContext(contextName); err != nil { + return err + } } if pkiOnly { diff --git a/command/context/select.go b/command/context/select.go index c4167178..fa51e422 100644 --- a/command/context/select.go +++ b/command/context/select.go @@ -1,14 +1,9 @@ package context import ( - "encoding/json" - - "github.com/pkg/errors" "github.com/smallstep/cli/ui" "github.com/urfave/cli" "go.step.sm/cli-utils/command" - "go.step.sm/cli-utils/errs" - "go.step.sm/cli-utils/fileutil" "go.step.sm/cli-utils/step" ) @@ -37,23 +32,10 @@ $ step context select alpha-one } func selectAction(ctx *cli.Context) error { - ctxStr := ctx.Args().Get(0) - if _, ok := step.GetContext(ctxStr); !ok { - return errors.Errorf("context '%s' not found", ctxStr) - } - - type currentCtxType struct { - Context string `json:"context"` - } - def := currentCtxType{Context: ctxStr} - b, err := json.Marshal(def) - if err != nil { + name := ctx.Args().Get(0) + if err := step.WriteCurrentContext(name); err != nil { return err } - ctx.Set("force", "true") - if err = fileutil.WriteFile(step.CurrentContextFile(), b, 0644); err != nil { - return errs.FileError(err, step.CurrentContextFile()) - } - ui.PrintSelected("Context", ctxStr) + ui.PrintSelected("Context", name) return nil } diff --git a/command/ssh/config.go b/command/ssh/config.go index 8295daa0..5760a6ca 100644 --- a/command/ssh/config.go +++ b/command/ssh/config.go @@ -22,7 +22,8 @@ func configCommand() cli.Command { [**--team**=] [**--host**] [**--set**=] [**--set-file**=] [**--dry-run**] [**--roots**] [**--federation**] [**--force**] [**--offline**] [**--ca-config**=] -[**--ca-url**=] [**--root**=] [**--context**=] [**--root**=] [**--context**=] [**--context-profile**=]`, Description: `**step ssh config** configures SSH to be used with certificates. It also supports flags to inspect the root certificates used to sign the certificates. @@ -84,14 +85,8 @@ times to set multiple variables.`, flags.Root, flags.Offline, flags.Context, - cli.StringFlag{ - Name: "context-name", - Usage: `The that will serve as the key for the context.`, - }, - cli.StringFlag{ - Name: "context-profile", - Usage: `The that will serve as the profile name for the context.`, - }, + flags.ContextName, + flags.ContextProfile, }, } } @@ -107,6 +102,10 @@ func configAction(ctx *cli.Context) (recoverErr error) { isFederation := ctx.Bool("federation") sets := ctx.StringSlice("set") + context := ctx.String("context") + contextName := ctx.String("context-name") + contextProfile := ctx.String("context-profile") + switch { case team != "" && isHost: return errs.IncompatibleFlagWithFlag(ctx, "team", "host") @@ -116,12 +115,18 @@ func configAction(ctx *cli.Context) (recoverErr error) { return errs.IncompatibleFlagWithFlag(ctx, "team", "federation") case team != "" && len(sets) > 0: return errs.IncompatibleFlagWithFlag(ctx, "team", "set") + case team != "" && context != "": + return errs.IncompatibleFlagWithFlag(ctx, "team", "context") case isRoots && isFederation: return errs.IncompatibleFlagWithFlag(ctx, "roots", "federation") case isRoots && len(sets) > 0: return errs.IncompatibleFlagWithFlag(ctx, "roots", "set") case isFederation && len(sets) > 0: return errs.IncompatibleFlagWithFlag(ctx, "federation", "set") + case context != "" && contextName != "": + return errs.IncompatibleFlagWithFlag(ctx, "context", "context-name") + case context != "" && contextProfile != "": + return errs.IncompatibleFlagWithFlag(ctx, "context", "context-profile") } // Bootstrap Authority @@ -135,15 +140,18 @@ func configAction(ctx *cli.Context) (recoverErr error) { args = append(args, os.Args[3:]...) if step.IsContextEnabled() { - ctxName := ctx.String("context-name") - if ctxName == "" { - ctxName = "ssh." + team + switch { + case context != "": + args = append(args, "--context", context) + case team != "" && contextName != "": + args = append(args, "--context", contextName) + case team != "": + args = append(args, "--context", "ssh."+team) } - args = append(args, "--context", ctxName) } if _, err := exec.Step(args...); err != nil { - return errors.Wrap(err, "error configuring ssh authority") + return errors.Wrap(err, "error configuring ssh") } return nil } diff --git a/command/ssh/configHelper.go b/command/ssh/configHelper.go index 97579724..f7a2a4d3 100644 --- a/command/ssh/configHelper.go +++ b/command/ssh/configHelper.go @@ -2,7 +2,6 @@ package ssh import ( "encoding/base64" - "fmt" "net/http" "runtime" "strings" @@ -171,7 +170,7 @@ func configHelperAction(ctx *cli.Context) (recoverErr error) { } for _, key := range keys { - fmt.Printf("%s %s\n", key.Type(), base64.StdEncoding.EncodeToString(key.Marshal())) + ui.Printf("%s %s\n", key.Type(), base64.StdEncoding.EncodeToString(key.Marshal())) } return nil } @@ -241,7 +240,7 @@ func configHelperAction(ctx *cli.Context) (recoverErr error) { templates = resp.UserTemplates } if len(templates) == 0 { - fmt.Println("No configuration changes were found.") + ui.Println("No configuration changes were found.") return nil } @@ -258,7 +257,7 @@ func configHelperAction(ctx *cli.Context) (recoverErr error) { if ctx.Bool("dry-run") { for _, t := range templates { ui.Printf("{{ \"%s\" | bold }}\n", step.Abs(t.Path)) - fmt.Println(string(t.Content)) + ui.Println(string(t.Content)) } return nil } diff --git a/flags/flags.go b/flags/flags.go index 3bd56015..5afe2417 100644 --- a/flags/flags.go +++ b/flags/flags.go @@ -192,6 +192,18 @@ generating key.`, Usage: "The to apply before running the given command.", } + // ContextName the name to use as the key for a new Context. + ContextName = cli.StringFlag{ + Name: "context-name", + Usage: `The that will serve as the key for the context.`, + } + + // ContextProfile the profile name to use for a new Context. + ContextProfile = cli.StringFlag{ + Name: "context-profile", + Usage: `The that will serve as the profile name for the context.`, + } + // Offline is a cli.Flag used to activate the offline flow. Offline = cli.BoolFlag{ Name: "offline",