1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

refactor: introduce engine api package (#6154)

* refactor: introduce engine api package

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

* status

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

---------

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-01-30 12:41:09 +01:00 committed by GitHub
parent 8250dc6ca3
commit fb94f6ea75
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 656 additions and 680 deletions

View file

@ -9,7 +9,7 @@ import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -89,7 +89,7 @@ func buildPolicyResults(infos []common.Info) map[string][]policyreportv1alpha2.P
for _, infoResult := range info.Results {
for _, rule := range infoResult.Rules {
if rule.Type != string(response.Validation) {
if rule.Type != string(engineapi.Validation) {
continue
}

View file

@ -8,7 +8,7 @@ import (
preport "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common"
kyvCommon "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"gotest.tools/assert"
v1 "k8s.io/api/core/v1"
)
@ -92,7 +92,7 @@ func Test_buildPolicyReports(t *testing.T) {
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
var er response.EngineResponse
var er engineapi.EngineResponse
err = json.Unmarshal(rawEngRes, &er)
assert.NilError(t, err)
@ -128,7 +128,7 @@ func Test_buildPolicyResults(t *testing.T) {
err := json.Unmarshal(rawPolicy, &policy)
assert.NilError(t, err)
var er response.EngineResponse
var er engineapi.EngineResponse
err = json.Unmarshal(rawEngRes, &er)
assert.NilError(t, err)

View file

@ -26,7 +26,7 @@ import (
"github.com/kyverno/kyverno/pkg/autogen"
"github.com/kyverno/kyverno/pkg/background/generate"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/openapi"
policy2 "github.com/kyverno/kyverno/pkg/policy"
gitutils "github.com/kyverno/kyverno/pkg/utils/git"
@ -427,7 +427,7 @@ func getLocalDirTestFiles(fs billy.Filesystem, path, fileName string, rc *result
return errors
}
func buildPolicyResults(engineResponses []*response.EngineResponse, testResults []api.TestResults, infos []common.Info, policyResourcePath string, fs billy.Filesystem, isGit bool) (map[string]policyreportv1alpha2.PolicyReportResult, []api.TestResults) {
func buildPolicyResults(engineResponses []*engineapi.EngineResponse, testResults []api.TestResults, infos []common.Info, policyResourcePath string, fs billy.Filesystem, isGit bool) (map[string]policyreportv1alpha2.PolicyReportResult, []api.TestResults) {
results := make(map[string]policyreportv1alpha2.PolicyReportResult)
now := metav1.Timestamp{Seconds: time.Now().Unix()}
@ -542,7 +542,7 @@ func buildPolicyResults(engineResponses []*response.EngineResponse, testResults
}
for _, rule := range resp.PolicyResponse.Rules {
if rule.Type != response.Generation || test.Rule != rule.Name {
if rule.Type != engineapi.Generation || test.Rule != rule.Name {
continue
}
@ -558,9 +558,9 @@ func buildPolicyResults(engineResponses []*response.EngineResponse, testResults
continue
}
if rule.Status == response.RuleStatusSkip {
if rule.Status == engineapi.RuleStatusSkip {
result.Result = policyreportv1alpha2.StatusSkip
} else if rule.Status == response.RuleStatusError {
} else if rule.Status == engineapi.RuleStatusError {
result.Result = policyreportv1alpha2.StatusError
} else {
var x string
@ -576,7 +576,7 @@ func buildPolicyResults(engineResponses []*response.EngineResponse, testResults
}
for _, rule := range resp.PolicyResponse.Rules {
if rule.Type != response.Mutation {
if rule.Type != engineapi.Mutation {
continue
}
@ -592,9 +592,9 @@ func buildPolicyResults(engineResponses []*response.EngineResponse, testResults
continue
}
if rule.Status == response.RuleStatusSkip {
if rule.Status == engineapi.RuleStatusSkip {
result.Result = policyreportv1alpha2.StatusSkip
} else if rule.Status == response.RuleStatusError {
} else if rule.Status == engineapi.RuleStatusError {
result.Result = policyreportv1alpha2.StatusError
} else {
var x string
@ -616,7 +616,7 @@ func buildPolicyResults(engineResponses []*response.EngineResponse, testResults
for _, info := range infos {
for _, infoResult := range info.Results {
for _, rule := range infoResult.Rules {
if rule.Type != string(response.Validation) && rule.Type != string(response.ImageVerify) {
if rule.Type != string(engineapi.Validation) && rule.Type != string(engineapi.ImageVerify) {
continue
}
@ -707,10 +707,10 @@ func getAndCompareResource(path string, engineResource unstructured.Unstructured
return status
}
func buildMessage(resp *response.EngineResponse) string {
func buildMessage(resp *engineapi.EngineResponse) string {
var bldr strings.Builder
for _, ruleResp := range resp.PolicyResponse.Rules {
fmt.Fprintf(&bldr, " %s: %s \n", ruleResp.Name, ruleResp.Status.String())
fmt.Fprintf(&bldr, " %s: %s \n", ruleResp.Name, ruleResp.Status)
fmt.Fprintf(&bldr, " %s \n", ruleResp.Message)
}
@ -731,7 +731,7 @@ func getFullPath(paths []string, policyResourcePath string, isGit bool) []string
}
func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, isGit bool, policyResourcePath string, rc *resultCounts, openApiManager openapi.Manager, tf *testFilter, failOnly, removeColor bool) (err error) {
engineResponses := make([]*response.EngineResponse, 0)
engineResponses := make([]*engineapi.EngineResponse, 0)
var dClient dclient.Interface
values := &api.Test{}
var variablesString string

View file

@ -23,8 +23,8 @@ import (
"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"
engineContext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/registryclient"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
@ -370,8 +370,8 @@ func GetVariable(variablesString, valuesFile string, fs billy.Filesystem, isGit
}
// ApplyPolicyOnResource - function to apply policy on resource
func ApplyPolicyOnResource(c ApplyPolicyConfig) ([]*response.EngineResponse, Info, error) {
var engineResponses []*response.EngineResponse
func ApplyPolicyOnResource(c ApplyPolicyConfig) ([]*engineapi.EngineResponse, Info, error) {
var engineResponses []*engineapi.EngineResponse
namespaceLabels := make(map[string]string)
operationIsDelete := false
@ -510,7 +510,7 @@ OuterLoop:
policyContext = policyContext.WithNewResource(mutateResponse.PatchedResource)
var info Info
var validateResponse *response.EngineResponse
var validateResponse *engineapi.EngineResponse
if policyHasValidate {
validateResponse = engine.Validate(context.Background(), registryclient.NewOrDie(), policyContext, cfg)
info = ProcessValidateEngineResponse(c.Policy, validateResponse, resPath, c.Rc, c.PolicyReport, c.AuditWarn)
@ -696,7 +696,7 @@ func GetResourceAccordingToResourcePath(fs billy.Filesystem, resourcePaths []str
return resources, err
}
func ProcessValidateEngineResponse(policy kyvernov1.PolicyInterface, validateResponse *response.EngineResponse, resPath string, rc *ResultCounts, policyReport bool, auditWarn bool) Info {
func ProcessValidateEngineResponse(policy kyvernov1.PolicyInterface, validateResponse *engineapi.EngineResponse, resPath string, rc *ResultCounts, policyReport bool, auditWarn bool) Info {
var violatedRules []kyvernov1.ViolatedRule
printCount := 0
@ -716,11 +716,11 @@ func ProcessValidateEngineResponse(policy kyvernov1.PolicyInterface, validateRes
}
switch valResponseRule.Status {
case response.RuleStatusPass:
case engineapi.RuleStatusPass:
rc.Pass++
vrule.Status = policyreportv1alpha2.StatusPass
case response.RuleStatusFail:
case engineapi.RuleStatusFail:
auditWarning := false
ann := policy.GetAnnotations()
if scored, ok := ann[kyvernov1.AnnotationPolicyScored]; ok && scored == "false" {
@ -749,15 +749,15 @@ func ProcessValidateEngineResponse(policy kyvernov1.PolicyInterface, validateRes
fmt.Printf("%d. %s: %s \n", i+1, valResponseRule.Name, valResponseRule.Message)
}
case response.RuleStatusError:
case engineapi.RuleStatusError:
rc.Error++
vrule.Status = policyreportv1alpha2.StatusError
case response.RuleStatusWarn:
case engineapi.RuleStatusWarn:
rc.Warn++
vrule.Status = policyreportv1alpha2.StatusWarn
case response.RuleStatusSkip:
case engineapi.RuleStatusSkip:
rc.Skip++
vrule.Status = policyreportv1alpha2.StatusSkip
}
@ -781,7 +781,7 @@ func ProcessValidateEngineResponse(policy kyvernov1.PolicyInterface, validateRes
return buildPVInfo(validateResponse, violatedRules)
}
func buildPVInfo(er *response.EngineResponse, violatedRules []kyvernov1.ViolatedRule) Info {
func buildPVInfo(er *engineapi.EngineResponse, violatedRules []kyvernov1.ViolatedRule) Info {
info := Info{
PolicyName: er.PolicyResponse.Policy.Name,
Namespace: er.PatchedResource.GetNamespace(),
@ -795,7 +795,7 @@ func buildPVInfo(er *response.EngineResponse, violatedRules []kyvernov1.Violated
return info
}
func updateResultCounts(policy kyvernov1.PolicyInterface, engineResponse *response.EngineResponse, resPath string, rc *ResultCounts, auditWarn bool) {
func updateResultCounts(policy kyvernov1.PolicyInterface, engineResponse *engineapi.EngineResponse, resPath string, rc *ResultCounts, auditWarn bool) {
printCount := 0
for _, policyRule := range autogen.ComputeRules(policy) {
ruleFoundInEngineResponse := false
@ -803,7 +803,7 @@ func updateResultCounts(policy kyvernov1.PolicyInterface, engineResponse *respon
if policyRule.Name == ruleResponse.Name {
ruleFoundInEngineResponse = true
if ruleResponse.Status == response.RuleStatusPass {
if ruleResponse.Status == engineapi.RuleStatusPass {
rc.Pass++
} else {
if printCount < 1 {
@ -862,7 +862,7 @@ func SetInStoreContext(mutatedPolicies []kyvernov1.PolicyInterface, variables ma
return variables
}
func processMutateEngineResponse(c ApplyPolicyConfig, mutateResponse *response.EngineResponse, resPath string) error {
func processMutateEngineResponse(c ApplyPolicyConfig, mutateResponse *engineapi.EngineResponse, resPath string) error {
var policyHasMutate bool
for _, rule := range autogen.ComputeRules(c.Policy) {
if rule.HasMutate() {
@ -880,13 +880,13 @@ func processMutateEngineResponse(c ApplyPolicyConfig, mutateResponse *response.E
for i, mutateResponseRule := range mutateResponse.PolicyResponse.Rules {
if policyRule.Name == mutateResponseRule.Name {
ruleFoundInEngineResponse = true
if mutateResponseRule.Status == response.RuleStatusPass {
if mutateResponseRule.Status == engineapi.RuleStatusPass {
c.Rc.Pass++
printMutatedRes = true
} else if mutateResponseRule.Status == response.RuleStatusSkip {
} else if mutateResponseRule.Status == engineapi.RuleStatusSkip {
fmt.Printf("\nskipped mutate policy %s -> resource %s", c.Policy.GetName(), resPath)
c.Rc.Skip++
} else if mutateResponseRule.Status == response.RuleStatusError {
} else if mutateResponseRule.Status == engineapi.RuleStatusError {
fmt.Printf("\nerror while applying mutate policy %s -> resource %s\nerror: %s", c.Policy.GetName(), resPath, mutateResponseRule.Message)
c.Rc.Error++
} else {
@ -1074,7 +1074,7 @@ func initializeMockController(objects []runtime.Object) (*generate.GenerateContr
}
// handleGeneratePolicy returns a new RuleResponse with the Kyverno generated resource configuration by applying the generate rule.
func handleGeneratePolicy(generateResponse *response.EngineResponse, policyContext engine.PolicyContext, ruleToCloneSourceResource map[string]string) ([]response.RuleResponse, error) {
func handleGeneratePolicy(generateResponse *engineapi.EngineResponse, policyContext engine.PolicyContext, ruleToCloneSourceResource map[string]string) ([]engineapi.RuleResponse, error) {
resource := policyContext.NewResource()
objects := []runtime.Object{&resource}
resources := []*unstructured.Unstructured{}
@ -1115,18 +1115,18 @@ func handleGeneratePolicy(generateResponse *response.EngineResponse, policyConte
},
}
var newRuleResponse []response.RuleResponse
var newRuleResponse []engineapi.RuleResponse
for _, rule := range generateResponse.PolicyResponse.Rules {
genResource, _, err := c.ApplyGeneratePolicy(log.Log, &policyContext, gr, []string{rule.Name})
if err != nil {
rule.Status = response.RuleStatusError
rule.Status = engineapi.RuleStatusError
return nil, err
}
unstrGenResource, err := c.GetUnstrResource(genResource[0])
if err != nil {
rule.Status = response.RuleStatusError
rule.Status = engineapi.RuleStatusError
return nil, err
}

View file

@ -2,7 +2,7 @@ package common
import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
)
// Info stores the policy application results for all matched resources
@ -14,6 +14,6 @@ type Info struct {
}
type EngineResponseResult struct {
Resource response.ResourceSpec
Resource engineapi.ResourceSpec
Rules []kyvernov1.ViolatedRule
}

View file

@ -21,9 +21,9 @@ import (
"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"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/context/resolvers"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/registryclient"
@ -211,7 +211,7 @@ func (c *GenerateController) applyGenerate(resource unstructured.Unstructured, u
var applicableRules []string
// Removing UR if rule is failed. Used when the generate condition failed but ur exist
for _, r := range engineResponse.PolicyResponse.Rules {
if r.Status != response.RuleStatusPass {
if r.Status != engineapi.RuleStatusPass {
logger.V(4).Info("querying all update requests")
selector := labels.SelectorFromSet(labels.Set(map[string]string{
kyvernov1beta1.URGeneratePolicyLabel: engineResponse.PolicyResponse.Policy.Name,

View file

@ -13,8 +13,8 @@ import (
"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/engine/context/resolvers"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/registryclient"
"github.com/kyverno/kyverno/pkg/utils"
@ -103,17 +103,17 @@ func (c *MutateExistingController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) e
patched := r.PatchedTarget
patchedTargetSubresourceName := r.PatchedTargetSubresourceName
switch r.Status {
case response.RuleStatusFail, response.RuleStatusError, response.RuleStatusWarn:
case engineapi.RuleStatusFail, engineapi.RuleStatusError, engineapi.RuleStatusWarn:
err := fmt.Errorf("failed to mutate existing resource, rule response%v: %s", r.Status, r.Message)
logger.Error(err, "")
errs = append(errs, err)
c.report(err, ur.Spec.Policy, rule.Name, patched)
case response.RuleStatusSkip:
case engineapi.RuleStatusSkip:
logger.Info("mutate existing rule skipped", "rule", r.Name, "message", r.Message)
c.report(err, ur.Spec.Policy, rule.Name, patched)
case response.RuleStatusPass:
case engineapi.RuleStatusPass:
patchedNew, err := addAnnotation(policy, patched, r)
if err != nil {
@ -127,7 +127,7 @@ func (c *MutateExistingController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) e
continue
}
if r.Status == response.RuleStatusPass {
if r.Status == engineapi.RuleStatusPass {
patchedNew.SetResourceVersion(patched.GetResourceVersion())
var updateErr error
if patchedTargetSubresourceName == "status" {
@ -204,7 +204,7 @@ func updateURStatus(statusControl common.StatusControlInterface, ur kyvernov1bet
return nil
}
func addAnnotation(policy kyvernov1.PolicyInterface, patched *unstructured.Unstructured, r response.RuleResponse) (patchedNew *unstructured.Unstructured, err error) {
func addAnnotation(policy kyvernov1.PolicyInterface, patched *unstructured.Unstructured, r engineapi.RuleResponse) (patchedNew *unstructured.Unstructured, err error) {
if patched == nil {
return
}

View file

@ -5,11 +5,11 @@ import (
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/event"
)
func GenerateEvents(logger logr.Logger, eventGen event.Interface, config config.Configuration, results ...*response.EngineResponse) {
func GenerateEvents(logger logr.Logger, eventGen event.Interface, config config.Configuration, results ...*engineapi.EngineResponse) {
for _, result := range results {
var eventInfos []event.Info
eventInfos = append(eventInfos, generateFailEvents(logger, result)...)
@ -21,7 +21,7 @@ func GenerateEvents(logger logr.Logger, eventGen event.Interface, config config.
}
}
func generateSuccessEvents(log logr.Logger, ers ...*response.EngineResponse) (eventInfos []event.Info) {
func generateSuccessEvents(log logr.Logger, ers ...*engineapi.EngineResponse) (eventInfos []event.Info) {
for _, er := range ers {
logger := log.WithValues("policy", er.PolicyResponse.Policy, "kind", er.PolicyResponse.Resource.Kind, "namespace", er.PolicyResponse.Resource.Namespace, "name", er.PolicyResponse.Resource.Name)
if !er.IsFailed() {
@ -33,11 +33,11 @@ func generateSuccessEvents(log logr.Logger, ers ...*response.EngineResponse) (ev
return eventInfos
}
func generateExceptionEvents(log logr.Logger, ers ...*response.EngineResponse) (eventInfos []event.Info) {
func generateExceptionEvents(log logr.Logger, ers ...*engineapi.EngineResponse) (eventInfos []event.Info) {
for _, er := range ers {
for i, ruleResp := range er.PolicyResponse.Rules {
isException := strings.Contains(ruleResp.Message, "rule skipped due to policy exception")
if ruleResp.Status == response.RuleStatusSkip && isException {
if ruleResp.Status == engineapi.RuleStatusSkip && isException {
eventInfos = append(eventInfos, event.NewPolicyExceptionEvents(er, &er.PolicyResponse.Rules[i])...)
}
}
@ -45,14 +45,14 @@ func generateExceptionEvents(log logr.Logger, ers ...*response.EngineResponse) (
return eventInfos
}
func generateFailEvents(log logr.Logger, ers ...*response.EngineResponse) (eventInfos []event.Info) {
func generateFailEvents(log logr.Logger, ers ...*engineapi.EngineResponse) (eventInfos []event.Info) {
for _, er := range ers {
eventInfos = append(eventInfos, generateFailEventsPerEr(log, er)...)
}
return eventInfos
}
func generateFailEventsPerEr(log logr.Logger, er *response.EngineResponse) []event.Info {
func generateFailEventsPerEr(log logr.Logger, er *engineapi.EngineResponse) []event.Info {
var eventInfos []event.Info
logger := log.WithValues(
"policy", er.PolicyResponse.Policy.Name,
@ -61,7 +61,7 @@ func generateFailEventsPerEr(log logr.Logger, er *response.EngineResponse) []eve
"name", er.PolicyResponse.Resource.Name,
)
for i, rule := range er.PolicyResponse.Rules {
if rule.Status != response.RuleStatusPass && rule.Status != response.RuleStatusSkip {
if rule.Status != engineapi.RuleStatusPass && rule.Status != engineapi.RuleStatusSkip {
eventResource := event.NewResourceViolationEvent(event.PolicyController, event.PolicyViolation, er, &er.PolicyResponse.Rules[i])
eventInfos = append(eventInfos, eventResource)
eventPolicy := event.NewPolicyFailEvent(event.PolicyController, event.PolicyViolation, er, &er.PolicyResponse.Rules[i], false)

View file

@ -8,9 +8,9 @@ import (
"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"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/context/resolvers"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/registryclient"
"go.uber.org/multierr"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@ -27,7 +27,7 @@ type scanner struct {
}
type ScanResult struct {
EngineResponse *response.EngineResponse
EngineResponse *engineapi.EngineResponse
Error error
}
@ -82,7 +82,7 @@ func (s *scanner) ScanResource(ctx context.Context, resource unstructured.Unstru
return results
}
func (s *scanner) validateResource(ctx context.Context, resource unstructured.Unstructured, nsLabels map[string]string, policy kyvernov1.PolicyInterface) (*response.EngineResponse, error) {
func (s *scanner) validateResource(ctx context.Context, resource unstructured.Unstructured, nsLabels map[string]string, policy kyvernov1.PolicyInterface) (*engineapi.EngineResponse, error) {
enginectx := enginecontext.NewContext()
if err := enginectx.AddResource(resource.Object); err != nil {
return nil, err
@ -107,7 +107,7 @@ func (s *scanner) validateResource(ctx context.Context, resource unstructured.Un
return engine.Validate(ctx, s.rclient, policyCtx, s.config), nil
}
func (s *scanner) validateImages(ctx context.Context, resource unstructured.Unstructured, nsLabels map[string]string, policy kyvernov1.PolicyInterface) (*response.EngineResponse, error) {
func (s *scanner) validateImages(ctx context.Context, resource unstructured.Unstructured, nsLabels map[string]string, policy kyvernov1.PolicyInterface) (*engineapi.EngineResponse, error) {
enginectx := enginecontext.NewContext()
if err := enginectx.AddResource(resource.Object); err != nil {
return nil, err

View file

@ -1,4 +1,4 @@
package response
package api
import (
"fmt"

View file

@ -1,4 +1,4 @@
package response
package api
import (
"testing"

76
pkg/engine/api/status.go Normal file
View file

@ -0,0 +1,76 @@
package api
// RuleStatus represents the status of rule execution
type RuleStatus string
// RuleStatusPass is used to report the result of processing a rule.
const (
// RuleStatusPass indicates that the resources meets the policy rule requirements
RuleStatusPass RuleStatus = "pass"
// RuleStatusFail indicates that the resource does not meet the policy rule requirements
RuleStatusFail RuleStatus = "fail"
// RuleStatusWarn indicates that the resource does not meet the policy rule requirements, but the policy is not scored
RuleStatusWarn RuleStatus = "warning"
// RuleStatusError indicates that the policy rule could not be evaluated due to a processing error, for
// example when a variable cannot be resolved in the policy rule definition. Note that variables
// that cannot be resolved in preconditions are replaced with empty values to allow existence
// checks.
RuleStatusError RuleStatus = "error"
// RuleStatusSkip indicates that the policy rule was not selected based on user inputs or applicability, for example
// when preconditions are not met, or when conditional or global anchors are not satistied.
RuleStatusSkip RuleStatus = "skip"
)
// // String implements Stringer interface
// func (s RuleStatus) String() string {
// return toString[s]
// }
// // MarshalJSON marshals the enum as a quoted json string
// func (s *RuleStatus) MarshalJSON() ([]byte, error) {
// var b strings.Builder
// fmt.Fprintf(&b, "\"%s\"", toString[*s])
// return []byte(b.String()), nil
// }
// // UnmarshalJSON unmarshals a quoted json string to the enum value
// func (s *RuleStatus) UnmarshalJSON(b []byte) error {
// var strVal string
// err := json.Unmarshal(b, &strVal)
// if err != nil {
// return err
// }
// statusVal, err := getRuleStatus(strVal)
// if err != nil {
// return err
// }
// *s = *statusVal
// return nil
// }
// func getRuleStatus(s string) (*RuleStatus, error) {
// for k, v := range toID {
// if s == k {
// return &v, nil
// }
// }
// return nil, fmt.Errorf("invalid status: %s", s)
// }
// func (s *RuleStatus) UnmarshalYAML(unmarshal func(interface{}) error) error {
// var str string
// if err := unmarshal(&str); err != nil {
// return err
// }
// statusVal, err := getRuleStatus(str)
// if err != nil {
// return err
// }
// *s = *statusVal
// return nil
// }

View file

@ -6,8 +6,8 @@ import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/autogen"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/common"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/registryclient"
@ -18,26 +18,26 @@ import (
// - the caller has to check the ruleResponse to determine whether the path exist
//
// 2. returns the list of rules that are applicable on this policy and resource, if 1 succeed
func ApplyBackgroundChecks(rclient registryclient.Client, policyContext *PolicyContext) (resp *response.EngineResponse) {
func ApplyBackgroundChecks(rclient registryclient.Client, policyContext *PolicyContext) (resp *engineapi.EngineResponse) {
policyStartTime := time.Now()
return filterRules(rclient, policyContext, policyStartTime)
}
func filterRules(rclient registryclient.Client, policyContext *PolicyContext, startTime time.Time) *response.EngineResponse {
func filterRules(rclient registryclient.Client, policyContext *PolicyContext, startTime time.Time) *engineapi.EngineResponse {
kind := policyContext.newResource.GetKind()
name := policyContext.newResource.GetName()
namespace := policyContext.newResource.GetNamespace()
apiVersion := policyContext.newResource.GetAPIVersion()
resp := &response.EngineResponse{
PolicyResponse: response.PolicyResponse{
Policy: response.PolicySpec{
resp := &engineapi.EngineResponse{
PolicyResponse: engineapi.PolicyResponse{
Policy: engineapi.PolicySpec{
Name: policyContext.policy.GetName(),
Namespace: policyContext.policy.GetNamespace(),
},
PolicyStats: response.PolicyStats{
PolicyStats: engineapi.PolicyStats{
PolicyExecutionTimestamp: startTime.Unix(),
},
Resource: response.ResourceSpec{
Resource: engineapi.ResourceSpec{
Kind: kind,
Name: name,
Namespace: namespace,
@ -55,7 +55,7 @@ func filterRules(rclient registryclient.Client, policyContext *PolicyContext, st
for _, rule := range autogen.ComputeRules(policyContext.policy) {
if ruleResp := filterRule(rclient, rule, policyContext); ruleResp != nil {
resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, *ruleResp)
if applyRules == kyvernov1.ApplyOne && ruleResp.Status != response.RuleStatusSkip {
if applyRules == kyvernov1.ApplyOne && ruleResp.Status != engineapi.RuleStatusSkip {
break
}
}
@ -64,7 +64,7 @@ func filterRules(rclient registryclient.Client, policyContext *PolicyContext, st
return resp
}
func filterRule(rclient registryclient.Client, rule kyvernov1.Rule, policyContext *PolicyContext) *response.RuleResponse {
func filterRule(rclient registryclient.Client, rule kyvernov1.Rule, policyContext *PolicyContext) *engineapi.RuleResponse {
if !rule.HasGenerate() && !rule.IsMutateExisting() {
return nil
}
@ -80,9 +80,9 @@ func filterRule(rclient registryclient.Client, rule kyvernov1.Rule, policyContex
return ruleResp
}
ruleType := response.Mutation
ruleType := engineapi.Mutation
if rule.HasGenerate() {
ruleType = response.Generation
ruleType = engineapi.Generation
}
startTime := time.Now()
@ -99,14 +99,14 @@ func filterRule(rclient registryclient.Client, rule kyvernov1.Rule, policyContex
"kind", newResource.GetKind(), "namespace", newResource.GetNamespace(), "name", newResource.GetName())
if err := MatchesResourceDescription(subresourceGVKToAPIResource, newResource, rule, admissionInfo, excludeGroupRole, namespaceLabels, "", policyContext.subresource); err != nil {
if ruleType == response.Generation {
if ruleType == engineapi.Generation {
// if the oldResource matched, return "false" to delete GR for it
if err = MatchesResourceDescription(subresourceGVKToAPIResource, oldResource, rule, admissionInfo, excludeGroupRole, namespaceLabels, "", policyContext.subresource); err == nil {
return &response.RuleResponse{
return &engineapi.RuleResponse{
Name: rule.Name,
Type: ruleType,
Status: response.RuleStatusFail,
RuleStats: response.RuleStats{
Status: engineapi.RuleStatusFail,
RuleStats: engineapi.RuleStats{
ProcessingTime: time.Since(startTime),
RuleExecutionTimestamp: startTime.Unix(),
},
@ -143,11 +143,11 @@ func filterRule(rclient registryclient.Client, rule kyvernov1.Rule, policyContex
// evaluate pre-conditions
if !variables.EvaluateConditions(logger, ctx, copyConditions) {
logger.V(4).Info("skip rule as preconditions are not met", "rule", ruleCopy.Name)
return &response.RuleResponse{
return &engineapi.RuleResponse{
Name: ruleCopy.Name,
Type: ruleType,
Status: response.RuleStatusSkip,
RuleStats: response.RuleStats{
Status: engineapi.RuleStatusSkip,
RuleStats: engineapi.RuleStats{
ProcessingTime: time.Since(startTime),
RuleExecutionTimestamp: startTime.Unix(),
},
@ -155,11 +155,11 @@ func filterRule(rclient registryclient.Client, rule kyvernov1.Rule, policyContex
}
// build rule Response
return &response.RuleResponse{
return &engineapi.RuleResponse{
Name: ruleCopy.Name,
Type: ruleType,
Status: response.RuleStatusPass,
RuleStats: response.RuleStats{
Status: engineapi.RuleStatusPass,
RuleStats: engineapi.RuleStats{
ProcessingTime: time.Since(startTime),
RuleExecutionTimestamp: startTime.Unix(),
},

View file

@ -5,9 +5,9 @@ import (
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/mutate"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/utils/api"
@ -78,8 +78,8 @@ func applyForEachMutate(name string, foreach []kyvernov1.ForEachMutation, resour
func applyPatches(name string, mergePatch apiextensions.JSON, jsonPatch string, resource unstructured.Unstructured, ctx context.Interface, logger logr.Logger) (unstructured.Unstructured, error) {
patcher := mutate.NewPatcher(name, mergePatch, jsonPatch, resource, ctx, logger)
resp, mutatedResource := patcher.Patch()
if resp.Status != response.RuleStatusPass {
return mutatedResource, fmt.Errorf("mutate status %q: %s", resp.Status.String(), resp.Message)
if resp.Status != engineapi.RuleStatusPass {
return mutatedResource, fmt.Errorf("mutate status %q: %s", resp.Status, resp.Message)
}
return mutatedResource, nil

View file

@ -5,19 +5,19 @@ import (
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/autogen"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/registryclient"
"k8s.io/client-go/tools/cache"
)
// GenerateResponse checks for validity of generate rule on the resource
func GenerateResponse(rclient registryclient.Client, policyContext *PolicyContext, gr kyvernov1beta1.UpdateRequest) (resp *response.EngineResponse) {
func GenerateResponse(rclient registryclient.Client, policyContext *PolicyContext, gr kyvernov1beta1.UpdateRequest) (resp *engineapi.EngineResponse) {
policyStartTime := time.Now()
return filterGenerateRules(rclient, policyContext, gr.Spec.Policy, policyStartTime)
}
func filterGenerateRules(rclient registryclient.Client, policyContext *PolicyContext, policyNameKey string, startTime time.Time) *response.EngineResponse {
func filterGenerateRules(rclient registryclient.Client, policyContext *PolicyContext, policyNameKey string, startTime time.Time) *engineapi.EngineResponse {
kind := policyContext.newResource.GetKind()
name := policyContext.newResource.GetName()
namespace := policyContext.newResource.GetNamespace()
@ -27,16 +27,16 @@ func filterGenerateRules(rclient registryclient.Client, policyContext *PolicyCon
logging.Error(err, "failed to spilt name and namespace", policyNameKey)
}
resp := &response.EngineResponse{
PolicyResponse: response.PolicyResponse{
Policy: response.PolicySpec{
resp := &engineapi.EngineResponse{
PolicyResponse: engineapi.PolicyResponse{
Policy: engineapi.PolicySpec{
Name: pName,
Namespace: pNamespace,
},
PolicyStats: response.PolicyStats{
PolicyStats: engineapi.PolicyStats{
PolicyExecutionTimestamp: startTime.Unix(),
},
Resource: response.ResourceSpec{
Resource: engineapi.ResourceSpec{
Kind: kind,
Name: name,
Namespace: namespace,

View file

@ -14,8 +14,8 @@ import (
"github.com/kyverno/kyverno/pkg/autogen"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/cosign"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/registryclient"
@ -71,8 +71,8 @@ func VerifyAndPatchImages(
rclient registryclient.Client,
policyContext *PolicyContext,
cfg config.Configuration,
) (*response.EngineResponse, *ImageVerificationMetadata) {
resp := &response.EngineResponse{}
) (*engineapi.EngineResponse, *ImageVerificationMetadata) {
resp := &engineapi.EngineResponse{}
policy := policyContext.policy
patchedResource := policyContext.newResource
@ -124,7 +124,7 @@ func VerifyAndPatchImages(
ruleImages, imageRefs, err := extractMatchingImages(policyContext, rule, cfg)
if err != nil {
appendResponse(resp, rule, fmt.Sprintf("failed to extract images: %s", err.Error()), response.RuleStatusError)
appendResponse(resp, rule, fmt.Sprintf("failed to extract images: %s", err.Error()), engineapi.RuleStatusError)
return
}
if len(ruleImages) == 0 {
@ -132,20 +132,20 @@ func VerifyAndPatchImages(
resp,
rule,
fmt.Sprintf("skip run verification as image in resource not found in imageRefs '%s'", imageRefs),
response.RuleStatusSkip,
engineapi.RuleStatusSkip,
)
return
}
policyContext.jsonContext.Restore()
if err := LoadContext(ctx, logger, rclient, rule.Context, policyContext, rule.Name); err != nil {
appendResponse(resp, rule, fmt.Sprintf("failed to load context: %s", err.Error()), response.RuleStatusError)
appendResponse(resp, rule, fmt.Sprintf("failed to load context: %s", err.Error()), engineapi.RuleStatusError)
return
}
ruleCopy, err := substituteVariables(rule, policyContext.jsonContext, logger)
if err != nil {
appendResponse(resp, rule, fmt.Sprintf("failed to substitute variables: %s", err.Error()), response.RuleStatusError)
appendResponse(resp, rule, fmt.Sprintf("failed to substitute variables: %s", err.Error()), engineapi.RuleStatusError)
return
}
@ -172,8 +172,8 @@ func VerifyAndPatchImages(
return resp, ivm
}
func appendResponse(resp *response.EngineResponse, rule *kyvernov1.Rule, msg string, status response.RuleStatus) {
rr := ruleResponse(*rule, response.ImageVerify, msg, status)
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)
incrementErrorCount(resp)
}
@ -204,7 +204,7 @@ type imageVerifier struct {
rclient registryclient.Client
policyContext *PolicyContext
rule *kyvernov1.Rule
resp *response.EngineResponse
resp *engineapi.EngineResponse
ivm *ImageVerificationMetadata
}
@ -220,7 +220,7 @@ func (iv *imageVerifier) verify(ctx context.Context, imageVerify kyvernov1.Image
if hasImageVerifiedAnnotationChanged(iv.policyContext, iv.logger) {
msg := imageVerifyAnnotationKey + " annotation cannot be changed"
iv.logger.Info("image verification error", "reason", msg)
ruleResp := ruleResponse(*iv.rule, response.ImageVerify, msg, response.RuleStatusFail)
ruleResp := ruleResponse(*iv.rule, engineapi.ImageVerify, msg, engineapi.RuleStatusFail)
iv.resp.PolicyResponse.Rules = append(iv.resp.PolicyResponse.Rules, *ruleResp)
incrementAppliedCount(iv.resp)
continue
@ -244,10 +244,10 @@ func (iv *imageVerifier) verify(ctx context.Context, imageVerify kyvernov1.Image
if imageVerify.MutateDigest {
patch, retrievedDigest, err := iv.handleMutateDigest(ctx, digest, imageInfo)
if err != nil {
ruleResp = ruleError(iv.rule, response.ImageVerify, "failed to update digest", err)
ruleResp = ruleError(iv.rule, engineapi.ImageVerify, "failed to update digest", err)
} else if patch != nil {
if ruleResp == nil {
ruleResp = ruleResponse(*iv.rule, response.ImageVerify, "mutated image digest", response.RuleStatusPass)
ruleResp = ruleResponse(*iv.rule, engineapi.ImageVerify, "mutated image digest", engineapi.RuleStatusPass)
}
ruleResp.Patches = append(ruleResp.Patches, patch)
@ -258,7 +258,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 == response.RuleStatusPass
verified := ruleResp.Status == engineapi.RuleStatusPass
iv.ivm.add(image, verified)
}
@ -323,7 +323,7 @@ func (iv *imageVerifier) verifyImage(
imageVerify kyvernov1.ImageVerification,
imageInfo apiutils.ImageInfo,
cfg config.Configuration,
) (*response.RuleResponse, string) {
) (*engineapi.RuleResponse, string) {
if len(imageVerify.Attestors) <= 0 && len(imageVerify.Attestations) <= 0 {
return nil, ""
}
@ -335,7 +335,7 @@ func (iv *imageVerifier) verifyImage(
if err := iv.policyContext.jsonContext.AddImageInfo(imageInfo, cfg); err != nil {
iv.logger.Error(err, "failed to add image to context")
msg := fmt.Sprintf("failed to add image to context %s: %s", image, err.Error())
return ruleResponse(*iv.rule, response.ImageVerify, msg, response.RuleStatusError), ""
return ruleResponse(*iv.rule, engineapi.ImageVerify, msg, engineapi.RuleStatusError), ""
}
if len(imageVerify.Attestors) > 0 {
@ -344,7 +344,7 @@ func (iv *imageVerifier) verifyImage(
}
ruleResp, cosignResp := iv.verifyAttestors(ctx, imageVerify.Attestors, imageVerify, imageInfo, "")
if ruleResp.Status != response.RuleStatusPass {
if ruleResp.Status != engineapi.RuleStatusPass {
return ruleResp, ""
}
@ -374,7 +374,7 @@ func (iv *imageVerifier) verifyAttestors(
imageVerify kyvernov1.ImageVerification,
imageInfo apiutils.ImageInfo,
predicateType string,
) (*response.RuleResponse, *cosign.Response) {
) (*engineapi.RuleResponse, *cosign.Response) {
var cosignResponse *cosign.Response
image := imageInfo.String()
@ -390,36 +390,36 @@ func (iv *imageVerifier) verifyAttestors(
}
if cosignResponse == nil {
return ruleError(iv.rule, response.ImageVerify, "invalid response", fmt.Errorf("nil")), nil
return ruleError(iv.rule, engineapi.ImageVerify, "invalid response", fmt.Errorf("nil")), nil
}
msg := fmt.Sprintf("verified image signatures for %s", image)
return ruleResponse(*iv.rule, response.ImageVerify, msg, response.RuleStatusPass), cosignResponse
return ruleResponse(*iv.rule, engineapi.ImageVerify, msg, engineapi.RuleStatusPass), cosignResponse
}
// handle registry network errors as a rule error (instead of a policy failure)
func (iv *imageVerifier) handleRegistryErrors(image string, err error) *response.RuleResponse {
func (iv *imageVerifier) handleRegistryErrors(image string, err error) *engineapi.RuleResponse {
msg := fmt.Sprintf("failed to verify image %s: %s", image, err.Error())
var netErr *net.OpError
if errors.As(err, &netErr) {
return ruleResponse(*iv.rule, response.ImageVerify, msg, response.RuleStatusError)
return ruleResponse(*iv.rule, engineapi.ImageVerify, msg, engineapi.RuleStatusError)
}
return ruleResponse(*iv.rule, response.ImageVerify, msg, response.RuleStatusFail)
return ruleResponse(*iv.rule, engineapi.ImageVerify, msg, engineapi.RuleStatusFail)
}
func (iv *imageVerifier) verifyAttestations(
ctx context.Context,
imageVerify kyvernov1.ImageVerification,
imageInfo apiutils.ImageInfo,
) (*response.RuleResponse, string) {
) (*engineapi.RuleResponse, string) {
image := imageInfo.String()
for i, attestation := range imageVerify.Attestations {
var attestationError error
path := fmt.Sprintf(".attestations[%d]", i)
if attestation.PredicateType == "" {
return ruleResponse(*iv.rule, response.ImageVerify, path+": missing predicateType", response.RuleStatusFail), ""
return ruleResponse(*iv.rule, engineapi.ImageVerify, path+": missing predicateType", engineapi.RuleStatusFail), ""
}
if len(attestation.Attestors) == 0 {
@ -449,7 +449,7 @@ func (iv *imageVerifier) verifyAttestations(
attestationError = iv.verifyAttestation(cosignResp.Statements, attestation, imageInfo)
if attestationError != nil {
attestationError = errors.Wrapf(attestationError, entryPath+subPath)
return ruleResponse(*iv.rule, response.ImageVerify, attestationError.Error(), response.RuleStatusFail), ""
return ruleResponse(*iv.rule, engineapi.ImageVerify, attestationError.Error(), engineapi.RuleStatusFail), ""
}
verifiedCount++
@ -461,7 +461,7 @@ func (iv *imageVerifier) verifyAttestations(
if verifiedCount < requiredCount {
msg := fmt.Sprintf("image attestations verification failed, verifiedCount: %v, requiredCount: %v", verifiedCount, requiredCount)
return ruleResponse(*iv.rule, response.ImageVerify, msg, response.RuleStatusFail), ""
return ruleResponse(*iv.rule, engineapi.ImageVerify, msg, engineapi.RuleStatusFail), ""
}
}
@ -470,7 +470,7 @@ func (iv *imageVerifier) verifyAttestations(
msg := fmt.Sprintf("verified image attestations for %s", image)
iv.logger.V(2).Info(msg)
return ruleResponse(*iv.rule, response.ImageVerify, msg, response.RuleStatusPass), imageInfo.Digest
return ruleResponse(*iv.rule, engineapi.ImageVerify, msg, engineapi.RuleStatusPass), imageInfo.Digest
}
func (iv *imageVerifier) verifyAttestorSet(

View file

@ -9,14 +9,14 @@ import (
gojmespath "github.com/jmespath/go-jmespath"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/registryclient"
apiutils "github.com/kyverno/kyverno/pkg/utils/api"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func processImageValidationRule(ctx context.Context, log logr.Logger, rclient registryclient.Client, enginectx *PolicyContext, rule *kyvernov1.Rule, cfg config.Configuration) *response.RuleResponse {
func processImageValidationRule(ctx context.Context, log logr.Logger, rclient registryclient.Client, enginectx *PolicyContext, rule *kyvernov1.Rule, cfg config.Configuration) *engineapi.RuleResponse {
if isDeleteRequest(enginectx) {
return nil
}
@ -24,10 +24,10 @@ func processImageValidationRule(ctx context.Context, log logr.Logger, rclient re
log = log.WithValues("rule", rule.Name)
matchingImages, _, err := extractMatchingImages(enginectx, rule, cfg)
if err != nil {
return ruleResponse(*rule, response.Validation, err.Error(), response.RuleStatusError)
return ruleResponse(*rule, engineapi.Validation, err.Error(), engineapi.RuleStatusError)
}
if len(matchingImages) == 0 {
return ruleResponse(*rule, response.Validation, "image verified", response.RuleStatusSkip)
return ruleResponse(*rule, engineapi.Validation, "image verified", engineapi.RuleStatusSkip)
}
if err := LoadContext(ctx, log, rclient, rule.Context, enginectx, rule.Name); err != nil {
if _, ok := err.(gojmespath.NotFoundError); ok {
@ -36,12 +36,12 @@ func processImageValidationRule(ctx context.Context, log logr.Logger, rclient re
log.Error(err, "failed to load context")
}
return ruleError(rule, response.Validation, "failed to load context", err)
return ruleError(rule, engineapi.Validation, "failed to load context", err)
}
preconditionsPassed, err := checkPreconditions(log, enginectx, rule.RawAnyAllConditions)
if err != nil {
return ruleError(rule, response.Validation, "failed to evaluate preconditions", err)
return ruleError(rule, engineapi.Validation, "failed to evaluate preconditions", err)
}
if !preconditionsPassed {
@ -49,7 +49,7 @@ func processImageValidationRule(ctx context.Context, log logr.Logger, rclient re
return nil
}
return ruleResponse(*rule, response.Validation, "preconditions not met", response.RuleStatusSkip)
return ruleResponse(*rule, engineapi.Validation, "preconditions not met", engineapi.RuleStatusSkip)
}
for _, v := range rule.VerifyImages {
@ -66,14 +66,14 @@ func processImageValidationRule(ctx context.Context, log logr.Logger, rclient re
log.V(4).Info("validating image", "image", image)
if err := validateImage(enginectx, imageVerify, name, imageInfo, log); err != nil {
return ruleResponse(*rule, response.ImageVerify, err.Error(), response.RuleStatusFail)
return ruleResponse(*rule, engineapi.ImageVerify, err.Error(), engineapi.RuleStatusFail)
}
}
}
}
log.V(4).Info("validated image", "rule", rule.Name)
return ruleResponse(*rule, response.Validation, "image verified", response.RuleStatusPass)
return ruleResponse(*rule, engineapi.Validation, "image verified", engineapi.RuleStatusPass)
}
func validateImage(ctx *PolicyContext, imageVerify *kyvernov1.ImageVerification, name string, imageInfo apiutils.ImageInfo, log logr.Logger) error {

View file

@ -10,9 +10,9 @@ import (
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/cosign"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/context/resolvers"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/registryclient"
@ -167,9 +167,9 @@ func Test_CosignMockAttest(t *testing.T) {
er, ivm := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusPass,
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass,
fmt.Sprintf("expected: %v, got: %v, failure: %v",
response.RuleStatusPass, er.PolicyResponse.Rules[0].Status, er.PolicyResponse.Rules[0].Message))
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)
}
@ -181,7 +181,7 @@ func Test_CosignMockAttest_fail(t *testing.T) {
er, _ := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusFail)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
}
func buildContext(t *testing.T, policy, resource string, oldResource string) *PolicyContext {
@ -430,7 +430,7 @@ func Test_ConfigMapMissingSuccess(t *testing.T) {
cosign.ClearMock()
err, _ := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusSkip, err.PolicyResponse.Rules[0].Message)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, engineapi.RuleStatusSkip, err.PolicyResponse.Rules[0].Message)
}
func Test_ConfigMapMissingFailure(t *testing.T) {
@ -442,7 +442,7 @@ func Test_ConfigMapMissingFailure(t *testing.T) {
cosign.ClearMock()
resp, _ := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(resp.PolicyResponse.Rules), 1)
assert.Equal(t, resp.PolicyResponse.Rules[0].Status, response.RuleStatusError, resp.PolicyResponse.Rules[0].Message)
assert.Equal(t, resp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusError, resp.PolicyResponse.Rules[0].Message)
}
func Test_SignatureGoodSigned(t *testing.T) {
@ -451,7 +451,7 @@ func Test_SignatureGoodSigned(t *testing.T) {
cosign.ClearMock()
engineResp, _ := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(engineResp.PolicyResponse.Rules), 1)
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, response.RuleStatusPass, engineResp.PolicyResponse.Rules[0].Message)
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)
patch := engineResp.PolicyResponse.Rules[0].Patches[0]
assert.Equal(t, string(patch), "{\"op\":\"replace\",\"path\":\"/spec/containers/0/image\",\"value\":\"ghcr.io/kyverno/test-verify-image:signed@sha256:b31bfb4d0213f254d361e0079deaaebefa4f82ba7aa76ef82e90b4935ad5b105\"}")
@ -463,7 +463,7 @@ func Test_SignatureUnsigned(t *testing.T) {
policyContext := buildContext(t, testSampleSingleKeyPolicy, unsigned, "")
engineResp, _ := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(engineResp.PolicyResponse.Rules), 1)
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, response.RuleStatusFail, engineResp.PolicyResponse.Rules[0].Message)
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail, engineResp.PolicyResponse.Rules[0].Message)
}
func Test_SignatureWrongKey(t *testing.T) {
@ -472,7 +472,7 @@ func Test_SignatureWrongKey(t *testing.T) {
policyContext := buildContext(t, testSampleSingleKeyPolicy, otherKey, "")
engineResp, _ := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(engineResp.PolicyResponse.Rules), 1)
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, response.RuleStatusFail, engineResp.PolicyResponse.Rules[0].Message)
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail, engineResp.PolicyResponse.Rules[0].Message)
}
func Test_SignaturesMultiKey(t *testing.T) {
@ -483,7 +483,7 @@ func Test_SignaturesMultiKey(t *testing.T) {
policyContext := buildContext(t, policy, testSampleResource, "")
engineResp, _ := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(engineResp.PolicyResponse.Rules), 1)
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, response.RuleStatusPass, engineResp.PolicyResponse.Rules[0].Message)
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass, engineResp.PolicyResponse.Rules[0].Message)
}
func Test_SignaturesMultiKeyFail(t *testing.T) {
@ -493,7 +493,7 @@ func Test_SignaturesMultiKeyFail(t *testing.T) {
policyContext := buildContext(t, policy, testSampleResource, "")
engineResp, _ := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(engineResp.PolicyResponse.Rules), 1)
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, response.RuleStatusFail, engineResp.PolicyResponse.Rules[0].Message)
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail, engineResp.PolicyResponse.Rules[0].Message)
}
func Test_SignaturesMultiKeyOneGoodKey(t *testing.T) {
@ -504,7 +504,7 @@ func Test_SignaturesMultiKeyOneGoodKey(t *testing.T) {
policyContext := buildContext(t, policy, testSampleResource, "")
engineResp, _ := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(engineResp.PolicyResponse.Rules), 1)
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, response.RuleStatusPass, engineResp.PolicyResponse.Rules[0].Message)
assert.Equal(t, engineResp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass, engineResp.PolicyResponse.Rules[0].Message)
}
func Test_SignaturesMultiKeyZeroGoodKey(t *testing.T) {
@ -515,7 +515,7 @@ func Test_SignaturesMultiKeyZeroGoodKey(t *testing.T) {
policyContext := buildContext(t, policy, testSampleResource, "")
resp, _ := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(resp.PolicyResponse.Rules), 1)
assert.Equal(t, resp.PolicyResponse.Rules[0].Status, response.RuleStatusFail, resp.PolicyResponse.Rules[0].Message)
assert.Equal(t, resp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail, resp.PolicyResponse.Rules[0].Message)
}
func Test_RuleSelectorImageVerify(t *testing.T) {
@ -531,14 +531,14 @@ func Test_RuleSelectorImageVerify(t *testing.T) {
resp, _ := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(resp.PolicyResponse.Rules), 2)
assert.Equal(t, resp.PolicyResponse.Rules[0].Status, response.RuleStatusPass, resp.PolicyResponse.Rules[0].Message)
assert.Equal(t, resp.PolicyResponse.Rules[1].Status, response.RuleStatusFail, resp.PolicyResponse.Rules[1].Message)
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, _ = VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(resp.PolicyResponse.Rules), 1)
assert.Equal(t, resp.PolicyResponse.Rules[0].Status, response.RuleStatusPass, resp.PolicyResponse.Rules[0].Message)
assert.Equal(t, resp.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass, resp.PolicyResponse.Rules[0].Message)
}
func newStaticKeyRule(name, imageReference, key string) *kyverno.Rule {
@ -642,7 +642,7 @@ func Test_NestedAttestors(t *testing.T) {
policyContext := buildContext(t, policy, testSampleResource, "")
err, _ := VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
policy = strings.Replace(testNestedAttestorPolicy, "KEY1", testVerifyImageKey, -1)
policy = strings.Replace(policy, "KEY2", testOtherKey, -1)
@ -650,7 +650,7 @@ func Test_NestedAttestors(t *testing.T) {
policyContext = buildContext(t, policy, testSampleResource, "")
err, _ = VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusFail)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
policy = strings.Replace(testNestedAttestorPolicy, "KEY1", testVerifyImageKey, -1)
policy = strings.Replace(policy, "KEY2", testOtherKey, -1)
@ -658,7 +658,7 @@ func Test_NestedAttestors(t *testing.T) {
policyContext = buildContext(t, policy, testSampleResource, "")
err, _ = VerifyAndPatchImages(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(err.PolicyResponse.Rules), 1)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
assert.Equal(t, err.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
}
func Test_ExpandKeys(t *testing.T) {
@ -752,7 +752,7 @@ func Test_MarkImageVerified(t *testing.T) {
engineResponse, verifiedImages := VerifyAndPatchImages(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, response.RuleStatusPass)
assert.Equal(t, engineResponse.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
assert.Assert(t, verifiedImages != nil)
assert.Assert(t, verifiedImages.Data != nil)
@ -845,7 +845,7 @@ func Test_ParsePEMDelimited(t *testing.T) {
engineResponse, verifiedImages := VerifyAndPatchImages(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, response.RuleStatusPass)
assert.Equal(t, engineResponse.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
assert.Assert(t, verifiedImages != nil)
assert.Assert(t, verifiedImages.Data != nil)

View file

@ -19,7 +19,7 @@ import (
"github.com/kyverno/kyverno/pkg/auth"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/pkg/errors"
"github.com/sigstore/k8s-manifest-sigstore/pkg/k8smanifest"
"go.uber.org/multierr"
@ -35,7 +35,7 @@ const (
//go:embed resources/default-config.yaml
var defaultConfigBytes []byte
func processYAMLValidationRule(log logr.Logger, ctx *PolicyContext, rule *kyvernov1.Rule) *response.RuleResponse {
func processYAMLValidationRule(log logr.Logger, ctx *PolicyContext, rule *kyvernov1.Rule) *engineapi.RuleResponse {
if isDeleteRequest(ctx) {
return nil
}
@ -43,17 +43,17 @@ func processYAMLValidationRule(log logr.Logger, ctx *PolicyContext, rule *kyvern
return ruleResp
}
func handleVerifyManifest(ctx *PolicyContext, rule *kyvernov1.Rule, logger logr.Logger) *response.RuleResponse {
func handleVerifyManifest(ctx *PolicyContext, rule *kyvernov1.Rule, logger logr.Logger) *engineapi.RuleResponse {
verified, reason, err := verifyManifest(ctx, *rule.Validation.Manifests, logger)
if err != nil {
logger.V(3).Info("verifyManifest return err", "error", err.Error())
return ruleError(rule, response.Validation, "error occurred during manifest verification", err)
return ruleError(rule, engineapi.Validation, "error occurred during manifest verification", err)
}
logger.V(3).Info("verifyManifest result", "verified", strconv.FormatBool(verified), "reason", reason)
if !verified {
return ruleResponse(*rule, response.Validation, reason, response.RuleStatusFail)
return ruleResponse(*rule, engineapi.Validation, reason, engineapi.RuleStatusFail)
}
return ruleResponse(*rule, response.Validation, reason, response.RuleStatusPass)
return ruleResponse(*rule, engineapi.Validation, reason, engineapi.RuleStatusPass)
}
func verifyManifest(policyContext *PolicyContext, verifyRule kyvernov1.Manifests, logger logr.Logger) (bool, string, error) {

View file

@ -6,9 +6,9 @@ import (
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/mutate/patch"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/variables"
datautils "github.com/kyverno/kyverno/pkg/utils/data"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
@ -16,17 +16,17 @@ import (
)
type Response struct {
Status response.RuleStatus
Status engineapi.RuleStatus
PatchedResource unstructured.Unstructured
Patches [][]byte
Message string
}
func NewErrorResponse(msg string, err error) *Response {
return NewResponse(response.RuleStatusError, unstructured.Unstructured{}, nil, fmt.Sprintf("%s: %v", msg, err))
return NewResponse(engineapi.RuleStatusError, unstructured.Unstructured{}, nil, fmt.Sprintf("%s: %v", msg, err))
}
func NewResponse(status response.RuleStatus, resource unstructured.Unstructured, patches [][]byte, msg string) *Response {
func NewResponse(status engineapi.RuleStatus, resource unstructured.Unstructured, patches [][]byte, msg string) *Response {
return &Response{
Status: status,
PatchedResource: resource,
@ -44,16 +44,16 @@ func Mutate(rule *kyvernov1.Rule, ctx context.Interface, resource unstructured.U
m := updatedRule.Mutation
patcher := NewPatcher(updatedRule.Name, m.GetPatchStrategicMerge(), m.PatchesJSON6902, resource, ctx, logger)
if patcher == nil {
return NewResponse(response.RuleStatusError, resource, nil, "empty mutate rule")
return NewResponse(engineapi.RuleStatusError, resource, nil, "empty mutate rule")
}
resp, patchedResource := patcher.Patch()
if resp.Status != response.RuleStatusPass {
if resp.Status != engineapi.RuleStatusPass {
return NewResponse(resp.Status, resource, nil, resp.Message)
}
if resp.Patches == nil {
return NewResponse(response.RuleStatusSkip, resource, nil, "no patches applied")
return NewResponse(engineapi.RuleStatusSkip, resource, nil, "no patches applied")
}
if rule.IsMutateExisting() {
@ -66,7 +66,7 @@ func Mutate(rule *kyvernov1.Rule, ctx context.Interface, resource unstructured.U
}
}
return NewResponse(response.RuleStatusPass, patchedResource, resp.Patches, resp.Message)
return NewResponse(engineapi.RuleStatusPass, patchedResource, resp.Patches, resp.Message)
}
func ForEach(name string, foreach kyvernov1.ForEachMutation, ctx context.Interface, resource unstructured.Unstructured, logger logr.Logger) *Response {
@ -77,23 +77,23 @@ func ForEach(name string, foreach kyvernov1.ForEachMutation, ctx context.Interfa
patcher := NewPatcher(name, fe.GetPatchStrategicMerge(), fe.PatchesJSON6902, resource, ctx, logger)
if patcher == nil {
return NewResponse(response.RuleStatusError, unstructured.Unstructured{}, nil, "no patches found")
return NewResponse(engineapi.RuleStatusError, unstructured.Unstructured{}, nil, "no patches found")
}
resp, patchedResource := patcher.Patch()
if resp.Status != response.RuleStatusPass {
if resp.Status != engineapi.RuleStatusPass {
return NewResponse(resp.Status, unstructured.Unstructured{}, nil, resp.Message)
}
if resp.Patches == nil {
return NewResponse(response.RuleStatusSkip, unstructured.Unstructured{}, nil, "no patches applied")
return NewResponse(engineapi.RuleStatusSkip, unstructured.Unstructured{}, nil, "no patches applied")
}
if err := ctx.AddResource(patchedResource.Object); err != nil {
return NewErrorResponse("failed to update patched resource in the JSON context", err)
}
return NewResponse(response.RuleStatusPass, patchedResource, resp.Patches, resp.Message)
return NewResponse(engineapi.RuleStatusPass, patchedResource, resp.Patches, resp.Message)
}
func substituteAllInForEach(fe kyvernov1.ForEachMutation, ctx context.Interface, logger logr.Logger) (*kyvernov1.ForEachMutation, error) {

View file

@ -5,8 +5,8 @@ import (
"testing"
types "github.com/kyverno/kyverno/api/kyverno/v1"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/logging"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
"gotest.tools/assert"
@ -46,20 +46,20 @@ const endpointsDocument string = `{
]
}`
func applyPatches(rule *types.Rule, resource unstructured.Unstructured) (*response.RuleResponse, unstructured.Unstructured) {
func applyPatches(rule *types.Rule, resource unstructured.Unstructured) (*engineapi.RuleResponse, unstructured.Unstructured) {
mutateResp := Mutate(rule, context.NewContext(), resource, logging.GlobalLogger())
if mutateResp.Status != response.RuleStatusPass {
return &response.RuleResponse{
Type: response.Mutation,
if mutateResp.Status != engineapi.RuleStatusPass {
return &engineapi.RuleResponse{
Type: engineapi.Mutation,
Status: mutateResp.Status,
Message: mutateResp.Message,
}, resource
}
return &response.RuleResponse{
Type: response.Mutation,
Status: response.RuleStatusPass,
return &engineapi.RuleResponse{
Type: engineapi.Mutation,
Status: engineapi.RuleStatusPass,
Patches: mutateResp.Patches,
}, mutateResp.PatchedResource
}
@ -72,7 +72,7 @@ func TestProcessPatches_EmptyPatches(t *testing.T) {
}
rr, _ := applyPatches(emptyRule, *resourceUnstructured)
assert.Equal(t, rr.Status, response.RuleStatusError)
assert.Equal(t, rr.Status, engineapi.RuleStatusError)
assert.Assert(t, len(rr.Patches) == 0)
}
@ -106,14 +106,14 @@ func makeRuleWithPatches(t *testing.T, patches []jsonPatch) *types.Rule {
func TestProcessPatches_EmptyDocument(t *testing.T) {
rule := makeRuleWithPatch(t, makeAddIsMutatedLabelPatch())
rr, _ := applyPatches(rule, unstructured.Unstructured{})
assert.Equal(t, rr.Status, response.RuleStatusFail)
assert.Equal(t, rr.Status, engineapi.RuleStatusFail)
assert.Assert(t, len(rr.Patches) == 0)
}
func TestProcessPatches_AllEmpty(t *testing.T) {
emptyRule := &types.Rule{}
rr, _ := applyPatches(emptyRule, unstructured.Unstructured{})
assert.Equal(t, rr.Status, response.RuleStatusError)
assert.Equal(t, rr.Status, engineapi.RuleStatusError)
assert.Assert(t, len(rr.Patches) == 0)
}
@ -126,7 +126,7 @@ func TestProcessPatches_AddPathDoesntExist(t *testing.T) {
t.Error(err)
}
rr, _ := applyPatches(rule, *resourceUnstructured)
assert.Equal(t, rr.Status, response.RuleStatusSkip)
assert.Equal(t, rr.Status, engineapi.RuleStatusSkip)
assert.Assert(t, len(rr.Patches) == 0)
}
@ -138,7 +138,7 @@ func TestProcessPatches_RemovePathDoesntExist(t *testing.T) {
t.Error(err)
}
rr, _ := applyPatches(rule, *resourceUnstructured)
assert.Equal(t, rr.Status, response.RuleStatusSkip)
assert.Equal(t, rr.Status, engineapi.RuleStatusSkip)
assert.Assert(t, len(rr.Patches) == 0)
}
@ -151,7 +151,7 @@ func TestProcessPatches_AddAndRemovePathsDontExist_EmptyResult(t *testing.T) {
t.Error(err)
}
rr, _ := applyPatches(rule, *resourceUnstructured)
assert.Equal(t, rr.Status, response.RuleStatusPass)
assert.Equal(t, rr.Status, engineapi.RuleStatusPass)
assert.Equal(t, len(rr.Patches), 1)
}
@ -166,7 +166,7 @@ func TestProcessPatches_AddAndRemovePathsDontExist_ContinueOnError_NotEmptyResul
}
rr, _ := applyPatches(rule, *resourceUnstructured)
assert.Equal(t, rr.Status, response.RuleStatusPass)
assert.Equal(t, rr.Status, engineapi.RuleStatusPass)
assert.Assert(t, len(rr.Patches) != 0)
assertEqStringAndData(t, `{"path":"/metadata/labels/label3","op":"add","value":"label3Value"}`, rr.Patches[0])
}
@ -179,7 +179,7 @@ func TestProcessPatches_RemovePathDoesntExist_EmptyResult(t *testing.T) {
t.Error(err)
}
rr, _ := applyPatches(rule, *resourceUnstructured)
assert.Equal(t, rr.Status, response.RuleStatusSkip)
assert.Equal(t, rr.Status, engineapi.RuleStatusSkip)
assert.Assert(t, len(rr.Patches) == 0)
}
@ -192,7 +192,7 @@ func TestProcessPatches_RemovePathDoesntExist_NotEmptyResult(t *testing.T) {
t.Error(err)
}
rr, _ := applyPatches(rule, *resourceUnstructured)
assert.Equal(t, rr.Status, response.RuleStatusPass)
assert.Equal(t, rr.Status, engineapi.RuleStatusPass)
assert.Assert(t, len(rr.Patches) == 1)
assertEqStringAndData(t, `{"path":"/metadata/labels/label2","op":"add","value":"label2Value"}`, rr.Patches[0])
}

View file

@ -6,18 +6,18 @@ import (
jsonpatch "github.com/evanphx/json-patch/v5"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/yaml"
)
// ProcessPatchJSON6902 ...
func ProcessPatchJSON6902(ruleName string, patchesJSON6902 []byte, resource unstructured.Unstructured, log logr.Logger) (resp response.RuleResponse, patchedResource unstructured.Unstructured) {
func ProcessPatchJSON6902(ruleName string, patchesJSON6902 []byte, resource unstructured.Unstructured, log logr.Logger) (resp engineapi.RuleResponse, patchedResource unstructured.Unstructured) {
logger := log.WithValues("rule", ruleName)
startTime := time.Now()
logger.V(4).Info("started JSON6902 patch", "startTime", startTime)
resp.Name = ruleName
resp.Type = response.Mutation
resp.Type = engineapi.Mutation
defer func() {
resp.RuleStats.ProcessingTime = time.Since(startTime)
resp.RuleStats.RuleExecutionTimestamp = startTime.Unix()
@ -26,7 +26,7 @@ func ProcessPatchJSON6902(ruleName string, patchesJSON6902 []byte, resource unst
resourceRaw, err := resource.MarshalJSON()
if err != nil {
resp.Status = response.RuleStatusFail
resp.Status = engineapi.RuleStatusFail
logger.Error(err, "failed to marshal resource")
resp.Message = fmt.Sprintf("failed to marshal resource: %v", err)
return resp, resource
@ -34,7 +34,7 @@ func ProcessPatchJSON6902(ruleName string, patchesJSON6902 []byte, resource unst
patchedResourceRaw, err := applyPatchesWithOptions(resourceRaw, patchesJSON6902)
if err != nil {
resp.Status = response.RuleStatusFail
resp.Status = engineapi.RuleStatusFail
logger.Error(err, "failed to apply JSON Patch")
resp.Message = fmt.Sprintf("failed to apply JSON Patch: %v", err)
return resp, resource
@ -42,7 +42,7 @@ func ProcessPatchJSON6902(ruleName string, patchesJSON6902 []byte, resource unst
patchesBytes, err := generatePatches(resourceRaw, patchedResourceRaw)
if err != nil {
resp.Status = response.RuleStatusFail
resp.Status = engineapi.RuleStatusFail
logger.Error(err, "unable generate patch bytes from base and patched document, apply patchesJSON6902 directly")
resp.Message = fmt.Sprintf("unable generate patch bytes from base and patched document, apply patchesJSON6902 directly: %v", err)
return resp, resource
@ -55,12 +55,12 @@ func ProcessPatchJSON6902(ruleName string, patchesJSON6902 []byte, resource unst
err = patchedResource.UnmarshalJSON(patchedResourceRaw)
if err != nil {
logger.Error(err, "failed to unmarshal resource")
resp.Status = response.RuleStatusFail
resp.Status = engineapi.RuleStatusFail
resp.Message = fmt.Sprintf("failed to unmarshal resource: %v", err)
return resp, resource
}
resp.Status = response.RuleStatusPass
resp.Status = engineapi.RuleStatusPass
resp.Message = string("applied JSON Patch")
resp.Patches = patchesBytes
return resp, patchedResource

View file

@ -4,9 +4,8 @@ import (
"fmt"
"testing"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/ghodss/yaml"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/logging"
assert "github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@ -52,7 +51,7 @@ func TestTypeConversion(t *testing.T) {
assert.Nil(t, err)
// apply patches
resp, _ := ProcessPatchJSON6902("type-conversion", jsonPatches, resource, logging.GlobalLogger())
if !assert.Equal(t, response.RuleStatusPass, resp.Status) {
if !assert.Equal(t, engineapi.RuleStatusPass, resp.Status) {
t.Fatal(resp.Message)
}

View file

@ -2,15 +2,15 @@ package patch
import (
"github.com/go-logr/logr"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/response"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
// Patcher patches the resource
type Patcher interface {
Patch() (resp response.RuleResponse, newPatchedResource unstructured.Unstructured)
Patch() (resp engineapi.RuleResponse, newPatchedResource unstructured.Unstructured)
}
// patchStrategicMergeHandler
@ -32,7 +32,7 @@ func NewPatchStrategicMerge(ruleName string, patch apiextensions.JSON, patchedRe
}
}
func (h patchStrategicMergeHandler) Patch() (response.RuleResponse, unstructured.Unstructured) {
func (h patchStrategicMergeHandler) Patch() (engineapi.RuleResponse, unstructured.Unstructured) {
return ProcessStrategicMergePatch(h.ruleName, h.patch, h.patchedResource, h.logger)
}
@ -53,13 +53,13 @@ func NewPatchesJSON6902(ruleName string, patches string, patchedResource unstruc
}
}
func (h patchesJSON6902Handler) Patch() (resp response.RuleResponse, patchedResource unstructured.Unstructured) {
func (h patchesJSON6902Handler) Patch() (resp engineapi.RuleResponse, patchedResource unstructured.Unstructured) {
resp.Name = h.ruleName
resp.Type = response.Mutation
resp.Type = engineapi.Mutation
patchesJSON6902, err := ConvertPatchesToJSON(h.patches)
if err != nil {
resp.Status = response.RuleStatusFail
resp.Status = engineapi.RuleStatusFail
h.logger.Error(err, "error in type conversion")
resp.Message = err.Error()
return resp, unstructured.Unstructured{}

View file

@ -7,7 +7,7 @@ import (
"time"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/kustomize/api/filters/patchstrategicmerge"
filtersutil "sigs.k8s.io/kustomize/kyaml/filtersutil"
@ -15,12 +15,12 @@ import (
)
// ProcessStrategicMergePatch ...
func ProcessStrategicMergePatch(ruleName string, overlay interface{}, resource unstructured.Unstructured, log logr.Logger) (resp response.RuleResponse, patchedResource unstructured.Unstructured) {
func ProcessStrategicMergePatch(ruleName string, overlay interface{}, resource unstructured.Unstructured, log logr.Logger) (resp engineapi.RuleResponse, patchedResource unstructured.Unstructured) {
startTime := time.Now()
logger := log.WithName("ProcessStrategicMergePatch").WithValues("rule", ruleName)
logger.V(4).Info("started applying strategicMerge patch", "startTime", startTime)
resp.Name = ruleName
resp.Type = response.Mutation
resp.Type = engineapi.Mutation
defer func() {
resp.RuleStats.ProcessingTime = time.Since(startTime)
@ -30,7 +30,7 @@ func ProcessStrategicMergePatch(ruleName string, overlay interface{}, resource u
overlayBytes, err := json.Marshal(overlay)
if err != nil {
resp.Status = response.RuleStatusFail
resp.Status = engineapi.RuleStatusFail
logger.Error(err, "failed to marshal resource")
resp.Message = fmt.Sprintf("failed to process patchStrategicMerge: %v", err)
return resp, resource
@ -38,7 +38,7 @@ func ProcessStrategicMergePatch(ruleName string, overlay interface{}, resource u
base, err := json.Marshal(resource.Object)
if err != nil {
resp.Status = response.RuleStatusFail
resp.Status = engineapi.RuleStatusFail
logger.Error(err, "failed to marshal resource")
resp.Message = fmt.Sprintf("failed to process patchStrategicMerge: %v", err)
return resp, resource
@ -47,7 +47,7 @@ func ProcessStrategicMergePatch(ruleName string, overlay interface{}, resource u
if err != nil {
log.Error(err, "failed to apply patchStrategicMerge")
msg := fmt.Sprintf("failed to apply patchStrategicMerge: %v", err)
resp.Status = response.RuleStatusFail
resp.Status = engineapi.RuleStatusFail
resp.Message = msg
return resp, resource
}
@ -55,7 +55,7 @@ func ProcessStrategicMergePatch(ruleName string, overlay interface{}, resource u
err = patchedResource.UnmarshalJSON(patchedBytes)
if err != nil {
logger.Error(err, "failed to unmarshal resource")
resp.Status = response.RuleStatusFail
resp.Status = engineapi.RuleStatusFail
resp.Message = fmt.Sprintf("failed to process patchStrategicMerge: %v", err)
return resp, resource
}
@ -65,7 +65,7 @@ func ProcessStrategicMergePatch(ruleName string, overlay interface{}, resource u
jsonPatches, err := generatePatches(base, patchedBytes)
if err != nil {
msg := fmt.Sprintf("failed to generated JSON patches from patched resource: %v", err.Error())
resp.Status = response.RuleStatusFail
resp.Status = engineapi.RuleStatusFail
log.V(2).Info(msg)
resp.Message = msg
return resp, patchedResource
@ -75,7 +75,7 @@ func ProcessStrategicMergePatch(ruleName string, overlay interface{}, resource u
log.V(5).Info("generated patch", "patch", string(p))
}
resp.Status = response.RuleStatusPass
resp.Status = engineapi.RuleStatusPass
resp.Patches = jsonPatches
resp.Message = "applied strategic merge patch"
return resp, patchedResource

View file

@ -11,8 +11,8 @@ import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store"
"github.com/kyverno/kyverno/pkg/autogen"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/mutate"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/registryclient"
"github.com/kyverno/kyverno/pkg/tracing"
@ -23,10 +23,10 @@ import (
)
// Mutate performs mutation. Overlay first and then mutation patches
func Mutate(ctx context.Context, rclient registryclient.Client, policyContext *PolicyContext) (resp *response.EngineResponse) {
func Mutate(ctx context.Context, rclient registryclient.Client, policyContext *PolicyContext) (resp *engineapi.EngineResponse) {
startTime := time.Now()
policy := policyContext.policy
resp = &response.EngineResponse{
resp = &engineapi.EngineResponse{
Policy: policy,
}
matchedResource := policyContext.newResource
@ -104,7 +104,7 @@ func Mutate(ctx context.Context, rclient registryclient.Client, policyContext *P
if !policyContext.admissionOperation && rule.IsMutateExisting() {
targets, err := loadTargets(ruleCopy.Mutation.Targets, policyContext, logger)
if err != nil {
rr := ruleResponse(rule, response.Mutation, err.Error(), response.RuleStatusError)
rr := ruleResponse(rule, engineapi.Mutation, err.Error(), engineapi.RuleStatusError)
resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, *rr)
} else {
patchedResources = append(patchedResources, targets...)
@ -157,7 +157,7 @@ func Mutate(ctx context.Context, rclient registryclient.Client, policyContext *P
if ruleResponse != nil {
resp.PolicyResponse.Rules = append(resp.PolicyResponse.Rules, *ruleResponse)
if ruleResponse.Status == response.RuleStatusError {
if ruleResponse.Status == engineapi.RuleStatusError {
incrementErrorCount(resp)
} else {
incrementAppliedCount(resp)
@ -174,7 +174,7 @@ func Mutate(ctx context.Context, rclient registryclient.Client, policyContext *P
for _, r := range resp.PolicyResponse.Rules {
for _, n := range skippedRules {
if r.Name == n {
r.Status = response.RuleStatusSkip
r.Status = engineapi.RuleStatusSkip
logger.V(4).Info("rule Status set as skip", "rule skippedRules", r.Name)
}
}
@ -191,7 +191,7 @@ func mutateResource(rule *kyvernov1.Rule, ctx *PolicyContext, resource unstructu
}
if !preconditionsPassed {
return mutate.NewResponse(response.RuleStatusSkip, resource, nil, "preconditions not met")
return mutate.NewResponse(engineapi.RuleStatusSkip, resource, nil, "preconditions not met")
}
return mutate.Mutate(rule, ctx.JSONContext(), resource, logger)
@ -223,7 +223,7 @@ func (f *forEachMutator) mutateForEach(ctx context.Context) *mutate.Response {
}
if !preconditionsPassed {
return mutate.NewResponse(response.RuleStatusSkip, f.resource.unstructured, nil, "preconditions not met")
return mutate.NewResponse(engineapi.RuleStatusSkip, f.resource.unstructured, nil, "preconditions not met")
}
elements, err := evaluateList(foreach.List, f.policyContext.JSONContext())
@ -233,11 +233,11 @@ func (f *forEachMutator) mutateForEach(ctx context.Context) *mutate.Response {
}
mutateResp := f.mutateElements(ctx, foreach, elements)
if mutateResp.Status == response.RuleStatusError {
if mutateResp.Status == engineapi.RuleStatusError {
return mutate.NewErrorResponse("failed to mutate elements", err)
}
if mutateResp.Status != response.RuleStatusSkip {
if mutateResp.Status != engineapi.RuleStatusSkip {
applyCount++
if len(mutateResp.Patches) > 0 {
f.resource.unstructured = mutateResp.PatchedResource
@ -248,10 +248,10 @@ func (f *forEachMutator) mutateForEach(ctx context.Context) *mutate.Response {
msg := fmt.Sprintf("%d elements processed", applyCount)
if applyCount == 0 {
return mutate.NewResponse(response.RuleStatusSkip, f.resource.unstructured, allPatches, msg)
return mutate.NewResponse(engineapi.RuleStatusSkip, f.resource.unstructured, allPatches, msg)
}
return mutate.NewResponse(response.RuleStatusPass, f.resource.unstructured, allPatches, msg)
return mutate.NewResponse(engineapi.RuleStatusPass, f.resource.unstructured, allPatches, msg)
}
func (f *forEachMutator) mutateElements(ctx context.Context, foreach kyvernov1.ForEachMutation, elements []interface{}) *mutate.Response {
@ -315,7 +315,7 @@ func (f *forEachMutator) mutateElements(ctx context.Context, foreach kyvernov1.F
mutateResp = mutate.ForEach(f.rule.Name, foreach, policyContext.JSONContext(), patchedResource.unstructured, f.log)
}
if mutateResp.Status == response.RuleStatusFail || mutateResp.Status == response.RuleStatusError {
if mutateResp.Status == engineapi.RuleStatusFail || mutateResp.Status == engineapi.RuleStatusError {
return mutateResp
}
@ -325,12 +325,12 @@ func (f *forEachMutator) mutateElements(ctx context.Context, foreach kyvernov1.F
}
}
return mutate.NewResponse(response.RuleStatusPass, patchedResource.unstructured, allPatches, "")
return mutate.NewResponse(engineapi.RuleStatusPass, patchedResource.unstructured, allPatches, "")
}
func buildRuleResponse(rule *kyvernov1.Rule, mutateResp *mutate.Response, info resourceInfo) *response.RuleResponse {
resp := ruleResponse(*rule, response.Mutation, mutateResp.Message, mutateResp.Status)
if resp.Status == response.RuleStatusPass {
func buildRuleResponse(rule *kyvernov1.Rule, mutateResp *mutate.Response, info resourceInfo) *engineapi.RuleResponse {
resp := ruleResponse(*rule, engineapi.Mutation, mutateResp.Message, mutateResp.Status)
if resp.Status == engineapi.RuleStatusPass {
resp.Patches = mutateResp.Patches
resp.Message = buildSuccessMessage(mutateResp.PatchedResource)
}
@ -356,7 +356,7 @@ func buildSuccessMessage(r unstructured.Unstructured) string {
return fmt.Sprintf("mutated %s/%s in namespace %s", r.GetKind(), r.GetName(), r.GetNamespace())
}
func startMutateResultResponse(resp *response.EngineResponse, policy kyvernov1.PolicyInterface, resource unstructured.Unstructured) {
func startMutateResultResponse(resp *engineapi.EngineResponse, policy kyvernov1.PolicyInterface, resource unstructured.Unstructured) {
if resp == nil {
return
}
@ -369,7 +369,7 @@ func startMutateResultResponse(resp *response.EngineResponse, policy kyvernov1.P
resp.PolicyResponse.Resource.APIVersion = resource.GetAPIVersion()
}
func endMutateResultResponse(logger logr.Logger, resp *response.EngineResponse, startTime time.Time) {
func endMutateResultResponse(logger logr.Logger, resp *engineapi.EngineResponse, startTime time.Time) {
if resp == nil {
return
}

View file

@ -10,8 +10,8 @@ import (
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store"
client "github.com/kyverno/kyverno/pkg/clients/dclient"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/registryclient"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
"gotest.tools/assert"
@ -657,7 +657,7 @@ func Test_foreach(t *testing.T) {
er := Mutate(context.TODO(), registryclient.NewOrDie(), policyContext)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
assert.NilError(t, err)
@ -764,7 +764,7 @@ func Test_foreach_element_mutation(t *testing.T) {
er := Mutate(context.TODO(), registryclient.NewOrDie(), policyContext)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
assert.NilError(t, err)
@ -890,7 +890,7 @@ func Test_Container_InitContainer_foreach(t *testing.T) {
er := Mutate(context.TODO(), registryclient.NewOrDie(), policyContext)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
assert.NilError(t, err)
@ -995,7 +995,7 @@ func Test_foreach_order_mutation_(t *testing.T) {
er := testApplyPolicyToResource(t, policyRaw, resourceRaw)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
containers, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "containers")
assert.NilError(t, err)
@ -1013,7 +1013,7 @@ func Test_foreach_order_mutation_(t *testing.T) {
}
}
func testApplyPolicyToResource(t *testing.T, policyRaw, resourceRaw []byte) *response.EngineResponse {
func testApplyPolicyToResource(t *testing.T, policyRaw, resourceRaw []byte) *engineapi.EngineResponse {
var policy kyverno.ClusterPolicy
err := json.Unmarshal(policyRaw, &policy)
assert.NilError(t, err)
@ -1148,7 +1148,7 @@ func Test_mutate_nested_foreach(t *testing.T) {
er := testApplyPolicyToResource(t, policyRaw, resourceRaw)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusPass)
assert.Equal(t, len(er.PolicyResponse.Rules[0].Patches), 2)
tlsArr, _, err := unstructured.NestedSlice(er.PatchedResource.Object, "spec", "tls")
@ -1593,7 +1593,7 @@ func Test_mutate_existing_resources(t *testing.T) {
for _, rr := range er.PolicyResponse.Rules {
for i, p := range rr.Patches {
assert.Equal(t, test.patches[i], string(p), "test %s failed:\nGot %s\nExpected: %s", test.name, rr.Patches[i], test.patches[i])
assert.Equal(t, rr.Status, response.RuleStatusPass, rr.Status)
assert.Equal(t, rr.Status, engineapi.RuleStatusPass, rr.Status)
}
}
}

View file

@ -1,97 +0,0 @@
package response
import (
"encoding/json"
"fmt"
"strings"
)
// RuleStatus represents the status of rule execution
type RuleStatus int
// RuleStatusPass is used to report the result of processing a rule.
const (
// RuleStatusPass indicates that the resources meets the policy rule requirements
RuleStatusPass RuleStatus = iota
// RuleStatusFail indicates that the resource does not meet the policy rule requirements
RuleStatusFail
// RuleStatusWarn indicates that the resource does not meet the policy rule requirements, but the policy is not scored
RuleStatusWarn
// RuleStatusError indicates that the policy rule could not be evaluated due to a processing error, for
// example when a variable cannot be resolved in the policy rule definition. Note that variables
// that cannot be resolved in preconditions are replaced with empty values to allow existence
// checks.
RuleStatusError
// RuleStatusSkip indicates that the policy rule was not selected based on user inputs or applicability, for example
// when preconditions are not met, or when conditional or global anchors are not satistied.
RuleStatusSkip
)
func (s *RuleStatus) String() string {
return toString[*s]
}
var toString = map[RuleStatus]string{
RuleStatusPass: "pass",
RuleStatusFail: "fail",
RuleStatusWarn: "warning",
RuleStatusError: "error",
RuleStatusSkip: "skip",
}
var toID = map[string]RuleStatus{
"pass": RuleStatusPass,
"fail": RuleStatusFail,
"warning": RuleStatusWarn,
"error": RuleStatusError,
"skip": RuleStatusSkip,
}
// MarshalJSON marshals the enum as a quoted json string
func (s *RuleStatus) MarshalJSON() ([]byte, error) {
var b strings.Builder
fmt.Fprintf(&b, "\"%s\"", toString[*s])
return []byte(b.String()), nil
}
// UnmarshalJSON unmarshals a quoted json string to the enum value
func (s *RuleStatus) UnmarshalJSON(b []byte) error {
var strVal string
err := json.Unmarshal(b, &strVal)
if err != nil {
return err
}
statusVal, err := getRuleStatus(strVal)
if err != nil {
return err
}
*s = *statusVal
return nil
}
func getRuleStatus(s string) (*RuleStatus, error) {
for k, v := range toID {
if s == k {
return &v, nil
}
}
return nil, fmt.Errorf("invalid status: %s", s)
}
func (s *RuleStatus) UnmarshalYAML(unmarshal func(interface{}) error) error {
var str string
if err := unmarshal(&str); err != nil {
return err
}
statusVal, err := getRuleStatus(str)
if err != nil {
return err
}
*s = *statusVal
return nil
}

View file

@ -10,9 +10,9 @@ import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/common"
"github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/variables"
datautils "github.com/kyverno/kyverno/pkg/utils/data"
matchutils "github.com/kyverno/kyverno/pkg/utils/match"
@ -354,13 +354,13 @@ func evaluateList(jmesPath string, ctx context.EvalInterface) ([]interface{}, er
return l, nil
}
func ruleError(rule *kyvernov1.Rule, ruleType response.RuleType, msg string, err error) *response.RuleResponse {
func ruleError(rule *kyvernov1.Rule, ruleType engineapi.RuleType, msg string, err error) *engineapi.RuleResponse {
msg = fmt.Sprintf("%s: %s", msg, err.Error())
return ruleResponse(*rule, ruleType, msg, response.RuleStatusError)
return ruleResponse(*rule, ruleType, msg, engineapi.RuleStatusError)
}
func ruleResponse(rule kyvernov1.Rule, ruleType response.RuleType, msg string, status response.RuleStatus) *response.RuleResponse {
resp := &response.RuleResponse{
func ruleResponse(rule kyvernov1.Rule, ruleType engineapi.RuleType, msg string, status engineapi.RuleStatus) *engineapi.RuleResponse {
resp := &engineapi.RuleResponse{
Name: rule.Name,
Type: ruleType,
Message: msg,
@ -369,11 +369,11 @@ func ruleResponse(rule kyvernov1.Rule, ruleType response.RuleType, msg string, s
return resp
}
func incrementAppliedCount(resp *response.EngineResponse) {
func incrementAppliedCount(resp *engineapi.EngineResponse) {
resp.PolicyResponse.RulesAppliedCount++
}
func incrementErrorCount(resp *response.EngineResponse) {
func incrementErrorCount(resp *engineapi.EngineResponse) {
resp.PolicyResponse.RulesErrorCount++
}

View file

@ -5,10 +5,8 @@ import (
"fmt"
"testing"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/anchor"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/logging"
"gotest.tools/assert"
@ -1363,259 +1361,259 @@ func TestConditionalAnchorWithMultiplePatterns(t *testing.T) {
name string
pattern []byte
resource []byte
status response.RuleStatus
status engineapi.RuleStatus
}{
{
name: "test-1",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:1.2.3", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusSkip,
status: engineapi.RuleStatusSkip,
},
{
name: "test-2",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-3",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-4",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx", "imagePullPolicy": "Never"}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
{
name: "test-5",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "Never"}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
{
name: "test-6",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:1.2.3", "imagePullPolicy": "Never"}]}}`),
status: response.RuleStatusSkip,
status: engineapi.RuleStatusSkip,
},
{
name: "test-7",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx", "imagePullPolicy": "Always"},{"name": "busybox","image": "busybox:1.28", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-8",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "Always"},{"name": "busybox","image": "busybox:1.28", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-9",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:1.2.3", "imagePullPolicy": "Always"},{"name": "busybox","image": "busybox:1.28", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusSkip,
status: engineapi.RuleStatusSkip,
},
{
name: "test-10",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx", "imagePullPolicy": "Never"},{"name": "busybox","image": "busybox:1.28", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
{
name: "test-11",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "Never"},{"name": "busybox","image": "busybox:1.28", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
{
name: "test-12",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:1.2.3", "imagePullPolicy": "Never"},{"name": "busybox","image": "busybox:1.28", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusSkip,
status: engineapi.RuleStatusSkip,
},
{
name: "test-13",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "busybox","image": "busybox:1.28", "imagePullPolicy": "Always"},{"name": "nginx","image": "nginx", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-14",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "busybox","image": "busybox:1.28", "imagePullPolicy": "Always"},{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-15",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "busybox","image": "busybox:1.28", "imagePullPolicy": "Always"},{"name": "nginx","image": "nginx:1.2.3", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusSkip,
status: engineapi.RuleStatusSkip,
},
{
name: "test-16",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "busybox","image": "busybox:1.28", "imagePullPolicy": "Always"},{"name": "nginx","image": "nginx", "imagePullPolicy": "Never"}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
{
name: "test-17",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "busybox","image": "busybox:1.28", "imagePullPolicy": "Always"},{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "Never"}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
{
name: "test-18",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "busybox","image": "busybox:1.28", "imagePullPolicy": "Always"},{"name": "nginx","image": "nginx:1.2.3", "imagePullPolicy": "Never"}]}}`),
status: response.RuleStatusSkip,
status: engineapi.RuleStatusSkip,
},
{
name: "test-19",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "busybox","image": "busybox", "imagePullPolicy": "Always"},{"name": "nginx","image": "nginx", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-20",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "busybox","image": "busybox:latest", "imagePullPolicy": "Always"},{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-21",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "*:latest | !*:*","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "busybox","image": "busybox:1.2.3", "imagePullPolicy": "Always"},{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "IfNotPresent"}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
{
name: "test-22",
pattern: []byte(`{"spec": {"containers": [{"name": "*","(image)": "!*:* | *:latest","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-23",
pattern: []byte(`{"spec": {"containers": [{"name": "*","<(image)": "*:latest","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-24",
pattern: []byte(`{"spec": {"containers": [{"name": "*","<(image)": "*:latest","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-25",
pattern: []byte(`{"spec": {"containers": [{"name": "*","<(image)": "nginx", "env": [{"<(name)": "foo", "<(value)": "bar" }],"imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx", "env": [{"name": "foo1", "value": "bar" }],"imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-26",
pattern: []byte(`{"spec": {"containers": [{"name": "*","<(image)": "nginx", "env": [{"<(name)": "foo", "<(value)": "bar" }],"imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx", "env": [{"name": "foo", "value": "bar" }],"imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-27",
pattern: []byte(`{"spec": {"containers": [{"name": "*", "env": [{"<(name)": "foo", "<(value)": "bar" }],"imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx", "env": [{"name": "foo1", "value": "bar" }],"imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-28",
pattern: []byte(`{"spec": {"containers": [{"name": "*", "env": [{"<(name)": "foo", "<(value)": "bar" }],"imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx", "env": [{"name": "foo", "value": "bar" }],"imagePullPolicy": "IfNotpresent"}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
{
name: "test-29",
pattern: []byte(`{"spec": {"containers": [{"name": "*", "env": [{"<(name)": "foo", "<(value)": "bar" }],"imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx", "env": [{"name": "foo", "value": "bar" }],"imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-30",
pattern: []byte(`{"metadata": {"<(name)": "nginx"},"spec": {"imagePullSecrets": [{"name": "regcred"}]}}`),
resource: []byte(`{"metadata": {"name": "somename"},"spec": {"containers": [{"name": "nginx","image": "nginx:latest"}], "imagePullSecrets": [{"name": "cred"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-31",
pattern: []byte(`{"metadata": {"<(name)": "nginx"},"spec": {"imagePullSecrets": [{"name": "regcred"}]}}`),
resource: []byte(`{"metadata": {"name": "nginx"},"spec": {"containers": [{"name": "nginx","image": "nginx:latest"}], "imagePullSecrets": [{"name": "cred"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-32",
pattern: []byte(`{"metadata": {"labels": {"<(foo)": "bar"}},"spec": {"containers": [{"name": "nginx","image": "!*:latest"}]}}`),
resource: []byte(`{"metadata": {"name": "nginx","labels": {"foo": "bar"}},"spec": {"containers": [{"name": "nginx","image": "nginx"}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
{
name: "test-33",
pattern: []byte(`{"metadata": {"labels": {"<(foo)": "bar"}},"spec": {"containers": [{"name": "nginx","image": "!*:latest"}]}}`),
resource: []byte(`{"metadata": {"name": "nginx","labels": {"foo": "bar"}},"spec": {"containers": [{"name": "nginx","image": "nginx:latest"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-34",
pattern: []byte(`{"spec": {"containers": [{"name": "*","<(image)": "nginx"}],"imagePullSecrets": [{"name": "my-registry-secret"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx"}], "imagePullSecrets": [{"name": "cred"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-35",
pattern: []byte(`{"spec": {"containers": [{"name": "*","<(image)": "nginx"}],"imagePullSecrets": [{"name": "my-registry-secret"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "somepod"}], "imagePullSecrets": [{"name": "cred"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-36",
pattern: []byte(`{"spec": {"containers": [{"name": "*","<(image)": "nginx"}],"imagePullSecrets": [{"name": "my-registry-secret"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx"}], "imagePullSecrets": [{"name": "my-registry-secret"}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
{
name: "test-37",
pattern: []byte(`{"metadata": {"labels": {"allow-docker": "true"}},"(spec)": {"(volumes)": [{"(hostPath)": {"path": "/var/run/docker.sock"}}]}}`),
resource: []byte(`{"metadata": {"labels": {"run": "nginx"},"name": "nginx"},"spec": {"containers": [{"image": "nginx","name": "nginx"}]}}`),
status: response.RuleStatusSkip,
status: engineapi.RuleStatusSkip,
},
{
name: "test-38",
pattern: []byte(`{"metadata": {"labels": {"allow-docker": "true"}},"(spec)": {"(volumes)": [{"(hostPath)": {"path": "/var/run/docker.sock"}}]}}`),
resource: []byte(`{"metadata": {"labels": {"run": "nginx"},"name": "nginx"},"spec": {"containers": [{"image": "nginx","name": "nginx"}],"volumes": [{"hostPath": {"path": "/var/run/docker.sock"}}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-39",
pattern: []byte(`{"metadata": {"labels": {"allow-docker": "true"}},"(spec)": {"(volumes)": [{"(hostPath)": {"path": "/var/run/docker.sock"}}]}}`),
resource: []byte(`{"metadata": {"labels": {"run": "nginx"},"name": "nginx"},"spec": {"containers": [{"image": "nginx","name": "nginx"}],"volumes": [{"hostPath": {"path": "/randome/value"}}]}}`),
status: response.RuleStatusSkip,
status: engineapi.RuleStatusSkip,
},
{
name: "test-40",
pattern: []byte(`{"metadata": {"labels": {"allow-docker": "true"}},"(spec)": {"(volumes)": [{"(hostPath)": {"path": "/var/run/docker.sock"}}]}}`),
resource: []byte(`{"metadata": {"labels": {"run": "nginx","allow-docker": "true"},"name": "nginx"},"spec": {"containers": [{"image": "nginx","name": "nginx"}],"volumes": [{"hostPath": {"path": "/var/run/docker.sock"}}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
{
name: "test-41",
pattern: []byte(`{"metadata": {"labels": {"allow-docker": "true"}},"(spec)": {"(volumes)": [{"(hostPath)": {"path": "/var/run/docker.sock"}}]}}`),
resource: []byte(`{"metadata": {"labels": {"run": "nginx","allow-docker": "false"},"name": "nginx"},"spec": {"containers": [{"image": "nginx","name": "nginx"}],"volumes": [{"hostPath": {"path": "/var/run/docker.sock"}}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "test-42",
pattern: []byte(`{"metadata": {"labels": {"allow-docker": "true"}},"(spec)": {"(volumes)": [{"(hostPath)": {"path": "/var/run/docker.sock"}}]}}`),
resource: []byte(`{"metadata": {"labels": {"run": "nginx"},"name": "nginx"},"spec": {"containers": [{"image": "nginx","name": "nginx"}],"volumes": [{"hostPath": {"path": "/var/run/docker.sock"}}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
}
@ -1629,31 +1627,31 @@ func Test_global_anchor(t *testing.T) {
name string
pattern []byte
resource []byte
status response.RuleStatus
status engineapi.RuleStatus
}{
{
name: "check_global_anchor_skip",
pattern: []byte(`{"spec": {"containers": [{"name": "*","<(image)": "*:latest","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:v1", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusSkip,
status: engineapi.RuleStatusSkip,
},
{
name: "check_global_anchor_fail",
pattern: []byte(`{"spec": {"containers": [{"name": "*","<(image)": "*:latest","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "Always"}]}}`),
status: response.RuleStatusFail,
status: engineapi.RuleStatusFail,
},
{
name: "check_global_anchor_pass",
pattern: []byte(`{"spec": {"containers": [{"name": "*","<(image)": "*:latest","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "IfNotPresent"}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
{
name: "check_global_anchor_mixed",
pattern: []byte(`{"spec": {"containers": [{"name": "*","<(image)": "*:latest","imagePullPolicy": "!Always"}]}}`),
resource: []byte(`{"spec": {"containers": [{"name": "nginx","image": "nginx:latest", "imagePullPolicy": "IfNotPresent"},{"name": "nginx","image": "nginx:v2", "imagePullPolicy": "IfNotPresent"}]}}`),
status: response.RuleStatusPass,
status: engineapi.RuleStatusPass,
},
}
@ -1666,7 +1664,7 @@ func testMatchPattern(t *testing.T, testCase struct {
name string
pattern []byte
resource []byte
status response.RuleStatus
status engineapi.RuleStatus
},
) {
var pattern, resource interface{}
@ -1677,9 +1675,9 @@ func testMatchPattern(t *testing.T, testCase struct {
err = MatchPattern(logging.GlobalLogger(), resource, pattern)
if testCase.status == response.RuleStatusPass {
if testCase.status == engineapi.RuleStatusPass {
assert.NilError(t, err, fmt.Sprintf("\nexpected pass - test: %s\npattern: %s\nresource: %s\n", testCase.name, pattern, resource))
} else if testCase.status == response.RuleStatusSkip {
} else if testCase.status == engineapi.RuleStatusSkip {
assert.Assert(t, err != nil, fmt.Sprintf("\nexpected skip error - test: %s\npattern: %s\nresource: %s\n", testCase.name, pattern, resource))
pe, ok := err.(*PatternError)
if !ok {
@ -1687,7 +1685,7 @@ func testMatchPattern(t *testing.T, testCase struct {
}
assert.Assert(t, pe.Skip, fmt.Sprintf("\nexpected skip == true - test: %s\npattern: %s\nresource: %s\n", testCase.name, pattern, resource))
} else if testCase.status == response.RuleStatusError {
} else if testCase.status == engineapi.RuleStatusError {
assert.Assert(t, err == nil, fmt.Sprintf("\nexpected error - test: %s\npattern: %s\nresource: %s\n", testCase.name, pattern, resource))
}
}

View file

@ -15,8 +15,8 @@ import (
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store"
"github.com/kyverno/kyverno/pkg/autogen"
"github.com/kyverno/kyverno/pkg/config"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/engine/common"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/validate"
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/logging"
@ -38,8 +38,8 @@ import (
)
// Validate applies validation rules from policy on the resource
func Validate(ctx context.Context, rclient registryclient.Client, policyContext *PolicyContext, cfg config.Configuration) (resp *response.EngineResponse) {
resp = &response.EngineResponse{}
func Validate(ctx context.Context, rclient registryclient.Client, policyContext *PolicyContext, cfg config.Configuration) (resp *engineapi.EngineResponse) {
resp = &engineapi.EngineResponse{}
startTime := time.Now()
logger := buildLogger(policyContext)
@ -65,8 +65,8 @@ func buildLogger(ctx *PolicyContext) logr.Logger {
return logger
}
func buildResponse(ctx *PolicyContext, resp *response.EngineResponse, startTime time.Time) {
if reflect.DeepEqual(resp, response.EngineResponse{}) {
func buildResponse(ctx *PolicyContext, resp *engineapi.EngineResponse, startTime time.Time) {
if reflect.DeepEqual(resp, engineapi.EngineResponse{}) {
return
}
@ -90,7 +90,7 @@ func buildResponse(ctx *PolicyContext, resp *response.EngineResponse, startTime
resp.PolicyResponse.ValidationFailureAction = ctx.policy.GetSpec().ValidationFailureAction
for _, v := range ctx.policy.GetSpec().ValidationFailureActionOverrides {
newOverrides := response.ValidationFailureActionOverride{Action: v.Action, Namespaces: v.Namespaces, NamespaceSelector: v.NamespaceSelector}
newOverrides := engineapi.ValidationFailureActionOverride{Action: v.Action, Namespaces: v.Namespaces, NamespaceSelector: v.NamespaceSelector}
resp.PolicyResponse.ValidationFailureActionOverrides = append(resp.PolicyResponse.ValidationFailureActionOverrides, newOverrides)
}
@ -98,8 +98,8 @@ func buildResponse(ctx *PolicyContext, resp *response.EngineResponse, startTime
resp.PolicyResponse.PolicyExecutionTimestamp = startTime.Unix()
}
func validateResource(ctx context.Context, log logr.Logger, rclient registryclient.Client, enginectx *PolicyContext, cfg config.Configuration) *response.EngineResponse {
resp := &response.EngineResponse{}
func validateResource(ctx context.Context, log logr.Logger, rclient registryclient.Client, enginectx *PolicyContext, cfg config.Configuration) *engineapi.EngineResponse {
resp := &engineapi.EngineResponse{}
enginectx.jsonContext.Checkpoint()
defer enginectx.jsonContext.Restore()
@ -127,7 +127,7 @@ func validateResource(ctx context.Context, log logr.Logger, rclient registryclie
ctx,
"pkg/engine",
fmt.Sprintf("RULE %s", rule.Name),
func(ctx context.Context, span trace.Span) *response.RuleResponse {
func(ctx context.Context, span trace.Span) *engineapi.RuleResponse {
hasValidate := rule.HasValidate()
hasValidateImage := rule.HasImagesValidationChecks()
hasYAMLSignatureVerify := rule.HasYAMLSignatureVerify()
@ -169,19 +169,19 @@ func validateResource(ctx context.Context, log logr.Logger, rclient registryclie
return resp
}
func processValidationRule(ctx context.Context, log logr.Logger, rclient registryclient.Client, policyContext *PolicyContext, rule *kyvernov1.Rule) *response.RuleResponse {
func processValidationRule(ctx context.Context, log logr.Logger, rclient registryclient.Client, policyContext *PolicyContext, rule *kyvernov1.Rule) *engineapi.RuleResponse {
v := newValidator(log, rclient, policyContext, rule)
return v.validate(ctx)
}
func addRuleResponse(log logr.Logger, resp *response.EngineResponse, ruleResp *response.RuleResponse, startTime time.Time) {
func addRuleResponse(log logr.Logger, resp *engineapi.EngineResponse, ruleResp *engineapi.RuleResponse, startTime time.Time) {
ruleResp.RuleStats.ProcessingTime = time.Since(startTime)
ruleResp.RuleStats.RuleExecutionTimestamp = startTime.Unix()
log.V(4).Info("finished processing rule", "processingTime", ruleResp.RuleStats.ProcessingTime.String())
if ruleResp.Status == response.RuleStatusPass || ruleResp.Status == response.RuleStatusFail {
if ruleResp.Status == engineapi.RuleStatusPass || ruleResp.Status == engineapi.RuleStatusFail {
incrementAppliedCount(resp)
} else if ruleResp.Status == response.RuleStatusError {
} else if ruleResp.Status == engineapi.RuleStatusError {
incrementErrorCount(resp)
}
@ -247,18 +247,18 @@ func newForEachValidator(foreach kyvernov1.ForEachValidation, rclient registrycl
}, nil
}
func (v *validator) validate(ctx context.Context) *response.RuleResponse {
func (v *validator) validate(ctx context.Context) *engineapi.RuleResponse {
if err := v.loadContext(ctx); err != nil {
return ruleError(v.rule, response.Validation, "failed to load context", err)
return ruleError(v.rule, engineapi.Validation, "failed to load context", err)
}
preconditionsPassed, err := checkPreconditions(v.log, v.policyContext, v.anyAllConditions)
if err != nil {
return ruleError(v.rule, response.Validation, "failed to evaluate preconditions", err)
return ruleError(v.rule, engineapi.Validation, "failed to evaluate preconditions", err)
}
if !preconditionsPassed {
return ruleResponse(*v.rule, response.Validation, "preconditions not met", response.RuleStatusSkip)
return ruleResponse(*v.rule, engineapi.Validation, "preconditions not met", engineapi.RuleStatusSkip)
}
if v.deny != nil {
@ -267,7 +267,7 @@ func (v *validator) validate(ctx context.Context) *response.RuleResponse {
if v.pattern != nil || v.anyPattern != nil {
if err = v.substitutePatterns(); err != nil {
return ruleError(v.rule, response.Validation, "variable substitution failed", err)
return ruleError(v.rule, engineapi.Validation, "variable substitution failed", err)
}
ruleResponse := v.validateResourceWithRule()
@ -290,7 +290,7 @@ func (v *validator) validate(ctx context.Context) *response.RuleResponse {
return nil
}
func (v *validator) validateForEach(ctx context.Context) *response.RuleResponse {
func (v *validator) validateForEach(ctx context.Context) *engineapi.RuleResponse {
applyCount := 0
for _, foreach := range v.forEach {
elements, err := evaluateList(foreach.List, (v.policyContext.JSONContext()))
@ -300,7 +300,7 @@ func (v *validator) validateForEach(ctx context.Context) *response.RuleResponse
}
resp, count := v.validateElements(ctx, v.rclient, foreach, elements, foreach.ElementScope)
if resp.Status != response.RuleStatusPass {
if resp.Status != engineapi.RuleStatusPass {
return resp
}
@ -312,13 +312,13 @@ func (v *validator) validateForEach(ctx context.Context) *response.RuleResponse
return nil
}
return ruleResponse(*v.rule, response.Validation, "rule skipped", response.RuleStatusSkip)
return ruleResponse(*v.rule, engineapi.Validation, "rule skipped", engineapi.RuleStatusSkip)
}
return ruleResponse(*v.rule, response.Validation, "rule passed", response.RuleStatusPass)
return ruleResponse(*v.rule, engineapi.Validation, "rule passed", engineapi.RuleStatusPass)
}
func (v *validator) validateElements(ctx context.Context, rclient registryclient.Client, foreach kyvernov1.ForEachValidation, elements []interface{}, elementScope *bool) (*response.RuleResponse, int) {
func (v *validator) validateElements(ctx context.Context, rclient registryclient.Client, foreach kyvernov1.ForEachValidation, elements []interface{}, elementScope *bool) (*engineapi.RuleResponse, int) {
v.policyContext.jsonContext.Checkpoint()
defer v.policyContext.jsonContext.Restore()
applyCount := 0
@ -335,38 +335,38 @@ func (v *validator) validateElements(ctx context.Context, rclient registryclient
policyContext := v.policyContext.Copy()
if err := addElementToContext(policyContext, e, i, v.nesting, elementScope); err != nil {
v.log.Error(err, "failed to add element to context")
return ruleError(v.rule, response.Validation, "failed to process foreach", err), applyCount
return ruleError(v.rule, engineapi.Validation, "failed to process foreach", err), applyCount
}
foreachValidator, err := newForEachValidator(foreach, rclient, v.nesting+1, v.rule, policyContext, v.log)
if err != nil {
v.log.Error(err, "failed to create foreach validator")
return ruleError(v.rule, response.Validation, "failed to create foreach validator", err), applyCount
return ruleError(v.rule, engineapi.Validation, "failed to create foreach validator", err), applyCount
}
r := foreachValidator.validate(ctx)
if r == nil {
v.log.V(2).Info("skip rule due to empty result")
continue
} else if r.Status == response.RuleStatusSkip {
} else if r.Status == engineapi.RuleStatusSkip {
v.log.V(2).Info("skip rule", "reason", r.Message)
continue
} else if r.Status != response.RuleStatusPass {
if r.Status == response.RuleStatusError {
} else if r.Status != engineapi.RuleStatusPass {
if r.Status == engineapi.RuleStatusError {
if i < len(elements)-1 {
continue
}
msg := fmt.Sprintf("validation failure: %v", r.Message)
return ruleResponse(*v.rule, response.Validation, msg, r.Status), applyCount
return ruleResponse(*v.rule, engineapi.Validation, msg, r.Status), applyCount
}
msg := fmt.Sprintf("validation failure: %v", r.Message)
return ruleResponse(*v.rule, response.Validation, msg, r.Status), applyCount
return ruleResponse(*v.rule, engineapi.Validation, msg, r.Status), applyCount
}
applyCount++
}
return ruleResponse(*v.rule, response.Validation, "", response.RuleStatusPass), applyCount
return ruleResponse(*v.rule, engineapi.Validation, "", engineapi.RuleStatusPass), applyCount
}
func addElementToContext(ctx *PolicyContext, e interface{}, elementIndex, nesting int, elementScope *bool) error {
@ -416,28 +416,28 @@ func (v *validator) loadContext(ctx context.Context) error {
return nil
}
func (v *validator) validateDeny() *response.RuleResponse {
func (v *validator) validateDeny() *engineapi.RuleResponse {
anyAllCond := v.deny.GetAnyAllConditions()
anyAllCond, err := variables.SubstituteAll(v.log, v.policyContext.jsonContext, anyAllCond)
if err != nil {
return ruleError(v.rule, response.Validation, "failed to substitute variables in deny conditions", err)
return ruleError(v.rule, engineapi.Validation, "failed to substitute variables in deny conditions", err)
}
if err = v.substituteDeny(); err != nil {
return ruleError(v.rule, response.Validation, "failed to substitute variables in rule", err)
return ruleError(v.rule, engineapi.Validation, "failed to substitute variables in rule", err)
}
denyConditions, err := common.TransformConditions(anyAllCond)
if err != nil {
return ruleError(v.rule, response.Validation, "invalid deny conditions", err)
return ruleError(v.rule, engineapi.Validation, "invalid deny conditions", err)
}
deny := variables.EvaluateConditions(v.log, v.policyContext.jsonContext, denyConditions)
if deny {
return ruleResponse(*v.rule, response.Validation, v.getDenyMessage(deny), response.RuleStatusFail)
return ruleResponse(*v.rule, engineapi.Validation, v.getDenyMessage(deny), engineapi.RuleStatusFail)
}
return ruleResponse(*v.rule, response.Validation, v.getDenyMessage(deny), response.RuleStatusPass)
return ruleResponse(*v.rule, engineapi.Validation, v.getDenyMessage(deny), engineapi.RuleStatusPass)
}
func (v *validator) getDenyMessage(deny bool) string {
@ -513,11 +513,11 @@ func getSpec(v *validator) (podSpec *corev1.PodSpec, metadata *metav1.ObjectMeta
}
// Unstructured
func (v *validator) validatePodSecurity() *response.RuleResponse {
func (v *validator) validatePodSecurity() *engineapi.RuleResponse {
// Marshal pod metadata and spec
podSpec, metadata, err := getSpec(v)
if err != nil {
return ruleError(v.rule, response.Validation, "Error while getting new resource", err)
return ruleError(v.rule, engineapi.Validation, "Error while getting new resource", err)
}
pod := &corev1.Pod{
@ -526,27 +526,27 @@ func (v *validator) validatePodSecurity() *response.RuleResponse {
}
allowed, pssChecks, err := pss.EvaluatePod(v.podSecurity, pod)
if err != nil {
return ruleError(v.rule, response.Validation, "failed to parse pod security api version", err)
return ruleError(v.rule, engineapi.Validation, "failed to parse pod security api version", err)
}
podSecurityChecks := &response.PodSecurityChecks{
podSecurityChecks := &engineapi.PodSecurityChecks{
Level: v.podSecurity.Level,
Version: v.podSecurity.Version,
Checks: pssChecks,
}
if allowed {
msg := fmt.Sprintf("Validation rule '%s' passed.", v.rule.Name)
rspn := ruleResponse(*v.rule, response.Validation, msg, response.RuleStatusPass)
rspn := ruleResponse(*v.rule, engineapi.Validation, msg, engineapi.RuleStatusPass)
rspn.PodSecurityChecks = podSecurityChecks
return rspn
} else {
msg := fmt.Sprintf(`Validation rule '%s' failed. It violates PodSecurity "%s:%s": %s`, v.rule.Name, v.podSecurity.Level, v.podSecurity.Version, pss.FormatChecksPrint(pssChecks))
rspn := ruleResponse(*v.rule, response.Validation, msg, response.RuleStatusFail)
rspn := ruleResponse(*v.rule, engineapi.Validation, msg, engineapi.RuleStatusFail)
rspn.PodSecurityChecks = podSecurityChecks
return rspn
}
}
func (v *validator) validateResourceWithRule() *response.RuleResponse {
func (v *validator) validateResourceWithRule() *engineapi.RuleResponse {
if !isEmptyUnstructured(&v.policyContext.element) {
return v.validatePatterns(v.policyContext.element)
}
@ -596,7 +596,7 @@ func matches(logger logr.Logger, rule *kyvernov1.Rule, ctx *PolicyContext, subre
}
// validatePatterns validate pattern and anyPattern
func (v *validator) validatePatterns(resource unstructured.Unstructured) *response.RuleResponse {
func (v *validator) validatePatterns(resource unstructured.Unstructured) *engineapi.RuleResponse {
if v.pattern != nil {
if err := validate.MatchPattern(v.log, resource.Object, v.pattern); err != nil {
pe, ok := err.(*validate.PatternError)
@ -604,22 +604,22 @@ func (v *validator) validatePatterns(resource unstructured.Unstructured) *respon
v.log.V(3).Info("validation error", "path", pe.Path, "error", err.Error())
if pe.Skip {
return ruleResponse(*v.rule, response.Validation, pe.Error(), response.RuleStatusSkip)
return ruleResponse(*v.rule, engineapi.Validation, pe.Error(), engineapi.RuleStatusSkip)
}
if pe.Path == "" {
return ruleResponse(*v.rule, response.Validation, v.buildErrorMessage(err, ""), response.RuleStatusError)
return ruleResponse(*v.rule, engineapi.Validation, v.buildErrorMessage(err, ""), engineapi.RuleStatusError)
}
return ruleResponse(*v.rule, response.Validation, v.buildErrorMessage(err, pe.Path), response.RuleStatusFail)
return ruleResponse(*v.rule, engineapi.Validation, v.buildErrorMessage(err, pe.Path), engineapi.RuleStatusFail)
}
return ruleResponse(*v.rule, response.Validation, v.buildErrorMessage(err, pe.Path), response.RuleStatusError)
return ruleResponse(*v.rule, engineapi.Validation, v.buildErrorMessage(err, pe.Path), engineapi.RuleStatusError)
}
v.log.V(4).Info("successfully processed rule")
msg := fmt.Sprintf("validation rule '%s' passed.", v.rule.Name)
return ruleResponse(*v.rule, response.Validation, msg, response.RuleStatusPass)
return ruleResponse(*v.rule, engineapi.Validation, msg, engineapi.RuleStatusPass)
}
if v.anyPattern != nil {
@ -630,14 +630,14 @@ func (v *validator) validatePatterns(resource unstructured.Unstructured) *respon
anyPatterns, err := deserializeAnyPattern(v.anyPattern)
if err != nil {
msg := fmt.Sprintf("failed to deserialize anyPattern, expected type array: %v", err)
return ruleResponse(*v.rule, response.Validation, msg, response.RuleStatusError)
return ruleResponse(*v.rule, engineapi.Validation, msg, engineapi.RuleStatusError)
}
for idx, pattern := range anyPatterns {
err := validate.MatchPattern(v.log, resource.Object, pattern)
if err == nil {
msg := fmt.Sprintf("validation rule '%s' anyPattern[%d] passed.", v.rule.Name, idx)
return ruleResponse(*v.rule, response.Validation, msg, response.RuleStatusPass)
return ruleResponse(*v.rule, engineapi.Validation, msg, engineapi.RuleStatusPass)
}
if pe, ok := err.(*validate.PatternError); ok {
@ -666,7 +666,7 @@ func (v *validator) validatePatterns(resource unstructured.Unstructured) *respon
}
v.log.V(4).Info(fmt.Sprintf("Validation rule '%s' skipped. %s", v.rule.Name, errorStr))
return ruleResponse(*v.rule, response.Validation, strings.Join(errorStr, " "), response.RuleStatusSkip)
return ruleResponse(*v.rule, engineapi.Validation, strings.Join(errorStr, " "), engineapi.RuleStatusSkip)
} else if len(failedAnyPatternsErrors) > 0 {
var errorStr []string
for _, err := range failedAnyPatternsErrors {
@ -675,11 +675,11 @@ func (v *validator) validatePatterns(resource unstructured.Unstructured) *respon
v.log.V(4).Info(fmt.Sprintf("Validation rule '%s' failed. %s", v.rule.Name, errorStr))
msg := buildAnyPatternErrorMessage(v.rule, errorStr)
return ruleResponse(*v.rule, response.Validation, msg, response.RuleStatusFail)
return ruleResponse(*v.rule, engineapi.Validation, msg, engineapi.RuleStatusFail)
}
}
return ruleResponse(*v.rule, response.Validation, v.rule.Validation.Message, response.RuleStatusPass)
return ruleResponse(*v.rule, engineapi.Validation, v.rule.Validation.Message, engineapi.RuleStatusPass)
}
func deserializeAnyPattern(anyPattern apiextensions.JSON) ([]interface{}, error) {
@ -806,7 +806,7 @@ func matchesException(
// hasPolicyExceptions returns nil when there are no matching exceptions.
// A rule response is returned when an exception is matched, or there is an error.
func hasPolicyExceptions(ctx *PolicyContext, rule *kyvernov1.Rule, subresourceGVKToAPIResource map[string]*metav1.APIResource, log logr.Logger) *response.RuleResponse {
func hasPolicyExceptions(ctx *PolicyContext, rule *kyvernov1.Rule, subresourceGVKToAPIResource map[string]*metav1.APIResource, log logr.Logger) *engineapi.RuleResponse {
// if matches, check if there is a corresponding policy exception
exception, err := matchesException(ctx, rule, subresourceGVKToAPIResource)
// if we found an exception
@ -814,17 +814,17 @@ func hasPolicyExceptions(ctx *PolicyContext, rule *kyvernov1.Rule, subresourceGV
key, err := cache.MetaNamespaceKeyFunc(exception)
if err != nil {
log.Error(err, "failed to compute policy exception key", "namespace", exception.GetNamespace(), "name", exception.GetName())
return &response.RuleResponse{
return &engineapi.RuleResponse{
Name: rule.Name,
Message: "failed to find matched exception " + key,
Status: response.RuleStatusError,
Status: engineapi.RuleStatusError,
}
}
log.V(3).Info("policy rule skipped due to policy exception", "exception", key)
return &response.RuleResponse{
return &engineapi.RuleResponse{
Name: rule.Name,
Message: "rule skipped due to policy exception " + key,
Status: response.RuleStatusSkip,
Status: engineapi.RuleStatusSkip,
}
}
return nil

View file

@ -9,8 +9,8 @@ import (
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
urkyverno "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/kyverno/kyverno/pkg/registryclient"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
@ -1485,7 +1485,7 @@ func Test_VariableSubstitutionPathNotExistInPattern(t *testing.T) {
er := Validate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusError)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusError)
assert.Assert(t, strings.Contains(er.PolicyResponse.Rules[0].Message, "Unknown key \"name1\" in path"))
}
@ -1579,7 +1579,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_OnePatternStatisfiesButSu
er := Validate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusError)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusError)
assert.Assert(t, strings.Contains(er.PolicyResponse.Rules[0].Message, "Unknown key \"name1\" in path"))
}
@ -1639,7 +1639,7 @@ func Test_VariableSubstitution_NotOperatorWithStringVariable(t *testing.T) {
newResource: *resourceUnstructured,
}
er := Validate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusFail)
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/")
}
@ -1733,7 +1733,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathNotPresent(t *test
er := Validate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, len(er.PolicyResponse.Rules), 1)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusError)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusError)
assert.Assert(t, strings.Contains(er.PolicyResponse.Rules[0].Message, "Unknown key \"name1\" in path"))
}
@ -1826,7 +1826,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathPresent_NonePatter
}
er := Validate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusFail)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
assert.Equal(t, er.PolicyResponse.Rules[0].Message,
"validation error: rule test-path-not-exist[0] failed at path /spec/template/spec/containers/0/name/ rule test-path-not-exist[1] failed at path /spec/template/spec/containers/0/name/")
}
@ -1931,7 +1931,7 @@ func Test_VariableSubstitutionValidate_VariablesInMessageAreResolved(t *testing.
newResource: *resourceUnstructured,
}
er := Validate(context.TODO(), registryclient.NewOrDie(), policyContext, cfg)
assert.Equal(t, er.PolicyResponse.Rules[0].Status, response.RuleStatusFail)
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.")
}
@ -1940,7 +1940,7 @@ func Test_Flux_Kustomization_PathNotPresent(t *testing.T) {
name string
policyRaw []byte
resourceRaw []byte
expectedResults []response.RuleStatus
expectedResults []engineapi.RuleStatus
expectedMessages []string
}{
{
@ -1948,7 +1948,7 @@ func Test_Flux_Kustomization_PathNotPresent(t *testing.T) {
policyRaw: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"flux-multi-tenancy"},"spec":{"validationFailureAction":"enforce","rules":[{"name":"serviceAccountName","exclude":{"resources":{"namespaces":["flux-system"]}},"match":{"resources":{"kinds":["Kustomization","HelmRelease"]}},"validate":{"message":".spec.serviceAccountName is required","pattern":{"spec":{"serviceAccountName":"?*"}}}},{"name":"sourceRefNamespace","exclude":{"resources":{"namespaces":["flux-system"]}},"match":{"resources":{"kinds":["Kustomization","HelmRelease"]}},"validate":{"message":"spec.sourceRef.namespace must be the same as metadata.namespace","deny":{"conditions":[{"key":"{{request.object.spec.sourceRef.namespace}}","operator":"NotEquals","value":"{{request.object.metadata.namespace}}"}]}}}]}}`),
// referred variable path not present
resourceRaw: []byte(`{"apiVersion":"kustomize.toolkit.fluxcd.io/v1beta1","kind":"Kustomization","metadata":{"name":"dev-team","namespace":"apps"},"spec":{"serviceAccountName":"dev-team","interval":"5m","sourceRef":{"kind":"GitRepository","name":"dev-team"},"prune":true,"validation":"client"}}`),
expectedResults: []response.RuleStatus{response.RuleStatusPass, response.RuleStatusError},
expectedResults: []engineapi.RuleStatus{engineapi.RuleStatusPass, engineapi.RuleStatusError},
expectedMessages: []string{"validation rule 'serviceAccountName' passed.", "failed to substitute variables in deny conditions: failed to resolve request.object.spec.sourceRef.namespace at path /0/key: JMESPath query failed: Unknown key \"namespace\" in path"},
},
{
@ -1956,7 +1956,7 @@ func Test_Flux_Kustomization_PathNotPresent(t *testing.T) {
policyRaw: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"flux-multi-tenancy"},"spec":{"validationFailureAction":"enforce","rules":[{"name":"serviceAccountName","exclude":{"resources":{"namespaces":["flux-system"]}},"match":{"resources":{"kinds":["Kustomization","HelmRelease"]}},"validate":{"message":".spec.serviceAccountName is required","pattern":{"spec":{"serviceAccountName":"?*"}}}},{"name":"sourceRefNamespace","exclude":{"resources":{"namespaces":["flux-system"]}},"match":{"resources":{"kinds":["Kustomization","HelmRelease"]}},"validate":{"message":"spec.sourceRef.namespace {{request.object.spec.sourceRef.namespace}} must be the same as metadata.namespace {{request.object.metadata.namespace}}","deny":{"conditions":[{"key":"{{request.object.spec.sourceRef.namespace}}","operator":"NotEquals","value":"{{request.object.metadata.namespace}}"}]}}}]}}`),
// referred variable path present with different value
resourceRaw: []byte(`{"apiVersion":"kustomize.toolkit.fluxcd.io/v1beta1","kind":"Kustomization","metadata":{"name":"dev-team","namespace":"apps"},"spec":{"serviceAccountName":"dev-team","interval":"5m","sourceRef":{"kind":"GitRepository","name":"dev-team","namespace":"default"},"prune":true,"validation":"client"}}`),
expectedResults: []response.RuleStatus{response.RuleStatusPass, response.RuleStatusFail},
expectedResults: []engineapi.RuleStatus{engineapi.RuleStatusPass, engineapi.RuleStatusFail},
expectedMessages: []string{"validation rule 'serviceAccountName' passed.", "spec.sourceRef.namespace default must be the same as metadata.namespace apps"},
},
{
@ -1964,7 +1964,7 @@ func Test_Flux_Kustomization_PathNotPresent(t *testing.T) {
policyRaw: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"flux-multi-tenancy"},"spec":{"validationFailureAction":"enforce","rules":[{"name":"serviceAccountName","exclude":{"resources":{"namespaces":["flux-system"]}},"match":{"resources":{"kinds":["Kustomization","HelmRelease"]}},"validate":{"message":".spec.serviceAccountName is required","pattern":{"spec":{"serviceAccountName":"?*"}}}},{"name":"sourceRefNamespace","exclude":{"resources":{"namespaces":["flux-system"]}},"match":{"resources":{"kinds":["Kustomization","HelmRelease"]}},"validate":{"message":"spec.sourceRef.namespace must be the same as metadata.namespace","deny":{"conditions":[{"key":"{{request.object.spec.sourceRef.namespace}}","operator":"NotEquals","value":"{{request.object.metadata.namespace}}"}]}}}]}}`),
// referred variable path present with same value - validate passes
resourceRaw: []byte(`{"apiVersion":"kustomize.toolkit.fluxcd.io/v1beta1","kind":"Kustomization","metadata":{"name":"dev-team","namespace":"apps"},"spec":{"serviceAccountName":"dev-team","interval":"5m","sourceRef":{"kind":"GitRepository","name":"dev-team","namespace":"apps"},"prune":true,"validation":"client"}}`),
expectedResults: []response.RuleStatus{response.RuleStatusPass, response.RuleStatusPass},
expectedResults: []engineapi.RuleStatus{engineapi.RuleStatusPass, engineapi.RuleStatusPass},
expectedMessages: []string{"validation rule 'serviceAccountName' passed.", "validation rule 'sourceRefNamespace' passed."},
},
}
@ -1987,7 +1987,7 @@ func Test_Flux_Kustomization_PathNotPresent(t *testing.T) {
er := Validate(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].String(), er.PolicyResponse.Rules[i].Status.String())
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)
assert.Equal(t, er.PolicyResponse.Rules[i].Message, test.expectedMessages[i], "\ntest %s failed\nexpected: %s\nactual: %s", test.name, test.expectedMessages[i], rule.Message)
}
}
@ -2476,7 +2476,7 @@ func Test_foreach_container_pass(t *testing.T) {
}
}`)
testForEach(t, policyraw, resourceRaw, "", response.RuleStatusPass)
testForEach(t, policyraw, resourceRaw, "", engineapi.RuleStatusPass)
}
func Test_foreach_container_fail(t *testing.T) {
@ -2512,7 +2512,7 @@ func Test_foreach_container_fail(t *testing.T) {
]
}}]}}`)
testForEach(t, policyraw, resourceRaw, "", response.RuleStatusFail)
testForEach(t, policyraw, resourceRaw, "", engineapi.RuleStatusFail)
}
func Test_foreach_container_deny_fail(t *testing.T) {
@ -2566,7 +2566,7 @@ func Test_foreach_container_deny_fail(t *testing.T) {
}
}`)
testForEach(t, policyraw, resourceRaw, "", response.RuleStatusFail)
testForEach(t, policyraw, resourceRaw, "", engineapi.RuleStatusFail)
}
func Test_foreach_container_deny_success(t *testing.T) {
@ -2608,7 +2608,7 @@ func Test_foreach_container_deny_success(t *testing.T) {
]
}}]}}`)
testForEach(t, policyraw, resourceRaw, "", response.RuleStatusFail)
testForEach(t, policyraw, resourceRaw, "", engineapi.RuleStatusFail)
}
func Test_foreach_container_deny_error(t *testing.T) {
@ -2662,7 +2662,7 @@ func Test_foreach_container_deny_error(t *testing.T) {
}
}`)
testForEach(t, policyraw, resourceRaw, "", response.RuleStatusError)
testForEach(t, policyraw, resourceRaw, "", engineapi.RuleStatusError)
}
func Test_foreach_context_preconditions(t *testing.T) {
@ -2755,7 +2755,7 @@ func Test_foreach_context_preconditions(t *testing.T) {
store.SetContext(configMapVariableContext)
store.SetMock(true)
testForEach(t, policyraw, resourceRaw, "", response.RuleStatusPass)
testForEach(t, policyraw, resourceRaw, "", engineapi.RuleStatusPass)
}
func Test_foreach_context_preconditions_fail(t *testing.T) {
@ -2849,7 +2849,7 @@ func Test_foreach_context_preconditions_fail(t *testing.T) {
store.SetContext(configMapVariableContext)
store.SetMock(true)
testForEach(t, policyraw, resourceRaw, "", response.RuleStatusFail)
testForEach(t, policyraw, resourceRaw, "", engineapi.RuleStatusFail)
}
func Test_foreach_element_validation(t *testing.T) {
@ -2896,7 +2896,7 @@ func Test_foreach_element_validation(t *testing.T) {
]
}}]}}`)
testForEach(t, policyraw, resourceRaw, "", response.RuleStatusPass)
testForEach(t, policyraw, resourceRaw, "", engineapi.RuleStatusPass)
}
func Test_outof_foreach_element_validation(t *testing.T) {
@ -2938,7 +2938,7 @@ func Test_outof_foreach_element_validation(t *testing.T) {
}
}}]}}`)
testForEach(t, policyraw, resourceRaw, "", response.RuleStatusError)
testForEach(t, policyraw, resourceRaw, "", engineapi.RuleStatusError)
}
func Test_foreach_skip_initContainer_pass(t *testing.T) {
@ -2992,7 +2992,7 @@ func Test_foreach_skip_initContainer_pass(t *testing.T) {
}
}`)
testForEach(t, policyraw, resourceRaw, "", response.RuleStatusPass)
testForEach(t, policyraw, resourceRaw, "", engineapi.RuleStatusPass)
}
func Test_foreach_validate_nested(t *testing.T) {
@ -3088,10 +3088,10 @@ func Test_foreach_validate_nested(t *testing.T) {
}
}`)
testForEach(t, policyraw, resourceRaw, "", response.RuleStatusPass)
testForEach(t, policyraw, resourceRaw, "", engineapi.RuleStatusPass)
}
func testForEach(t *testing.T, policyraw []byte, resourceRaw []byte, msg string, status response.RuleStatus) {
func testForEach(t *testing.T, policyraw []byte, resourceRaw []byte, msg string, status engineapi.RuleStatus) {
var policy kyverno.ClusterPolicy
assert.NilError(t, json.Unmarshal(policyraw, &policy))
resourceUnstructured, err := kubeutils.BytesToUnstructured(resourceRaw)
@ -3172,7 +3172,7 @@ func Test_delete_ignore_pattern(t *testing.T) {
}
engineResponseCreate := Validate(context.TODO(), registryclient.NewOrDie(), policyContextCreate, cfg)
assert.Equal(t, len(engineResponseCreate.PolicyResponse.Rules), 1)
assert.Equal(t, engineResponseCreate.PolicyResponse.Rules[0].Status, response.RuleStatusFail)
assert.Equal(t, engineResponseCreate.PolicyResponse.Rules[0].Status, engineapi.RuleStatusFail)
policyContextDelete := &PolicyContext{
policy: &policy,

View file

@ -5,11 +5,11 @@ import (
"strings"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func NewPolicyFailEvent(source Source, reason Reason, engineResponse *response.EngineResponse, ruleResp *response.RuleResponse, blocked bool) Info {
func NewPolicyFailEvent(source Source, reason Reason, engineResponse *engineapi.EngineResponse, ruleResp *engineapi.RuleResponse, blocked bool) Info {
return Info{
Kind: getPolicyKind(engineResponse.Policy),
Name: engineResponse.PolicyResponse.Policy.Name,
@ -20,7 +20,7 @@ func NewPolicyFailEvent(source Source, reason Reason, engineResponse *response.E
}
}
func buildPolicyEventMessage(resp *response.RuleResponse, resource response.ResourceSpec, blocked bool) string {
func buildPolicyEventMessage(resp *engineapi.RuleResponse, resource engineapi.ResourceSpec, blocked bool) string {
var b strings.Builder
if resource.Namespace != "" {
fmt.Fprintf(&b, "%s %s/%s", resource.Kind, resource.Namespace, resource.Name)
@ -28,12 +28,12 @@ func buildPolicyEventMessage(resp *response.RuleResponse, resource response.Reso
fmt.Fprintf(&b, "%s %s", resource.Kind, resource.Name)
}
fmt.Fprintf(&b, ": [%s] %s", resp.Name, resp.Status.String())
fmt.Fprintf(&b, ": [%s] %s", resp.Name, resp.Status)
if blocked {
fmt.Fprintf(&b, " (blocked)")
}
if resp.Status == response.RuleStatusError && resp.Message != "" {
if resp.Status == engineapi.RuleStatusError && resp.Message != "" {
fmt.Fprintf(&b, "; %s", resp.Message)
}
@ -47,7 +47,7 @@ func getPolicyKind(policy kyvernov1.PolicyInterface) string {
return "ClusterPolicy"
}
func NewPolicyAppliedEvent(source Source, engineResponse *response.EngineResponse) Info {
func NewPolicyAppliedEvent(source Source, engineResponse *engineapi.EngineResponse) Info {
resource := engineResponse.PolicyResponse.Resource
var bldr strings.Builder
defer bldr.Reset()
@ -68,12 +68,12 @@ func NewPolicyAppliedEvent(source Source, engineResponse *response.EngineRespons
}
}
func NewResourceViolationEvent(source Source, reason Reason, engineResponse *response.EngineResponse, ruleResp *response.RuleResponse) Info {
func NewResourceViolationEvent(source Source, reason Reason, engineResponse *engineapi.EngineResponse, ruleResp *engineapi.RuleResponse) Info {
var bldr strings.Builder
defer bldr.Reset()
fmt.Fprintf(&bldr, "policy %s/%s %s: %s", engineResponse.Policy.GetName(),
ruleResp.Name, ruleResp.Status.String(), ruleResp.Message)
ruleResp.Name, ruleResp.Status, ruleResp.Message)
resource := engineResponse.GetResourceSpec()
return Info{
@ -123,7 +123,7 @@ func NewBackgroundSuccessEvent(policy, rule string, source Source, r *unstructur
return events
}
func NewPolicyExceptionEvents(engineResponse *response.EngineResponse, ruleResp *response.RuleResponse) []Info {
func NewPolicyExceptionEvents(engineResponse *engineapi.EngineResponse, ruleResp *engineapi.RuleResponse) []Info {
exceptionName, exceptionNamespace := getExceptionEventInfoFromRuleResponseMsg(ruleResp.Message)
policyMessage := fmt.Sprintf("resource %s was skipped from rule %s due to policy exception %s/%s", engineResponse.PatchedResource.GetName(), ruleResp.Name, exceptionNamespace, exceptionName)
var exceptionMessage string

View file

@ -5,7 +5,7 @@ import (
"reflect"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
)
func ParsePolicyValidationMode(validationFailureAction kyvernov1.ValidationFailureAction) (PolicyValidationMode, error) {
@ -53,7 +53,7 @@ func ParseResourceRequestOperation(requestOperationStr string) (ResourceRequestO
}
}
func ParseRuleTypeFromEngineRuleResponse(rule response.RuleResponse) RuleType {
func ParseRuleTypeFromEngineRuleResponse(rule engineapi.RuleResponse) RuleType {
switch rule.Type {
case "Validation":
return Validate

View file

@ -4,7 +4,7 @@ import (
"context"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/metrics"
)
@ -32,7 +32,7 @@ func registerPolicyExecutionDurationMetric(
// policy - policy related data
// engineResponse - resource and rule related data
func ProcessEngineResponse(ctx context.Context, m metrics.MetricsConfigManager, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse, executionCause metrics.RuleExecutionCause, resourceRequestOperation metrics.ResourceRequestOperation) error {
func ProcessEngineResponse(ctx context.Context, m metrics.MetricsConfigManager, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse, executionCause metrics.RuleExecutionCause, resourceRequestOperation metrics.ResourceRequestOperation) error {
name, namespace, policyType, backgroundMode, validationMode, err := metrics.GetPolicyInfos(policy)
if err != nil {
return err
@ -45,15 +45,15 @@ func ProcessEngineResponse(ctx context.Context, m metrics.MetricsConfigManager,
ruleType := metrics.ParseRuleTypeFromEngineRuleResponse(rule)
var ruleResult metrics.RuleResult
switch rule.Status {
case response.RuleStatusPass:
case engineapi.RuleStatusPass:
ruleResult = metrics.Pass
case response.RuleStatusFail:
case engineapi.RuleStatusFail:
ruleResult = metrics.Fail
case response.RuleStatusWarn:
case engineapi.RuleStatusWarn:
ruleResult = metrics.Warn
case response.RuleStatusError:
case engineapi.RuleStatusError:
ruleResult = metrics.Error
case response.RuleStatusSkip:
case engineapi.RuleStatusSkip:
ruleResult = metrics.Skip
default:
ruleResult = metrics.Fail

View file

@ -4,7 +4,7 @@ import (
"context"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/metrics"
)
@ -32,7 +32,7 @@ func registerPolicyResultsMetric(
// policy - policy related data
// engineResponse - resource and rule related data
func ProcessEngineResponse(ctx context.Context, m metrics.MetricsConfigManager, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse, executionCause metrics.RuleExecutionCause, resourceRequestOperation metrics.ResourceRequestOperation) error {
func ProcessEngineResponse(ctx context.Context, m metrics.MetricsConfigManager, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse, executionCause metrics.RuleExecutionCause, resourceRequestOperation metrics.ResourceRequestOperation) error {
name, namespace, policyType, backgroundMode, validationMode, err := metrics.GetPolicyInfos(policy)
if err != nil {
return err
@ -46,15 +46,15 @@ func ProcessEngineResponse(ctx context.Context, m metrics.MetricsConfigManager,
ruleType := metrics.ParseRuleTypeFromEngineRuleResponse(rule)
var ruleResult metrics.RuleResult
switch rule.Status {
case response.RuleStatusPass:
case engineapi.RuleStatusPass:
ruleResult = metrics.Pass
case response.RuleStatusFail:
case engineapi.RuleStatusFail:
ruleResult = metrics.Fail
case response.RuleStatusWarn:
case engineapi.RuleStatusWarn:
ruleResult = metrics.Warn
case response.RuleStatusError:
case engineapi.RuleStatusError:
ruleResult = metrics.Error
case response.RuleStatusSkip:
case engineapi.RuleStatusSkip:
ruleResult = metrics.Skip
default:
ruleResult = metrics.Fail

View file

@ -22,8 +22,8 @@ import (
"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/engine/context/resolvers"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/registryclient"
@ -521,7 +521,7 @@ func (pc *PolicyController) handleUpdateRequest(ur *kyvernov1beta1.UpdateRequest
}
for _, ruleResponse := range engineResponse.PolicyResponse.Rules {
if ruleResponse.Status != response.RuleStatusPass {
if ruleResponse.Status != engineapi.RuleStatusPass {
pc.log.Error(err, "can not create new UR on policy update", "policy", policy.GetName(), "rule", rule.Name, "rule.Status", ruleResponse.Status)
continue
}

View file

@ -15,7 +15,7 @@ import (
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/registryclient"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
@ -53,19 +53,19 @@ type Mutation struct {
// path to the patched resource to be compared with
PatchedResource string `yaml:"patchedresource,omitempty"`
// expected response from the policy engine
PolicyResponse response.PolicyResponse `yaml:"policyresponse"`
PolicyResponse engineapi.PolicyResponse `yaml:"policyresponse"`
}
type Validation struct {
// expected response from the policy engine
PolicyResponse response.PolicyResponse `yaml:"policyresponse"`
PolicyResponse engineapi.PolicyResponse `yaml:"policyresponse"`
}
type Generation struct {
// generated resources
GeneratedResources []kyvernov1.ResourceSpec `yaml:"generatedResources"`
// expected response from the policy engine
PolicyResponse response.PolicyResponse `yaml:"policyresponse"`
PolicyResponse engineapi.PolicyResponse `yaml:"policyresponse"`
}
// RootDir returns the kyverno project directory based on the location of the current file.
@ -231,9 +231,9 @@ func validateResource(t *testing.T, responseResource unstructured.Unstructured,
t.Log("success: response resource returned matches expected resource")
}
func validateResponse(t *testing.T, er response.PolicyResponse, expected response.PolicyResponse) {
func validateResponse(t *testing.T, er engineapi.PolicyResponse, expected engineapi.PolicyResponse) {
t.Helper()
if reflect.DeepEqual(expected, response.PolicyResponse{}) {
if reflect.DeepEqual(expected, engineapi.PolicyResponse{}) {
t.Log("no response expected")
return
}
@ -259,7 +259,7 @@ func validateResponse(t *testing.T, er response.PolicyResponse, expected respons
}
}
func comparePolicySpec(t *testing.T, policy response.PolicySpec, expectedPolicy response.PolicySpec) {
func comparePolicySpec(t *testing.T, policy engineapi.PolicySpec, expectedPolicy engineapi.PolicySpec) {
t.Helper()
// namespace
if policy.Namespace != expectedPolicy.Namespace {
@ -271,7 +271,7 @@ func comparePolicySpec(t *testing.T, policy response.PolicySpec, expectedPolicy
}
}
func compareResourceSpec(t *testing.T, resource response.ResourceSpec, expectedResource response.ResourceSpec) {
func compareResourceSpec(t *testing.T, resource engineapi.ResourceSpec, expectedResource engineapi.ResourceSpec) {
t.Helper()
// kind
if resource.Kind != expectedResource.Kind {
@ -292,7 +292,7 @@ func compareResourceSpec(t *testing.T, resource response.ResourceSpec, expectedR
}
}
func compareRules(t *testing.T, rule response.RuleResponse, expectedRule response.RuleResponse) {
func compareRules(t *testing.T, rule engineapi.RuleResponse, expectedRule engineapi.RuleResponse) {
t.Helper()
// name
if rule.Name != expectedRule.Name {
@ -315,7 +315,7 @@ func compareRules(t *testing.T, rule response.RuleResponse, expectedRule respons
// success
if rule.Status != expectedRule.Status {
t.Errorf("rule status mismatch: expected %s, received %s", expectedRule.Status.String(), rule.Status.String())
t.Errorf("rule status mismatch: expected %s, received %s", expectedRule.Status, rule.Status)
}
}

View file

@ -4,7 +4,7 @@ import (
"os"
"testing"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"gopkg.in/yaml.v3"
"gotest.tools/assert"
)
@ -39,7 +39,7 @@ func Test_parse_yaml(t *testing.T) {
assert.Equal(t, s.Expected.Validation.PolicyResponse.Policy.Name, "disallow-bind-mounts")
assert.Equal(t, 1, len(s.Expected.Validation.PolicyResponse.Rules), "invalid rule count")
assert.Equal(t, response.RuleStatusFail, s.Expected.Validation.PolicyResponse.Rules[0].Status, "invalid status")
assert.Equal(t, engineapi.RuleStatusFail, s.Expected.Validation.PolicyResponse.Rules[0].Status, "invalid status")
}
func Test_parse_file(t *testing.T) {
@ -49,7 +49,7 @@ func Test_parse_file(t *testing.T) {
assert.Equal(t, 1, len(s.TestCases))
assert.Equal(t, s.TestCases[0].Expected.Validation.PolicyResponse.Policy.Name, "disallow-bind-mounts")
assert.Equal(t, 1, len(s.TestCases[0].Expected.Validation.PolicyResponse.Rules), "invalid rule count")
assert.Equal(t, response.RuleStatusFail, s.TestCases[0].Expected.Validation.PolicyResponse.Rules[0].Status, "invalid status")
assert.Equal(t, engineapi.RuleStatusFail, s.TestCases[0].Expected.Validation.PolicyResponse.Rules[0].Status, "invalid status")
}
func Test_parse_file2(t *testing.T) {
@ -66,5 +66,5 @@ func Test_parse_file2(t *testing.T) {
assert.Equal(t, s.Expected.Validation.PolicyResponse.Policy.Name, "disallow-bind-mounts")
assert.Equal(t, 1, len(s.Expected.Validation.PolicyResponse.Rules), "invalid rule count")
assert.Equal(t, response.RuleStatusFail, s.Expected.Validation.PolicyResponse.Rules[0].Status, "invalid status")
assert.Equal(t, engineapi.RuleStatusFail, s.Expected.Validation.PolicyResponse.Rules[0].Status, "invalid status")
}

View file

@ -5,7 +5,7 @@ import (
"strings"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
yamlv2 "gopkg.in/yaml.v2"
)
@ -33,7 +33,7 @@ var OperationToPastTense = map[string]string{
"test": "tested",
}
func GenerateAnnotationPatches(engineResponses []*response.EngineResponse, log logr.Logger) [][]byte {
func GenerateAnnotationPatches(engineResponses []*engineapi.EngineResponse, log logr.Logger) [][]byte {
var annotations map[string]string
var patchBytes [][]byte
for _, er := range engineResponses {
@ -91,7 +91,7 @@ func GenerateAnnotationPatches(engineResponses []*response.EngineResponse, log l
return patchBytes
}
func annotationFromEngineResponses(engineResponses []*response.EngineResponse, log logr.Logger) []byte {
func annotationFromEngineResponses(engineResponses []*engineapi.EngineResponse, log logr.Logger) []byte {
annotationContent := make(map[string]string)
for _, engineResponse := range engineResponses {
if !engineResponse.IsSuccessful() {
@ -119,7 +119,7 @@ func annotationFromEngineResponses(engineResponses []*response.EngineResponse, l
return result
}
func annotationFromPolicyResponse(policyResponse response.PolicyResponse, log logr.Logger) []RulePatch {
func annotationFromPolicyResponse(policyResponse engineapi.PolicyResponse, log logr.Logger) []RulePatch {
var RulePatches []RulePatch
for _, ruleInfo := range policyResponse.Rules {
for _, patch := range ruleInfo.Patches {

View file

@ -3,21 +3,21 @@ package utils
import (
"testing"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/logging"
"gotest.tools/assert"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func newPolicyResponse(policy, rule string, patchesStr []string, status response.RuleStatus) response.PolicyResponse {
func newPolicyResponse(policy, rule string, patchesStr []string, status engineapi.RuleStatus) engineapi.PolicyResponse {
var patches [][]byte
for _, p := range patchesStr {
patches = append(patches, []byte(p))
}
return response.PolicyResponse{
Policy: response.PolicySpec{Name: policy},
Rules: []response.RuleResponse{
return engineapi.PolicyResponse{
Policy: engineapi.PolicySpec{Name: policy},
Rules: []engineapi.RuleResponse{
{
Name: rule,
Patches: patches,
@ -27,8 +27,8 @@ func newPolicyResponse(policy, rule string, patchesStr []string, status response
}
}
func newEngineResponse(policy, rule string, patchesStr []string, status response.RuleStatus, annotation map[string]interface{}) *response.EngineResponse {
return &response.EngineResponse{
func newEngineResponse(policy, rule string, patchesStr []string, status engineapi.RuleStatus, annotation map[string]interface{}) *engineapi.EngineResponse {
return &engineapi.EngineResponse{
PatchedResource: unstructured.Unstructured{
Object: map[string]interface{}{
"metadata": map[string]interface{}{
@ -42,8 +42,8 @@ func newEngineResponse(policy, rule string, patchesStr []string, status response
func Test_empty_annotation(t *testing.T) {
patchStr := `{ "op": "replace", "path": "/spec/containers/0/imagePullPolicy", "value": "IfNotPresent" }`
engineResponse := newEngineResponse("mutate-container", "default-imagepullpolicy", []string{patchStr}, response.RuleStatusPass, nil)
annPatches := GenerateAnnotationPatches([]*response.EngineResponse{engineResponse}, logging.GlobalLogger())
engineResponse := newEngineResponse("mutate-container", "default-imagepullpolicy", []string{patchStr}, engineapi.RuleStatusPass, nil)
annPatches := GenerateAnnotationPatches([]*engineapi.EngineResponse{engineResponse}, logging.GlobalLogger())
expectedPatches := `{"path":"/metadata/annotations","op":"add","value":{"policies.kyverno.io/last-applied-patches":"default-imagepullpolicy.mutate-container.kyverno.io: replaced /spec/containers/0/imagePullPolicy\n"}}`
assert.Equal(t, string(annPatches[0]), expectedPatches)
}
@ -53,8 +53,8 @@ func Test_exist_annotation(t *testing.T) {
"test": "annotation",
}
patchStr := `{ "op": "replace", "path": "/spec/containers/0/imagePullPolicy", "value": "IfNotPresent" }`
engineResponse := newEngineResponse("mutate-container", "default-imagepullpolicy", []string{patchStr}, response.RuleStatusPass, annotation)
annPatches := GenerateAnnotationPatches([]*response.EngineResponse{engineResponse}, logging.GlobalLogger())
engineResponse := newEngineResponse("mutate-container", "default-imagepullpolicy", []string{patchStr}, engineapi.RuleStatusPass, annotation)
annPatches := GenerateAnnotationPatches([]*engineapi.EngineResponse{engineResponse}, logging.GlobalLogger())
expectedPatches := `{"path":"/metadata/annotations/policies.kyverno.io~1last-applied-patches","op":"add","value":"default-imagepullpolicy.mutate-container.kyverno.io: replaced /spec/containers/0/imagePullPolicy\n"}`
assert.Equal(t, string(annPatches[0]), expectedPatches)
}
@ -64,8 +64,8 @@ func Test_exist_kyverno_annotation(t *testing.T) {
"policies.kyverno.patches": "old-annotation",
}
patchStr := `{ "op": "replace", "path": "/spec/containers/0/imagePullPolicy", "value": "IfNotPresent" }`
engineResponse := newEngineResponse("mutate-container", "default-imagepullpolicy", []string{patchStr}, response.RuleStatusPass, annotation)
annPatches := GenerateAnnotationPatches([]*response.EngineResponse{engineResponse}, logging.GlobalLogger())
engineResponse := newEngineResponse("mutate-container", "default-imagepullpolicy", []string{patchStr}, engineapi.RuleStatusPass, annotation)
annPatches := GenerateAnnotationPatches([]*engineapi.EngineResponse{engineResponse}, logging.GlobalLogger())
expectedPatches := `{"path":"/metadata/annotations/policies.kyverno.io~1last-applied-patches","op":"add","value":"default-imagepullpolicy.mutate-container.kyverno.io: replaced /spec/containers/0/imagePullPolicy\n"}`
assert.Equal(t, string(annPatches[0]), expectedPatches)
}
@ -74,11 +74,11 @@ func Test_annotation_nil_patch(t *testing.T) {
annotation := map[string]interface{}{
"policies.kyverno.patches": "old-annotation",
}
engineResponse := newEngineResponse("mutate-container", "default-imagepullpolicy", nil, response.RuleStatusPass, annotation)
annPatches := GenerateAnnotationPatches([]*response.EngineResponse{engineResponse}, logging.GlobalLogger())
engineResponse := newEngineResponse("mutate-container", "default-imagepullpolicy", nil, engineapi.RuleStatusPass, annotation)
annPatches := GenerateAnnotationPatches([]*engineapi.EngineResponse{engineResponse}, logging.GlobalLogger())
assert.Assert(t, annPatches == nil)
engineResponseNew := newEngineResponse("mutate-container", "default-imagepullpolicy", []string{""}, response.RuleStatusPass, annotation)
annPatchesNew := GenerateAnnotationPatches([]*response.EngineResponse{engineResponseNew}, logging.GlobalLogger())
engineResponseNew := newEngineResponse("mutate-container", "default-imagepullpolicy", []string{""}, engineapi.RuleStatusPass, annotation)
annPatchesNew := GenerateAnnotationPatches([]*engineapi.EngineResponse{engineResponseNew}, logging.GlobalLogger())
assert.Assert(t, annPatchesNew == nil)
}
@ -86,8 +86,8 @@ func Test_annotation_failed_Patch(t *testing.T) {
annotation := map[string]interface{}{
"policies.kyverno.patches": "old-annotation",
}
engineResponse := newEngineResponse("mutate-container", "default-imagepullpolicy", nil, response.RuleStatusFail, annotation)
annPatches := GenerateAnnotationPatches([]*response.EngineResponse{engineResponse}, logging.GlobalLogger())
engineResponse := newEngineResponse("mutate-container", "default-imagepullpolicy", nil, engineapi.RuleStatusFail, annotation)
annPatches := GenerateAnnotationPatches([]*engineapi.EngineResponse{engineResponse}, logging.GlobalLogger())
assert.Assert(t, annPatches == nil)
}
@ -96,8 +96,8 @@ func Test_exist_patches(t *testing.T) {
"policies.kyverno.io/patches": "present",
}
patchStr := `{ "op": "replace", "path": "/spec/containers/0/imagePullPolicy", "value": "IfNotPresent" }`
engineResponse := newEngineResponse("mutate-container", "default-imagepullpolicy", []string{patchStr}, response.RuleStatusPass, annotation)
annPatches := GenerateAnnotationPatches([]*response.EngineResponse{engineResponse}, logging.GlobalLogger())
engineResponse := newEngineResponse("mutate-container", "default-imagepullpolicy", []string{patchStr}, engineapi.RuleStatusPass, annotation)
annPatches := GenerateAnnotationPatches([]*engineapi.EngineResponse{engineResponse}, logging.GlobalLogger())
expectedPatches1 := `{"path":"/metadata/annotations/policies.kyverno.io~1patches","op":"remove"}`
expectedPatches2 := `{"path":"/metadata/annotations/policies.kyverno.io~1last-applied-patches","op":"add","value":"default-imagepullpolicy.mutate-container.kyverno.io: replaced /spec/containers/0/imagePullPolicy\n"}`
assert.Equal(t, string(annPatches[0]), expectedPatches1)

View file

@ -2,11 +2,11 @@ package engine
import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
)
// IsResponseSuccessful return true if all responses are successful
func IsResponseSuccessful(engineReponses []*response.EngineResponse) bool {
func IsResponseSuccessful(engineReponses []*engineapi.EngineResponse) bool {
for _, er := range engineReponses {
if !er.IsSuccessful() {
return false
@ -18,7 +18,7 @@ func IsResponseSuccessful(engineReponses []*response.EngineResponse) bool {
// BlockRequest returns true when:
// 1. a policy fails (i.e. creates a violation) and validationFailureAction is set to 'enforce'
// 2. a policy has a processing error and failurePolicy is set to 'Fail`
func BlockRequest(er *response.EngineResponse, failurePolicy kyvernov1.FailurePolicyType) bool {
func BlockRequest(er *engineapi.EngineResponse, failurePolicy kyvernov1.FailurePolicyType) bool {
if er.IsFailed() && er.GetValidationFailureAction().Enforce() {
return true
}

View file

@ -3,7 +3,7 @@ package report
import (
kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
controllerutils "github.com/kyverno/kyverno/pkg/utils/controller"
admissionv1 "k8s.io/api/admission/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -32,7 +32,7 @@ func NewAdmissionReport(namespace, name, owner string, uid types.UID, gvk metav1
return report
}
func BuildAdmissionReport(resource unstructured.Unstructured, request *admissionv1.AdmissionRequest, gvk metav1.GroupVersionKind, responses ...*response.EngineResponse) kyvernov1alpha2.ReportInterface {
func BuildAdmissionReport(resource unstructured.Unstructured, request *admissionv1.AdmissionRequest, gvk metav1.GroupVersionKind, responses ...*engineapi.EngineResponse) kyvernov1alpha2.ReportInterface {
report := NewAdmissionReport(resource.GetNamespace(), string(request.UID), resource.GetName(), resource.GetUID(), gvk)
SetResourceVersionLabels(report, &resource)
SetResponses(report, responses...)

View file

@ -9,7 +9,7 @@ import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2"
policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"golang.org/x/exp/slices"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/cache"
@ -53,17 +53,17 @@ func CalculateSummary(results []policyreportv1alpha2.PolicyReportResult) (summar
return
}
func toPolicyResult(status response.RuleStatus) policyreportv1alpha2.PolicyResult {
func toPolicyResult(status engineapi.RuleStatus) policyreportv1alpha2.PolicyResult {
switch status {
case response.RuleStatusPass:
case engineapi.RuleStatusPass:
return policyreportv1alpha2.StatusPass
case response.RuleStatusFail:
case engineapi.RuleStatusFail:
return policyreportv1alpha2.StatusFail
case response.RuleStatusError:
case engineapi.RuleStatusError:
return policyreportv1alpha2.StatusError
case response.RuleStatusWarn:
case engineapi.RuleStatusWarn:
return policyreportv1alpha2.StatusWarn
case response.RuleStatusSkip:
case engineapi.RuleStatusSkip:
return policyreportv1alpha2.StatusSkip
}
return ""
@ -81,7 +81,7 @@ func severityFromString(severity string) policyreportv1alpha2.PolicySeverity {
return ""
}
func EngineResponseToReportResults(response *response.EngineResponse) []policyreportv1alpha2.PolicyReportResult {
func EngineResponseToReportResults(response *engineapi.EngineResponse) []policyreportv1alpha2.PolicyReportResult {
key, _ := cache.MetaNamespaceKeyFunc(response.Policy)
var results []policyreportv1alpha2.PolicyReportResult
for _, ruleResult := range response.PolicyResponse.Rules {
@ -153,7 +153,7 @@ func SetResults(report kyvernov1alpha2.ReportInterface, results ...policyreportv
report.SetSummary(CalculateSummary(results))
}
func SetResponses(report kyvernov1alpha2.ReportInterface, engineResponses ...*response.EngineResponse) {
func SetResponses(report kyvernov1alpha2.ReportInterface, engineResponses ...*engineapi.EngineResponse) {
var ruleResults []policyreportv1alpha2.PolicyReportResult
for _, result := range engineResponses {
SetPolicyLabel(report, result.Policy)

View file

@ -16,7 +16,7 @@ import (
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/registryclient"
@ -85,17 +85,17 @@ func (h *generationHandler) Handle(
) {
h.log.V(6).Info("update request for generate policy")
var engineResponses []*response.EngineResponse
var engineResponses []*engineapi.EngineResponse
if (request.Operation == admissionv1.Create || request.Operation == admissionv1.Update) && len(policies) != 0 {
for _, policy := range policies {
var rules []response.RuleResponse
var rules []engineapi.RuleResponse
policyContext := policyContext.WithPolicy(policy)
if request.Kind.Kind != "Namespace" && request.Namespace != "" {
policyContext = policyContext.WithNamespaceLabels(engineutils.GetNamespaceSelectorsFromNamespaceLister(request.Kind.Kind, request.Namespace, h.nsLister, h.log))
}
engineResponse := engine.ApplyBackgroundChecks(h.rclient, policyContext)
for _, rule := range engineResponse.PolicyResponse.Rules {
if rule.Status != response.RuleStatusPass {
if rule.Status != engineapi.RuleStatusPass {
h.deleteGR(ctx, engineResponse)
continue
}
@ -243,7 +243,7 @@ func (h *generationHandler) handleUpdateGenerateTargetResource(ctx context.Conte
}
}
func (h *generationHandler) deleteGR(ctx context.Context, engineResponse *response.EngineResponse) {
func (h *generationHandler) deleteGR(ctx context.Context, engineResponse *engineapi.EngineResponse) {
h.log.V(4).Info("querying all update requests")
selector := labels.SelectorFromSet(labels.Set(map[string]string{
kyvernov1beta1.URGeneratePolicyLabel: engineResponse.PolicyResponse.Policy.Name,

View file

@ -9,8 +9,8 @@ import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/clients/dclient"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
"github.com/kyverno/kyverno/pkg/engine/response"
"github.com/kyverno/kyverno/pkg/engine/variables"
"github.com/kyverno/kyverno/pkg/webhooks/updaterequest"
admissionv1 "k8s.io/api/admission/v1"
@ -122,7 +122,7 @@ func applyUpdateRequest(
grGenerator updaterequest.Generator,
userRequestInfo kyvernov1beta1.RequestInfo,
action admissionv1.Operation,
engineResponses ...*response.EngineResponse,
engineResponses ...*engineapi.EngineResponse,
) (failedUpdateRequest []updateRequestResponse) {
admissionRequestInfo := kyvernov1beta1.AdmissionRequestInfoObject{
AdmissionRequest: request,
@ -139,7 +139,7 @@ func applyUpdateRequest(
return
}
func transform(admissionRequestInfo kyvernov1beta1.AdmissionRequestInfoObject, userRequestInfo kyvernov1beta1.RequestInfo, er *response.EngineResponse, ruleType kyvernov1beta1.RequestType) kyvernov1beta1.UpdateRequestSpec {
func transform(admissionRequestInfo kyvernov1beta1.AdmissionRequestInfoObject, userRequestInfo kyvernov1beta1.RequestInfo, er *engineapi.EngineResponse, ruleType kyvernov1beta1.RequestType) kyvernov1beta1.UpdateRequestSpec {
var PolicyNameNamespaceKey string
if er.PolicyResponse.Policy.Namespace != "" {
PolicyNameNamespaceKey = er.PolicyResponse.Policy.Namespace + "/" + er.PolicyResponse.Policy.Name

View file

@ -11,7 +11,7 @@ import (
"github.com/kyverno/kyverno/pkg/client/clientset/versioned"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/registryclient"
"github.com/kyverno/kyverno/pkg/tracing"
@ -81,7 +81,7 @@ func (h *imageVerificationHandler) handleVerifyImages(
if len(policies) == 0 {
return true, "", nil, nil
}
var engineResponses []*response.EngineResponse
var engineResponses []*engineapi.EngineResponse
var patches [][]byte
verifiedImageData := &engine.ImageVerificationMetadata{}
for _, policy := range policies {
@ -152,7 +152,7 @@ func (v *imageVerificationHandler) handleAudit(
resource unstructured.Unstructured,
request *admissionv1.AdmissionRequest,
namespaceLabels map[string]string,
engineResponses ...*response.EngineResponse,
engineResponses ...*engineapi.EngineResponse,
) {
if !v.admissionReports {
return

View file

@ -9,7 +9,7 @@ import (
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/openapi"
@ -83,7 +83,7 @@ func (v *mutationHandler) applyMutations(
request *admissionv1.AdmissionRequest,
policies []kyvernov1.PolicyInterface,
policyContext *engine.PolicyContext,
) ([]byte, []*response.EngineResponse, error) {
) ([]byte, []*engineapi.EngineResponse, error) {
if len(policies) == 0 {
return nil, nil, nil
}
@ -93,7 +93,7 @@ func (v *mutationHandler) applyMutations(
}
var patches [][]byte
var engineResponses []*response.EngineResponse
var engineResponses []*engineapi.EngineResponse
for _, policy := range policies {
spec := policy.GetSpec()
@ -153,7 +153,7 @@ func (v *mutationHandler) applyMutations(
return jsonutils.JoinPatches(patches...), engineResponses, nil
}
func (h *mutationHandler) applyMutation(ctx context.Context, request *admissionv1.AdmissionRequest, policyContext *engine.PolicyContext) (*response.EngineResponse, [][]byte, error) {
func (h *mutationHandler) applyMutation(ctx context.Context, request *admissionv1.AdmissionRequest, policyContext *engine.PolicyContext) (*engineapi.EngineResponse, [][]byte, error) {
if request.Kind.Kind != "Namespace" && request.Namespace != "" {
policyContext = policyContext.WithNamespaceLabels(engineutils.GetNamespaceSelectorsFromNamespaceLister(request.Kind.Kind, request.Namespace, h.nsLister, h.log))
}
@ -175,7 +175,7 @@ func (h *mutationHandler) applyMutation(ctx context.Context, request *admissionv
return engineResponse, policyPatches, nil
}
func logMutationResponse(patches [][]byte, engineResponses []*response.EngineResponse, logger logr.Logger) {
func logMutationResponse(patches [][]byte, engineResponses []*engineapi.EngineResponse, logger logr.Logger) {
if len(patches) != 0 {
logger.V(4).Info("created patches", "count", len(patches))
}

View file

@ -9,7 +9,7 @@ import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/engine"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/webhooks/resource/generation"
webhookutils "github.com/kyverno/kyverno/pkg/webhooks/utils"
@ -34,19 +34,19 @@ func (h *handlers) handleMutateExisting(ctx context.Context, logger logr.Logger,
return
}
var engineResponses []*response.EngineResponse
var engineResponses []*engineapi.EngineResponse
for _, policy := range policies {
if !policy.GetSpec().IsMutateExisting() {
continue
}
logger.V(4).Info("update request for mutateExisting policy")
var rules []response.RuleResponse
var rules []engineapi.RuleResponse
policyContext := policyContext.WithPolicy(policy)
engineResponse := engine.ApplyBackgroundChecks(h.rclient, policyContext)
for _, rule := range engineResponse.PolicyResponse.Rules {
if rule.Status == response.RuleStatusPass {
if rule.Status == engineapi.RuleStatusPass {
rules = append(rules, rule)
}
}

View file

@ -7,7 +7,7 @@ import (
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
"github.com/kyverno/kyverno/pkg/webhooks/updaterequest"
@ -52,7 +52,7 @@ func applyUpdateRequest(
grGenerator updaterequest.Generator,
userRequestInfo kyvernov1beta1.RequestInfo,
action admissionv1.Operation,
engineResponses ...*response.EngineResponse,
engineResponses ...*engineapi.EngineResponse,
) (failedUpdateRequest []updateRequestResponse) {
admissionRequestInfo := kyvernov1beta1.AdmissionRequestInfoObject{
AdmissionRequest: request,
@ -69,7 +69,7 @@ func applyUpdateRequest(
return
}
func transform(admissionRequestInfo kyvernov1beta1.AdmissionRequestInfoObject, userRequestInfo kyvernov1beta1.RequestInfo, er *response.EngineResponse, ruleType kyvernov1beta1.RequestType) kyvernov1beta1.UpdateRequestSpec {
func transform(admissionRequestInfo kyvernov1beta1.AdmissionRequestInfoObject, userRequestInfo kyvernov1beta1.RequestInfo, er *engineapi.EngineResponse, ruleType kyvernov1beta1.RequestType) kyvernov1beta1.UpdateRequestSpec {
var PolicyNameNamespaceKey string
if er.PolicyResponse.Policy.Namespace != "" {
PolicyNameNamespaceKey = er.PolicyResponse.Policy.Namespace + "/" + er.PolicyResponse.Policy.Name

View file

@ -11,7 +11,7 @@ import (
"github.com/kyverno/kyverno/pkg/client/clientset/versioned"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/event"
"github.com/kyverno/kyverno/pkg/metrics"
"github.com/kyverno/kyverno/pkg/policycache"
@ -101,7 +101,7 @@ func (v *validationHandler) HandleValidation(
return true, "", nil
}
var engineResponses []*response.EngineResponse
var engineResponses []*engineapi.EngineResponse
failurePolicy := kyvernov1.Ignore
for _, policy := range policies {
tracing.ChildSpan(
@ -159,13 +159,13 @@ func (v *validationHandler) buildAuditResponses(
resource unstructured.Unstructured,
request *admissionv1.AdmissionRequest,
namespaceLabels map[string]string,
) ([]*response.EngineResponse, error) {
) ([]*engineapi.EngineResponse, error) {
policies := v.pCache.GetPolicies(policycache.ValidateAudit, request.Kind.Kind, request.Namespace)
policyContext, err := v.pcBuilder.Build(request)
if err != nil {
return nil, err
}
var responses []*response.EngineResponse
var responses []*engineapi.EngineResponse
for _, policy := range policies {
tracing.ChildSpan(
ctx,
@ -185,7 +185,7 @@ func (v *validationHandler) handleAudit(
resource unstructured.Unstructured,
request *admissionv1.AdmissionRequest,
namespaceLabels map[string]string,
engineResponses ...*response.EngineResponse,
engineResponses ...*engineapi.EngineResponse,
) {
if !v.admissionReports {
return

View file

@ -9,7 +9,7 @@ import (
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
log "github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/registryclient"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
@ -1072,7 +1072,7 @@ func TestValidate_failure_action_overrides(t *testing.T) {
}
failurePolicy := kyvernov1.Fail
blocked := webhookutils.BlockRequest([]*response.EngineResponse{er}, failurePolicy, log.WithName("WebhookServer"))
blocked := webhookutils.BlockRequest([]*engineapi.EngineResponse{er}, failurePolicy, log.WithName("WebhookServer"))
assert.Assert(t, tc.blocked == blocked)
})
}
@ -1129,7 +1129,7 @@ func Test_RuleSelector(t *testing.T) {
assert.Assert(t, resp.PolicyResponse.RulesErrorCount == 0)
log := log.WithName("Test_RuleSelector")
blocked := webhookutils.BlockRequest([]*response.EngineResponse{resp}, kyvernov1.Fail, log)
blocked := webhookutils.BlockRequest([]*engineapi.EngineResponse{resp}, kyvernov1.Fail, log)
assert.Assert(t, blocked == true)
applyOne := kyvernov1.ApplyOne
@ -1139,6 +1139,6 @@ func Test_RuleSelector(t *testing.T) {
assert.Assert(t, resp.PolicyResponse.RulesAppliedCount == 1)
assert.Assert(t, resp.PolicyResponse.RulesErrorCount == 0)
blocked = webhookutils.BlockRequest([]*response.EngineResponse{resp}, kyvernov1.Fail, log)
blocked = webhookutils.BlockRequest([]*engineapi.EngineResponse{resp}, kyvernov1.Fail, log)
assert.Assert(t, blocked == false)
}

View file

@ -5,7 +5,7 @@ import (
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
engineutils "github.com/kyverno/kyverno/pkg/utils/engine"
"gopkg.in/yaml.v2"
)
@ -23,7 +23,7 @@ func getAction(hasViolations bool, i int) string {
// returns true -> if there is even one policy that blocks resource request
// returns false -> if all the policies are meant to report only, we dont block resource request
func BlockRequest(engineResponses []*response.EngineResponse, failurePolicy kyvernov1.FailurePolicyType, log logr.Logger) bool {
func BlockRequest(engineResponses []*engineapi.EngineResponse, failurePolicy kyvernov1.FailurePolicyType, log logr.Logger) bool {
for _, er := range engineResponses {
if engineutils.BlockRequest(er, failurePolicy) {
log.V(2).Info("blocking admission request", "policy", er.PolicyResponse.Policy.Name)
@ -35,7 +35,7 @@ func BlockRequest(engineResponses []*response.EngineResponse, failurePolicy kyve
}
// GetBlockedMessages gets the error messages for rules with error or fail status
func GetBlockedMessages(engineResponses []*response.EngineResponse) string {
func GetBlockedMessages(engineResponses []*engineapi.EngineResponse) string {
if len(engineResponses) == 0 {
return ""
}
@ -44,9 +44,9 @@ func GetBlockedMessages(engineResponses []*response.EngineResponse) string {
for _, er := range engineResponses {
ruleToReason := make(map[string]string)
for _, rule := range er.PolicyResponse.Rules {
if rule.Status != response.RuleStatusPass {
if rule.Status != engineapi.RuleStatusPass {
ruleToReason[rule.Name] = rule.Message
if rule.Status == response.RuleStatusFail {
if rule.Status == engineapi.RuleStatusFail {
hasViolations = true
}
}

View file

@ -5,7 +5,7 @@ import (
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/stretchr/testify/assert"
)
@ -45,7 +45,7 @@ func Test_getAction(t *testing.T) {
func TestBlockRequest(t *testing.T) {
type args struct {
engineResponses []*response.EngineResponse
engineResponses []*engineapi.EngineResponse
failurePolicy kyvernov1.FailurePolicyType
log logr.Logger
}
@ -56,14 +56,14 @@ func TestBlockRequest(t *testing.T) {
}{{
name: "failure - enforce",
args: args{
engineResponses: []*response.EngineResponse{
engineResponses: []*engineapi.EngineResponse{
{
PolicyResponse: response.PolicyResponse{
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Enforce",
Rules: []response.RuleResponse{
Rules: []engineapi.RuleResponse{
{
Name: "rule-fail",
Status: response.RuleStatusFail,
Status: engineapi.RuleStatusFail,
Message: "message fail",
},
},
@ -77,14 +77,14 @@ func TestBlockRequest(t *testing.T) {
}, {
name: "failure - audit",
args: args{
engineResponses: []*response.EngineResponse{
engineResponses: []*engineapi.EngineResponse{
{
PolicyResponse: response.PolicyResponse{
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []response.RuleResponse{
Rules: []engineapi.RuleResponse{
{
Name: "rule-fail",
Status: response.RuleStatusFail,
Status: engineapi.RuleStatusFail,
Message: "message fail",
},
},
@ -98,14 +98,14 @@ func TestBlockRequest(t *testing.T) {
}, {
name: "error - fail",
args: args{
engineResponses: []*response.EngineResponse{
engineResponses: []*engineapi.EngineResponse{
{
PolicyResponse: response.PolicyResponse{
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []response.RuleResponse{
Rules: []engineapi.RuleResponse{
{
Name: "rule-error",
Status: response.RuleStatusError,
Status: engineapi.RuleStatusError,
Message: "message error",
},
},
@ -119,14 +119,14 @@ func TestBlockRequest(t *testing.T) {
}, {
name: "error - ignore",
args: args{
engineResponses: []*response.EngineResponse{
engineResponses: []*engineapi.EngineResponse{
{
PolicyResponse: response.PolicyResponse{
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []response.RuleResponse{
Rules: []engineapi.RuleResponse{
{
Name: "rule-error",
Status: response.RuleStatusError,
Status: engineapi.RuleStatusError,
Message: "message error",
},
},
@ -140,14 +140,14 @@ func TestBlockRequest(t *testing.T) {
}, {
name: "warning - ignore",
args: args{
engineResponses: []*response.EngineResponse{
engineResponses: []*engineapi.EngineResponse{
{
PolicyResponse: response.PolicyResponse{
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []response.RuleResponse{
Rules: []engineapi.RuleResponse{
{
Name: "rule-warning",
Status: response.RuleStatusWarn,
Status: engineapi.RuleStatusWarn,
Message: "message warning",
},
},
@ -161,14 +161,14 @@ func TestBlockRequest(t *testing.T) {
}, {
name: "warning - fail",
args: args{
engineResponses: []*response.EngineResponse{
engineResponses: []*engineapi.EngineResponse{
{
PolicyResponse: response.PolicyResponse{
PolicyResponse: engineapi.PolicyResponse{
ValidationFailureAction: "Audit",
Rules: []response.RuleResponse{
Rules: []engineapi.RuleResponse{
{
Name: "rule-warning",
Status: response.RuleStatusWarn,
Status: engineapi.RuleStatusWarn,
Message: "message warning",
},
},
@ -190,7 +190,7 @@ func TestBlockRequest(t *testing.T) {
func TestGetBlockedMessages(t *testing.T) {
type args struct {
engineResponses []*response.EngineResponse
engineResponses []*engineapi.EngineResponse
}
tests := []struct {
name string
@ -199,21 +199,21 @@ func TestGetBlockedMessages(t *testing.T) {
}{{
name: "failure - enforce",
args: args{
engineResponses: []*response.EngineResponse{
engineResponses: []*engineapi.EngineResponse{
{
PolicyResponse: response.PolicyResponse{
Policy: response.PolicySpec{
PolicyResponse: engineapi.PolicyResponse{
Policy: engineapi.PolicySpec{
Name: "test",
},
ValidationFailureAction: "Enforce",
Rules: []response.RuleResponse{
Rules: []engineapi.RuleResponse{
{
Name: "rule-fail",
Status: response.RuleStatusFail,
Status: engineapi.RuleStatusFail,
Message: "message fail",
},
},
Resource: response.ResourceSpec{
Resource: engineapi.ResourceSpec{
Kind: "foo",
Namespace: "bar",
Name: "baz",
@ -226,21 +226,21 @@ func TestGetBlockedMessages(t *testing.T) {
}, {
name: "error - enforce",
args: args{
engineResponses: []*response.EngineResponse{
engineResponses: []*engineapi.EngineResponse{
{
PolicyResponse: response.PolicyResponse{
Policy: response.PolicySpec{
PolicyResponse: engineapi.PolicyResponse{
Policy: engineapi.PolicySpec{
Name: "test",
},
ValidationFailureAction: "Enforce",
Rules: []response.RuleResponse{
Rules: []engineapi.RuleResponse{
{
Name: "rule-error",
Status: response.RuleStatusError,
Status: engineapi.RuleStatusError,
Message: "message error",
},
},
Resource: response.ResourceSpec{
Resource: engineapi.ResourceSpec{
Kind: "foo",
Namespace: "bar",
Name: "baz",
@ -253,26 +253,26 @@ func TestGetBlockedMessages(t *testing.T) {
}, {
name: "error and failure - enforce",
args: args{
engineResponses: []*response.EngineResponse{
engineResponses: []*engineapi.EngineResponse{
{
PolicyResponse: response.PolicyResponse{
Policy: response.PolicySpec{
PolicyResponse: engineapi.PolicyResponse{
Policy: engineapi.PolicySpec{
Name: "test",
},
ValidationFailureAction: "Enforce",
Rules: []response.RuleResponse{
Rules: []engineapi.RuleResponse{
{
Name: "rule-fail",
Status: response.RuleStatusFail,
Status: engineapi.RuleStatusFail,
Message: "message fail",
},
{
Name: "rule-error",
Status: response.RuleStatusError,
Status: engineapi.RuleStatusError,
Message: "message error",
},
},
Resource: response.ResourceSpec{
Resource: engineapi.ResourceSpec{
Kind: "foo",
Namespace: "bar",
Name: "baz",

View file

@ -4,10 +4,10 @@ import (
"fmt"
"strings"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
)
func GetErrorMsg(engineReponses []*response.EngineResponse) string {
func GetErrorMsg(engineReponses []*engineapi.EngineResponse) string {
var str []string
var resourceInfo string
for _, er := range engineReponses {
@ -16,7 +16,7 @@ func GetErrorMsg(engineReponses []*response.EngineResponse) string {
resourceInfo = fmt.Sprintf("%s/%s/%s", er.PolicyResponse.Resource.Kind, er.PolicyResponse.Resource.Namespace, er.PolicyResponse.Resource.Name)
str = append(str, fmt.Sprintf("failed policy %s:", er.PolicyResponse.Policy.Name))
for _, rule := range er.PolicyResponse.Rules {
if rule.Status != response.RuleStatusPass {
if rule.Status != engineapi.RuleStatusPass {
str = append(str, rule.ToString())
}
}

View file

@ -3,12 +3,12 @@ package utils
import (
"strings"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/event"
)
// GenerateEvents generates event info for the engine responses
func GenerateEvents(engineResponses []*response.EngineResponse, blocked bool) []event.Info {
func GenerateEvents(engineResponses []*engineapi.EngineResponse, blocked bool) []event.Info {
var events []event.Info
// - Some/All policies fail or error
// - report failure events on policy
@ -23,7 +23,7 @@ func GenerateEvents(engineResponses []*response.EngineResponse, blocked bool) []
}
if !er.IsSuccessful() {
for i, ruleResp := range er.PolicyResponse.Rules {
if ruleResp.Status == response.RuleStatusFail || ruleResp.Status == response.RuleStatusError {
if ruleResp.Status == engineapi.RuleStatusFail || ruleResp.Status == engineapi.RuleStatusError {
e := event.NewPolicyFailEvent(event.AdmissionController, event.PolicyViolation, er, &er.PolicyResponse.Rules[i], blocked)
events = append(events, e)
}
@ -35,7 +35,7 @@ func GenerateEvents(engineResponses []*response.EngineResponse, blocked bool) []
} else if er.IsSkipped() { // Handle PolicyException Event
for i, ruleResp := range er.PolicyResponse.Rules {
isException := strings.Contains(ruleResp.Message, "rule skipped due to policy exception")
if ruleResp.Status == response.RuleStatusSkip && !blocked && isException {
if ruleResp.Status == engineapi.RuleStatusSkip && !blocked && isException {
events = append(events, event.NewPolicyExceptionEvents(er, &er.PolicyResponse.Rules[i])...)
}
}

View file

@ -6,7 +6,7 @@ import (
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/kyverno/kyverno/pkg/metrics"
policyExecutionDuration "github.com/kyverno/kyverno/pkg/metrics/policyexecutionduration"
policyResults "github.com/kyverno/kyverno/pkg/metrics/policyresults"
@ -26,19 +26,19 @@ func registerMetric(logger logr.Logger, m string, requestOperation string, r rep
// POLICY RESULTS
func RegisterPolicyResultsMetricMutation(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse) {
func RegisterPolicyResultsMetricMutation(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse) {
registerMetric(logger, "kyverno_policy_results_total", requestOperation, func(op metrics.ResourceRequestOperation) error {
return policyResults.ProcessEngineResponse(ctx, metricsConfig, policy, engineResponse, metrics.AdmissionRequest, op)
})
}
func RegisterPolicyResultsMetricValidation(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse) {
func RegisterPolicyResultsMetricValidation(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse) {
registerMetric(logger, "kyverno_policy_results_total", requestOperation, func(op metrics.ResourceRequestOperation) error {
return policyResults.ProcessEngineResponse(ctx, metricsConfig, policy, engineResponse, metrics.AdmissionRequest, op)
})
}
func RegisterPolicyResultsMetricGeneration(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse) {
func RegisterPolicyResultsMetricGeneration(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse) {
registerMetric(logger, "kyverno_policy_results_total", requestOperation, func(op metrics.ResourceRequestOperation) error {
return policyResults.ProcessEngineResponse(ctx, metricsConfig, policy, engineResponse, metrics.AdmissionRequest, op)
})
@ -46,19 +46,19 @@ func RegisterPolicyResultsMetricGeneration(ctx context.Context, logger logr.Logg
// POLICY EXECUTION
func RegisterPolicyExecutionDurationMetricMutate(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse) {
func RegisterPolicyExecutionDurationMetricMutate(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse) {
registerMetric(logger, "kyverno_policy_execution_duration_seconds", requestOperation, func(op metrics.ResourceRequestOperation) error {
return policyExecutionDuration.ProcessEngineResponse(ctx, metricsConfig, policy, engineResponse, metrics.AdmissionRequest, op)
})
}
func RegisterPolicyExecutionDurationMetricValidate(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse) {
func RegisterPolicyExecutionDurationMetricValidate(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse) {
registerMetric(logger, "kyverno_policy_execution_duration_seconds", requestOperation, func(op metrics.ResourceRequestOperation) error {
return policyExecutionDuration.ProcessEngineResponse(ctx, metricsConfig, policy, engineResponse, metrics.AdmissionRequest, op)
})
}
func RegisterPolicyExecutionDurationMetricGenerate(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse) {
func RegisterPolicyExecutionDurationMetricGenerate(ctx context.Context, logger logr.Logger, metricsConfig metrics.MetricsConfigManager, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse engineapi.EngineResponse) {
registerMetric(logger, "kyverno_policy_execution_duration_seconds", requestOperation, func(op metrics.ResourceRequestOperation) error {
return policyExecutionDuration.ProcessEngineResponse(ctx, metricsConfig, policy, engineResponse, metrics.AdmissionRequest, op)
})

View file

@ -3,14 +3,14 @@ package utils
import (
"fmt"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
)
func GetWarningMessages(engineResponses []*response.EngineResponse) []string {
func GetWarningMessages(engineResponses []*engineapi.EngineResponse) []string {
var warnings []string
for _, er := range engineResponses {
for _, rule := range er.PolicyResponse.Rules {
if rule.Status != response.RuleStatusPass && rule.Status != response.RuleStatusSkip {
if rule.Status != engineapi.RuleStatusPass && rule.Status != engineapi.RuleStatusSkip {
msg := fmt.Sprintf("policy %s.%s: %s", er.Policy.GetName(), rule.Name, rule.Message)
warnings = append(warnings, msg)
}

View file

@ -4,14 +4,14 @@ import (
"testing"
v1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/engine/response"
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestGetWarningMessages(t *testing.T) {
type args struct {
engineResponses []*response.EngineResponse
engineResponses []*engineapi.EngineResponse
}
tests := []struct {
name string
@ -23,22 +23,22 @@ func TestGetWarningMessages(t *testing.T) {
want: nil,
}, {
name: "enmpty response",
args: args{[]*response.EngineResponse{}},
args: args{[]*engineapi.EngineResponse{}},
want: nil,
}, {
name: "warning",
args: args{[]*response.EngineResponse{
args: args{[]*engineapi.EngineResponse{
{
Policy: &v1.ClusterPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
},
PolicyResponse: response.PolicyResponse{
Rules: []response.RuleResponse{
PolicyResponse: engineapi.PolicyResponse{
Rules: []engineapi.RuleResponse{
{
Name: "rule",
Status: response.RuleStatusWarn,
Status: engineapi.RuleStatusWarn,
Message: "message warn",
},
},
@ -50,38 +50,38 @@ func TestGetWarningMessages(t *testing.T) {
},
}, {
name: "multiple rules",
args: args{[]*response.EngineResponse{
args: args{[]*engineapi.EngineResponse{
{
Policy: &v1.ClusterPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
},
PolicyResponse: response.PolicyResponse{
Rules: []response.RuleResponse{
PolicyResponse: engineapi.PolicyResponse{
Rules: []engineapi.RuleResponse{
{
Name: "rule-pass",
Status: response.RuleStatusPass,
Status: engineapi.RuleStatusPass,
Message: "message pass",
},
{
Name: "rule-warn",
Status: response.RuleStatusWarn,
Status: engineapi.RuleStatusWarn,
Message: "message warn",
},
{
Name: "rule-fail",
Status: response.RuleStatusFail,
Status: engineapi.RuleStatusFail,
Message: "message fail",
},
{
Name: "rule-error",
Status: response.RuleStatusError,
Status: engineapi.RuleStatusError,
Message: "message error",
},
{
Name: "rule-skip",
Status: response.RuleStatusSkip,
Status: engineapi.RuleStatusSkip,
Message: "message skip",
},
},