mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
3510998d4f
* feat: support CEL expression warnings Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: allow the policy creation but return warnings to the API server Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix tests Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> --------- Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> Signed-off-by: ShutingZhao <shuting@nirmata.com> Co-authored-by: ShutingZhao <shuting@nirmata.com>
95 lines
3.4 KiB
Go
95 lines
3.4 KiB
Go
package policy
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"slices"
|
|
|
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
|
authChecker "github.com/kyverno/kyverno/pkg/auth/checker"
|
|
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
|
"github.com/kyverno/kyverno/pkg/logging"
|
|
"github.com/kyverno/kyverno/pkg/policy/auth"
|
|
"github.com/kyverno/kyverno/pkg/policy/auth/fake"
|
|
"github.com/kyverno/kyverno/pkg/policy/generate"
|
|
"github.com/kyverno/kyverno/pkg/policy/mutate"
|
|
"github.com/kyverno/kyverno/pkg/policy/validate"
|
|
"github.com/kyverno/kyverno/pkg/toggle"
|
|
"github.com/kyverno/kyverno/pkg/validatingadmissionpolicy"
|
|
)
|
|
|
|
// Validation provides methods to validate a rule
|
|
type Validation interface {
|
|
Validate(ctx context.Context) (string, error)
|
|
}
|
|
|
|
// validateAction performs validation on the rule actions
|
|
// - Mutate
|
|
// - Validation
|
|
// - Generate
|
|
func validateActions(idx int, rule *kyvernov1.Rule, client dclient.Interface, mock bool, username string) (string, error) {
|
|
if rule == nil {
|
|
return "", nil
|
|
}
|
|
|
|
var checker Validation
|
|
// Mutate
|
|
if rule.HasMutate() {
|
|
var authChecker auth.Operations
|
|
if mock {
|
|
authChecker = fake.NewFakeAuth()
|
|
} else {
|
|
authChecker = auth.NewAuth(client, username, logging.GlobalLogger())
|
|
}
|
|
checker = mutate.NewMutateFactory(rule.Mutation, authChecker, username)
|
|
if path, err := checker.Validate(context.TODO()); err != nil {
|
|
return "", fmt.Errorf("path: spec.rules[%d].mutate.%s.: %v", idx, path, err)
|
|
}
|
|
}
|
|
|
|
// Validate
|
|
if rule.HasValidate() {
|
|
checker = validate.NewValidateFactory(&rule.Validation)
|
|
if path, err := checker.Validate(context.TODO()); err != nil {
|
|
return "", fmt.Errorf("path: spec.rules[%d].validate.%s.: %v", idx, path, err)
|
|
}
|
|
|
|
// In case generateValidatingAdmissionPolicy flag is set to true, check the required permissions.
|
|
if toggle.FromContext(context.TODO()).GenerateValidatingAdmissionPolicy() {
|
|
authCheck := authChecker.NewSelfChecker(client.GetKubeClient().AuthorizationV1().SelfSubjectAccessReviews())
|
|
// check if the controller has the required permissions to generate validating admission policies.
|
|
if !validatingadmissionpolicy.HasValidatingAdmissionPolicyPermission(authCheck) {
|
|
return "insufficient permissions to generate ValidatingAdmissionPolicies", nil
|
|
}
|
|
|
|
// check if the controller has the required permissions to generate validating admission policy bindings.
|
|
if !validatingadmissionpolicy.HasValidatingAdmissionPolicyBindingPermission(authCheck) {
|
|
return "insufficient permissions to generate ValidatingAdmissionPolicyBindings", nil
|
|
}
|
|
}
|
|
}
|
|
|
|
// Generate
|
|
if rule.HasGenerate() {
|
|
// TODO: this check is there to support offline validations
|
|
// generate uses selfSubjectReviews to verify actions
|
|
// this need to modified to use different implementation for online and offline mode
|
|
if mock {
|
|
checker = generate.NewFakeGenerate(rule.Generation)
|
|
if path, err := checker.Validate(context.TODO()); err != nil {
|
|
return "", fmt.Errorf("path: spec.rules[%d].generate.%s.: %v", idx, path, err)
|
|
}
|
|
} else {
|
|
checker = generate.NewGenerateFactory(client, rule.Generation, username, logging.GlobalLogger())
|
|
if path, err := checker.Validate(context.TODO()); err != nil {
|
|
return "", fmt.Errorf("path: spec.rules[%d].generate.%s.: %v", idx, path, err)
|
|
}
|
|
}
|
|
|
|
if slices.Contains(rule.MatchResources.Kinds, rule.Generation.Kind) {
|
|
return "", fmt.Errorf("generation kind and match resource kind should not be the same")
|
|
}
|
|
}
|
|
|
|
return "", nil
|
|
}
|