Working with IMetadata interface

This commit is contained in:
David Wertenteil
2021-11-28 08:14:00 +02:00
committed by GitHub
11 changed files with 128 additions and 116 deletions
+2 -1
View File
@@ -2,11 +2,12 @@ package cautils
import (
"github.com/armosec/armoapi-go/armotypes"
"github.com/armosec/k8s-interface/workloadinterface"
"github.com/armosec/opa-utils/reporthandling"
)
// K8SResources map[<api group>/<api version>/<resource>]<resource object>
type K8SResources map[string]interface{}
type K8SResources map[string][]workloadinterface.IMetadata
type OPASessionObj struct {
Frameworks []reporthandling.Framework
+3 -3
View File
@@ -4,8 +4,8 @@ go 1.17
require (
github.com/armosec/armoapi-go v0.0.23
github.com/armosec/k8s-interface v0.0.17
github.com/armosec/opa-utils v0.0.51
github.com/armosec/k8s-interface v0.0.19
github.com/armosec/opa-utils v0.0.53
github.com/armosec/rbac-utils v0.0.1
github.com/armosec/utils-go v0.0.3
github.com/briandowns/spinner v1.16.0
@@ -62,7 +62,7 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
+6 -5
View File
@@ -87,10 +87,10 @@ github.com/armosec/armoapi-go v0.0.2/go.mod h1:vIK17yoKbJRQyZXWWLe3AqfqCRITxW8qm
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/k8s-interface v0.0.8/go.mod h1:xxS+V5QT3gVQTwZyAMMDrYLWGrfKOpiJ7Jfhfa0w9sM=
github.com/armosec/k8s-interface v0.0.17 h1:Wm6reX9eBQchFQACkn4mxNo6voJK3LVgPaghBcneMd0=
github.com/armosec/k8s-interface v0.0.17/go.mod h1:Oy8JDHZ5/LEZDA+s734twVdsfAZydZ1GkNuhiPcgL5g=
github.com/armosec/opa-utils v0.0.51 h1:i+/4jexyNpswWDrFS0H8rctkxUWLx2+Chf/hvID8M0I=
github.com/armosec/opa-utils v0.0.51/go.mod h1:7985am4HVVyiZRdAwlrpJv5n2sINcqUVv9UjIYsTrdo=
github.com/armosec/k8s-interface v0.0.19 h1:GhWxAyBCWLx2Qqw8uFSZ4rpZf3IV5k922mBtpQsoW2g=
github.com/armosec/k8s-interface v0.0.19/go.mod h1:0ztwEWLez2lpMMKHbs0DoZV64S0YIA4s72vCs9iAAiE=
github.com/armosec/opa-utils v0.0.53 h1:ibmKPK15kEcm53ddFIu8ZcL+hks1l/3ujMDYL1EXz2Q=
github.com/armosec/opa-utils v0.0.53/go.mod h1:9uMk9NbbJydxVztXcwhSgX307xMdGRD2R4pYwzSPi28=
github.com/armosec/rbac-utils v0.0.1 h1:N2MI98F/0zbDjmRZ29CNElU1AXkFLk5csd/qAHOBdXY=
github.com/armosec/rbac-utils v0.0.1/go.mod h1:pQ8CBiij8kSKV7aeZm9FMvtZN28VgA7LZcYyTWimq40=
github.com/armosec/utils-go v0.0.2/go.mod h1:itWmRLzRdsnwjpEOomL0mBWGnVNNIxSjDAdyc+b0iUo=
@@ -489,8 +489,9 @@ github.com/open-policy-agent/opa v0.33.1 h1:EJe00U5H82iMsemgxcNm9RFwjW8zPyRMvL+0
github.com/open-policy-agent/opa v0.33.1/go.mod h1:Zb+IdRe0s7M++Rv/KgyuB0qvxO3CUpQ+ZW5v+w/cRUo=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+4 -24
View File
@@ -10,6 +10,7 @@ import (
"github.com/armosec/opa-utils/reporthandling"
"github.com/armosec/k8s-interface/k8sinterface"
"github.com/armosec/k8s-interface/workloadinterface"
"github.com/armosec/opa-utils/resources"
"github.com/golang/glog"
@@ -152,13 +153,12 @@ func (opap *OPAProcessor) processRule(rule *reporthandling.PolicyRule) (*reporth
if !isRuleKubescapeVersionCompatible(rule) {
return nil, nil
}
k8sObjects := getKubernetesObjects(opap.K8SResources, rule.Match)
k8sObjects, err := reporthandling.RegoResourcesAggregator(rule, k8sObjects)
inputResources, err := reporthandling.RegoResourcesAggregator(rule, getKubernetesObjects(opap.K8SResources, rule.Match))
if err != nil {
glog.Error(err)
return nil, fmt.Errorf("error getting aggregated k8sObjects: %s", err.Error())
}
ruleReport, err := opap.runOPAOnSingleRule(rule, k8sObjects)
ruleReport, err := opap.runOPAOnSingleRule(rule, workloadinterface.ListMetaToMap(inputResources))
if err != nil {
ruleReport.RuleStatus.Status = "failure"
ruleReport.RuleStatus.Message = err.Error()
@@ -166,30 +166,10 @@ func (opap *OPAProcessor) processRule(rule *reporthandling.PolicyRule) (*reporth
} else {
ruleReport.RuleStatus.Status = "success"
}
ruleReport.ListInputResources = k8sObjects
ruleReport.ListInputKinds = workloadinterface.ListMetaIDs(inputResources)
return &ruleReport, err
}
func isRuleKubescapeVersionCompatible(rule *reporthandling.PolicyRule) bool {
if from, ok := rule.Attributes["useFromKubescapeVersion"]; ok {
if cautils.BuildNumber != "" {
if from.(string) > cautils.BuildNumber {
return false
}
}
}
if until, ok := rule.Attributes["useUntilKubescapeVersion"]; ok {
if cautils.BuildNumber != "" {
if until.(string) <= cautils.BuildNumber {
return false
}
} else {
return false
}
}
return true
}
func (opap *OPAProcessor) runOPAOnSingleRule(rule *reporthandling.PolicyRule, k8sObjects []map[string]interface{}) (reporthandling.RuleReport, error) {
switch rule.RuleLanguage {
case reporthandling.RegoLanguage, reporthandling.RegoLanguage2:
+2 -44
View File
@@ -3,12 +3,12 @@ package opaprocessor
import (
"testing"
"github.com/armosec/armoapi-go/armotypes"
"github.com/armosec/kubescape/cautils"
"github.com/armosec/opa-utils/reporthandling"
"github.com/armosec/opa-utils/resources"
"github.com/armosec/k8s-interface/k8sinterface"
"github.com/armosec/k8s-interface/workloadinterface"
// _ "k8s.io/client-go/plugin/pkg/client/auth"
)
@@ -19,7 +19,7 @@ func TestProcess(t *testing.T) {
// set k8s
k8sResources := make(cautils.K8SResources)
k8sResources["/v1/pods"] = k8sinterface.ConvertUnstructuredSliceToMap(k8sinterface.V1KubeSystemNamespaceMock().Items)
k8sResources["/v1/pods"] = workloadinterface.ListMapToMeta(k8sinterface.ConvertUnstructuredSliceToMap(k8sinterface.V1KubeSystemNamespaceMock().Items))
// set opaSessionObj
opaSessionObj := cautils.NewOPASessionObjMock()
@@ -43,45 +43,3 @@ func TestProcess(t *testing.T) {
}
}
var rule_v1_0_131 = &reporthandling.PolicyRule{PortalBase: armotypes.PortalBase{
Attributes: map[string]interface{}{"useUntilKubescapeVersion": "v1.0.132"}}}
var rule_v1_0_132 = &reporthandling.PolicyRule{PortalBase: armotypes.PortalBase{
Attributes: map[string]interface{}{"useFromKubescapeVersion": "v1.0.132", "useUntilKubescapeVersion": "v1.0.133"}}}
var rule_v1_0_133 = &reporthandling.PolicyRule{PortalBase: armotypes.PortalBase{
Attributes: map[string]interface{}{"useFromKubescapeVersion": "v1.0.133", "useUntilKubescapeVersion": "v1.0.134"}}}
var rule_v1_0_134 = &reporthandling.PolicyRule{PortalBase: armotypes.PortalBase{
Attributes: map[string]interface{}{"useFromKubescapeVersion": "v1.0.134"}}}
func TestIsRuleKubescapeVersionCompatible(t *testing.T) {
// local build- no build number
// should use only rules that don't have "until"
cautils.BuildNumber = ""
if isRuleKubescapeVersionCompatible(rule_v1_0_131) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
if isRuleKubescapeVersionCompatible(rule_v1_0_132) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
if isRuleKubescapeVersionCompatible(rule_v1_0_133) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
if !isRuleKubescapeVersionCompatible(rule_v1_0_134) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
// should only use rules that version is in range of use
cautils.BuildNumber = "v1.0.133"
if isRuleKubescapeVersionCompatible(rule_v1_0_131) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
if isRuleKubescapeVersionCompatible(rule_v1_0_132) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
if !isRuleKubescapeVersionCompatible(rule_v1_0_133) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
if isRuleKubescapeVersionCompatible(rule_v1_0_134) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
}
+23 -11
View File
@@ -11,11 +11,10 @@ import (
resources "github.com/armosec/opa-utils/resources"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func getKubernetesObjects(k8sResources *cautils.K8SResources, match []reporthandling.RuleMatchObjects) []map[string]interface{} {
k8sObjects := []map[string]interface{}{}
func getKubernetesObjects(k8sResources *cautils.K8SResources, match []reporthandling.RuleMatchObjects) []workloadinterface.IMetadata {
k8sObjects := []workloadinterface.IMetadata{}
for m := range match {
for _, groups := range match[m].APIGroups {
for _, version := range match[m].APIVersions {
@@ -25,15 +24,8 @@ func getKubernetesObjects(k8sResources *cautils.K8SResources, match []reporthand
if k8sObj, ok := (*k8sResources)[groupResource]; ok {
if k8sObj == nil {
// glog.Errorf("Resource '%s' is nil, probably failed to pull the resource", groupResource)
} else if v, k := k8sObj.([]map[string]interface{}); k {
k8sObjects = append(k8sObjects, v...)
} else if v, k := k8sObj.(map[string]interface{}); k {
k8sObjects = append(k8sObjects, v)
} else if v, k := k8sObj.([]unstructured.Unstructured); k {
k8sObjects = append(k8sObjects, k8sinterface.ConvertUnstructuredSliceToMap(v)...) //
} else {
glog.Errorf("In 'getKubernetesObjects' resource '%s' unknown type", groupResource)
}
k8sObjects = append(k8sObjects, k8sObj...)
}
}
}
@@ -83,3 +75,23 @@ func ruleWithArmoOpaDependency(annotations map[string]interface{}) bool {
}
return false
}
func isRuleKubescapeVersionCompatible(rule *reporthandling.PolicyRule) bool {
if from, ok := rule.Attributes["useFromKubescapeVersion"]; ok {
if cautils.BuildNumber != "" {
if from.(string) > cautils.BuildNumber {
return false
}
}
}
if until, ok := rule.Attributes["useUntilKubescapeVersion"]; ok {
if cautils.BuildNumber != "" {
if until.(string) <= cautils.BuildNumber {
return false
}
} else {
return false
}
}
return true
}
@@ -2,7 +2,53 @@ package opaprocessor
import (
"testing"
"github.com/armosec/armoapi-go/armotypes"
"github.com/armosec/kubescape/cautils"
"github.com/armosec/opa-utils/reporthandling"
)
func TestGetKubernetesObjects(t *testing.T) {
}
var rule_v1_0_131 = &reporthandling.PolicyRule{PortalBase: armotypes.PortalBase{
Attributes: map[string]interface{}{"useUntilKubescapeVersion": "v1.0.132"}}}
var rule_v1_0_132 = &reporthandling.PolicyRule{PortalBase: armotypes.PortalBase{
Attributes: map[string]interface{}{"useFromKubescapeVersion": "v1.0.132", "useUntilKubescapeVersion": "v1.0.133"}}}
var rule_v1_0_133 = &reporthandling.PolicyRule{PortalBase: armotypes.PortalBase{
Attributes: map[string]interface{}{"useFromKubescapeVersion": "v1.0.133", "useUntilKubescapeVersion": "v1.0.134"}}}
var rule_v1_0_134 = &reporthandling.PolicyRule{PortalBase: armotypes.PortalBase{
Attributes: map[string]interface{}{"useFromKubescapeVersion": "v1.0.134"}}}
func TestIsRuleKubescapeVersionCompatible(t *testing.T) {
// local build- no build number
// should use only rules that don't have "until"
cautils.BuildNumber = ""
if isRuleKubescapeVersionCompatible(rule_v1_0_131) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
if isRuleKubescapeVersionCompatible(rule_v1_0_132) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
if isRuleKubescapeVersionCompatible(rule_v1_0_133) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
if !isRuleKubescapeVersionCompatible(rule_v1_0_134) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
// should only use rules that version is in range of use
cautils.BuildNumber = "v1.0.133"
if isRuleKubescapeVersionCompatible(rule_v1_0_131) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
if isRuleKubescapeVersionCompatible(rule_v1_0_132) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
if !isRuleKubescapeVersionCompatible(rule_v1_0_133) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
if isRuleKubescapeVersionCompatible(rule_v1_0_134) {
t.Error("error in isRuleKubescapeVersionCompatible")
}
}
+27 -19
View File
@@ -43,7 +43,7 @@ func NewFileResourceHandler(inputPatterns []string) *FileResourceHandler {
}
func (fileHandler *FileResourceHandler) GetResources(frameworks []reporthandling.Framework, designator *armotypes.PortalDesignator) (*cautils.K8SResources, error) {
workloads := []k8sinterface.IWorkload{}
workloads := []workloadinterface.IMetadata{}
// load resource from local file system
w, err := loadResourcesFromFiles(fileHandler.inputPatterns)
@@ -89,7 +89,7 @@ func (fileHandler *FileResourceHandler) GetClusterAPIServerInfo() *version.Info
return nil
}
func loadResourcesFromFiles(inputPatterns []string) ([]k8sinterface.IWorkload, error) {
func loadResourcesFromFiles(inputPatterns []string) ([]workloadinterface.IMetadata, error) {
files, errs := listFiles(inputPatterns)
if len(errs) > 0 {
cautils.ErrorDisplay(fmt.Sprintf("%v", errs)) // TODO - print error
@@ -106,32 +106,36 @@ func loadResourcesFromFiles(inputPatterns []string) ([]k8sinterface.IWorkload, e
}
// build resources map
func mapResources(workloads []k8sinterface.IWorkload) map[string][]map[string]interface{} {
allResources := map[string][]map[string]interface{}{}
func mapResources(workloads []workloadinterface.IMetadata) map[string][]workloadinterface.IMetadata {
allResources := map[string][]workloadinterface.IMetadata{}
for i := range workloads {
groupVersionResource, err := k8sinterface.GetGroupVersionResource(workloads[i].GetKind())
if err != nil {
// TODO - print warning
continue
}
if groupVersionResource.Group != workloads[i].GetGroup() || groupVersionResource.Version != workloads[i].GetVersion() {
// TODO - print warning
continue
if workloadinterface.IsTypeWorkload(workloads[i].GetObject()) {
w := workloadinterface.NewWorkloadObj(workloads[i].GetObject())
if groupVersionResource.Group != w.GetGroup() || groupVersionResource.Version != w.GetVersion() {
// TODO - print warning
continue
}
}
resourceTriplets := k8sinterface.JoinResourceTriplets(groupVersionResource.Group, groupVersionResource.Version, groupVersionResource.Resource)
if r, ok := allResources[resourceTriplets]; ok {
r = append(r, workloads[i].GetWorkload())
r = append(r, workloads...)
allResources[resourceTriplets] = r
} else {
allResources[resourceTriplets] = []map[string]interface{}{workloads[i].GetWorkload()}
allResources[resourceTriplets] = workloads
}
}
return allResources
}
func loadFiles(filePaths []string) ([]k8sinterface.IWorkload, []error) {
workloads := []k8sinterface.IWorkload{}
func loadFiles(filePaths []string) ([]workloadinterface.IMetadata, []error) {
workloads := []workloadinterface.IMetadata{}
errs := []error{}
for i := range filePaths {
f, err := loadFile(filePaths[i])
@@ -151,7 +155,7 @@ func loadFiles(filePaths []string) ([]k8sinterface.IWorkload, []error) {
func loadFile(filePath string) ([]byte, error) {
return os.ReadFile(filePath)
}
func readFile(fileContent []byte, fileFromat FileFormat) ([]k8sinterface.IWorkload, []error) {
func readFile(fileContent []byte, fileFromat FileFormat) ([]workloadinterface.IMetadata, []error) {
switch fileFromat {
case YAML_FILE_FORMAT:
@@ -185,12 +189,12 @@ func listFiles(patterns []string) ([]string, []error) {
return files, errs
}
func readYamlFile(yamlFile []byte) ([]k8sinterface.IWorkload, []error) {
func readYamlFile(yamlFile []byte) ([]workloadinterface.IMetadata, []error) {
errs := []error{}
r := bytes.NewReader(yamlFile)
dec := yaml.NewDecoder(r)
yamlObjs := []k8sinterface.IWorkload{}
yamlObjs := []workloadinterface.IMetadata{}
var t interface{}
for dec.Decode(&t) == nil {
@@ -199,7 +203,9 @@ func readYamlFile(yamlFile []byte) ([]k8sinterface.IWorkload, []error) {
continue
}
if obj, ok := j.(map[string]interface{}); ok {
yamlObjs = append(yamlObjs, workloadinterface.NewWorkloadObj(obj))
if o := workloadinterface.NewObject(obj); o != nil {
yamlObjs = append(yamlObjs, o)
}
} else {
errs = append(errs, fmt.Errorf("failed to convert yaml file to map[string]interface, file content: %v", j))
}
@@ -208,8 +214,8 @@ func readYamlFile(yamlFile []byte) ([]k8sinterface.IWorkload, []error) {
return yamlObjs, errs
}
func readJsonFile(jsonFile []byte) ([]k8sinterface.IWorkload, []error) {
workloads := []k8sinterface.IWorkload{}
func readJsonFile(jsonFile []byte) ([]workloadinterface.IMetadata, []error) {
workloads := []workloadinterface.IMetadata{}
var jsonObj interface{}
if err := json.Unmarshal(jsonFile, &jsonObj); err != nil {
return workloads, []error{err}
@@ -219,11 +225,13 @@ func readJsonFile(jsonFile []byte) ([]k8sinterface.IWorkload, []error) {
return workloads, nil
}
func convertJsonToWorkload(jsonObj interface{}, workloads *[]k8sinterface.IWorkload) {
func convertJsonToWorkload(jsonObj interface{}, workloads *[]workloadinterface.IMetadata) {
switch x := jsonObj.(type) {
case map[string]interface{}:
(*workloads) = append(*workloads, workloadinterface.NewWorkloadObj(x))
if o := workloadinterface.NewObject(x); o != nil {
(*workloads) = append(*workloads, o)
}
case []interface{}:
for i := range x {
convertJsonToWorkload(x[i], workloads)
+11 -1
View File
@@ -8,6 +8,7 @@ import (
"github.com/armosec/opa-utils/reporthandling"
"github.com/armosec/k8s-interface/k8sinterface"
"github.com/armosec/k8s-interface/workloadinterface"
"github.com/armosec/armoapi-go/armotypes"
@@ -74,7 +75,7 @@ func (k8sHandler *K8sResourceHandler) pullResources(k8sResources *cautils.K8SRes
}
} else {
// store result as []map[string]interface{}
(*k8sResources)[groupResource] = k8sinterface.ConvertUnstructuredSliceToMap(k8sinterface.FilterOutOwneredResources(result))
(*k8sResources)[groupResource] = ConvertMapListToMeta(k8sinterface.ConvertUnstructuredSliceToMap(k8sinterface.FilterOutOwneredResources(result)))
}
}
return errs
@@ -109,3 +110,12 @@ func (k8sHandler *K8sResourceHandler) pullSingleResource(resource *schema.GroupV
return result.Items, nil
}
func ConvertMapListToMeta(resourceMap []map[string]interface{}) []workloadinterface.IMetadata {
workloads := []workloadinterface.IMetadata{}
for i := range resourceMap {
if w := workloadinterface.NewObject(resourceMap[i]); w != nil {
workloads = append(workloads, w)
}
}
return workloads
}
+4 -4
View File
@@ -7,11 +7,11 @@ import (
"net/http"
"strings"
"github.com/armosec/k8s-interface/k8sinterface"
"github.com/armosec/k8s-interface/workloadinterface"
"github.com/armosec/kubescape/cautils"
)
func loadResourcesFromUrl(inputPatterns []string) ([]k8sinterface.IWorkload, error) {
func loadResourcesFromUrl(inputPatterns []string) ([]workloadinterface.IMetadata, error) {
urls := listUrls(inputPatterns)
if len(urls) == 0 {
return nil, nil
@@ -43,8 +43,8 @@ func listUrls(patterns []string) []string {
return urls
}
func downloadFiles(urls []string) ([]k8sinterface.IWorkload, []error) {
workloads := []k8sinterface.IWorkload{}
func downloadFiles(urls []string) ([]workloadinterface.IMetadata, []error) {
workloads := []workloadinterface.IMetadata{}
errs := []error{}
for i := range urls {
f, err := downloadFile(urls[i])
-4
View File
@@ -37,10 +37,6 @@ func (controlSummary *ControlSummary) ToSlice() []string {
return s
}
func (workloadSummary *WorkloadSummary) ToString() string {
return fmt.Sprintf("/%s/%s/%s/%s", workloadSummary.FailedWorkload.GetApiVersion(), workloadSummary.FailedWorkload.GetNamespace(), workloadSummary.FailedWorkload.GetKind(), workloadSummary.FailedWorkload.GetName())
}
func workloadSummaryFailed(workloadSummary *WorkloadSummary) bool {
return workloadSummary.Exception == nil
}