support view/set/delete commands

This commit is contained in:
dwertent
2022-02-01 17:16:27 +02:00
parent d1695b7f10
commit 2ffb7fcdb4
30 changed files with 374 additions and 128 deletions
+104 -51
View File
@@ -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
}
}
+25 -25
View File
@@ -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[<control name>][<input arguments>]
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)
+5 -5
View File
@@ -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
+9 -2
View File
@@ -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 {
+1 -1
View File
@@ -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
}
+7
View File
@@ -0,0 +1,7 @@
package clihandler
func CliDelete() error {
tenant := getTenantConfig("", "", getKubernetesApi()) // change k8sinterface
return tenant.DeleteCachedConfig()
}
+4 -4
View File
@@ -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
+7 -7
View File
@@ -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
@@ -1,4 +1,4 @@
package cautils
package cliobjects
type ListPolicies struct {
Target string
+7
View File
@@ -0,0 +1,7 @@
package cliobjects
type SetConfig struct {
Account string
ClientID string
AccessKey string
}
+5
View File
@@ -0,0 +1,5 @@
package cliobjects
type Submit struct {
Account string
}
+22
View File
@@ -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()
}
+9
View File
@@ -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
}
+2 -2
View File
@@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra"
)
var setCmd = &cobra.Command{
var setClusterCmd = &cobra.Command{
Use: "set <key>=<value>",
Short: "Set configuration in cluster",
Long: ``,
@@ -40,5 +40,5 @@ var setCmd = &cobra.Command{
}
func init() {
clusterCmd.AddCommand(setCmd)
clusterCmd.AddCommand(setClusterCmd)
}
+4 -3
View File
@@ -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) {
},
}
+34
View File
@@ -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)
}
+1 -1
View File
@@ -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/<policy name>.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/<policy name>.json`")
}
+2 -1
View File
@@ -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 <policy> [flags]",
+1 -1
View File
@@ -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())
+1 -1
View File
@@ -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())
+1 -2
View File
@@ -10,7 +10,6 @@ import (
"github.com/spf13/cobra"
)
var cfgFile string
var armoBEURLs = ""
const envFlagUsage = "Send report results to specific URL. Format:<ReportReceiver>,<Backend>,<Frontend>.\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")
+3 -1
View File
@@ -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")
+53
View File
@@ -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 <account id> --client-id <client id> --access-key <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)
}
+6 -2
View File
@@ -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 <command>",
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
}
+36
View File
@@ -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)
}
+5 -5
View File
@@ -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
+1 -3
View File
@@ -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 {
+16 -8
View File
@@ -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
}
@@ -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,
}
@@ -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,
}