diff --git a/Makefile b/Makefile index 61c94cd7c3..0d94b03661 100644 --- a/Makefile +++ b/Makefile @@ -51,6 +51,7 @@ CNSFILES = \ $(wildcard cns/networkcontainers/*.go) \ $(wildcard cns/requestcontroller/*.go) \ $(wildcard cns/requestcontroller/kubecontroller/*.go) \ + $(wildcard cns/fakes/*.go) \ $(COREFILES) \ $(CNMFILES) diff --git a/cns/NetworkContainerContract.go b/cns/NetworkContainerContract.go index 8b8b12fe32..bbb7e91508 100644 --- a/cns/NetworkContainerContract.go +++ b/cns/NetworkContainerContract.go @@ -207,7 +207,8 @@ type PodIpInfo struct { // DeleteNetworkContainerRequest specifies the details about the request to delete a specifc network container. type HostIPInfo struct { - IPConfig IPSubnet + PrimaryIP string + Subnet string } // DeleteNetworkContainerRequest specifies the details about the request to delete a specifc network container. diff --git a/cns/cnsclient/cnsclient_test.go b/cns/cnsclient/cnsclient_test.go index df58661ebc..fb49b0d9cd 100644 --- a/cns/cnsclient/cnsclient_test.go +++ b/cns/cnsclient/cnsclient_test.go @@ -14,6 +14,7 @@ import ( "github.com/Azure/azure-container-networking/cns" "github.com/Azure/azure-container-networking/cns/common" + "github.com/Azure/azure-container-networking/cns/fakes" "github.com/Azure/azure-container-networking/cns/logger" "github.com/Azure/azure-container-networking/cns/restserver" "github.com/Azure/azure-container-networking/log" @@ -117,7 +118,7 @@ func TestMain(m *testing.M) { logger.InitLogger(logName, 0, 0, tmpLogDir+"/") config := common.ServiceConfig{} - httpRestService, err := restserver.NewHTTPRestService(&config) + httpRestService, err := restserver.NewHTTPRestService(&config, fakes.NewFakeImdsClient()) svc = httpRestService.(*restserver.HTTPRestService) svc.Name = "cns-test-server" if err != nil { diff --git a/cns/dockerclient/dockerclient.go b/cns/dockerclient/dockerclient.go index cd67ed0c17..ac4ab06a1d 100644 --- a/cns/dockerclient/dockerclient.go +++ b/cns/dockerclient/dockerclient.go @@ -25,19 +25,19 @@ const ( // DockerClient specifies a client to connect to docker. type DockerClient struct { connectionURL string - imdsClient *imdsclient.ImdsClient + imdsClient imdsclient.ImdsClientInterface } // NewDockerClient create a new docker client. func NewDockerClient(url string) (*DockerClient, error) { return &DockerClient{ connectionURL: url, - imdsClient: &imdsclient.ImdsClient{}, + imdsClient: new(imdsclient.ImdsClient), }, nil } // NewDefaultDockerClient create a new docker client. -func NewDefaultDockerClient(imdsClient *imdsclient.ImdsClient) (*DockerClient, error) { +func NewDefaultDockerClient(imdsClient imdsclient.ImdsClientInterface) (*DockerClient, error) { return &DockerClient{ connectionURL: defaultDockerConnectionURL, imdsClient: imdsClient, diff --git a/cns/fakes/imdsclientfake.go b/cns/fakes/imdsclientfake.go new file mode 100644 index 0000000000..e2e9413af8 --- /dev/null +++ b/cns/fakes/imdsclientfake.go @@ -0,0 +1,49 @@ +// Copyright 2017 Microsoft. All rights reserved. +// MIT License + +package fakes + +import ( + "github.com/Azure/azure-container-networking/cns/imdsclient" + "github.com/Azure/azure-container-networking/cns/logger" +) + +var ( + HostPrimaryIpTest = "10.0.0.4" + HostSubnetTest = "10.0.0.0/24" +) + +// ImdsClient can be used to connect to VM Host agent in Azure. +type ImdsClientTest struct { +} + +func NewFakeImdsClient() *ImdsClientTest { + return &ImdsClientTest{} +} + +// GetNetworkContainerInfoFromHost- Mock implementation to return Container version info. +func (imdsClient *ImdsClientTest) GetNetworkContainerInfoFromHost(networkContainerID string, primaryAddress string, authToken string, apiVersion string) (*imdsclient.ContainerVersion, error) { + + ret := &imdsclient.ContainerVersion{} + + return ret, nil +} + +// GetPrimaryInterfaceInfoFromHost - Mock implementation to return Host interface info +func (imdsClient *ImdsClientTest) GetPrimaryInterfaceInfoFromHost() (*imdsclient.InterfaceInfo, error) { + logger.Printf("[Azure CNS] GetPrimaryInterfaceInfoFromHost") + + interfaceInfo := &imdsclient.InterfaceInfo{ + Subnet: HostSubnetTest, + PrimaryIP: HostPrimaryIpTest, + } + + return interfaceInfo, nil +} + +// GetPrimaryInterfaceInfoFromMemory - Mock implementation to return host interface info +func (imdsClient *ImdsClientTest) GetPrimaryInterfaceInfoFromMemory() (*imdsclient.InterfaceInfo, error) { + logger.Printf("[Azure CNS] GetPrimaryInterfaceInfoFromMemory") + + return imdsClient.GetPrimaryInterfaceInfoFromHost() +} diff --git a/cns/imdsclient/api.go b/cns/imdsclient/api.go index 3c8bebd3ca..0af765f07c 100644 --- a/cns/imdsclient/api.go +++ b/cns/imdsclient/api.go @@ -68,3 +68,10 @@ type ContainerVersion struct { NetworkContainerID string ProgrammedVersion string } + +// An ImdsInterface performs CRUD operations on IP reservations +type ImdsClientInterface interface { + GetNetworkContainerInfoFromHost(networkContainerID string, primaryAddress string, authToken string, apiVersion string) (*ContainerVersion, error) + GetPrimaryInterfaceInfoFromHost() (*InterfaceInfo, error) + GetPrimaryInterfaceInfoFromMemory() (*InterfaceInfo, error) +} diff --git a/cns/restserver/api_test.go b/cns/restserver/api_test.go index 6bb9f86b8d..8ab654ad7f 100644 --- a/cns/restserver/api_test.go +++ b/cns/restserver/api_test.go @@ -17,6 +17,7 @@ import ( "github.com/Azure/azure-container-networking/cns" "github.com/Azure/azure-container-networking/cns/common" + "github.com/Azure/azure-container-networking/cns/fakes" "github.com/Azure/azure-container-networking/cns/logger" acncommon "github.com/Azure/azure-container-networking/common" ) @@ -656,7 +657,7 @@ func startService() { var err error // Create the service. config := common.ServiceConfig{} - service, err = NewHTTPRestService(&config) + service, err = NewHTTPRestService(&config, fakes.NewFakeImdsClient()) if err != nil { fmt.Printf("Failed to create CNS object %v\n", err) os.Exit(1) diff --git a/cns/restserver/ipam_test.go b/cns/restserver/ipam_test.go index 6e4cc4326f..0f39dcdd64 100644 --- a/cns/restserver/ipam_test.go +++ b/cns/restserver/ipam_test.go @@ -11,6 +11,7 @@ import ( "github.com/Azure/azure-container-networking/cns" "github.com/Azure/azure-container-networking/cns/common" + "github.com/Azure/azure-container-networking/cns/fakes" ) var ( @@ -40,7 +41,7 @@ var ( func getTestService() *HTTPRestService { var config common.ServiceConfig - httpsvc, _ := NewHTTPRestService(&config) + httpsvc, _ := NewHTTPRestService(&config, fakes.NewFakeImdsClient()) svc = httpsvc.(*HTTPRestService) setOrchestratorTypeInternal(cns.KubernetesCRD) @@ -98,6 +99,14 @@ func requestIpAddressAndGetState(t *testing.T, req cns.GetIPConfigRequest) (ipCo t.Fatalf("Pod IP Prefix length is not added as expected ipConfig %+v, expected: %+v", PodIpInfo.PodIPConfig, subnetPrfixLength) } + if reflect.DeepEqual(PodIpInfo.HostPrimaryIPInfo.PrimaryIP, fakes.HostPrimaryIpTest) != true { + t.Fatalf("Host PrimaryIP is not added as expected ipConfig %+v, expected primaryIP: %+v", PodIpInfo.HostPrimaryIPInfo, fakes.HostPrimaryIpTest) + } + + if reflect.DeepEqual(PodIpInfo.HostPrimaryIPInfo.Subnet, fakes.HostSubnetTest) != true { + t.Fatalf("Host Subnet is not added as expected ipConfig %+v, expected Host subnet: %+v", PodIpInfo.HostPrimaryIPInfo, fakes.HostSubnetTest) + } + // retrieve podinfo from orchestrator context if err := json.Unmarshal(req.OrchestratorContext, &podInfo); err != nil { return ipState, err diff --git a/cns/restserver/restserver.go b/cns/restserver/restserver.go index 062750e902..065960ac11 100644 --- a/cns/restserver/restserver.go +++ b/cns/restserver/restserver.go @@ -37,7 +37,7 @@ var ( type HTTPRestService struct { *cns.Service dockerClient *dockerclient.DockerClient - imdsClient *imdsclient.ImdsClient + imdsClient imdsclient.ImdsClientInterface ipamClient *ipamclient.IpamClient networkContainer *networkcontainers.NetworkContainers PodIPIDByOrchestratorContext map[string]string // OrchestratorContext is key and value is Pod IP uuid. @@ -102,16 +102,16 @@ type HTTPService interface { } // NewHTTPRestService creates a new HTTP Service object. -func NewHTTPRestService(config *common.ServiceConfig) (HTTPService, error) { +func NewHTTPRestService(config *common.ServiceConfig, imdsClientInterface imdsclient.ImdsClientInterface) (HTTPService, error) { service, err := cns.NewService(config.Name, config.Version, config.ChannelMode, config.Store) if err != nil { return nil, err } - imdsClient := &imdsclient.ImdsClient{} + imdsClient := imdsClientInterface routingTable := &routes.RoutingTable{} nc := &networkcontainers.NetworkContainers{} - dc, err := dockerclient.NewDefaultDockerClient(imdsClient) + dc, err := dockerclient.NewDefaultDockerClient(imdsClientInterface) if err != nil { return nil, err diff --git a/cns/restserver/util.go b/cns/restserver/util.go index 806763e81b..0fed060471 100644 --- a/cns/restserver/util.go +++ b/cns/restserver/util.go @@ -661,7 +661,13 @@ func (service *HTTPRestService) populateIpConfigInfoUntransacted(ipConfigStatus podIpInfo.NetworkContainerPrimaryIPConfig = primaryIpConfiguration - // TODO Add Host Primary ipinfo + hostInterfaceInfo, err := service.imdsClient.GetPrimaryInterfaceInfoFromMemory() + if err != nil { + return fmt.Errorf("Failed to get the HostInterfaceInfo %s", err) + } + + podIpInfo.HostPrimaryIPInfo.PrimaryIP = hostInterfaceInfo.PrimaryIP + podIpInfo.HostPrimaryIPInfo.Subnet = hostInterfaceInfo.Subnet return nil } diff --git a/cns/service/main.go b/cns/service/main.go index ba6edda866..e4b3c4dfcf 100644 --- a/cns/service/main.go +++ b/cns/service/main.go @@ -23,6 +23,7 @@ import ( "github.com/Azure/azure-container-networking/cns/common" "github.com/Azure/azure-container-networking/cns/configuration" "github.com/Azure/azure-container-networking/cns/hnsclient" + "github.com/Azure/azure-container-networking/cns/imdsclient" "github.com/Azure/azure-container-networking/cns/logger" "github.com/Azure/azure-container-networking/cns/requestcontroller" "github.com/Azure/azure-container-networking/cns/requestcontroller/kubecontroller" @@ -367,7 +368,7 @@ func main() { } // Create CNS object. - httpRestService, err := restserver.NewHTTPRestService(&config) + httpRestService, err := restserver.NewHTTPRestService(&config, new(imdsclient.ImdsClient)) if err != nil { logger.Errorf("Failed to create CNS object, err:%v.\n", err) return