Skip to content

Commit 818908a

Browse files
committed
fix: Upgrade to Go 1.21, test Kubernetes 1.25-1.28, refine engine & CLI
* Perform compatibility tests with Kubernetes versions 1.25 to 1.28 * Transition to using Go version 1.21 * Update end-to-end tests for the latest GKE and EKS versions, including various CNIs * Rectify a critical bug in the engine which led to delays post parent context cancellation * Refactor CLI for precise association of command line flags with their intended subcommands
1 parent 19cfdf9 commit 818908a

34 files changed

+5308
-181
lines changed

.github/workflows/build.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ jobs:
2020
- name: Run golangci-lint
2121
uses: reviewdog/action-golangci-lint@v2
2222
with:
23-
go_version: "1.20"
23+
go_version: "1.21"
24+
golangci_lint_flags: "--timeout=5m0s"
2425
build:
2526
runs-on: ubuntu-latest
2627
needs: lint
@@ -31,7 +32,7 @@ jobs:
3132
- name: Setup Go
3233
uses: actions/setup-go@v3
3334
with:
34-
go-version: '1.20.x'
35+
go-version: '1.21.x'
3536

3637
- name: Install dependencies
3738
run: go get ./...

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@ All notable changes to this project will be documented in this file.
44

55
## Table of Contents
66

