diff --git a/cautils/listpolicies.go b/cautils/listpolicies.go new file mode 100644 index 00000000..044c2c00 --- /dev/null +++ b/cautils/listpolicies.go @@ -0,0 +1,7 @@ +package cautils + +type ListPolicies struct { + Target string + ListIDs bool + Account string +} diff --git a/clihandler/clidownload.go b/clihandler/clidownload.go index c12453ec..cca9ada2 100644 --- a/clihandler/clidownload.go +++ b/clihandler/clidownload.go @@ -2,7 +2,6 @@ package clihandler import ( "fmt" - "os" "github.com/armosec/kubescape/cautils" "github.com/armosec/kubescape/cautils/getter" @@ -26,10 +25,9 @@ func DownloadSupportCommands() []string { func CliDownload(downloadInfo *cautils.DownloadInfo) error { if f, ok := downloadFunc[downloadInfo.Target]; ok { if err := f(downloadInfo); err != nil { - fmt.Println(err) - os.Exit(1) + return err } - fmt.Println(fmt.Sprintf("'%s' downloaded successfully and saved at: '%s'", downloadInfo.Target, downloadInfo.Path)) + fmt.Printf("'%s' downloaded successfully and saved at: '%s'\n", downloadInfo.Target, downloadInfo.Path) return nil } return fmt.Errorf("unknown command to download") @@ -95,7 +93,7 @@ func downloadFramework(downloadInfo *cautils.DownloadInfo) error { func downloadControl(downloadInfo *cautils.DownloadInfo) error { tenant := getTenantConfig(downloadInfo.Account, getKubernetesApi()) // change k8sinterface - g := getPolicyGetter(nil, tenant.GetCustomerGUID(), true, nil) + g := getPolicyGetter(nil, tenant.GetCustomerGUID(), false, nil) if downloadInfo.Name == "" { // TODO - support diff --git a/clihandler/clilist.go b/clihandler/clilist.go new file mode 100644 index 00000000..7d31f76f --- /dev/null +++ b/clihandler/clilist.go @@ -0,0 +1,58 @@ +package clihandler + +import ( + "fmt" + "sort" + "strings" + + "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/cautils/getter" +) + +var listFunc = map[string]func(*cautils.ListPolicies) ([]string, error){ + "controls": listControls, + "frameworks": listFrameworks, +} + +func ListSupportCommands() []string { + commands := []string{} + for k := range listFunc { + commands = append(commands, k) + } + return commands +} +func CliList(listPolicies *cautils.ListPolicies) error { + if f, ok := listFunc[listPolicies.Target]; ok { + policies, err := f(listPolicies) + if err != nil { + return err + } + sort.Strings(policies) + + sep := "\n * " + usageCmd := strings.TrimSuffix(listPolicies.Target, "s") + fmt.Printf("Supported %s:%s%s\n", listPolicies.Target, sep, strings.Join(policies, sep)) + fmt.Printf("\nUseage:\n") + fmt.Printf("$ kubescape scan %s \"name\"\n", usageCmd) + fmt.Printf("$ kubescape scan %s \"name-0\",\"name-1\"\n\n", usageCmd) + return nil + } + return fmt.Errorf("unknown command to download") +} + +func listFrameworks(listPolicies *cautils.ListPolicies) ([]string, error) { + tenant := getTenantConfig(listPolicies.Account, getKubernetesApi()) // change k8sinterface + g := getPolicyGetter(nil, tenant.GetCustomerGUID(), true, nil) + + return g.ListFrameworks() +} + +func listControls(listPolicies *cautils.ListPolicies) ([]string, error) { + tenant := getTenantConfig(listPolicies.Account, getKubernetesApi()) // change k8sinterface + g := getPolicyGetter(nil, tenant.GetCustomerGUID(), false, nil) + l := getter.ListName + if listPolicies.ListIDs { + l = getter.ListID + } + return g.ListControls(l) +} diff --git a/clihandler/cmd/list.go b/clihandler/cmd/list.go new file mode 100644 index 00000000..0d516854 --- /dev/null +++ b/clihandler/cmd/list.go @@ -0,0 +1,66 @@ +package cmd + +import ( + "fmt" + "os" + "strings" + + "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/clihandler" + "github.com/spf13/cobra" +) + +var ( + listExample = ` + # List default supported frameworks names + kubescape list frameworks + + # List all supported frameworks names + kubescape list frameworks --account + + # List all supported controls names + kubescape list controls + + # List all supported controls id's + kubescape list controls --id + + Control documentation: + https://hub.armo.cloud/docs/controls +` +) +var listPolicies = cautils.ListPolicies{} + +var listCmd = &cobra.Command{ + Use: "list [flags]", + Short: "List frameworks/controls will list the supported frameworks and controls", + Long: ``, + Example: listExample, + Args: func(cmd *cobra.Command, args []string) error { + supported := strings.Join(clihandler.ListSupportCommands(), ",") + + if len(args) < 1 { + return fmt.Errorf("policy type requeued, supported: %s", supported) + } + if cautils.StringInSlice(clihandler.ListSupportCommands(), args[0]) == cautils.ValueNotFound { + return fmt.Errorf("invalid parameter '%s'. Supported parameters: %s", args[0], supported) + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + listPolicies.Target = args[0] + + if err := clihandler.CliList(&listPolicies); err != nil { + fmt.Fprintf(os.Stderr, "error: %v\n", err) + os.Exit(1) + } + return nil + }, +} + +func init() { + // cobra.OnInitialize(initConfig) + + rootCmd.AddCommand(listCmd) + listCmd.PersistentFlags().StringVarP(&listPolicies.Account, "account", "", "", "Armo portal account ID. Default will load account ID from configMap or config file") + listCmd.PersistentFlags().BoolVarP(&listPolicies.ListIDs, "id", "", false, "List control ID's instead of controls names") +}