github.com/jlmeeker/kismatic@v1.10.1-0.20180612190640-57f9005a1f1a/pkg/cli/certificates_generate.go (about) 1 package cli 2 3 import ( 4 "fmt" 5 "io" 6 "path/filepath" 7 8 "github.com/apprenda/kismatic/pkg/install" 9 "github.com/apprenda/kismatic/pkg/util" 10 "github.com/spf13/cobra" 11 ) 12 13 type certificatesGenerateOpts struct { 14 commonName string 15 validityPeriod int 16 subjAltNames []string 17 organizations []string 18 overwrite bool 19 generatedAssetsDir string 20 } 21 22 // NewCmdGenerate creates a new certificates generate command 23 func NewCmdGenerate(out io.Writer) *cobra.Command { 24 opts := &certificatesGenerateOpts{} 25 26 cmd := &cobra.Command{ 27 Use: "generate <name> [options]", 28 Short: "Generate a cluster certificate, expects 'ca.pem' and 'ca-key.pem' to be in the --generated-assets-dir", 29 Args: func(cmd *cobra.Command, args []string) error { 30 if len(args) == 0 || args[0] == "" { 31 cmd.Help() 32 return fmt.Errorf("no valid <name> argument provided") 33 } 34 if len(args) != 1 { 35 cmd.Help() 36 return fmt.Errorf("invalid arguments provided: %v", args) 37 } 38 return nil 39 }, 40 RunE: func(cmd *cobra.Command, args []string) error { 41 if opts.validityPeriod <= 0 { 42 cmd.Help() 43 return fmt.Errorf("--validity-period must be greater than 0") 44 } 45 return doCertificatesGenerate(args[0], opts, out) 46 }, 47 } 48 49 cmd.Flags().StringVar(&opts.commonName, "common-name", "", "override the common name. If left blank, will use <name>") 50 cmd.Flags().IntVar(&opts.validityPeriod, "validity-period", 365, "specify the number of days this certificate should be valid for. Expiration date will be calculated relative to the machine's clock.") 51 cmd.Flags().StringSliceVar(&opts.subjAltNames, "subj-alt-names", []string{}, "comma-separated list of names that should be included in the certificate's subject alternative names field.") 52 cmd.Flags().StringSliceVar(&opts.organizations, "organizations", []string{}, "comma-separated list of names that should be included in the certificate's organization field.") 53 cmd.Flags().BoolVar(&opts.overwrite, "overwrite", false, "overwrite existing certificate if it already exists in the target directory.") 54 cmd.Flags().StringVar(&opts.generatedAssetsDir, "generated-assets-dir", "generated", "path to the directory where assets generated during the installation process will be stored") 55 56 return cmd 57 } 58 59 func doCertificatesGenerate(name string, opts *certificatesGenerateOpts, out io.Writer) error { 60 ansibleDir := "ansible" 61 certsDir := filepath.Join(opts.generatedAssetsDir, "keys") 62 pki := &install.LocalPKI{ 63 CACsr: filepath.Join(ansibleDir, "playbooks", "tls", "ca-csr.json"), 64 GeneratedCertsDirectory: certsDir, 65 Log: out, 66 } 67 ca, err := pki.GetClusterCA() 68 if err != nil { 69 return err 70 } 71 commonName := opts.commonName 72 if commonName == "" { 73 commonName = name 74 } 75 validityPeriod := fmt.Sprintf("%dh", opts.validityPeriod*24) 76 exists, err := pki.GenerateCertificate(name, validityPeriod, commonName, opts.subjAltNames, opts.organizations, ca, opts.overwrite) 77 if err != nil { 78 return err 79 } 80 if exists && !opts.overwrite { 81 util.PrettyPrintWarn(out, "Certficate '%s.pem' already exists in '%s' directory, use --overwrite option", name, opts.generatedAssetsDir) 82 } else { 83 util.PrettyPrintOk(out, "Certficate '%s.pem' created successfully in '%s' directory", name, opts.generatedAssetsDir) 84 } 85 86 return nil 87 }