mirror of
https://github.com/aquasecurity/kube-bench.git
synced 2024-12-22 14:48:07 +00:00
Merge pull request #34 from aquasecurity/kubectl-version
Use kubectl to check the kubernetes version
This commit is contained in:
commit
45cf25e007
@ -45,7 +45,8 @@ var (
|
|||||||
errmsgs string
|
errmsgs string
|
||||||
|
|
||||||
// TODO: Consider specifying this in config file.
|
// TODO: Consider specifying this in config file.
|
||||||
kubeVersion = "1.7.0"
|
kubeMajorVersion = "1"
|
||||||
|
kubeMinorVersion = "7"
|
||||||
)
|
)
|
||||||
|
|
||||||
func runChecks(t check.NodeType) {
|
func runChecks(t check.NodeType) {
|
||||||
@ -77,6 +78,7 @@ func runChecks(t check.NodeType) {
|
|||||||
fedControllerManagerBin = viper.GetString("installation." + installation + ".federated.bin.controller-manager")
|
fedControllerManagerBin = viper.GetString("installation." + installation + ".federated.bin.controller-manager")
|
||||||
|
|
||||||
// Run kubernetes installation validation checks.
|
// Run kubernetes installation validation checks.
|
||||||
|
verifyKubeVersion(kubeMajorVersion, kubeMinorVersion)
|
||||||
verifyNodeType(t)
|
verifyNodeType(t)
|
||||||
|
|
||||||
switch t {
|
switch t {
|
||||||
@ -150,15 +152,12 @@ func runChecks(t check.NodeType) {
|
|||||||
func verifyNodeType(t check.NodeType) {
|
func verifyNodeType(t check.NodeType) {
|
||||||
switch t {
|
switch t {
|
||||||
case check.MASTER:
|
case check.MASTER:
|
||||||
verifyKubeVersion(apiserverBin)
|
|
||||||
verifyBin(apiserverBin, schedulerBin, controllerManagerBin)
|
verifyBin(apiserverBin, schedulerBin, controllerManagerBin)
|
||||||
verifyConf(apiserverConf, schedulerConf, controllerManagerConf)
|
verifyConf(apiserverConf, schedulerConf, controllerManagerConf)
|
||||||
case check.NODE:
|
case check.NODE:
|
||||||
verifyKubeVersion(kubeletBin)
|
|
||||||
verifyBin(kubeletBin, proxyBin)
|
verifyBin(kubeletBin, proxyBin)
|
||||||
verifyConf(kubeletConf, proxyConf)
|
verifyConf(kubeletConf, proxyConf)
|
||||||
case check.FEDERATED:
|
case check.FEDERATED:
|
||||||
verifyKubeVersion(fedApiserverBin)
|
|
||||||
verifyBin(fedApiserverBin, fedControllerManagerBin)
|
verifyBin(fedApiserverBin, fedControllerManagerBin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
53
cmd/util.go
53
cmd/util.go
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/aquasecurity/kube-bench/check"
|
"github.com/aquasecurity/kube-bench/check"
|
||||||
@ -123,25 +124,61 @@ func verifyBin(binPath ...string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyKubeVersion(b string) {
|
func verifyKubeVersion(major string, minor string) {
|
||||||
// These executables might not be on the user's path.
|
// These executables might not be on the user's path.
|
||||||
// TODO! Check the version number using kubectl, which is more likely to be on the path.
|
|
||||||
|
|
||||||
_, err := exec.LookPath(b)
|
_, err := exec.LookPath("kubectl")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continueWithError(err, sprintlnWarn("Kubernetes version check skipped"))
|
continueWithError(err, sprintlnWarn("Kubernetes version check skipped"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.Command(b, "--version")
|
cmd := exec.Command("kubectl", "version")
|
||||||
out, err := cmd.Output()
|
out, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continueWithError(err, sprintlnWarn("Kubernetes version check skipped"))
|
s := fmt.Sprintf("Kubernetes version check skipped with error %v", err)
|
||||||
|
continueWithError(err, sprintlnWarn(s))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
matched := strings.Contains(string(out), kubeVersion)
|
msg := checkVersion("Client", string(out), major, minor)
|
||||||
if !matched {
|
if msg != "" {
|
||||||
printlnWarn(fmt.Sprintf("Unsupported kubernetes version: %s", out))
|
continueWithError(fmt.Errorf(msg), msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = checkVersion("Server", string(out), major, minor)
|
||||||
|
if msg != "" {
|
||||||
|
continueWithError(fmt.Errorf(msg), msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var regexVersionMajor = regexp.MustCompile("Major:\"([0-9]+)\"")
|
||||||
|
var regexVersionMinor = regexp.MustCompile("Minor:\"([0-9]+)\"")
|
||||||
|
|
||||||
|
func checkVersion(x string, s string, expMajor string, expMinor string) string {
|
||||||
|
regexVersion, err := regexp.Compile(x + " Version: version.Info{(.*)}")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("Error checking Kubernetes version: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ss := regexVersion.FindString(s)
|
||||||
|
major := versionMatch(regexVersionMajor, ss)
|
||||||
|
minor := versionMatch(regexVersionMinor, ss)
|
||||||
|
if major == "" || minor == "" {
|
||||||
|
return fmt.Sprintf("Couldn't find %s version from kubectl output '%s'", x, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
if major != expMajor || minor != expMinor {
|
||||||
|
return fmt.Sprintf("Unexpected %s version %s.%s", x, major, minor)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func versionMatch(r *regexp.Regexp, s string) string {
|
||||||
|
match := r.FindStringSubmatch(s)
|
||||||
|
if len(match) < 2 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return match[1]
|
||||||
|
}
|
||||||
|
77
cmd/util_test.go
Normal file
77
cmd/util_test.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// Copyright © 2017 Aqua Security Software Ltd. <info@aquasec.com>
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCheckVersion(t *testing.T) {
|
||||||
|
kubeoutput := `Client Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-06-30T09:51:01Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"darwin/amd64"}
|
||||||
|
Server Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-07-26T00:12:31Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}`
|
||||||
|
cases := []struct {
|
||||||
|
t string
|
||||||
|
s string
|
||||||
|
major string
|
||||||
|
minor string
|
||||||
|
exp string
|
||||||
|
}{
|
||||||
|
{t: "Client", s: kubeoutput, major: "1", minor: "7"},
|
||||||
|
{t: "Server", s: kubeoutput, major: "1", minor: "7"},
|
||||||
|
{t: "Client", s: kubeoutput, major: "1", minor: "6", exp: "Unexpected Client version 1.7"},
|
||||||
|
{t: "Client", s: kubeoutput, major: "2", minor: "0", exp: "Unexpected Client version 1.7"},
|
||||||
|
{t: "Server", s: "something unexpected", major: "2", minor: "0", exp: "Couldn't find Server version from kubectl output 'something unexpected'"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
t.Run("", func(t *testing.T) {
|
||||||
|
m := checkVersion(c.t, c.s, c.major, c.minor)
|
||||||
|
if m != c.exp {
|
||||||
|
t.Fatalf("Got: %s, expected: %s", m, c.exp)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVersionMatch(t *testing.T) {
|
||||||
|
minor := regexVersionMinor
|
||||||
|
major := regexVersionMajor
|
||||||
|
client := `Client Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-06-30T09:51:01Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"darwin/amd64"}`
|
||||||
|
server := `Server Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-07-26T00:12:31Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}`
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
r *regexp.Regexp
|
||||||
|
s string
|
||||||
|
exp string
|
||||||
|
}{
|
||||||
|
{r: major, s: server, exp: "1"},
|
||||||
|
{r: minor, s: server, exp: "7"},
|
||||||
|
{r: major, s: client, exp: "1"},
|
||||||
|
{r: minor, s: client, exp: "7"},
|
||||||
|
{r: major, s: "Some unexpected string"},
|
||||||
|
{r: minor}, // Checking that we don't fall over if the string is empty
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
t.Run("", func(t *testing.T) {
|
||||||
|
m := versionMatch(c.r, c.s)
|
||||||
|
if m != c.exp {
|
||||||
|
t.Fatalf("Got %s expected %s", m, c.exp)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user