mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-15 20:20:22 +00:00
refactor: don't process context/preconditions in invokeHandler (#6751)
* refactor: engine handlers 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> * refactor: don't process context/preconditions in invokeHandler 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 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> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
e75c766acd
commit
b4a4e3a4f3
18 changed files with 217 additions and 219 deletions
|
@ -162,7 +162,7 @@ func (c *GenerateController) applyGenerate(resource unstructured.Unstructured, u
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the policy still applies to the resource
|
// check if the policy still applies to the resource
|
||||||
engineResponse := c.engine.GenerateResponse(context.Background(), policyContext, ur)
|
engineResponse := c.engine.Generate(context.Background(), policyContext)
|
||||||
if len(engineResponse.PolicyResponse.Rules) == 0 {
|
if len(engineResponse.PolicyResponse.Rules) == 0 {
|
||||||
logger.V(4).Info(doesNotApply)
|
logger.V(4).Info(doesNotApply)
|
||||||
return nil, errors.New(doesNotApply)
|
return nil, errors.New(doesNotApply)
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
|
||||||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -28,6 +27,12 @@ type Engine interface {
|
||||||
policyContext PolicyContext,
|
policyContext PolicyContext,
|
||||||
) EngineResponse
|
) EngineResponse
|
||||||
|
|
||||||
|
// Generate checks for validity of generate rule on the resource
|
||||||
|
Generate(
|
||||||
|
ctx context.Context,
|
||||||
|
policyContext PolicyContext,
|
||||||
|
) EngineResponse
|
||||||
|
|
||||||
// VerifyAndPatchImages ...
|
// VerifyAndPatchImages ...
|
||||||
VerifyAndPatchImages(
|
VerifyAndPatchImages(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
@ -44,13 +49,6 @@ type Engine interface {
|
||||||
policyContext PolicyContext,
|
policyContext PolicyContext,
|
||||||
) EngineResponse
|
) EngineResponse
|
||||||
|
|
||||||
// GenerateResponse checks for validity of generate rule on the resource
|
|
||||||
GenerateResponse(
|
|
||||||
ctx context.Context,
|
|
||||||
policyContext PolicyContext,
|
|
||||||
gr kyvernov1beta1.UpdateRequest,
|
|
||||||
) EngineResponse
|
|
||||||
|
|
||||||
ContextLoader(
|
ContextLoader(
|
||||||
policy kyvernov1.PolicyInterface,
|
policy kyvernov1.PolicyInterface,
|
||||||
rule kyvernov1.Rule,
|
rule kyvernov1.Rule,
|
||||||
|
|
|
@ -6,9 +6,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
gojmespath "github.com/jmespath/go-jmespath"
|
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
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/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"
|
||||||
|
@ -34,6 +32,7 @@ type engine struct {
|
||||||
validateResourceHandler handlers.Handler
|
validateResourceHandler handlers.Handler
|
||||||
validateManifestHandler handlers.Handler
|
validateManifestHandler handlers.Handler
|
||||||
validatePssHandler handlers.Handler
|
validatePssHandler handlers.Handler
|
||||||
|
validateImageHandler handlers.Handler
|
||||||
mutateResourceHandler handlers.Handler
|
mutateResourceHandler handlers.Handler
|
||||||
mutateExistingHandler handlers.Handler
|
mutateExistingHandler handlers.Handler
|
||||||
}
|
}
|
||||||
|
@ -63,11 +62,12 @@ func NewEngine(
|
||||||
rclient: rclient,
|
rclient: rclient,
|
||||||
engineContextLoaderFactory: engineContextLoaderFactory,
|
engineContextLoaderFactory: engineContextLoaderFactory,
|
||||||
exceptionSelector: exceptionSelector,
|
exceptionSelector: exceptionSelector,
|
||||||
validateResourceHandler: validation.NewValidateResourceHandler(engineContextLoaderFactory),
|
validateResourceHandler: validation.NewValidateResourceHandler(),
|
||||||
validateManifestHandler: validation.NewValidateManifestHandler(client),
|
validateManifestHandler: validation.NewValidateManifestHandler(client),
|
||||||
validatePssHandler: validation.NewValidatePssHandler(),
|
validatePssHandler: validation.NewValidatePssHandler(),
|
||||||
mutateResourceHandler: mutation.NewMutateResourceHandler(engineContextLoaderFactory),
|
validateImageHandler: validation.NewValidateImageHandler(configuration),
|
||||||
mutateExistingHandler: mutation.NewMutateExistingHandler(client, engineContextLoaderFactory),
|
mutateResourceHandler: mutation.NewMutateResourceHandler(),
|
||||||
|
mutateExistingHandler: mutation.NewMutateExistingHandler(client),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +99,19 @@ func (e *engine) Mutate(
|
||||||
return response.Done(time.Now())
|
return response.Done(time.Now())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *engine) Generate(
|
||||||
|
ctx context.Context,
|
||||||
|
policyContext engineapi.PolicyContext,
|
||||||
|
) engineapi.EngineResponse {
|
||||||
|
response := engineapi.NewEngineResponseFromPolicyContext(policyContext, time.Now())
|
||||||
|
logger := internal.LoggerWithPolicyContext(logging.WithName("engine.generate"), policyContext)
|
||||||
|
if internal.MatchPolicyContext(logger, policyContext, e.configuration) {
|
||||||
|
policyResponse := e.generateResponse(ctx, logger, policyContext)
|
||||||
|
response = response.WithPolicyResponse(policyResponse)
|
||||||
|
}
|
||||||
|
return response.Done(time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
func (e *engine) VerifyAndPatchImages(
|
func (e *engine) VerifyAndPatchImages(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
policyContext engineapi.PolicyContext,
|
policyContext engineapi.PolicyContext,
|
||||||
|
@ -126,20 +139,6 @@ func (e *engine) ApplyBackgroundChecks(
|
||||||
return response.Done(time.Now())
|
return response.Done(time.Now())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *engine) GenerateResponse(
|
|
||||||
ctx context.Context,
|
|
||||||
policyContext engineapi.PolicyContext,
|
|
||||||
gr kyvernov1beta1.UpdateRequest,
|
|
||||||
) engineapi.EngineResponse {
|
|
||||||
response := engineapi.NewEngineResponseFromPolicyContext(policyContext, time.Now())
|
|
||||||
logger := internal.LoggerWithPolicyContext(logging.WithName("engine.generate"), policyContext)
|
|
||||||
if internal.MatchPolicyContext(logger, policyContext, e.configuration) {
|
|
||||||
policyResponse := e.generateResponse(ctx, logger, policyContext, gr)
|
|
||||||
response = response.WithPolicyResponse(policyResponse)
|
|
||||||
}
|
|
||||||
return response.Done(time.Now())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *engine) ContextLoader(
|
func (e *engine) ContextLoader(
|
||||||
policy kyvernov1.PolicyInterface,
|
policy kyvernov1.PolicyInterface,
|
||||||
rule kyvernov1.Rule,
|
rule kyvernov1.Rule,
|
||||||
|
@ -189,7 +188,7 @@ func matches(
|
||||||
func (e *engine) invokeRuleHandler(
|
func (e *engine) invokeRuleHandler(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
logger logr.Logger,
|
logger logr.Logger,
|
||||||
handlerFactory handlers.HandlerFactory,
|
handler handlers.Handler,
|
||||||
policyContext engineapi.PolicyContext,
|
policyContext engineapi.PolicyContext,
|
||||||
resource unstructured.Unstructured,
|
resource unstructured.Unstructured,
|
||||||
rule kyvernov1.Rule,
|
rule kyvernov1.Rule,
|
||||||
|
@ -209,32 +208,8 @@ func (e *engine) invokeRuleHandler(
|
||||||
if ruleResp := e.hasPolicyExceptions(logger, ruleType, policyContext, rule); ruleResp != nil {
|
if ruleResp := e.hasPolicyExceptions(logger, ruleType, policyContext, rule); ruleResp != nil {
|
||||||
return resource, handlers.RuleResponses(ruleResp)
|
return resource, handlers.RuleResponses(ruleResp)
|
||||||
}
|
}
|
||||||
if handlerFactory == nil {
|
// process handler
|
||||||
return resource, handlers.RuleResponses(internal.RuleError(rule, ruleType, "failed to instantiate handler", nil))
|
return handler.Process(ctx, logger, policyContext, resource, rule, e.ContextLoader(policyContext.Policy(), rule))
|
||||||
} else if handler, err := handlerFactory(); err != nil {
|
|
||||||
return resource, handlers.RuleResponses(internal.RuleError(rule, ruleType, "failed to instantiate handler", err))
|
|
||||||
} else if handler != nil {
|
|
||||||
// load rule context
|
|
||||||
if err := internal.LoadContext(ctx, e, policyContext, rule); err != nil {
|
|
||||||
if _, ok := err.(gojmespath.NotFoundError); ok {
|
|
||||||
logger.V(3).Info("failed to load context", "reason", err.Error())
|
|
||||||
} else {
|
|
||||||
logger.Error(err, "failed to load context")
|
|
||||||
}
|
|
||||||
return resource, handlers.RuleResponses(internal.RuleError(rule, ruleType, "failed to load context", err))
|
|
||||||
}
|
|
||||||
// check preconditions
|
|
||||||
preconditionsPassed, err := internal.CheckPreconditions(logger, policyContext.JSONContext(), rule.GetAnyAllConditions())
|
|
||||||
if err != nil {
|
|
||||||
return resource, handlers.RuleResponses(internal.RuleError(rule, ruleType, "failed to evaluate preconditions", err))
|
|
||||||
}
|
|
||||||
if !preconditionsPassed {
|
|
||||||
return resource, handlers.RuleResponses(internal.RuleSkip(rule, ruleType, "preconditions not met"))
|
|
||||||
}
|
|
||||||
// process handler
|
|
||||||
return handler.Process(ctx, logger, policyContext, resource, rule)
|
|
||||||
}
|
|
||||||
return resource, nil
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,8 @@ package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
|
||||||
"github.com/kyverno/kyverno/pkg/autogen"
|
"github.com/kyverno/kyverno/pkg/autogen"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/internal"
|
"github.com/kyverno/kyverno/pkg/engine/internal"
|
||||||
|
@ -16,16 +14,6 @@ func (e *engine) generateResponse(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
logger logr.Logger,
|
logger logr.Logger,
|
||||||
policyContext engineapi.PolicyContext,
|
policyContext engineapi.PolicyContext,
|
||||||
gr kyvernov1beta1.UpdateRequest,
|
|
||||||
) engineapi.PolicyResponse {
|
|
||||||
return e.filterGenerateRules(policyContext, logger, gr.Spec.Policy, time.Now())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *engine) filterGenerateRules(
|
|
||||||
policyContext engineapi.PolicyContext,
|
|
||||||
logger logr.Logger,
|
|
||||||
policyNameKey string,
|
|
||||||
startTime time.Time,
|
|
||||||
) engineapi.PolicyResponse {
|
) engineapi.PolicyResponse {
|
||||||
resp := engineapi.NewPolicyResponse()
|
resp := engineapi.NewPolicyResponse()
|
||||||
for _, rule := range autogen.ComputeRules(policyContext.Policy()) {
|
for _, rule := range autogen.ComputeRules(policyContext.Policy()) {
|
||||||
|
|
|
@ -16,17 +16,10 @@ type Handler interface {
|
||||||
engineapi.PolicyContext,
|
engineapi.PolicyContext,
|
||||||
unstructured.Unstructured,
|
unstructured.Unstructured,
|
||||||
kyvernov1.Rule,
|
kyvernov1.Rule,
|
||||||
|
engineapi.EngineContextLoader,
|
||||||
) (unstructured.Unstructured, []engineapi.RuleResponse)
|
) (unstructured.Unstructured, []engineapi.RuleResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
type HandlerFactory = func() (Handler, error)
|
|
||||||
|
|
||||||
func WithHandler(handler Handler) HandlerFactory {
|
|
||||||
return func() (Handler, error) {
|
|
||||||
return handler, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func RuleResponses(rrs ...*engineapi.RuleResponse) []engineapi.RuleResponse {
|
func RuleResponses(rrs ...*engineapi.RuleResponse) []engineapi.RuleResponse {
|
||||||
var out []engineapi.RuleResponse
|
var out []engineapi.RuleResponse
|
||||||
for _, rr := range rrs {
|
for _, rr := range rrs {
|
||||||
|
|
|
@ -14,17 +14,26 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mutateResource(rule *kyvernov1.Rule, policyContext engineapi.PolicyContext, resource unstructured.Unstructured, logger logr.Logger) *mutate.Response {
|
func mutateResource(
|
||||||
|
ctx context.Context,
|
||||||
|
contextLoader engineapi.EngineContextLoader,
|
||||||
|
rule kyvernov1.Rule,
|
||||||
|
policyContext engineapi.PolicyContext,
|
||||||
|
resource unstructured.Unstructured,
|
||||||
|
logger logr.Logger,
|
||||||
|
) *mutate.Response {
|
||||||
|
if err := contextLoader(ctx, rule.Context, policyContext.JSONContext()); err != nil {
|
||||||
|
logger.Error(err, "failed to load context")
|
||||||
|
return mutate.NewErrorResponse("failed to load context", err)
|
||||||
|
}
|
||||||
preconditionsPassed, err := internal.CheckPreconditions(logger, policyContext.JSONContext(), rule.GetAnyAllConditions())
|
preconditionsPassed, err := internal.CheckPreconditions(logger, policyContext.JSONContext(), rule.GetAnyAllConditions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return mutate.NewErrorResponse("failed to evaluate preconditions", err)
|
return mutate.NewErrorResponse("failed to evaluate preconditions", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !preconditionsPassed {
|
if !preconditionsPassed {
|
||||||
return mutate.NewResponse(engineapi.RuleStatusSkip, resource, nil, "preconditions not met")
|
return mutate.NewResponse(engineapi.RuleStatusSkip, resource, nil, "preconditions not met")
|
||||||
}
|
}
|
||||||
|
return mutate.Mutate(&rule, policyContext.JSONContext(), resource, logger)
|
||||||
return mutate.Mutate(rule, policyContext.JSONContext(), resource, logger)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type forEachMutator struct {
|
type forEachMutator struct {
|
||||||
|
|
|
@ -14,17 +14,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type mutateExistingHandler struct {
|
type mutateExistingHandler struct {
|
||||||
client dclient.Interface
|
client dclient.Interface
|
||||||
contextLoader engineapi.EngineContextLoaderFactory
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMutateExistingHandler(
|
func NewMutateExistingHandler(
|
||||||
client dclient.Interface,
|
client dclient.Interface,
|
||||||
contextLoader engineapi.EngineContextLoaderFactory,
|
|
||||||
) handlers.Handler {
|
) handlers.Handler {
|
||||||
return mutateExistingHandler{
|
return mutateExistingHandler{
|
||||||
client: client,
|
client: client,
|
||||||
contextLoader: contextLoader,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,9 +31,8 @@ func (h mutateExistingHandler) Process(
|
||||||
policyContext engineapi.PolicyContext,
|
policyContext engineapi.PolicyContext,
|
||||||
resource unstructured.Unstructured,
|
resource unstructured.Unstructured,
|
||||||
rule kyvernov1.Rule,
|
rule kyvernov1.Rule,
|
||||||
|
contextLoader engineapi.EngineContextLoader,
|
||||||
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
||||||
policy := policyContext.Policy()
|
|
||||||
contextLoader := h.contextLoader(policy, rule)
|
|
||||||
var responses []engineapi.RuleResponse
|
var responses []engineapi.RuleResponse
|
||||||
logger.V(3).Info("processing mutate rule")
|
logger.V(3).Info("processing mutate rule")
|
||||||
var patchedResources []resourceInfo
|
var patchedResources []resourceInfo
|
||||||
|
@ -72,7 +68,7 @@ func (h mutateExistingHandler) Process(
|
||||||
}
|
}
|
||||||
mutateResp = m.mutateForEach(ctx)
|
mutateResp = m.mutateForEach(ctx)
|
||||||
} else {
|
} else {
|
||||||
mutateResp = mutateResource(&rule, policyContext, patchedResource.unstructured, logger)
|
mutateResp = mutateResource(ctx, contextLoader, rule, policyContext, patchedResource.unstructured, logger)
|
||||||
}
|
}
|
||||||
if ruleResponse := buildRuleResponse(&rule, mutateResp, patchedResource); ruleResponse != nil {
|
if ruleResponse := buildRuleResponse(&rule, mutateResp, patchedResource); ruleResponse != nil {
|
||||||
responses = append(responses, *ruleResponse)
|
responses = append(responses, *ruleResponse)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
|
gojmespath "github.com/jmespath/go-jmespath"
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
"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"
|
||||||
|
@ -13,7 +14,6 @@ import (
|
||||||
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
|
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/variables"
|
"github.com/kyverno/kyverno/pkg/engine/variables"
|
||||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||||
apiutils "github.com/kyverno/kyverno/pkg/utils/api"
|
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,30 +21,18 @@ type mutateImageHandler struct {
|
||||||
configuration config.Configuration
|
configuration config.Configuration
|
||||||
rclient registryclient.Client
|
rclient registryclient.Client
|
||||||
ivm *engineapi.ImageVerificationMetadata
|
ivm *engineapi.ImageVerificationMetadata
|
||||||
images []apiutils.ImageInfo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMutateImageHandler(
|
func NewMutateImageHandler(
|
||||||
policyContext engineapi.PolicyContext,
|
|
||||||
resource unstructured.Unstructured,
|
|
||||||
rule kyvernov1.Rule,
|
|
||||||
configuration config.Configuration,
|
configuration config.Configuration,
|
||||||
rclient registryclient.Client,
|
rclient registryclient.Client,
|
||||||
ivm *engineapi.ImageVerificationMetadata,
|
ivm *engineapi.ImageVerificationMetadata,
|
||||||
) (handlers.Handler, error) {
|
) handlers.Handler {
|
||||||
ruleImages, _, err := engineutils.ExtractMatchingImages(resource, policyContext.JSONContext(), rule, configuration)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(ruleImages) == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return mutateImageHandler{
|
return mutateImageHandler{
|
||||||
configuration: configuration,
|
configuration: configuration,
|
||||||
rclient: rclient,
|
rclient: rclient,
|
||||||
ivm: ivm,
|
ivm: ivm,
|
||||||
images: ruleImages,
|
}
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h mutateImageHandler) Process(
|
func (h mutateImageHandler) Process(
|
||||||
|
@ -53,11 +41,39 @@ func (h mutateImageHandler) Process(
|
||||||
policyContext engineapi.PolicyContext,
|
policyContext engineapi.PolicyContext,
|
||||||
resource unstructured.Unstructured,
|
resource unstructured.Unstructured,
|
||||||
rule kyvernov1.Rule,
|
rule kyvernov1.Rule,
|
||||||
|
contextLoader engineapi.EngineContextLoader,
|
||||||
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
||||||
|
if engineutils.IsDeleteRequest(policyContext) {
|
||||||
|
return resource, nil
|
||||||
|
}
|
||||||
if len(rule.VerifyImages) == 0 {
|
if len(rule.VerifyImages) == 0 {
|
||||||
return resource, nil
|
return resource, nil
|
||||||
}
|
}
|
||||||
|
ruleImages, _, err := engineutils.ExtractMatchingImages(resource, policyContext.JSONContext(), rule, h.configuration)
|
||||||
|
if err != nil {
|
||||||
|
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.ImageVerify, "failed to extract images", err))
|
||||||
|
}
|
||||||
|
if len(ruleImages) == 0 {
|
||||||
|
return resource, nil
|
||||||
|
}
|
||||||
jsonContext := policyContext.JSONContext()
|
jsonContext := policyContext.JSONContext()
|
||||||
|
// load context
|
||||||
|
if err := contextLoader(ctx, rule.Context, jsonContext); err != nil {
|
||||||
|
if _, ok := err.(gojmespath.NotFoundError); ok {
|
||||||
|
logger.V(3).Info("failed to load context", "reason", err.Error())
|
||||||
|
} else {
|
||||||
|
logger.Error(err, "failed to load context")
|
||||||
|
}
|
||||||
|
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.ImageVerify, "failed to load context", err))
|
||||||
|
}
|
||||||
|
// check preconditions
|
||||||
|
preconditionsPassed, err := internal.CheckPreconditions(logger, jsonContext, rule.GetAnyAllConditions())
|
||||||
|
if err != nil {
|
||||||
|
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.ImageVerify, "failed to evaluate preconditions", err))
|
||||||
|
}
|
||||||
|
if !preconditionsPassed {
|
||||||
|
return resource, handlers.RuleResponses(internal.RuleSkip(rule, engineapi.ImageVerify, "preconditions not met"))
|
||||||
|
}
|
||||||
ruleCopy, err := substituteVariables(rule, jsonContext, logger)
|
ruleCopy, err := substituteVariables(rule, jsonContext, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resource, handlers.RuleResponses(
|
return resource, handlers.RuleResponses(
|
||||||
|
@ -67,7 +83,7 @@ func (h mutateImageHandler) Process(
|
||||||
iv := internal.NewImageVerifier(logger, h.rclient, policyContext, *ruleCopy, h.ivm)
|
iv := internal.NewImageVerifier(logger, h.rclient, policyContext, *ruleCopy, h.ivm)
|
||||||
var engineResponses []*engineapi.RuleResponse
|
var engineResponses []*engineapi.RuleResponse
|
||||||
for _, imageVerify := range ruleCopy.VerifyImages {
|
for _, imageVerify := range ruleCopy.VerifyImages {
|
||||||
engineResponses = append(engineResponses, iv.Verify(ctx, imageVerify, h.images, h.configuration)...)
|
engineResponses = append(engineResponses, iv.Verify(ctx, imageVerify, ruleImages, h.configuration)...)
|
||||||
}
|
}
|
||||||
return resource, handlers.RuleResponses(engineResponses...)
|
return resource, handlers.RuleResponses(engineResponses...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,10 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mutateResourceHandler struct {
|
type mutateResourceHandler struct{}
|
||||||
contextLoader engineapi.EngineContextLoaderFactory
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMutateResourceHandler(
|
func NewMutateResourceHandler() handlers.Handler {
|
||||||
contextLoader engineapi.EngineContextLoaderFactory,
|
return mutateResourceHandler{}
|
||||||
) handlers.Handler {
|
|
||||||
return mutateResourceHandler{
|
|
||||||
contextLoader: contextLoader,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h mutateResourceHandler) Process(
|
func (h mutateResourceHandler) Process(
|
||||||
|
@ -30,9 +24,8 @@ func (h mutateResourceHandler) Process(
|
||||||
policyContext engineapi.PolicyContext,
|
policyContext engineapi.PolicyContext,
|
||||||
resource unstructured.Unstructured,
|
resource unstructured.Unstructured,
|
||||||
rule kyvernov1.Rule,
|
rule kyvernov1.Rule,
|
||||||
|
contextLoader engineapi.EngineContextLoader,
|
||||||
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
||||||
policy := policyContext.Policy()
|
|
||||||
contextLoader := h.contextLoader(policy, rule)
|
|
||||||
_, subresource := policyContext.ResourceKind()
|
_, subresource := policyContext.ResourceKind()
|
||||||
logger.V(3).Info("processing mutate rule")
|
logger.V(3).Info("processing mutate rule")
|
||||||
var parentResourceGVR metav1.GroupVersionResource
|
var parentResourceGVR metav1.GroupVersionResource
|
||||||
|
@ -58,7 +51,7 @@ func (h mutateResourceHandler) Process(
|
||||||
}
|
}
|
||||||
mutateResp = m.mutateForEach(ctx)
|
mutateResp = m.mutateForEach(ctx)
|
||||||
} else {
|
} else {
|
||||||
mutateResp = mutateResource(&rule, policyContext, resourceInfo.unstructured, logger)
|
mutateResp = mutateResource(ctx, contextLoader, rule, policyContext, resourceInfo.unstructured, logger)
|
||||||
}
|
}
|
||||||
if mutateResp == nil {
|
if mutateResp == nil {
|
||||||
return resource, nil
|
return resource, nil
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
|
gojmespath "github.com/jmespath/go-jmespath"
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
"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"
|
||||||
|
@ -15,22 +16,16 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
)
|
)
|
||||||
|
|
||||||
type validateImageHandler struct{}
|
type validateImageHandler struct {
|
||||||
|
configuration config.Configuration
|
||||||
|
}
|
||||||
|
|
||||||
func NewValidateImageHandler(
|
func NewValidateImageHandler(
|
||||||
policyContext engineapi.PolicyContext,
|
|
||||||
resource unstructured.Unstructured,
|
|
||||||
rule kyvernov1.Rule,
|
|
||||||
configuration config.Configuration,
|
configuration config.Configuration,
|
||||||
) (handlers.Handler, error) {
|
) handlers.Handler {
|
||||||
ruleImages, _, err := engineutils.ExtractMatchingImages(resource, policyContext.JSONContext(), rule, configuration)
|
return validateImageHandler{
|
||||||
if err != nil {
|
configuration: configuration,
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
if len(ruleImages) == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return validateImageHandler{}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h validateImageHandler) Process(
|
func (h validateImageHandler) Process(
|
||||||
|
@ -39,11 +34,32 @@ func (h validateImageHandler) Process(
|
||||||
policyContext engineapi.PolicyContext,
|
policyContext engineapi.PolicyContext,
|
||||||
resource unstructured.Unstructured,
|
resource unstructured.Unstructured,
|
||||||
rule kyvernov1.Rule,
|
rule kyvernov1.Rule,
|
||||||
|
contextLoader engineapi.EngineContextLoader,
|
||||||
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
||||||
if engineutils.IsDeleteRequest(policyContext) {
|
if engineutils.IsDeleteRequest(policyContext) {
|
||||||
return resource, nil
|
return resource, nil
|
||||||
}
|
}
|
||||||
preconditionsPassed, err := internal.CheckPreconditions(logger, policyContext.JSONContext(), rule.RawAnyAllConditions)
|
if len(rule.VerifyImages) == 0 {
|
||||||
|
return resource, nil
|
||||||
|
}
|
||||||
|
ruleImages, _, err := engineutils.ExtractMatchingImages(resource, policyContext.JSONContext(), rule, h.configuration)
|
||||||
|
if err != nil {
|
||||||
|
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.Validation, "failed to extract images", err))
|
||||||
|
}
|
||||||
|
if len(ruleImages) == 0 {
|
||||||
|
return resource, nil
|
||||||
|
}
|
||||||
|
// load context
|
||||||
|
if err := contextLoader(ctx, rule.Context, policyContext.JSONContext()); err != nil {
|
||||||
|
if _, ok := err.(gojmespath.NotFoundError); ok {
|
||||||
|
logger.V(3).Info("failed to load context", "reason", err.Error())
|
||||||
|
} else {
|
||||||
|
logger.Error(err, "failed to load context")
|
||||||
|
}
|
||||||
|
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.Validation, "failed to load context", err))
|
||||||
|
}
|
||||||
|
// check preconditions
|
||||||
|
preconditionsPassed, err := internal.CheckPreconditions(logger, policyContext.JSONContext(), rule.GetAnyAllConditions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.Validation, "failed to evaluate preconditions", err))
|
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.Validation, "failed to evaluate preconditions", err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
|
gojmespath "github.com/jmespath/go-jmespath"
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
"github.com/kyverno/kyverno/pkg/auth"
|
"github.com/kyverno/kyverno/pkg/auth"
|
||||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||||
|
@ -50,10 +51,29 @@ func (h validateManifestHandler) Process(
|
||||||
policyContext engineapi.PolicyContext,
|
policyContext engineapi.PolicyContext,
|
||||||
resource unstructured.Unstructured,
|
resource unstructured.Unstructured,
|
||||||
rule kyvernov1.Rule,
|
rule kyvernov1.Rule,
|
||||||
|
contextLoader engineapi.EngineContextLoader,
|
||||||
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
||||||
if engineutils.IsDeleteRequest(policyContext) {
|
if engineutils.IsDeleteRequest(policyContext) {
|
||||||
return resource, nil
|
return resource, nil
|
||||||
}
|
}
|
||||||
|
// load context
|
||||||
|
if err := contextLoader(ctx, rule.Context, policyContext.JSONContext()); err != nil {
|
||||||
|
if _, ok := err.(gojmespath.NotFoundError); ok {
|
||||||
|
logger.V(3).Info("failed to load context", "reason", err.Error())
|
||||||
|
} else {
|
||||||
|
logger.Error(err, "failed to load context")
|
||||||
|
}
|
||||||
|
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.Validation, "failed to load context", err))
|
||||||
|
}
|
||||||
|
// check preconditions
|
||||||
|
preconditionsPassed, err := internal.CheckPreconditions(logger, policyContext.JSONContext(), rule.GetAnyAllConditions())
|
||||||
|
if err != nil {
|
||||||
|
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.Validation, "failed to evaluate preconditions", err))
|
||||||
|
}
|
||||||
|
if !preconditionsPassed {
|
||||||
|
return resource, handlers.RuleResponses(internal.RuleSkip(rule, engineapi.Validation, "preconditions not met"))
|
||||||
|
}
|
||||||
|
// verify manifest
|
||||||
verified, reason, err := h.verifyManifest(ctx, logger, policyContext, *rule.Validation.Manifests)
|
verified, reason, err := h.verifyManifest(ctx, logger, policyContext, *rule.Validation.Manifests)
|
||||||
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())
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
|
gojmespath "github.com/jmespath/go-jmespath"
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/handlers"
|
"github.com/kyverno/kyverno/pkg/engine/handlers"
|
||||||
|
@ -30,9 +31,27 @@ func (h validatePssHandler) Process(
|
||||||
policyContext engineapi.PolicyContext,
|
policyContext engineapi.PolicyContext,
|
||||||
resource unstructured.Unstructured,
|
resource unstructured.Unstructured,
|
||||||
rule kyvernov1.Rule,
|
rule kyvernov1.Rule,
|
||||||
|
contextLoader engineapi.EngineContextLoader,
|
||||||
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
||||||
podSecurity := rule.Validation.PodSecurity
|
// load context
|
||||||
|
if err := contextLoader(ctx, rule.Context, policyContext.JSONContext()); err != nil {
|
||||||
|
if _, ok := err.(gojmespath.NotFoundError); ok {
|
||||||
|
logger.V(3).Info("failed to load context", "reason", err.Error())
|
||||||
|
} else {
|
||||||
|
logger.Error(err, "failed to load context")
|
||||||
|
}
|
||||||
|
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.Validation, "failed to load context", err))
|
||||||
|
}
|
||||||
|
// check preconditions
|
||||||
|
preconditionsPassed, err := internal.CheckPreconditions(logger, policyContext.JSONContext(), rule.GetAnyAllConditions())
|
||||||
|
if err != nil {
|
||||||
|
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.Validation, "failed to evaluate preconditions", err))
|
||||||
|
}
|
||||||
|
if !preconditionsPassed {
|
||||||
|
return resource, handlers.RuleResponses(internal.RuleSkip(rule, engineapi.Validation, "preconditions not met"))
|
||||||
|
}
|
||||||
// Marshal pod metadata and spec
|
// Marshal pod metadata and spec
|
||||||
|
podSecurity := rule.Validation.PodSecurity
|
||||||
podSpec, metadata, err := getSpec(resource)
|
podSpec, metadata, err := getSpec(resource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.Validation, "Error while getting new resource", err))
|
return resource, handlers.RuleResponses(internal.RuleError(rule, engineapi.Validation, "Error while getting new resource", err))
|
||||||
|
|
|
@ -21,16 +21,10 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
)
|
)
|
||||||
|
|
||||||
type validateResourceHandler struct {
|
type validateResourceHandler struct{}
|
||||||
contextLoader engineapi.EngineContextLoaderFactory
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewValidateResourceHandler(
|
func NewValidateResourceHandler() handlers.Handler {
|
||||||
contextLoader engineapi.EngineContextLoaderFactory,
|
return validateResourceHandler{}
|
||||||
) handlers.Handler {
|
|
||||||
return validateResourceHandler{
|
|
||||||
contextLoader: contextLoader,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h validateResourceHandler) Process(
|
func (h validateResourceHandler) Process(
|
||||||
|
@ -39,9 +33,8 @@ func (h validateResourceHandler) Process(
|
||||||
policyContext engineapi.PolicyContext,
|
policyContext engineapi.PolicyContext,
|
||||||
resource unstructured.Unstructured,
|
resource unstructured.Unstructured,
|
||||||
rule kyvernov1.Rule,
|
rule kyvernov1.Rule,
|
||||||
|
contextLoader engineapi.EngineContextLoader,
|
||||||
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
) (unstructured.Unstructured, []engineapi.RuleResponse) {
|
||||||
policy := policyContext.Policy()
|
|
||||||
contextLoader := h.contextLoader(policy, rule)
|
|
||||||
v := newValidator(logger, contextLoader, policyContext, rule)
|
v := newValidator(logger, contextLoader, policyContext, rule)
|
||||||
return resource, handlers.RuleResponses(v.validate(ctx))
|
return resource, handlers.RuleResponses(v.validate(ctx))
|
||||||
}
|
}
|
||||||
|
@ -87,12 +80,10 @@ func newForEachValidator(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to convert ruleCopy.Validation.ForEachValidation.AnyAllConditions: %w", err)
|
return nil, fmt.Errorf("failed to convert ruleCopy.Validation.ForEachValidation.AnyAllConditions: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
nestedForEach, err := api.DeserializeJSONArray[kyvernov1.ForEachValidation](foreach.ForEachValidation)
|
nestedForEach, err := api.DeserializeJSONArray[kyvernov1.ForEachValidation](foreach.ForEachValidation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to convert ruleCopy.Validation.ForEachValidation.AnyAllConditions: %w", err)
|
return nil, fmt.Errorf("failed to convert ruleCopy.Validation.ForEachValidation.AnyAllConditions: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &validator{
|
return &validator{
|
||||||
log: log,
|
log: log,
|
||||||
policyContext: ctx,
|
policyContext: ctx,
|
||||||
|
@ -112,12 +103,10 @@ func (v *validator) validate(ctx context.Context) *engineapi.RuleResponse {
|
||||||
if err := v.loadContext(ctx); err != nil {
|
if err := v.loadContext(ctx); err != nil {
|
||||||
return internal.RuleError(v.rule, engineapi.Validation, "failed to load context", err)
|
return internal.RuleError(v.rule, engineapi.Validation, "failed to load context", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
preconditionsPassed, err := internal.CheckPreconditions(v.log, v.policyContext.JSONContext(), v.anyAllConditions)
|
preconditionsPassed, err := internal.CheckPreconditions(v.log, v.policyContext.JSONContext(), v.anyAllConditions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return internal.RuleError(v.rule, engineapi.Validation, "failed to evaluate preconditions", err)
|
return internal.RuleError(v.rule, engineapi.Validation, "failed to evaluate preconditions", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !preconditionsPassed {
|
if !preconditionsPassed {
|
||||||
return internal.RuleSkip(v.rule, engineapi.Validation, "preconditions not met")
|
return internal.RuleSkip(v.rule, engineapi.Validation, "preconditions not met")
|
||||||
}
|
}
|
||||||
|
@ -222,10 +211,8 @@ func (v *validator) loadContext(ctx context.Context) error {
|
||||||
} else {
|
} else {
|
||||||
v.log.Error(err, "failed to load context")
|
v.log.Error(err, "failed to load context")
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||||
"github.com/kyverno/kyverno/pkg/autogen"
|
"github.com/kyverno/kyverno/pkg/autogen"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/handlers"
|
|
||||||
"github.com/kyverno/kyverno/pkg/engine/handlers/mutation"
|
"github.com/kyverno/kyverno/pkg/engine/handlers/mutation"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/internal"
|
"github.com/kyverno/kyverno/pkg/engine/internal"
|
||||||
)
|
)
|
||||||
|
@ -19,45 +18,42 @@ func (e *engine) verifyAndPatchImages(
|
||||||
policyContext engineapi.PolicyContext,
|
policyContext engineapi.PolicyContext,
|
||||||
) (engineapi.PolicyResponse, engineapi.ImageVerificationMetadata) {
|
) (engineapi.PolicyResponse, engineapi.ImageVerificationMetadata) {
|
||||||
resp := engineapi.NewPolicyResponse()
|
resp := engineapi.NewPolicyResponse()
|
||||||
|
policy := policyContext.Policy()
|
||||||
|
matchedResource := policyContext.NewResource()
|
||||||
|
applyRules := policy.GetSpec().GetApplyRules()
|
||||||
|
ivm := engineapi.ImageVerificationMetadata{}
|
||||||
|
|
||||||
policyContext.JSONContext().Checkpoint()
|
policyContext.JSONContext().Checkpoint()
|
||||||
defer policyContext.JSONContext().Restore()
|
defer policyContext.JSONContext().Restore()
|
||||||
|
|
||||||
ivm := engineapi.ImageVerificationMetadata{}
|
for _, rule := range autogen.ComputeRules(policy) {
|
||||||
policy := policyContext.Policy()
|
startTime := time.Now()
|
||||||
matchedResource := policyContext.NewResource()
|
logger := internal.LoggerWithRule(logger, rule)
|
||||||
applyRules := policy.GetSpec().GetApplyRules()
|
if !rule.HasVerifyImages() {
|
||||||
for _, rule := range autogen.ComputeRules(policyContext.Policy()) {
|
continue
|
||||||
if rule.HasVerifyImages() {
|
}
|
||||||
startTime := time.Now()
|
handler := mutation.NewMutateImageHandler(
|
||||||
handlerFactory := func() (handlers.Handler, error) {
|
e.configuration,
|
||||||
return mutation.NewMutateImageHandler(
|
e.rclient,
|
||||||
policyContext,
|
&ivm,
|
||||||
matchedResource,
|
)
|
||||||
rule,
|
resource, ruleResp := e.invokeRuleHandler(
|
||||||
e.configuration,
|
ctx,
|
||||||
e.rclient,
|
logger,
|
||||||
&ivm,
|
handler,
|
||||||
)
|
policyContext,
|
||||||
}
|
matchedResource,
|
||||||
resource, ruleResp := e.invokeRuleHandler(
|
rule,
|
||||||
ctx,
|
engineapi.ImageVerify,
|
||||||
logger,
|
)
|
||||||
handlerFactory,
|
matchedResource = resource
|
||||||
policyContext,
|
for _, ruleResp := range ruleResp {
|
||||||
matchedResource,
|
ruleResp := ruleResp
|
||||||
rule,
|
internal.AddRuleResponse(&resp, &ruleResp, startTime)
|
||||||
engineapi.ImageVerify,
|
logger.V(4).Info("finished processing rule", "processingTime", ruleResp.Stats.ProcessingTime.String())
|
||||||
)
|
}
|
||||||
matchedResource = resource
|
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
|
||||||
for _, ruleResp := range ruleResp {
|
break
|
||||||
ruleResp := ruleResp
|
|
||||||
internal.AddRuleResponse(&resp, &ruleResp, startTime)
|
|
||||||
logger.V(4).Info("finished processing rule", "processingTime", ruleResp.Stats.ProcessingTime.String())
|
|
||||||
}
|
|
||||||
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: i doesn't make sense to not return the patched resource here
|
// TODO: i doesn't make sense to not return the patched resource here
|
|
@ -22,26 +22,26 @@ func (e *engine) mutate(
|
||||||
resp := engineapi.NewPolicyResponse()
|
resp := engineapi.NewPolicyResponse()
|
||||||
policy := policyContext.Policy()
|
policy := policyContext.Policy()
|
||||||
matchedResource := policyContext.NewResource()
|
matchedResource := policyContext.NewResource()
|
||||||
|
applyRules := policy.GetSpec().GetApplyRules()
|
||||||
|
|
||||||
policyContext.JSONContext().Checkpoint()
|
policyContext.JSONContext().Checkpoint()
|
||||||
defer policyContext.JSONContext().Restore()
|
defer policyContext.JSONContext().Restore()
|
||||||
|
|
||||||
applyRules := policy.GetSpec().GetApplyRules()
|
|
||||||
|
|
||||||
for _, rule := range autogen.ComputeRules(policy) {
|
for _, rule := range autogen.ComputeRules(policy) {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
logger := internal.LoggerWithRule(logger, rule)
|
logger := internal.LoggerWithRule(logger, rule)
|
||||||
if !rule.HasMutate() {
|
if !rule.HasMutate() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
handlerFactory := handlers.WithHandler(e.mutateResourceHandler)
|
var handler handlers.Handler
|
||||||
|
handler = e.mutateResourceHandler
|
||||||
if !policyContext.AdmissionOperation() && rule.IsMutateExisting() {
|
if !policyContext.AdmissionOperation() && rule.IsMutateExisting() {
|
||||||
handlerFactory = handlers.WithHandler(e.mutateExistingHandler)
|
handler = e.mutateExistingHandler
|
||||||
}
|
}
|
||||||
resource, ruleResp := e.invokeRuleHandler(
|
resource, ruleResp := e.invokeRuleHandler(
|
||||||
ctx,
|
ctx,
|
||||||
logger,
|
logger,
|
||||||
handlerFactory,
|
handler,
|
||||||
policyContext,
|
policyContext,
|
||||||
matchedResource,
|
matchedResource,
|
||||||
rule,
|
rule,
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"github.com/kyverno/kyverno/pkg/autogen"
|
"github.com/kyverno/kyverno/pkg/autogen"
|
||||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/handlers"
|
"github.com/kyverno/kyverno/pkg/engine/handlers"
|
||||||
"github.com/kyverno/kyverno/pkg/engine/handlers/validation"
|
|
||||||
"github.com/kyverno/kyverno/pkg/engine/internal"
|
"github.com/kyverno/kyverno/pkg/engine/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,56 +18,49 @@ func (e *engine) validate(
|
||||||
policyContext engineapi.PolicyContext,
|
policyContext engineapi.PolicyContext,
|
||||||
) engineapi.PolicyResponse {
|
) engineapi.PolicyResponse {
|
||||||
resp := engineapi.NewPolicyResponse()
|
resp := engineapi.NewPolicyResponse()
|
||||||
|
policy := policyContext.Policy()
|
||||||
|
matchedResource := policyContext.NewResource()
|
||||||
|
applyRules := policy.GetSpec().GetApplyRules()
|
||||||
|
|
||||||
policyContext.JSONContext().Checkpoint()
|
policyContext.JSONContext().Checkpoint()
|
||||||
defer policyContext.JSONContext().Restore()
|
defer policyContext.JSONContext().Restore()
|
||||||
|
|
||||||
applyRules := policyContext.Policy().GetSpec().GetApplyRules()
|
for _, rule := range autogen.ComputeRules(policy) {
|
||||||
|
|
||||||
for _, rule := range autogen.ComputeRules(policyContext.Policy()) {
|
|
||||||
logger := internal.LoggerWithRule(logger, rule)
|
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
|
logger := internal.LoggerWithRule(logger, rule)
|
||||||
hasValidate := rule.HasValidate()
|
hasValidate := rule.HasValidate()
|
||||||
hasVerifyImageChecks := rule.HasVerifyImageChecks()
|
hasVerifyImageChecks := rule.HasVerifyImageChecks()
|
||||||
if !hasValidate && !hasVerifyImageChecks {
|
if !hasValidate && !hasVerifyImageChecks {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var handlerFactory handlers.HandlerFactory
|
var handler handlers.Handler
|
||||||
if hasValidate {
|
if hasValidate {
|
||||||
hasVerifyManifest := rule.HasVerifyManifests()
|
hasVerifyManifest := rule.HasVerifyManifests()
|
||||||
hasValidatePss := rule.HasValidatePodSecurity()
|
hasValidatePss := rule.HasValidatePodSecurity()
|
||||||
if hasVerifyManifest {
|
if hasVerifyManifest {
|
||||||
handlerFactory = handlers.WithHandler(e.validateManifestHandler)
|
handler = e.validateManifestHandler
|
||||||
} else if hasValidatePss {
|
} else if hasValidatePss {
|
||||||
handlerFactory = handlers.WithHandler(e.validatePssHandler)
|
handler = e.validatePssHandler
|
||||||
} else {
|
} else {
|
||||||
handlerFactory = handlers.WithHandler(e.validateResourceHandler)
|
handler = e.validateResourceHandler
|
||||||
}
|
}
|
||||||
} else if hasVerifyImageChecks {
|
} else if hasVerifyImageChecks {
|
||||||
handlerFactory = func() (handlers.Handler, error) {
|
handler = e.validateImageHandler
|
||||||
return validation.NewValidateImageHandler(
|
|
||||||
policyContext,
|
|
||||||
policyContext.NewResource(),
|
|
||||||
rule,
|
|
||||||
e.configuration,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if handlerFactory != nil {
|
resource, ruleResp := e.invokeRuleHandler(
|
||||||
_, ruleResp := e.invokeRuleHandler(
|
ctx,
|
||||||
ctx,
|
logger,
|
||||||
logger,
|
handler,
|
||||||
handlerFactory,
|
policyContext,
|
||||||
policyContext,
|
matchedResource,
|
||||||
policyContext.NewResource(),
|
rule,
|
||||||
rule,
|
engineapi.Validation,
|
||||||
engineapi.Validation,
|
)
|
||||||
)
|
matchedResource = resource
|
||||||
for _, ruleResp := range ruleResp {
|
for _, ruleResp := range ruleResp {
|
||||||
ruleResp := ruleResp
|
ruleResp := ruleResp
|
||||||
internal.AddRuleResponse(&resp, &ruleResp, startTime)
|
internal.AddRuleResponse(&resp, &ruleResp, startTime)
|
||||||
logger.V(4).Info("finished processing rule", "processingTime", ruleResp.Stats.ProcessingTime.String())
|
logger.V(4).Info("finished processing rule", "processingTime", ruleResp.Stats.ProcessingTime.String())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
|
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
|
||||||
break
|
break
|
||||||
|
|
Loading…
Add table
Reference in a new issue