Skip to content

Commit 84c2c2e

Browse files
Kubectl version requirement cannot be satisfied #69 (#70)
* Fix cheking of requirement bin versions #69 * Do not use make in gh action
1 parent 42cac30 commit 84c2c2e

File tree

4 files changed

+92
-35
lines changed

4 files changed

+92
-35
lines changed

.github/workflows/go.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444

4545
-
4646
name: Run tests
47-
run: make test
47+
run: go test -race -timeout 60s ./cmd/hub/...
4848

4949
-
5050
name: Build

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ staticcheck: bin/$(OS)/staticcheck
6262
@$(GOBIN)/staticcheck github.com/epam/hubctl/...
6363
.PHONY: staticcheck
6464

65-
test:
65+
test: deps
6666
go test -race -timeout 60s ./cmd/hub/...
6767
.PHONY: test
6868

cmd/hub/lifecycle/requirement.go

+16-13
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727

2828
const (
2929
providedByEnv = "*environment*"
30-
gcpServiceAccountsHelp = "https://cloud.google.com/docs/authentication/getting-started"
30+
gcpServiceAccountsHelp = "https://cloud.google.com/docs/authentication/provide-credentials-adc"
3131
azureGoSdkAuthHelp = "https://docs.microsoft.com/en-us/go/azure/azure-sdk-go-authorization"
3232
)
3333

@@ -160,14 +160,15 @@ func setupRequirement(requirement string, provider string,
160160
}
161161

162162
var bins = map[string][]string{
163-
"aws": {"aws", "s3", "ls", "--page-size", "5"},
163+
"aws": {"aws", "--version"},
164164
"azure": {"az", "version"},
165165
"gcp": {"gcloud", "version"},
166166
"gcs": {"gsutil", "version"},
167-
"kubectl": {"kubectl", "version", "--client"},
168-
"kubernetes": {"kubectl", "version", "--client"},
169-
"helm": {"helm", "version", "--client"},
170-
"etcd": {"etcdctl", "--version"},
167+
"kubectl": {"kubectl", "version", "--client", "--output=json"},
168+
"kubernetes": {"kubectl", "version", "--client", "--output=json"},
169+
"vault": {"vault", "version"},
170+
"helm": {"helm", "version"},
171+
"terraform": {"terraform", "version"},
171172
}
172173

