diff --git a/cmd/helm/get.go b/cmd/helm/get.go index 477f730d5..94245a08d 100644 --- a/cmd/helm/get.go +++ b/cmd/helm/get.go @@ -72,9 +72,9 @@ func newGetCmd(client helm.Interface, out io.Writer) *cobra.Command { cmd.Flags().Int32Var(&get.version, "revision", 0, "get the named release with revision") - cmd.AddCommand(addFlagsTLS(newGetValuesCmd(nil, out))) - cmd.AddCommand(addFlagsTLS(newGetManifestCmd(nil, out))) - cmd.AddCommand(addFlagsTLS(newGetHooksCmd(nil, out))) + cmd.AddCommand(newGetValuesCmd(nil, out)) + cmd.AddCommand(newGetManifestCmd(nil, out)) + cmd.AddCommand(newGetHooksCmd(nil, out)) return cmd } diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 3810cfb8e..8b318c6f3 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -39,16 +39,6 @@ import ( ) var ( - tlsCaCertFile string // path to TLS CA certificate file - tlsCertFile string // path to TLS certificate file - tlsKeyFile string // path to TLS key file - tlsVerify bool // enable TLS and verify remote certificates - tlsEnable bool // enable TLS - - tlsCaCertDefault = "$HELM_HOME/ca.pem" - tlsCertDefault = "$HELM_HOME/cert.pem" - tlsKeyDefault = "$HELM_HOME/key.pem" - tillerTunnel *kube.Tunnel settings helm_env.EnvSettings ) @@ -75,6 +65,11 @@ Environment: $HELM_NO_PLUGINS disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. $TILLER_NAMESPACE set an alternative Tiller namespace (default "kube-system") $KUBECONFIG set an alternative Kubernetes configuration file (default "~/.kube/config") + $HELM_TLS_CA_CERT path to TLS CA certificate file to verify Tiller server certificate (default "$HELM_HOME/ca.pem") + $HELM_TLS_CERT path to TLS client certificate file for authenticating to Tiller (default "$HELM_HOME/cert.pem") + $HELM_TLS_KEY path to TLS cient key file for authenticating to Tiller (default "$HELM_HOME/key.pem") + $HELM_TLS_VERIFY enable TLS for request and verify remote (default "false") + $HELM_TLS_ENABLE enable TLS for request (default "false") ` func newRootCmd(args []string) *cobra.Command { @@ -83,11 +78,6 @@ func newRootCmd(args []string) *cobra.Command { Short: "The Helm package manager for Kubernetes.", Long: globalUsage, SilenceUsage: true, - PersistentPreRun: func(*cobra.Command, []string) { - tlsCaCertFile = os.ExpandEnv(tlsCaCertFile) - tlsCertFile = os.ExpandEnv(tlsCertFile) - tlsKeyFile = os.ExpandEnv(tlsKeyFile) - }, PersistentPostRun: func(*cobra.Command, []string) { teardown() }, @@ -112,18 +102,18 @@ func newRootCmd(args []string) *cobra.Command { newVerifyCmd(out), // release commands - addFlagsTLS(newDeleteCmd(nil, out)), - addFlagsTLS(newGetCmd(nil, out)), - addFlagsTLS(newHistoryCmd(nil, out)), - addFlagsTLS(newInstallCmd(nil, out)), - addFlagsTLS(newListCmd(nil, out)), - addFlagsTLS(newRollbackCmd(nil, out)), - addFlagsTLS(newStatusCmd(nil, out)), - addFlagsTLS(newUpgradeCmd(nil, out)), - - addFlagsTLS(newReleaseTestCmd(nil, out)), - addFlagsTLS(newResetCmd(nil, out)), - addFlagsTLS(newVersionCmd(nil, out)), + newDeleteCmd(nil, out), + newGetCmd(nil, out), + newHistoryCmd(nil, out), + newInstallCmd(nil, out), + newListCmd(nil, out), + newRollbackCmd(nil, out), + newStatusCmd(nil, out), + newUpgradeCmd(nil, out), + + newReleaseTestCmd(nil, out), + newResetCmd(nil, out), + newVersionCmd(nil, out), newCompletionCmd(out), newHomeCmd(out), @@ -266,20 +256,11 @@ func ensureHelmClient(h helm.Interface) helm.Interface { func newClient() helm.Interface { options := []helm.Option{helm.Host(settings.TillerHost)} - if tlsVerify || tlsEnable { - if tlsCaCertFile == "" { - tlsCaCertFile = settings.Home.TLSCaCert() - } - if tlsCertFile == "" { - tlsCertFile = settings.Home.TLSCert() - } - if tlsKeyFile == "" { - tlsKeyFile = settings.Home.TLSKey() - } - debug("Key=%q, Cert=%q, CA=%q\n", tlsKeyFile, tlsCertFile, tlsCaCertFile) - tlsopts := tlsutil.Options{KeyFile: tlsKeyFile, CertFile: tlsCertFile, InsecureSkipVerify: true} - if tlsVerify { - tlsopts.CaCertFile = tlsCaCertFile + if settings.TLSVerify || settings.TLSEnable { + debug("Key=%q, Cert=%q, CA=%q\n", settings.TLSKeyFile, settings.TLSCertFile, settings.TLSCaCertFile) + tlsopts := tlsutil.Options{KeyFile: settings.TLSKeyFile, CertFile: settings.TLSCertFile, InsecureSkipVerify: true} + if settings.TLSVerify { + tlsopts.CaCertFile = settings.TLSCaCertFile tlsopts.InsecureSkipVerify = false } tlscfg, err := tlsutil.ClientConfig(tlsopts) @@ -291,16 +272,3 @@ func newClient() helm.Interface { } return helm.NewClient(options...) } - -// addFlagsTLS adds the flags for supporting client side TLS to the -// helm command (only those that invoke communicate to Tiller.) -func addFlagsTLS(cmd *cobra.Command) *cobra.Command { - - // add flags - cmd.Flags().StringVar(&tlsCaCertFile, "tls-ca-cert", tlsCaCertDefault, "path to TLS CA certificate file") - cmd.Flags().StringVar(&tlsCertFile, "tls-cert", tlsCertDefault, "path to TLS certificate file") - cmd.Flags().StringVar(&tlsKeyFile, "tls-key", tlsKeyDefault, "path to TLS key file") - cmd.Flags().BoolVar(&tlsVerify, "tls-verify", false, "enable TLS for request and verify remote") - cmd.Flags().BoolVar(&tlsEnable, "tls", false, "enable TLS for request") - return cmd -} diff --git a/cmd/helm/init.go b/cmd/helm/init.go index c8753874f..fbff110e4 100644 --- a/cmd/helm/init.go +++ b/cmd/helm/init.go @@ -87,6 +87,11 @@ type initCmd struct { serviceAccount string maxHistory int wait bool + tlsEnable bool + tlsVerify bool + tlsKeyFile string + tlsCertFile string + tlsCaCertFile string } func newInitCmd(out io.Writer) *cobra.Command { @@ -103,6 +108,11 @@ func newInitCmd(out io.Writer) *cobra.Command { i.namespace = settings.TillerNamespace i.home = settings.Home i.client = ensureHelmClient(i.client) + i.tlsEnable = settings.TLSEnable + i.tlsVerify = settings.TLSVerify + i.tlsKeyFile = settings.TLSKeyFile + i.tlsCertFile = settings.TLSCertFile + i.tlsCaCertFile = settings.TLSCaCertFile return i.run() }, @@ -118,12 +128,6 @@ func newInitCmd(out io.Writer) *cobra.Command { f.BoolVar(&i.skipRefresh, "skip-refresh", false, "do not refresh (download) the local repository cache") f.BoolVar(&i.wait, "wait", false, "block until Tiller is running and ready to receive requests") - f.BoolVar(&tlsEnable, "tiller-tls", false, "install Tiller with TLS enabled") - f.BoolVar(&tlsVerify, "tiller-tls-verify", false, "install Tiller with TLS enabled and to verify remote certificates") - f.StringVar(&tlsKeyFile, "tiller-tls-key", "", "path to TLS key file to install with Tiller") - f.StringVar(&tlsCertFile, "tiller-tls-cert", "", "path to TLS certificate file to install with Tiller") - f.StringVar(&tlsCaCertFile, "tls-ca-cert", "", "path to CA root certificate") - f.StringVar(&stableRepositoryURL, "stable-repo-url", stableRepositoryURL, "URL for stable repository") f.StringVar(&localRepositoryURL, "local-repo-url", localRepositoryURL, "URL for local repository") @@ -141,22 +145,22 @@ func newInitCmd(out io.Writer) *cobra.Command { // tlsOptions sanitizes the tls flags as well as checks for the existence of required // tls files indicated by those flags, if any. func (i *initCmd) tlsOptions() error { - i.opts.EnableTLS = tlsEnable || tlsVerify - i.opts.VerifyTLS = tlsVerify + i.opts.EnableTLS = i.tlsEnable || i.tlsVerify + i.opts.VerifyTLS = i.tlsVerify if i.opts.EnableTLS { missing := func(file string) bool { _, err := os.Stat(file) return os.IsNotExist(err) } - if i.opts.TLSKeyFile = tlsKeyFile; i.opts.TLSKeyFile == "" || missing(i.opts.TLSKeyFile) { + if i.opts.TLSKeyFile = i.tlsKeyFile; i.opts.TLSKeyFile == "" || missing(i.opts.TLSKeyFile) { return errors.New("missing required TLS key file") } - if i.opts.TLSCertFile = tlsCertFile; i.opts.TLSCertFile == "" || missing(i.opts.TLSCertFile) { + if i.opts.TLSCertFile = i.tlsCertFile; i.opts.TLSCertFile == "" || missing(i.opts.TLSCertFile) { return errors.New("missing required TLS certificate file") } if i.opts.VerifyTLS { - if i.opts.TLSCaCertFile = tlsCaCertFile; i.opts.TLSCaCertFile == "" || missing(i.opts.TLSCaCertFile) { + if i.opts.TLSCaCertFile = i.tlsCaCertFile; i.opts.TLSCaCertFile == "" || missing(i.opts.TLSCaCertFile) { return errors.New("missing required TLS CA file") } } diff --git a/pkg/helm/environment/environment.go b/pkg/helm/environment/environment.go index b8bcf0def..5e460dd8d 100644 --- a/pkg/helm/environment/environment.go +++ b/pkg/helm/environment/environment.go @@ -49,6 +49,16 @@ type EnvSettings struct { KubeContext string // KubeConfig is the name of the kubeconfig file. KubeConfig string + // TLSCaCertFile is the path to TLS CA certificate file for Helm to verify the Tiller server certificate + TLSCaCertFile string + // TLSCertFile is the path to Helm TLS client certificate file for authenticating to Tiller + TLSCertFile string + // TLSKeyFile is the path to Helm TLS client key file for authenticating to Tiller + TLSKeyFile string + // TLSVerify enables TLS between Helm and Tiller and verification of the Tiller server certificate + TLSVerify bool + // TLSEnable enables TLS between Helm and Tiller + TLSEnable bool } // AddFlags binds flags to the given flagset. @@ -59,6 +69,11 @@ func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&s.KubeConfig, "kubeconfig", "", "path to kubeconfig file. Overrides $KUBECONFIG") fs.BoolVar(&s.Debug, "debug", false, "enable verbose output") fs.StringVar(&s.TillerNamespace, "tiller-namespace", "kube-system", "namespace of Tiller") + fs.StringVar(&s.TLSCaCertFile, "tls-ca-cert", "", "path to TLS CA certificate file for Helm to verify Tiller server certificate") + fs.StringVar(&s.TLSCertFile, "tls-cert", "", "path to Helm TLS client certificate file for authenticating to Tiller") + fs.StringVar(&s.TLSKeyFile, "tls-key", "", "path to Helm TLS client key file for authenticating to Tiller") + fs.BoolVar(&s.TLSVerify, "tls-verify", false, "enable TLS connection between Helm and Tiller and verify Tiller server certificate") + fs.BoolVar(&s.TLSEnable, "tls", false, "enable TLS connection between Helm and Tiller") } // Init sets values from the environment. @@ -66,6 +81,16 @@ func (s *EnvSettings) Init(fs *pflag.FlagSet) { for name, envar := range envMap { setFlagFromEnv(name, envar, fs) } + // TLS defaults that depend on Home value + if s.TLSCaCertFile == "" { + s.TLSCaCertFile = s.Home.TLSCaCert() + } + if s.TLSCertFile == "" { + s.TLSCertFile = s.Home.TLSCert() + } + if s.TLSKeyFile == "" { + s.TLSKeyFile = s.Home.TLSKey() + } } // PluginDirs is the path to the plugin directories. @@ -83,6 +108,11 @@ var envMap = map[string]string{ "host": "HELM_HOST", "kubeconfig": "KUBECONFIG", "tiller-namespace": "TILLER_NAMESPACE", + "tls-ca-cert": "HELM_TLS_CA_CERT", + "tls-cert": "HELM_TLS_CERT", + "tls-key": "HELM_TLS_KEY", + "tls-verify": "HELM_TLS_VERIFY", + "tls": "HELM_TLS_ENABLE", } func setFlagFromEnv(name, envar string, fs *pflag.FlagSet) { @@ -90,7 +120,7 @@ func setFlagFromEnv(name, envar string, fs *pflag.FlagSet) { return } if v, ok := os.LookupEnv(envar); ok { - fs.Set(name, v) + fs.Set(name, os.ExpandEnv(v)) } }