Skip to content

Commit

Permalink
Merge pull request #141 from aquasecurity/version-default
Browse files Browse the repository at this point in the history
Default version
  • Loading branch information
lizrice authored Jul 2, 2018
2 parents 8c3bb62 + 9d01418 commit 668a9e1
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 28 deletions.
46 changes: 19 additions & 27 deletions cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package cmd
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"

"github.com/aquasecurity/kube-bench/check"
Expand All @@ -28,56 +29,50 @@ var (
errmsgs string
)

func runChecks(t check.NodeType) {
func runChecks(nodetype check.NodeType) {
var summary check.Summary
var nodetype string
var file string
var err error
var typeConf *viper.Viper

switch t {
switch nodetype {
case check.MASTER:
file = masterFile
nodetype = "master"
case check.NODE:
file = nodeFile
nodetype = "node"
case check.FEDERATED:
file = federatedFile
nodetype = "federated"
}

var ver string
if kubeVersion != "" {
ver = kubeVersion
} else {
ver = getKubeVersion()
}

switch ver {
case "1.9", "1.10":
continueWithError(nil, fmt.Sprintf("No CIS spec for %s - using tests from CIS 1.2.0 spec for Kubernetes 1.8\n", ver))
ver = "1.8"
path, err := getConfigFilePath(kubeVersion, getKubeVersion(), file)
if err != nil {
exitWithError(fmt.Errorf("can't find %s controls file in %s: %v", nodetype, cfgDir, err))
}

path := filepath.Join(cfgDir, ver)
def := filepath.Join(path, file)

in, err := ioutil.ReadFile(def)
if err != nil {
exitWithError(fmt.Errorf("error opening %s controls file: %v", t, err))
exitWithError(fmt.Errorf("error opening %s controls file: %v", nodetype, err))
}

glog.V(1).Info(fmt.Sprintf("Using benchmark file: %s\n", def))

// Merge kubernetes version specific config if any.
viper.SetConfigFile(path + "/config.yaml")
err = viper.MergeInConfig()
if err != nil {
continueWithError(err, fmt.Sprintf("Reading %s specific configuration file", ver))
if os.IsNotExist(err) {
glog.V(2).Info(fmt.Sprintf("No version-specific config.yaml file in %s", path))
} else {
exitWithError(fmt.Errorf("couldn't read config file %s: %v", path+"/config.yaml", err))
}
} else {
glog.V(1).Info(fmt.Sprintf("Using config file: %s\n", viper.ConfigFileUsed()))
}
typeConf = viper.Sub(nodetype)

// Get the set of exectuables and config files we care about on this type of node. This also
// checks that the executables we need for the node type are running.
typeConf = viper.Sub(string(nodetype))
binmap := getBinaries(typeConf)
confmap := getConfigFiles(typeConf)

Expand All @@ -86,12 +81,9 @@ func runChecks(t check.NodeType) {
s = makeSubstitutions(s, "bin", binmap)
s = makeSubstitutions(s, "conf", confmap)

glog.V(1).Info(fmt.Sprintf("Using config file: %s\n", viper.ConfigFileUsed()))
glog.V(1).Info(fmt.Sprintf("Using benchmark file: %s\n", def))

controls, err := check.NewControls(t, []byte(s))
controls, err := check.NewControls(nodetype, []byte(s))
if err != nil {
exitWithError(fmt.Errorf("error setting up %s controls: %v", t, err))
exitWithError(fmt.Errorf("error setting up %s controls: %v", nodetype, err))
}

if groupList != "" && checkList == "" {
Expand Down
55 changes: 54 additions & 1 deletion cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"

"github.com/aquasecurity/kube-bench/check"
Expand Down Expand Up @@ -116,6 +118,57 @@ func getBinaries(v *viper.Viper) map[string]string {
return binmap
}

// getConfigFilePath locates the config files we should be using based on either the specified
// version, or the running version of kubernetes if not specified
func getConfigFilePath(specifiedVersion string, runningVersion string, filename string) (path string, err error) {
var fileVersion string

if specifiedVersion != "" {
fileVersion = specifiedVersion
} else {
fileVersion = runningVersion
}

for {
path = filepath.Join(cfgDir, fileVersion)
file := filepath.Join(path, string(filename))
glog.V(2).Info(fmt.Sprintf("Looking for config file: %s\n", file))

if _, err = os.Stat(file); !os.IsNotExist(err) {
if specifiedVersion == "" && fileVersion != runningVersion {
glog.V(1).Info(fmt.Sprintf("No test file found for %s - using tests for Kubernetes %s\n", runningVersion, fileVersion))
}
return path, nil
}

// If we were given an explicit version to look for, don't look for any others
if specifiedVersion != "" {
return "", err
}

fileVersion = decrementVersion(fileVersion)
if fileVersion == "" {
return "", fmt.Errorf("no test files found <= runningVersion")
}
}
}

// decrementVersion decrements the version number
// We want to decrement individually even through versions where we don't supply test files
// just in case someone wants to specify their own test files for that version
func decrementVersion(version string) string {
split := strings.Split(version, ".")
minor, err := strconv.Atoi(split[1])
if err != nil {
return ""
}
if minor <= 1 {
return ""
}
split[1] = strconv.Itoa(minor - 1)
return strings.Join(split, ".")
}

// getConfigFiles finds which of the set of candidate config files exist
// accepts a string 't' which indicates the type of config file, conf,
// podspec or untifile.
Expand Down Expand Up @@ -275,7 +328,7 @@ func makeSubstitutions(s string, ext string, m map[string]string) string {
glog.V(2).Info(fmt.Sprintf("No subsitution for '%s'\n", subst))
continue
}
glog.V(1).Info(fmt.Sprintf("Substituting %s with '%s'\n", subst, v))
glog.V(2).Info(fmt.Sprintf("Substituting %s with '%s'\n", subst, v))
s = multiWordReplace(s, subst, v)
}

Expand Down
44 changes: 44 additions & 0 deletions cmd/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
package cmd

import (
"io/ioutil"
"os"
"path/filepath"
"reflect"
"strconv"
"testing"
Expand Down Expand Up @@ -306,3 +308,45 @@ func TestMakeSubsitutions(t *testing.T) {
})
}
}

func TestGetConfigFilePath(t *testing.T) {
var err error
cfgDir, err = ioutil.TempDir("", "kube-bench-test")
if err != nil {
t.Fatalf("Failed to create temp directory")
}
defer os.RemoveAll(cfgDir)
d := filepath.Join(cfgDir, "1.8")
err = os.Mkdir(d, 0666)
if err != nil {
t.Fatalf("Failed to create temp file")
}
ioutil.WriteFile(filepath.Join(d, "master.yaml"), []byte("hello world"), 0666)

cases := []struct {
specifiedVersion string
runningVersion string
succeed bool
exp string
}{
{runningVersion: "1.8", succeed: true, exp: d},
{runningVersion: "1.9", succeed: true, exp: d},
{runningVersion: "1.10", succeed: true, exp: d},
{runningVersion: "1.1", succeed: false},
{specifiedVersion: "1.8", succeed: true, exp: d},
{specifiedVersion: "1.9", succeed: false},
{specifiedVersion: "1.10", succeed: false},
}

for _, c := range cases {
t.Run(c.specifiedVersion+"-"+c.runningVersion, func(t *testing.T) {
path, err := getConfigFilePath(c.specifiedVersion, c.runningVersion, "/master.yaml")
if err != nil && c.succeed {
t.Fatalf("Error %v", err)
}
if path != c.exp {
t.Fatalf("Got %s expected %s", path, c.exp)
}
})
}
}

0 comments on commit 668a9e1

Please sign in to comment.