diff --git a/cni/network/network.go b/cni/network/network.go index 093d812426..fc8db6b988 100644 --- a/cni/network/network.go +++ b/cni/network/network.go @@ -15,6 +15,7 @@ import ( "github.com/Azure/azure-container-networking/aitelemetry" "github.com/Azure/azure-container-networking/cni" + "github.com/Azure/azure-container-networking/cni/utils" "github.com/Azure/azure-container-networking/cns" "github.com/Azure/azure-container-networking/cns/cnsclient" "github.com/Azure/azure-container-networking/common" @@ -710,6 +711,7 @@ func (plugin *netPlugin) Get(args *cniSkel.CmdArgs) error { // Initialize values from network config. if networkId, err = getNetworkName(k8sPodName, k8sNamespace, args.IfName, nwCfg); err != nil { + // TODO: Ideally we should return from here only. log.Printf("[cni-net] Failed to extract network name from network config. error: %v", err) } @@ -796,8 +798,16 @@ func (plugin *netPlugin) Delete(args *cniSkel.CmdArgs) error { } // Initialize values from network config. - if networkId, err = getNetworkName(k8sPodName, k8sNamespace, args.IfName, nwCfg); err != nil { + networkId, err = getNetworkName(k8sPodName, k8sNamespace, args.IfName, nwCfg) + + // If error is not found error, then we ignore it, to comply with CNI SPEC. + if err != nil { log.Printf("[cni-net] Failed to extract network name from network config. error: %v", err) + + if !utils.IsNotFoundError(err) { + err = plugin.Errorf("Failed to extract network name from network config. error: %v", err) + return err + } } endpointId := GetEndpointID(args) diff --git a/cni/network/network_windows.go b/cni/network/network_windows.go index ab4b7c19ab..5aad6b526d 100644 --- a/cni/network/network_windows.go +++ b/cni/network/network_windows.go @@ -153,19 +153,30 @@ func updateSubnetPrefix(cnsNwConfig *cns.GetNetworkContainerResponse, subnetPref return nil } -func getNetworkName(podName, podNs, ifName string, nwCfg *cni.NetworkConfig) (networkName string, err error) { +func getNetworkName(podName, podNs, ifName string, nwCfg *cni.NetworkConfig) (string, error) { + var ( + networkName string + err error + cnsNetworkConfig *cns.GetNetworkContainerResponse + ) + networkName = nwCfg.Name err = nil + if nwCfg.MultiTenancy { determineWinVer() if len(strings.TrimSpace(podName)) == 0 || len(strings.TrimSpace(podNs)) == 0 { err = fmt.Errorf("POD info cannot be empty. PodName: %s, PodNamespace: %s", podName, podNs) - return + return networkName, err } - _, cnsNetworkConfig, _, err := getContainerNetworkConfiguration(nwCfg, podName, podNs, ifName) + _, cnsNetworkConfig, _, err = getContainerNetworkConfiguration(nwCfg, podName, podNs, ifName) if err != nil { - log.Printf("GetContainerNetworkConfiguration failed for podname %v namespace %v with error %v", podName, podNs, err) + log.Printf( + "GetContainerNetworkConfiguration failed for podname %v namespace %v with error %v", + podName, + podNs, + err) } else { var subnet net.IPNet if err = updateSubnetPrefix(cnsNetworkConfig, &subnet); err == nil { @@ -177,7 +188,7 @@ func getNetworkName(podName, podNs, ifName string, nwCfg *cni.NetworkConfig) (ne } } - return + return networkName, err } func setupInfraVnetRoutingForMultitenancy( diff --git a/cni/utils/errutils.go b/cni/utils/errutils.go new file mode 100644 index 0000000000..86a51091a1 --- /dev/null +++ b/cni/utils/errutils.go @@ -0,0 +1,15 @@ +package utils + +import ( + "github.com/Azure/azure-container-networking/cns/cnsclient" + "github.com/Azure/azure-container-networking/cns/restserver" +) + +// TODO : Move to common directory like common, after fixing circular dependencies +func IsNotFoundError(err error) bool { + switch e := err.(type) { + case *cnsclient.CNSClientError: + return (e.Code == restserver.UnknownContainerID) + } + return false +} diff --git a/cns/cnsclient/cnsclient.go b/cns/cnsclient/cnsclient.go index 06954565d8..65b74feb27 100644 --- a/cns/cnsclient/cnsclient.go +++ b/cns/cnsclient/cnsclient.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/Azure/azure-container-networking/cns" + "github.com/Azure/azure-container-networking/cns/restserver" "github.com/Azure/azure-container-networking/log" ) @@ -44,15 +45,20 @@ func GetCnsClient() (*CNSClient, error) { var err error if cnsClient == nil { - err = fmt.Errorf("[Azure CNSClient] CNS Client not initialized") + err = &CNSClientError{ + restserver.UnexpectedError, + fmt.Errorf("[Azure CNSClient] CNS Client not initialized")} } return cnsClient, err } // GetNetworkConfiguration Request to get network config. -func (cnsClient *CNSClient) GetNetworkConfiguration(orchestratorContext []byte) (*cns.GetNetworkContainerResponse, error) { - var body bytes.Buffer +func (cnsClient *CNSClient) GetNetworkConfiguration(orchestratorContext []byte) ( + *cns.GetNetworkContainerResponse, error) { + var ( + body bytes.Buffer + ) httpc := &http.Client{} url := cnsClient.connectionURL + cns.GetNetworkContainerByOrchestratorContext @@ -65,13 +71,13 @@ func (cnsClient *CNSClient) GetNetworkConfiguration(orchestratorContext []byte) err := json.NewEncoder(&body).Encode(payload) if err != nil { log.Errorf("encoding json failed with %v", err) - return nil, err + return nil, &CNSClientError{restserver.UnexpectedError, err} } res, err := httpc.Post(url, contentTypeJSON, &body) if err != nil { log.Errorf("[Azure CNSClient] HTTP Post returned error %v", err.Error()) - return nil, err + return nil, &CNSClientError{restserver.UnexpectedError, err} } defer res.Body.Close() @@ -79,7 +85,7 @@ func (cnsClient *CNSClient) GetNetworkConfiguration(orchestratorContext []byte) if res.StatusCode != http.StatusOK { errMsg := fmt.Sprintf("[Azure CNSClient] GetNetworkConfiguration invalid http status code: %v", res.StatusCode) log.Errorf(errMsg) - return nil, fmt.Errorf(errMsg) + return nil, &CNSClientError{restserver.UnexpectedError, fmt.Errorf(errMsg)} } var resp cns.GetNetworkContainerResponse @@ -87,12 +93,15 @@ func (cnsClient *CNSClient) GetNetworkConfiguration(orchestratorContext []byte) err = json.NewDecoder(res.Body).Decode(&resp) if err != nil { log.Errorf("[Azure CNSClient] Error received while parsing GetNetworkConfiguration response resp:%v err:%v", res.Body, err.Error()) - return nil, err + return nil, &CNSClientError{restserver.UnexpectedError, err} } if resp.Response.ReturnCode != 0 { - log.Errorf("[Azure CNSClient] GetNetworkConfiguration received error response :%v", resp.Response.Message) - return nil, fmt.Errorf(resp.Response.Message) + log.Errorf( + "[Azure CNSClient] GetNetworkConfiguration received error response :%v , Code : %d", + resp.Response.Message, + resp.Response.ReturnCode) + return nil, &CNSClientError{resp.Response.ReturnCode, fmt.Errorf(resp.Response.Message)} } return &resp, nil diff --git a/cns/cnsclient/error.go b/cns/cnsclient/error.go new file mode 100644 index 0000000000..d68955fa1b --- /dev/null +++ b/cns/cnsclient/error.go @@ -0,0 +1,15 @@ +package cnsclient + +import ( + "fmt" +) + +// CNSClientError records an error and relevant code +type CNSClientError struct { + Code int + Err error +} + +func (e *CNSClientError) Error() string { + return fmt.Sprintf("[Azure CNSClient] Code: %d , Error: %v", e.Code, e.Err) +}