pull/3496/merge
Keith Burdis 7 years ago committed by GitHub
commit d4f1928a96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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
}

@ -40,16 +40,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
)
@ -76,6 +66,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 used to verify the Helm client and Tiller server certificates (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 client key file for authenticating to Tiller (default "$HELM_HOME/key.pem")
$HELM_TLS_VERIFY enable TLS connection between Helm and Tiller and verify Tiller server certificate (default "false")
$HELM_TLS_ENABLE enable TLS connection between Helm and Tiller (default "false")
`
func newRootCmd(args []string) *cobra.Command {
@ -84,11 +79,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()
},
@ -113,18 +103,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),
@ -270,20 +260,11 @@ func ensureHelmClient(h helm.Interface) helm.Interface {
func newClient() helm.Interface {
options := []helm.Option{helm.Host(settings.TillerHost), helm.ConnectTimeout(settings.TillerConnectionTimeout)}
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)
@ -295,16 +276,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
}

@ -90,6 +90,11 @@ type initCmd struct {
maxHistory int
replicas int
wait bool
tlsEnable bool
tlsVerify bool
tlsKeyFile string
tlsCertFile string
tlsCaCertFile string
}
func newInitCmd(out io.Writer) *cobra.Command {
@ -105,6 +110,7 @@ func newInitCmd(out io.Writer) *cobra.Command {
}
i.namespace = settings.TillerNamespace
i.home = settings.Home
i.tlsCaCertFile = settings.TLSCaCertFile
i.client = ensureHelmClient(i.client)
return i.run()
@ -121,11 +127,10 @@ 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.BoolVar(&i.tlsEnable, "tiller-tls", false, "install Tiller with TLS enabled")
f.BoolVar(&i.tlsVerify, "tiller-tls-verify", false, "install Tiller with TLS and Helm client certificate verification enabled")
f.StringVar(&i.tlsKeyFile, "tiller-tls-key", "", "path to Tiller TLS server key file")
f.StringVar(&i.tlsCertFile, "tiller-tls-cert", "", "path to Tiller TLS server certificate file")
f.StringVar(&stableRepositoryURL, "stable-repo-url", stableRepositoryURL, "URL for stable repository")
f.StringVar(&localRepositoryURL, "local-repo-url", localRepositoryURL, "URL for local repository")
@ -145,22 +150,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) {
return errors.New("missing required TLS key file")
if i.opts.TLSKeyFile = i.tlsKeyFile; i.opts.TLSKeyFile == "" || missing(i.opts.TLSKeyFile) {
return errors.New("missing required TLS server key file")
}
if i.opts.TLSCertFile = tlsCertFile; i.opts.TLSCertFile == "" || missing(i.opts.TLSCertFile) {
return errors.New("missing required TLS certificate file")
if i.opts.TLSCertFile = i.tlsCertFile; i.opts.TLSCertFile == "" || missing(i.opts.TLSCertFile) {
return errors.New("missing required TLS server 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")
}
}

@ -280,13 +280,14 @@ func TestInitCmd_tlsOptions(t *testing.T) {
}
for _, tt := range tests {
// emulate tls file specific flags
tlsCaCertFile, tlsCertFile, tlsKeyFile = tt.caFile, tt.certFile, tt.keyFile
// emulate tls enable/verify flags
tlsEnable, tlsVerify = tt.enable, tt.verify
cmd := &initCmd{}
// emulate tls flags
cmd := &initCmd{
tlsCaCertFile: tt.caFile,
tlsCertFile: tt.certFile,
tlsKeyFile: tt.keyFile,
tlsVerify: tt.verify,
tlsEnable: tt.enable,
}
if err := cmd.tlsOptions(); err != nil {
t.Fatalf("unexpected error: %v", err)
}

@ -49,6 +49,16 @@ type EnvSettings struct {
Debug bool
// KubeContext is the name of the kubeconfig context.
KubeContext string
// TLSCaCertFile is the path to TLS CA certificate file used to verify the Helm client and Tiller server certificates
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.BoolVar(&s.Debug, "debug", false, "enable verbose output")
fs.StringVar(&s.TillerNamespace, "tiller-namespace", "kube-system", "namespace of Tiller")
fs.Int64Var(&s.TillerConnectionTimeout, "tiller-connection-timeout", int64(300), "the duration (in seconds) Helm will wait to establish a connection to tiller")
fs.StringVar(&s.TLSCaCertFile, "tls-ca-cert", "", "path to TLS CA certificate file used to verify the Helm client and Tiller server certificates")
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.
@ -82,6 +107,11 @@ var envMap = map[string]string{
"home": "HELM_HOME",
"host": "HELM_HOST",
"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) {
@ -89,7 +119,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))
}
}

@ -37,6 +37,8 @@ func TestEnvSettings(t *testing.T) {
// expected values
home, host, ns, kcontext, plugins string
debug bool
tlsca, tlscert, tlskey string
tlsenable, tlsverify bool
}{
{
name: "defaults",
@ -44,6 +46,11 @@ func TestEnvSettings(t *testing.T) {
home: DefaultHelmHome,
plugins: helmpath.Home(DefaultHelmHome).Plugins(),
ns: "kube-system",
tlsca: helmpath.Home(DefaultHelmHome).TLSCaCert(),
tlscert: helmpath.Home(DefaultHelmHome).TLSCert(),
tlskey: helmpath.Home(DefaultHelmHome).TLSKey(),
tlsenable: false,
tlsverify: false,
},
{
name: "with flags set",
@ -53,6 +60,11 @@ func TestEnvSettings(t *testing.T) {
host: "here",
ns: "myns",
debug: true,
tlsca: helmpath.Home("/foo").TLSCaCert(),
tlscert: helmpath.Home("/foo").TLSCert(),
tlskey: helmpath.Home("/foo").TLSKey(),
tlsenable: false,
tlsverify: false,
},
{
name: "with envvars set",
@ -63,6 +75,11 @@ func TestEnvSettings(t *testing.T) {
host: "there",
ns: "yourns",
debug: true,
tlsca: helmpath.Home("/bar").TLSCaCert(),
tlscert: helmpath.Home("/bar").TLSCert(),
tlskey: helmpath.Home("/bar").TLSKey(),
tlsenable: false,
tlsverify: false,
},
{
name: "with flags and envvars set",
@ -73,6 +90,50 @@ func TestEnvSettings(t *testing.T) {
host: "here",
ns: "myns",
debug: true,
tlsca: helmpath.Home("/foo").TLSCaCert(),
tlscert: helmpath.Home("/foo").TLSCert(),
tlskey: helmpath.Home("/foo").TLSKey(),
tlsenable: false,
tlsverify: false,
},
{
name: "with TLS flags set",
args: []string{"--home", "/bar", "--tls-ca-cert", "/a/ca.crt", "--tls-cert=/a/client.crt", "--tls-key", "/a/client.key", "--tls-verify", "--tls"},
home: "/bar",
plugins: helmpath.Home("/bar").Plugins(),
ns: "kube-system",
debug: false,
tlsca: "/a/ca.crt",
tlscert: "/a/client.crt",
tlskey: "/a/client.key",
tlsenable: true,
tlsverify: true,
},
{
name: "with TLS envvars set",
args: []string{},
envars: map[string]string{"HELM_HOME": "/bar", "HELM_TLS_CA_CERT": "/e/ca.crt", "HELM_TLS_CERT": "/e/client.crt", "HELM_TLS_KEY": "/e/client.key", "HELM_TLS_VERIFY": "true", "HELM_TLS_ENABLE": "true"},
home: "/bar",
plugins: helmpath.Home("/bar").Plugins(),
ns: "kube-system",
tlsca: "/e/ca.crt",
tlscert: "/e/client.crt",
tlskey: "/e/client.key",
tlsenable: true,
tlsverify: true,
},
{
name: "with TLS flags and envvars set",
args: []string{"--tls-ca-cert", "/a/ca.crt", "--tls-cert=/a/client.crt", "--tls-key", "/a/client.key", "--tls-verify"},
envars: map[string]string{"HELM_HOME": "/bar", "HELM_TLS_CA_CERT": "/e/ca.crt", "HELM_TLS_CERT": "/e/client.crt", "HELM_TLS_KEY": "/e/client.key", "HELM_TLS_VERIFY": "true", "HELM_TLS_ENABLE": "true"},
home: "/bar",
plugins: helmpath.Home("/bar").Plugins(),
ns: "kube-system",
tlsca: "/a/ca.crt",
tlscert: "/a/client.crt",
tlskey: "/a/client.key",
tlsenable: true,
tlsverify: true,
},
}
@ -111,7 +172,25 @@ func TestEnvSettings(t *testing.T) {
if settings.KubeContext != tt.kcontext {
t.Errorf("expected kube-context %q, got %q", tt.kcontext, settings.KubeContext)
}
if settings.TLSCaCertFile != tt.tlsca {
t.Errorf("expected tls-ca-cert %q, got %q", tt.tlsca, settings.TLSCaCertFile)
}
if settings.TLSCertFile != tt.tlscert {
t.Errorf("expected tls-cert %q, got %q", tt.tlscert, settings.TLSCertFile)
}
if settings.TLSKeyFile != tt.tlskey {
t.Errorf("expected tls-key %q, got %q", tt.tlskey, settings.TLSKeyFile)
}
if settings.TLSEnable != tt.tlsenable {
t.Errorf("expected tls %t, got %t", tt.tlsenable, settings.TLSEnable)
}
if settings.TLSVerify != tt.tlsverify {
t.Errorf("expected tls-verify %t, got %t", tt.tlsverify, settings.TLSVerify)
}
for k := range tt.envars {
os.Unsetenv(k)
}
cleanup()
})
}

Loading…
Cancel
Save