Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions cns/restserver/internalapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,13 +434,19 @@ func (service *HTTPRestService) CreateOrUpdateNetworkContainerInternal(req *cns.
if ok {
existingReq := existingNCInfo.CreateNetworkContainerRequest
if !reflect.DeepEqual(existingReq.IPConfiguration.IPSubnet, req.IPConfiguration.IPSubnet) {
logger.Errorf("[Azure CNS] Error. PrimaryCA is not same, NCId %s, old CA %s/%d, new CA %s/%d",
req.NetworkContainerid,
existingReq.IPConfiguration.IPSubnet.IPAddress,
existingReq.IPConfiguration.IPSubnet.PrefixLength,
req.IPConfiguration.IPSubnet.IPAddress,
req.IPConfiguration.IPSubnet.PrefixLength)
return types.PrimaryCANotSame
// check for potential overlay subnet expansion - checking if new subnet is a superset of old subnet
isCIDRSuperset := validateCIDRSuperset(
fmt.Sprintf("%s/%d", req.IPConfiguration.IPSubnet.IPAddress, req.IPConfiguration.IPSubnet.PrefixLength),
fmt.Sprintf("%s/%d", existingReq.IPConfiguration.IPSubnet.IPAddress, existingReq.IPConfiguration.IPSubnet.PrefixLength))
if !isCIDRSuperset {
logger.Errorf("[Azure CNS] Error. PrimaryCA is not same, NCId %s, old CA %s/%d, new CA %s/%d", //nolint:staticcheck // Suppress SA1019: logger.Errorf is deprecated
req.NetworkContainerid,
existingReq.IPConfiguration.IPSubnet.IPAddress,
existingReq.IPConfiguration.IPSubnet.PrefixLength,
req.IPConfiguration.IPSubnet.IPAddress,
req.IPConfiguration.IPSubnet.PrefixLength)
return types.PrimaryCANotSame
}
}
}

Expand Down
128 changes: 105 additions & 23 deletions cns/restserver/internalapi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,35 +57,117 @@ func TestReconcileNCStatePrimaryIPChangeShouldFail(t *testing.T) {
setOrchestratorTypeInternal(cns.KubernetesCRD)
svc.state.ContainerStatus = make(map[string]containerstatus)

// start with a NC in state
ncID := "555ac5c9-89f2-4b5d-b8d0-616894d6d151"
svc.state.ContainerStatus[ncID] = containerstatus{
ID: ncID,
VMVersion: "0",
HostVersion: "0",
CreateNetworkContainerRequest: cns.CreateNetworkContainerRequest{
NetworkContainerid: ncID,
IPConfiguration: cns.IPConfiguration{
IPSubnet: cns.IPSubnet{
IPAddress: "10.0.1.0",
PrefixLength: 24,
testCases := []struct {
reqIPAddress string
reqPrefixLength uint8
existingIPAddress string
existingPrefixLength uint8
}{
{"10.240.1.0", 16, "10.240.0.0", 16},
{"10.240.0.0", 64, "2001:db8::", 64},
{"2001:db8::", 64, "10.240.0.0", 16},
{"10.0.1.0", 24, "10.0.2.0", 22},
{"10.0.1.0", 23, "10.0.1.0", 21},
}

// Run test cases
for _, tc := range testCases {
// start with a NC in state
ncID := "555ac5c9-89f2-4b5d-b8d0-616894d6d150"
svc.state.ContainerStatus[ncID] = containerstatus{
ID: ncID,
VMVersion: "0",
HostVersion: "0",
CreateNetworkContainerRequest: cns.CreateNetworkContainerRequest{
NetworkContainerid: ncID,
IPConfiguration: cns.IPConfiguration{
IPSubnet: cns.IPSubnet{
IPAddress: tc.existingIPAddress,
PrefixLength: tc.existingPrefixLength,
},
},
},
},
}

ncReqs := []*cns.CreateNetworkContainerRequest{
{
NetworkContainerid: ncID,
IPConfiguration: cns.IPConfiguration{
IPSubnet: cns.IPSubnet{
IPAddress: tc.reqIPAddress,
PrefixLength: tc.reqPrefixLength,
},
},
},
}

// now try to reconcile the state where the NC primary IP has changed
resp := svc.ReconcileIPAMStateForSwift(ncReqs, map[string]cns.PodInfo{}, &v1alpha.NodeNetworkConfig{})

assert.Equal(t, types.PrimaryCANotSame, resp)
}

// now try to reconcile the state where the NC primary IP has changed
resp := svc.ReconcileNCState(&cns.CreateNetworkContainerRequest{
NetworkContainerid: ncID,
IPConfiguration: cns.IPConfiguration{
IPSubnet: cns.IPSubnet{
IPAddress: "10.0.2.0", // note this IP has changed
PrefixLength: 24,
}

// TestReconcileNCStatePrimaryIPChangeShouldNotFail tests that reconciling NC state with
// a NC whose IP has changed should not fail if new IP is superset of old IP
func TestReconcileNCStatePrimaryIPChangeShouldNotFail(t *testing.T) {
restartService()
setEnv(t)
setOrchestratorTypeInternal(cns.KubernetesCRD)
svc.state.ContainerStatus = make(map[string]containerstatus)

testCases := []struct {
reqIPAddress string
reqPrefixLength uint8
existingIPAddress string
existingPrefixLength uint8
}{
{"10.240.0.0", 20, "10.240.0.0", 24},

{"10.0.1.0", 22, "10.0.2.0", 24},
{"10.0.1.0", 18, "10.0.1.0", 20},
{"10.0.1.0", 15, "10.0.0.0", 19},
{"10.0.1.0", 18, "10.0.1.0", 18},
}

// Run test cases
for _, tc := range testCases {
// start with a NC in state
ncID := "555ac5c9-89f2-4b5d-b8d0-616894d6d150"
svc.state.ContainerStatus[ncID] = containerstatus{
ID: ncID,
VMVersion: "0",
HostVersion: "0",
CreateNetworkContainerRequest: cns.CreateNetworkContainerRequest{
NetworkContainerid: ncID,
IPConfiguration: cns.IPConfiguration{
IPSubnet: cns.IPSubnet{
IPAddress: tc.existingIPAddress,
PrefixLength: tc.existingPrefixLength,
},
},
},
},
}, map[string]cns.PodInfo{}, &v1alpha.NodeNetworkConfig{})
}

assert.Equal(t, types.PrimaryCANotSame, resp)
ncReqs := []*cns.CreateNetworkContainerRequest{
{
NetworkContainerid: ncID,
IPConfiguration: cns.IPConfiguration{
IPSubnet: cns.IPSubnet{
IPAddress: tc.reqIPAddress,
PrefixLength: tc.reqPrefixLength,
},
},
NetworkContainerType: cns.Kubernetes,
},
}

// now try to reconcile the state where the NC primary IP has changed
resp := svc.ReconcileIPAMStateForSwift(ncReqs, map[string]cns.PodInfo{}, &v1alpha.NodeNetworkConfig{})

assert.Equal(t, types.Success, resp)
}
}

// TestReconcileNCStateGatewayChange tests that NC state gets updated when reconciled
Expand Down