diff --git a/cmd/config/config.go b/cmd/config/config.go index 9259bc64..632385c1 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -25,6 +25,9 @@ var ( # Set access key kubescape config set secretKey + + # Set cloudAPI + kubescape config set cloudAPI ` ) diff --git a/cmd/config/set.go b/cmd/config/set.go index 4bcca3e6..6e45529d 100644 --- a/cmd/config/set.go +++ b/cmd/config/set.go @@ -33,9 +33,13 @@ func getSetCmd(ks meta.IKubescape) *cobra.Command { } var supportConfigSet = map[string]func(*metav1.SetConfig, string){ - "accountID": func(s *metav1.SetConfig, account string) { s.Account = account }, - "clientID": func(s *metav1.SetConfig, clientID string) { s.ClientID = clientID }, - "secretKey": func(s *metav1.SetConfig, secretKey string) { s.SecretKey = secretKey }, + "accountID": func(s *metav1.SetConfig, account string) { s.Account = account }, + "clientID": func(s *metav1.SetConfig, clientID string) { s.ClientID = clientID }, + "secretKey": func(s *metav1.SetConfig, secretKey string) { s.SecretKey = secretKey }, + "cloudAPI": func(s *metav1.SetConfig, cloudAPI string) { s.CloudAPI = cloudAPI }, + "cloudAuth": func(s *metav1.SetConfig, cloudAuth string) { s.CloudAuth = cloudAuth }, + "cloudReport": func(s *metav1.SetConfig, cloudReport string) { s.CloudReport = cloudReport }, + "cloudUI": func(s *metav1.SetConfig, cloudUI string) { s.CloudUI = cloudUI }, } func stringKeysToSlice(m map[string]func(*metav1.SetConfig, string)) []string { diff --git a/core/cautils/customerloader.go b/core/cautils/customerloader.go index 44df78cb..c503a678 100644 --- a/core/cautils/customerloader.go +++ b/core/cautils/customerloader.go @@ -11,6 +11,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" logger "github.com/kubescape/go-logger" + "github.com/kubescape/go-logger/helpers" "github.com/kubescape/k8s-interface/k8sinterface" "github.com/kubescape/kubescape/v2/core/cautils/getter" corev1 "k8s.io/api/core/v1" @@ -32,6 +33,10 @@ type ConfigObj struct { Token string `json:"invitationParam,omitempty"` CustomerAdminEMail string `json:"adminMail,omitempty"` ClusterName string `json:"clusterName,omitempty"` + CloudReport string `json:"cloudReport,omitempty"` + CloudAPI string `json:"cloudAPI,omitempty"` + CloudUI string `json:"cloudUI,omitempty"` + CloudAuth string `json:"cloudAuth,omitempty"` } // Config - convert ConfigObj to config file @@ -75,6 +80,10 @@ type ITenantConfig interface { GetClientID() string GetSecretKey() string GetConfigObj() *ConfigObj + GetCloudReport() string + GetCloudAPI() string + GetCloudUI() string + GetCloudAuth() string // GetBackendAPI() getter.IBackend // GenerateURL() @@ -103,6 +112,7 @@ func NewLocalConfig( } updateCredentials(lc.configObj, credentials) + updateCloudURLs(lc.configObj) // If a custom cluster name is provided then set that name, else use the cluster's original name if customClusterName != "" { @@ -114,6 +124,11 @@ func NewLocalConfig( lc.backendAPI.SetAccountID(lc.configObj.AccountID) lc.backendAPI.SetClientID(lc.configObj.ClientID) lc.backendAPI.SetSecretKey(lc.configObj.SecretKey) + lc.backendAPI.SetCloudAPI(lc.configObj.CloudAPI) + lc.backendAPI.SetCloudAuth(lc.configObj.CloudAuth) + lc.backendAPI.SetCloudReport(lc.configObj.CloudReport) + lc.backendAPI.SetCloudUI(lc.configObj.CloudUI) + logger.L().Debug("Kubescape Cloud URLs", helpers.String("api", lc.backendAPI.GetCloudAPI()), helpers.String("auth", lc.backendAPI.GetCloudAuth()), helpers.String("report", lc.backendAPI.GetCloudReport()), helpers.String("UI", lc.backendAPI.GetCloudUI())) return lc } @@ -125,6 +140,10 @@ func (lc *LocalConfig) GetClientID() string { return lc.configObj.ClientID func (lc *LocalConfig) GetSecretKey() string { return lc.configObj.SecretKey } func (lc *LocalConfig) GetContextName() string { return lc.configObj.ClusterName } func (lc *LocalConfig) GetToken() string { return lc.configObj.Token } +func (lc *LocalConfig) GetCloudReport() string { return lc.configObj.CloudReport } +func (lc *LocalConfig) GetCloudAPI() string { return lc.configObj.CloudAPI } +func (lc *LocalConfig) GetCloudUI() string { return lc.configObj.CloudUI } +func (lc *LocalConfig) GetCloudAuth() string { return lc.configObj.CloudAuth } func (lc *LocalConfig) IsConfigFound() bool { return existsConfigFile() } func (lc *LocalConfig) SetTenant() error { @@ -213,6 +232,7 @@ func NewClusterConfig(k8s *k8sinterface.KubernetesApi, backendAPI getter.IBacken loadConfigFromFile(c.configObj) } updateCredentials(c.configObj, credentials) + updateCloudURLs(c.configObj) // If a custom cluster name is provided then set that name, else use the cluster's original name if customClusterName != "" { @@ -230,6 +250,11 @@ func NewClusterConfig(k8s *k8sinterface.KubernetesApi, backendAPI getter.IBacken c.backendAPI.SetAccountID(c.configObj.AccountID) c.backendAPI.SetClientID(c.configObj.ClientID) c.backendAPI.SetSecretKey(c.configObj.SecretKey) + c.backendAPI.SetCloudAPI(c.configObj.CloudAPI) + c.backendAPI.SetCloudAuth(c.configObj.CloudAuth) + c.backendAPI.SetCloudReport(c.configObj.CloudReport) + c.backendAPI.SetCloudUI(c.configObj.CloudUI) + logger.L().Debug("Kubescape Cloud URLs", helpers.String("api", c.backendAPI.GetCloudAPI()), helpers.String("auth", c.backendAPI.GetCloudAuth()), helpers.String("report", c.backendAPI.GetCloudReport()), helpers.String("UI", c.backendAPI.GetCloudUI())) return c } @@ -241,7 +266,12 @@ func (c *ClusterConfig) GetClientID() string { return c.configObj.ClientID func (c *ClusterConfig) GetSecretKey() string { return c.configObj.SecretKey } func (c *ClusterConfig) GetTenantEmail() string { return c.configObj.CustomerAdminEMail } func (c *ClusterConfig) GetToken() string { return c.configObj.Token } -func (c *ClusterConfig) IsConfigFound() bool { return existsConfigFile() || c.existsConfigMap() } +func (c *ClusterConfig) GetCloudReport() string { return c.configObj.CloudReport } +func (c *ClusterConfig) GetCloudAPI() string { return c.configObj.CloudAPI } +func (c *ClusterConfig) GetCloudUI() string { return c.configObj.CloudUI } +func (c *ClusterConfig) GetCloudAuth() string { return c.configObj.CloudAuth } + +func (c *ClusterConfig) IsConfigFound() bool { return existsConfigFile() || c.existsConfigMap() } func (c *ClusterConfig) SetTenant() error { @@ -540,3 +570,39 @@ func updateCredentials(configObj *ConfigObj, credentials *Credentials) { } } + +func getCloudURLsFromEnv(cloudURLs *CloudURLs) { + // load from env + if cloudAPI := os.Getenv("KS_CLOUD_API_URL"); cloudAPI != "" { + cloudURLs.CloudAPI = cloudAPI + } + if cloudAuth := os.Getenv("KS_CLOUD_AUTH_URL"); cloudAuth != "" { + cloudURLs.CloudAuth = cloudAuth + } + if cloudReport := os.Getenv("KS_CLOUD_REPORT_URL"); cloudReport != "" { + cloudURLs.CloudReport = cloudReport + } + if cloudUI := os.Getenv("KS_CLOUD_UI_URL"); cloudUI != "" { + cloudURLs.CloudUI = cloudUI + } +} + +func updateCloudURLs(configObj *ConfigObj) { + cloudURLs := &CloudURLs{} + + getCloudURLsFromEnv(cloudURLs) + + if cloudURLs.CloudAPI != "" { + configObj.CloudAPI = cloudURLs.CloudAPI // override config CloudAPI + } + if cloudURLs.CloudAuth != "" { + configObj.CloudAuth = cloudURLs.CloudAuth // override config CloudAuth + } + if cloudURLs.CloudReport != "" { + configObj.CloudReport = cloudURLs.CloudReport // override config CloudReport + } + if cloudURLs.CloudUI != "" { + configObj.CloudUI = cloudURLs.CloudUI // override config CloudUI + } + +} diff --git a/core/cautils/customerloader_test.go b/core/cautils/customerloader_test.go index 8a7f1ce5..3c52172b 100644 --- a/core/cautils/customerloader_test.go +++ b/core/cautils/customerloader_test.go @@ -2,6 +2,7 @@ package cautils import ( "encoding/json" + "os" "testing" "github.com/stretchr/testify/assert" @@ -16,6 +17,10 @@ func mockConfigObj() *ConfigObj { ClusterName: "ddd", CustomerAdminEMail: "ab@cd", Token: "eee", + CloudReport: "report.armo.cloud", + CloudAPI: "api.armosec.io", + CloudUI: "cloud.armosec.io", + CloudAuth: "auth.armosec.io", } } func mockLocalConfig() *LocalConfig { @@ -39,6 +44,10 @@ func TestConfig(t *testing.T) { assert.Equal(t, co.AccountID, cop.AccountID) assert.Equal(t, co.ClientID, cop.ClientID) assert.Equal(t, co.SecretKey, cop.SecretKey) + assert.Equal(t, co.CloudReport, cop.CloudReport) + assert.Equal(t, co.CloudAPI, cop.CloudAPI) + assert.Equal(t, co.CloudUI, cop.CloudUI) + assert.Equal(t, co.CloudAuth, cop.CloudAuth) assert.Equal(t, "", cop.ClusterName) // Not copied to bytes assert.Equal(t, "", cop.CustomerAdminEMail) // Not copied to bytes assert.Equal(t, "", cop.Token) // Not copied to bytes @@ -60,6 +69,10 @@ func TestITenantConfig(t *testing.T) { assert.Equal(t, co.ClusterName, lc.GetContextName()) assert.Equal(t, co.CustomerAdminEMail, lc.GetTenantEmail()) assert.Equal(t, co.Token, lc.GetToken()) + assert.Equal(t, co.CloudReport, lc.GetCloudReport()) + assert.Equal(t, co.CloudAPI, lc.GetCloudAPI()) + assert.Equal(t, co.CloudUI, lc.GetCloudUI()) + assert.Equal(t, co.CloudAuth, lc.GetCloudAuth()) // test ClusterConfig methods assert.Equal(t, co.AccountID, c.GetAccountID()) @@ -68,6 +81,10 @@ func TestITenantConfig(t *testing.T) { assert.Equal(t, co.ClusterName, c.GetContextName()) assert.Equal(t, co.CustomerAdminEMail, c.GetTenantEmail()) assert.Equal(t, co.Token, c.GetToken()) + assert.Equal(t, co.CloudReport, c.GetCloudReport()) + assert.Equal(t, co.CloudAPI, c.GetCloudAPI()) + assert.Equal(t, co.CloudUI, c.GetCloudUI()) + assert.Equal(t, co.CloudAuth, c.GetCloudAuth()) } func TestUpdateConfigData(t *testing.T) { @@ -80,6 +97,10 @@ func TestUpdateConfigData(t *testing.T) { assert.Equal(t, c.GetAccountID(), configMap.Data["accountID"]) assert.Equal(t, c.GetClientID(), configMap.Data["clientID"]) assert.Equal(t, c.GetSecretKey(), configMap.Data["secretKey"]) + assert.Equal(t, c.GetCloudReport(), configMap.Data["cloudReport"]) + assert.Equal(t, c.GetCloudAPI(), configMap.Data["cloudAPI"]) + assert.Equal(t, c.GetCloudUI(), configMap.Data["cloudUI"]) + assert.Equal(t, c.GetCloudAuth(), configMap.Data["cloudAuth"]) } func TestReadConfig(t *testing.T) { @@ -97,6 +118,10 @@ func TestReadConfig(t *testing.T) { assert.Equal(t, com.ClusterName, co.ClusterName) assert.Equal(t, com.CustomerAdminEMail, co.CustomerAdminEMail) assert.Equal(t, com.Token, co.Token) + assert.Equal(t, com.CloudReport, co.CloudReport) + assert.Equal(t, com.CloudAPI, co.CloudAPI) + assert.Equal(t, com.CloudUI, co.CloudUI) + assert.Equal(t, com.CloudAuth, co.CloudAuth) } func TestLoadConfigFromData(t *testing.T) { @@ -120,6 +145,10 @@ func TestLoadConfigFromData(t *testing.T) { assert.Equal(t, c.GetContextName(), co.ClusterName) assert.Equal(t, c.GetTenantEmail(), co.CustomerAdminEMail) assert.Equal(t, c.GetToken(), co.Token) + assert.Equal(t, c.GetCloudReport(), co.CloudReport) + assert.Equal(t, c.GetCloudAPI(), co.CloudAPI) + assert.Equal(t, c.GetCloudUI(), co.CloudUI) + assert.Equal(t, c.GetCloudAuth(), co.CloudAuth) } // use case: all data is in config.json @@ -139,6 +168,10 @@ func TestLoadConfigFromData(t *testing.T) { assert.Equal(t, c.GetAccountID(), co.AccountID) assert.Equal(t, c.GetClientID(), co.ClientID) assert.Equal(t, c.GetSecretKey(), co.SecretKey) + assert.Equal(t, c.GetCloudReport(), co.CloudReport) + assert.Equal(t, c.GetCloudAPI(), co.CloudAPI) + assert.Equal(t, c.GetCloudUI(), co.CloudUI) + assert.Equal(t, c.GetCloudAuth(), co.CloudAuth) } // use case: some data is in config.json @@ -151,10 +184,12 @@ func TestLoadConfigFromData(t *testing.T) { // add to map configMap.Data["clientID"] = c.configObj.ClientID configMap.Data["secretKey"] = c.configObj.SecretKey + configMap.Data["cloudReport"] = c.configObj.CloudReport // delete the content c.configObj.ClientID = "" c.configObj.SecretKey = "" + c.configObj.CloudReport = "" configMap.Data["config.json"] = string(c.GetConfigObj().Config()) loadConfigFromData(c.configObj, configMap.Data) @@ -162,6 +197,7 @@ func TestLoadConfigFromData(t *testing.T) { assert.NotEmpty(t, c.GetAccountID()) assert.NotEmpty(t, c.GetClientID()) assert.NotEmpty(t, c.GetSecretKey()) + assert.NotEmpty(t, c.GetCloudReport()) } // use case: some data is in config.json @@ -222,3 +258,13 @@ func TestAdoptClusterName(t *testing.T) { }) } } + +func TestUpdateCloudURLs(t *testing.T) { + co := mockConfigObj() + mockCloudAPI := "1-2-3-4.com" + os.Setenv("KS_CLOUD_API_URL", mockCloudAPI) + + assert.NotEqual(t, co.CloudAPI, mockCloudAPI) + updateCloudURLs(co) + assert.Equal(t, co.CloudAPI, mockCloudAPI) +} diff --git a/core/cautils/getter/getpolicies.go b/core/cautils/getter/getpolicies.go index 6dacca80..18c6c284 100644 --- a/core/cautils/getter/getpolicies.go +++ b/core/cautils/getter/getpolicies.go @@ -28,10 +28,18 @@ type IBackend interface { GetAccountID() string GetClientID() string GetSecretKey() string + GetCloudReport() string + GetCloudAPI() string + GetCloudUI() string + GetCloudAuth() string SetAccountID(accountID string) SetClientID(clientID string) SetSecretKey(secretKey string) + SetCloudReport(cloudReport string) + SetCloudAPI(cloudAPI string) + SetCloudUI(cloudUI string) + SetCloudAuth(cloudAuth string) GetTenant() (*TenantResponse, error) } diff --git a/core/cautils/getter/kscloudapi.go b/core/cautils/getter/kscloudapi.go index 3bf04179..9b57c0d9 100644 --- a/core/cautils/getter/kscloudapi.go +++ b/core/cautils/getter/kscloudapi.go @@ -10,8 +10,6 @@ import ( "time" "github.com/armosec/armoapi-go/armotypes" - logger "github.com/kubescape/go-logger" - "github.com/kubescape/go-logger/helpers" "github.com/kubescape/opa-utils/reporthandling" "github.com/kubescape/opa-utils/reporthandling/attacktrack/v1alpha1" ) @@ -35,23 +33,22 @@ var ( // KSCloudAPI allows accessing the API of the Kubescape Cloud offering type KSCloudAPI struct { - httpClient *http.Client - apiURL string - authURL string - erURL string - feURL string - accountID string - clientID string - secretKey string - authCookie string - feToken FeLoginResponse - loggedIn bool + httpClient *http.Client + cloudAPI string + cloudAuth string + cloudReport string + cloudUI string + accountID string + clientID string + secretKey string + authCookie string + feToken FeLoginResponse + loggedIn bool } var globalKSCloudAPIConnector *KSCloudAPI func SetKSCloudAPIConnector(ksCloudAPI *KSCloudAPI) { - logger.L().Debug("Kubescape Cloud URLs", helpers.String("api", ksCloudAPI.apiURL), helpers.String("auth", ksCloudAPI.authURL), helpers.String("report", ksCloudAPI.erURL), helpers.String("UI", ksCloudAPI.feURL)) globalKSCloudAPIConnector = ksCloudAPI } @@ -65,10 +62,10 @@ func GetKSCloudAPIConnector() *KSCloudAPI { func NewKSCloudAPIDev() *KSCloudAPI { apiObj := newKSCloudAPI() - apiObj.apiURL = ksCloudDevBEURL - apiObj.authURL = ksCloudDevAUTHURL - apiObj.erURL = ksCloudDevERURL - apiObj.feURL = ksCloudDevFEURL + apiObj.cloudAPI = ksCloudDevBEURL + apiObj.cloudAuth = ksCloudDevAUTHURL + apiObj.cloudReport = ksCloudDevERURL + apiObj.cloudUI = ksCloudDevFEURL return apiObj } @@ -76,10 +73,10 @@ func NewKSCloudAPIDev() *KSCloudAPI { func NewKSCloudAPIProd() *KSCloudAPI { apiObj := newKSCloudAPI() - apiObj.apiURL = ksCloudBEURL - apiObj.erURL = ksCloudERURL - apiObj.feURL = ksCloudFEURL - apiObj.authURL = ksCloudAUTHURL + apiObj.cloudAPI = ksCloudBEURL + apiObj.cloudReport = ksCloudERURL + apiObj.cloudUI = ksCloudFEURL + apiObj.cloudAuth = ksCloudAUTHURL return apiObj } @@ -87,10 +84,10 @@ func NewKSCloudAPIProd() *KSCloudAPI { func NewKSCloudAPIStaging() *KSCloudAPI { apiObj := newKSCloudAPI() - apiObj.apiURL = ksCloudStageBEURL - apiObj.erURL = ksCloudStageERURL - apiObj.feURL = ksCloudStageFEURL - apiObj.authURL = ksCloudStageAUTHURL + apiObj.cloudAPI = ksCloudStageBEURL + apiObj.cloudReport = ksCloudStageERURL + apiObj.cloudUI = ksCloudStageFEURL + apiObj.cloudAuth = ksCloudStageAUTHURL return apiObj } @@ -98,10 +95,10 @@ func NewKSCloudAPIStaging() *KSCloudAPI { func NewKSCloudAPICustomized(ksCloudERURL, ksCloudBEURL, ksCloudFEURL, ksCloudAUTHURL string) *KSCloudAPI { apiObj := newKSCloudAPI() - apiObj.erURL = ksCloudERURL - apiObj.apiURL = ksCloudBEURL - apiObj.feURL = ksCloudFEURL - apiObj.authURL = ksCloudAUTHURL + apiObj.cloudReport = ksCloudERURL + apiObj.cloudAPI = ksCloudBEURL + apiObj.cloudUI = ksCloudFEURL + apiObj.cloudAuth = ksCloudAUTHURL return apiObj } @@ -136,17 +133,38 @@ func (api *KSCloudAPI) Get(fullURL string, headers map[string]string) (string, e return HttpGetter(api.httpClient, fullURL, headers) } -func (api *KSCloudAPI) GetAccountID() string { return api.accountID } -func (api *KSCloudAPI) IsLoggedIn() bool { return api.loggedIn } -func (api *KSCloudAPI) GetClientID() string { return api.clientID } -func (api *KSCloudAPI) GetSecretKey() string { return api.secretKey } -func (api *KSCloudAPI) GetFrontendURL() string { return api.feURL } -func (api *KSCloudAPI) GetApiURL() string { return api.apiURL } -func (api *KSCloudAPI) GetAuthURL() string { return api.authURL } -func (api *KSCloudAPI) GetReportReceiverURL() string { return api.erURL } +func (api *KSCloudAPI) GetAccountID() string { return api.accountID } +func (api *KSCloudAPI) IsLoggedIn() bool { return api.loggedIn } +func (api *KSCloudAPI) GetClientID() string { return api.clientID } +func (api *KSCloudAPI) GetSecretKey() string { return api.secretKey } +func (api *KSCloudAPI) GetCloudReport() string { return api.cloudReport } +func (api *KSCloudAPI) GetCloudAPI() string { return api.cloudAPI } +func (api *KSCloudAPI) GetCloudUI() string { return api.cloudUI } +func (api *KSCloudAPI) GetCloudAuth() string { return api.cloudAuth } + func (api *KSCloudAPI) SetAccountID(accountID string) { api.accountID = accountID } func (api *KSCloudAPI) SetClientID(clientID string) { api.clientID = clientID } func (api *KSCloudAPI) SetSecretKey(secretKey string) { api.secretKey = secretKey } +func (api *KSCloudAPI) SetCloudReport(cloudReport string) { + if cloudReport != "" { + api.cloudReport = cloudReport + } +} +func (api *KSCloudAPI) SetCloudAPI(cloudAPI string) { + if cloudAPI != "" { + api.cloudAPI = cloudAPI + } +} +func (api *KSCloudAPI) SetCloudUI(cloudUI string) { + if cloudUI != "" { + api.cloudUI = cloudUI + } +} +func (api *KSCloudAPI) SetCloudAuth(cloudAuth string) { + if cloudAuth != "" { + api.cloudAuth = cloudAuth + } +} func (api *KSCloudAPI) GetAttackTracks() ([]v1alpha1.AttackTrack, error) { respStr, err := api.Get(api.getAttackTracksURL(), nil) diff --git a/core/cautils/getter/kscloudapiutils.go b/core/cautils/getter/kscloudapiutils.go index 254d40ee..99d42b13 100644 --- a/core/cautils/getter/kscloudapiutils.go +++ b/core/cautils/getter/kscloudapiutils.go @@ -13,7 +13,7 @@ var NativeFrameworks = []string{"nsa", "mitre", "armobest", "devopsbest"} func (api *KSCloudAPI) getFrameworkURL(frameworkName string) string { u := url.URL{} - u.Scheme, u.Host = parseHost(api.GetApiURL()) + u.Scheme, u.Host = parseHost(api.GetCloudAPI()) u.Path = "api/v1/armoFrameworks" q := u.Query() q.Add("customerGUID", api.getCustomerGUIDFallBack()) @@ -30,7 +30,7 @@ func (api *KSCloudAPI) getFrameworkURL(frameworkName string) string { func (api *KSCloudAPI) getAttackTracksURL() string { u := url.URL{} - u.Scheme, u.Host = parseHost(api.GetApiURL()) + u.Scheme, u.Host = parseHost(api.GetCloudAPI()) u.Path = "api/v1/attackTracks" q := u.Query() q.Add("customerGUID", api.getCustomerGUIDFallBack()) @@ -41,7 +41,7 @@ func (api *KSCloudAPI) getAttackTracksURL() string { func (api *KSCloudAPI) getListFrameworkURL() string { u := url.URL{} - u.Scheme, u.Host = parseHost(api.GetApiURL()) + u.Scheme, u.Host = parseHost(api.GetCloudAPI()) u.Path = "api/v1/armoFrameworks" q := u.Query() q.Add("customerGUID", api.getCustomerGUIDFallBack()) @@ -51,7 +51,7 @@ func (api *KSCloudAPI) getListFrameworkURL() string { } func (api *KSCloudAPI) getExceptionsURL(clusterName string) string { u := url.URL{} - u.Scheme, u.Host = parseHost(api.GetApiURL()) + u.Scheme, u.Host = parseHost(api.GetCloudAPI()) u.Path = "api/v1/armoPostureExceptions" q := u.Query() @@ -66,7 +66,7 @@ func (api *KSCloudAPI) getExceptionsURL(clusterName string) string { func (api *KSCloudAPI) exceptionsURL(exceptionsPolicyName string) string { u := url.URL{} - u.Scheme, u.Host = parseHost(api.GetApiURL()) + u.Scheme, u.Host = parseHost(api.GetCloudAPI()) u.Path = "api/v1/postureExceptionPolicy" q := u.Query() @@ -88,7 +88,7 @@ func (api *KSCloudAPI) getAccountConfigDefault(clusterName string) string { func (api *KSCloudAPI) getAccountConfig(clusterName string) string { u := url.URL{} - u.Scheme, u.Host = parseHost(api.GetApiURL()) + u.Scheme, u.Host = parseHost(api.GetCloudAPI()) u.Path = "api/v1/armoCustomerConfiguration" q := u.Query() @@ -103,21 +103,21 @@ func (api *KSCloudAPI) getAccountConfig(clusterName string) string { func (api *KSCloudAPI) getAccountURL() string { u := url.URL{} - u.Scheme, u.Host = parseHost(api.GetApiURL()) + u.Scheme, u.Host = parseHost(api.GetCloudAPI()) u.Path = "api/v1/createTenant" return u.String() } func (api *KSCloudAPI) getApiToken() string { u := url.URL{} - u.Scheme, u.Host = parseHost(api.GetAuthURL()) + u.Scheme, u.Host = parseHost(api.GetCloudAuth()) u.Path = "identity/resources/auth/v1/api-token" return u.String() } func (api *KSCloudAPI) getOpenidCustomers() string { u := url.URL{} - u.Scheme, u.Host = parseHost(api.GetApiURL()) + u.Scheme, u.Host = parseHost(api.GetCloudAPI()) u.Path = "api/v1/openid_customers" return u.String() } diff --git a/core/cautils/rootinfo.go b/core/cautils/rootinfo.go index 28201a59..099efe86 100644 --- a/core/cautils/rootinfo.go +++ b/core/cautils/rootinfo.go @@ -17,6 +17,12 @@ type RootInfo struct { KSCloudBEURLsDep string // Kubescape Cloud URL } +type CloudURLs struct { + CloudReport string + CloudAPI string + CloudUI string + CloudAuth string +} type Credentials struct { Account string diff --git a/core/core/cachedconfig.go b/core/core/cachedconfig.go index 94d057f1..6db3f63c 100644 --- a/core/core/cachedconfig.go +++ b/core/core/cachedconfig.go @@ -19,6 +19,18 @@ func (ks *Kubescape) SetCachedConfig(setConfig *metav1.SetConfig) error { if setConfig.ClientID != "" { tenant.GetConfigObj().ClientID = setConfig.ClientID } + if setConfig.CloudAPI != "" { + tenant.GetConfigObj().CloudAPI = setConfig.CloudAPI + } + if setConfig.CloudAuth != "" { + tenant.GetConfigObj().CloudAuth = setConfig.CloudAuth + } + if setConfig.CloudReport != "" { + tenant.GetConfigObj().CloudReport = setConfig.CloudReport + } + if setConfig.CloudUI != "" { + tenant.GetConfigObj().CloudUI = setConfig.CloudUI + } return tenant.UpdateCachedConfig() } diff --git a/core/core/initutils.go b/core/core/initutils.go index b46b925a..327d06c8 100644 --- a/core/core/initutils.go +++ b/core/core/initutils.go @@ -128,6 +128,8 @@ func policyIdentifierNames(pi []cautils.PolicyIdentifier) string { func setSubmitBehavior(scanInfo *cautils.ScanInfo, tenantConfig cautils.ITenantConfig) { /* + If CloudReport not set - Do not send report + If "First run (local config not found)" - Default/keep-local - Do not send report Submit - Create tenant & Submit report @@ -138,6 +140,11 @@ func setSubmitBehavior(scanInfo *cautils.ScanInfo, tenantConfig cautils.ITenantC */ + if getter.GetKSCloudAPIConnector().GetCloudAPI() == "" { + scanInfo.Submit = false + return + } + // do not submit control scanning if !scanInfo.FrameworkScan { scanInfo.Submit = false @@ -166,11 +173,11 @@ func setSubmitBehavior(scanInfo *cautils.ScanInfo, tenantConfig cautils.ITenantC } // setPolicyGetter set the policy getter - local file/github release/Kubescape Cloud API -func getPolicyGetter(loadPoliciesFromFile []string, tennatEmail string, frameworkScope bool, downloadReleasedPolicy *getter.DownloadReleasedPolicy) getter.IPolicyGetter { +func getPolicyGetter(loadPoliciesFromFile []string, tenantEmail string, frameworkScope bool, downloadReleasedPolicy *getter.DownloadReleasedPolicy) getter.IPolicyGetter { if len(loadPoliciesFromFile) > 0 { return getter.NewLoadPolicy(loadPoliciesFromFile) } - if tennatEmail != "" && frameworkScope { + if tenantEmail != "" && getter.GetKSCloudAPIConnector().GetCloudAPI() != "" && frameworkScope { g := getter.GetKSCloudAPIConnector() // download policy from Kubescape Cloud backend return g } diff --git a/core/meta/datastructures/v1/config.go b/core/meta/datastructures/v1/config.go index 4ae0aea7..bfe01aa4 100644 --- a/core/meta/datastructures/v1/config.go +++ b/core/meta/datastructures/v1/config.go @@ -3,9 +3,13 @@ package v1 import "io" type SetConfig struct { - Account string - ClientID string - SecretKey string + Account string + ClientID string + SecretKey string + CloudReport string + CloudAPI string + CloudUI string + CloudAuth string } type ViewConfig struct { diff --git a/core/pkg/registryadaptors/armosec/v1/civksadaptor.go b/core/pkg/registryadaptors/armosec/v1/civksadaptor.go index 885b3906..06ee814f 100644 --- a/core/pkg/registryadaptors/armosec/v1/civksadaptor.go +++ b/core/pkg/registryadaptors/armosec/v1/civksadaptor.go @@ -51,7 +51,7 @@ func (ksCivAdaptor *KSCivAdaptor) GetImageVulnerability(imageID *registryvulnera pageNumber := 1 request := V2ListRequest{PageSize: &pageSize, PageNum: &pageNumber, InnerFilters: filter, OrderBy: "timestamp:desc"} requestBody, _ := json.Marshal(request) - requestUrl := fmt.Sprintf("https://%s/api/v1/vulnerability/scanResultsDetails?customerGUID=%s", ksCivAdaptor.ksCloudAPI.GetApiURL(), ksCivAdaptor.ksCloudAPI.GetAccountID()) + requestUrl := fmt.Sprintf("https://%s/api/v1/vulnerability/scanResultsDetails?customerGUID=%s", ksCivAdaptor.ksCloudAPI.GetCloudAPI(), ksCivAdaptor.ksCloudAPI.GetAccountID()) resp, err := ksCivAdaptor.ksCloudAPI.Post(requestUrl, map[string]string{"Content-Type": "application/json"}, requestBody) if err != nil { diff --git a/core/pkg/registryadaptors/armosec/v1/civksadaptorutils.go b/core/pkg/registryadaptors/armosec/v1/civksadaptorutils.go index 5aaf2d32..729c69d4 100644 --- a/core/pkg/registryadaptors/armosec/v1/civksadaptorutils.go +++ b/core/pkg/registryadaptors/armosec/v1/civksadaptorutils.go @@ -14,7 +14,7 @@ func (armoCivAdaptor *KSCivAdaptor) getImageLastScanId(imageID *registryvulnerab pageNumber := 1 request := V2ListRequest{PageSize: &pageSize, PageNum: &pageNumber, InnerFilters: filter, OrderBy: "timestamp:desc"} requestBody, _ := json.Marshal(request) - requestUrl := fmt.Sprintf("https://%s/api/v1/vulnerability/scanResultsSumSummary?customerGUID=%s", armoCivAdaptor.ksCloudAPI.GetApiURL(), armoCivAdaptor.ksCloudAPI.GetAccountID()) + requestUrl := fmt.Sprintf("https://%s/api/v1/vulnerability/scanResultsSumSummary?customerGUID=%s", armoCivAdaptor.ksCloudAPI.GetCloudAPI(), armoCivAdaptor.ksCloudAPI.GetAccountID()) resp, err := armoCivAdaptor.ksCloudAPI.Post(requestUrl, map[string]string{"Content-Type": "application/json"}, requestBody) if err != nil { diff --git a/core/pkg/resultshandling/reporter/v2/mockreporter.go b/core/pkg/resultshandling/reporter/v2/mockreporter.go index 570757bd..0d7d00f3 100644 --- a/core/pkg/resultshandling/reporter/v2/mockreporter.go +++ b/core/pkg/resultshandling/reporter/v2/mockreporter.go @@ -32,7 +32,7 @@ func (reportMock *ReportMock) SetClusterName(clusterName string) { } func (reportMock *ReportMock) GetURL() string { - u := fmt.Sprintf("https://%s/account/sign-up", getter.GetKSCloudAPIConnector().GetFrontendURL()) + u := fmt.Sprintf("https://%s/account/sign-up", getter.GetKSCloudAPIConnector().GetCloudUI()) if reportMock.query != "" { u += fmt.Sprintf("?%s", reportMock.query) } diff --git a/core/pkg/resultshandling/reporter/v2/reporteventreceiver.go b/core/pkg/resultshandling/reporter/v2/reporteventreceiver.go index 1de82e9d..5196cbf8 100644 --- a/core/pkg/resultshandling/reporter/v2/reporteventreceiver.go +++ b/core/pkg/resultshandling/reporter/v2/reporteventreceiver.go @@ -105,7 +105,7 @@ func (report *ReportEventReceiver) prepareReport(opaSessionObj *cautils.OPASessi func (report *ReportEventReceiver) GetURL() string { u := url.URL{} - u.Host = getter.GetKSCloudAPIConnector().GetFrontendURL() + u.Host = getter.GetKSCloudAPIConnector().GetCloudUI() parseHost(&u) report.addPathURL(&u) diff --git a/core/pkg/resultshandling/reporter/v2/reporteventreceiverutils.go b/core/pkg/resultshandling/reporter/v2/reporteventreceiverutils.go index f3a4d19f..2b9eac01 100644 --- a/core/pkg/resultshandling/reporter/v2/reporteventreceiverutils.go +++ b/core/pkg/resultshandling/reporter/v2/reporteventreceiverutils.go @@ -11,7 +11,7 @@ import ( func (report *ReportEventReceiver) initEventReceiverURL() { urlObj := url.URL{} - urlObj.Host = getter.GetKSCloudAPIConnector().GetReportReceiverURL() + urlObj.Host = getter.GetKSCloudAPIConnector().GetCloudReport() parseHost(&urlObj) urlObj.Path = "/k8s/v2/postureReport"