in cns/restserver/util.go [605:708]
func (service *HTTPRestService) attachOrDetachHelper(req cns.ConfigureContainerNetworkingRequest, operation, method string) cns.Response {
if method != "POST" {
return cns.Response{
ReturnCode: types.InvalidParameter,
Message: "[Azure CNS] Error. " + operation + "ContainerToNetwork did not receive a POST.",
}
}
if req.Containerid == "" {
return cns.Response{
ReturnCode: types.DockerContainerNotSpecified,
Message: "[Azure CNS] Error. Containerid is empty",
}
}
if req.NetworkContainerid == "" {
return cns.Response{
ReturnCode: types.NetworkContainerNotSpecified,
Message: "[Azure CNS] Error. NetworkContainerid is empty",
}
}
existing, ok := service.getNetworkContainerDetails(cns.SwiftPrefix + req.NetworkContainerid)
if service.ChannelMode == cns.Managed && operation == attach {
if ok {
if !existing.VfpUpdateComplete {
ctx, cancel := context.WithTimeout(context.Background(), nmaAPICallTimeout)
defer cancel()
ncVersionListResp, err := service.nma.GetNCVersionList(ctx)
if err != nil {
logger.Errorf("failed to get nc version list from nmagent")
return cns.Response{
ReturnCode: types.NmAgentInternalServerError,
Message: err.Error(),
}
}
nmaNCs := map[string]string{}
for _, nc := range ncVersionListResp.Containers {
// store nmaNCID as lower case to allow case insensitive comparison with nc stored in CNS
nmaNCs[strings.TrimPrefix(lowerCaseNCGuid(nc.NetworkContainerID), cns.SwiftPrefix)] = nc.Version
}
_, returnCode, message := service.isNCWaitingForUpdate(existing.CreateNetworkContainerRequest.Version, req.NetworkContainerid, nmaNCs)
if returnCode == types.NetworkContainerVfpProgramPending {
return cns.Response{
ReturnCode: returnCode,
Message: message,
}
}
}
} else {
var (
dncEP = service.GetOption(acn.OptPrivateEndpoint).(string)
infraVnet = service.GetOption(acn.OptInfrastructureNetworkID).(string)
nodeID = service.GetOption(acn.OptNodeID).(string)
)
returnCode, msg := service.SyncNodeStatus(dncEP, infraVnet, nodeID, json.RawMessage{})
if returnCode != types.Success {
return cns.Response{
ReturnCode: returnCode,
Message: msg,
}
}
existing, _ = service.getNetworkContainerDetails(cns.SwiftPrefix + req.NetworkContainerid)
}
} else if !ok {
return cns.Response{
ReturnCode: types.NotFound,
Message: fmt.Sprintf("[Azure CNS] Error. Network Container %s does not exist.", req.NetworkContainerid),
}
}
var returnCode types.ResponseCode
var returnMessage string
switch service.state.OrchestratorType {
case cns.Batch:
podInfo, err := cns.UnmarshalPodInfo(existing.CreateNetworkContainerRequest.OrchestratorContext)
if err != nil {
returnCode = types.UnexpectedError
returnMessage = fmt.Sprintf("Unmarshalling orchestrator context failed with error %+v", err)
} else {
nc := service.networkContainer
netPluginConfig := service.getNetPluginDetails()
switch operation {
case attach:
err = nc.Attach(podInfo, req.Containerid, netPluginConfig)
case detach:
err = nc.Detach(podInfo, req.Containerid, netPluginConfig)
}
if err != nil {
returnCode = types.UnexpectedError
returnMessage = fmt.Sprintf("[Azure CNS] Error. "+operation+"ContainerToNetwork failed %+v", err.Error())
}
}
default:
returnMessage = fmt.Sprintf("[Azure CNS] Invalid orchestrator type %v", service.state.OrchestratorType)
returnCode = types.UnsupportedOrchestratorType
}
return cns.Response{
ReturnCode: returnCode,
Message: returnMessage,
}
}