diff --git a/cni/Dockerfile b/cni/Dockerfile index 7b2369cb04..5867fd09b2 100644 --- a/cni/Dockerfile +++ b/cni/Dockerfile @@ -6,7 +6,7 @@ ARG OS_VERSION ARG OS # mcr.microsoft.com/oss/go/microsoft/golang:1.24-azurelinux3.0 -FROM --platform=linux/${ARCH} mcr.microsoft.com/oss/go/microsoft/golang@sha256:281d086598c336073a59d32cd6fc614a892e90c0c0b881e5051d014859739f0e AS go +FROM --platform=linux/${ARCH} mcr.microsoft.com/oss/go/microsoft/golang@sha256:7bbbda682ce4a462855bd8a61c5efdc1e79ab89d9e32c2610f41e6f9502e1cf4 AS go # mcr.microsoft.com/azurelinux/base/core:3.0 FROM --platform=linux/${ARCH} mcr.microsoft.com/azurelinux/base/core@sha256:833693619d523c23b1fe4d9c1f64a6c697e2a82f7a6ee26e1564897c3fe3fa02 AS mariner-core diff --git a/cns/Dockerfile b/cns/Dockerfile index b88fecca61..7908371aea 100644 --- a/cns/Dockerfile +++ b/cns/Dockerfile @@ -5,7 +5,7 @@ ARG OS_VERSION ARG OS # mcr.microsoft.com/oss/go/microsoft/golang:1.24-azurelinux3.0 -FROM --platform=linux/${ARCH} mcr.microsoft.com/oss/go/microsoft/golang@sha256:281d086598c336073a59d32cd6fc614a892e90c0c0b881e5051d014859739f0e AS go +FROM --platform=linux/${ARCH} mcr.microsoft.com/oss/go/microsoft/golang@sha256:7bbbda682ce4a462855bd8a61c5efdc1e79ab89d9e32c2610f41e6f9502e1cf4 AS go # mcr.microsoft.com/azurelinux/base/core:3.0 FROM mcr.microsoft.com/azurelinux/base/core@sha256:833693619d523c23b1fe4d9c1f64a6c697e2a82f7a6ee26e1564897c3fe3fa02 AS mariner-core diff --git a/cns/service/main.go b/cns/service/main.go index 7c41ba366a..67f7872f44 100644 --- a/cns/service/main.go +++ b/cns/service/main.go @@ -118,9 +118,6 @@ const ( initialIBNICCount = 0 ) -// ErrHomeAzNotAvailable indicates that HomeAZ information is not available from CNS -var ErrHomeAzNotAvailable = errors.New("home AZ not available from CNS") - type cniConflistScenario string const ( @@ -1694,8 +1691,8 @@ func getPodInfoByIPProvider( return podInfoByIPProvider, nil } -// createOrUpdateNodeInfoCRD polls IMDS to learn the VM Unique ID and CNS to get the HomeAZ, -// then creates or updates the NodeInfo CRD with that information +// createOrUpdateNodeInfoCRD polls imds to learn the VM Unique ID and then creates or updates the NodeInfo CRD +// with that vm unique ID func createOrUpdateNodeInfoCRD(ctx context.Context, restConfig *rest.Config, node *corev1.Node) error { imdsCli := imds.NewClient() vmUniqueID, err := imdsCli.GetVMUniqueID(ctx) @@ -1703,22 +1700,6 @@ func createOrUpdateNodeInfoCRD(ctx context.Context, restConfig *rest.Config, nod return errors.Wrap(err, "error getting vm unique ID from imds") } - cnsClient, err := cnsclient.New("", cnsReqTimeout) - if err != nil { - return errors.Wrap(err, "error creating CNS client") - } - var homeAZ string - homeAzResponse, err := cnsClient.GetHomeAz(ctx) - if err != nil { - return errors.Wrap(err, "error getting home AZ from CNS") - } - if homeAzResponse.Response.ReturnCode == cnstypes.Success && homeAzResponse.HomeAzResponse.IsSupported { - homeAZ = fmt.Sprintf("AZ%02d", homeAzResponse.HomeAzResponse.HomeAz) - } else { - return errors.Wrapf(ErrHomeAzNotAvailable, "ReturnCode=%d (expected=%d), IsSupported=%t", - homeAzResponse.Response.ReturnCode, cnstypes.Success, homeAzResponse.HomeAzResponse.IsSupported) - } - directcli, err := client.New(restConfig, client.Options{Scheme: multitenancy.Scheme}) if err != nil { return errors.Wrap(err, "failed to create ctrl client") @@ -1734,7 +1715,6 @@ func createOrUpdateNodeInfoCRD(ctx context.Context, restConfig *rest.Config, nod }, Spec: mtv1alpha1.NodeInfoSpec{ VMUniqueID: vmUniqueID, - HomeAZ: homeAZ, }, } diff --git a/cns/service/main_test.go b/cns/service/main_test.go index 17dbcd1af9..42a64df761 100644 --- a/cns/service/main_test.go +++ b/cns/service/main_test.go @@ -3,24 +3,14 @@ package main import ( "bytes" "context" - "encoding/json" - "fmt" "io" "net/http" - "net/http/httptest" - "strings" "testing" - "time" "github.com/Azure/azure-container-networking/cns" "github.com/Azure/azure-container-networking/cns/fakes" "github.com/Azure/azure-container-networking/cns/logger" - "github.com/Azure/azure-container-networking/crd/multitenancy/api/v1alpha1" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/rest" ) // MockHTTPClient is a mock implementation of HTTPClient @@ -79,184 +69,3 @@ func TestSendRegisterNodeRequest_StatusAccepted(t *testing.T) { assert.Error(t, sendRegisterNodeRequest(ctx, mockClient, httpServiceFake, nodeRegisterReq, url)) } - -func TestCreateOrUpdateNodeInfoCRD_PopulatesHomeAZ(t *testing.T) { - vmID := "test-vm-unique-id-12345" - homeAZ := uint(2) - HomeAZStr := fmt.Sprintf("AZ0%d", homeAZ) - - // Create mock IMDS server - mockIMDSServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if strings.Contains(r.URL.Path, "/metadata/instance/compute") { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - response := map[string]interface{}{ - "vmId": vmID, - "name": "test-vm", - "resourceGroupName": "test-rg", - } - _ = json.NewEncoder(w).Encode(response) - return - } - w.WriteHeader(http.StatusNotFound) - })) - defer mockIMDSServer.Close() - - // Create mock CNS server - mockCNSServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if strings.Contains(r.URL.Path, "/homeaz") || strings.Contains(r.URL.Path, "homeaz") { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - response := map[string]interface{}{ - "ReturnCode": 0, - "Message": "", - "HomeAzResponse": map[string]interface{}{ - "IsSupported": true, - "HomeAz": homeAZ, - }, - } - _ = json.NewEncoder(w).Encode(response) - return - } - w.WriteHeader(http.StatusNotFound) - })) - defer mockCNSServer.Close() - - // Set up HTTP transport to mock IMDS and CNS - originalTransport := http.DefaultTransport - defer func() { http.DefaultTransport = originalTransport }() - - http.DefaultTransport = &mockTransport{ - imdsServer: mockIMDSServer, - cnsServer: mockCNSServer, - original: originalTransport, - } - - // Create a mock Kubernetes server that captures the NodeInfo being created - var capturedNodeInfo *v1alpha1.NodeInfo - - mockK8sServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Handle specific API group discovery - multitenancy.acn.azure.com - if r.URL.Path == "/apis/multitenancy.acn.azure.com/v1alpha1" && r.Method == "GET" { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - _ = json.NewEncoder(w).Encode(map[string]interface{}{ - "kind": "APIResourceList", - "groupVersion": "multitenancy.acn.azure.com/v1alpha1", - "resources": []map[string]interface{}{ - { - "name": "nodeinfos", - "singularName": "nodeinfo", - "namespaced": false, - "kind": "NodeInfo", - "verbs": []string{"create", "delete", "get", "list", "patch", "update", "watch"}, - }, - }, - }) - return - } - - // Handle NodeInfo resource requests - if strings.Contains(r.URL.Path, "nodeinfos") || strings.Contains(r.URL.Path, "multitenancy") { - if r.Method == "POST" || r.Method == "PATCH" || r.Method == "PUT" { - body, _ := io.ReadAll(r.Body) - - // Try to parse the NodeInfo from the request - var nodeInfo v1alpha1.NodeInfo - if err := json.Unmarshal(body, &nodeInfo); err == nil { - capturedNodeInfo = &nodeInfo - } - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - // Return the created NodeInfo - _ = json.NewEncoder(w).Encode(map[string]interface{}{ - "apiVersion": "multitenancy.acn.azure.com/v1alpha1", - "kind": "NodeInfo", - "metadata": map[string]interface{}{ - "name": "test-node", - }, - "spec": map[string]interface{}{ - "vmUniqueID": vmID, - "homeAZ": HomeAZStr, - }, - }) - return - } - } - - // Default success response for any other API calls - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - _ = json.NewEncoder(w).Encode(map[string]interface{}{ - "kind": "Status", - "status": "Success", - }) - })) - defer mockK8sServer.Close() - - // Test the function with mocked dependencies - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - // Point to our mock Kubernetes server - restConfig := &rest.Config{ - Host: mockK8sServer.URL, - } - - node := &corev1.Node{ - ObjectMeta: metav1.ObjectMeta{Name: "test-node"}, - } - - // Call the createOrUpdateNodeInfoCRD function - err := createOrUpdateNodeInfoCRD(ctx, restConfig, node) - - // Verify the function succeeded - require.NoError(t, err, "Function should succeed with mocked dependencies") - - // Verify the captured values - assert.NotNil(t, capturedNodeInfo, "NodeInfo should have been captured from K8s API call") - if capturedNodeInfo != nil { - assert.Equal(t, vmID, capturedNodeInfo.Spec.VMUniqueID, "VMUniqueID should be from IMDS") - assert.Equal(t, HomeAZStr, capturedNodeInfo.Spec.HomeAZ, "HomeAZ should be formatted from CNS response") - } -} - -// mockTransport redirects HTTP requests to mock servers for testing. -// It intercepts requests to IMDS and CNS endpoints and routes them to local test servers. -type mockTransport struct { - imdsServer *httptest.Server - cnsServer *httptest.Server - original http.RoundTripper -} - -func (m *mockTransport) RoundTrip(req *http.Request) (*http.Response, error) { - // Redirect IMDS calls to mock IMDS server - if req.URL.Host == "169.254.169.254" { - req.URL.Scheme = "http" - req.URL.Host = strings.TrimPrefix(m.imdsServer.URL, "http://") - resp, err := m.original.RoundTrip(req) - if err != nil { - return nil, fmt.Errorf("IMDS mock transport failed: %w", err) - } - return resp, nil - } - - // Redirect CNS calls to mock CNS server - if req.URL.Host == "localhost:10090" || strings.Contains(req.URL.Host, "10090") { - req.URL.Scheme = "http" - req.URL.Host = strings.TrimPrefix(m.cnsServer.URL, "http://") - resp, err := m.original.RoundTrip(req) - if err != nil { - return nil, fmt.Errorf("CNS mock transport failed: %w", err) - } - return resp, nil - } - - // All other calls go through original transport - resp, err := m.original.RoundTrip(req) - if err != nil { - return nil, fmt.Errorf("mock transport failed: %w", err) - } - return resp, nil -}