diff --git a/cns/NetworkContainerContract.go b/cns/NetworkContainerContract.go index afb7978b9b..3d7530dac2 100644 --- a/cns/NetworkContainerContract.go +++ b/cns/NetworkContainerContract.go @@ -529,10 +529,11 @@ func (p PublishNetworkContainerResponse) String() string { // UnpublishNetworkContainerRequest specifies request to unpublish network container via NMAgent. type UnpublishNetworkContainerRequest struct { - NetworkID string - NetworkContainerID string - JoinNetworkURL string - DeleteNetworkContainerURL string + NetworkID string + NetworkContainerID string + JoinNetworkURL string + DeleteNetworkContainerURL string + DeleteNetworkContainerRequestBody []byte } // UnpublishNetworkContainerResponse specifies the response to unpublish network container request. diff --git a/cns/fakes/wireserverproxyfake.go b/cns/fakes/wireserverproxyfake.go index 2e8bd3195a..e6e52e7c54 100644 --- a/cns/fakes/wireserverproxyfake.go +++ b/cns/fakes/wireserverproxyfake.go @@ -12,7 +12,7 @@ import ( type WireserverProxyFake struct { JoinNetworkFunc func(context.Context, string) (*http.Response, error) PublishNCFunc func(context.Context, cns.NetworkContainerParameters, []byte) (*http.Response, error) - UnpublishNCFunc func(context.Context, cns.NetworkContainerParameters) (*http.Response, error) + UnpublishNCFunc func(context.Context, cns.NetworkContainerParameters, []byte) (*http.Response, error) } const defaultResponseBody = `{"httpStatusCode":"200"}` @@ -41,9 +41,9 @@ func (w *WireserverProxyFake) PublishNC(ctx context.Context, ncParams cns.Networ return defaultResponse(), nil } -func (w *WireserverProxyFake) UnpublishNC(ctx context.Context, ncParams cns.NetworkContainerParameters) (*http.Response, error) { +func (w *WireserverProxyFake) UnpublishNC(ctx context.Context, ncParams cns.NetworkContainerParameters, payload []byte) (*http.Response, error) { if w.UnpublishNCFunc != nil { - return w.UnpublishNCFunc(ctx, ncParams) + return w.UnpublishNCFunc(ctx, ncParams, payload) } return defaultResponse(), nil diff --git a/cns/restserver/api.go b/cns/restserver/api.go index eb8de07981..171657c666 100644 --- a/cns/restserver/api.go +++ b/cns/restserver/api.go @@ -1298,7 +1298,7 @@ func (service *HTTPRestService) unpublishNetworkContainer(w http.ResponseWriter, logger.Printf("[Azure-CNS] joined vnet %s during nc %s unpublish. wireserver response: %v", req.NetworkID, req.NetworkContainerID, string(joinBytes)) } - publishResp, err := service.wsproxy.UnpublishNC(ctx, ncParams) + publishResp, err := service.wsproxy.UnpublishNC(ctx, ncParams, req.DeleteNetworkContainerRequestBody) if err != nil { resp := cns.UnpublishNetworkContainerResponse{ Response: cns.Response{ diff --git a/cns/restserver/api_test.go b/cns/restserver/api_test.go index fb6b39c216..a60289a5c3 100644 --- a/cns/restserver/api_test.go +++ b/cns/restserver/api_test.go @@ -955,7 +955,7 @@ func TestUnpublishNCViaCNS(t *testing.T) { func TestUnpublishNCViaCNS401(t *testing.T) { wsproxy := fakes.WireserverProxyFake{ - UnpublishNCFunc: func(_ context.Context, _ cns.NetworkContainerParameters) (*http.Response, error) { + UnpublishNCFunc: func(_ context.Context, _ cns.NetworkContainerParameters, i []byte) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString(`{"httpStatusCode":"401"}`)), @@ -974,10 +974,11 @@ func TestUnpublishNCViaCNS401(t *testing.T) { joinNetworkURL := "http://" + nmagentEndpoint + "/dummyVnetURL" unpublishNCRequest := &cns.UnpublishNetworkContainerRequest{ - NetworkID: networkID, - NetworkContainerID: networkContainerID, - JoinNetworkURL: joinNetworkURL, - DeleteNetworkContainerURL: deleteNetworkContainerURL, + NetworkID: networkID, + NetworkContainerID: networkContainerID, + JoinNetworkURL: joinNetworkURL, + DeleteNetworkContainerURL: deleteNetworkContainerURL, + DeleteNetworkContainerRequestBody: []byte("{}"), } var body bytes.Buffer @@ -1035,10 +1036,11 @@ func unpublishNCViaCNS(networkID, networkContainerID, deleteNetworkContainerURL joinNetworkURL := "http://" + nmagentEndpoint + "/dummyVnetURL" unpublishNCRequest := &cns.UnpublishNetworkContainerRequest{ - NetworkID: networkID, - NetworkContainerID: networkContainerID, - JoinNetworkURL: joinNetworkURL, - DeleteNetworkContainerURL: deleteNetworkContainerURL, + NetworkID: networkID, + NetworkContainerID: networkContainerID, + JoinNetworkURL: joinNetworkURL, + DeleteNetworkContainerURL: deleteNetworkContainerURL, + DeleteNetworkContainerRequestBody: []byte("{}"), } var body bytes.Buffer diff --git a/cns/restserver/restserver.go b/cns/restserver/restserver.go index 743a5e6408..3ec5359a6a 100644 --- a/cns/restserver/restserver.go +++ b/cns/restserver/restserver.go @@ -47,7 +47,7 @@ type nmagentClient interface { type wireserverProxy interface { JoinNetwork(ctx context.Context, vnetID string) (*http.Response, error) PublishNC(ctx context.Context, ncParams cns.NetworkContainerParameters, payload []byte) (*http.Response, error) - UnpublishNC(ctx context.Context, ncParams cns.NetworkContainerParameters) (*http.Response, error) + UnpublishNC(ctx context.Context, ncParams cns.NetworkContainerParameters, payload []byte) (*http.Response, error) } // HTTPRestService represents http listener for CNS - Container Networking Service. diff --git a/cns/wireserver/proxy.go b/cns/wireserver/proxy.go index ad2540c453..d180ff9ccc 100644 --- a/cns/wireserver/proxy.go +++ b/cns/wireserver/proxy.go @@ -57,10 +57,17 @@ func (p *Proxy) PublishNC(ctx context.Context, ncParams cns.NetworkContainerPara return resp, nil } -func (p *Proxy) UnpublishNC(ctx context.Context, ncParams cns.NetworkContainerParameters) (*http.Response, error) { +func (p *Proxy) UnpublishNC(ctx context.Context, ncParams cns.NetworkContainerParameters, payload []byte) (*http.Response, error) { reqURL := fmt.Sprintf(unpublishNCURLFmt, p.Host, ncParams.AssociatedInterfaceID, ncParams.NCID, ncParams.AuthToken) - req, err := http.NewRequestWithContext(ctx, http.MethodPost, reqURL, bytes.NewBufferString(`""`)) + // a POST to wireserver must contain a body. For legacy purposes, + // an empty json string (two quote characters) should be sent by default. + body := []byte(`""`) + if len(payload) > 0 { + body = payload + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, reqURL, bytes.NewBuffer(body)) if err != nil { return nil, errors.Wrap(err, "wireserver proxy: unpublish nc: could not build http request") } diff --git a/nmagent/requests.go b/nmagent/requests.go index c520c3b773..16083ce673 100644 --- a/nmagent/requests.go +++ b/nmagent/requests.go @@ -278,7 +278,9 @@ var _ Request = DeleteContainerRequest{} // DeleteContainerRequest represents all information necessary to request that // NMAgent delete a particular network container type DeleteContainerRequest struct { - NCID string `json:"-"` // the Network Container ID + NCID string `json:"-"` // the Network Container ID + AzID uint `json:"azID"` // home AZ of the Network Container + EnableAZR bool `json:"enableAZR"` // whether AZR is enabled or not // PrimaryAddress is the primary customer address of the interface in the // management VNET