diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a07c05a7..ac0e0b35 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -43,10 +43,7 @@ jobs: ArmoBEServer: api.armo.cloud ArmoERServer: report.euprod1.cyberarmorsoft.com ArmoWebsite: portal.armo.cloud - BEServerConst: github.com/armosec/kubescape/cautils/getter.ArmoBEURL - ERServerConst: github.com/armosec/kubescape/cautils/getter.ArmoERURL - WebsiteConst: github.com/armosec/kubescape/cautils/getter.ArmoFEURL - run: mkdir -p build/${{ matrix.os }} && go mod tidy && go build -ldflags "-w -s -X github.com/armosec/kubescape/cmd.BuildNumber=$RELEASE -X $BEServerConst=$ArmoBEServer -X $ERServerConst=$ArmoERServer -X $WebsiteConst=$ArmoWebsite" -o build/${{ matrix.os }}/kubescape # && md5sum build/${{ matrix.os }}/kubescape > build/${{ matrix.os }}/kubescape.md5 + run: mkdir -p build/${{ matrix.os }} && go mod tidy && go build -ldflags "-w -s -X github.com/armosec/kubescape/cmd.BuildNumber=$RELEASE -X github.com/armosec/kubescape/cautils/getter.ArmoBEURL=$ArmoBEServer -X github.com/armosec/kubescape/cautils/getter.ArmoERURL=$ArmoERServer -X github.com/armosec/kubescape/cautils/getter.ArmoFEURL=$ArmoWebsite" -o build/${{ matrix.os }}/kubescape # && md5sum build/${{ matrix.os }}/kubescape > build/${{ matrix.os }}/kubescape.md5 - name: Upload Release binaries id: upload-release-asset diff --git a/cautils/customerloader.go b/cautils/customerloader.go index 053217c7..5cc4097d 100644 --- a/cautils/customerloader.go +++ b/cautils/customerloader.go @@ -23,7 +23,7 @@ const ( type ConfigObj struct { CustomerGUID string `json:"customerGUID"` - Token string `json:"token"` + Token string `json:"invitationParam"` CustomerAdminEMail string `json:"adminMail"` } @@ -81,6 +81,9 @@ func (c *ClusterConfig) GenerateURL() { u := url.URL{} u.Scheme = "https" u.Host = getter.ArmoFEURL + if c.configObj == nil { + return + } if c.configObj.CustomerAdminEMail != "" { msgStr := fmt.Sprintf("To view all controls and get remediations ask access permissions to %s from %s", u.String(), c.configObj.CustomerAdminEMail) InfoTextDisplay(os.Stdout, msgStr+"\n") @@ -103,6 +106,48 @@ func (c *ClusterConfig) GetCustomerGUID() string { } return "" } + +func (c *ClusterConfig) GetValueByKeyFromConfigMap(key string) (string, error) { + + configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Get(context.Background(), configMapName, metav1.GetOptions{}) + + if err != nil { + return "", err + } + if val, ok := configMap.Data[key]; ok { + return val, nil + } else { + return "", fmt.Errorf("value does not exist.") + } + +} + +func (c *ClusterConfig) SetKeyValueInConfigmap(key string, value string) error { + + 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, + }, + } + } + + if len(configMap.Data) == 0 { + configMap.Data = make(map[string]string) + } + + configMap.Data[key] = value + + 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{}) + } + + return err +} + func (c *ClusterConfig) SetCustomerGUID() error { // get from configMap diff --git a/cautils/getter/armoapi.go b/cautils/getter/armoapi.go index 4b239e29..dd06be4c 100644 --- a/cautils/getter/armoapi.go +++ b/cautils/getter/armoapi.go @@ -13,6 +13,8 @@ import ( // ======================================================================================================================= var ( + // ATTENTION!!! + // Changes in this URLs variable names, or in the usage is affecting the build process! BE CAREFULL ArmoBEURL = "eggdashbe.eudev3.cyberarmorsoft.com" ArmoERURL = "report.eudev3.cyberarmorsoft.com" ArmoFEURL = "armoui.eudev3.cyberarmorsoft.com" diff --git a/cautils/scaninfo.go b/cautils/scaninfo.go index 2bb23564..d9e3cd7a 100644 --- a/cautils/scaninfo.go +++ b/cautils/scaninfo.go @@ -2,6 +2,7 @@ package cautils import ( "path/filepath" + "strings" "github.com/armosec/kubescape/cautils/getter" "github.com/armosec/kubescape/cautils/opapolicy" @@ -67,7 +68,7 @@ func (scanInfo *ScanInfo) setOutputFile() { return } if scanInfo.Format == "json" { - if filepath.Ext(scanInfo.Output) != "json" { + if filepath.Ext(scanInfo.Output) != "json" && !strings.HasSuffix(scanInfo.Output, ".json") { scanInfo.Output += ".json" } } diff --git a/cmd/cluster.go b/cmd/cluster.go new file mode 100644 index 00000000..e81ec7d0 --- /dev/null +++ b/cmd/cluster.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "github.com/spf13/cobra" +) + +// clusterCmd represents the cluster command +var clusterCmd = &cobra.Command{ + Use: "cluster", + Short: "Set configuration for cluster", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + }, +} + +func init() { + configCmd.AddCommand(clusterCmd) +} diff --git a/cmd/config.go b/cmd/config.go new file mode 100644 index 00000000..9b4e4d4a --- /dev/null +++ b/cmd/config.go @@ -0,0 +1,19 @@ +package cmd + +import ( + "github.com/spf13/cobra" +) + +// configCmd represents the config command +var configCmd = &cobra.Command{ + Use: "config", + Short: "Set configuration", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + + }, +} + +func init() { + rootCmd.AddCommand(configCmd) +} diff --git a/cmd/get.go b/cmd/get.go new file mode 100644 index 00000000..83915524 --- /dev/null +++ b/cmd/get.go @@ -0,0 +1,50 @@ +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" +) + +var getCmd = &cobra.Command{ + Use: "get ", + Short: "Get configuration in cluster", + Long: ``, + ValidArgs: supportedFrameworks, + 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() { + clusterCmd.AddCommand(getCmd) +} diff --git a/cmd/set.go b/cmd/set.go new file mode 100644 index 00000000..c464c490 --- /dev/null +++ b/cmd/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" +) + +var setCmd = &cobra.Command{ + Use: "set =", + Short: "Set configuration in cluster", + Long: ``, + ValidArgs: supportedFrameworks, + 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.SetKeyValueInConfigmap(key, data); err != nil { + return err + } + fmt.Println("Value added successfully.") + return nil + }, +} + +func init() { + clusterCmd.AddCommand(setCmd) +}