Start two CNS servers with different handlers (#2650)

* start two cns servers

* fix linter issues

* fix linter issue

* enhance echo server log

* fix Quang's comments

* gofumpt cns service.go

* fix defaultAPIServerAddress

* run servers asynchoronsly

* add server_test.go

* fix UT test

* enhance log

* fix log issue

* fix an issue

* add a check for defaultAPIServerURL

* fix GetOption func

* enhance comments

* fix defaultAPI URL to 127.0.0.1

* fix restapi method in echo server

* remove unnecessary log info

* fix comment1

* fix comments

* add context to control echo server

* fix TM's comments

* do not enable local server if user specifies cnsurl by -c option

* add -p port check when getting nodeURL

* fix comments and use -p select from customer to start local server

* fix a case when customer does not provide -p option

* fix the issue if customer also does not provide -p and -c option

* add UTs to launch server with different combinations

* fix linter issue for UTs

* fix UT linter issues

* UT needs to stop service

* remove duplicated test case

* comments fix

* fix linter issue

* fix Tim's comments

* fix comments

* fix linter issue

* handle type assertion

* Adding cnsURL and cnsPort options to test server

The startService function is a mistake that has been perpetuated through
time and needs to be removed. As a consequence of its existence, it
requires mixing concerns in all tests and stands in the way of
refactoring.

The addition of two type assertion checks caused this function to break,
because the corresponding options were not set in the Service's
configuration. This is a problem in itself--there's no reason the
options should be pulled out of a map[string]interface{}. Given this, we
can just set these two options in startService, committing sins to
offset the ones in service.(*HTTPRestService).Service.Options.

---------

Signed-off-by: Paul Yu <129891899+paulyufan2@users.noreply.github.com>
Co-authored-by: Tim Raymond <traymond@microsoft.com>
This commit is contained in:
Paul Yu 2024-04-29 19:16:58 -04:00 коммит произвёл GitHub
Родитель 654b1fab62
Коммит be2dcc0324
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
15 изменённых файлов: 412 добавлений и 211 удалений

Просмотреть файл

@ -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)
}

Просмотреть файл

