From 4a757c1bf1abb04ecf7e5e42e29aeb9decca4a85 Mon Sep 17 00:00:00 2001 From: David Wertenteil Date: Wed, 25 May 2022 17:26:12 +0300 Subject: [PATCH 1/3] adding logs --- .../handlerequests/v1/datastructuremethods_test.go | 11 +++++++++++ httphandler/handlerequests/v1/prometheus.go | 6 +++++- httphandler/handlerequests/v1/requestshandler.go | 8 ++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/httphandler/handlerequests/v1/datastructuremethods_test.go b/httphandler/handlerequests/v1/datastructuremethods_test.go index 747c2854..6d9403d3 100644 --- a/httphandler/handlerequests/v1/datastructuremethods_test.go +++ b/httphandler/handlerequests/v1/datastructuremethods_test.go @@ -72,6 +72,17 @@ func TestSetTargetInScanInfo(t *testing.T) { assert.True(t, scanInfo.ScanAll) assert.Equal(t, 0, len(scanInfo.PolicyIdentifier)) } + { + req := &utilsmetav1.PostScanRequest{ + TargetType: apisv1.KindFramework, + TargetNames: []string{}, + } + scanInfo := &cautils.ScanInfo{} + setTargetInScanInfo(req, scanInfo) + assert.True(t, scanInfo.FrameworkScan) + assert.True(t, scanInfo.ScanAll) + assert.Equal(t, 0, len(scanInfo.PolicyIdentifier)) + } { req := &utilsmetav1.PostScanRequest{ TargetType: apisv1.KindFramework, diff --git a/httphandler/handlerequests/v1/prometheus.go b/httphandler/handlerequests/v1/prometheus.go index 1ab250a3..250da843 100644 --- a/httphandler/handlerequests/v1/prometheus.go +++ b/httphandler/handlerequests/v1/prometheus.go @@ -7,6 +7,8 @@ import ( "path/filepath" "github.com/armosec/kubescape/v2/core/cautils" + "github.com/armosec/kubescape/v2/core/cautils/logger" + "github.com/armosec/kubescape/v2/core/cautils/logger/helpers" utilsapisv1 "github.com/armosec/opa-utils/httpserver/apis/v1" "github.com/google/uuid" ) @@ -34,6 +36,7 @@ func (handler *HTTPHandler) Metrics(w http.ResponseWriter, r *http.Request) { defer handler.scanResponseChan.delete(scanID) // send to scan queue + logger.L().Info("requesting scan", helpers.String("scanID", scanID), helpers.String("api", "v1/metrics")) handler.scanRequestChan <- scanParams // wait for scan to complete @@ -64,7 +67,8 @@ func (handler *HTTPHandler) Metrics(w http.ResponseWriter, r *http.Request) { func getPrometheusDefaultScanCommand(scanID, resultsFile string) *cautils.ScanInfo { scanInfo := defaultScanInfo() - scanInfo.Local = true // do not submit results every scan + scanInfo.Submit = false // do not submit results every scan + scanInfo.Local = true // do not submit results every scan scanInfo.FrameworkScan = true scanInfo.ScanAll = true // scan all frameworks scanInfo.ScanID = scanID // scan ID diff --git a/httphandler/handlerequests/v1/requestshandler.go b/httphandler/handlerequests/v1/requestshandler.go index a69eefcc..6233a30c 100644 --- a/httphandler/handlerequests/v1/requestshandler.go +++ b/httphandler/handlerequests/v1/requestshandler.go @@ -48,12 +48,16 @@ func (handler *HTTPHandler) Status(w http.ResponseWriter, r *http.Request) { statusQueryParams := &StatusQueryParams{} if err := schema.NewDecoder().Decode(statusQueryParams, r.URL.Query()); err != nil { + w.WriteHeader(http.StatusInternalServerError) handler.writeError(w, fmt.Errorf("failed to parse query params, reason: %s", err.Error()), "") return } + logger.L().Info("requesting status", helpers.String("scanID", statusQueryParams.ScanID), helpers.String("api", "v1/status")) + w.WriteHeader(http.StatusOK) if !handler.state.isBusy(statusQueryParams.ScanID) { response.Type = utilsapisv1.NotBusyScanResponseType + logger.L().Debug("status: not busy", helpers.String("ID", statusQueryParams.ScanID)) w.Write(responseToBytes(&response)) return } @@ -65,6 +69,8 @@ func (handler *HTTPHandler) Status(w http.ResponseWriter, r *http.Request) { response.Response = statusQueryParams.ScanID response.ID = statusQueryParams.ScanID response.Type = utilsapisv1.BusyScanResponseType + + logger.L().Debug("status: busy", helpers.String("ID", statusQueryParams.ScanID)) w.Write(responseToBytes(&response)) } @@ -102,6 +108,7 @@ func (handler *HTTPHandler) Scan(w http.ResponseWriter, r *http.Request) { // you must use a goroutine since the executeScan function is not always listening to the channel go func() { // send to scanning handler + logger.L().Info("requesting scan", helpers.String("scanID", scanID), helpers.String("api", "v1/scan")) handler.scanRequestChan <- scanRequestParams }() @@ -141,6 +148,7 @@ func (handler *HTTPHandler) Results(w http.ResponseWriter, r *http.Request) { handler.writeError(w, fmt.Errorf("failed to parse query params, reason: %s", err.Error()), "") return } + logger.L().Info("requesting results", helpers.String("scanID", resultsQueryParams.ScanID), helpers.String("api", "v1/results"), helpers.String("method", r.Method)) if resultsQueryParams.ScanID == "" { resultsQueryParams.ScanID = handler.state.getLatestID() From 046ea1d79f2adf44aeb2ac34ba0030beb0016ba1 Mon Sep 17 00:00:00 2001 From: David Wertenteil Date: Thu, 26 May 2022 11:01:26 +0300 Subject: [PATCH 2/3] support secret key and account ID from cmd --- cmd/delete/delete.go | 4 +- cmd/delete/exceptions.go | 2 +- cmd/download/download.go | 5 +- cmd/list/list.go | 4 +- cmd/root.go | 3 +- cmd/scan/scan.go | 4 +- cmd/submit/exceptions.go | 2 +- cmd/submit/rbac.go | 8 +-- cmd/submit/results.go | 2 +- cmd/submit/submit.go | 4 +- core/cautils/customerloader.go | 49 ++++++++++++------- core/cautils/rootinfo.go | 7 +++ core/cautils/scaninfo.go | 2 +- core/core/cachedconfig.go | 6 +-- core/core/delete.go | 2 +- core/core/download.go | 8 +-- core/core/initutils.go | 6 +-- core/core/list.go | 6 +-- core/core/scan.go | 2 +- core/core/submit.go | 4 +- core/meta/datastructures/v1/delete.go | 6 ++- core/meta/datastructures/v1/download.go | 12 +++-- core/meta/datastructures/v1/listpolicies.go | 10 ++-- core/meta/datastructures/v1/submit.go | 6 ++- core/meta/ksinterface.go | 4 +- .../armosec/v1/civarmoadaptor.go | 3 +- core/pkg/resourcehandler/k8sresources.go | 8 +-- core/pkg/resourcehandler/registrydata.go | 8 +-- httphandler/go.mod | 2 +- httphandler/go.sum | 2 - .../handlerequests/v1/datastructuremethods.go | 2 +- .../v1/datastructuremethods_test.go | 2 +- .../handlerequests/v1/requestparser_test.go | 4 +- .../v1/requestshandlerutil_test.go | 4 +- .../handlerequests/v1/requestshandlerutils.go | 2 +- 35 files changed, 123 insertions(+), 82 deletions(-) diff --git a/cmd/delete/delete.go b/cmd/delete/delete.go index 9895376d..6512b459 100644 --- a/cmd/delete/delete.go +++ b/cmd/delete/delete.go @@ -24,7 +24,9 @@ func GetDeleteCmd(ks meta.IKubescape) *cobra.Command { Run: func(cmd *cobra.Command, args []string) { }, } - deleteCmd.PersistentFlags().StringVarP(&deleteInfo.Account, "account", "", "", "Armo portal account ID. Default will load account ID from configMap or config file") + deleteCmd.PersistentFlags().StringVarP(&deleteInfo.Credentials.Account, "account", "", "", "Kubescape SaaS account ID. Default will load account ID from cache") + deleteCmd.PersistentFlags().StringVarP(&deleteInfo.Credentials.ClientID, "client-id", "", "", "Kubescape SaaS client ID. Default will load client ID from cache, read more - https://hub.armo.cloud/docs/authentication") + deleteCmd.PersistentFlags().StringVarP(&deleteInfo.Credentials.SecretKey, "secret-key", "", "", "Kubescape SaaS secret key. Default will load secret key from cache, read more - https://hub.armo.cloud/docs/authentication") deleteCmd.AddCommand(getExceptionsCmd(ks, &deleteInfo)) diff --git a/cmd/delete/exceptions.go b/cmd/delete/exceptions.go index 6b9bfcfb..c75a9ff6 100644 --- a/cmd/delete/exceptions.go +++ b/cmd/delete/exceptions.go @@ -26,7 +26,7 @@ func getExceptionsCmd(ks meta.IKubescape, deleteInfo *v1.Delete) *cobra.Command if len(exceptionsNames) == 0 { logger.L().Fatal("missing exceptions names") } - if err := ks.DeleteExceptions(&v1.DeleteExceptions{Account: deleteInfo.Account, Exceptions: exceptionsNames}); err != nil { + if err := ks.DeleteExceptions(&v1.DeleteExceptions{Credentials: deleteInfo.Credentials, Exceptions: exceptionsNames}); err != nil { logger.L().Fatal(err.Error()) } }, diff --git a/cmd/download/download.go b/cmd/download/download.go index 360ac0c2..7411899d 100644 --- a/cmd/download/download.go +++ b/cmd/download/download.go @@ -72,7 +72,10 @@ func GeDownloadCmd(ks meta.IKubescape) *cobra.Command { return nil }, } - downloadCmd.PersistentFlags().StringVarP(&downloadInfo.Account, "account", "", "", "Armo portal account ID. Default will load account ID from configMap or config file") + + downloadCmd.PersistentFlags().StringVarP(&downloadInfo.Credentials.Account, "account", "", "", "Kubescape SaaS account ID. Default will load account ID from cache") + downloadCmd.PersistentFlags().StringVarP(&downloadInfo.Credentials.ClientID, "client-id", "", "", "Kubescape SaaS client ID. Default will load client ID from cache, read more - https://hub.armo.cloud/docs/authentication") + downloadCmd.PersistentFlags().StringVarP(&downloadInfo.Credentials.SecretKey, "secret-key", "", "", "Kubescape SaaS secret key. Default will load secret key from cache, read more - https://hub.armo.cloud/docs/authentication") downloadCmd.Flags().StringVarP(&downloadInfo.Path, "output", "o", "", "Output file. If not specified, will save in `~/.kubescape/.json`") return downloadCmd diff --git a/cmd/list/list.go b/cmd/list/list.go index 4f1518c3..a4b89734 100644 --- a/cmd/list/list.go +++ b/cmd/list/list.go @@ -59,7 +59,9 @@ func GetListCmd(ks meta.IKubescape) *cobra.Command { return nil }, } - listCmd.PersistentFlags().StringVar(&listPolicies.Account, "account", "", "Armo portal account ID. Default will load account ID from configMap or config file") + listCmd.PersistentFlags().StringVarP(&listPolicies.Credentials.Account, "account", "", "", "Kubescape SaaS account ID. Default will load account ID from cache") + listCmd.PersistentFlags().StringVarP(&listPolicies.Credentials.ClientID, "client-id", "", "", "Kubescape SaaS client ID. Default will load client ID from cache, read more - https://hub.armo.cloud/docs/authentication") + listCmd.PersistentFlags().StringVarP(&listPolicies.Credentials.SecretKey, "secret-key", "", "", "Kubescape SaaS secret key. Default will load secret key from cache, read more - https://hub.armo.cloud/docs/authentication") listCmd.PersistentFlags().StringVar(&listPolicies.Format, "format", "pretty-print", "output format. supported: 'pretty-printer'/'json'") listCmd.PersistentFlags().BoolVarP(&listPolicies.ListIDs, "id", "", false, "List control ID's instead of controls names") diff --git a/cmd/root.go b/cmd/root.go index bb22535f..b90e45e2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -48,8 +48,7 @@ func getRootCmd(ks meta.IKubescape) *cobra.Command { rootCmd := &cobra.Command{ Use: "kubescape", Version: cautils.BuildNumber, - Short: "Kubescape is a tool for testing Kubernetes security posture", - Long: `Based on NSA \ MITRE ATT&CKĀ® and other frameworks specifications`, + Short: "Kubescape is a tool for testing Kubernetes security posture. Docs: https://hub.armo.cloud/docs", Example: ksExamples, } diff --git a/cmd/scan/scan.go b/cmd/scan/scan.go index 20398892..feaa0142 100644 --- a/cmd/scan/scan.go +++ b/cmd/scan/scan.go @@ -63,7 +63,9 @@ func GetScanCommand(ks meta.IKubescape) *cobra.Command { }, } - scanCmd.PersistentFlags().StringVarP(&scanInfo.Account, "account", "", "", "ARMO portal account ID. Default will load account ID from configMap or config file") + scanCmd.PersistentFlags().StringVarP(&scanInfo.Credentials.Account, "account", "", "", "Kubescape SaaS account ID. Default will load account ID from cache") + scanCmd.PersistentFlags().StringVarP(&scanInfo.Credentials.ClientID, "client-id", "", "", "Kubescape SaaS client ID. Default will load client ID from cache, read more - https://hub.armo.cloud/docs/authentication") + scanCmd.PersistentFlags().StringVarP(&scanInfo.Credentials.SecretKey, "secret-key", "", "", "Kubescape SaaS secret key. Default will load secret key from cache, read more - https://hub.armo.cloud/docs/authentication") 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") diff --git a/cmd/submit/exceptions.go b/cmd/submit/exceptions.go index 171443c3..b54073bd 100644 --- a/cmd/submit/exceptions.go +++ b/cmd/submit/exceptions.go @@ -21,7 +21,7 @@ func getExceptionsCmd(ks meta.IKubescape, submitInfo *metav1.Submit) *cobra.Comm return nil }, Run: func(cmd *cobra.Command, args []string) { - if err := ks.SubmitExceptions(submitInfo.Account, args[0]); err != nil { + if err := ks.SubmitExceptions(&submitInfo.Credentials, args[0]); err != nil { logger.L().Fatal(err.Error()) } }, diff --git a/cmd/submit/rbac.go b/cmd/submit/rbac.go index f529f039..e5d17f76 100644 --- a/cmd/submit/rbac.go +++ b/cmd/submit/rbac.go @@ -27,7 +27,7 @@ func getRBACCmd(ks meta.IKubescape, submitInfo *v1.Submit) *cobra.Command { k8s := k8sinterface.NewKubernetesApi() // get config - clusterConfig := getTenantConfig(submitInfo.Account, "", k8s) + clusterConfig := getTenantConfig(&submitInfo.Credentials, "", k8s) if err := clusterConfig.SetTenant(); err != nil { logger.L().Error("failed setting account ID", helpers.Error(err)) } @@ -60,9 +60,9 @@ func getKubernetesApi() *k8sinterface.KubernetesApi { } return k8sinterface.NewKubernetesApi() } -func getTenantConfig(Account, clusterName string, k8s *k8sinterface.KubernetesApi) cautils.ITenantConfig { +func getTenantConfig(credentials *cautils.Credentials, clusterName string, k8s *k8sinterface.KubernetesApi) cautils.ITenantConfig { if !k8sinterface.IsConnectedToCluster() || k8s == nil { - return cautils.NewLocalConfig(getter.GetArmoAPIConnector(), Account, clusterName) + return cautils.NewLocalConfig(getter.GetArmoAPIConnector(), credentials, clusterName) } - return cautils.NewClusterConfig(k8s, getter.GetArmoAPIConnector(), Account, clusterName) + return cautils.NewClusterConfig(k8s, getter.GetArmoAPIConnector(), credentials, clusterName) } diff --git a/cmd/submit/results.go b/cmd/submit/results.go index 89480ca4..47c587f3 100644 --- a/cmd/submit/results.go +++ b/cmd/submit/results.go @@ -69,7 +69,7 @@ func getResultsCmd(ks meta.IKubescape, submitInfo *v1.Submit) *cobra.Command { k8s := getKubernetesApi() // get config - clusterConfig := getTenantConfig(submitInfo.Account, "", k8s) + clusterConfig := getTenantConfig(&submitInfo.Credentials, "", k8s) if err := clusterConfig.SetTenant(); err != nil { logger.L().Error("failed setting account ID", helpers.Error(err)) } diff --git a/cmd/submit/submit.go b/cmd/submit/submit.go index 7c767fba..f06c96f5 100644 --- a/cmd/submit/submit.go +++ b/cmd/submit/submit.go @@ -20,7 +20,9 @@ func GetSubmitCmd(ks meta.IKubescape) *cobra.Command { Run: func(cmd *cobra.Command, args []string) { }, } - submitCmd.PersistentFlags().StringVarP(&submitInfo.Account, "account", "", "", "Armo portal account ID. Default will load account ID from configMap or config file") + submitCmd.PersistentFlags().StringVarP(&submitInfo.Credentials.Account, "account", "", "", "Kubescape SaaS account ID. Default will load account ID from cache") + submitCmd.PersistentFlags().StringVarP(&submitInfo.Credentials.ClientID, "client-id", "", "", "Kubescape SaaS client ID. Default will load client ID from cache, read more - https://hub.armo.cloud/docs/authentication") + submitCmd.PersistentFlags().StringVarP(&submitInfo.Credentials.SecretKey, "secret-key", "", "", "Kubescape SaaS secret key. Default will load secret key from cache, read more - https://hub.armo.cloud/docs/authentication") submitCmd.AddCommand(getExceptionsCmd(ks, &submitInfo)) submitCmd.AddCommand(getResultsCmd(ks, &submitInfo)) diff --git a/core/cautils/customerloader.go b/core/cautils/customerloader.go index aa4e51f8..d6eb4b60 100644 --- a/core/cautils/customerloader.go +++ b/core/cautils/customerloader.go @@ -90,7 +90,7 @@ type LocalConfig struct { } func NewLocalConfig( - backendAPI getter.IBackend, customerGUID, clusterName string) *LocalConfig { + backendAPI getter.IBackend, credentials *Credentials, clusterName string) *LocalConfig { lc := &LocalConfig{ backendAPI: backendAPI, @@ -101,13 +101,11 @@ func NewLocalConfig( loadConfigFromFile(lc.configObj) } - if customerGUID != "" { - lc.configObj.AccountID = customerGUID // override config customerGUID - } + updateCredentials(lc.configObj, credentials) + if clusterName != "" { lc.configObj.ClusterName = AdoptClusterName(clusterName) // override config clusterName } - getAccountFromEnv(lc.configObj) lc.backendAPI.SetAccountID(lc.configObj.AccountID) lc.backendAPI.SetClientID(lc.configObj.ClientID) @@ -191,7 +189,7 @@ type ClusterConfig struct { configObj *ConfigObj } -func NewClusterConfig(k8s *k8sinterface.KubernetesApi, backendAPI getter.IBackend, customerGUID, clusterName string) *ClusterConfig { +func NewClusterConfig(k8s *k8sinterface.KubernetesApi, backendAPI getter.IBackend, credentials *Credentials, clusterName string) *ClusterConfig { // var configObj *ConfigObj c := &ClusterConfig{ k8s: k8s, @@ -210,13 +208,11 @@ func NewClusterConfig(k8s *k8sinterface.KubernetesApi, backendAPI getter.IBacken if existsConfigFile() { // get from file loadConfigFromFile(c.configObj) } - if customerGUID != "" { - c.configObj.AccountID = customerGUID // override config customerGUID - } + updateCredentials(c.configObj, credentials) + if clusterName != "" { c.configObj.ClusterName = AdoptClusterName(clusterName) // override config clusterName } - getAccountFromEnv(c.configObj) if c.configObj.ClusterName == "" { c.configObj.ClusterName = AdoptClusterName(k8sinterface.GetContextName()) @@ -489,15 +485,34 @@ func getConfigMapNamespace() string { return "default" } -func getAccountFromEnv(configObj *ConfigObj) { +func getAccountFromEnv(credentials *Credentials) { // load from env - if accountID := os.Getenv("KS_ACCOUNT_ID"); accountID != "" { - configObj.AccountID = accountID + if accountID := os.Getenv("KS_ACCOUNT_ID"); credentials.Account != "" && accountID != "" { + credentials.Account = accountID } - if clientID := os.Getenv("KS_CLIENT_ID"); clientID != "" { - configObj.ClientID = clientID + if clientID := os.Getenv("KS_CLIENT_ID"); credentials.ClientID != "" && clientID != "" { + credentials.ClientID = clientID } - if secretKey := os.Getenv("KS_SECRET_KEY"); secretKey != "" { - configObj.SecretKey = secretKey + if secretKey := os.Getenv("KS_SECRET_KEY"); credentials.SecretKey != "" && secretKey != "" { + credentials.SecretKey = secretKey } } + +func updateCredentials(configObj *ConfigObj, credentials *Credentials) { + + if credentials == nil { + credentials = &Credentials{} + } + getAccountFromEnv(credentials) + + if credentials.Account != "" { + configObj.AccountID = credentials.Account // override config Account + } + if credentials.ClientID != "" { + configObj.ClientID = credentials.ClientID // override config ClientID + } + if credentials.SecretKey != "" { + configObj.SecretKey = credentials.SecretKey // override config SecretKey + } + +} diff --git a/core/cautils/rootinfo.go b/core/cautils/rootinfo.go index 1c5fcba4..dc70e560 100644 --- a/core/cautils/rootinfo.go +++ b/core/cautils/rootinfo.go @@ -8,6 +8,13 @@ type RootInfo struct { ArmoBEURLs string // armo url ArmoBEURLsDep string // armo url + +} + +type Credentials struct { + Account string + ClientID string + SecretKey string } // func (rootInfo *RootInfo) InitLogger() { diff --git a/core/cautils/scaninfo.go b/core/cautils/scaninfo.go index 3b3cc45a..4a5c24fb 100644 --- a/core/cautils/scaninfo.go +++ b/core/cautils/scaninfo.go @@ -107,7 +107,7 @@ type ScanInfo struct { HostSensorEnabled BoolPtrFlag // Deploy ARMO K8s host scanner to collect data from certain controls HostSensorYamlPath string // Path to hostsensor file Local bool // Do not submit results - Account string // account ID + Credentials Credentials // account ID KubeContext string // context name FrameworkScan bool // false if scanning control ScanAll bool // true if scan all frameworks diff --git a/core/core/cachedconfig.go b/core/core/cachedconfig.go index 569cedc9..7d0bebc4 100644 --- a/core/core/cachedconfig.go +++ b/core/core/cachedconfig.go @@ -8,7 +8,7 @@ import ( func (ks *Kubescape) SetCachedConfig(setConfig *metav1.SetConfig) error { - tenant := getTenantConfig("", "", getKubernetesApi()) + tenant := getTenantConfig(nil, "", getKubernetesApi()) if setConfig.Account != "" { tenant.GetConfigObj().AccountID = setConfig.Account @@ -25,13 +25,13 @@ func (ks *Kubescape) SetCachedConfig(setConfig *metav1.SetConfig) error { // View cached configurations func (ks *Kubescape) ViewCachedConfig(viewConfig *metav1.ViewConfig) error { - tenant := getTenantConfig("", "", getKubernetesApi()) // change k8sinterface + tenant := getTenantConfig(nil, "", getKubernetesApi()) // change k8sinterface fmt.Fprintf(viewConfig.Writer, "%s\n", tenant.GetConfigObj().Config()) return nil } func (ks *Kubescape) DeleteCachedConfig(deleteConfig *metav1.DeleteConfig) error { - tenant := getTenantConfig("", "", getKubernetesApi()) // change k8sinterface + tenant := getTenantConfig(nil, "", getKubernetesApi()) // change k8sinterface return tenant.DeleteCachedConfig() } diff --git a/core/core/delete.go b/core/core/delete.go index 93c24aaf..0b055133 100644 --- a/core/core/delete.go +++ b/core/core/delete.go @@ -12,7 +12,7 @@ import ( func (ks *Kubescape) DeleteExceptions(delExceptions *v1.DeleteExceptions) error { // load cached config - getTenantConfig(delExceptions.Account, "", getKubernetesApi()) + getTenantConfig(&delExceptions.Credentials, "", getKubernetesApi()) // login kubescape SaaS armoAPI := getter.GetArmoAPIConnector() diff --git a/core/core/download.go b/core/core/download.go index 1704d019..90826fcb 100644 --- a/core/core/download.go +++ b/core/core/download.go @@ -80,7 +80,7 @@ func downloadArtifacts(downloadInfo *metav1.DownloadInfo) error { } func downloadConfigInputs(downloadInfo *metav1.DownloadInfo) error { - tenant := getTenantConfig(downloadInfo.Account, "", getKubernetesApi()) + tenant := getTenantConfig(&downloadInfo.Credentials, "", getKubernetesApi()) controlsInputsGetter := getConfigInputsGetter(downloadInfo.Name, tenant.GetAccountID(), nil) controlInputs, err := controlsInputsGetter.GetControlsInputs(tenant.GetContextName()) @@ -104,7 +104,7 @@ func downloadConfigInputs(downloadInfo *metav1.DownloadInfo) error { func downloadExceptions(downloadInfo *metav1.DownloadInfo) error { var err error - tenant := getTenantConfig(downloadInfo.Account, "", getKubernetesApi()) + tenant := getTenantConfig(&downloadInfo.Credentials, "", getKubernetesApi()) exceptionsGetter := getExceptionsGetter("") exceptions := []armotypes.PostureExceptionPolicy{} @@ -128,7 +128,7 @@ func downloadExceptions(downloadInfo *metav1.DownloadInfo) error { func downloadFramework(downloadInfo *metav1.DownloadInfo) error { - tenant := getTenantConfig(downloadInfo.Account, "", getKubernetesApi()) + tenant := getTenantConfig(&downloadInfo.Credentials, "", getKubernetesApi()) g := getPolicyGetter(nil, tenant.GetTenantEmail(), true, nil) @@ -170,7 +170,7 @@ func downloadFramework(downloadInfo *metav1.DownloadInfo) error { func downloadControl(downloadInfo *metav1.DownloadInfo) error { - tenant := getTenantConfig(downloadInfo.Account, "", getKubernetesApi()) + tenant := getTenantConfig(&downloadInfo.Credentials, "", getKubernetesApi()) g := getPolicyGetter(nil, tenant.GetTenantEmail(), false, nil) diff --git a/core/core/initutils.go b/core/core/initutils.go index 41b6f0e1..433f4b20 100644 --- a/core/core/initutils.go +++ b/core/core/initutils.go @@ -23,11 +23,11 @@ func getKubernetesApi() *k8sinterface.KubernetesApi { } return k8sinterface.NewKubernetesApi() } -func getTenantConfig(Account, clusterName string, k8s *k8sinterface.KubernetesApi) cautils.ITenantConfig { +func getTenantConfig(credentials *cautils.Credentials, clusterName string, k8s *k8sinterface.KubernetesApi) cautils.ITenantConfig { if !k8sinterface.IsConnectedToCluster() || k8s == nil { - return cautils.NewLocalConfig(getter.GetArmoAPIConnector(), Account, clusterName) + return cautils.NewLocalConfig(getter.GetArmoAPIConnector(), credentials, clusterName) } - return cautils.NewClusterConfig(k8s, getter.GetArmoAPIConnector(), Account, clusterName) + return cautils.NewClusterConfig(k8s, getter.GetArmoAPIConnector(), credentials, clusterName) } func getExceptionsGetter(useExceptions string) getter.IExceptionsGetter { diff --git a/core/core/list.go b/core/core/list.go index 4259a6b9..0f357bc3 100644 --- a/core/core/list.go +++ b/core/core/list.go @@ -44,14 +44,14 @@ func (ks *Kubescape) List(listPolicies *metav1.ListPolicies) error { } func listFrameworks(listPolicies *metav1.ListPolicies) ([]string, error) { - tenant := getTenantConfig(listPolicies.Account, "", getKubernetesApi()) // change k8sinterface + tenant := getTenantConfig(&listPolicies.Credentials, "", getKubernetesApi()) // change k8sinterface g := getPolicyGetter(nil, tenant.GetTenantEmail(), true, nil) return listFrameworksNames(g), nil } func listControls(listPolicies *metav1.ListPolicies) ([]string, error) { - tenant := getTenantConfig(listPolicies.Account, "", getKubernetesApi()) // change k8sinterface + tenant := getTenantConfig(&listPolicies.Credentials, "", getKubernetesApi()) // change k8sinterface g := getPolicyGetter(nil, tenant.GetTenantEmail(), false, nil) l := getter.ListName @@ -63,7 +63,7 @@ func listControls(listPolicies *metav1.ListPolicies) ([]string, error) { func listExceptions(listPolicies *metav1.ListPolicies) ([]string, error) { // load tenant metav1 - getTenantConfig(listPolicies.Account, "", getKubernetesApi()) + getTenantConfig(&listPolicies.Credentials, "", getKubernetesApi()) var exceptionsNames []string armoAPI := getExceptionsGetter("") diff --git a/core/core/scan.go b/core/core/scan.go index 7fd93b7a..1bb640b9 100644 --- a/core/core/scan.go +++ b/core/core/scan.go @@ -43,7 +43,7 @@ func getInterfaces(scanInfo *cautils.ScanInfo) componentInterfaces { // ================== setup tenant object ====================================== - tenantConfig := getTenantConfig(scanInfo.Account, scanInfo.KubeContext, k8s) + tenantConfig := getTenantConfig(&scanInfo.Credentials, scanInfo.KubeContext, k8s) // Set submit behavior AFTER loading tenant config setSubmitBehavior(scanInfo, tenantConfig) diff --git a/core/core/submit.go b/core/core/submit.go index e2737dcc..db28b8be 100644 --- a/core/core/submit.go +++ b/core/core/submit.go @@ -29,11 +29,11 @@ func (ks *Kubescape) Submit(submitInterfaces cliinterfaces.SubmitInterfaces) err return nil } -func (ks *Kubescape) SubmitExceptions(accountID, excPath string) error { +func (ks *Kubescape) SubmitExceptions(credentials *cautils.Credentials, excPath string) error { logger.L().Info("submitting exceptions", helpers.String("path", excPath)) // load cached config - tenantConfig := getTenantConfig(accountID, "", getKubernetesApi()) + tenantConfig := getTenantConfig(credentials, "", getKubernetesApi()) if err := tenantConfig.SetTenant(); err != nil { logger.L().Error("failed setting account ID", helpers.Error(err)) } diff --git a/core/meta/datastructures/v1/delete.go b/core/meta/datastructures/v1/delete.go index ca57c332..68d1ac30 100644 --- a/core/meta/datastructures/v1/delete.go +++ b/core/meta/datastructures/v1/delete.go @@ -1,6 +1,8 @@ package v1 +import "github.com/armosec/kubescape/v2/core/cautils" + type DeleteExceptions struct { - Account string - Exceptions []string + Credentials cautils.Credentials + Exceptions []string } diff --git a/core/meta/datastructures/v1/download.go b/core/meta/datastructures/v1/download.go index 44af9648..10de6d8a 100644 --- a/core/meta/datastructures/v1/download.go +++ b/core/meta/datastructures/v1/download.go @@ -1,9 +1,11 @@ package v1 +import "github.com/armosec/kubescape/v2/core/cautils" + type DownloadInfo struct { - Path string // directory to save artifact. Default is "~/.kubescape/" - FileName string // can be empty - Target string // type of artifact to download - Name string // name of artifact to download - Account string // AccountID + Path string // directory to save artifact. Default is "~/.kubescape/" + FileName string // can be empty + Target string // type of artifact to download + Name string // name of artifact to download + Credentials cautils.Credentials } diff --git a/core/meta/datastructures/v1/listpolicies.go b/core/meta/datastructures/v1/listpolicies.go index 6fefa59d..f3926a11 100644 --- a/core/meta/datastructures/v1/listpolicies.go +++ b/core/meta/datastructures/v1/listpolicies.go @@ -1,10 +1,12 @@ package v1 +import "github.com/armosec/kubescape/v2/core/cautils" + type ListPolicies struct { - Target string - ListIDs bool - Account string - Format string + Target string + ListIDs bool + Format string + Credentials cautils.Credentials } type ListResponse struct { diff --git a/core/meta/datastructures/v1/submit.go b/core/meta/datastructures/v1/submit.go index db124406..21794a06 100644 --- a/core/meta/datastructures/v1/submit.go +++ b/core/meta/datastructures/v1/submit.go @@ -1,9 +1,11 @@ package v1 +import "github.com/armosec/kubescape/v2/core/cautils" + type Submit struct { - Account string + Credentials cautils.Credentials } type Delete struct { - Account string + Credentials cautils.Credentials } diff --git a/core/meta/ksinterface.go b/core/meta/ksinterface.go index 68d9af21..bb4f4a5e 100644 --- a/core/meta/ksinterface.go +++ b/core/meta/ksinterface.go @@ -15,8 +15,8 @@ type IKubescape interface { Download(downloadInfo *metav1.DownloadInfo) error // TODO - return downloaded policies // submit - Submit(submitInterfaces cliinterfaces.SubmitInterfaces) error // TODO - func should receive object - SubmitExceptions(accountID, excPath string) error // TODO - remove + Submit(submitInterfaces cliinterfaces.SubmitInterfaces) error // TODO - func should receive object + SubmitExceptions(credentials *cautils.Credentials, excPath string) error // TODO - remove // config SetCachedConfig(setConfig *metav1.SetConfig) error diff --git a/core/pkg/registryadaptors/armosec/v1/civarmoadaptor.go b/core/pkg/registryadaptors/armosec/v1/civarmoadaptor.go index 06db0980..b8e67b1a 100644 --- a/core/pkg/registryadaptors/armosec/v1/civarmoadaptor.go +++ b/core/pkg/registryadaptors/armosec/v1/civarmoadaptor.go @@ -83,8 +83,7 @@ func (armoCivAdaptor *ArmoCivAdaptor) GetImageVulnerability(imageID *registryvul } func (armoCivAdaptor *ArmoCivAdaptor) DescribeAdaptor() string { - // TODO - return "" + return "armo image vulnerabilities scanner, docs: https://hub.armo.cloud/docs/cluster-vulnerability-scanning" } func (armoCivAdaptor *ArmoCivAdaptor) GetImagesInformation(imageIDs []registryvulnerabilities.ContainerImageIdentifier) ([]registryvulnerabilities.ContainerImageInformation, error) { diff --git a/core/pkg/resourcehandler/k8sresources.go b/core/pkg/resourcehandler/k8sresources.go index 55af92bc..0c125503 100644 --- a/core/pkg/resourcehandler/k8sresources.go +++ b/core/pkg/resourcehandler/k8sresources.go @@ -86,9 +86,11 @@ func (k8sHandler *K8sResourceHandler) GetResources(sessionObj *cautils.OPASessio if len(imgVulnResources) > 0 { if err := k8sHandler.registryAdaptors.collectImagesVulnerabilities(k8sResourcesMap, allResources, armoResourceMap); err != nil { logger.L().Warning("failed to collect image vulnerabilities", helpers.Error(err)) - } - if isEmptyImgVulns(*armoResourceMap) { - cautils.SetInfoMapForResources("image scanning is not configured. for more information: https://hub.armo.cloud/docs/cluster-vulnerability-scanning", imgVulnResources, sessionObj.InfoMap) + cautils.SetInfoMapForResources(fmt.Sprintf("failed to pull image scanning data: %s", err.Error()), imgVulnResources, sessionObj.InfoMap) + } else { + if isEmptyImgVulns(*armoResourceMap) { + cautils.SetInfoMapForResources("image scanning is not configured. for more information: https://hub.armo.cloud/docs/cluster-vulnerability-scanning", imgVulnResources, sessionObj.InfoMap) + } } } diff --git a/core/pkg/resourcehandler/registrydata.go b/core/pkg/resourcehandler/registrydata.go index 014ba5d2..2aadc770 100644 --- a/core/pkg/resourcehandler/registrydata.go +++ b/core/pkg/resourcehandler/registrydata.go @@ -1,12 +1,13 @@ package resourcehandler import ( + "fmt" + "github.com/armosec/k8s-interface/k8sinterface" "github.com/armosec/k8s-interface/workloadinterface" "github.com/armosec/kubescape/v2/core/cautils" "github.com/armosec/kubescape/v2/core/cautils/getter" "github.com/armosec/kubescape/v2/core/cautils/logger" - "github.com/armosec/kubescape/v2/core/cautils/logger/helpers" armosecadaptorv1 "github.com/armosec/kubescape/v2/core/pkg/registryadaptors/armosec/v1" "github.com/armosec/kubescape/v2/core/pkg/registryadaptors/registryvulnerabilities" @@ -45,8 +46,9 @@ func (registryAdaptors *RegistryAdaptors) collectImagesVulnerabilities(k8sResour for i := range registryAdaptors.adaptors { // login and and get vulnerabilities if err := registryAdaptors.adaptors[i].Login(); err != nil { - logger.L().Error("failed to login", helpers.Error(err)) - continue + if err != nil { + return fmt.Errorf("failed to login, adaptor: '%s', reason: '%s'", registryAdaptors.adaptors[i].DescribeAdaptor(), err.Error()) + } } vulnerabilities, err := registryAdaptors.adaptors[i].GetImagesVulnerabilities(imagesIdentifiers) if err != nil { diff --git a/httphandler/go.mod b/httphandler/go.mod index 33c69db5..be7b9854 100644 --- a/httphandler/go.mod +++ b/httphandler/go.mod @@ -12,6 +12,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/gorilla/schema v1.2.0 github.com/stretchr/testify v1.7.1 + k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 ) require ( @@ -129,7 +130,6 @@ require ( k8s.io/client-go v0.23.5 // indirect k8s.io/klog/v2 v2.30.0 // indirect k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect - k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect sigs.k8s.io/controller-runtime v0.11.1 // indirect sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect diff --git a/httphandler/go.sum b/httphandler/go.sum index 59151a8c..58df7881 100644 --- a/httphandler/go.sum +++ b/httphandler/go.sum @@ -119,11 +119,9 @@ github.com/armosec/go-git-url v0.0.4 h1:emG9Yfl53rHpuX41fXLD92ehzhRoNSSnGT6Pr7og github.com/armosec/go-git-url v0.0.4/go.mod h1:PJqdEyJyFxTQvawBcyOM0Ies6+uezire5gpwfr1XX5M= github.com/armosec/k8s-interface v0.0.8/go.mod h1:xxS+V5QT3gVQTwZyAMMDrYLWGrfKOpiJ7Jfhfa0w9sM= github.com/armosec/k8s-interface v0.0.37/go.mod h1:vHxGWqD/uh6+GQb9Sqv7OGMs+Rvc2dsFVc0XtgRh1ZU= -github.com/armosec/k8s-interface v0.0.70/go.mod h1:8NX4xWXh8mwW7QyZdZea1czNdM2azCK9BbUNmiZYXW0= github.com/armosec/k8s-interface v0.0.76 h1:pQaF+8BcNMm6GTYTjdG7vCM1l4BIk7oALXoT6v5gCAk= github.com/armosec/k8s-interface v0.0.76/go.mod h1:8NX4xWXh8mwW7QyZdZea1czNdM2azCK9BbUNmiZYXW0= github.com/armosec/opa-utils v0.0.64/go.mod h1:6tQP8UDq2EvEfSqh8vrUdr/9QVSCG4sJfju1SXQOn4c= -github.com/armosec/opa-utils v0.0.139/go.mod h1:VnRVJgDDPFAprGDcibTtKHf9wgkoyTU8wmX2BxEIwok= github.com/armosec/opa-utils v0.0.140 h1:iv6inb6+D0qgeVkv7f+ZIHpy239IUpAwg6Dau0JAWzg= github.com/armosec/opa-utils v0.0.140/go.mod h1:Hwm9ZkcW87mB2567WT6mBuSBEzaKowBNfrl3Q0IVsV8= github.com/armosec/rbac-utils v0.0.1/go.mod h1:pQ8CBiij8kSKV7aeZm9FMvtZN28VgA7LZcYyTWimq40= diff --git a/httphandler/handlerequests/v1/datastructuremethods.go b/httphandler/handlerequests/v1/datastructuremethods.go index 52d2c585..8eab9af3 100644 --- a/httphandler/handlerequests/v1/datastructuremethods.go +++ b/httphandler/handlerequests/v1/datastructuremethods.go @@ -17,7 +17,7 @@ func ToScanInfo(scanRequest *utilsmetav1.PostScanRequest) *cautils.ScanInfo { setTargetInScanInfo(scanRequest, scanInfo) if scanRequest.Account != "" { - scanInfo.Account = scanRequest.Account + scanInfo.Credentials.Account = scanRequest.Account } if len(scanRequest.ExcludedNamespaces) > 0 { scanInfo.ExcludedNamespaces = strings.Join(scanRequest.ExcludedNamespaces, ",") diff --git a/httphandler/handlerequests/v1/datastructuremethods_test.go b/httphandler/handlerequests/v1/datastructuremethods_test.go index 6d9403d3..10af3905 100644 --- a/httphandler/handlerequests/v1/datastructuremethods_test.go +++ b/httphandler/handlerequests/v1/datastructuremethods_test.go @@ -21,7 +21,7 @@ func TestToScanInfo(t *testing.T) { TargetNames: []string{"nsa", "mitre"}, } s := ToScanInfo(req) - assert.Equal(t, "abc", s.Account) + assert.Equal(t, "abc", s.Credentials.Account) assert.Equal(t, "v2", s.FormatVersion) assert.Equal(t, "pdf", s.Format) assert.Equal(t, 2, len(s.PolicyIdentifier)) diff --git a/httphandler/handlerequests/v1/requestparser_test.go b/httphandler/handlerequests/v1/requestparser_test.go index 7131e0f9..bae44f1e 100644 --- a/httphandler/handlerequests/v1/requestparser_test.go +++ b/httphandler/handlerequests/v1/requestparser_test.go @@ -41,7 +41,7 @@ func TestGetScanParamsFromRequest(t *testing.T) { assert.True(t, req.scanQueryParams.ReturnResults) assert.True(t, req.scanInfo.HostSensorEnabled.GetBool()) assert.True(t, req.scanInfo.Submit) - assert.Equal(t, "aaaaaaaaaa", req.scanInfo.Account) + assert.Equal(t, "aaaaaaaaaa", req.scanInfo.Credentials.Account) } { @@ -71,6 +71,6 @@ func TestGetScanParamsFromRequest(t *testing.T) { assert.False(t, req.scanQueryParams.ReturnResults) assert.False(t, req.scanInfo.HostSensorEnabled.GetBool()) assert.False(t, req.scanInfo.Submit) - assert.Equal(t, "aaaaaaaaaa", req.scanInfo.Account) + assert.Equal(t, "aaaaaaaaaa", req.scanInfo.Credentials.Account) } } diff --git a/httphandler/handlerequests/v1/requestshandlerutil_test.go b/httphandler/handlerequests/v1/requestshandlerutil_test.go index a5094e8b..0a70ea05 100644 --- a/httphandler/handlerequests/v1/requestshandlerutil_test.go +++ b/httphandler/handlerequests/v1/requestshandlerutil_test.go @@ -11,7 +11,7 @@ import ( func TestDefaultScanInfo(t *testing.T) { s := defaultScanInfo() - assert.Equal(t, "", s.Account) + assert.Equal(t, "", s.Credentials.Account) assert.Equal(t, "v2", s.FormatVersion) assert.Equal(t, "json", s.Format) assert.False(t, s.HostSensorEnabled.GetBool()) @@ -24,7 +24,7 @@ func TestGetScanCommand(t *testing.T) { TargetType: apisv1.KindFramework, } s := getScanCommand(&req, "abc") - assert.Equal(t, "", s.Account) + assert.Equal(t, "", s.Credentials.Account) assert.Equal(t, "abc", s.ScanID) assert.Equal(t, "v2", s.FormatVersion) assert.Equal(t, "json", s.Format) diff --git a/httphandler/handlerequests/v1/requestshandlerutils.go b/httphandler/handlerequests/v1/requestshandlerutils.go index 106c7285..1db56b0b 100644 --- a/httphandler/handlerequests/v1/requestshandlerutils.go +++ b/httphandler/handlerequests/v1/requestshandlerutils.go @@ -137,7 +137,7 @@ func getScanCommand(scanRequest *utilsmetav1.PostScanRequest, scanID string) *ca func defaultScanInfo() *cautils.ScanInfo { scanInfo := &cautils.ScanInfo{} scanInfo.FailThreshold = 100 - scanInfo.Account = envToString("KS_ACCOUNT", "") // publish results to Kubescape SaaS + scanInfo.Credentials.Account = envToString("KS_ACCOUNT", "") // publish results to Kubescape SaaS scanInfo.ExcludedNamespaces = envToString("KS_EXCLUDE_NAMESPACES", "") // namespaces to exclude scanInfo.IncludeNamespaces = envToString("KS_INCLUDE_NAMESPACES", "") // namespaces to include scanInfo.HostSensorYamlPath = envToString("KS_HOST_SCAN_YAML", "") // path to host scan YAML From 35b2b350a0db13c072f33efa121182d725a66d4c Mon Sep 17 00:00:00 2001 From: David Wertenteil Date: Thu, 26 May 2022 11:42:24 +0300 Subject: [PATCH 3/3] print submit error --- core/pkg/resultshandling/reporter/v2/reporteventreceiver.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/pkg/resultshandling/reporter/v2/reporteventreceiver.go b/core/pkg/resultshandling/reporter/v2/reporteventreceiver.go index 15e2c597..96bca9a2 100644 --- a/core/pkg/resultshandling/reporter/v2/reporteventreceiver.go +++ b/core/pkg/resultshandling/reporter/v2/reporteventreceiver.go @@ -57,8 +57,7 @@ func (report *ReportEventReceiver) Submit(opaSessionObj *cautils.OPASessionObj) if err == nil { report.generateMessage() } else { - - err = fmt.Errorf("failed to submit scan results. url: '%s'", report.GetURL()) + err = fmt.Errorf("failed to submit scan results. url: '%s', reason: %s", report.GetURL(), err.Error()) } logger.L().Debug("", helpers.String("account ID", report.customerGUID))