7+
- [2.0.3](#203)
78
- [2.0.2](#202)
89
- [2.0.1](#201)
910
- [2.0.0](#200)
1011
- [0.1.0](#010)
1112

1213
---
1314

15+
## `2.0.3`
16+
17+
- test with latest version of Kubernetes and update to Go 1.21
18+
- update e2e tests with latest version of EKS and GKE and Calico CNI
19+
1420
## `2.0.2`
1521

1622
- integrate e2e tests with network policies
@@ -31,4 +37,4 @@ All notable changes to this project will be documented in this file.
3137
## `0.1.0`
3238

3339
- initial release
34-
- no artifacts available
40+
- no artifacts available

README.md

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ The [`sniffer`](https://github.com/controlplaneio/netassertv2-packet-sniffer) an
2424

2525
## Installation
2626

27-
Download the latest stable version of `NetAssert` from the [releases](https://github.com/controlplaneio/netassert/releases) page
27+
- Please download the latest stable version of `NetAssert` from [releases](https://github.com/controlplaneio/netassert/releases) page. The binary is available for Linux, MacOS and Windows platforms.
28+
29+
- If you are on Unix/Linux, you can also use the [download.sh](./download.sh) script to download the latest version of `NetAssert` into the current path:
30+
31+
```bash
32+
curl -sL https://raw.githubusercontent.com/controlplaneio/netassert/master/download.sh | bash
33+
```
2834

2935
## Test specification
3036

@@ -257,37 +263,42 @@ All the tests are read from an YAML file or a directory (step **1**) and the res
257263
statefulset.apps/web created
258264
```
259265

260-
- Run the netassert binary pointing it to the test cases:
266+
- Run the netassert binary pointing it to the test cases, one of the test cases will fail and this is by design:
261267

262268
```bash
263-
❯ ./netassert run --input-file cmd/netassert/cli/test-cases.yaml
269+
## if you have Go installed, you can build the binary using the the following command
270+
❯ just build ## from the root of the project
271+
go build -ldflags="-X 'main.appName=NetAssert' -X 'main.version=2.0.0-dev'" -o bin/netassert cmd/netassert/cli/*.go
264272

265-
❯ cat results.tap
266-
1..4
273+
❯ bin/netassert run --input-file ./sample-tests/test-cases/test-cases.yaml
274+
275+
❯ cat results.tap
276+
TAP version 14
277+
1..6
267278
ok 1 - busybox-deploy-to-echoserver-deploy
268-
ok 2 - busybox-deploy-to-core-dns
269-
ok 3 - test-from-busybox-to-web-statefulset
270-
not ok 4 - test-from-busybox-to-host
279+
ok 2 - busybox-deploy-to-echoserver-deploy-2
280+
ok 3 - busybox-deploy-to-web-statefulset
281+
ok 4 - busybox-deploy-to-control-plane-dot-io
282+
ok 5 - test-from-pod1-to-pod2
283+
not ok 6 - busybox-deploy-to-fake-host
271284
---
272-
reason: ephemeral container netassertv2-client-u8dqy3qwo exit code for test test-from-busybox-to-host
285+
reason: ephemeral container netassertv2-client-7y16ra1f9 exit code for test busybox-deploy-to-fake-host
273286
is 1 instead of 0
274-
...
275-
276287

277288
```
278289

279290
## Compatibility
280291

281-
Netassert has been tested with the following flavours of Kubernetes:
292+
NetAssert is architected for compatibility with Kubernetes versions that offer support for ephemeral containers. We have thoroughly tested NetAssert with Kubernetes versions 1.25 to 1.28, confirming compatibility and performance stability.
293+
294+
For broader validation, our team has also executed comprehensive [end-to-end tests](./e2e/README.md) against various Kubernetes distributions and CNIs which is detailed below:
282295

283-
| K8s Distribution | Version | CNI | Working |
284-
|------------------|---------|---------------------------------|---------|
285-
| AWS EKS | 1.25 | AWS VPC CNI | Yes |
286-
| AWS EKS | 1.24 | AWS VPC CNI | Yes |
287-
| AWS EKS | 1.25 | Calico Version 3.25 | Yes |
288-
| AWS EKS | 1.24 | Calico version 3.25 | Yes |
289-
| GCP GKE | 1.24 | GCP VPC CNI | Yes |
290-
| GCP GKE | 1.24 | GCP Cilium 1.11 (Dataplane v2) | Yes |
296+
| Kubernetes Distribution | Supported Version | Container Network Interface (CNI) |
297+
|-------------------------|-------------------|------------------------------------
298+
| Amazon EKS | 1.25 and higher | AWS VPC CNI |
299+
| Amazon EKS | 1.25 and higher | Calico (Version 3.25 or later) |
300+
| Google GKE | 1.24 and higher | Google Cloud Platform VPC CNI |
301+
| Google GKE | 1.24 and higher | Google Cloud Dataplane V2 |
291302

292303
## Checking for ephemeral container support
293304

cmd/netassert/cli/common.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import (
55

66
"github.com/controlplaneio/netassert/v2/internal/data"
77
"github.com/controlplaneio/netassert/v2/internal/kubeops"
8+
"github.com/hashicorp/go-hclog"
89
)
910

1011
// loadTestCases - Reads test from a file or Directory
11-
func loadTestCases() (data.Tests, error) {
12+
func loadTestCases(testCasesFile, testCasesDir string) (data.Tests, error) {
1213
if testCasesFile == "" && testCasesDir == "" {
1314
return nil, errors.New("either an input file or an input dir containing the tests must be provided using " +
1415
"flags (--input-file or --input-dir)")
@@ -35,11 +36,11 @@ func loadTestCases() (data.Tests, error) {
3536
}
3637

3738
// createService - creates a new kubernetes operations service
38-
func createService() (*kubeops.Service, error) {
39+
func createService(kubeconfigPath string, l hclog.Logger) (*kubeops.Service, error) {
3940
// if the user has supplied a kubeConfig file location then
40-
if kubeConfig != "" {
41-
return kubeops.NewServiceFromKubeConfigFile(kubeConfig, lg)
41+
if kubeconfigPath != "" {
42+
return kubeops.NewServiceFromKubeConfigFile(kubeconfigPath, l)
4243
}
4344

44-
return kubeops.NewDefaultService(lg)
45+
return kubeops.NewDefaultService(l)
4546
}

cmd/netassert/cli/gen_result.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import (
44
"fmt"
55
"os"
66

7+
"github.com/hashicorp/go-hclog"
8+
79
"github.com/controlplaneio/netassert/v2/internal/data"
810
)
911

1012
// genResult - Prints results to Stdout and writes it to a Tap file
11-
func genResult(testCases data.Tests) error {
13+
func genResult(testCases data.Tests, tapFile string, lg hclog.Logger) error {
1214
failedTestCases := 0
1315

1416
for _, v := range testCases {
@@ -35,7 +37,7 @@ func genResult(testCases data.Tests) error {
3537
return fmt.Errorf("unable to close tap file %q: %w", tapFile, err)
3638
}
3739

38-
lg.Info("✍ Wrote TAP File", "fileName", tapFile)
40+
lg.Info("✍ Wrote test result in a TAP File", "fileName", tapFile)
3941

4042
if failedTestCases > 0 {
4143
return fmt.Errorf("total %v test cases have failed", failedTestCases)

cmd/netassert/cli/ping.go

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,51 @@ package main
22

33
import (
44
"context"
5+
"fmt"
56
"os"
7+
"time"
68

79
"github.com/spf13/cobra"
10+
11+
"github.com/controlplaneio/netassert/v2/internal/logger"
12+
)
13+
14+
const (
15+
apiServerHealthEndpoint = `/healthz` // health endpoint for the K8s server
816
)
917

10-
// health endpoint for the K8s server
11-
var apiServerHealthEndpoint = `/healthz`
18+
type pingCmdConfig struct {
19+
KubeConfig string
20+
PingTimeout time.Duration
21+
}
22+
23+
var pingCmdCfg = pingCmdConfig{}
1224

1325
var pingCmd = &cobra.Command{
1426
Use: "ping",
15-
Short: "pings the K8s API server over HTTP to see if it is alive and also checks if the server has support for " +
16-
"ephemeral containers",
17-
Long: "pings the K8s API server over HTTP to see if it is alive and also checks if the server has support for " +
18-
"ephemeral/debug containers",
27+
Short: "pings the K8s API server over HTTP(S) to see if it is alive and also checks if the server has support for " +
28+
"ephemeral containers.",
29+
Long: "pings the K8s API server over HTTP(S) to see if it is alive and also checks if the server has support for " +
30+
"ephemeral/debug containers.",
1931
Run: func(cmd *cobra.Command, args []string) {
20-
ping()
32+
ctx, cancel := context.WithTimeout(context.Background(), pingCmdCfg.PingTimeout)
33+
defer cancel()
34+
ping(ctx)
2135
},
2236
Version: rootCmd.Version,
2337
}
2438

2539
// checkEphemeralContainerSupport checks to see if ephemeral containers are supported by the K8s server
26-
func ping() {
27-
k8sSvc, err := createService()
40+
func ping(ctx context.Context) {
41+
lg := logger.NewHCLogger("info", fmt.Sprintf("%s-%s", appName, version), os.Stdout)
42+
43+
k8sSvc, err := createService(pingCmdCfg.KubeConfig, lg)
44+
2845
if err != nil {
29-
lg.Error("Failed to build K8s Client", "error", err)
46+
lg.Error("Ping failed, unable to build K8s Client", "error", err)
3047
os.Exit(1)
3148
}
3249

33-
ctx := context.Background()
34-
3550
if err := k8sSvc.PingHealthEndpoint(ctx, apiServerHealthEndpoint); err != nil {
3651
lg.Error("Ping failed", "error", err)
3752
os.Exit(1)
@@ -47,3 +62,9 @@ func ping() {
4762

4863
lg.Info("✅ Ephemeral containers are supported by the Kubernetes server")
4964
}
65+
66+
func init() {
67+
pingCmd.Flags().DurationVarP(&pingCmdCfg.PingTimeout, "timeout", "t", 60*time.Second,
68+
"Timeout for the ping command")
69+
pingCmd.Flags().StringVarP(&pingCmdCfg.KubeConfig, "kubeconfig", "k", "", "path to kubeconfig file")
70+
}

cmd/netassert/cli/root.go

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,30 @@ package main
22

33
import (
44
"fmt"
5-
"os"
65

7-
"github.com/controlplaneio/netassert/v2/internal/logger"
8-
"github.com/hashicorp/go-hclog"
96
"github.com/spf13/cobra"
107
)
118

129
var (
13-
logLevel string // our log leve
14-
lg hclog.Logger // command logger
15-
kubeConfig string // location of kubeconfig file
16-
testCasesFile string // location of test cases file
17-
testCasesDir string // location of directory containing the test cases
18-
version = "v2.0.0-dev" // netassert version
19-
appName = "NetAssert" // name of the application
20-
gitHash = "" // the git hash of the build
21-
buildDate = "" // build date, will be injected by the build system
10+
version = "v2.0.0-dev" // netassert version
11+
appName = "NetAssert" // name of the application
12+
gitHash = "" // the git hash of the build
13+
buildDate = "" // build date, will be injected by the build system
2214
)
2315

2416
var rootCmd = &cobra.Command{
2517
Use: "netassert",
2618
Short: "NetAssert is a command line utility to test network connectivity between kubernetes objects",
2719
Long: "NetAssert is a command line utility to test network connectivity between kubernetes objects. " +
2820
"It currently supports Deployment, Pod, Statefulset and Daemonset. You can check the traffic flow between these objects or from these " +
29-
"objects to a remote host or an IP address",
21+
"objects to a remote host or an IP address.",
3022

31-
PersistentPreRun: initCommon,
3223
Version: fmt.Sprintf("\nNetAssert by control-plane.io\n"+
3324
"Version: %s\nCommit Hash: %s\nBuild Date: %s\n",
3425
version, gitHash, buildDate),
3526
}
3627

37-
// init the logger and log basic app info
38-
func initCommon(cmd *cobra.Command, args []string) {
39-
lg = logger.NewHCLogger(logLevel, fmt.Sprintf("%s-%s", appName, version), os.Stdout)
40-
}
41-
4228
func init() {
43-
rootCmd.PersistentFlags().StringVarP(&kubeConfig, "kubeconfig", "k", kubeConfig, "kubeconfig path")
44-
rootCmd.PersistentFlags().StringVarP(&testCasesFile, "input-file", "f", "", "input test file that contains a list of netassert tests")
45-
rootCmd.PersistentFlags().StringVarP(&testCasesDir, "input-dir", "d", "", "input test directory that contains a list of netassert test files")
46-
rootCmd.PersistentFlags().StringVarP(&logLevel, "log-level", "l", "info", "set log level (info, debug or trace)")
47-
4829
// add our subcommands
4930
rootCmd.AddCommand(runCmd)
5031
rootCmd.AddCommand(validateCmd)

0 commit comments

Comments
 (0)