diff --git a/exceptions/comparator.go b/exceptions/comparator.go index 63f4cf26..cfafcbd3 100644 --- a/exceptions/comparator.go +++ b/exceptions/comparator.go @@ -40,6 +40,10 @@ func (c *comparator) compareName(workload workloadinterface.IMetadata, name stri return c.regexCompare(name, workload.GetName()) } +func (c *comparator) compareResourceID(workload workloadinterface.IMetadata, resourceID string) bool { + return c.regexCompare(resourceID, workload.GetID()) +} + func (c *comparator) comparePath(workload workloadinterface.IMetadata, path string) bool { w := workload.GetObject() if !k8sinterface.IsTypeWorkload(w) { diff --git a/exceptions/exceptionprocessor.go b/exceptions/exceptionprocessor.go index 6b70d59c..8a945826 100644 --- a/exceptions/exceptionprocessor.go +++ b/exceptions/exceptionprocessor.go @@ -163,7 +163,7 @@ func (p *Processor) hasException(clusterName string, designator *armotypes.Porta p.designatorCache.Set(designator, attributes) } - if attributes.GetCluster() == "" && attributes.GetNamespace() == "" && attributes.GetKind() == "" && attributes.GetName() == "" && attributes.GetPath() == "" && len(attributes.GetLabels()) == 0 { + if attributes.GetCluster() == "" && attributes.GetNamespace() == "" && attributes.GetKind() == "" && attributes.GetName() == "" && attributes.GetResourceID() == "" && attributes.GetPath() == "" && len(attributes.GetLabels()) == 0 { return false // if designators are empty } @@ -183,6 +183,10 @@ func (p *Processor) hasException(clusterName string, designator *armotypes.Porta return false // names do not match } + if attributes.GetResourceID() != "" && !p.compareResourceID(workload, attributes.GetResourceID()) { + return false // names do not match + } + if attributes.GetPath() != "" && !p.comparePath(workload, attributes.GetPath()) { return false // paths do not match } diff --git a/exceptions/exceptionprocessor_test.go b/exceptions/exceptionprocessor_test.go index da961249..1110dfdc 100644 --- a/exceptions/exceptionprocessor_test.go +++ b/exceptions/exceptionprocessor_test.go @@ -63,6 +63,30 @@ func postureLabelsRegexExceptionPolicyAlertOnlyMock() *armotypes.PostureExceptio } } +func postureResourceIDExceptionPolicyMock(resourceID string) *armotypes.PostureExceptionPolicy { + return &armotypes.PostureExceptionPolicy{ + PortalBase: armotypes.PortalBase{ + Name: "postureResourceIDExceptionPolicyMock", + }, + PolicyType: "postureExceptionPolicy", + Actions: []armotypes.PostureExceptionPolicyActions{armotypes.AlertOnly}, + Resources: []armotypes.PortalDesignator{ + { + DesignatorType: armotypes.DesignatorAttributes, + Attributes: map[string]string{ + armotypes.AttributeCluster: "test", + armotypes.AttributeResourceID: resourceID, + }, + }, + }, + PosturePolicies: []armotypes.PosturePolicy{ + { + FrameworkName: "MIT.*", + }, + }, + } +} + func emptyPostureExceptionPolicyAlertOnlyMock() *armotypes.PostureExceptionPolicy { return &armotypes.PostureExceptionPolicy{ PortalBase: armotypes.PortalBase{ @@ -153,6 +177,13 @@ func TestGetResourceExceptions(t *testing.T) { withAnnotationObj, err := workloadinterface.NewBaseObjBytes([]byte(`{"apiVersion": "v1", "kind":"Deployment", "metadata": {"name": "test", "annotations": {"myLabelOrAnnotation" : "static_test"}}}`)) require.NoError(t, err) + idObj, err := workloadinterface.NewBaseObjBytes([]byte(`{"apiVersion": "v1/core", "kind":"Deployment", "metadata": {"name": "test", "namespace": "default"}}`)) + require.NoError(t, err) + + exceptionPolicyResourceID := postureResourceIDExceptionPolicyMock(idObj.GetID()) + exceptionPolicyResourceIDRegex := postureResourceIDExceptionPolicyMock("*") + exceptionPolicyResourceOtherID := postureResourceIDExceptionPolicyMock("v1/core/default/ConfigMap/test") + exceptionPolicy := postureLabelsRegexExceptionPolicyAlertOnlyMock() exceptionPolicyRegex := postureLabelsRegexExceptionPolicyAlertOnlyMock() exceptionPolicyRegex.Resources[0].Attributes["myLabelOrAnnotation"] = "static_.*" @@ -201,6 +232,24 @@ func TestGetResourceExceptions(t *testing.T) { workloadObj: withAnnotationObj, expectedExceptionsCount: 1, }, + { + desc: "exception by ID", + exceptionPolicy: exceptionPolicyResourceID, + workloadObj: idObj, + expectedExceptionsCount: 1, + }, + { + desc: "exception by ID regex", + exceptionPolicy: exceptionPolicyResourceIDRegex, + workloadObj: idObj, + expectedExceptionsCount: 1, + }, + { + desc: "exception with not matching ID", + exceptionPolicy: exceptionPolicyResourceOtherID, + workloadObj: idObj, + expectedExceptionsCount: 0, + }, } for _, test := range testCases { @@ -208,7 +257,7 @@ func TestGetResourceExceptions(t *testing.T) { t.Run(test.desc, func(t *testing.T) { t.Parallel() - res := p.GetResourceExceptions([]armotypes.PostureExceptionPolicy{*exceptionPolicy}, test.workloadObj, "") + res := p.GetResourceExceptions([]armotypes.PostureExceptionPolicy{*test.exceptionPolicy}, test.workloadObj, "test") assert.Equal(t, test.expectedExceptionsCount, len(res)) }) } diff --git a/go.mod b/go.mod index 0fe03f41..9dab26f5 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/kubescape/opa-utils go 1.19 require ( - github.com/armosec/armoapi-go v0.0.151 + github.com/armosec/armoapi-go v0.0.173 github.com/armosec/utils-go v0.0.12 github.com/francoispqt/gojay v1.2.13 github.com/kubescape/k8s-interface v0.0.99 @@ -92,6 +92,7 @@ require ( github.com/pquerna/cachecontrol v0.1.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stripe/stripe-go/v74 v74.8.0 // indirect github.com/vektah/gqlparser/v2 v2.4.5 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect diff --git a/go.sum b/go.sum index bf86878e..684f855a 100644 --- a/go.sum +++ b/go.sum @@ -164,8 +164,8 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= 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.151 h1:vyoQVk1y8cb4DHlfRKyFqDtiB1G13w4o5aoG8+YUMq0= -github.com/armosec/armoapi-go v0.0.151/go.mod h1:5MQAHYUFm1JrTSgb4+EglR5vNsrqUD0krh/5xWm2RdI= +github.com/armosec/armoapi-go v0.0.173 h1:TwNxmTxx9ATJPZBlld/53s/WvSVUfoF4gxgHT6UbFng= +github.com/armosec/armoapi-go v0.0.173/go.mod h1:xlW8dGq0vVzbuk+kDZqMQIkfU9P/iiiiDavoCIboqgI= github.com/armosec/utils-go v0.0.12 h1:NXkG/BhbSVAmTVXr0qqsK02CmxEiXuJyPmdTRcZ4jAo= github.com/armosec/utils-go v0.0.12/go.mod h1:F/K1mI/qcj7fNuJl7xktoCeHM83azOF0Zq6eC2WuPyU= github.com/armosec/utils-k8s-go v0.0.12 h1:u7kHSUp4PpvPP3hEaRXMbM0Vw23IyLhAzzE+2TW6Jkk= @@ -1088,6 +1088,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stripe/stripe-go/v74 v74.8.0 h1:0+3EfQSBhMg8SQ1+w+AP6Gxyko2crWbUG2uXbzYs8SU= +github.com/stripe/stripe-go/v74 v74.8.0/go.mod h1:5PoXNp30AJ3tGq57ZcFuaMylzNi8KpwlrYAFmO1fHZw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=