mirror of
https://github.com/kubescape/kubescape.git
synced 2026-03-03 02:00:27 +00:00
168 lines
5.2 KiB
Go
168 lines
5.2 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/armosec/kubescape/cautils"
|
|
"github.com/armosec/kubescape/cautils/getter"
|
|
"github.com/armosec/kubescape/cautils/logger"
|
|
"github.com/armosec/kubescape/cautils/logger/helpers"
|
|
"github.com/armosec/kubescape/cmd/completion"
|
|
"github.com/armosec/kubescape/cmd/config"
|
|
"github.com/armosec/kubescape/cmd/delete"
|
|
"github.com/armosec/kubescape/cmd/download"
|
|
"github.com/armosec/kubescape/cmd/list"
|
|
"github.com/armosec/kubescape/cmd/scan"
|
|
"github.com/armosec/kubescape/cmd/submit"
|
|
"github.com/armosec/kubescape/cmd/version"
|
|
"github.com/armosec/kubescape/core/core"
|
|
|
|
"github.com/mattn/go-isatty"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var armoBEURLs = ""
|
|
var armoBEURLsDep = ""
|
|
|
|
const envFlagUsage = "Send report results to specific URL. Format:<ReportReceiver>,<Backend>,<Frontend>.\n\t\tExample:report.armo.cloud,api.armo.cloud,portal.armo.cloud"
|
|
|
|
var ksExamples = `
|
|
# Scan command
|
|
kubescape scan --submit
|
|
|
|
# List supported frameworks
|
|
kubescape list frameworks
|
|
|
|
# Download artifacts (air-gapped environment support)
|
|
kubescape download artifacts
|
|
|
|
# View cached configurations
|
|
kubescape config view
|
|
`
|
|
|
|
func getRootCmd() *cobra.Command {
|
|
var rootInfo cautils.RootInfo
|
|
|
|
rootCmd := &cobra.Command{
|
|
Use: "kubescape",
|
|
Version: cautils.BuildNumber,
|
|
Short: "Kubescape is a tool for testing Kubernetes security posture",
|
|
Long: `Based on NSA \ MITRE ATT&CK® and other frameworks specifications`,
|
|
Example: ksExamples,
|
|
}
|
|
|
|
rootCmd.PersistentFlags().StringVar(&armoBEURLsDep, "environment", "", envFlagUsage)
|
|
rootCmd.PersistentFlags().StringVar(&armoBEURLs, "env", "", envFlagUsage)
|
|
rootCmd.PersistentFlags().MarkDeprecated("environment", "use 'env' instead")
|
|
rootCmd.PersistentFlags().MarkHidden("environment")
|
|
rootCmd.PersistentFlags().MarkHidden("env")
|
|
|
|
rootCmd.PersistentFlags().StringVar(&rootInfo.LoggerName, "logger-name", "", fmt.Sprintf("Logger name. Supported: %s [$KS_LOGGER_NAME]", strings.Join(logger.ListLoggersNames(), "/")))
|
|
rootCmd.PersistentFlags().MarkHidden("logger-name")
|
|
|
|
rootCmd.PersistentFlags().StringVarP(&rootInfo.Logger, "logger", "l", helpers.InfoLevel.String(), fmt.Sprintf("Logger level. Supported: %s [$KS_LOGGER]", strings.Join(helpers.SupportedLevels(), "/")))
|
|
rootCmd.PersistentFlags().StringVar(&rootInfo.CacheDir, "cache-dir", getter.DefaultLocalStore, "Cache directory [$KS_CACHE_DIR]")
|
|
rootCmd.PersistentFlags().BoolVarP(&rootInfo.DisableColor, "disable-color", "", false, "Disable Color output for logging")
|
|
|
|
// Initialize
|
|
initLogger(&rootInfo)
|
|
initLoggerLevel(&rootInfo)
|
|
initEnvironment(&rootInfo)
|
|
initCacheDir(&rootInfo)
|
|
|
|
ks := core.NewKubescape()
|
|
|
|
// Supported commands
|
|
rootCmd.AddCommand(scan.GetScanCommand(ks))
|
|
rootCmd.AddCommand(download.GeDownloadCmd(ks))
|
|
rootCmd.AddCommand(delete.GetDeleteCmd(ks))
|
|
rootCmd.AddCommand(list.GetListCmd(ks))
|
|
rootCmd.AddCommand(submit.GetSubmitCmd(ks))
|
|
rootCmd.AddCommand(completion.GetCompletionCmd())
|
|
rootCmd.AddCommand(version.GetVersionCmd())
|
|
rootCmd.AddCommand(config.GetConfigCmd(ks))
|
|
|
|
return rootCmd
|
|
}
|
|
|
|
func Execute() {
|
|
rootCmd := getRootCmd()
|
|
rootCmd.Execute()
|
|
}
|
|
|
|
func initLogger(rootInfo *cautils.RootInfo) {
|
|
logger.DisableColor(rootInfo.DisableColor)
|
|
|
|
if rootInfo.LoggerName == "" {
|
|
if l := os.Getenv("KS_LOGGER_NAME"); l != "" {
|
|
rootInfo.LoggerName = l
|
|
} else {
|
|
if isatty.IsTerminal(os.Stdout.Fd()) {
|
|
rootInfo.LoggerName = "pretty"
|
|
} else {
|
|
rootInfo.LoggerName = "zap"
|
|
}
|
|
}
|
|
}
|
|
|
|
logger.InitLogger(rootInfo.LoggerName)
|
|
|
|
}
|
|
func initLoggerLevel(rootInfo *cautils.RootInfo) {
|
|
if rootInfo.Logger != helpers.InfoLevel.String() {
|
|
} else if l := os.Getenv("KS_LOGGER"); l != "" {
|
|
rootInfo.Logger = l
|
|
}
|
|
|
|
if err := logger.L().SetLevel(rootInfo.Logger); err != nil {
|
|
logger.L().Fatal(fmt.Sprintf("supported levels: %s", strings.Join(helpers.SupportedLevels(), "/")), helpers.Error(err))
|
|
}
|
|
}
|
|
|
|
func initCacheDir(rootInfo *cautils.RootInfo) {
|
|
if rootInfo.CacheDir == getter.DefaultLocalStore {
|
|
getter.DefaultLocalStore = rootInfo.CacheDir
|
|
} else if cacheDir := os.Getenv("KS_CACHE_DIR"); cacheDir != "" {
|
|
getter.DefaultLocalStore = cacheDir
|
|
} else {
|
|
return // using default cache dir location
|
|
}
|
|
|
|
logger.L().Debug("cache dir updated", helpers.String("path", getter.DefaultLocalStore))
|
|
}
|
|
func initEnvironment(rootInfo *cautils.RootInfo) {
|
|
if armoBEURLsDep != "" {
|
|
armoBEURLs = armoBEURLsDep
|
|
}
|
|
urlSlices := strings.Split(armoBEURLs, ",")
|
|
if len(urlSlices) != 1 && len(urlSlices) < 3 {
|
|
logger.L().Fatal("expected at least 3 URLs (report, api, frontend, auth)")
|
|
}
|
|
switch len(urlSlices) {
|
|
case 1:
|
|
switch urlSlices[0] {
|
|
case "dev", "development":
|
|
getter.SetARMOAPIConnector(getter.NewARMOAPIDev())
|
|
case "stage", "staging":
|
|
getter.SetARMOAPIConnector(getter.NewARMOAPIStaging())
|
|
case "":
|
|
getter.SetARMOAPIConnector(getter.NewARMOAPIProd())
|
|
default:
|
|
logger.L().Fatal("--environment flag usage: " + envFlagUsage)
|
|
}
|
|
case 2:
|
|
logger.L().Fatal("--environment flag usage: " + envFlagUsage)
|
|
case 3, 4:
|
|
var armoAUTHURL string
|
|
armoERURL := urlSlices[0] // mandatory
|
|
armoBEURL := urlSlices[1] // mandatory
|
|
armoFEURL := urlSlices[2] // mandatory
|
|
if len(urlSlices) <= 4 {
|
|
armoAUTHURL = urlSlices[3]
|
|
}
|
|
getter.SetARMOAPIConnector(getter.NewARMOAPICustomized(armoERURL, armoBEURL, armoFEURL, armoAUTHURL))
|
|
}
|
|
}
|