mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-29 02:45:06 +00:00
refactor: simplify autogen package (#3532)
Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com> Co-authored-by: Vyankatesh Kudtarkar <vyankateshkd@gmail.com> Co-authored-by: shuting <shuting@nirmata.com>
This commit is contained in:
parent
29d7010e25
commit
594a04db01
8 changed files with 331 additions and 536 deletions
|
@ -30,6 +30,18 @@ type MatchResources struct {
|
|||
ResourceDescription `json:"resources,omitempty" yaml:"resources,omitempty"`
|
||||
}
|
||||
|
||||
// GetKinds returns all kinds
|
||||
func (m *MatchResources) GetKinds() []string {
|
||||
kinds := m.ResourceDescription.Kinds
|
||||
for _, value := range m.All {
|
||||
kinds = append(kinds, value.ResourceDescription.Kinds...)
|
||||
}
|
||||
for _, value := range m.Any {
|
||||
kinds = append(kinds, value.ResourceDescription.Kinds...)
|
||||
}
|
||||
return kinds
|
||||
}
|
||||
|
||||
// Validate implements programmatic validation
|
||||
func (m *MatchResources) Validate(path *field.Path, namespaced bool, clusterResources sets.String) (errs field.ErrorList) {
|
||||
if len(m.Any) > 0 && len(m.All) > 0 {
|
||||
|
|
|
@ -81,31 +81,6 @@ func (r *Rule) HasGenerate() bool {
|
|||
return !reflect.DeepEqual(r.Generation, Generation{})
|
||||
}
|
||||
|
||||
// MatchKinds returns a slice of all kinds to match
|
||||
func (r *Rule) MatchKinds() []string {
|
||||
matchKinds := r.MatchResources.ResourceDescription.Kinds
|
||||
for _, value := range r.MatchResources.All {
|
||||
matchKinds = append(matchKinds, value.ResourceDescription.Kinds...)
|
||||
}
|
||||
for _, value := range r.MatchResources.Any {
|
||||
matchKinds = append(matchKinds, value.ResourceDescription.Kinds...)
|
||||
}
|
||||
|
||||
return matchKinds
|
||||
}
|
||||
|
||||
// ExcludeKinds returns a slice of all kinds to exclude
|
||||
func (r *Rule) ExcludeKinds() []string {
|
||||
excludeKinds := r.ExcludeResources.ResourceDescription.Kinds
|
||||
for _, value := range r.ExcludeResources.All {
|
||||
excludeKinds = append(excludeKinds, value.ResourceDescription.Kinds...)
|
||||
}
|
||||
for _, value := range r.ExcludeResources.Any {
|
||||
excludeKinds = append(excludeKinds, value.ResourceDescription.Kinds...)
|
||||
}
|
||||
return excludeKinds
|
||||
}
|
||||
|
||||
func (r *Rule) GetAnyAllConditions() apiextensions.JSON {
|
||||
return FromJSON(r.RawAnyAllConditions)
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/toggle"
|
||||
"github.com/kyverno/kyverno/pkg/utils"
|
||||
jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
log "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
||||
|
@ -22,6 +24,46 @@ const (
|
|||
PodControllers = "DaemonSet,Deployment,Job,StatefulSet,CronJob"
|
||||
)
|
||||
|
||||
var (
|
||||
podControllersKindsSet = sets.NewString(append(strings.Split(PodControllers, ","), "Pod")...)
|
||||
podSet = sets.NewString("Pod")
|
||||
)
|
||||
|
||||
func isKindOtherthanPod(kinds []string) bool {
|
||||
if len(kinds) > 1 && kubeutils.ContainsKind(kinds, "Pod") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func checkAutogenSupport(needed *bool, subjects ...kyverno.ResourceDescription) bool {
|
||||
for _, subject := range subjects {
|
||||
if subject.Name != "" || subject.Selector != nil || subject.Annotations != nil || isKindOtherthanPod(subject.Kinds) {
|
||||
return false
|
||||
}
|
||||
if needed != nil {
|
||||
*needed = *needed || podControllersKindsSet.HasAny(subject.Kinds...)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// stripCronJob removes CronJob from controllers
|
||||
func stripCronJob(controllers string) string {
|
||||
var newControllers []string
|
||||
controllerArr := strings.Split(controllers, ",")
|
||||
for _, c := range controllerArr {
|
||||
if c == PodControllerCronJob {
|
||||
continue
|
||||
}
|
||||
newControllers = append(newControllers, c)
|
||||
}
|
||||
if len(newControllers) == 0 {
|
||||
return ""
|
||||
}
|
||||
return strings.Join(newControllers, ",")
|
||||
}
|
||||
|
||||
// CanAutoGen checks whether the rule(s) (in policy) can be applied to Pod controllers
|
||||
// returns controllers as:
|
||||
// - "" if:
|
||||
|
@ -31,82 +73,44 @@ const (
|
|||
// - mutate.Patches/mutate.PatchesJSON6902/validate.deny/generate rule is defined
|
||||
// - otherwise it returns all pod controllers
|
||||
func CanAutoGen(spec *kyverno.Spec, log logr.Logger) (applyAutoGen bool, controllers string) {
|
||||
var needAutogen bool
|
||||
rules := spec.Rules
|
||||
for _, rule := range rules {
|
||||
match := rule.MatchResources
|
||||
exclude := rule.ExcludeResources
|
||||
|
||||
if match.ResourceDescription.Name != "" || match.ResourceDescription.Selector != nil || match.ResourceDescription.Annotations != nil ||
|
||||
exclude.ResourceDescription.Name != "" || exclude.ResourceDescription.Selector != nil || exclude.ResourceDescription.Annotations != nil {
|
||||
needed := false
|
||||
for _, rule := range spec.Rules {
|
||||
if rule.Mutation.PatchesJSON6902 != "" || rule.HasGenerate() {
|
||||
return false, "none"
|
||||
}
|
||||
match, exclude := rule.MatchResources, rule.ExcludeResources
|
||||
if !checkAutogenSupport(&needed, match.ResourceDescription, exclude.ResourceDescription) {
|
||||
log.V(3).Info("skip generating rule on pod controllers: Name / Selector in resource description may not be applicable.", "rule", rule.Name)
|
||||
return false, ""
|
||||
}
|
||||
|
||||
if isKindOtherthanPod(match.Kinds) || isKindOtherthanPod(exclude.Kinds) {
|
||||
return false, ""
|
||||
}
|
||||
|
||||
needAutogen = hasAutogenKinds(match.Kinds) || hasAutogenKinds(exclude.Kinds)
|
||||
|
||||
for _, value := range match.Any {
|
||||
if isKindOtherthanPod(value.Kinds) {
|
||||
return false, ""
|
||||
}
|
||||
if !needAutogen {
|
||||
needAutogen = hasAutogenKinds(value.Kinds)
|
||||
}
|
||||
if value.Name != "" || value.Selector != nil || value.Annotations != nil {
|
||||
if !checkAutogenSupport(&needed, value.ResourceDescription) {
|
||||
log.V(3).Info("skip generating rule on pod controllers: Name / Selector in match any block is not be applicable.", "rule", rule.Name)
|
||||
return false, ""
|
||||
}
|
||||
}
|
||||
for _, value := range match.All {
|
||||
if isKindOtherthanPod(value.Kinds) {
|
||||
return false, ""
|
||||
}
|
||||
if !needAutogen {
|
||||
needAutogen = hasAutogenKinds(value.Kinds)
|
||||
}
|
||||
if value.Name != "" || value.Selector != nil || value.Annotations != nil {
|
||||
if !checkAutogenSupport(&needed, value.ResourceDescription) {
|
||||
log.V(3).Info("skip generating rule on pod controllers: Name / Selector in match all block is not be applicable.", "rule", rule.Name)
|
||||
return false, ""
|
||||
}
|
||||
}
|
||||
for _, value := range exclude.Any {
|
||||
if isKindOtherthanPod(value.Kinds) {
|
||||
return false, ""
|
||||
}
|
||||
if !needAutogen {
|
||||
needAutogen = hasAutogenKinds(value.Kinds)
|
||||
}
|
||||
if value.Name != "" || value.Selector != nil || value.Annotations != nil {
|
||||
if !checkAutogenSupport(&needed, value.ResourceDescription) {
|
||||
log.V(3).Info("skip generating rule on pod controllers: Name / Selector in exclude any block is not be applicable.", "rule", rule.Name)
|
||||
return false, ""
|
||||
}
|
||||
}
|
||||
for _, value := range exclude.All {
|
||||
if isKindOtherthanPod(value.Kinds) {
|
||||
return false, ""
|
||||
}
|
||||
if !needAutogen {
|
||||
needAutogen = hasAutogenKinds(value.Kinds)
|
||||
}
|
||||
if value.Name != "" || value.Selector != nil || value.Annotations != nil {
|
||||
if !checkAutogenSupport(&needed, value.ResourceDescription) {
|
||||
log.V(3).Info("skip generating rule on pod controllers: Name / Selector in exclud all block is not be applicable.", "rule", rule.Name)
|
||||
return false, ""
|
||||
}
|
||||
}
|
||||
|
||||
if rule.Mutation.PatchesJSON6902 != "" || rule.HasGenerate() {
|
||||
return false, "none"
|
||||
}
|
||||
}
|
||||
|
||||
if !needAutogen {
|
||||
if !needed {
|
||||
return false, ""
|
||||
}
|
||||
|
||||
return true, PodControllers
|
||||
}
|
||||
|
||||
|
@ -139,14 +143,11 @@ func GetRequestedControllers(meta *metav1.ObjectMeta) []string {
|
|||
// It returns the requested, supported and effective controllers (intersection of requested and supported ones).
|
||||
func GetControllers(meta *metav1.ObjectMeta, spec *kyverno.Spec, log logr.Logger) ([]string, []string, []string) {
|
||||
// compute supported and requested controllers
|
||||
supported := GetSupportedControllers(spec, log)
|
||||
requested := GetRequestedControllers(meta)
|
||||
|
||||
supported, requested := GetSupportedControllers(spec, log), GetRequestedControllers(meta)
|
||||
// no specific request, we can return supported controllers without further filtering
|
||||
if requested == nil {
|
||||
return requested, supported, supported
|
||||
}
|
||||
|
||||
// filter supported controllers, keeping only those that have been requested
|
||||
var activated []string
|
||||
for _, controller := range supported {
|
||||
|
@ -168,24 +169,19 @@ func GetControllers(meta *metav1.ObjectMeta, spec *kyverno.Spec, log logr.Logger
|
|||
|
||||
// GenerateRulePatches generates rule for podControllers based on scenario A and C
|
||||
func GenerateRulePatches(spec *kyverno.Spec, controllers string, log logr.Logger) (rulePatches [][]byte, errs []error) {
|
||||
ruleMap := createRuleMap(spec.Rules)
|
||||
var ruleIndex = make(map[string]int)
|
||||
for index, rule := range spec.Rules {
|
||||
ruleIndex[rule.Name] = index
|
||||
}
|
||||
insertIdx := len(spec.Rules)
|
||||
for _, rule := range spec.Rules {
|
||||
genRules := generateRules(spec, controllers, log)
|
||||
for i := range genRules {
|
||||
patchPostion := insertIdx
|
||||
convertToPatches := func(genRule kyvernoRule, patchPostion int) []byte {
|
||||
operation := "add"
|
||||
if existingAutoGenRule, alreadyExists := ruleMap[genRule.Name]; alreadyExists {
|
||||
existingAutoGenRuleRaw, _ := json.Marshal(existingAutoGenRule)
|
||||
genRuleRaw, _ := json.Marshal(genRule)
|
||||
if string(existingAutoGenRuleRaw) == string(genRuleRaw) {
|
||||
return nil
|
||||
}
|
||||
if existingIndex, alreadyExists := ruleIndex[genRule.Name]; alreadyExists {
|
||||
operation = "replace"
|
||||
patchPostion = ruleIndex[genRule.Name]
|
||||
patchPostion = existingIndex
|
||||
}
|
||||
patch := jsonutils.NewPatch(fmt.Sprintf("/spec/rules/%s", strconv.Itoa(patchPostion)), operation, genRule)
|
||||
pbytes, err := patch.Marshal()
|
||||
|
@ -199,27 +195,15 @@ func GenerateRulePatches(spec *kyverno.Spec, controllers string, log logr.Logger
|
|||
}
|
||||
return pbytes
|
||||
}
|
||||
// handle all other controllers other than CronJob
|
||||
genRule := generateRuleForControllers(rule, stripCronJob(controllers), log)
|
||||
genRule := createRule(&genRules[i])
|
||||
if genRule != nil {
|
||||
pbytes := convertToPatches(*genRule, patchPostion)
|
||||
pbytes = updateGenRuleByte(pbytes, "Pod", *genRule)
|
||||
if pbytes != nil {
|
||||
rulePatches = append(rulePatches, pbytes)
|
||||
}
|
||||
insertIdx++
|
||||
patchPostion = insertIdx
|
||||
}
|
||||
// handle CronJob, it appends an additional rule
|
||||
genRule = generateCronJobRule(rule, controllers, log)
|
||||
if genRule != nil {
|
||||
pbytes := convertToPatches(*genRule, patchPostion)
|
||||
pbytes = updateGenRuleByte(pbytes, "Cronjob", *genRule)
|
||||
if pbytes != nil {
|
||||
rulePatches = append(rulePatches, pbytes)
|
||||
}
|
||||
insertIdx++
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -233,18 +217,18 @@ func GenerateRulePatches(spec *kyverno.Spec, controllers string, log logr.Logger
|
|||
// copy entire match / exclude block, it's users' responsibility to
|
||||
// make sure all fields are applicable to pod controllers
|
||||
|
||||
// GenerateRules generates rule for podControllers based on scenario A and C
|
||||
func GenerateRules(spec *kyverno.Spec, controllers string, log logr.Logger) []kyverno.Rule {
|
||||
// generateRules generates rule for podControllers based on scenario A and C
|
||||
func generateRules(spec *kyverno.Spec, controllers string, log logr.Logger) []kyverno.Rule {
|
||||
var rules []kyverno.Rule
|
||||
for _, rule := range spec.Rules {
|
||||
for i := range spec.Rules {
|
||||
// handle all other controllers other than CronJob
|
||||
if genRule := generateRuleForControllers(*rule.DeepCopy(), stripCronJob(controllers), log); genRule != nil {
|
||||
if genRule := createRule(generateRuleForControllers(&spec.Rules[i], stripCronJob(controllers), log)); genRule != nil {
|
||||
if convRule, err := convertRule(*genRule, "Pod"); err == nil {
|
||||
rules = append(rules, *convRule)
|
||||
}
|
||||
}
|
||||
// handle CronJob, it appends an additional rule
|
||||
if genRule := generateCronJobRule(*rule.DeepCopy(), controllers, log); genRule != nil {
|
||||
if genRule := createRule(generateCronJobRule(&spec.Rules[i], controllers, log)); genRule != nil {
|
||||
if convRule, err := convertRule(*genRule, "Cronjob"); err == nil {
|
||||
rules = append(rules, *convRule)
|
||||
}
|
||||
|
@ -257,7 +241,7 @@ func convertRule(rule kyvernoRule, kind string) (*kyverno.Rule, error) {
|
|||
if bytes, err := json.Marshal(rule); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
bytes = updateGenRuleByte(bytes, kind, rule)
|
||||
bytes = updateGenRuleByte(bytes, kind)
|
||||
if err := json.Unmarshal(bytes, &rule); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -308,7 +292,7 @@ func ComputeRules(p kyverno.PolicyInterface) []kyverno.Rule {
|
|||
if actualControllers == "none" {
|
||||
return spec.Rules
|
||||
}
|
||||
genRules := GenerateRules(spec.DeepCopy(), actualControllers, log.Log)
|
||||
genRules := generateRules(spec.DeepCopy(), actualControllers, log.Log)
|
||||
if len(genRules) == 0 {
|
||||
return spec.Rules
|
||||
}
|
||||
|
|
|
@ -11,12 +11,47 @@ import (
|
|||
|
||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/utils"
|
||||
jsonutils "github.com/kyverno/kyverno/pkg/utils/json"
|
||||
"gotest.tools/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
||||
func Test_getAutogenRuleName(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
ruleName string
|
||||
prefix string
|
||||
expected string
|
||||
}{
|
||||
{"valid", "valid-rule-name", "autogen", "autogen-valid-rule-name"},
|
||||
{"truncated", "too-long-this-rule-name-will-be-truncated-to-63-characters", "autogen", "autogen-too-long-this-rule-name-will-be-truncated-to-63-charact"},
|
||||
{"valid-cronjob", "valid-rule-name", "autogen-cronjob", "autogen-cronjob-valid-rule-name"},
|
||||
{"truncated-cronjob", "too-long-this-rule-name-will-be-truncated-to-63-characters", "autogen-cronjob", "autogen-cronjob-too-long-this-rule-name-will-be-truncated-to-63"},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
res := getAutogenRuleName(test.prefix, test.ruleName)
|
||||
assert.Equal(t, test.expected, res)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_isAutogenRule(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
ruleName string
|
||||
expected bool
|
||||
}{
|
||||
{"normal", "valid-rule-name", false},
|
||||
{"simple", "autogen-simple", true},
|
||||
{"simple-cronjob", "autogen-cronjob-simple", true},
|
||||
{"truncated", "autogen-too-long-this-rule-name-will-be-truncated-to-63-charact", true},
|
||||
{"truncated-cronjob", "autogen-cronjob-too-long-this-rule-name-will-be-truncated-to-63", true},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
res := isAutogenRuleName(test.ruleName)
|
||||
assert.Equal(t, test.expected, res)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_CanAutoGen(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
@ -271,7 +306,6 @@ func Test_Any(t *testing.T) {
|
|||
}
|
||||
|
||||
rulePatches, errs := GenerateRulePatches(spec, PodControllers, log.Log)
|
||||
fmt.Println("utils.JoinPatches(patches)erterter", string(jsonutils.JoinPatches(rulePatches...)))
|
||||
if len(errs) != 0 {
|
||||
t.Log(errs)
|
||||
}
|
||||
|
@ -359,7 +393,6 @@ func Test_Exclude(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_CronJobOnly(t *testing.T) {
|
||||
|
||||
controllers := PodControllerCronJob
|
||||
dir, err := os.Getwd()
|
||||
baseDir := filepath.Dir(filepath.Dir(dir))
|
||||
|
@ -424,7 +457,6 @@ func Test_ForEachPod(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_CronJob_hasExclude(t *testing.T) {
|
||||
|
||||
controllers := PodControllerCronJob
|
||||
dir, err := os.Getwd()
|
||||
baseDir := filepath.Dir(filepath.Dir(dir))
|
||||
|
@ -518,7 +550,10 @@ func Test_UpdateVariablePath(t *testing.T) {
|
|||
[]byte(`{"path":"/spec/rules/2","op":"add","value":{"name":"autogen-cronjob-select-secrets-from-volumes","match":{"resources":{"kinds":["CronJob"]}},"context":[{"name":"volsecret","apiCall":{"urlPath":"/api/v1/namespaces/{{request.object.spec.template.metadata.namespace}}/secrets/{{request.object.spec.jobTemplate.spec.template.spec.volumes[0].secret.secretName}}","jmesPath":"metadata.labels.foo"}}],"preconditions":[{"key":"{{ request.operation }}","operator":"Equals","value":"CREATE"}],"validate":{"message":"The Secret named {{request.object.spec.jobTemplate.spec.template.spec.volumes[0].secret.secretName}} is restricted and may not be used.","pattern":{"spec":{"jobTemplate":{"spec":{"template":{"spec":{"containers":[{"image":"registry.domain.com/*"}]}}}}}}}}}`),
|
||||
}
|
||||
|
||||
assert.DeepEqual(t, rulePatches, expectedPatches)
|
||||
for i, ep := range expectedPatches {
|
||||
assert.Equal(t, string(rulePatches[i]), string(ep),
|
||||
fmt.Sprintf("unexpected patch: %s\nexpected: %s", rulePatches[i], ep))
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Deny(t *testing.T) {
|
||||
|
@ -545,7 +580,6 @@ func Test_Deny(t *testing.T) {
|
|||
}
|
||||
|
||||
rulePatches, errs := GenerateRulePatches(spec, PodControllers, log.Log)
|
||||
fmt.Println("utils.JoinPatches(patches)erterter", string(jsonutils.JoinPatches(rulePatches...)))
|
||||
if len(errs) != 0 {
|
||||
t.Log(errs)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package autogen
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
|
@ -34,55 +32,199 @@ type kyvernoRule struct {
|
|||
VerifyImages []*kyverno.ImageVerification `json:"verifyImages,omitempty" yaml:"verifyImages,omitempty"`
|
||||
}
|
||||
|
||||
func createRuleMap(rules []kyverno.Rule) map[string]kyvernoRule {
|
||||
var ruleMap = make(map[string]kyvernoRule)
|
||||
for _, rule := range rules {
|
||||
var jsonFriendlyStruct kyvernoRule
|
||||
|
||||
jsonFriendlyStruct.Name = rule.Name
|
||||
|
||||
if !reflect.DeepEqual(rule.MatchResources, kyverno.MatchResources{}) {
|
||||
jsonFriendlyStruct.MatchResources = rule.MatchResources.DeepCopy()
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(rule.ExcludeResources, kyverno.MatchResources{}) {
|
||||
jsonFriendlyStruct.ExcludeResources = rule.ExcludeResources.DeepCopy()
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(rule.Mutation, kyverno.Mutation{}) {
|
||||
jsonFriendlyStruct.Mutation = rule.Mutation.DeepCopy()
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(rule.Validation, kyverno.Validation{}) {
|
||||
jsonFriendlyStruct.Validation = rule.Validation.DeepCopy()
|
||||
}
|
||||
|
||||
ruleMap[rule.Name] = jsonFriendlyStruct
|
||||
func createRule(rule *kyverno.Rule) *kyvernoRule {
|
||||
if rule == nil {
|
||||
return nil
|
||||
}
|
||||
return ruleMap
|
||||
jsonFriendlyStruct := kyvernoRule{
|
||||
Name: rule.Name,
|
||||
}
|
||||
if !reflect.DeepEqual(rule.MatchResources, kyverno.MatchResources{}) {
|
||||
jsonFriendlyStruct.MatchResources = rule.MatchResources.DeepCopy()
|
||||
}
|
||||
if !reflect.DeepEqual(rule.ExcludeResources, kyverno.MatchResources{}) {
|
||||
jsonFriendlyStruct.ExcludeResources = rule.ExcludeResources.DeepCopy()
|
||||
}
|
||||
if !reflect.DeepEqual(rule.Mutation, kyverno.Mutation{}) {
|
||||
jsonFriendlyStruct.Mutation = rule.Mutation.DeepCopy()
|
||||
}
|
||||
if !reflect.DeepEqual(rule.Validation, kyverno.Validation{}) {
|
||||
jsonFriendlyStruct.Validation = rule.Validation.DeepCopy()
|
||||
}
|
||||
kyvernoAnyAllConditions, _ := utils.ApiextensionsJsonToKyvernoConditions(rule.GetAnyAllConditions())
|
||||
switch typedAnyAllConditions := kyvernoAnyAllConditions.(type) {
|
||||
case kyverno.AnyAllConditions:
|
||||
if !reflect.DeepEqual(typedAnyAllConditions, kyverno.AnyAllConditions{}) {
|
||||
jsonFriendlyStruct.AnyAllConditions = rule.DeepCopy().RawAnyAllConditions
|
||||
}
|
||||
case []kyverno.Condition:
|
||||
if len(typedAnyAllConditions) > 0 {
|
||||
jsonFriendlyStruct.AnyAllConditions = rule.DeepCopy().RawAnyAllConditions
|
||||
}
|
||||
}
|
||||
if len(rule.Context) > 0 {
|
||||
jsonFriendlyStruct.Context = &rule.DeepCopy().Context
|
||||
}
|
||||
return &jsonFriendlyStruct
|
||||
}
|
||||
|
||||
func generateRuleForControllers(rule kyverno.Rule, controllers string, log logr.Logger) *kyvernoRule {
|
||||
logger := log.WithName("generateRuleForControllers")
|
||||
type generateResourceFilters func(kyverno.ResourceFilters, []string) kyverno.ResourceFilters
|
||||
|
||||
if strings.HasPrefix(rule.Name, "autogen-") || controllers == "" {
|
||||
func generateRule(logger logr.Logger, name string, rule *kyverno.Rule, tplKey, shift string, kinds []string, grf generateResourceFilters) *kyverno.Rule {
|
||||
if rule == nil {
|
||||
return nil
|
||||
}
|
||||
rule = rule.DeepCopy()
|
||||
rule.Name = name
|
||||
// overwrite Kinds by pod controllers defined in the annotation
|
||||
if len(rule.MatchResources.Any) > 0 {
|
||||
rule.MatchResources.Any = grf(rule.MatchResources.Any, kinds)
|
||||
} else if len(rule.MatchResources.All) > 0 {
|
||||
rule.MatchResources.All = grf(rule.MatchResources.All, kinds)
|
||||
} else {
|
||||
rule.MatchResources.Kinds = kinds
|
||||
}
|
||||
if len(rule.ExcludeResources.Any) > 0 {
|
||||
rule.ExcludeResources.Any = grf(rule.ExcludeResources.Any, kinds)
|
||||
} else if len(rule.ExcludeResources.All) > 0 {
|
||||
rule.ExcludeResources.All = grf(rule.ExcludeResources.All, kinds)
|
||||
} else {
|
||||
if len(rule.ExcludeResources.Kinds) != 0 {
|
||||
rule.ExcludeResources.Kinds = kinds
|
||||
}
|
||||
}
|
||||
if target := rule.Mutation.GetPatchStrategicMerge(); target != nil {
|
||||
newMutation := kyverno.Mutation{}
|
||||
newMutation.SetPatchStrategicMerge(
|
||||
map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
tplKey: target,
|
||||
},
|
||||
},
|
||||
)
|
||||
rule.Mutation = newMutation
|
||||
return rule
|
||||
}
|
||||
if len(rule.Mutation.ForEachMutation) > 0 && rule.Mutation.ForEachMutation != nil {
|
||||
var newForeachMutation []*kyverno.ForEachMutation
|
||||
for _, foreach := range rule.Mutation.ForEachMutation {
|
||||
temp := kyverno.ForEachMutation{
|
||||
List: foreach.List,
|
||||
Context: foreach.Context,
|
||||
AnyAllConditions: foreach.AnyAllConditions,
|
||||
}
|
||||
temp.SetPatchStrategicMerge(
|
||||
map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
tplKey: foreach.GetPatchStrategicMerge(),
|
||||
},
|
||||
},
|
||||
)
|
||||
newForeachMutation = append(newForeachMutation, &temp)
|
||||
}
|
||||
rule.Mutation = kyverno.Mutation{
|
||||
ForEachMutation: newForeachMutation,
|
||||
}
|
||||
return rule
|
||||
}
|
||||
if target := rule.Validation.GetPattern(); target != nil {
|
||||
newValidate := kyverno.Validation{
|
||||
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "pattern"),
|
||||
}
|
||||
newValidate.SetPattern(
|
||||
map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
tplKey: target,
|
||||
},
|
||||
},
|
||||
)
|
||||
rule.Validation = newValidate
|
||||
return rule
|
||||
}
|
||||
if rule.Validation.Deny != nil {
|
||||
deny := kyverno.Validation{
|
||||
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "deny"),
|
||||
Deny: rule.Validation.Deny,
|
||||
}
|
||||
rule.Validation = deny
|
||||
return rule
|
||||
}
|
||||
if rule.Validation.GetAnyPattern() != nil {
|
||||
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to deserialize anyPattern, expect type array")
|
||||
}
|
||||
var patterns []interface{}
|
||||
for _, pattern := range anyPatterns {
|
||||
newPattern := map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
tplKey: pattern,
|
||||
},
|
||||
}
|
||||
patterns = append(patterns, newPattern)
|
||||
}
|
||||
rule.Validation = kyverno.Validation{
|
||||
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "anyPattern"),
|
||||
}
|
||||
rule.Validation.SetAnyPattern(patterns)
|
||||
return rule
|
||||
}
|
||||
if len(rule.Validation.ForEachValidation) > 0 && rule.Validation.ForEachValidation != nil {
|
||||
newForeachValidate := make([]*kyverno.ForEachValidation, len(rule.Validation.ForEachValidation))
|
||||
for i, foreach := range rule.Validation.ForEachValidation {
|
||||
newForeachValidate[i] = foreach
|
||||
}
|
||||
rule.Validation = kyverno.Validation{
|
||||
Message: variables.FindAndShiftReferences(logger, rule.Validation.Message, shift, "pattern"),
|
||||
ForEachValidation: newForeachValidate,
|
||||
}
|
||||
return rule
|
||||
}
|
||||
if rule.VerifyImages != nil {
|
||||
newVerifyImages := make([]*kyverno.ImageVerification, len(rule.VerifyImages))
|
||||
for i, vi := range rule.VerifyImages {
|
||||
newVerifyImages[i] = vi.DeepCopy()
|
||||
}
|
||||
rule.VerifyImages = newVerifyImages
|
||||
return rule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getAutogenRuleName(prefix string, name string) string {
|
||||
name = prefix + "-" + name
|
||||
if len(name) > 63 {
|
||||
name = name[:63]
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func isAutogenRuleName(name string) bool {
|
||||
return strings.HasPrefix(name, "autogen-")
|
||||
}
|
||||
|
||||
func getAnyAllAutogenRule(v kyverno.ResourceFilters, match string, kinds []string) kyverno.ResourceFilters {
|
||||
anyKind := v.DeepCopy()
|
||||
for i, value := range v {
|
||||
if kubeutils.ContainsKind(value.Kinds, match) {
|
||||
anyKind[i].Kinds = kinds
|
||||
}
|
||||
}
|
||||
return anyKind
|
||||
}
|
||||
|
||||
func generateRuleForControllers(rule *kyverno.Rule, controllers string, log logr.Logger) *kyverno.Rule {
|
||||
logger := log.WithName("generateRuleForControllers")
|
||||
if isAutogenRuleName(rule.Name) || controllers == "" {
|
||||
logger.V(5).Info("skip generateRuleForControllers")
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.V(3).Info("processing rule", "rulename", rule.Name)
|
||||
|
||||
match := rule.MatchResources
|
||||
exclude := rule.ExcludeResources
|
||||
|
||||
matchResourceDescriptionsKinds := rule.MatchKinds()
|
||||
excludeResourceDescriptionsKinds := rule.ExcludeKinds()
|
||||
|
||||
if !kubeutils.ContainsKind(matchResourceDescriptionsKinds, "Pod") ||
|
||||
(len(excludeResourceDescriptionsKinds) != 0 && !kubeutils.ContainsKind(excludeResourceDescriptionsKinds, "Pod")) {
|
||||
match, exclude := rule.MatchResources, rule.ExcludeResources
|
||||
matchKinds, excludeKinds := match.GetKinds(), exclude.GetKinds()
|
||||
if !kubeutils.ContainsKind(matchKinds, "Pod") || (len(excludeKinds) != 0 && !kubeutils.ContainsKind(excludeKinds, "Pod")) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Support backwards compatibility
|
||||
skipAutoGeneration := false
|
||||
var controllersValidated []string
|
||||
|
@ -99,7 +241,6 @@ func generateRuleForControllers(rule kyverno.Rule, controllers string, log logr.
|
|||
skipAutoGeneration = true
|
||||
}
|
||||
}
|
||||
|
||||
if skipAutoGeneration {
|
||||
if controllers == "all" {
|
||||
controllers = "DaemonSet,Deployment,Job,StatefulSet"
|
||||
|
@ -107,317 +248,40 @@ func generateRuleForControllers(rule kyverno.Rule, controllers string, log logr.
|
|||
controllers = strings.Join(controllersValidated, ",")
|
||||
}
|
||||
}
|
||||
|
||||
name := fmt.Sprintf("autogen-%s", rule.Name)
|
||||
if len(name) > 63 {
|
||||
name = name[:63]
|
||||
}
|
||||
|
||||
controllerRule := &kyvernoRule{
|
||||
Name: name,
|
||||
MatchResources: match.DeepCopy(),
|
||||
}
|
||||
|
||||
if len(rule.Context) > 0 {
|
||||
controllerRule.Context = &rule.DeepCopy().Context
|
||||
}
|
||||
|
||||
kyvernoAnyAllConditions, _ := utils.ApiextensionsJsonToKyvernoConditions(rule.GetAnyAllConditions())
|
||||
switch typedAnyAllConditions := kyvernoAnyAllConditions.(type) {
|
||||
case kyverno.AnyAllConditions:
|
||||
if !reflect.DeepEqual(typedAnyAllConditions, kyverno.AnyAllConditions{}) {
|
||||
controllerRule.AnyAllConditions = rule.DeepCopy().RawAnyAllConditions
|
||||
}
|
||||
case []kyverno.Condition:
|
||||
if len(typedAnyAllConditions) > 0 {
|
||||
controllerRule.AnyAllConditions = rule.DeepCopy().RawAnyAllConditions
|
||||
}
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(exclude, kyverno.MatchResources{}) {
|
||||
controllerRule.ExcludeResources = exclude.DeepCopy()
|
||||
}
|
||||
|
||||
// overwrite Kinds by pod controllers defined in the annotation
|
||||
if len(rule.MatchResources.Any) > 0 {
|
||||
rule := getAnyAllAutogenRule(controllerRule.MatchResources.Any, controllers)
|
||||
controllerRule.MatchResources.Any = rule
|
||||
} else if len(rule.MatchResources.All) > 0 {
|
||||
rule := getAnyAllAutogenRule(controllerRule.MatchResources.All, controllers)
|
||||
controllerRule.MatchResources.All = rule
|
||||
} else {
|
||||
controllerRule.MatchResources.Kinds = strings.Split(controllers, ",")
|
||||
}
|
||||
|
||||
if len(rule.ExcludeResources.Any) > 0 {
|
||||
rule := getAnyAllAutogenRule(controllerRule.ExcludeResources.Any, controllers)
|
||||
controllerRule.ExcludeResources.Any = rule
|
||||
} else if len(rule.ExcludeResources.All) > 0 {
|
||||
rule := getAnyAllAutogenRule(controllerRule.ExcludeResources.All, controllers)
|
||||
controllerRule.ExcludeResources.All = rule
|
||||
} else {
|
||||
if len(exclude.Kinds) != 0 {
|
||||
controllerRule.ExcludeResources.Kinds = strings.Split(controllers, ",")
|
||||
}
|
||||
}
|
||||
|
||||
if target := rule.Mutation.GetPatchStrategicMerge(); target != nil {
|
||||
newMutation := &kyverno.Mutation{}
|
||||
newMutation.SetPatchStrategicMerge(
|
||||
map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"template": target,
|
||||
},
|
||||
},
|
||||
)
|
||||
controllerRule.Mutation = newMutation.DeepCopy()
|
||||
return controllerRule
|
||||
}
|
||||
|
||||
if len(rule.Mutation.ForEachMutation) > 0 && rule.Mutation.ForEachMutation != nil {
|
||||
var newForeachMutation []*kyverno.ForEachMutation
|
||||
for _, foreach := range rule.Mutation.ForEachMutation {
|
||||
temp := &kyverno.ForEachMutation{
|
||||
List: foreach.List,
|
||||
Context: foreach.Context,
|
||||
AnyAllConditions: foreach.AnyAllConditions,
|
||||
}
|
||||
temp.SetPatchStrategicMerge(
|
||||
map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"template": foreach.GetPatchStrategicMerge(),
|
||||
},
|
||||
},
|
||||
)
|
||||
newForeachMutation = append(newForeachMutation, temp)
|
||||
}
|
||||
controllerRule.Mutation = &kyverno.Mutation{
|
||||
ForEachMutation: newForeachMutation,
|
||||
}
|
||||
return controllerRule
|
||||
}
|
||||
|
||||
if target := rule.Validation.GetPattern(); target != nil {
|
||||
newValidate := &kyverno.Validation{
|
||||
Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/template", "pattern"),
|
||||
}
|
||||
newValidate.SetPattern(
|
||||
map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"template": target,
|
||||
},
|
||||
},
|
||||
)
|
||||
controllerRule.Validation = newValidate.DeepCopy()
|
||||
return controllerRule
|
||||
}
|
||||
|
||||
if rule.Validation.Deny != nil {
|
||||
deny := &kyverno.Validation{
|
||||
Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/template", "deny"),
|
||||
Deny: rule.Validation.Deny,
|
||||
}
|
||||
controllerRule.Validation = deny.DeepCopy()
|
||||
return controllerRule
|
||||
}
|
||||
|
||||
if rule.Validation.GetAnyPattern() != nil {
|
||||
anyPatterns, err := rule.Validation.DeserializeAnyPattern()
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to deserialize anyPattern, expect type array")
|
||||
}
|
||||
patterns := validateAnyPattern(anyPatterns)
|
||||
controllerRule.Validation = &kyverno.Validation{
|
||||
Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/template", "anyPattern"),
|
||||
}
|
||||
controllerRule.Validation.SetAnyPattern(patterns)
|
||||
return controllerRule
|
||||
}
|
||||
|
||||
if len(rule.Validation.ForEachValidation) > 0 && rule.Validation.ForEachValidation != nil {
|
||||
newForeachValidate := make([]*kyverno.ForEachValidation, len(rule.Validation.ForEachValidation))
|
||||
for i, foreach := range rule.Validation.ForEachValidation {
|
||||
newForeachValidate[i] = foreach
|
||||
}
|
||||
controllerRule.Validation = &kyverno.Validation{
|
||||
Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/template", "pattern"),
|
||||
ForEachValidation: newForeachValidate,
|
||||
}
|
||||
return controllerRule
|
||||
}
|
||||
|
||||
if rule.VerifyImages != nil {
|
||||
newVerifyImages := make([]*kyverno.ImageVerification, len(rule.VerifyImages))
|
||||
for i, vi := range rule.VerifyImages {
|
||||
newVerifyImages[i] = vi.DeepCopy()
|
||||
}
|
||||
|
||||
controllerRule.VerifyImages = newVerifyImages
|
||||
return controllerRule
|
||||
}
|
||||
|
||||
return nil
|
||||
return generateRule(
|
||||
logger,
|
||||
getAutogenRuleName("autogen", rule.Name),
|
||||
rule,
|
||||
"template",
|
||||
"spec/template",
|
||||
strings.Split(controllers, ","),
|
||||
func(r kyverno.ResourceFilters, kinds []string) kyverno.ResourceFilters {
|
||||
return getAnyAllAutogenRule(r, "Pod", kinds)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func generateCronJobRule(rule kyverno.Rule, controllers string, log logr.Logger) *kyvernoRule {
|
||||
logger := log.WithName("handleCronJob")
|
||||
|
||||
func generateCronJobRule(rule *kyverno.Rule, controllers string, log logr.Logger) *kyverno.Rule {
|
||||
logger := log.WithName("generateCronJobRule")
|
||||
hasCronJob := strings.Contains(controllers, PodControllerCronJob) || strings.Contains(controllers, "all")
|
||||
if !hasCronJob {
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.V(3).Info("generating rule for cronJob")
|
||||
jobRule := generateRuleForControllers(rule, "Job", logger)
|
||||
|
||||
if jobRule == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
cronJobRule := jobRule
|
||||
|
||||
name := fmt.Sprintf("autogen-cronjob-%s", rule.Name)
|
||||
if len(name) > 63 {
|
||||
name = name[:63]
|
||||
}
|
||||
cronJobRule.Name = name
|
||||
|
||||
if len(jobRule.MatchResources.Any) > 0 {
|
||||
rule := cronJobAnyAllAutogenRule(cronJobRule.MatchResources.Any)
|
||||
cronJobRule.MatchResources.Any = rule
|
||||
} else if len(jobRule.MatchResources.All) > 0 {
|
||||
rule := cronJobAnyAllAutogenRule(cronJobRule.MatchResources.All)
|
||||
cronJobRule.MatchResources.All = rule
|
||||
} else {
|
||||
cronJobRule.MatchResources.Kinds = []string{PodControllerCronJob}
|
||||
}
|
||||
|
||||
if (jobRule.ExcludeResources) != nil && len(jobRule.ExcludeResources.Any) > 0 {
|
||||
rule := cronJobAnyAllAutogenRule(cronJobRule.ExcludeResources.Any)
|
||||
cronJobRule.ExcludeResources.Any = rule
|
||||
} else if (jobRule.ExcludeResources) != nil && len(jobRule.ExcludeResources.All) > 0 {
|
||||
rule := cronJobAnyAllAutogenRule(cronJobRule.ExcludeResources.All)
|
||||
cronJobRule.ExcludeResources.All = rule
|
||||
} else {
|
||||
if (jobRule.ExcludeResources) != nil && (len(jobRule.ExcludeResources.Kinds) > 0) {
|
||||
cronJobRule.ExcludeResources.Kinds = []string{PodControllerCronJob}
|
||||
}
|
||||
}
|
||||
|
||||
if jobRule.Mutation != nil {
|
||||
if target := jobRule.Mutation.GetPatchStrategicMerge(); target != nil {
|
||||
newMutation := &kyverno.Mutation{}
|
||||
newMutation.SetPatchStrategicMerge(
|
||||
map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"jobTemplate": target,
|
||||
},
|
||||
},
|
||||
)
|
||||
cronJobRule.Mutation = newMutation.DeepCopy()
|
||||
return cronJobRule
|
||||
}
|
||||
}
|
||||
|
||||
if jobRule.Validation != nil {
|
||||
if target := jobRule.Validation.GetPattern(); target != nil {
|
||||
newValidate := &kyverno.Validation{
|
||||
Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/jobTemplate/spec/template", "pattern"),
|
||||
}
|
||||
newValidate.SetPattern(
|
||||
map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"jobTemplate": target,
|
||||
},
|
||||
},
|
||||
)
|
||||
cronJobRule.Validation = newValidate.DeepCopy()
|
||||
return cronJobRule
|
||||
}
|
||||
|
||||
if jobRule.Validation.Deny != nil {
|
||||
newValidate := &kyverno.Validation{
|
||||
Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/jobTemplate/spec/template", "pattern"),
|
||||
Deny: jobRule.Validation.Deny,
|
||||
}
|
||||
cronJobRule.Validation = newValidate.DeepCopy()
|
||||
return cronJobRule
|
||||
}
|
||||
|
||||
if target := jobRule.Validation.GetAnyPattern(); target != nil {
|
||||
var patterns []interface{}
|
||||
anyPatterns, err := jobRule.Validation.DeserializeAnyPattern()
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to deserialize anyPattern, expect type array")
|
||||
}
|
||||
for _, pattern := range anyPatterns {
|
||||
newPattern := map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"jobTemplate": pattern,
|
||||
},
|
||||
}
|
||||
patterns = append(patterns, newPattern)
|
||||
}
|
||||
cronJobRule.Validation = &kyverno.Validation{
|
||||
Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/jobTemplate/spec/template", "anyPattern"),
|
||||
}
|
||||
cronJobRule.Validation.SetAnyPattern(patterns)
|
||||
return cronJobRule
|
||||
}
|
||||
|
||||
if len(jobRule.Validation.ForEachValidation) > 0 && jobRule.Validation.ForEachValidation != nil {
|
||||
newForeachValidate := make([]*kyverno.ForEachValidation, len(jobRule.Validation.ForEachValidation))
|
||||
for i, foreach := range rule.Validation.ForEachValidation {
|
||||
newForeachValidate[i] = foreach
|
||||
}
|
||||
cronJobRule.Validation = &kyverno.Validation{
|
||||
Message: variables.FindAndShiftReferences(log, rule.Validation.Message, "spec/template", "pattern"),
|
||||
ForEachValidation: newForeachValidate,
|
||||
}
|
||||
return cronJobRule
|
||||
}
|
||||
}
|
||||
|
||||
if jobRule.Mutation != nil && len(jobRule.Mutation.ForEachMutation) > 0 && jobRule.Mutation.ForEachMutation != nil {
|
||||
var newForeachMutation []*kyverno.ForEachMutation
|
||||
for _, foreach := range jobRule.Mutation.ForEachMutation {
|
||||
temp := &kyverno.ForEachMutation{
|
||||
List: foreach.List,
|
||||
Context: foreach.Context,
|
||||
AnyAllConditions: foreach.AnyAllConditions,
|
||||
}
|
||||
temp.SetPatchStrategicMerge(
|
||||
map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"jobTemplate": foreach.GetPatchStrategicMerge(),
|
||||
},
|
||||
},
|
||||
)
|
||||
newForeachMutation = append(newForeachMutation, temp)
|
||||
}
|
||||
cronJobRule.Mutation = &kyverno.Mutation{
|
||||
ForEachMutation: newForeachMutation,
|
||||
}
|
||||
return cronJobRule
|
||||
}
|
||||
|
||||
if jobRule.VerifyImages != nil {
|
||||
newVerifyImages := make([]*kyverno.ImageVerification, len(jobRule.VerifyImages))
|
||||
for i, vi := range rule.VerifyImages {
|
||||
newVerifyImages[i] = vi.DeepCopy()
|
||||
}
|
||||
cronJobRule.VerifyImages = newVerifyImages
|
||||
return cronJobRule
|
||||
}
|
||||
|
||||
return nil
|
||||
return generateRule(
|
||||
logger,
|
||||
getAutogenRuleName("autogen-cronjob", rule.Name),
|
||||
generateRuleForControllers(rule, controllers, log),
|
||||
"jobTemplate",
|
||||
"spec/jobTemplate/spec/template",
|
||||
[]string{PodControllerCronJob},
|
||||
func(r kyverno.ResourceFilters, kinds []string) kyverno.ResourceFilters {
|
||||
return getAnyAllAutogenRule(r, "Job", kinds)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func updateGenRuleByte(pbyte []byte, kind string, genRule kyvernoRule) (obj []byte) {
|
||||
// TODO: do we need to unmarshall here ?
|
||||
if err := json.Unmarshal(pbyte, &genRule); err != nil {
|
||||
return obj
|
||||
}
|
||||
func updateGenRuleByte(pbyte []byte, kind string) (obj []byte) {
|
||||
if kind == "Pod" {
|
||||
obj = []byte(strings.ReplaceAll(string(pbyte), "request.object.spec", "request.object.spec.template.spec"))
|
||||
}
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
package autogen
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
)
|
||||
|
||||
func isKindOtherthanPod(kinds []string) bool {
|
||||
if len(kinds) > 1 && kubeutils.ContainsKind(kinds, "Pod") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func hasAutogenKinds(kind []string) bool {
|
||||
for _, v := range kind {
|
||||
if v == "Pod" || strings.Contains(PodControllers, v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func validateAnyPattern(anyPatterns []interface{}) []interface{} {
|
||||
var patterns []interface{}
|
||||
for _, pattern := range anyPatterns {
|
||||
newPattern := map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"template": pattern,
|
||||
},
|
||||
}
|
||||
patterns = append(patterns, newPattern)
|
||||
}
|
||||
return patterns
|
||||
}
|
||||
|
||||
func getAnyAllAutogenRule(v kyverno.ResourceFilters, controllers string) kyverno.ResourceFilters {
|
||||
anyKind := v.DeepCopy()
|
||||
for i, value := range v {
|
||||
if kubeutils.ContainsKind(value.Kinds, "Pod") {
|
||||
anyKind[i].Kinds = strings.Split(controllers, ",")
|
||||
}
|
||||
}
|
||||
return anyKind
|
||||
}
|
||||
|
||||
// stripCronJob removes CronJob from controllers
|
||||
func stripCronJob(controllers string) string {
|
||||
var newControllers []string
|
||||
controllerArr := strings.Split(controllers, ",")
|
||||
for _, c := range controllerArr {
|
||||
if c == PodControllerCronJob {
|
||||
continue
|
||||
}
|
||||
newControllers = append(newControllers, c)
|
||||
}
|
||||
if len(newControllers) == 0 {
|
||||
return ""
|
||||
}
|
||||
return strings.Join(newControllers, ",")
|
||||
}
|
||||
|
||||
func cronJobAnyAllAutogenRule(v kyverno.ResourceFilters) kyverno.ResourceFilters {
|
||||
anyKind := v.DeepCopy()
|
||||
for i, value := range v {
|
||||
if kubeutils.ContainsKind(value.Kinds, "Job") {
|
||||
anyKind[i].Kinds = []string{PodControllerCronJob}
|
||||
}
|
||||
}
|
||||
return anyKind
|
||||
}
|
|
@ -30,8 +30,7 @@ func (pc *PolicyController) processExistingResources(policy kyverno.PolicyInterf
|
|||
if !rule.HasValidate() && !rule.HasVerifyImages() {
|
||||
continue
|
||||
}
|
||||
|
||||
matchKinds := rule.MatchKinds()
|
||||
matchKinds := rule.MatchResources.GetKinds()
|
||||
pc.processExistingKinds(matchKinds, policy, rule, logger)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -734,7 +734,7 @@ func (m *webhookConfigManager) mergeWebhook(dst *webhook, policy kyverno.PolicyI
|
|||
for _, rule := range autogen.ComputeRules(policy) {
|
||||
// matching kinds in generate policies need to be added to both webhook
|
||||
if rule.HasGenerate() {
|
||||
matchedGVK = append(matchedGVK, rule.MatchKinds()...)
|
||||
matchedGVK = append(matchedGVK, rule.MatchResources.GetKinds()...)
|
||||
matchedGVK = append(matchedGVK, rule.Generation.ResourceSpec.Kind)
|
||||
continue
|
||||
}
|
||||
|
@ -742,7 +742,7 @@ func (m *webhookConfigManager) mergeWebhook(dst *webhook, policy kyverno.PolicyI
|
|||
if (updateValidate && rule.HasValidate()) ||
|
||||
(!updateValidate && rule.HasMutate()) ||
|
||||
(!updateValidate && rule.HasVerifyImages()) {
|
||||
matchedGVK = append(matchedGVK, rule.MatchKinds()...)
|
||||
matchedGVK = append(matchedGVK, rule.MatchResources.GetKinds()...)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -847,7 +847,7 @@ func webhookKey(webhookKind, failurePolicy string) string {
|
|||
|
||||
func hasWildcard(spec *kyverno.Spec) bool {
|
||||
for _, rule := range spec.Rules {
|
||||
if kinds := rule.MatchKinds(); utils.ContainsString(kinds, "*") {
|
||||
if kinds := rule.MatchResources.GetKinds(); utils.ContainsString(kinds, "*") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue