From 9e7cc06f975420be32111fc934e8a727a79da2ce Mon Sep 17 00:00:00 2001 From: Daniel-GrunbergerCA Date: Tue, 14 Sep 2021 17:14:21 +0300 Subject: [PATCH 1/3] give higher priority to config.json --- cautils/customerloader.go | 97 ++++++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 21 deletions(-) diff --git a/cautils/customerloader.go b/cautils/customerloader.go index 5cc4097d..40aa97e6 100644 --- a/cautils/customerloader.go +++ b/cautils/customerloader.go @@ -72,6 +72,10 @@ func NewClusterConfig(k8s *k8sinterface.KubernetesApi, armoAPI *getter.ArmoAPI) defaultNS: k8sinterface.GetDefaultNamespace(), } } +func (c *ClusterConfig) createConfigJson() { + ioutil.WriteFile(getter.GetDefaultPath(configFileName+".json"), nil, 0664) + +} func (c *ClusterConfig) update(configObj *ConfigObj) { c.configObj = configObj @@ -122,6 +126,26 @@ func (c *ClusterConfig) GetValueByKeyFromConfigMap(key string) (string, error) { } +func (c *ClusterConfig) SetKeyValueInConfigJson(key string, value string) error { + data, err := ioutil.ReadFile(getter.GetDefaultPath(configFileName + ".json")) + if err != nil { + return err + } + var obj map[string]interface{} + err = json.Unmarshal(data, &obj) + + if err != nil { + return err + } + obj[key] = value + newData, err := json.Marshal(obj) + if err != nil { + return err + } + + return ioutil.WriteFile(getter.GetDefaultPath(configFileName+".json"), newData, 0664) +} + func (c *ClusterConfig) SetKeyValueInConfigmap(key string, value string) error { configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Get(context.Background(), configMapName, metav1.GetOptions{}) @@ -150,25 +174,35 @@ func (c *ClusterConfig) SetKeyValueInConfigmap(key string, value string) error { func (c *ClusterConfig) SetCustomerGUID() error { - // get from configMap - if configObj, _ := c.loadConfigFromConfigMap(); configObj != nil { - c.update(configObj) + // get from file + if c.existsConfigJson() { + c.configObj, _ = c.loadConfigFromFile() + } else if c.existsConfigMap() { + c.configObj, _ = c.loadConfigFromConfigMap() + } else { + c.createConfigMap() + c.createConfigJson() } - // get from file - if configObj, _ := c.loadConfigFromFile(); configObj != nil { - c.update(configObj) - c.updateConfigMap() - } customerGUID := c.GetCustomerGUID() // get from armoBE tenantResponse, err := c.armoAPI.GetCustomerGUID(customerGUID) if err == nil && tenantResponse != nil { if tenantResponse.AdminMail != "" { // this customer already belongs to some user - c.update(&ConfigObj{CustomerGUID: customerGUID, CustomerAdminEMail: tenantResponse.AdminMail}) + if c.existsConfigJson() { + c.update(&ConfigObj{CustomerGUID: customerGUID, CustomerAdminEMail: tenantResponse.AdminMail}) + } + if c.existsConfigMap() { + c.updateConfigMap() + } } else { - c.update(&ConfigObj{CustomerGUID: tenantResponse.TenantID, Token: tenantResponse.Token}) - return c.updateConfigMap() + if c.existsConfigJson() { + c.update(&ConfigObj{CustomerGUID: tenantResponse.TenantID, Token: tenantResponse.Token}) + } + if c.existsConfigMap() { + c.configObj = &ConfigObj{CustomerGUID: tenantResponse.TenantID, Token: tenantResponse.Token} + c.updateConfigMap() + } } } else { if err != nil && strings.Contains(err.Error(), "Invitation for tenant already exists") { @@ -194,28 +228,49 @@ func (c *ClusterConfig) loadConfigFromConfigMap() (*ConfigObj, error) { return nil, nil } +func (c *ClusterConfig) existsConfigMap() bool { + _, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Get(context.Background(), configMapName, metav1.GetOptions{}) + return err == nil +} + +func (c *ClusterConfig) existsConfigJson() bool { + _, err := ioutil.ReadFile(getter.GetDefaultPath(configFileName + ".json")) + + return err == nil + +} + +func (c *ClusterConfig) createConfigMap() error { + if c.k8s == nil { + return nil + } + configMap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: configMapName, + }, + } + c.updateConfigData(configMap) + + _, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Create(context.Background(), configMap, metav1.CreateOptions{}) + return err +} + func (c *ClusterConfig) updateConfigMap() error { if c.k8s == nil { return nil } configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Get(context.Background(), configMapName, metav1.GetOptions{}) + if err != nil { - configMap = &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: configMapName, - }, - } + return err } c.updateConfigData(configMap) - if err != nil { - _, err = c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Create(context.Background(), configMap, metav1.CreateOptions{}) - } else { - _, err = c.k8s.KubernetesClient.CoreV1().ConfigMaps(configMap.Namespace).Update(context.Background(), configMap, metav1.UpdateOptions{}) - } + _, err = c.k8s.KubernetesClient.CoreV1().ConfigMaps(configMap.Namespace).Update(context.Background(), configMap, metav1.UpdateOptions{}) return err } + func (c *ClusterConfig) updateConfigData(configMap *corev1.ConfigMap) { if len(configMap.Data) == 0 { configMap.Data = make(map[string]string) From 5bb961bdc665294aba821a95c1b53ca7016c9cb7 Mon Sep 17 00:00:00 2001 From: Daniel-GrunbergerCA Date: Tue, 14 Sep 2021 17:53:21 +0300 Subject: [PATCH 2/3] start get/set for config.json --- cautils/customerloader.go | 3 +- cmd/local.go | 17 +++++++++++ cmd/local_get.go | 60 +++++++++++++++++++++++++++++++++++++++ cmd/local_set.go | 45 +++++++++++++++++++++++++++++ cmd/set.go | 7 ++--- 5 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 cmd/local.go create mode 100644 cmd/local_get.go create mode 100644 cmd/local_set.go diff --git a/cautils/customerloader.go b/cautils/customerloader.go index 40aa97e6..e0b3b73c 100644 --- a/cautils/customerloader.go +++ b/cautils/customerloader.go @@ -121,7 +121,7 @@ func (c *ClusterConfig) GetValueByKeyFromConfigMap(key string) (string, error) { if val, ok := configMap.Data[key]; ok { return val, nil } else { - return "", fmt.Errorf("value does not exist.") + return "", fmt.Errorf("value does not exist") } } @@ -144,6 +144,7 @@ func (c *ClusterConfig) SetKeyValueInConfigJson(key string, value string) error } return ioutil.WriteFile(getter.GetDefaultPath(configFileName+".json"), newData, 0664) + } func (c *ClusterConfig) SetKeyValueInConfigmap(key string, value string) error { diff --git a/cmd/local.go b/cmd/local.go new file mode 100644 index 00000000..75e7b680 --- /dev/null +++ b/cmd/local.go @@ -0,0 +1,17 @@ +package cmd + +import ( + "github.com/spf13/cobra" +) + +var localCmd = &cobra.Command{ + Use: "local", + Short: "Set configuration locally (for config.json)", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + }, +} + +func init() { + configCmd.AddCommand(localCmd) +} diff --git a/cmd/local_get.go b/cmd/local_get.go new file mode 100644 index 00000000..8245a840 --- /dev/null +++ b/cmd/local_get.go @@ -0,0 +1,60 @@ +package cmd + +import ( + "fmt" + "strings" + + "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/cautils/getter" + "github.com/armosec/kubescape/cautils/k8sinterface" + "github.com/spf13/cobra" +) + +// localGetCmd represents the localGet command +var localGetCmd = &cobra.Command{ + Use: "get ", + Short: "Get configuration locally", + Long: ``, + Args: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 || len(args) > 1 { + return fmt.Errorf("requires one argument") + } + + keyValue := strings.Split(args[0], "=") + if len(keyValue) != 1 { + return fmt.Errorf("requires one argument") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + keyValue := strings.Split(args[0], "=") + key := keyValue[0] + + k8s := k8sinterface.NewKubernetesApi() + clusterConfig := cautils.NewClusterConfig(k8s, getter.NewArmoAPI()) + val, err := clusterConfig.GetValueByKeyFromConfigMap(key) + if err != nil { + if err.Error() == "value does not exist." { + fmt.Printf("Could net get value from configmap, reason: %s\n", err) + return nil + } + return err + } + fmt.Println(key + "=" + val) + return nil + }, +} + +func init() { + localCmd.AddCommand(localGetCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // localGetCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // localGetCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} diff --git a/cmd/local_set.go b/cmd/local_set.go new file mode 100644 index 00000000..c43cf653 --- /dev/null +++ b/cmd/local_set.go @@ -0,0 +1,45 @@ +package cmd + +import ( + "fmt" + "strings" + + "github.com/armosec/kubescape/cautils" + "github.com/armosec/kubescape/cautils/getter" + "github.com/armosec/kubescape/cautils/k8sinterface" + "github.com/spf13/cobra" +) + +// localSetCmd represents the localSet command +var localSetCmd = &cobra.Command{ + Use: "set =", + Short: "Set configuration locally", + Long: ``, + Args: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 || len(args) > 1 { + return fmt.Errorf("requires one argument: =") + } + keyValue := strings.Split(args[0], "=") + if len(keyValue) != 2 { + return fmt.Errorf("requires one argument: =") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + keyValue := strings.Split(args[0], "=") + key := keyValue[0] + data := keyValue[1] + + k8s := k8sinterface.NewKubernetesApi() + clusterConfig := cautils.NewClusterConfig(k8s, getter.NewArmoAPI()) + if err := clusterConfig.SetKeyValueInConfigJson(key, data); err != nil { + return err + } + fmt.Println("Value added successfully.") + return nil + }, +} + +func init() { + localCmd.AddCommand(localSetCmd) +} diff --git a/cmd/set.go b/cmd/set.go index c464c490..f7c94b84 100644 --- a/cmd/set.go +++ b/cmd/set.go @@ -11,10 +11,9 @@ import ( ) var setCmd = &cobra.Command{ - Use: "set =", - Short: "Set configuration in cluster", - Long: ``, - ValidArgs: supportedFrameworks, + Use: "set =", + Short: "Set configuration in cluster", + Long: ``, Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 || len(args) > 1 { return fmt.Errorf("requires one argument: =") From 01c1b44bfcac1e921996cd00f03d131858468d88 Mon Sep 17 00:00:00 2001 From: Daniel-GrunbergerCA Date: Sun, 19 Sep 2021 14:53:04 +0300 Subject: [PATCH 3/3] finish config local flags --- cautils/customerloader.go | 56 ++++++++++++++++++++++------------ cmd/{get.go => cluster_get.go} | 0 cmd/{set.go => cluster_set.go} | 0 cmd/local_get.go | 18 ++--------- cmd/local_set.go | 7 +---- 5 files changed, 39 insertions(+), 42 deletions(-) rename cmd/{get.go => cluster_get.go} (100%) rename cmd/{set.go => cluster_set.go} (100%) diff --git a/cautils/customerloader.go b/cautils/customerloader.go index e0b3b73c..72a11549 100644 --- a/cautils/customerloader.go +++ b/cautils/customerloader.go @@ -18,7 +18,7 @@ import ( const ( configMapName = "kubescape" - configFileName = "config" + ConfigFileName = "config" ) type ConfigObj struct { @@ -72,14 +72,13 @@ func NewClusterConfig(k8s *k8sinterface.KubernetesApi, armoAPI *getter.ArmoAPI) defaultNS: k8sinterface.GetDefaultNamespace(), } } -func (c *ClusterConfig) createConfigJson() { - ioutil.WriteFile(getter.GetDefaultPath(configFileName+".json"), nil, 0664) +func createConfigJson() { + ioutil.WriteFile(getter.GetDefaultPath(ConfigFileName+".json"), nil, 0664) } -func (c *ClusterConfig) update(configObj *ConfigObj) { - c.configObj = configObj - ioutil.WriteFile(getter.GetDefaultPath(configFileName+".json"), c.configObj.Json(), 0664) +func update(configObj *ConfigObj) { + ioutil.WriteFile(getter.GetDefaultPath(ConfigFileName+".json"), configObj.Json(), 0664) } func (c *ClusterConfig) GenerateURL() { u := url.URL{} @@ -126,8 +125,23 @@ func (c *ClusterConfig) GetValueByKeyFromConfigMap(key string) (string, error) { } -func (c *ClusterConfig) SetKeyValueInConfigJson(key string, value string) error { - data, err := ioutil.ReadFile(getter.GetDefaultPath(configFileName + ".json")) +func GetValueFromConfigJson(key string) (string, error) { + data, err := ioutil.ReadFile(getter.GetDefaultPath(ConfigFileName + ".json")) + if err != nil { + return "", err + } + var obj map[string]interface{} + err = json.Unmarshal(data, &obj) + if val, ok := obj[key]; ok { + return fmt.Sprint(val), nil + } else { + return "", fmt.Errorf("value does not exist") + } + +} + +func SetKeyValueInConfigJson(key string, value string) error { + data, err := ioutil.ReadFile(getter.GetDefaultPath(ConfigFileName + ".json")) if err != nil { return err } @@ -143,7 +157,7 @@ func (c *ClusterConfig) SetKeyValueInConfigJson(key string, value string) error return err } - return ioutil.WriteFile(getter.GetDefaultPath(configFileName+".json"), newData, 0664) + return ioutil.WriteFile(getter.GetDefaultPath(ConfigFileName+".json"), newData, 0664) } @@ -176,29 +190,31 @@ func (c *ClusterConfig) SetKeyValueInConfigmap(key string, value string) error { func (c *ClusterConfig) SetCustomerGUID() error { // get from file - if c.existsConfigJson() { - c.configObj, _ = c.loadConfigFromFile() + if existsConfigJson() { + c.configObj, _ = loadConfigFromFile() } else if c.existsConfigMap() { c.configObj, _ = c.loadConfigFromConfigMap() } else { c.createConfigMap() - c.createConfigJson() + createConfigJson() } customerGUID := c.GetCustomerGUID() // get from armoBE tenantResponse, err := c.armoAPI.GetCustomerGUID(customerGUID) + if err == nil && tenantResponse != nil { if tenantResponse.AdminMail != "" { // this customer already belongs to some user - if c.existsConfigJson() { - c.update(&ConfigObj{CustomerGUID: customerGUID, CustomerAdminEMail: tenantResponse.AdminMail}) + if existsConfigJson() { + update(&ConfigObj{CustomerGUID: customerGUID, CustomerAdminEMail: tenantResponse.AdminMail}) } if c.existsConfigMap() { + c.configObj.CustomerAdminEMail = tenantResponse.AdminMail c.updateConfigMap() } } else { - if c.existsConfigJson() { - c.update(&ConfigObj{CustomerGUID: tenantResponse.TenantID, Token: tenantResponse.Token}) + if existsConfigJson() { + update(&ConfigObj{CustomerGUID: tenantResponse.TenantID, Token: tenantResponse.Token}) } if c.existsConfigMap() { c.configObj = &ConfigObj{CustomerGUID: tenantResponse.TenantID, Token: tenantResponse.Token} @@ -234,8 +250,8 @@ func (c *ClusterConfig) existsConfigMap() bool { return err == nil } -func (c *ClusterConfig) existsConfigJson() bool { - _, err := ioutil.ReadFile(getter.GetDefaultPath(configFileName + ".json")) +func existsConfigJson() bool { + _, err := ioutil.ReadFile(getter.GetDefaultPath(ConfigFileName + ".json")) return err == nil @@ -283,8 +299,8 @@ func (c *ClusterConfig) updateConfigData(configMap *corev1.ConfigMap) { } } } -func (c *ClusterConfig) loadConfigFromFile() (*ConfigObj, error) { - dat, err := ioutil.ReadFile(getter.GetDefaultPath(configFileName + ".json")) +func loadConfigFromFile() (*ConfigObj, error) { + dat, err := ioutil.ReadFile(getter.GetDefaultPath(ConfigFileName + ".json")) if err != nil { return nil, err } diff --git a/cmd/get.go b/cmd/cluster_get.go similarity index 100% rename from cmd/get.go rename to cmd/cluster_get.go diff --git a/cmd/set.go b/cmd/cluster_set.go similarity index 100% rename from cmd/set.go rename to cmd/cluster_set.go diff --git a/cmd/local_get.go b/cmd/local_get.go index 8245a840..e8499681 100644 --- a/cmd/local_get.go +++ b/cmd/local_get.go @@ -6,11 +6,9 @@ import ( "github.com/armosec/kubescape/cautils" "github.com/armosec/kubescape/cautils/getter" - "github.com/armosec/kubescape/cautils/k8sinterface" "github.com/spf13/cobra" ) -// localGetCmd represents the localGet command var localGetCmd = &cobra.Command{ Use: "get ", Short: "Get configuration locally", @@ -30,12 +28,10 @@ var localGetCmd = &cobra.Command{ keyValue := strings.Split(args[0], "=") key := keyValue[0] - k8s := k8sinterface.NewKubernetesApi() - clusterConfig := cautils.NewClusterConfig(k8s, getter.NewArmoAPI()) - val, err := clusterConfig.GetValueByKeyFromConfigMap(key) + val, err := cautils.GetValueFromConfigJson(key) if err != nil { if err.Error() == "value does not exist." { - fmt.Printf("Could net get value from configmap, reason: %s\n", err) + fmt.Printf("Could net get value from: %s, reason: %s\n", getter.GetDefaultPath(cautils.ConfigFileName+".json"), err) return nil } return err @@ -47,14 +43,4 @@ var localGetCmd = &cobra.Command{ func init() { localCmd.AddCommand(localGetCmd) - - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // localGetCmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - // localGetCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") } diff --git a/cmd/local_set.go b/cmd/local_set.go index c43cf653..e5e8c7c4 100644 --- a/cmd/local_set.go +++ b/cmd/local_set.go @@ -5,12 +5,9 @@ import ( "strings" "github.com/armosec/kubescape/cautils" - "github.com/armosec/kubescape/cautils/getter" - "github.com/armosec/kubescape/cautils/k8sinterface" "github.com/spf13/cobra" ) -// localSetCmd represents the localSet command var localSetCmd = &cobra.Command{ Use: "set =", Short: "Set configuration locally", @@ -30,9 +27,7 @@ var localSetCmd = &cobra.Command{ key := keyValue[0] data := keyValue[1] - k8s := k8sinterface.NewKubernetesApi() - clusterConfig := cautils.NewClusterConfig(k8s, getter.NewArmoAPI()) - if err := clusterConfig.SetKeyValueInConfigJson(key, data); err != nil { + if err := cautils.SetKeyValueInConfigJson(key, data); err != nil { return err } fmt.Println("Value added successfully.")