diff --git a/controlplane/kubeadm/internal/control_plane_test.go b/controlplane/kubeadm/internal/control_plane_test.go index 540da5cbf350..5d79cb9a8e58 100644 --- a/controlplane/kubeadm/internal/control_plane_test.go +++ b/controlplane/kubeadm/internal/control_plane_test.go @@ -22,8 +22,12 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/pointer" clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha3" + bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha3" controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1alpha3" ) @@ -164,6 +168,36 @@ var _ = Describe("Control Plane", func() { }) }) }) + + Describe("Generating components", func() { + Context("That is after machine creation time", func() { + BeforeEach(func() { + controlPlane.KCP = &controlplanev1.KubeadmControlPlane{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cp", + UID: types.UID("test-uid"), + }, + } + controlPlane.Cluster = &clusterv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + }, + } + }) + It("should generate kubeadmconfig without controller reference", func() { + spec := &bootstrapv1.KubeadmConfigSpec{} + kubeadmConfig := controlPlane.GenerateKubeadmConfig(spec) + Expect(kubeadmConfig.Labels["cluster.x-k8s.io/cluster-name"]).To(Equal("test-cluster")) + Expect(kubeadmConfig.Labels["kubeadm.controlplane.cluster.x-k8s.io/hash"]).ToNot(BeEmpty()) + Expect(kubeadmConfig.OwnerReferences[0].Controller).To(BeNil()) + }) + It("should generate new machine with controller reference", func() { + machine := controlPlane.NewMachine(&corev1.ObjectReference{Namespace: "foobar"}, &corev1.ObjectReference{Namespace: "foobar"}, pointer.StringPtr("failureDomain")) + Expect(machine.OwnerReferences[0].Controller).ToNot(BeNil()) + }) + }) + }) + }) func failureDomain(controlPlane bool) clusterv1.FailureDomainSpec { diff --git a/controlplane/kubeadm/internal/etcd/etcd_test.go b/controlplane/kubeadm/internal/etcd/etcd_test.go new file mode 100644 index 000000000000..eaec1fa0fca3 --- /dev/null +++ b/controlplane/kubeadm/internal/etcd/etcd_test.go @@ -0,0 +1,106 @@ +/* +Copyright 2020 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 etcd + +import ( + "context" + "testing" + + . "github.com/onsi/gomega" + "github.com/pkg/errors" + + "go.etcd.io/etcd/clientv3" + "go.etcd.io/etcd/etcdserver/etcdserverpb" + + etcdfake "sigs.k8s.io/cluster-api/controlplane/kubeadm/internal/etcd/fake" +) + +func TestEtcdMembers_WithErrors(t *testing.T) { + g := NewWithT(t) + + ctx := context.Background() + fakeEtcdClient := &etcdfake.FakeEtcdClient{ + EtcdEndpoints: []string{"https://etcd-instance:2379"}, + MemberListResponse: &clientv3.MemberListResponse{ + Header: &etcdserverpb.ResponseHeader{}, + Members: []*etcdserverpb.Member{ + {ID: 1234, Name: "foo", PeerURLs: []string{"https://1.2.3.4:2000"}}, + }, + }, + MoveLeaderResponse: &clientv3.MoveLeaderResponse{}, + MemberRemoveResponse: &clientv3.MemberRemoveResponse{}, + StatusResponse: &clientv3.StatusResponse{}, + ErrorResponse: errors.New("something went wrong"), + } + + client, err := NewClientWithEtcd(ctx, fakeEtcdClient) + g.Expect(err).NotTo(HaveOccurred()) + + members, err := client.Members(ctx) + g.Expect(err).To(HaveOccurred()) + g.Expect(len(members)).To(Equal(0)) + + err = client.MoveLeader(ctx, 1) + g.Expect(err).To(HaveOccurred()) + + err = client.RemoveMember(ctx, 1234) + g.Expect(err).To(HaveOccurred()) + +} + +func TestEtcdMembers_WithSuccess(t *testing.T) { + g := NewWithT(t) + + ctx := context.Background() + fakeEtcdClient := &etcdfake.FakeEtcdClient{ + EtcdEndpoints: []string{"https://etcd-instance:2379"}, + MemberListResponse: &clientv3.MemberListResponse{ + Header: &etcdserverpb.ResponseHeader{}, + Members: []*etcdserverpb.Member{ + {ID: 1234, Name: "foo", PeerURLs: []string{"https://1.2.3.4:2000"}}, + }, + }, + MoveLeaderResponse: &clientv3.MoveLeaderResponse{}, + MemberUpdateResponse: &clientv3.MemberUpdateResponse{ + Header: &etcdserverpb.ResponseHeader{}, + Members: []*etcdserverpb.Member{ + {ID: 1234, Name: "foo", PeerURLs: []string{"https://1.2.3.4:2000", "https://4.5.6.7:2000"}}, + }, + }, + MemberRemoveResponse: &clientv3.MemberRemoveResponse{}, + AlarmResponse: &clientv3.AlarmResponse{}, + StatusResponse: &clientv3.StatusResponse{}, + } + + client, err := NewClientWithEtcd(ctx, fakeEtcdClient) + g.Expect(err).NotTo(HaveOccurred()) + + members, err := client.Members(ctx) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(len(members)).To(Equal(1)) + + err = client.MoveLeader(ctx, 1) + g.Expect(err).NotTo(HaveOccurred()) + + err = client.RemoveMember(ctx, 1234) + g.Expect(err).NotTo(HaveOccurred()) + + updatedMembers, err := client.UpdateMemberPeerURLs(ctx, 1234, []string{"https://4.5.6.7:2000"}) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(len(updatedMembers[0].PeerURLs)).To(Equal(2)) + g.Expect(updatedMembers[0].PeerURLs).To(Equal([]string{"https://1.2.3.4:2000", "https://4.5.6.7:2000"})) +} diff --git a/controlplane/kubeadm/internal/etcd/fake/client.go b/controlplane/kubeadm/internal/etcd/fake/client.go index b7fe83188e94..25f353a89151 100644 --- a/controlplane/kubeadm/internal/etcd/fake/client.go +++ b/controlplane/kubeadm/internal/etcd/fake/client.go @@ -30,6 +30,7 @@ type FakeEtcdClient struct { MemberUpdateResponse *clientv3.MemberUpdateResponse MoveLeaderResponse *clientv3.MoveLeaderResponse StatusResponse *clientv3.StatusResponse + ErrorResponse error } func (c *FakeEtcdClient) Endpoints() []string { @@ -37,7 +38,7 @@ func (c *FakeEtcdClient) Endpoints() []string { } func (c *FakeEtcdClient) MoveLeader(_ context.Context, _ uint64) (*clientv3.MoveLeaderResponse, error) { - return c.MoveLeaderResponse, nil + return c.MoveLeaderResponse, c.ErrorResponse } func (c *FakeEtcdClient) Close() error { @@ -45,17 +46,17 @@ func (c *FakeEtcdClient) Close() error { } func (c *FakeEtcdClient) AlarmList(_ context.Context) (*clientv3.AlarmResponse, error) { - return c.AlarmResponse, nil + return c.AlarmResponse, c.ErrorResponse } func (c *FakeEtcdClient) MemberList(_ context.Context) (*clientv3.MemberListResponse, error) { - return c.MemberListResponse, nil + return c.MemberListResponse, c.ErrorResponse } func (c *FakeEtcdClient) MemberRemove(_ context.Context, _ uint64) (*clientv3.MemberRemoveResponse, error) { - return c.MemberRemoveResponse, nil + return c.MemberRemoveResponse, c.ErrorResponse } func (c *FakeEtcdClient) MemberUpdate(_ context.Context, _ uint64, _ []string) (*clientv3.MemberUpdateResponse, error) { - return c.MemberUpdateResponse, nil + return c.MemberUpdateResponse, c.ErrorResponse } func (c *FakeEtcdClient) Status(_ context.Context, _ string) (*clientv3.StatusResponse, error) { return c.StatusResponse, nil