Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
db4166e
feat: support for cilium + nodesubnet
santhoshmprabhu Oct 18, 2024
9cc4ec6
fix: make linter happy
santhoshmprabhu Oct 18, 2024
107ebce
fix: make linter happy
santhoshmprabhu Oct 18, 2024
636ab39
Merge branch 'master' into sanprabhu/cilium-node-subnet
santhoshmprabhu Oct 18, 2024
07a8575
fix: make linter happy
santhoshmprabhu Oct 18, 2024
7f10972
Merge branch 'sanprabhu/cilium-node-subnet' of github.com:Azure/azure…
santhoshmprabhu Oct 18, 2024
c59f2dc
test: add test for nodesubnet
santhoshmprabhu Oct 21, 2024
fbd60a5
chore: add missing files
santhoshmprabhu Oct 21, 2024
4ee1a90
nicer comment
santhoshmprabhu Oct 21, 2024
f94cb77
chore: fix comment typo
santhoshmprabhu Oct 21, 2024
a1c4bfe
fix: update cns/restserver/nodesubnet.go
santhoshmprabhu Oct 22, 2024
2f15117
fix: update cns/restserver/restserver.go
santhoshmprabhu Oct 22, 2024
6e8bda0
refactor: address comments
santhoshmprabhu Oct 22, 2024
7879de5
Merge branch 'sanprabhu/cilium-node-subnet' of github.com:Azure/azure…
santhoshmprabhu Oct 22, 2024
0fe2285
Merge branch 'master' into sanprabhu/cilium-node-subnet
santhoshmprabhu Oct 22, 2024
301de9f
fix: address comments
santhoshmprabhu Oct 22, 2024
73424b5
Merge branch 'sanprabhu/cilium-node-subnet' of github.com:Azure/azure…
santhoshmprabhu Oct 23, 2024
c4d9408
chore:comment cleanup
santhoshmprabhu Oct 23, 2024
2b210d6
fix: do not use bash in ip config update
santhoshmprabhu Oct 23, 2024
a15ee32
fix: address comments
santhoshmprabhu Oct 23, 2024
30c7aa2
fix: make linter happy
santhoshmprabhu Oct 23, 2024
a8b4cf1
Merge branch 'master' into sanprabhu/cilium-node-subnet
santhoshmprabhu Oct 23, 2024
356dc69
chore: move pipeline changes out
santhoshmprabhu Oct 23, 2024
56f3d48
Merge branch 'master' into sanprabhu/cilium-node-subnet
santhoshmprabhu Oct 23, 2024
b3ac582
test: more elaborate test including checks on IP pool state
santhoshmprabhu Oct 24, 2024
6385042
fix: use comments suitable for documentation
santhoshmprabhu Oct 24, 2024
d9b4384
chore: address comments
santhoshmprabhu Oct 24, 2024
2a6881f
chore:make linter happy
santhoshmprabhu Oct 24, 2024
f8f724d
fix: address comments
santhoshmprabhu Oct 25, 2024
a78a6b1
chore: typo
santhoshmprabhu Oct 25, 2024
800785e
chore: address comments
santhoshmprabhu Oct 29, 2024
03b2531
Merge branch 'master' into sanprabhu/cilium-node-subnet
santhoshmprabhu Oct 29, 2024
d06db5d
Merge branch 'master' into sanprabhu/cilium-node-subnet
santhoshmprabhu Oct 30, 2024
f764c8a
fix: update comments
santhoshmprabhu Oct 30, 2024
8acfe0c
Merge branch 'sanprabhu/cilium-node-subnet' of github.com:Azure/azure…
santhoshmprabhu Oct 30, 2024
8530f85
Merge branch 'master' into sanprabhu/cilium-node-subnet
santhoshmprabhu Oct 31, 2024
0cae5e4
Merge branch 'master' into sanprabhu/cilium-node-subnet
santhoshmprabhu Nov 1, 2024
50c2a1c
Merge branch 'master' into sanprabhu/cilium-node-subnet
santhoshmprabhu Nov 1, 2024
f8bcb26
Merge remote-tracking branch 'origin/master' into sanprabhu/cilium-no…
santhoshmprabhu Nov 4, 2024
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
16 changes: 16 additions & 0 deletions .pipelines/pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,17 @@ stages:
k8sVersion: ""
dependsOn: "containerize"

