Update auto-detection codes to support check platform version (#1074)

Co-authored-by: Yoav Rotem <yoavrotems97@gmail.com>
pull/939/head^2
Huang Huang 2 years ago committed by GitHub
parent 7dd6fccd17
commit 1fad8f5083
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -313,13 +313,13 @@ func loadTargetMapping(v *viper.Viper) (map[string][]string, error) {
return benchmarkVersionToTargetsMap, nil return benchmarkVersionToTargetsMap, nil
} }
func getBenchmarkVersion(kubeVersion, benchmarkVersion, platformName string, v *viper.Viper) (bv string, err error) { func getBenchmarkVersion(kubeVersion, benchmarkVersion string, platform Platform, v *viper.Viper) (bv string, err error) {
detecetedKubeVersion = "none" detecetedKubeVersion = "none"
if !isEmpty(kubeVersion) && !isEmpty(benchmarkVersion) { if !isEmpty(kubeVersion) && !isEmpty(benchmarkVersion) {
return "", fmt.Errorf("It is an error to specify both --version and --benchmark flags") return "", fmt.Errorf("It is an error to specify both --version and --benchmark flags")
} }
if isEmpty(benchmarkVersion) && isEmpty(kubeVersion) && !isEmpty(platformName) { if isEmpty(benchmarkVersion) && isEmpty(kubeVersion) && !isEmpty(platform.Name) {
benchmarkVersion = getPlatformBenchmarkVersion(platformName) benchmarkVersion = getPlatformBenchmarkVersion(platform)
if !isEmpty(benchmarkVersion) { if !isEmpty(benchmarkVersion) {
detecetedKubeVersion = benchmarkVersion detecetedKubeVersion = benchmarkVersion
} }

@ -324,9 +324,9 @@ func TestGetBenchmarkVersion(t *testing.T) {
t.Fatalf("Unable to load config file %v", err) t.Fatalf("Unable to load config file %v", err)
} }
type getBenchmarkVersionFnToTest func(kubeVersion, benchmarkVersion, platformName string, v *viper.Viper) (string, error) type getBenchmarkVersionFnToTest func(kubeVersion, benchmarkVersion string, platform Platform, v *viper.Viper) (string, error)
withFakeKubectl := func(kubeVersion, benchmarkVersion, platformName string, v *viper.Viper, fn getBenchmarkVersionFnToTest) (string, error) { withFakeKubectl := func(kubeVersion, benchmarkVersion string, platform Platform, v *viper.Viper, fn getBenchmarkVersionFnToTest) (string, error) {
execCode := `#!/bin/sh execCode := `#!/bin/sh
echo '{"serverVersion": {"major": "1", "minor": "18", "gitVersion": "v1.18.10"}}' echo '{"serverVersion": {"major": "1", "minor": "18", "gitVersion": "v1.18.10"}}'
` `
@ -336,40 +336,40 @@ func TestGetBenchmarkVersion(t *testing.T) {
} }
defer restore() defer restore()
return fn(kubeVersion, benchmarkVersion, platformName, v) return fn(kubeVersion, benchmarkVersion, platform, v)
} }
withNoPath := func(kubeVersion, benchmarkVersion, platformName string, v *viper.Viper, fn getBenchmarkVersionFnToTest) (string, error) { withNoPath := func(kubeVersion, benchmarkVersion string, platform Platform, v *viper.Viper, fn getBenchmarkVersionFnToTest) (string, error) {
restore, err := prunePath() restore, err := prunePath()
if err != nil { if err != nil {
t.Fatal("Failed when calling prunePath ", err) t.Fatal("Failed when calling prunePath ", err)
} }
defer restore() defer restore()
return fn(kubeVersion, benchmarkVersion, platformName, v) return fn(kubeVersion, benchmarkVersion, platform, v)
} }
type getBenchmarkVersionFn func(string, string, string, *viper.Viper, getBenchmarkVersionFnToTest) (string, error) type getBenchmarkVersionFn func(string, string, Platform, *viper.Viper, getBenchmarkVersionFnToTest) (string, error)
cases := []struct { cases := []struct {
n string n string
kubeVersion string kubeVersion string
benchmarkVersion string benchmarkVersion string
platformName string platform Platform
v *viper.Viper v *viper.Viper
callFn getBenchmarkVersionFn callFn getBenchmarkVersionFn
exp string exp string
succeed bool succeed bool
}{ }{
{n: "both versions", kubeVersion: "1.11", benchmarkVersion: "cis-1.3", platformName: "", exp: "cis-1.3", callFn: withNoPath, v: viper.New(), succeed: false}, {n: "both versions", kubeVersion: "1.11", benchmarkVersion: "cis-1.3", platform: Platform{}, exp: "cis-1.3", callFn: withNoPath, v: viper.New(), succeed: false},
{n: "no version-missing-kubectl", kubeVersion: "", benchmarkVersion: "", platformName: "", v: viperWithData, exp: "cis-1.6", callFn: withNoPath, succeed: true}, {n: "no version-missing-kubectl", kubeVersion: "", benchmarkVersion: "", platform: Platform{}, v: viperWithData, exp: "cis-1.6", callFn: withNoPath, succeed: true},
{n: "no version-fakeKubectl", kubeVersion: "", benchmarkVersion: "", platformName: "", v: viperWithData, exp: "cis-1.6", callFn: withFakeKubectl, succeed: true}, {n: "no version-fakeKubectl", kubeVersion: "", benchmarkVersion: "", platform: Platform{}, v: viperWithData, exp: "cis-1.6", callFn: withFakeKubectl, succeed: true},
{n: "kubeVersion", kubeVersion: "1.15", benchmarkVersion: "", platformName: "", v: viperWithData, exp: "cis-1.5", callFn: withNoPath, succeed: true}, {n: "kubeVersion", kubeVersion: "1.15", benchmarkVersion: "", platform: Platform{}, v: viperWithData, exp: "cis-1.5", callFn: withNoPath, succeed: true},
{n: "ocpVersion310", kubeVersion: "ocp-3.10", benchmarkVersion: "", platformName: "", v: viperWithData, exp: "rh-0.7", callFn: withNoPath, succeed: true}, {n: "ocpVersion310", kubeVersion: "ocp-3.10", benchmarkVersion: "", platform: Platform{}, v: viperWithData, exp: "rh-0.7", callFn: withNoPath, succeed: true},
{n: "ocpVersion311", kubeVersion: "ocp-3.11", benchmarkVersion: "", platformName: "", v: viperWithData, exp: "rh-0.7", callFn: withNoPath, succeed: true}, {n: "ocpVersion311", kubeVersion: "ocp-3.11", benchmarkVersion: "", platform: Platform{}, v: viperWithData, exp: "rh-0.7", callFn: withNoPath, succeed: true},
{n: "gke12", kubeVersion: "gke-1.2.0", benchmarkVersion: "", platformName: "", v: viperWithData, exp: "gke-1.2.0", callFn: withNoPath, succeed: true}, {n: "gke12", kubeVersion: "gke-1.2.0", benchmarkVersion: "", platform: Platform{}, v: viperWithData, exp: "gke-1.2.0", callFn: withNoPath, succeed: true},
} }
for _, c := range cases { for _, c := range cases {
rv, err := c.callFn(c.kubeVersion, c.benchmarkVersion, c.platformName, c.v, getBenchmarkVersion) rv, err := c.callFn(c.kubeVersion, c.benchmarkVersion, c.platform, c.v, getBenchmarkVersion)
if c.succeed { if c.succeed {
if err != nil { if err != nil {
t.Errorf("[%q]-Unexpected error: %v", c.n, err) t.Errorf("[%q]-Unexpected error: %v", c.n, err)

@ -28,7 +28,7 @@ var masterCmd = &cobra.Command{
Short: "Run Kubernetes benchmark checks from the master.yaml file.", Short: "Run Kubernetes benchmark checks from the master.yaml file.",
Long: `Run Kubernetes benchmark checks from the master.yaml file in cfg/<version>.`, Long: `Run Kubernetes benchmark checks from the master.yaml file in cfg/<version>.`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
bv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformName(), viper.GetViper()) bv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformInfo(), viper.GetViper())
if err != nil { if err != nil {
exitWithError(fmt.Errorf("unable to determine benchmark version: %v", err)) exitWithError(fmt.Errorf("unable to determine benchmark version: %v", err))
} }

@ -28,7 +28,7 @@ var nodeCmd = &cobra.Command{
Short: "Run Kubernetes benchmark checks from the node.yaml file.", Short: "Run Kubernetes benchmark checks from the node.yaml file.",
Long: `Run Kubernetes benchmark checks from the node.yaml file in cfg/<version>.`, Long: `Run Kubernetes benchmark checks from the node.yaml file in cfg/<version>.`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
bv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformName(), viper.GetViper()) bv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformInfo(), viper.GetViper())
if err != nil { if err != nil {
exitWithError(fmt.Errorf("unable to determine benchmark version: %v", err)) exitWithError(fmt.Errorf("unable to determine benchmark version: %v", err))
} }

@ -69,7 +69,7 @@ var RootCmd = &cobra.Command{
Short: "Run CIS Benchmarks checks against a Kubernetes deployment", Short: "Run CIS Benchmarks checks against a Kubernetes deployment",
Long: `This tool runs the CIS Kubernetes Benchmark (https://www.cisecurity.org/benchmark/kubernetes/)`, Long: `This tool runs the CIS Kubernetes Benchmark (https://www.cisecurity.org/benchmark/kubernetes/)`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
bv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformName(), viper.GetViper()) bv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformInfo(), viper.GetViper())
if err != nil { if err != nil {
exitWithError(fmt.Errorf("unable to determine benchmark version: %v", err)) exitWithError(fmt.Errorf("unable to determine benchmark version: %v", err))
} }

@ -32,7 +32,7 @@ var runCmd = &cobra.Command{
exitWithError(fmt.Errorf("unable to get `targets` from command line :%v", err)) exitWithError(fmt.Errorf("unable to get `targets` from command line :%v", err))
} }
bv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformName(), viper.GetViper()) bv, err := getBenchmarkVersion(kubeVersion, benchmarkVersion, getPlatformInfo(), viper.GetViper())
if err != nil { if err != nil {
exitWithError(fmt.Errorf("unable to get benchmark version. error: %v", err)) exitWithError(fmt.Errorf("unable to get benchmark version. error: %v", err))
} }

@ -42,6 +42,15 @@ func init() {
getBinariesFunc = getBinaries getBinariesFunc = getBinaries
} }
type Platform struct {
Name string
Version string
}
func (p Platform) String() string {
return fmt.Sprintf("Platform{ Name: %s Version: %s }", p.Name, p.Version)
}
func exitWithError(err error) { func exitWithError(err error) {
fmt.Fprintf(os.Stderr, "\n%v\n", err) fmt.Fprintf(os.Stderr, "\n%v\n", err)
// flush before exit non-zero // flush before exit non-zero
@ -427,49 +436,59 @@ These program names are provided in the config.yaml, section '%s.%s.bins'
return fmt.Sprintf(errMessageTemplate, component, componentRoleName, binList, componentType, component) return fmt.Sprintf(errMessageTemplate, component, componentRoleName, binList, componentType, component)
} }
func getPlatformName() string { func getPlatformInfo() Platform {
openShiftVersion := getOpenShiftVersion() openShiftInfo := getOpenShiftInfo()
if openShiftVersion != "" { if openShiftInfo.Name != "" && openShiftInfo.Version != "" {
return openShiftVersion return openShiftInfo
} }
kv, err := getKubeVersion() kv, err := getKubeVersion()
if err != nil { if err != nil {
glog.V(2).Info(err) glog.V(2).Info(err)
return "" return Platform{}
} }
return getPlatformNameFromVersion(kv.GitVersion) return getPlatformInfoFromVersion(kv.GitVersion)
} }
func getPlatformNameFromVersion(s string) string { func getPlatformInfoFromVersion(s string) Platform {
versionRe := regexp.MustCompile(`v\d+\.\d+\.\d+-(\w+)(?:[.\-])\w+`) versionRe := regexp.MustCompile(`v(\d+\.\d+)\.\d+-(\w+)(?:[.\-])\w+`)
subs := versionRe.FindStringSubmatch(s) subs := versionRe.FindStringSubmatch(s)
if len(subs) < 2 { if len(subs) < 3 {
return "" return Platform{}
}
return Platform{
Name: subs[2],
Version: subs[1],
} }
return subs[1]
} }
func getPlatformBenchmarkVersion(platform string) string { func getPlatformBenchmarkVersion(platform Platform) string {
glog.V(3).Infof("getPlatformBenchmarkVersion platform: %s", platform) glog.V(3).Infof("getPlatformBenchmarkVersion platform: %s", platform)
switch platform { switch platform.Name {
case "eks": case "eks":
return "eks-1.0.1" return "eks-1.0.1"
case "gke": case "gke":
// TODO: support check kubeVersion switch platform.Version {
return "gke-1.2.0" case "1.15", "1.16", "1.17", "1.18", "1.19":
return "gke-1.0"
default:
return "gke-1.2.0"
}
case "aliyun": case "aliyun":
return "ack-1.0" return "ack-1.0"
case "ocp-3.10": case "ocp":
return "rh-0.7" switch platform.Version {
case "ocp-4.1": case "3.10":
return "rh-1.0" return "rh-0.7"
case "4.1":
return "rh-1.0"
}
} }
return "" return ""
} }
func getOpenShiftVersion() string { func getOpenShiftInfo() Platform {
glog.V(1).Info("Checking for oc") glog.V(1).Info("Checking for oc")
_, err := exec.LookPath("oc") _, err := exec.LookPath("oc")
@ -485,10 +504,10 @@ func getOpenShiftVersion() string {
subs = versionRe.FindStringSubmatch(string(out)) subs = versionRe.FindStringSubmatch(string(out))
} }
if len(subs) > 1 { if len(subs) > 1 {
glog.V(2).Infof("OCP output '%s' \nplatform is %s \nocp %v", string(out), getPlatformNameFromVersion(string(out)), subs[1]) glog.V(2).Infof("OCP output '%s' \nplatform is %s \nocp %v", string(out), getPlatformInfoFromVersion(string(out)), subs[1])
ocpBenchmarkVersion, err := getOcpValidVersion(subs[1]) ocpBenchmarkVersion, err := getOcpValidVersion(subs[1])
if err == nil { if err == nil {
return fmt.Sprintf("ocp-%s", ocpBenchmarkVersion) return Platform{Name: "ocp", Version: ocpBenchmarkVersion}
} else { } else {
glog.V(1).Infof("Can't get getOcpValidVersion: %v", err) glog.V(1).Infof("Can't get getOcpValidVersion: %v", err)
} }
@ -501,7 +520,7 @@ func getOpenShiftVersion() string {
} else { } else {
glog.V(1).Infof("Can't find oc command: %v", err) glog.V(1).Infof("Can't find oc command: %v", err)
} }
return "" return Platform{}
} }
func getOcpValidVersion(ocpVer string) (string, error) { func getOcpValidVersion(ocpVer string) (string, error) {

@ -527,46 +527,45 @@ func Test_getPlatformNameFromKubectlOutput(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
args args args args
want string want Platform
}{ }{
{ {
name: "eks", name: "eks",
args: args{s: "v1.17.9-eks-4c6976"}, args: args{s: "v1.17.9-eks-4c6976"},
want: "eks", want: Platform{Name: "eks", Version: "1.17"},
}, },
{ {
name: "gke", name: "gke",
args: args{s: "v1.17.6-gke.1"}, args: args{s: "v1.17.6-gke.1"},
want: "gke", want: Platform{Name: "gke", Version: "1.17"},
}, },
{ {
name: "ack", name: "ack",
args: args{s: "v1.18.8-aliyun.1"}, args: args{s: "v1.18.8-aliyun.1"},
want: "aliyun", want: Platform{Name: "aliyun", Version: "1.18"},
}, },
{ {
name: "unknown", name: "unknown",
args: args{s: "v1.17.6"}, args: args{s: "v1.17.6"},
want: "", want: Platform{},
}, },
{ {
name: "empty string", name: "empty string",
args: args{s: ""}, args: args{s: ""},
want: "", want: Platform{},
}, },
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if got := getPlatformNameFromVersion(tt.args.s); got != tt.want { got := getPlatformInfoFromVersion(tt.args.s)
t.Errorf("getPlatformNameFromKubectlOutput() = %v, want %v", got, tt.want) assert.Equal(t, tt.want, got)
}
}) })
} }
} }
func Test_getPlatformBenchmarkVersion(t *testing.T) { func Test_getPlatformBenchmarkVersion(t *testing.T) {
type args struct { type args struct {
platform string platform Platform
} }
tests := []struct { tests := []struct {
name string name string
@ -576,49 +575,63 @@ func Test_getPlatformBenchmarkVersion(t *testing.T) {
{ {
name: "eks", name: "eks",
args: args{ args: args{
platform: "eks", platform: Platform{Name: "eks"},
}, },
want: "eks-1.0.1", want: "eks-1.0.1",
}, },
{ {
name: "gke", name: "gke 1.19",
args: args{
platform: Platform{Name: "gke", Version: "1.19"},
},
want: "gke-1.0",
},
{
name: "gke 1.20",
args: args{
platform: Platform{Name: "gke", Version: "1.20"},
},
want: "gke-1.2.0",
},
{
name: "gke 1.22",
args: args{ args: args{
platform: "gke", platform: Platform{Name: "gke", Version: "1.22"},
}, },
want: "gke-1.2.0", want: "gke-1.2.0",
}, },
{ {
name: "aliyun", name: "aliyun",
args: args{ args: args{
platform: "aliyun", platform: Platform{Name: "aliyun"},
}, },
want: "ack-1.0", want: "ack-1.0",
}, },
{ {
name: "unknown", name: "unknown",
args: args{ args: args{
platform: "rh", platform: Platform{Name: "rh"},
}, },
want: "", want: "",
}, },
{ {
name: "empty", name: "empty",
args: args{ args: args{
platform: "", platform: Platform{},
}, },
want: "", want: "",
}, },
{ {
name: "openshift3", name: "openshift3",
args: args{ args: args{
platform: "ocp-3.10", platform: Platform{Name: "ocp", Version: "3.10"},
}, },
want: "rh-0.7", want: "rh-0.7",
}, },
{ {
name: "openshift4", name: "openshift4",
args: args{ args: args{
platform: "ocp-4.1", platform: Platform{Name: "ocp", Version: "4.1"},
}, },
want: "rh-1.0", want: "rh-1.0",
}, },

Loading…
Cancel
Save