12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040 |
- /*
- 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 cloud
- import (
- "errors"
- "testing"
- "time"
- "k8s.io/api/core/v1"
- "k8s.io/client-go/kubernetes/fake"
- "k8s.io/client-go/kubernetes/scheme"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/types"
- "k8s.io/client-go/informers"
- "k8s.io/client-go/tools/record"
- cloudprovider "k8s.io/cloud-provider"
- fakecloud "k8s.io/cloud-provider/fake"
- "k8s.io/kubernetes/pkg/controller"
- "k8s.io/kubernetes/pkg/controller/testutil"
- kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
- schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
- "github.com/stretchr/testify/assert"
- "k8s.io/klog"
- )
- func TestEnsureNodeExistsByProviderID(t *testing.T) {
- testCases := []struct {
- testName string
- node *v1.Node
- expectedCalls []string
- expectedNodeExists bool
- hasInstanceID bool
- existsByProviderID bool
- nodeNameErr error
- providerIDErr error
- }{
- {
- testName: "node exists by provider id",
- existsByProviderID: true,
- providerIDErr: nil,
- hasInstanceID: true,
- nodeNameErr: errors.New("unimplemented"),
- expectedCalls: []string{"instance-exists-by-provider-id"},
- expectedNodeExists: true,
- node: &v1.Node{
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- },
- Spec: v1.NodeSpec{
- ProviderID: "node0",
- },
- },
- },
- {
- testName: "does not exist by provider id",
- existsByProviderID: false,
- providerIDErr: nil,
- hasInstanceID: true,
- nodeNameErr: errors.New("unimplemented"),
- expectedCalls: []string{"instance-exists-by-provider-id"},
- expectedNodeExists: false,
- node: &v1.Node{
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- },
- Spec: v1.NodeSpec{
- ProviderID: "node0",
- },
- },
- },
- {
- testName: "exists by instance id",
- existsByProviderID: true,
- providerIDErr: nil,
- hasInstanceID: true,
- nodeNameErr: nil,
- expectedCalls: []string{"instance-id", "instance-exists-by-provider-id"},
- expectedNodeExists: true,
- node: &v1.Node{
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- },
- },
- },
- {
- testName: "does not exist by no instance id",
- existsByProviderID: true,
- providerIDErr: nil,
- hasInstanceID: false,
- nodeNameErr: cloudprovider.InstanceNotFound,
- expectedCalls: []string{"instance-id"},
- expectedNodeExists: false,
- node: &v1.Node{
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- },
- },
- },
- {
- testName: "provider id returns error",
- existsByProviderID: false,
- providerIDErr: errors.New("unimplemented"),
- hasInstanceID: true,
- nodeNameErr: cloudprovider.InstanceNotFound,
- expectedCalls: []string{"instance-exists-by-provider-id"},
- expectedNodeExists: false,
- node: &v1.Node{
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- },
- Spec: v1.NodeSpec{
- ProviderID: "node0",
- },
- },
- },
- }
- for _, tc := range testCases {
- t.Run(tc.testName, func(t *testing.T) {
- fc := &fakecloud.Cloud{
- ExistsByProviderID: tc.existsByProviderID,
- Err: tc.nodeNameErr,
- ErrByProviderID: tc.providerIDErr,
- }
- if tc.hasInstanceID {
- fc.ExtID = map[types.NodeName]string{
- types.NodeName(tc.node.Name): "provider-id://a",
- }
- }
- instances, _ := fc.Instances()
- exists, err := ensureNodeExistsByProviderID(instances, tc.node)
- assert.Equal(t, err, tc.providerIDErr)
- assert.EqualValues(t, tc.expectedCalls, fc.Calls,
- "expected cloud provider methods `%v` to be called but `%v` was called ",
- tc.expectedCalls, fc.Calls)
- assert.Equal(t, tc.expectedNodeExists, exists,
- "expected exists to be `%t` but got `%t`",
- tc.existsByProviderID, exists)
- })
- }
- }
- // This test checks that a node with the external cloud provider taint is cloudprovider initialized
- func TestNodeInitialized(t *testing.T) {
- fnh := &testutil.FakeNodeHandler{
- Existing: []*v1.Node{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- },
- Status: v1.NodeStatus{
- Conditions: []v1.NodeCondition{
- {
- Type: v1.NodeReady,
- Status: v1.ConditionUnknown,
- LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- },
- },
- },
- Spec: v1.NodeSpec{
- Taints: []v1.Taint{
- {
- Key: schedulerapi.TaintExternalCloudProvider,
- Value: "true",
- Effect: v1.TaintEffectNoSchedule,
- },
- },
- },
- },
- },
- Clientset: fake.NewSimpleClientset(&v1.PodList{}),
- DeleteWaitChan: make(chan struct{}),
- }
- factory := informers.NewSharedInformerFactory(fnh, controller.NoResyncPeriodFunc())
- fakeCloud := &fakecloud.Cloud{
- InstanceTypes: map[types.NodeName]string{
- types.NodeName("node0"): "t1.micro",
- },
- Addresses: []v1.NodeAddress{
- {
- Type: v1.NodeHostName,
- Address: "node0.cloud.internal",
- },
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- },
- Err: nil,
- }
- eventBroadcaster := record.NewBroadcaster()
- cloudNodeController := &CloudNodeController{
- kubeClient: fnh,
- nodeInformer: factory.Core().V1().Nodes(),
- cloud: fakeCloud,
- recorder: eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "cloud-node-controller"}),
- nodeStatusUpdateFrequency: 1 * time.Second,
- }
- eventBroadcaster.StartLogging(klog.Infof)
- cloudNodeController.AddCloudNode(fnh.Existing[0])
- assert.Equal(t, 1, len(fnh.UpdatedNodes), "Node was not updated")
- assert.Equal(t, "node0", fnh.UpdatedNodes[0].Name, "Node was not updated")
- assert.Equal(t, 0, len(fnh.UpdatedNodes[0].Spec.Taints), "Node Taint was not removed after cloud init")
- }
- // This test checks that a node without the external cloud provider taint are NOT cloudprovider initialized
- func TestNodeIgnored(t *testing.T) {
- fnh := &testutil.FakeNodeHandler{
- Existing: []*v1.Node{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- },
- Status: v1.NodeStatus{
- Conditions: []v1.NodeCondition{
- {
- Type: v1.NodeReady,
- Status: v1.ConditionUnknown,
- LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- },
- },
- },
- },
- },
- Clientset: fake.NewSimpleClientset(&v1.PodList{}),
- DeleteWaitChan: make(chan struct{}),
- }
- factory := informers.NewSharedInformerFactory(fnh, controller.NoResyncPeriodFunc())
- fakeCloud := &fakecloud.Cloud{
- InstanceTypes: map[types.NodeName]string{
- types.NodeName("node0"): "t1.micro",
- },
- Addresses: []v1.NodeAddress{
- {
- Type: v1.NodeHostName,
- Address: "node0.cloud.internal",
- },
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- },
- Err: nil,
- }
- eventBroadcaster := record.NewBroadcaster()
- cloudNodeController := &CloudNodeController{
- kubeClient: fnh,
- nodeInformer: factory.Core().V1().Nodes(),
- cloud: fakeCloud,
- recorder: eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "cloud-node-controller"}),
- }
- eventBroadcaster.StartLogging(klog.Infof)
- cloudNodeController.AddCloudNode(fnh.Existing[0])
- assert.Equal(t, 0, len(fnh.UpdatedNodes), "Node was wrongly updated")
- }
- // This test checks that a node with the external cloud provider taint is cloudprovider initialized and
- // the GCE route condition is added if cloudprovider is GCE
- func TestGCECondition(t *testing.T) {
- fnh := &testutil.FakeNodeHandler{
- Existing: []*v1.Node{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- },
- Status: v1.NodeStatus{
- Conditions: []v1.NodeCondition{
- {
- Type: v1.NodeReady,
- Status: v1.ConditionUnknown,
- LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- },
- },
- },
- Spec: v1.NodeSpec{
- Taints: []v1.Taint{
- {
- Key: schedulerapi.TaintExternalCloudProvider,
- Value: "true",
- Effect: v1.TaintEffectNoSchedule,
- },
- },
- },
- },
- },
- Clientset: fake.NewSimpleClientset(&v1.PodList{}),
- DeleteWaitChan: make(chan struct{}),
- }
- factory := informers.NewSharedInformerFactory(fnh, controller.NoResyncPeriodFunc())
- fakeCloud := &fakecloud.Cloud{
- InstanceTypes: map[types.NodeName]string{
- types.NodeName("node0"): "t1.micro",
- },
- Addresses: []v1.NodeAddress{
- {
- Type: v1.NodeHostName,
- Address: "node0.cloud.internal",
- },
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- },
- Provider: "gce",
- Err: nil,
- }
- eventBroadcaster := record.NewBroadcaster()
- cloudNodeController := &CloudNodeController{
- kubeClient: fnh,
- nodeInformer: factory.Core().V1().Nodes(),
- cloud: fakeCloud,
- recorder: eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "cloud-node-controller"}),
- }
- eventBroadcaster.StartLogging(klog.Infof)
- cloudNodeController.AddCloudNode(fnh.Existing[0])
- assert.Equal(t, 1, len(fnh.UpdatedNodes), "Node was not updated")
- assert.Equal(t, "node0", fnh.UpdatedNodes[0].Name, "Node was not updated")
- assert.Equal(t, 2, len(fnh.UpdatedNodes[0].Status.Conditions), "No new conditions were added for GCE")
- conditionAdded := false
- for _, cond := range fnh.UpdatedNodes[0].Status.Conditions {
- if cond.Status == "True" && cond.Type == "NetworkUnavailable" && cond.Reason == "NoRouteCreated" {
- conditionAdded = true
- }
- }
- assert.True(t, conditionAdded, "Network Route Condition for GCE not added by external cloud initializer")
- }
- // This test checks that a node with the external cloud provider taint is cloudprovider initialized and
- // and that zone labels are added correctly
- func TestZoneInitialized(t *testing.T) {
- fnh := &testutil.FakeNodeHandler{
- Existing: []*v1.Node{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- Labels: map[string]string{},
- },
- Status: v1.NodeStatus{
- Conditions: []v1.NodeCondition{
- {
- Type: v1.NodeReady,
- Status: v1.ConditionUnknown,
- LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- },
- },
- },
- Spec: v1.NodeSpec{
- Taints: []v1.Taint{
- {
- Key: schedulerapi.TaintExternalCloudProvider,
- Value: "true",
- Effect: v1.TaintEffectNoSchedule,
- },
- },
- },
- },
- },
- Clientset: fake.NewSimpleClientset(&v1.PodList{}),
- DeleteWaitChan: make(chan struct{}),
- }
- factory := informers.NewSharedInformerFactory(fnh, controller.NoResyncPeriodFunc())
- fakeCloud := &fakecloud.Cloud{
- InstanceTypes: map[types.NodeName]string{
- types.NodeName("node0"): "t1.micro",
- },
- Addresses: []v1.NodeAddress{
- {
- Type: v1.NodeHostName,
- Address: "node0.cloud.internal",
- },
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- },
- Provider: "aws",
- Zone: cloudprovider.Zone{
- FailureDomain: "us-west-1a",
- Region: "us-west",
- },
- Err: nil,
- }
- eventBroadcaster := record.NewBroadcaster()
- cloudNodeController := &CloudNodeController{
- kubeClient: fnh,
- nodeInformer: factory.Core().V1().Nodes(),
- cloud: fakeCloud,
- recorder: eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "cloud-node-controller"}),
- }
- eventBroadcaster.StartLogging(klog.Infof)
- cloudNodeController.AddCloudNode(fnh.Existing[0])
- assert.Equal(t, 1, len(fnh.UpdatedNodes), "Node was not updated")
- assert.Equal(t, "node0", fnh.UpdatedNodes[0].Name, "Node was not updated")
- assert.Equal(t, 2, len(fnh.UpdatedNodes[0].ObjectMeta.Labels),
- "Node label for Region and Zone were not set")
- assert.Equal(t, "us-west", fnh.UpdatedNodes[0].ObjectMeta.Labels[v1.LabelZoneRegion],
- "Node Region not correctly updated")
- assert.Equal(t, "us-west-1a", fnh.UpdatedNodes[0].ObjectMeta.Labels[v1.LabelZoneFailureDomain],
- "Node FailureDomain not correctly updated")
- }
- // This test checks that a node with the external cloud provider taint is cloudprovider initialized and
- // and nodeAddresses are updated from the cloudprovider
- func TestNodeAddresses(t *testing.T) {
- fnh := &testutil.FakeNodeHandler{
- Existing: []*v1.Node{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- Labels: map[string]string{},
- },
- Status: v1.NodeStatus{
- Conditions: []v1.NodeCondition{
- {
- Type: v1.NodeReady,
- Status: v1.ConditionUnknown,
- LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- },
- },
- },
- Spec: v1.NodeSpec{
- Taints: []v1.Taint{
- {
- Key: "ImproveCoverageTaint",
- Value: "true",
- Effect: v1.TaintEffectNoSchedule,
- },
- {
- Key: schedulerapi.TaintExternalCloudProvider,
- Value: "true",
- Effect: v1.TaintEffectNoSchedule,
- },
- },
- },
- },
- },
- Clientset: fake.NewSimpleClientset(&v1.PodList{}),
- DeleteWaitChan: make(chan struct{}),
- }
- factory := informers.NewSharedInformerFactory(fnh, controller.NoResyncPeriodFunc())
- fakeCloud := &fakecloud.Cloud{
- InstanceTypes: map[types.NodeName]string{},
- Addresses: []v1.NodeAddress{
- {
- Type: v1.NodeHostName,
- Address: "node0.cloud.internal",
- },
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- },
- Provider: "aws",
- Zone: cloudprovider.Zone{
- FailureDomain: "us-west-1a",
- Region: "us-west",
- },
- ExistsByProviderID: true,
- Err: nil,
- }
- eventBroadcaster := record.NewBroadcaster()
- cloudNodeController := &CloudNodeController{
- kubeClient: fnh,
- nodeInformer: factory.Core().V1().Nodes(),
- cloud: fakeCloud,
- nodeStatusUpdateFrequency: 1 * time.Second,
- recorder: eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "cloud-node-controller"}),
- }
- eventBroadcaster.StartLogging(klog.Infof)
- cloudNodeController.AddCloudNode(fnh.Existing[0])
- assert.Equal(t, 1, len(fnh.UpdatedNodes), "Node was not updated")
- assert.Equal(t, "node0", fnh.UpdatedNodes[0].Name, "Node was not updated")
- assert.Equal(t, 3, len(fnh.UpdatedNodes[0].Status.Addresses), "Node status not updated")
- fakeCloud.Addresses = []v1.NodeAddress{
- {
- Type: v1.NodeHostName,
- Address: "node0.cloud.internal",
- },
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- }
- cloudNodeController.UpdateNodeStatus()
- updatedNodes := fnh.GetUpdatedNodesCopy()
- assert.Equal(t, 2, len(updatedNodes[0].Status.Addresses), "Node Addresses not correctly updated")
- }
- // This test checks that a node with the external cloud provider taint is cloudprovider initialized and
- // and the provided node ip is validated with the cloudprovider and nodeAddresses are updated from the cloudprovider
- func TestNodeProvidedIPAddresses(t *testing.T) {
- fnh := &testutil.FakeNodeHandler{
- Existing: []*v1.Node{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- Labels: map[string]string{},
- Annotations: map[string]string{
- kubeletapis.AnnotationProvidedIPAddr: "10.0.0.1",
- },
- },
- Status: v1.NodeStatus{
- Conditions: []v1.NodeCondition{
- {
- Type: v1.NodeReady,
- Status: v1.ConditionUnknown,
- LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- },
- },
- Addresses: []v1.NodeAddress{
- {
- Type: v1.NodeHostName,
- Address: "node0.cloud.internal",
- },
- },
- },
- Spec: v1.NodeSpec{
- Taints: []v1.Taint{
- {
- Key: "ImproveCoverageTaint",
- Value: "true",
- Effect: v1.TaintEffectNoSchedule,
- },
- {
- Key: schedulerapi.TaintExternalCloudProvider,
- Value: "true",
- Effect: v1.TaintEffectNoSchedule,
- },
- },
- ProviderID: "node0.aws.12345",
- },
- },
- },
- Clientset: fake.NewSimpleClientset(&v1.PodList{}),
- DeleteWaitChan: make(chan struct{}),
- }
- factory := informers.NewSharedInformerFactory(fnh, controller.NoResyncPeriodFunc())
- fakeCloud := &fakecloud.Cloud{
- InstanceTypes: map[types.NodeName]string{
- types.NodeName("node0"): "t1.micro",
- types.NodeName("node0.aws.12345"): "t2.macro",
- },
- Addresses: []v1.NodeAddress{
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- },
- Provider: "aws",
- Zone: cloudprovider.Zone{
- FailureDomain: "us-west-1a",
- Region: "us-west",
- },
- ExistsByProviderID: true,
- Err: nil,
- }
- eventBroadcaster := record.NewBroadcaster()
- cloudNodeController := &CloudNodeController{
- kubeClient: fnh,
- nodeInformer: factory.Core().V1().Nodes(),
- cloud: fakeCloud,
- nodeStatusUpdateFrequency: 1 * time.Second,
- recorder: eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "cloud-node-controller"}),
- }
- eventBroadcaster.StartLogging(klog.Infof)
- cloudNodeController.AddCloudNode(fnh.Existing[0])
- assert.Equal(t, 1, len(fnh.UpdatedNodes), "Node was not updated")
- assert.Equal(t, "node0", fnh.UpdatedNodes[0].Name, "Node was not updated")
- assert.Equal(t, 3, len(fnh.UpdatedNodes[0].Status.Addresses), "Node status unexpectedly updated")
- cloudNodeController.UpdateNodeStatus()
- updatedNodes := fnh.GetUpdatedNodesCopy()
- assert.Equal(t, 3, len(updatedNodes[0].Status.Addresses), "Node Addresses not correctly updated")
- assert.Equal(t, "10.0.0.1", updatedNodes[0].Status.Addresses[0].Address, "Node Addresses not correctly updated")
- }
- // Tests that node address changes are detected correctly
- func TestNodeAddressesChangeDetected(t *testing.T) {
- addressSet1 := []v1.NodeAddress{
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- }
- addressSet2 := []v1.NodeAddress{
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- }
- assert.False(t, nodeAddressesChangeDetected(addressSet1, addressSet2),
- "Node address changes are not detected correctly")
- addressSet1 = []v1.NodeAddress{
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.164",
- },
- }
- addressSet2 = []v1.NodeAddress{
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- }
- assert.True(t, nodeAddressesChangeDetected(addressSet1, addressSet2),
- "Node address changes are not detected correctly")
- addressSet1 = []v1.NodeAddress{
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.164",
- },
- {
- Type: v1.NodeHostName,
- Address: "hostname.zone.region.aws.test",
- },
- }
- addressSet2 = []v1.NodeAddress{
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.164",
- },
- }
- assert.True(t, nodeAddressesChangeDetected(addressSet1, addressSet2),
- "Node address changes are not detected correctly")
- addressSet1 = []v1.NodeAddress{
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.164",
- },
- }
- addressSet2 = []v1.NodeAddress{
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.164",
- },
- {
- Type: v1.NodeHostName,
- Address: "hostname.zone.region.aws.test",
- },
- }
- assert.True(t, nodeAddressesChangeDetected(addressSet1, addressSet2),
- "Node address changes are not detected correctly")
- addressSet1 = []v1.NodeAddress{
- {
- Type: v1.NodeExternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeInternalIP,
- Address: "132.143.154.163",
- },
- }
- addressSet2 = []v1.NodeAddress{
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- }
- assert.True(t, nodeAddressesChangeDetected(addressSet1, addressSet2),
- "Node address changes are not detected correctly")
- }
- // This test checks that a node with the external cloud provider taint is cloudprovider initialized and
- // and node addresses will not be updated when node isn't present according to the cloudprovider
- func TestNodeAddressesNotUpdate(t *testing.T) {
- fnh := &testutil.FakeNodeHandler{
- Existing: []*v1.Node{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- Labels: map[string]string{},
- },
- Status: v1.NodeStatus{
- Conditions: []v1.NodeCondition{
- {
- Type: v1.NodeReady,
- Status: v1.ConditionUnknown,
- LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- },
- },
- },
- Spec: v1.NodeSpec{
- Taints: []v1.Taint{
- {
- Key: "ImproveCoverageTaint",
- Value: "true",
- Effect: v1.TaintEffectNoSchedule,
- },
- },
- },
- },
- },
- }
- factory := informers.NewSharedInformerFactory(fnh, controller.NoResyncPeriodFunc())
- fakeCloud := &fakecloud.Cloud{
- InstanceTypes: map[types.NodeName]string{},
- Addresses: []v1.NodeAddress{
- {
- Type: v1.NodeHostName,
- Address: "node0.cloud.internal",
- },
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- },
- ExistsByProviderID: false,
- Err: nil,
- }
- cloudNodeController := &CloudNodeController{
- kubeClient: fnh,
- nodeInformer: factory.Core().V1().Nodes(),
- cloud: fakeCloud,
- }
- cloudNodeController.updateNodeAddress(fnh.Existing[0], fakeCloud)
- if len(fnh.UpdatedNodes) != 0 {
- t.Errorf("Node was not correctly updated, the updated len(nodes) got: %v, wanted=0", len(fnh.UpdatedNodes))
- }
- }
- // This test checks that a node is set with the correct providerID
- func TestNodeProviderID(t *testing.T) {
- fnh := &testutil.FakeNodeHandler{
- Existing: []*v1.Node{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- Labels: map[string]string{},
- },
- Status: v1.NodeStatus{
- Conditions: []v1.NodeCondition{
- {
- Type: v1.NodeReady,
- Status: v1.ConditionUnknown,
- LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- },
- },
- },
- Spec: v1.NodeSpec{
- Taints: []v1.Taint{
- {
- Key: "ImproveCoverageTaint",
- Value: "true",
- Effect: v1.TaintEffectNoSchedule,
- },
- {
- Key: schedulerapi.TaintExternalCloudProvider,
- Value: "true",
- Effect: v1.TaintEffectNoSchedule,
- },
- },
- },
- },
- },
- Clientset: fake.NewSimpleClientset(&v1.PodList{}),
- DeleteWaitChan: make(chan struct{}),
- }
- factory := informers.NewSharedInformerFactory(fnh, controller.NoResyncPeriodFunc())
- fakeCloud := &fakecloud.Cloud{
- InstanceTypes: map[types.NodeName]string{},
- Addresses: []v1.NodeAddress{
- {
- Type: v1.NodeHostName,
- Address: "node0.cloud.internal",
- },
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- },
- Provider: "test",
- ExtID: map[types.NodeName]string{
- types.NodeName("node0"): "12345",
- },
- Err: nil,
- }
- eventBroadcaster := record.NewBroadcaster()
- cloudNodeController := &CloudNodeController{
- kubeClient: fnh,
- nodeInformer: factory.Core().V1().Nodes(),
- cloud: fakeCloud,
- nodeStatusUpdateFrequency: 1 * time.Second,
- recorder: eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "cloud-node-controller"}),
- }
- eventBroadcaster.StartLogging(klog.Infof)
- cloudNodeController.AddCloudNode(fnh.Existing[0])
- assert.Equal(t, 1, len(fnh.UpdatedNodes), "Node was not updated")
- assert.Equal(t, "node0", fnh.UpdatedNodes[0].Name, "Node was not updated")
- assert.Equal(t, "test://12345", fnh.UpdatedNodes[0].Spec.ProviderID, "Node ProviderID not set correctly")
- }
- // This test checks that a node's provider ID will not be overwritten
- func TestNodeProviderIDAlreadySet(t *testing.T) {
- fnh := &testutil.FakeNodeHandler{
- Existing: []*v1.Node{
- {
- ObjectMeta: metav1.ObjectMeta{
- Name: "node0",
- CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
- Labels: map[string]string{},
- },
- Status: v1.NodeStatus{
- Conditions: []v1.NodeCondition{
- {
- Type: v1.NodeReady,
- Status: v1.ConditionUnknown,
- LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
- },
- },
- },
- Spec: v1.NodeSpec{
- ProviderID: "test-provider-id",
- Taints: []v1.Taint{
- {
- Key: "ImproveCoverageTaint",
- Value: "true",
- Effect: v1.TaintEffectNoSchedule,
- },
- {
- Key: schedulerapi.TaintExternalCloudProvider,
- Value: "true",
- Effect: v1.TaintEffectNoSchedule,
- },
- },
- },
- },
- },
- Clientset: fake.NewSimpleClientset(&v1.PodList{}),
- DeleteWaitChan: make(chan struct{}),
- }
- factory := informers.NewSharedInformerFactory(fnh, controller.NoResyncPeriodFunc())
- fakeCloud := &fakecloud.Cloud{
- InstanceTypes: map[types.NodeName]string{},
- Addresses: []v1.NodeAddress{
- {
- Type: v1.NodeHostName,
- Address: "node0.cloud.internal",
- },
- {
- Type: v1.NodeInternalIP,
- Address: "10.0.0.1",
- },
- {
- Type: v1.NodeExternalIP,
- Address: "132.143.154.163",
- },
- },
- Provider: "test",
- ExtID: map[types.NodeName]string{
- types.NodeName("node0"): "12345",
- },
- Err: nil,
- }
- eventBroadcaster := record.NewBroadcaster()
- cloudNodeController := &CloudNodeController{
- kubeClient: fnh,
- nodeInformer: factory.Core().V1().Nodes(),
- cloud: fakeCloud,
- nodeStatusUpdateFrequency: 1 * time.Second,
- recorder: eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "cloud-node-controller"}),
- }
- eventBroadcaster.StartLogging(klog.Infof)
- cloudNodeController.AddCloudNode(fnh.Existing[0])
- assert.Equal(t, 1, len(fnh.UpdatedNodes), "Node was not updated")
- assert.Equal(t, "node0", fnh.UpdatedNodes[0].Name, "Node was not updated")
- // CCM node controller should not overwrite provider if it's already set
- assert.Equal(t, "test-provider-id", fnh.UpdatedNodes[0].Spec.ProviderID, "Node ProviderID not set correctly")
- }
|