# Cilium Nodesubnet E2E tests
- template: singletenancy/cilium-nodesubnet/cilium-nodesubnet-e2e-job-template.yaml
parameters:
name: "cilium_nodesubnet_e2e"
displayName: Cilium NodeSubnet
clusterType: nodesubnet-byocni-nokubeproxy-up
clusterName: "cilndsubnete2e"
vmSize: Standard_B2s
k8sVersion: ""
dependsOn: "containerize"

# Cilium Overlay E2E tests
- template: singletenancy/cilium-overlay/cilium-overlay-e2e-job-template.yaml
parameters:
Expand Down Expand Up @@ -405,6 +416,7 @@ stages:
- azure_overlay_stateless_e2e
- aks_swift_e2e
- cilium_e2e
- cilium_nodesubnet_e2e
- cilium_overlay_e2e
- cilium_h_overlay_e2e
- aks_ubuntu_22_linux_e2e
Expand All @@ -425,6 +437,10 @@ stages:
cilium_e2e:
name: cilium_e2e
clusterName: "ciliume2e"
region: $(REGION_AKS_CLUSTER_TEST)
cilium_nodesubnet_e2e:
name: cilium_nodesubnet_e2e
clusterName: "cilndsubnete2e"
region: $(REGION_AKS_CLUSTER_TEST)
cilium_overlay_e2e:
name: cilium_overlay_e2e
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ stages:
os: ${{ parameters.os }}
datapath: true
dns: true
cni: cilium
portforward: true
service: true
hostport: true
dependsOn: ${{ parameters.name }}

