mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-13 19:28:55 +00:00
refactor: introduce engine interface in engine api (#6181)
* refactor: introduce policy context interface in engine api 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> * more interface funcs Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * interface Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * rename Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * merge main Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * refactor: introduce engine interface in engine api 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> * refactor: introduce engine interface in engine api Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * makefile 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> Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com>
This commit is contained in:
parent
e8146e786e
commit
78016a5a51
32 changed files with 314 additions and 205 deletions
|
@ -64,6 +64,7 @@ func setupCosign(logger logr.Logger, imageSignatureRepository string) {
|
|||
}
|
||||
|
||||
func createNonLeaderControllers(
|
||||
eng engineapi.Engine,
|
||||
genWorkers int,
|
||||
kubeInformer kubeinformers.SharedInformerFactory,
|
||||
kubeKyvernoInformer kubeinformers.SharedInformerFactory,
|
||||
|
@ -78,6 +79,7 @@ func createNonLeaderControllers(
|
|||
updateRequestController := background.NewController(
|
||||
kyvernoClient,
|
||||
dynamicClient,
|
||||
eng,
|
||||
engine.LegacyContextLoaderFactory(rclient),
|
||||
kyvernoInformer.Kyverno().V1().ClusterPolicies(),
|
||||
kyvernoInformer.Kyverno().V1().Policies(),
|
||||
|
@ -224,8 +226,10 @@ func main() {
|
|||
kyvernoInformer.Kyverno().V1().ClusterPolicies(),
|
||||
kyvernoInformer.Kyverno().V1().Policies(),
|
||||
)
|
||||
engine := engine.NewEgine()
|
||||
// create non leader controllers
|
||||
nonLeaderControllers := createNonLeaderControllers(
|
||||
engine,
|
||||
genWorkers,
|
||||
kubeInformer,
|
||||
kubeKyvernoInformer,
|
||||
|
|
|
@ -474,7 +474,7 @@ OuterLoop:
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
eng := engine.NewEgine()
|
||||
policyContext := engine.NewPolicyContextWithJsonContext(ctx).
|
||||
WithPolicy(c.Policy).
|
||||
WithNewResource(*updatedResource).
|
||||
|
@ -483,7 +483,7 @@ OuterLoop:
|
|||
WithClient(c.Client).
|
||||
WithSubresourcesInPolicy(subresources)
|
||||
|
||||
mutateResponse := engine.Mutate(
|
||||
mutateResponse := eng.Mutate(
|
||||
context.Background(),
|
||||
engine.LegacyContextLoaderFactory(registryclient.NewOrDie()),
|
||||
policyContext,
|
||||
|
@ -511,7 +511,7 @@ OuterLoop:
|
|||
var info Info
|
||||
var validateResponse *engineapi.EngineResponse
|
||||
if policyHasValidate {
|
||||
validateResponse = engine.Validate(
|
||||
validateResponse = eng.Validate(
|
||||
context.Background(),
|
||||
engine.LegacyContextLoaderFactory(registryclient.NewOrDie()),
|
||||
policyContext,
|
||||
|
@ -524,7 +524,7 @@ OuterLoop:
|
|||
engineResponses = append(engineResponses, validateResponse)
|
||||
}
|
||||
|
||||
verifyImageResponse, _ := engine.VerifyAndPatchImages(
|
||||
verifyImageResponse, _ := eng.VerifyAndPatchImages(
|
||||
context.Background(),
|
||||
engine.LegacyContextLoaderFactory(registryclient.NewOrDie()),
|
||||
registryclient.NewOrDie(),
|
||||
|
|
|
@ -101,6 +101,7 @@ func sanityChecks(dynamicClient dclient.Interface) error {
|
|||
}
|
||||
|
||||
func createNonLeaderControllers(
|
||||
eng engineapi.Engine,
|
||||
genWorkers int,
|
||||
kubeInformer kubeinformers.SharedInformerFactory,
|
||||
kubeKyvernoInformer kubeinformers.SharedInformerFactory,
|
||||
|
@ -354,8 +355,10 @@ func main() {
|
|||
kubeKyvernoInformer.Apps().V1().Deployments(),
|
||||
certRenewer,
|
||||
)
|
||||
eng := engine.NewEgine()
|
||||
// create non leader controllers
|
||||
nonLeaderControllers, nonLeaderBootstrap := createNonLeaderControllers(
|
||||
eng,
|
||||
genWorkers,
|
||||
kubeInformer,
|
||||
kubeKyvernoInformer,
|
||||
|
@ -472,6 +475,7 @@ func main() {
|
|||
}
|
||||
}
|
||||
resourceHandlers := webhooksresource.NewHandlers(
|
||||
eng,
|
||||
engine.LegacyContextLoaderFactory(rclient),
|
||||
dClient,
|
||||
kyvernoClient,
|
||||
|
|
|
@ -67,6 +67,7 @@ func setupCosign(logger logr.Logger, imageSignatureRepository string) {
|
|||
}
|
||||
|
||||
func createReportControllers(
|
||||
eng engineapi.Engine,
|
||||
backgroundScan bool,
|
||||
admissionReports bool,
|
||||
reportsChunkSize int,
|
||||
|
@ -130,6 +131,7 @@ func createReportControllers(
|
|||
client,
|
||||
kyvernoClient,
|
||||
rclient,
|
||||
eng,
|
||||
engine.LegacyContextLoaderFactory(rclient),
|
||||
metadataFactory,
|
||||
kyvernoV1.Policies(),
|
||||
|
@ -157,6 +159,7 @@ func createReportControllers(
|
|||
}
|
||||
|
||||
func createrLeaderControllers(
|
||||
eng engineapi.Engine,
|
||||
backgroundScan bool,
|
||||
admissionReports bool,
|
||||
reportsChunkSize int,
|
||||
|
@ -173,6 +176,7 @@ func createrLeaderControllers(
|
|||
backgroundScanInterval time.Duration,
|
||||
) ([]internal.Controller, func(context.Context) error, error) {
|
||||
reportControllers, warmup := createReportControllers(
|
||||
eng,
|
||||
backgroundScan,
|
||||
admissionReports,
|
||||
reportsChunkSize,
|
||||
|
@ -298,6 +302,7 @@ func main() {
|
|||
}
|
||||
// start event generator
|
||||
go eventGenerator.Run(ctx, 3)
|
||||
eng := engine.NewEgine()
|
||||
// setup leader election
|
||||
le, err := leaderelection.New(
|
||||
logger.WithName("leader-election"),
|
||||
|
@ -315,6 +320,7 @@ func main() {
|
|||
metadataInformer := metadatainformers.NewSharedInformerFactory(metadataClient, 15*time.Minute)
|
||||
// create leader controllers
|
||||
leaderControllers, warmup, err := createrLeaderControllers(
|
||||
eng,
|
||||
backgroundScan,
|
||||
admissionReports,
|
||||
reportsChunkSize,
|
||||
|
|
|
@ -42,7 +42,7 @@ type GenerateController struct {
|
|||
client dclient.Interface
|
||||
kyvernoClient versioned.Interface
|
||||
statusControl common.StatusControlInterface
|
||||
contextLoader engine.ContextLoaderFactory
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
|
||||
// listers
|
||||
urLister kyvernov1beta1listers.UpdateRequestNamespaceLister
|
||||
|
@ -62,7 +62,7 @@ func NewGenerateController(
|
|||
client dclient.Interface,
|
||||
kyvernoClient versioned.Interface,
|
||||
statusControl common.StatusControlInterface,
|
||||
contextLoader engine.ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
policyLister kyvernov1listers.ClusterPolicyLister,
|
||||
npolicyLister kyvernov1listers.PolicyLister,
|
||||
urLister kyvernov1beta1listers.UpdateRequestNamespaceLister,
|
||||
|
@ -828,7 +828,7 @@ func (c *GenerateController) ApplyResource(resource *unstructured.Unstructured)
|
|||
}
|
||||
|
||||
// NewGenerateControllerWithOnlyClient returns an instance of Controller with only the client.
|
||||
func NewGenerateControllerWithOnlyClient(client dclient.Interface, contextLoader engine.ContextLoaderFactory) *GenerateController {
|
||||
func NewGenerateControllerWithOnlyClient(client dclient.Interface, contextLoader engineapi.ContextLoaderFactory) *GenerateController {
|
||||
c := GenerateController{
|
||||
client: client,
|
||||
contextLoader: contextLoader,
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
"github.com/kyverno/kyverno/pkg/utils"
|
||||
|
@ -31,7 +30,8 @@ type MutateExistingController struct {
|
|||
// clients
|
||||
client dclient.Interface
|
||||
statusControl common.StatusControlInterface
|
||||
contextLoader engine.ContextLoaderFactory
|
||||
engine engineapi.Engine
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
|
||||
// listers
|
||||
policyLister kyvernov1listers.ClusterPolicyLister
|
||||
|
@ -49,7 +49,8 @@ type MutateExistingController struct {
|
|||
func NewMutateExistingController(
|
||||
client dclient.Interface,
|
||||
statusControl common.StatusControlInterface,
|
||||
contextLoader engine.ContextLoaderFactory,
|
||||
engine engineapi.Engine,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
policyLister kyvernov1listers.ClusterPolicyLister,
|
||||
npolicyLister kyvernov1listers.PolicyLister,
|
||||
nsLister corev1listers.NamespaceLister,
|
||||
|
@ -61,6 +62,7 @@ func NewMutateExistingController(
|
|||
c := MutateExistingController{
|
||||
client: client,
|
||||
statusControl: statusControl,
|
||||
engine: engine,
|
||||
contextLoader: contextLoader,
|
||||
policyLister: policyLister,
|
||||
npolicyLister: npolicyLister,
|
||||
|
@ -103,7 +105,7 @@ func (c *MutateExistingController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) e
|
|||
continue
|
||||
}
|
||||
|
||||
er := engine.Mutate(context.TODO(), c.contextLoader, policyContext)
|
||||
er := c.engine.Mutate(context.TODO(), c.contextLoader, policyContext)
|
||||
for _, r := range er.PolicyResponse.Rules {
|
||||
patched := r.PatchedTarget
|
||||
patchedTargetSubresourceName := r.PatchedTargetSubresourceName
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
kyvernov1beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1"
|
||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/engine"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
|
@ -48,7 +47,8 @@ type controller struct {
|
|||
// clients
|
||||
client dclient.Interface
|
||||
kyvernoClient versioned.Interface
|
||||
contextLoader engine.ContextLoaderFactory
|
||||
engine engineapi.Engine
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
|
||||
// listers
|
||||
cpolLister kyvernov1listers.ClusterPolicyLister
|
||||
|
@ -71,7 +71,8 @@ type controller struct {
|
|||
func NewController(
|
||||
kyvernoClient versioned.Interface,
|
||||
client dclient.Interface,
|
||||
contextLoader engine.ContextLoaderFactory,
|
||||
engine engineapi.Engine,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
cpolInformer kyvernov1informers.ClusterPolicyInformer,
|
||||
polInformer kyvernov1informers.PolicyInformer,
|
||||
urInformer kyvernov1beta1informers.UpdateRequestInformer,
|
||||
|
@ -85,6 +86,7 @@ func NewController(
|
|||
c := controller{
|
||||
client: client,
|
||||
kyvernoClient: kyvernoClient,
|
||||
engine: engine,
|
||||
contextLoader: contextLoader,
|
||||
cpolLister: cpolInformer.Lister(),
|
||||
polLister: polInformer.Lister(),
|
||||
|
@ -419,7 +421,7 @@ func (c *controller) processUR(ur *kyvernov1beta1.UpdateRequest) error {
|
|||
statusControl := common.NewStatusControl(c.kyvernoClient, c.urLister)
|
||||
switch ur.Spec.Type {
|
||||
case kyvernov1beta1.Mutate:
|
||||
ctrl := mutate.NewMutateExistingController(c.client, statusControl, c.contextLoader, c.cpolLister, c.polLister, c.nsLister, c.configuration, c.informerCacheResolvers, c.eventGen, logger)
|
||||
ctrl := mutate.NewMutateExistingController(c.client, statusControl, c.engine, c.contextLoader, c.cpolLister, c.polLister, c.nsLister, c.configuration, c.informerCacheResolvers, c.eventGen, logger)
|
||||
return ctrl.ProcessUR(ur)
|
||||
case kyvernov1beta1.Generate:
|
||||
ctrl := generate.NewGenerateController(c.client, c.kyvernoClient, statusControl, c.contextLoader, c.cpolLister, c.polLister, c.urLister, c.nsLister, c.configuration, c.informerCacheResolvers, c.eventGen, logger)
|
||||
|
|
|
@ -49,7 +49,8 @@ type controller struct {
|
|||
client dclient.Interface
|
||||
kyvernoClient versioned.Interface
|
||||
rclient registryclient.Client
|
||||
contextLoader engine.ContextLoaderFactory
|
||||
engine engineapi.Engine
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
|
||||
// listers
|
||||
polLister kyvernov1listers.PolicyLister
|
||||
|
@ -76,7 +77,8 @@ func NewController(
|
|||
client dclient.Interface,
|
||||
kyvernoClient versioned.Interface,
|
||||
rclient registryclient.Client,
|
||||
contextLoader engine.ContextLoaderFactory,
|
||||
engine engineapi.Engine,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
metadataFactory metadatainformers.SharedInformerFactory,
|
||||
polInformer kyvernov1informers.PolicyInformer,
|
||||
cpolInformer kyvernov1informers.ClusterPolicyInformer,
|
||||
|
@ -95,6 +97,7 @@ func NewController(
|
|||
client: client,
|
||||
kyvernoClient: kyvernoClient,
|
||||
rclient: rclient,
|
||||
engine: engine,
|
||||
contextLoader: contextLoader,
|
||||
polLister: polInformer.Lister(),
|
||||
cpolLister: cpolInformer.Lister(),
|
||||
|
@ -312,7 +315,7 @@ func (c *controller) reconcileReport(
|
|||
// calculate necessary results
|
||||
for _, policy := range backgroundPolicies {
|
||||
if full || actual[reportutils.PolicyLabel(policy)] != policy.GetResourceVersion() {
|
||||
scanner := utils.NewScanner(logger, c.contextLoader, c.client, c.rclient, c.informerCacheResolvers, c.polexLister, c.config)
|
||||
scanner := utils.NewScanner(logger, c.engine, c.contextLoader, c.client, c.rclient, c.informerCacheResolvers, c.polexLister, c.config)
|
||||
for _, result := range scanner.ScanResource(ctx, *target, nsLabels, policy) {
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
|
|
|
@ -17,7 +17,8 @@ import (
|
|||
|
||||
type scanner struct {
|
||||
logger logr.Logger
|
||||
contextLoader engine.ContextLoaderFactory
|
||||
engine engineapi.Engine
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
client dclient.Interface
|
||||
rclient registryclient.Client
|
||||
informerCacheResolvers engineapi.ConfigmapResolver
|
||||
|
@ -37,7 +38,8 @@ type Scanner interface {
|
|||
|
||||
func NewScanner(
|
||||
logger logr.Logger,
|
||||
contextLoader engine.ContextLoaderFactory,
|
||||
engine engineapi.Engine,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
client dclient.Interface,
|
||||
rclient registryclient.Client,
|
||||
informerCacheResolvers engineapi.ConfigmapResolver,
|
||||
|
@ -47,6 +49,7 @@ func NewScanner(
|
|||
) Scanner {
|
||||
return &scanner{
|
||||
logger: logger,
|
||||
engine: engine,
|
||||
contextLoader: contextLoader,
|
||||
client: client,
|
||||
rclient: rclient,
|
||||
|
@ -106,7 +109,7 @@ func (s *scanner) validateResource(ctx context.Context, resource unstructured.Un
|
|||
WithExcludeGroupRole(s.excludeGroupRole...).
|
||||
WithInformerCacheResolver(s.informerCacheResolvers).
|
||||
WithExceptions(s.polexLister)
|
||||
return engine.Validate(ctx, s.contextLoader, policyCtx, s.config), nil
|
||||
return s.engine.Validate(ctx, s.contextLoader, policyCtx, s.config), nil
|
||||
}
|
||||
|
||||
func (s *scanner) validateImages(ctx context.Context, resource unstructured.Unstructured, nsLabels map[string]string, policy kyvernov1.PolicyInterface) (*engineapi.EngineResponse, error) {
|
||||
|
@ -131,7 +134,7 @@ func (s *scanner) validateImages(ctx context.Context, resource unstructured.Unst
|
|||
WithExcludeGroupRole(s.excludeGroupRole...).
|
||||
WithInformerCacheResolver(s.informerCacheResolvers).
|
||||
WithExceptions(s.polexLister)
|
||||
response, _ := engine.VerifyAndPatchImages(ctx, s.contextLoader, s.rclient, policyCtx, s.config)
|
||||
response, _ := s.engine.VerifyAndPatchImages(ctx, s.contextLoader, s.rclient, policyCtx, s.config)
|
||||
if len(response.PolicyResponse.Rules) > 0 {
|
||||
s.logger.Info("validateImages", "policy", policy, "response", response)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
||||
)
|
||||
|
||||
type ContextLoaderFactory = func(pContext PolicyContext, ruleName string) ContextLoader
|
||||
|
||||
type ContextLoader interface {
|
||||
Load(ctx context.Context, contextEntries []kyvernov1.ContextEntry, jsonContext enginecontext.Interface) error
|
||||
}
|
||||
|
|
34
pkg/engine/api/engine.go
Normal file
34
pkg/engine/api/engine.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
)
|
||||
|
||||
type Engine interface {
|
||||
// Validate applies validation rules from policy on the resource
|
||||
Validate(
|
||||
ctx context.Context,
|
||||
contextLoader ContextLoaderFactory,
|
||||
policyContext PolicyContext,
|
||||
cfg config.Configuration,
|
||||
) *EngineResponse
|
||||
|
||||
// Mutate performs mutation. Overlay first and then mutation patches
|
||||
Mutate(
|
||||
ctx context.Context,
|
||||
contextLoader ContextLoaderFactory,
|
||||
policyContext PolicyContext,
|
||||
) *EngineResponse
|
||||
|
||||
// VerifyAndPatchImages ...
|
||||
VerifyAndPatchImages(
|
||||
ctx context.Context,
|
||||
contextLoader ContextLoaderFactory,
|
||||
rclient registryclient.Client,
|
||||
policyContext PolicyContext,
|
||||
cfg config.Configuration,
|
||||
) (*EngineResponse, *ImageVerificationMetadata)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package engine
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
@ -8,39 +8,35 @@ import (
|
|||
"github.com/go-logr/logr"
|
||||
)
|
||||
|
||||
const imageVerifyAnnotationKey = "kyverno.io/verify-images"
|
||||
const ImageVerifyAnnotationKey = "kyverno.io/verify-images"
|
||||
|
||||
type ImageVerificationMetadata struct {
|
||||
Data map[string]bool `json:"data"`
|
||||
}
|
||||
|
||||
func (ivm *ImageVerificationMetadata) add(image string, verified bool) {
|
||||
func (ivm *ImageVerificationMetadata) Add(image string, verified bool) {
|
||||
if ivm.Data == nil {
|
||||
ivm.Data = make(map[string]bool)
|
||||
}
|
||||
|
||||
ivm.Data[image] = verified
|
||||
}
|
||||
|
||||
func (ivm *ImageVerificationMetadata) isVerified(image string) bool {
|
||||
func (ivm *ImageVerificationMetadata) IsVerified(image string) bool {
|
||||
if ivm.Data == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
verified, ok := ivm.Data[image]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
return verified
|
||||
}
|
||||
|
||||
func parseImageMetadata(jsonData string) (*ImageVerificationMetadata, error) {
|
||||
func ParseImageMetadata(jsonData string) (*ImageVerificationMetadata, error) {
|
||||
var data map[string]bool
|
||||
if err := json.Unmarshal([]byte(jsonData), &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ImageVerificationMetadata{
|
||||
Data: data,
|
||||
}, nil
|
||||
|
@ -84,7 +80,7 @@ func (ivm *ImageVerificationMetadata) Patches(hasAnnotations bool, log logr.Logg
|
|||
|
||||
func (ivm *ImageVerificationMetadata) Merge(other *ImageVerificationMetadata) {
|
||||
for k, v := range other.Data {
|
||||
ivm.add(k, v)
|
||||
ivm.Add(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,5 +89,5 @@ func (ivm *ImageVerificationMetadata) IsEmpty() bool {
|
|||
}
|
||||
|
||||
func makeAnnotationKeyForJSONPatch() string {
|
||||
return "/metadata/annotations/" + strings.ReplaceAll(imageVerifyAnnotationKey, "/", "~1")
|
||||
return "/metadata/annotations/" + strings.ReplaceAll(ImageVerifyAnnotationKey, "/", "~1")
|
||||
}
|
|
@ -18,7 +18,7 @@ import (
|
|||
//
|
||||
// 2. returns the list of rules that are applicable on this policy and resource, if 1 succeed
|
||||
func ApplyBackgroundChecks(
|
||||
contextLoader ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
policyContext engineapi.PolicyContext,
|
||||
) (resp *engineapi.EngineResponse) {
|
||||
policyStartTime := time.Now()
|
||||
|
@ -26,7 +26,7 @@ func ApplyBackgroundChecks(
|
|||
}
|
||||
|
||||
func filterRules(
|
||||
contextLoader ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
policyContext engineapi.PolicyContext,
|
||||
startTime time.Time,
|
||||
) *engineapi.EngineResponse {
|
||||
|
@ -75,7 +75,7 @@ func filterRules(
|
|||
}
|
||||
|
||||
func filterRule(
|
||||
contextLoader ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
rule kyvernov1.Rule,
|
||||
policyContext engineapi.PolicyContext,
|
||||
) *engineapi.RuleResponse {
|
||||
|
|
42
pkg/engine/engine.go
Normal file
42
pkg/engine/engine.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package engine
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/registryclient"
|
||||
)
|
||||
|
||||
type engine struct{}
|
||||
|
||||
func NewEgine() engineapi.Engine {
|
||||
return &engine{}
|
||||
}
|
||||
|
||||
func (e *engine) Validate(
|
||||
ctx context.Context,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
policyContext engineapi.PolicyContext,
|
||||
cfg config.Configuration,
|
||||
) *engineapi.EngineResponse {
|
||||
return doValidate(ctx, contextLoader, policyContext, cfg)
|
||||
}
|
||||
|
||||
func (e *engine) Mutate(
|
||||
ctx context.Context,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
policyContext engineapi.PolicyContext,
|
||||
) *engineapi.EngineResponse {
|
||||
return doMutate(ctx, contextLoader, policyContext)
|
||||
}
|
||||
|
||||
func (e *engine) VerifyAndPatchImages(
|
||||
ctx context.Context,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
rclient registryclient.Client,
|
||||
policyContext engineapi.PolicyContext,
|
||||
cfg config.Configuration,
|
||||
) (*engineapi.EngineResponse, *engineapi.ImageVerificationMetadata) {
|
||||
return doVerifyAndPatchImages(ctx, contextLoader, rclient, policyContext, cfg)
|
||||
}
|
|
@ -12,7 +12,7 @@ import (
|
|||
|
||||
// GenerateResponse checks for validity of generate rule on the resource
|
||||
func GenerateResponse(
|
||||
contextLoader ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
policyContext engineapi.PolicyContext,
|
||||
gr kyvernov1beta1.UpdateRequest,
|
||||
) (resp *engineapi.EngineResponse) {
|
||||
|
@ -21,7 +21,7 @@ func GenerateResponse(
|
|||
}
|
||||
|
||||
func filterGenerateRules(
|
||||
contextLoader ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
policyContext engineapi.PolicyContext,
|
||||
policyNameKey string,
|
||||
startTime time.Time,
|
||||
|
|
|
@ -29,50 +29,13 @@ import (
|
|||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
func getMatchingImages(images map[string]map[string]apiutils.ImageInfo, rule *kyvernov1.Rule) ([]apiutils.ImageInfo, string) {
|
||||
imageInfos := []apiutils.ImageInfo{}
|
||||
imageRefs := []string{}
|
||||
for _, infoMap := range images {
|
||||
for _, imageInfo := range infoMap {
|
||||
image := imageInfo.String()
|
||||
for _, verifyImage := range rule.VerifyImages {
|
||||
verifyImage = *verifyImage.Convert()
|
||||
imageRefs = append(imageRefs, verifyImage.ImageReferences...)
|
||||
if imageMatches(image, verifyImage.ImageReferences) {
|
||||
imageInfos = append(imageInfos, imageInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return imageInfos, strings.Join(imageRefs, ",")
|
||||
}
|
||||
|
||||
func extractMatchingImages(policyContext engineapi.PolicyContext, rule *kyvernov1.Rule, cfg config.Configuration) ([]apiutils.ImageInfo, string, error) {
|
||||
var (
|
||||
images map[string]map[string]apiutils.ImageInfo
|
||||
err error
|
||||
)
|
||||
newResource := policyContext.NewResource()
|
||||
images = policyContext.JSONContext().ImageInfo()
|
||||
if rule.ImageExtractors != nil {
|
||||
images, err = policyContext.JSONContext().GenerateCustomImageInfo(&newResource, rule.ImageExtractors, cfg)
|
||||
if err != nil {
|
||||
// if we get an error while generating custom images from image extractors,
|
||||
// don't check for matching images in imageExtractors
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
matchingImages, imageRefs := getMatchingImages(images, rule)
|
||||
return matchingImages, imageRefs, nil
|
||||
}
|
||||
|
||||
func VerifyAndPatchImages(
|
||||
func doVerifyAndPatchImages(
|
||||
ctx context.Context,
|
||||
contextLoader ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
rclient registryclient.Client,
|
||||
policyContext engineapi.PolicyContext,
|
||||
cfg config.Configuration,
|
||||
) (*engineapi.EngineResponse, *ImageVerificationMetadata) {
|
||||
) (*engineapi.EngineResponse, *engineapi.ImageVerificationMetadata) {
|
||||
resp := &engineapi.EngineResponse{}
|
||||
|
||||
policy := policyContext.Policy()
|
||||
|
@ -91,7 +54,7 @@ func VerifyAndPatchImages(
|
|||
policyContext.JSONContext().Checkpoint()
|
||||
defer policyContext.JSONContext().Restore()
|
||||
|
||||
ivm := &ImageVerificationMetadata{}
|
||||
ivm := &engineapi.ImageVerificationMetadata{}
|
||||
rules := autogen.ComputeRules(policyContext.Policy())
|
||||
applyRules := policy.GetSpec().GetApplyRules()
|
||||
|
||||
|
@ -173,6 +136,43 @@ func VerifyAndPatchImages(
|
|||
return resp, ivm
|
||||
}
|
||||
|
||||
func getMatchingImages(images map[string]map[string]apiutils.ImageInfo, rule *kyvernov1.Rule) ([]apiutils.ImageInfo, string) {
|
||||
imageInfos := []apiutils.ImageInfo{}
|
||||
imageRefs := []string{}
|
||||
for _, infoMap := range images {
|
||||
for _, imageInfo := range infoMap {
|
||||
image := imageInfo.String()
|
||||
for _, verifyImage := range rule.VerifyImages {
|
||||
verifyImage = *verifyImage.Convert()
|
||||
imageRefs = append(imageRefs, verifyImage.ImageReferences...)
|
||||
if imageMatches(image, verifyImage.ImageReferences) {
|
||||
imageInfos = append(imageInfos, imageInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return imageInfos, strings.Join(imageRefs, ",")
|
||||
}
|
||||
|
||||
func extractMatchingImages(policyContext engineapi.PolicyContext, rule *kyvernov1.Rule, cfg config.Configuration) ([]apiutils.ImageInfo, string, error) {
|
||||
var (
|
||||
images map[string]map[string]apiutils.ImageInfo
|
||||
err error
|
||||
)
|
||||
newResource := policyContext.NewResource()
|
||||
images = policyContext.JSONContext().ImageInfo()
|
||||
if rule.ImageExtractors != nil {
|
||||
images, err = policyContext.JSONContext().GenerateCustomImageInfo(&newResource, rule.ImageExtractors, cfg)
|
||||
if err != nil {
|
||||
// if we get an error while generating custom images from image extractors,
|
||||
// don't check for matching images in imageExtractors
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
matchingImages, imageRefs := getMatchingImages(images, rule)
|
||||
return matchingImages, imageRefs, nil
|
||||
}
|
||||
|
||||
func appendResponse(resp *engineapi.EngineResponse, rule *kyvernov1.Rule, msg string, status engineapi.RuleStatus) {
|
||||
rr := ruleResponse(*rule, engineapi.ImageVerify, msg, status)
|
||||
resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, *rr)
|
||||
|
@ -206,7 +206,7 @@ type imageVerifier struct {
|
|||
policyContext engineapi.PolicyContext
|
||||
rule *kyvernov1.Rule
|
||||
resp *engineapi.EngineResponse
|
||||
ivm *ImageVerificationMetadata
|
||||
ivm *engineapi.ImageVerificationMetadata
|
||||
}
|
||||
|
||||
// verify applies policy rules to each matching image. The policy rule results and annotation patches are
|
||||
|
@ -219,7 +219,7 @@ func (iv *imageVerifier) verify(ctx context.Context, imageVerify kyvernov1.Image
|
|||
image := imageInfo.String()
|
||||
|
||||
if hasImageVerifiedAnnotationChanged(iv.policyContext, iv.logger) {
|
||||
msg := imageVerifyAnnotationKey + " annotation cannot be changed"
|
||||
msg := engineapi.ImageVerifyAnnotationKey + " annotation cannot be changed"
|
||||
iv.logger.Info("image verification error", "reason", msg)
|
||||
ruleResp := ruleResponse(*iv.rule, engineapi.ImageVerify, msg, engineapi.RuleStatusFail)
|
||||
iv.resp.PolicyResponse.Rules = append(iv.resp.PolicyResponse.Rules, *ruleResp)
|
||||
|
@ -260,7 +260,7 @@ func (iv *imageVerifier) verify(ctx context.Context, imageVerify kyvernov1.Image
|
|||
if ruleResp != nil {
|
||||
if len(imageVerify.Attestors) > 0 || len(imageVerify.Attestations) > 0 {
|
||||
verified := ruleResp.Status == engineapi.RuleStatusPass
|
||||
iv.ivm.add(image, verified)
|
||||
iv.ivm.Add(image, verified)
|
||||
}
|
||||
|
||||
iv.resp.PolicyResponse.Rules = append(iv.resp.PolicyResponse.Rules, *ruleResp)
|
||||
|
@ -300,7 +300,7 @@ func hasImageVerifiedAnnotationChanged(ctx engineapi.PolicyContext, log logr.Log
|
|||
return false
|
||||
}
|
||||
|
||||
key := imageVerifyAnnotationKey
|
||||
key := engineapi.ImageVerifyAnnotationKey
|
||||
newValue := newResource.GetAnnotations()[key]
|
||||
oldValue := oldResource.GetAnnotations()[key]
|
||||
result := newValue != oldValue
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
func processImageValidationRule(
|
||||
ctx context.Context,
|
||||
contextLoader ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
log logr.Logger,
|
||||
enginectx engineapi.PolicyContext,
|
||||
rule *kyvernov1.Rule,
|
||||
|
@ -110,18 +110,18 @@ func isImageVerified(resource unstructured.Unstructured, image string, log logr.
|
|||
return false, nil
|
||||
}
|
||||
|
||||
key := imageVerifyAnnotationKey
|
||||
key := engineapi.ImageVerifyAnnotationKey
|
||||
data, ok := annotations[key]
|
||||
if !ok {
|
||||
log.V(2).Info("missing image metadata in annotation", "key", key)
|
||||
return false, fmt.Errorf("image is not verified")
|
||||
}
|
||||
|
||||
ivm, err := parseImageMetadata(data)
|
||||
ivm, err := engineapi.ParseImageMetadata(data)
|
||||
if err != nil {
|
||||
log.Error(err, "failed to parse image verification metadata", "data", data)
|
||||
return false, fmt.Errorf("failed to parse image metadata: %w", err)
|
||||
}
|
||||
|
||||
return ivm.isVerified(image), nil
|
||||
return ivm.IsVerified(image), nil
|
||||
}
|
||||
|
|
|
@ -160,13 +160,13 @@ var signaturePayloads = [][]byte{
|
|||
|
||||
var cfg = config.NewDefaultConfiguration()
|
||||
|
||||
func doVerifyAndPatchImages(
|
||||
func testVerifyAndPatchImages(
|
||||
ctx context.Context,
|
||||
rclient registryclient.Client,
|
||||
pContext engineapi.PolicyContext,
|
||||
cfg config.Configuration,
|
||||
) (*engineapi.EngineResponse, *ImageVerificationMetadata) {
|
||||
return VerifyAndPatchImages(
|
||||
) (*engineapi.EngineResponse, *engineapi.ImageVerificationMetadata) {
|
||||
return doVerifyAndPatchImages(
|
||||
ctx,
|
||||
LegacyContextLoaderFactory(rclient),
|
||||
rclient,
|
||||
|
@ -181,13 +181,13 @@ func Test_CosignMockAttest(t *testing.T) {
|
|||
err := cosign.SetMock("ghcr.io/jimbugwadia/pause2:latest", attestationPayloads)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er, ivm := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
er, ivm := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass,
|
||||
fmt.Sprintf("expected: %v, got: %v, failure: %v",
|
||||
engineapi.RuleStatusPass, er.PolicyResponse.Rules[0].Status, er.PolicyResponse.Rules[0].Message))
|
||||
assert.Equal(t, ivm.IsEmpty(), false)
|
||||
assert.Equal(t, ivm.isVerified("ghcr.io/jimbugwadia/pause2:latest"), true)
|
||||
assert.Equal(t, ivm.IsVerified("ghcr.io/jimbugwadia/pause2:latest"), true)
|
||||
}
|
||||
|
||||
func Test_CosignMockAttest_fail(t *testing.T) {
|
||||
|
@ -195,7 +195,7 @@ func Test_CosignMockAttest_fail(t *testing.T) {
|
|||
err := cosign.SetMock("ghcr.io/jimbugwadia/pause2:latest", attestationPayloads)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er, _ := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
er, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
|
||||
}
|
||||
|
@ -444,7 +444,7 @@ var (
|
|||
func Test_ConfigMapMissingSuccess(t *testing.T) {
|
||||
policyContext := buildContext(t, testConfigMapMissing, testConfigMapMissingResource, "")
|
||||
cosign.ClearMock()
|
||||
err, _ := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
err, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, err.PolicyResponse.Rules[0].Status, engineapi.RuleStatusSkip, err.PolicyResponse.Rules[0].Message)
|
||||
}
|
||||
|
@ -456,7 +456,7 @@ func Test_ConfigMapMissingFailure(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
policyContext.informerCacheResolvers = resolver
|
||||
cosign.ClearMock()
|
||||
resp, _ := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
resp, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(resp.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, resp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusError, resp.PolicyResponse.Rules[0].Message)
|
||||
}
|
||||
|
@ -465,7 +465,7 @@ func Test_SignatureGoodSigned(t *testing.T) {
|
|||
policyContext := buildContext(t, testSampleSingleKeyPolicy, testSampleResource, "")
|
||||
policyContext.policy.GetSpec().Rules[0].VerifyImages[0].MutateDigest = true
|
||||
cosign.ClearMock()
|
||||
engineResp, _ := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
engineResp, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(engineResp.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass, engineResp.PolicyResponse.Rules[0].Message)
|
||||
assert.Equal(t, len(engineResp.PolicyResponse.Rules[0].Patches), 1)
|
||||
|
@ -477,7 +477,7 @@ func Test_SignatureUnsigned(t *testing.T) {
|
|||
cosign.ClearMock()
|
||||
unsigned := strings.Replace(testSampleResource, ":signed", ":unsigned", -1)
|
||||
policyContext := buildContext(t, testSampleSingleKeyPolicy, unsigned, "")
|
||||
engineResp, _ := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
engineResp, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(engineResp.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail, engineResp.PolicyResponse.Rules[0].Message)
|
||||
}
|
||||
|
@ -486,7 +486,7 @@ func Test_SignatureWrongKey(t *testing.T) {
|
|||
cosign.ClearMock()
|
||||
otherKey := strings.Replace(testSampleResource, ":signed", ":signed-by-someone-else", -1)
|
||||
policyContext := buildContext(t, testSampleSingleKeyPolicy, otherKey, "")
|
||||
engineResp, _ := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
engineResp, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(engineResp.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail, engineResp.PolicyResponse.Rules[0].Message)
|
||||
}
|
||||
|
@ -497,7 +497,7 @@ func Test_SignaturesMultiKey(t *testing.T) {
|
|||
policy = strings.Replace(policy, "KEY2", testVerifyImageKey, -1)
|
||||
policy = strings.Replace(policy, "COUNT", "0", -1)
|
||||
policyContext := buildContext(t, policy, testSampleResource, "")
|
||||
engineResp, _ := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
engineResp, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(engineResp.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass, engineResp.PolicyResponse.Rules[0].Message)
|
||||
}
|
||||
|
@ -507,7 +507,7 @@ func Test_SignaturesMultiKeyFail(t *testing.T) {
|
|||
policy := strings.Replace(testSampleMultipleKeyPolicy, "KEY1", testVerifyImageKey, -1)
|
||||
policy = strings.Replace(policy, "COUNT", "0", -1)
|
||||
policyContext := buildContext(t, policy, testSampleResource, "")
|
||||
engineResp, _ := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
engineResp, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(engineResp.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail, engineResp.PolicyResponse.Rules[0].Message)
|
||||
}
|
||||
|
@ -518,7 +518,7 @@ func Test_SignaturesMultiKeyOneGoodKey(t *testing.T) {
|
|||
policy = strings.Replace(policy, "KEY2", testOtherKey, -1)
|
||||
policy = strings.Replace(policy, "COUNT", "1", -1)
|
||||
policyContext := buildContext(t, policy, testSampleResource, "")
|
||||
engineResp, _ := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
engineResp, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(engineResp.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass, engineResp.PolicyResponse.Rules[0].Message)
|
||||
}
|
||||
|
@ -529,7 +529,7 @@ func Test_SignaturesMultiKeyZeroGoodKey(t *testing.T) {
|
|||
policy = strings.Replace(policy, "KEY2", testOtherKey, -1)
|
||||
policy = strings.Replace(policy, "COUNT", "1", -1)
|
||||
policyContext := buildContext(t, policy, testSampleResource, "")
|
||||
resp, _ := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
resp, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(resp.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, resp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail, resp.PolicyResponse.Rules[0].Message)
|
||||
}
|
||||
|
@ -545,14 +545,14 @@ func Test_RuleSelectorImageVerify(t *testing.T) {
|
|||
applyAll := kyverno.ApplyAll
|
||||
spec.ApplyRules = &applyAll
|
||||
|
||||
resp, _ := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
resp, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(resp.PolicyResponse.Rules), 2)
|
||||
assert.Equal(t, resp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass, resp.PolicyResponse.Rules[0].Message)
|
||||
assert.Equal(t, resp.PolicyResponse.Rules[1].Status, engineapi.RuleStatusFail, resp.PolicyResponse.Rules[1].Message)
|
||||
|
||||
applyOne := kyverno.ApplyOne
|
||||
spec.ApplyRules = &applyOne
|
||||
resp, _ = doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
resp, _ = testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(resp.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, resp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass, resp.PolicyResponse.Rules[0].Message)
|
||||
}
|
||||
|
@ -656,7 +656,7 @@ func Test_NestedAttestors(t *testing.T) {
|
|||
policy = strings.Replace(policy, "KEY2", testVerifyImageKey, -1)
|
||||
policy = strings.Replace(policy, "COUNT", "0", -1)
|
||||
policyContext := buildContext(t, policy, testSampleResource, "")
|
||||
err, _ := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
err, _ := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, err.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
|
||||
|
||||
|
@ -664,7 +664,7 @@ func Test_NestedAttestors(t *testing.T) {
|
|||
policy = strings.Replace(policy, "KEY2", testOtherKey, -1)
|
||||
policy = strings.Replace(policy, "COUNT", "0", -1)
|
||||
policyContext = buildContext(t, policy, testSampleResource, "")
|
||||
err, _ = doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
err, _ = testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, err.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
|
||||
|
||||
|
@ -672,7 +672,7 @@ func Test_NestedAttestors(t *testing.T) {
|
|||
policy = strings.Replace(policy, "KEY2", testOtherKey, -1)
|
||||
policy = strings.Replace(policy, "COUNT", "1", -1)
|
||||
policyContext = buildContext(t, policy, testSampleResource, "")
|
||||
err, _ = doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
err, _ = testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, err.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
|
||||
}
|
||||
|
@ -737,7 +737,7 @@ func createStaticKeyAttestorSet(s string, withPublicKey, withSecret, withKMS boo
|
|||
}
|
||||
|
||||
func Test_ChangedAnnotation(t *testing.T) {
|
||||
annotationKey := imageVerifyAnnotationKey
|
||||
annotationKey := engineapi.ImageVerifyAnnotationKey
|
||||
annotationNew := fmt.Sprintf("\"annotations\": {\"%s\": \"%s\"}", annotationKey, "true")
|
||||
newResource := strings.ReplaceAll(testResource, "\"annotations\": {}", annotationNew)
|
||||
|
||||
|
@ -765,7 +765,7 @@ func Test_MarkImageVerified(t *testing.T) {
|
|||
err := cosign.SetMock(image, attestationPayloads)
|
||||
assert.NilError(t, err)
|
||||
|
||||
engineResponse, verifiedImages := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
engineResponse, verifiedImages := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Assert(t, engineResponse != nil)
|
||||
assert.Equal(t, len(engineResponse.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, engineResponse.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
|
||||
|
@ -773,7 +773,7 @@ func Test_MarkImageVerified(t *testing.T) {
|
|||
assert.Assert(t, verifiedImages != nil)
|
||||
assert.Assert(t, verifiedImages.Data != nil)
|
||||
assert.Equal(t, len(verifiedImages.Data), 1)
|
||||
assert.Equal(t, verifiedImages.isVerified(image), true)
|
||||
assert.Equal(t, verifiedImages.IsVerified(image), true)
|
||||
|
||||
patches, err := verifiedImages.Patches(false, logging.GlobalLogger())
|
||||
assert.NilError(t, err)
|
||||
|
@ -783,7 +783,7 @@ func Test_MarkImageVerified(t *testing.T) {
|
|||
patchedAnnotations := resource.GetAnnotations()
|
||||
assert.Equal(t, len(patchedAnnotations), 1)
|
||||
|
||||
json := patchedAnnotations[imageVerifyAnnotationKey]
|
||||
json := patchedAnnotations[engineapi.ImageVerifyAnnotationKey]
|
||||
assert.Assert(t, json != "")
|
||||
|
||||
verified, err := isImageVerified(resource, image, logging.GlobalLogger())
|
||||
|
@ -858,7 +858,7 @@ func Test_ParsePEMDelimited(t *testing.T) {
|
|||
err := cosign.SetMock(image, signaturePayloads)
|
||||
assert.NilError(t, err)
|
||||
|
||||
engineResponse, verifiedImages := doVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
engineResponse, verifiedImages := testVerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Assert(t, engineResponse != nil)
|
||||
assert.Equal(t, len(engineResponse.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, engineResponse.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
|
||||
|
@ -866,5 +866,5 @@ func Test_ParsePEMDelimited(t *testing.T) {
|
|||
assert.Assert(t, verifiedImages != nil)
|
||||
assert.Assert(t, verifiedImages.Data != nil)
|
||||
assert.Equal(t, len(verifiedImages.Data), 1)
|
||||
assert.Equal(t, verifiedImages.isVerified(image), true)
|
||||
assert.Equal(t, verifiedImages.IsVerified(image), true)
|
||||
}
|
||||
|
|
|
@ -19,9 +19,7 @@ import (
|
|||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
type ContextLoaderFactory = func(pContext engineapi.PolicyContext, ruleName string) engineapi.ContextLoader
|
||||
|
||||
func LegacyContextLoaderFactory(rclient registryclient.Client) ContextLoaderFactory {
|
||||
func LegacyContextLoaderFactory(rclient registryclient.Client) engineapi.ContextLoaderFactory {
|
||||
if store.IsMock() {
|
||||
return func(pContext engineapi.PolicyContext, ruleName string) engineapi.ContextLoader {
|
||||
policy := pContext.Policy()
|
||||
|
@ -122,7 +120,7 @@ func (l *mockContextLoader) Load(ctx context.Context, contextEntries []kyvernov1
|
|||
return nil
|
||||
}
|
||||
|
||||
func LoadContext(ctx context.Context, factory ContextLoaderFactory, contextEntries []kyvernov1.ContextEntry, pContext engineapi.PolicyContext, ruleName string) error {
|
||||
func LoadContext(ctx context.Context, factory engineapi.ContextLoaderFactory, contextEntries []kyvernov1.ContextEntry, pContext engineapi.PolicyContext, ruleName string) error {
|
||||
return factory(pContext, ruleName).Load(ctx, contextEntries, pContext.JSONContext())
|
||||
}
|
||||
|
||||
|
|
|
@ -21,9 +21,9 @@ import (
|
|||
)
|
||||
|
||||
// Mutate performs mutation. Overlay first and then mutation patches
|
||||
func Mutate(
|
||||
func doMutate(
|
||||
ctx context.Context,
|
||||
contextLoader ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
policyContext engineapi.PolicyContext,
|
||||
) (resp *engineapi.EngineResponse) {
|
||||
startTime := time.Now()
|
||||
|
@ -205,7 +205,7 @@ type forEachMutator struct {
|
|||
foreach []kyvernov1.ForEachMutation
|
||||
resource resourceInfo
|
||||
nesting int
|
||||
contextLoader ContextLoaderFactory
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
log logr.Logger
|
||||
}
|
||||
|
||||
|
|
|
@ -20,12 +20,12 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func doMutate(
|
||||
func testMutate(
|
||||
ctx context.Context,
|
||||
rclient registryclient.Client,
|
||||
pContext *PolicyContext,
|
||||
) *engineapi.EngineResponse {
|
||||
return Mutate(
|
||||
return doMutate(
|
||||
ctx,
|
||||
LegacyContextLoaderFactory(rclient),
|
||||
pContext,
|
||||
|
@ -107,7 +107,7 @@ func Test_VariableSubstitutionPatchStrategicMerge(t *testing.T) {
|
|||
jsonContext: ctx,
|
||||
newResource: *resourceUnstructured,
|
||||
}
|
||||
er := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
t.Log(string(expectedPatch))
|
||||
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
|
@ -181,7 +181,7 @@ func Test_variableSubstitutionPathNotExist(t *testing.T) {
|
|||
jsonContext: ctx,
|
||||
newResource: *resourceUnstructured,
|
||||
}
|
||||
er := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Assert(t, strings.Contains(er.PolicyResponse.Rules[0].Message, "Unknown key \"name1\" in path"))
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ func Test_variableSubstitutionCLI(t *testing.T) {
|
|||
newResource: *resourceUnstructured,
|
||||
}
|
||||
|
||||
er := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules[0].Patches), 1)
|
||||
t.Log(string(expectedPatch))
|
||||
|
@ -383,7 +383,7 @@ func Test_chained_rules(t *testing.T) {
|
|||
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, containers[0].(map[string]interface{})["image"], "otherregistry.corp.com/foo/bash:5.0")
|
||||
|
@ -471,7 +471,7 @@ func Test_precondition(t *testing.T) {
|
|||
newResource: *resourceUnstructured,
|
||||
}
|
||||
|
||||
er := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
t.Log(string(expectedPatch))
|
||||
t.Log(string(er.PolicyResponse.Rules[0].Patches[0]))
|
||||
if !reflect.DeepEqual(expectedPatch, er.PolicyResponse.Rules[0].Patches[0]) {
|
||||
|
@ -568,7 +568,7 @@ func Test_nonZeroIndexNumberPatchesJson6902(t *testing.T) {
|
|||
newResource: *resourceUnstructured,
|
||||
}
|
||||
|
||||
er := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
t.Log(string(expectedPatch))
|
||||
t.Log(string(er.PolicyResponse.Rules[0].Patches[0]))
|
||||
if !reflect.DeepEqual(expectedPatch, er.PolicyResponse.Rules[0].Patches[0]) {
|
||||
|
@ -662,7 +662,7 @@ func Test_foreach(t *testing.T) {
|
|||
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
|
||||
|
@ -769,7 +769,7 @@ func Test_foreach_element_mutation(t *testing.T) {
|
|||
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
|
||||
|
@ -895,7 +895,7 @@ func Test_Container_InitContainer_foreach(t *testing.T) {
|
|||
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
|
||||
|
@ -1045,7 +1045,7 @@ func testApplyPolicyToResource(t *testing.T, policyRaw, resourceRaw []byte) *eng
|
|||
err = enginecontext.MutateResourceWithImageInfo(resourceRaw, ctx)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
return er
|
||||
}
|
||||
|
||||
|
@ -1596,7 +1596,7 @@ func Test_mutate_existing_resources(t *testing.T) {
|
|||
newResource: *trigger,
|
||||
}
|
||||
}
|
||||
er := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
|
||||
for _, rr := range er.PolicyResponse.Rules {
|
||||
for i, p := range rr.Patches {
|
||||
|
@ -1704,7 +1704,7 @@ func Test_RuleSelectorMutate(t *testing.T) {
|
|||
newResource: *resourceUnstructured,
|
||||
}
|
||||
|
||||
er := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 2)
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules[0].Patches), 1)
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules[1].Patches), 1)
|
||||
|
@ -1719,7 +1719,7 @@ func Test_RuleSelectorMutate(t *testing.T) {
|
|||
applyOne := kyverno.ApplyOne
|
||||
policyContext.policy.GetSpec().ApplyRules = &applyOne
|
||||
|
||||
er = doMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
er = testMutate(context.TODO(), registryclient.NewOrDie(), policyContext)
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules[0].Patches), 1)
|
||||
|
||||
|
@ -2086,7 +2086,7 @@ func Test_SpecialCharacters(t *testing.T) {
|
|||
}
|
||||
|
||||
// Mutate and make sure that we got the expected amount of rules.
|
||||
patches := doMutate(context.TODO(), registryclient.NewOrDie(), policyContext).GetPatches()
|
||||
patches := testMutate(context.TODO(), registryclient.NewOrDie(), policyContext).GetPatches()
|
||||
if !reflect.DeepEqual(patches, tt.want) {
|
||||
t.Errorf("Mutate() got patches %s, expected %s", patches, tt.want)
|
||||
}
|
||||
|
|
|
@ -34,10 +34,9 @@ import (
|
|||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// Validate applies validation rules from policy on the resource
|
||||
func Validate(
|
||||
func doValidate(
|
||||
ctx context.Context,
|
||||
contextLoader ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
policyContext engineapi.PolicyContext,
|
||||
cfg config.Configuration,
|
||||
) (resp *engineapi.EngineResponse) {
|
||||
|
@ -104,7 +103,7 @@ func buildResponse(ctx engineapi.PolicyContext, resp *engineapi.EngineResponse,
|
|||
|
||||
func validateResource(
|
||||
ctx context.Context,
|
||||
contextLoader ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
log logr.Logger,
|
||||
enginectx engineapi.PolicyContext,
|
||||
cfg config.Configuration,
|
||||
|
@ -183,7 +182,7 @@ func validateResource(
|
|||
|
||||
func processValidationRule(
|
||||
ctx context.Context,
|
||||
contextLoader ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
log logr.Logger,
|
||||
policyContext engineapi.PolicyContext,
|
||||
rule *kyvernov1.Rule,
|
||||
|
@ -217,11 +216,11 @@ type validator struct {
|
|||
deny *kyvernov1.Deny
|
||||
podSecurity *kyvernov1.PodSecurity
|
||||
forEach []kyvernov1.ForEachValidation
|
||||
contextLoader ContextLoaderFactory
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
nesting int
|
||||
}
|
||||
|
||||
func newValidator(log logr.Logger, contextLoader ContextLoaderFactory, ctx engineapi.PolicyContext, rule *kyvernov1.Rule) *validator {
|
||||
func newValidator(log logr.Logger, contextLoader engineapi.ContextLoaderFactory, ctx engineapi.PolicyContext, rule *kyvernov1.Rule) *validator {
|
||||
ruleCopy := rule.DeepCopy()
|
||||
return &validator{
|
||||
log: log,
|
||||
|
@ -240,7 +239,7 @@ func newValidator(log logr.Logger, contextLoader ContextLoaderFactory, ctx engin
|
|||
|
||||
func newForEachValidator(
|
||||
foreach kyvernov1.ForEachValidation,
|
||||
contextLoader ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
nesting int,
|
||||
rule *kyvernov1.Rule,
|
||||
ctx engineapi.PolicyContext,
|
||||
|
|
|
@ -19,8 +19,8 @@ import (
|
|||
admissionv1 "k8s.io/api/admission/v1"
|
||||
)
|
||||
|
||||
func doValidate(ctx context.Context, rclient registryclient.Client, pContext *PolicyContext, cfg config.Configuration) *engineapi.EngineResponse {
|
||||
return Validate(
|
||||
func testValidate(ctx context.Context, rclient registryclient.Client, pContext *PolicyContext, cfg config.Configuration) *engineapi.EngineResponse {
|
||||
return doValidate(
|
||||
ctx,
|
||||
LegacyContextLoaderFactory(rclient),
|
||||
pContext,
|
||||
|
@ -121,7 +121,7 @@ func TestValidate_image_tag_fail(t *testing.T) {
|
|||
"validation error: imagePullPolicy 'Always' required with tag 'latest'. rule validate-latest failed at path /spec/containers/0/imagePullPolicy/",
|
||||
}
|
||||
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ func TestValidate_image_tag_pass(t *testing.T) {
|
|||
"validation rule 'validate-tag' passed.",
|
||||
"validation rule 'validate-latest' passed.",
|
||||
}
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ func TestValidate_Fail_anyPattern(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
assert.Assert(t, !er.IsSuccessful())
|
||||
|
||||
msgs := []string{"validation error: A namespace is required. rule check-default-namespace[0] failed at path /metadata/namespace/ rule check-default-namespace[1] failed at path /metadata/namespace/"}
|
||||
|
@ -378,7 +378,7 @@ func TestValidate_host_network_port(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
msgs := []string{"validation error: Host network and port are not allowed. rule validate-host-network-port failed at path /spec/containers/0/ports/0/hostPort/"}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -468,7 +468,7 @@ func TestValidate_anchor_arraymap_pass(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
msgs := []string{"validation rule 'validate-host-path' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -556,7 +556,7 @@ func TestValidate_anchor_arraymap_fail(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
msgs := []string{"validation error: Host path '/var/lib/' is not allowed. rule validate-host-path failed at path /spec/volumes/0/hostPath/path/"}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -626,7 +626,7 @@ func TestValidate_anchor_map_notfound(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
msgs := []string{"validation rule 'pod rule 2' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -699,7 +699,7 @@ func TestValidate_anchor_map_found_valid(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
msgs := []string{"validation rule 'pod rule 2' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -773,7 +773,7 @@ func TestValidate_inequality_List_Processing(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
msgs := []string{"validation rule 'pod rule 2' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -853,7 +853,7 @@ func TestValidate_inequality_List_ProcessingBrackets(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
msgs := []string{"validation rule 'pod rule 2' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -927,7 +927,7 @@ func TestValidate_anchor_map_found_invalid(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
msgs := []string{"validation error: pod: validate run as non root user. rule pod rule 2 failed at path /spec/securityContext/runAsNonRoot/"}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -1002,7 +1002,7 @@ func TestValidate_AnchorList_pass(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
msgs := []string{"validation rule 'pod image rule' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -1077,7 +1077,7 @@ func TestValidate_AnchorList_fail(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
assert.Assert(t, !er.IsSuccessful())
|
||||
}
|
||||
|
||||
|
@ -1147,7 +1147,7 @@ func TestValidate_existenceAnchor_fail(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
assert.Assert(t, !er.IsSuccessful())
|
||||
}
|
||||
|
||||
|
@ -1217,7 +1217,7 @@ func TestValidate_existenceAnchor_pass(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
msgs := []string{"validation rule 'pod image rule' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -1305,7 +1305,7 @@ func TestValidate_negationAnchor_deny(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
msgs := []string{"validation error: Host path is not allowed. rule validate-host-path failed at path /spec/volumes/0/hostPath/"}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -1392,7 +1392,7 @@ func TestValidate_negationAnchor_pass(t *testing.T) {
|
|||
|
||||
resourceUnstructured, err := kubeutils.BytesToUnstructured(rawResource)
|
||||
assert.NilError(t, err)
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
msgs := []string{"validation rule 'validate-host-path' passed."}
|
||||
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
|
@ -1469,7 +1469,7 @@ func Test_VariableSubstitutionPathNotExistInPattern(t *testing.T) {
|
|||
jsonContext: ctx,
|
||||
newResource: *resourceUnstructured,
|
||||
}
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusError)
|
||||
|
@ -1563,7 +1563,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_OnePatternStatisfiesButSu
|
|||
jsonContext: ctx,
|
||||
newResource: *resourceUnstructured,
|
||||
}
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusError)
|
||||
|
@ -1625,7 +1625,7 @@ func Test_VariableSubstitution_NotOperatorWithStringVariable(t *testing.T) {
|
|||
jsonContext: ctx,
|
||||
newResource: *resourceUnstructured,
|
||||
}
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Message, "validation error: rule not-operator-with-variable-should-alway-fail-validation failed at path /spec/content/")
|
||||
}
|
||||
|
@ -1717,7 +1717,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathNotPresent(t *test
|
|||
jsonContext: ctx,
|
||||
newResource: *resourceUnstructured,
|
||||
}
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
|
||||
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusError)
|
||||
|
@ -1811,7 +1811,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathPresent_NonePatter
|
|||
jsonContext: ctx,
|
||||
newResource: *resourceUnstructured,
|
||||
}
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Message,
|
||||
|
@ -1917,7 +1917,7 @@ func Test_VariableSubstitutionValidate_VariablesInMessageAreResolved(t *testing.
|
|||
jsonContext: ctx,
|
||||
newResource: *resourceUnstructured,
|
||||
}
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Message, "The animal cow is not in the allowed list of animals.")
|
||||
}
|
||||
|
@ -1971,7 +1971,7 @@ func Test_Flux_Kustomization_PathNotPresent(t *testing.T) {
|
|||
jsonContext: ctx,
|
||||
newResource: *resourceUnstructured,
|
||||
}
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
|
||||
for i, rule := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, er.PolicyResponse.Rules[i].Status, test.expectedResults[i], "\ntest %s failed\nexpected: %s\nactual: %s", test.name, test.expectedResults[i], er.PolicyResponse.Rules[i].Status)
|
||||
|
@ -2137,7 +2137,7 @@ func executeTest(t *testing.T, test testCase) {
|
|||
jsonContext: ctx,
|
||||
}
|
||||
|
||||
resp := doValidate(context.TODO(), registryclient.NewOrDie(), pc, cfg)
|
||||
resp := testValidate(context.TODO(), registryclient.NewOrDie(), pc, cfg)
|
||||
if resp.IsSuccessful() && test.requestDenied {
|
||||
t.Errorf("Testcase has failed, policy: %v", policy.Name)
|
||||
}
|
||||
|
@ -2232,7 +2232,7 @@ func TestValidate_context_variable_substitution_CLI(t *testing.T) {
|
|||
msgs := []string{
|
||||
"restrict pod counts to be no more than 10 on node minikube",
|
||||
}
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
for index, r := range er.PolicyResponse.Rules {
|
||||
assert.Equal(t, r.Message, msgs[index])
|
||||
}
|
||||
|
@ -2321,7 +2321,7 @@ func Test_EmptyStringInDenyCondition(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: ctx}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: ctx}, cfg)
|
||||
assert.Assert(t, !er.IsSuccessful())
|
||||
}
|
||||
|
||||
|
@ -2410,7 +2410,7 @@ func Test_StringInDenyCondition(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: ctx}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: ctx}, cfg)
|
||||
assert.Assert(t, er.IsSuccessful())
|
||||
}
|
||||
|
||||
|
@ -3081,7 +3081,7 @@ func testForEach(t *testing.T, policyraw []byte, resourceRaw []byte, msg string,
|
|||
jsonContext: ctx,
|
||||
newResource: *resourceUnstructured,
|
||||
}
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
|
||||
|
||||
assert.Equal(t, er.PolicyResponse.Rules[0].Status, status)
|
||||
if msg != "" {
|
||||
|
@ -3145,7 +3145,7 @@ func Test_delete_ignore_pattern(t *testing.T) {
|
|||
jsonContext: ctx,
|
||||
newResource: *resourceUnstructured,
|
||||
}
|
||||
engineResponseCreate := doValidate(context.TODO(), registryclient.NewOrDie(), policyContextCreate, cfg)
|
||||
engineResponseCreate := testValidate(context.TODO(), registryclient.NewOrDie(), policyContextCreate, cfg)
|
||||
assert.Equal(t, len(engineResponseCreate.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, engineResponseCreate.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
|
||||
|
||||
|
@ -3154,7 +3154,7 @@ func Test_delete_ignore_pattern(t *testing.T) {
|
|||
jsonContext: ctx,
|
||||
oldResource: *resourceUnstructured,
|
||||
}
|
||||
engineResponseDelete := doValidate(context.TODO(), registryclient.NewOrDie(), policyContextDelete, cfg)
|
||||
engineResponseDelete := testValidate(context.TODO(), registryclient.NewOrDie(), policyContextDelete, cfg)
|
||||
assert.Equal(t, len(engineResponseDelete.PolicyResponse.Rules), 0)
|
||||
}
|
||||
|
||||
|
@ -3213,7 +3213,7 @@ func Test_ValidatePattern_anyPattern(t *testing.T) {
|
|||
resourceUnstructured, err := kubeutils.BytesToUnstructured(tc.rawResource)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er := doValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
er := testValidate(context.TODO(), registryclient.NewOrDie(), &PolicyContext{policy: &policy, newResource: *resourceUnstructured, jsonContext: enginecontext.NewContext()}, cfg)
|
||||
if tc.expectedFailed {
|
||||
assert.Assert(t, er.IsFailed())
|
||||
} else if tc.expectedSkipped {
|
||||
|
|
|
@ -57,7 +57,7 @@ const (
|
|||
type PolicyController struct {
|
||||
client dclient.Interface
|
||||
kyvernoClient versioned.Interface
|
||||
contextLoader engine.ContextLoaderFactory
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
|
||||
pInformer kyvernov1informers.ClusterPolicyInformer
|
||||
npInformer kyvernov1informers.PolicyInformer
|
||||
|
@ -98,7 +98,7 @@ type PolicyController struct {
|
|||
func NewPolicyController(
|
||||
kyvernoClient versioned.Interface,
|
||||
client dclient.Interface,
|
||||
contextLoader engine.ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
pInformer kyvernov1informers.ClusterPolicyInformer,
|
||||
npInformer kyvernov1informers.PolicyInformer,
|
||||
urInformer kyvernov1beta1informers.UpdateRequestInformer,
|
||||
|
|
|
@ -146,8 +146,8 @@ func runTestCase(t *testing.T, tc TestCase) bool {
|
|||
}
|
||||
|
||||
policyContext := engine.NewPolicyContext().WithPolicy(policy).WithNewResource(*resource)
|
||||
|
||||
er := engine.Mutate(
|
||||
eng := engine.NewEgine()
|
||||
er := eng.Mutate(
|
||||
context.TODO(),
|
||||
engine.LegacyContextLoaderFactory(registryclient.NewOrDie()),
|
||||
policyContext,
|
||||
|
@ -164,7 +164,7 @@ func runTestCase(t *testing.T, tc TestCase) bool {
|
|||
policyContext = policyContext.WithNewResource(*resource)
|
||||
|
||||
cfg := config.NewDefaultConfiguration()
|
||||
er = engine.Validate(
|
||||
er = eng.Validate(
|
||||
context.TODO(),
|
||||
engine.LegacyContextLoaderFactory(registryclient.NewOrDie()),
|
||||
policyContext,
|
||||
|
|
|
@ -56,6 +56,7 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) webhook
|
|||
openApiManager: openapi.NewFake(),
|
||||
pcBuilder: webhookutils.NewPolicyContextBuilder(configuration, dclient, rbLister, crbLister, configMapResolver, peLister),
|
||||
urUpdater: webhookutils.NewUpdateRequestUpdater(kyvernoclient, urLister),
|
||||
engine: engine.NewEgine(),
|
||||
contextLoader: engine.LegacyContextLoaderFactory(rclient),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ func NewGenerationHandler(
|
|||
log logr.Logger,
|
||||
client dclient.Interface,
|
||||
kyvernoClient versioned.Interface,
|
||||
contextLoader engine.ContextLoaderFactory,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
nsLister corev1listers.NamespaceLister,
|
||||
urLister kyvernov1beta1listers.UpdateRequestNamespaceLister,
|
||||
urGenerator webhookgenerate.Generator,
|
||||
|
@ -65,7 +65,7 @@ type generationHandler struct {
|
|||
log logr.Logger
|
||||
client dclient.Interface
|
||||
kyvernoClient versioned.Interface
|
||||
contextLoader engine.ContextLoaderFactory
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
nsLister corev1listers.NamespaceLister
|
||||
urLister kyvernov1beta1listers.UpdateRequestNamespaceLister
|
||||
urGenerator webhookgenerate.Generator
|
||||
|
|
|
@ -41,7 +41,8 @@ type handlers struct {
|
|||
client dclient.Interface
|
||||
kyvernoClient versioned.Interface
|
||||
rclient registryclient.Client
|
||||
contextLoader engine.ContextLoaderFactory
|
||||
engine engineapi.Engine
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
|
||||
// config
|
||||
configuration config.Configuration
|
||||
|
@ -67,7 +68,8 @@ type handlers struct {
|
|||
}
|
||||
|
||||
func NewHandlers(
|
||||
contextLoader engine.ContextLoaderFactory,
|
||||
engine engineapi.Engine,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
client dclient.Interface,
|
||||
kyvernoClient versioned.Interface,
|
||||
rclient registryclient.Client,
|
||||
|
@ -86,6 +88,7 @@ func NewHandlers(
|
|||
admissionReports bool,
|
||||
) webhooks.ResourceHandlers {
|
||||
return &handlers{
|
||||
engine: engine,
|
||||
contextLoader: contextLoader,
|
||||
client: client,
|
||||
kyvernoClient: kyvernoClient,
|
||||
|
@ -140,7 +143,7 @@ func (h *handlers) Validate(ctx context.Context, logger logr.Logger, request *ad
|
|||
namespaceLabels = engineutils.GetNamespaceSelectorsFromNamespaceLister(request.Kind.Kind, request.Namespace, h.nsLister, logger)
|
||||
}
|
||||
policyContext = policyContext.WithNamespaceLabels(namespaceLabels)
|
||||
vh := validation.NewValidationHandler(logger, h.kyvernoClient, h.contextLoader, h.pCache, h.pcBuilder, h.eventGen, h.admissionReports, h.metricsConfig, h.configuration)
|
||||
vh := validation.NewValidationHandler(logger, h.kyvernoClient, h.engine, h.contextLoader, h.pCache, h.pcBuilder, h.eventGen, h.admissionReports, h.metricsConfig, h.configuration)
|
||||
|
||||
ok, msg, warnings := vh.HandleValidation(ctx, request, policies, policyContext, startTime)
|
||||
if !ok {
|
||||
|
@ -174,7 +177,7 @@ func (h *handlers) Mutate(ctx context.Context, logger logr.Logger, request *admi
|
|||
if err := enginectx.MutateResourceWithImageInfo(request.Object.Raw, policyContext.JSONContext()); err != nil {
|
||||
logger.Error(err, "failed to patch images info to resource, policies that mutate images may be impacted")
|
||||
}
|
||||
mh := mutation.NewMutationHandler(logger, h.contextLoader, h.eventGen, h.openApiManager, h.nsLister, h.metricsConfig)
|
||||
mh := mutation.NewMutationHandler(logger, h.engine, h.contextLoader, h.eventGen, h.openApiManager, h.nsLister, h.metricsConfig)
|
||||
mutatePatches, mutateWarnings, err := mh.HandleMutation(ctx, request, mutatePolicies, policyContext, startTime)
|
||||
if err != nil {
|
||||
logger.Error(err, "mutation failed")
|
||||
|
@ -187,7 +190,7 @@ func (h *handlers) Mutate(ctx context.Context, logger logr.Logger, request *admi
|
|||
logger.Error(err, "failed to build policy context")
|
||||
return admissionutils.Response(request.UID, err)
|
||||
}
|
||||
ivh := imageverification.NewImageVerificationHandler(logger, h.kyvernoClient, h.contextLoader, h.rclient, h.eventGen, h.admissionReports, h.configuration)
|
||||
ivh := imageverification.NewImageVerificationHandler(logger, h.kyvernoClient, h.engine, h.contextLoader, h.rclient, h.eventGen, h.admissionReports, h.configuration)
|
||||
imagePatches, imageVerifyWarnings, err := ivh.Handle(ctx, newRequest, verifyImagesPolicies, policyContext)
|
||||
if err != nil {
|
||||
logger.Error(err, "image verification failed")
|
||||
|
|
|
@ -32,7 +32,8 @@ type ImageVerificationHandler interface {
|
|||
|
||||
type imageVerificationHandler struct {
|
||||
kyvernoClient versioned.Interface
|
||||
contextLoader engine.ContextLoaderFactory
|
||||
engine engineapi.Engine
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
rclient registryclient.Client
|
||||
log logr.Logger
|
||||
eventGen event.Interface
|
||||
|
@ -43,7 +44,8 @@ type imageVerificationHandler struct {
|
|||
func NewImageVerificationHandler(
|
||||
log logr.Logger,
|
||||
kyvernoClient versioned.Interface,
|
||||
contextLoader engine.ContextLoaderFactory,
|
||||
engine engineapi.Engine,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
rclient registryclient.Client,
|
||||
eventGen event.Interface,
|
||||
admissionReports bool,
|
||||
|
@ -51,6 +53,7 @@ func NewImageVerificationHandler(
|
|||
) ImageVerificationHandler {
|
||||
return &imageVerificationHandler{
|
||||
kyvernoClient: kyvernoClient,
|
||||
engine: engine,
|
||||
contextLoader: contextLoader,
|
||||
rclient: rclient,
|
||||
log: log,
|
||||
|
@ -86,7 +89,7 @@ func (h *imageVerificationHandler) handleVerifyImages(
|
|||
}
|
||||
var engineResponses []*engineapi.EngineResponse
|
||||
var patches [][]byte
|
||||
verifiedImageData := &engine.ImageVerificationMetadata{}
|
||||
verifiedImageData := &engineapi.ImageVerificationMetadata{}
|
||||
for _, policy := range policies {
|
||||
tracing.ChildSpan(
|
||||
ctx,
|
||||
|
@ -94,7 +97,7 @@ func (h *imageVerificationHandler) handleVerifyImages(
|
|||
fmt.Sprintf("POLICY %s/%s", policy.GetNamespace(), policy.GetName()),
|
||||
func(ctx context.Context, span trace.Span) {
|
||||
policyContext := policyContext.WithPolicy(policy)
|
||||
resp, ivm := engine.VerifyAndPatchImages(ctx, h.contextLoader, h.rclient, policyContext, h.cfg)
|
||||
resp, ivm := h.engine.VerifyAndPatchImages(ctx, h.contextLoader, h.rclient, policyContext, h.cfg)
|
||||
|
||||
engineResponses = append(engineResponses, resp)
|
||||
patches = append(patches, resp.GetPatches()...)
|
||||
|
|
|
@ -34,7 +34,8 @@ type MutationHandler interface {
|
|||
|
||||
func NewMutationHandler(
|
||||
log logr.Logger,
|
||||
contextLoader engine.ContextLoaderFactory,
|
||||
engine engineapi.Engine,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
eventGen event.Interface,
|
||||
openApiManager openapi.ValidateInterface,
|
||||
nsLister corev1listers.NamespaceLister,
|
||||
|
@ -42,6 +43,7 @@ func NewMutationHandler(
|
|||
) MutationHandler {
|
||||
return &mutationHandler{
|
||||
log: log,
|
||||
engine: engine,
|
||||
contextLoader: contextLoader,
|
||||
eventGen: eventGen,
|
||||
openApiManager: openApiManager,
|
||||
|
@ -52,7 +54,8 @@ func NewMutationHandler(
|
|||
|
||||
type mutationHandler struct {
|
||||
log logr.Logger
|
||||
contextLoader engine.ContextLoaderFactory
|
||||
engine engineapi.Engine
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
eventGen event.Interface
|
||||
openApiManager openapi.ValidateInterface
|
||||
nsLister corev1listers.NamespaceLister
|
||||
|
@ -156,7 +159,7 @@ func (h *mutationHandler) applyMutation(ctx context.Context, request *admissionv
|
|||
policyContext = policyContext.WithNamespaceLabels(engineutils.GetNamespaceSelectorsFromNamespaceLister(request.Kind.Kind, request.Namespace, h.nsLister, h.log))
|
||||
}
|
||||
|
||||
engineResponse := engine.Mutate(ctx, h.contextLoader, policyContext)
|
||||
engineResponse := h.engine.Mutate(ctx, h.contextLoader, policyContext)
|
||||
policyPatches := engineResponse.GetPatches()
|
||||
|
||||
if !engineResponse.IsSuccessful() {
|
||||
|
|
|
@ -37,7 +37,8 @@ type ValidationHandler interface {
|
|||
func NewValidationHandler(
|
||||
log logr.Logger,
|
||||
kyvernoClient versioned.Interface,
|
||||
contextLoader engine.ContextLoaderFactory,
|
||||
engine engineapi.Engine,
|
||||
contextLoader engineapi.ContextLoaderFactory,
|
||||
pCache policycache.Cache,
|
||||
pcBuilder webhookutils.PolicyContextBuilder,
|
||||
eventGen event.Interface,
|
||||
|
@ -48,6 +49,7 @@ func NewValidationHandler(
|
|||
return &validationHandler{
|
||||
log: log,
|
||||
kyvernoClient: kyvernoClient,
|
||||
engine: engine,
|
||||
contextLoader: contextLoader,
|
||||
pCache: pCache,
|
||||
pcBuilder: pcBuilder,
|
||||
|
@ -61,7 +63,8 @@ func NewValidationHandler(
|
|||
type validationHandler struct {
|
||||
log logr.Logger
|
||||
kyvernoClient versioned.Interface
|
||||
contextLoader engine.ContextLoaderFactory
|
||||
engine engineapi.Engine
|
||||
contextLoader engineapi.ContextLoaderFactory
|
||||
pCache policycache.Cache
|
||||
pcBuilder webhookutils.PolicyContextBuilder
|
||||
eventGen event.Interface
|
||||
|
@ -106,7 +109,7 @@ func (v *validationHandler) HandleValidation(
|
|||
failurePolicy = kyvernov1.Fail
|
||||
}
|
||||
|
||||
engineResponse := engine.Validate(ctx, v.contextLoader, policyContext, v.cfg)
|
||||
engineResponse := v.engine.Validate(ctx, v.contextLoader, policyContext, v.cfg)
|
||||
if engineResponse.IsNil() {
|
||||
// we get an empty response if old and new resources created the same response
|
||||
// allow updates if resource update doesnt change the policy evaluation
|
||||
|
@ -164,7 +167,7 @@ func (v *validationHandler) buildAuditResponses(
|
|||
fmt.Sprintf("POLICY %s/%s", policy.GetNamespace(), policy.GetName()),
|
||||
func(ctx context.Context, span trace.Span) {
|
||||
policyContext := policyContext.WithPolicy(policy)
|
||||
responses = append(responses, engine.Validate(ctx, v.contextLoader, policyContext, v.cfg))
|
||||
responses = append(responses, v.engine.Validate(ctx, v.contextLoader, policyContext, v.cfg))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1050,6 +1050,7 @@ func TestValidate_failure_action_overrides(t *testing.T) {
|
|||
}
|
||||
|
||||
cfg := config.NewDefaultConfiguration()
|
||||
eng := engine.NewEgine()
|
||||
for i, tc := range testcases {
|
||||
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
||||
var policy kyvernov1.ClusterPolicy
|
||||
|
@ -1059,7 +1060,7 @@ func TestValidate_failure_action_overrides(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
|
||||
ctx := engine.NewPolicyContext().WithPolicy(&policy).WithNewResource(*resourceUnstructured).WithNamespaceLabels(tc.rawResourceNamespaceLabels)
|
||||
er := engine.Validate(
|
||||
er := eng.Validate(
|
||||
context.TODO(),
|
||||
engine.LegacyContextLoaderFactory(registryclient.NewOrDie()),
|
||||
ctx,
|
||||
|
@ -1125,7 +1126,8 @@ func Test_RuleSelector(t *testing.T) {
|
|||
ctx := engine.NewPolicyContext().WithPolicy(&policy).WithNewResource(*resourceUnstructured)
|
||||
|
||||
cfg := config.NewDefaultConfiguration()
|
||||
resp := engine.Validate(
|
||||
eng := engine.NewEgine()
|
||||
resp := eng.Validate(
|
||||
context.TODO(),
|
||||
engine.LegacyContextLoaderFactory(registryclient.NewOrDie()),
|
||||
ctx,
|
||||
|
@ -1140,8 +1142,7 @@ func Test_RuleSelector(t *testing.T) {
|
|||
|
||||
applyOne := kyvernov1.ApplyOne
|
||||
policy.Spec.ApplyRules = &applyOne
|
||||
|
||||
resp = engine.Validate(
|
||||
resp = eng.Validate(
|
||||
context.TODO(),
|
||||
engine.LegacyContextLoaderFactory(registryclient.NewOrDie()),
|
||||
ctx,
|
||||
|
|
Loading…
Add table
Reference in a new issue