mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +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:
parent
6b3be9ada1
commit
7a1d4374c6
29 changed files with 127 additions and 97 deletions
|
@ -213,7 +213,8 @@ func main() {
|
||||||
)
|
)
|
||||||
engine := engine.NewEngine(
|
engine := engine.NewEngine(
|
||||||
configuration,
|
configuration,
|
||||||
engine.LegacyContextLoaderFactory(rclient, configMapResolver),
|
dClient,
|
||||||
|
engine.LegacyContextLoaderFactory(dClient, rclient, configMapResolver),
|
||||||
// TODO: do we need exceptions here ?
|
// TODO: do we need exceptions here ?
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
|
|
@ -476,7 +476,8 @@ OuterLoop:
|
||||||
}
|
}
|
||||||
eng := engine.NewEngine(
|
eng := engine.NewEngine(
|
||||||
cfg,
|
cfg,
|
||||||
engine.LegacyContextLoaderFactory(registryclient.NewOrDie(), nil),
|
c.Client,
|
||||||
|
engine.LegacyContextLoaderFactory(c.Client, registryclient.NewOrDie(), nil),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
policyContext := engine.NewPolicyContextWithJsonContext(ctx).
|
policyContext := engine.NewPolicyContextWithJsonContext(ctx).
|
||||||
|
@ -484,7 +485,6 @@ OuterLoop:
|
||||||
WithNewResource(*updatedResource).
|
WithNewResource(*updatedResource).
|
||||||
WithNamespaceLabels(namespaceLabels).
|
WithNamespaceLabels(namespaceLabels).
|
||||||
WithAdmissionInfo(c.UserInfo).
|
WithAdmissionInfo(c.UserInfo).
|
||||||
WithClient(c.Client).
|
|
||||||
WithSubresourcesInPolicy(subresources)
|
WithSubresourcesInPolicy(subresources)
|
||||||
|
|
||||||
mutateResponse := eng.Mutate(
|
mutateResponse := eng.Mutate(
|
||||||
|
@ -1080,7 +1080,8 @@ func initializeMockController(objects []runtime.Object) (*generate.GenerateContr
|
||||||
client.SetDiscovery(dclient.NewFakeDiscoveryClient(nil))
|
client.SetDiscovery(dclient.NewFakeDiscoveryClient(nil))
|
||||||
c := generate.NewGenerateControllerWithOnlyClient(client, engine.NewEngine(
|
c := generate.NewGenerateControllerWithOnlyClient(client, engine.NewEngine(
|
||||||
config.NewDefaultConfiguration(),
|
config.NewDefaultConfiguration(),
|
||||||
engine.LegacyContextLoaderFactory(nil, nil),
|
client,
|
||||||
|
engine.LegacyContextLoaderFactory(client, nil, nil),
|
||||||
nil,
|
nil,
|
||||||
))
|
))
|
||||||
return c, nil
|
return c, nil
|
||||||
|
|
|
@ -366,7 +366,8 @@ func main() {
|
||||||
}
|
}
|
||||||
eng := engine.NewEngine(
|
eng := engine.NewEngine(
|
||||||
configuration,
|
configuration,
|
||||||
engine.LegacyContextLoaderFactory(rclient, configMapResolver),
|
dClient,
|
||||||
|
engine.LegacyContextLoaderFactory(dClient, rclient, configMapResolver),
|
||||||
exceptionsLister,
|
exceptionsLister,
|
||||||
)
|
)
|
||||||
// create non leader controllers
|
// create non leader controllers
|
||||||
|
|
|
@ -314,7 +314,8 @@ func main() {
|
||||||
go eventGenerator.Run(ctx, 3)
|
go eventGenerator.Run(ctx, 3)
|
||||||
eng := engine.NewEngine(
|
eng := engine.NewEngine(
|
||||||
configuration,
|
configuration,
|
||||||
engine.LegacyContextLoaderFactory(rclient, configMapResolver),
|
dClient,
|
||||||
|
engine.LegacyContextLoaderFactory(dClient, rclient, configMapResolver),
|
||||||
exceptionsLister,
|
exceptionsLister,
|
||||||
)
|
)
|
||||||
// setup leader election
|
// setup leader election
|
||||||
|
|
|
@ -81,8 +81,7 @@ func NewBackgroundContext(dclient dclient.Interface, ur *kyvernov1beta1.UpdateRe
|
||||||
WithNewResource(*trigger).
|
WithNewResource(*trigger).
|
||||||
WithOldResource(old).
|
WithOldResource(old).
|
||||||
WithAdmissionInfo(ur.Spec.Context.UserRequestInfo).
|
WithAdmissionInfo(ur.Spec.Context.UserRequestInfo).
|
||||||
WithNamespaceLabels(namespaceLabels).
|
WithNamespaceLabels(namespaceLabels)
|
||||||
WithClient(dclient)
|
|
||||||
|
|
||||||
return policyContext, false, nil
|
return policyContext, false, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,6 @@ func (s *scanner) validateResource(ctx context.Context, resource unstructured.Un
|
||||||
policyCtx := engine.NewPolicyContextWithJsonContext(enginectx).
|
policyCtx := engine.NewPolicyContextWithJsonContext(enginectx).
|
||||||
WithNewResource(resource).
|
WithNewResource(resource).
|
||||||
WithPolicy(policy).
|
WithPolicy(policy).
|
||||||
WithClient(s.client).
|
|
||||||
WithNamespaceLabels(nsLabels)
|
WithNamespaceLabels(nsLabels)
|
||||||
return s.engine.Validate(ctx, policyCtx), nil
|
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).
|
policyCtx := engine.NewPolicyContextWithJsonContext(enginectx).
|
||||||
WithNewResource(resource).
|
WithNewResource(resource).
|
||||||
WithPolicy(policy).
|
WithPolicy(policy).
|
||||||
WithClient(s.client).
|
|
||||||
WithNamespaceLabels(nsLabels)
|
WithNamespaceLabels(nsLabels)
|
||||||
response, _ := s.engine.VerifyAndPatchImages(ctx, s.rclient, policyCtx)
|
response, _ := s.engine.VerifyAndPatchImages(ctx, s.rclient, policyCtx)
|
||||||
if len(response.PolicyResponse.Rules) > 0 {
|
if len(response.PolicyResponse.Rules) > 0 {
|
||||||
|
|
|
@ -7,8 +7,10 @@ import (
|
||||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
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
|
type ContextLoaderFactory = func(pContext PolicyContext, ruleName string) ContextLoader
|
||||||
|
|
||||||
|
// ContextLoader abstracts the mechanics to load context entries in the underlying json context
|
||||||
type ContextLoader interface {
|
type ContextLoader interface {
|
||||||
Load(ctx context.Context, contextEntries []kyvernov1.ContextEntry, jsonContext enginecontext.Interface) error
|
Load(ctx context.Context, contextEntries []kyvernov1.ContextEntry, jsonContext enginecontext.Interface) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,19 +4,10 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||||
kyvernov2alpha1 "github.com/kyverno/kyverno/api/kyverno/v2alpha1"
|
|
||||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type NamespacedResourceSelector[T any] interface {
|
// Engine is the main interface to run policies against resources
|
||||||
// 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]
|
|
||||||
|
|
||||||
type Engine interface {
|
type Engine interface {
|
||||||
// Validate applies validation rules from policy on the resource
|
// Validate applies validation rules from policy on the resource
|
||||||
Validate(
|
Validate(
|
||||||
|
|
|
@ -3,7 +3,6 @@ package api
|
||||||
import (
|
import (
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
|
||||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
@ -31,6 +30,5 @@ type PolicyContext interface {
|
||||||
SetElement(element unstructured.Unstructured)
|
SetElement(element unstructured.Unstructured)
|
||||||
|
|
||||||
JSONContext() enginecontext.Interface
|
JSONContext() enginecontext.Interface
|
||||||
Client() dclient.Interface
|
|
||||||
Copy() PolicyContext
|
Copy() PolicyContext
|
||||||
}
|
}
|
||||||
|
|
17
pkg/engine/api/selector.go
Normal file
17
pkg/engine/api/selector.go
Normal 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]
|
|
@ -84,7 +84,7 @@ func (e *engine) filterRule(
|
||||||
logger := logging.WithName("exception")
|
logger := logging.WithName("exception")
|
||||||
|
|
||||||
kindsInPolicy := append(rule.MatchResources.GetKinds(), rule.ExcludeResources.GetKinds()...)
|
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
|
// check if there is a corresponding policy exception
|
||||||
ruleResp := hasPolicyExceptions(logger, e.exceptionSelector, policyContext, &rule, subresourceGVKToAPIResource, e.configuration)
|
ruleResp := hasPolicyExceptions(logger, e.exceptionSelector, policyContext, &rule, subresourceGVKToAPIResource, e.configuration)
|
||||||
|
|
|
@ -3,13 +3,14 @@ package engine
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
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.
|
// 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)
|
subresourceGVKToAPIResource := make(map[string]*metav1.APIResource)
|
||||||
for _, gvk := range kindsInPolicy {
|
for _, gvk := range kindsInPolicy {
|
||||||
gv, k := kubeutils.GetKindFromGVK(gvk)
|
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
|
// 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 err == nil {
|
||||||
if kubeutils.IsSubresource(apiResource.Name) {
|
if kubeutils.IsSubresource(apiResource.Name) {
|
||||||
subresourceGVKToAPIResource[gvk] = apiResource
|
subresourceGVKToAPIResource[gvk] = apiResource
|
||||||
|
|
|
@ -51,7 +51,7 @@ func Test_GetSubresourceGVKToAPIResourceMap(t *testing.T) {
|
||||||
|
|
||||||
kindsInPolicy := []string{"Pod", "Eviction", "Pod/status", "Pod/eviction"}
|
kindsInPolicy := []string{"Pod", "Eviction", "Pod/status", "Pod/eviction"}
|
||||||
|
|
||||||
subresourceGVKToAPIResourceMap := GetSubresourceGVKToAPIResourceMap(kindsInPolicy, policyContext)
|
subresourceGVKToAPIResourceMap := GetSubresourceGVKToAPIResourceMap(nil, kindsInPolicy, policyContext)
|
||||||
|
|
||||||
podStatusResourceFromMap := subresourceGVKToAPIResourceMap["Pod/status"]
|
podStatusResourceFromMap := subresourceGVKToAPIResourceMap["Pod/status"]
|
||||||
assert.Equal(t, podStatusResourceFromMap.Name, podStatusAPIResource.Name)
|
assert.Equal(t, podStatusResourceFromMap.Name, podStatusAPIResource.Name)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||||
|
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||||
"github.com/kyverno/kyverno/pkg/config"
|
"github.com/kyverno/kyverno/pkg/config"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||||
|
@ -11,17 +12,20 @@ import (
|
||||||
|
|
||||||
type engine struct {
|
type engine struct {
|
||||||
configuration config.Configuration
|
configuration config.Configuration
|
||||||
|
client dclient.Interface
|
||||||
contextLoader engineapi.ContextLoaderFactory
|
contextLoader engineapi.ContextLoaderFactory
|
||||||
exceptionSelector engineapi.PolicyExceptionSelector
|
exceptionSelector engineapi.PolicyExceptionSelector
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEngine(
|
func NewEngine(
|
||||||
configuration config.Configuration,
|
configuration config.Configuration,
|
||||||
|
client dclient.Interface,
|
||||||
contextLoader engineapi.ContextLoaderFactory,
|
contextLoader engineapi.ContextLoaderFactory,
|
||||||
exceptionSelector engineapi.PolicyExceptionSelector,
|
exceptionSelector engineapi.PolicyExceptionSelector,
|
||||||
) engineapi.Engine {
|
) engineapi.Engine {
|
||||||
return &engine{
|
return &engine{
|
||||||
configuration: configuration,
|
configuration: configuration,
|
||||||
|
client: client,
|
||||||
contextLoader: contextLoader,
|
contextLoader: contextLoader,
|
||||||
exceptionSelector: exceptionSelector,
|
exceptionSelector: exceptionSelector,
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ func (e *engine) verifyAndPatchImages(
|
||||||
}
|
}
|
||||||
|
|
||||||
kindsInPolicy := append(rule.MatchResources.GetKinds(), rule.ExcludeResources.GetKinds()...)
|
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) {
|
if !matches(logger, rule, policyContext, subresourceGVKToAPIResource, e.configuration) {
|
||||||
return
|
return
|
||||||
|
|
|
@ -169,7 +169,8 @@ func testVerifyAndPatchImages(
|
||||||
) (*engineapi.EngineResponse, *engineapi.ImageVerificationMetadata) {
|
) (*engineapi.EngineResponse, *engineapi.ImageVerificationMetadata) {
|
||||||
e := NewEngine(
|
e := NewEngine(
|
||||||
cfg,
|
cfg,
|
||||||
LegacyContextLoaderFactory(rclient, cmResolver),
|
nil,
|
||||||
|
LegacyContextLoaderFactory(nil, rclient, cmResolver),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
return e.VerifyAndPatchImages(
|
return e.VerifyAndPatchImages(
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func LegacyContextLoaderFactory(
|
func LegacyContextLoaderFactory(
|
||||||
|
client dclient.Interface,
|
||||||
rclient registryclient.Client,
|
rclient registryclient.Client,
|
||||||
cmResolver engineapi.ConfigmapResolver,
|
cmResolver engineapi.ConfigmapResolver,
|
||||||
) engineapi.ContextLoaderFactory {
|
) engineapi.ContextLoaderFactory {
|
||||||
|
@ -29,7 +30,7 @@ func LegacyContextLoaderFactory(
|
||||||
logger: logging.WithName("MockContextLoaderFactory"),
|
logger: logging.WithName("MockContextLoaderFactory"),
|
||||||
policyName: policy.GetName(),
|
policyName: policy.GetName(),
|
||||||
ruleName: ruleName,
|
ruleName: ruleName,
|
||||||
client: pContext.Client(),
|
client: client,
|
||||||
rclient: rclient,
|
rclient: rclient,
|
||||||
cmResolver: cmResolver,
|
cmResolver: cmResolver,
|
||||||
}
|
}
|
||||||
|
@ -38,7 +39,7 @@ func LegacyContextLoaderFactory(
|
||||||
return func(pContext engineapi.PolicyContext, ruleName string) engineapi.ContextLoader {
|
return func(pContext engineapi.PolicyContext, ruleName string) engineapi.ContextLoader {
|
||||||
return &contextLoader{
|
return &contextLoader{
|
||||||
logger: logging.WithName("LegacyContextLoaderFactory"),
|
logger: logging.WithName("LegacyContextLoaderFactory"),
|
||||||
client: pContext.Client(),
|
client: client,
|
||||||
rclient: rclient,
|
rclient: rclient,
|
||||||
cmResolver: cmResolver,
|
cmResolver: cmResolver,
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,26 @@ const (
|
||||||
//go:embed resources/default-config.yaml
|
//go:embed resources/default-config.yaml
|
||||||
var defaultConfigBytes []byte
|
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) {
|
if isDeleteRequest(ctx) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
ruleResp := handleVerifyManifest(ctx, rule, log)
|
ruleResp := handleVerifyManifest(client, ctx, rule, log)
|
||||||
return ruleResp
|
return ruleResp
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleVerifyManifest(ctx engineapi.PolicyContext, rule *kyvernov1.Rule, logger logr.Logger) *engineapi.RuleResponse {
|
func handleVerifyManifest(
|
||||||
verified, reason, err := verifyManifest(ctx, *rule.Validation.Manifests, logger)
|
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 {
|
if err != nil {
|
||||||
logger.V(3).Info("verifyManifest return err", "error", err.Error())
|
logger.V(3).Info("verifyManifest return err", "error", err.Error())
|
||||||
return internal.RuleError(rule, engineapi.Validation, "error occurred during manifest verification", err)
|
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)
|
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
|
// load AdmissionRequest
|
||||||
request, err := policyContext.JSONContext().Query("request")
|
request, err := policyContext.JSONContext().Query("request")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -106,7 +121,7 @@ func verifyManifest(policyContext engineapi.PolicyContext, verifyRule kyvernov1.
|
||||||
}
|
}
|
||||||
if !vo.DisableDryRun {
|
if !vo.DisableDryRun {
|
||||||
// check if kyverno can 'create' dryrun resource
|
// 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 {
|
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())
|
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
|
vo.DisableDryRun = true
|
||||||
|
|
|
@ -628,7 +628,7 @@ func Test_VerifyManifest_SignedYAML(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
logger := logr.Discard()
|
logger := logr.Discard()
|
||||||
verified, _, err := verifyManifest(policyContext, verifyRule, logger)
|
verified, _, err := verifyManifest(nil, policyContext, verifyRule, logger)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, verified, true)
|
assert.Equal(t, verified, true)
|
||||||
}
|
}
|
||||||
|
@ -650,7 +650,7 @@ func Test_VerifyManifest_UnsignedYAML(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
logger := logr.Discard()
|
logger := logr.Discard()
|
||||||
verified, _, err := verifyManifest(policyContext, verifyRule, logger)
|
verified, _, err := verifyManifest(nil, policyContext, verifyRule, logger)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, verified, false)
|
assert.Equal(t, verified, false)
|
||||||
}
|
}
|
||||||
|
@ -672,7 +672,7 @@ func Test_VerifyManifest_InvalidYAML(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
logger := logr.Discard()
|
logger := logr.Discard()
|
||||||
verified, _, err := verifyManifest(policyContext, verifyRule, logger)
|
verified, _, err := verifyManifest(nil, policyContext, verifyRule, logger)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, verified, false)
|
assert.Equal(t, verified, false)
|
||||||
}
|
}
|
||||||
|
@ -699,7 +699,7 @@ func Test_VerifyManifest_MustAll_InvalidYAML(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
logger := logr.Discard()
|
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"]`
|
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.Error(t, err, errMsg)
|
||||||
assert.Equal(t, verified, false)
|
assert.Equal(t, verified, false)
|
||||||
|
@ -732,7 +732,7 @@ func Test_VerifyManifest_MustAll_ValidYAML(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
logger := logr.Discard()
|
logger := logr.Discard()
|
||||||
verified, _, err := verifyManifest(policyContext, verifyRule, logger)
|
verified, _, err := verifyManifest(nil, policyContext, verifyRule, logger)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, verified, true)
|
assert.Equal(t, verified, true)
|
||||||
}
|
}
|
||||||
|
@ -761,7 +761,7 @@ func Test_VerifyManifest_AtLeastOne(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
logger := logr.Discard()
|
logger := logr.Discard()
|
||||||
verified, _, err := verifyManifest(policyContext, verifyRule, logger)
|
verified, _, err := verifyManifest(nil, policyContext, verifyRule, logger)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, verified, true)
|
assert.Equal(t, verified, true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
|
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/variables"
|
"github.com/kyverno/kyverno/pkg/engine/variables"
|
||||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||||
|
@ -24,7 +25,12 @@ type resourceInfo struct {
|
||||||
parentResourceGVR metav1.GroupVersionResource
|
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 targetObjects []resourceInfo
|
||||||
var errors []error
|
var errors []error
|
||||||
|
|
||||||
|
@ -35,7 +41,7 @@ func loadTargets(targets []kyvernov1.ResourceSpec, ctx engineapi.PolicyContext,
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
objs, err := getTargets(spec, ctx)
|
objs, err := getTargets(client, spec, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errors = append(errors, err)
|
errors = append(errors, err)
|
||||||
continue
|
continue
|
||||||
|
@ -76,7 +82,11 @@ func resolveSpec(i int, target kyvernov1.ResourceSpec, ctx engineapi.PolicyConte
|
||||||
}, nil
|
}, 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
|
var targetObjects []resourceInfo
|
||||||
namespace := target.Namespace
|
namespace := target.Namespace
|
||||||
name := target.Name
|
name := target.Name
|
||||||
|
@ -86,7 +96,6 @@ func getTargets(target kyvernov1.ResourceSpec, ctx engineapi.PolicyContext) ([]r
|
||||||
if policy.IsNamespaced() {
|
if policy.IsNamespaced() {
|
||||||
namespace = policy.GetNamespace()
|
namespace = policy.GetNamespace()
|
||||||
}
|
}
|
||||||
client := ctx.Client()
|
|
||||||
apiResource, parentAPIResource, _, err := client.Discovery().FindResource(target.APIVersion, target.Kind)
|
apiResource, parentAPIResource, _, err := client.Discovery().FindResource(target.APIVersion, target.Kind)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -67,7 +67,7 @@ func (e *engine) mutate(
|
||||||
}
|
}
|
||||||
|
|
||||||
kindsInPolicy := append(rule.MatchResources.GetKinds(), rule.ExcludeResources.GetKinds()...)
|
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 {
|
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())
|
logger.V(4).Info("rule not matched", "reason", err.Error())
|
||||||
skippedRules = append(skippedRules, rule.Name)
|
skippedRules = append(skippedRules, rule.Name)
|
||||||
|
@ -104,7 +104,7 @@ func (e *engine) mutate(
|
||||||
ruleCopy := rule.DeepCopy()
|
ruleCopy := rule.DeepCopy()
|
||||||
var patchedResources []resourceInfo
|
var patchedResources []resourceInfo
|
||||||
if !policyContext.AdmissionOperation() && rule.IsMutateExisting() {
|
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 {
|
if err != nil {
|
||||||
rr := internal.RuleResponse(rule, engineapi.Mutation, err.Error(), engineapi.RuleStatusError)
|
rr := internal.RuleResponse(rule, engineapi.Mutation, err.Error(), engineapi.RuleStatusError)
|
||||||
resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, *rr)
|
resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, *rr)
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store"
|
"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"
|
client "github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||||
|
@ -22,12 +23,14 @@ import (
|
||||||
|
|
||||||
func testMutate(
|
func testMutate(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
client dclient.Interface,
|
||||||
rclient registryclient.Client,
|
rclient registryclient.Client,
|
||||||
pContext *PolicyContext,
|
pContext *PolicyContext,
|
||||||
) *engineapi.EngineResponse {
|
) *engineapi.EngineResponse {
|
||||||
e := NewEngine(
|
e := NewEngine(
|
||||||
cfg,
|
cfg,
|
||||||
LegacyContextLoaderFactory(rclient, nil),
|
client,
|
||||||
|
LegacyContextLoaderFactory(client, rclient, nil),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
return e.Mutate(
|
return e.Mutate(
|
||||||
|
@ -111,7 +114,7 @@ func Test_VariableSubstitutionPatchStrategicMerge(t *testing.T) {
|
||||||
jsonContext: ctx,
|
jsonContext: ctx,
|
||||||
newResource: *resourceUnstructured,
|
newResource: *resourceUnstructured,
|
||||||
}
|
}
|
||||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
|
||||||
t.Log(string(expectedPatch))
|
t.Log(string(expectedPatch))
|
||||||
|
|
||||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||||
|
@ -185,7 +188,7 @@ func Test_variableSubstitutionPathNotExist(t *testing.T) {
|
||||||
jsonContext: ctx,
|
jsonContext: ctx,
|
||||||
newResource: *resourceUnstructured,
|
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), 1)
|
||||||
assert.Assert(t, strings.Contains(er.PolicyResponse.Rules[0].Message, "Unknown key \"name1\" in path"))
|
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,
|
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), 1)
|
||||||
assert.Equal(t, len(er.PolicyResponse.Rules[0].Patches), 1)
|
assert.Equal(t, len(er.PolicyResponse.Rules[0].Patches), 1)
|
||||||
t.Log(string(expectedPatch))
|
t.Log(string(expectedPatch))
|
||||||
|
@ -387,7 +390,7 @@ func Test_chained_rules(t *testing.T) {
|
||||||
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
|
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||||
assert.NilError(t, err)
|
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")
|
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, containers[0].(map[string]interface{})["image"], "otherregistry.corp.com/foo/bash:5.0")
|
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,
|
newResource: *resourceUnstructured,
|
||||||
}
|
}
|
||||||
|
|
||||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
|
||||||
t.Log(string(expectedPatch))
|
t.Log(string(expectedPatch))
|
||||||
t.Log(string(er.PolicyResponse.Rules[0].Patches[0]))
|
t.Log(string(er.PolicyResponse.Rules[0].Patches[0]))
|
||||||
if !reflect.DeepEqual(expectedPatch, 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,
|
newResource: *resourceUnstructured,
|
||||||
}
|
}
|
||||||
|
|
||||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
|
||||||
t.Log(string(expectedPatch))
|
t.Log(string(expectedPatch))
|
||||||
t.Log(string(er.PolicyResponse.Rules[0].Patches[0]))
|
t.Log(string(er.PolicyResponse.Rules[0].Patches[0]))
|
||||||
if !reflect.DeepEqual(expectedPatch, 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)
|
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||||
assert.NilError(t, err)
|
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, len(er.PolicyResponse.Rules), 1)
|
||||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
|
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)
|
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||||
assert.NilError(t, err)
|
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, len(er.PolicyResponse.Rules), 1)
|
||||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
|
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)
|
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||||
assert.NilError(t, err)
|
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, len(er.PolicyResponse.Rules), 1)
|
||||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
|
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)
|
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
er := testMutate(context.TODO(), nil, registryclient.NewOrDie(), policyContext)
|
||||||
return er
|
return er
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1594,13 +1597,12 @@ func Test_mutate_existing_resources(t *testing.T) {
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
policyContext = &PolicyContext{
|
policyContext = &PolicyContext{
|
||||||
client: dclient,
|
|
||||||
policy: &policy,
|
policy: &policy,
|
||||||
jsonContext: ctx,
|
jsonContext: ctx,
|
||||||
newResource: *trigger,
|
newResource: *trigger,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
er := testMutate(context.TODO(), dclient, registryclient.NewOrDie(), policyContext)
|
||||||
|
|
||||||
for _, rr := range er.PolicyResponse.Rules {
|
for _, rr := range er.PolicyResponse.Rules {
|
||||||
for i, p := range rr.Patches {
|
for i, p := range rr.Patches {
|
||||||
|
@ -1609,6 +1611,7 @@ func Test_mutate_existing_resources(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_RuleSelectorMutate(t *testing.T) {
|
func Test_RuleSelectorMutate(t *testing.T) {
|
||||||
|
@ -1708,7 +1711,7 @@ func Test_RuleSelectorMutate(t *testing.T) {
|
||||||
newResource: *resourceUnstructured,
|
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), 2)
|
||||||
assert.Equal(t, len(er.PolicyResponse.Rules[0].Patches), 1)
|
assert.Equal(t, len(er.PolicyResponse.Rules[0].Patches), 1)
|
||||||
assert.Equal(t, len(er.PolicyResponse.Rules[1].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
|
applyOne := kyverno.ApplyOne
|
||||||
policyContext.policy.GetSpec().ApplyRules = &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), 1)
|
||||||
assert.Equal(t, len(er.PolicyResponse.Rules[0].Patches), 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.
|
// 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) {
|
if !reflect.DeepEqual(patches, tt.want) {
|
||||||
t.Errorf("Mutate() got patches %s, expected %s", patches, tt.want)
|
t.Errorf("Mutate() got patches %s, expected %s", patches, tt.want)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
|
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
|
||||||
"github.com/kyverno/kyverno/pkg/config"
|
"github.com/kyverno/kyverno/pkg/config"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
enginectx "github.com/kyverno/kyverno/pkg/engine/context"
|
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).
|
// and `requestResource: {group:"apps", version:"v1beta1", resource:"deployments"}` (indicating the resource of the original API request).
|
||||||
requestResource metav1.GroupVersionResource
|
requestResource metav1.GroupVersionResource
|
||||||
|
|
||||||
// Dynamic client - used for api lookups
|
|
||||||
client dclient.Interface
|
|
||||||
|
|
||||||
// jsonContext is the variable context
|
// jsonContext is the variable context
|
||||||
jsonContext enginectx.Interface
|
jsonContext enginectx.Interface
|
||||||
|
|
||||||
|
@ -113,10 +109,6 @@ func (c *PolicyContext) JSONContext() enginectx.Interface {
|
||||||
return c.jsonContext
|
return c.jsonContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *PolicyContext) Client() dclient.Interface {
|
|
||||||
return c.client
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c PolicyContext) Copy() engineapi.PolicyContext {
|
func (c PolicyContext) Copy() engineapi.PolicyContext {
|
||||||
return c.copy()
|
return c.copy()
|
||||||
}
|
}
|
||||||
|
@ -163,12 +155,6 @@ func (c *PolicyContext) WithResources(newResource unstructured.Unstructured, old
|
||||||
return c.WithNewResource(newResource).WithOldResource(oldResource)
|
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 {
|
func (c *PolicyContext) withAdmissionOperation(admissionOperation bool) *PolicyContext {
|
||||||
copy := c.copy()
|
copy := c.copy()
|
||||||
copy.admissionOperation = admissionOperation
|
copy.admissionOperation = admissionOperation
|
||||||
|
@ -207,7 +193,6 @@ func NewPolicyContextFromAdmissionRequest(
|
||||||
request *admissionv1.AdmissionRequest,
|
request *admissionv1.AdmissionRequest,
|
||||||
admissionInfo kyvernov1beta1.RequestInfo,
|
admissionInfo kyvernov1beta1.RequestInfo,
|
||||||
configuration config.Configuration,
|
configuration config.Configuration,
|
||||||
client dclient.Interface,
|
|
||||||
) (*PolicyContext, error) {
|
) (*PolicyContext, error) {
|
||||||
ctx, err := newVariablesContext(request, &admissionInfo)
|
ctx, err := newVariablesContext(request, &admissionInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -225,7 +210,6 @@ func NewPolicyContextFromAdmissionRequest(
|
||||||
WithNewResource(newResource).
|
WithNewResource(newResource).
|
||||||
WithOldResource(oldResource).
|
WithOldResource(oldResource).
|
||||||
WithAdmissionInfo(admissionInfo).
|
WithAdmissionInfo(admissionInfo).
|
||||||
WithClient(client).
|
|
||||||
withAdmissionOperation(true).
|
withAdmissionOperation(true).
|
||||||
WithRequestResource(*requestResource).
|
WithRequestResource(*requestResource).
|
||||||
WithSubresource(request.SubResource)
|
WithSubresource(request.SubResource)
|
||||||
|
|
|
@ -87,7 +87,7 @@ func (e *engine) validateResource(
|
||||||
}
|
}
|
||||||
log = log.WithValues("rule", rule.Name)
|
log = log.WithValues("rule", rule.Name)
|
||||||
kindsInPolicy := append(rule.MatchResources.GetKinds(), rule.ExcludeResources.GetKinds()...)
|
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) {
|
if !matches(log, rule, enginectx, subresourceGVKToAPIResource, e.configuration) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -104,7 +104,7 @@ func (e *engine) validateResource(
|
||||||
} else if hasValidateImage {
|
} else if hasValidateImage {
|
||||||
return e.processImageValidationRule(ctx, log, enginectx, rule)
|
return e.processImageValidationRule(ctx, log, enginectx, rule)
|
||||||
} else if hasYAMLSignatureVerify {
|
} else if hasYAMLSignatureVerify {
|
||||||
return processYAMLValidationRule(log, enginectx, rule)
|
return processYAMLValidationRule(e.client, log, enginectx, rule)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,7 +22,8 @@ import (
|
||||||
func testValidate(ctx context.Context, rclient registryclient.Client, pContext *PolicyContext, cfg config.Configuration) *engineapi.EngineResponse {
|
func testValidate(ctx context.Context, rclient registryclient.Client, pContext *PolicyContext, cfg config.Configuration) *engineapi.EngineResponse {
|
||||||
e := NewEngine(
|
e := NewEngine(
|
||||||
cfg,
|
cfg,
|
||||||
LegacyContextLoaderFactory(rclient, nil),
|
nil,
|
||||||
|
LegacyContextLoaderFactory(nil, rclient, nil),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
return e.Validate(
|
return e.Validate(
|
||||||
|
|
|
@ -148,7 +148,8 @@ func runTestCase(t *testing.T, tc TestCase) bool {
|
||||||
policyContext := engine.NewPolicyContext().WithPolicy(policy).WithNewResource(*resource)
|
policyContext := engine.NewPolicyContext().WithPolicy(policy).WithNewResource(*resource)
|
||||||
eng := engine.NewEngine(
|
eng := engine.NewEngine(
|
||||||
config.NewDefaultConfiguration(),
|
config.NewDefaultConfiguration(),
|
||||||
engine.LegacyContextLoaderFactory(registryclient.NewOrDie(), nil),
|
nil,
|
||||||
|
engine.LegacyContextLoaderFactory(nil, registryclient.NewOrDie(), nil),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
er := eng.Mutate(
|
er := eng.Mutate(
|
||||||
|
@ -183,7 +184,7 @@ func runTestCase(t *testing.T, tc TestCase) bool {
|
||||||
if err := createNamespace(client, resource); err != nil {
|
if err := createNamespace(client, resource); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
} else {
|
} else {
|
||||||
policyContext := policyContext.WithClient(client)
|
// policyContext := policyContext.WithClient(client)
|
||||||
|
|
||||||
er = eng.ApplyBackgroundChecks(
|
er = eng.ApplyBackgroundChecks(
|
||||||
policyContext,
|
policyContext,
|
||||||
|
|
|
@ -58,7 +58,8 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) webhook
|
||||||
urUpdater: webhookutils.NewUpdateRequestUpdater(kyvernoclient, urLister),
|
urUpdater: webhookutils.NewUpdateRequestUpdater(kyvernoclient, urLister),
|
||||||
engine: engine.NewEngine(
|
engine: engine.NewEngine(
|
||||||
configuration,
|
configuration,
|
||||||
engine.LegacyContextLoaderFactory(rclient, configMapResolver),
|
dclient,
|
||||||
|
engine.LegacyContextLoaderFactory(dclient, rclient, configMapResolver),
|
||||||
peLister,
|
peLister,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1051,7 +1051,8 @@ func TestValidate_failure_action_overrides(t *testing.T) {
|
||||||
|
|
||||||
eng := engine.NewEngine(
|
eng := engine.NewEngine(
|
||||||
config.NewDefaultConfiguration(),
|
config.NewDefaultConfiguration(),
|
||||||
engine.LegacyContextLoaderFactory(registryclient.NewOrDie(), nil),
|
nil,
|
||||||
|
engine.LegacyContextLoaderFactory(nil, registryclient.NewOrDie(), nil),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
for i, tc := range testcases {
|
for i, tc := range testcases {
|
||||||
|
@ -1128,7 +1129,8 @@ func Test_RuleSelector(t *testing.T) {
|
||||||
|
|
||||||
eng := engine.NewEngine(
|
eng := engine.NewEngine(
|
||||||
config.NewDefaultConfiguration(),
|
config.NewDefaultConfiguration(),
|
||||||
engine.LegacyContextLoaderFactory(registryclient.NewOrDie(), nil),
|
nil,
|
||||||
|
engine.LegacyContextLoaderFactory(nil, registryclient.NewOrDie(), nil),
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
resp := eng.Validate(
|
resp := eng.Validate(
|
||||||
|
|
|
@ -18,7 +18,6 @@ type PolicyContextBuilder interface {
|
||||||
|
|
||||||
type policyContextBuilder struct {
|
type policyContextBuilder struct {
|
||||||
configuration config.Configuration
|
configuration config.Configuration
|
||||||
client dclient.Interface
|
|
||||||
rbLister rbacv1listers.RoleBindingLister
|
rbLister rbacv1listers.RoleBindingLister
|
||||||
crbLister rbacv1listers.ClusterRoleBindingLister
|
crbLister rbacv1listers.ClusterRoleBindingLister
|
||||||
}
|
}
|
||||||
|
@ -31,7 +30,6 @@ func NewPolicyContextBuilder(
|
||||||
) PolicyContextBuilder {
|
) PolicyContextBuilder {
|
||||||
return &policyContextBuilder{
|
return &policyContextBuilder{
|
||||||
configuration: configuration,
|
configuration: configuration,
|
||||||
client: client,
|
|
||||||
rbLister: rbLister,
|
rbLister: rbLister,
|
||||||
crbLister: crbLister,
|
crbLister: crbLister,
|
||||||
}
|
}
|
||||||
|
@ -47,5 +45,5 @@ func (b *policyContextBuilder) Build(request *admissionv1.AdmissionRequest) (*en
|
||||||
userRequestInfo.Roles = roles
|
userRequestInfo.Roles = roles
|
||||||
userRequestInfo.ClusterRoles = clusterRoles
|
userRequestInfo.ClusterRoles = clusterRoles
|
||||||
}
|
}
|
||||||
return engine.NewPolicyContextFromAdmissionRequest(request, userRequestInfo, b.configuration, b.client)
|
return engine.NewPolicyContextFromAdmissionRequest(request, userRequestInfo, b.configuration)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue