1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-28 02:18:15 +00:00

fix: policy exceptions not working in background mode (#5980)

* fix: policy exceptions not working in background mode

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* kuttl tests

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* fix kuttl test

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* Update test/conformance/kuttl/reports/admission/exception/README.md

Signed-off-by: shuting <shutting06@gmail.com>

* Update test/conformance/kuttl/reports/background/exception/README.md

Signed-off-by: shuting <shutting06@gmail.com>

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
Signed-off-by: shuting <shutting06@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
Co-authored-by: shuting <shutting06@gmail.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-01-13 11:58:02 +01:00 committed by GitHub
parent b66b06b70b
commit 07264a3f3f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 226 additions and 4 deletions

View file

@ -176,6 +176,7 @@ func createReportControllers(
var ctrls []internal.Controller
var warmups []func(context.Context) error
kyvernoV1 := kyvernoInformer.Kyverno().V1()
kyvernoV2Alpha1 := kyvernoInformer.Kyverno().V2alpha1()
if backgroundScan || admissionReports {
resourceReportController := resourcereportcontroller.NewController(
client,
@ -224,6 +225,7 @@ func createReportControllers(
kyvernoV1.Policies(),
kyvernoV1.ClusterPolicies(),
kubeInformer.Core().V1().Namespaces(),
kyvernoV2Alpha1.PolicyExceptions(),
resourceReportController,
configMapResolver,
backgroundScanInterval,

View file

@ -11,7 +11,9 @@ import (
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
"github.com/kyverno/kyverno/pkg/client/clientset/versioned"
kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1"
kyvernov2alpha1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v2alpha1"
kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1"
kyvernov2alpha1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v2alpha1"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/controllers"
@ -55,6 +57,7 @@ type controller struct {
bgscanrLister cache.GenericLister
cbgscanrLister cache.GenericLister
nsLister corev1listers.NamespaceLister
polexLister kyvernov2alpha1listers.PolicyExceptionLister
// queue
queue workqueue.RateLimitingInterface
@ -77,6 +80,7 @@ func NewController(
polInformer kyvernov1informers.PolicyInformer,
cpolInformer kyvernov1informers.ClusterPolicyInformer,
nsInformer corev1informers.NamespaceInformer,
polexInformer kyvernov2alpha1informers.PolicyExceptionInformer,
metadataCache resource.MetadataCache,
informerCacheResolvers resolvers.ConfigmapResolver,
forceDelay time.Duration,
@ -95,6 +99,7 @@ func NewController(
bgscanrLister: bgscanr.Lister(),
cbgscanrLister: cbgscanr.Lister(),
nsLister: nsInformer.Lister(),
polexLister: polexInformer.Lister(),
queue: queue,
metadataCache: metadataCache,
informerCacheResolvers: informerCacheResolvers,
@ -305,7 +310,7 @@ func (c *controller) reconcileReport(
// calculate necessary results
for _, policy := range backgroundPolicies {
if full || actual[reportutils.PolicyLabel(policy)] != policy.GetResourceVersion() {
scanner := utils.NewScanner(logger, c.client, c.rclient, c.informerCacheResolvers, c.config)
scanner := utils.NewScanner(logger, c.client, c.rclient, c.informerCacheResolvers, c.polexLister, c.config)
for _, result := range scanner.ScanResource(ctx, *target, nsLabels, policy) {
if result.Error != nil {
return result.Error

View file

@ -5,6 +5,7 @@ import (
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov2alpha1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v2alpha1"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine"
@ -21,6 +22,7 @@ type scanner struct {
client dclient.Interface
rclient registryclient.Client
informerCacheResolvers resolvers.ConfigmapResolver
polexLister kyvernov2alpha1listers.PolicyExceptionLister
excludeGroupRole []string
config config.Configuration
}
@ -39,6 +41,7 @@ func NewScanner(
client dclient.Interface,
rclient registryclient.Client,
informerCacheResolvers resolvers.ConfigmapResolver,
polexLister kyvernov2alpha1listers.PolicyExceptionLister,
config config.Configuration,
excludeGroupRole ...string,
) Scanner {
@ -47,6 +50,7 @@ func NewScanner(
client: client,
rclient: rclient,
informerCacheResolvers: informerCacheResolvers,
polexLister: polexLister,
config: config,
excludeGroupRole: excludeGroupRole,
}
@ -99,7 +103,8 @@ func (s *scanner) validateResource(ctx context.Context, resource unstructured.Un
WithClient(s.client).
WithNamespaceLabels(nsLabels).
WithExcludeGroupRole(s.excludeGroupRole...).
WithInformerCacheResolver(s.informerCacheResolvers)
WithInformerCacheResolver(s.informerCacheResolvers).
WithExceptions(s.polexLister)
return engine.Validate(ctx, s.rclient, policyCtx, s.config), nil
}
@ -123,7 +128,8 @@ func (s *scanner) validateImages(ctx context.Context, resource unstructured.Unst
WithClient(s.client).
WithNamespaceLabels(nsLabels).
WithExcludeGroupRole(s.excludeGroupRole...).
WithInformerCacheResolver(s.informerCacheResolvers)
WithInformerCacheResolver(s.informerCacheResolvers).
WithExceptions(s.polexLister)
response, _ := engine.VerifyAndPatchImages(ctx, s.rclient, policyCtx, s.config)
if len(response.PolicyResponse.Rules) > 0 {
s.logger.Info("validateImages", "policy", policy, "response", response)

View file

@ -818,7 +818,6 @@ func hasPolicyExceptions(ctx *PolicyContext, rule *kyvernov1.Rule, subresourceGV
Status: response.RuleStatusError,
}
}
log.V(3).Info("policy rule skipped due to policy exception", "exception", key)
return &response.RuleResponse{
Name: rule.Name,

View file

@ -0,0 +1,6 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
apply:
- policy.yaml
assert:
- policy-assert.yaml

View file

@ -0,0 +1,4 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
apply:
- exception.yaml

View file

@ -0,0 +1,6 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
apply:
- file: configmap.yaml
assert:
- configmap.yaml

View file

@ -0,0 +1,4 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
assert:
- report-assert.yaml

View file

@ -0,0 +1,12 @@
## Description
This test creates a policy, a policy exception and a configmap.
It makes sure the generated admission report contains a skipped result instead of a failed one.
## Steps
1. - Create a cluster policy
- Assert the policy becomes ready
1. - Create a policy exception for the cluster policy created above, configured to apply to configmap named `emergency`
1. - Try to create a confimap named `emergency`
1. - Assert that an admission report exists with a skipped result

View file

@ -0,0 +1,4 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: emergency

View file

@ -0,0 +1,16 @@
apiVersion: kyverno.io/v2alpha1
kind: PolicyException
metadata:
name: mynewpolex
spec:
exceptions:
- policyName: require-labels
ruleNames:
- require-team
match:
any:
- resources:
kinds:
- ConfigMap
names:
- emergency

View file

@ -0,0 +1,9 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

View file

@ -0,0 +1,20 @@
apiVersion: kyverno.io/v2beta1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-team
match:
any:
- resources:
kinds:
- ConfigMap
validate:
message: 'The label `team` is required.'
pattern:
metadata:
labels:
team: '?*'

View file

@ -0,0 +1,28 @@
apiVersion: kyverno.io/v1alpha2
kind: AdmissionReport
metadata:
ownerReferences:
- apiVersion: v1
kind: ConfigMap
name: emergency
spec:
owner:
apiVersion: v1
kind: ConfigMap
name: emergency
results:
- policy: require-labels
resources:
- apiVersion: v1
kind: ConfigMap
name: emergency
result: skip
rule: require-team
scored: true
source: kyverno
summary:
error: 0
fail: 0
pass: 0
skip: 1
warn: 0

View file

@ -0,0 +1,6 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
apply:
- policy.yaml
assert:
- policy-assert.yaml

View file

@ -0,0 +1,4 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
apply:
- exception.yaml

View file

@ -0,0 +1,6 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
apply:
- file: configmap.yaml
assert:
- configmap.yaml

View file

@ -0,0 +1,4 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
assert:
- report-assert.yaml

View file

@ -0,0 +1,12 @@
## Description
This test creates a policy, a policy exception and a configmap.
It makes sure the generated background scan report contains a skipped result instead of a failed one.
## Steps
1. - Create a cluster policy
- Assert the policy becomes ready
1. - Create a policy exception for the cluster policy created above, configured to apply to configmap named `emergency`
1. - Try to create a confimap named `emergency`
1. - Assert that an background scan report exists with a skipped result

View file

@ -0,0 +1,4 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: emergency

View file

@ -0,0 +1,16 @@
apiVersion: kyverno.io/v2alpha1
kind: PolicyException
metadata:
name: mynewpolex
spec:
exceptions:
- policyName: require-labels
ruleNames:
- require-team
match:
any:
- resources:
kinds:
- ConfigMap
names:
- emergency

View file

@ -0,0 +1,9 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

View file

@ -0,0 +1,20 @@
apiVersion: kyverno.io/v2beta1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-team
match:
any:
- resources:
kinds:
- ConfigMap
validate:
message: 'The label `team` is required.'
pattern:
metadata:
labels:
team: '?*'

View file

@ -0,0 +1,20 @@
apiVersion: kyverno.io/v1alpha2
kind: BackgroundScanReport
metadata:
ownerReferences:
- apiVersion: v1
kind: ConfigMap
name: emergency
spec:
results:
- policy: require-labels
result: skip
rule: require-team
scored: true
source: kyverno
summary:
error: 0
fail: 0
pass: 0
skip: 1
warn: 0