Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
43c1596
Add name field to mutation match
julianKatz Aug 25, 2021
807d981
Add name to constraint match
julianKatz Aug 27, 2021
b551107
Add name matching (with prefix glob support) to constraints (rego)
julianKatz Sep 8, 2021
581008f
Add prefix matching to mutation match
julianKatz Sep 8, 2021
e42fc74
Merge branch 'master' of github.com:open-policy-agent/gatekeeper into…
julianKatz Sep 8, 2021
208b171
Add name match support
julianKatz Sep 8, 2021
cc3a4be
Merge branch 'master' of github.com:open-policy-agent/gatekeeper into…
julianKatz Sep 9, 2021
f2b4a98
Merge branch 'master' of github.com:open-policy-agent/gatekeeper into…
julianKatz Sep 9, 2021
1894500
Add description for name in MatchSchema and mutation Match
julianKatz Sep 9, 2021
30b7515
Add pattern validation for `name` in match
julianKatz Sep 9, 2021
5eea07a
Use the pre-existing PrefixWildcard type for all prefix-matching
julianKatz Sep 9, 2021
2c6219d
Remove test for now invalid object name `test-`, as regex makes it in…
julianKatz Sep 9, 2021
d6ac702
Fix a compiler error from missing util.PrefixWildcard
julianKatz Sep 9, 2021
4d1c280
Add name to the website
julianKatz Sep 10, 2021
369a9b5
Removed unused prefixMatch function in mutation
julianKatz Sep 10, 2021
2a46e94
Add prefix-based glob info to both namespaces and excludedNamespaces …
julianKatz Sep 17, 2021
421aa72
Merge branch 'master' of github.com:open-policy-agent/gatekeeper into…
julianKatz Sep 17, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions config/crd/bases/mutations.gatekeeper.sh_assign.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ spec:
properties:
excludedNamespaces:
items:
description: 'A string that supports globbing at its end. Ex: "kube-*" will match "kube-system" or "kube-public". The asterisk is required for wildcard matching.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
type: array
kinds:
Expand Down Expand Up @@ -106,6 +108,10 @@ spec:
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
name:
description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix-based glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
Comment thread
julianKatz marked this conversation as resolved.
namespaceSelector:
description: A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.
properties:
Expand Down Expand Up @@ -138,6 +144,8 @@ spec:
type: object
namespaces:
items:
description: 'A string that supports globbing at its end. Ex: "kube-*" will match "kube-system" or "kube-public". The asterisk is required for wildcard matching.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
type: array
scope:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ spec:
properties:
excludedNamespaces:
items:
description: 'A string that supports globbing at its end. Ex: "kube-*" will match "kube-system" or "kube-public". The asterisk is required for wildcard matching.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
type: array
kinds:
Expand Down Expand Up @@ -86,6 +88,10 @@ spec:
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
name:
description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix-based glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
namespaceSelector:
description: A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.
properties:
Expand Down Expand Up @@ -118,6 +124,8 @@ spec:
type: object
namespaces:
items:
description: 'A string that supports globbing at its end. Ex: "kube-*" will match "kube-system" or "kube-public". The asterisk is required for wildcard matching.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
type: array
scope:
Expand Down
8 changes: 8 additions & 0 deletions config/crd/bases/mutations.gatekeeper.sh_modifyset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ spec:
properties:
excludedNamespaces:
items:
description: 'A string that supports globbing at its end. Ex: "kube-*" will match "kube-system" or "kube-public". The asterisk is required for wildcard matching.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
type: array
kinds:
Expand Down Expand Up @@ -106,6 +108,10 @@ spec:
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
name:
description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix-based glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
namespaceSelector:
description: A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.
properties:
Expand Down Expand Up @@ -138,6 +144,8 @@ spec:
type: object
namespaces:
items:
description: 'A string that supports globbing at its end. Ex: "kube-*" will match "kube-system" or "kube-public". The asterisk is required for wildcard matching.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
type: array
scope:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ spec:
properties:
excludedNamespaces:
items:
description: 'A string that supports globbing at its end. Ex: "kube-*" will match "kube-system" or "kube-public". The asterisk is required for wildcard matching.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
type: array
kinds:
Expand Down Expand Up @@ -110,6 +112,10 @@ spec:
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
name:
description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix-based glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
namespaceSelector:
description: A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.
properties:
Expand Down Expand Up @@ -142,6 +148,8 @@ spec:
type: object
namespaces:
items:
description: 'A string that supports globbing at its end. Ex: "kube-*" will match "kube-system" or "kube-public". The asterisk is required for wildcard matching.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
type: array
scope:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ spec:
properties:
excludedNamespaces:
items:
description: 'A string that supports globbing at its end. Ex: "kube-*" will match "kube-system" or "kube-public". The asterisk is required for wildcard matching.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
type: array
kinds:
Expand Down Expand Up @@ -90,6 +92,10 @@ spec:
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
name:
description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix-based glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
namespaceSelector:
description: A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.
properties:
Expand Down Expand Up @@ -122,6 +128,8 @@ spec:
type: object
namespaces:
items:
description: 'A string that supports globbing at its end. Ex: "kube-*" will match "kube-system" or "kube-public". The asterisk is required for wildcard matching.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
type: array
scope:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ spec:
properties:
excludedNamespaces:
items:
description: 'A string that supports globbing at its end. Ex: "kube-*" will match "kube-system" or "kube-public". The asterisk is required for wildcard matching.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
type: array
kinds:
Expand Down Expand Up @@ -110,6 +112,10 @@ spec:
description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed.
type: object
type: object
name:
description: 'Name is the name of an object. If defined, it will match against objects with the specified name. Name also supports a prefix-based glob. For example, `name: pod-*` would match both `pod-a` and `pod-b`.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
namespaceSelector:
description: A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.
properties:
Expand Down Expand Up @@ -142,6 +148,8 @@ spec:
type: object
namespaces:
items:
description: 'A string that supports globbing at its end. Ex: "kube-*" will match "kube-system" or "kube-public". The asterisk is required for wildcard matching.'
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\*|-\*)?$
type: string
type: array
scope:
Expand Down
37 changes: 21 additions & 16 deletions pkg/mutation/match/match.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package match

