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

refactor: move client out of policy context (#6233)

* refactor: move client out of policy context

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

* fix

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

* fix

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

* fix test

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

---------

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-02-07 16:09:15 +01:00 committed by GitHub
parent 6b3be9ada1
commit 7a1d4374c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 127 additions and 97 deletions

View file

@ -213,7 +213,8 @@ func main() {
)
engine := engine.NewEngine(
configuration,
engine.LegacyContextLoaderFactory(rclient, configMapResolver),
dClient,
engine.LegacyContextLoaderFactory(dClient, rclient, configMapResolver),
// TODO: do we need exceptions here ?
nil,
)

View file

@ -476,7 +476,8 @@ OuterLoop:
}
eng := engine.NewEngine(
cfg,
engine.LegacyContextLoaderFactory(registryclient.NewOrDie(), nil),
c.Client,
engine.LegacyContextLoaderFactory(c.Client, registryclient.NewOrDie(), nil),
nil,
)
policyContext := engine.NewPolicyContextWithJsonContext(ctx).
@ -484,7 +485,6 @@ OuterLoop:
WithNewResource(*updatedResource).
WithNamespaceLabels(namespaceLabels).
WithAdmissionInfo(c.UserInfo).
WithClient(c.Client).
WithSubresourcesInPolicy(subresources)
mutateResponse := eng.Mutate(
@ -1080,7 +1080,8 @@ func initializeMockController(objects []runtime.Object) (*generate.GenerateContr
client.SetDiscovery(dclient.NewFakeDiscoveryClient(nil))
c := generate.NewGenerateControllerWithOnlyClient(client, engine.NewEngine(
config.NewDefaultConfiguration(),
engine.LegacyContextLoaderFactory(nil, nil),
client,
engine.LegacyContextLoaderFactory(client, nil, nil),
nil,
))
return c, nil

View file

@ -366,7 +366,8 @@ func main() {
}
eng := engine.NewEngine(
configuration,
engine.LegacyContextLoaderFactory(rclient, configMapResolver),
dClient,
engine.LegacyContextLoaderFactory(dClient, rclient, configMapResolver),
exceptionsLister,
)
// create non leader controllers

View file

@ -314,7 +314,8 @@ func main() {
go eventGenerator.Run(ctx, 3)
eng := engine.NewEngine(
configuration,
engine.LegacyContextLoaderFactory(rclient, configMapResolver),
dClient,
engine.LegacyContextLoaderFactory(dClient, rclient, configMapResolver),
exceptionsLister,
)
// setup leader election

View file

@ -81,8 +81,7 @@ func NewBackgroundContext(dclient dclient.Interface, ur *kyvernov1beta1.UpdateRe
WithNewResource(*trigger).
WithOldResource(old).
WithAdmissionInfo(ur.Spec.Context.UserRequestInfo).
WithNamespaceLabels(namespaceLabels).
WithClient(dclient)
WithNamespaceLabels(namespaceLabels)
return policyContext, false, nil
}

View file

@ -92,7 +92,6 @@ func (s *scanner) validateResource(ctx context.Context, resource unstructured.Un
policyCtx := engine.NewPolicyContextWithJsonContext(enginectx).
WithNewResource(resource).
WithPolicy(policy).
WithClient(s.client).
WithNamespaceLabels(nsLabels)
return s.engine.Validate(ctx, policyCtx), nil
}
@ -114,7 +113,6 @@ func (s *scanner) validateImages(ctx context.Context, resource unstructured.Unst
policyCtx := engine.NewPolicyContextWithJsonContext(enginectx).
WithNewResource(resource).
WithPolicy(policy).
WithClient(s.client).
WithNamespaceLabels(nsLabels)
response, _ := s.engine.VerifyAndPatchImages(ctx, s.rclient, policyCtx)
if len(response.PolicyResponse.Rules) > 0 {

View file

@ -7,8 +7,10 @@ import (
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
)
// ContextLoaderFactory provides a ContextLoader given a policy context and rule name
type ContextLoaderFactory = func(pContext PolicyContext, ruleName string) ContextLoader
// ContextLoader abstracts the mechanics to load context entries in the underlying json context
type ContextLoader interface {
Load(ctx context.Context, contextEntries []kyvernov1.ContextEntry, jsonContext enginecontext.Interface) error
}

View file

@ -4,19 +4,10 @@ import (
"context"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
kyvernov2alpha1 "github.com/kyverno/kyverno/api/kyverno/v2alpha1"
"github.com/kyverno/kyverno/pkg/registryclient"
"k8s.io/apimachinery/pkg/labels"
)
type NamespacedResourceSelector[T any] interface {
// List selects resources based on label selector.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []T, err error)
}
type PolicyExceptionSelector = NamespacedResourceSelector[*kyvernov2alpha1.PolicyException]
// Engine is the main interface to run policies against resources
type Engine interface {
// Validate applies validation rules from policy on the resource
Validate(

View file

@ -3,7 +3,6 @@ package api
import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/clients/dclient"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@ -31,6 +30,5 @@ type PolicyContext interface {
SetElement(element unstructured.Unstructured)
JSONContext() enginecontext.Interface
Client() dclient.Interface
Copy() PolicyContext
}

View file

@ -0,0 +1,17 @@
package api
import (
kyvernov2alpha1 "github.com/kyverno/kyverno/api/kyverno/v2alpha1"
"k8s.io/apimachinery/pkg/labels"
)
// NamespacedResourceSelector is an abstract interface used to list namespaced resources given a label selector
// Any implementation might exist, cache based, file based, client based etc...
type NamespacedResourceSelector[T any] interface {
// List selects resources based on label selector.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []T, err error)
}
// PolicyExceptionSelector is an abstract interface used to resolve poliicy exceptions
type PolicyExceptionSelector = NamespacedResourceSelector[*kyvernov2alpha1.PolicyException]

View file

@ -84,7 +84,7 @@ func (e *engine) filterRule(
logger := logging.WithName("exception")
kindsInPolicy := append(rule.MatchResources.GetKinds(), rule.ExcludeResources.GetKinds()...)
subresourceGVKToAPIResource := GetSubresourceGVKToAPIResourceMap(kindsInPolicy, policyContext)
subresourceGVKToAPIResource := GetSubresourceGVKToAPIResourceMap(e.client, kindsInPolicy, policyContext)
// check if there is a corresponding policy exception
ruleResp := hasPolicyExceptions(logger, e.exceptionSelector, policyContext, &rule, subresourceGVKToAPIResource, e.configuration)

View file

@ -3,13 +3,14 @@ package engine
import (
"strings"
"github.com/kyverno/kyverno/pkg/clients/dclient"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// GetSubresourceGVKToAPIResourceMap returns a map of subresource GVK to APIResource. This is used to determine if a resource is a subresource.
func GetSubresourceGVKToAPIResourceMap(kindsInPolicy []string, ctx engineapi.PolicyContext) map[string]*metav1.APIResource {
func GetSubresourceGVKToAPIResourceMap(client dclient.Interface, kindsInPolicy []string, ctx engineapi.PolicyContext) map[string]*metav1.APIResource {
subresourceGVKToAPIResource := make(map[string]*metav1.APIResource)
for _, gvk := range kindsInPolicy {
gv, k := kubeutils.GetKindFromGVK(gvk)
@ -50,9 +51,9 @@ func GetSubresourceGVKToAPIResourceMap(kindsInPolicy []string, ctx engineapi.Pol
}
}
}
} else if ctx.Client() != nil {
} else if client != nil {
// find the resource from API client
apiResource, _, _, err := ctx.Client().Discovery().FindResource(gv, k)
apiResource, _, _, err := client.Discovery().FindResource(gv, k)
if err == nil {
if kubeutils.IsSubresource(apiResource.Name) {
subresourceGVKToAPIResource[gvk] = apiResource

View file

@ -51,7 +51,7 @@ func Test_GetSubresourceGVKToAPIResourceMap(t *testing.T) {
kindsInPolicy := []string{"Pod", "Eviction", "Pod/status", "Pod/eviction"}
subresourceGVKToAPIResourceMap := GetSubresourceGVKToAPIResourceMap(kindsInPolicy, policyContext)
subresourceGVKToAPIResourceMap := GetSubresourceGVKToAPIResourceMap(nil, kindsInPolicy, policyContext)
podStatusResourceFromMap := subresourceGVKToAPIResourceMap["Pod/status"]
assert.Equal(t, podStatusResourceFromMap.Name, podStatusAPIResource.Name)

View file

@ -4,6 +4,7 @@ import (
"context"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/config"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/registryclient"
@ -11,17 +12,20 @@ import (
type engine struct {
configuration config.Configuration
client dclient.Interface
contextLoader engineapi.ContextLoaderFactory
exceptionSelector engineapi.PolicyExceptionSelector
}
func NewEngine(
configuration config.Configuration,
client dclient.Interface,
contextLoader engineapi.ContextLoaderFactory,
exceptionSelector engineapi.PolicyExceptionSelector,
) engineapi.Engine {
return &engine{
configuration: configuration,
client: client,
contextLoader: contextLoader,
exceptionSelector: exceptionSelector,
}

View file

@ -70,7 +70,7 @@ func (e *engine) verifyAndPatchImages(
}
kindsInPolicy := append(rule.MatchResources.GetKinds(), rule.ExcludeResources.GetKinds()...)
subresourceGVKToAPIResource := GetSubresourceGVKToAPIResourceMap(kindsInPolicy, policyContext)
subresourceGVKToAPIResource := GetSubresourceGVKToAPIResourceMap(e.client, kindsInPolicy, policyContext)
if !matches(logger, rule, policyContext, subresourceGVKToAPIResource, e.configuration) {
return

View file

@ -169,7 +169,8 @@ func testVerifyAndPatchImages(
) (*engineapi.EngineResponse, *engineapi.ImageVerificationMetadata) {
e := NewEngine(
cfg,
LegacyContextLoaderFactory(rclient, cmResolver),
nil,
LegacyContextLoaderFactory(nil, rclient, cmResolver),
nil,
)
return e.VerifyAndPatchImages(

View file

@ -19,6 +19,7 @@ import (
)
func LegacyContextLoaderFactory(
client dclient.Interface,
rclient registryclient.Client,
cmResolver engineapi.ConfigmapResolver,
) engineapi.ContextLoaderFactory {
@ -29,7 +30,7 @@ func LegacyContextLoaderFactory(
logger: logging.WithName("MockContextLoaderFactory"),
policyName: policy.GetName(),
ruleName: ruleName,
client: pContext.Client(),
client: client,
rclient: rclient,
cmResolver: cmResolver,
}
@ -38,7 +39,7 @@ func LegacyContextLoaderFactory(
return func(pContext engineapi.PolicyContext, ruleName string) engineapi.ContextLoader {
return &contextLoader{
logger: logging.WithName("LegacyContextLoaderFactory"),
client: pContext.Client(),
client: client,
rclient: rclient,
cmResolver: cmResolver,
}

View file

@ -35,16 +35,26 @@ const (
//go:embed resources/default-config.yaml
var defaultConfigBytes []byte
func processYAMLValidationRule(log logr.Logger, ctx engineapi.PolicyContext, rule *kyvernov1.Rule) *engineapi.RuleResponse {
func processYAMLValidationRule(
client dclient.Interface,
log logr.Logger,
ctx engineapi.PolicyContext,
rule *kyvernov1.Rule,
) *engineapi.RuleResponse {
if isDeleteRequest(ctx) {
return nil
}
ruleResp := handleVerifyManifest(ctx, rule, log)
ruleResp := handleVerifyManifest(client, ctx, rule, log)
return ruleResp
}
func handleVerifyManifest(ctx engineapi.PolicyContext, rule *kyvernov1.Rule, logger logr.Logger) *engineapi.RuleResponse {
verified, reason, err := verifyManifest(ctx, *rule.Validation.Manifests, logger)
func handleVerifyManifest(
client dclient.Interface,
ctx engineapi.PolicyContext,
rule *kyvernov1.Rule,
logger logr.Logger,
) *engineapi.RuleResponse {
verified, reason, err := verifyManifest(client, ctx, *rule.Validation.Manifests, logger)
if err != nil {
logger.V(3).Info("verifyManifest return err", "error", err.Error())
return internal.RuleError(rule, engineapi.Validation, "error occurred during manifest verification", err)
@ -56,7 +66,12 @@ func handleVerifyManifest(ctx engineapi.PolicyContext, rule *kyvernov1.Rule, log
return internal.RuleResponse(*rule, engineapi.Validation, reason, engineapi.RuleStatusPass)
}
func verifyManifest(policyContext engineapi.PolicyContext, verifyRule kyvernov1.Manifests, logger logr.Logger) (bool, string, error) {
func verifyManifest(
client dclient.Interface,
policyContext engineapi.PolicyContext,
verifyRule kyvernov1.Manifests,
logger logr.Logger,
) (bool, string, error) {
// load AdmissionRequest
request, err := policyContext.JSONContext().Query("request")
if err != nil {
@ -106,7 +121,7 @@ func verifyManifest(policyContext engineapi.PolicyContext, verifyRule kyvernov1.
}
if !vo.DisableDryRun {
// check if kyverno can 'create' dryrun resource
ok, err := checkDryRunPermission(policyContext.Client(), adreq.Kind.Kind, vo.DryRunNamespace)
ok, err := checkDryRunPermission(client, adreq.Kind.Kind, vo.DryRunNamespace)
if err != nil {
logger.V(1).Info("failed to check permissions to 'create' resource. disabled DryRun option.", "dryrun namespace", vo.DryRunNamespace, "kind", adreq.Kind.Kind, "error", err.Error())
vo.DisableDryRun = true

View file

@ -628,7 +628,7 @@ func Test_VerifyManifest_SignedYAML(t *testing.T) {
},
})
logger := logr.Discard()
verified, _, err := verifyManifest(policyContext, verifyRule, logger)
verified, _, err := verifyManifest(nil, policyContext, verifyRule, logger)
assert.NilError(t, err)
assert.Equal(t, verified, true)
}
@ -650,7 +650,7 @@ func Test_VerifyManifest_UnsignedYAML(t *testing.T) {
},
})
logger := logr.Discard()
verified, _, err := verifyManifest(policyContext, verifyRule, logger)
verified, _, err := verifyManifest(nil, policyContext, verifyRule, logger)
assert.NilError(t, err)
assert.Equal(t, verified, false)
}
@ -672,7 +672,7 @@ func Test_VerifyManifest_InvalidYAML(t *testing.T) {
},
})
logger := logr.Discard()
verified, _, err := verifyManifest(policyContext, verifyRule, logger)
verified, _, err := verifyManifest(nil, policyContext, verifyRule, logger)
assert.NilError(t, err)
assert.Equal(t, verified, false)
}
@ -699,7 +699,7 @@ func Test_VerifyManifest_MustAll_InvalidYAML(t *testing.T) {
},
})
logger := logr.Discard()
verified, _, err := verifyManifest(policyContext, verifyRule, logger)
verified, _, err := verifyManifest(nil, policyContext, verifyRule, logger)
errMsg := `.attestors[0].entries[1].keys: failed to verify signature: verification failed for 1 signature. all trials: ["[publickey 1/1] [signature 1/1] error: cosign.VerifyBlobCmd() returned an error: invalid signature when validating ASN.1 encoded signature"]`
assert.Error(t, err, errMsg)
assert.Equal(t, verified, false)
@ -732,7 +732,7 @@ func Test_VerifyManifest_MustAll_ValidYAML(t *testing.T) {
},
})
logger := logr.Discard()
verified, _, err := verifyManifest(policyContext, verifyRule, logger)
verified, _, err := verifyManifest(nil, policyContext, verifyRule, logger)
assert.NilError(t, err)
assert.Equal(t, verified, true)
}
@ -761,7 +761,7 @@ func Test_VerifyManifest_AtLeastOne(t *testing.T) {
},
})
logger := logr.Discard()
verified, _, err := verifyManifest(policyContext, verifyRule, logger)
verified, _, err := verifyManifest(nil, policyContext, verifyRule, logger)
assert.NilError(t, err)
assert.Equal(t, verified, true)
}

View file

@ -7,6 +7,7 @@ import (
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/clients/dclient"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/variables"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
@ -24,7 +25,12 @@ type resourceInfo struct {
parentResourceGVR metav1.GroupVersionResource
}
func loadTargets(targets []kyvernov1.ResourceSpec, ctx engineapi.PolicyContext, logger logr.Logger) ([]resourceInfo, error) {
func loadTargets(
client dclient.Interface,
targets []kyvernov1.ResourceSpec,
ctx engineapi.PolicyContext,
logger logr.Logger,
) ([]resourceInfo, error) {
var targetObjects []resourceInfo
var errors []error
@ -35,7 +41,7 @@ func loadTargets(targets []kyvernov1.ResourceSpec, ctx engineapi.PolicyContext,
continue
}
objs, err := getTargets(spec, ctx)
objs, err := getTargets(client, spec, ctx)
if err != nil {
errors = append(errors, err)
continue
@ -76,7 +82,11 @@ func resolveSpec(i int, target kyvernov1.ResourceSpec, ctx engineapi.PolicyConte
}, nil
}
func getTargets(target kyvernov1.ResourceSpec, ctx engineapi.PolicyContext) ([]resourceInfo, error) {
func getTargets(
client dclient.Interface,
target kyvernov1.ResourceSpec,
ctx engineapi.PolicyContext,
) ([]resourceInfo, error) {
var targetObjects []resourceInfo
namespace := target.Namespace
name := target.Name
@ -86,7 +96,6 @@ func getTargets(target kyvernov1.ResourceSpec, ctx engineapi.PolicyContext) ([]r
if policy.IsNamespaced() {
namespace = policy.GetNamespace()
}
client := ctx.Client()
apiResource, parentAPIResource, _, err := client.Discovery().FindResource(target.APIVersion, target.Kind)
if err != nil {
return nil, err

View file

@ -67,7 +67,7 @@ func (e *engine) mutate(
}
kindsInPolicy := append(rule.MatchResources.GetKinds(), rule.ExcludeResources.GetKinds()...)
subresourceGVKToAPIResource := GetSubresourceGVKToAPIResourceMap(kindsInPolicy, policyContext)
subresourceGVKToAPIResource := GetSubresourceGVKToAPIResourceMap(e.client, kindsInPolicy, policyContext)
if err = MatchesResourceDescription(subresourceGVKToAPIResource, matchedResource, rule, policyContext.AdmissionInfo(), excludeResource, policyContext.NamespaceLabels(), policyContext.Policy().GetNamespace(), policyContext.SubResource()); err != nil {
logger.V(4).Info("rule not matched", "reason", err.Error())
skippedRules = append(skippedRules, rule.Name)
@ -104,7 +104,7 @@ func (e *engine) mutate(
ruleCopy := rule.DeepCopy()
var patchedResources []resourceInfo
if !policyContext.AdmissionOperation() && rule.IsMutateExisting() {
targets, err := loadTargets(ruleCopy.Mutation.Targets, policyContext, logger)
targets, err := loadTargets(e.client, ruleCopy.Mutation.Targets, policyContext, logger)
if err != nil {
rr := internal.RuleResponse(rule, engineapi.Mutation, err.Error(), engineapi.RuleStatusError)
resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, *rr)

View file

@ -9,6 +9,7 @@ import (
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store"
"github.com/kyverno/kyverno/pkg/clients/dclient"
client "github.com/kyverno/kyverno/pkg/clients/dclient"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
@ -22,12 +23,14 @@ import (
func testMutate(
ctx context.Context,
client dclient.Interface,
rclient registryclient.Client,
pContext *PolicyContext,
) *engineapi.EngineResponse {
e := NewEngine(
cfg,
LegacyContextLoaderFactory(rclient, nil),
client,
LegacyContextLoaderFactory(client, rclient, nil),
nil,
)
return e.Mutate(
@ -111,7 +114,7 @@ func Test_VariableSubstitutionPatchStrategicMerge(t *testing.T) {
jsonContext: ctx,
newResource: *resourceUnstructured,
}
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
t.Log(string(expectedPatch))
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
@ -185,7 +188,7 @@ func Test_variableSubstitutionPathNotExist(t *testing.T) {
jsonContext: ctx,
newResource: *resourceUnstructured,
}
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Assert(t, strings.Contains(er.PolicyResponse.Rules[0].Message, "Unknown key \"name1\" in path"))
}
@ -278,7 +281,7 @@ func Test_variableSubstitutionCLI(t *testing.T) {
newResource: *resourceUnstructured,
}
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, len(er.PolicyResponse.Rules[0].Patches), 1)
t.Log(string(expectedPatch))
@ -387,7 +390,7 @@ func Test_chained_rules(t *testing.T) {
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
assert.NilError(t, err)
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
assert.NilError(t, err)
assert.Equal(t, containers[0].(map[string]interface{})["image"], "otherregistry.corp.com/foo/bash:5.0")
@ -475,7 +478,7 @@ func Test_precondition(t *testing.T) {
newResource: *resourceUnstructured,
}
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
t.Log(string(expectedPatch))
t.Log(string(er.PolicyResponse.Rules[0].Patches[0]))
if !reflect.DeepEqual(expectedPatch, er.PolicyResponse.Rules[0].Patches[0]) {
@ -572,7 +575,7 @@ func Test_nonZeroIndexNumberPatchesJson6902(t *testing.T) {
newResource: *resourceUnstructured,
}
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
t.Log(string(expectedPatch))
t.Log(string(er.PolicyResponse.Rules[0].Patches[0]))
if !reflect.DeepEqual(expectedPatch, er.PolicyResponse.Rules[0].Patches[0]) {
@ -666,7 +669,7 @@ func Test_foreach(t *testing.T) {
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
assert.NilError(t, err)
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
@ -773,7 +776,7 @@ func Test_foreach_element_mutation(t *testing.T) {
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
assert.NilError(t, err)
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
@ -899,7 +902,7 @@ func Test_Container_InitContainer_foreach(t *testing.T) {
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
assert.NilError(t, err)
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
@ -1049,7 +1052,7 @@ func testApplyPolicyToResource(t *testing.T, policyRaw, resourceRaw []byte) *eng
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
assert.NilError(t, err)
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
return er
}
@ -1594,18 +1597,18 @@ func Test_mutate_existing_resources(t *testing.T) {
assert.NilError(t, err)
policyContext = &PolicyContext{
client: dclient,
policy: &policy,
jsonContext: ctx,
newResource: *trigger,
}
}
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
for _, rr := range er.PolicyResponse.Rules {
for i, p := range rr.Patches {
assert.Equal(t, test.patches[i], string(p), "test %s failed:\nGot %s\nExpected: %s", test.name, rr.Patches[i], test.patches[i])
assert.Equal(t, rr.Status, engineapi.RuleStatusPass, rr.Status)
er := testMutate(context.TODO(), dclient, registryclient.NewOrDie(), policyContext)
for _, rr := range er.PolicyResponse.Rules {
for i, p := range rr.Patches {
assert.Equal(t, test.patches[i], string(p), "test %s failed:\nGot %s\nExpected: %s", test.name, rr.Patches[i], test.patches[i])
assert.Equal(t, rr.Status, engineapi.RuleStatusPass, rr.Status)
}
}
}
}
@ -1708,7 +1711,7 @@ func Test_RuleSelectorMutate(t *testing.T) {
newResource: *resourceUnstructured,
}
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
assert.Equal(t, len(er.PolicyResponse.Rules), 2)
assert.Equal(t, len(er.PolicyResponse.Rules[0].Patches), 1)
assert.Equal(t, len(er.PolicyResponse.Rules[1].Patches), 1)
@ -1723,7 +1726,7 @@ func Test_RuleSelectorMutate(t *testing.T) {
applyOne := kyverno.ApplyOne
policyContext.policy.GetSpec().ApplyRules = &applyOne
er = testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
er = testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, len(er.PolicyResponse.Rules[0].Patches), 1)
@ -2090,7 +2093,7 @@ func Test_SpecialCharacters(t *testing.T) {
}
// Mutate and make sure that we got the expected amount of rules.
patches := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext).GetPatches()
patches := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext).GetPatches()
if !reflect.DeepEqual(patches, tt.want) {
t.Errorf("Mutate() got patches %s, expected %s", patches, tt.want)
}

View file

@ -5,7 +5,6 @@ import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/config"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginectx "github.com/kyverno/kyverno/pkg/engine/context"
@ -42,9 +41,6 @@ type PolicyContext struct {
// and `requestResource: {group:"apps", version:"v1beta1", resource:"deployments"}` (indicating the resource of the original API request).
requestResource metav1.GroupVersionResource
// Dynamic client - used for api lookups
client dclient.Interface
// jsonContext is the variable context
jsonContext enginectx.Interface
@ -113,10 +109,6 @@ func (c *PolicyContext) JSONContext() enginectx.Interface {
return c.jsonContext
}
func (c *PolicyContext) Client() dclient.Interface {
return c.client
}
func (c PolicyContext) Copy() engineapi.PolicyContext {
return c.copy()
}
@ -163,12 +155,6 @@ func (c *PolicyContext) WithResources(newResource unstructured.Unstructured, old
return c.WithNewResource(newResource).WithOldResource(oldResource)
}
func (c *PolicyContext) WithClient(client dclient.Interface) *PolicyContext {
copy := c.copy()
copy.client = client
return copy
}
func (c *PolicyContext) withAdmissionOperation(admissionOperation bool) *PolicyContext {
copy := c.copy()
copy.admissionOperation = admissionOperation
@ -207,7 +193,6 @@ func NewPolicyContextFromAdmissionRequest(
request *admissionv1.AdmissionRequest,
admissionInfo kyvernov1beta1.RequestInfo,
configuration config.Configuration,
client dclient.Interface,
) (*PolicyContext, error) {
ctx, err := newVariablesContext(request, &admissionInfo)
if err != nil {
@ -225,7 +210,6 @@ func NewPolicyContextFromAdmissionRequest(
WithNewResource(newResource).
WithOldResource(oldResource).
WithAdmissionInfo(admissionInfo).
WithClient(client).
withAdmissionOperation(true).
WithRequestResource(*requestResource).
WithSubresource(request.SubResource)

View file

@ -87,7 +87,7 @@ func (e *engine) validateResource(
}
log = log.WithValues("rule", rule.Name)
kindsInPolicy := append(rule.MatchResources.GetKinds(), rule.ExcludeResources.GetKinds()...)
subresourceGVKToAPIResource := GetSubresourceGVKToAPIResourceMap(kindsInPolicy, enginectx)
subresourceGVKToAPIResource := GetSubresourceGVKToAPIResourceMap(e.client, kindsInPolicy, enginectx)
if !matches(log, rule, enginectx, subresourceGVKToAPIResource, e.configuration) {
return nil
@ -104,7 +104,7 @@ func (e *engine) validateResource(
} else if hasValidateImage {
return e.processImageValidationRule(ctx, log, enginectx, rule)
} else if hasYAMLSignatureVerify {
return processYAMLValidationRule(log, enginectx, rule)
return processYAMLValidationRule(e.client, log, enginectx, rule)
}
return nil
},

View file

@ -22,7 +22,8 @@ import (
func testValidate(ctx context.Context, rclient registryclient.Client, pContext *PolicyContext, cfg config.Configuration) *engineapi.EngineResponse {
e := NewEngine(
cfg,
LegacyContextLoaderFactory(rclient, nil),
nil,
LegacyContextLoaderFactory(nil, rclient, nil),
nil,
)
return e.Validate(

View file

@ -148,7 +148,8 @@ func runTestCase(t *testing.T, tc TestCase) bool {
policyContext := engine.NewPolicyContext().WithPolicy(policy).WithNewResource(*resource)
eng := engine.NewEngine(
config.NewDefaultConfiguration(),
engine.LegacyContextLoaderFactory(registryclient.NewOrDie(), nil),
nil,
engine.LegacyContextLoaderFactory(nil, registryclient.NewOrDie(), nil),
nil,
)
er := eng.Mutate(
@ -183,7 +184,7 @@ func runTestCase(t *testing.T, tc TestCase) bool {
if err := createNamespace(client, resource); err != nil {
t.Error(err)
} else {
policyContext := policyContext.WithClient(client)
// policyContext := policyContext.WithClient(client)
er = eng.ApplyBackgroundChecks(
policyContext,

View file

@ -58,7 +58,8 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) webhook
urUpdater: webhookutils.NewUpdateRequestUpdater(kyvernoclient, urLister),
engine: engine.NewEngine(
configuration,
engine.LegacyContextLoaderFactory(rclient, configMapResolver),
dclient,
engine.LegacyContextLoaderFactory(dclient, rclient, configMapResolver),
peLister,
),
}

View file

@ -1051,7 +1051,8 @@ func TestValidate_failure_action_overrides(t *testing.T) {
eng := engine.NewEngine(
config.NewDefaultConfiguration(),
engine.LegacyContextLoaderFactory(registryclient.NewOrDie(), nil),
nil,
engine.LegacyContextLoaderFactory(nil, registryclient.NewOrDie(), nil),
nil,
)
for i, tc := range testcases {
@ -1128,7 +1129,8 @@ func Test_RuleSelector(t *testing.T) {
eng := engine.NewEngine(
config.NewDefaultConfiguration(),
engine.LegacyContextLoaderFactory(registryclient.NewOrDie(), nil),
nil,
engine.LegacyContextLoaderFactory(nil, registryclient.NewOrDie(), nil),
nil,
)
resp := eng.Validate(

View file

@ -18,7 +18,6 @@ type PolicyContextBuilder interface {
type policyContextBuilder struct {
configuration config.Configuration
client dclient.Interface
rbLister rbacv1listers.RoleBindingLister
crbLister rbacv1listers.ClusterRoleBindingLister
}
@ -31,7 +30,6 @@ func NewPolicyContextBuilder(
) PolicyContextBuilder {
return &policyContextBuilder{
configuration: configuration,
client: client,
rbLister: rbLister,
crbLister: crbLister,
}
@ -47,5 +45,5 @@ func (b *policyContextBuilder) Build(request *admissionv1.AdmissionRequest) (*en
userRequestInfo.Roles = roles
userRequestInfo.ClusterRoles = clusterRoles
}
return engine.NewPolicyContextFromAdmissionRequest(request, userRequestInfo, b.configuration, b.client)
return engine.NewPolicyContextFromAdmissionRequest(request, userRequestInfo, b.configuration)
}