173174
type BinVersion struct {
@@ -184,12 +185,14 @@ func semver(s string) *version.Version {
184185
}
185186

186187
var binVersion = map[string]*BinVersion{
187-
"gcloud": {semver("246.0.0"), regexp.MustCompile(`Google Cloud SDK ([\d.]+)`)},
188-
"gsutil": {semver("4.38"), regexp.MustCompile(`version: ([\d.]+)`)},
189-
"vault": {semver("1.3.2"), regexp.MustCompile(`Vault v([\d.]+)`)},
190-
"kubectl": {semver("1.18.15"), regexp.MustCompile(`GitVersion:"v([\d.]+)`)},
191-
"helm": {semver("3.5.1"), regexp.MustCompile(`(?:SemVer|Version):"v([\d.]+)`)},
192-
"terraform": {semver("0.14.0"), regexp.MustCompile(`Terraform v([\d.]+)`)},
188+
"aws": {semver("2.10.0"), regexp.MustCompile(`aws-cli/([\d.]+)`)},
189+
"az": {semver("2.40.0"), regexp.MustCompile(`"azure-cli": "([\d.]+)"`)},
190+
"gcloud": {semver("400.0.0"), regexp.MustCompile(`Google Cloud SDK ([\d.]+)`)},
191+
"gsutil": {semver("5.0"), regexp.MustCompile(`version: ([\d.]+)`)},
192+
"vault": {semver("1.10"), regexp.MustCompile(`Vault v([\d.]+)`)},
193+
"kubectl": {semver("1.19"), regexp.MustCompile(`"gitVersion": "v([\d.]+)"`)},
194+
"helm": {semver("3.11"), regexp.MustCompile(`(?:SemVer|Version):"v([\d.]+)"`)},
195+
"terraform": {semver("1.0"), regexp.MustCompile(`Terraform v([\d.]+)`)},
193196
}
194197

195198
func checkStackRequires(requires []string, optional, requiresOfOptionalComponents map[string][]string) map[string][]string {
@@ -289,7 +292,7 @@ func checkRequiresBin(bin ...string) ([]byte, error) {
289292
// validates binary version against minimum required version
290293
//
291294
// reqVer: required version and regexp to extract version string
292-
// currVer: raw output from binary
295+
// out: raw output from binary
293296
//
294297
// returns error version is not valid
295298
func checkRequiresBinVersion(reqVer *BinVersion, out []byte) error {

cmd/hub/lifecycle/requirement_test.go

+74-20
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,89 @@ import (
44
"fmt"
55
"testing"
66

7-
"github.com/hashicorp/go-version"
87
"github.com/stretchr/testify/assert"
98
)
109

11-
var helmVerTpl = "version.BuildInfo{Version:\"%s\", GitCommit:\"50f003e5ee8704ec937a756c646870227d7c8b58\", GitTreeState:\"clean\", GoVersion:\"go1.18.8\"}"
10+
var outputTemplates = map[string]string{
11+
"aws": "aws-cli/%s Python/3.11.5 Linux/5.15.90.1 source/x86_64.ubuntu.22 prompt/off",
12+
"az": `{
13+
"azure-cli": "%s",
14+
"azure-cli-core": "2.52.0",
15+
"azure-cli-telemetry": "1.1.0",
16+
"extensions": {}
17+
}`,
18+
"gcloud": `Google Cloud SDK %s
19+
alpha 2023.09.13
20+
beta 2023.09.13
21+
bq 2.0.98
22+
bundled-python3-unix 3.9.16
23+
core 2023.09.13
24+
gcloud-crc32c 1.0.0
25+
gsutil 5.25`,
26+
"gsutil": "version: %s",
27+
"vault": "Vault v%s ('56debfa71653e72433345f23cd26276bc90629ce+CHANGES'), built 2023-09-11T21:23:55Z",
28+
"kubectl": `{
29+
"clientVersion": {
30+
"major": "1",
31+
"minor": "28",
32+
"gitVersion": "v%s",
33+
"gitCommit": "8dc49c4b984b897d423aab4971090e1879eb4f23",
34+
"gitTreeState": "clean",
35+
"buildDate": "2023-08-24T11:16:29Z",
36+
"goVersion": "go1.20.7",
37+
"compiler": "gc",
38+
"platform": "linux/amd64"
39+
},
40+
"kustomizeVersion": "v5.0.4-0.20230601165947-6ce0bf390ce3"
41+
}`,
42+
"helm": "version.BuildInfo{Version:\"v%s\", GitCommit:\"3a31588ad33fe3b89af5a2a54ee1d25bfe6eaa5e\", GitTreeState:\"clean\", GoVersion:\"go1.20.7\"}",
43+
"terraform": "Terraform v%s\non linux_amd64",
44+
}
45+
46+
func formatVersion(binary, version string) []byte {
47+
return []byte(fmt.Sprintf(outputTemplates[binary], version))
48+
}
49+
50+
func testRequiredbinaryVersion(binary, equalVersion, newerVersion, olderVersion, startFromTen string, t *testing.T) {
51+
reqVer := binVersion[binary]
52+
err := checkRequiresBinVersion(reqVer, formatVersion(binary, equalVersion))
53+
assert.NoError(t, err, "When version is equal with minimal required, checkRequiresBinVersion should not return validation error")
54+
err = checkRequiresBinVersion(reqVer, formatVersion(binary, newerVersion))
55+
assert.NoError(t, err, "When version is greater than minimal required, checkRequiresBinVersion should not return validation error")
56+
err = checkRequiresBinVersion(reqVer, formatVersion(binary, olderVersion))
57+
assert.Error(t, err, "When version is less than minimal required, checkRequiresBinVersion should return validation error")
58+
err = checkRequiresBinVersion(reqVer, formatVersion(binary, startFromTen))
59+
assert.NoError(t, err, "When version number starts with 1 but actually is 10, checkRequiresBinVersion should not return validation error")
60+
}
61+
62+
func TestCheckAwsVersion(t *testing.T) {
63+
testRequiredbinaryVersion("aws", "2.10", "2.13.19", "2.0.2", "10.1.1", t)
64+
}
1265

13-
func formatHelmVersion(version string) []byte {
14-
return []byte(fmt.Sprintf(helmVerTpl, version))
66+
func TestCheckAzureVersion(t *testing.T) {
67+
testRequiredbinaryVersion("az", "2.40", "2.52.0", "2.0.2", "10.1.1", t)
1568
}
1669

17-
func TestCheckRequiresBinVersion(t *testing.T) {
18-
min, _ := version.NewVersion("3.5.2")
19-
helm := binVersion["helm"]
20-
helm.minVersion = min
70+
func TestCheckGcloudVersion(t *testing.T) {
71+
testRequiredbinaryVersion("gcloud", "400.0.0", "446.0.1", "140.0.2", "1010.1.1", t)
72+
}
2173

22-
raw_data := formatHelmVersion(min.String())
23-
err := checkRequiresBinVersion(helm, raw_data)
24-
assert.Error(t, err, "When versions are equal, checkRequiresBinVersion should not return validation error")
74+
func TestCheckGsutilVersion(t *testing.T) {
75+
testRequiredbinaryVersion("gsutil", "5.0", "5.25", "3.52", "10.1.1", t)
76+
}
2577

26-
raw_data = formatHelmVersion("v0.0.1")
27-
err = checkRequiresBinVersion(helm, raw_data)
28-
assert.Error(t, err, "When version is less than required, checkRequiresBinVersion should return validation error")
78+
func TestCheckVaultVersion(t *testing.T) {
79+
testRequiredbinaryVersion("vault", "1.10.0", "1.14.3", "1.9.10", "10.1.1", t)
80+
}
2981

30-
raw_data = formatHelmVersion("v100.0.0")
31-
err = checkRequiresBinVersion(helm, raw_data)
32-
assert.NoError(t, err, "When version is greater than required, checkRequiresBinVersion should not return validation error")
82+
func TestCheckKubectlVersion(t *testing.T) {
83+
testRequiredbinaryVersion("kubectl", "1.19", "1.28.1", "1.18.15", "10.1.1", t)
84+
}
3385

34-
raw_data = formatHelmVersion("v3.10.2")
35-
err = checkRequiresBinVersion(helm, raw_data)
36-
assert.NoError(t, err, "When version number starts with 1 but actually is 10 there should be no error")
86+
func TestCheckHelmVersion(t *testing.T) {
87+
testRequiredbinaryVersion("helm", "3.11", "3.12.3", "3.5.1", "10.1.1", t)
88+
}
3789

90+
func TestCheckTerraformVersion(t *testing.T) {
91+
testRequiredbinaryVersion("terraform", "1.0", "1.5.7", "0.14.1", "10.1.1", t)
3892
}

0 commit comments

Comments
 (0)