Skip to content

Commit ae9aedc

Browse files
authored
[CNI] Parse CNI version in CNI client (#899)
* get CNI version * update makefile to produce cni-manager image * return proper type
1 parent fecf08d commit ae9aedc

File tree

15 files changed

+1157
-23
lines changed

15 files changed

+1157
-23
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ CNS_ARCHIVE_NAME = azure-cns-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
136136
CNMS_ARCHIVE_NAME = azure-cnms-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
137137
NPM_ARCHIVE_NAME = azure-npm-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
138138
NPM_IMAGE_ARCHIVE_NAME = azure-npm-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
139+
CNI_IMAGE_ARCHIVE_NAME = azure-cni-manager-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
139140
CNMS_IMAGE_ARCHIVE_NAME = azure-cnms-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
140141
TELEMETRY_IMAGE_ARCHIVE_NAME = azure-vnet-telemetry-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
141142
CNS_IMAGE_ARCHIVE_NAME = azure-cns-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT)
@@ -279,6 +280,7 @@ tools: acncli
279280
.PHONY: tools-images
280281
tools-images:
281282
docker build --no-cache -f ./tools/acncli/Dockerfile --build-arg VERSION=$(VERSION) -t $(AZURE_CNI_IMAGE):$(VERSION) .
283+
docker save $(AZURE_CNI_IMAGE):$(VERSION) | gzip -c > $(IMAGE_DIR)/$(CNI_IMAGE_ARCHIVE_NAME)
282284

283285
# Build the Azure CNM plugin image, installable with "docker plugin install".
284286
.PHONY: azure-vnet-plugin-image

cni/client/client.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import (
44
"encoding/json"
55
"fmt"
66
"os"
7+
"strings"
78

89
"github.com/Azure/azure-container-networking/cni"
910
"github.com/Azure/azure-container-networking/cni/api"
1011
"github.com/Azure/azure-container-networking/log"
12+
semver "github.com/hashicorp/go-version"
1113
utilexec "k8s.io/utils/exec"
1214
)
1315

@@ -24,13 +26,7 @@ type AzureCNIClient struct {
2426
exec utilexec.Interface
2527
}
2628

