diff --git a/cmd/kops/integration_test.go b/cmd/kops/integration_test.go index 0ea4dbf1a7..1891521eb9 100644 --- a/cmd/kops/integration_test.go +++ b/cmd/kops/integration_test.go @@ -36,14 +36,14 @@ import ( "k8s.io/kops/cmd/kops/util" "k8s.io/kops/pkg/diff" + "k8s.io/kops/pkg/featureflag" "k8s.io/kops/pkg/jsonutils" "k8s.io/kops/pkg/testutils" + "k8s.io/kops/upup/pkg/fi/cloudup" + "k8s.io/kops/upup/pkg/fi/cloudup/gce" "github.com/ghodss/yaml" "golang.org/x/crypto/ssh" - "k8s.io/kops/pkg/featureflag" - "k8s.io/kops/upup/pkg/fi/cloudup" - "k8s.io/kops/upup/pkg/fi/cloudup/gce" ) // updateClusterTestBase is added automatically to the srcDir on all diff --git a/cmd/kops/update_cluster.go b/cmd/kops/update_cluster.go index b97560f189..7d3af48eeb 100644 --- a/cmd/kops/update_cluster.go +++ b/cmd/kops/update_cluster.go @@ -207,19 +207,18 @@ func RunUpdateCluster(f *util.Factory, clusterName string, out io.Writer, c *Upd } applyCmd := &cloudup.ApplyClusterCmd{ - Cluster: cluster, - Models: strings.Split(c.Models, ","), Clientset: clientset, - TargetName: targetName, - OutDir: c.OutDir, + Cluster: cluster, DryRun: isDryrun, - MaxTaskDuration: c.MaxTaskDuration, InstanceGroups: instanceGroups, + MaxTaskDuration: c.MaxTaskDuration, + Models: strings.Split(c.Models, ","), + OutDir: c.OutDir, Phase: phase, + TargetName: targetName, } - err = applyCmd.Run() - if err != nil { + if err := applyCmd.Run(); err != nil { return err } diff --git a/nodeup/pkg/model/calico.go b/nodeup/pkg/model/calico.go new file mode 100644 index 0000000000..192402b89a --- /dev/null +++ b/nodeup/pkg/model/calico.go @@ -0,0 +1,54 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package model + +import ( + "fmt" + + "k8s.io/kops/upup/pkg/fi" +) + +// CalicoBuilder configures the calico CNI provider +type CalicoBuilder struct { + *NodeupModelContext +} + +var _ fi.ModelBuilder = &CalicoBuilder{} + +// Build is responsible for performing any setup to the calico CNI provider +func (b *CalicoBuilder) Build(c *fi.ModelBuilderContext) error { + // @check if tls is enabled and if so, we need to download the client certificates + if b.UseEtcdTLS() { + name := "calico-client" + dirname := "calico" + ca := fmt.Sprintf("%s/ca.pem", dirname) + certificate := fmt.Sprintf("%s/%s.pem", dirname, name) + key := fmt.Sprintf("%s/%s-key.pem", dirname, name) + + if err := b.BuildCertificateTask(c, name, certificate); err != nil { + return err + } + if err := b.BuildPrivateTask(c, name, key); err != nil { + return err + } + if err := b.BuildCertificateTask(c, fi.CertificateId_CA, ca); err != nil { + return err + } + } + + return nil +} diff --git a/nodeup/pkg/model/context.go b/nodeup/pkg/model/context.go index b4f43b62d0..827d153763 100644 --- a/nodeup/pkg/model/context.go +++ b/nodeup/pkg/model/context.go @@ -28,6 +28,7 @@ import ( "k8s.io/kops/pkg/apis/nodeup" "k8s.io/kops/pkg/kubeconfig" "k8s.io/kops/upup/pkg/fi" + "k8s.io/kops/upup/pkg/fi/nodeup/nodetasks" ) // NodeupModelContext is the context supplied the nodeup tasks @@ -268,3 +269,55 @@ func (c *NodeupModelContext) KubectlPath() string { } return kubeletCommand } + +// BuildCertificateTask is responsible for build a certificate request task +func (c *NodeupModelContext) BuildCertificateTask(ctx *fi.ModelBuilderContext, name, filename string) error { + cert, err := c.KeyStore.FindCert(name) + if err != nil { + return err + } + + if cert == nil { + return fmt.Errorf("certificate %q not found", name) + } + + serialized, err := cert.AsString() + if err != nil { + return err + } + + ctx.AddTask(&nodetasks.File{ + Path: filepath.Join(c.PathSrvKubernetes(), filename), + Contents: fi.NewStringResource(serialized), + Type: nodetasks.FileType_File, + Mode: s("0400"), + }) + + return nil +} + +// BuildPrivateKeyTask is responsible for build a certificate request task +func (c *NodeupModelContext) BuildPrivateTask(ctx *fi.ModelBuilderContext, name, filename string) error { + cert, err := c.KeyStore.FindPrivateKey(name) + if err != nil { + return err + } + + if cert == nil { + return fmt.Errorf("private key %q not found", name) + } + + serialized, err := cert.AsString() + if err != nil { + return err + } + + ctx.AddTask(&nodetasks.File{ + Path: filepath.Join(c.PathSrvKubernetes(), filename), + Contents: fi.NewStringResource(serialized), + Type: nodetasks.FileType_File, + Mode: s("0400"), + }) + + return nil +} diff --git a/nodeup/pkg/model/protokube.go b/nodeup/pkg/model/protokube.go index bc50f666f9..687f210596 100644 --- a/nodeup/pkg/model/protokube.go +++ b/nodeup/pkg/model/protokube.go @@ -70,12 +70,12 @@ func (t *ProtokubeBuilder) Build(c *fi.ModelBuilderContext) error { // retrieve the etcd peer certificates and private keys from the keystore if t.UseEtcdTLS() { for _, x := range []string{"etcd", "etcd-client"} { - if err := t.buildCertificateTask(c, x, fmt.Sprintf("%s.pem", x)); err != nil { + if err := t.BuildCertificateTask(c, x, fmt.Sprintf("%s.pem", x)); err != nil { return err } } for _, x := range []string{"etcd", "etcd-client"} { - if err := t.buildPrivateTask(c, x, fmt.Sprintf("%s-key.pem", x)); err != nil { + if err := t.BuildPrivateTask(c, x, fmt.Sprintf("%s-key.pem", x)); err != nil { return err } } @@ -378,55 +378,3 @@ func (t *ProtokubeBuilder) writeProxyEnvVars(buffer *bytes.Buffer) { buffer.WriteString(" ") } } - -// buildCertificateTask is responsible for build a certificate request task -func (t *ProtokubeBuilder) buildCertificateTask(c *fi.ModelBuilderContext, name, filename string) error { - cert, err := t.KeyStore.FindCert(name) - if err != nil { - return err - } - - if cert == nil { - return fmt.Errorf("certificate %q not found", name) - } - - serialized, err := cert.AsString() - if err != nil { - return err - } - - c.AddTask(&nodetasks.File{ - Path: filepath.Join(t.PathSrvKubernetes(), filename), - Contents: fi.NewStringResource(serialized), - Type: nodetasks.FileType_File, - Mode: s("0400"), - }) - - return nil -} - -// buildPrivateKeyTask is responsible for build a certificate request task -func (t *ProtokubeBuilder) buildPrivateTask(c *fi.ModelBuilderContext, name, filename string) error { - cert, err := t.KeyStore.FindPrivateKey(name) - if err != nil { - return err - } - - if cert == nil { - return fmt.Errorf("private key %q not found", name) - } - - serialized, err := cert.AsString() - if err != nil { - return err - } - - c.AddTask(&nodetasks.File{ - Path: filepath.Join(t.PathSrvKubernetes(), filename), - Contents: fi.NewStringResource(serialized), - Type: nodetasks.FileType_File, - Mode: s("0400"), - }) - - return nil -} diff --git a/pkg/assets/builder.go b/pkg/assets/builder.go index 01c3b999c4..7b6cc673d5 100644 --- a/pkg/assets/builder.go +++ b/pkg/assets/builder.go @@ -25,6 +25,7 @@ import ( "strings" "github.com/golang/glog" + "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/featureflag" "k8s.io/kops/pkg/kubemanifest" @@ -51,7 +52,6 @@ type ContainerAsset struct { // DockerImage will be the name of the container we should run. // This is used to copy a container to a ContainerRegistry. DockerImage string - // CanonicalLocation will be the source location of the container. CanonicalLocation string } @@ -60,10 +60,8 @@ type ContainerAsset struct { type FileAsset struct { // FileURL is the URL of a file that is accessed by a Kubernetes cluster. FileURL *url.URL - // CanonicalFileURL is the source URL of a file. This is used to copy a file to a FileRepository. CanonicalFileURL *url.URL - // SHAValue is the SHA hash of the FileAsset. SHAValue string } @@ -84,6 +82,7 @@ func (a *AssetBuilder) RemapManifest(data []byte) ([]byte, error) { if !RewriteManifests.Enabled() { return data, nil } + manifests, err := kubemanifest.LoadManifestsFrom(data) if err != nil { return nil, err @@ -92,10 +91,10 @@ func (a *AssetBuilder) RemapManifest(data []byte) ([]byte, error) { var yamlSeparator = []byte("\n---\n\n") var remappedManifests [][]byte for _, manifest := range manifests { - err := manifest.RemapImages(a.RemapImage) - if err != nil { + if err := manifest.RemapImages(a.RemapImage); err != nil { return nil, fmt.Errorf("error remapping images: %v", err) } + y, err := manifest.ToYAML() if err != nil { return nil, fmt.Errorf("error re-marshalling manifest: %v", err) diff --git a/pkg/model/iam.go b/pkg/model/iam.go index 87d2fe5b5b..4f7fd39de9 100644 --- a/pkg/model/iam.go +++ b/pkg/model/iam.go @@ -143,7 +143,6 @@ func (b *IAMModelBuilder) Build(c *fi.ModelBuilderContext) error { if b.Cluster.Spec.AdditionalPolicies != nil { roleAsString := reflect.ValueOf(role).String() additionalPolicies := *(b.Cluster.Spec.AdditionalPolicies) - additionalPolicy = additionalPolicies[strings.ToLower(roleAsString)] } diff --git a/pkg/model/iam/iam_builder.go b/pkg/model/iam/iam_builder.go index d0aebe4f2c..64d8be8422 100644 --- a/pkg/model/iam/iam_builder.go +++ b/pkg/model/iam/iam_builder.go @@ -359,15 +359,30 @@ func (b *PolicyBuilder) AddS3Permissions(p *Policy) (*Policy, error) { ), }) - if b.Cluster.Spec.Networking != nil && b.Cluster.Spec.Networking.Kuberouter != nil { - p.Statement = append(p.Statement, &Statement{ - Sid: "kopsK8sS3NodeBucketGetKuberouter", - Effect: StatementEffectAllow, - Action: stringorslice.Slice([]string{"s3:Get*"}), - Resource: stringorslice.Of( - strings.Join([]string{b.IAMPrefix(), ":s3:::", iamS3Path, "/pki/private/kube-router/*"}, ""), - ), - }) + if b.Cluster.Spec.Networking != nil { + // @check if kuberoute is enabled and permit access to the private key + if b.Cluster.Spec.Networking.Kuberouter != nil { + p.Statement = append(p.Statement, &Statement{ + Sid: "kopsK8sS3NodeBucketGetKuberouter", + Effect: StatementEffectAllow, + Action: stringorslice.Slice([]string{"s3:Get*"}), + Resource: stringorslice.Of( + strings.Join([]string{b.IAMPrefix(), ":s3:::", iamS3Path, "/pki/private/kube-router/*"}, ""), + ), + }) + } + + // @check if calico is enabled as the CNI provider and permit access to the client TLS certificate by default + if b.Cluster.Spec.Networking.Calico != nil { + p.Statement = append(p.Statement, &Statement{ + Sid: "kopsK8sS3NodeBucketGetCalicoClient", + Effect: StatementEffectAllow, + Action: stringorslice.Slice([]string{"s3:Get*"}), + Resource: stringorslice.Of( + strings.Join([]string{b.IAMPrefix(), ":s3:::", iamS3Path, "/pki/private/calico-client/*"}, ""), + ), + }) + } } } } diff --git a/pkg/model/pki.go b/pkg/model/pki.go index fd14216706..139f66675b 100644 --- a/pkg/model/pki.go +++ b/pkg/model/pki.go @@ -109,23 +109,30 @@ func (b *PKIModelBuilder) Build(c *fi.ModelBuilderContext) error { // For clients assuming we are using etcdv3 is can switch on user authentication and map the common names for auth. if b.UseEtcdTLS() { alternativeNames := []string{fmt.Sprintf("*.internal.%s", b.ClusterName()), "localhost", "127.0.0.1"} - { - // @question should wildcard's be here instead of generating per node. If we ever provide the - // ability to resize the master, this will become a blocker + // @question should wildcard's be here instead of generating per node. If we ever provide the + // ability to resize the master, this will become a blocker + c.AddTask(&fitasks.Keypair{ + AlternateNames: alternativeNames, + Lifecycle: b.Lifecycle, + Name: fi.String("etcd"), + Subject: "cn=etcd", + Type: "server", + Signer: defaultCA, + }) + c.AddTask(&fitasks.Keypair{ + Name: fi.String("etcd-client"), + Lifecycle: b.Lifecycle, + Subject: "cn=etcd-client", + Type: "client", + Signer: defaultCA, + }) + + // @check if calico is enabled as the CNI provider + if b.KopsModelContext.Cluster.Spec.Networking.Calico != nil { c.AddTask(&fitasks.Keypair{ - AlternateNames: alternativeNames, - Lifecycle: b.Lifecycle, - Name: fi.String("etcd"), - Subject: "cn=etcd", - Type: "server", - Signer: defaultCA, - }) - } - { - c.AddTask(&fitasks.Keypair{ - Name: fi.String("etcd-client"), + Name: fi.String("calico-client"), Lifecycle: b.Lifecycle, - Subject: "cn=etcd-client", + Subject: "cn=calico-client", Type: "client", Signer: defaultCA, }) diff --git a/upup/models/cloudup/resources/addons/networking.projectcalico.org/k8s-1.6.yaml.template b/upup/models/cloudup/resources/addons/networking.projectcalico.org/k8s-1.6.yaml.template index a200143327..f1c9b30f79 100644 --- a/upup/models/cloudup/resources/addons/networking.projectcalico.org/k8s-1.6.yaml.template +++ b/upup/models/cloudup/resources/addons/networking.projectcalico.org/k8s-1.6.yaml.template @@ -1,3 +1,4 @@ +{{- $etcd_scheme := EtcdScheme }} # This ConfigMap is used to configure a self-hosted Calico installation. kind: ConfigMap apiVersion: v1 @@ -9,7 +10,7 @@ data: etcd_endpoints: "{{ $cluster := index .EtcdClusters 0 -}} {{- range $j, $member := $cluster.Members -}} {{- if $j }},{{ end -}} - http://etcd-{{ $member.Name }}.internal.{{ ClusterName }}:4001 + {{ $etcd_scheme }}://etcd-{{ $member.Name }}.internal.{{ ClusterName }}:4001 {{- end }}" # Configure the Calico backend to use. @@ -21,6 +22,12 @@ data: "name": "k8s-pod-network", "type": "calico", "etcd_endpoints": "__ETCD_ENDPOINTS__", + {{- if eq $etcd_scheme "https" }} + "etcd_ca_cert_file": "/srv/kubernetes/calico/ca.pem", + "etcd_cert_file": "/srv/kubernetes/calico/calico-client.pem", + "etcd_key_file": "/srv/kubernetes/calico/calico-client-key.pem", + "etcd_scheme": "https", + {{- end }} "log_level": "info", "ipam": { "type": "calico-ipam" @@ -141,6 +148,14 @@ spec: configMapKeyRef: name: calico-config key: etcd_endpoints + {{- if eq $etcd_scheme "https" }} + - name: ETCD_CERT_FILE + value: /certs/calico-client.pem + - name: ETCD_KEY_FILE + value: /certs/calico-client-key.pem + - name: ETCD_CA_CERT_FILE + value: /certs/ca.pem + {{- end }} # Enable BGP. Disable to enforce policy only. - name: CALICO_NETWORKING_BACKEND valueFrom: @@ -182,6 +197,11 @@ spec: - mountPath: /etc/hosts name: etc-hosts readOnly: true + {{- if eq $etcd_scheme "https" }} + - mountPath: /certs + name: calico + readOnly: true + {{- end }} # This container installs the Calico CNI binaries # and CNI network config file on each node. - name: install-cni @@ -234,6 +254,11 @@ spec: - name: etc-hosts hostPath: path: /etc/hosts + {{- if eq $etcd_scheme "https" }} + - name: calico + hostPath: + path: /srv/kubernetes/calico + {{- end }} --- @@ -271,16 +296,32 @@ spec: configMapKeyRef: name: calico-config key: etcd_endpoints - + {{- if eq $etcd_scheme "https" }} + - name: ETCD_CERT_FILE + value: /certs/calico-client.pem + - name: ETCD_KEY_FILE + value: /certs/calico-client-key.pem + - name: ETCD_CA_CERT_FILE + value: /certs/ca.pem + {{- end }} volumeMounts: - # Necessary for gossip based DNS - mountPath: /etc/hosts name: etc-hosts readOnly: true + {{- if eq $etcd_scheme "https" }} + - mountPath: /certs + name: calico + readOnly: true + {{- end }} volumes: - name: etc-hosts hostPath: path: /etc/hosts + {{- if eq $etcd_scheme "https" }} + - name: calico + hostPath: + path: /srv/kubernetes/calico + {{- end }} --- # This manifest deploys the Calico Kubernetes controllers. @@ -328,8 +369,27 @@ spec: configMapKeyRef: name: calico-config key: etcd_endpoints - - + {{- if eq $etcd_scheme "https" }} + - name: ETCD_CERT_FILE + value: /certs/calico-client.pem + - name: ETCD_KEY_FILE + value: /certs/calico-client-key.pem + - name: ETCD_CA_CERT_FILE + value: /certs/ca.pem + volumeMounts: + - mountPath: /certs + name: calico + readOnly: true + {{- end }} + volumes: + - name: etc-hosts + hostPath: + path: /etc/hosts + {{- if eq $etcd_scheme "https" }} + - name: calico + hostPath: + path: /srv/kubernetes/calico + {{- end }} {{ if and (eq .CloudProvider "aws") (.Networking.Calico.CrossSubnet) -}} # This manifest installs the k8s-ec2-srcdst container, which disables diff --git a/upup/models/cloudup/resources/addons/networking.projectcalico.org/k8s-1.7.yaml.template b/upup/models/cloudup/resources/addons/networking.projectcalico.org/k8s-1.7.yaml.template index b36e517b70..9bccd75d72 100644 --- a/upup/models/cloudup/resources/addons/networking.projectcalico.org/k8s-1.7.yaml.template +++ b/upup/models/cloudup/resources/addons/networking.projectcalico.org/k8s-1.7.yaml.template @@ -1,3 +1,4 @@ +{{- $etcd_scheme := EtcdScheme }} # This ConfigMap is used to configure a self-hosted Calico installation. kind: ConfigMap apiVersion: v1 @@ -9,7 +10,7 @@ data: etcd_endpoints: "{{ $cluster := index .EtcdClusters 0 -}} {{- range $j, $member := $cluster.Members -}} {{- if $j }},{{ end -}} - http://etcd-{{ $member.Name }}.internal.{{ ClusterName }}:4001 + {{ $etcd_scheme }}://etcd-{{ $member.Name }}.internal.{{ ClusterName }}:4001 {{- end }}" # Configure the Calico backend to use. @@ -24,6 +25,12 @@ data: { "type": "calico", "etcd_endpoints": "__ETCD_ENDPOINTS__", + {{- if eq $etcd_scheme "https" }} + "etcd_ca_cert_file": "/srv/kubernetes/calico/ca.pem", + "etcd_cert_file": "/srv/kubernetes/calico/calico-client.pem", + "etcd_key_file": "/srv/kubernetes/calico/calico-client-key.pem", + "etcd_scheme": "https", + {{- end }} "log_level": "info", "ipam": { "type": "calico-ipam" @@ -152,6 +159,14 @@ spec: configMapKeyRef: name: calico-config key: etcd_endpoints + {{- if eq $etcd_scheme "https" }} + - name: ETCD_CERT_FILE + value: /certs/calico-client.pem + - name: ETCD_KEY_FILE + value: /certs/calico-client-key.pem + - name: ETCD_CA_CERT_FILE + value: /certs/ca.pem + {{- end }} # Enable BGP. Disable to enforce policy only. - name: CALICO_NETWORKING_BACKEND valueFrom: @@ -193,6 +208,11 @@ spec: - mountPath: /etc/hosts name: etc-hosts readOnly: true + {{- if eq $etcd_scheme "https" }} + - mountPath: /certs + name: calico + readOnly: true + {{- end }} # This container installs the Calico CNI binaries # and CNI network config file on each node. - name: install-cni @@ -245,6 +265,11 @@ spec: - name: etc-hosts hostPath: path: /etc/hosts + {{- if eq $etcd_scheme "https" }} + - name: calico + hostPath: + path: /srv/kubernetes/calico + {{- end }} --- @@ -293,7 +318,27 @@ spec: configMapKeyRef: name: calico-config key: etcd_endpoints - + {{- if eq $etcd_scheme "https" }} + - name: ETCD_CERT_FILE + value: /certs/calico-client.pem + - name: ETCD_KEY_FILE + value: /certs/calico-client-key.pem + - name: ETCD_CA_CERT_FILE + value: /certs/ca.pem + volumeMounts: + - mountPath: /certs + name: calico + readOnly: true + {{- end }} + volumes: + - name: etc-hosts + hostPath: + path: /etc/hosts + {{- if eq $etcd_scheme "https" }} + - name: calico + hostPath: + path: /srv/kubernetes/calico + {{- end }} --- # This deployment turns off the old "policy-controller". It should remain at 0 replicas, and then @@ -330,16 +375,33 @@ spec: configMapKeyRef: name: calico-config key: etcd_endpoints - + {{- if eq $etcd_scheme "https" }} + - name: ETCD_CERT_FILE + value: /certs/calico-client.pem + - name: ETCD_KEY_FILE + value: /certs/calico-client-key.pem + - name: ETCD_CA_CERT_FILE + value: /certs/ca.pem + {{- end }} volumeMounts: # Necessary for gossip based DNS - mountPath: /etc/hosts name: etc-hosts readOnly: true + {{- if eq $etcd_scheme "https" }} + - mountPath: /certs + name: calico + readOnly: true + {{ end }} volumes: - name: etc-hosts hostPath: path: /etc/hosts + {{- if eq $etcd_scheme "https" }} + - name: calico + hostPath: + path: /srv/kubernetes/calico + {{- end }} {{ if and (eq .CloudProvider "aws") (.Networking.Calico.CrossSubnet) -}} # This manifest installs the k8s-ec2-srcdst container, which disables diff --git a/upup/pkg/fi/cloudup/bootstrapchannelbuilder.go b/upup/pkg/fi/cloudup/bootstrapchannelbuilder.go index 9671030a2b..238a62d6fd 100644 --- a/upup/pkg/fi/cloudup/bootstrapchannelbuilder.go +++ b/upup/pkg/fi/cloudup/bootstrapchannelbuilder.go @@ -41,7 +41,6 @@ var _ fi.ModelBuilder = &BootstrapChannelBuilder{} // Build is responsible for adding the addons to the channel func (b *BootstrapChannelBuilder) Build(c *fi.ModelBuilderContext) error { - addons, manifests, err := b.buildManifest() if err != nil { return err @@ -53,15 +52,13 @@ func (b *BootstrapChannelBuilder) Build(c *fi.ModelBuilderContext) error { } name := b.cluster.ObjectMeta.Name + "-addons-bootstrap" - tasks := c.Tasks tasks[name] = &fitasks.ManagedFile{ - Name: fi.String(name), + Contents: fi.WrapResource(fi.NewBytesResource(addonsYAML)), Lifecycle: b.Lifecycle, - - Location: fi.String("addons/bootstrap-channel.yaml"), - Contents: fi.WrapResource(fi.NewBytesResource(addonsYAML)), + Location: fi.String("addons/bootstrap-channel.yaml"), + Name: fi.String(name), } for key, manifest := range manifests { @@ -83,11 +80,10 @@ func (b *BootstrapChannelBuilder) Build(c *fi.ModelBuilderContext) error { } tasks[name] = &fitasks.ManagedFile{ - Name: fi.String(name), + Contents: fi.WrapResource(fi.NewBytesResource(manifestBytes)), Lifecycle: b.Lifecycle, - - Location: fi.String(manifest), - Contents: fi.WrapResource(fi.NewBytesResource(manifestBytes)), + Location: fi.String(manifest), + Name: fi.String(name), } } @@ -95,16 +91,14 @@ func (b *BootstrapChannelBuilder) Build(c *fi.ModelBuilderContext) error { } func (b *BootstrapChannelBuilder) buildManifest() (*channelsapi.Addons, map[string]string, error) { - manifests := make(map[string]string) - addons := &channelsapi.Addons{} addons.Kind = "Addons" addons.ObjectMeta.Name = "bootstrap" + manifests := make(map[string]string) { key := "core.addons.k8s.io" version := "1.4.0" - location := key + "/v" + version + ".yaml" addons.Spec.Addons = append(addons.Spec.Addons, &channelsapi.AddonSpec{ @@ -174,7 +168,6 @@ func (b *BootstrapChannelBuilder) buildManifest() (*channelsapi.Addons, map[stri { key := "limit-range.addons.k8s.io" version := "1.5.0" - location := key + "/v" + version + ".yaml" addons.Spec.Addons = append(addons.Spec.Addons, &channelsapi.AddonSpec{ @@ -686,7 +679,6 @@ func (b *BootstrapChannelBuilder) buildManifest() (*channelsapi.Addons, map[stri if b.cluster.Spec.KubeScheduler.UsePolicyConfigMap != nil { key := "scheduler.addons.k8s.io" version := "1.7.0" - location := key + "/v" + version + ".yaml" addons.Spec.Addons = append(addons.Spec.Addons, &channelsapi.AddonSpec{ diff --git a/upup/pkg/fi/cloudup/template_functions.go b/upup/pkg/fi/cloudup/template_functions.go index b498314304..1ed1083dc9 100644 --- a/upup/pkg/fi/cloudup/template_functions.go +++ b/upup/pkg/fi/cloudup/template_functions.go @@ -43,25 +43,24 @@ import ( "k8s.io/kops/upup/pkg/fi/cloudup/gce" ) +// TemplateFunctions provides a collection of methods used throughout the templates type TemplateFunctions struct { cluster *kops.Cluster instanceGroups []*kops.InstanceGroup - - tags sets.String - region string - - modelContext *model.KopsModelContext + modelContext *model.KopsModelContext + region string + tags sets.String } // This will define the available functions we can use in our YAML models // If we are trying to get a new function implemented it MUST // be defined here. func (tf *TemplateFunctions) AddTo(dest template.FuncMap) { + dest["EtcdScheme"] = tf.EtcdScheme dest["SharedVPC"] = tf.SharedVPC - + dest["UseEtcdTLS"] = tf.UseEtcdTLS // Remember that we may be on a different arch from the target. Hard-code for now. dest["Arch"] = func() string { return "amd64" } - dest["replace"] = func(s, find, replace string) string { return strings.Replace(s, find, replace, -1) } @@ -71,7 +70,6 @@ func (tf *TemplateFunctions) AddTo(dest template.FuncMap) { dest["ClusterName"] = tf.modelContext.ClusterName dest["HasTag"] = tf.HasTag - dest["WithDefaultBool"] = func(v *bool, defaultValue bool) bool { if v != nil { return *v @@ -106,6 +104,26 @@ func (tf *TemplateFunctions) AddTo(dest template.FuncMap) { } } +// UseEtcdTLS checks if cluster is using etcd tls +func (tf *TemplateFunctions) UseEtcdTLS() bool { + for _, x := range tf.cluster.Spec.EtcdClusters { + if x.EnableEtcdTLS { + return true + } + } + + return false +} + +// EtcdScheme parses and grabs the protocol to the etcd cluster +func (tf *TemplateFunctions) EtcdScheme() string { + if tf.UseEtcdTLS() { + return "https" + } + + return "http" +} + // SharedVPC is a simple helper function which makes the templates for a shared VPC clearer func (tf *TemplateFunctions) SharedVPC() bool { return tf.cluster.SharedVPC() diff --git a/upup/pkg/fi/nodeup/command.go b/upup/pkg/fi/nodeup/command.go index 0d5311a674..476a206425 100644 --- a/upup/pkg/fi/nodeup/command.go +++ b/upup/pkg/fi/nodeup/command.go @@ -26,6 +26,7 @@ import ( "time" "github.com/golang/glog" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/kops/nodeup/pkg/distros" "k8s.io/kops/nodeup/pkg/model" @@ -236,6 +237,9 @@ func (c *NodeUpCommand) Run(out io.Writer) error { } else { loader.Builders = append(loader.Builders, &model.KubeRouterBuilder{NodeupModelContext: modelContext}) } + if c.cluster.Spec.Networking.Calico != nil { + loader.Builders = append(loader.Builders, &model.CalicoBuilder{NodeupModelContext: modelContext}) + } taskMap, err := loader.Build(c.ModelDir) if err != nil {