From 0cac7cb1a5768f6dc811fdf900cc6b518a883b80 Mon Sep 17 00:00:00 2001 From: Daniel-GrunbergerCA Date: Tue, 21 Dec 2021 09:23:38 +0200 Subject: [PATCH 01/17] fix kubeletcmd for marshalling --- go.mod | 2 +- go.sum | 4 ++-- hostsensorutils/hostsensorgetfrompod.go | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 4f903f82..ac4d14f5 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/armosec/armoapi-go v0.0.23 - github.com/armosec/k8s-interface v0.0.44 + github.com/armosec/k8s-interface v0.0.45 github.com/armosec/opa-utils v0.0.68 github.com/armosec/rbac-utils v0.0.9 github.com/armosec/utils-go v0.0.3 diff --git a/go.sum b/go.sum index b12f132f..21f29534 100644 --- a/go.sum +++ b/go.sum @@ -89,8 +89,8 @@ github.com/armosec/armoapi-go v0.0.23/go.mod h1:iaVVGyc23QGGzAdv4n+szGQg3Rbpixn9 github.com/armosec/k8s-interface v0.0.8/go.mod h1:xxS+V5QT3gVQTwZyAMMDrYLWGrfKOpiJ7Jfhfa0w9sM= github.com/armosec/k8s-interface v0.0.37/go.mod h1:vHxGWqD/uh6+GQb9Sqv7OGMs+Rvc2dsFVc0XtgRh1ZU= github.com/armosec/k8s-interface v0.0.43/go.mod h1:vHxGWqD/uh6+GQb9Sqv7OGMs+Rvc2dsFVc0XtgRh1ZU= -github.com/armosec/k8s-interface v0.0.44 h1:UsmVPo0GyyBuTVIP+F8rgHpEaZqQE7sUYjj1DT3kHmc= -github.com/armosec/k8s-interface v0.0.44/go.mod h1:vHxGWqD/uh6+GQb9Sqv7OGMs+Rvc2dsFVc0XtgRh1ZU= +github.com/armosec/k8s-interface v0.0.45 h1:LnncyBfarM29vXB0JwteSiLphVsiu7ONrNmmWSi377M= +github.com/armosec/k8s-interface v0.0.45/go.mod h1:vHxGWqD/uh6+GQb9Sqv7OGMs+Rvc2dsFVc0XtgRh1ZU= github.com/armosec/opa-utils v0.0.64/go.mod h1:6tQP8UDq2EvEfSqh8vrUdr/9QVSCG4sJfju1SXQOn4c= github.com/armosec/opa-utils v0.0.68 h1:qsmDjEVPdfJ6+hlSeoBZF5sgeR63HdtPfpVQIg0r1G0= github.com/armosec/opa-utils v0.0.68/go.mod h1:NVJEQ7695VyylqC7dHw2nD7MHIGJrRIXLgyej1onF64= diff --git a/hostsensorutils/hostsensorgetfrompod.go b/hostsensorutils/hostsensorgetfrompod.go index e6e9f480..2f77ba70 100644 --- a/hostsensorutils/hostsensorgetfrompod.go +++ b/hostsensorutils/hostsensorgetfrompod.go @@ -80,6 +80,13 @@ func (hsh *HostSensorHandler) sendAllPodsHTTPGETRequest(path, requestKind string hostSensorDataEnvelope.SetApiVersion(k8sinterface.JoinGroupVersion(hostsensor.GroupHostSensor, hostsensor.Version)) hostSensorDataEnvelope.SetKind(requestKind) hostSensorDataEnvelope.SetName(podList[podName]) + if requestKind == "KubeletCommandLine" { + data := map[string]interface{}{"fullCommand": string(resBytes)} + resBytesMarshal, err := json.Marshal(data) + if err == nil { + resBytes = resBytesMarshal + } + } hostSensorDataEnvelope.SetData(resBytes) res = append(res, hostSensorDataEnvelope) } From a1c34646f1ca3f30b0300f84661b79d37c20c95c Mon Sep 17 00:00:00 2001 From: Daniel-GrunbergerCA Date: Tue, 21 Dec 2021 13:34:31 +0200 Subject: [PATCH 02/17] waning for host sensor --- clihandler/initcliutils.go | 3 +- hostsensorutils/hostsensorgetfrompod.go | 44 ++++++++++++++++++++----- resourcehandler/k8sresources.go | 2 +- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/clihandler/initcliutils.go b/clihandler/initcliutils.go index 55a35b4e..9521d937 100644 --- a/clihandler/initcliutils.go +++ b/clihandler/initcliutils.go @@ -58,11 +58,12 @@ func getHostSensorHandler(scanInfo *cautils.ScanInfo, k8s *k8sinterface.Kubernet // we need to determined which controls needs host sensor if scanInfo.HostSensor.Get() == nil && hasHostSensorControls { scanInfo.HostSensor.SetBool(askUserForHostSensor()) + cautils.WarningDisplay(os.Stdout, "Warning: K8S nodes scanning is disabled. This is required to collect valuable data for certain controls. You can enable it using the --enable-host-scan flag\n") } if hostSensorVal := scanInfo.HostSensor.Get(); hostSensorVal != nil && *hostSensorVal { hostSensorHandler, err := hostsensorutils.NewHostSensorHandler(k8s) if err != nil { - glog.Errorf("failed to create host sensor: %v", err) + cautils.WarningDisplay(os.Stdout, fmt.Sprintf("Warning: failed to create host sensor: %v\n", err.Error())) return &hostsensorutils.HostSensorHandlerMock{} } return hostSensorHandler diff --git a/hostsensorutils/hostsensorgetfrompod.go b/hostsensorutils/hostsensorgetfrompod.go index 2f77ba70..c82f3d33 100644 --- a/hostsensorutils/hostsensorgetfrompod.go +++ b/hostsensorutils/hostsensorgetfrompod.go @@ -3,6 +3,7 @@ package hostsensorutils import ( "encoding/json" "fmt" + "strings" "sync" "github.com/armosec/k8s-interface/k8sinterface" @@ -80,13 +81,6 @@ func (hsh *HostSensorHandler) sendAllPodsHTTPGETRequest(path, requestKind string hostSensorDataEnvelope.SetApiVersion(k8sinterface.JoinGroupVersion(hostsensor.GroupHostSensor, hostsensor.Version)) hostSensorDataEnvelope.SetKind(requestKind) hostSensorDataEnvelope.SetName(podList[podName]) - if requestKind == "KubeletCommandLine" { - data := map[string]interface{}{"fullCommand": string(resBytes)} - resBytesMarshal, err := json.Marshal(data) - if err == nil { - resBytes = resBytesMarshal - } - } hostSensorDataEnvelope.SetData(resBytes) res = append(res, hostSensorDataEnvelope) } @@ -112,7 +106,41 @@ func (hsh *HostSensorHandler) GetLinuxSecurityHardeningStatus() ([]hostsensor.Ho // return list of KubeletCommandLine func (hsh *HostSensorHandler) GetKubeletCommandLine() ([]hostsensor.HostSensorDataEnvelope, error) { // loop over pods and port-forward it to each of them - return hsh.sendAllPodsHTTPGETRequest("/kubeletCommandLine", "KubeletCommandLine") + resps, err := hsh.sendAllPodsHTTPGETRequest("/kubeletCommandLine", "KubeletCommandLine") + if err != nil { + return resps, err + } + for resp := range resps { + data := makeCmdLineMap(string(resps[resp].Data)) + resBytesMarshal, err := json.Marshal(data) + // TODO catch error + if err == nil { + resps[resp].Data = json.RawMessage(resBytesMarshal) + } + } + + return resps, nil + +} + +func makeCmdLineMap(fullCommand string) map[string]interface{} { + + commands := strings.Split(fullCommand, " ") + if len(commands) < 1 { + return nil + } + command := commands[0] + var cmdMap = make(map[string]interface{}) + cmdMap["command"] = command + for _, cmd := range commands { + splitted := strings.Split(cmd, "=") + if len(splitted) == 2 { + if strings.HasPrefix(splitted[0], "--") { + cmdMap[splitted[0][2:]] = splitted[1] + } + } + } + return cmdMap } // return list of diff --git a/resourcehandler/k8sresources.go b/resourcehandler/k8sresources.go index 4bcc499f..5e56a696 100644 --- a/resourcehandler/k8sresources.go +++ b/resourcehandler/k8sresources.go @@ -59,7 +59,7 @@ func (k8sHandler *K8sResourceHandler) GetResources(frameworks []reporthandling.F return k8sResourcesMap, allResources, err } if err := k8sHandler.collectHostResources(allResources, k8sResourcesMap); err != nil { - return k8sResourcesMap, allResources, err + cautils.WarningDisplay(os.Stdout, "Warning: failed to collect host sensor resources\n") } if err := k8sHandler.collectRbacResources(allResources); err != nil { From 35682bf5b858d41c9265817b59c25259b1db43b9 Mon Sep 17 00:00:00 2001 From: Daniel-GrunbergerCA Date: Tue, 21 Dec 2021 19:02:16 +0200 Subject: [PATCH 03/17] pull regoes from dev --- cautils/getter/downloadreleasedpolicy.go | 2 +- hostsensorutils/hostsensorgetfrompod.go | 2 +- opaprocessor/processorhandler.go | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/cautils/getter/downloadreleasedpolicy.go b/cautils/getter/downloadreleasedpolicy.go index 9b6f9f86..75ca0529 100644 --- a/cautils/getter/downloadreleasedpolicy.go +++ b/cautils/getter/downloadreleasedpolicy.go @@ -18,7 +18,7 @@ type DownloadReleasedPolicy struct { func NewDownloadReleasedPolicy() *DownloadReleasedPolicy { return &DownloadReleasedPolicy{ - gs: gitregostore.NewDefaultGitRegoStore(-1), + gs: gitregostore.InitGitRegoStore("https://api.github.com/repos", "armosec", "regolibrary", "git/trees", "", "dev", -1), } } diff --git a/hostsensorutils/hostsensorgetfrompod.go b/hostsensorutils/hostsensorgetfrompod.go index 69d81301..30519bd5 100644 --- a/hostsensorutils/hostsensorgetfrompod.go +++ b/hostsensorutils/hostsensorgetfrompod.go @@ -157,7 +157,7 @@ func (hsh *HostSensorHandler) GetOsReleaseFile() ([]hostsensor.HostSensorDataEnv // return list of func (hsh *HostSensorHandler) GetKubeletConfigurations() ([]hostsensor.HostSensorDataEnvelope, error) { // loop over pods and port-forward it to each of them - res, err := hsh.sendAllPodsHTTPGETRequest("/kubeletConfigurations", "KubeletConfigurations") // empty kind, will be overridden + res, err := hsh.sendAllPodsHTTPGETRequest("/kubeletConfigurations", "KubeletConfiguration") // empty kind, will be overridden for resIdx := range res { jsonBytes, err := yaml.YAMLToJSON(res[resIdx].Data) if err != nil { diff --git a/opaprocessor/processorhandler.go b/opaprocessor/processorhandler.go index 7a320b92..6015be54 100644 --- a/opaprocessor/processorhandler.go +++ b/opaprocessor/processorhandler.go @@ -171,7 +171,6 @@ func (opap *OPAProcessor) processRule(rule *reporthandling.PolicyRule) (*reporth } inputRawResources := workloadinterface.ListMetaToMap(inputResources) - ruleReport, err := opap.runOPAOnSingleRule(rule, inputRawResources, ruleData) if err != nil { // ruleReport.RuleStatus.Status = reporthandling.StatusFailed From 972793b98a7b0faa5915e7af5a83380716876354 Mon Sep 17 00:00:00 2001 From: Daniel-GrunbergerCA Date: Tue, 21 Dec 2021 20:27:23 +0200 Subject: [PATCH 04/17] print json --- opaprocessor/processorhandler.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/opaprocessor/processorhandler.go b/opaprocessor/processorhandler.go index 6015be54..6a03d967 100644 --- a/opaprocessor/processorhandler.go +++ b/opaprocessor/processorhandler.go @@ -2,6 +2,7 @@ package opaprocessor import ( "context" + "encoding/json" "fmt" "time" @@ -171,6 +172,9 @@ func (opap *OPAProcessor) processRule(rule *reporthandling.PolicyRule) (*reporth } inputRawResources := workloadinterface.ListMetaToMap(inputResources) + jsonStr, _ := json.Marshal(inputRawResources) + fmt.Println(jsonStr) + ruleReport, err := opap.runOPAOnSingleRule(rule, inputRawResources, ruleData) if err != nil { // ruleReport.RuleStatus.Status = reporthandling.StatusFailed From cfa3993b79dfd8fdf0dbf0631af304f928d56f31 Mon Sep 17 00:00:00 2001 From: Daniel-GrunbergerCA Date: Tue, 21 Dec 2021 20:31:12 +0200 Subject: [PATCH 05/17] print json --- opaprocessor/processorhandler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opaprocessor/processorhandler.go b/opaprocessor/processorhandler.go index 6a03d967..374f1923 100644 --- a/opaprocessor/processorhandler.go +++ b/opaprocessor/processorhandler.go @@ -173,7 +173,7 @@ func (opap *OPAProcessor) processRule(rule *reporthandling.PolicyRule) (*reporth inputRawResources := workloadinterface.ListMetaToMap(inputResources) jsonStr, _ := json.Marshal(inputRawResources) - fmt.Println(jsonStr) + fmt.Println(string(jsonStr)) ruleReport, err := opap.runOPAOnSingleRule(rule, inputRawResources, ruleData) if err != nil { From ad94ac7595e3ddbb8881f958ea07af70e6c71359 Mon Sep 17 00:00:00 2001 From: Daniel-GrunbergerCA Date: Wed, 22 Dec 2021 08:29:35 +0200 Subject: [PATCH 06/17] rm json print --- opaprocessor/processorhandler.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/opaprocessor/processorhandler.go b/opaprocessor/processorhandler.go index 374f1923..7a320b92 100644 --- a/opaprocessor/processorhandler.go +++ b/opaprocessor/processorhandler.go @@ -2,7 +2,6 @@ package opaprocessor import ( "context" - "encoding/json" "fmt" "time" @@ -172,8 +171,6 @@ func (opap *OPAProcessor) processRule(rule *reporthandling.PolicyRule) (*reporth } inputRawResources := workloadinterface.ListMetaToMap(inputResources) - jsonStr, _ := json.Marshal(inputRawResources) - fmt.Println(string(jsonStr)) ruleReport, err := opap.runOPAOnSingleRule(rule, inputRawResources, ruleData) if err != nil { From e49499f08574cbfd21182b83530224d389b2c5bd Mon Sep 17 00:00:00 2001 From: Daniel-GrunbergerCA Date: Mon, 27 Dec 2021 08:45:50 +0200 Subject: [PATCH 07/17] use regoes from master --- cautils/getter/downloadreleasedpolicy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cautils/getter/downloadreleasedpolicy.go b/cautils/getter/downloadreleasedpolicy.go index 75ca0529..9b6f9f86 100644 --- a/cautils/getter/downloadreleasedpolicy.go +++ b/cautils/getter/downloadreleasedpolicy.go @@ -18,7 +18,7 @@ type DownloadReleasedPolicy struct { func NewDownloadReleasedPolicy() *DownloadReleasedPolicy { return &DownloadReleasedPolicy{ - gs: gitregostore.InitGitRegoStore("https://api.github.com/repos", "armosec", "regolibrary", "git/trees", "", "dev", -1), + gs: gitregostore.NewDefaultGitRegoStore(-1), } } From accd80eda8c8da6d7aefa1ec5fd936085b307850 Mon Sep 17 00:00:00 2001 From: Daniel-GrunbergerCA Date: Tue, 28 Dec 2021 09:07:50 +0200 Subject: [PATCH 08/17] rm cmdline map --- go.mod | 4 ++-- go.sum | 7 ++++--- hostsensorutils/hostsensorgetfrompod.go | 24 ++---------------------- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/go.mod b/go.mod index 72545313..ce063198 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,9 @@ module github.com/armosec/kubescape go 1.17 require ( - github.com/armosec/armoapi-go v0.0.23 + github.com/armosec/armoapi-go v0.0.40 github.com/armosec/k8s-interface v0.0.50 - github.com/armosec/opa-utils v0.0.75 + github.com/armosec/opa-utils v0.0.78 github.com/armosec/rbac-utils v0.0.9 github.com/armosec/utils-go v0.0.3 github.com/briandowns/spinner v1.18.0 diff --git a/go.sum b/go.sum index eea11167..525a97a2 100644 --- a/go.sum +++ b/go.sum @@ -84,15 +84,16 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armosec/armoapi-go v0.0.2/go.mod h1:vIK17yoKbJRQyZXWWLe3AqfqCRITxW8qmSkApyq5xFs= -github.com/armosec/armoapi-go v0.0.23 h1:jqoLIWM5CR7DCD9fpFgN0ePqtHvOCoZv/XzCwsUluJU= github.com/armosec/armoapi-go v0.0.23/go.mod h1:iaVVGyc23QGGzAdv4n+szGQg3Rbpixn9yQTU3qWRpaw= +github.com/armosec/armoapi-go v0.0.40 h1:KQRJXFqw95s6cV7HoGgw1x8qrRZ9eNVze//yQbo24Lk= +github.com/armosec/armoapi-go v0.0.40/go.mod h1:iaVVGyc23QGGzAdv4n+szGQg3Rbpixn9yQTU3qWRpaw= github.com/armosec/k8s-interface v0.0.8/go.mod h1:xxS+V5QT3gVQTwZyAMMDrYLWGrfKOpiJ7Jfhfa0w9sM= github.com/armosec/k8s-interface v0.0.37/go.mod h1:vHxGWqD/uh6+GQb9Sqv7OGMs+Rvc2dsFVc0XtgRh1ZU= github.com/armosec/k8s-interface v0.0.50 h1:iLPGI0j85vwKANr9QDAnba4Efjg3DyIJg15jRJdvOnc= github.com/armosec/k8s-interface v0.0.50/go.mod h1:vHxGWqD/uh6+GQb9Sqv7OGMs+Rvc2dsFVc0XtgRh1ZU= github.com/armosec/opa-utils v0.0.64/go.mod h1:6tQP8UDq2EvEfSqh8vrUdr/9QVSCG4sJfju1SXQOn4c= -github.com/armosec/opa-utils v0.0.75 h1:GBI3K18xc3WXJHIorIu4bGNAsfMYHUc1x7zueDz2ZbY= -github.com/armosec/opa-utils v0.0.75/go.mod h1:L7d+uiIIXAZ3LEyKtmEIbMcI1hWgWaXGpn5zVCqzwSU= +github.com/armosec/opa-utils v0.0.78 h1:wFkVqJ1vEftn3E1hHdUfKlp5xHgof616ljyKKebuNkI= +github.com/armosec/opa-utils v0.0.78/go.mod h1:ZOXYVTtuyrV4TldcfbzgRqP6F9Drlf4hB0zr210OXgM= github.com/armosec/rbac-utils v0.0.1/go.mod h1:pQ8CBiij8kSKV7aeZm9FMvtZN28VgA7LZcYyTWimq40= github.com/armosec/rbac-utils v0.0.9 h1:rIOWp4K7BELUNX32ktSjVbb8d/0SpH7W76W6Tf+8rzw= github.com/armosec/rbac-utils v0.0.9/go.mod h1:Ex/IdGWhGv9HZq6Hs8N/ApzCKSIvpNe/ETqDfnuyah0= diff --git a/hostsensorutils/hostsensorgetfrompod.go b/hostsensorutils/hostsensorgetfrompod.go index 30519bd5..906e7ca9 100644 --- a/hostsensorutils/hostsensorgetfrompod.go +++ b/hostsensorutils/hostsensorgetfrompod.go @@ -3,7 +3,6 @@ package hostsensorutils import ( "encoding/json" "fmt" - "strings" "sync" "github.com/armosec/k8s-interface/k8sinterface" @@ -110,7 +109,8 @@ func (hsh *HostSensorHandler) GetKubeletCommandLine() ([]hostsensor.HostSensorDa return resps, err } for resp := range resps { - data := makeCmdLineMap(string(resps[resp].Data)) + var data = make(map[string]interface{}) + data["fullCommand"] = string(resps[resp].Data) resBytesMarshal, err := json.Marshal(data) // TODO catch error if err == nil { @@ -122,26 +122,6 @@ func (hsh *HostSensorHandler) GetKubeletCommandLine() ([]hostsensor.HostSensorDa } -func makeCmdLineMap(fullCommand string) map[string]interface{} { - - commands := strings.Split(fullCommand, " ") - if len(commands) < 1 { - return nil - } - command := commands[0] - var cmdMap = make(map[string]interface{}) - cmdMap["command"] = command - for _, cmd := range commands { - splitted := strings.Split(cmd, "=") - if len(splitted) == 2 { - if strings.HasPrefix(splitted[0], "--") { - cmdMap[splitted[0][2:]] = splitted[1] - } - } - } - return cmdMap -} - // return list of func (hsh *HostSensorHandler) GetKernelVersion() ([]hostsensor.HostSensorDataEnvelope, error) { // loop over pods and port-forward it to each of them From 5f7391a76b228328376e3378ce20d6cb4be656b6 Mon Sep 17 00:00:00 2001 From: Daniel-GrunbergerCA Date: Tue, 28 Dec 2021 09:20:05 +0200 Subject: [PATCH 09/17] stdout to stderror --- clihandler/initcliutils.go | 6 +++--- resourcehandler/k8sresources.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clihandler/initcliutils.go b/clihandler/initcliutils.go index cc7ebb35..47c9bdfe 100644 --- a/clihandler/initcliutils.go +++ b/clihandler/initcliutils.go @@ -58,12 +58,12 @@ func getHostSensorHandler(scanInfo *cautils.ScanInfo, k8s *k8sinterface.Kubernet // we need to determined which controls needs host sensor if scanInfo.HostSensor.Get() == nil && hasHostSensorControls { scanInfo.HostSensor.SetBool(askUserForHostSensor()) - cautils.WarningDisplay(os.Stdout, "Warning: K8S nodes scanning is disabled. This is required to collect valuable data for certain controls. You can enable it using the --enable-host-scan flag\n") + cautils.WarningDisplay(os.Stderr, "Warning: Kubernetes cluster nodes scanning is disabled. This is required to collect valuable data for certain controls. You can enable it using the --enable-host-scan flag\n") } if hostSensorVal := scanInfo.HostSensor.Get(); hostSensorVal != nil && *hostSensorVal { hostSensorHandler, err := hostsensorutils.NewHostSensorHandler(k8s) if err != nil { - cautils.WarningDisplay(os.Stdout, fmt.Sprintf("Warning: failed to create host sensor: %v\n", err.Error())) + cautils.WarningDisplay(os.Stderr, fmt.Sprintf("Warning: failed to create host sensor: %v\n", err.Error())) return &hostsensorutils.HostSensorHandlerMock{} } return hostSensorHandler @@ -153,7 +153,7 @@ func setPolicyGetter(scanInfo *cautils.ScanInfo, customerGUID string) { func setDownloadReleasedPolicy(scanInfo *cautils.ScanInfo) { g := getter.NewDownloadReleasedPolicy() // download policy from github release if err := g.SetRegoObjects(); err != nil { // if failed to pull policy, fallback to cache - cautils.WarningDisplay(os.Stdout, "Warning: failed to get policies from github release, loading policies from cache\n") + cautils.WarningDisplay(os.Stderr, "Warning: failed to get policies from github release, loading policies from cache\n") scanInfo.PolicyGetter = getter.NewLoadPolicy(getDefaultFrameworksPaths()) } else { scanInfo.PolicyGetter = g diff --git a/resourcehandler/k8sresources.go b/resourcehandler/k8sresources.go index 3aa926ad..75528038 100644 --- a/resourcehandler/k8sresources.go +++ b/resourcehandler/k8sresources.go @@ -61,14 +61,14 @@ func (k8sHandler *K8sResourceHandler) GetResources(frameworks []reporthandling.F return k8sResourcesMap, allResources, err } if err := k8sHandler.collectHostResources(allResources, k8sResourcesMap); err != nil { - cautils.WarningDisplay(os.Stdout, "Warning: failed to collect host sensor resources\n") + cautils.WarningDisplay(os.Stderr, "Warning: failed to collect host sensor resources\n") } if err := k8sHandler.collectRbacResources(allResources); err != nil { - cautils.WarningDisplay(os.Stdout, "Warning: failed to collect rbac resources\n") + cautils.WarningDisplay(os.Stderr, "Warning: failed to collect rbac resources\n") } if err := getCloudProviderDescription(allResources, k8sResourcesMap); err != nil { - cautils.WarningDisplay(os.Stdout, fmt.Sprintf("Warning: %v\n", err.Error())) + cautils.WarningDisplay(os.Stderr, fmt.Sprintf("Warning: %v\n", err.Error())) } cautils.StopSpinner() From 1b0e2b87de8d701d037857da6e9c6e432be8316d Mon Sep 17 00:00:00 2001 From: dwertent Date: Tue, 28 Dec 2021 10:47:12 +0200 Subject: [PATCH 10/17] Handle all resources failure --- clihandler/initcli.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clihandler/initcli.go b/clihandler/initcli.go index 0d3b1735..c8faee0f 100644 --- a/clihandler/initcli.go +++ b/clihandler/initcli.go @@ -124,7 +124,7 @@ func ScanCliSetup(scanInfo *cautils.ScanInfo) error { // print report url interfaces.report.DisplayReportURL() - if score >= float32(scanInfo.FailThreshold) { + if score > float32(scanInfo.FailThreshold) { return fmt.Errorf("scan risk-score %.2f is above permitted threshold %d", score, scanInfo.FailThreshold) } From 716bdaaf38393e52666257ecaa5c3e9ecc1c06e0 Mon Sep 17 00:00:00 2001 From: dwertent Date: Wed, 29 Dec 2021 12:06:48 +0200 Subject: [PATCH 11/17] support kind List --- resourcehandler/filesloader.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/resourcehandler/filesloader.go b/resourcehandler/filesloader.go index 25cc7e74..c4052fe2 100644 --- a/resourcehandler/filesloader.go +++ b/resourcehandler/filesloader.go @@ -213,7 +213,11 @@ func readYamlFile(yamlFile []byte) ([]workloadinterface.IMetadata, []error) { } if obj, ok := j.(map[string]interface{}); ok { if o := objectsenvelopes.NewObject(obj); o != nil { - yamlObjs = append(yamlObjs, o) + if o.GetKind() == "List" { + yamlObjs = append(yamlObjs, handleListObject(o)...) + } else { + yamlObjs = append(yamlObjs, o) + } } } else { errs = append(errs, fmt.Errorf("failed to convert yaml file to map[string]interface, file content: %v", j)) @@ -303,3 +307,20 @@ func getFileFormat(filePath string) FileFormat { return FileFormat(filePath) } } + +// handleListObject handle a List manifest +func handleListObject(obj workloadinterface.IMetadata) []workloadinterface.IMetadata { + yamlObjs := []workloadinterface.IMetadata{} + if i, ok := workloadinterface.InspectMap(obj.GetObject(), "items"); ok && i != nil { + if items, ok := i.([]interface{}); ok && items != nil { + for item := range items { + if m, ok := items[item].(map[string]interface{}); ok && m != nil { + if o := objectsenvelopes.NewObject(m); o != nil { + yamlObjs = append(yamlObjs, o) + } + } + } + } + } + return yamlObjs +} From f22f60508fff276eca726ce33b050470a7762fc4 Mon Sep 17 00:00:00 2001 From: yiscah Date: Wed, 29 Dec 2021 16:23:14 +0200 Subject: [PATCH 12/17] rbacTable and rbac struct deprecated --- cautils/rbac.go | 10 ---------- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/cautils/rbac.go b/cautils/rbac.go index 47667cab..61eac56a 100644 --- a/cautils/rbac.go +++ b/cautils/rbac.go @@ -43,16 +43,6 @@ func (rbacObjects *RBACObjects) ListAllResources() (map[string]workloadinterface func (rbacObjects *RBACObjects) rbacObjectsToResources(resources *rbacutils.RbacObjects) (map[string]workloadinterface.IMetadata, error) { allresources := map[string]workloadinterface.IMetadata{} // wrap rbac aggregated objects in IMetadata and add to allresources - rbacIMeta, err := rbacutils.RbacObjectIMetadataWrapper(resources.Rbac) - if err != nil { - return nil, err - } - allresources[rbacIMeta.GetID()] = rbacIMeta - rbacTableIMeta, err := rbacutils.RbacTableObjectIMetadataWrapper(resources.RbacT) - if err != nil { - return nil, err - } - allresources[rbacTableIMeta.GetID()] = rbacTableIMeta SA2WLIDmapIMeta, err := rbacutils.SA2WLIDmapIMetadataWrapper(resources.SA2WLIDmap) if err != nil { return nil, err diff --git a/go.mod b/go.mod index ce063198..1be3fc6a 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/armosec/armoapi-go v0.0.40 github.com/armosec/k8s-interface v0.0.50 github.com/armosec/opa-utils v0.0.78 - github.com/armosec/rbac-utils v0.0.9 + github.com/armosec/rbac-utils v0.0.10 github.com/armosec/utils-go v0.0.3 github.com/briandowns/spinner v1.18.0 github.com/enescakir/emoji v1.0.0 diff --git a/go.sum b/go.sum index 525a97a2..e5c512ca 100644 --- a/go.sum +++ b/go.sum @@ -95,8 +95,8 @@ github.com/armosec/opa-utils v0.0.64/go.mod h1:6tQP8UDq2EvEfSqh8vrUdr/9QVSCG4sJf github.com/armosec/opa-utils v0.0.78 h1:wFkVqJ1vEftn3E1hHdUfKlp5xHgof616ljyKKebuNkI= github.com/armosec/opa-utils v0.0.78/go.mod h1:ZOXYVTtuyrV4TldcfbzgRqP6F9Drlf4hB0zr210OXgM= github.com/armosec/rbac-utils v0.0.1/go.mod h1:pQ8CBiij8kSKV7aeZm9FMvtZN28VgA7LZcYyTWimq40= -github.com/armosec/rbac-utils v0.0.9 h1:rIOWp4K7BELUNX32ktSjVbb8d/0SpH7W76W6Tf+8rzw= -github.com/armosec/rbac-utils v0.0.9/go.mod h1:Ex/IdGWhGv9HZq6Hs8N/ApzCKSIvpNe/ETqDfnuyah0= +github.com/armosec/rbac-utils v0.0.10 h1:bFjesO8+xJS1ryR9vqj4xFEo1cQ0HvClzR+LWHzozW4= +github.com/armosec/rbac-utils v0.0.10/go.mod h1:Ex/IdGWhGv9HZq6Hs8N/ApzCKSIvpNe/ETqDfnuyah0= github.com/armosec/utils-go v0.0.2/go.mod h1:itWmRLzRdsnwjpEOomL0mBWGnVNNIxSjDAdyc+b0iUo= github.com/armosec/utils-go v0.0.3 h1:uyQI676yRciQM0sSN9uPoqHkbspTxHO0kmzXhBeE/xU= github.com/armosec/utils-go v0.0.3/go.mod h1:itWmRLzRdsnwjpEOomL0mBWGnVNNIxSjDAdyc+b0iUo= From 0de6892ddddc7cad13af00485116778858321743 Mon Sep 17 00:00:00 2001 From: Benyamin Hirschberg <59160382+BenHirschbergCa@users.noreply.github.com> Date: Thu, 30 Dec 2021 10:44:08 +0200 Subject: [PATCH 13/17] adding container image vunerability adaptor proposal --- .../container-image-vulnerability-adaptor.md | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 docs/proposals/container-image-vulnerability-adaptor.md diff --git a/docs/proposals/container-image-vulnerability-adaptor.md b/docs/proposals/container-image-vulnerability-adaptor.md new file mode 100644 index 00000000..f3dc4b28 --- /dev/null +++ b/docs/proposals/container-image-vulnerability-adaptor.md @@ -0,0 +1,117 @@ +# Container image vulnerabilty adaptor interface proposal + +## Rationale + +source #287 + +### Big picture + +* Kubescape team planning to create controls which take into account image vulnerabilities, example: looking for public internet facing workloads with critical vulnerabilities. These are seriously effecting the security health of a cluster and therefore we think it is important to cover it. We think that most container registries are/will support image scanning like Harbor and therefore the ability to get information from them is important. +* There are information in the image repository which is important for existing controls as well. They are incomplete without it, example see this issue: Non-root containers check is broken #19 . These are not necessarily image vulnerability related. Can be information in the image manifest (like the issue before), but it can be the image BOM related. + +### Relation to this proposal + +There are multiple changes and design decisions needs to be made before Kubescape will support the before outlined controls. However, a focal point the whole picutre is the ability to access vulnerabilty databases of container images. We anticiapte that most container image repositories will support image vulnerabilty scanning, some major players are already do. Since there is no a single API available which all of these data sources support it is important to create an adaption layer within Kubescape so different datasources can serve Kubescape's goals. + +## High level design of Kubescape + +### Layers + +* Controls and Rules: that actual control logic implementation, the "tests" themselves. Implemented in rego +* OPA engine: the [OPA](https://github.com/open-policy-agent/opa) rego interpreter +* Rules processor: Kubescape component, it enumerates and runs the controls while also preparing the all the input data that the controls need for running +* Data sources: set of different modules providing data to the Rules processor so it can run the controls with them. Examples: Kubernetes objects, cloud vendor API objects and adding in this proposal the vulnerability infomration +* Cloud Image Vulnerability adaption interface: the subject of this proposal, it gives a common interface for different registry/vulnerabilty vendors to adapt to. +* CIV adaptors: specific implementation of the CIV interface, example Harbor adaption +``` + ----------------------- +| Controls/Rules (rego) | + ----------------------- + | + ----------------------- +| OPA engine | + ----------------------- + | + ----------------------- +| Rules processor | + ----------------------- + | + ----------------------- +| Data sources | + ----------------------- + | + ======================= +| CIV adaption interface| <- Adding this layer in this proposal + ======================= + | + ----------------------- +| Specific CIV adaptors | <- will be implemented based on this proposal + ----------------------- + + + +``` + +## Functionalities to cover + +The interface needs to cover the following functionalities: + +* Authentication against the information source (abstracted login) +* Triggering image scan (if applicable, the source might store vulnerabilities for images but cannot scan alone) +* Reading image scan status (with last scan date and etc.) +* Getting vulnerability information for a given image +* Getting image information + * Image manifests + * Image BOMs (bill of material) + +## Go API proposal + +``` + +/*type ContainerImageRegistryCredentials struct { + map[string]string + Password string + Tag string + Hash string +}*/ + +type ContainerImageIdentifier struct { + Registry string + Repository string + Tag string + Hash string +} + +type ContainerImageScanStatus struct { + ImageID ContainerImageIdentifier + IsScanAvailable bool + IsBomAvailable bool + LastScanDate time.Time +} + +type ContainerImageVulnerability struct { + ImageID ContainerImageIdentifier + // TBD +} + +type ContainerImageInformation struct { + ImageID ContainerImageIdentifier + Bom []string + ImageManifest Manifest // will use here Docker package definition +} + +type IContainerImageVulnerabilityAdaptor interface { + // Credentials are coming from user input (CLI or configuration file) and they are abstracted at string to string map level + // so and example use would be like registry: "simpledockerregistry:80" and credentials like {"username":"joedoe","password":"abcd1234"} + Login(registry string, credentials map[string]string) error + + // For "help" purposes + DescribeAdaptor() string + + GetImagesScanStatus(imageIDs []ContainerImageIdentifier) ([]ContainerImageScanStatus, error) + + GetImagesVulnerabilties(imageIDs []ContainerImageIdentifier) ([]ContainerImageVulnerability, error) + + GetImagesInformation(imageIDs []ContainerImageIdentifier) ([]ContainerImageInformation, error) +} +``` \ No newline at end of file From 803e62020ecef5ba30b27ae223c90e22f36477c6 Mon Sep 17 00:00:00 2001 From: Rotem Refael Date: Thu, 30 Dec 2021 16:40:07 +0200 Subject: [PATCH 14/17] add devopsbest framework --- cautils/getter/armoapiutils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cautils/getter/armoapiutils.go b/cautils/getter/armoapiutils.go index 4991fcea..8cb157ef 100644 --- a/cautils/getter/armoapiutils.go +++ b/cautils/getter/armoapiutils.go @@ -5,7 +5,7 @@ import ( "strings" ) -var NativeFrameworks = []string{"nsa", "mitre", "armobest"} +var NativeFrameworks = []string{"nsa", "mitre", "armobest", "devopsbest"} func (armoAPI *ArmoAPI) getFrameworkURL(frameworkName string) string { u := url.URL{} From 7bc2c2be13ffbfd7986dbf23d79caadbafff7306 Mon Sep 17 00:00:00 2001 From: dwertent Date: Mon, 3 Jan 2022 13:36:29 +0200 Subject: [PATCH 15/17] fliter ot reources based on owners --- cautils/getter/armoapi.go | 2 +- opaprocessor/processorhandlerutils.go | 27 ++++++++++++++++++++++++++- resourcehandler/k8sresources.go | 2 +- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/cautils/getter/armoapi.go b/cautils/getter/armoapi.go index 93ebbf9c..ed920136 100644 --- a/cautils/getter/armoapi.go +++ b/cautils/getter/armoapi.go @@ -100,7 +100,7 @@ func (armoAPI *ArmoAPI) GetReportReceiverURL() string { func (armoAPI *ArmoAPI) GetFramework(name string) (*reporthandling.Framework, error) { respStr, err := HttpGetter(armoAPI.httpClient, armoAPI.getFrameworkURL(name), nil) if err != nil { - return nil, err + return nil, nil } framework := &reporthandling.Framework{} diff --git a/opaprocessor/processorhandlerutils.go b/opaprocessor/processorhandlerutils.go index beb2c208..8c727465 100644 --- a/opaprocessor/processorhandlerutils.go +++ b/opaprocessor/processorhandlerutils.go @@ -41,6 +41,7 @@ func getAllSupportedObjects(k8sResources *cautils.K8SResources, allResources map func getKubernetesObjects(k8sResources *cautils.K8SResources, allResources map[string]workloadinterface.IMetadata, match []reporthandling.RuleMatchObjects) []workloadinterface.IMetadata { k8sObjects := []workloadinterface.IMetadata{} + for m := range match { for _, groups := range match[m].APIGroups { for _, version := range match[m].APIVersions { @@ -62,9 +63,33 @@ func getKubernetesObjects(k8sResources *cautils.K8SResources, allResources map[s } } - return k8sObjects + return filterOutChildResources(k8sObjects, match) } +// filterOutChildResources filter out child resources if the parent resource is in the list +func filterOutChildResources(objects []workloadinterface.IMetadata, match []reporthandling.RuleMatchObjects) []workloadinterface.IMetadata { + response := []workloadinterface.IMetadata{} + owners := []string{} + for m := range match { + for i := range match[m].Resources { + owners = append(owners, match[m].Resources[i]) + } + } + for i := range objects { + if !k8sinterface.IsTypeWorkload(objects[i].GetObject()) { + response = append(response, objects[i]) + continue + } + w := workloadinterface.NewWorkloadObj(objects[i].GetObject()) + ownerReferences, err := w.GetOwnerReferences() + if err != nil || len(ownerReferences) == 0 { + response = append(response, w) + } else if !k8sinterface.IsStringInSlice(owners, ownerReferences[0].Kind) { + response = append(response, w) + } + } + return response +} func getRuleDependencies() (map[string]string, error) { modules := resources.LoadRegoModules() if len(modules) == 0 { diff --git a/resourcehandler/k8sresources.go b/resourcehandler/k8sresources.go index 75528038..aa308f76 100644 --- a/resourcehandler/k8sresources.go +++ b/resourcehandler/k8sresources.go @@ -105,7 +105,7 @@ func (k8sHandler *K8sResourceHandler) pullResources(k8sResources *cautils.K8SRes continue } // store result as []map[string]interface{} - metaObjs := ConvertMapListToMeta(k8sinterface.ConvertUnstructuredSliceToMap(k8sinterface.FilterOutOwneredResources(result))) + metaObjs := ConvertMapListToMeta(k8sinterface.ConvertUnstructuredSliceToMap(result)) for i := range metaObjs { allResources[metaObjs[i].GetID()] = metaObjs[i] } From 5bb64b634a005a8dc4036470c37735e801fd48e1 Mon Sep 17 00:00:00 2001 From: dwertent Date: Tue, 4 Jan 2022 14:42:25 +0200 Subject: [PATCH 16/17] support loading ks config in env --- cautils/customerloader.go | 93 ++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/cautils/customerloader.go b/cautils/customerloader.go index fab50611..b6fc0de1 100644 --- a/cautils/customerloader.go +++ b/cautils/customerloader.go @@ -14,10 +14,7 @@ import ( corev1 "k8s.io/api/core/v1" ) -const ( - configMapName = "kubescape" - configFileName = "config" -) +const configFileName = "config" func ConfigFileFullPath() string { return getter.GetDefaultPath(configFileName + ".json") } @@ -145,26 +142,38 @@ func getTenantConfigFromBE(backendAPI getter.IBackend, configObj *ConfigObj) err // ========================== Cluster Config ============================================ // ====================================================================================== +// ClusterConfig configuration of specific cluster +/* + +Supported environments variables: +KS_DEFAULT_CONFIGMAP_NAME // name of configmap, if not set default is 'kubescape' +KS_DEFAULT_CONFIGMAP_NAMESPACE // configmap namespace, if not set default is 'default' + +TODO - supprot: +KS_ACCOUNT // Account ID +KS_CACHE // path to cached files +*/ type ClusterConfig struct { - k8s *k8sinterface.KubernetesApi - defaultNS string - backendAPI getter.IBackend - configObj *ConfigObj + k8s *k8sinterface.KubernetesApi + configMapName string + configMapNamespace string + backendAPI getter.IBackend + configObj *ConfigObj } func NewClusterConfig(k8s *k8sinterface.KubernetesApi, backendAPI getter.IBackend, customerGUID string) *ClusterConfig { - defaultNS := k8sinterface.GetDefaultNamespace() var configObj *ConfigObj c := &ClusterConfig{ - k8s: k8s, - backendAPI: backendAPI, - configObj: &ConfigObj{}, - defaultNS: defaultNS, + k8s: k8s, + backendAPI: backendAPI, + configObj: &ConfigObj{}, + configMapName: getConfigMapName(), + configMapNamespace: getConfigMapNamespace(), } // get from configMap - if existsConfigMap(k8s, defaultNS) { - configObj, _ = loadConfigFromConfigMap(k8s, defaultNS) + if c.existsConfigMap() { + configObj, _ = c.loadConfigFromConfigMap() } else if existsConfigFile() { // get from file configObj, _ = loadConfigFromFile() } @@ -189,10 +198,10 @@ func NewClusterConfig(k8s *k8sinterface.KubernetesApi, backendAPI getter.IBacken } func (c *ClusterConfig) GetConfigObj() *ConfigObj { return c.configObj } -func (c *ClusterConfig) GetDefaultNS() string { return c.defaultNS } +func (c *ClusterConfig) GetDefaultNS() string { return c.configMapNamespace } func (c *ClusterConfig) GetCustomerGUID() string { return c.configObj.CustomerGUID } func (c *ClusterConfig) IsConfigFound() bool { - return existsConfigFile() || existsConfigMap(c.k8s, c.defaultNS) + return existsConfigFile() || c.existsConfigMap() } func (c *ClusterConfig) SetTenant() error { @@ -202,7 +211,7 @@ func (c *ClusterConfig) SetTenant() error { return err } // update/create config - if existsConfigMap(c.k8s, c.defaultNS) { + if c.existsConfigMap() { c.updateConfigMap() } else { c.createConfigMap() @@ -223,8 +232,8 @@ func (c *ClusterConfig) ToMapString() map[string]interface{} { } return m } -func loadConfigFromConfigMap(k8s *k8sinterface.KubernetesApi, ns string) (*ConfigObj, error) { - configMap, err := k8s.KubernetesClient.CoreV1().ConfigMaps(ns).Get(context.Background(), configMapName, metav1.GetOptions{}) +func (c *ClusterConfig) loadConfigFromConfigMap() (*ConfigObj, error) { + configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Get(context.Background(), c.configMapName, metav1.GetOptions{}) if err != nil { return nil, err } @@ -235,15 +244,15 @@ func loadConfigFromConfigMap(k8s *k8sinterface.KubernetesApi, ns string) (*Confi return nil, nil } -func existsConfigMap(k8s *k8sinterface.KubernetesApi, ns string) bool { - _, err := k8s.KubernetesClient.CoreV1().ConfigMaps(ns).Get(context.Background(), configMapName, metav1.GetOptions{}) +func (c *ClusterConfig) existsConfigMap() bool { + _, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Get(context.Background(), c.configMapName, metav1.GetOptions{}) // TODO - check if has customerGUID return err == nil } func (c *ClusterConfig) GetValueByKeyFromConfigMap(key string) (string, error) { - configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Get(context.Background(), configMapName, metav1.GetOptions{}) + configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Get(context.Background(), c.configMapName, metav1.GetOptions{}) if err != nil { return "", err @@ -295,11 +304,11 @@ func SetKeyValueInConfigJson(key string, value string) error { func (c *ClusterConfig) SetKeyValueInConfigmap(key string, value string) error { - configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Get(context.Background(), configMapName, metav1.GetOptions{}) + configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Get(context.Background(), c.configMapName, metav1.GetOptions{}) if err != nil { configMap = &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: configMapName, + Name: c.configMapName, }, } } @@ -311,9 +320,9 @@ func (c *ClusterConfig) SetKeyValueInConfigmap(key string, value string) error { configMap.Data[key] = value if err != nil { - _, err = c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Create(context.Background(), configMap, metav1.CreateOptions{}) + _, err = c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Create(context.Background(), configMap, metav1.CreateOptions{}) } else { - _, err = c.k8s.KubernetesClient.CoreV1().ConfigMaps(configMap.Namespace).Update(context.Background(), configMap, metav1.UpdateOptions{}) + _, err = c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Update(context.Background(), configMap, metav1.UpdateOptions{}) } return err @@ -330,12 +339,12 @@ func (c *ClusterConfig) createConfigMap() error { } configMap := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: configMapName, + Name: c.configMapName, }, } c.updateConfigData(configMap) - _, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Create(context.Background(), configMap, metav1.CreateOptions{}) + _, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Create(context.Background(), configMap, metav1.CreateOptions{}) return err } @@ -343,7 +352,7 @@ func (c *ClusterConfig) updateConfigMap() error { if c.k8s == nil { return nil } - configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.defaultNS).Get(context.Background(), configMapName, metav1.GetOptions{}) + configMap, err := c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Get(context.Background(), c.configMapName, metav1.GetOptions{}) if err != nil { return err @@ -351,7 +360,7 @@ func (c *ClusterConfig) updateConfigMap() error { c.updateConfigData(configMap) - _, err = c.k8s.KubernetesClient.CoreV1().ConfigMaps(configMap.Namespace).Update(context.Background(), configMap, metav1.UpdateOptions{}) + _, err = c.k8s.KubernetesClient.CoreV1().ConfigMaps(c.configMapNamespace).Update(context.Background(), configMap, metav1.UpdateOptions{}) return err } @@ -394,7 +403,7 @@ func readConfig(dat []byte) (*ConfigObj, error) { // Check if the customer is submitted func (clusterConfig *ClusterConfig) IsSubmitted() bool { - return existsConfigMap(clusterConfig.k8s, clusterConfig.defaultNS) || existsConfigFile() + return clusterConfig.existsConfigMap() || existsConfigFile() } // Check if the customer is registered @@ -411,7 +420,7 @@ func (clusterConfig *ClusterConfig) IsRegistered() bool { } func (clusterConfig *ClusterConfig) DeleteConfig() error { - if err := DeleteConfigMap(clusterConfig.k8s); err != nil { + if err := clusterConfig.DeleteConfigMap(); err != nil { return err } if err := DeleteConfigFile(); err != nil { @@ -419,8 +428,8 @@ func (clusterConfig *ClusterConfig) DeleteConfig() error { } return nil } -func DeleteConfigMap(k8s *k8sinterface.KubernetesApi) error { - return k8s.KubernetesClient.CoreV1().ConfigMaps(k8sinterface.GetDefaultNamespace()).Delete(context.Background(), configMapName, metav1.DeleteOptions{}) +func (clusterConfig *ClusterConfig) DeleteConfigMap() error { + return clusterConfig.k8s.KubernetesClient.CoreV1().ConfigMaps(clusterConfig.configMapNamespace).Delete(context.Background(), clusterConfig.configMapName, metav1.DeleteOptions{}) } func DeleteConfigFile() error { @@ -430,3 +439,17 @@ func DeleteConfigFile() error { func AdoptClusterName(clusterName string) string { return strings.ReplaceAll(clusterName, "/", "-") } + +func getConfigMapName() string { + if n := os.Getenv("KS_DEFAULT_CONFIGMAP_NAME"); n != "" { + return n + } + return "kubescape" +} + +func getConfigMapNamespace() string { + if n := os.Getenv("KS_DEFAULT_CONFIGMAP_NAMESPACE"); n != "" { + return n + } + return "default" +} From bbf68d4ce85e05f098f7bd9aff1503733272947e Mon Sep 17 00:00:00 2001 From: Jonas Kint Date: Wed, 5 Jan 2022 13:49:26 +0100 Subject: [PATCH 17/17] Fixing typo in the ActionSendReport error message --- resultshandling/reporter/reporteventreceiver.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resultshandling/reporter/reporteventreceiver.go b/resultshandling/reporter/reporteventreceiver.go index fc090e42..7e77254f 100644 --- a/resultshandling/reporter/reporteventreceiver.go +++ b/resultshandling/reporter/reporteventreceiver.go @@ -44,7 +44,7 @@ func NewReportEventReceiver(tenantConfig *cautils.ConfigObj) *ReportEventReceive func (report *ReportEventReceiver) ActionSendReport(opaSessionObj *cautils.OPASessionObj) error { if report.customerGUID == "" || report.clusterName == "" { - return fmt.Errorf("missing accout ID or cluster name. AccountID: '%s', Cluster name: '%s'", report.customerGUID, report.clusterName) + return fmt.Errorf("missing account ID or cluster name. AccountID: '%s', Cluster name: '%s'", report.customerGUID, report.clusterName) } if err := report.prepareReport(opaSessionObj.PostureReport, opaSessionObj.AllResources); err != nil {