mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
vendor update for CSI 0.3.0
This commit is contained in:
1
vendor/k8s.io/kubernetes/pkg/controller/cloud/BUILD
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/controller/cloud/BUILD
generated
vendored
@ -17,6 +17,7 @@ go_library(
|
||||
"//pkg/api/v1/node:go_default_library",
|
||||
"//pkg/cloudprovider:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/util/node:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//pkg/scheduler/algorithm:go_default_library",
|
||||
"//pkg/util/node:go_default_library",
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/controller/cloud/OWNERS
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/controller/cloud/OWNERS
generated
vendored
@ -2,7 +2,9 @@ approvers:
|
||||
- thockin
|
||||
- luxas
|
||||
- wlan0
|
||||
- andrewsykim
|
||||
reviewers:
|
||||
- thockin
|
||||
- luxas
|
||||
- wlan0
|
||||
- andrewsykim
|
||||
|
81
vendor/k8s.io/kubernetes/pkg/controller/cloud/node_controller.go
generated
vendored
81
vendor/k8s.io/kubernetes/pkg/controller/cloud/node_controller.go
generated
vendored
@ -18,6 +18,7 @@ package cloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@ -37,6 +38,8 @@ import (
|
||||
clientretry "k8s.io/client-go/util/retry"
|
||||
nodeutilv1 "k8s.io/kubernetes/pkg/api/v1/node"
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
nodectrlutil "k8s.io/kubernetes/pkg/controller/util/node"
|
||||
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
||||
"k8s.io/kubernetes/pkg/scheduler/algorithm"
|
||||
nodeutil "k8s.io/kubernetes/pkg/util/node"
|
||||
@ -84,7 +87,7 @@ func NewCloudNodeController(
|
||||
eventBroadcaster.StartLogging(glog.Infof)
|
||||
if kubeClient != nil {
|
||||
glog.V(0).Infof("Sending events to api server.")
|
||||
eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.CoreV1().RESTClient()).Events("")})
|
||||
eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: kubeClient.CoreV1().Events("")})
|
||||
} else {
|
||||
glog.V(0).Infof("No api server defined - no events will be sent to API server.")
|
||||
}
|
||||
@ -110,7 +113,7 @@ func NewCloudNodeController(
|
||||
|
||||
// This controller deletes a node if kubelet is not reporting
|
||||
// and the node is gone from the cloud provider.
|
||||
func (cnc *CloudNodeController) Run() {
|
||||
func (cnc *CloudNodeController) Run(stopCh <-chan struct{}) {
|
||||
defer utilruntime.HandleCrash()
|
||||
|
||||
// The following loops run communicate with the APIServer with a worst case complexity
|
||||
@ -118,10 +121,10 @@ func (cnc *CloudNodeController) Run() {
|
||||
// very infrequently. DO NOT MODIFY this to perform frequent operations.
|
||||
|
||||
// Start a loop to periodically update the node addresses obtained from the cloud
|
||||
go wait.Until(cnc.UpdateNodeStatus, cnc.nodeStatusUpdateFrequency, wait.NeverStop)
|
||||
go wait.Until(cnc.UpdateNodeStatus, cnc.nodeStatusUpdateFrequency, stopCh)
|
||||
|
||||
// Start a loop to periodically check if any nodes have been deleted from cloudprovider
|
||||
go wait.Until(cnc.MonitorNode, cnc.nodeMonitorPeriod, wait.NeverStop)
|
||||
go wait.Until(cnc.MonitorNode, cnc.nodeMonitorPeriod, stopCh)
|
||||
}
|
||||
|
||||
// UpdateNodeStatus updates the node status, such as node addresses
|
||||
@ -152,7 +155,7 @@ func (cnc *CloudNodeController) updateNodeAddress(node *v1.Node, instances cloud
|
||||
return
|
||||
}
|
||||
// Node that isn't present according to the cloud provider shouldn't have its address updated
|
||||
exists, err := ensureNodeExistsByProviderIDOrExternalID(instances, node)
|
||||
exists, err := ensureNodeExistsByProviderID(instances, node)
|
||||
if err != nil {
|
||||
// Continue to update node address when not sure the node is not exists
|
||||
glog.Errorf("%v", err)
|
||||
@ -166,6 +169,12 @@ func (cnc *CloudNodeController) updateNodeAddress(node *v1.Node, instances cloud
|
||||
glog.Errorf("%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(nodeAddresses) == 0 {
|
||||
glog.V(5).Infof("Skipping node address update for node %q since cloud provider did not return any", node.Name)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if a hostname address exists in the cloud provided addresses
|
||||
hostnameExists := false
|
||||
for i := range nodeAddresses {
|
||||
@ -189,7 +198,6 @@ func (cnc *CloudNodeController) updateNodeAddress(node *v1.Node, instances cloud
|
||||
glog.Errorf("Specified Node IP not found in cloudprovider")
|
||||
return
|
||||
}
|
||||
nodeAddresses = []v1.NodeAddress{*nodeIP}
|
||||
}
|
||||
newNode := node.DeepCopy()
|
||||
newNode.Status.Addresses = nodeAddresses
|
||||
@ -243,9 +251,27 @@ func (cnc *CloudNodeController) MonitorNode() {
|
||||
// from the cloud provider. If node cannot be found in cloudprovider, then delete the node immediately
|
||||
if currentReadyCondition != nil {
|
||||
if currentReadyCondition.Status != v1.ConditionTrue {
|
||||
// we need to check this first to get taint working in similar in all cloudproviders
|
||||
// current problem is that shutdown nodes are not working in similar way ie. all cloudproviders
|
||||
// does not delete node from kubernetes cluster when instance it is shutdown see issue #46442
|
||||
shutdown, err := nodectrlutil.ShutdownInCloudProvider(context.TODO(), cnc.cloud, node)
|
||||
if err != nil {
|
||||
glog.Errorf("Error getting data for node %s from cloud: %v", node.Name, err)
|
||||
}
|
||||
|
||||
if shutdown && err == nil {
|
||||
// if node is shutdown add shutdown taint
|
||||
err = controller.AddOrUpdateTaintOnNode(cnc.kubeClient, node.Name, controller.ShutdownTaint)
|
||||
if err != nil {
|
||||
glog.Errorf("Error patching node taints: %v", err)
|
||||
}
|
||||
// Continue checking the remaining nodes since the current one is shutdown.
|
||||
continue
|
||||
}
|
||||
|
||||
// Check with the cloud provider to see if the node still exists. If it
|
||||
// doesn't, delete the node immediately.
|
||||
exists, err := ensureNodeExistsByProviderIDOrExternalID(instances, node)
|
||||
exists, err := ensureNodeExistsByProviderID(instances, node)
|
||||
if err != nil {
|
||||
glog.Errorf("Error getting data for node %s from cloud: %v", node.Name, err)
|
||||
continue
|
||||
@ -275,6 +301,12 @@ func (cnc *CloudNodeController) MonitorNode() {
|
||||
}
|
||||
}(node.Name)
|
||||
|
||||
} else {
|
||||
// if taint exist remove taint
|
||||
err = controller.RemoveTaintOffNode(cnc.kubeClient, node.Name, node, controller.ShutdownTaint)
|
||||
if err != nil {
|
||||
glog.Errorf("Error patching node taints: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -324,21 +356,18 @@ func (cnc *CloudNodeController) AddCloudNode(obj interface{}) {
|
||||
|
||||
nodeAddresses, err := getNodeAddressesByProviderIDOrName(instances, curNode)
|
||||
if err != nil {
|
||||
glog.Errorf("%v", err)
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// If user provided an IP address, ensure that IP address is found
|
||||
// in the cloud provider before removing the taint on the node
|
||||
if nodeIP, ok := ensureNodeProvidedIPExists(curNode, nodeAddresses); ok {
|
||||
if nodeIP == nil {
|
||||
glog.Errorf("failed to get specified nodeIP in cloudprovider")
|
||||
return nil
|
||||
return errors.New("failed to find kubelet node IP from cloud provider")
|
||||
}
|
||||
}
|
||||
|
||||
if instanceType, err := getInstanceTypeByProviderIDOrName(instances, curNode); err != nil {
|
||||
glog.Errorf("%v", err)
|
||||
return err
|
||||
} else if instanceType != "" {
|
||||
glog.V(2).Infof("Adding node label from cloud provider: %s=%s", kubeletapis.LabelInstanceType, instanceType)
|
||||
@ -412,23 +441,27 @@ func excludeTaintFromList(taints []v1.Taint, toExclude v1.Taint) []v1.Taint {
|
||||
return newTaints
|
||||
}
|
||||
|
||||
// ensureNodeExistsByProviderIDOrExternalID first checks if the instance exists by the provider id and then by calling external id with node name
|
||||
func ensureNodeExistsByProviderIDOrExternalID(instances cloudprovider.Instances, node *v1.Node) (bool, error) {
|
||||
exists, err := instances.InstanceExistsByProviderID(context.TODO(), node.Spec.ProviderID)
|
||||
if err != nil {
|
||||
providerIDErr := err
|
||||
_, err = instances.ExternalID(context.TODO(), types.NodeName(node.Name))
|
||||
if err == nil {
|
||||
return true, nil
|
||||
// ensureNodeExistsByProviderID checks if the instance exists by the provider id,
|
||||
// If provider id in spec is empty it calls instanceId with node name to get provider id
|
||||
func ensureNodeExistsByProviderID(instances cloudprovider.Instances, node *v1.Node) (bool, error) {
|
||||
providerID := node.Spec.ProviderID
|
||||
if providerID == "" {
|
||||
var err error
|
||||
providerID, err = instances.InstanceID(context.TODO(), types.NodeName(node.Name))
|
||||
if err != nil {
|
||||
if err == cloudprovider.InstanceNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if err == cloudprovider.InstanceNotFound {
|
||||
|
||||
if providerID == "" {
|
||||
glog.Warningf("Cannot find valid providerID for node name %q, assuming non existence", node.Name)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("InstanceExistsByProviderID: Error fetching by providerID: %v Error fetching by NodeName: %v", providerIDErr, err)
|
||||
}
|
||||
|
||||
return exists, nil
|
||||
return instances.InstanceExistsByProviderID(context.TODO(), providerID)
|
||||
}
|
||||
|
||||
func getNodeAddressesByProviderIDOrName(instances cloudprovider.Instances, node *v1.Node) ([]v1.NodeAddress, error) {
|
||||
|
181
vendor/k8s.io/kubernetes/pkg/controller/cloud/node_controller_test.go
generated
vendored
181
vendor/k8s.io/kubernetes/pkg/controller/cloud/node_controller_test.go
generated
vendored
@ -41,13 +41,14 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEnsureNodeExistsByProviderIDOrNodeName(t *testing.T) {
|
||||
func TestEnsureNodeExistsByProviderID(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
testName string
|
||||
node *v1.Node
|
||||
expectedCalls []string
|
||||
existsByNodeName bool
|
||||
expectedNodeExists bool
|
||||
hasInstanceID bool
|
||||
existsByProviderID bool
|
||||
nodeNameErr error
|
||||
providerIDErr error
|
||||
@ -56,9 +57,10 @@ func TestEnsureNodeExistsByProviderIDOrNodeName(t *testing.T) {
|
||||
testName: "node exists by provider id",
|
||||
existsByProviderID: true,
|
||||
providerIDErr: nil,
|
||||
existsByNodeName: false,
|
||||
hasInstanceID: true,
|
||||
nodeNameErr: errors.New("unimplemented"),
|
||||
expectedCalls: []string{"instance-exists-by-provider-id"},
|
||||
expectedNodeExists: true,
|
||||
node: &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node0",
|
||||
@ -72,9 +74,10 @@ func TestEnsureNodeExistsByProviderIDOrNodeName(t *testing.T) {
|
||||
testName: "does not exist by provider id",
|
||||
existsByProviderID: false,
|
||||
providerIDErr: nil,
|
||||
existsByNodeName: false,
|
||||
hasInstanceID: true,
|
||||
nodeNameErr: errors.New("unimplemented"),
|
||||
expectedCalls: []string{"instance-exists-by-provider-id"},
|
||||
expectedNodeExists: false,
|
||||
node: &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node0",
|
||||
@ -85,28 +88,41 @@ func TestEnsureNodeExistsByProviderIDOrNodeName(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "node exists by node name",
|
||||
existsByProviderID: false,
|
||||
providerIDErr: errors.New("unimplemented"),
|
||||
existsByNodeName: true,
|
||||
testName: "exists by instance id",
|
||||
existsByProviderID: true,
|
||||
providerIDErr: nil,
|
||||
hasInstanceID: true,
|
||||
nodeNameErr: nil,
|
||||
expectedCalls: []string{"instance-exists-by-provider-id", "external-id"},
|
||||
expectedCalls: []string{"instance-id", "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 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: "does not exist by node name",
|
||||
testName: "provider id returns error",
|
||||
existsByProviderID: false,
|
||||
providerIDErr: errors.New("unimplemented"),
|
||||
existsByNodeName: false,
|
||||
hasInstanceID: true,
|
||||
nodeNameErr: cloudprovider.InstanceNotFound,
|
||||
expectedCalls: []string{"instance-exists-by-provider-id", "external-id"},
|
||||
expectedCalls: []string{"instance-exists-by-provider-id"},
|
||||
expectedNodeExists: false,
|
||||
node: &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node0",
|
||||
@ -121,28 +137,137 @@ func TestEnsureNodeExistsByProviderIDOrNodeName(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.testName, func(t *testing.T) {
|
||||
fc := &fakecloud.FakeCloud{
|
||||
Exists: tc.existsByNodeName,
|
||||
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 := ensureNodeExistsByProviderIDOrExternalID(instances, tc.node)
|
||||
assert.NoError(t, err)
|
||||
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.False(t, tc.existsByProviderID && tc.existsByProviderID != exists,
|
||||
"expected exist by provider id to be `%t` but got `%t`",
|
||||
assert.Equal(t, tc.expectedNodeExists, exists,
|
||||
"expected exists to be `%t` but got `%t`",
|
||||
tc.existsByProviderID, exists)
|
||||
})
|
||||
}
|
||||
|
||||
assert.False(t, tc.existsByNodeName && tc.existsByNodeName != exists,
|
||||
"expected exist by node name to be `%t` but got `%t`", tc.existsByNodeName, exists)
|
||||
}
|
||||
|
||||
func TestNodeShutdown(t *testing.T) {
|
||||
|
||||
testCases := []struct {
|
||||
testName string
|
||||
node *v1.Node
|
||||
existsByProviderID bool
|
||||
shutdown bool
|
||||
}{
|
||||
{
|
||||
testName: "node shutdowned add taint",
|
||||
existsByProviderID: true,
|
||||
shutdown: true,
|
||||
node: &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node0",
|
||||
CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
Spec: v1.NodeSpec{
|
||||
ProviderID: "node0",
|
||||
},
|
||||
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),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "node started after shutdown remove taint",
|
||||
existsByProviderID: true,
|
||||
shutdown: false,
|
||||
node: &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "node0",
|
||||
CreationTimestamp: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
Spec: v1.NodeSpec{
|
||||
ProviderID: "node0",
|
||||
Taints: []v1.Taint{
|
||||
{
|
||||
Key: algorithm.TaintNodeShutdown,
|
||||
Effect: v1.TaintEffectNoSchedule,
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: v1.NodeStatus{
|
||||
Conditions: []v1.NodeCondition{
|
||||
{
|
||||
Type: v1.NodeReady,
|
||||
Status: v1.ConditionTrue,
|
||||
LastHeartbeatTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
|
||||
LastTransitionTime: metav1.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.testName, func(t *testing.T) {
|
||||
fc := &fakecloud.FakeCloud{
|
||||
ExistsByProviderID: tc.existsByProviderID,
|
||||
NodeShutdown: tc.shutdown,
|
||||
}
|
||||
fnh := &testutil.FakeNodeHandler{
|
||||
Existing: []*v1.Node{tc.node},
|
||||
Clientset: fake.NewSimpleClientset(),
|
||||
PatchWaitChan: make(chan struct{}),
|
||||
}
|
||||
|
||||
factory := informers.NewSharedInformerFactory(fnh, controller.NoResyncPeriodFunc())
|
||||
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
cloudNodeController := &CloudNodeController{
|
||||
kubeClient: fnh,
|
||||
nodeInformer: factory.Core().V1().Nodes(),
|
||||
cloud: fc,
|
||||
nodeMonitorPeriod: 1 * time.Second,
|
||||
recorder: eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: "cloud-node-controller"}),
|
||||
nodeStatusUpdateFrequency: 1 * time.Second,
|
||||
}
|
||||
eventBroadcaster.StartLogging(glog.Infof)
|
||||
|
||||
cloudNodeController.Run(wait.NeverStop)
|
||||
|
||||
select {
|
||||
case <-fnh.PatchWaitChan:
|
||||
case <-time.After(1 * time.Second):
|
||||
t.Errorf("Timed out waiting %v for node to be updated", wait.ForeverTestTimeout)
|
||||
}
|
||||
|
||||
assert.Equal(t, 1, len(fnh.UpdatedNodes), "Node was not updated")
|
||||
if tc.shutdown {
|
||||
assert.Equal(t, 1, len(fnh.UpdatedNodes[0].Spec.Taints), "Node Taint was not added")
|
||||
assert.Equal(t, "node.cloudprovider.kubernetes.io/shutdown", fnh.UpdatedNodes[0].Spec.Taints[0].Key, "Node Taint key is not correct")
|
||||
} else {
|
||||
assert.Equal(t, 0, len(fnh.UpdatedNodes[0].Spec.Taints), "Node Taint was not removed after node is back in ready state")
|
||||
}
|
||||
|
||||
assert.False(t, !tc.existsByNodeName && !tc.existsByProviderID && exists,
|
||||
"node is not supposed to exist")
|
||||
})
|
||||
}
|
||||
|
||||
@ -226,7 +351,7 @@ func TestNodeDeleted(t *testing.T) {
|
||||
}
|
||||
eventBroadcaster.StartLogging(glog.Infof)
|
||||
|
||||
cloudNodeController.Run()
|
||||
cloudNodeController.Run(wait.NeverStop)
|
||||
|
||||
select {
|
||||
case <-fnh.DeleteWaitChan:
|
||||
@ -643,7 +768,7 @@ func TestNodeAddresses(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
cloudNodeController.Run()
|
||||
cloudNodeController.Run(wait.NeverStop)
|
||||
|
||||
<-time.After(2 * time.Second)
|
||||
|
||||
@ -745,15 +870,15 @@ func TestNodeProvidedIPAddresses(t *testing.T) {
|
||||
|
||||
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, 1, len(fnh.UpdatedNodes[0].Status.Addresses), "Node status unexpectedly updated")
|
||||
assert.Equal(t, 3, len(fnh.UpdatedNodes[0].Status.Addresses), "Node status unexpectedly updated")
|
||||
|
||||
cloudNodeController.Run()
|
||||
cloudNodeController.Run(wait.NeverStop)
|
||||
|
||||
<-time.After(2 * time.Second)
|
||||
|
||||
updatedNodes := fnh.GetUpdatedNodesCopy()
|
||||
|
||||
assert.Equal(t, 1, len(updatedNodes[0].Status.Addresses), 1, "Node Addresses not correctly updated")
|
||||
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")
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user