diff --git a/Makefile b/Makefile index 972d12ec1c..dcf23db14f 100644 --- a/Makefile +++ b/Makefile @@ -79,6 +79,7 @@ test: go test k8s.io/kops/protokube/... -args -v=1 -logtostderr go test k8s.io/kops/dns-controller/pkg/... -args -v=1 -logtostderr go test k8s.io/kops/cmd/... -args -v=1 -logtostderr + go test k8s.io/kops/tests/... -args -v=1 -logtostderr crossbuild-nodeup: mkdir -p .build/dist/ diff --git a/cmd/kops/create_cluster.go b/cmd/kops/create_cluster.go index 19add45ddc..5242b70058 100644 --- a/cmd/kops/create_cluster.go +++ b/cmd/kops/create_cluster.go @@ -332,7 +332,13 @@ func RunCreateCluster(f *util.Factory, out io.Writer, c *CreateClusterOptions) e for _, masterName := range masterNames { ig := masterInstanceGroups[masterName] m := &api.EtcdMemberSpec{} - m.Name = ig.ObjectMeta.Name + + name := ig.ObjectMeta.Name + // We expect the IG to have a `master-` prefix, but this is both superfluous + // and not how we named things previously + name = strings.TrimPrefix(name, "master-") + m.Name = name + m.InstanceGroup = fi.String(ig.ObjectMeta.Name) etcd.Members = append(etcd.Members, m) } diff --git a/hack/.packages b/hack/.packages index 84ec0e9f5c..49922f6199 100644 --- a/hack/.packages +++ b/hack/.packages @@ -34,6 +34,7 @@ k8s.io/kops/pkg/model/resources k8s.io/kops/pkg/validation k8s.io/kops/protokube/cmd/protokube k8s.io/kops/protokube/pkg/protokube +k8s.io/kops/tests/integration/conversion k8s.io/kops/upup/models k8s.io/kops/upup/pkg/fi k8s.io/kops/upup/pkg/fi/cloudup diff --git a/pkg/apis/kops/v1alpha1/conversion.go b/pkg/apis/kops/v1alpha1/conversion.go index 1fd6f2d1cd..201504ae89 100644 --- a/pkg/apis/kops/v1alpha1/conversion.go +++ b/pkg/apis/kops/v1alpha1/conversion.go @@ -217,7 +217,6 @@ func Convert_kops_EtcdMemberSpec_To_v1alpha1_EtcdMemberSpec(in *kops.EtcdMemberS } zone = strings.TrimPrefix(zone, "master-") out.Zone = &zone - out.Name = zone } else { out.Zone = nil } diff --git a/tests/integration/conversion/integration_test.go b/tests/integration/conversion/integration_test.go new file mode 100644 index 0000000000..2e1d108ba1 --- /dev/null +++ b/tests/integration/conversion/integration_test.go @@ -0,0 +1,117 @@ +/* +Copyright 2016 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 main + +import ( + "bytes" + "io/ioutil" + "k8s.io/kops/pkg/apis/kops" + "k8s.io/kops/pkg/apis/kops/v1alpha1" + "k8s.io/kops/pkg/apis/kops/v1alpha2" + "k8s.io/kops/pkg/diff" + k8sapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/runtime/schema" + "path" + "testing" + + _ "k8s.io/kops/pkg/apis/kops/install" + "strings" +) + +// TestMinimal runs the test on a minimum configuration, similar to kops create cluster minimal.example.com --zones us-west-1a +func TestMinimal(t *testing.T) { + runTest(t, "minimal", "v1alpha1", "v1alpha2") + runTest(t, "minimal", "v1alpha2", "v1alpha1") + + runTest(t, "minimal", "v1alpha0", "v1alpha1") + runTest(t, "minimal", "v1alpha0", "v1alpha2") +} + +func runTest(t *testing.T, srcDir string, fromVersion string, toVersion string) { + sourcePath := path.Join(srcDir, fromVersion+".yaml") + sourceBytes, err := ioutil.ReadFile(sourcePath) + if err != nil { + t.Fatalf("unexpected error reading sourcePath %q: %v", sourcePath, err) + } + + expectedPath := path.Join(srcDir, toVersion+".yaml") + expectedBytes, err := ioutil.ReadFile(expectedPath) + if err != nil { + t.Fatalf("unexpected error reading expectedPath %q: %v", expectedPath, err) + } + + codec := k8sapi.Codecs.UniversalDecoder(kops.SchemeGroupVersion) + + defaults := &schema.GroupVersionKind{ + Group: v1alpha1.SchemeGroupVersion.Group, + Version: v1alpha1.SchemeGroupVersion.Version, + } + + yaml, ok := runtime.SerializerInfoForMediaType(k8sapi.Codecs.SupportedMediaTypes(), "application/yaml") + if !ok { + t.Fatalf("no YAML serializer registered") + } + var encoder runtime.Encoder + + switch toVersion { + case "v1alpha1": + encoder = k8sapi.Codecs.EncoderForVersion(yaml.Serializer, v1alpha1.SchemeGroupVersion) + case "v1alpha2": + encoder = k8sapi.Codecs.EncoderForVersion(yaml.Serializer, v1alpha2.SchemeGroupVersion) + + default: + t.Fatalf("unknown version %q", toVersion) + } + + //decoder := k8sapi.Codecs.DecoderToVersion(yaml.Serializer, kops.SchemeGroupVersion) + + var actual []string + + for _, s := range strings.Split(string(sourceBytes), "\n---\n") { + o, gvk, err := codec.Decode([]byte(s), defaults, nil) + if err != nil { + t.Fatalf("error parsing file %q: %v", sourcePath, err) + } + + expectVersion := fromVersion + if expectVersion == "v1alpha0" { + // Our version before we had v1alpha1 + expectVersion = "v1alpha1" + } + if gvk.Version != expectVersion { + t.Fatalf("unexpected version: %q vs %q", gvk.Version, expectVersion) + } + + var b bytes.Buffer + if err := encoder.Encode(o, &b); err != nil { + t.Fatalf("error encoding object: %v", err) + } + + actual = append(actual, b.String()) + } + + actualString := strings.TrimSpace(strings.Join(actual, "\n---\n\n")) + expectedString := strings.TrimSpace(string(expectedBytes)) + + if actualString != expectedString { + diffString := diff.FormatDiff(expectedString, actualString) + t.Logf("diff:\n%s\n", diffString) + + t.Fatalf("converted output differed from expected") + } +} diff --git a/tests/integration/conversion/minimal/v1alpha0.yaml b/tests/integration/conversion/minimal/v1alpha0.yaml new file mode 100644 index 0000000000..cbad5486b8 --- /dev/null +++ b/tests/integration/conversion/minimal/v1alpha0.yaml @@ -0,0 +1,73 @@ +kind: Cluster +metadata: + creationTimestamp: "2016-12-10T22:42:27Z" + name: minimal.example.com +spec: + adminAccess: + - 0.0.0.0/0 + channel: stable + cloudProvider: aws + configBase: memfs://clusters.example.com/minimal.example.com + etcdClusters: + - etcdMembers: + - name: us-test-1a + zone: us-test-1a + name: main + - etcdMembers: + - name: us-test-1a + zone: us-test-1a + name: events + kubernetesVersion: v1.4.6 + masterInternalName: api.internal.minimal.example.com + masterPublicName: api.minimal.example.com + networkCIDR: 172.20.0.0/16 + networking: + kubenet: {} + nonMasqueradeCIDR: 100.64.0.0/10 + topology: + bastion: + idleTimeout: 120 + machineType: t2.medium + masters: public + nodes: public + zones: + - cidr: 172.20.32.0/19 + name: us-test-1a + +--- + +kind: InstanceGroup +metadata: + creationTimestamp: "2016-12-10T22:42:28Z" + name: nodes + labels: + kops.k8s.io/cluster: minimal.example.com +spec: + associatePublicIp: true + image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21 + machineType: t2.medium + maxSize: 2 + minSize: 2 + role: Node + zones: + - us-test-1a + +--- + +kind: InstanceGroup +metadata: + creationTimestamp: "2016-12-10T22:42:28Z" + name: master-us-test-1a + labels: + kops.k8s.io/cluster: minimal.example.com +spec: + associatePublicIp: true + image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21 + machineType: m3.medium + maxSize: 1 + minSize: 1 + role: Master + zones: + - us-test-1a + + diff --git a/tests/integration/conversion/minimal/v1alpha1.yaml b/tests/integration/conversion/minimal/v1alpha1.yaml new file mode 100644 index 0000000000..358de99f50 --- /dev/null +++ b/tests/integration/conversion/minimal/v1alpha1.yaml @@ -0,0 +1,75 @@ +apiVersion: kops/v1alpha1 +kind: Cluster +metadata: + creationTimestamp: "2016-12-10T22:42:27Z" + name: minimal.example.com +spec: + adminAccess: + - 0.0.0.0/0 + api: + dns: {} + channel: stable + cloudProvider: aws + configBase: memfs://clusters.example.com/minimal.example.com + etcdClusters: + - etcdMembers: + - name: us-test-1a + zone: us-test-1a + name: main + - etcdMembers: + - name: us-test-1a + zone: us-test-1a + name: events + kubernetesVersion: v1.4.6 + masterInternalName: api.internal.minimal.example.com + masterPublicName: api.minimal.example.com + networkCIDR: 172.20.0.0/16 + networking: + kubenet: {} + nonMasqueradeCIDR: 100.64.0.0/10 + topology: + masters: public + nodes: public + zones: + - cidr: 172.20.32.0/19 + name: us-test-1a + +--- + +apiVersion: kops/v1alpha1 +kind: InstanceGroup +metadata: + creationTimestamp: "2016-12-10T22:42:28Z" + labels: + kops.k8s.io/cluster: minimal.example.com + name: nodes +spec: + associatePublicIp: true + image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21 + machineType: t2.medium + maxSize: 2 + minSize: 2 + role: Node + zones: + - us-test-1a + +--- + +apiVersion: kops/v1alpha1 +kind: InstanceGroup +metadata: + creationTimestamp: "2016-12-10T22:42:28Z" + labels: + kops.k8s.io/cluster: minimal.example.com + name: master-us-test-1a +spec: + associatePublicIp: true + image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21 + machineType: m3.medium + maxSize: 1 + minSize: 1 + role: Master + zones: + - us-test-1a + + diff --git a/tests/integration/conversion/minimal/v1alpha2.yaml b/tests/integration/conversion/minimal/v1alpha2.yaml new file mode 100644 index 0000000000..31881f54d9 --- /dev/null +++ b/tests/integration/conversion/minimal/v1alpha2.yaml @@ -0,0 +1,77 @@ +apiVersion: kops/v1alpha2 +kind: Cluster +metadata: + creationTimestamp: "2016-12-10T22:42:27Z" + name: minimal.example.com +spec: + api: + dns: {} + channel: stable + cloudProvider: aws + configBase: memfs://clusters.example.com/minimal.example.com + etcdClusters: + - etcdMembers: + - instanceGroup: master-us-test-1a + name: us-test-1a + name: main + - etcdMembers: + - instanceGroup: master-us-test-1a + name: us-test-1a + name: events + kubernetesApiAccess: + - 0.0.0.0/0 + kubernetesVersion: v1.4.6 + masterInternalName: api.internal.minimal.example.com + masterPublicName: api.minimal.example.com + networkCIDR: 172.20.0.0/16 + networking: + kubenet: {} + nonMasqueradeCIDR: 100.64.0.0/10 + sshAccess: + - 0.0.0.0/0 + subnets: + - cidr: 172.20.32.0/19 + name: us-test-1a + type: Public + zone: us-test-1a + topology: + masters: public + nodes: public + +--- + +apiVersion: kops/v1alpha2 +kind: InstanceGroup +metadata: + creationTimestamp: "2016-12-10T22:42:28Z" + labels: + kops.k8s.io/cluster: minimal.example.com + name: nodes +spec: + associatePublicIp: true + image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21 + machineType: t2.medium + maxSize: 2 + minSize: 2 + role: Node + subnets: + - us-test-1a + +--- + +apiVersion: kops/v1alpha2 +kind: InstanceGroup +metadata: + creationTimestamp: "2016-12-10T22:42:28Z" + labels: + kops.k8s.io/cluster: minimal.example.com + name: master-us-test-1a +spec: + associatePublicIp: true + image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21 + machineType: m3.medium + maxSize: 1 + minSize: 1 + role: Master + subnets: + - us-test-1a diff --git a/tests/integration/minimal/in-v1alpha2.yaml b/tests/integration/minimal/in-v1alpha2.yaml index 7246585bc9..e85e7b6fd0 100644 --- a/tests/integration/minimal/in-v1alpha2.yaml +++ b/tests/integration/minimal/in-v1alpha2.yaml @@ -12,11 +12,11 @@ spec: etcdClusters: - etcdMembers: - instanceGroup: master-us-test-1a - name: master-us-test-1a + name: us-test-1a name: main - etcdMembers: - instanceGroup: master-us-test-1a - name: master-us-test-1a + name: us-test-1a name: events kubernetesVersion: v1.4.6 masterInternalName: api.internal.minimal.example.com diff --git a/tests/integration/privatecalico/in-v1alpha2.yaml b/tests/integration/privatecalico/in-v1alpha2.yaml index 6324087981..9aac6ef63c 100644 --- a/tests/integration/privatecalico/in-v1alpha2.yaml +++ b/tests/integration/privatecalico/in-v1alpha2.yaml @@ -12,11 +12,11 @@ spec: etcdClusters: - etcdMembers: - instanceGroup: master-us-test-1a - name: master-us-test-1a + name: us-test-1a name: main - etcdMembers: - instanceGroup: master-us-test-1a - name: master-us-test-1a + name: us-test-1a name: events kubernetesVersion: v1.4.6 masterInternalName: api.internal.privatecalico.example.com diff --git a/tests/integration/privateweave/in-v1alpha2.yaml b/tests/integration/privateweave/in-v1alpha2.yaml index a3d91933eb..9e0d263e19 100644 --- a/tests/integration/privateweave/in-v1alpha2.yaml +++ b/tests/integration/privateweave/in-v1alpha2.yaml @@ -12,11 +12,11 @@ spec: etcdClusters: - etcdMembers: - instanceGroup: master-us-test-1a - name: master-us-test-1a + name: us-test-1a name: main - etcdMembers: - instanceGroup: master-us-test-1a - name: master-us-test-1a + name: us-test-1a name: events kubernetesVersion: v1.4.6 masterInternalName: api.internal.privateweave.example.com