@ -128,7 +128,7 @@ func (plugin *netPlugin) getCapabilities(w http.ResponseWriter, r *http.Request)
log.Request(plugin.Name, &req, nil)
resp := getCapabilitiesResponse{Scope: plugin.scope}
err := plugin.Listener.Encode(w, &resp)
err := common.Encode(w, &resp)
log.Response(plugin.Name, &resp, returnCode, returnStr, err)
}
@ -138,7 +138,7 @@ func (plugin *netPlugin) createNetwork(w http.ResponseWriter, r *http.Request) {
var req createNetworkRequest
// 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
@ -182,7 +182,7 @@ func (plugin *netPlugin) createNetwork(w http.ResponseWriter, r *http.Request) {
// Encode response.
resp := createNetworkResponse{}
err = plugin.Listener.Encode(w, &resp)
err = common.Encode(w, &resp)
log.Response(plugin.Name, &resp, returnCode, returnStr, err)
}
@ -192,7 +192,7 @@ func (plugin *netPlugin) deleteNetwork(w http.ResponseWriter, r *http.Request) {
var req deleteNetworkRequest
// 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
@ -207,7 +207,7 @@ func (plugin *netPlugin) deleteNetwork(w http.ResponseWriter, r *http.Request) {
// Encode response.
resp := deleteNetworkResponse{}
err = plugin.Listener.Encode(w, &resp)
err = common.Encode(w, &resp)
log.Response(plugin.Name, &resp, returnCode, returnStr, err)
}
@ -217,7 +217,7 @@ func (plugin *netPlugin) createEndpoint(w http.ResponseWriter, r *http.Request)
var req createEndpointRequest
// 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
@ -256,7 +256,7 @@ func (plugin *netPlugin) createEndpoint(w http.ResponseWriter, r *http.Request)
// Encode response.
resp := createEndpointResponse{}
err = plugin.Listener.Encode(w, &resp)
err = common.Encode(w, &resp)
log.Response(plugin.Name, &resp, returnCode, returnStr, err)
}
@ -266,7 +266,7 @@ func (plugin *netPlugin) deleteEndpoint(w http.ResponseWriter, r *http.Request)
var req deleteEndpointRequest
// 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
@ -281,7 +281,7 @@ func (plugin *netPlugin) deleteEndpoint(w http.ResponseWriter, r *http.Request)
// Encode response.
resp := deleteEndpointResponse{}
err = plugin.Listener.Encode(w, &resp)
err = common.Encode(w, &resp)
log.Response(plugin.Name, &resp, returnCode, returnStr, err)
}
@ -291,7 +291,7 @@ func (plugin *netPlugin) join(w http.ResponseWriter, r *http.Request) {
var req joinRequest
// 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
@ -315,7 +315,7 @@ func (plugin *netPlugin) join(w http.ResponseWriter, r *http.Request) {
Gateway: ep.Gateways[0].String(),
}
err = plugin.Listener.Encode(w, &resp)
err = common.Encode(w, &resp)
log.Response(plugin.Name, &resp, returnCode, returnStr, err)
}
@ -325,7 +325,7 @@ func (plugin *netPlugin) leave(w http.ResponseWriter, r *http.Request) {
var req leaveRequest
// 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
@ -340,7 +340,7 @@ func (plugin *netPlugin) leave(w http.ResponseWriter, r *http.Request) {
// Encode response.
resp := leaveResponse{}
err = plugin.Listener.Encode(w, &resp)
err = common.Encode(w, &resp)
log.Response(plugin.Name, &resp, returnCode, returnStr, err)
}
@ -350,7 +350,7 @@ func (plugin *netPlugin) endpointOperInfo(w http.ResponseWriter, r *http.Request
var req endpointOperInfoRequest
// 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
@ -365,7 +365,7 @@ func (plugin *netPlugin) endpointOperInfo(w http.ResponseWriter, r *http.Request
// Encode response.
resp := endpointOperInfoResponse{Value: epInfo.Data}
err = plugin.Listener.Encode(w, &resp)
err = common.Encode(w, &resp)
log.Response(plugin.Name, &resp, returnCode, returnStr, err)
}

Просмотреть файл

@ -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)
}

Просмотреть файл

@ -38,8 +38,16 @@ type ServiceConfig struct {
Listener *acn.Listener
ErrChan chan<- error
Store store.KeyValueStore
Server server
ChannelMode string
TlsSettings tls.TlsSettings
TLSSettings tls.TlsSettings
}
// server struct to store primaryInterfaceIP from VM, port where customer provides by -p and temporary flag EnableLocalServer
type server struct {
PrimaryInterfaceIP string
Port string
EnableLocalServer bool // TODO: Remove this flag once -c option gets deprecated
}
// NewService creates a new Service object.

Просмотреть файл

@ -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"
"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 := common.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 = common.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 = common.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 = common.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 := common.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 = common.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 = common.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 = common.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 = common.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 = common.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 := common.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 = common.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 := common.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 = common.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 := common.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 := common.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 := common.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 := common.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 := common.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 := common.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 := common.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 := common.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 = common.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 := common.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 = common.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 := common.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 = common.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 := common.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 = common.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 := common.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 = common.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 := common.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 = common.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 := common.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 = common.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 := common.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 = common.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 := common.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 = common.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 := common.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 = common.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 = common.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 = common.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 = common.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 = common.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 := common.Encode(w, &nmAgentSupportedApisResponse)
logger.Response(service.Name, nmAgentSupportedApisResponse, resp.ReturnCode, serviceErr)
}

Просмотреть файл

