-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
feat(sourceNamespace): Regex Support (#19016) #19017
Conversation
❌ Preview Environment deleted from BunnyshellAvailable commands (reply to this comment):
|
❌ Preview Environment deleted from BunnyshellAvailable commands (reply to this comment):
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @ArthurVardevanyan, thank you for trying to tackle this!
Instead of introducing a new command line option, WDYT of having a negation pattern (i.e. !
) in the namespace list?
So, to specify all but a few namespaces, one could use:
--application-namespaces *,!foo,!bar
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #19017 +/- ##
==========================================
- Coverage 55.84% 55.82% -0.03%
==========================================
Files 315 316 +1
Lines 43654 43668 +14
==========================================
- Hits 24377 24376 -1
- Misses 16722 16731 +9
- Partials 2555 2561 +6 ☔ View full report in Codecov by Sentry. |
36e76eb
to
201d849
Compare
I agree, updated pr. additionally, looks like the underlying glob library has a bug, otherwise this would have worked from day 1. I wrote two solutions, this one, kinda shoehorns in the logic needed to make the negate work. This is a regex re-implement: |
73a0165
to
437e2f0
Compare
f8b431c
to
0432d76
Compare
While I think it might be a good idea, you already mentioned that the change will be a breaking. I think the added value of using regexp is not sufficient to justify a breaking change. It might even have some weird side effects for people unaware of that change taking place, when their globs are now handled as regexps and could potentially introduce security issues or production outages in those environments. We can definitely keep that in mind for the next major version, though. If you'd like, you can go ahead and create an enhancement issue which I'll pin to the 3.0 milestone then. Just snooping at what the changes in this PR look like, I think we're on a pretty good way now. I'll give it a thorough review tomorrow. |
0432d76
to
514c48c
Compare
I think I am content what the PR as it sits, I may add a few more tests for more scenarios, since technically this is not a "pure" glob implementation, want to make sure strange edge cases are accounted for. However, it is not done like how the suggestion was: So I wrote it as, anything with a negate out front, just inverts the output from the glob library for that line item. |
514c48c
to
17e087b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test case I added fails:
{
"allow anything prefixed test, but not test-test",
"test-test",
"argocd",
[]string{"!test-test", "test-*"},
false,
},
I was thinking that maybe we can have a function that takes a list of patterns, maybe with a similar signature to: MatchList(patterns []string, text string, separators ...rune)
.
It will then build two lists, one having the positive globs, the second having the negative globs. Then it will:
- Match in the negative list. If there's a match, deny the namespace.
- Match in the positive list. If there's a match, allow the namespace. If there's no match, deny the namespace.
This would have the benefit that patterns do not need to be ordered (e.g. negatives first, positives last) and be a little more predictable.
util/glob/glob.go
Outdated
func Match(pattern, text string, separators ...rune) bool { | ||
compiledGlob, err := glob.Compile(pattern, separators...) | ||
if err != nil { | ||
log.Warnf("failed to compile pattern %s due to error %v", pattern, err) | ||
return false | ||
if strings.HasPrefix(pattern, "!") { | ||
compiledGlob, err := glob.Compile(pattern[1:], separators...) | ||
if err != nil { | ||
log.Warnf("failed to compile pattern %s due to error %v", pattern, err) | ||
return false | ||
} | ||
return !compiledGlob.Match(text) | ||
} else { | ||
compiledGlob, err := glob.Compile(pattern, separators...) | ||
if err != nil { | ||
log.Warnf("failed to compile pattern %s due to error %v", pattern, err) | ||
return false | ||
} | ||
return compiledGlob.Match(text) | ||
} | ||
return compiledGlob.Match(text) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this change has too much scope, since other pieces in the code base will use this function too. This could potentially lead to undesired side effects.
IMO, it would make sense to add a new function to util/glob
, let's say MatchWithInvert
(just a proposal for the name), and adapt the pieces of the code that take care of matching source namespace globs to use that new function.
The following is a simple, non-optimized and untested example to illustrate the idea: https://play.golang.com/p/9JxiCrJM8XC |
That is interesting, could try that as well, But IE, if string starts with /, compute as regex ? |
That is actually a brilliant idea IMO! This will allow for a non-breaking change too, since |
0c967c6
to
fe80772
Compare
Testing with operator: ArthurVardevanyan/HomeLab@f1843ce?diff=split&w=0 |
94f7c5b
to
4ac948f
Compare
Updated Doc |
Sorry for the delay here, @ArthurVardevanyan and thanks for your patience. I think it would make most sense to modify
|
Signed-off-by: Arthur <[email protected]>
0fc2753
to
c9ebe95
Compare
Sounds good, took a stab at it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're quick :) Thanks. I only have a final comment now.
util/glob/list.go
Outdated
if patternMatch == "regexp" && strings.HasPrefix(ll, "/") && strings.HasSuffix(ll, "/") && regex.Match(ll[1:len(ll)-1], item) { | ||
return true | ||
} else if (patternMatch == "regexp" || patternMatch == "glob") && Match(ll, item) { | ||
return true | ||
} else if patternMatch == "exact" && item == ll { | ||
return true | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the only thing left to do is to make the "exact", "glob" and "regexp" strings constants and then use them throughout the code. And then should be good to go!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to use constants .
c9ebe95
to
9c51634
Compare
Signed-off-by: Arthur <[email protected]>
9c51634
to
707af58
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Thank you and congratulations on your first contribution to Argo CD, @ArthurVardevanyan 🎉
* feat(sourceNamespace): Regex Support Signed-off-by: Arthur <[email protected]> * feat(sourceNamespace): Separate exactMatch into patternMatch Signed-off-by: Arthur <[email protected]> --------- Signed-off-by: Arthur <[email protected]>
* feat(sourceNamespace): Regex Support Signed-off-by: Arthur <[email protected]> * feat(sourceNamespace): Separate exactMatch into patternMatch Signed-off-by: Arthur <[email protected]> --------- Signed-off-by: Arthur <[email protected]> Signed-off-by: ChichiCaleb <ChichiCaleb@[email protected]>
* feat(sourceNamespace): Regex Support Signed-off-by: Arthur <[email protected]> * feat(sourceNamespace): Separate exactMatch into patternMatch Signed-off-by: Arthur <[email protected]> --------- Signed-off-by: Arthur <[email protected]> Signed-off-by: ChichiCaleb <ChichiCaleb@[email protected]> Signed-off-by: ChichiCaleb <[email protected]>
/cherry-pick release-2.12 |
* feat(sourceNamespace): Regex Support Signed-off-by: Arthur <[email protected]> * feat(sourceNamespace): Separate exactMatch into patternMatch Signed-off-by: Arthur <[email protected]> --------- Signed-off-by: Arthur <[email protected]>
* feat(sourceNamespace): Regex Support * feat(sourceNamespace): Separate exactMatch into patternMatch --------- Signed-off-by: Arthur <[email protected]> Co-authored-by: Arthur Vardevanyan <[email protected]>
Here is a PR with my attempt at solving the below scenario: #19016
It seems to work, however I may not have accounted for everything..
Checklist: