Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
da24d70
Switch PublishNetworkContainer to nmagent package
timraymond Aug 23, 2022
10f3d1b
Use Unpublish method from nmagent package
timraymond Aug 26, 2022
8ebe248
Use JoinNetwork from new nmagent client
timraymond Aug 26, 2022
e63161d
Add SupportedAPIs method to nmagent and use it
timraymond Aug 29, 2022
ae2d605
Add GetNCVersion to nmagent and use it in CNS
timraymond Aug 31, 2022
8a960d7
Use test helpers for context and checking errs
timraymond Aug 31, 2022
03e92be
Fix broken tests & improve the suite
timraymond Sep 2, 2022
461050f
Add GetNCVersionList endpoint to NMAgent client
timraymond Sep 6, 2022
4c912e6
Remove incorrect error shadowing
timraymond Oct 12, 2022
161383b
Replace error type assertions with errors.As
timraymond Oct 12, 2022
757d8be
Use context for joinNetwork
timraymond Oct 12, 2022
f1a0e1f
Add error wrapping to an otherwise-opaque error
timraymond Oct 12, 2022
bdf016c
Remove error shadowing in the tests
timraymond Oct 12, 2022
4f2da3e
Silence complaints about dynamic errors in tests
timraymond Oct 12, 2022
b51f3b1
Add missing return for fmt.Errorf
timraymond Oct 12, 2022
e862f6c
Remove yet another shadowed err
timraymond Oct 13, 2022
e07f2fc
Finish wiring in the NMAgent Client
timraymond Oct 14, 2022
ce89172
Add config for Wireserver to NMAgent Client
timraymond Oct 14, 2022
827f7d4
Silence the linter
timraymond Oct 14, 2022
4a2658a
Rename jnr -> req and nma -> nmagent
timraymond Oct 18, 2022
6ab0a2e
Rename NodeInquirer -> NodeInterrogator
timraymond Oct 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cns/NetworkContainerContract.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"

"github.com/Azure/azure-container-networking/cns/types"
"github.com/Azure/azure-container-networking/nmagent"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
)
Expand Down Expand Up @@ -496,7 +497,7 @@ type PublishNetworkContainerRequest struct {
NetworkContainerID string
JoinNetworkURL string
CreateNetworkContainerURL string
CreateNetworkContainerRequestBody []byte
CreateNetworkContainerRequestBody nmagent.PutNetworkContainerRequest
}

// NetworkContainerParameters parameters available in network container operations
Expand Down
9 changes: 5 additions & 4 deletions cns/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/Azure/azure-container-networking/cns/types"
"github.com/Azure/azure-container-networking/crd/nodenetworkconfig/api/v1alpha"
"github.com/Azure/azure-container-networking/log"
"github.com/Azure/azure-container-networking/nmagent"
"github.com/google/go-cmp/cmp"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -1032,14 +1033,14 @@ func TestPublishNC(t *testing.T) {
NetworkContainerID: "frob",
JoinNetworkURL: "http://example.com",
CreateNetworkContainerURL: "http://example.com",
CreateNetworkContainerRequestBody: []byte{},
CreateNetworkContainerRequestBody: nmagent.PutNetworkContainerRequest{},
},
&cns.PublishNetworkContainerRequest{
NetworkID: "foo",
NetworkContainerID: "frob",
JoinNetworkURL: "http://example.com",
CreateNetworkContainerURL: "http://example.com",
CreateNetworkContainerRequestBody: []byte{},
CreateNetworkContainerRequestBody: nmagent.PutNetworkContainerRequest{},
},
false,
},
Expand All @@ -1061,14 +1062,14 @@ func TestPublishNC(t *testing.T) {
NetworkContainerID: "frob",
JoinNetworkURL: "http://example.com",
CreateNetworkContainerURL: "http://example.com",
CreateNetworkContainerRequestBody: []byte{},
CreateNetworkContainerRequestBody: nmagent.PutNetworkContainerRequest{},
},
&cns.PublishNetworkContainerRequest{
NetworkID: "foo",
NetworkContainerID: "frob",
JoinNetworkURL: "http://example.com",
CreateNetworkContainerURL: "http://example.com",
CreateNetworkContainerRequestBody: []byte{},
CreateNetworkContainerRequestBody: nmagent.PutNetworkContainerRequest{},
},
true,
},
Expand Down
34 changes: 29 additions & 5 deletions cns/fakes/nmagentclientfake.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,39 @@ package fakes
import (
"context"

"github.com/Azure/azure-container-networking/cns/nmagent"
"github.com/Azure/azure-container-networking/nmagent"
)

