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
ad614b91
Commit
ad614b91
authored
Mar 20, 2017
by
fibonacci1729
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: helm support for TLS
parent
1c1bfb27
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 @
ad614b91
...
...
@@ -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 @
ad614b91
...
...
@@ -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 @
ad614b91
...
...
@@ -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 @
ad614b91
...
...
@@ -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 @
ad614b91
...
...
@@ -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 @
ad614b91
...
...
@@ -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