diff --git a/pkg/apis/policy/v1alpha1/propagation_types.go b/pkg/apis/policy/v1alpha1/propagation_types.go index fe9316f72ca3..9e9245dca344 100644 --- a/pkg/apis/policy/v1alpha1/propagation_types.go +++ b/pkg/apis/policy/v1alpha1/propagation_types.go @@ -68,6 +68,10 @@ type PropagationSpec struct { // +kubebuilder:validation:MinItems=1 ResourceSelectors []ResourceSelector `json:"resourceSelectors"` + // NamespaceSelectors used to select resources. + // +optional + NamespaceSelectors []NamespaceSelector `json:"namespaceSelectors"` + // Association tells if relevant resources should be selected automatically. // e.g. a ConfigMap referred by a Deployment. // default false. @@ -228,6 +232,13 @@ type ResourceSelector struct { LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"` } +// NamespaceSelector the resource namespace will be selected. +type NamespaceSelector struct { + // A label query over a set of namespaces. + // +required + LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"` +} + // FieldSelector is a field filter. type FieldSelector struct { // A list of field selector requirements. diff --git a/pkg/detector/compare.go b/pkg/detector/compare.go index 80c30b239456..4aee6759a211 100644 --- a/pkg/detector/compare.go +++ b/pkg/detector/compare.go @@ -33,12 +33,26 @@ func getHighestPriorityPropagationPolicy(policies []*policyv1alpha1.PropagationP var matchedPolicy *policyv1alpha1.PropagationPolicy for _, policy := range policies { + // any namespace selector matches ? + if len(policy.Spec.NamespaceSelectors) != 0 { + matched := false + for _, ns := range policy.Spec.NamespaceSelectors { + if !util.MatchesSelector(GetNamespace(resource.GetNamespace()), ns.LabelSelector) { + matched = true + } + } + if !matched { + continue + } + } + + // any resource selector matches ? implicitPriority := util.ResourceMatchSelectorsPriority(resource, policy.Spec.ResourceSelectors...) if implicitPriority <= util.PriorityMisMatch { continue } - explicitPriority := policy.ExplicitPriority() + explicitPriority := policy.ExplicitPriority() if matchedPolicyExplicitPriority < explicitPriority { matchedPolicyImplicitPriority = implicitPriority matchedPolicyExplicitPriority = explicitPriority diff --git a/pkg/util/selector.go b/pkg/util/selector.go index 83a15274748f..00c114de0ff8 100644 --- a/pkg/util/selector.go +++ b/pkg/util/selector.go @@ -79,17 +79,22 @@ func ResourceSelectorPriority(resource *unstructured.Unstructured, rs policyv1al } // case 3: matches with selector - var s labels.Selector - var err error - if s, err = metav1.LabelSelectorAsSelector(rs.LabelSelector); err != nil { - // should not happen because all resource selector should be fully validated by webhook. - return PriorityMisMatch + if MatchesSelector(resource, rs.LabelSelector) { + return PriorityMatchLabelSelector } + return PriorityMisMatch +} +func MatchesSelector(resource *unstructured.Unstructured, ls *metav1.LabelSelector) bool { + s, err := metav1.LabelSelectorAsSelector(ls) + if err != nil { + // should not happen because all resource selector should be fully validated by webhook. + return false + } if s.Matches(labels.Set(resource.GetLabels())) { - return PriorityMatchLabelSelector + return true } - return PriorityMisMatch + return false } // ClusterMatches tells if specific cluster matches the affinity.