Skip to content

Commit de466f5

Browse files
authored
feat: add multi-tenant NetworkContainer controller (#876)
1 parent ee7538c commit de466f5

30 files changed

+2561
-34
lines changed

Makefile

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ CNSFILES = \
5151
$(wildcard cns/networkcontainers/*.go) \
5252
$(wildcard cns/requestcontroller/*.go) \
5353
$(wildcard cns/requestcontroller/kubecontroller/*.go) \
54+
$(wildcard cns/multitenantcontroller/*.go) \
55+
$(wildcard cns/multitenantcontroller/multitenantoperator/*.go) \
5456
$(wildcard cns/fakes/*.go) \
5557
$(COREFILES) \
5658
$(CNMFILES)
@@ -181,13 +183,13 @@ azure-npm: $(NPM_BUILD_DIR)/azure-npm$(EXE_EXT) npm-archive
181183
endif
182184

183185
ifeq ($(GOOS),linux)
184-
all-binaries: azure-cnm-plugin azure-cni-plugin azure-cns azure-cnms azure-npm
186+
all-binaries: azure-cnm-plugin azure-cni-plugin azure-cns azure-cnms azure-npm
185187
else
186188
all-binaries: azure-cnm-plugin azure-cni-plugin azure-cns
187189
endif
188190

189191
ifeq ($(GOOS),linux)
190-
all-images: azure-npm-image azure-cns-image
192+
all-images: azure-npm-image azure-cns-image
191193
else
192194
all-images:
193195
@echo "Nothing to build. Skip."
@@ -223,7 +225,7 @@ $(CNI_BUILD_DIR)/azure-vnet-telemetry$(EXE_EXT): $(CNIFILES)
223225
# Build the Azure CLI network plugin.
224226
$(ACNCLI_BUILD_DIR)/acncli$(EXE_EXT): $(CNIFILES)
225227
CGO_ENABLED=0 go build -v -o $(ACNCLI_BUILD_DIR)/acn$(EXE_EXT) -ldflags "-X main.version=$(VERSION)" -gcflags="-dwarflocationlists=true" $(ACNCLI_DIR)/*.go
226-
228+
227229
# Build the Azure CNS Service.
228230
$(CNS_BUILD_DIR)/azure-cns$(EXE_EXT): $(CNSFILES)
229231
go build -v -o $(CNS_BUILD_DIR)/azure-cns$(EXE_EXT) -ldflags "-X main.version=$(VERSION) -X $(cnsaipath)=$(CNS_AI_ID)" -gcflags="-dwarflocationlists=true" $(CNS_DIR)/*.go
@@ -259,7 +261,7 @@ all-containerized:
259261

260262
# Make both linux and windows binaries
261263
.PHONY: all-binaries-platforms
262-
all-binaries-platforms:
264+
all-binaries-platforms:
263265
export GOOS=linux; make all-binaries
264266
export GOOS=windows; make all-binaries
265267

@@ -268,7 +270,7 @@ all-binaries-platforms:
268270
tools: acncli
269271

270272
.PHONY: tools-images
271-
tools-images:
273+
tools-images:
272274
docker build --no-cache -f ./tools/acncli/Dockerfile --build-arg VERSION=$(VERSION) -t $(AZURE_CNI_IMAGE):$(VERSION) .
273275

274276
# Build the Azure CNM plugin image, installable with "docker plugin install".
@@ -409,7 +411,7 @@ ifeq ($(GOOS),linux)
409411
cp $(CNI_BUILD_DIR)/azure-vnet$(EXE_EXT) $(CNI_BUILD_DIR)/azure-vnet-ipam$(EXE_EXT) $(CNI_BUILD_DIR)/azure-vnet-telemetry$(EXE_EXT) $(CNI_SWIFT_BUILD_DIR)
410412
chmod 0755 $(CNI_SWIFT_BUILD_DIR)/azure-vnet$(EXE_EXT) $(CNI_SWIFT_BUILD_DIR)/azure-vnet-ipam$(EXE_EXT)
411413
cd $(CNI_SWIFT_BUILD_DIR) && $(ARCHIVE_CMD) $(CNI_SWIFT_ARCHIVE_NAME) azure-vnet$(EXE_EXT) azure-vnet-ipam$(EXE_EXT) azure-vnet-telemetry$(EXE_EXT) 10-azure.conflist azure-vnet-telemetry.config
412-
endif
414+
endif
413415

414416
# Create a CNM archive for the target platform.
415417
.PHONY: cnm-archive
@@ -453,7 +455,7 @@ endif
453455
.PHONY: release
454456
release:
455457
./scripts/semver-release.sh
456-
458+
457459

458460
PRETTYGOTEST := $(shell command -v gotest 2> /dev/null)
459461

cns/NetworkContainerContract.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,10 @@ const (
6969

7070
// ChannelMode :- CNS channel modes
7171
const (
72-
Direct = "Direct"
73-
Managed = "Managed"
74-
CRD = "CRD"
72+
Direct = "Direct"
73+
Managed = "Managed"
74+
CRD = "CRD"
75+
MultiTenantCRD = "MultiTenantCRD"
7576
)
7677

7778
// CreateNetworkContainerRequest specifies request to create a network container or network isolation boundary.

cns/cnsclient/apiclient.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,8 @@ import (
88
// APIClient interface to update cns state
99
type APIClient interface {
1010
ReconcileNCState(nc *cns.CreateNetworkContainerRequest, pods map[string]cns.KubernetesPodInfo, scalar nnc.Scaler, spec nnc.NodeNetworkConfigSpec) error
11-
CreateOrUpdateNC(nc cns.CreateNetworkContainerRequest, scalar nnc.Scaler, spec nnc.NodeNetworkConfigSpec) error
11+
CreateOrUpdateNC(nc cns.CreateNetworkContainerRequest) error
12+
UpdateIPAMPoolMonitor(scalar nnc.Scaler, spec nnc.NodeNetworkConfigSpec) error
13+
GetNC(nc cns.GetNetworkContainerRequest) (cns.GetNetworkContainerResponse, error)
14+
DeleteNC(nc cns.DeleteNetworkContainerRequest) error
1215
}

cns/cnsclient/cnsclient_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,15 @@ func addTestStateToRestServer(t *testing.T, secondaryIps []string) {
7373
Version: "-1",
7474
}
7575

76-
returnCode := svc.CreateOrUpdateNetworkContainerInternal(req, fakes.NewFakeScalar(releasePercent, requestPercent, batchSize), fakes.NewFakeNodeNetworkConfigSpec(initPoolSize))
76+
returnCode := svc.CreateOrUpdateNetworkContainerInternal(req)
7777
if returnCode != 0 {
7878
t.Fatalf("Failed to createNetworkContainerRequest, req: %+v, err: %d", req, returnCode)
7979
}
80+
81+
returnCode = svc.UpdateIPAMPoolMonitorInternal(fakes.NewFakeScalar(releasePercent, requestPercent, batchSize), fakes.NewFakeNodeNetworkConfigSpec(initPoolSize))
82+
if returnCode != 0 {
83+
t.Fatalf("Failed to UpdateIPAMPoolMonitorInternal, err: %d", returnCode)
84+
}
8085
}
8186

8287
func getIPNetFromResponse(resp *cns.IPConfigResponse) (net.IPNet, error) {

cns/cnsclient/httpapi/client.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ type Client struct {
1414
}
1515

1616
// CreateOrUpdateNC updates cns state
17-
func (client *Client) CreateOrUpdateNC(ncRequest cns.CreateNetworkContainerRequest, scalar nnc.Scaler, spec nnc.NodeNetworkConfigSpec) error {
18-
returnCode := client.RestService.CreateOrUpdateNetworkContainerInternal(ncRequest, scalar, spec)
17+
func (client *Client) CreateOrUpdateNC(ncRequest cns.CreateNetworkContainerRequest) error {
18+
returnCode := client.RestService.CreateOrUpdateNetworkContainerInternal(ncRequest)
1919

2020
if returnCode != 0 {
2121
return fmt.Errorf("Failed to Create NC request: %+v, errorCode: %d", ncRequest, returnCode)
@@ -24,6 +24,17 @@ func (client *Client) CreateOrUpdateNC(ncRequest cns.CreateNetworkContainerReque
2424
return nil
2525
}
2626

27+
// UpdateIPAMPoolMonitor updates IPAM pool monitor.
28+
func (client *Client) UpdateIPAMPoolMonitor(scalar nnc.Scaler, spec nnc.NodeNetworkConfigSpec) error {
29+
returnCode := client.RestService.UpdateIPAMPoolMonitorInternal(scalar, spec)
30+
31+
if returnCode != 0 {
32+
return fmt.Errorf("Failed to update IPAM pool monitor scalar: %+v, spec: %+v, errorCode: %d", scalar, spec, returnCode)
33+
}
34+
35+
return nil
36+
}
37+
2738
// ReconcileNCState initializes cns state
2839
func (client *Client) ReconcileNCState(ncRequest *cns.CreateNetworkContainerRequest, podInfoByIP map[string]cns.KubernetesPodInfo, scalar nnc.Scaler, spec nnc.NodeNetworkConfigSpec) error {
2940
returnCode := client.RestService.ReconcileNCState(ncRequest, podInfoByIP, scalar, spec)
@@ -34,3 +45,24 @@ func (client *Client) ReconcileNCState(ncRequest *cns.CreateNetworkContainerRequ
3445

3546
return nil
3647
}
48+
49+
func (client *Client) GetNC(req cns.GetNetworkContainerRequest) (cns.GetNetworkContainerResponse, error) {
50+
response, returnCode := client.RestService.GetNetworkContainerInternal(req)
51+
if returnCode != 0 {
52+
if returnCode == restserver.UnknownContainerID {
53+
return response, fmt.Errorf("NotFound")
54+
}
55+
return response, fmt.Errorf("Failed to get NC, request: %+v, errorCode: %d", req, returnCode)
56+
}
57+
58+
return response, nil
59+
}
60+
61+
func (client *Client) DeleteNC(req cns.DeleteNetworkContainerRequest) error {
62+
returnCode := client.RestService.DeleteNetworkContainerInternal(req)
63+
if returnCode != 0 {
64+
return fmt.Errorf("Failed to delete NC, request: %+v, errorCode: %d", req, returnCode)
65+
}
66+
67+
return nil
68+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Mock Clients
2+
3+
Run the following command to generate mock clients:
4+
5+
```sh
6+
mockgen -source=$GOPATH/src/github.com/Azure/azure-container-networking/cns/cnsclient/apiclient.go -package=mockclients APIClient >cnsclient.go
7+
mockgen -source=$GOPATH/src/sigs.k8s.io/controller-runtime/pkg/client/interfaces.go -package=mockclients Client >kubeclient.go
8+
```

cns/multitenantcontroller/mockclients/cnsclient.go

Lines changed: 106 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)