// NMAgentClientFake can be used to query to VM Host info.
type NMAgentClientFake struct {
GetNCVersionListFunc func(context.Context) (*nmagent.NetworkContainerListResponse, error)
PutNetworkContainerF func(context.Context, *nmagent.PutNetworkContainerRequest) error
DeleteNetworkContainerF func(context.Context, nmagent.DeleteContainerRequest) error
JoinNetworkF func(context.Context, nmagent.JoinNetworkRequest) error
SupportedAPIsF func(context.Context) ([]string, error)
GetNCVersionF func(context.Context, nmagent.NCVersionRequest) (nmagent.NCVersion, error)
GetNCVersionListF func(context.Context) (nmagent.NCVersionList, error)
}

// GetNcVersionListWithOutToken is mock implementation to return nc version list.
func (c *NMAgentClientFake) GetNCVersionList(ctx context.Context) (*nmagent.NetworkContainerListResponse, error) {
return c.GetNCVersionListFunc(ctx)
func (c *NMAgentClientFake) PutNetworkContainer(ctx context.Context, req *nmagent.PutNetworkContainerRequest) error {
return c.PutNetworkContainerF(ctx, req)
}

func (c *NMAgentClientFake) DeleteNetworkContainer(ctx context.Context, req nmagent.DeleteContainerRequest) error {
return c.DeleteNetworkContainerF(ctx, req)
}

func (c *NMAgentClientFake) JoinNetwork(ctx context.Context, req nmagent.JoinNetworkRequest) error {
return c.JoinNetworkF(ctx, req)
}

func (c *NMAgentClientFake) SupportedAPIs(ctx context.Context) ([]string, error) {
return c.SupportedAPIsF(ctx)
}

func (c *NMAgentClientFake) GetNCVersion(ctx context.Context, req nmagent.NCVersionRequest) (nmagent.NCVersion, error) {
return c.GetNCVersionF(ctx, req)
}

func (c *NMAgentClientFake) GetNCVersionList(ctx context.Context) (nmagent.NCVersionList, error) {
return c.GetNCVersionListF(ctx)
}
211 changes: 0 additions & 211 deletions cns/nmagent/client.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
package nmagent

import (
"bytes"
"context"
"encoding/json"
"encoding/xml"
"fmt"
"io"
"net/http"
"net/url"
"time"

"github.com/Azure/azure-container-networking/cns/logger"
"github.com/Azure/azure-container-networking/common"
"github.com/pkg/errors"
)

const (
Expand Down Expand Up @@ -41,10 +29,6 @@ type NetworkContainerResponse struct {
Version string `json:"version"`
}

type SupportedAPIsResponseXML struct {
SupportedApis []string `xml:"type"`
}

type ContainerInfo struct {
NetworkContainerID string `json:"networkContainerId"`
Version string `json:"version"`
Expand All @@ -69,198 +53,3 @@ func NewClient(url string) (*Client, error) {
connectionURL: url,
}, nil
}

// JoinNetwork joins the given network
func JoinNetwork(networkID string) (*http.Response, error) {
logger.Printf("[NMAgentClient] JoinNetwork: %s", networkID)

// Empty body is required as wireserver cannot handle a post without the body.
var body bytes.Buffer
json.NewEncoder(&body).Encode("")

joinNetworkTypeValue := fmt.Sprintf(
JoinNetworkURLFmt,
networkID)

joinNetworkURL := url.URL{
Host: WireserverIP,
Path: WireServerPath,
Scheme: WireServerScheme,
}

queryString := joinNetworkURL.Query()
queryString.Set("type", joinNetworkTypeValue)
queryString.Set("comp", "nmagent")

joinNetworkURL.RawQuery = queryString.Encode()

response, err := common.PostCtx(context.TODO(), common.GetHttpClient(), joinNetworkURL.String(), "application/json", &body)

if err == nil && response.StatusCode == http.StatusOK {
defer response.Body.Close()
}

logger.Printf("[NMAgentClient][Response] Join network: %s. Response: %+v. Error: %v",
networkID, response, err)

return response, err
}

// PublishNetworkContainer publishes given network container
func PublishNetworkContainer(networkContainerID, associatedInterfaceID, accessToken string, requestBodyData []byte) (*http.Response, error) {
logger.Printf("[NMAgentClient] PublishNetworkContainer NC: %s", networkContainerID)

createNcTypeValue := fmt.Sprintf(
PutNetworkValueFmt,
associatedInterfaceID,
networkContainerID,
accessToken)

createURL := url.URL{
Host: WireserverIP,
Path: WireServerPath,
Scheme: WireServerScheme,
}

queryString := createURL.Query()
queryString.Set("type", createNcTypeValue)
queryString.Set("comp", "nmagent")

createURL.RawQuery = queryString.Encode()

requestBody := bytes.NewBuffer(requestBodyData)
response, err := common.PostCtx(context.TODO(), common.GetHttpClient(), createURL.String(), "application/json", requestBody)

logger.Printf("[NMAgentClient][Response] Publish NC: %s. Response: %+v. Error: %v",
networkContainerID, response, err)

return response, err
}

// UnpublishNetworkContainer unpublishes given network container
func UnpublishNetworkContainer(networkContainerID, associatedInterfaceID, accessToken string) (*http.Response, error) {
logger.Printf("[NMAgentClient] UnpublishNetworkContainer NC: %s", networkContainerID)

deleteNCTypeValue := fmt.Sprintf(
DeleteNetworkContainerURLFmt,
associatedInterfaceID,
networkContainerID,
accessToken)

deleteURL := url.URL{
Host: WireserverIP,
Path: WireServerPath,
Scheme: WireServerScheme,
}

queryString := deleteURL.Query()
queryString.Set("type", deleteNCTypeValue)
queryString.Set("comp", "nmagent")

deleteURL.RawQuery = queryString.Encode()

// Empty body is required as wireserver cannot handle a post without the body.
var body bytes.Buffer
json.NewEncoder(&body).Encode("")
response, err := common.PostCtx(context.TODO(), common.GetHttpClient(), deleteURL.String(), "application/json", &body)

logger.Printf("[NMAgentClient][Response] Unpublish NC: %s. Response: %+v. Error: %v",
networkContainerID, response, err)

return response, err
}

// GetNetworkContainerVersion :- Retrieves NC version from NMAgent
func GetNetworkContainerVersion(networkContainerID, getNetworkContainerVersionURL string) (*http.Response, error) {
logger.Printf("[NMAgentClient] GetNetworkContainerVersion NC: %s", networkContainerID)

response, err := common.GetHttpClient().Get(getNetworkContainerVersionURL)

logger.Printf("[NMAgentClient][Response] GetNetworkContainerVersion NC: %s. Response: %+v. Error: %v",
networkContainerID, response, err)
return response, err
}

// GetNmAgentSupportedApis :- Retrieves Supported Apis from NMAgent
func GetNmAgentSupportedApis(httpc *http.Client, getNmAgentSupportedApisURL string) ([]string, error) {
var returnErr error

if getNmAgentSupportedApisURL == "" {
getNmAgentSupportedApisURL = fmt.Sprintf(
GetNmAgentSupportedApiURLFmt, WireserverIP)
}

req, err := http.NewRequestWithContext(context.TODO(), http.MethodGet, getNmAgentSupportedApisURL, nil)
if err != nil {
return nil, errors.Wrap(err, "failed to build request")
}

resp, err := httpc.Do(req)
if err != nil {
returnErr = fmt.Errorf(
"Failed to retrieve Supported Apis from NMAgent with error %v",
err.Error())
logger.Errorf("[Azure-CNS] %s", returnErr)
return nil, returnErr
}
if resp == nil {
returnErr = fmt.Errorf(
"Response from getNmAgentSupportedApis call is <nil>")
logger.Errorf("[Azure-CNS] %s", returnErr)
return nil, returnErr
}
defer resp.Body.Close()
b, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrap(err, "failed to read response body")
}
if resp.StatusCode != http.StatusOK {
returnErr = fmt.Errorf(
"Failed to retrieve Supported Apis from NMAgent with StatusCode: %d",
resp.StatusCode)
logger.Errorf("[Azure-CNS] %s", returnErr)
return nil, returnErr
}

var xmlDoc SupportedAPIsResponseXML
err = xml.NewDecoder(bytes.NewReader(b)).Decode(&xmlDoc)
if err != nil {
returnErr = fmt.Errorf(
"Failed to decode XML response of Supported Apis from NMAgent with error %v",
err.Error())
logger.Errorf("[Azure-CNS] %s", returnErr)
return nil, returnErr
}

logger.Printf("[NMAgentClient][Response] GetNmAgentSupportedApis. Response: %+v.", resp)
return xmlDoc.SupportedApis, nil
}

// GetNCVersionList query nmagent for programmed container versions.
func (c *Client) GetNCVersionList(ctx context.Context) (*NetworkContainerListResponse, error) {
now := time.Now()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.connectionURL, nil)
if err != nil {
return nil, errors.Wrap(err, "failed to build nmagent request")
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, errors.Wrap(err, "failed to make nmagent request")
}
defer resp.Body.Close()
b, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrap(err, "failed to read response body")
}
logger.Printf("[NMAgentClient][Response] GetNcVersionListWithOutToken response: %s, latency is %d", string(b), time.Since(now).Milliseconds())

if resp.StatusCode != http.StatusOK {
return nil, errors.Errorf("failed to GetNCVersionList with status %d", resp.StatusCode)
}

var response NetworkContainerListResponse
if err := json.Unmarshal(b, &response); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal response")
}
return &response, nil
}
Loading