1
0
mirror of https://github.com/aquasecurity/kube-bench.git synced 2024-12-24 15:38:06 +00:00
kube-bench/cmd/root.go
Abubakr-Sadik Nii Nai Davis 92df9cb36c Read kubernetes version from environment (#390)
* Read kubernetes version from environment

Set kubernetes version to the value of the environment variable `KUBE_BENCH_VERSION` if it is defined and the flag `--version` is not specified on the kube-bench command line.

The command line flag `--version` takes precedence of the environment variable `KUBE_BENCH_VERSION` if both are defined.

* Add info about KUBE_BENCH_VERSION to README
2019-08-27 09:04:11 +01:00

157 lines
5.2 KiB
Go

// 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 (
goflag "flag"
"fmt"
"os"
"github.com/aquasecurity/kube-bench/check"
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
type FilterOpts struct {
CheckList string
GroupList string
Scored bool
Unscored bool
}
var (
envVarsPrefix = "KUBE_BENCH"
defaultKubeVersion = "1.6"
kubeVersion string
cfgFile string
cfgDir string
jsonFmt bool
pgSQL bool
masterFile = "master.yaml"
nodeFile = "node.yaml"
federatedFile string
noResults bool
noSummary bool
noRemediations bool
filterOpts FilterOpts
includeTestOutput bool
outputFile string
configFileError error
)
// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: os.Args[0],
Short: "Run CIS Benchmarks checks against a Kubernetes deployment",
Long: `This tool runs the CIS Kubernetes Benchmark (https://www.cisecurity.org/benchmark/kubernetes/)`,
Run: func(cmd *cobra.Command, args []string) {
if isMaster() {
glog.V(1).Info("== Running master checks ==\n")
runChecks(check.MASTER)
}
glog.V(1).Info("== Running node checks ==\n")
runChecks(check.NODE)
},
}
// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
goflag.Set("logtostderr", "true")
goflag.CommandLine.Parse([]string{})
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
// flush before exit non-zero
glog.Flush()
os.Exit(-1)
}
// flush before exit
glog.Flush()
}
func init() {
cobra.OnInitialize(initConfig)
// Output control
RootCmd.PersistentFlags().BoolVar(&noResults, "noresults", false, "Disable printing of results section")
RootCmd.PersistentFlags().BoolVar(&noSummary, "nosummary", false, "Disable printing of summary section")
RootCmd.PersistentFlags().BoolVar(&noRemediations, "noremediations", false, "Disable printing of remediations section")
RootCmd.PersistentFlags().BoolVar(&jsonFmt, "json", false, "Prints the results as JSON")
RootCmd.PersistentFlags().BoolVar(&pgSQL, "pgsql", false, "Save the results to PostgreSQL")
RootCmd.PersistentFlags().BoolVar(&filterOpts.Scored, "scored", true, "Run the scored CIS checks")
RootCmd.PersistentFlags().BoolVar(&filterOpts.Unscored, "unscored", true, "Run the unscored CIS checks")
RootCmd.PersistentFlags().BoolVar(&includeTestOutput, "include-test-output", false, "Prints the actual result when test fails")
RootCmd.PersistentFlags().StringVar(&outputFile, "outputfile", "", "Writes the JSON results to output file")
RootCmd.PersistentFlags().StringVarP(
&filterOpts.CheckList,
"check",
"c",
"",
`A comma-delimited list of checks to run as specified in CIS document. Example --check="1.1.1,1.1.2"`,
)
RootCmd.PersistentFlags().StringVarP(
&filterOpts.GroupList,
"group",
"g",
"",
`Run all the checks under this comma-delimited list of groups. Example --group="1.1"`,
)
RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./cfg/config.yaml)")
RootCmd.PersistentFlags().StringVarP(&cfgDir, "config-dir", "D", "./cfg/", "config directory")
RootCmd.PersistentFlags().StringVar(&kubeVersion, "version", "", "Manually specify Kubernetes version, automatically detected if unset")
goflag.CommandLine.VisitAll(func(goflag *goflag.Flag) {
RootCmd.PersistentFlags().AddGoFlag(goflag)
})
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
if cfgFile != "" { // enable ability to specify config file via flag
viper.SetConfigFile(cfgFile)
} else {
viper.SetConfigName("config") // name of config file (without extension)
viper.AddConfigPath(cfgDir) // adding ./cfg as first search path
}
// Read flag values from environment variables.
// Precedence: Command line flags take precedence over environment variables.
viper.SetEnvPrefix(envVarsPrefix)
viper.AutomaticEnv()
if kubeVersion == "" {
if env := viper.Get("version"); env != nil {
kubeVersion = env.(string)
}
}
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found; ignore error for now to prevent commands
// which don't need the config file exiting.
configFileError = err
} else {
// Config file was found but another error was produced
colorPrint(check.FAIL, fmt.Sprintf("Failed to read config file: %v\n", err))
os.Exit(1)
}
}
}