mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
feat: use pointer in rule (exclude field) (#11050)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
9934c0e61a
commit
b5e1c97913
20 changed files with 219 additions and 178 deletions
|
@ -46,6 +46,9 @@ func (m *MatchResources) GetKinds() []string {
|
||||||
|
|
||||||
// Validate implements programmatic validation
|
// Validate implements programmatic validation
|
||||||
func (m *MatchResources) Validate(path *field.Path, namespaced bool, clusterResources sets.Set[string]) (errs field.ErrorList) {
|
func (m *MatchResources) Validate(path *field.Path, namespaced bool, clusterResources sets.Set[string]) (errs field.ErrorList) {
|
||||||
|
if m == nil {
|
||||||
|
return errs
|
||||||
|
}
|
||||||
if len(m.Any) > 0 && len(m.All) > 0 {
|
if len(m.Any) > 0 && len(m.All) > 0 {
|
||||||
errs = append(errs, field.Invalid(path, m, "Can't specify any and all together"))
|
errs = append(errs, field.Invalid(path, m, "Can't specify any and all together"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ type Rule struct {
|
||||||
// criteria can include resource information (e.g. kind, name, namespace, labels)
|
// criteria can include resource information (e.g. kind, name, namespace, labels)
|
||||||
// and admission review request information like the name or role.
|
// and admission review request information like the name or role.
|
||||||
// +optional
|
// +optional
|
||||||
ExcludeResources MatchResources `json:"exclude,omitempty"`
|
ExcludeResources *MatchResources `json:"exclude,omitempty"`
|
||||||
|
|
||||||
// ImageExtractors defines a mapping from kinds to ImageExtractorConfigs.
|
// ImageExtractors defines a mapping from kinds to ImageExtractorConfigs.
|
||||||
// This config is only valid for verifyImages rules.
|
// This config is only valid for verifyImages rules.
|
||||||
|
@ -252,6 +252,9 @@ func (r *Rule) ValidateRuleType(path *field.Path) (errs field.ErrorList) {
|
||||||
|
|
||||||
// ValidateMatchExcludeConflict checks if the resultant of match and exclude block is not an empty set
|
// ValidateMatchExcludeConflict checks if the resultant of match and exclude block is not an empty set
|
||||||
func (r *Rule) ValidateMatchExcludeConflict(path *field.Path) (errs field.ErrorList) {
|
func (r *Rule) ValidateMatchExcludeConflict(path *field.Path) (errs field.ErrorList) {
|
||||||
|
if r.ExcludeResources == nil {
|
||||||
|
return errs
|
||||||
|
}
|
||||||
if len(r.ExcludeResources.All) > 0 || len(r.MatchResources.All) > 0 {
|
if len(r.ExcludeResources.All) > 0 || len(r.MatchResources.All) > 0 {
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
@ -266,7 +269,7 @@ func (r *Rule) ValidateMatchExcludeConflict(path *field.Path) (errs field.ErrorL
|
||||||
}
|
}
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
if datautils.DeepEqual(r.ExcludeResources, MatchResources{}) {
|
if datautils.DeepEqual(*r.ExcludeResources, MatchResources{}) {
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
excludeRoles := sets.New(r.ExcludeResources.Roles...)
|
excludeRoles := sets.New(r.ExcludeResources.Roles...)
|
||||||
|
|
|
@ -1396,7 +1396,11 @@ func (in *Rule) DeepCopyInto(out *Rule) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in.MatchResources.DeepCopyInto(&out.MatchResources)
|
in.MatchResources.DeepCopyInto(&out.MatchResources)
|
||||||
in.ExcludeResources.DeepCopyInto(&out.ExcludeResources)
|
if in.ExcludeResources != nil {
|
||||||
|
in, out := &in.ExcludeResources, &out.ExcludeResources
|
||||||
|
*out = new(MatchResources)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.ImageExtractors != nil {
|
if in.ImageExtractors != nil {
|
||||||
in, out := &in.ImageExtractors, &out.ImageExtractors
|
in, out := &in.ImageExtractors, &out.ImageExtractors
|
||||||
*out = make(ImageExtractorConfigs, len(*in))
|
*out = make(ImageExtractorConfigs, len(*in))
|
||||||
|
|
|
@ -41,6 +41,9 @@ func (m *MatchResources) GetKinds() []string {
|
||||||
|
|
||||||
// ValidateNoUserInfo verifies that no user info is used
|
// ValidateNoUserInfo verifies that no user info is used
|
||||||
func (m *MatchResources) ValidateNoUserInfo(path *field.Path) (errs field.ErrorList) {
|
func (m *MatchResources) ValidateNoUserInfo(path *field.Path) (errs field.ErrorList) {
|
||||||
|
if m == nil {
|
||||||
|
return errs
|
||||||
|
}
|
||||||
anyPath := path.Child("any")
|
anyPath := path.Child("any")
|
||||||
for i, filter := range m.Any {
|
for i, filter := range m.Any {
|
||||||
errs = append(errs, filter.UserInfo.ValidateNoUserInfo(anyPath.Index(i))...)
|
errs = append(errs, filter.UserInfo.ValidateNoUserInfo(anyPath.Index(i))...)
|
||||||
|
@ -54,6 +57,9 @@ func (m *MatchResources) ValidateNoUserInfo(path *field.Path) (errs field.ErrorL
|
||||||
|
|
||||||
// ValidateResourceWithNoUserInfo implements programmatic validation and verifies that no user info is used
|
// ValidateResourceWithNoUserInfo implements programmatic validation and verifies that no user info is used
|
||||||
func (m *MatchResources) ValidateResourceWithNoUserInfo(path *field.Path, namespaced bool, clusterResources sets.Set[string]) (errs field.ErrorList) {
|
func (m *MatchResources) ValidateResourceWithNoUserInfo(path *field.Path, namespaced bool, clusterResources sets.Set[string]) (errs field.ErrorList) {
|
||||||
|
if m == nil {
|
||||||
|
return errs
|
||||||
|
}
|
||||||
if len(m.Any) > 0 && len(m.All) > 0 {
|
if len(m.Any) > 0 && len(m.All) > 0 {
|
||||||
errs = append(errs, field.Invalid(path, m, "Can't specify any and all together"))
|
errs = append(errs, field.Invalid(path, m, "Can't specify any and all together"))
|
||||||
}
|
}
|
||||||
|
@ -72,6 +78,9 @@ func (m *MatchResources) ValidateResourceWithNoUserInfo(path *field.Path, namesp
|
||||||
|
|
||||||
// Validate implements programmatic validation
|
// Validate implements programmatic validation
|
||||||
func (m *MatchResources) Validate(path *field.Path, namespaced bool, clusterResources sets.Set[string]) (errs field.ErrorList) {
|
func (m *MatchResources) Validate(path *field.Path, namespaced bool, clusterResources sets.Set[string]) (errs field.ErrorList) {
|
||||||
|
if m == nil {
|
||||||
|
return errs
|
||||||
|
}
|
||||||
if len(m.Any) > 0 && len(m.All) > 0 {
|
if len(m.Any) > 0 && len(m.All) > 0 {
|
||||||
errs = append(errs, field.Invalid(path, m, "Can't specify any and all together"))
|
errs = append(errs, field.Invalid(path, m, "Can't specify any and all together"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ type Rule struct {
|
||||||
// criteria can include resource information (e.g. kind, name, namespace, labels)
|
// criteria can include resource information (e.g. kind, name, namespace, labels)
|
||||||
// and admission review request information like the name or role.
|
// and admission review request information like the name or role.
|
||||||
// +optional
|
// +optional
|
||||||
ExcludeResources MatchResources `json:"exclude,omitempty"`
|
ExcludeResources *MatchResources `json:"exclude,omitempty"`
|
||||||
|
|
||||||
// ImageExtractors defines a mapping from kinds to ImageExtractorConfigs.
|
// ImageExtractors defines a mapping from kinds to ImageExtractorConfigs.
|
||||||
// This config is only valid for verifyImages rules.
|
// This config is only valid for verifyImages rules.
|
||||||
|
@ -160,6 +160,9 @@ func (r *Rule) ValidateRuleType(path *field.Path) (errs field.ErrorList) {
|
||||||
|
|
||||||
// ValidateMatchExcludeConflict checks if the resultant of match and exclude block is not an empty set
|
// ValidateMatchExcludeConflict checks if the resultant of match and exclude block is not an empty set
|
||||||
func (r *Rule) ValidateMatchExcludeConflict(path *field.Path) (errs field.ErrorList) {
|
func (r *Rule) ValidateMatchExcludeConflict(path *field.Path) (errs field.ErrorList) {
|
||||||
|
if r.ExcludeResources == nil {
|
||||||
|
return errs
|
||||||
|
}
|
||||||
if len(r.ExcludeResources.All) > 0 || len(r.MatchResources.All) > 0 {
|
if len(r.ExcludeResources.All) > 0 || len(r.MatchResources.All) > 0 {
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
|
@ -712,7 +712,11 @@ func (in *Rule) DeepCopyInto(out *Rule) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in.MatchResources.DeepCopyInto(&out.MatchResources)
|
in.MatchResources.DeepCopyInto(&out.MatchResources)
|
||||||
in.ExcludeResources.DeepCopyInto(&out.ExcludeResources)
|
if in.ExcludeResources != nil {
|
||||||
|
in, out := &in.ExcludeResources, &out.ExcludeResources
|
||||||
|
*out = new(MatchResources)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
if in.ImageExtractors != nil {
|
if in.ImageExtractors != nil {
|
||||||
in, out := &in.ImageExtractors, &out.ImageExtractors
|
in, out := &in.ImageExtractors, &out.ImageExtractors
|
||||||
*out = make(v1.ImageExtractorConfigs, len(*in))
|
*out = make(v1.ImageExtractorConfigs, len(*in))
|
||||||
|
|
|
@ -98,6 +98,7 @@ func GetKindsFromPolicy(out io.Writer, policy kyvernov1.PolicyInterface, subreso
|
||||||
}
|
}
|
||||||
knownkinds.Insert(k)
|
knownkinds.Insert(k)
|
||||||
}
|
}
|
||||||
|
if rule.ExcludeResources != nil {
|
||||||
for _, kind := range rule.ExcludeResources.ResourceDescription.Kinds {
|
for _, kind := range rule.ExcludeResources.ResourceDescription.Kinds {
|
||||||
k, err := getKind(kind, subresources, dClient)
|
k, err := getKind(kind, subresources, dClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -107,6 +108,7 @@ func GetKindsFromPolicy(out io.Writer, policy kyvernov1.PolicyInterface, subreso
|
||||||
knownkinds.Insert(k)
|
knownkinds.Insert(k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return knownkinds
|
return knownkinds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,8 +77,8 @@ func CanAutoGen(spec *kyvernov1.Spec) (applyAutoGen bool, controllers sets.Set[s
|
||||||
return false, sets.New("none")
|
return false, sets.New("none")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match, exclude := rule.MatchResources, rule.ExcludeResources
|
match := rule.MatchResources
|
||||||
if !checkAutogenSupport(&needed, match.ResourceDescription, exclude.ResourceDescription) {
|
if !checkAutogenSupport(&needed, match.ResourceDescription) {
|
||||||
debug.Info("skip generating rule on pod controllers: Name / Selector in resource description may not be applicable.", "rule", rule.Name)
|
debug.Info("skip generating rule on pod controllers: Name / Selector in resource description may not be applicable.", "rule", rule.Name)
|
||||||
return false, sets.New[string]()
|
return false, sets.New[string]()
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,11 @@ func CanAutoGen(spec *kyvernov1.Spec) (applyAutoGen bool, controllers sets.Set[s
|
||||||
return false, sets.New[string]()
|
return false, sets.New[string]()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if exclude := rule.ExcludeResources; exclude != nil {
|
||||||
|
if !checkAutogenSupport(&needed, exclude.ResourceDescription) {
|
||||||
|
debug.Info("skip generating rule on pod controllers: Name / Selector in resource description may not be applicable.", "rule", rule.Name)
|
||||||
|
return false, sets.New[string]()
|
||||||
|
}
|
||||||
for _, value := range exclude.Any {
|
for _, value := range exclude.Any {
|
||||||
if !checkAutogenSupport(&needed, value.ResourceDescription) {
|
if !checkAutogenSupport(&needed, value.ResourceDescription) {
|
||||||
debug.Info("skip generating rule on pod controllers: Name / Selector in exclude any block is not applicable.", "rule", rule.Name)
|
debug.Info("skip generating rule on pod controllers: Name / Selector in exclude any block is not applicable.", "rule", rule.Name)
|
||||||
|
@ -107,6 +112,7 @@ func CanAutoGen(spec *kyvernov1.Spec) (applyAutoGen bool, controllers sets.Set[s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if !needed {
|
if !needed {
|
||||||
return false, sets.New[string]()
|
return false, sets.New[string]()
|
||||||
}
|
}
|
||||||
|
@ -210,7 +216,7 @@ func convertRule(rule kyvernoRule, kind string) (*kyvernov1.Rule, error) {
|
||||||
out.MatchResources = *rule.MatchResources
|
out.MatchResources = *rule.MatchResources
|
||||||
}
|
}
|
||||||
if rule.ExcludeResources != nil {
|
if rule.ExcludeResources != nil {
|
||||||
out.ExcludeResources = *rule.ExcludeResources
|
out.ExcludeResources = rule.ExcludeResources
|
||||||
}
|
}
|
||||||
if rule.Context != nil {
|
if rule.Context != nil {
|
||||||
out.Context = *rule.Context
|
out.Context = *rule.Context
|
||||||
|
|
|
@ -42,7 +42,7 @@ func createRule(rule *kyvernov1.Rule) *kyvernoRule {
|
||||||
if !datautils.DeepEqual(rule.MatchResources, kyvernov1.MatchResources{}) {
|
if !datautils.DeepEqual(rule.MatchResources, kyvernov1.MatchResources{}) {
|
||||||
jsonFriendlyStruct.MatchResources = rule.MatchResources.DeepCopy()
|
jsonFriendlyStruct.MatchResources = rule.MatchResources.DeepCopy()
|
||||||
}
|
}
|
||||||
if !datautils.DeepEqual(rule.ExcludeResources, kyvernov1.MatchResources{}) {
|
if rule.ExcludeResources != nil && !datautils.DeepEqual(*rule.ExcludeResources, kyvernov1.MatchResources{}) {
|
||||||
jsonFriendlyStruct.ExcludeResources = rule.ExcludeResources.DeepCopy()
|
jsonFriendlyStruct.ExcludeResources = rule.ExcludeResources.DeepCopy()
|
||||||
}
|
}
|
||||||
if !datautils.DeepEqual(rule.Mutation, kyvernov1.Mutation{}) {
|
if !datautils.DeepEqual(rule.Mutation, kyvernov1.Mutation{}) {
|
||||||
|
@ -84,6 +84,7 @@ func generateRule(name string, rule *kyvernov1.Rule, tplKey, shift string, kinds
|
||||||
} else {
|
} else {
|
||||||
rule.MatchResources.Kinds = kinds
|
rule.MatchResources.Kinds = kinds
|
||||||
}
|
}
|
||||||
|
if rule.ExcludeResources != nil {
|
||||||
if len(rule.ExcludeResources.Any) > 0 {
|
if len(rule.ExcludeResources.Any) > 0 {
|
||||||
rule.ExcludeResources.Any = grf(rule.ExcludeResources.Any, kinds)
|
rule.ExcludeResources.Any = grf(rule.ExcludeResources.Any, kinds)
|
||||||
} else if len(rule.ExcludeResources.All) > 0 {
|
} else if len(rule.ExcludeResources.All) > 0 {
|
||||||
|
@ -93,6 +94,7 @@ func generateRule(name string, rule *kyvernov1.Rule, tplKey, shift string, kinds
|
||||||
rule.ExcludeResources.Kinds = kinds
|
rule.ExcludeResources.Kinds = kinds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if target := rule.Mutation.GetPatchStrategicMerge(); target != nil {
|
if target := rule.Mutation.GetPatchStrategicMerge(); target != nil {
|
||||||
newMutation := kyvernov1.Mutation{}
|
newMutation := kyvernov1.Mutation{}
|
||||||
newMutation.SetPatchStrategicMerge(
|
newMutation.SetPatchStrategicMerge(
|
||||||
|
@ -255,8 +257,12 @@ func generateRuleForControllers(rule *kyvernov1.Rule, controllers string) *kyver
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
debug.Info("processing rule", "rulename", rule.Name)
|
debug.Info("processing rule", "rulename", rule.Name)
|
||||||
match, exclude := rule.MatchResources, rule.ExcludeResources
|
match := rule.MatchResources
|
||||||
matchKinds, excludeKinds := match.GetKinds(), exclude.GetKinds()
|
matchKinds := match.GetKinds()
|
||||||
|
var excludeKinds []string
|
||||||
|
if exclude := rule.ExcludeResources; exclude != nil {
|
||||||
|
excludeKinds = exclude.GetKinds()
|
||||||
|
}
|
||||||
if !kubeutils.ContainsKind(matchKinds, "Pod") || (len(excludeKinds) != 0 && !kubeutils.ContainsKind(excludeKinds, "Pod")) {
|
if !kubeutils.ContainsKind(matchKinds, "Pod") || (len(excludeKinds) != 0 && !kubeutils.ContainsKind(excludeKinds, "Pod")) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,7 @@ func TestAddOperationsForValidatingWebhookConf(t *testing.T) {
|
||||||
Kinds: []string{"ConfigMap"},
|
Kinds: []string{"ConfigMap"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ExcludeResources: kyverno.MatchResources{
|
ExcludeResources: &kyverno.MatchResources{
|
||||||
ResourceDescription: kyverno.ResourceDescription{
|
ResourceDescription: kyverno.ResourceDescription{
|
||||||
Operations: []kyverno.AdmissionOperation{"DELETE", "CONNECT", "CREATE"},
|
Operations: []kyverno.AdmissionOperation{"DELETE", "CONNECT", "CREATE"},
|
||||||
},
|
},
|
||||||
|
@ -263,7 +263,7 @@ func TestAddOperationsForMutatingtingWebhookConf(t *testing.T) {
|
||||||
Kinds: []string{"Secret"},
|
Kinds: []string{"Secret"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ExcludeResources: kyverno.MatchResources{
|
ExcludeResources: &kyverno.MatchResources{
|
||||||
ResourceDescription: kyverno.ResourceDescription{
|
ResourceDescription: kyverno.ResourceDescription{
|
||||||
Operations: []kyverno.AdmissionOperation{"UPDATE"},
|
Operations: []kyverno.AdmissionOperation{"UPDATE"},
|
||||||
},
|
},
|
||||||
|
|
|
@ -263,6 +263,7 @@ func computeOperationsForValidatingWebhookConf(r kyvernov1.Rule, operationStatus
|
||||||
operationStatusMap[webhookConnect] = true
|
operationStatusMap[webhookConnect] = true
|
||||||
operationStatusMap[webhookDelete] = true
|
operationStatusMap[webhookDelete] = true
|
||||||
}
|
}
|
||||||
|
if r.ExcludeResources != nil {
|
||||||
if r.ExcludeResources.ResourceDescription.Operations != nil {
|
if r.ExcludeResources.ResourceDescription.Operations != nil {
|
||||||
for _, o := range r.ExcludeResources.ResourceDescription.Operations {
|
for _, o := range r.ExcludeResources.ResourceDescription.Operations {
|
||||||
operationStatusMap[string(o)] = false
|
operationStatusMap[string(o)] = false
|
||||||
|
@ -274,6 +275,7 @@ func computeOperationsForValidatingWebhookConf(r kyvernov1.Rule, operationStatus
|
||||||
if len(r.ExcludeResources.All) != 0 {
|
if len(r.ExcludeResources.All) != 0 {
|
||||||
_, operationStatusMap = scanResourceFilterForExclude(r.ExcludeResources.All, operationStatusMap)
|
_, operationStatusMap = scanResourceFilterForExclude(r.ExcludeResources.All, operationStatusMap)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return operationStatusMap
|
return operationStatusMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,6 +309,7 @@ func computeOperationsForMutatingWebhookConf(r kyvernov1.Rule, operationStatusMa
|
||||||
operationStatusMap[webhookCreate] = true
|
operationStatusMap[webhookCreate] = true
|
||||||
operationStatusMap[webhookUpdate] = true
|
operationStatusMap[webhookUpdate] = true
|
||||||
}
|
}
|
||||||
|
if r.ExcludeResources != nil {
|
||||||
if r.ExcludeResources.ResourceDescription.Operations != nil {
|
if r.ExcludeResources.ResourceDescription.Operations != nil {
|
||||||
for _, o := range r.ExcludeResources.ResourceDescription.Operations {
|
for _, o := range r.ExcludeResources.ResourceDescription.Operations {
|
||||||
operationStatusMap[string(o)] = false
|
operationStatusMap[string(o)] = false
|
||||||
|
@ -319,6 +322,7 @@ func computeOperationsForMutatingWebhookConf(r kyvernov1.Rule, operationStatusMa
|
||||||
_, operationStatusMap = scanResourceFilterForExclude(r.ExcludeResources.All, operationStatusMap)
|
_, operationStatusMap = scanResourceFilterForExclude(r.ExcludeResources.All, operationStatusMap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return operationStatusMap
|
return operationStatusMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,18 +379,20 @@ func computeResourcesOfRule(r kyvernov1.Rule) []string {
|
||||||
if len(r.MatchResources.All) != 0 {
|
if len(r.MatchResources.All) != 0 {
|
||||||
resources = scanResourceFilterForResources(r.MatchResources.Any)
|
resources = scanResourceFilterForResources(r.MatchResources.Any)
|
||||||
}
|
}
|
||||||
|
if r.MatchResources.ResourceDescription.Kinds != nil {
|
||||||
|
resources = append(resources, r.MatchResources.ResourceDescription.Kinds...)
|
||||||
|
}
|
||||||
|
if r.ExcludeResources != nil {
|
||||||
if len(r.ExcludeResources.Any) != 0 {
|
if len(r.ExcludeResources.Any) != 0 {
|
||||||
resources = scanResourceFilterForResources(r.MatchResources.Any)
|
resources = scanResourceFilterForResources(r.MatchResources.Any)
|
||||||
}
|
}
|
||||||
if len(r.ExcludeResources.All) != 0 {
|
if len(r.ExcludeResources.All) != 0 {
|
||||||
resources = scanResourceFilterForResources(r.MatchResources.Any)
|
resources = scanResourceFilterForResources(r.MatchResources.Any)
|
||||||
}
|
}
|
||||||
if r.MatchResources.ResourceDescription.Kinds != nil {
|
|
||||||
resources = append(resources, r.MatchResources.ResourceDescription.Kinds...)
|
|
||||||
}
|
|
||||||
if r.ExcludeResources.ResourceDescription.Kinds != nil {
|
if r.ExcludeResources.ResourceDescription.Kinds != nil {
|
||||||
resources = append(resources, r.ExcludeResources.ResourceDescription.Kinds...)
|
resources = append(resources, r.ExcludeResources.ResourceDescription.Kinds...)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return resources
|
return resources
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -241,14 +241,14 @@ func TestComputeOperationsForMutatingWebhookConf(t *testing.T) {
|
||||||
PatchesJSON6902: "add",
|
PatchesJSON6902: "add",
|
||||||
},
|
},
|
||||||
MatchResources: kyvernov1.MatchResources{},
|
MatchResources: kyvernov1.MatchResources{},
|
||||||
ExcludeResources: kyvernov1.MatchResources{},
|
ExcludeResources: &kyvernov1.MatchResources{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Mutation: kyvernov1.Mutation{
|
Mutation: kyvernov1.Mutation{
|
||||||
PatchesJSON6902: "add",
|
PatchesJSON6902: "add",
|
||||||
},
|
},
|
||||||
MatchResources: kyvernov1.MatchResources{},
|
MatchResources: kyvernov1.MatchResources{},
|
||||||
ExcludeResources: kyvernov1.MatchResources{},
|
ExcludeResources: &kyvernov1.MatchResources{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedResult: map[string]bool{
|
expectedResult: map[string]bool{
|
||||||
|
@ -264,7 +264,7 @@ func TestComputeOperationsForMutatingWebhookConf(t *testing.T) {
|
||||||
PatchesJSON6902: "add",
|
PatchesJSON6902: "add",
|
||||||
},
|
},
|
||||||
MatchResources: kyvernov1.MatchResources{},
|
MatchResources: kyvernov1.MatchResources{},
|
||||||
ExcludeResources: kyvernov1.MatchResources{
|
ExcludeResources: &kyvernov1.MatchResources{
|
||||||
ResourceDescription: kyvernov1.ResourceDescription{
|
ResourceDescription: kyvernov1.ResourceDescription{
|
||||||
Operations: []kyvernov1.AdmissionOperation{webhookCreate},
|
Operations: []kyvernov1.AdmissionOperation{webhookCreate},
|
||||||
},
|
},
|
||||||
|
@ -317,7 +317,7 @@ func TestComputeOperationsForValidatingWebhookConf(t *testing.T) {
|
||||||
rules: []kyvernov1.Rule{
|
rules: []kyvernov1.Rule{
|
||||||
{
|
{
|
||||||
MatchResources: kyvernov1.MatchResources{},
|
MatchResources: kyvernov1.MatchResources{},
|
||||||
ExcludeResources: kyvernov1.MatchResources{},
|
ExcludeResources: &kyvernov1.MatchResources{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedResult: map[string]bool{
|
expectedResult: map[string]bool{
|
||||||
|
@ -336,7 +336,7 @@ func TestComputeOperationsForValidatingWebhookConf(t *testing.T) {
|
||||||
Operations: []kyvernov1.AdmissionOperation{webhookCreate, webhookUpdate},
|
Operations: []kyvernov1.AdmissionOperation{webhookCreate, webhookUpdate},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ExcludeResources: kyvernov1.MatchResources{
|
ExcludeResources: &kyvernov1.MatchResources{
|
||||||
ResourceDescription: kyvernov1.ResourceDescription{
|
ResourceDescription: kyvernov1.ResourceDescription{
|
||||||
Operations: []kyvernov1.AdmissionOperation{webhookDelete},
|
Operations: []kyvernov1.AdmissionOperation{webhookDelete},
|
||||||
},
|
},
|
||||||
|
|
|
@ -25,7 +25,7 @@ func matchResource(resource unstructured.Unstructured, rule kyvernov1.Rule) bool
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if rule.ExcludeResources != nil {
|
||||||
if rule.ExcludeResources.All != nil || rule.ExcludeResources.Any != nil {
|
if rule.ExcludeResources.All != nil || rule.ExcludeResources.Any != nil {
|
||||||
excluded := match.CheckMatchesResources(
|
excluded := match.CheckMatchesResources(
|
||||||
resource,
|
resource,
|
||||||
|
@ -42,5 +42,6 @@ func matchResource(resource unstructured.Unstructured, rule kyvernov1.Rule) bool
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,7 +209,7 @@ func MatchesResourceDescription(
|
||||||
}
|
}
|
||||||
|
|
||||||
// check exlude conditions only if match succeeds
|
// check exlude conditions only if match succeeds
|
||||||
if len(reasonsForFailure) == 0 {
|
if len(reasonsForFailure) == 0 && rule.ExcludeResources != nil {
|
||||||
if len(rule.ExcludeResources.Any) > 0 {
|
if len(rule.ExcludeResources.Any) > 0 {
|
||||||
// exclude the object if ANY of the criteria match
|
// exclude the object if ANY of the criteria match
|
||||||
for _, rer := range rule.ExcludeResources.Any {
|
for _, rer := range rule.ExcludeResources.Any {
|
||||||
|
|
|
@ -1963,7 +1963,7 @@ func TestResourceDescriptionMatch_ExcludeDefaultGroups(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
ExcludeResources: v1.MatchResources{},
|
ExcludeResources: &v1.MatchResources{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is the request info that was also passed with the mocked pod
|
// this is the request info that was also passed with the mocked pod
|
||||||
|
@ -1996,7 +1996,7 @@ func TestResourceDescriptionMatch_ExcludeDefaultGroups(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
ExcludeResources: v1.MatchResources{Any: v1.ResourceFilters{}},
|
ExcludeResources: &v1.MatchResources{Any: v1.ResourceFilters{}},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second test: confirm that matching this rule does not create any errors (and raise if err != nil)
|
// Second test: confirm that matching this rule does not create any errors (and raise if err != nil)
|
||||||
|
@ -2005,7 +2005,7 @@ func TestResourceDescriptionMatch_ExcludeDefaultGroups(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we extend the previous rule to have an Exclude part. Making it 'not-empty' should make the exclude-code run.
|
// Now we extend the previous rule to have an Exclude part. Making it 'not-empty' should make the exclude-code run.
|
||||||
rule2.ExcludeResources = v1.MatchResources{Any: v1.ResourceFilters{
|
rule2.ExcludeResources = &v1.MatchResources{Any: v1.ResourceFilters{
|
||||||
v1.ResourceFilter{
|
v1.ResourceFilter{
|
||||||
ResourceDescription: v1.ResourceDescription{
|
ResourceDescription: v1.ResourceDescription{
|
||||||
Kinds: []string{"Pod"},
|
Kinds: []string{"Pod"},
|
||||||
|
@ -2461,7 +2461,7 @@ func TestResourceDescriptionExclude_Label_Expression_Match(t *testing.T) {
|
||||||
|
|
||||||
rule := v1.Rule{
|
rule := v1.Rule{
|
||||||
MatchResources: v1.MatchResources{ResourceDescription: resourceDescription},
|
MatchResources: v1.MatchResources{ResourceDescription: resourceDescription},
|
||||||
ExcludeResources: v1.MatchResources{ResourceDescription: resourceDescriptionExclude},
|
ExcludeResources: &v1.MatchResources{ResourceDescription: resourceDescriptionExclude},
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := MatchesResourceDescription(*resource, rule, v2.RequestInfo{}, nil, "", resource.GroupVersionKind(), "", "CREATE"); err == nil {
|
if err := MatchesResourceDescription(*resource, rule, v2.RequestInfo{}, nil, "", resource.GroupVersionKind(), "", "CREATE"); err == nil {
|
||||||
|
|
|
@ -179,7 +179,7 @@ func createRule(f *fuzz.ConsumeFuzzer) (*kyvernov1.Rule, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rule, err
|
return rule, err
|
||||||
}
|
}
|
||||||
rule.ExcludeResources = *er
|
rule.ExcludeResources = er
|
||||||
}
|
}
|
||||||
|
|
||||||
setRawAnyAllConditions, err := f.GetBool()
|
setRawAnyAllConditions, err := f.GetBool()
|
||||||
|
|
|
@ -57,7 +57,7 @@ func BuildValidatingAdmissionPolicy(
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert the exclude block
|
// convert the exclude block
|
||||||
exclude := rule.ExcludeResources
|
if exclude := rule.ExcludeResources; exclude != nil {
|
||||||
if !exclude.ResourceDescription.IsEmpty() {
|
if !exclude.ResourceDescription.IsEmpty() {
|
||||||
if err := translateResource(discoveryClient, &matchResources, &excludeRules, exclude.ResourceDescription, false); err != nil {
|
if err := translateResource(discoveryClient, &matchResources, &excludeRules, exclude.ResourceDescription, false); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -74,6 +74,7 @@ func BuildValidatingAdmissionPolicy(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// convert the exceptions if exist
|
// convert the exceptions if exist
|
||||||
for _, exception := range exceptions {
|
for _, exception := range exceptions {
|
||||||
|
|
|
@ -72,25 +72,16 @@ func checkPolicy(spec *kyvernov1.Spec) (bool, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the matched/excluded resources of the CEL rule.
|
// check the matched/excluded resources of the CEL rule.
|
||||||
match, exclude := rule.MatchResources, rule.ExcludeResources
|
match := rule.MatchResources
|
||||||
if ok, msg := checkUserInfo(match.UserInfo); !ok {
|
if ok, msg := checkUserInfo(match.UserInfo); !ok {
|
||||||
return false, msg
|
return false, msg
|
||||||
}
|
}
|
||||||
if ok, msg := checkUserInfo(exclude.UserInfo); !ok {
|
|
||||||
return false, msg
|
|
||||||
}
|
|
||||||
|
|
||||||
if ok, msg := checkResources(match.ResourceDescription, true); !ok {
|
if ok, msg := checkResources(match.ResourceDescription, true); !ok {
|
||||||
return false, msg
|
return false, msg
|
||||||
}
|
}
|
||||||
if ok, msg := checkResources(exclude.ResourceDescription, false); !ok {
|
|
||||||
return false, msg
|
|
||||||
}
|
|
||||||
|
|
||||||
if ok, msg := checkResourceFilter(match.Any, true); !ok {
|
if ok, msg := checkResourceFilter(match.Any, true); !ok {
|
||||||
return false, msg
|
return false, msg
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(match.All) > 1 {
|
if len(match.All) > 1 {
|
||||||
msg = "skip generating ValidatingAdmissionPolicy: multiple 'all' in the match block is not applicable."
|
msg = "skip generating ValidatingAdmissionPolicy: multiple 'all' in the match block is not applicable."
|
||||||
return false, msg
|
return false, msg
|
||||||
|
@ -98,11 +89,17 @@ func checkPolicy(spec *kyvernov1.Spec) (bool, string) {
|
||||||
if ok, msg := checkResourceFilter(match.All, true); !ok {
|
if ok, msg := checkResourceFilter(match.All, true); !ok {
|
||||||
return false, msg
|
return false, msg
|
||||||
}
|
}
|
||||||
|
if rule.ExcludeResources != nil {
|
||||||
|
exclude := rule.ExcludeResources
|
||||||
|
if ok, msg := checkUserInfo(exclude.UserInfo); !ok {
|
||||||
|
return false, msg
|
||||||
|
}
|
||||||
|
if ok, msg := checkResources(exclude.ResourceDescription, false); !ok {
|
||||||
|
return false, msg
|
||||||
|
}
|
||||||
if ok, msg := checkResourceFilter(exclude.Any, false); !ok {
|
if ok, msg := checkResourceFilter(exclude.Any, false); !ok {
|
||||||
return false, msg
|
return false, msg
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(exclude.All) > 1 {
|
if len(exclude.All) > 1 {
|
||||||
msg = "skip generating ValidatingAdmissionPolicy: multiple 'all' in the exclude block is not applicable."
|
msg = "skip generating ValidatingAdmissionPolicy: multiple 'all' in the exclude block is not applicable."
|
||||||
return false, msg
|
return false, msg
|
||||||
|
@ -110,6 +107,7 @@ func checkPolicy(spec *kyvernov1.Spec) (bool, string) {
|
||||||
if ok, msg := checkResourceFilter(exclude.All, false); !ok {
|
if ok, msg := checkResourceFilter(exclude.All, false); !ok {
|
||||||
return false, msg
|
return false, msg
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true, msg
|
return true, msg
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,11 +43,6 @@ func hasUserMatchExclude(idx int, rule *kyvernov1.Rule) error {
|
||||||
if path := userInfoDefined(rule.MatchResources.UserInfo); path != "" {
|
if path := userInfoDefined(rule.MatchResources.UserInfo); path != "" {
|
||||||
return fmt.Errorf("invalid variable used at path: spec/rules[%d]/match/%s", idx, path)
|
return fmt.Errorf("invalid variable used at path: spec/rules[%d]/match/%s", idx, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
if path := userInfoDefined(rule.ExcludeResources.UserInfo); path != "" {
|
|
||||||
return fmt.Errorf("invalid variable used at path: spec/rules[%d]/exclude/%s", idx, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(rule.MatchResources.Any) > 0 {
|
if len(rule.MatchResources.Any) > 0 {
|
||||||
for i, value := range rule.MatchResources.Any {
|
for i, value := range rule.MatchResources.Any {
|
||||||
if path := userInfoDefined(value.UserInfo); path != "" {
|
if path := userInfoDefined(value.UserInfo); path != "" {
|
||||||
|
@ -55,7 +50,6 @@ func hasUserMatchExclude(idx int, rule *kyvernov1.Rule) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(rule.MatchResources.All) > 0 {
|
if len(rule.MatchResources.All) > 0 {
|
||||||
for i, value := range rule.MatchResources.All {
|
for i, value := range rule.MatchResources.All {
|
||||||
if path := userInfoDefined(value.UserInfo); path != "" {
|
if path := userInfoDefined(value.UserInfo); path != "" {
|
||||||
|
@ -63,7 +57,10 @@ func hasUserMatchExclude(idx int, rule *kyvernov1.Rule) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if rule.ExcludeResources != nil {
|
||||||
|
if path := userInfoDefined(rule.ExcludeResources.UserInfo); path != "" {
|
||||||
|
return fmt.Errorf("invalid variable used at path: spec/rules[%d]/exclude/%s", idx, path)
|
||||||
|
}
|
||||||
if len(rule.ExcludeResources.All) > 0 {
|
if len(rule.ExcludeResources.All) > 0 {
|
||||||
for i, value := range rule.ExcludeResources.All {
|
for i, value := range rule.ExcludeResources.All {
|
||||||
if path := userInfoDefined(value.UserInfo); path != "" {
|
if path := userInfoDefined(value.UserInfo); path != "" {
|
||||||
|
@ -71,7 +68,6 @@ func hasUserMatchExclude(idx int, rule *kyvernov1.Rule) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(rule.ExcludeResources.Any) > 0 {
|
if len(rule.ExcludeResources.Any) > 0 {
|
||||||
for i, value := range rule.ExcludeResources.Any {
|
for i, value := range rule.ExcludeResources.Any {
|
||||||
if path := userInfoDefined(value.UserInfo); path != "" {
|
if path := userInfoDefined(value.UserInfo); path != "" {
|
||||||
|
@ -79,7 +75,7 @@ func hasUserMatchExclude(idx int, rule *kyvernov1.Rule) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -236,7 +236,6 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf
|
||||||
|
|
||||||
for i, rule := range rules {
|
for i, rule := range rules {
|
||||||
match := rule.MatchResources
|
match := rule.MatchResources
|
||||||
exclude := rule.ExcludeResources
|
|
||||||
for j, value := range match.Any {
|
for j, value := range match.Any {
|
||||||
if err := validateKinds(value.ResourceDescription.Kinds, rule, mock, background, client); err != nil {
|
if err := validateKinds(value.ResourceDescription.Kinds, rule, mock, background, client); err != nil {
|
||||||
return warnings, fmt.Errorf("path: spec.rules[%d].match.any[%d].kinds: %v", i, j, err)
|
return warnings, fmt.Errorf("path: spec.rules[%d].match.any[%d].kinds: %v", i, j, err)
|
||||||
|
@ -247,6 +246,10 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf
|
||||||
return warnings, fmt.Errorf("path: spec.rules[%d].match.all[%d].kinds: %v", i, j, err)
|
return warnings, fmt.Errorf("path: spec.rules[%d].match.all[%d].kinds: %v", i, j, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := validateKinds(rule.MatchResources.Kinds, rule, mock, background, client); err != nil {
|
||||||
|
return warnings, fmt.Errorf("path: spec.rules[%d].match.kinds: %v", i, err)
|
||||||
|
}
|
||||||
|
if exclude := rule.ExcludeResources; exclude != nil {
|
||||||
for j, value := range exclude.Any {
|
for j, value := range exclude.Any {
|
||||||
if err := validateKinds(value.ResourceDescription.Kinds, rule, mock, background, client); err != nil {
|
if err := validateKinds(value.ResourceDescription.Kinds, rule, mock, background, client); err != nil {
|
||||||
return warnings, fmt.Errorf("path: spec.rules[%d].exclude.any[%d].kinds: %v", i, j, err)
|
return warnings, fmt.Errorf("path: spec.rules[%d].exclude.any[%d].kinds: %v", i, j, err)
|
||||||
|
@ -257,15 +260,11 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf
|
||||||
return warnings, fmt.Errorf("path: spec.rules[%d].exclude.all[%d].kinds: %v", i, j, err)
|
return warnings, fmt.Errorf("path: spec.rules[%d].exclude.all[%d].kinds: %v", i, j, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := validateKinds(exclude.Kinds, rule, mock, background, client); err != nil {
|
||||||
if err := validateKinds(rule.MatchResources.Kinds, rule, mock, background, client); err != nil {
|
|
||||||
return warnings, fmt.Errorf("path: spec.rules[%d].match.kinds: %v", i, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := validateKinds(rule.ExcludeResources.Kinds, rule, mock, background, client); err != nil {
|
|
||||||
return warnings, fmt.Errorf("path: spec.rules[%d].exclude.kinds: %v", i, err)
|
return warnings, fmt.Errorf("path: spec.rules[%d].exclude.kinds: %v", i, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for i, rule := range rules {
|
for i, rule := range rules {
|
||||||
rulePath := rulesPath.Index(i)
|
rulePath := rulesPath.Index(i)
|
||||||
|
@ -377,12 +376,13 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf
|
||||||
}
|
}
|
||||||
|
|
||||||
match := rule.MatchResources
|
match := rule.MatchResources
|
||||||
exclude := rule.ExcludeResources
|
|
||||||
matchKinds := match.GetKinds()
|
matchKinds := match.GetKinds()
|
||||||
excludeKinds := exclude.GetKinds()
|
var allKinds []string
|
||||||
allKinds := make([]string, 0, len(matchKinds)+len(excludeKinds))
|
|
||||||
allKinds = append(allKinds, matchKinds...)
|
allKinds = append(allKinds, matchKinds...)
|
||||||
|
if exclude := rule.ExcludeResources; exclude != nil {
|
||||||
|
excludeKinds := exclude.GetKinds()
|
||||||
allKinds = append(allKinds, excludeKinds...)
|
allKinds = append(allKinds, excludeKinds...)
|
||||||
|
}
|
||||||
if rule.HasValidate() {
|
if rule.HasValidate() {
|
||||||
validationElem := rule.Validation.DeepCopy()
|
validationElem := rule.Validation.DeepCopy()
|
||||||
if validationElem.Deny != nil {
|
if validationElem.Deny != nil {
|
||||||
|
@ -691,17 +691,16 @@ func jsonPatchPathHasVariables(patch string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func objectHasVariables(object interface{}) error {
|
func objectHasVariables(object any) error {
|
||||||
var err error
|
if object != nil {
|
||||||
objectJSON, err := json.Marshal(object)
|
objectJSON, err := json.Marshal(object)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(regexVariables.FindAllStringSubmatch(string(objectJSON), -1)) > 0 {
|
if len(regexVariables.FindAllStringSubmatch(string(objectJSON), -1)) > 0 {
|
||||||
return fmt.Errorf("invalid variables")
|
return fmt.Errorf("invalid variables")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -963,22 +962,22 @@ func ruleOnlyDealsWithResourceMetaData(rule kyvernov1.Rule) bool {
|
||||||
|
|
||||||
func validateResources(path *field.Path, rule kyvernov1.Rule) (string, error) {
|
func validateResources(path *field.Path, rule kyvernov1.Rule) (string, error) {
|
||||||
// validate userInfo in match and exclude
|
// validate userInfo in match and exclude
|
||||||
if errs := rule.ExcludeResources.UserInfo.Validate(path.Child("exclude")); len(errs) != 0 {
|
if exclude := rule.ExcludeResources; exclude != nil {
|
||||||
|
if errs := exclude.UserInfo.Validate(path.Child("exclude")); len(errs) != 0 {
|
||||||
return "exclude", errs.ToAggregate()
|
return "exclude", errs.ToAggregate()
|
||||||
}
|
}
|
||||||
|
if (len(exclude.Any) > 0 || len(exclude.All) > 0) && !datautils.DeepEqual(exclude.ResourceDescription, kyvernov1.ResourceDescription{}) {
|
||||||
|
return "exclude.", fmt.Errorf("can't specify any/all together with exclude resources")
|
||||||
|
}
|
||||||
|
if len(exclude.Any) > 0 && len(exclude.All) > 0 {
|
||||||
|
return "match.", fmt.Errorf("can't specify any and all together")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (len(rule.MatchResources.Any) > 0 || len(rule.MatchResources.All) > 0) && !datautils.DeepEqual(rule.MatchResources.ResourceDescription, kyvernov1.ResourceDescription{}) {
|
if (len(rule.MatchResources.Any) > 0 || len(rule.MatchResources.All) > 0) && !datautils.DeepEqual(rule.MatchResources.ResourceDescription, kyvernov1.ResourceDescription{}) {
|
||||||
return "match.", fmt.Errorf("can't specify any/all together with match resources")
|
return "match.", fmt.Errorf("can't specify any/all together with match resources")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len(rule.ExcludeResources.Any) > 0 || len(rule.ExcludeResources.All) > 0) && !datautils.DeepEqual(rule.ExcludeResources.ResourceDescription, kyvernov1.ResourceDescription{}) {
|
|
||||||
return "exclude.", fmt.Errorf("can't specify any/all together with exclude resources")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(rule.ExcludeResources.Any) > 0 && len(rule.ExcludeResources.All) > 0 {
|
|
||||||
return "match.", fmt.Errorf("can't specify any and all together")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(rule.MatchResources.Any) > 0 {
|
if len(rule.MatchResources.Any) > 0 {
|
||||||
for _, rmr := range rule.MatchResources.Any {
|
for _, rmr := range rule.MatchResources.Any {
|
||||||
// matched resources
|
// matched resources
|
||||||
|
|
Loading…
Reference in a new issue