27-
func NewCNIClient(exec utilexec.Interface) *AzureCNIClient {
28-
return &AzureCNIClient{
29-
exec: exec,
30-
}
31-
}
32-
33-
func (c *AzureCNIClient) GetEndpointState() (api.CNIState, error) {
29+
func (c *AzureCNIClient) GetEndpointState() (*api.AzureCNIState, error) {
3430
cmd := c.exec.Command(azureVnetBinName)
3531
cmd.SetDir(azureVnetBinDirectory)
3632

@@ -52,3 +48,21 @@ func (c *AzureCNIClient) GetEndpointState() (api.CNIState, error) {
5248

5349
return state, nil
5450
}
51+
52+
func (c *AzureCNIClient) GetVersion() (*semver.Version, error) {
53+
cmd := c.exec.Command(azureVnetBinName, "-v")
54+
cmd.SetDir(azureVnetBinDirectory)
55+
56+
output, err := cmd.CombinedOutput()
57+
if err != nil {
58+
return nil, fmt.Errorf("failed to get Azure CNI version with err: [%w], output: [%s]", err, string(output))
59+
}
60+
61+
res := strings.Fields(string(output))
62+
63+
if len(res) != 4 {
64+
return nil, fmt.Errorf("Unexpected Azure CNI Version formatting: %v", output)
65+
}
66+
67+
return semver.NewVersion(res[3])
68+
}

cni/client/client_integration_test.go

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,62 @@ package client
55

66
import (
77
"io"
8+
"log"
89
"os"
910
"testing"
1011

1112
"github.com/Azure/azure-container-networking/cni/api"
1213
testutils "github.com/Azure/azure-container-networking/test/utils"
14+
ver "github.com/hashicorp/go-version"
1315
"github.com/stretchr/testify/require"
1416
"k8s.io/utils/exec"
1517
)
1618

17-
// todo: enable this test in CI, requires built azure vnet
18-
func TestGetStateFromAzureCNI(t *testing.T) {
19-
testutils.RequireRootforTest(t)
20-
19+
func TestMain(m *testing.M) {
20+
testutils.RequireRootforTestMain()
21+
var err error
2122
// copy test state file to /var/run/azure-vnet.json
2223
in, err := os.Open("./testresources/azure-vnet-test.json")
23-
require.NoError(t, err)
24-
25-
defer in.Close()
24+
if err != nil {
25+
return
26+
}
2627

2728
out, err := os.Create("/var/run/azure-vnet.json")
28-
require.NoError(t, err)
29+
if err != nil {
30+
return
31+
}
2932

33+
exit := 0
3034
defer func() {
31-
out.Close()
35+
if in != nil {
36+
in.Close()
37+
}
38+
39+
if out != nil {
40+
out.Close()
41+
}
42+
3243
err := os.Remove("/var/run/azure-vnet.json")
33-
require.NoError(t, err)
44+
if err != nil {
45+
log.Print(err)
46+
os.Exit(1)
47+
}
48+
49+
os.Exit(exit)
3450
}()
3551

3652
_, err = io.Copy(out, in)
37-
require.NoError(t, err)
53+
if err != nil {
54+
return
55+
}
56+
57+
exit = m.Run()
58+
}
3859

39-
out.Close()
60+
// todo: enable this test in CI, requires built azure vnet
61+
func TestGetStateFromAzureCNI(t *testing.T) {
4062

41-
realexec := exec.New()
42-
c := NewCNIClient(realexec)
63+
c := AzureCNIClient{exec: exec.New()}
4364
state, err := c.GetEndpointState()
4465
require.NoError(t, err)
4566

@@ -52,3 +73,14 @@ func TestGetStateFromAzureCNI(t *testing.T) {
5273

5374
require.Exactly(t, res, state)
5475
}
76+
77+
func TestGetVersion(t *testing.T) {
78+
c := &AzureCNIClient{exec: exec.New()}
79+
version, err := c.GetVersion()
80+
require.NoError(t, err)
81+
82+
expectedVersion, err := ver.NewVersion("v1.4.0-2-g984c5a5e-dirty")
83+
require.NoError(t, err)
84+
85+
require.Equal(t, expectedVersion, version)
86+
}

cni/client/client_unit_test.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/Azure/azure-container-networking/cni/api"
99
testutils "github.com/Azure/azure-container-networking/test/utils"
10+
ver "github.com/hashicorp/go-version"
1011
"github.com/stretchr/testify/require"
1112
)
1213

@@ -17,7 +18,7 @@ func TestGetState(t *testing.T) {
1718

1819
fakeexec, _ := testutils.GetFakeExecWithScripts(calls)
1920

20-
c := NewCNIClient(fakeexec)
21+
c := &AzureCNIClient{exec: fakeexec}
2122
state, err := c.GetEndpointState()
2223
require.NoError(t, err)
2324

@@ -30,3 +31,20 @@ func TestGetState(t *testing.T) {
3031

3132
require.Equal(t, res, state)
3233
}
34+
35+
func TestGetVersion(t *testing.T) {
36+
calls := []testutils.TestCmd{
37+
{Cmd: []string{"./azure-vnet", "-v"}, Stdout: `Azure CNI Version v1.4.0-2-g984c5a5e-dirty`},
38+
}
39+
40+
fakeexec, _ := testutils.GetFakeExecWithScripts(calls)
41+
42+
c := &AzureCNIClient{exec: fakeexec}
43+
version, err := c.GetVersion()
44+
require.NoError(t, err)
45+
46+
expectedVersion, err := ver.NewVersion("v1.4.0-2-g984c5a5e-dirty")
47+
require.NoError(t, err)
48+
49+
require.Equal(t, expectedVersion, version)
50+
}

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require (
1515
github.com/golang/mock v1.2.0
1616
github.com/google/uuid v1.1.1
1717
github.com/gorilla/mux v1.8.0
18+
github.com/hashicorp/go-version v1.3.0
1819
github.com/hashicorp/golang-lru v0.5.3 // indirect
1920
github.com/imdario/mergo v0.3.8 // indirect
2021
github.com/ishidawataru/sctp v0.0.0-20210226210310-f2269e66cdee // indirect
@@ -43,9 +44,11 @@ require (
4344
google.golang.org/protobuf v1.25.0
4445
gotest.tools/v3 v3.0.2 // indirect
4546
k8s.io/api v0.18.19
47+
k8s.io/apiextensions-apiserver v0.18.2
4648
k8s.io/apimachinery v0.18.19
4749
k8s.io/client-go v0.18.19
4850
k8s.io/klog v1.0.0
4951
k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89
5052
sigs.k8s.io/controller-runtime v0.6.0
53+
sigs.k8s.io/yaml v1.2.0
5154
)

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb
206206
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
207207
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
208208
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
209+
github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw=
210+
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
209211
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
210212
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
211213
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=

test/utils/utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func RequireRootforTest(t *testing.T) {
6565
}
6666
}
6767

68-
func RequireRootforTestMain(m *testing.M) {
68+
func RequireRootforTestMain() {
6969
if !isCurrentUserRoot() {
7070
log.Printf("These tests require root!")
7171
os.Exit(1)

vendor/github.com/hashicorp/go-version/CHANGELOG.md

Lines changed: 25 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)