Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
H
helm3
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
helm3
Commits
d7cb50bf
Commit
d7cb50bf
authored
Mar 22, 2017
by
Brian
Committed by
GitHub
Mar 22, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2144 from fibonacci1729/feat/helm-tls
helm (client/deployment) support for TLS
parents
1c1bfb27
ad614b91
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
205 additions
and
45 deletions
+205
-45
helm.go
cmd/helm/helm.go
+8
-0
init.go
cmd/helm/init.go
+59
-11
install.go
cmd/helm/installer/install.go
+100
-28
install_test.go
cmd/helm/installer/install_test.go
+11
-3
options.go
cmd/helm/installer/options.go
+21
-1
uninstall_test.go
cmd/helm/installer/uninstall_test.go
+6
-2
No files found.
cmd/helm/helm.go
View file @
d7cb50bf
...
...
@@ -45,6 +45,14 @@ const (
tillerNamespaceEnvVar
=
"TILLER_NAMESPACE"
)
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
)
var
(
helmHome
string
tillerHost
string
...
...
cmd/helm/init.go
View file @
d7cb50bf
...
...
@@ -70,6 +70,7 @@ type initCmd struct {
dryRun
bool
out
io
.
Writer
home
helmpath
.
Home
opts
installer
.
Options
kubeClient
internalclientset
.
Interface
}
...
...
@@ -99,25 +100,73 @@ func newInitCmd(out io.Writer) *cobra.Command {
f
.
BoolVarP
(
&
i
.
clientOnly
,
"client-only"
,
"c"
,
false
,
"if set does not install tiller"
)
f
.
BoolVar
(
&
i
.
dryRun
,
"dry-run"
,
false
,
"do not install local or remote"
)
// 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")
return
cmd
}
// 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
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
.
TLSCertFile
=
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
)
{
return
errors
.
New
(
"missing required TLS CA file"
)
}
}
}
return
nil
}
// runInit initializes local config and installs tiller to Kubernetes Cluster
func
(
i
*
initCmd
)
run
()
error
{
if
err
:=
i
.
tlsOptions
();
err
!=
nil
{
return
err
}
i
.
opts
.
Namespace
=
i
.
namespace
i
.
opts
.
UseCanary
=
i
.
canary
i
.
opts
.
ImageSpec
=
i
.
image
if
flagDebug
{
dm
,
err
:=
installer
.
DeploymentManifest
(
i
.
namespace
,
i
.
image
,
i
.
canary
)
if
err
!=
nil
{
var
mfs
string
var
err
error
// write deployment manifest
if
mfs
,
err
=
installer
.
DeploymentManifest
(
&
i
.
opts
);
err
!=
nil
{
return
err
}
fm
:=
fmt
.
Sprintf
(
"apiVersion: extensions/v1beta1
\n
kind: Deployment
\n
%s"
,
dm
)
fmt
.
Fprintln
(
i
.
out
,
fm
)
fmt
.
Fprintln
(
i
.
out
,
fmt
.
Sprintf
(
"apiVersion: extensions/v1beta1
\n
kind: Deployment
\n
%s"
,
mfs
))
sm
,
err
:=
installer
.
ServiceManifest
(
i
.
namespace
)
if
err
!=
nil
{
// write service manifest
if
mfs
,
err
=
installer
.
ServiceManifest
(
i
.
namespace
);
err
!=
nil
{
return
err
}
fm
=
fmt
.
Sprintf
(
"apiVersion: v1
\n
kind: Service
\n
%s"
,
sm
)
fmt
.
Fprintln
(
i
.
out
,
fm
)
fmt
.
Fprintln
(
i
.
out
,
fmt
.
Sprintf
(
"apiVersion: v1
\n
kind: Service
\n
%s"
,
mfs
))
// write secret manifest
if
i
.
opts
.
EnableTLS
{
if
mfs
,
err
=
installer
.
SecretManifest
(
&
i
.
opts
);
err
!=
nil
{
return
err
}
fmt
.
Fprintln
(
i
.
out
,
fmt
.
Sprintf
(
"apiVersion: v1
\n
kind: Secret
\n
%s"
,
mfs
))
}
}
if
i
.
dryRun
{
...
...
@@ -143,13 +192,12 @@ func (i *initCmd) run() error {
}
i
.
kubeClient
=
c
}
opts
:=
&
installer
.
Options
{
Namespace
:
i
.
namespace
,
ImageSpec
:
i
.
image
,
UseCanary
:
i
.
canary
}
if
err
:=
installer
.
Install
(
i
.
kubeClient
,
opts
);
err
!=
nil
{
if
err
:=
installer
.
Install
(
i
.
kubeClient
,
&
i
.
opts
);
err
!=
nil
{
if
!
kerrors
.
IsAlreadyExists
(
err
)
{
return
fmt
.
Errorf
(
"error installing: %s"
,
err
)
}
if
i
.
upgrade
{
if
err
:=
installer
.
Upgrade
(
i
.
kubeClient
,
opts
);
err
!=
nil
{
if
err
:=
installer
.
Upgrade
(
i
.
kubeClient
,
&
i
.
opts
);
err
!=
nil
{
return
fmt
.
Errorf
(
"error when upgrading: %s"
,
err
)
}
fmt
.
Fprintln
(
i
.
out
,
"
\n
Tiller (the helm server side component) has been upgraded to the current version."
)
...
...
cmd/helm/installer/install.go
View file @
d7cb50bf
...
...
@@ -17,7 +17,7 @@ limitations under the License.
package
installer
// import "k8s.io/helm/cmd/helm/installer"
import
(
"
fmt
"
"
io/ioutil
"
"github.com/ghodss/yaml"
...
...
@@ -28,22 +28,23 @@ import (
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
extensionsclient
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion"
"k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/helm/pkg/version"
)
const
defaultImage
=
"gcr.io/kubernetes-helm/tiller"
// Install uses kubernetes client to install tiller.
//
// Returns an error if the command failed.
func
Install
(
client
internalclientset
.
Interface
,
opts
*
Options
)
error
{
if
err
:=
createDeployment
(
client
.
Extensions
(),
opts
.
Namespace
,
opts
.
ImageSpec
,
opts
.
UseCanary
);
err
!=
nil
{
if
err
:=
createDeployment
(
client
.
Extensions
(),
opts
);
err
!=
nil
{
return
err
}
if
err
:=
createService
(
client
.
Core
(),
opts
.
Namespace
);
err
!=
nil
{
return
err
}
if
opts
.
tls
()
{
if
err
:=
createSecret
(
client
.
Core
(),
opts
);
err
!=
nil
{
return
err
}
}
return
nil
}
...
...
@@ -55,7 +56,7 @@ func Upgrade(client internalclientset.Interface, opts *Options) error {
if
err
!=
nil
{
return
err
}
obj
.
Spec
.
Template
.
Spec
.
Containers
[
0
]
.
Image
=
selectImage
(
opts
.
ImageSpec
,
opts
.
UseCanary
)
obj
.
Spec
.
Template
.
Spec
.
Containers
[
0
]
.
Image
=
opts
.
selectImage
(
)
if
_
,
err
:=
client
.
Extensions
()
.
Deployments
(
opts
.
Namespace
)
.
Update
(
obj
);
err
!=
nil
{
return
err
}
...
...
@@ -73,15 +74,15 @@ func Upgrade(client internalclientset.Interface, opts *Options) error {
}
// createDeployment creates the Tiller deployment reource
func
createDeployment
(
client
extensionsclient
.
DeploymentsGetter
,
namespace
,
image
string
,
canary
bool
)
error
{
obj
:=
deployment
(
namespace
,
image
,
canary
)
func
createDeployment
(
client
extensionsclient
.
DeploymentsGetter
,
opts
*
Options
)
error
{
obj
:=
deployment
(
opts
)
_
,
err
:=
client
.
Deployments
(
obj
.
Namespace
)
.
Create
(
obj
)
return
err
}
// deployment gets the deployment object that installs Tiller.
func
deployment
(
namespace
,
image
string
,
canary
bool
)
*
extensions
.
Deployment
{
return
generateDeployment
(
namespace
,
selectImage
(
image
,
canary
)
)
func
deployment
(
opts
*
Options
)
*
extensions
.
Deployment
{
return
generateDeployment
(
opts
)
}
// createService creates the Tiller service resource
...
...
@@ -96,21 +97,10 @@ func service(namespace string) *api.Service {
return
generateService
(
namespace
)
}
func
selectImage
(
image
string
,
canary
bool
)
string
{
switch
{
case
canary
:
image
=
defaultImage
+
":canary"
case
image
==
""
:
image
=
fmt
.
Sprintf
(
"%s:%s"
,
defaultImage
,
version
.
Version
)
}
return
image
}
// DeploymentManifest gets the manifest (as a string) that describes the Tiller Deployment
// resource.
func
DeploymentManifest
(
namespace
,
image
string
,
canary
bool
)
(
string
,
error
)
{
obj
:=
deployment
(
namespace
,
image
,
canary
)
func
DeploymentManifest
(
opts
*
Options
)
(
string
,
error
)
{
obj
:=
deployment
(
opts
)
buf
,
err
:=
yaml
.
Marshal
(
obj
)
return
string
(
buf
),
err
}
...
...
@@ -129,11 +119,11 @@ func generateLabels(labels map[string]string) map[string]string {
return
labels
}
func
generateDeployment
(
namespace
,
image
string
)
*
extensions
.
Deployment
{
func
generateDeployment
(
opts
*
Options
)
*
extensions
.
Deployment
{
labels
:=
generateLabels
(
map
[
string
]
string
{
"name"
:
"tiller"
})
d
:=
&
extensions
.
Deployment
{
ObjectMeta
:
api
.
ObjectMeta
{
Namespace
:
n
amespace
,
Namespace
:
opts
.
N
amespace
,
Name
:
"tiller-deploy"
,
Labels
:
labels
,
},
...
...
@@ -147,13 +137,13 @@ func generateDeployment(namespace, image string) *extensions.Deployment {
Containers
:
[]
api
.
Container
{
{
Name
:
"tiller"
,
Image
:
image
,
Image
:
opts
.
selectImage
()
,
ImagePullPolicy
:
"IfNotPresent"
,
Ports
:
[]
api
.
ContainerPort
{
{
ContainerPort
:
44134
,
Name
:
"tiller"
},
},
Env
:
[]
api
.
EnvVar
{
{
Name
:
"TILLER_NAMESPACE"
,
Value
:
n
amespace
},
{
Name
:
"TILLER_NAMESPACE"
,
Value
:
opts
.
N
amespace
},
},
LivenessProbe
:
&
api
.
Probe
{
Handler
:
api
.
Handler
{
...
...
@@ -181,6 +171,37 @@ func generateDeployment(namespace, image string) *extensions.Deployment {
},
},
}
if
opts
.
tls
()
{
const
certsDir
=
"/etc/certs"
var
tlsVerify
,
tlsEnable
=
""
,
"1"
if
opts
.
VerifyTLS
{
tlsVerify
=
"1"
}
// Mount secret to "/etc/certs"
d
.
Spec
.
Template
.
Spec
.
Containers
[
0
]
.
VolumeMounts
=
append
(
d
.
Spec
.
Template
.
Spec
.
Containers
[
0
]
.
VolumeMounts
,
api
.
VolumeMount
{
Name
:
"tiller-certs"
,
ReadOnly
:
true
,
MountPath
:
certsDir
,
})
// Add environment variable required for enabling TLS
d
.
Spec
.
Template
.
Spec
.
Containers
[
0
]
.
Env
=
append
(
d
.
Spec
.
Template
.
Spec
.
Containers
[
0
]
.
Env
,
[]
api
.
EnvVar
{
{
Name
:
"TILLER_TLS_VERIFY"
,
Value
:
tlsVerify
},
{
Name
:
"TILLER_TLS_ENABLE"
,
Value
:
tlsEnable
},
{
Name
:
"TILLER_TLS_CERTS"
,
Value
:
certsDir
},
}
...
)
// Add secret volume to deployment
d
.
Spec
.
Template
.
Spec
.
Volumes
=
append
(
d
.
Spec
.
Template
.
Spec
.
Volumes
,
api
.
Volume
{
Name
:
"tiller-certs"
,
VolumeSource
:
api
.
VolumeSource
{
Secret
:
&
api
.
SecretVolumeSource
{
SecretName
:
"tiller-secret"
,
},
},
})
}
return
d
}
...
...
@@ -206,3 +227,54 @@ func generateService(namespace string) *api.Service {
}
return
s
}
// SecretManifest gets the manifest (as a string) that describes the Tiller Secret resource.
func
SecretManifest
(
opts
*
Options
)
(
string
,
error
)
{
o
,
err
:=
generateSecret
(
opts
)
if
err
!=
nil
{
return
""
,
err
}
buf
,
err
:=
yaml
.
Marshal
(
o
)
return
string
(
buf
),
err
}
// createSecret creates the Tiller secret resource.
func
createSecret
(
client
internalversion
.
SecretsGetter
,
opts
*
Options
)
error
{
o
,
err
:=
generateSecret
(
opts
)
if
err
!=
nil
{
return
err
}
_
,
err
=
client
.
Secrets
(
o
.
Namespace
)
.
Create
(
o
)
return
err
}
// generateSecret builds the secret object that hold Tiller secrets.
func
generateSecret
(
opts
*
Options
)
(
*
api
.
Secret
,
error
)
{
const
secretName
=
"tiller-secret"
labels
:=
generateLabels
(
map
[
string
]
string
{
"name"
:
"tiller"
})
secret
:=
&
api
.
Secret
{
Type
:
api
.
SecretTypeOpaque
,
Data
:
make
(
map
[
string
][]
byte
),
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
secretName
,
Labels
:
labels
,
Namespace
:
opts
.
Namespace
,
},
}
var
err
error
if
secret
.
Data
[
"tls.key"
],
err
=
read
(
opts
.
TLSKeyFile
);
err
!=
nil
{
return
nil
,
err
}
if
secret
.
Data
[
"tls.crt"
],
err
=
read
(
opts
.
TLSCertFile
);
err
!=
nil
{
return
nil
,
err
}
if
opts
.
VerifyTLS
{
if
secret
.
Data
[
"ca.crt"
],
err
=
read
(
opts
.
TLSCaCertFile
);
err
!=
nil
{
return
nil
,
err
}
}
return
secret
,
nil
}
func
read
(
path
string
)
(
b
[]
byte
,
err
error
)
{
return
ioutil
.
ReadFile
(
path
)
}
cmd/helm/installer/install_test.go
View file @
d7cb50bf
...
...
@@ -45,7 +45,7 @@ func TestDeploymentManifest(t *testing.T) {
}
for
_
,
tt
:=
range
tests
{
o
,
err
:=
DeploymentManifest
(
api
.
NamespaceDefault
,
tt
.
image
,
tt
.
canary
)
o
,
err
:=
DeploymentManifest
(
&
Options
{
Namespace
:
api
.
NamespaceDefault
,
ImageSpec
:
tt
.
image
,
UseCanary
:
tt
.
canary
}
)
if
err
!=
nil
{
t
.
Fatalf
(
"%s: error %q"
,
tt
.
name
,
err
)
}
...
...
@@ -146,7 +146,11 @@ func TestInstall_canary(t *testing.T) {
func
TestUpgrade
(
t
*
testing
.
T
)
{
image
:=
"gcr.io/kubernetes-helm/tiller:v2.0.0"
existingDeployment
:=
deployment
(
api
.
NamespaceDefault
,
"imageToReplace"
,
false
)
existingDeployment
:=
deployment
(
&
Options
{
Namespace
:
api
.
NamespaceDefault
,
ImageSpec
:
"imageToReplace"
,
UseCanary
:
false
,
})
existingService
:=
service
(
api
.
NamespaceDefault
)
fc
:=
&
fake
.
Clientset
{}
...
...
@@ -178,7 +182,11 @@ func TestUpgrade(t *testing.T) {
func
TestUpgrade_serviceNotFound
(
t
*
testing
.
T
)
{
image
:=
"gcr.io/kubernetes-helm/tiller:v2.0.0"
existingDeployment
:=
deployment
(
api
.
NamespaceDefault
,
"imageToReplace"
,
false
)
existingDeployment
:=
deployment
(
&
Options
{
Namespace
:
api
.
NamespaceDefault
,
ImageSpec
:
"imageToReplace"
,
UseCanary
:
false
,
})
fc
:=
&
fake
.
Clientset
{}
fc
.
AddReactor
(
"get"
,
"deployments"
,
func
(
action
testcore
.
Action
)
(
bool
,
runtime
.
Object
,
error
)
{
...
...
cmd/helm/installer/options.go
View file @
d7cb50bf
...
...
@@ -16,6 +16,13 @@ limitations under the License.
package
installer
// import "k8s.io/helm/cmd/helm/installer"
import
(
"fmt"
"k8s.io/helm/pkg/version"
)
const
defaultImage
=
"gcr.io/kubernetes-helm/tiller"
// Options control how to install tiller into a cluster, upgrade, and uninstall tiller from a cluster.
type
Options
struct
{
// EnableTLS instructs tiller to serve with TLS enabled.
...
...
@@ -43,7 +50,7 @@ type Options struct {
// key tiller should use.
//
// Required and valid if and only if EnableTLS or VerifyTLS is set.
TLSKey
string
TLSKey
File
string
// TLSCertFile identifies the file containing the pem encoded TLS
// certificate tiller should use.
...
...
@@ -57,3 +64,16 @@ type Options struct {
// Required and valid if and only if VerifyTLS is set.
TLSCaCertFile
string
}
func
(
opts
*
Options
)
selectImage
()
string
{
switch
{
case
opts
.
UseCanary
:
return
defaultImage
+
":canary"
case
opts
.
ImageSpec
==
""
:
return
fmt
.
Sprintf
(
"%s:%s"
,
defaultImage
,
version
.
Version
)
default
:
return
opts
.
ImageSpec
}
}
func
(
opts
*
Options
)
tls
()
bool
{
return
opts
.
EnableTLS
||
opts
.
VerifyTLS
}
cmd/helm/installer/uninstall_test.go
View file @
d7cb50bf
...
...
@@ -55,7 +55,11 @@ func (f *fakeReaperFactory) Reaper(mapping *meta.RESTMapping) (kubectl.Reaper, e
func
TestUninstall
(
t
*
testing
.
T
)
{
existingService
:=
service
(
api
.
NamespaceDefault
)
existingDeployment
:=
deployment
(
api
.
NamespaceDefault
,
"image"
,
false
)
existingDeployment
:=
deployment
(
&
Options
{
Namespace
:
api
.
NamespaceDefault
,
ImageSpec
:
"image"
,
UseCanary
:
false
,
})
fc
:=
&
fake
.
Clientset
{}
fc
.
AddReactor
(
"get"
,
"services"
,
func
(
action
testcore
.
Action
)
(
bool
,
runtime
.
Object
,
error
)
{
...
...
@@ -92,7 +96,7 @@ func TestUninstall(t *testing.T) {
}
func
TestUninstall_serviceNotFound
(
t
*
testing
.
T
)
{
existingDeployment
:=
deployment
(
api
.
NamespaceDefault
,
"imageToReplace"
,
false
)
existingDeployment
:=
deployment
(
&
Options
{
Namespace
:
api
.
NamespaceDefault
,
ImageSpec
:
"imageToReplace"
,
UseCanary
:
false
}
)
fc
:=
&
fake
.
Clientset
{}
fc
.
AddReactor
(
"get"
,
"services"
,
func
(
action
testcore
.
Action
)
(
bool
,
runtime
.
Object
,
error
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment