mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 16:06:56 +00:00
fix: autogen refactor (#12286)
* fix: autogen refactor Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * fix: more refactor Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> --------- Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com>
This commit is contained in:
parent
bfb4d20cb3
commit
0dda60bf12
5 changed files with 45 additions and 75 deletions
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/kyverno/kyverno/api/kyverno"
|
"github.com/kyverno/kyverno/api/kyverno"
|
||||||
policiesv1alpha1 "github.com/kyverno/kyverno/api/policies.kyverno.io/v1alpha1"
|
policiesv1alpha1 "github.com/kyverno/kyverno/api/policies.kyverno.io/v1alpha1"
|
||||||
|
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,8 +18,7 @@ var podControllers = sets.New("daemonsets", "deployments", "jobs", "statefulsets
|
||||||
// - Pod is not defined
|
// - Pod is not defined
|
||||||
//
|
//
|
||||||
// Otherwise it returns all pod controllers
|
// Otherwise it returns all pod controllers
|
||||||
func CanAutoGen(spec *policiesv1alpha1.ValidatingPolicySpec) (bool, sets.Set[string]) {
|
func CanAutoGen(match *admissionregistrationv1.MatchResources) (bool, sets.Set[string]) {
|
||||||
match := spec.MatchConstraints
|
|
||||||
if match.NamespaceSelector != nil {
|
if match.NamespaceSelector != nil {
|
||||||
if len(match.NamespaceSelector.MatchLabels) > 0 || len(match.NamespaceSelector.MatchExpressions) > 0 {
|
if len(match.NamespaceSelector.MatchLabels) > 0 || len(match.NamespaceSelector.MatchExpressions) > 0 {
|
||||||
return false, sets.New[string]()
|
return false, sets.New[string]()
|
||||||
|
@ -50,7 +50,7 @@ func generateRules(spec *policiesv1alpha1.ValidatingPolicySpec, controllers stri
|
||||||
// strip cronjobs from controllers if exist
|
// strip cronjobs from controllers if exist
|
||||||
isRemoved, controllers := stripCronJob(controllers)
|
isRemoved, controllers := stripCronJob(controllers)
|
||||||
// generate rule for pod controllers
|
// generate rule for pod controllers
|
||||||
if genRule, err := generateRuleForControllers(spec, controllers); err == nil {
|
if genRule, err := generatePodControllerRule(spec, controllers); err == nil {
|
||||||
genRules = append(genRules, *genRule.DeepCopy())
|
genRules = append(genRules, *genRule.DeepCopy())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ func stripCronJob(controllers string) (bool, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ComputeRules(policy policiesv1alpha1.GenericPolicy) []policiesv1alpha1.AutogenRule {
|
func ComputeRules(policy policiesv1alpha1.GenericPolicy) []policiesv1alpha1.AutogenRule {
|
||||||
applyAutoGen, desiredControllers := CanAutoGen(policy.GetSpec())
|
applyAutoGen, desiredControllers := CanAutoGen(policy.GetSpec().MatchConstraints)
|
||||||
if !applyAutoGen {
|
if !applyAutoGen {
|
||||||
return []policiesv1alpha1.AutogenRule{}
|
return []policiesv1alpha1.AutogenRule{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,7 +272,7 @@ func Test_CanAutoGen(t *testing.T) {
|
||||||
err := json.Unmarshal(test.policy, &policy)
|
err := json.Unmarshal(test.policy, &policy)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
applyAutoGen, controllers := CanAutoGen(&policy.Spec)
|
applyAutoGen, controllers := CanAutoGen(policy.Spec.MatchConstraints)
|
||||||
if !applyAutoGen {
|
if !applyAutoGen {
|
||||||
controllers = sets.New("none")
|
controllers = sets.New("none")
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,68 +10,20 @@ import (
|
||||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func generateCronJobRule(spec *policiesv1alpha1.ValidatingPolicySpec, controllers string) (*policiesv1alpha1.AutogenRule, error) {
|
type autogencontroller string
|
||||||
operations := spec.MatchConstraints.ResourceRules[0].Operations
|
|
||||||
// create a resource rule for the cronjob resource
|
|
||||||
matchConstraints := createMatchConstraints(controllers, operations)
|
|
||||||
|
|
||||||
// convert match conditions
|
var (
|
||||||
matchConditions, err := convertMatchconditions(spec.MatchConditions, "cronjobs", cronjobMatchConditionName, cronJobMatchConditionExpression)
|
PODS autogencontroller = "pods"
|
||||||
if err != nil {
|
CRONJOBS autogencontroller = "cronjobs"
|
||||||
return nil, err
|
)
|
||||||
}
|
|
||||||
|
|
||||||
// convert validations
|
func generateRuleForControllers(spec *policiesv1alpha1.ValidatingPolicySpec, controllers string, resource autogencontroller) (*policiesv1alpha1.AutogenRule, error) {
|
||||||
validations := spec.Validations
|
|
||||||
for i := range validations {
|
|
||||||
if bytes, err := json.Marshal(validations[i]); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
bytes = updateFields(bytes, controllers)
|
|
||||||
if err := json.Unmarshal(bytes, &validations[i]); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert audit annotations
|
|
||||||
auditAnnotations := spec.AuditAnnotations
|
|
||||||
if bytes, err := json.Marshal(auditAnnotations); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
bytes = updateFields(bytes, controllers)
|
|
||||||
if err := json.Unmarshal(bytes, &auditAnnotations); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert variables
|
|
||||||
variables := spec.Variables
|
|
||||||
if bytes, err := json.Marshal(variables); err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else {
|
|
||||||
bytes = updateFields(bytes, controllers)
|
|
||||||
if err := json.Unmarshal(bytes, &variables); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &policiesv1alpha1.AutogenRule{
|
|
||||||
MatchConstraints: matchConstraints,
|
|
||||||
MatchConditions: matchConditions,
|
|
||||||
Validations: validations,
|
|
||||||
AuditAnnotation: auditAnnotations,
|
|
||||||
Variables: variables,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateRuleForControllers(spec *policiesv1alpha1.ValidatingPolicySpec, controllers string) (*policiesv1alpha1.AutogenRule, error) {
|
|
||||||
operations := spec.MatchConstraints.ResourceRules[0].Operations
|
operations := spec.MatchConstraints.ResourceRules[0].Operations
|
||||||
// create a resource rule for pod controllers
|
// create a resource rule for pod controllers
|
||||||
matchConstraints := createMatchConstraints(controllers, operations)
|
matchConstraints := createMatchConstraints(controllers, operations)
|
||||||
|
|
||||||
// convert match conditions
|
// convert match conditions
|
||||||
matchConditions, err := convertMatchconditions(spec.MatchConditions, "pods", podControllerMatchConditionName, podControllersMatchConditionExpression)
|
matchConditions, err := convertMatchconditions(spec.MatchConditions, resource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -81,7 +33,7 @@ func generateRuleForControllers(spec *policiesv1alpha1.ValidatingPolicySpec, con
|
||||||
if bytes, err := json.Marshal(validations); err != nil {
|
if bytes, err := json.Marshal(validations); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
bytes = updateFields(bytes, "pods")
|
bytes = updateFields(bytes, resource)
|
||||||
if err := json.Unmarshal(bytes, &validations); err != nil {
|
if err := json.Unmarshal(bytes, &validations); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -92,7 +44,7 @@ func generateRuleForControllers(spec *policiesv1alpha1.ValidatingPolicySpec, con
|
||||||
if bytes, err := json.Marshal(auditAnnotations); err != nil {
|
if bytes, err := json.Marshal(auditAnnotations); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
bytes = updateFields(bytes, "pods")
|
bytes = updateFields(bytes, resource)
|
||||||
if err := json.Unmarshal(bytes, &auditAnnotations); err != nil {
|
if err := json.Unmarshal(bytes, &auditAnnotations); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -103,7 +55,7 @@ func generateRuleForControllers(spec *policiesv1alpha1.ValidatingPolicySpec, con
|
||||||
if bytes, err := json.Marshal(variables); err != nil {
|
if bytes, err := json.Marshal(variables); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
bytes = updateFields(bytes, "pods")
|
bytes = updateFields(bytes, resource)
|
||||||
if err := json.Unmarshal(bytes, &variables); err != nil {
|
if err := json.Unmarshal(bytes, &variables); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -118,6 +70,14 @@ func generateRuleForControllers(spec *policiesv1alpha1.ValidatingPolicySpec, con
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateCronJobRule(spec *policiesv1alpha1.ValidatingPolicySpec, controllers string) (*policiesv1alpha1.AutogenRule, error) {
|
||||||
|
return generateRuleForControllers(spec, controllers, CRONJOBS)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generatePodControllerRule(spec *policiesv1alpha1.ValidatingPolicySpec, controllers string) (*policiesv1alpha1.AutogenRule, error) {
|
||||||
|
return generateRuleForControllers(spec, controllers, PODS)
|
||||||
|
}
|
||||||
|
|
||||||
func createMatchConstraints(controllers string, operations []admissionregistrationv1.OperationType) *admissionregistrationv1.MatchResources {
|
func createMatchConstraints(controllers string, operations []admissionregistrationv1.OperationType) *admissionregistrationv1.MatchResources {
|
||||||
resources := strings.Split(controllers, ",")
|
resources := strings.Split(controllers, ",")
|
||||||
|
|
||||||
|
@ -164,7 +124,17 @@ func createMatchConstraints(controllers string, operations []admissionregistrati
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertMatchconditions(conditions []admissionregistrationv1.MatchCondition, resource, name, expression string) (matchConditions []admissionregistrationv1.MatchCondition, err error) {
|
func convertMatchconditions(conditions []admissionregistrationv1.MatchCondition, resource autogencontroller) (matchConditions []admissionregistrationv1.MatchCondition, err error) {
|
||||||
|
var name, expression string
|
||||||
|
switch resource {
|
||||||
|
case PODS:
|
||||||
|
name = podControllerMatchConditionName
|
||||||
|
expression = podControllersMatchConditionExpression
|
||||||
|
case CRONJOBS:
|
||||||
|
name = cronjobMatchConditionName
|
||||||
|
expression = cronJobMatchConditionExpression
|
||||||
|
}
|
||||||
|
|
||||||
for _, m := range conditions {
|
for _, m := range conditions {
|
||||||
m.Name = name + m.Name
|
m.Name = name + m.Name
|
||||||
m.Expression = expression + m.Expression
|
m.Expression = expression + m.Expression
|
||||||
|
@ -201,13 +171,13 @@ var (
|
||||||
cronJobMatchConditionExpression = "!(object.kind =='CronJob') || "
|
cronJobMatchConditionExpression = "!(object.kind =='CronJob') || "
|
||||||
)
|
)
|
||||||
|
|
||||||
func updateFields(data []byte, resource string) []byte {
|
func updateFields(data []byte, resource autogencontroller) []byte {
|
||||||
switch resource {
|
switch resource {
|
||||||
case "pods":
|
case PODS:
|
||||||
for _, replacement := range podReplacementRules {
|
for _, replacement := range podReplacementRules {
|
||||||
data = bytes.ReplaceAll(data, replacement[0], replacement[1])
|
data = bytes.ReplaceAll(data, replacement[0], replacement[1])
|
||||||
}
|
}
|
||||||
case "cronjobs":
|
case CRONJOBS:
|
||||||
for _, replacement := range cronJobReplacementRules {
|
for _, replacement := range cronJobReplacementRules {
|
||||||
data = bytes.ReplaceAll(data, replacement[0], replacement[1])
|
data = bytes.ReplaceAll(data, replacement[0], replacement[1])
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,11 +199,11 @@ func TestGenerateRuleForControllers(t *testing.T) {
|
||||||
err := json.Unmarshal(test.policySpec, &spec)
|
err := json.Unmarshal(test.policySpec, &spec)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
genRule, err := generateRuleForControllers(spec, test.controllers)
|
genRule, err := generatePodControllerRule(spec, test.controllers)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
if !reflect.DeepEqual(genRule, &test.generatedRule) {
|
if !reflect.DeepEqual(genRule, &test.generatedRule) {
|
||||||
t.Errorf("generateRuleForControllers() = %v, want %v", genRule, test.generatedRule)
|
t.Errorf("generatePodControllerRule() = %v, want %v", genRule, test.generatedRule)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -415,7 +415,7 @@ func TestGenerateCronJobRule(t *testing.T) {
|
||||||
func TestUpdateGenRuleByte(t *testing.T) {
|
func TestUpdateGenRuleByte(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
pbyte []byte
|
pbyte []byte
|
||||||
resource string
|
resource autogencontroller
|
||||||
want []byte
|
want []byte
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,7 +52,7 @@ func buildWebhookRules(cfg config.Configuration, server string, servicePort int3
|
||||||
fineGrainedWebhook := false
|
fineGrainedWebhook := false
|
||||||
if vpol.GetMatchConditions() != nil {
|
if vpol.GetMatchConditions() != nil {
|
||||||
for _, m := range vpol.GetMatchConditions() {
|
for _, m := range vpol.GetMatchConditions() {
|
||||||
if ok, _ := autogen.CanAutoGen(vpol.GetSpec()); ok {
|
if ok, _ := autogen.CanAutoGen(vpol.GetSpec().MatchConstraints); ok {
|
||||||
webhook.MatchConditions = append(webhook.MatchConditions, admissionregistrationv1.MatchCondition{
|
webhook.MatchConditions = append(webhook.MatchConditions, admissionregistrationv1.MatchCondition{
|
||||||
Name: m.Name,
|
Name: m.Name,
|
||||||
Expression: "!(object.kind == 'Pod') || " + m.Expression,
|
Expression: "!(object.kind == 'Pod') || " + m.Expression,
|
||||||
|
|
Loading…
Add table
Reference in a new issue