Родитель
e03248d9e5
Коммит
568e3dc177
|
@ -4,6 +4,6 @@ import "github.com/Azure/azure-container-networking/cns"
|
|||
|
||||
// APIClient interface to update cns state
|
||||
type APIClient interface {
|
||||
InitCNSState(*cns.CreateNetworkContainerRequest, map[string]*cns.KubernetesPodInfo) error
|
||||
ReconcileNCState(*cns.CreateNetworkContainerRequest, map[string]cns.KubernetesPodInfo) error
|
||||
CreateOrUpdateNC(cns.CreateNetworkContainerRequest) error
|
||||
}
|
||||
|
|
|
@ -23,12 +23,13 @@ func (client *Client) CreateOrUpdateNC(ncRequest cns.CreateNetworkContainerReque
|
|||
return nil
|
||||
}
|
||||
|
||||
// InitCNSState initializes cns state
|
||||
func (client *Client) InitCNSState(ncRequest *cns.CreateNetworkContainerRequest, podInfoByIP map[string]*cns.KubernetesPodInfo) error {
|
||||
// client.RestService.Lock()
|
||||
// client.RestService.ReadyToIPAM = true
|
||||
// client.RestService.Unlock()
|
||||
// ReconcileNCState initializes cns state
|
||||
func (client *Client) ReconcileNCState(ncRequest *cns.CreateNetworkContainerRequest, podInfoByIP map[string]cns.KubernetesPodInfo) error {
|
||||
returnCode := client.RestService.ReconcileNCState(ncRequest, podInfoByIP)
|
||||
|
||||
if returnCode != 0 {
|
||||
return fmt.Errorf("Failed to Reconcile ncState: ncRequest %+v, podInfoMap: %+v, errorCode: %d", *ncRequest, podInfoByIP, returnCode)
|
||||
}
|
||||
|
||||
// return client.RestService.AddIPConfigsToState(ipConfigs)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -171,9 +171,9 @@ func (crdRC *crdRequestController) initCNS() error {
|
|||
var (
|
||||
pods *corev1.PodList
|
||||
pod corev1.Pod
|
||||
podInfo *cns.KubernetesPodInfo
|
||||
podInfo cns.KubernetesPodInfo
|
||||
nodeNetConfig *nnc.NodeNetworkConfig
|
||||
podInfoByIP map[string]*cns.KubernetesPodInfo
|
||||
podInfoByIP map[string]cns.KubernetesPodInfo
|
||||
cntxt context.Context
|
||||
ncRequest cns.CreateNetworkContainerRequest
|
||||
err error
|
||||
|
@ -191,7 +191,7 @@ func (crdRC *crdRequestController) initCNS() error {
|
|||
|
||||
// If instance of crd is not found, pass nil to CNSClient
|
||||
if client.IgnoreNotFound(err) == nil {
|
||||
return crdRC.CNSClient.InitCNSState(nil, nil)
|
||||
return crdRC.CNSClient.ReconcileNCState(nil, nil)
|
||||
}
|
||||
|
||||
// If it's any other error, log it and return
|
||||
|
@ -201,7 +201,7 @@ func (crdRC *crdRequestController) initCNS() error {
|
|||
|
||||
// If there are no NCs, pass nil to CNSClient
|
||||
if len(nodeNetConfig.Status.NetworkContainers) == 0 {
|
||||
return crdRC.CNSClient.InitCNSState(nil, nil)
|
||||
return crdRC.CNSClient.ReconcileNCState(nil, nil)
|
||||
}
|
||||
|
||||
// Convert to CreateNetworkContainerRequest
|
||||
|
@ -218,11 +218,11 @@ func (crdRC *crdRequestController) initCNS() error {
|
|||
|
||||
// Convert pod list to map of pod ip -> kubernetes pod info
|
||||
if len(pods.Items) != 0 {
|
||||
podInfoByIP = make(map[string]*cns.KubernetesPodInfo)
|
||||
podInfoByIP = make(map[string]cns.KubernetesPodInfo)
|
||||
for _, pod = range pods.Items {
|
||||
//Only add pods that aren't on the host network
|
||||
if !pod.Spec.HostNetwork {
|
||||
podInfo = &cns.KubernetesPodInfo{
|
||||
podInfo = cns.KubernetesPodInfo{
|
||||
PodName: pod.Name,
|
||||
PodNamespace: pod.Namespace,
|
||||
}
|
||||
|
@ -231,7 +231,9 @@ func (crdRC *crdRequestController) initCNS() error {
|
|||
}
|
||||
}
|
||||
|
||||
return crdRC.CNSClient.InitCNSState(&ncRequest, podInfoByIP)
|
||||
// Call cnsclient init cns passing those two things
|
||||
return crdRC.CNSClient.ReconcileNCState(&ncRequest, podInfoByIP)
|
||||
|
||||
}
|
||||
|
||||
// UpdateCRDSpec updates the CRD spec
|
||||
|
|
|
@ -93,7 +93,7 @@ func (mc MockKubeClient) Update(ctx context.Context, obj runtime.Object, opts ..
|
|||
type MockCNSClient struct {
|
||||
MockCNSUpdated bool
|
||||
MockCNSInitialized bool
|
||||
Pods map[string]*cns.KubernetesPodInfo
|
||||
Pods map[string]cns.KubernetesPodInfo
|
||||
NCRequest *cns.CreateNetworkContainerRequest
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ func (mi *MockCNSClient) CreateOrUpdateNC(ncRequest cns.CreateNetworkContainerRe
|
|||
return nil
|
||||
}
|
||||
|
||||
func (mi *MockCNSClient) InitCNSState(ncRequest *cns.CreateNetworkContainerRequest, podInfoByIP map[string]*cns.KubernetesPodInfo) error {
|
||||
func (mi *MockCNSClient) ReconcileNCState(ncRequest *cns.CreateNetworkContainerRequest, podInfoByIP map[string]cns.KubernetesPodInfo) error {
|
||||
mi.MockCNSInitialized = true
|
||||
mi.Pods = podInfoByIP
|
||||
mi.NCRequest = ncRequest
|
||||
|
|
|
@ -99,29 +99,7 @@ func TestMain(m *testing.M) {
|
|||
logger.InitLogger("testlogs", 0, 0, "./")
|
||||
|
||||
// Create the service.
|
||||
config := common.ServiceConfig{}
|
||||
service, err = NewHTTPRestService(&config)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to create CNS object %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
svc = service.(*HTTPRestService)
|
||||
svc.Name = "cns-test-server"
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to create CNS object, err:%v.\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if service != nil {
|
||||
err = service.Start(&config)
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to start CNS, err:%v.\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Get the internal http mux as test hook.
|
||||
mux = service.(*HTTPRestService).Listener.GetMux()
|
||||
startService()
|
||||
|
||||
// Setup mock nmagent server
|
||||
u, err := url.Parse("tcp://" + nmagentEndpoint)
|
||||
|
@ -276,34 +254,34 @@ func TestGetNetworkContainerByOrchestratorContext(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetNetworkContainerStatus(t *testing.T) {
|
||||
// requires more than 30 seconds to run
|
||||
fmt.Println("Test: TestCreateNetworkContainer")
|
||||
// func TestGetNetworkContainerStatus(t *testing.T) {
|
||||
// // requires more than 30 seconds to run
|
||||
// fmt.Println("Test: TestCreateNetworkContainer")
|
||||
|
||||
setEnv(t)
|
||||
setOrchestratorType(t, cns.Kubernetes)
|
||||
// setEnv(t)
|
||||
// setOrchestratorType(t, cns.Kubernetes)
|
||||
|
||||
err := creatOrUpdateNetworkContainerWithName(t, "ethWebApp", "11.0.0.5", cns.AzureContainerInstance)
|
||||
if err != nil {
|
||||
t.Errorf("creatOrUpdateWebAppContainerWithName failed Err:%+v", err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
// err := creatOrUpdateNetworkContainerWithName(t, "ethWebApp", "11.0.0.5", cns.AzureContainerInstance)
|
||||
// if err != nil {
|
||||
// t.Errorf("creatOrUpdateWebAppContainerWithName failed Err:%+v", err)
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
|
||||
fmt.Println("Now calling getNetworkContainerStatus")
|
||||
err = getNetworkContainerStatus(t, "ethWebApp")
|
||||
if err != nil {
|
||||
t.Errorf("getNetworkContainerStatus failed Err:%+v", err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
// fmt.Println("Now calling getNetworkContainerStatus")
|
||||
// err = getNetworkContainerStatus(t, "ethWebApp")
|
||||
// if err != nil {
|
||||
// t.Errorf("getNetworkContainerStatus failed Err:%+v", err)
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
|
||||
fmt.Println("Now calling DeleteNetworkContainer")
|
||||
// fmt.Println("Now calling DeleteNetworkContainer")
|
||||
|
||||
err = deleteNetworkAdapterWithName(t, "ethWebApp")
|
||||
if err != nil {
|
||||
t.Errorf("Deleting interface failed Err:%+v", err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
// err = deleteNetworkAdapterWithName(t, "ethWebApp")
|
||||
// if err != nil {
|
||||
// t.Errorf("Deleting interface failed Err:%+v", err)
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
// }
|
||||
|
||||
func TestGetInterfaceForNetworkContainer(t *testing.T) {
|
||||
// requires more than 30 seconds to run
|
||||
|
@ -674,6 +652,34 @@ func setEnv(t *testing.T) *httptest.ResponseRecorder {
|
|||
return w
|
||||
}
|
||||
|
||||
func startService() {
|
||||
var err error
|
||||
// Create the service.
|
||||
config := common.ServiceConfig{}
|
||||
service, err = NewHTTPRestService(&config)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to create CNS object %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
svc = service.(*HTTPRestService)
|
||||
svc.Name = "cns-test-server"
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to create CNS object, err:%v.\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if service != nil {
|
||||
err = service.Start(&config)
|
||||
if err != nil {
|
||||
logger.Errorf("Failed to start CNS, err:%v.\n", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Get the internal http mux as test hook.
|
||||
mux = service.(*HTTPRestService).Listener.GetMux()
|
||||
}
|
||||
|
||||
// IGNORE TEST AS IT IS FAILING. TODO:- Fix it https://msazure.visualstudio.com/One/_workitems/edit/7720083
|
||||
// // Tests CreateNetwork functionality.
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ const (
|
|||
InconsistentIPConfigState = 29
|
||||
InvalidSecondaryIPConfig = 30
|
||||
NetworkContainerPendingStatePropagation = 31
|
||||
FailedToAllocateIpConfig = 32
|
||||
UnexpectedError = 99
|
||||
)
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/Azure/azure-container-networking/cns/logger"
|
||||
"github.com/Azure/azure-container-networking/cns/nmagentclient"
|
||||
"github.com/Azure/azure-container-networking/common"
|
||||
"github.com/Azure/azure-container-networking/log"
|
||||
)
|
||||
|
||||
// This file contains the internal functions called by either HTTP APIs (api.go) or
|
||||
|
@ -149,6 +150,54 @@ func (service *HTTPRestService) SyncNodeStatus(dncEP, infraVnet, nodeID string,
|
|||
return
|
||||
}
|
||||
|
||||
// This API will be called by CNS RequestController on CRD update.
|
||||
func (service *HTTPRestService) ReconcileNCState(ncRequest *cns.CreateNetworkContainerRequest, podInfoByIp map[string]cns.KubernetesPodInfo) int {
|
||||
// check if ncRequest is null, then return as there is no CRD state yet
|
||||
if ncRequest == nil {
|
||||
log.Logf("CNS starting with no NC state, podInfoMap count %d", len(podInfoByIp))
|
||||
return Success
|
||||
}
|
||||
|
||||
returnCode := service.CreateOrUpdateNetworkContainerInternal(*ncRequest)
|
||||
|
||||
// If the NC was created successfully, then reconcile the allocated pod state
|
||||
if returnCode != Success {
|
||||
return returnCode
|
||||
}
|
||||
|
||||
// now parse the secondaryIP list, if it exists in PodInfo list, then allocate that ip
|
||||
for _, secIpConfig := range ncRequest.SecondaryIPConfigs {
|
||||
if podInfo, exists := podInfoByIp[secIpConfig.IPSubnet.IPAddress]; exists {
|
||||
log.Logf("SecondaryIP %+v is allocated to Pod. %+v, ncId: %s", secIpConfig, podInfo, ncRequest.NetworkContainerid)
|
||||
|
||||
desiredIPConfig := cns.IPSubnet{
|
||||
IPAddress: secIpConfig.IPSubnet.IPAddress,
|
||||
PrefixLength: secIpConfig.IPSubnet.PrefixLength,
|
||||
}
|
||||
|
||||
kubernetesPodInfo := cns.KubernetesPodInfo{
|
||||
PodName: podInfo.PodName,
|
||||
PodNamespace: podInfo.PodNamespace,
|
||||
}
|
||||
jsonContext, _ := json.Marshal(kubernetesPodInfo)
|
||||
|
||||
ipconfigRequest := cns.GetIPConfigRequest{
|
||||
DesiredIPConfig: desiredIPConfig,
|
||||
OrchestratorContext: jsonContext,
|
||||
}
|
||||
|
||||
if _, err := requestIPConfigHelper(service, ipconfigRequest); err != nil {
|
||||
log.Errorf("AllocateIPConfig failed for SecondaryIP %+v, podInfo %+v, ncId %s, error: %v", secIpConfig, podInfo, ncRequest.NetworkContainerid, err)
|
||||
return FailedToAllocateIpConfig
|
||||
}
|
||||
} else {
|
||||
log.Logf("SecondaryIP %+v is not allocated. ncId: %s", secIpConfig, ncRequest.NetworkContainerid)
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// This API will be called by CNS RequestController on CRD update.
|
||||
func (service *HTTPRestService) CreateOrUpdateNetworkContainerInternal(req cns.CreateNetworkContainerRequest) int {
|
||||
if req.NetworkContainerid == "" {
|
||||
|
|
|
@ -4,22 +4,24 @@
|
|||
package restserver
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/azure-container-networking/cns"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const (
|
||||
primaryIp = "10.0.0.5"
|
||||
gatewayIp = "10.0.0.1"
|
||||
primaryIp = "10.0.0.5"
|
||||
gatewayIp = "10.0.0.1"
|
||||
dockerContainerType = cns.Docker
|
||||
)
|
||||
|
||||
func TestCreateOrUpdateNetworkContainerInternal(t *testing.T) {
|
||||
fmt.Println("Test: TestCreateOrUpdateNetworkContainerInternal")
|
||||
restartService()
|
||||
|
||||
setEnv(t)
|
||||
setOrchestratorTypeInternal(cns.KubernetesCRD)
|
||||
|
@ -27,6 +29,97 @@ func TestCreateOrUpdateNetworkContainerInternal(t *testing.T) {
|
|||
validateCreateOrUpdateNCInternal(t, 2)
|
||||
}
|
||||
|
||||
func TestReconcileNCWithEmptyState(t *testing.T) {
|
||||
restartService()
|
||||
setEnv(t)
|
||||
setOrchestratorTypeInternal(cns.KubernetesCRD)
|
||||
|
||||
expectedNcCount := len(svc.state.ContainerStatus)
|
||||
expectedAllocatedPods := make(map[string]cns.KubernetesPodInfo)
|
||||
returnCode := svc.ReconcileNCState(nil, expectedAllocatedPods)
|
||||
if returnCode != Success {
|
||||
t.Errorf("Unexpected failure on reconcile with no state %d", returnCode)
|
||||
}
|
||||
|
||||
validateNCStateAfterReconcile(t, nil, expectedNcCount, expectedAllocatedPods)
|
||||
}
|
||||
|
||||
func TestReconcileNCWithExistingState(t *testing.T) {
|
||||
restartService()
|
||||
setEnv(t)
|
||||
setOrchestratorTypeInternal(cns.KubernetesCRD)
|
||||
|
||||
secondaryIPConfigs := make(map[string]cns.SecondaryIPConfig)
|
||||
|
||||
var startingIndex = 6
|
||||
for i := 0; i < 4; i++ {
|
||||
ipaddress := "10.0.0." + strconv.Itoa(startingIndex)
|
||||
secIpConfig := newSecondaryIPConfig(ipaddress, 32)
|
||||
ipId := uuid.New()
|
||||
secondaryIPConfigs[ipId.String()] = secIpConfig
|
||||
startingIndex++
|
||||
}
|
||||
req := generateNetworkContainerRequest(secondaryIPConfigs, "reconcileNc1")
|
||||
|
||||
expectedAllocatedPods := make(map[string]cns.KubernetesPodInfo)
|
||||
expectedAllocatedPods["10.0.0.6"] = cns.KubernetesPodInfo{
|
||||
PodName: "reconcilePod1",
|
||||
PodNamespace: "PodNS1",
|
||||
}
|
||||
|
||||
expectedAllocatedPods["10.0.0.7"] = cns.KubernetesPodInfo{
|
||||
PodName: "reconcilePod2",
|
||||
PodNamespace: "PodNS1",
|
||||
}
|
||||
|
||||
expectedNcCount := len(svc.state.ContainerStatus)
|
||||
returnCode := svc.ReconcileNCState(&req, expectedAllocatedPods)
|
||||
if returnCode != Success {
|
||||
t.Errorf("Unexpected failure on reconcile with no state %d", returnCode)
|
||||
}
|
||||
|
||||
validateNCStateAfterReconcile(t, &req, expectedNcCount+1, expectedAllocatedPods)
|
||||
}
|
||||
|
||||
func TestReconcileNCWithSystemPods(t *testing.T) {
|
||||
restartService()
|
||||
setEnv(t)
|
||||
setOrchestratorTypeInternal(cns.KubernetesCRD)
|
||||
|
||||
secondaryIPConfigs := make(map[string]cns.SecondaryIPConfig)
|
||||
|
||||
var startingIndex = 6
|
||||
for i := 0; i < 4; i++ {
|
||||
ipaddress := "10.0.0." + strconv.Itoa(startingIndex)
|
||||
secIpConfig := newSecondaryIPConfig(ipaddress, 32)
|
||||
ipId := uuid.New()
|
||||
secondaryIPConfigs[ipId.String()] = secIpConfig
|
||||
startingIndex++
|
||||
}
|
||||
req := generateNetworkContainerRequest(secondaryIPConfigs, uuid.New().String())
|
||||
|
||||
expectedAllocatedPods := make(map[string]cns.KubernetesPodInfo)
|
||||
expectedAllocatedPods["10.0.0.6"] = cns.KubernetesPodInfo{
|
||||
PodName: "customerpod1",
|
||||
PodNamespace: "PodNS1",
|
||||
}
|
||||
|
||||
// Allocate non-vnet IP for system pod
|
||||
expectedAllocatedPods["192.168.0.1"] = cns.KubernetesPodInfo{
|
||||
PodName: "systempod",
|
||||
PodNamespace: "kube-system",
|
||||
}
|
||||
|
||||
expectedNcCount := len(svc.state.ContainerStatus)
|
||||
returnCode := svc.ReconcileNCState(&req, expectedAllocatedPods)
|
||||
if returnCode != Success {
|
||||
t.Errorf("Unexpected failure on reconcile with no state %d", returnCode)
|
||||
}
|
||||
|
||||
delete(expectedAllocatedPods, "192.168.0.1")
|
||||
validateNCStateAfterReconcile(t, &req, expectedNcCount, expectedAllocatedPods)
|
||||
}
|
||||
|
||||
func setOrchestratorTypeInternal(orchestratorType string) {
|
||||
fmt.Println("setOrchestratorTypeInternal")
|
||||
svc.state.OrchestratorType = orchestratorType
|
||||
|
@ -34,6 +127,7 @@ func setOrchestratorTypeInternal(orchestratorType string) {
|
|||
|
||||
func validateCreateOrUpdateNCInternal(t *testing.T, secondaryIpCount int) {
|
||||
secondaryIPConfigs := make(map[string]cns.SecondaryIPConfig)
|
||||
ncId := "testNc1"
|
||||
|
||||
var startingIndex = 6
|
||||
for i := 0; i < secondaryIpCount; i++ {
|
||||
|
@ -43,8 +137,8 @@ func validateCreateOrUpdateNCInternal(t *testing.T, secondaryIpCount int) {
|
|||
secondaryIPConfigs[ipId.String()] = secIpConfig
|
||||
startingIndex++
|
||||
}
|
||||
|
||||
createAndValidateNCRequest(t, secondaryIPConfigs)
|
||||
|
||||
createAndValidateNCRequest(t, secondaryIPConfigs, ncId)
|
||||
|
||||
// now Validate Update, add more secondaryIpConfig and it should handle the update
|
||||
fmt.Println("Validate Scaleup")
|
||||
|
@ -56,7 +150,7 @@ func validateCreateOrUpdateNCInternal(t *testing.T, secondaryIpCount int) {
|
|||
startingIndex++
|
||||
}
|
||||
|
||||
createAndValidateNCRequest(t, secondaryIPConfigs)
|
||||
createAndValidateNCRequest(t, secondaryIPConfigs, ncId)
|
||||
|
||||
// now Scale down, delete 3 ipaddresses from secondaryIpConfig req
|
||||
fmt.Println("Validate Scale down")
|
||||
|
@ -70,7 +164,7 @@ func validateCreateOrUpdateNCInternal(t *testing.T, secondaryIpCount int) {
|
|||
}
|
||||
}
|
||||
|
||||
createAndValidateNCRequest(t, secondaryIPConfigs)
|
||||
createAndValidateNCRequest(t, secondaryIPConfigs, ncId)
|
||||
|
||||
// Cleanup all SecondaryIps
|
||||
fmt.Println("Validate no SecondaryIpconfigs")
|
||||
|
@ -78,20 +172,20 @@ func validateCreateOrUpdateNCInternal(t *testing.T, secondaryIpCount int) {
|
|||
delete(secondaryIPConfigs, ipid)
|
||||
}
|
||||
|
||||
createAndValidateNCRequest(t, secondaryIPConfigs)
|
||||
createAndValidateNCRequest(t, secondaryIPConfigs, ncId)
|
||||
}
|
||||
|
||||
func createAndValidateNCRequest(t *testing.T, secondaryIPConfigs map[string]cns.SecondaryIPConfig) {
|
||||
req := generateNetworkContainerRequest(secondaryIPConfigs)
|
||||
func createAndValidateNCRequest(t *testing.T, secondaryIPConfigs map[string]cns.SecondaryIPConfig, ncId string) {
|
||||
req := generateNetworkContainerRequest(secondaryIPConfigs, ncId)
|
||||
returnCode := svc.CreateOrUpdateNetworkContainerInternal(req)
|
||||
if returnCode != 0 {
|
||||
t.Fatalf("Failed to createNetworkContainerRequest, req: %+v, err: %d", req, returnCode)
|
||||
}
|
||||
validateNetworkRequest(t, req)
|
||||
validateNetworkRequest(t, req, false)
|
||||
}
|
||||
|
||||
// Validate the networkRequest is persisted.
|
||||
func validateNetworkRequest(t *testing.T, req cns.CreateNetworkContainerRequest) {
|
||||
func validateNetworkRequest(t *testing.T, req cns.CreateNetworkContainerRequest, skipAvailableCheck bool) {
|
||||
containerStatus := svc.state.ContainerStatus[req.NetworkContainerid]
|
||||
|
||||
if containerStatus.ID != req.NetworkContainerid {
|
||||
|
@ -103,7 +197,7 @@ func validateNetworkRequest(t *testing.T, req cns.CreateNetworkContainerRequest)
|
|||
t.Fatalf("Failed as ContainerTyper doesnt match, expected:%s, actual %s", req.NetworkContainerType, actualReq.NetworkContainerType)
|
||||
}
|
||||
|
||||
if actualReq.IPConfiguration.IPSubnet.IPAddress != req.IPConfiguration.IPSubnet.IPAddress {
|
||||
if actualReq.IPConfiguration.IPSubnet.IPAddress != req.IPConfiguration.IPSubnet.IPAddress {
|
||||
t.Fatalf("Failed as Primary IPAddress doesnt match, expected:%s, actual %s", req.IPConfiguration.IPSubnet.IPAddress, actualReq.IPConfiguration.IPSubnet.IPAddress)
|
||||
}
|
||||
|
||||
|
@ -123,7 +217,8 @@ func validateNetworkRequest(t *testing.T, req cns.CreateNetworkContainerRequest)
|
|||
}
|
||||
|
||||
// Validate IP state
|
||||
if ipStatus.State != cns.Available {
|
||||
if !skipAvailableCheck &&
|
||||
ipStatus.State != cns.Available {
|
||||
t.Fatalf("IPId: %s State is not Available, ipStatus: %+v", ipid, ipStatus)
|
||||
}
|
||||
|
||||
|
@ -138,8 +233,8 @@ func validateNetworkRequest(t *testing.T, req cns.CreateNetworkContainerRequest)
|
|||
}
|
||||
}
|
||||
|
||||
func generateNetworkContainerRequest(secondaryIps map[string]cns.SecondaryIPConfig) cns.CreateNetworkContainerRequest{
|
||||
var ipConfig cns.IPConfiguration
|
||||
func generateNetworkContainerRequest(secondaryIps map[string]cns.SecondaryIPConfig, ncId string) cns.CreateNetworkContainerRequest {
|
||||
var ipConfig cns.IPConfiguration
|
||||
ipConfig.DNSServers = []string{"8.8.8.8", "8.8.4.4"}
|
||||
ipConfig.GatewayIPAddress = gatewayIp
|
||||
var ipSubnet cns.IPSubnet
|
||||
|
@ -148,9 +243,9 @@ func generateNetworkContainerRequest(secondaryIps map[string]cns.SecondaryIPConf
|
|||
ipConfig.IPSubnet = ipSubnet
|
||||
|
||||
req := cns.CreateNetworkContainerRequest{
|
||||
NetworkContainerType: dockerContainerType,
|
||||
NetworkContainerid: "testNcId1",
|
||||
IPConfiguration: ipConfig,
|
||||
NetworkContainerType: dockerContainerType,
|
||||
NetworkContainerid: ncId,
|
||||
IPConfiguration: ipConfig,
|
||||
}
|
||||
|
||||
req.SecondaryIPConfigs = make(map[string]cns.SecondaryIPConfig)
|
||||
|
@ -158,5 +253,74 @@ func generateNetworkContainerRequest(secondaryIps map[string]cns.SecondaryIPConf
|
|||
req.SecondaryIPConfigs[k] = v
|
||||
}
|
||||
|
||||
fmt.Printf("NC Request %+v", req)
|
||||
|
||||
return req
|
||||
}
|
||||
}
|
||||
|
||||
func validateNCStateAfterReconcile(t *testing.T, ncRequest *cns.CreateNetworkContainerRequest, expectedNcCount int, expectedAllocatedPods map[string]cns.KubernetesPodInfo) {
|
||||
if ncRequest == nil {
|
||||
// check svc ContainerStatus will be empty
|
||||
if len(svc.state.ContainerStatus) != expectedNcCount {
|
||||
t.Fatalf("CNS has some stale ContainerStatus, count: %d, state: %+v", len(svc.state.ContainerStatus), svc.state.ContainerStatus)
|
||||
}
|
||||
} else {
|
||||
validateNetworkRequest(t, *ncRequest, true)
|
||||
}
|
||||
|
||||
if len(expectedAllocatedPods) != len(svc.PodIPIDByOrchestratorContext) {
|
||||
t.Fatalf("Unexpected allocated pods, actual: %d, expected: %d", len(svc.PodIPIDByOrchestratorContext), len(expectedAllocatedPods))
|
||||
}
|
||||
|
||||
for ipaddress, podInfo := range expectedAllocatedPods {
|
||||
ipId := svc.PodIPIDByOrchestratorContext[podInfo.GetOrchestratorContextKey()]
|
||||
ipConfigstate := svc.PodIPConfigState[ipId]
|
||||
|
||||
if ipConfigstate.State != cns.Allocated {
|
||||
t.Fatalf("IpAddress %s is not marked as allocated for Pod: %+v, ipState: %+v", ipaddress, podInfo, ipConfigstate)
|
||||
}
|
||||
|
||||
// Validate if IPAddress matches
|
||||
if ipConfigstate.IPSubnet.IPAddress != ipaddress {
|
||||
t.Fatalf("IpAddress %s is not same, for Pod: %+v, actual ipState: %+v", ipaddress, podInfo, ipConfigstate)
|
||||
}
|
||||
|
||||
// Valdate pod context
|
||||
var expectedPodInfo cns.KubernetesPodInfo
|
||||
json.Unmarshal(ipConfigstate.OrchestratorContext, &expectedPodInfo)
|
||||
if reflect.DeepEqual(expectedPodInfo, podInfo) != true {
|
||||
t.Fatalf("OrchestrationContext: is not same, expected: %+v, actual %+v", expectedPodInfo, podInfo)
|
||||
}
|
||||
|
||||
// Validate this IP belongs to a valid NCRequest
|
||||
nc := svc.state.ContainerStatus[ipConfigstate.NCID]
|
||||
if _, exists := nc.CreateNetworkContainerRequest.SecondaryIPConfigs[ipConfigstate.ID]; !exists {
|
||||
t.Fatalf("Secondary IP config doest exist in NC, ncid: %s, ipId %s", ipConfigstate.NCID, ipConfigstate.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// validate rest of Secondary IPs in Available state
|
||||
if ncRequest != nil {
|
||||
for secIpId, secIpConfig := range ncRequest.SecondaryIPConfigs {
|
||||
if _, exists := expectedAllocatedPods[secIpConfig.IPSubnet.IPAddress]; exists {
|
||||
continue
|
||||
}
|
||||
|
||||
// Validate IP state
|
||||
if secIpConfigState, found := svc.PodIPConfigState[secIpId]; found {
|
||||
if secIpConfigState.State != cns.Available {
|
||||
t.Fatalf("IPId: %s State is not Available, ipStatus: %+v", secIpId, secIpConfigState)
|
||||
}
|
||||
} else {
|
||||
t.Fatalf("IPId: %s, IpAddress: %+v State doesnt exists in PodIp Map", secIpId, secIpConfig)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func restartService() {
|
||||
fmt.Println("Restart Service")
|
||||
|
||||
service.Stop()
|
||||
startService()
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ func (service *HTTPRestService) requestIPConfigHandler(w http.ResponseWriter, r
|
|||
|
||||
// retrieve ipconfig from nc
|
||||
if ipState, err = requestIPConfigHelper(service, ipconfigRequest); err != nil {
|
||||
returnCode = UnexpectedError
|
||||
returnCode = FailedToAllocateIpConfig
|
||||
returnMessage = fmt.Sprintf("AllocateIPConfig failed: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -217,7 +217,11 @@ func (service *HTTPRestService) updateIpConfigsStateUntransacted(req cns.CreateN
|
|||
if exists {
|
||||
// pod ip exists, validate if state is not allocated, else fail
|
||||
if ipConfigStatus.State == cns.Allocated {
|
||||
errMsg := fmt.Sprintf("Failed to delete an Allocated IP %v", ipConfigStatus)
|
||||
var expectedPodInfo cns.KubernetesPodInfo
|
||||
if len(ipConfigStatus.OrchestratorContext) != 0 {
|
||||
json.Unmarshal(ipConfigStatus.OrchestratorContext, &expectedPodInfo)
|
||||
}
|
||||
errMsg := fmt.Sprintf("Failed to delete an Allocated IP %v, PodInfo %+v", ipConfigStatus, expectedPodInfo)
|
||||
return InconsistentIPConfigState, errMsg
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче