Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add prefix-based matching for namespaces and excludedNamespaces #1404

Conversation

julianKatz
Copy link
Contributor

@julianKatz julianKatz commented Jun 25, 2021

Add prefix-based glob matching support across
Gatekeeper's various match sections.

These include:

  • Constraints (via the regolib match)
  • Config resource (via the process excluder)
  • Mutations (via the match package)

Fixes #1009

@codecov-commenter
Copy link

codecov-commenter commented Jun 25, 2021

Codecov Report

Merging #1404 (d96060f) into master (b791188) will decrease coverage by 0.07%.
The diff coverage is 79.16%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1404      +/-   ##
==========================================
- Coverage   50.06%   49.99%   -0.08%     
==========================================
  Files          73       75       +2     
  Lines        5019     5061      +42     
==========================================
+ Hits         2513     2530      +17     
- Misses       2155     2180      +25     
  Partials      351      351              
Flag Coverage Δ
unittests 49.99% <79.16%> (-0.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
pkg/controller/config/config_controller.go 65.56% <ø> (ø)
pkg/controller/config/process/excluder.go 10.00% <37.50%> (ø)
pkg/mutation/match/match.go 88.75% <100.00%> (+3.03%) ⬆️
pkg/target/target.go 68.14% <100.00%> (+0.72%) ⬆️
pkg/util/prefix_wildcard.go 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b791188...d96060f. Read the comment docs.

Copy link
Contributor

@maxsmythe maxsmythe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rego basically LGTM, with some comments.

We will need to have some way to ensure wildcards only show up at the end of the match schema... either a validation check in the JSONSchema, or as part of the validating webhook.

JSONSchema is preferable, if possible.

pkg/target/regolib/src.rego Outdated Show resolved Hide resolved
pkg/target/regolib/src.rego Show resolved Hide resolved
@julianKatz julianKatz marked this pull request as draft June 28, 2021 21:06
@julianKatz
Copy link
Contributor Author

either a validation check in the JSONSchema

@maxsmythe I've added a regex to the JSONSchema

Copy link
Contributor

@maxsmythe maxsmythe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with one nit

@shomron @sozercan LGTY?

pkg/target/regolib/src.rego Show resolved Hide resolved
@julianKatz julianKatz marked this pull request as ready for review June 29, 2021 19:27
@julianKatz julianKatz force-pushed the 175156959-1009-allow-wildcard-in-excludednamespaces branch from d523013 to d58ec48 Compare June 29, 2021 19:30
Copy link
Contributor

@maxsmythe maxsmythe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New changes LGTM, 1 nit

pkg/controller/config/config_controller.go Outdated Show resolved Hide resolved
@julianKatz
Copy link
Contributor Author

ping :) @sozercan @shomron

Copy link
Member

@sozercan sozercan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor suggestion, LGTM

},
ns: "kube-system",
excluded: false,
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add a wildcard only and empty test here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I think the best way to deal with this is to implement a pattern requirement on the excludedNamespace field. I believe I can do that with a kubebuilder annotation. Will research now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a pattern check on excludedNamespaces in the config resource's match section. This will prevent both "*" and "" from being added under excludedNamespaces.

@sozercan @maxsmythe is that a reasonable way to solve this problem?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change count as backwards incompatible? At least at the level of the CRD, those were valid entries before. They weren't valid namespaces, so perhaps it's alright...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it's fine. "*" and "" never would have matched an existing namespace (invalid namespace names), so there would be no behavioral change that would impact users.

If, for some reason, these values were in user's constraints, they weren't doing anything and they should probably be notified of that as it was likely a mistake.

@maxsmythe
Copy link
Contributor

Looks like there are some failing tests --- type error?

cannot use make([]string, len(*in)) (value of type []string) as []validWilcardNamespace value in assignment (typecheck)

@maxsmythe
Copy link
Contributor

Looks like the type error could be fixed by running make generate

@julianKatz
Copy link
Contributor Author

Looks like the type error could be fixed by running make generate

Done

julianKatz and others added 11 commits July 8, 2021 11:52
- some updates and question comments
- prefix matching for both namespaces and excludednamespaces

Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
…tion

Signed-off-by: juliankatz <juliankatz@google.com>
* Add PreserveUnknownFields: false to CRDs

First commit, adds PreserveUnknownFields: false to the non-mutation
CRDs.  The kustomization pipeline is in a bit of a weird state given it
being in alpha, so I'm not sure what else to add for that yet.

Signed-off-by: juliankatz <juliankatz@google.com>

* Preserve --> preserve

Signed-off-by: juliankatz <juliankatz@google.com>

* Fix mutation CRDs kustomization

The patching was in the wrong place.  Per Rita's comment, I moved it
from:

config/overlays/mutation/kustomization.yaml

to

config/overlays/mutation_webhook/kustomization.yaml

Now the CRDs are actually being kustomized.

Signed-off-by: juliankatz <juliankatz@google.com>

* Add PreserveUnknownFields: false to CRDs

First commit, adds PreserveUnknownFields: false to the non-mutation
CRDs.  The kustomization pipeline is in a bit of a weird state given it
being in alpha, so I'm not sure what else to add for that yet.

Signed-off-by: juliankatz <juliankatz@google.com>

* Preserve --> preserve

Signed-off-by: juliankatz <juliankatz@google.com>

* Add load_restrictor LoadRestrictionsNone in deploy-mutation

