diff --git a/Gopkg.lock b/Gopkg.lock index d60c829e5..e258713b5 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -701,6 +701,7 @@ "encoding/proto", "grpclb/grpc_lb_v1/messages", "grpclog", + "health/grpc_health_v1", "internal", "keepalive", "metadata", @@ -772,6 +773,14 @@ revision = "072894a440bdee3a891dea811fe42902311cd2a3" version = "kubernetes-1.11.0" +[[projects]] + branch = "master" + digest = "1:0a865e7f317907161f1c2df5f270595b9d7ba09850b7eb39a2b11cc8f9a50d28" + name = "k8s.io/apiextensions-apiserver" + packages = ["pkg/features"] + pruneopts = "" + revision = "84f7c7786e298ad1479d00ff314a2cfa0006cd0c" + [[projects]] digest = "1:b6b2fb7b4da1ac973b64534ace2299a02504f16bc7820cb48edb8ca4077183e1" name = "k8s.io/apimachinery" @@ -825,6 +834,17 @@ revision = "103fd098999dc9c0c88536f5c9ad2e5da39373ae" version = "kubernetes-1.11.0" +[[projects]] + branch = "master" + digest = "1:307114f0d43e1f0b8ce6fba0ca3369b7270504e99fd9125a698b4ef0b6f686c6" + name = "k8s.io/apiserver" + packages = [ + "pkg/features", + "pkg/util/feature", + ] + pruneopts = "" + revision = "f2e7e4864e403362f09eded9fb122b0f0b622c7c" + [[projects]] digest = "1:d04779a8de7d5465e0463bd986506348de5e89677c74777f695d3145a7a8d15e" name = "k8s.io/client-go" @@ -965,7 +985,7 @@ revision = "b58fc7edb82e0c6ffc9b8aef61813c7261b785d4" [[projects]] - digest = "1:0bb3ef18f8f199bf341cab6b7de16b4b132cca2cfcbf498228a37e4c6a4a732e" + digest = "1:ec6534bd79f79351514d62ff48f4f547aeb53ea0c9ee45ca5594fbdfbd2fc258" name = "k8s.io/helm" packages = [ "pkg/chartutil", @@ -975,13 +995,15 @@ "pkg/proto/hapi/release", "pkg/proto/hapi/services", "pkg/proto/hapi/version", + "pkg/storage/driver", "pkg/sympath", "pkg/tlsutil", + "pkg/urlutil", "pkg/version", ] pruneopts = "" - revision = "6af75a8fd72e2aa18a2b278cfe5c7a1c5feca7f2" - version = "v2.8.1" + revision = "9ad53aac42165a5fadc6c87be0dea6b115f93090" + version = "v2.10.0" [[projects]] branch = "master" @@ -991,6 +1013,88 @@ pruneopts = "" revision = "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" +[[projects]] + digest = "1:89eef4670d767c8f3e520d71509f40e77698b4bc898305b6ee0220300840b788" + name = "k8s.io/kubernetes" + packages = [ + "pkg/api/legacyscheme", + "pkg/api/ref", + "pkg/apis/admissionregistration", + "pkg/apis/admissionregistration/install", + "pkg/apis/admissionregistration/v1alpha1", + "pkg/apis/admissionregistration/v1beta1", + "pkg/apis/apps", + "pkg/apis/apps/install", + "pkg/apis/apps/v1", + "pkg/apis/apps/v1beta1", + "pkg/apis/apps/v1beta2", + "pkg/apis/authentication", + "pkg/apis/authentication/install", + "pkg/apis/authentication/v1", + "pkg/apis/authentication/v1beta1", + "pkg/apis/authorization", + "pkg/apis/authorization/install", + "pkg/apis/authorization/v1", + "pkg/apis/authorization/v1beta1", + "pkg/apis/autoscaling", + "pkg/apis/autoscaling/install", + "pkg/apis/autoscaling/v1", + "pkg/apis/autoscaling/v2beta1", + "pkg/apis/batch", + "pkg/apis/batch/install", + "pkg/apis/batch/v1", + "pkg/apis/batch/v1beta1", + "pkg/apis/batch/v2alpha1", + "pkg/apis/certificates", + "pkg/apis/certificates/install", + "pkg/apis/certificates/v1beta1", + "pkg/apis/componentconfig", + "pkg/apis/componentconfig/install", + "pkg/apis/componentconfig/v1alpha1", + "pkg/apis/core", + "pkg/apis/core/install", + "pkg/apis/core/v1", + "pkg/apis/events", + "pkg/apis/events/install", + "pkg/apis/events/v1beta1", + "pkg/apis/extensions", + "pkg/apis/extensions/install", + "pkg/apis/extensions/v1beta1", + "pkg/apis/networking", + "pkg/apis/networking/install", + "pkg/apis/networking/v1", + "pkg/apis/policy", + "pkg/apis/policy/install", + "pkg/apis/policy/v1beta1", + "pkg/apis/rbac", + "pkg/apis/rbac/install", + "pkg/apis/rbac/v1", + "pkg/apis/rbac/v1alpha1", + "pkg/apis/rbac/v1beta1", + "pkg/apis/scheduling", + "pkg/apis/scheduling/install", + "pkg/apis/scheduling/v1alpha1", + "pkg/apis/scheduling/v1beta1", + "pkg/apis/settings", + "pkg/apis/settings/install", + "pkg/apis/settings/v1alpha1", + "pkg/apis/storage", + "pkg/apis/storage/install", + "pkg/apis/storage/v1", + "pkg/apis/storage/v1alpha1", + "pkg/apis/storage/v1beta1", + "pkg/client/clientset_generated/internalclientset/scheme", + "pkg/client/clientset_generated/internalclientset/typed/core/internalversion", + "pkg/features", + "pkg/kubelet/apis", + "pkg/master/ports", + "pkg/util/parsers", + "pkg/util/pointer", + ] + pruneopts = "" + revision = "bf9a868e8ea3d3a8fa53cbb22f566771b3f8068b" + version = "v1.11.4" + [solve-meta] analyzer-name = "dep" analyzer-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 9459924ae..6b65fd62e 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -40,7 +40,7 @@ required = ["k8s.io/code-generator/cmd/client-gen"] [[constraint]] name = "k8s.io/helm" - version = "v2.8.1" + version = "~v2.10.0" [[constraint]] name = "github.com/justinbarrick/go-k8s-portforward" diff --git a/chart/flux/templates/helm-operator-deployment.yaml b/chart/flux/templates/helm-operator-deployment.yaml index d395b75f1..93afbbcf2 100644 --- a/chart/flux/templates/helm-operator-deployment.yaml +++ b/chart/flux/templates/helm-operator-deployment.yaml @@ -98,6 +98,9 @@ spec: {{- if .Values.helmOperator.tls.verify }} - --tiller-tls-verify={{ .Values.helmOperator.tls.verify }} - --tiller-tls-ca-cert-path=/etc/fluxd/helm-ca/ca.crt + {{- if .Values.helmOperator.tls.hostname }} + - --tiller-tls-hostname={{ .Values.helmOperator.tls.hostname }} + {{- end }} {{- end }} {{- end }} {{- if .Values.helmOperator.extraEnvs }} diff --git a/chart/flux/templates/helm-tls.yaml b/chart/flux/templates/helm-tls.yaml index 1f926bd97..78814a606 100644 --- a/chart/flux/templates/helm-tls.yaml +++ b/chart/flux/templates/helm-tls.yaml @@ -6,6 +6,6 @@ metadata: name: {{ template "flux.fullname" . }}-helm-tls-ca-config data: ca.crt: | - {{ .Values.helmOperator.tls.caContent | indent 4 }} +{{ .Values.helmOperator.tls.caContent | indent 4 }} {{- end -}} {{- end -}} diff --git a/chart/flux/values.yaml b/chart/flux/values.yaml index 10a33141e..f2efc4fba 100644 --- a/chart/flux/values.yaml +++ b/chart/flux/values.yaml @@ -37,6 +37,7 @@ helmOperator: keyFile: "tls.key" certFile: "tls.crt" caContent: "" + hostname: "" # Override Flux git settings git: url: "" diff --git a/cmd/helm-operator/main.go b/cmd/helm-operator/main.go index aee1745b5..c3bc5efa7 100644 --- a/cmd/helm-operator/main.go +++ b/cmd/helm-operator/main.go @@ -42,11 +42,12 @@ var ( tillerPort *string tillerNamespace *string - tillerTLSVerify *bool - tillerTLSEnable *bool - tillerTLSKey *string - tillerTLSCert *string - tillerTLSCACert *string + tillerTLSVerify *bool + tillerTLSEnable *bool + tillerTLSKey *string + tillerTLSCert *string + tillerTLSCACert *string + tillerTLSHostname *string chartsSyncInterval *time.Duration chartsSyncTimeout *time.Duration @@ -100,6 +101,7 @@ func init() { tillerTLSKey = fs.String("tiller-tls-key-path", "/etc/fluxd/helm/tls.key", "Path to private key file used to communicate with the Tiller server.") tillerTLSCert = fs.String("tiller-tls-cert-path", "/etc/fluxd/helm/tls.crt", "Path to certificate file used to communicate with the Tiller server.") tillerTLSCACert = fs.String("tiller-tls-ca-cert-path", "", "Path to CA certificate file used to validate the Tiller server. Required if tiller-tls-verify is enabled.") + tillerTLSHostname = fs.String("tiller-tls-hostname", "", "The server name used to verify the hostname on the returned certificates from the server.") chartsSyncInterval = fs.Duration("charts-sync-interval", 3*time.Minute, "Interval at which to check for changed charts") chartsSyncTimeout = fs.Duration("charts-sync-timeout", 1*time.Minute, "Timeout when checking for changed charts") @@ -177,14 +179,15 @@ func main() { // HELM --------------------------------------------------------------------------------- helmClient := fluxhelm.ClientSetup(log.With(logger, "component", "helm"), kubeClient, fluxhelm.TillerOptions{ - IP: *tillerIP, - Port: *tillerPort, - Namespace: *tillerNamespace, - TLSVerify: *tillerTLSVerify, - TLSEnable: *tillerTLSEnable, - TLSKey: *tillerTLSKey, - TLSCert: *tillerTLSCert, - TLSCACert: *tillerTLSCACert, + Host: *tillerIP, + Port: *tillerPort, + Namespace: *tillerNamespace, + TLSVerify: *tillerTLSVerify, + TLSEnable: *tillerTLSEnable, + TLSKey: *tillerTLSKey, + TLSCert: *tillerTLSCert, + TLSCACert: *tillerTLSCACert, + TLSHostname: *tillerTLSHostname, }) // The status updater, to keep track the release status for each diff --git a/integrations/helm/helm.go b/integrations/helm/helm.go index 070c786d2..29960df71 100644 --- a/integrations/helm/helm.go +++ b/integrations/helm/helm.go @@ -5,7 +5,6 @@ import ( "time" "github.com/go-kit/kit/log" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" k8shelm "k8s.io/helm/pkg/helm" @@ -26,14 +25,15 @@ type RepoConfig struct { } type TillerOptions struct { - IP string - Port string - Namespace string - TLSVerify bool - TLSEnable bool - TLSKey string - TLSCert string - TLSCACert string + Host string + Port string + Namespace string + TLSVerify bool + TLSEnable bool + TLSKey string + TLSCert string + TLSCACert string + TLSHostname string } // Helm struct provides access to helm client @@ -52,13 +52,19 @@ func newClient(kubeClient *kubernetes.Clientset, opts TillerOptions) (*k8shelm.C options := []k8shelm.Option{k8shelm.Host(host)} if opts.TLSVerify || opts.TLSEnable { - tlscfg, err := tlsutil.ClientConfig(tlsutil.Options{ + tlsopts := tlsutil.Options{ KeyFile: opts.TLSKey, CertFile: opts.TLSCert, - InsecureSkipVerify: !opts.TLSVerify, - CaCertFile: opts.TLSCACert, - }) - + InsecureSkipVerify: true, + } + if opts.TLSVerify { + tlsopts.CaCertFile = opts.TLSCACert + tlsopts.InsecureSkipVerify = false + } + if opts.TLSHostname != "" { + tlsopts.ServerName = opts.TLSHostname + } + tlscfg, err := tlsutil.ClientConfig(tlsopts) if err != nil { return &k8shelm.Client{}, err } @@ -98,26 +104,13 @@ func GetTillerVersion(cl k8shelm.Client, h string) (string, error) { // TODO ... set up based on the tiller existing in the cluster, if no ops given func tillerHost(kubeClient *kubernetes.Clientset, opts TillerOptions) (string, error) { - var ts *corev1.Service - var err error - var ip string - var port string - - if opts.IP == "" { - ts, err = kubeClient.CoreV1().Services(opts.Namespace).Get("tiller-deploy", metav1.GetOptions{}) + if opts.Host == "" || opts.Port == "" { + ts, err := kubeClient.CoreV1().Services(opts.Namespace).Get("tiller-deploy", metav1.GetOptions{}) if err != nil { return "", err } - ip = ts.Spec.ClusterIP - port = fmt.Sprintf("%v", ts.Spec.Ports[0].Port) - } - - if opts.IP != "" { - ip = opts.IP - } - if opts.Port != "" { - port = fmt.Sprintf("%v", opts.Port) + return fmt.Sprintf("%s.%s:%v", ts.Name, ts.Namespace, ts.Spec.Ports[0].Port), nil } - return fmt.Sprintf("%s:%s", ip, port), nil + return fmt.Sprintf("%s:%s", opts.Host, opts.Port), nil } diff --git a/site/helm-operator.md b/site/helm-operator.md index 64c33073c..7f0148fd2 100644 --- a/site/helm-operator.md +++ b/site/helm-operator.md @@ -23,6 +23,7 @@ helm-operator requires setup and offers customization though a multitude of flag |--tiller-tls-tls-key-path |`/etc/fluxd/helm/tls.key` | Path to private key file used to communicate with the Tiller server. | |--tiller-tls-tls-cert-path |`/etc/fluxd/helm/tls.crt` | Path to certificate file used to communicate with the Tiller server. | |--tiller-tls-tls-ca-cert-path | | Path to CA certificate file used to validate the Tiller server. Required if tiller-tls-verify is enabled. | +|--tiller-tls-hostname | | The server name used to verify the hostname on the returned certificates from the Tiller server. | | | | **Git repo & key etc.**| |--git-url | | URL of git repo with Helm Charts; e.g., `ssh://git@github.com/weaveworks/flux-example`| |--git-branch | `master` | Branch of git repo to use for Kubernetes manifests| @@ -41,12 +42,15 @@ helm-operator requires setup and offers customization though a multitude of flag ### Installing Helm / Tiller -Generate certificates for Tiller and Flux. This will provide a CA, servercerts for tiller and client certs for helm / weave flux. +Generate certificates for Tiller and Flux. This will provide a CA, servercerts for Tiller and client certs for Helm / Weave Flux. + +> **Note**: When creating the certificate for Tiller the Common Name should match the hostname you are connecting to from the Helm operator. The following script can be used for that (requires [cfssl](https://github.com/cloudflare/cfssl)): ```bash -export TILLER_HOSTNAME=tiller-server +# TILLER_HOSTNAME=. +export TILLER_HOSTNAME=tiller-deploy.kube-system export TILLER_SERVER=server export USER_NAME=flux-helm-operator @@ -163,10 +167,11 @@ Error: transport is closing When providing the certificates, it should work correctly: ```bash -helm --tls \ +helm --tls --tls-verify \ --tls-ca-cert ./tls/ca.pem \ --tls-cert ./tls/flux-helm-operator.pem \ --tls-key ././tls/flux-helm-operator-key.pem \ + --tls-hostname tiller-deploy.kube-system \ ls ```