diff --git a/cns/middlewares/k8sSwiftV2.go b/cns/middlewares/k8sSwiftV2.go index 8805996060..835c552dbc 100644 --- a/cns/middlewares/k8sSwiftV2.go +++ b/cns/middlewares/k8sSwiftV2.go @@ -28,6 +28,7 @@ var ( errGetMTPNC = errors.New(NetworkNotReadyErrorMsg + " - failed to get MTPNC") errInvalidSWIFTv2NICType = errors.New("invalid NIC type for SWIFT v2 scenario") errInvalidMTPNCPrefixLength = errors.New("invalid prefix length for MTPNC primaryIP, must be 32") + errMTPNCDeleting = errors.New(NetworkNotReadyErrorMsg + " - mtpnc for previous pod is being deleted, waiting for new mtpnc to be ready") ) type K8sSWIFTv2Middleware struct { @@ -54,7 +55,9 @@ func (k *K8sSWIFTv2Middleware) GetPodInfoForIPConfigsRequest(ctx context.Context if respCode != types.Success { return nil, respCode, message } - + if mtpnc.IsDeleting() { + return nil, types.UnexpectedError, errMTPNCDeleting.Error() + } // update ipConfigRequest respCode, message = k.UpdateIPConfigRequest(mtpnc, req) if respCode != types.Success { diff --git a/cns/middlewares/k8sSwiftV2_linux_test.go b/cns/middlewares/k8sSwiftV2_linux_test.go index 52b257acfb..c5d84b5865 100644 --- a/cns/middlewares/k8sSwiftV2_linux_test.go +++ b/cns/middlewares/k8sSwiftV2_linux_test.go @@ -41,6 +41,9 @@ var ( testPod9GUID = "2006cad4-e54d-472e-863d-c4bac66200a7" testPod9Info = cns.NewPodInfo("2006cad4-eth0", testPod9GUID, "testpod9", "testpod9namespace") + + testPodMtpncTerminatingGUID = "e3b0c442-98fc-1fc1-9b93-7a1c2e5c8e6f" + testPodMtpncTerminatingInfo = cns.NewPodInfo("2006cad4-eth0", testPodMtpncTerminatingGUID, "testpodMtpncTerminating", "testpodMtpncTerminatingnamespace") ) func TestMain(m *testing.M) { @@ -217,6 +220,13 @@ func TestValidateMultitenantIPConfigsRequestFailure(t *testing.T) { _, respCode, msg = middleware.GetPodInfoForIPConfigsRequest(context.TODO(), failReq) assert.Equal(t, respCode, types.UnexpectedError) assert.Assert(t, strings.Contains(msg, NetworkNotReadyErrorMsg), "expected error message to contain '%s', got '%s'", NetworkNotReadyErrorMsg, msg) + + // Delete Timestamp is set + b, _ = testPodMtpncTerminatingInfo.OrchestratorContext() + failReq.OrchestratorContext = b + _, respCode, msg = middleware.GetPodInfoForIPConfigsRequest(context.TODO(), failReq) + assert.Equal(t, respCode, types.UnexpectedError) + assert.Assert(t, strings.Contains(msg, NetworkNotReadyErrorMsg), "expected error message to contain '%s', got '%s'", NetworkNotReadyErrorMsg, msg) } func TestGetSWIFTv2IPConfigSuccess(t *testing.T) { diff --git a/cns/middlewares/mock/mockClient.go b/cns/middlewares/mock/mockClient.go index 843f03111a..52ebd04225 100644 --- a/cns/middlewares/mock/mockClient.go +++ b/cns/middlewares/mock/mockClient.go @@ -7,6 +7,7 @@ import ( "github.com/Azure/azure-container-networking/crd/multitenancy/api/v1alpha1" "github.com/pkg/errors" v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -66,31 +67,35 @@ func NewClient() *Client { testPod10.Labels = make(map[string]string) testPod10.Labels[configuration.LabelPodNetworkInstanceSwiftV2] = podNetwork + testPodMtpncTerminating := v1.Pod{} + testPodMtpncTerminating.Labels = make(map[string]string) + testPodMtpncTerminating.Labels[configuration.LabelPodSwiftV2] = podNetwork + testInterfaceInfos1 := v1alpha1.InterfaceInfo{ - NCID: "testncid", - PrimaryIP: "192.168.0.1/32", - MacAddress: "00:00:00:00:00:00", - GatewayIP: "10.0.0.1", - DeviceType: v1alpha1.DeviceTypeVnetNIC, - AccelnetEnabled: false, + NCID: "testncid", + PrimaryIP: "192.168.0.1/32", + MacAddress: "00:00:00:00:00:00", + GatewayIP: "10.0.0.1", + DeviceType: v1alpha1.DeviceTypeVnetNIC, + AccelnetEnabled: false, SubnetAddressSpace: "192.168.0.0/24", } testInterfaceInfos3 := v1alpha1.InterfaceInfo{ - NCID: "testncid", - PrimaryIP: "192.168.0.1/32", - MacAddress: "00:00:00:00:00:00", - GatewayIP: "10.0.0.1", - DeviceType: v1alpha1.DeviceTypeVnetNIC, - AccelnetEnabled: false, + NCID: "testncid", + PrimaryIP: "192.168.0.1/32", + MacAddress: "00:00:00:00:00:00", + GatewayIP: "10.0.0.1", + DeviceType: v1alpha1.DeviceTypeVnetNIC, + AccelnetEnabled: false, SubnetAddressSpace: "192.168.0.0/24", } testInterfaceInfos5 := v1alpha1.InterfaceInfo{ - NCID: "testncid", - PrimaryIP: "192.168.0.1/32", - MacAddress: "00:00:00:00:00:00", - GatewayIP: "10.0.0.1", - DeviceType: v1alpha1.DeviceTypeInfiniBandNIC, - AccelnetEnabled: true, + NCID: "testncid", + PrimaryIP: "192.168.0.1/32", + MacAddress: "00:00:00:00:00:00", + GatewayIP: "10.0.0.1", + DeviceType: v1alpha1.DeviceTypeInfiniBandNIC, + AccelnetEnabled: true, SubnetAddressSpace: "192.168.0.0/24", } @@ -166,28 +171,38 @@ func NewClient() *Client { Status: v1alpha1.MultitenantPodNetworkConfigStatus{}, } + testMTPNCTerminating := v1alpha1.MultitenantPodNetworkConfig{ + Status: v1alpha1.MultitenantPodNetworkConfigStatus{ + InterfaceInfos: []v1alpha1.InterfaceInfo{testInterfaceInfos1}, + }, + } + now := metav1.Now() + testMTPNCTerminating.DeletionTimestamp = &now + return &Client{ mtPodCache: map[string]*v1.Pod{ - "testpod1namespace/testpod1": &testPod1, - "testpod3namespace/testpod3": &testPod3, - "testpod4namespace/testpod4": &testPod4, - "testpod5namespace/testpod5": &testPod5, - "testpod6namespace/testpod6": &testPod6, - "testpod7namespace/testpod7": &testPod7, - "testpod8namespace/testpod8": &testPod8, - "testpod9namespace/testpod9": &testPod9, - "testpod10namespace/testpod10": &testPod10, + "testpod1namespace/testpod1": &testPod1, + "testpod3namespace/testpod3": &testPod3, + "testpod4namespace/testpod4": &testPod4, + "testpod5namespace/testpod5": &testPod5, + "testpod6namespace/testpod6": &testPod6, + "testpod7namespace/testpod7": &testPod7, + "testpod8namespace/testpod8": &testPod8, + "testpod9namespace/testpod9": &testPod9, + "testpod10namespace/testpod10": &testPod10, + "testpodMtpncTerminatingnamespace/testpodMtpncTerminating": &testPodMtpncTerminating, }, mtpncCache: map[string]*v1alpha1.MultitenantPodNetworkConfig{ - "testpod1namespace/testpod1": &testMTPNC1, - "testpod2namespace/testpod2": &testMTPNC2, - "testpod4namespace/testpod4": &testMTPNC4, - "testpod5namespace/testpod5": &testMTPNC3, - "testpod6namespace/testpod6": &testMTPNC5, - "testpod7namespace/testpod7": &testMTPNCMulti, - "testpod8namespace/testpod8": &testMTPNC8, - "testpod9namespace/testpod9": &testMTPNC9, - "testpod10namespace/testpod10": &testMTPNC10, + "testpod1namespace/testpod1": &testMTPNC1, + "testpod2namespace/testpod2": &testMTPNC2, + "testpod4namespace/testpod4": &testMTPNC4, + "testpod5namespace/testpod5": &testMTPNC3, + "testpod6namespace/testpod6": &testMTPNC5, + "testpod7namespace/testpod7": &testMTPNCMulti, + "testpod8namespace/testpod8": &testMTPNC8, + "testpod9namespace/testpod9": &testMTPNC9, + "testpod10namespace/testpod10": &testMTPNC10, + "testpodMtpncTerminatingnamespace/testpodMtpncTerminating": &testMTPNCTerminating, }, } } @@ -213,12 +228,12 @@ func (c *Client) Get(_ context.Context, key client.ObjectKey, obj client.Object, func (c *Client) SetMTPNCReady() { testInterfaceInfos1 := v1alpha1.InterfaceInfo{ - NCID: "testncid", - PrimaryIP: "192.168.0.1/32", - MacAddress: "00:00:00:00:00:00", - GatewayIP: "10.0.0.1", - DeviceType: v1alpha1.DeviceTypeVnetNIC, - AccelnetEnabled: false, + NCID: "testncid", + PrimaryIP: "192.168.0.1/32", + MacAddress: "00:00:00:00:00:00", + GatewayIP: "10.0.0.1", + DeviceType: v1alpha1.DeviceTypeVnetNIC, + AccelnetEnabled: false, SubnetAddressSpace: "192.168.0.0/24", } diff --git a/crd/multitenancy/api/v1alpha1/utils.go b/crd/multitenancy/api/v1alpha1/utils.go index 49bedd9358..0cd6990ec0 100644 --- a/crd/multitenancy/api/v1alpha1/utils.go +++ b/crd/multitenancy/api/v1alpha1/utils.go @@ -9,3 +9,9 @@ func (m *MultitenantPodNetworkConfig) IsReady() bool { // Check if InterfaceInfos slice is not empty return !reflect.DeepEqual(m.Status, MultitenantPodNetworkConfigStatus{}) } + +// IsDeleting returns true if the MultitenantPodNetworkConfig resource has been marked for deletion. +// A resource is considered to be deleting when its DeletionTimestamp field is set. +func (m *MultitenantPodNetworkConfig) IsDeleting() bool { + return !m.DeletionTimestamp.IsZero() +}