Signed-off-by: juliankatz <juliankatz@google.com>

Co-authored-by: Sertaç Özercan <852750+sozercan@users.noreply.github.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Will Beason and others added 13 commits July 8, 2021 11:52
Implement functionality for reading test Suites. This includes reading
single file, reading suites in a single directory, and reading suites in
a directory and its subdirectories.

Note that it is intentional that the Suite type is still empty - a
parallel CL will begin adding fields and functionality to it. This CL is
just focused on reading Suites from the disk.

I've opted to not test certain edge cases - for example permission
errors - as we'd either have to define our own fs.FS implementation or
have unit tests that write/read from disk. As-is, unit tests cover the
core logic paths and 90% of the code.

Signed-off-by: Will Beason <willbeason@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
…ate.yaml"

This reverts commit 9d0e20c.

Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
This reverts commit e61e1bd.

Signed-off-by: juliankatz <juliankatz@google.com>
This reverts commit 19143ce.

Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
This PR incorporates frameworks commit
1dbe2618668df5f48b6a256bdcd724eeb2b1c130
Add ConstraintTemplate v1 (#121)

An imperative install CRD install step was added to the
Helm Upgrade GH Workflow, as Helm does not update
CRDs.

Contributes to open-policy-agent#550

Signed-off-by: juliankatz juliankatz@google.com
Signed-off-by: juliankatz <juliankatz@google.com>
@julianKatz julianKatz force-pushed the 175156959-1009-allow-wildcard-in-excludednamespaces branch from 4248d5b to 91e0d1c Compare July 8, 2021 18:53
… 175156959-1009-allow-wildcard-in-excludednamespaces

Signed-off-by: juliankatz <juliankatz@google.com>
@@ -38,6 +38,8 @@ spec:
properties:
excludedNamespaces:
items:
description: PrefixWildcard is a string that supports globbing at its end.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description should be targeted at consumers of the API, so no "PrefixWildCard", maybe some guidance as to correct inputs and what they do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far I haven't been able to find a way to do this with kubebuilder. It defaults to using the description that's written on the custom PrefixWildcard type in pkg/util/prefix_wildcard.go.

Removing PrefixWildcard is a from this string causes a lint error:

pkg/util/prefix_wildcard.go:7:1: exported: comment on exported type PrefixWildcard should be of the form "PrefixWildcard ..." (with optional leading article) (revive)
// a string that supports globbing at its end.
^

Rather than add to the jumbled mess of kustomize, I'm going to add a //nolint:revive to the comment and call it a day.

LMK what you think of the more in-depth description I added.

func exactOrPrefixMatch(boolMap map[util.PrefixWildcard]bool, ns string) bool {
for k, val := range boolMap {
if k.Matches(ns) {
return val
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: drop val, return an explicit true, val has no relation to whether a given field matches.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the boolMap's values don't matter (i.e., we always return true), should it be refactored to be a map of struct{}? If it's always returning true, then it's essentially functioning as a set.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, it's a set. bool is a little easier to work with for sets, as it allows you to test for membership just by accessing the value. Example: isMember["a"] returns true if "a" is a member, but the default value (false) if it's not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rodger that. I've updated the function to always return true.

pkg/util/prefix_wildcard.go Outdated Show resolved Hide resolved
pkg/util/prefix_wildcard_test.go Show resolved Hide resolved
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
Copy link
Contributor

@maxsmythe maxsmythe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with one nit

config/crd/bases/config.gatekeeper.sh_configs.yaml Outdated Show resolved Hide resolved
… 175156959-1009-allow-wildcard-in-excludednamespaces

Signed-off-by: juliankatz <juliankatz@google.com>
Signed-off-by: juliankatz <juliankatz@google.com>
@julianKatz julianKatz merged commit 5776a6b into open-policy-agent:master Jul 12, 2021
@julianKatz julianKatz deleted the 175156959-1009-allow-wildcard-in-excludednamespaces branch July 12, 2021 16:26
julianKatz added a commit to julianKatz/gatekeeper that referenced this pull request Jul 27, 2021
…-policy-agent#1404)

Add prefix-based glob matching support across
Gatekeeper's various match sections.

These include:

- Constraints (via the regolib match)
- Config resource (via the process excluder)
- Mutations (via the match package)

Fixes open-policy-agent#1009

Signed-off-by: juliankatz <juliankatz@google.com>
@erezo9
Copy link
Contributor

erezo9 commented Jun 23, 2022

Is there a way to add an astrix at the beginning of the namespace name?
Im trying to do match namespaces like -myenv-
but it doesnt work cause the astrix is only allowed at the end of the regular expression

@maxsmythe
Copy link
Contributor

maxsmythe commented Jun 23, 2022

It looks like currently we only support prefix or suffix matching, not midfix. Can you open a bug so we can discuss the feature? I'd imagine there may be some concerns about potentially making future performance optimizations harder, but better to hash that out in a dedicated spot.

func (w Wildcard) Matches(candidate string) bool {
wStr := string(w)
switch {
case strings.HasPrefix(wStr, "*"):
return strings.HasSuffix(candidate, strings.TrimPrefix(wStr, "*"))
case strings.HasSuffix(wStr, "*"):
return strings.HasPrefix(candidate, strings.TrimSuffix(wStr, "*"))
default:
return wStr == candidate
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow wildcard in excludedNamespaces
7 participants