@ -1684,6 +1684,8 @@ func startService() error {
return err
}
svc = service.(*HTTPRestService)
svc.Service.Options[acncommon.OptCnsURL] = ""
svc.Service.Options[acncommon.OptCnsPort] = ""
svc.Name = "cns-test-server"
nmagentClient.GetNCVersionListF = func(context.Context) (nmagent.NCVersionList, error) {
@ -1720,6 +1722,9 @@ func startService() error {
file, _ := os.Create(cnsJsonFileName)
file.Close()
// mock localhost as primary interface IP
config.Server.PrimaryInterfaceIP = "localhost"
err = service.Init(&config)
if err != nil {
logger.Errorf("Failed to Init CNS, err:%v.\n", err)

Просмотреть файл

@ -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 map[string]*IPInfo
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
}
@ -1104,7 +1104,7 @@ func (service *HTTPRestService) UpdateEndpointHandler(w http.ResponseWriter, r *
Message: 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
}
@ -1116,7 +1116,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
}
@ -1125,7 +1125,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)
}

Просмотреть файл

@ -186,6 +186,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.Server.PrimaryInterfaceIP = primaryInterface.PrimaryIP
serviceState := &httpRestServiceState{
Networks: make(map[string]*networkInfo),
joinedNetworks: make(map[string]struct{}),

Просмотреть файл

@ -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)
}

Просмотреть файл

