From 825faf927bae3d8016add27131f7bc0a2e97bbd5 Mon Sep 17 00:00:00 2001 From: paulyufan2 Date: Tue, 19 Mar 2024 17:25:49 -0400 Subject: [PATCH] start two cns servers --- cnm/ipam/ipam.go | 24 +++++----- cnm/plugin.go | 4 +- cns/common/service.go | 15 +++--- cns/restserver/api.go | 93 ++++++++++++++++++------------------ cns/restserver/api_test.go | 27 +++++++++++ cns/restserver/ipam.go | 60 +++++++++++------------ cns/restserver/restserver.go | 18 ++----- cns/restserver/util.go | 10 ++-- cns/service.go | 83 ++++++++++++++++---------------- cns/service/main.go | 13 ++++- common/listener.go | 4 +- 11 files changed, 190 insertions(+), 161 deletions(-) diff --git a/cnm/ipam/ipam.go b/cnm/ipam/ipam.go index ec15b31aaf..4a6d2fec90 100644 --- a/cnm/ipam/ipam.go +++ b/cnm/ipam/ipam.go @@ -118,7 +118,7 @@ func (plugin *ipamPlugin) getCapabilities(w http.ResponseWriter, r *http.Request RequiresRequestReplay: requiresRequestReplay, } - err := plugin.Listener.Encode(w, &resp) + err := common.Encode(w, &resp) log.Response(plugin.Name, &resp, returnCode, returnStr, err) } @@ -135,7 +135,7 @@ func (plugin *ipamPlugin) getDefaultAddressSpaces(w http.ResponseWriter, r *http resp.LocalDefaultAddressSpace = localId resp.GlobalDefaultAddressSpace = globalId - err := plugin.Listener.Encode(w, &resp) + err := common.Encode(w, &resp) log.Response(plugin.Name, &resp, returnCode, returnStr, err) } @@ -145,7 +145,7 @@ func (plugin *ipamPlugin) requestPool(w http.ResponseWriter, r *http.Request) { var req RequestPoolRequest // Decode request. - err := plugin.Listener.Decode(w, r, &req) + err := common.Decode(w, r, &req) log.Request(plugin.Name, &req, err) if err != nil { return @@ -163,7 +163,7 @@ func (plugin *ipamPlugin) requestPool(w http.ResponseWriter, r *http.Request) { poolId = ipam.NewAddressPoolId(req.AddressSpace, poolId, "").String() resp := RequestPoolResponse{PoolID: poolId, Pool: subnet, Data: data} - err = plugin.Listener.Encode(w, &resp) + err = common.Encode(w, &resp) log.Response(plugin.Name, &resp, returnCode, returnStr, err) } @@ -173,7 +173,7 @@ func (plugin *ipamPlugin) releasePool(w http.ResponseWriter, r *http.Request) { var req ReleasePoolRequest // Decode request. - err := plugin.Listener.Decode(w, r, &req) + err := common.Decode(w, r, &req) log.Request(plugin.Name, &req, err) if err != nil { return @@ -195,7 +195,7 @@ func (plugin *ipamPlugin) releasePool(w http.ResponseWriter, r *http.Request) { // Encode response. resp := ReleasePoolResponse{} - err = plugin.Listener.Encode(w, &resp) + err = common.Encode(w, &resp) log.Response(plugin.Name, &resp, returnCode, returnStr, err) } @@ -205,7 +205,7 @@ func (plugin *ipamPlugin) getPoolInfo(w http.ResponseWriter, r *http.Request) { var req GetPoolInfoRequest // Decode request. - err := plugin.Listener.Decode(w, r, &req) + err := common.Decode(w, r, &req) log.Request(plugin.Name, &req, err) if err != nil { return @@ -234,7 +234,7 @@ func (plugin *ipamPlugin) getPoolInfo(w http.ResponseWriter, r *http.Request) { resp.UnhealthyAddresses = append(resp.UnhealthyAddresses, addr.String()) } - err = plugin.Listener.Encode(w, &resp) + err = common.Encode(w, &resp) log.Response(plugin.Name, &resp, returnCode, returnStr, err) } @@ -244,7 +244,7 @@ func (plugin *ipamPlugin) requestAddress(w http.ResponseWriter, r *http.Request) var req RequestAddressRequest // Decode request. - err := plugin.Listener.Decode(w, r, &req) + err := common.Decode(w, r, &req) log.Request(plugin.Name, &req, err) if err != nil { return @@ -275,7 +275,7 @@ func (plugin *ipamPlugin) requestAddress(w http.ResponseWriter, r *http.Request) data := make(map[string]string) resp := RequestAddressResponse{Address: addr, Data: data} - err = plugin.Listener.Encode(w, &resp) + err = common.Encode(w, &resp) log.Response(plugin.Name, &resp, returnCode, returnStr, err) } @@ -285,7 +285,7 @@ func (plugin *ipamPlugin) releaseAddress(w http.ResponseWriter, r *http.Request) var req ReleaseAddressRequest // Decode request. - err := plugin.Listener.Decode(w, r, &req) + err := common.Decode(w, r, &req) log.Request(plugin.Name, &req, err) if err != nil { return @@ -307,7 +307,7 @@ func (plugin *ipamPlugin) releaseAddress(w http.ResponseWriter, r *http.Request) // Encode response. resp := ReleaseAddressResponse{} - err = plugin.Listener.Encode(w, &resp) + err = common.Encode(w, &resp) log.Response(plugin.Name, &resp, returnCode, returnStr, err) } diff --git a/cnm/plugin.go b/cnm/plugin.go index af22dcd1f8..417552920c 100644 --- a/cnm/plugin.go +++ b/cnm/plugin.go @@ -121,7 +121,7 @@ func (plugin *Plugin) activate(w http.ResponseWriter, r *http.Request) { log.Request(plugin.Name, &req, nil) resp := ActivateResponse{Implements: plugin.Listener.GetEndpoints()} - err := plugin.Listener.Encode(w, &resp) + err := common.Encode(w, &resp) log.Response(plugin.Name, &resp, 0, "Success", err) } @@ -129,7 +129,7 @@ func (plugin *Plugin) activate(w http.ResponseWriter, r *http.Request) { // SendErrorResponse sends and logs an error response. func (plugin *Plugin) SendErrorResponse(w http.ResponseWriter, errMsg error) { resp := errorResponse{errMsg.Error()} - err := plugin.Listener.Encode(w, &resp) + err := common.Encode(w, &resp) log.Response(plugin.Name, &resp, 0, "Success", err) } diff --git a/cns/common/service.go b/cns/common/service.go index b621c07d1d..e59cfa3d2e 100644 --- a/cns/common/service.go +++ b/cns/common/service.go @@ -33,13 +33,14 @@ type ServiceAPI interface { // ServiceConfig specifies common configuration. type ServiceConfig struct { - Name string - Version string - Listener *acn.Listener - ErrChan chan<- error - Store store.KeyValueStore - ChannelMode string - TlsSettings tls.TlsSettings + Name string + Version string + Listener *acn.Listener + ErrChan chan<- error + Store store.KeyValueStore + PrimaryInterfaceIP string + ChannelMode string + TLSSettings tls.TlsSettings } // NewService creates a new Service object. diff --git a/cns/restserver/api.go b/cns/restserver/api.go index 61bee3ac12..db36d83f05 100644 --- a/cns/restserver/api.go +++ b/cns/restserver/api.go @@ -20,6 +20,7 @@ import ( "github.com/Azure/azure-container-networking/cns/logger" "github.com/Azure/azure-container-networking/cns/types" "github.com/Azure/azure-container-networking/cns/wireserver" + acn "github.com/Azure/azure-container-networking/common" "github.com/pkg/errors" ) @@ -46,7 +47,7 @@ func (service *HTTPRestService) setEnvironment(w http.ResponseWriter, r *http.Re logger.Printf("[Azure CNS] setEnvironment") var req cns.SetEnvironmentRequest - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { @@ -64,7 +65,7 @@ func (service *HTTPRestService) setEnvironment(w http.ResponseWriter, r *http.Re } resp := &cns.Response{ReturnCode: 0} - err = service.Listener.Encode(w, &resp) + err = acn.Encode(w, &resp) logger.Response(service.Name, resp, resp.ReturnCode, err) } @@ -79,7 +80,7 @@ func (service *HTTPRestService) createNetwork(w http.ResponseWriter, r *http.Req if service.state.Initialized { var req cns.CreateNetworkRequest - err = service.Listener.Decode(w, r, &req) + err = acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { @@ -166,7 +167,7 @@ func (service *HTTPRestService) createNetwork(w http.ResponseWriter, r *http.Req Message: returnMessage, } - err = service.Listener.Encode(w, &resp) + err = acn.Encode(w, &resp) if returnCode == 0 { service.saveState() @@ -182,7 +183,7 @@ func (service *HTTPRestService) deleteNetwork(w http.ResponseWriter, r *http.Req var req cns.DeleteNetworkRequest var returnCode types.ResponseCode returnMessage := "" - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { @@ -221,7 +222,7 @@ func (service *HTTPRestService) deleteNetwork(w http.ResponseWriter, r *http.Req Message: returnMessage, } - err = service.Listener.Encode(w, &resp) + err = acn.Encode(w, &resp) if returnCode == 0 { service.removeNetworkInfo(req.NetworkName) @@ -240,7 +241,7 @@ func (service *HTTPRestService) createHnsNetwork(w http.ResponseWriter, r *http. returnMessage := "" var req cns.CreateHnsNetworkRequest - err = service.Listener.Decode(w, r, &req) + err = acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { @@ -273,7 +274,7 @@ func (service *HTTPRestService) createHnsNetwork(w http.ResponseWriter, r *http. Message: returnMessage, } - err = service.Listener.Encode(w, &resp) + err = acn.Encode(w, &resp) if returnCode == 0 { service.saveState() @@ -291,7 +292,7 @@ func (service *HTTPRestService) deleteHnsNetwork(w http.ResponseWriter, r *http. var returnCode types.ResponseCode returnMessage := "" - err = service.Listener.Decode(w, r, &req) + err = acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { @@ -324,7 +325,7 @@ func (service *HTTPRestService) deleteHnsNetwork(w http.ResponseWriter, r *http. Message: returnMessage, } - err = service.Listener.Encode(w, &resp) + err = acn.Encode(w, &resp) if returnCode == 0 { service.removeNetworkInfo(req.NetworkName) @@ -343,7 +344,7 @@ func (service *HTTPRestService) reserveIPAddress(w http.ResponseWriter, r *http. returnMessage := "" addr := "" address := "" - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) @@ -414,7 +415,7 @@ func (service *HTTPRestService) reserveIPAddress(w http.ResponseWriter, r *http. } reserveResp := &cns.ReserveIPAddressResponse{Response: resp, IPAddress: address} - err = service.Listener.Encode(w, &reserveResp) + err = acn.Encode(w, &reserveResp) logger.Response(service.Name, reserveResp, resp.ReturnCode, err) } @@ -426,7 +427,7 @@ func (service *HTTPRestService) releaseIPAddress(w http.ResponseWriter, r *http. var returnCode types.ResponseCode returnMessage := "" - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { @@ -485,7 +486,7 @@ func (service *HTTPRestService) releaseIPAddress(w http.ResponseWriter, r *http. publishIPStateMetrics(service.buildIPState()) } - err = service.Listener.Encode(w, &resp) + err = acn.Encode(w, &resp) logger.Response(service.Name, resp, resp.ReturnCode, err) } @@ -536,7 +537,7 @@ func (service *HTTPRestService) getHostLocalIP(w http.ResponseWriter, r *http.Re IPAddress: hostLocalIP, } - err := service.Listener.Encode(w, &hostLocalIPResponse) + err := acn.Encode(w, &hostLocalIPResponse) logger.Response(service.Name, hostLocalIPResponse, resp.ReturnCode, err) } @@ -602,7 +603,7 @@ func (service *HTTPRestService) getIPAddressUtilization(w http.ResponseWriter, r Unhealthy: len(unhealthyAddrs), } - err := service.Listener.Encode(w, &utilResponse) + err := acn.Encode(w, &utilResponse) logger.Response(service.Name, utilResponse, resp.ReturnCode, err) } @@ -613,7 +614,7 @@ func (service *HTTPRestService) getAvailableIPAddresses(w http.ResponseWriter, r resp := cns.Response{ReturnCode: 0} ipResp := &cns.GetIPAddressesResponse{Response: resp} - err := service.Listener.Encode(w, &ipResp) + err := acn.Encode(w, &ipResp) logger.Response(service.Name, ipResp, resp.ReturnCode, err) } @@ -625,7 +626,7 @@ func (service *HTTPRestService) getReservedIPAddresses(w http.ResponseWriter, r resp := cns.Response{ReturnCode: 0} ipResp := &cns.GetIPAddressesResponse{Response: resp} - err := service.Listener.Encode(w, &ipResp) + err := acn.Encode(w, &ipResp) logger.Response(service.Name, ipResp, resp.ReturnCode, err) } @@ -689,7 +690,7 @@ func (service *HTTPRestService) getUnhealthyIPAddresses(w http.ResponseWriter, r IPAddresses: unhealthyAddrs, } - err := service.Listener.Encode(w, &ipResp) + err := acn.Encode(w, &ipResp) logger.Response(service.Name, ipResp, resp.ReturnCode, err) } @@ -700,7 +701,7 @@ func (service *HTTPRestService) getAllIPAddresses(w http.ResponseWriter, r *http resp := cns.Response{ReturnCode: 0} ipResp := &cns.GetIPAddressesResponse{Response: resp} - err := service.Listener.Encode(w, &ipResp) + err := acn.Encode(w, &ipResp) logger.Response(service.Name, ipResp, resp.ReturnCode, err) } @@ -711,7 +712,7 @@ func (service *HTTPRestService) getHealthReport(w http.ResponseWriter, r *http.R logger.Request(service.Name, "getHealthReport", nil) resp := &cns.Response{ReturnCode: 0} - err := service.Listener.Encode(w, &resp) + err := acn.Encode(w, &resp) logger.Response(service.Name, resp, resp.ReturnCode, err) } @@ -726,7 +727,7 @@ func (service *HTTPRestService) setOrchestratorType(w http.ResponseWriter, r *ht nodeID string ) - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) if err != nil { return } @@ -759,7 +760,7 @@ func (service *HTTPRestService) setOrchestratorType(w http.ResponseWriter, r *ht Message: returnMessage, } - err = service.Listener.Encode(w, &resp) + err = acn.Encode(w, &resp) logger.Response(service.Name, resp, resp.ReturnCode, err) } @@ -784,7 +785,7 @@ func (service *HTTPRestService) getHomeAz(w http.ResponseWriter, r *http.Request func (service *HTTPRestService) createOrUpdateNetworkContainer(w http.ResponseWriter, r *http.Request) { var req cns.CreateNetworkContainerRequest - if err := service.Listener.Decode(w, r, &req); err != nil { + if err := acn.Decode(w, r, &req); err != nil { logger.Errorf("[Azure CNS] could not decode request: %v", err) w.WriteHeader(http.StatusBadRequest) return @@ -843,7 +844,7 @@ func (service *HTTPRestService) createOrUpdateNetworkContainer(w http.ResponseWr } reserveResp := &cns.CreateNetworkContainerResponse{Response: resp} - err = service.Listener.Encode(w, &reserveResp) + err = acn.Encode(w, &reserveResp) // If the NC was created successfully, log NC snapshot. if returnCode == types.Success { @@ -860,7 +861,7 @@ func (service *HTTPRestService) getNetworkContainerByID(w http.ResponseWriter, r var returnCode types.ResponseCode returnMessage := "" - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { return @@ -872,7 +873,7 @@ func (service *HTTPRestService) getNetworkContainerByID(w http.ResponseWriter, r } reserveResp := &cns.GetNetworkContainerResponse{Response: resp} - err = service.Listener.Encode(w, &reserveResp) + err = acn.Encode(w, &reserveResp) logger.Response(service.Name, reserveResp, resp.ReturnCode, err) } @@ -882,7 +883,7 @@ func (service *HTTPRestService) GetAllNetworkContainers(w http.ResponseWriter, r var req cns.GetNetworkContainerRequest - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { logger.Errorf("[Azure CNS] failed to decode cns request with req %+v due to %+v", req, err) @@ -915,7 +916,7 @@ func (service *HTTPRestService) GetAllNetworkContainers(w http.ResponseWriter, r resp.Response.Message = "Successfully retrieved NCs" } - err = service.Listener.Encode(w, &resp) + err = acn.Encode(w, &resp) logger.Response(service.Name, resp, resp.Response.ReturnCode, err) } @@ -924,14 +925,14 @@ func (service *HTTPRestService) GetNetworkContainerByOrchestratorContext(w http. var req cns.GetNetworkContainerRequest - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { return } getNetworkContainerResponses := service.getAllNetworkContainerResponses(req) // nolint - err = service.Listener.Encode(w, &getNetworkContainerResponses[0]) + err = acn.Encode(w, &getNetworkContainerResponses[0]) logger.Response(service.Name, getNetworkContainerResponses[0], getNetworkContainerResponses[0].Response.ReturnCode, err) } @@ -963,7 +964,7 @@ func (service *HTTPRestService) deleteNetworkContainer(w http.ResponseWriter, r var returnCode types.ResponseCode returnMessage := "" - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { return @@ -1027,7 +1028,7 @@ func (service *HTTPRestService) deleteNetworkContainer(w http.ResponseWriter, r } reserveResp := &cns.DeleteNetworkContainerResponse{Response: resp} - err = service.Listener.Encode(w, &reserveResp) + err = acn.Encode(w, &reserveResp) logger.Response(service.Name, reserveResp, resp.ReturnCode, err) } @@ -1038,7 +1039,7 @@ func (service *HTTPRestService) getInterfaceForContainer(w http.ResponseWriter, var returnCode types.ResponseCode returnMessage := "" - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { return @@ -1080,7 +1081,7 @@ func (service *HTTPRestService) getInterfaceForContainer(w http.ResponseWriter, NetworkContainerVersion: version, } - err = service.Listener.Encode(w, &getInterfaceForContainerResponse) + err = acn.Encode(w, &getInterfaceForContainerResponse) logger.Response(service.Name, getInterfaceForContainerResponse, resp.ReturnCode, err) } @@ -1089,7 +1090,7 @@ func (service *HTTPRestService) attachNetworkContainerToNetwork(w http.ResponseW logger.Printf("[Azure CNS] attachNetworkContainerToNetwork") var req cns.ConfigureContainerNetworkingRequest - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { return @@ -1097,7 +1098,7 @@ func (service *HTTPRestService) attachNetworkContainerToNetwork(w http.ResponseW resp := service.attachOrDetachHelper(req, attach, r.Method) attachResp := &cns.AttachContainerToNetworkResponse{Response: resp} - err = service.Listener.Encode(w, &attachResp) + err = acn.Encode(w, &attachResp) logger.Response(service.Name, attachResp, resp.ReturnCode, err) } @@ -1105,7 +1106,7 @@ func (service *HTTPRestService) detachNetworkContainerFromNetwork(w http.Respons logger.Printf("[Azure CNS] detachNetworkContainerFromNetwork") var req cns.ConfigureContainerNetworkingRequest - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { return @@ -1113,7 +1114,7 @@ func (service *HTTPRestService) detachNetworkContainerFromNetwork(w http.Respons resp := service.attachOrDetachHelper(req, detach, r.Method) detachResp := &cns.DetachContainerFromNetworkResponse{Response: resp} - err = service.Listener.Encode(w, &detachResp) + err = acn.Encode(w, &detachResp) logger.Response(service.Name, detachResp, resp.ReturnCode, err) } @@ -1143,7 +1144,7 @@ func (service *HTTPRestService) getNumberOfCPUCores(w http.ResponseWriter, r *ht NumOfCPUCores: num, } - err := service.Listener.Encode(w, &numOfCPUCoresResp) + err := acn.Encode(w, &numOfCPUCoresResp) logger.Response(service.Name, numOfCPUCoresResp, resp.ReturnCode, err) } @@ -1392,7 +1393,7 @@ func (service *HTTPRestService) CreateHostNCApipaEndpoint(w http.ResponseWriter, endpointID string ) - err = service.Listener.Decode(w, r, &req) + err = acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { return @@ -1436,7 +1437,7 @@ func (service *HTTPRestService) CreateHostNCApipaEndpoint(w http.ResponseWriter, EndpointID: endpointID, } - err = service.Listener.Encode(w, &response) + err = acn.Encode(w, &response) logger.Response(service.Name, response, response.Response.ReturnCode, err) } @@ -1450,7 +1451,7 @@ func (service *HTTPRestService) DeleteHostNCApipaEndpoint(w http.ResponseWriter, returnMessage string ) - err = service.Listener.Decode(w, r, &req) + err = acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { return @@ -1475,7 +1476,7 @@ func (service *HTTPRestService) DeleteHostNCApipaEndpoint(w http.ResponseWriter, }, } - err = service.Listener.Encode(w, &response) + err = acn.Encode(w, &response) logger.Response(service.Name, response, response.Response.ReturnCode, err) } @@ -1492,7 +1493,7 @@ func (service *HTTPRestService) nmAgentSupportedApisHandler(w http.ResponseWrite ctx := r.Context() - err = service.Listener.Decode(w, r, &req) + err = acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { return @@ -1517,7 +1518,7 @@ func (service *HTTPRestService) nmAgentSupportedApisHandler(w http.ResponseWrite SupportedApis: supportedApis, } - serviceErr := service.Listener.Encode(w, &nmAgentSupportedApisResponse) + serviceErr := acn.Encode(w, &nmAgentSupportedApisResponse) logger.Response(service.Name, nmAgentSupportedApisResponse, resp.ReturnCode, serviceErr) } diff --git a/cns/restserver/api_test.go b/cns/restserver/api_test.go index 4188bb3e54..22461e3233 100644 --- a/cns/restserver/api_test.go +++ b/cns/restserver/api_test.go @@ -1666,6 +1666,27 @@ func setEnv(t *testing.T) *httptest.ResponseRecorder { return w } +// Since UT can only run with localhost, to mock all api test cases, add nodeListener service handlers +func addHandlersToListener(service *HTTPRestService) { + // Add handlers for UT + listener := service.Listener + + listener.AddHandler(cns.GetNetworkContainerByOrchestratorContext, service.GetNetworkContainerByOrchestratorContext) + listener.AddHandler(cns.GetAllNetworkContainers, service.GetAllNetworkContainers) + listener.AddHandler(cns.CreateHostNCApipaEndpointPath, service.CreateHostNCApipaEndpoint) + listener.AddHandler(cns.DeleteHostNCApipaEndpointPath, service.DeleteHostNCApipaEndpoint) + listener.AddHandler(cns.RequestIPConfig, NewHandlerFuncWithHistogram(service.RequestIPConfigHandler, HTTPRequestLatency)) + listener.AddHandler(cns.RequestIPConfigs, NewHandlerFuncWithHistogram(service.RequestIPConfigsHandler, HTTPRequestLatency)) + listener.AddHandler(cns.ReleaseIPConfig, NewHandlerFuncWithHistogram(service.ReleaseIPConfigHandler, HTTPRequestLatency)) + listener.AddHandler(cns.ReleaseIPConfigs, NewHandlerFuncWithHistogram(service.ReleaseIPConfigsHandler, HTTPRequestLatency)) + listener.AddHandler(cns.PathDebugIPAddresses, service.HandleDebugIPAddresses) + listener.AddHandler(cns.PathDebugPodContext, service.HandleDebugPodContext) + listener.AddHandler(cns.PathDebugRestData, service.HandleDebugRestData) + listener.AddHandler(cns.V2Prefix+cns.GetNetworkContainerByOrchestratorContext, service.GetNetworkContainerByOrchestratorContext) + listener.AddHandler(cns.V2Prefix+cns.GetAllNetworkContainers, service.GetAllNetworkContainers) + listener.AddHandler(cns.V2Prefix+cns.CreateHostNCApipaEndpointPath, service.CreateHostNCApipaEndpoint) +} + func startService() error { // Create the service. config := common.ServiceConfig{} @@ -1720,12 +1741,18 @@ func startService() error { file, _ := os.Create(cnsJsonFileName) file.Close() + // mock localhost as primary interface IP + config.PrimaryInterfaceIP = "localhost" + err = service.Init(&config) if err != nil { logger.Errorf("Failed to Init CNS, err:%v.\n", err) return err } + service := service.(*HTTPRestService) + addHandlersToListener(service) + err = service.Start(&config) if err != nil { logger.Errorf("Failed to start CNS, err:%v.\n", err) diff --git a/cns/restserver/ipam.go b/cns/restserver/ipam.go index 2e1115039c..d05cd4180f 100644 --- a/cns/restserver/ipam.go +++ b/cns/restserver/ipam.go @@ -94,7 +94,7 @@ func (service *HTTPRestService) requestIPConfigHandlerHelper(ctx context.Context // RequestIPConfigHandler requests an IPConfig from the CNS state func (service *HTTPRestService) RequestIPConfigHandler(w http.ResponseWriter, r *http.Request) { var ipconfigRequest cns.IPConfigRequest - err := service.Listener.Decode(w, r, &ipconfigRequest) + err := common.Decode(w, r, &ipconfigRequest) operationName := "requestIPConfigHandler" logger.Request(service.Name+operationName, ipconfigRequest, err) if err != nil { @@ -111,7 +111,7 @@ func (service *HTTPRestService) RequestIPConfigHandler(w http.ResponseWriter, r }, } w.Header().Set(cnsReturnCode, reserveResp.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &reserveResp) + err = common.Encode(w, &reserveResp) logger.ResponseEx(service.Name+operationName, ipconfigRequest, reserveResp, reserveResp.Response.ReturnCode, err) return } @@ -136,7 +136,7 @@ func (service *HTTPRestService) RequestIPConfigHandler(w http.ResponseWriter, r Response: ipConfigsResp.Response, } w.Header().Set(cnsReturnCode, reserveResp.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &reserveResp) + err = common.Encode(w, &reserveResp) logger.ResponseEx(service.Name+operationName, ipconfigsRequest, reserveResp, reserveResp.Response.ReturnCode, err) return } @@ -152,7 +152,7 @@ func (service *HTTPRestService) RequestIPConfigHandler(w http.ResponseWriter, r }, } w.Header().Set(cnsReturnCode, reserveResp.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &reserveResp) + err = common.Encode(w, &reserveResp) logger.ResponseEx(service.Name+operationName, ipconfigRequest, reserveResp, reserveResp.Response.ReturnCode, err) return } @@ -162,14 +162,14 @@ func (service *HTTPRestService) RequestIPConfigHandler(w http.ResponseWriter, r PodIpInfo: ipConfigsResp.PodIPInfo[0], } w.Header().Set(cnsReturnCode, reserveResp.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &reserveResp) + err = common.Encode(w, &reserveResp) logger.ResponseEx(service.Name+operationName, ipconfigsRequest, reserveResp, reserveResp.Response.ReturnCode, err) } // RequestIPConfigsHandler requests multiple IPConfigs from the CNS state func (service *HTTPRestService) RequestIPConfigsHandler(w http.ResponseWriter, r *http.Request) { var ipconfigsRequest cns.IPConfigsRequest - err := service.Listener.Decode(w, r, &ipconfigsRequest) + err := common.Decode(w, r, &ipconfigsRequest) operationName := "requestIPConfigsHandler" logger.Request(service.Name+operationName, ipconfigsRequest, err) if err != nil { @@ -188,13 +188,13 @@ func (service *HTTPRestService) RequestIPConfigsHandler(w http.ResponseWriter, r if err != nil { w.Header().Set(cnsReturnCode, ipConfigsResp.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &ipConfigsResp) + err = common.Encode(w, &ipConfigsResp) logger.ResponseEx(service.Name+operationName, ipconfigsRequest, ipConfigsResp, ipConfigsResp.Response.ReturnCode, err) return } w.Header().Set(cnsReturnCode, ipConfigsResp.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &ipConfigsResp) + err = common.Encode(w, &ipConfigsResp) logger.ResponseEx(service.Name+operationName, ipconfigsRequest, ipConfigsResp, ipConfigsResp.Response.ReturnCode, err) } @@ -304,7 +304,7 @@ func (service *HTTPRestService) ReleaseIPConfigHandlerHelper(ctx context.Context // ReleaseIPConfigHandler frees the IP assigned to a pod from CNS func (service *HTTPRestService) ReleaseIPConfigHandler(w http.ResponseWriter, r *http.Request) { var ipconfigRequest cns.IPConfigRequest - err := service.Listener.Decode(w, r, &ipconfigRequest) + err := common.Decode(w, r, &ipconfigRequest) logger.Request(service.Name+"releaseIPConfigHandler", ipconfigRequest, err) if err != nil { resp := cns.Response{ @@ -313,7 +313,7 @@ func (service *HTTPRestService) ReleaseIPConfigHandler(w http.ResponseWriter, r } logger.Errorf("releaseIPConfigHandler decode failed becase %v, release IP config info %s", resp.Message, ipconfigRequest) w.Header().Set(cnsReturnCode, resp.ReturnCode.String()) - err = service.Listener.Encode(w, &resp) + err = common.Encode(w, &resp) logger.ResponseEx(service.Name, ipconfigRequest, resp, resp.ReturnCode, err) return } @@ -327,7 +327,7 @@ func (service *HTTPRestService) ReleaseIPConfigHandler(w http.ResponseWriter, r }, } w.Header().Set(cnsReturnCode, reserveResp.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &reserveResp) + err = common.Encode(w, &reserveResp) logger.ResponseEx(service.Name, ipconfigRequest, reserveResp, reserveResp.Response.ReturnCode, err) return } @@ -345,19 +345,19 @@ func (service *HTTPRestService) ReleaseIPConfigHandler(w http.ResponseWriter, r resp, err := service.ReleaseIPConfigHandlerHelper(r.Context(), ipconfigsRequest) if err != nil { w.Header().Set(cnsReturnCode, resp.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &resp) + err = common.Encode(w, &resp) logger.ResponseEx(service.Name, ipconfigRequest, resp, resp.Response.ReturnCode, err) } w.Header().Set(cnsReturnCode, resp.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &resp) + err = common.Encode(w, &resp) logger.ResponseEx(service.Name, ipconfigRequest, resp, resp.Response.ReturnCode, err) } // ReleaseIPConfigsHandler frees multiple IPConfigs from the CNS state func (service *HTTPRestService) ReleaseIPConfigsHandler(w http.ResponseWriter, r *http.Request) { var ipconfigsRequest cns.IPConfigsRequest - err := service.Listener.Decode(w, r, &ipconfigsRequest) + err := common.Decode(w, r, &ipconfigsRequest) logger.Request(service.Name+"releaseIPConfigsHandler", ipconfigsRequest, err) if err != nil { resp := cns.Response{ @@ -366,7 +366,7 @@ func (service *HTTPRestService) ReleaseIPConfigsHandler(w http.ResponseWriter, r } logger.Errorf("releaseIPConfigsHandler decode failed because %v, release IP config info %+v", resp.Message, ipconfigsRequest) w.Header().Set(cnsReturnCode, resp.ReturnCode.String()) - err = service.Listener.Encode(w, &resp) + err = common.Encode(w, &resp) logger.ResponseEx(service.Name, ipconfigsRequest, resp, resp.ReturnCode, err) return } @@ -374,12 +374,12 @@ func (service *HTTPRestService) ReleaseIPConfigsHandler(w http.ResponseWriter, r resp, err := service.ReleaseIPConfigHandlerHelper(r.Context(), ipconfigsRequest) if err != nil { w.Header().Set(cnsReturnCode, resp.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &resp) + err = common.Encode(w, &resp) logger.ResponseEx(service.Name, ipconfigsRequest, resp, resp.Response.ReturnCode, err) } w.Header().Set(cnsReturnCode, resp.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &resp) + err = common.Encode(w, &resp) logger.ResponseEx(service.Name, ipconfigsRequest, resp, resp.Response.ReturnCode, err) } @@ -566,7 +566,7 @@ func (service *HTTPRestService) HandleDebugPodContext(w http.ResponseWriter, r * resp := cns.GetPodContextResponse{ PodContext: service.PodIPIDByPodInterfaceKey, } - err := service.Listener.Encode(w, &resp) + err := common.Encode(w, &resp) logger.Response(service.Name, resp, resp.Response.ReturnCode, err) } @@ -579,20 +579,20 @@ func (service *HTTPRestService) HandleDebugRestData(w http.ResponseWriter, r *ht PodIPConfigState: service.PodIPConfigState, }, } - err := service.Listener.Encode(w, &resp) + err := common.Encode(w, &resp) logger.Response(service.Name, resp, resp.Response.ReturnCode, err) } func (service *HTTPRestService) HandleDebugIPAddresses(w http.ResponseWriter, r *http.Request) { var req cns.GetIPAddressesRequest - if err := service.Listener.Decode(w, r, &req); err != nil { + if err := common.Decode(w, r, &req); err != nil { resp := cns.GetIPAddressStatusResponse{ Response: cns.Response{ ReturnCode: types.UnexpectedError, Message: err.Error(), }, } - err = service.Listener.Encode(w, &resp) + err = common.Encode(w, &resp) logger.ResponseEx(service.Name, req, resp, resp.Response.ReturnCode, err) return } @@ -600,7 +600,7 @@ func (service *HTTPRestService) HandleDebugIPAddresses(w http.ResponseWriter, r resp := cns.GetIPAddressStatusResponse{ IPConfigurationStatus: filter.MatchAnyIPConfigState(service.PodIPConfigState, filter.PredicatesForStates(req.IPConfigStateFilter...)...), } - err := service.Listener.Encode(w, &resp) + err := common.Encode(w, &resp) logger.ResponseEx(service.Name, req, resp, resp.Response.ReturnCode, err) } @@ -991,7 +991,7 @@ func (service *HTTPRestService) EndpointHandlerAPI(w http.ResponseWriter, r *htt ReturnCode: types.UnexpectedError, Message: fmt.Sprintf("[EndpointHandlerAPI] EndpointHandlerAPI failed with error: %s", ErrOptManageEndpointState), } - err := service.Listener.Encode(w, &response) + err := common.Encode(w, &response) logger.Response(service.Name, response, response.ReturnCode, err) return } @@ -1027,7 +1027,7 @@ func (service *HTTPRestService) GetEndpointHandler(w http.ResponseWriter, r *htt } } w.Header().Set(cnsReturnCode, response.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &response) + err = common.Encode(w, &response) logger.Response(service.Name, response, response.Response.ReturnCode, err) return } @@ -1039,7 +1039,7 @@ func (service *HTTPRestService) GetEndpointHandler(w http.ResponseWriter, r *htt EndpointInfo: *endpointInfo, } w.Header().Set(cnsReturnCode, response.Response.ReturnCode.String()) - err = service.Listener.Encode(w, &response) + err = common.Encode(w, &response) logger.Response(service.Name, response, response.Response.ReturnCode, err) } @@ -1084,7 +1084,7 @@ func (service *HTTPRestService) UpdateEndpointHandler(w http.ResponseWriter, r * logger.Printf("[updateEndpoint] updateEndpoint for %s", r.URL.Path) var req cns.EndpointRequest - err := service.Listener.Decode(w, r, &req) + err := common.Decode(w, r, &req) endpointID := strings.TrimPrefix(r.URL.Path, cns.EndpointPath) logger.Request(service.Name, &req, err) // Check if the request is valid @@ -1094,7 +1094,7 @@ func (service *HTTPRestService) UpdateEndpointHandler(w http.ResponseWriter, r * Message: fmt.Sprintf("[updateEndpoint] updateEndpoint failed with error: %s", err.Error()), } w.Header().Set(cnsReturnCode, response.ReturnCode.String()) - err = service.Listener.Encode(w, &response) + err = common.Encode(w, &response) logger.Response(service.Name, response, response.ReturnCode, err) return } @@ -1105,7 +1105,7 @@ func (service *HTTPRestService) UpdateEndpointHandler(w http.ResponseWriter, r * Message: "[updateEndpoint] No HnsEndpointID or HostVethName has been provided", } w.Header().Set(cnsReturnCode, response.ReturnCode.String()) - err = service.Listener.Encode(w, &response) + err = common.Encode(w, &response) logger.Response(service.Name, response, response.ReturnCode, err) return } @@ -1117,7 +1117,7 @@ func (service *HTTPRestService) UpdateEndpointHandler(w http.ResponseWriter, r * Message: fmt.Sprintf("[updateEndpoint] updateEndpoint failed with error: %s", err.Error()), } w.Header().Set(cnsReturnCode, response.ReturnCode.String()) - err = service.Listener.Encode(w, &response) + err = common.Encode(w, &response) logger.Response(service.Name, response, response.ReturnCode, err) return } @@ -1126,7 +1126,7 @@ func (service *HTTPRestService) UpdateEndpointHandler(w http.ResponseWriter, r * Message: "[updateEndpoint] updateEndpoint retruned successfully", } w.Header().Set(cnsReturnCode, response.ReturnCode.String()) - err = service.Listener.Encode(w, &response) + err = common.Encode(w, &response) logger.Response(service.Name, response, response.ReturnCode, err) } diff --git a/cns/restserver/restserver.go b/cns/restserver/restserver.go index d8e9604a7b..19eb64610d 100644 --- a/cns/restserver/restserver.go +++ b/cns/restserver/restserver.go @@ -185,6 +185,9 @@ func NewHTTPRestService(config *common.ServiceConfig, wscli interfaceGetter, wsp return nil, errors.Wrap(err, "failed to get primary interface from IMDS response") } + // add primaryInterfaceIP to cns config + config.PrimaryInterfaceIP = primaryInterface.PrimaryIP + serviceState := &httpRestServiceState{ Networks: make(map[string]*networkInfo), joinedNetworks: make(map[string]struct{}), @@ -249,25 +252,14 @@ func (service *HTTPRestService) Init(config *common.ServiceConfig) error { listener.AddHandler(cns.DeleteNetworkContainer, service.deleteNetworkContainer) listener.AddHandler(cns.GetInterfaceForContainer, service.getInterfaceForContainer) listener.AddHandler(cns.SetOrchestratorType, service.setOrchestratorType) - listener.AddHandler(cns.GetNetworkContainerByOrchestratorContext, service.GetNetworkContainerByOrchestratorContext) - listener.AddHandler(cns.GetAllNetworkContainers, service.GetAllNetworkContainers) listener.AddHandler(cns.AttachContainerToNetwork, service.attachNetworkContainerToNetwork) listener.AddHandler(cns.DetachContainerFromNetwork, service.detachNetworkContainerFromNetwork) listener.AddHandler(cns.CreateHnsNetworkPath, service.createHnsNetwork) listener.AddHandler(cns.DeleteHnsNetworkPath, service.deleteHnsNetwork) listener.AddHandler(cns.NumberOfCPUCoresPath, service.getNumberOfCPUCores) - listener.AddHandler(cns.CreateHostNCApipaEndpointPath, service.CreateHostNCApipaEndpoint) - listener.AddHandler(cns.DeleteHostNCApipaEndpointPath, service.DeleteHostNCApipaEndpoint) listener.AddHandler(cns.PublishNetworkContainer, service.publishNetworkContainer) listener.AddHandler(cns.UnpublishNetworkContainer, service.unpublishNetworkContainer) - listener.AddHandler(cns.RequestIPConfig, NewHandlerFuncWithHistogram(service.RequestIPConfigHandler, HTTPRequestLatency)) - listener.AddHandler(cns.RequestIPConfigs, NewHandlerFuncWithHistogram(service.RequestIPConfigsHandler, HTTPRequestLatency)) - listener.AddHandler(cns.ReleaseIPConfig, NewHandlerFuncWithHistogram(service.ReleaseIPConfigHandler, HTTPRequestLatency)) - listener.AddHandler(cns.ReleaseIPConfigs, NewHandlerFuncWithHistogram(service.ReleaseIPConfigsHandler, HTTPRequestLatency)) listener.AddHandler(cns.NmAgentSupportedApisPath, service.nmAgentSupportedApisHandler) - listener.AddHandler(cns.PathDebugIPAddresses, service.HandleDebugIPAddresses) - listener.AddHandler(cns.PathDebugPodContext, service.HandleDebugPodContext) - listener.AddHandler(cns.PathDebugRestData, service.HandleDebugRestData) listener.AddHandler(cns.NetworkContainersURLPath, service.getOrRefreshNetworkContainers) listener.AddHandler(cns.GetHomeAz, service.getHomeAz) listener.AddHandler(cns.EndpointPath, service.EndpointHandlerAPI) @@ -284,15 +276,11 @@ func (service *HTTPRestService) Init(config *common.ServiceConfig) error { listener.AddHandler(cns.V2Prefix+cns.DeleteNetworkContainer, service.deleteNetworkContainer) listener.AddHandler(cns.V2Prefix+cns.GetInterfaceForContainer, service.getInterfaceForContainer) listener.AddHandler(cns.V2Prefix+cns.SetOrchestratorType, service.setOrchestratorType) - listener.AddHandler(cns.V2Prefix+cns.GetNetworkContainerByOrchestratorContext, service.GetNetworkContainerByOrchestratorContext) - listener.AddHandler(cns.V2Prefix+cns.GetAllNetworkContainers, service.GetAllNetworkContainers) listener.AddHandler(cns.V2Prefix+cns.AttachContainerToNetwork, service.attachNetworkContainerToNetwork) listener.AddHandler(cns.V2Prefix+cns.DetachContainerFromNetwork, service.detachNetworkContainerFromNetwork) listener.AddHandler(cns.V2Prefix+cns.CreateHnsNetworkPath, service.createHnsNetwork) listener.AddHandler(cns.V2Prefix+cns.DeleteHnsNetworkPath, service.deleteHnsNetwork) listener.AddHandler(cns.V2Prefix+cns.NumberOfCPUCoresPath, service.getNumberOfCPUCores) - listener.AddHandler(cns.V2Prefix+cns.CreateHostNCApipaEndpointPath, service.CreateHostNCApipaEndpoint) - listener.AddHandler(cns.V2Prefix+cns.DeleteHostNCApipaEndpointPath, service.DeleteHostNCApipaEndpoint) listener.AddHandler(cns.V2Prefix+cns.NmAgentSupportedApisPath, service.nmAgentSupportedApisHandler) listener.AddHandler(cns.V2Prefix+cns.GetHomeAz, service.getHomeAz) listener.AddHandler(cns.V2Prefix+cns.EndpointPath, service.EndpointHandlerAPI) diff --git a/cns/restserver/util.go b/cns/restserver/util.go index b65e440a54..94a51048e8 100644 --- a/cns/restserver/util.go +++ b/cns/restserver/util.go @@ -913,7 +913,7 @@ func (service *HTTPRestService) handleGetNetworkContainers(w http.ResponseWriter ReturnCode: types.Success, }, } - err := service.Listener.Encode(w, &response) + err := acn.Encode(w, &response) logger.Response(service.Name, response, response.Response.ReturnCode, err) } @@ -921,7 +921,7 @@ func (service *HTTPRestService) handleGetNetworkContainers(w http.ResponseWriter func (service *HTTPRestService) handlePostNetworkContainers(w http.ResponseWriter, r *http.Request) { logger.Printf("[Azure CNS] handlePostNetworkContainers") var req cns.PostNetworkContainersRequest - err := service.Listener.Decode(w, r, &req) + err := acn.Decode(w, r, &req) logger.Request(service.Name, &req, err) if err != nil { response := cns.PostNetworkContainersResponse{ @@ -930,7 +930,7 @@ func (service *HTTPRestService) handlePostNetworkContainers(w http.ResponseWrite Message: fmt.Sprintf("[Azure CNS] handlePostNetworkContainers failed with error: %s", err.Error()), }, } - err = service.Listener.Encode(w, &response) + err = acn.Encode(w, &response) logger.Response(service.Name, response, response.Response.ReturnCode, err) return } @@ -944,7 +944,7 @@ func (service *HTTPRestService) handlePostNetworkContainers(w http.ResponseWrite response := cns.PostNetworkContainersResponse{ Response: createNCsResp, } - err = service.Listener.Encode(w, &response) + err = acn.Encode(w, &response) logger.Response(service.Name, response, response.Response.ReturnCode, err) } @@ -982,7 +982,7 @@ func (service *HTTPRestService) createNetworkContainers(createNetworkContainerRe // setResponse encodes the http response func (service *HTTPRestService) setResponse(w http.ResponseWriter, returnCode types.ResponseCode, response interface{}) { - serviceErr := service.Listener.Encode(w, &response) + serviceErr := acn.Encode(w, &response) logger.Response(service.Name, response, returnCode, serviceErr) } diff --git a/cns/service.go b/cns/service.go index 4f9e398eca..4482080818 100644 --- a/cns/service.go +++ b/cns/service.go @@ -24,9 +24,9 @@ import ( ) const ( - // Default CNS server URL. - defaultAPIServerURL = "tcp://localhost:10090" - genericData = "com.microsoft.azure.network.generic" + DefaultAPIServerURL = "tcp://localhost:10090" + defaultAPIServerPort = "10090" + genericData = "com.microsoft.azure.network.generic" ) // Service defines Container Networking Service. @@ -48,64 +48,65 @@ func NewService(name, version, channelMode string, store store.KeyValueStore) (* }, nil } -// GetAPIServerURL returns the API server URL. -func (service *Service) getAPIServerURL() string { - urls, _ := service.GetOption(acn.OptCnsURL).(string) - if urls == "" { - urls = defaultAPIServerURL +func (service *Service) AddListener(config *common.ServiceConfig) error { + // Fetch and parse the API server URL. + var nodeURL *url.URL + cnsURL, _ := service.GetOption(acn.OptCnsURL).(string) + if cnsURL == "" { + // get VM primary interface's private IP + nodeURL, _ = url.Parse(fmt.Sprintf("tcp://%s:%s", config.PrimaryInterfaceIP, defaultAPIServerPort)) + } else { + // use the URL that customer provides + nodeURL, _ = url.Parse(cnsURL) } - return urls -} - -// Initialize initializes the service and starts the listener. -func (service *Service) Initialize(config *common.ServiceConfig) error { - log.Debugf("[Azure CNS] Going to initialize a service with config: %+v", config) + nodeListener, err := acn.NewListener(nodeURL) - // Initialize the base service. - if err := service.Service.Initialize(config); err != nil { - return errors.Wrap(err, "failed to initialize") + if err != nil { + return errors.Wrap(err, "Failed to construct url for node listener") } - // Initialize the listener. - if config.Listener == nil { - // Fetch and parse the API server URL. - u, err := url.Parse(service.getAPIServerURL()) - if err != nil { - return err - } - - listener, err := acn.NewListener(u) - if err != nil { - return err - } - - if config.TlsSettings.TLSPort != "" { + // only use TLS connection for DNC/CNS listener: + if config.TLSSettings.TLSPort != "" { + if config.TLSSettings.TLSPort != "" { // listener.URL.Host will always be hostname:port, passed in to CNS via CNS command // else it will default to localhost // extract hostname and override tls port. - hostParts := strings.Split(listener.URL.Host, ":") - tlsAddress := net.JoinHostPort(hostParts[0], config.TlsSettings.TLSPort) + hostParts := strings.Split(nodeListener.URL.Host, ":") + tlsAddress := net.JoinHostPort(hostParts[0], config.TLSSettings.TLSPort) // Start the listener and HTTP and HTTPS server. - tlsConfig, err := getTLSConfig(config.TlsSettings, config.ErrChan) + tlsConfig, err := getTLSConfig(config.TLSSettings, config.ErrChan) //nolint if err != nil { log.Printf("Failed to compose Tls Configuration with error: %+v", err) return errors.Wrap(err, "could not get tls config") } - if err := listener.StartTLS(config.ErrChan, tlsConfig, tlsAddress); err != nil { - return err + if err := nodeListener.StartTLS(config.ErrChan, tlsConfig, tlsAddress); err != nil { + return errors.Wrap(err, "could not start tls") } } + } + + service.Listener = nodeListener + log.Debugf("[Azure CNS] Successfully initialized a service with config: %+v", config) + + return nil +} + +// Initialize initializes the service and starts the listener. +func (service *Service) Initialize(config *common.ServiceConfig) error { + log.Debugf("[Azure CNS] Going to initialize a service with config: %+v", config) - logger.Printf("HTTP listener will be started later after CNS state has been reconciled") - config.Listener = listener + // Initialize the base service. + if err := service.Service.Initialize(config); err != nil { + return errors.Wrap(err, "failed to initialize") } - service.Listener = config.Listener + if err := service.AddListener(config); err != nil { + return errors.Wrap(err, "failed to initialize listener") + } - log.Debugf("[Azure CNS] Successfully initialized a service with config: %+v", config) return nil } @@ -226,6 +227,6 @@ func (service *Service) ParseOptions(options OptionMap) OptionMap { // SendErrorResponse sends and logs an error response. func (service *Service) SendErrorResponse(w http.ResponseWriter, errMsg error) { resp := errorResponse{errMsg.Error()} - err := service.Listener.Encode(w, &resp) + err := acn.Encode(w, &resp) log.Errorf("[%s] %+v %s.", service.Name, &resp, err.Error()) } diff --git a/cns/service/main.go b/cns/service/main.go index 5a0bac7dc0..9d7bb955fc 100644 --- a/cns/service/main.go +++ b/cns/service/main.go @@ -9,6 +9,7 @@ import ( "encoding/json" "fmt" "io/fs" + "math/rand/v2" "net/http" "os" "os/signal" @@ -43,6 +44,7 @@ import ( "github.com/Azure/azure-container-networking/cns/multitenantcontroller" "github.com/Azure/azure-container-networking/cns/multitenantcontroller/multitenantoperator" "github.com/Azure/azure-container-networking/cns/restserver" + "github.com/Azure/azure-container-networking/cns/restserver/v2" cnstypes "github.com/Azure/azure-container-networking/cns/types" "github.com/Azure/azure-container-networking/cns/wireserver" acn "github.com/Azure/azure-container-networking/common" @@ -766,7 +768,7 @@ func main() { logger.Printf("[Azure CNS] Initialize HTTPRestService") if httpRestService != nil { if cnsconfig.UseHTTPS { - config.TlsSettings = localtls.TlsSettings{ + config.TLSSettings = localtls.TlsSettings{ TLSSubjectName: cnsconfig.TLSSubjectName, TLSCertificatePath: cnsconfig.TLSCertificatePath, TLSPort: cnsconfig.TLSPort, @@ -856,7 +858,16 @@ func main() { logger.Errorf("Failed to start multiTenantController, err:%v.\n", err) return } + } + logger.Printf("[Azure CNS] Start HTTP local echo server") + httpEchoRestService := v2.New(httpRestService) + if httpEchoRestService != nil { + err = httpEchoRestService.Start(z.Log(zap.InfoLevel, ""), cns.DefaultAPIServerURL) + if err != nil { + logger.Errorf("Failed to start localhost echo server, err:%v.\n", err) + return + } } logger.Printf("[Azure CNS] Start HTTP listener") diff --git a/common/listener.go b/common/listener.go index 06645741f9..0214c36b59 100644 --- a/common/listener.go +++ b/common/listener.go @@ -133,7 +133,7 @@ func (l *Listener) AddHandler(path string, handler http.HandlerFunc) { // todo: Decode and Encode below should not be methods, just functions. They make no use of Listener fields. // Decode receives and decodes JSON payload to a request. -func (l *Listener) Decode(w http.ResponseWriter, r *http.Request, request interface{}) error { +func Decode(w http.ResponseWriter, r *http.Request, request interface{}) error { var err error if r.Body == nil { err = errors.New("request body is empty") @@ -149,7 +149,7 @@ func (l *Listener) Decode(w http.ResponseWriter, r *http.Request, request interf } // Encode encodes and sends a response as JSON payload. -func (l *Listener) Encode(w http.ResponseWriter, response interface{}) error { +func Encode(w http.ResponseWriter, response interface{}) error { // Set the content type as application json w.Header().Set("Content-Type", "application/json; charset=UTF-8") err := json.NewEncoder(w).Encode(response)