diff --git a/cmd/tk/check.go b/cmd/tk/check.go index 4ebb03ab..1a3f75c4 100644 --- a/cmd/tk/check.go +++ b/cmd/tk/check.go @@ -5,6 +5,7 @@ import ( "os" "os/exec" + "github.com/blang/semver" "github.com/spf13/cobra" ) @@ -30,19 +31,24 @@ func init() { } func runCheckCmd(cmd *cobra.Command, args []string) error { - if !checkLocal() { + if !kubectlCheck(">=1.14.0") { os.Exit(1) } + + if !kustomizeCheck(">=3.5.0") { + os.Exit(1) + } + if checkPre { fmt.Println(`✔`, "all prerequisites checks passed") return nil } - if !checkRemote() { + if !kubernetesCheck(">=1.14.0") { os.Exit(1) - } else { - fmt.Println(`✔`, "all checks passed") } + + fmt.Println(`✔`, "all checks passed") return nil } @@ -57,10 +63,69 @@ func checkLocal() bool { fmt.Println(`✔`, cmd, "found") } } + return ok } -func checkRemote() bool { +func kubectlCheck(version string) bool { + _, err := exec.LookPath("kubectl") + if err != nil { + fmt.Println(`✗`, "kubectl not found") + return false + } + + output, err := execCommand("kubectl version --client --short | awk '{ print $3 }'") + if err != nil { + fmt.Println(`✗`, "kubectl version can't be determined") + return false + } + + v, err := semver.ParseTolerant(output) + if err != nil { + fmt.Println(`✗`, "kubectl version can't be determined") + return false + } + + rng, _ := semver.ParseRange(version) + if !rng(v) { + fmt.Println(`✗`, "kubectl version must be", version) + return false + } + + fmt.Println(`✔`, "kubectl", v.String()) + return true +} + +func kustomizeCheck(version string) bool { + _, err := exec.LookPath("kustomize") + if err != nil { + fmt.Println(`✗`, "kustomize not found") + return false + } + + output, err := execCommand("kustomize version --short | awk '{ print $1 }' | cut -c2-") + if err != nil { + fmt.Println(`✗`, "kustomize version can't be determined") + return false + } + + v, err := semver.ParseTolerant(output) + if err != nil { + fmt.Println(`✗`, "kustomize version can't be determined") + return false + } + + rng, _ := semver.ParseRange(version) + if !rng(v) { + fmt.Println(`✗`, "kustomize version must be", version) + return false + } + + fmt.Println(`✔`, "kustomize", v.String()) + return true +} + +func kubernetesCheck(version string) bool { client, err := NewKubernetesClient() if err != nil { fmt.Println(`✗`, "kubernetes client initialization failed", err.Error()) @@ -73,6 +138,27 @@ func checkRemote() bool { return false } - fmt.Println(`✔`, "kubernetes version", ver.String()) + v, err := semver.ParseTolerant(ver.String()) + if err != nil { + fmt.Println(`✗`, "kubernetes version can't be determined") + return false + } + + rng, _ := semver.ParseRange(version) + if !rng(v) { + fmt.Println(`✗`, "kubernetes version must be", version) + return false + } + + fmt.Println(`✔`, "kubernetes", v.String()) return true } + +func execCommand(command string) (string, error) { + c := exec.Command("/bin/sh", "-c", command) + output, err := c.CombinedOutput() + if err != nil { + return "", err + } + return string(output), nil +} diff --git a/go.mod b/go.mod index dedccacb..b95b3c7b 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/fluxcd/toolkit go 1.14 require ( + github.com/blang/semver v3.5.1+incompatible github.com/spf13/cobra v0.0.6 k8s.io/client-go v0.18.0 ) diff --git a/go.sum b/go.sum index 4ebe84a9..7a5d5664 100644 --- a/go.sum +++ b/go.sum @@ -26,6 +26,9 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/blang/semver v1.1.0 h1:ol1rO7QQB5uy7umSNV7VAmLugfLRD+17sYJujRNYPhg= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=