mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-07 00:17:13 +00:00
103 lines
3.1 KiB
Go
103 lines
3.1 KiB
Go
package autogen
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/kyverno/kyverno/api/kyverno"
|
|
policiesv1alpha1 "github.com/kyverno/kyverno/api/policies.kyverno.io/v1alpha1"
|
|
"k8s.io/apimachinery/pkg/util/sets"
|
|
)
|
|
|
|
var podControllers = sets.New("daemonsets", "deployments", "jobs", "statefulsets", "replicasets", "cronjobs")
|
|
|
|
// canAutoGen checks whether the policy can be applied to Pod controllers
|
|
// It returns false if:
|
|
// - name or selector is defined
|
|
// - mixed kinds (Pod + pod controller) is defined
|
|
// - Pod is not defined
|
|
//
|
|
// Otherwise it returns all pod controllers
|
|
func CanAutoGen(spec *policiesv1alpha1.ValidatingPolicySpec) (bool, sets.Set[string]) {
|
|
match := spec.MatchConstraints
|
|
if match.NamespaceSelector != nil {
|
|
if len(match.NamespaceSelector.MatchLabels) > 0 || len(match.NamespaceSelector.MatchExpressions) > 0 {
|
|
return false, sets.New[string]()
|
|
}
|
|
}
|
|
if match.ObjectSelector != nil {
|
|
if len(match.ObjectSelector.MatchLabels) > 0 || len(match.ObjectSelector.MatchExpressions) > 0 {
|
|
return false, sets.New[string]()
|
|
}
|
|
}
|
|
|
|
rules := match.ResourceRules
|
|
for _, rule := range rules {
|
|
if len(rule.ResourceNames) > 0 {
|
|
return false, sets.New[string]()
|
|
}
|
|
if len(rule.Resources) > 1 {
|
|
return false, sets.New[string]()
|
|
}
|
|
if rule.Resources[0] != "pods" {
|
|
return false, sets.New[string]()
|
|
}
|
|
}
|
|
return true, podControllers
|
|
}
|
|
|
|
func generateRules(spec *policiesv1alpha1.ValidatingPolicySpec, controllers string) []policiesv1alpha1.AutogenRule {
|
|
var genRules []policiesv1alpha1.AutogenRule
|
|
// strip cronjobs from controllers if exist
|
|
isRemoved, controllers := stripCronJob(controllers)
|
|
// generate rule for pod controllers
|
|
if genRule, err := generateRuleForControllers(spec, controllers); err == nil {
|
|
genRules = append(genRules, *genRule.DeepCopy())
|
|
}
|
|
|
|
// generate rule for cronjobs if exist
|
|
if isRemoved {
|
|
if genRule, err := generateCronJobRule(spec, "cronjobs"); err == nil {
|
|
genRules = append(genRules, *genRule.DeepCopy())
|
|
}
|
|
}
|
|
return genRules
|
|
}
|
|
|
|
// stripCronJob removes the cronjobs from controllers
|
|
// it returns true, if cronjobs is removed
|
|
func stripCronJob(controllers string) (bool, string) {
|
|
controllerArr := strings.Split(controllers, ",")
|
|
newControllers := make([]string, 0, len(controllerArr))
|
|
isRemoved := false
|
|
for _, c := range controllerArr {
|
|
if c == "cronjobs" {
|
|
isRemoved = true
|
|
continue
|
|
}
|
|
newControllers = append(newControllers, c)
|
|
}
|
|
if len(newControllers) == 0 {
|
|
return isRemoved, ""
|
|
}
|
|
return isRemoved, strings.Join(newControllers, ",")
|
|
}
|
|
|
|
func ComputeRules(policy policiesv1alpha1.GenericPolicy) []policiesv1alpha1.AutogenRule {
|
|
applyAutoGen, desiredControllers := CanAutoGen(policy.GetSpec())
|
|
if !applyAutoGen {
|
|
return []policiesv1alpha1.AutogenRule{}
|
|
}
|
|
|
|
var actualControllers sets.Set[string]
|
|
ann := policy.GetAnnotations()
|
|
actualControllersString, ok := ann[kyverno.AnnotationAutogenControllers]
|
|
if !ok {
|
|
actualControllers = desiredControllers
|
|
} else {
|
|
actualControllers = sets.New(strings.Split(actualControllersString, ",")...)
|
|
}
|
|
|
|
resources := strings.Join(sets.List(actualControllers), ",")
|
|
genRules := generateRules(policy.GetSpec().DeepCopy(), resources)
|
|
return genRules
|
|
}
|