@ -1,12 +1,14 @@
package v2
import (
"context"
"net/http"
"github.com/Azure/azure-container-networking/cns"
"github.com/Azure/azure-container-networking/cns/logger"
"github.com/Azure/azure-container-networking/cns/restserver"
"github.com/labstack/echo/v4"
"go.uber.org/zap"
"github.com/pkg/errors"
)
type Server struct {
@ -17,28 +19,38 @@ func New(s *restserver.HTTPRestService) *Server {
return &Server{s}
}
func (s Server) Start(log *zap.Logger, addr string) {
func (s Server) Start(ctx context.Context, addr string) error {
e := echo.New()
e.HideBanner = true
e.GET(cns.RequestIPConfig, echo.WrapHandler(restserver.NewHandlerFuncWithHistogram(s.RequestIPConfigHandler, restserver.HTTPRequestLatency)))
e.GET(cns.RequestIPConfigs, echo.WrapHandler(restserver.NewHandlerFuncWithHistogram(s.RequestIPConfigsHandler, restserver.HTTPRequestLatency)))
e.GET(cns.ReleaseIPConfig, echo.WrapHandler(restserver.NewHandlerFuncWithHistogram(s.ReleaseIPConfigHandler, restserver.HTTPRequestLatency)))
e.GET(cns.ReleaseIPConfigs, echo.WrapHandler(restserver.NewHandlerFuncWithHistogram(s.ReleaseIPConfigsHandler, restserver.HTTPRequestLatency)))
e.GET(cns.PathDebugIPAddresses, echo.WrapHandler(http.HandlerFunc(s.HandleDebugIPAddresses)))
e.GET(cns.PathDebugPodContext, echo.WrapHandler(http.HandlerFunc(s.HandleDebugPodContext)))
e.GET(cns.PathDebugRestData, echo.WrapHandler(http.HandlerFunc(s.HandleDebugRestData)))
e.GET(cns.GetNetworkContainerByOrchestratorContext, echo.WrapHandler(http.HandlerFunc(s.GetNetworkContainerByOrchestratorContext)))
e.GET(cns.GetAllNetworkContainers, echo.WrapHandler(http.HandlerFunc(s.GetAllNetworkContainers)))
e.GET(cns.CreateHostNCApipaEndpointPath, echo.WrapHandler(http.HandlerFunc(s.CreateHostNCApipaEndpoint)))
e.GET(cns.DeleteHostNCApipaEndpointPath, echo.WrapHandler(http.HandlerFunc(s.DeleteHostNCApipaEndpoint)))
e.POST(cns.RequestIPConfig, echo.WrapHandler(restserver.NewHandlerFuncWithHistogram(s.RequestIPConfigHandler, restserver.HTTPRequestLatency)))
e.POST(cns.RequestIPConfigs, echo.WrapHandler(restserver.NewHandlerFuncWithHistogram(s.RequestIPConfigsHandler, restserver.HTTPRequestLatency)))
e.POST(cns.ReleaseIPConfig, echo.WrapHandler(restserver.NewHandlerFuncWithHistogram(s.ReleaseIPConfigHandler, restserver.HTTPRequestLatency)))
e.POST(cns.ReleaseIPConfigs, echo.WrapHandler(restserver.NewHandlerFuncWithHistogram(s.ReleaseIPConfigsHandler, restserver.HTTPRequestLatency)))
e.POST(cns.PathDebugIPAddresses, echo.WrapHandler(http.HandlerFunc(s.HandleDebugIPAddresses)))
e.POST(cns.PathDebugPodContext, echo.WrapHandler(http.HandlerFunc(s.HandleDebugPodContext)))
e.POST(cns.PathDebugRestData, echo.WrapHandler(http.HandlerFunc(s.HandleDebugRestData)))
e.POST(cns.GetNetworkContainerByOrchestratorContext, echo.WrapHandler(http.HandlerFunc(s.GetNetworkContainerByOrchestratorContext)))
e.POST(cns.GetAllNetworkContainers, echo.WrapHandler(http.HandlerFunc(s.GetAllNetworkContainers)))
e.POST(cns.CreateHostNCApipaEndpointPath, echo.WrapHandler(http.HandlerFunc(s.CreateHostNCApipaEndpoint)))
e.POST(cns.DeleteHostNCApipaEndpointPath, echo.WrapHandler(http.HandlerFunc(s.DeleteHostNCApipaEndpoint)))
// for handlers 2.0
e.GET(cns.V2Prefix+cns.GetNetworkContainerByOrchestratorContext, echo.WrapHandler(http.HandlerFunc(s.GetNetworkContainerByOrchestratorContext)))
e.GET(cns.V2Prefix+cns.GetAllNetworkContainers, echo.WrapHandler(http.HandlerFunc(s.GetAllNetworkContainers)))
e.GET(cns.V2Prefix+cns.CreateHostNCApipaEndpointPath, echo.WrapHandler(http.HandlerFunc(s.CreateHostNCApipaEndpoint)))
e.GET(cns.V2Prefix+cns.DeleteHostNCApipaEndpointPath, echo.WrapHandler(http.HandlerFunc(s.DeleteHostNCApipaEndpoint)))
e.POST(cns.V2Prefix+cns.GetNetworkContainerByOrchestratorContext, echo.WrapHandler(http.HandlerFunc(s.GetNetworkContainerByOrchestratorContext)))
e.POST(cns.V2Prefix+cns.GetAllNetworkContainers, echo.WrapHandler(http.HandlerFunc(s.GetAllNetworkContainers)))
e.POST(cns.V2Prefix+cns.CreateHostNCApipaEndpointPath, echo.WrapHandler(http.HandlerFunc(s.CreateHostNCApipaEndpoint)))
e.POST(cns.V2Prefix+cns.DeleteHostNCApipaEndpointPath, echo.WrapHandler(http.HandlerFunc(s.DeleteHostNCApipaEndpoint)))
if err := e.Start(addr); err != nil {
log.Error("failed to run server", zap.Error(err))
logger.Errorf("failed to run echo server due to %+v", err)
return errors.Wrap(err, "failed to start echo server")
}
// after context is done, shutdown local server
<-ctx.Done()
if err := e.Shutdown(ctx); err != nil {
logger.Errorf("failed to shutdown echo server due to %+v", err)
return errors.Wrap(err, "failed to shutdown echo server")
}
return nil
}

Просмотреть файл

@ -0,0 +1,98 @@
package v2
import (
"net"
"net/url"
"testing"
"time"
"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"
acncommon "github.com/Azure/azure-container-networking/common"
"github.com/pkg/errors"
)
// TestStartServices will test three scenarios:
// 1. when customer provides -p option, make sure local server is running and server is using this port
// 2. when customer provides -c option, local server will this -c URL
func TestStartServerWithCNSPort(t *testing.T) {
var err error
logger.InitLogger("testlogs", 0, 0, "./")
cnsPort := "8000"
// Create the service with -p 8000
if err = startService(cnsPort, ""); err != nil {
t.Fatalf("Failed to connect to CNS Service on expected port:%s. Error: %v", cnsPort, err)
}
}
func TestStartServerWithCNSURL(t *testing.T) {
var err error
logger.InitLogger("testlogs", 0, 0, "./")
// Create the service with -c "localhost:8000"
cnsURL := "tcp://localhost:8500"
if err = startService("", cnsURL); err != nil {
t.Fatalf("Failed to connect to CNS Service by this cns url:%s. Error: %v", cnsURL, err)
}
}
// startService will return a URL that running server is using and check if sever can start
// mock primaryVMIP as a fixed IP
func startService(cnsPort, cnsURL string) error {
// Create the service.
config := common.ServiceConfig{}
nmagentClient := &fakes.NMAgentClientFake{}
service, err := restserver.NewHTTPRestService(&config, &fakes.WireserverClientFake{}, &fakes.WireserverProxyFake{}, nmagentClient, nil, nil, nil)
if err != nil {
return errors.Wrap(err, "Failed to initialize service")
}
if service != nil {
service.Name = "cns-test-server"
service.SetOption(acncommon.OptCnsPort, cnsPort)
service.SetOption(acncommon.OptCnsURL, cnsURL)
config.Server.PrimaryInterfaceIP = "localhost"
err = service.Init(&config)
if err != nil {
logger.Errorf("Failed to Init CNS, err:%v.\n", err)
return errors.Wrap(err, "Failed to Init CNS")
}
err = service.Start(&config)
if err != nil {
logger.Errorf("Failed to start CNS, err:%v.\n", err)
return errors.Wrap(err, "Failed to Start CNS")
}
}
if cnsPort == "" {
cnsPort = "10090"
}
// check if we can reach this URL
urls := "localhost:" + cnsPort
if cnsURL != "" {
u, _ := url.Parse(cnsURL)
port := u.Port()
urls = "localhost:" + port
}
_, err = net.DialTimeout("tcp", urls, 10*time.Millisecond)
if err != nil {
return errors.Wrapf(err, "Failed to check reachability to urls %+v", urls)
}
service.Stop()
return nil
}

Просмотреть файл

@ -24,9 +24,8 @@ import (
)
const (
// Default CNS server URL.
defaultAPIServerURL = "tcp://localhost:10090"
genericData = "com.microsoft.azure.network.generic"
defaultAPIServerPort = "10090"
genericData = "com.microsoft.azure.network.generic"
)
// Service defines Container Networking Service.
@ -48,14 +47,85 @@ 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 {
var (
err error
nodeURL *url.URL
)
// if cnsURL is empty the VM primary interface IP will be used
// if customer specifies -c option, then use this URL with warning message and it will be deprecated soon
cnsURL, ok := service.GetOption(acn.OptCnsURL).(string)
if !ok {
return errors.New("cnsURL type is wrong")
}
return urls
// if customer provides port number by -p option, then use VM IP with this port and localhost server also uses this port
// otherwise it will use defaultAPIServerPort 10090
cnsPort, ok := service.GetOption(acn.OptCnsPort).(string)
if !ok {
return errors.New("cnsPort type is wrong")
}
if cnsURL == "" {
config.Server.EnableLocalServer = true
// get VM primary interface's private IP
// if customer does use -p option, then use port number customers provide
if cnsPort == "" {
nodeURL, err = url.Parse(fmt.Sprintf("tcp://%s:%s", config.Server.PrimaryInterfaceIP, defaultAPIServerPort))
} else {
config.Server.Port = cnsPort
nodeURL, err = url.Parse(fmt.Sprintf("tcp://%s:%s", config.Server.PrimaryInterfaceIP, cnsPort))
}
if err != nil {
return errors.Wrap(err, "Failed to parse URL for legacy server")
}
} else {
// use the URL that customer provides by -c
logger.Printf("user specifies -c option")
// do not enable local server if customer uses -c option
config.Server.EnableLocalServer = false
nodeURL, err = url.Parse(cnsURL)
if err != nil {
return errors.Wrap(err, "Failed to parse URL that customer provides")
}
}
logger.Debugf("CNS remote server url: %+v", nodeURL)
nodeListener, err := acn.NewListener(nodeURL)
if err != nil {
return errors.Wrap(err, "Failed to construct url for node listener")
}
// 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(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) //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 := 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.
@ -67,45 +137,10 @@ func (service *Service) Initialize(config *common.ServiceConfig) error {
return errors.Wrap(err, "failed to initialize")
}
// 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 != "" {
// 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)
// Start the listener and HTTP and HTTPS server.
tlsConfig, err := getTLSConfig(config.TlsSettings, config.ErrChan)
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
}
}
logger.Printf("HTTP listener will be started later after CNS state has been reconciled")
config.Listener = listener
if err := service.AddListener(config); err != nil {
return errors.Wrap(err, "failed to initialize listener")
}
service.Listener = config.Listener
log.Debugf("[Azure CNS] Successfully initialized a service with config: %+v", config)
return nil
}
@ -226,6 +261,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())
}