import (
"errors"
"strings"

"github.com/open-policy-agent/gatekeeper/pkg/util"
corev1 "k8s.io/api/core/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -46,10 +46,14 @@ func (a ApplyTo) Flatten() []schema.GroupVersionKind {
type Match struct {
Kinds []Kinds `json:"kinds,omitempty"`
Scope apiextensionsv1.ResourceScope `json:"scope,omitempty"`
Namespaces []string `json:"namespaces,omitempty"`
ExcludedNamespaces []string `json:"excludedNamespaces,omitempty"`
Namespaces []util.PrefixWildcard `json:"namespaces,omitempty"`
ExcludedNamespaces []util.PrefixWildcard `json:"excludedNamespaces,omitempty"`
LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"`
NamespaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty"`
// Name is the name of an object. If defined, it will match against objects with the specified
// name. Name also supports a prefix-based glob. For example, `name: pod-*` would match both
// `pod-a` and `pod-b`.
Name util.PrefixWildcard `json:"name,omitempty"`
}

// Kinds accepts a list of objects with apiGroups and kinds fields
Expand Down Expand Up @@ -79,6 +83,7 @@ func Matches(match *Match, obj client.Object, ns *corev1.Namespace) (bool, error
excludedNamespacesMatch,
labelSelectorMatch,
namespaceSelectorMatch,
namesMatch,
}

for _, fn := range topLevelMatchers {
Expand Down Expand Up @@ -142,7 +147,7 @@ func excludedNamespacesMatch(match *Match, obj client.Object, ns *corev1.Namespa
}

for _, n := range match.ExcludedNamespaces {
if ns.Name == n || prefixMatch(n, ns.Name) {
if n.Matches(ns.Name) {
return false, nil
}
}
Expand All @@ -157,7 +162,7 @@ func namespacesMatch(match *Match, obj client.Object, ns *corev1.Namespace) (boo
}

for _, n := range match.Namespaces {
if ns.Name == n || prefixMatch(n, ns.Name) {
if n.Matches(ns.Name) {
return true, nil
}
}
Expand Down Expand Up @@ -206,6 +211,17 @@ func kindsMatch(match *Match, obj client.Object, ns *corev1.Namespace) (bool, er
return false, nil
}

func namesMatch(match *Match, obj client.Object, ns *corev1.Namespace) (bool, error) {
// A blank string could be undefined or an intentional blank string by the user. Either way,
// we will assume this means "any name". This goes with the undefined == match everything
// pattern that we've already got going in the Match.
if match.Name == "" {
return true, nil
}

return match.Name.Matches(obj.GetName()), nil
}

func scopeMatch(match *Match, obj client.Object, ns *corev1.Namespace) (bool, error) {
clusterScoped := ns == nil || isNamespace(obj)

Expand All @@ -222,17 +238,6 @@ func scopeMatch(match *Match, obj client.Object, ns *corev1.Namespace) (bool, er
return true, nil
}

// prefixMatch matches checks if the candidate contains the prefix defined in the source.
// The source is expected to end with a "*", which acts as a glob. It is removed when
// performing the prefix-based match.
func prefixMatch(source, candidate string) bool {
if !strings.HasSuffix(source, "*") {
return false
}

return strings.HasPrefix(candidate, strings.TrimSuffix(source, "*"))
}

// AppliesTo checks if any item the given slice of ApplyTo applies to the given object.
func AppliesTo(applyTo []ApplyTo, obj runtime.Object) bool {
gvk := obj.GetObjectKind().GroupVersionKind()
Expand Down
Loading