1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-29 02:45:06 +00:00

fix ns selector (#6887)

* fix ns selector

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* remove debug

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add kuttl tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

---------

Signed-off-by: Jim Bugwadia <jim@nirmata.com>
Co-authored-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Jim Bugwadia 2023-04-13 01:17:28 -07:00 committed by GitHub
parent 2948adba57
commit a054f7c957
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 140 additions and 8 deletions

View file

@ -122,7 +122,7 @@ func doesResourceMatchConditionBlock(
errs = append(errs, fmt.Errorf("failed to parse namespace selector: %v", err))
} else {
if !hasPassed {
errs = append(errs, fmt.Errorf("namespace selector does not match"))
errs = append(errs, fmt.Errorf("namespace selector does not match labels"))
}
}
}

View file

@ -196,7 +196,7 @@ func (gen *generator) syncHandler(key Info) error {
eventType = corev1.EventTypeNormal
}
logger.V(2).Info("creating the event", "source", key.Source, "type", eventType, "resource", key.Resource())
logger.V(3).Info("creating the event", "source", key.Source, "type", eventType, "resource", key.Resource())
// based on the source of event generation, use different event recorders
switch key.Source {
case AdmissionController:

View file

@ -51,8 +51,8 @@ func (i *ImageInfo) ReferenceWithTag() string {
}
func GetImageInfo(image string, cfg config.Configuration) (*ImageInfo, error) {
logger.V(2).Info(
"Getting the image info",
logger.V(3).Info(
"getting the image info",
"image", image,
"defaultRegistry", config.Configuration.GetDefaultRegistry(cfg),
"enableDefaultRegistryMutation", config.Configuration.GetEnableDefaultRegistryMutation(cfg),
@ -86,8 +86,8 @@ func GetImageInfo(image string, cfg config.Configuration) (*ImageInfo, error) {
registry = ""
}
logger.V(2).Info(
"Getting the image info",
logger.V(3).Info(
"getting the image info",
"image", image,
"registry", registry,
"name", name,

View file

@ -176,7 +176,7 @@ func (h *resourceHandlers) Mutate(ctx context.Context, logger logr.Logger, reque
logger.Error(err, "failed to build policy context")
return admissionutils.Response(request.UID, err)
}
ivh := imageverification.NewImageVerificationHandler(logger, h.kyvernoClient, h.engine, h.eventGen, h.admissionReports, h.configuration)
ivh := imageverification.NewImageVerificationHandler(logger, h.kyvernoClient, h.engine, h.eventGen, h.admissionReports, h.configuration, h.nsLister)
imagePatches, imageVerifyWarnings, err := ivh.Handle(ctx, newRequest, verifyImagesPolicies, policyContext)
if err != nil {
logger.Error(err, "image verification failed")

View file

@ -14,6 +14,7 @@ import (
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/tracing"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
engineutils "github.com/kyverno/kyverno/pkg/utils/engine"
jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
reportutils "github.com/kyverno/kyverno/pkg/utils/report"
webhookutils "github.com/kyverno/kyverno/pkg/webhooks/utils"
@ -21,6 +22,7 @@ import (
admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
corev1listers "k8s.io/client-go/listers/core/v1"
)
type ImageVerificationHandler interface {
@ -34,6 +36,7 @@ type imageVerificationHandler struct {
eventGen event.Interface
admissionReports bool
cfg config.Configuration
nsLister corev1listers.NamespaceLister
}
func NewImageVerificationHandler(
@ -43,6 +46,7 @@ func NewImageVerificationHandler(
eventGen event.Interface,
admissionReports bool,
cfg config.Configuration,
nsLister corev1listers.NamespaceLister,
) ImageVerificationHandler {
return &imageVerificationHandler{
kyvernoClient: kyvernoClient,
@ -51,6 +55,7 @@ func NewImageVerificationHandler(
eventGen: eventGen,
admissionReports: admissionReports,
cfg: cfg,
nsLister: nsLister,
}
}
@ -81,24 +86,34 @@ func (h *imageVerificationHandler) handleVerifyImages(
var engineResponses []engineapi.EngineResponse
var patches [][]byte
verifiedImageData := engineapi.ImageVerificationMetadata{}
failurePolicy := kyvernov1.Ignore
for _, policy := range policies {
tracing.ChildSpan(
ctx,
"",
fmt.Sprintf("POLICY %s/%s", policy.GetNamespace(), policy.GetName()),
func(ctx context.Context, span trace.Span) {
if policy.GetSpec().GetFailurePolicy() == kyvernov1.Fail {
failurePolicy = kyvernov1.Fail
}
policyContext := policyContext.WithPolicy(policy)
if request.Kind.Kind != "Namespace" && request.Namespace != "" {
policyContext = policyContext.WithNamespaceLabels(engineutils.GetNamespaceSelectorsFromNamespaceLister(request.Kind.Kind, request.Namespace, h.nsLister, h.log))
}
resp, ivm := h.engine.VerifyAndPatchImages(ctx, policyContext)
if !resp.IsEmpty() {
engineResponses = append(engineResponses, resp)
}
patches = append(patches, resp.GetPatches()...)
verifiedImageData.Merge(ivm)
},
)
}
failurePolicy := policies[0].GetSpec().GetFailurePolicy()
blocked := webhookutils.BlockRequest(engineResponses, failurePolicy, logger)
events := webhookutils.GenerateEvents(engineResponses, blocked)
h.eventGen.Add(events...)

View file

@ -0,0 +1,9 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: keyed-basic-ns-selector-policy
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

View file

@ -0,0 +1,47 @@
apiVersion: v1
kind: Namespace
metadata:
name: test-verify-images
labels:
signed: "true"
---
apiVersion: v1
kind: Namespace
metadata:
name: test-verify-images-unprotected
labels:
signed: "false"
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: keyed-basic-ns-selector-policy
spec:
validationFailureAction: Enforce
background: false
webhookTimeoutSeconds: 30
failurePolicy: Fail
rules:
- name: keyed-basic-rule
match:
all:
- resources:
kinds:
- Pod
namespaceSelector:
matchExpressions:
- key: signed
operator: In
values:
- "true"
verifyImages:
- imageReferences:
- "ghcr.io/kyverno/test-verify-image:*"
attestors:
- entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM
5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA==
-----END PUBLIC KEY-----

View file

@ -0,0 +1,5 @@
apiVersion: v1
kind: Pod
metadata:
name: test-signed-pod
namespace: test-verify-images

View file

@ -0,0 +1,9 @@
apiVersion: v1
kind: Pod
metadata:
name: test-signed-pod
namespace: test-verify-images
spec:
containers:
- image: ghcr.io/kyverno/test-verify-image:signed
name: test-secret

View file

@ -0,0 +1,9 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
apply:
- file: pod-unsigned.yaml
shouldFail: true
- file: pod-signed.yaml
shouldFail: false
- file: pod-unprotected-ns.yaml
shouldFail: false

View file

@ -0,0 +1,11 @@
## Description
This test performs a simple verification of an image using a public key specified directly in the policy.
## Expected Behavior
Pod creation should pass as the image has been signed by the public key specified in the policy.
## Reference Issue(s)
N/A

View file

@ -0,0 +1,9 @@
apiVersion: v1
kind: Pod
metadata:
name: test-signed-pod2
namespace: test-verify-images
spec:
containers:
- image: ghcr.io/kyverno/test-verify-image:signed
name: test-signed2

View file

@ -0,0 +1,9 @@
apiVersion: v1
kind: Pod
metadata:
name: test-unsigned-pod
namespace: test-verify-images-unprotected
spec:
containers:
- image: ghcr.io/kyverno/test-verify-image:unsigned
name: test-unsigned

View file

@ -0,0 +1,9 @@
apiVersion: v1
kind: Pod
metadata:
name: test-unsigned-pod
namespace: test-verify-images
spec:
containers:
- image: ghcr.io/kyverno/test-verify-image:unsigned
name: test-unsigned