Просмотреть файл

@ -43,6 +43,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"
restserverv2 "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"
@ -101,7 +102,9 @@ const (
// envVarEnableCNIConflistGeneration enables cni conflist generation if set (value doesn't matter)
envVarEnableCNIConflistGeneration = "CNS_ENABLE_CNI_CONFLIST_GENERATION"
cnsReqTimeout = 15 * time.Second
cnsReqTimeout = 15 * time.Second
defaultLocalServerIP = "localhost"
defaultLocalServerPort = "10090"
)
type cniConflistScenario string
@ -200,6 +203,13 @@ var args = acn.ArgumentList{
Type: "string",
DefaultValue: "",
},
{
Name: acn.OptCnsPort,
Shorthand: acn.OptCnsPortAlias,
Description: "Set the URL port for CNS to listen on",
Type: "string",
DefaultValue: "",
},
{
Name: acn.OptStartAzureCNM,
Shorthand: acn.OptStartAzureCNMAlias,
@ -490,6 +500,7 @@ func main() {
cniPath := acn.GetArg(acn.OptNetPluginPath).(string)
cniConfigFile := acn.GetArg(acn.OptNetPluginConfigFile).(string)
cnsURL := acn.GetArg(acn.OptCnsURL).(string)
cnsPort := acn.GetArg(acn.OptCnsPort).(string)
logLevel := acn.GetArg(acn.OptLogLevel).(int)
logTarget := acn.GetArg(acn.OptLogTarget).(int)
logDirectory := acn.GetArg(acn.OptLogLocation).(string)
@ -735,7 +746,7 @@ func main() {
Logger: logger.Log,
}
httpRestService, err := restserver.NewHTTPRestService(&config, wsclient, &wsProxy, nmaClient,
httpRemoteRestService, err := restserver.NewHTTPRestService(&config, wsclient, &wsProxy, nmaClient,
endpointStateStore, conflistGenerator, homeAzMonitor)
if err != nil {
logger.Errorf("Failed to create CNS object, err:%v.\n", err)
@ -743,14 +754,15 @@ func main() {
}
// Set CNS options.
httpRestService.SetOption(acn.OptCnsURL, cnsURL)
httpRestService.SetOption(acn.OptNetPluginPath, cniPath)
httpRestService.SetOption(acn.OptNetPluginConfigFile, cniConfigFile)
httpRestService.SetOption(acn.OptCreateDefaultExtNetworkType, createDefaultExtNetworkType)
httpRestService.SetOption(acn.OptHttpConnectionTimeout, httpConnectionTimeout)
httpRestService.SetOption(acn.OptHttpResponseHeaderTimeout, httpResponseHeaderTimeout)
httpRestService.SetOption(acn.OptProgramSNATIPTables, cnsconfig.ProgramSNATIPTables)
httpRestService.SetOption(acn.OptManageEndpointState, cnsconfig.ManageEndpointState)
httpRemoteRestService.SetOption(acn.OptCnsURL, cnsURL)
httpRemoteRestService.SetOption(acn.OptCnsPort, cnsPort)
httpRemoteRestService.SetOption(acn.OptNetPluginPath, cniPath)
httpRemoteRestService.SetOption(acn.OptNetPluginConfigFile, cniConfigFile)
httpRemoteRestService.SetOption(acn.OptCreateDefaultExtNetworkType, createDefaultExtNetworkType)
httpRemoteRestService.SetOption(acn.OptHttpConnectionTimeout, httpConnectionTimeout)
httpRemoteRestService.SetOption(acn.OptHttpResponseHeaderTimeout, httpResponseHeaderTimeout)
httpRemoteRestService.SetOption(acn.OptProgramSNATIPTables, cnsconfig.ProgramSNATIPTables)
httpRemoteRestService.SetOption(acn.OptManageEndpointState, cnsconfig.ManageEndpointState)
// Create default ext network if commandline option is set
if len(strings.TrimSpace(createDefaultExtNetworkType)) > 0 {
@ -762,10 +774,10 @@ func main() {
}
}
logger.Printf("[Azure CNS] Initialize HTTPRestService")
if httpRestService != nil {
logger.Printf("[Azure CNS] Initialize HTTPRemoteRestService")
if httpRemoteRestService != nil {
if cnsconfig.UseHTTPS {
config.TlsSettings = localtls.TlsSettings{
config.TLSSettings = localtls.TlsSettings{
TLSSubjectName: cnsconfig.TLSSubjectName,
TLSCertificatePath: cnsconfig.TLSCertificatePath,
TLSPort: cnsconfig.TLSPort,
@ -776,7 +788,7 @@ func main() {
}
}
err = httpRestService.Init(&config)
err = httpRemoteRestService.Init(&config)
if err != nil {
logger.Errorf("Failed to init HTTPService, err:%v.\n", err)
return
@ -840,7 +852,7 @@ func main() {
logger.Printf("Set GlobalPodInfoScheme %v (InitializeFromCNI=%t)", cns.GlobalPodInfoScheme, cnsconfig.InitializeFromCNI)
err = InitializeCRDState(rootCtx, httpRestService, cnsconfig)
err = InitializeCRDState(rootCtx, httpRemoteRestService, cnsconfig)
if err != nil {
logger.Errorf("Failed to start CRD Controller, err:%v.\n", err)
return
@ -848,26 +860,51 @@ func main() {
}
// Initialize multi-tenant controller if the CNS is running in MultiTenantCRD mode.
// It must be started before we start HTTPRestService.
// It must be started before we start HTTPRemoteRestService.
if config.ChannelMode == cns.MultiTenantCRD {
err = InitializeMultiTenantController(rootCtx, httpRestService, *cnsconfig)
err = InitializeMultiTenantController(rootCtx, httpRemoteRestService, *cnsconfig)
if err != nil {
logger.Errorf("Failed to start multiTenantController, err:%v.\n", err)
return
}
}
// if user provides cns url by -c option, then only start HTTP remote server using this url
logger.Printf("[Azure CNS] Start HTTP Remote server")
if httpRemoteRestService != nil {
if cnsconfig.EnablePprof {
httpRemoteRestService.RegisterPProfEndpoints()
}
err = httpRemoteRestService.Start(&config)
if err != nil {
logger.Errorf("Failed to start CNS, err:%v.\n", err)
return
}
}
logger.Printf("[Azure CNS] Start HTTP listener")
if httpRestService != nil {
if cnsconfig.EnablePprof {
httpRestService.RegisterPProfEndpoints()
// if user does not provide cns url by -c option, then start http local server
// TODO: we will deprecated -c option in next phase and start local server in any case
if config.Server.EnableLocalServer {
logger.Printf("[Azure CNS] Start HTTP local server")
var localServerURL string
if config.Server.Port != "" {
localServerURL = fmt.Sprintf(defaultLocalServerIP + ":" + config.Server.Port)
} else {
localServerURL = fmt.Sprintf(defaultLocalServerIP + ":" + defaultLocalServerPort)
}
err = httpRestService.Start(&config)
if err != nil {
logger.Errorf("Failed to start CNS, err:%v.\n", err)
return
httpLocalRestService := restserverv2.New(httpRemoteRestService)
if httpLocalRestService != nil {
go func() {
err = httpLocalRestService.Start(rootCtx, localServerURL)
if err != nil {
logger.Errorf("Failed to start local echo server, err:%v.\n", err)
return
}
}()
}
}
@ -896,7 +933,7 @@ func main() {
if !disableTelemetry {
go logger.SendHeartBeat(rootCtx, cnsconfig.TelemetrySettings.HeartBeatIntervalInMins)
go httpRestService.SendNCSnapShotPeriodically(rootCtx, cnsconfig.TelemetrySettings.SnapshotIntervalInMins)
go httpRemoteRestService.SendNCSnapShotPeriodically(rootCtx, cnsconfig.TelemetrySettings.SnapshotIntervalInMins)
}
// If CNS is running on managed DNC mode
@ -909,14 +946,14 @@ func main() {
return
}
httpRestService.SetOption(acn.OptPrivateEndpoint, privateEndpoint)
httpRestService.SetOption(acn.OptInfrastructureNetworkID, infravnet)
httpRestService.SetOption(acn.OptNodeID, nodeID)
httpRemoteRestService.SetOption(acn.OptPrivateEndpoint, privateEndpoint)
httpRemoteRestService.SetOption(acn.OptInfrastructureNetworkID, infravnet)
httpRemoteRestService.SetOption(acn.OptNodeID, nodeID)
// Passing in the default http client that already implements Do function
standardClient := http.DefaultClient
registerErr := registerNode(rootCtx, standardClient, httpRestService, privateEndpoint, infravnet, nodeID, nmaClient)
registerErr := registerNode(rootCtx, standardClient, httpRemoteRestService, privateEndpoint, infravnet, nodeID, nmaClient)
if registerErr != nil {
logger.Errorf("[Azure CNS] Registering Node failed with error: %v PrivateEndpoint: %s InfrastructureNetworkID: %s NodeID: %s",
registerErr,
@ -930,7 +967,7 @@ func main() {
tickerChannel := time.Tick(time.Duration(cnsconfig.ManagedSettings.NodeSyncIntervalInSeconds) * time.Second)
for {
<-tickerChannel
httpRestService.SyncNodeStatus(ep, vnet, node, json.RawMessage{})
httpRemoteRestService.SyncNodeStatus(ep, vnet, node, json.RawMessage{})
}
}(privateEndpoint, infravnet, nodeID)
}
@ -1009,8 +1046,8 @@ func main() {
logger.Printf("stop cns service")
// Cleanup.
if httpRestService != nil {
httpRestService.Stop()
if httpRemoteRestService != nil {
httpRemoteRestService.Stop()
}
if startCNM {

Просмотреть файл

@ -18,6 +18,8 @@ const (
OptAPIServerURLAlias = "u"
OptCnsURL = "cns-url"
OptCnsURLAlias = "c"
OptCnsPort = "cns-port"
OptCnsPortAlias = "p"
// Logging level.
OptLogLevel = "log-level"

Просмотреть файл

@ -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)