mirror of
https://github.com/kubescape/kubescape.git
synced 2026-02-14 18:09:55 +00:00
Support backend access key (#1404)
Support backend access key Signed-off-by: Amir Malka <amirm@armosec.io>
This commit is contained in:
@@ -33,6 +33,7 @@ func getSetCmd(ks meta.IKubescape) *cobra.Command {
|
||||
}
|
||||
|
||||
var supportConfigSet = map[string]func(*metav1.SetConfig, string){
|
||||
"accessKey": func(s *metav1.SetConfig, accessKey string) { s.AccessKey = accessKey },
|
||||
"accountID": func(s *metav1.SetConfig, account string) { s.Account = account },
|
||||
"cloudAPIURL": func(s *metav1.SetConfig, cloudAPIURL string) { s.CloudAPIURL = cloudAPIURL },
|
||||
"cloudReportURL": func(s *metav1.SetConfig, cloudReportURL string) { s.CloudReportURL = cloudReportURL },
|
||||
|
||||
@@ -84,6 +84,7 @@ func GetDownloadCmd(ks meta.IKubescape) *cobra.Command {
|
||||
}
|
||||
|
||||
downloadCmd.PersistentFlags().StringVarP(&downloadInfo.AccountID, "account", "", "", "Kubescape SaaS account ID. Default will load account ID from cache")
|
||||
downloadCmd.PersistentFlags().StringVarP(&downloadInfo.AccessKey, "accessKey", "", "", "Kubescape SaaS access key. Default will load access key from cache")
|
||||
downloadCmd.PersistentFlags().MarkDeprecated("client-id", "Client ID is no longer supported. Feel free to contact the Kubescape maintainers for more information.")
|
||||
downloadCmd.PersistentFlags().MarkDeprecated("secret-key", "Secret Key is no longer supported. Feel free to contact the Kubescape maintainers for more information.")
|
||||
downloadCmd.Flags().StringVarP(&downloadInfo.Path, "output", "o", "", "Output file. If not specified, will save in `~/.kubescape/<policy name>.json`")
|
||||
|
||||
@@ -64,6 +64,7 @@ func GetListCmd(ks meta.IKubescape) *cobra.Command {
|
||||
},
|
||||
}
|
||||
listCmd.PersistentFlags().StringVarP(&listPolicies.AccountID, "account", "", "", "Kubescape SaaS account ID. Default will load account ID from cache")
|
||||
listCmd.PersistentFlags().StringVarP(&listPolicies.AccessKey, "accessKey", "", "", "Kubescape SaaS access key. Default will load access key from cache")
|
||||
listCmd.PersistentFlags().StringVar(&listPolicies.Format, "format", "pretty-print", "output format. supported: 'pretty-print'/'json'")
|
||||
listCmd.PersistentFlags().MarkDeprecated("id", "Control ID's are included in list outputs")
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ func initEnvironment() {
|
||||
|
||||
logger.L().Debug("configuring service discovery URLs", helpers.String("cloudAPIURL", services.GetApiServerUrl()), helpers.String("cloudReportURL", services.GetReportReceiverHttpUrl()))
|
||||
|
||||
tenant := cautils.GetTenantConfig("", "", "", nil)
|
||||
tenant := cautils.GetTenantConfig("", "", "", "", nil)
|
||||
if services.GetApiServerUrl() != "" {
|
||||
tenant.GetConfigObj().CloudAPIURL = services.GetApiServerUrl()
|
||||
}
|
||||
@@ -99,6 +99,7 @@ func initEnvironment() {
|
||||
services.GetApiServerUrl(),
|
||||
services.GetReportReceiverHttpUrl(),
|
||||
"",
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
logger.L().Fatal("failed to create KS Cloud client", helpers.Error(err))
|
||||
|
||||
@@ -21,19 +21,21 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
configFileName string = "config"
|
||||
kubescapeNamespace string = "kubescape"
|
||||
kubescapeConfigMapName string = "kubescape-config"
|
||||
kubescapeCloudConfigMapName string = "ks-cloud-config"
|
||||
configFileName string = "config"
|
||||
kubescapeNamespace string = "kubescape"
|
||||
|
||||
kubescapeConfigMapName string = "kubescape-config" // deprecated - for backward compatibility
|
||||
kubescapeCloudConfigMapName string = "ks-cloud-config" // deprecated - for backward compatibility
|
||||
|
||||
cloudConfigMapLabelSelector string = "kubescape.io/infra=config"
|
||||
credsLabelSelectors string = "kubescape.io/infra=credentials" //nolint:gosec
|
||||
|
||||
// env vars
|
||||
defaultConfigMapNameEnvVar string = "KS_DEFAULT_CONFIGMAP_NAME"
|
||||
defaultCloudConfigMapNameEnvVar string = "KS_DEFAULT_CLOUD_CONFIGMAP_NAME"
|
||||
defaultConfigMapNamespaceEnvVar string = "KS_DEFAULT_CONFIGMAP_NAMESPACE"
|
||||
accountIdEnvVar string = "KS_ACCOUNT_ID"
|
||||
accessKeyEnvVar string = "KS_ACCESS_KEY"
|
||||
cloudApiUrlEnvVar string = "KS_CLOUD_API_URL"
|
||||
cloudReportUrlEnvVar string = "KS_CLOUD_REPORT_URL"
|
||||
storageEnabledEnvVar string = "KS_STORAGE_ENABLED"
|
||||
)
|
||||
|
||||
func ConfigFileFullPath() string { return getter.GetDefaultPath(configFileName + ".json") }
|
||||
@@ -47,7 +49,7 @@ type ConfigObj struct {
|
||||
ClusterName string `json:"clusterName,omitempty"`
|
||||
CloudReportURL string `json:"cloudReportURL,omitempty"`
|
||||
CloudAPIURL string `json:"cloudAPIURL,omitempty"`
|
||||
StorageEnabled bool `json:"storageEnabled,omitempty"`
|
||||
AccessKey string `json:"accessKey,omitempty"`
|
||||
}
|
||||
|
||||
// Config - convert ConfigObj to config file
|
||||
@@ -92,15 +94,15 @@ type ITenantConfig interface {
|
||||
UpdateCachedConfig() error
|
||||
DeleteCachedConfig(ctx context.Context) error
|
||||
GenerateAccountID() (string, error)
|
||||
DeleteAccountID() error
|
||||
DeleteCredentials() error
|
||||
|
||||
// getters
|
||||
GetContextName() string
|
||||
GetAccountID() string
|
||||
GetAccessKey() string
|
||||
GetConfigObj() *ConfigObj
|
||||
GetCloudReportURL() string
|
||||
GetCloudAPIURL() string
|
||||
IsStorageEnabled() bool
|
||||
}
|
||||
|
||||
// ======================================================================================
|
||||
@@ -114,7 +116,7 @@ type LocalConfig struct {
|
||||
configObj *ConfigObj
|
||||
}
|
||||
|
||||
func NewLocalConfig(accountID, clusterName string, customClusterName string) *LocalConfig {
|
||||
func NewLocalConfig(accountID, accessKey, clusterName, customClusterName string) *LocalConfig {
|
||||
lc := &LocalConfig{
|
||||
configObj: &ConfigObj{},
|
||||
}
|
||||
@@ -123,9 +125,8 @@ func NewLocalConfig(accountID, clusterName string, customClusterName string) *Lo
|
||||
loadConfigFromFile(lc.configObj)
|
||||
}
|
||||
|
||||
updateAccountID(lc.configObj, accountID)
|
||||
updateCredentials(lc.configObj, accountID, accessKey)
|
||||
updateCloudURLs(lc.configObj)
|
||||
updateStorageEnabled(lc.configObj)
|
||||
|
||||
// If a custom cluster name is provided then set that name, else use the cluster's original name
|
||||
if customClusterName != "" {
|
||||
@@ -145,7 +146,7 @@ func (lc *LocalConfig) GetAccountID() string { return lc.configObj.AccountI
|
||||
func (lc *LocalConfig) GetContextName() string { return lc.configObj.ClusterName }
|
||||
func (lc *LocalConfig) GetCloudReportURL() string { return lc.configObj.CloudReportURL }
|
||||
func (lc *LocalConfig) GetCloudAPIURL() string { return lc.configObj.CloudAPIURL }
|
||||
func (lc *LocalConfig) IsStorageEnabled() bool { return lc.configObj.StorageEnabled }
|
||||
func (lc *LocalConfig) GetAccessKey() string { return lc.configObj.AccessKey }
|
||||
|
||||
func (lc *LocalConfig) GenerateAccountID() (string, error) {
|
||||
lc.configObj.AccountID = uuid.NewString()
|
||||
@@ -153,7 +154,8 @@ func (lc *LocalConfig) GenerateAccountID() (string, error) {
|
||||
return lc.configObj.AccountID, err
|
||||
}
|
||||
|
||||
func (lc *LocalConfig) DeleteAccountID() error {
|
||||
func (lc *LocalConfig) DeleteCredentials() error {
|
||||
lc.configObj.AccessKey = ""
|
||||
lc.configObj.AccountID = ""
|
||||
return lc.UpdateCachedConfig()
|
||||
}
|
||||
@@ -189,20 +191,16 @@ KS_CACHE // path to cached files
|
||||
var _ ITenantConfig = &ClusterConfig{}
|
||||
|
||||
type ClusterConfig struct {
|
||||
k8s *k8sinterface.KubernetesApi
|
||||
configObj *ConfigObj
|
||||
configMapNamespace string
|
||||
ksConfigMapName string
|
||||
ksCloudConfigMapName string
|
||||
k8s *k8sinterface.KubernetesApi
|
||||
configObj *ConfigObj
|
||||
configMapNamespace string
|
||||
}
|
||||
|
||||
func NewClusterConfig(k8s *k8sinterface.KubernetesApi, accountID, clusterName string, customClusterName string) *ClusterConfig {
|
||||
func NewClusterConfig(k8s *k8sinterface.KubernetesApi, accountID, accessKey, clusterName, customClusterName string) *ClusterConfig {
|
||||
c := &ClusterConfig{
|
||||
k8s: k8s,
|
||||
configObj: &ConfigObj{},
|
||||
ksConfigMapName: getKubescapeConfigMapName(),
|
||||
ksCloudConfigMapName: getKubescapeCloudConfigMapName(),
|
||||
configMapNamespace: GetConfigMapNamespace(),
|
||||
k8s: k8s,
|
||||
configObj: &ConfigObj{},
|
||||
configMapNamespace: GetConfigMapNamespace(),
|
||||
}
|
||||
|
||||
// first, load from file
|
||||
@@ -210,19 +208,14 @@ func NewClusterConfig(k8s *k8sinterface.KubernetesApi, accountID, clusterName st
|
||||
loadConfigFromFile(c.configObj)
|
||||
}
|
||||
|
||||
// second, load from configMap
|
||||
if c.existsConfigMap(c.ksConfigMapName) {
|
||||
c.updateConfigEmptyFieldsFromKubescapeConfigMap()
|
||||
}
|
||||
// second, load urls from config map
|
||||
c.updateConfigEmptyFieldsFromKubescapeConfigMap()
|
||||
|
||||
// third, load urls from cloudConfigMap
|
||||
if c.existsConfigMap(c.ksCloudConfigMapName) {
|
||||
c.updateConfigEmptyFieldsFromKubescapeCloudConfigMap()
|
||||
}
|
||||
// third, credentials from secret
|
||||
c.updateConfigEmptyFieldsFromCredentialsSecret()
|
||||
|
||||
updateAccountID(c.configObj, accountID)
|
||||
updateCredentials(c.configObj, accountID, accessKey)
|
||||
updateCloudURLs(c.configObj)
|
||||
updateStorageEnabled(c.configObj)
|
||||
|
||||
// If a custom cluster name is provided then set that name, else use the cluster's original name
|
||||
if customClusterName != "" {
|
||||
@@ -246,7 +239,7 @@ func (c *ClusterConfig) GetDefaultNS() string { return c.configMapNamespace
|
||||
func (c *ClusterConfig) GetAccountID() string { return c.configObj.AccountID }
|
||||
func (c *ClusterConfig) GetCloudReportURL() string { return c.configObj.CloudReportURL }
|
||||
func (c *ClusterConfig) GetCloudAPIURL() string { return c.configObj.CloudAPIURL }
|
||||
func (c *ClusterConfig) IsStorageEnabled() bool { return c.configObj.StorageEnabled }
|
||||
func (c *ClusterConfig) GetAccessKey() string { return c.configObj.AccessKey }
|
||||
|
||||
func (c *ClusterConfig) UpdateCachedConfig() error {
|
||||
logger.L().Debug("updating cached config", helpers.Interface("configObj", c.configObj))
|
||||
@@ -272,42 +265,78 @@ func (c *ClusterConfig) ToMapString() map[string]interface{} {
|
||||
}
|
||||
|
||||
func (c *ClusterConfig) updateConfigEmptyFieldsFromKubescapeConfigMap() error {
|
||||
configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Get(context.Background(), c.ksConfigMapName, metav1.GetOptions{})
|
||||
configMaps, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).List(context.Background(), metav1.ListOptions{
|
||||
LabelSelector: cloudConfigMapLabelSelector,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tempCO := ConfigObj{}
|
||||
if jsonConf, ok := configMap.Data["config.json"]; ok {
|
||||
if err = json.Unmarshal([]byte(jsonConf), &tempCO); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.configObj.updateEmptyFields(&tempCO)
|
||||
var ksConfigMap *corev1.ConfigMap
|
||||
var urlsConfigMap *corev1.ConfigMap
|
||||
if len(configMaps.Items) == 0 {
|
||||
// try to find configmaps by name (for backward compatibility)
|
||||
ksConfigMap, _ = c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Get(context.Background(), kubescapeConfigMapName, metav1.GetOptions{})
|
||||
urlsConfigMap, _ = c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Get(context.Background(), kubescapeCloudConfigMapName, metav1.GetOptions{})
|
||||
} else {
|
||||
// use the first configmap with the label
|
||||
ksConfigMap = &configMaps.Items[0]
|
||||
urlsConfigMap = &configMaps.Items[0]
|
||||
}
|
||||
|
||||
if ksConfigMap != nil {
|
||||
if jsonConf, ok := ksConfigMap.Data["clusterData"]; ok {
|
||||
tempCO := ConfigObj{}
|
||||
if err = json.Unmarshal([]byte(jsonConf), &tempCO); err != nil {
|
||||
return err
|
||||
}
|
||||
c.configObj.updateEmptyFields(&tempCO)
|
||||
}
|
||||
}
|
||||
|
||||
if urlsConfigMap != nil {
|
||||
if jsonConf, ok := urlsConfigMap.Data["services"]; ok {
|
||||
services, err := servicediscovery.GetServices(
|
||||
servicediscoveryv1.NewServiceDiscoveryStreamV1([]byte(jsonConf)),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if services.GetApiServerUrl() != "" {
|
||||
c.configObj.CloudAPIURL = services.GetApiServerUrl()
|
||||
}
|
||||
if services.GetReportReceiverHttpUrl() != "" {
|
||||
c.configObj.CloudReportURL = services.GetReportReceiverHttpUrl()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *ClusterConfig) updateConfigEmptyFieldsFromKubescapeCloudConfigMap() error {
|
||||
configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Get(context.Background(), c.ksCloudConfigMapName, metav1.GetOptions{})
|
||||
func (c *ClusterConfig) updateConfigEmptyFieldsFromCredentialsSecret() error {
|
||||
secrets, err := c.k8s.KubernetesClient.CoreV1().Secrets(c.configMapNamespace).List(context.Background(),
|
||||
metav1.ListOptions{LabelSelector: credsLabelSelectors})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if jsonConf, ok := configMap.Data["services"]; ok {
|
||||
services, err := servicediscovery.GetServices(
|
||||
servicediscoveryv1.NewServiceDiscoveryStreamV1([]byte(jsonConf)),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(secrets.Items) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if services.GetApiServerUrl() != "" {
|
||||
c.configObj.CloudAPIURL = services.GetApiServerUrl()
|
||||
}
|
||||
if services.GetReportReceiverHttpUrl() != "" {
|
||||
c.configObj.CloudReportURL = services.GetReportReceiverHttpUrl()
|
||||
if jsonConf, ok := secrets.Items[0].Data["account"]; ok {
|
||||
if account := string(jsonConf); account != "" {
|
||||
c.configObj.AccountID = account
|
||||
}
|
||||
}
|
||||
|
||||
if jsonConf, ok := secrets.Items[0].Data["accessKey"]; ok {
|
||||
if accessKey := string(jsonConf); accessKey != "" {
|
||||
c.configObj.AccessKey = accessKey
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -323,11 +352,6 @@ func loadConfigFromData(co *ConfigObj, data map[string]string) error {
|
||||
return e
|
||||
}
|
||||
|
||||
func (c *ClusterConfig) existsConfigMap(name string) bool {
|
||||
_, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Get(context.Background(), name, metav1.GetOptions{})
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func existsConfigFile() bool {
|
||||
_, err := os.ReadFile(ConfigFileFullPath())
|
||||
return err == nil
|
||||
@@ -349,8 +373,9 @@ func (c *ClusterConfig) GenerateAccountID() (string, error) {
|
||||
return c.configObj.AccountID, err
|
||||
}
|
||||
|
||||
func (c *ClusterConfig) DeleteAccountID() error {
|
||||
func (c *ClusterConfig) DeleteCredentials() error {
|
||||
c.configObj.AccountID = ""
|
||||
c.configObj.AccessKey = ""
|
||||
return c.UpdateCachedConfig()
|
||||
}
|
||||
|
||||
@@ -396,21 +421,6 @@ func AdoptClusterName(clusterName string) string {
|
||||
return re.ReplaceAllString(clusterName, "-")
|
||||
}
|
||||
|
||||
func getKubescapeConfigMapName() string {
|
||||
if n := os.Getenv(defaultConfigMapNameEnvVar); n != "" {
|
||||
return n
|
||||
}
|
||||
return kubescapeConfigMapName
|
||||
}
|
||||
|
||||
func getKubescapeCloudConfigMapName() string {
|
||||
if n := os.Getenv(defaultCloudConfigMapNameEnvVar); n != "" {
|
||||
return n
|
||||
}
|
||||
|
||||
return kubescapeCloudConfigMapName
|
||||
}
|
||||
|
||||
// GetConfigMapNamespace returns the namespace of the cluster config, which is the same for all in-cluster components
|
||||
func GetConfigMapNamespace() string {
|
||||
if n := os.Getenv(defaultConfigMapNamespaceEnvVar); n != "" {
|
||||
@@ -419,7 +429,15 @@ func GetConfigMapNamespace() string {
|
||||
return kubescapeNamespace
|
||||
}
|
||||
|
||||
func updateAccountID(configObj *ConfigObj, accountID string) {
|
||||
func updateCredentials(configObj *ConfigObj, accountID, accessKey string) {
|
||||
if accessKey != "" {
|
||||
configObj.AccessKey = accessKey
|
||||
}
|
||||
|
||||
if envAccessKey := os.Getenv(accessKeyEnvVar); envAccessKey != "" {
|
||||
configObj.AccessKey = envAccessKey
|
||||
}
|
||||
|
||||
if accountID != "" {
|
||||
configObj.AccountID = accountID
|
||||
}
|
||||
@@ -429,10 +447,6 @@ func updateAccountID(configObj *ConfigObj, accountID string) {
|
||||
}
|
||||
}
|
||||
|
||||
func updateStorageEnabled(configObj *ConfigObj) {
|
||||
configObj.StorageEnabled, _ = ParseBoolEnvVar(storageEnabledEnvVar, configObj.StorageEnabled)
|
||||
}
|
||||
|
||||
func getCloudURLsFromEnv(cloudURLs *CloudURLs) {
|
||||
// load from env
|
||||
if cloudAPIURL := os.Getenv(cloudApiUrlEnvVar); cloudAPIURL != "" {
|
||||
@@ -460,18 +474,53 @@ func updateCloudURLs(configObj *ConfigObj) {
|
||||
}
|
||||
|
||||
func initializeCloudAPI(c ITenantConfig) *v1.KSCloudAPI {
|
||||
logger.L().Debug("initializing KS Cloud API from config", helpers.String("accountID", c.GetAccountID()), helpers.String("cloudAPIURL", c.GetCloudAPIURL()), helpers.String("cloudReportURL", c.GetCloudReportURL()))
|
||||
cloud, err := v1.NewKSCloudAPI(c.GetCloudAPIURL(), c.GetCloudReportURL(), c.GetAccountID())
|
||||
if err != nil {
|
||||
logger.L().Fatal("failed to create KS Cloud client", helpers.Error(err))
|
||||
if ksCloud := getter.GetKSCloudAPIConnector(); ksCloud != nil {
|
||||
logger.L().Debug("KS Cloud API already initialized")
|
||||
|
||||
if val := c.GetCloudAPIURL(); val != "" && val != ksCloud.GetCloudAPIURL() {
|
||||
logger.L().Debug("updating KS Cloud API from config", helpers.String("old", ksCloud.GetCloudAPIURL()), helpers.String("new", val))
|
||||
ksCloud.SetCloudAPIURL(val)
|
||||
}
|
||||
if val := c.GetCloudReportURL(); val != "" && val != ksCloud.GetCloudReportURL() {
|
||||
logger.L().Debug("updating KS Cloud Report from config", helpers.String("old", ksCloud.GetCloudReportURL()), helpers.String("new", val))
|
||||
ksCloud.SetCloudReportURL(val)
|
||||
}
|
||||
if val := c.GetAccountID(); val != "" && val != ksCloud.GetAccountID() {
|
||||
logger.L().Debug("updating Account ID from config", helpers.String("old", ksCloud.GetAccountID()), helpers.String("new", val))
|
||||
ksCloud.SetAccountID(val)
|
||||
}
|
||||
if val := c.GetAccessKey(); val != "" && val != ksCloud.GetAccessKey() {
|
||||
logger.L().Debug("updating Access Key from config", helpers.Int("old (len)", len(ksCloud.GetAccessKey())), helpers.Int("new (len)", len(val)))
|
||||
ksCloud.SetAccessKey(val)
|
||||
}
|
||||
getter.SetKSCloudAPIConnector(ksCloud)
|
||||
} else {
|
||||
logger.L().Debug("initializing KS Cloud API from config", helpers.String("accountID", c.GetAccountID()), helpers.String("cloudAPIURL", c.GetCloudAPIURL()), helpers.String("cloudReportURL", c.GetCloudReportURL()))
|
||||
cloud, err := v1.NewKSCloudAPI(
|
||||
c.GetCloudAPIURL(),
|
||||
c.GetCloudReportURL(),
|
||||
c.GetAccountID(),
|
||||
c.GetAccessKey())
|
||||
if err != nil {
|
||||
logger.L().Fatal("failed to create KS Cloud client", helpers.Error(err))
|
||||
}
|
||||
getter.SetKSCloudAPIConnector(cloud)
|
||||
}
|
||||
getter.SetKSCloudAPIConnector(cloud)
|
||||
|
||||
return getter.GetKSCloudAPIConnector()
|
||||
}
|
||||
|
||||
func GetTenantConfig(accountID, clusterName, customClusterName string, k8s *k8sinterface.KubernetesApi) ITenantConfig {
|
||||
func GetTenantConfig(accountID, accessKey, clusterName, customClusterName string, k8s *k8sinterface.KubernetesApi) ITenantConfig {
|
||||
if !k8sinterface.IsConnectedToCluster() || k8s == nil {
|
||||
return NewLocalConfig(accountID, clusterName, customClusterName)
|
||||
return NewLocalConfig(accountID, accessKey, clusterName, customClusterName)
|
||||
}
|
||||
return NewClusterConfig(k8s, accountID, clusterName, customClusterName)
|
||||
return NewClusterConfig(k8s, accountID, accessKey, clusterName, customClusterName)
|
||||
}
|
||||
|
||||
// firstNonEmpty returns the first non-empty string
|
||||
func firstNonEmpty(s1, s2 string) string {
|
||||
if s1 != "" {
|
||||
return s1
|
||||
}
|
||||
return s2
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func TestGlobalKSCloudAPIConnector(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("initialized global connector should yield the same pointer", func(t *testing.T) {
|
||||
ksCloud, _ := v1.NewKSCloudAPI("test-123", "test-456", "account")
|
||||
ksCloud, _ := v1.NewKSCloudAPI("test-123", "test-456", "account", "token")
|
||||
SetKSCloudAPIConnector(ksCloud)
|
||||
|
||||
client := GetKSCloudAPIConnector()
|
||||
|
||||
@@ -129,6 +129,7 @@ type ScanInfo struct {
|
||||
HostSensorYamlPath string // Path to hostsensor file
|
||||
Local bool // Do not submit results
|
||||
AccountID string // account ID
|
||||
AccessKey string // access key
|
||||
FrameworkScan bool // false if scanning control
|
||||
ScanAll bool // true if scan all frameworks
|
||||
OmitRawResources bool // true if omit raw resources from the output
|
||||
|
||||
@@ -9,11 +9,15 @@ import (
|
||||
)
|
||||
|
||||
func (ks *Kubescape) SetCachedConfig(setConfig *metav1.SetConfig) error {
|
||||
tenant := cautils.GetTenantConfig("", "", "", nil)
|
||||
tenant := cautils.GetTenantConfig("", "", "", "", nil)
|
||||
|
||||
if setConfig.Account != "" {
|
||||
tenant.GetConfigObj().AccountID = setConfig.Account
|
||||
}
|
||||
if setConfig.AccessKey != "" {
|
||||
tenant.GetConfigObj().AccessKey = setConfig.AccessKey
|
||||
}
|
||||
|
||||
if setConfig.CloudAPIURL != "" {
|
||||
tenant.GetConfigObj().CloudAPIURL = setConfig.CloudAPIURL
|
||||
}
|
||||
@@ -26,13 +30,13 @@ func (ks *Kubescape) SetCachedConfig(setConfig *metav1.SetConfig) error {
|
||||
|
||||
// View cached configurations
|
||||
func (ks *Kubescape) ViewCachedConfig(viewConfig *metav1.ViewConfig) error {
|
||||
tenant := cautils.GetTenantConfig("", "", "", getKubernetesApi()) // change k8sinterface
|
||||
tenant := cautils.GetTenantConfig("", "", "", "", getKubernetesApi()) // change k8sinterface
|
||||
fmt.Fprintf(viewConfig.Writer, "%s\n", tenant.GetConfigObj().Config())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ks *Kubescape) DeleteCachedConfig(ctx context.Context, deleteConfig *metav1.DeleteConfig) error {
|
||||
|
||||
tenant := cautils.GetTenantConfig("", "", "", nil) // change k8sinterface
|
||||
tenant := cautils.GetTenantConfig("", "", "", "", nil) // change k8sinterface
|
||||
return tenant.DeleteCachedConfig(ctx)
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ func downloadArtifacts(ctx context.Context, downloadInfo *metav1.DownloadInfo) e
|
||||
}
|
||||
|
||||
func downloadConfigInputs(ctx context.Context, downloadInfo *metav1.DownloadInfo) error {
|
||||
tenant := cautils.GetTenantConfig(downloadInfo.AccountID, "", "", getKubernetesApi())
|
||||
tenant := cautils.GetTenantConfig(downloadInfo.AccountID, downloadInfo.AccessKey, "", "", getKubernetesApi())
|
||||
|
||||
controlsInputsGetter := getConfigInputsGetter(ctx, downloadInfo.Identifier, tenant.GetAccountID(), nil)
|
||||
controlInputs, err := controlsInputsGetter.GetControlsInputs(tenant.GetContextName())
|
||||
@@ -115,7 +115,7 @@ func downloadConfigInputs(ctx context.Context, downloadInfo *metav1.DownloadInfo
|
||||
}
|
||||
|
||||
func downloadExceptions(ctx context.Context, downloadInfo *metav1.DownloadInfo) error {
|
||||
tenant := cautils.GetTenantConfig(downloadInfo.AccountID, "", "", getKubernetesApi())
|
||||
tenant := cautils.GetTenantConfig(downloadInfo.AccountID, downloadInfo.AccessKey, "", "", getKubernetesApi())
|
||||
exceptionsGetter := getExceptionsGetter(ctx, "", tenant.GetAccountID(), nil)
|
||||
|
||||
exceptions, err := exceptionsGetter.GetExceptions(tenant.GetContextName())
|
||||
@@ -137,7 +137,7 @@ func downloadExceptions(ctx context.Context, downloadInfo *metav1.DownloadInfo)
|
||||
|
||||
func downloadAttackTracks(ctx context.Context, downloadInfo *metav1.DownloadInfo) error {
|
||||
var err error
|
||||
tenant := cautils.GetTenantConfig(downloadInfo.AccountID, "", "", getKubernetesApi())
|
||||
tenant := cautils.GetTenantConfig(downloadInfo.AccountID, downloadInfo.AccessKey, "", "", getKubernetesApi())
|
||||
|
||||
attackTracksGetter := getAttackTracksGetter(ctx, "", tenant.GetAccountID(), nil)
|
||||
|
||||
@@ -161,7 +161,7 @@ func downloadAttackTracks(ctx context.Context, downloadInfo *metav1.DownloadInfo
|
||||
|
||||
func downloadFramework(ctx context.Context, downloadInfo *metav1.DownloadInfo) error {
|
||||
|
||||
tenant := cautils.GetTenantConfig(downloadInfo.AccountID, "", "", getKubernetesApi())
|
||||
tenant := cautils.GetTenantConfig(downloadInfo.AccountID, downloadInfo.AccessKey, "", "", getKubernetesApi())
|
||||
|
||||
g := getPolicyGetter(ctx, nil, tenant.GetAccountID(), true, nil)
|
||||
|
||||
@@ -203,7 +203,7 @@ func downloadFramework(ctx context.Context, downloadInfo *metav1.DownloadInfo) e
|
||||
|
||||
func downloadControl(ctx context.Context, downloadInfo *metav1.DownloadInfo) error {
|
||||
|
||||
tenant := cautils.GetTenantConfig(downloadInfo.AccountID, "", "", getKubernetesApi())
|
||||
tenant := cautils.GetTenantConfig(downloadInfo.AccountID, downloadInfo.AccessKey, "", "", getKubernetesApi())
|
||||
|
||||
g := getPolicyGetter(ctx, nil, tenant.GetAccountID(), false, nil)
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ func getReporter(ctx context.Context, tenantConfig cautils.ITenantConfig, report
|
||||
if scanInfo.GetScanningContext() != cautils.ContextCluster {
|
||||
submitData = reporterv2.SubmitContextRepository
|
||||
}
|
||||
return reporterv2.NewReportEventReceiver(tenantConfig, reportID, submitData)
|
||||
return reporterv2.NewReportEventReceiver(tenantConfig, reportID, submitData, getter.GetKSCloudAPIConnector())
|
||||
}
|
||||
if tenantConfig.GetAccountID() == "" {
|
||||
// Add link only when scanning a cluster using a framework
|
||||
|
||||
@@ -54,14 +54,14 @@ func (ks *Kubescape) List(ctx context.Context, listPolicies *metav1.ListPolicies
|
||||
}
|
||||
|
||||
func listFrameworks(ctx context.Context, listPolicies *metav1.ListPolicies) ([]string, error) {
|
||||
tenant := cautils.GetTenantConfig(listPolicies.AccountID, "", "", getKubernetesApi()) // change k8sinterface
|
||||
tenant := cautils.GetTenantConfig(listPolicies.AccountID, listPolicies.AccessKey, "", "", getKubernetesApi()) // change k8sinterface
|
||||
policyGetter := getPolicyGetter(ctx, nil, tenant.GetAccountID(), true, nil)
|
||||
|
||||
return listFrameworksNames(policyGetter), nil
|
||||
}
|
||||
|
||||
func listControls(ctx context.Context, listPolicies *metav1.ListPolicies) ([]string, error) {
|
||||
tenant := cautils.GetTenantConfig(listPolicies.AccountID, "", "", getKubernetesApi()) // change k8sinterface
|
||||
tenant := cautils.GetTenantConfig(listPolicies.AccountID, listPolicies.AccessKey, "", "", getKubernetesApi()) // change k8sinterface
|
||||
|
||||
policyGetter := getPolicyGetter(ctx, nil, tenant.GetAccountID(), false, nil)
|
||||
return policyGetter.ListControls()
|
||||
@@ -69,7 +69,7 @@ func listControls(ctx context.Context, listPolicies *metav1.ListPolicies) ([]str
|
||||
|
||||
func listExceptions(ctx context.Context, listPolicies *metav1.ListPolicies) ([]string, error) {
|
||||
// load tenant metav1
|
||||
tenant := cautils.GetTenantConfig(listPolicies.AccountID, "", "", getKubernetesApi())
|
||||
tenant := cautils.GetTenantConfig(listPolicies.AccountID, listPolicies.AccessKey, "", "", getKubernetesApi())
|
||||
|
||||
var exceptionsNames []string
|
||||
ksCloudAPI := getExceptionsGetter(ctx, "", tenant.GetAccountID(), nil)
|
||||
|
||||
@@ -49,7 +49,7 @@ func getInterfaces(ctx context.Context, scanInfo *cautils.ScanInfo) componentInt
|
||||
}
|
||||
|
||||
// ================== setup tenant object ======================================
|
||||
tenantConfig := cautils.GetTenantConfig(scanInfo.AccountID, k8sinterface.GetContextName(), scanInfo.CustomClusterName, k8s)
|
||||
tenantConfig := cautils.GetTenantConfig(scanInfo.AccountID, scanInfo.AccessKey, k8sinterface.GetContextName(), scanInfo.CustomClusterName, k8s)
|
||||
|
||||
// Set submit behavior AFTER loading tenant config
|
||||
setSubmitBehavior(scanInfo, tenantConfig)
|
||||
|
||||
@@ -4,6 +4,7 @@ import "io"
|
||||
|
||||
type SetConfig struct {
|
||||
Account string
|
||||
AccessKey string
|
||||
CloudReportURL string
|
||||
CloudAPIURL string
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@ type DownloadInfo struct {
|
||||
Target string // type of artifact to download
|
||||
Identifier string // identifier of artifact to download
|
||||
AccountID string
|
||||
AccessKey string
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ type ListPolicies struct {
|
||||
Target string
|
||||
Format string
|
||||
AccountID string
|
||||
AccessKey string
|
||||
}
|
||||
|
||||
type ListResponse struct {
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -39,18 +37,17 @@ var _ reporter.IReport = &ReportEventReceiver{}
|
||||
|
||||
type ReportEventReceiver struct {
|
||||
reportTime time.Time
|
||||
httpClient *http.Client
|
||||
client *client.KSCloudAPI
|
||||
tenantConfig cautils.ITenantConfig
|
||||
eventReceiverURL *url.URL
|
||||
message string
|
||||
reportID string
|
||||
submitContext SubmitContext
|
||||
accountIdGenerated bool
|
||||
}
|
||||
|
||||
func NewReportEventReceiver(tenantConfig cautils.ITenantConfig, reportID string, submitContext SubmitContext) *ReportEventReceiver {
|
||||
func NewReportEventReceiver(tenantConfig cautils.ITenantConfig, reportID string, submitContext SubmitContext, client *client.KSCloudAPI) *ReportEventReceiver {
|
||||
return &ReportEventReceiver{
|
||||
httpClient: &http.Client{},
|
||||
client: client,
|
||||
tenantConfig: tenantConfig,
|
||||
reportID: reportID,
|
||||
submitContext: submitContext,
|
||||
@@ -69,6 +66,8 @@ func (report *ReportEventReceiver) Submit(ctx context.Context, opaSessionObj *ca
|
||||
return err
|
||||
}
|
||||
report.accountIdGenerated = true
|
||||
report.client.SetAccountID(accountID)
|
||||
getter.SetKSCloudAPIConnector(report.client)
|
||||
logger.L().Debug("generated account ID", helpers.String("account ID", accountID))
|
||||
}
|
||||
|
||||
@@ -78,7 +77,7 @@ func (report *ReportEventReceiver) Submit(ctx context.Context, opaSessionObj *ca
|
||||
}
|
||||
|
||||
if err := report.prepareReport(opaSessionObj); err != nil {
|
||||
return fmt.Errorf("failed to submit scan results. url: '%s', reason: %s", report.eventReceiverURL, err.Error())
|
||||
return fmt.Errorf("failed to submit scan results. url: '%s', reason: %s", report.getReportUrl(), err.Error())
|
||||
}
|
||||
|
||||
logger.L().Debug("", helpers.String("account ID", report.GetAccountID()))
|
||||
@@ -113,18 +112,20 @@ func (report *ReportEventReceiver) prepareReport(opaSessionObj *cautils.OPASessi
|
||||
}()
|
||||
}
|
||||
|
||||
var err error
|
||||
report.eventReceiverURL, err = client.GetPostureReportUrl(getter.GetKSCloudAPIConnector().GetCloudReportURL(), report.GetAccountID(), report.GetClusterName(), report.reportID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cautils.StartSpinner()
|
||||
defer cautils.StopSpinner()
|
||||
|
||||
return report.sendResources(opaSessionObj)
|
||||
}
|
||||
|
||||
func (report *ReportEventReceiver) getReportUrl() string {
|
||||
url, err := client.GetPostureReportUrl(report.client.GetCloudReportURL(), report.GetAccountID(), report.GetClusterName(), report.reportID)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return url.String()
|
||||
}
|
||||
|
||||
func (report *ReportEventReceiver) sendResources(opaSessionObj *cautils.OPASessionObj) error {
|
||||
splittedPostureReport := report.setSubReport(opaSessionObj)
|
||||
|
||||
@@ -234,19 +235,22 @@ func (report *ReportEventReceiver) sendReport(postureReport *reporthandlingv2.Po
|
||||
ReportNumber: counter,
|
||||
IsLastReport: isLastReport,
|
||||
}
|
||||
reqBody, err := json.Marshal(postureReport)
|
||||
if err != nil {
|
||||
return fmt.Errorf("in 'sendReport' failed to json.Marshal, reason: %v", err)
|
||||
}
|
||||
strResponse, err := getter.HttpPost(report.httpClient, report.eventReceiverURL.String(), nil, reqBody)
|
||||
logger.L().Debug("sending report",
|
||||
helpers.String("url", report.getReportUrl()),
|
||||
helpers.String("account", report.client.GetAccountID()),
|
||||
helpers.Int("accessKey length", len(report.client.GetAccessKey())),
|
||||
helpers.Int("reportNumber", counter),
|
||||
)
|
||||
|
||||
strResponse, err := report.client.SubmitReport(postureReport)
|
||||
if err != nil {
|
||||
// in case of error, we need to revert the generated account ID
|
||||
// otherwise the next run will fail using a non existing account ID
|
||||
if report.accountIdGenerated {
|
||||
report.tenantConfig.DeleteAccountID()
|
||||
report.tenantConfig.DeleteCredentials()
|
||||
}
|
||||
|
||||
return fmt.Errorf("%s, %v:%s", report.eventReceiverURL.String(), err, strResponse)
|
||||
return fmt.Errorf("%s, %v:%s", report.getReportUrl(), err, strResponse)
|
||||
}
|
||||
|
||||
// message is taken only from last report
|
||||
|
||||
@@ -8,9 +8,11 @@ import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
v1 "github.com/kubescape/backend/pkg/client/v1"
|
||||
logger "github.com/kubescape/go-logger"
|
||||
"github.com/kubescape/go-logger/prettylogger"
|
||||
"github.com/kubescape/kubescape/v2/core/cautils"
|
||||
"github.com/kubescape/kubescape/v2/core/cautils/getter"
|
||||
reporthandlingv2 "github.com/kubescape/opa-utils/reporthandling/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -22,6 +24,7 @@ var mxStdio sync.Mutex
|
||||
type TenantConfigMock struct {
|
||||
clusterName string
|
||||
accountID string
|
||||
accessKey string
|
||||
}
|
||||
|
||||
const testGeneratedAccountIDString = "6a1ff233-5297-4193-bb51-5d67bc841cbf"
|
||||
@@ -59,11 +62,16 @@ func (tcm *TenantConfigMock) GenerateAccountID() (string, error) {
|
||||
return testGeneratedAccountIDString, nil
|
||||
}
|
||||
|
||||
func (tcm *TenantConfigMock) DeleteAccountID() error {
|
||||
func (tcm *TenantConfigMock) DeleteCredentials() error {
|
||||
tcm.accountID = ""
|
||||
tcm.accessKey = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tcm *TenantConfigMock) GetAccessKey() string {
|
||||
return tcm.accessKey
|
||||
}
|
||||
|
||||
func TestDisplayMessage(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -77,6 +85,7 @@ func TestDisplayMessage(t *testing.T) {
|
||||
},
|
||||
"",
|
||||
SubmitContextScan,
|
||||
getter.GetKSCloudAPIConnector(),
|
||||
)
|
||||
|
||||
capture, clean := captureStderr(t)
|
||||
@@ -101,6 +110,7 @@ func TestDisplayMessage(t *testing.T) {
|
||||
},
|
||||
"",
|
||||
SubmitContextScan,
|
||||
getter.GetKSCloudAPIConnector(),
|
||||
)
|
||||
reporter.setMessage("message returned from server")
|
||||
|
||||
@@ -142,6 +152,7 @@ func TestPrepareReport(t *testing.T) {
|
||||
},
|
||||
"",
|
||||
SubmitContextScan,
|
||||
getter.GetKSCloudAPIConnector(),
|
||||
)
|
||||
|
||||
for _, tc := range testCases {
|
||||
@@ -171,25 +182,44 @@ func TestSubmit(t *testing.T) {
|
||||
srv := mockAPIServer(t)
|
||||
t.Cleanup(srv.Close)
|
||||
|
||||
const account = "1e3ae7c4-a8bb-4d7c-9bdf-eb86bc25e6bb"
|
||||
const accessKey = "ef871116-b4c9-4dbc-9abb-f422f025429f"
|
||||
|
||||
t.Run("should submit simple report", func(t *testing.T) {
|
||||
ksCloud, err := v1.NewKSCloudAPI(
|
||||
srv.Root(),
|
||||
srv.Root(),
|
||||
account,
|
||||
accessKey,
|
||||
v1.WithHTTPClient(hijackedClient(t, srv))) // re-route the http client to our mock server, as this is not easily configurable in the reporter.
|
||||
require.NoError(t, err)
|
||||
|
||||
reporter := NewReportEventReceiver(
|
||||
&TenantConfigMock{
|
||||
clusterName: "test",
|
||||
accountID: "1e3ae7c4-a8bb-4d7c-9bdf-eb86bc25e6bb",
|
||||
accountID: account,
|
||||
accessKey: accessKey,
|
||||
},
|
||||
"cbabd56f-bac6-416a-836b-b815ef347647",
|
||||
SubmitContextScan,
|
||||
ksCloud,
|
||||
)
|
||||
|
||||
opaSession := mockOPASessionObj(t)
|
||||
reporter.httpClient = hijackedClient(t, srv) // re-route the http client to our mock server, as this is not easily configurable in the reporter.
|
||||
|
||||
require.NoError(t,
|
||||
reporter.Submit(ctx, opaSession),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("should generate new customerGUID when no customerGUID", func(t *testing.T) {
|
||||
t.Run("should generate new account if account is empty", func(t *testing.T) {
|
||||
ksCloud, err := v1.NewKSCloudAPI(
|
||||
srv.Root(),
|
||||
srv.Root(),
|
||||
"",
|
||||
"",
|
||||
v1.WithHTTPClient(hijackedClient(t, srv))) // re-route the http client to our mock server, as this is not easily configurable in the reporter.
|
||||
require.NoError(t, err)
|
||||
|
||||
reporter := NewReportEventReceiver(
|
||||
&TenantConfigMock{
|
||||
clusterName: "test",
|
||||
@@ -197,10 +227,10 @@ func TestSubmit(t *testing.T) {
|
||||
},
|
||||
"cbabd56f-bac6-416a-836b-b815ef347647",
|
||||
SubmitContextScan,
|
||||
ksCloud,
|
||||
)
|
||||
|
||||
opaSession := mockOPASessionObj(t)
|
||||
reporter.httpClient = hijackedClient(t, srv)
|
||||
|
||||
capture, clean := captureStderr(t)
|
||||
if pretty, ok := logger.L().(*prettylogger.PrettyLogger); ok {
|
||||
@@ -222,20 +252,28 @@ func TestSubmit(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("should warn when no cluster name", func(t *testing.T) {
|
||||
ksCloud, err := v1.NewKSCloudAPI(
|
||||
srv.Root(),
|
||||
srv.Root(),
|
||||
account,
|
||||
accessKey,
|
||||
v1.WithHTTPClient(hijackedClient(t, srv))) // re-route the http client to our mock server, as this is not easily configurable in the reporter.
|
||||
require.NoError(t, err)
|
||||
|
||||
reporter := NewReportEventReceiver(
|
||||
&TenantConfigMock{
|
||||
clusterName: "",
|
||||
accountID: "1e3ae7c4-a8bb-4d7c-9bdf-eb86bc25e6bb",
|
||||
accountID: account,
|
||||
accessKey: accessKey,
|
||||
},
|
||||
"cbabd56f-bac6-416a-836b-b815ef347647",
|
||||
SubmitContextScan,
|
||||
ksCloud,
|
||||
)
|
||||
|
||||
opaSession := mockOPASessionObj(t)
|
||||
opaSession.Metadata.ScanMetadata.ScanningTarget = reporthandlingv2.Cluster
|
||||
|
||||
reporter.httpClient = hijackedClient(t, srv)
|
||||
|
||||
capture, clean := captureStderr(t)
|
||||
if pretty, ok := logger.L().(*prettylogger.PrettyLogger); ok {
|
||||
pretty.SetWriter(capture)
|
||||
@@ -275,6 +313,7 @@ func TestSetters(t *testing.T) {
|
||||
},
|
||||
"cbabd56f-bac6-416a-836b-b815ef347647",
|
||||
SubmitContextScan,
|
||||
getter.GetKSCloudAPIConnector(),
|
||||
)
|
||||
|
||||
t.Run("should set tenantConfig", func(t *testing.T) {
|
||||
|
||||
16
go.mod
16
go.mod
@@ -8,8 +8,8 @@ require (
|
||||
github.com/anchore/stereoscope v0.0.0-20230727211946-d1f3d766295e
|
||||
github.com/anchore/syft v0.86.1
|
||||
github.com/armosec/armoapi-go v0.0.256
|
||||
github.com/armosec/utils-go v0.0.20
|
||||
github.com/armosec/utils-k8s-go v0.0.17
|
||||
github.com/armosec/utils-go v0.0.40
|
||||
github.com/armosec/utils-k8s-go v0.0.18
|
||||
github.com/briandowns/spinner v1.23.0
|
||||
github.com/distribution/distribution v2.8.3+incompatible
|
||||
github.com/docker/distribution v2.8.2+incompatible
|
||||
@@ -17,11 +17,11 @@ require (
|
||||
github.com/francoispqt/gojay v1.2.13
|
||||
github.com/go-git/go-git/v5 v5.8.1
|
||||
github.com/google/go-containerregistry v0.16.1
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/johnfercher/maroto v0.42.0
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/jwalton/gchalk v1.3.0
|
||||
github.com/kubescape/backend v0.0.2
|
||||
github.com/kubescape/backend v0.0.11
|
||||
github.com/kubescape/go-git-url v0.0.25
|
||||
github.com/kubescape/go-logger v0.0.21
|
||||
github.com/kubescape/k8s-interface v0.0.142
|
||||
@@ -224,7 +224,7 @@ require (
|
||||
github.com/go-restruct/restruct v1.2.0-alpha // indirect
|
||||
github.com/go-test/deep v1.1.0 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/goccy/go-json v0.9.11 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/goccy/go-yaml v1.9.6 // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
@@ -366,7 +366,7 @@ require (
|
||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
||||
github.com/tonistiigi/vt100 v0.0.0-20230623042737-f9a4f7ef6531 // indirect
|
||||
github.com/transparency-dev/merkle v0.0.2 // indirect
|
||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||
github.com/ulikunitz/xz v0.5.11 // indirect
|
||||
github.com/uptrace/opentelemetry-go-extra/otelutil v0.2.2 // indirect
|
||||
github.com/uptrace/opentelemetry-go-extra/otelzap v0.2.2 // indirect
|
||||
github.com/uptrace/uptrace-go v1.18.0 // indirect
|
||||
@@ -404,8 +404,8 @@ require (
|
||||
go.step.sm/crypto v0.32.1 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.26.0 // indirect
|
||||
golang.org/x/crypto v0.14.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/crypto v0.13.0 // indirect
|
||||
golang.org/x/net v0.15.0 // indirect
|
||||
golang.org/x/oauth2 v0.12.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
|
||||
30
go.sum
30
go.sum
@@ -611,10 +611,10 @@ github.com/armosec/armoapi-go v0.0.256 h1:eV8WWQ1r+2D0KHhLA6ux6lx67+uqkYe/uVHrOU
|
||||
github.com/armosec/armoapi-go v0.0.256/go.mod h1:CJT5iH5VF30zjdQYXaQhsAm8IEHtM1T87HcFVXeLX54=
|
||||
github.com/armosec/gojay v1.2.15 h1:sSB2vnAvacUNkw9nzUYZKcPzhJOyk6/5LK2JCNdmoZY=
|
||||
github.com/armosec/gojay v1.2.15/go.mod h1:vzVAaay2TWJAngOpxu8aqLbye9jMgoKleuAOK+xsOts=
|
||||
github.com/armosec/utils-go v0.0.20 h1:bvr+TMumEYdMsGFGSsaQysST7K02nNROFvuajNuKPlw=
|
||||
github.com/armosec/utils-go v0.0.20/go.mod h1:ZEFiSv8KpTFNT19jHis1IengiF/BGDvg7tHmXo+cwxs=
|
||||
github.com/armosec/utils-k8s-go v0.0.17 h1:HUntJGR0/PHt7bp8S0zLhVcJ6sDz061Hc9mAM9ha1lA=
|
||||
github.com/armosec/utils-k8s-go v0.0.17/go.mod h1:FJRG/MRz7jT4ExSEYHIFsilVsAF11M+GJRhLl4PFZ4s=
|
||||
github.com/armosec/utils-go v0.0.40 h1:FdH8TxRG0SH3heKLrZ0Mj0eq5dNgk5go8/mteSCg2wY=
|
||||
github.com/armosec/utils-go v0.0.40/go.mod h1:pDaq3SNKQ8wliAAOq4B8re9MWmT0bX9di2Jn1jZI7lE=
|
||||
github.com/armosec/utils-k8s-go v0.0.18 h1:SBmj+j/5JrROVQVLjlHsoMcPZKK/AKWEK1SMMf3hd1U=
|
||||
github.com/armosec/utils-k8s-go v0.0.18/go.mod h1:FJRG/MRz7jT4ExSEYHIFsilVsAF11M+GJRhLl4PFZ4s=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
@@ -1021,8 +1021,8 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V
|
||||
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
|
||||
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-yaml v1.9.6 h1:KhAu1zf9JXnm3vbG49aDE0E5uEBUsM4uwD31/58ZWyI=
|
||||
github.com/goccy/go-yaml v1.9.6/go.mod h1:JubOolP3gh0HpiBc4BLRD4YmjEjHAmIIB2aaXKkTfoE=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
@@ -1148,8 +1148,9 @@ github.com/google/tink/go v1.7.0 h1:6Eox8zONGebBFcCBqkVmt60LaWZa6xg1cl/DwAh/J1w=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
|
||||
@@ -1352,8 +1353,8 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kubescape/backend v0.0.2 h1:s/aQ5/U9lLXBcVTuGz9vxGtD/koem6eojRTA3lRiyYo=
|
||||
github.com/kubescape/backend v0.0.2/go.mod h1:rEkxLNQdOGQNKAZekZBn0z/r8FIymBRSmwLFqkUenAQ=
|
||||
github.com/kubescape/backend v0.0.11 h1:M8AgIBUkAkSgx20604GW/uvnzQNhG7JxPyyIJQtJu1w=
|
||||
github.com/kubescape/backend v0.0.11/go.mod h1:ug9NFmmxT4DcQx3sgdLRzlLPWMKGHE/fpbcYUm5G5Qo=
|
||||
github.com/kubescape/go-git-url v0.0.25 h1:i7SSSC1+1m/Dg+4LV3erp0YklnWj1Z0cVlRxCT3Zy/0=
|
||||
github.com/kubescape/go-git-url v0.0.25/go.mod h1:IbVT7Wsxlghsa+YxI5KOx4k9VQJaa3z0kTaQz5D3nKM=
|
||||
github.com/kubescape/go-logger v0.0.21 h1:4ZRIEw3UGUH6BG/cH3yiqFipzQSfGAoCrxlsZuk37ys=
|
||||
@@ -1807,8 +1808,9 @@ github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqri
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
|
||||
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
|
||||
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/uptrace/opentelemetry-go-extra/otelutil v0.2.2 h1:CNznWHkrbA6o1q2H/BsH4tIHf4zbKNtndeoV+AH8z0U=
|
||||
github.com/uptrace/opentelemetry-go-extra/otelutil v0.2.2/go.mod h1:7YSrHCmYPHIXjTWnKSU7EGT0TFEcm3WwSeQquwCGg38=
|
||||
github.com/uptrace/opentelemetry-go-extra/otelzap v0.2.2 h1:uyrW06oJi4iWvhjPLVfk4qrSP2Zm0AMozKKDmp6i4pE=
|
||||
@@ -1980,8 +1982,8 @@ golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -2107,8 +2109,8 @@ golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
|
||||
29
httphandler/config/config.go
Normal file
29
httphandler/config/config.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Namespace string `mapstructure:"namespace"`
|
||||
ClusterName string `mapstructure:"clusterName"`
|
||||
ContinuousPostureScan bool `mapstructure:"continuousPostureScan"`
|
||||
}
|
||||
|
||||
// LoadConfig reads configuration from file or environment variables.
|
||||
func LoadConfig(path string) (Config, error) {
|
||||
viper.AddConfigPath(path)
|
||||
viper.SetConfigName("clusterData")
|
||||
viper.SetConfigType("json")
|
||||
|
||||
viper.AutomaticEnv()
|
||||
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
var config Config
|
||||
err = viper.Unmarshal(&config)
|
||||
return config, err
|
||||
}
|
||||
20
httphandler/config/credentials.go
Normal file
20
httphandler/config/credentials.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package config
|
||||
|
||||
var accessKey string
|
||||
var account string
|
||||
|
||||
func SetAccessKey(key string) {
|
||||
accessKey = key
|
||||
}
|
||||
|
||||
func GetAccessKey() string {
|
||||
return accessKey
|
||||
}
|
||||
|
||||
func SetAccount(accountId string) {
|
||||
account = accountId
|
||||
}
|
||||
|
||||
func GetAccount() string {
|
||||
return account
|
||||
}
|
||||
@@ -6,17 +6,18 @@ replace github.com/kubescape/kubescape/v2 => ../
|
||||
|
||||
require (
|
||||
github.com/armosec/armoapi-go v0.0.256
|
||||
github.com/armosec/utils-go v0.0.20
|
||||
github.com/armosec/utils-go v0.0.40
|
||||
github.com/go-openapi/runtime v0.26.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gorilla/schema v1.2.0
|
||||
github.com/kubescape/backend v0.0.2
|
||||
github.com/kubescape/backend v0.0.11
|
||||
github.com/kubescape/go-logger v0.0.21
|
||||
github.com/kubescape/k8s-interface v0.0.144
|
||||
github.com/kubescape/kubescape/v2 v2.0.0-00010101000000-000000000000
|
||||
github.com/kubescape/opa-utils v0.0.270
|
||||
github.com/kubescape/storage v0.0.20
|
||||
github.com/spf13/viper v1.16.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.45.0
|
||||
go.opentelemetry.io/otel v1.19.0
|
||||
@@ -111,7 +112,7 @@ require (
|
||||
github.com/aquasecurity/trivy v0.44.1 // indirect
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20230726112157-167ba4f2faeb // indirect
|
||||
github.com/armosec/gojay v1.2.15 // indirect
|
||||
github.com/armosec/utils-k8s-go v0.0.17 // indirect
|
||||
github.com/armosec/utils-k8s-go v0.0.18 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/aws/aws-sdk-go v1.44.312 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.20.0 // indirect
|
||||
@@ -358,7 +359,6 @@ require (
|
||||
github.com/spf13/cobra v1.7.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.16.0 // indirect
|
||||
github.com/spiffe/go-spiffe/v2 v2.1.6 // indirect
|
||||
github.com/stripe/stripe-go/v74 v74.28.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
|
||||
@@ -611,10 +611,10 @@ github.com/armosec/armoapi-go v0.0.256 h1:eV8WWQ1r+2D0KHhLA6ux6lx67+uqkYe/uVHrOU
|
||||
github.com/armosec/armoapi-go v0.0.256/go.mod h1:CJT5iH5VF30zjdQYXaQhsAm8IEHtM1T87HcFVXeLX54=
|
||||
github.com/armosec/gojay v1.2.15 h1:sSB2vnAvacUNkw9nzUYZKcPzhJOyk6/5LK2JCNdmoZY=
|
||||
github.com/armosec/gojay v1.2.15/go.mod h1:vzVAaay2TWJAngOpxu8aqLbye9jMgoKleuAOK+xsOts=
|
||||
github.com/armosec/utils-go v0.0.20 h1:bvr+TMumEYdMsGFGSsaQysST7K02nNROFvuajNuKPlw=
|
||||
github.com/armosec/utils-go v0.0.20/go.mod h1:ZEFiSv8KpTFNT19jHis1IengiF/BGDvg7tHmXo+cwxs=
|
||||
github.com/armosec/utils-k8s-go v0.0.17 h1:HUntJGR0/PHt7bp8S0zLhVcJ6sDz061Hc9mAM9ha1lA=
|
||||
github.com/armosec/utils-k8s-go v0.0.17/go.mod h1:FJRG/MRz7jT4ExSEYHIFsilVsAF11M+GJRhLl4PFZ4s=
|
||||
github.com/armosec/utils-go v0.0.40 h1:FdH8TxRG0SH3heKLrZ0Mj0eq5dNgk5go8/mteSCg2wY=
|
||||
github.com/armosec/utils-go v0.0.40/go.mod h1:pDaq3SNKQ8wliAAOq4B8re9MWmT0bX9di2Jn1jZI7lE=
|
||||
github.com/armosec/utils-k8s-go v0.0.18 h1:SBmj+j/5JrROVQVLjlHsoMcPZKK/AKWEK1SMMf3hd1U=
|
||||
github.com/armosec/utils-k8s-go v0.0.18/go.mod h1:FJRG/MRz7jT4ExSEYHIFsilVsAF11M+GJRhLl4PFZ4s=
|
||||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
@@ -1149,8 +1149,9 @@ github.com/google/tink/go v1.7.0 h1:6Eox8zONGebBFcCBqkVmt60LaWZa6xg1cl/DwAh/J1w=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
|
||||
@@ -1355,8 +1356,8 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kubescape/backend v0.0.2 h1:s/aQ5/U9lLXBcVTuGz9vxGtD/koem6eojRTA3lRiyYo=
|
||||
github.com/kubescape/backend v0.0.2/go.mod h1:rEkxLNQdOGQNKAZekZBn0z/r8FIymBRSmwLFqkUenAQ=
|
||||
github.com/kubescape/backend v0.0.11 h1:M8AgIBUkAkSgx20604GW/uvnzQNhG7JxPyyIJQtJu1w=
|
||||
github.com/kubescape/backend v0.0.11/go.mod h1:ug9NFmmxT4DcQx3sgdLRzlLPWMKGHE/fpbcYUm5G5Qo=
|
||||
github.com/kubescape/go-git-url v0.0.25 h1:i7SSSC1+1m/Dg+4LV3erp0YklnWj1Z0cVlRxCT3Zy/0=
|
||||
github.com/kubescape/go-git-url v0.0.25/go.mod h1:IbVT7Wsxlghsa+YxI5KOx4k9VQJaa3z0kTaQz5D3nKM=
|
||||
github.com/kubescape/go-logger v0.0.21 h1:4ZRIEw3UGUH6BG/cH3yiqFipzQSfGAoCrxlsZuk37ys=
|
||||
|
||||
@@ -3,6 +3,7 @@ package v1
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kubescape/kubescape/v2/httphandler/config"
|
||||
apisv1 "github.com/kubescape/opa-utils/httpserver/apis/v1"
|
||||
utilsmetav1 "github.com/kubescape/opa-utils/httpserver/meta/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -14,6 +15,7 @@ func TestDefaultScanInfo(t *testing.T) {
|
||||
assert.Equal(t, "", s.AccountID)
|
||||
assert.Equal(t, "v2", s.FormatVersion)
|
||||
assert.Equal(t, "json", s.Format)
|
||||
assert.Equal(t, "", s.AccessKey)
|
||||
assert.False(t, s.HostSensorEnabled.GetBool())
|
||||
assert.False(t, s.Local)
|
||||
assert.False(t, s.Submit)
|
||||
@@ -28,6 +30,24 @@ func TestGetScanCommand(t *testing.T) {
|
||||
assert.Equal(t, "abc", s.ScanID)
|
||||
assert.Equal(t, "v2", s.FormatVersion)
|
||||
assert.Equal(t, "json", s.Format)
|
||||
assert.Equal(t, "", s.AccessKey)
|
||||
assert.False(t, s.HostSensorEnabled.GetBool())
|
||||
assert.False(t, s.Local)
|
||||
assert.False(t, s.Submit)
|
||||
}
|
||||
|
||||
func TestGetScanCommandWithAccessKey(t *testing.T) {
|
||||
config.SetAccessKey("test-123")
|
||||
|
||||
req := utilsmetav1.PostScanRequest{
|
||||
TargetType: apisv1.KindFramework,
|
||||
}
|
||||
s := getScanCommand(&req, "abc")
|
||||
assert.Equal(t, "", s.AccountID)
|
||||
assert.Equal(t, "abc", s.ScanID)
|
||||
assert.Equal(t, "v2", s.FormatVersion)
|
||||
assert.Equal(t, "json", s.Format)
|
||||
assert.Equal(t, "test-123", s.AccessKey)
|
||||
assert.False(t, s.HostSensorEnabled.GetBool())
|
||||
assert.False(t, s.Local)
|
||||
assert.False(t, s.Submit)
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/kubescape/kubescape/v2/core/cautils"
|
||||
"github.com/kubescape/kubescape/v2/core/cautils/getter"
|
||||
"github.com/kubescape/kubescape/v2/core/core"
|
||||
"github.com/kubescape/kubescape/v2/httphandler/config"
|
||||
"github.com/kubescape/kubescape/v2/httphandler/storage"
|
||||
utilsapisv1 "github.com/kubescape/opa-utils/httpserver/apis/v1"
|
||||
utilsmetav1 "github.com/kubescape/opa-utils/httpserver/meta/v1"
|
||||
@@ -168,7 +169,8 @@ func defaultScanInfo() *cautils.ScanInfo {
|
||||
scanInfo := &cautils.ScanInfo{}
|
||||
scanInfo.FailThreshold = 100
|
||||
scanInfo.ComplianceThreshold = 0
|
||||
scanInfo.AccountID = envToString("KS_ACCOUNT", "") // publish results to Kubescape SaaS
|
||||
scanInfo.AccountID = envToString("KS_ACCOUNT_ID", config.GetAccount()) // publish results to Kubescape SaaS
|
||||
scanInfo.AccessKey = envToString("KS_ACCESS_KEY", config.GetAccessKey()) // 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
|
||||
|
||||
@@ -5,20 +5,21 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
v1 "github.com/kubescape/backend/pkg/client/v1"
|
||||
"github.com/kubescape/backend/pkg/servicediscovery"
|
||||
servicediscoveryv1 "github.com/kubescape/backend/pkg/servicediscovery/v1"
|
||||
"github.com/kubescape/backend/pkg/utils"
|
||||
logger "github.com/kubescape/go-logger"
|
||||
"github.com/kubescape/go-logger/helpers"
|
||||
"github.com/kubescape/go-logger/zaplogger"
|
||||
"github.com/kubescape/k8s-interface/k8sinterface"
|
||||
"github.com/kubescape/kubescape/v2/core/cautils"
|
||||
"github.com/kubescape/kubescape/v2/core/cautils/getter"
|
||||
"github.com/kubescape/kubescape/v2/httphandler/config"
|
||||
_ "github.com/kubescape/kubescape/v2/httphandler/docs"
|
||||
"github.com/kubescape/kubescape/v2/httphandler/listener"
|
||||
"github.com/kubescape/kubescape/v2/httphandler/storage"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
v1 "github.com/kubescape/backend/pkg/client/v1"
|
||||
"github.com/kubescape/backend/pkg/servicediscovery"
|
||||
servicediscoveryv1 "github.com/kubescape/backend/pkg/servicediscovery/v1"
|
||||
"github.com/kubescape/go-logger/helpers"
|
||||
"github.com/kubescape/go-logger/zaplogger"
|
||||
"github.com/kubescape/kubescape/v2/core/cautils/getter"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -27,12 +28,22 @@ const (
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg, err := config.LoadConfig("/etc/config")
|
||||
if err != nil {
|
||||
logger.L().Ctx(ctx).Error("load config error", helpers.Error(err))
|
||||
}
|
||||
|
||||
loadAndSetCredentials()
|
||||
|
||||
clusterName := getClusterName(cfg)
|
||||
|
||||
// to enable otel, set OTEL_COLLECTOR_SVC=otel-collector:4317
|
||||
if otelHost, present := os.LookupEnv("OTEL_COLLECTOR_SVC"); present {
|
||||
ctx = logger.InitOtel("kubescape",
|
||||
os.Getenv(cautils.BuildNumber),
|
||||
os.Getenv("ACCOUNT_ID"),
|
||||
os.Getenv("CLUSTER_NAME"),
|
||||
config.GetAccount(),
|
||||
clusterName,
|
||||
url.URL{Host: otelHost})
|
||||
defer logger.ShutdownOtel(ctx)
|
||||
}
|
||||
@@ -43,21 +54,19 @@ func main() {
|
||||
initializeLoggerName()
|
||||
initializeLoggerLevel()
|
||||
initializeSaaSEnv()
|
||||
initializeStorage()
|
||||
|
||||
initializeStorage(cfg)
|
||||
// traces will be created by otelmux.Middleware in SetupHTTPListener()
|
||||
|
||||
logger.L().Ctx(ctx).Fatal(listener.SetupHTTPListener().Error())
|
||||
}
|
||||
|
||||
func initializeStorage() {
|
||||
if !cautils.GetTenantConfig("", "", "", nil).IsStorageEnabled() {
|
||||
logger.L().Debug("storage disabled - skipping initialization")
|
||||
func initializeStorage(cfg config.Config) {
|
||||
if !cfg.ContinuousPostureScan {
|
||||
logger.L().Debug("continuous posture scan - skipping storage initialization")
|
||||
return
|
||||
}
|
||||
|
||||
namespace := getNamespace()
|
||||
logger.L().Debug("storage enabled", helpers.String("namespace", namespace))
|
||||
namespace := getNamespace(cfg)
|
||||
logger.L().Debug("initializing storage", helpers.String("namespace", namespace))
|
||||
|
||||
// for local storage, use the k8s config
|
||||
var config *rest.Config
|
||||
@@ -119,17 +128,51 @@ func initializeSaaSEnv() {
|
||||
return
|
||||
}
|
||||
|
||||
if ksCloud, err := v1.NewKSCloudAPI(backendServices.GetReportReceiverHttpUrl(), backendServices.GetApiServerUrl(), ""); err != nil {
|
||||
if ksCloud, err := v1.NewKSCloudAPI(backendServices.GetReportReceiverHttpUrl(), backendServices.GetApiServerUrl(), config.GetAccount(), config.GetAccessKey()); err != nil {
|
||||
logger.L().Fatal("failed to initialize cloud api", helpers.Error(err))
|
||||
} else {
|
||||
getter.SetKSCloudAPIConnector(ksCloud)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func getNamespace() string {
|
||||
func getClusterName(cfg config.Config) string {
|
||||
if clusterName, ok := os.LookupEnv("CLUSTER_NAME"); ok {
|
||||
return clusterName
|
||||
}
|
||||
return cfg.ClusterName
|
||||
}
|
||||
|
||||
func getNamespace(cfg config.Config) string {
|
||||
if ns, ok := os.LookupEnv("NAMESPACE"); ok {
|
||||
return ns
|
||||
}
|
||||
if cfg.Namespace != "" {
|
||||
return cfg.Namespace
|
||||
}
|
||||
|
||||
return defaultNamespace
|
||||
}
|
||||
|
||||
func loadAndSetCredentials() {
|
||||
credentialsPath := "/etc/credentials"
|
||||
if envVar := os.Getenv("KS_CREDENTIALS_SECRET_PATH"); envVar != "" {
|
||||
credentialsPath = envVar
|
||||
}
|
||||
|
||||
credentials, err := utils.LoadCredentialsFromFile(credentialsPath)
|
||||
if err != nil {
|
||||
logger.L().Error("failed to load credentials", helpers.Error(err))
|
||||
// fallback (backward compatibility)
|
||||
config.SetAccount(os.Getenv("ACCOUNT_ID"))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
logger.L().Info("credentials loaded from path",
|
||||
helpers.String("path", credentialsPath),
|
||||
helpers.Int("accessKeyLength", len(credentials.AccessKey)),
|
||||
helpers.Int("accountLength", len(credentials.Account)))
|
||||
|
||||
config.SetAccessKey(credentials.AccessKey)
|
||||
config.SetAccount(credentials.Account)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user