diff --git a/cautils/customerloader.go b/cautils/customerloader.go index f0bb0334..56770636 100644 --- a/cautils/customerloader.go +++ b/cautils/customerloader.go @@ -23,10 +23,12 @@ func ConfigFileFullPath() string { return getter.GetDefaultPath(configFileName + // ====================================================================================== type ConfigObj struct { - CustomerGUID string `json:"customerGUID"` - Token string `json:"invitationParam"` - CustomerAdminEMail string `json:"adminMail"` - ClusterName string `json:"clusterName"` + AccountID string `json:"customerGUID,omitempty"` + Token string `json:"invitationParam,omitempty"` + CustomerAdminEMail string `json:"adminMail,omitempty"` + ClusterName string `json:"clusterName,omitempty"` + ClientID string `json:"clientID,omitempty"` + AccessKey string `json:"accessKey,omitempty"` } func (co *ConfigObj) Json() []byte { @@ -38,10 +40,20 @@ func (co *ConfigObj) Json() []byte { // Config - convert ConfigObj to config file func (co *ConfigObj) Config() []byte { + + // remove cluster name before saving to file clusterName := co.ClusterName - co.ClusterName = "" // remove cluster name before saving to file - b, err := json.Marshal(co) + customerAdminEMail := co.CustomerAdminEMail + token := co.Token + co.ClusterName = "" + co.Token = "" + co.CustomerAdminEMail = "" + + b, err := json.MarshalIndent(co, "", " ") + co.ClusterName = clusterName + co.CustomerAdminEMail = customerAdminEMail + co.Token = token if err == nil { return b @@ -56,10 +68,12 @@ func (co *ConfigObj) Config() []byte { type ITenantConfig interface { // set SetTenant() error + UpdateCachedConfig() error + DeleteCachedConfig() error // getters GetClusterName() string - GetCustomerGUID() string + GetAccountID() string GetConfigObj() *ConfigObj // GetBackendAPI() getter.IBackend // GenerateURL() @@ -93,12 +107,18 @@ func NewLocalConfig(backendAPI getter.IBackend, customerGUID, clusterName string lc.configObj = configObj } if customerGUID != "" { - lc.configObj.CustomerGUID = customerGUID // override config customerGUID + lc.configObj.AccountID = customerGUID // override config customerGUID } if clusterName != "" { lc.configObj.ClusterName = AdoptClusterName(clusterName) // override config clusterName } - if lc.configObj.CustomerGUID != "" { + getAccountFromEnv(lc.configObj) + + lc.backendAPI.SetAccountID(lc.configObj.AccountID) + lc.backendAPI.SetClientID(lc.configObj.ClientID) + lc.backendAPI.SetAccessKey(lc.configObj.AccessKey) + + if lc.configObj.AccountID != "" { if err := lc.SetTenant(); err != nil { fmt.Println(err) } @@ -107,32 +127,38 @@ func NewLocalConfig(backendAPI getter.IBackend, customerGUID, clusterName string return lc } -func (lc *LocalConfig) GetConfigObj() *ConfigObj { return lc.configObj } -func (lc *LocalConfig) GetCustomerGUID() string { return lc.configObj.CustomerGUID } -func (lc *LocalConfig) SetCustomerGUID(customerGUID string) { lc.configObj.CustomerGUID = customerGUID } -func (lc *LocalConfig) GetClusterName() string { return lc.configObj.ClusterName } -func (lc *LocalConfig) IsConfigFound() bool { return existsConfigFile() } +func (lc *LocalConfig) GetConfigObj() *ConfigObj { return lc.configObj } +func (lc *LocalConfig) GetAccountID() string { return lc.configObj.AccountID } +func (lc *LocalConfig) GetClusterName() string { return lc.configObj.ClusterName } +func (lc *LocalConfig) IsConfigFound() bool { return existsConfigFile() } func (lc *LocalConfig) SetTenant() error { + // ARMO tenant GUID if err := getTenantConfigFromBE(lc.backendAPI, lc.configObj); err != nil { return err } - updateConfigFile(lc.configObj) + lc.UpdateCachedConfig() return nil } +func (lc *LocalConfig) UpdateCachedConfig() error { + return updateConfigFile(lc.configObj) +} + +func (lc *LocalConfig) DeleteCachedConfig() error { + return DeleteConfigFile() +} func getTenantConfigFromBE(backendAPI getter.IBackend, configObj *ConfigObj) error { // get from armoBE - backendAPI.SetCustomerGUID(configObj.CustomerGUID) - tenantResponse, err := backendAPI.GetCustomerGUID() + tenantResponse, err := backendAPI.GetTenant() if err == nil && tenantResponse != nil { if tenantResponse.AdminMail != "" { // registered tenant configObj.CustomerAdminEMail = tenantResponse.AdminMail } else { // new tenant configObj.Token = tenantResponse.Token - configObj.CustomerGUID = tenantResponse.TenantID + configObj.AccountID = tenantResponse.TenantID } } else { if err != nil && !strings.Contains(err.Error(), "already exists") { @@ -154,8 +180,11 @@ Supported environments variables: KS_DEFAULT_CONFIGMAP_NAME // name of configmap, if not set default is 'kubescape' KS_DEFAULT_CONFIGMAP_NAMESPACE // configmap namespace, if not set default is 'default' +KS_ACCOUNT_ID +KS_CLIENT_ID +KS_ACCESS_KEY + TODO - supprot: -KS_ACCOUNT // Account ID KS_CACHE // path to cached files */ type ClusterConfig struct { @@ -187,32 +216,36 @@ func NewClusterConfig(k8s *k8sinterface.KubernetesApi, backendAPI getter.IBacken c.configObj = configObj } if customerGUID != "" { - c.configObj.CustomerGUID = customerGUID // override config customerGUID + c.configObj.AccountID = customerGUID // override config customerGUID } if clusterName != "" { c.configObj.ClusterName = AdoptClusterName(clusterName) // override config clusterName } - if c.configObj.CustomerGUID != "" { - if err := c.SetTenant(); err != nil { - fmt.Println(err) - } - } + getAccountFromEnv(c.configObj) + if c.configObj.ClusterName == "" { c.configObj.ClusterName = AdoptClusterName(k8sinterface.GetClusterName()) } else { // override the cluster name if it has unwanted characters c.configObj.ClusterName = AdoptClusterName(c.configObj.ClusterName) } + c.backendAPI.SetAccountID(c.configObj.AccountID) + c.backendAPI.SetClientID(c.configObj.ClientID) + c.backendAPI.SetAccessKey(c.configObj.AccessKey) + + if c.configObj.AccountID != "" { + if err := c.SetTenant(); err != nil { + fmt.Println(err) // TODO: print to log + } + } + return c } -func (c *ClusterConfig) GetConfigObj() *ConfigObj { return c.configObj } -func (c *ClusterConfig) GetDefaultNS() string { return c.configMapNamespace } -func (c *ClusterConfig) GetCustomerGUID() string { return c.configObj.CustomerGUID } -func (c *ClusterConfig) SetCustomerGUID(customerGUID string) { c.configObj.CustomerGUID = customerGUID } -func (c *ClusterConfig) IsConfigFound() bool { - return existsConfigFile() || c.existsConfigMap() -} +func (c *ClusterConfig) GetConfigObj() *ConfigObj { return c.configObj } +func (c *ClusterConfig) GetDefaultNS() string { return c.configMapNamespace } +func (c *ClusterConfig) GetAccountID() string { return c.configObj.AccountID } +func (c *ClusterConfig) IsConfigFound() bool { return existsConfigFile() || c.existsConfigMap() } func (c *ClusterConfig) SetTenant() error { @@ -220,17 +253,34 @@ func (c *ClusterConfig) SetTenant() error { if err := getTenantConfigFromBE(c.backendAPI, c.configObj); err != nil { return err } - // update/create config - if c.existsConfigMap() { - c.updateConfigMap() - } else { - c.createConfigMap() - } - updateConfigFile(c.configObj) + c.UpdateCachedConfig() return nil } +func (c *ClusterConfig) UpdateCachedConfig() error { + // update/create config + if c.existsConfigMap() { + if err := c.updateConfigMap(); err != nil { + return err + } + } else { + if err := c.createConfigMap(); err != nil { + return err + } + } + return updateConfigFile(c.configObj) +} + +func (c *ClusterConfig) DeleteCachedConfig() error { + if err := c.deleteConfigMap(); err != nil { + return err + } + if err := DeleteConfigFile(); err != nil { + return err + } + return nil +} func (c *ClusterConfig) GetClusterName() string { return c.configObj.ClusterName } @@ -421,8 +471,7 @@ func (clusterConfig *ClusterConfig) IsSubmitted() bool { func (clusterConfig *ClusterConfig) IsRegistered() bool { // get from armoBE - clusterConfig.backendAPI.SetCustomerGUID(clusterConfig.GetCustomerGUID()) - tenantResponse, err := clusterConfig.backendAPI.GetCustomerGUID() + tenantResponse, err := clusterConfig.backendAPI.GetTenant() if err == nil && tenantResponse != nil { if tenantResponse.AdminMail != "" { // this customer already belongs to some user return true @@ -431,16 +480,7 @@ func (clusterConfig *ClusterConfig) IsRegistered() bool { return false } -func (clusterConfig *ClusterConfig) DeleteConfig() error { - if err := clusterConfig.DeleteConfigMap(); err != nil { - return err - } - if err := DeleteConfigFile(); err != nil { - return err - } - return nil -} -func (clusterConfig *ClusterConfig) DeleteConfigMap() error { +func (clusterConfig *ClusterConfig) deleteConfigMap() error { return clusterConfig.k8s.KubernetesClient.CoreV1().ConfigMaps(clusterConfig.configMapNamespace).Delete(context.Background(), clusterConfig.configMapName, metav1.DeleteOptions{}) } @@ -465,3 +505,16 @@ func getConfigMapNamespace() string { } return "default" } + +func getAccountFromEnv(configObj *ConfigObj) { + // load from env + if accountID := os.Getenv("KS_ACCOUNT_ID"); accountID != "" { + configObj.AccountID = accountID + } + if clientID := os.Getenv("KS_CLIENT_ID"); clientID != "" { + configObj.ClientID = clientID + } + if accessKey := os.Getenv("KS_ACCESS_KEY"); accessKey != "" { + configObj.AccessKey = accessKey + } +} diff --git a/cautils/getter/armoapi.go b/cautils/getter/armoapi.go index f194f4f1..f70480da 100644 --- a/cautils/getter/armoapi.go +++ b/cautils/getter/armoapi.go @@ -30,24 +30,26 @@ var ( // Armo API for downloading policies type ArmoAPI struct { - httpClient *http.Client - apiURL string - erURL string - feURL string - customerGUID string + httpClient *http.Client + apiURL string + erURL string + feURL string + accountID string + clientID string + accessKey string } -var globalArmoAPIConnecctor *ArmoAPI +var globalArmoAPIConnector *ArmoAPI func SetARMOAPIConnector(armoAPI *ArmoAPI) { - globalArmoAPIConnecctor = armoAPI + globalArmoAPIConnector = armoAPI } func GetArmoAPIConnector() *ArmoAPI { - if globalArmoAPIConnecctor == nil { + if globalArmoAPIConnector == nil { glog.Error("returning nil API connector") } - return globalArmoAPIConnecctor + return globalArmoAPIConnector } func NewARMOAPIDev() *ArmoAPI { @@ -85,17 +87,15 @@ func newArmoAPI() *ArmoAPI { httpClient: &http.Client{Timeout: time.Duration(61) * time.Second}, } } -func (armoAPI *ArmoAPI) SetCustomerGUID(customerGUID string) { - armoAPI.customerGUID = customerGUID -} -func (armoAPI *ArmoAPI) GetFrontendURL() string { - return armoAPI.feURL -} - -func (armoAPI *ArmoAPI) GetReportReceiverURL() string { - return armoAPI.erURL -} +func (armoAPI *ArmoAPI) GetAccountID() string { return armoAPI.accountID } +func (armoAPI *ArmoAPI) GetClientID() string { return armoAPI.clientID } +func (armoAPI *ArmoAPI) GetAccessKey() string { return armoAPI.accessKey } +func (armoAPI *ArmoAPI) GetFrontendURL() string { return armoAPI.feURL } +func (armoAPI *ArmoAPI) GetReportReceiverURL() string { return armoAPI.erURL } +func (armoAPI *ArmoAPI) SetAccountID(accountID string) { armoAPI.accountID = accountID } +func (armoAPI *ArmoAPI) SetClientID(clientID string) { armoAPI.clientID = clientID } +func (armoAPI *ArmoAPI) SetAccessKey(accessKey string) { armoAPI.accessKey = accessKey } func (armoAPI *ArmoAPI) GetFramework(name string) (*reporthandling.Framework, error) { respStr, err := HttpGetter(armoAPI.httpClient, armoAPI.getFrameworkURL(name), nil) @@ -146,10 +146,10 @@ func (armoAPI *ArmoAPI) GetExceptions(clusterName string) ([]armotypes.PostureEx return exceptions, nil } -func (armoAPI *ArmoAPI) GetCustomerGUID() (*TenantResponse, error) { - url := armoAPI.getCustomerURL() - if armoAPI.customerGUID != "" { - url = fmt.Sprintf("%s?customerGUID=%s", url, armoAPI.customerGUID) +func (armoAPI *ArmoAPI) GetTenant() (*TenantResponse, error) { + url := armoAPI.getAccountURL() + if armoAPI.accountID != "" { + url = fmt.Sprintf("%s?customerGUID=%s", url, armoAPI.accountID) } respStr, err := HttpGetter(armoAPI.httpClient, url, nil) if err != nil { @@ -159,14 +159,14 @@ func (armoAPI *ArmoAPI) GetCustomerGUID() (*TenantResponse, error) { if err = JSONDecoder(respStr).Decode(tenant); err != nil { return nil, err } - + armoAPI.accountID = tenant.TenantID return tenant, nil } // ControlsInputs // map[][] func (armoAPI *ArmoAPI) GetAccountConfig(clusterName string) (*armotypes.CustomerConfig, error) { accountConfig := &armotypes.CustomerConfig{} - if armoAPI.customerGUID == "" { + if armoAPI.accountID == "" { return accountConfig, nil } respStr, err := HttpGetter(armoAPI.httpClient, armoAPI.getAccountConfig(clusterName), nil) diff --git a/cautils/getter/armoapiutils.go b/cautils/getter/armoapiutils.go index 3c14040f..ab326010 100644 --- a/cautils/getter/armoapiutils.go +++ b/cautils/getter/armoapiutils.go @@ -13,7 +13,7 @@ func (armoAPI *ArmoAPI) getFrameworkURL(frameworkName string) string { u.Host = armoAPI.apiURL u.Path = "api/v1/armoFrameworks" q := u.Query() - q.Add("customerGUID", armoAPI.customerGUID) + q.Add("customerGUID", armoAPI.accountID) if isNativeFramework(frameworkName) { q.Add("frameworkName", strings.ToUpper(frameworkName)) } else { @@ -31,7 +31,7 @@ func (armoAPI *ArmoAPI) getListFrameworkURL() string { u.Host = armoAPI.apiURL u.Path = "api/v1/armoFrameworks" q := u.Query() - q.Add("customerGUID", armoAPI.customerGUID) + q.Add("customerGUID", armoAPI.accountID) u.RawQuery = q.Encode() return u.String() @@ -43,7 +43,7 @@ func (armoAPI *ArmoAPI) getExceptionsURL(clusterName string) string { u.Path = "api/v1/armoPostureExceptions" q := u.Query() - q.Add("customerGUID", armoAPI.customerGUID) + q.Add("customerGUID", armoAPI.accountID) // if clusterName != "" { // TODO - fix customer name support in Armo BE // q.Add("clusterName", clusterName) // } @@ -59,7 +59,7 @@ func (armoAPI *ArmoAPI) getAccountConfig(clusterName string) string { u.Path = "api/v1/armoCustomerConfiguration" q := u.Query() - q.Add("customerGUID", armoAPI.customerGUID) + q.Add("customerGUID", armoAPI.accountID) if clusterName != "" { // TODO - fix customer name support in Armo BE q.Add("clusterName", clusterName) } @@ -68,7 +68,7 @@ func (armoAPI *ArmoAPI) getAccountConfig(clusterName string) string { return u.String() } -func (armoAPI *ArmoAPI) getCustomerURL() string { +func (armoAPI *ArmoAPI) getAccountURL() string { u := url.URL{} u.Scheme = "https" u.Host = armoAPI.apiURL diff --git a/cautils/getter/getpolicies.go b/cautils/getter/getpolicies.go index cb3abdf8..572aed32 100644 --- a/cautils/getter/getpolicies.go +++ b/cautils/getter/getpolicies.go @@ -24,8 +24,15 @@ type IExceptionsGetter interface { GetExceptions(clusterName string) ([]armotypes.PostureExceptionPolicy, error) } type IBackend interface { - GetCustomerGUID() (*TenantResponse, error) - SetCustomerGUID(customerGUID string) + GetAccountID() string + GetClientID() string + GetAccessKey() string + + SetAccountID(accountID string) + SetClientID(clientID string) + SetAccessKey(accessKey string) + + GetTenant() (*TenantResponse, error) } type IControlsInputsGetter interface { diff --git a/cautils/getter/getpoliciesutils.go b/cautils/getter/getpoliciesutils.go index fa859594..a88ddcf0 100644 --- a/cautils/getter/getpoliciesutils.go +++ b/cautils/getter/getpoliciesutils.go @@ -21,7 +21,7 @@ func GetDefaultPath(name string) string { } func SaveInFile(policy interface{}, pathStr string) error { - encodedData, err := json.Marshal(policy) + encodedData, err := json.MarshalIndent(policy, "", " ") if err != nil { return err } diff --git a/clihandler/clidelete.go b/clihandler/clidelete.go new file mode 100644 index 00000000..77e9f7ba --- /dev/null +++ b/clihandler/clidelete.go @@ -0,0 +1,7 @@ +package clihandler + +func CliDelete() error { + + tenant := getTenantConfig("", "", getKubernetesApi()) // change k8sinterface + return tenant.DeleteCachedConfig() +} diff --git a/clihandler/clidownload.go b/clihandler/clidownload.go index ca07847a..74778552 100644 --- a/clihandler/clidownload.go +++ b/clihandler/clidownload.go @@ -75,7 +75,7 @@ func downloadArtifacts(downloadInfo *cautils.DownloadInfo) error { func downloadConfigInputs(downloadInfo *cautils.DownloadInfo) error { tenant := getTenantConfig(downloadInfo.Account, "", getKubernetesApi()) - controlsInputsGetter := getConfigInputsGetter(downloadInfo.Name, tenant.GetCustomerGUID(), nil) + controlsInputsGetter := getConfigInputsGetter(downloadInfo.Name, tenant.GetAccountID(), nil) controlInputs, err := controlsInputsGetter.GetControlsInputs(tenant.GetClusterName()) if err != nil { return err @@ -97,7 +97,7 @@ func downloadExceptions(downloadInfo *cautils.DownloadInfo) error { tenant := getTenantConfig(downloadInfo.Account, "", getKubernetesApi()) exceptionsGetter := getExceptionsGetter("") exceptions := []armotypes.PostureExceptionPolicy{} - if tenant.GetCustomerGUID() != "" { + if tenant.GetAccountID() != "" { exceptions, err = exceptionsGetter.GetExceptions(tenant.GetClusterName()) if err != nil { return err @@ -118,7 +118,7 @@ func downloadExceptions(downloadInfo *cautils.DownloadInfo) error { func downloadFramework(downloadInfo *cautils.DownloadInfo) error { tenant := getTenantConfig(downloadInfo.Account, "", getKubernetesApi()) - g := getPolicyGetter(nil, tenant.GetCustomerGUID(), true, nil) + g := getPolicyGetter(nil, tenant.GetAccountID(), true, nil) if downloadInfo.Name == "" { // if framework name not specified - download all frameworks @@ -154,7 +154,7 @@ func downloadFramework(downloadInfo *cautils.DownloadInfo) error { func downloadControl(downloadInfo *cautils.DownloadInfo) error { tenant := getTenantConfig(downloadInfo.Account, "", getKubernetesApi()) - g := getPolicyGetter(nil, tenant.GetCustomerGUID(), false, nil) + g := getPolicyGetter(nil, tenant.GetAccountID(), false, nil) if downloadInfo.Name == "" { // TODO - support diff --git a/clihandler/clilist.go b/clihandler/clilist.go index e0c4878e..dda856ee 100644 --- a/clihandler/clilist.go +++ b/clihandler/clilist.go @@ -5,11 +5,11 @@ import ( "sort" "strings" - "github.com/armosec/kubescape/cautils" "github.com/armosec/kubescape/cautils/getter" + "github.com/armosec/kubescape/clihandler/cliobjects" ) -var listFunc = map[string]func(*cautils.ListPolicies) ([]string, error){ +var listFunc = map[string]func(*cliobjects.ListPolicies) ([]string, error){ "controls": listControls, "frameworks": listFrameworks, } @@ -21,7 +21,7 @@ func ListSupportCommands() []string { } return commands } -func CliList(listPolicies *cautils.ListPolicies) error { +func CliList(listPolicies *cliobjects.ListPolicies) error { if f, ok := listFunc[listPolicies.Target]; ok { policies, err := f(listPolicies) if err != nil { @@ -40,16 +40,16 @@ func CliList(listPolicies *cautils.ListPolicies) error { return fmt.Errorf("unknown command to download") } -func listFrameworks(listPolicies *cautils.ListPolicies) ([]string, error) { +func listFrameworks(listPolicies *cliobjects.ListPolicies) ([]string, error) { tenant := getTenantConfig(listPolicies.Account, "", getKubernetesApi()) // change k8sinterface - g := getPolicyGetter(nil, tenant.GetCustomerGUID(), true, nil) + g := getPolicyGetter(nil, tenant.GetAccountID(), true, nil) return listFrameworksNames(g), nil } -func listControls(listPolicies *cautils.ListPolicies) ([]string, error) { +func listControls(listPolicies *cliobjects.ListPolicies) ([]string, error) { tenant := getTenantConfig(listPolicies.Account, "", getKubernetesApi()) // change k8sinterface - g := getPolicyGetter(nil, tenant.GetCustomerGUID(), false, nil) + g := getPolicyGetter(nil, tenant.GetAccountID(), false, nil) l := getter.ListName if listPolicies.ListIDs { l = getter.ListID diff --git a/cautils/listpolicies.go b/clihandler/cliobjects/listpolicies.go similarity index 80% rename from cautils/listpolicies.go rename to clihandler/cliobjects/listpolicies.go index 044c2c00..c8385b0c 100644 --- a/cautils/listpolicies.go +++ b/clihandler/cliobjects/listpolicies.go @@ -1,4 +1,4 @@ -package cautils +package cliobjects type ListPolicies struct { Target string diff --git a/clihandler/cliobjects/set.go b/clihandler/cliobjects/set.go new file mode 100644 index 00000000..53ab2940 --- /dev/null +++ b/clihandler/cliobjects/set.go @@ -0,0 +1,7 @@ +package cliobjects + +type SetConfig struct { + Account string + ClientID string + AccessKey string +} diff --git a/clihandler/cliobjects/submit.go b/clihandler/cliobjects/submit.go new file mode 100644 index 00000000..e250e880 --- /dev/null +++ b/clihandler/cliobjects/submit.go @@ -0,0 +1,5 @@ +package cliobjects + +type Submit struct { + Account string +} diff --git a/clihandler/cliset.go b/clihandler/cliset.go new file mode 100644 index 00000000..3ff6d3da --- /dev/null +++ b/clihandler/cliset.go @@ -0,0 +1,22 @@ +package clihandler + +import ( + "github.com/armosec/kubescape/clihandler/cliobjects" +) + +func CliSetConfig(setConfig *cliobjects.SetConfig) error { + + tenant := getTenantConfig("", "", getKubernetesApi()) + + if setConfig.Account != "" { + tenant.GetConfigObj().AccountID = setConfig.Account + } + if setConfig.AccessKey != "" { + tenant.GetConfigObj().AccessKey = setConfig.AccessKey + } + if setConfig.ClientID != "" { + tenant.GetConfigObj().ClientID = setConfig.ClientID + } + + return tenant.UpdateCachedConfig() +} diff --git a/clihandler/cliview.go b/clihandler/cliview.go new file mode 100644 index 00000000..bd76ecb7 --- /dev/null +++ b/clihandler/cliview.go @@ -0,0 +1,9 @@ +package clihandler + +import "fmt" + +func CliView() error { + tenant := getTenantConfig("", "", getKubernetesApi()) // change k8sinterface + fmt.Printf("%s\n", tenant.GetConfigObj().Config()) + return nil +} diff --git a/clihandler/cmd/cluster_set.go b/clihandler/cmd/cluster_set.go index 609d0ca5..5103c7ea 100644 --- a/clihandler/cmd/cluster_set.go +++ b/clihandler/cmd/cluster_set.go @@ -10,7 +10,7 @@ import ( "github.com/spf13/cobra" ) -var setCmd = &cobra.Command{ +var setClusterCmd = &cobra.Command{ Use: "set =", Short: "Set configuration in cluster", Long: ``, @@ -40,5 +40,5 @@ var setCmd = &cobra.Command{ } func init() { - clusterCmd.AddCommand(setCmd) + clusterCmd.AddCommand(setClusterCmd) } diff --git a/clihandler/cmd/config.go b/clihandler/cmd/config.go index 10b0f3ec..cedcd969 100644 --- a/clihandler/cmd/config.go +++ b/clihandler/cmd/config.go @@ -6,9 +6,10 @@ import ( // configCmd represents the config command var configCmd = &cobra.Command{ - Use: "config", - Short: "Set configuration", - Long: ``, + Use: "config", + Short: "Set configuration", + Long: ``, + Deprecated: "use the 'set' command instead", Run: func(cmd *cobra.Command, args []string) { }, } diff --git a/clihandler/cmd/delete.go b/clihandler/cmd/delete.go new file mode 100644 index 00000000..5caf85e2 --- /dev/null +++ b/clihandler/cmd/delete.go @@ -0,0 +1,34 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/armosec/kubescape/clihandler" + "github.com/spf13/cobra" +) + +var deleteCmd = &cobra.Command{ + Use: "delete", + Short: "Delete cached configurations and other data", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + }, +} + +var deleteConfigCmd = &cobra.Command{ + Use: "config", + Short: "Delete cached configurations", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + if err := clihandler.CliDelete(); err != nil { + fmt.Fprintf(os.Stderr, "error: %v\n", err) + os.Exit(1) + } + }, +} + +func init() { + rootCmd.AddCommand(deleteCmd) + deleteCmd.AddCommand(deleteConfigCmd) +} diff --git a/clihandler/cmd/download.go b/clihandler/cmd/download.go index 412c3733..77d9166f 100644 --- a/clihandler/cmd/download.go +++ b/clihandler/cmd/download.go @@ -69,7 +69,7 @@ func init() { // cobra.OnInitialize(initConfig) rootCmd.AddCommand(downloadCmd) - downloadCmd.Flags().StringVarP(&downloadInfo.Path, "output", "o", "", "Output file. If not specified, will save in `~/.kubescape/.json`") downloadCmd.PersistentFlags().StringVarP(&downloadInfo.Account, "account", "", "", "Armo portal account ID. Default will load account ID from configMap or config file") + downloadCmd.Flags().StringVarP(&downloadInfo.Path, "output", "o", "", "Output file. If not specified, will save in `~/.kubescape/.json`") } diff --git a/clihandler/cmd/list.go b/clihandler/cmd/list.go index 06befd99..0c9706b8 100644 --- a/clihandler/cmd/list.go +++ b/clihandler/cmd/list.go @@ -7,6 +7,7 @@ import ( "github.com/armosec/kubescape/cautils" "github.com/armosec/kubescape/clihandler" + "github.com/armosec/kubescape/clihandler/cliobjects" "github.com/spf13/cobra" ) @@ -28,7 +29,7 @@ var ( https://hub.armo.cloud/docs/controls ` ) -var listPolicies = cautils.ListPolicies{} +var listPolicies = cliobjects.ListPolicies{} var listCmd = &cobra.Command{ Use: "list [flags]", diff --git a/clihandler/cmd/rbac.go b/clihandler/cmd/rbac.go index 9ece1ba4..2762ddf7 100644 --- a/clihandler/cmd/rbac.go +++ b/clihandler/cmd/rbac.go @@ -29,7 +29,7 @@ var rabcCmd = &cobra.Command{ } // list RBAC - rbacObjects := cautils.NewRBACObjects(rbacscanner.NewRbacScannerFromK8sAPI(k8s, clusterConfig.GetCustomerGUID(), clusterConfig.GetClusterName())) + rbacObjects := cautils.NewRBACObjects(rbacscanner.NewRbacScannerFromK8sAPI(k8s, clusterConfig.GetAccountID(), clusterConfig.GetClusterName())) // submit resources r := reporterv1.NewReportEventReceiver(clusterConfig.GetConfigObj()) diff --git a/clihandler/cmd/results.go b/clihandler/cmd/results.go index 081e9913..1932ccb9 100644 --- a/clihandler/cmd/results.go +++ b/clihandler/cmd/results.go @@ -67,7 +67,7 @@ var resultsCmd = &cobra.Command{ return err } - resultsObjects := NewResultsObject(clusterConfig.GetCustomerGUID(), clusterConfig.GetClusterName(), args[0]) + resultsObjects := NewResultsObject(clusterConfig.GetAccountID(), clusterConfig.GetClusterName(), args[0]) // submit resources r := reporterv1.NewReportEventReceiver(clusterConfig.GetConfigObj()) diff --git a/clihandler/cmd/root.go b/clihandler/cmd/root.go index 4fd5792f..c035e216 100644 --- a/clihandler/cmd/root.go +++ b/clihandler/cmd/root.go @@ -10,7 +10,6 @@ import ( "github.com/spf13/cobra" ) -var cfgFile string var armoBEURLs = "" const envFlagUsage = "Send report results to specific URL. Format:,,.\n\t\tExample:report.armo.cloud,api.armo.cloud,portal.armo.cloud" @@ -31,7 +30,7 @@ func Execute() { } func init() { - rootCmd.PersistentFlags().StringVarP(&scanInfo.Account, "account", "", "", "Armo portal account ID. Default will load account ID from configMap or config file") + flag.CommandLine.StringVar(&armoBEURLs, "environment", "", envFlagUsage) rootCmd.PersistentFlags().StringVar(&armoBEURLs, "environment", "", envFlagUsage) rootCmd.PersistentFlags().MarkHidden("environment") diff --git a/clihandler/cmd/scan.go b/clihandler/cmd/scan.go index 76761bc7..20469c3e 100644 --- a/clihandler/cmd/scan.go +++ b/clihandler/cmd/scan.go @@ -42,7 +42,9 @@ func init() { cobra.OnInitialize(frameworkInitConfig) rootCmd.AddCommand(scanCmd) - rootCmd.PersistentFlags().StringVarP(&scanInfo.KubeContext, "kube-context", "", "", "Kube context. Default will use the current-context") + + scanCmd.PersistentFlags().StringVarP(&scanInfo.Account, "account", "", "", "Armo portal account ID. Default will load account ID from configMap or config file") + scanCmd.PersistentFlags().StringVarP(&scanInfo.KubeContext, "kube-context", "", "", "Kube context. Default will use the current-context") scanCmd.PersistentFlags().StringVar(&scanInfo.ControlsInputs, "controls-config", "", "Path to an controls-config obj. If not set will download controls-config from ARMO management portal") scanCmd.PersistentFlags().StringVar(&scanInfo.UseExceptions, "exceptions", "", "Path to an exceptions obj. If not set will download exceptions from ARMO management portal") scanCmd.PersistentFlags().StringVar(&scanInfo.UseArtifactsFrom, "use-artifacts-from", "", "Load artifacts from local directory. If not used will download them") diff --git a/clihandler/cmd/set.go b/clihandler/cmd/set.go new file mode 100644 index 00000000..a54d4d2c --- /dev/null +++ b/clihandler/cmd/set.go @@ -0,0 +1,53 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/armosec/kubescape/clihandler" + "github.com/armosec/kubescape/clihandler/cliobjects" + "github.com/spf13/cobra" +) + +var ( + setConfigExample = ` + # Set account credentials + kubescape set config --account --client-id --access-key +` +) +var setConfig = cliobjects.SetConfig{} + +// configCmd represents the config command +var setCmd = &cobra.Command{ + Use: "set", + Short: "Set configurations and other data", + Long: ``, + Example: setConfigExample, + Run: func(cmd *cobra.Command, args []string) { + }, +} + +// configCmd represents the config command +var setConfigCmd = &cobra.Command{ + Use: "config", + Short: "Set cached configurations", + Long: ``, + Example: setConfigExample, + Run: func(cmd *cobra.Command, args []string) { + if err := clihandler.CliSetConfig(&setConfig); err != nil { + fmt.Fprintf(os.Stderr, "error: %v\n", err) + os.Exit(1) + } + }, +} + +func init() { + + setConfigCmd.PersistentFlags().StringVarP(&setConfig.Account, "account", "", "", "Set Armo account ID") + setConfigCmd.PersistentFlags().StringVarP(&setConfig.ClientID, "client-id", "", "", "Set Armo client ID") + setConfigCmd.PersistentFlags().StringVarP(&setConfig.AccessKey, "access-key", "", "", "Set Armo access key") + + rootCmd.AddCommand(setCmd) + setCmd.AddCommand(setConfigCmd) + +} diff --git a/clihandler/cmd/submit.go b/clihandler/cmd/submit.go index 1f27b4eb..7677fa84 100644 --- a/clihandler/cmd/submit.go +++ b/clihandler/cmd/submit.go @@ -4,9 +4,12 @@ import ( "github.com/armosec/k8s-interface/k8sinterface" "github.com/armosec/kubescape/cautils" "github.com/armosec/kubescape/cautils/getter" + "github.com/armosec/kubescape/clihandler/cliobjects" "github.com/spf13/cobra" ) +var submitInfo cliobjects.Submit + var submitCmd = &cobra.Command{ Use: "submit ", Short: "Submit an object to the Kubescape SaaS version", @@ -16,12 +19,13 @@ var submitCmd = &cobra.Command{ } func init() { + submitCmd.PersistentFlags().StringVarP(&submitInfo.Account, "account", "", "", "Armo portal account ID. Default will load account ID from configMap or config file") rootCmd.AddCommand(submitCmd) } func getSubmittedClusterConfig(k8s *k8sinterface.KubernetesApi) (*cautils.ClusterConfig, error) { - clusterConfig := cautils.NewClusterConfig(k8s, getter.GetArmoAPIConnector(), scanInfo.Account, scanInfo.KubeContext) // TODO - support none cluster env submit - if clusterConfig.GetCustomerGUID() != "" { + clusterConfig := cautils.NewClusterConfig(k8s, getter.GetArmoAPIConnector(), submitInfo.Account, scanInfo.KubeContext) // TODO - support none cluster env submit + if clusterConfig.GetAccountID() != "" { if err := clusterConfig.SetTenant(); err != nil { return clusterConfig, err } diff --git a/clihandler/cmd/view.go b/clihandler/cmd/view.go new file mode 100644 index 00000000..77cbdf2c --- /dev/null +++ b/clihandler/cmd/view.go @@ -0,0 +1,36 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/armosec/kubescape/clihandler" + "github.com/spf13/cobra" +) + +// configCmd represents the config command +var viewCmd = &cobra.Command{ + Use: "view", + Short: "View configurations and other data", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + }, +} + +// configCmd represents the config command +var viewConfigCmd = &cobra.Command{ + Use: "config", + Short: "View cached configurations", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + if err := clihandler.CliView(); err != nil { + fmt.Fprintf(os.Stderr, "error: %v\n", err) + os.Exit(1) + } + }, +} + +func init() { + rootCmd.AddCommand(viewCmd) + viewCmd.AddCommand(viewConfigCmd) +} diff --git a/clihandler/initcli.go b/clihandler/initcli.go index 375b2638..81d7ddf5 100644 --- a/clihandler/initcli.go +++ b/clihandler/initcli.go @@ -99,16 +99,16 @@ func ScanCliSetup(scanInfo *cautils.ScanInfo) error { processNotification := make(chan *cautils.OPASessionObj) reportResults := make(chan *cautils.OPASessionObj) - cautils.ClusterName = interfaces.tenantConfig.GetClusterName() // TODO - Deprecated - cautils.CustomerGUID = interfaces.tenantConfig.GetCustomerGUID() // TODO - Deprecated + cautils.ClusterName = interfaces.tenantConfig.GetClusterName() // TODO - Deprecated + cautils.CustomerGUID = interfaces.tenantConfig.GetAccountID() // TODO - Deprecated interfaces.report.SetClusterName(interfaces.tenantConfig.GetClusterName()) - interfaces.report.SetCustomerGUID(interfaces.tenantConfig.GetCustomerGUID()) + interfaces.report.SetCustomerGUID(interfaces.tenantConfig.GetAccountID()) downloadReleasedPolicy := getter.NewDownloadReleasedPolicy() // download config inputs from github release // set policy getter only after setting the customerGUID - scanInfo.Getters.PolicyGetter = getPolicyGetter(scanInfo.UseFrom, interfaces.tenantConfig.GetCustomerGUID(), scanInfo.FrameworkScan, downloadReleasedPolicy) - scanInfo.Getters.ControlsInputsGetter = getConfigInputsGetter(scanInfo.ControlsInputs, interfaces.tenantConfig.GetCustomerGUID(), downloadReleasedPolicy) + scanInfo.Getters.PolicyGetter = getPolicyGetter(scanInfo.UseFrom, interfaces.tenantConfig.GetAccountID(), scanInfo.FrameworkScan, downloadReleasedPolicy) + scanInfo.Getters.ControlsInputsGetter = getConfigInputsGetter(scanInfo.ControlsInputs, interfaces.tenantConfig.GetAccountID(), downloadReleasedPolicy) scanInfo.Getters.ExceptionsGetter = getExceptionsGetter(scanInfo.UseExceptions) // TODO - list supported frameworks/controls diff --git a/clihandler/initcliutils.go b/clihandler/initcliutils.go index 1c231dc5..56c122e5 100644 --- a/clihandler/initcliutils.go +++ b/clihandler/initcliutils.go @@ -42,7 +42,7 @@ func getExceptionsGetter(useExceptions string) getter.IExceptionsGetter { func getRBACHandler(tenantConfig cautils.ITenantConfig, k8s *k8sinterface.KubernetesApi, submit bool) *cautils.RBACObjects { if submit { - return cautils.NewRBACObjects(rbacscanner.NewRbacScannerFromK8sAPI(k8s, tenantConfig.GetCustomerGUID(), tenantConfig.GetClusterName())) + return cautils.NewRBACObjects(rbacscanner.NewRbacScannerFromK8sAPI(k8s, tenantConfig.GetAccountID(), tenantConfig.GetClusterName())) } return nil } @@ -153,7 +153,6 @@ func getPolicyGetter(loadPoliciesFromFile []string, accountID string, frameworkS } if accountID != "" && frameworkScope { g := getter.GetArmoAPIConnector() // download policy from ARMO backend - g.SetCustomerGUID(accountID) return g } if downloadReleasedPolicy == nil { @@ -184,7 +183,6 @@ func getConfigInputsGetter(ControlsInputs string, accountID string, downloadRele } if accountID != "" { g := getter.GetArmoAPIConnector() // download config from ARMO backend - g.SetCustomerGUID(accountID) return g } if downloadReleasedPolicy == nil { diff --git a/resourcehandler/registrydata.go b/resourcehandler/registrydata.go index 65df1165..7805f1a9 100644 --- a/resourcehandler/registrydata.go +++ b/resourcehandler/registrydata.go @@ -4,6 +4,7 @@ import ( "github.com/armosec/k8s-interface/k8sinterface" "github.com/armosec/k8s-interface/workloadinterface" "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/cautils/getter" armosecadaptorv1 "github.com/armosec/kubescape/registryadaptors/armosec/v1" "github.com/armosec/kubescape/registryadaptors/registryvulnerabilities" "github.com/armosec/opa-utils/shared" @@ -131,17 +132,24 @@ func imageTagsToContainerImageIdentifier(images []string) []registryvulnerabilit return imagesIdentifiers } func listAdaptores() ([]registryvulnerabilities.IContainerImageVulnerabilityAdaptor, error) { - customerGUID := " " - clientID := " " - accessKey := " " - registry := "armoui-dev.eudev3.cyberarmorsoft.com" adaptors := []registryvulnerabilities.IContainerImageVulnerabilityAdaptor{} - armosecAdaptor, err := armosecadaptorv1.NewArmoAdaptor(registry, map[string]string{"accountID": customerGUID, "clientID": clientID, "accessKey": accessKey}) - if err != nil { - return nil, err + + armoAPI := getter.GetArmoAPIConnector() + if armoAPI == nil { + accountID := armoAPI.GetAccountID() + clientID := armoAPI.GetClientID() + accessKey := armoAPI.GetAccessKey() + if accountID != "" && clientID != "" && accessKey != "" { + armosecAdaptor, err := armosecadaptorv1.NewArmoAdaptor(armoAPI.GetFrontendURL(), map[string]string{"accountID": accountID, "clientID": clientID, "accessKey": accessKey}) + if err != nil { + return nil, err + } + adaptors = append(adaptors, armosecAdaptor) + } else { + // TODO - print warning + } } - adaptors = append(adaptors, armosecAdaptor) return adaptors, nil } diff --git a/resultshandling/reporter/v1/reporteventreceiver.go b/resultshandling/reporter/v1/reporteventreceiver.go index 853700ef..88d1087b 100644 --- a/resultshandling/reporter/v1/reporteventreceiver.go +++ b/resultshandling/reporter/v1/reporteventreceiver.go @@ -31,7 +31,7 @@ func NewReportEventReceiver(tenantConfig *cautils.ConfigObj) *ReportEventReceive return &ReportEventReceiver{ httpClient: &http.Client{}, clusterName: tenantConfig.ClusterName, - customerGUID: tenantConfig.CustomerGUID, + customerGUID: tenantConfig.AccountID, token: tenantConfig.Token, customerAdminEMail: tenantConfig.CustomerAdminEMail, } diff --git a/resultshandling/reporter/v2/reporteventreceiver.go b/resultshandling/reporter/v2/reporteventreceiver.go index 03664b97..3784eab4 100644 --- a/resultshandling/reporter/v2/reporteventreceiver.go +++ b/resultshandling/reporter/v2/reporteventreceiver.go @@ -32,7 +32,7 @@ func NewReportEventReceiver(tenantConfig *cautils.ConfigObj) *ReportEventReceive return &ReportEventReceiver{ httpClient: &http.Client{}, clusterName: tenantConfig.ClusterName, - customerGUID: tenantConfig.CustomerGUID, + customerGUID: tenantConfig.AccountID, token: tenantConfig.Token, customerAdminEMail: tenantConfig.CustomerAdminEMail, }