2022-03-01 23:19:31 +00:00
|
|
|
package autogen
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2022-03-10 15:51:29 +00:00
|
|
|
"strings"
|
2022-03-01 23:19:31 +00:00
|
|
|
|
2022-05-17 11:12:43 +00:00
|
|
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
2022-04-05 15:12:22 +00:00
|
|
|
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
2022-11-29 08:04:49 +00:00
|
|
|
"golang.org/x/exp/slices"
|
2022-03-10 15:51:29 +00:00
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
2022-04-05 15:12:22 +00:00
|
|
|
"k8s.io/apimachinery/pkg/util/sets"
|
2022-03-09 13:48:04 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// PodControllerCronJob represent CronJob string
|
|
|
|
PodControllerCronJob = "CronJob"
|
2022-05-17 06:19:03 +00:00
|
|
|
// PodControllers stores the list of Pod-controllers in csv string
|
2022-11-14 10:18:45 +00:00
|
|
|
PodControllers = "DaemonSet,Deployment,Job,StatefulSet,ReplicaSet,ReplicationController,CronJob"
|
2022-03-01 23:19:31 +00:00
|
|
|
)
|
|
|
|
|
2022-12-21 22:33:51 +00:00
|
|
|
var podControllersKindsSet = sets.New(append(strings.Split(PodControllers, ","), "Pod")...)
|
2022-04-05 15:12:22 +00:00
|
|
|
|
|
|
|
func isKindOtherthanPod(kinds []string) bool {
|
|
|
|
if len(kinds) > 1 && kubeutils.ContainsKind(kinds, "Pod") {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-05-17 11:12:43 +00:00
|
|
|
func checkAutogenSupport(needed *bool, subjects ...kyvernov1.ResourceDescription) bool {
|
2022-04-05 15:12:22 +00:00
|
|
|
for _, subject := range subjects {
|
2022-10-12 06:09:02 +00:00
|
|
|
if subject.Name != "" || len(subject.Names) > 0 || subject.Selector != nil || subject.Annotations != nil || isKindOtherthanPod(subject.Kinds) {
|
2022-04-05 15:12:22 +00:00
|
|
|
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, ",")
|
|
|
|
}
|
|
|
|
|
2022-03-01 23:19:31 +00:00
|
|
|
// CanAutoGen checks whether the rule(s) (in policy) can be applied to Pod controllers
|
|
|
|
// returns controllers as:
|
|
|
|
// - "" if:
|
2022-08-24 13:08:24 +00:00
|
|
|
// - name or selector is defined
|
|
|
|
// - mixed kinds (Pod + pod controller) is defined
|
|
|
|
// - Pod and PodControllers are not defined
|
|
|
|
// - mutate.Patches/mutate.PatchesJSON6902/validate.deny/generate rule is defined
|
|
|
|
//
|
2022-03-01 23:19:31 +00:00
|
|
|
// - otherwise it returns all pod controllers
|
2022-05-17 11:12:43 +00:00
|
|
|
func CanAutoGen(spec *kyvernov1.Spec) (applyAutoGen bool, controllers string) {
|
2022-04-05 15:12:22 +00:00
|
|
|
needed := false
|
|
|
|
for _, rule := range spec.Rules {
|
|
|
|
if rule.Mutation.PatchesJSON6902 != "" || rule.HasGenerate() {
|
|
|
|
return false, "none"
|
2022-03-01 23:19:31 +00:00
|
|
|
}
|
2023-04-25 08:32:19 +00:00
|
|
|
for _, foreach := range rule.Mutation.ForEachMutation {
|
|
|
|
if foreach.PatchesJSON6902 != "" {
|
|
|
|
return false, "none"
|
|
|
|
}
|
|
|
|
}
|
2022-04-05 15:12:22 +00:00
|
|
|
match, exclude := rule.MatchResources, rule.ExcludeResources
|
|
|
|
if !checkAutogenSupport(&needed, match.ResourceDescription, exclude.ResourceDescription) {
|
2022-12-14 13:06:24 +00:00
|
|
|
debug.Info("skip generating rule on pod controllers: Name / Selector in resource description may not be applicable.", "rule", rule.Name)
|
2022-03-01 23:19:31 +00:00
|
|
|
return false, ""
|
|
|
|
}
|
|
|
|
for _, value := range match.Any {
|
2022-04-05 15:12:22 +00:00
|
|
|
if !checkAutogenSupport(&needed, value.ResourceDescription) {
|
2022-12-14 13:06:24 +00:00
|
|
|
debug.Info("skip generating rule on pod controllers: Name / Selector in match any block is not applicable.", "rule", rule.Name)
|
2022-03-01 23:19:31 +00:00
|
|
|
return false, ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, value := range match.All {
|
2022-04-05 15:12:22 +00:00
|
|
|
if !checkAutogenSupport(&needed, value.ResourceDescription) {
|
2022-12-14 13:06:24 +00:00
|
|
|
debug.Info("skip generating rule on pod controllers: Name / Selector in match all block is not applicable.", "rule", rule.Name)
|
2022-03-01 23:19:31 +00:00
|
|
|
return false, ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, value := range exclude.Any {
|
2022-04-05 15:12:22 +00:00
|
|
|
if !checkAutogenSupport(&needed, value.ResourceDescription) {
|
2022-12-14 13:06:24 +00:00
|
|
|
debug.Info("skip generating rule on pod controllers: Name / Selector in exclude any block is not applicable.", "rule", rule.Name)
|
2022-03-01 23:19:31 +00:00
|
|
|
return false, ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, value := range exclude.All {
|
2022-04-05 15:12:22 +00:00
|
|
|
if !checkAutogenSupport(&needed, value.ResourceDescription) {
|
2022-12-14 13:06:24 +00:00
|
|
|
debug.Info("skip generating rule on pod controllers: Name / Selector in exclud all block is not applicable.", "rule", rule.Name)
|
2022-03-01 23:19:31 +00:00
|
|
|
return false, ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-04-05 15:12:22 +00:00
|
|
|
if !needed {
|
2022-03-01 23:19:31 +00:00
|
|
|
return false, ""
|
|
|
|
}
|
2022-03-09 13:48:04 +00:00
|
|
|
return true, PodControllers
|
2022-03-01 23:19:31 +00:00
|
|
|
}
|
|
|
|
|
2022-03-10 15:51:29 +00:00
|
|
|
// GetSupportedControllers returns the supported autogen controllers for a given spec.
|
2022-05-17 11:12:43 +00:00
|
|
|
func GetSupportedControllers(spec *kyvernov1.Spec) []string {
|
2022-04-29 09:12:21 +00:00
|
|
|
apply, controllers := CanAutoGen(spec)
|
2022-03-10 15:51:29 +00:00
|
|
|
if !apply || controllers == "none" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return strings.Split(controllers, ",")
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetRequestedControllers returns the requested autogen controllers based on object annotations.
|
2022-03-25 14:43:47 +00:00
|
|
|
func GetRequestedControllers(meta *metav1.ObjectMeta) []string {
|
2022-03-10 15:51:29 +00:00
|
|
|
annotations := meta.GetAnnotations()
|
|
|
|
if annotations == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2022-05-17 11:12:43 +00:00
|
|
|
controllers, ok := annotations[kyvernov1.PodControllersAnnotation]
|
2022-03-10 15:51:29 +00:00
|
|
|
if !ok || controllers == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if controllers == "none" {
|
|
|
|
return []string{}
|
|
|
|
}
|
|
|
|
return strings.Split(controllers, ",")
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetControllers computes the autogen controllers that should be applied to a policy.
|
|
|
|
// It returns the requested, supported and effective controllers (intersection of requested and supported ones).
|
2022-05-17 11:12:43 +00:00
|
|
|
func GetControllers(meta *metav1.ObjectMeta, spec *kyvernov1.Spec) ([]string, []string, []string) {
|
2022-03-10 15:51:29 +00:00
|
|
|
// compute supported and requested controllers
|
2022-04-29 09:12:21 +00:00
|
|
|
supported, requested := GetSupportedControllers(spec), GetRequestedControllers(meta)
|
2022-03-10 15:51:29 +00:00
|
|
|
// 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 {
|
2022-11-29 08:04:49 +00:00
|
|
|
if slices.Contains(requested, controller) {
|
2022-03-10 15:51:29 +00:00
|
|
|
activated = append(activated, controller)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return requested, supported, activated
|
|
|
|
}
|
|
|
|
|
2022-03-01 23:19:31 +00:00
|
|
|
// podControllersKey annotation could be:
|
|
|
|
// scenario A: not exist, set default to "all", which generates on all pod controllers
|
|
|
|
// - if name / selector exist in resource description -> skip
|
|
|
|
// as these fields may not be applicable to pod controllers
|
|
|
|
// scenario B: "none", user explicitly disable this feature -> skip
|
2022-03-28 14:01:27 +00:00
|
|
|
// scenario C: some certain controllers that user set -> generate on defined controllers
|
|
|
|
// copy entire match / exclude block, it's users' responsibility to
|
|
|
|
// make sure all fields are applicable to pod controllers
|
|
|
|
|
2022-04-05 15:12:22 +00:00
|
|
|
// generateRules generates rule for podControllers based on scenario A and C
|
2022-05-17 11:12:43 +00:00
|
|
|
func generateRules(spec *kyvernov1.Spec, controllers string) []kyvernov1.Rule {
|
|
|
|
var rules []kyvernov1.Rule
|
2022-04-05 15:12:22 +00:00
|
|
|
for i := range spec.Rules {
|
2022-03-28 14:01:27 +00:00
|
|
|
// handle all other controllers other than CronJob
|
2022-04-29 09:12:21 +00:00
|
|
|
if genRule := createRule(generateRuleForControllers(&spec.Rules[i], stripCronJob(controllers))); genRule != nil {
|
2022-03-28 14:01:27 +00:00
|
|
|
if convRule, err := convertRule(*genRule, "Pod"); err == nil {
|
|
|
|
rules = append(rules, *convRule)
|
2022-09-12 07:03:35 +00:00
|
|
|
} else {
|
|
|
|
logger.Error(err, "failed to create rule")
|
2022-03-28 14:01:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// handle CronJob, it appends an additional rule
|
2022-04-29 09:12:21 +00:00
|
|
|
if genRule := createRule(generateCronJobRule(&spec.Rules[i], controllers)); genRule != nil {
|
2022-03-28 14:01:27 +00:00
|
|
|
if convRule, err := convertRule(*genRule, "Cronjob"); err == nil {
|
|
|
|
rules = append(rules, *convRule)
|
2022-09-12 07:03:35 +00:00
|
|
|
} else {
|
|
|
|
logger.Error(err, "failed to create Cronjob rule")
|
2022-03-28 14:01:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rules
|
|
|
|
}
|
|
|
|
|
2022-05-17 11:12:43 +00:00
|
|
|
func convertRule(rule kyvernoRule, kind string) (*kyvernov1.Rule, error) {
|
2022-03-28 14:01:27 +00:00
|
|
|
if bytes, err := json.Marshal(rule); err != nil {
|
|
|
|
return nil, err
|
|
|
|
} else {
|
Extend Pod Security Admission (#4364)
* init commit for pss
Signed-off-by: ShutingZhao <shuting@nirmata.com>
* add test for Volume Type control
* add test for App Armor control except ExemptProfile. Fix PSS profile check in EvaluatePSS()
* remove unused code, still a JMESPATH problem with app armor ExemptProfile()
* test for Host Process / Host Namespaces controls
* test for Privileged containers controls
* test for HostPathVolume control
* test for HostPorts control
* test for HostPorts control
* test for SELinux control
* test for Proc mount type control
* Set to baseline
* test for Seccomp control
* test for Sysctl control
* test for Privilege escalation control
* test for Run as non root control
* test for Restricted Seccomp control
* Add problems to address
* add solutions to problems
* Add validate rule for PSA
* api.Version --> string. latest by default
* Exclude all values for a restrictedField
* add tests for kyverno engine
* code to be used to match kyverno rule's namespace
* Refacto pkg/pss
* fix multiple problems: not matching containers, add contains methods, select the right container when we have the same exclude.RestrictedField for multiple containers:
* EvaluatePod
* Use EvaluatePod in kyverno engine
* Set pod instead of container in context to use full Jmespath. e.g.: securityContext.capabilities.add --> spec.containers[*].securityContext.capabilities.add
* Check if PSSCheckResult matched at least one exclude value
* add tests for engine
* fix engine validation test
* config
* update go.mod and go.sum
* crds
* Check validate value: add PodSecurity
* exclude all restrictedFields when we only specify the controlName
* ExemptProfile(): check if exclud.RestrictedField matches at least one restrictedField.path
* handle containers, initContainers, ephemeralContainers when we only specify the controlName (all restrictedFields are excluded)
* refacto pks/pss/evaluate.go and add pkg/engine/validation_test.go
* add all controls with containers in restrictedFields as comments
* add tests for capabilities and privileged containers and fix some errors
* add tests for host ports control
* add tests for proc mount control
* add tests for privilege escalation control
* add tests for capabilities control
* remove comments
* new algo
* refacto algo, working. Add test for hostProcess control
* remove unused code
* fix getPodWithNotMatchingContainers(), add tests for host namespaces control
* refacto ExemptProfile()
* get values for a specific container. add test for SELinuxOptions control
* fix allowedValues for SELinuxOptions
* add tests for seccompProfile_baseline control
* refacto checkContainers(), add test for seccomp control
* add test for running as non root control
* add some tests for runAsUser control, have to update current PSA version
* add sysctls control
* add allowed values for restrictedVolumes control
* add some tests for appArmor, volume types controls
* add tests for volume types control
* add tests for hostPath volume control
* finish merge conflicts and add tests for runAsUser
* update charts and crds
* exclude.images optional
* change volume types control exclude values
* add appAmor control
* fix: did not match any exclude value for pod-level restrictedFields
* create autogen for validate.PodSecurity
* clean code, remove logs
* fix sonatype lift errors
* fix sonatype lift errors: duplication
* fix crash in pkg/policy/validate/ tests and unmarshall errors for pkg/engine tests
* beginning of autogen implement for validate.exclude
* Autogen for validation.PodSecurity
* working autogen with simple tests
* change validate.PodSecurity failure response format
* make codegen
* fix lint errors, remove debug prints
* fix tags
* fix tags
* fix crash when deleting pods matching validate.podSecurity rule. Only check validatePodSecurity() when it's not a delete request
* Changes requested
* Changes requested 2
* Changes requested 3
* Changes requested 4
* Changes requested and make codegen
* fix host namespaces control
* fix lint
* fix codegen error
* update docs/crd/v1/index.html
Signed-off-by: ShutingZhao <shuting@nirmata.com>
* fix path
Signed-off-by: ShutingZhao <shuting@nirmata.com>
* update crd schema
Signed-off-by: ShutingZhao <shuting@nirmata.com>
* update charts/kyverno/templates/crds.yaml
Signed-off-by: ShutingZhao <shuting@nirmata.com>
Signed-off-by: ShutingZhao <shuting@nirmata.com>
Co-authored-by: ShutingZhao <shuting@nirmata.com>
2022-08-31 09:16:31 +00:00
|
|
|
if rule.Validation != nil && rule.Validation.PodSecurity != nil {
|
|
|
|
bytes = updateRestrictedFields(bytes, kind)
|
|
|
|
if err := json.Unmarshal(bytes, &rule); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
bytes = updateGenRuleByte(bytes, kind)
|
|
|
|
if err := json.Unmarshal(bytes, &rule); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2022-03-28 14:01:27 +00:00
|
|
|
}
|
|
|
|
}
|
Extend Pod Security Admission (#4364)
* init commit for pss
Signed-off-by: ShutingZhao <shuting@nirmata.com>
* add test for Volume Type control
* add test for App Armor control except ExemptProfile. Fix PSS profile check in EvaluatePSS()
* remove unused code, still a JMESPATH problem with app armor ExemptProfile()
* test for Host Process / Host Namespaces controls
* test for Privileged containers controls
* test for HostPathVolume control
* test for HostPorts control
* test for HostPorts control
* test for SELinux control
* test for Proc mount type control
* Set to baseline
* test for Seccomp control
* test for Sysctl control
* test for Privilege escalation control
* test for Run as non root control
* test for Restricted Seccomp control
* Add problems to address
* add solutions to problems
* Add validate rule for PSA
* api.Version --> string. latest by default
* Exclude all values for a restrictedField
* add tests for kyverno engine
* code to be used to match kyverno rule's namespace
* Refacto pkg/pss
* fix multiple problems: not matching containers, add contains methods, select the right container when we have the same exclude.RestrictedField for multiple containers:
* EvaluatePod
* Use EvaluatePod in kyverno engine
* Set pod instead of container in context to use full Jmespath. e.g.: securityContext.capabilities.add --> spec.containers[*].securityContext.capabilities.add
* Check if PSSCheckResult matched at least one exclude value
* add tests for engine
* fix engine validation test
* config
* update go.mod and go.sum
* crds
* Check validate value: add PodSecurity
* exclude all restrictedFields when we only specify the controlName
* ExemptProfile(): check if exclud.RestrictedField matches at least one restrictedField.path
* handle containers, initContainers, ephemeralContainers when we only specify the controlName (all restrictedFields are excluded)
* refacto pks/pss/evaluate.go and add pkg/engine/validation_test.go
* add all controls with containers in restrictedFields as comments
* add tests for capabilities and privileged containers and fix some errors
* add tests for host ports control
* add tests for proc mount control
* add tests for privilege escalation control
* add tests for capabilities control
* remove comments
* new algo
* refacto algo, working. Add test for hostProcess control
* remove unused code
* fix getPodWithNotMatchingContainers(), add tests for host namespaces control
* refacto ExemptProfile()
* get values for a specific container. add test for SELinuxOptions control
* fix allowedValues for SELinuxOptions
* add tests for seccompProfile_baseline control
* refacto checkContainers(), add test for seccomp control
* add test for running as non root control
* add some tests for runAsUser control, have to update current PSA version
* add sysctls control
* add allowed values for restrictedVolumes control
* add some tests for appArmor, volume types controls
* add tests for volume types control
* add tests for hostPath volume control
* finish merge conflicts and add tests for runAsUser
* update charts and crds
* exclude.images optional
* change volume types control exclude values
* add appAmor control
* fix: did not match any exclude value for pod-level restrictedFields
* create autogen for validate.PodSecurity
* clean code, remove logs
* fix sonatype lift errors
* fix sonatype lift errors: duplication
* fix crash in pkg/policy/validate/ tests and unmarshall errors for pkg/engine tests
* beginning of autogen implement for validate.exclude
* Autogen for validation.PodSecurity
* working autogen with simple tests
* change validate.PodSecurity failure response format
* make codegen
* fix lint errors, remove debug prints
* fix tags
* fix tags
* fix crash when deleting pods matching validate.podSecurity rule. Only check validatePodSecurity() when it's not a delete request
* Changes requested
* Changes requested 2
* Changes requested 3
* Changes requested 4
* Changes requested and make codegen
* fix host namespaces control
* fix lint
* fix codegen error
* update docs/crd/v1/index.html
Signed-off-by: ShutingZhao <shuting@nirmata.com>
* fix path
Signed-off-by: ShutingZhao <shuting@nirmata.com>
* update crd schema
Signed-off-by: ShutingZhao <shuting@nirmata.com>
* update charts/kyverno/templates/crds.yaml
Signed-off-by: ShutingZhao <shuting@nirmata.com>
Signed-off-by: ShutingZhao <shuting@nirmata.com>
Co-authored-by: ShutingZhao <shuting@nirmata.com>
2022-08-31 09:16:31 +00:00
|
|
|
|
2022-05-17 11:12:43 +00:00
|
|
|
out := kyvernov1.Rule{
|
2022-03-28 14:01:27 +00:00
|
|
|
Name: rule.Name,
|
|
|
|
VerifyImages: rule.VerifyImages,
|
|
|
|
}
|
|
|
|
if rule.MatchResources != nil {
|
|
|
|
out.MatchResources = *rule.MatchResources
|
|
|
|
}
|
|
|
|
if rule.ExcludeResources != nil {
|
|
|
|
out.ExcludeResources = *rule.ExcludeResources
|
|
|
|
}
|
|
|
|
if rule.Context != nil {
|
|
|
|
out.Context = *rule.Context
|
|
|
|
}
|
|
|
|
if rule.AnyAllConditions != nil {
|
|
|
|
out.SetAnyAllConditions(*rule.AnyAllConditions)
|
|
|
|
}
|
|
|
|
if rule.Mutation != nil {
|
|
|
|
out.Mutation = *rule.Mutation
|
|
|
|
}
|
|
|
|
if rule.Validation != nil {
|
|
|
|
out.Validation = *rule.Validation
|
|
|
|
}
|
|
|
|
return &out, nil
|
|
|
|
}
|
|
|
|
|
2022-05-17 11:12:43 +00:00
|
|
|
func ComputeRules(p kyvernov1.PolicyInterface) []kyvernov1.Rule {
|
2022-04-29 11:48:22 +00:00
|
|
|
return computeRules(p)
|
|
|
|
}
|
|
|
|
|
2022-05-17 11:12:43 +00:00
|
|
|
func computeRules(p kyvernov1.PolicyInterface) []kyvernov1.Rule {
|
2022-04-29 11:48:22 +00:00
|
|
|
spec := p.GetSpec()
|
2022-04-29 09:12:21 +00:00
|
|
|
applyAutoGen, desiredControllers := CanAutoGen(spec)
|
2022-03-28 14:01:27 +00:00
|
|
|
if !applyAutoGen {
|
|
|
|
desiredControllers = "none"
|
|
|
|
}
|
|
|
|
ann := p.GetAnnotations()
|
2022-05-17 11:12:43 +00:00
|
|
|
actualControllers, ok := ann[kyvernov1.PodControllersAnnotation]
|
2022-03-28 14:01:27 +00:00
|
|
|
if !ok || !applyAutoGen {
|
|
|
|
actualControllers = desiredControllers
|
|
|
|
} else {
|
|
|
|
if !applyAutoGen {
|
|
|
|
actualControllers = desiredControllers
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if actualControllers == "none" {
|
|
|
|
return spec.Rules
|
|
|
|
}
|
2022-04-29 09:12:21 +00:00
|
|
|
genRules := generateRules(spec.DeepCopy(), actualControllers)
|
2022-03-28 14:01:27 +00:00
|
|
|
if len(genRules) == 0 {
|
|
|
|
return spec.Rules
|
|
|
|
}
|
2022-05-17 11:12:43 +00:00
|
|
|
var out []kyvernov1.Rule
|
2022-08-23 06:42:46 +00:00
|
|
|
for _, rule := range spec.Rules {
|
|
|
|
if !isAutogenRuleName(rule.Name) {
|
|
|
|
out = append(out, rule)
|
|
|
|
}
|
|
|
|
}
|
2022-03-28 14:01:27 +00:00
|
|
|
out = append(out, genRules...)
|
|
|
|
return out
|
|
|
|
}
|