- job: failedE2ELogs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ steps:
pwd
kubectl cluster-info
kubectl get po -owide -A
CILIUM_VERSION_TAG=${CILIUM_NODE_SUBNET_VERSION}
echo "install Cilium ${CILIUM_VERSION_TAG}"
export DIR=${CILIUM_VERSION_TAG%.*}
echo "installing files from ${DIR}"
Expand Down
11 changes: 8 additions & 3 deletions cns/fakes/nmagentclientfake.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import (

// NMAgentClientFake can be used to query to VM Host info.
type NMAgentClientFake struct {
SupportedAPIsF func(context.Context) ([]string, error)
GetNCVersionListF func(context.Context) (nmagent.NCVersionList, error)
GetHomeAzF func(context.Context) (nmagent.AzResponse, error)
SupportedAPIsF func(context.Context) ([]string, error)
GetNCVersionListF func(context.Context) (nmagent.NCVersionList, error)
GetHomeAzF func(context.Context) (nmagent.AzResponse, error)
GetInterfaceIPInfoF func(ctx context.Context) (nmagent.Interfaces, error)
}

func (n *NMAgentClientFake) SupportedAPIs(ctx context.Context) ([]string, error) {
Expand All @@ -30,3 +31,7 @@ func (n *NMAgentClientFake) GetNCVersionList(ctx context.Context) (nmagent.NCVer
func (n *NMAgentClientFake) GetHomeAz(ctx context.Context) (nmagent.AzResponse, error) {
return n.GetHomeAzF(ctx)
}

func (n *NMAgentClientFake) GetInterfaceIPInfo(ctx context.Context) (nmagent.Interfaces, error) {
return n.GetInterfaceIPInfoF(ctx)
}
80 changes: 80 additions & 0 deletions cns/restserver/helper_for_nodesubnet_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package restserver

import (
"context"
"net/netip"

"github.com/Azure/azure-container-networking/cns"
"github.com/Azure/azure-container-networking/cns/common"
"github.com/Azure/azure-container-networking/cns/fakes"
"github.com/Azure/azure-container-networking/cns/nodesubnet"
acn "github.com/Azure/azure-container-networking/common"
"github.com/Azure/azure-container-networking/nmagent"
"github.com/Azure/azure-container-networking/store"
)

func GetRestServiceObjectForNodeSubnetTest(generator CNIConflistGenerator) *HTTPRestService {
config := &common.ServiceConfig{
Name: "test",
Version: "1.0",
ChannelMode: "AzureHost",
Store: store.NewMockStore("test"),
}
interfaces := nmagent.Interfaces{
Entries: []nmagent.Interface{
{
MacAddress: nmagent.MACAddress{0x00, 0x0D, 0x3A, 0xF9, 0xDC, 0xA6},
IsPrimary: true,
InterfaceSubnets: []nmagent.InterfaceSubnet{
{
Prefix: "10.240.0.0/16",
IPAddress: []nmagent.NodeIP{
{
Address: nmagent.IPAddress(netip.AddrFrom4([4]byte{10, 240, 0, 5})),
IsPrimary: true,
},
{
Address: nmagent.IPAddress(netip.AddrFrom4([4]byte{10, 240, 0, 6})),
IsPrimary: false,
},
},
},
},
},
},
}

svc, err := cns.NewService(config.Name, config.Version, config.ChannelMode, config.Store)
if err != nil {
return nil
}

svc.SetOption(acn.OptCnsURL, "")
svc.SetOption(acn.OptCnsPort, "")
err = svc.Initialize(config)
if err != nil {
return nil
}

return &HTTPRestService{
Service: svc,
cniConflistGenerator: generator,
state: &httpRestServiceState{},
PodIPConfigState: make(map[string]cns.IPConfigurationStatus),
nma: &fakes.NMAgentClientFake{
GetInterfaceIPInfoF: func(_ context.Context) (nmagent.Interfaces, error) {
return interfaces, nil
},
},
}
}

// SetCNIConflistGenerator sets the CNIConflistGenerator for the HTTPRestService.
func (service *HTTPRestService) SetCNIConflistGenerator(generator CNIConflistGenerator) {
service.cniConflistGenerator = generator
}

// GetNodesubnetIPFetcher gets the nodesubnet.IPFetcher from the HTTPRestService.
func (service *HTTPRestService) GetNodesubnetIPFetcher() *nodesubnet.IPFetcher {
return service.nodesubnetIPFetcher
}
59 changes: 59 additions & 0 deletions cns/restserver/nodesubnet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package restserver

import (
"context"
"net/netip"

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

var _ nodesubnet.IPConsumer = &HTTPRestService{}

// Implement the UpdateIPsForNodeSubnet method for HTTPRestService
func (service *HTTPRestService) UpdateIPsForNodeSubnet(secondaryIPs []netip.Addr) error {
secondaryIPStrs := make([]string, len(secondaryIPs))
for i, ip := range secondaryIPs {
secondaryIPStrs[i] = ip.String()
}

networkContainerRequest := nodesubnet.CreateNodeSubnetNCRequest(secondaryIPStrs)

code, msg := service.saveNetworkContainerGoalState(*networkContainerRequest)
if code != types.Success {
logger.Debugf("Error in processing IP change")
return errors.Errorf("failed to save fetched ips. code: %d, message %s", code, msg)
}

logger.Debugf("IP change processed successfully")

// saved NC successfully, generate conflist to indicate CNS is ready
go service.MustGenerateCNIConflistOnce()
return nil
}

func (service *HTTPRestService) InitializeNodeSubnet(ctx context.Context, podInfoByIPProvider cns.PodInfoByIPProvider) error {
// Set orchestrator type
orchestrator := cns.SetOrchestratorTypeRequest{
OrchestratorType: cns.KubernetesCRD,
}
service.SetNodeOrchestrator(&orchestrator)

if podInfoByIPProvider == nil {
logger.Printf("PodInfoByIPProvider is nil, this usually means no saved endpoint state. Skipping reconciliation")
} else if _, err := nodesubnet.ReconcileInitialCNSState(ctx, service, podInfoByIPProvider); err != nil {
return errors.Wrap(err, "reconcile initial CNS state")
}
// statefile (if any) is reconciled. Initialize the IP fetcher. Start the IP fetcher only after the service is started,
// and any pending async delete operations are completed.
service.nodesubnetIPFetcher = nodesubnet.NewIPFetcher(service.nma, service, 0, 0, logger.Log)

return nil
}

func (service *HTTPRestService) StartNodeSubnet(ctx context.Context) {
service.nodesubnetIPFetcher.Start(ctx)
}
78 changes: 78 additions & 0 deletions cns/restserver/nodesubnet_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package restserver_test

import (
"context"
"testing"

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

// Mock implementation of PodInfoByIPProvider
type MockPodInfoByIPProvider struct{}

func (m *MockPodInfoByIPProvider) PodInfoByIP() (res map[string]cns.PodInfo, err error) {
return res, nil
}

// Mock implementation of CNIConflistGenerator
type MockCNIConflistGenerator struct {
GenerateCalled chan bool
}

func (m *MockCNIConflistGenerator) Generate() error {
m.GenerateCalled <- true
return nil
}

func (m *MockCNIConflistGenerator) Close() error {
// Implement the Close method logic here if needed
return nil
}

func TestNodeSubnet(t *testing.T) {
mockPodInfoProvider := new(MockPodInfoByIPProvider)

// Create a real HTTPRestService object
mockCNIConflistGenerator := &MockCNIConflistGenerator{
GenerateCalled: make(chan bool),
}
service := restserver.GetRestServiceObjectForNodeSubnetTest(mockCNIConflistGenerator)
defer service.Service.Uninitialize()

ctx, cancel := testContext(t)
defer cancel()

err := service.InitializeNodeSubnet(ctx, mockPodInfoProvider)
service.StartNodeSubnet(ctx)

if err != nil {
t.Errorf("InitializeNodeSubnet returned an error: %v", err)
}

if service.GetNodesubnetIPFetcher() == nil {
t.Error("NodeSubnetIPFetcher is not initialized")
}

select {
case <-ctx.Done():
t.Error("Test context was canceled before conflist generation")
return
case <-mockCNIConflistGenerator.GenerateCalled:
break
}
}

// testContext creates a context from the provided testing.T that will be
// canceled if the test suite is terminated.
func testContext(t *testing.T) (context.Context, context.CancelFunc) {
if deadline, ok := t.Deadline(); ok {
return context.WithDeadline(context.Background(), deadline)
}
return context.WithCancel(context.Background())
}

func init() {
logger.InitLogger("testlogs", 0, 0, "./")
}
3 changes: 3 additions & 0 deletions cns/restserver/restserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/Azure/azure-container-networking/cns/dockerclient"
"github.com/Azure/azure-container-networking/cns/logger"
"github.com/Azure/azure-container-networking/cns/networkcontainers"
nodesubnet "github.com/Azure/azure-container-networking/cns/nodesubnet"
"github.com/Azure/azure-container-networking/cns/routes"
"github.com/Azure/azure-container-networking/cns/types"
"github.com/Azure/azure-container-networking/cns/types/bounded"
Expand Down Expand Up @@ -40,6 +41,7 @@ type nmagentClient interface {
SupportedAPIs(context.Context) ([]string, error)
GetNCVersionList(context.Context) (nma.NCVersionList, error)
GetHomeAz(context.Context) (nma.AzResponse, error)
GetInterfaceIPInfo(ctx context.Context) (nma.Interfaces, error)
}

type wireserverProxy interface {
Expand Down Expand Up @@ -76,6 +78,7 @@ type HTTPRestService struct {
IPConfigsHandlerMiddleware cns.IPConfigsHandlerMiddleware
PnpIDByMacAddress map[string]string
imdsClient imdsClient
nodesubnetIPFetcher *nodesubnet.IPFetcher
}

type CNIConflistGenerator interface {
Expand Down
Loading
Loading