-
Notifications
You must be signed in to change notification settings - Fork 40k
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
Extending label.Parse method to support exact match #4486
Conversation
// \s+ | ||
// | ||
// <exact-match-restriction> ::= ["="|"=="|"!="] VALUE_NOT_EMPTY | ||
// KEY is a sequence of one or more characters that does not contain: ('=', '!', '(', ')', ',') |
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.
Might be simpler to define it as we do in validation (much tighter spec)?
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 tried to BNF style I found. So would you prefer a regex style based as in validation.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.
I'm fine with regex for simple token-scope docs and validation. Obviously not for the full parser :)
Needs testing somewhere for keys that fit the qualified name syntax for keys: [ DNS_SUBDOMAIN "/" ] DNS_LABEL. Specifically, test cases like "example.com/my-key" and "my-key-with-a-long-name" and "0.1.2.domain/99" are all valid as per validation rules today. |
@thockin I've add a very simple test here https://github.com/GoogleCloudPlatform/kubernetes/pull/4486/files#diff-b2970db202ffdb1dec2b170d88679d3bR504 |
func validateLabelKey(k string) error { | ||
if !util.IsDNSLabel(k) { | ||
if !util.IsQualifiedName(k) { | ||
return errors.NewFieldNotSupported("key", k) |
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 should be NewFieldInvalid()
@thockin @smarterclayton in the next hours I will submit and update to fix the less controversial issues (typo, testcases, error report function) |
On Our general pattern is that constants in API fields are CameCase, like WDYT, @smarterclayton ? |
@smarterclayton @thockin @bgrant0607 PTAL |
{"x=a", &LabelSelector{Requirements: []Requirement{ | ||
getRequirement("x", In, util.NewStringSet("a"), ExactMatch, t), | ||
}}, true, true}, | ||
{"x=a,y!=b", &LabelSelector{Requirements: []Requirement{ |
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 would like to see a test that combines the exact-match syntax and the set-based syntax, such as:
x=a,y!=b,z in (h,i,j)
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.
OK.
This is purely a personal opinion - but I think NotIn would be ugly in general use. Seeing "foo not in bar" or "fo in bar" seems much clearer than "foo In bar" and "foo NotIn bar". I generally prefer lower case for operator words (or caseless) before mixed case. Again, this purely an "attractiveness" argument.
|
yeah, NotIn is hurtful to me. I don't think an embedded grammar syntax What about !in or !(x in y)? We have to decide if this just a small hacky As for keys and values: I TOTALLY agree that reusing common rules is a We need to have agreement on:
Now for keys. We could just loosen all qualified names to be Alternately we could define it as caseless - but that impacts all callers. What think? On Thu, Feb 19, 2015 at 10:16 AM, Clayton Coleman notifications@github.com
|
@bgrant0607 |
switch operator { | ||
case In, NotIn: | ||
values, err = p.parseValues() | ||
case Equal, Eequal, Nequal: |
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.
why do we support and distinguish = and == both?
I don't have any further gripes |
Re. |
Ah, I meant the stringified syntax being "NotIn" is painful. Go-level On Fri, Feb 20, 2015 at 11:03 AM, Brian Grant notifications@github.com
|
To be clear, it would be an API constant string, not just a Go type. See above comparison with As for URL syntax, the decision is |
@bgrant0607 modified operators to constant strings. Sorry for the delay. |
@bgrant0607 I made a mess with my previous push, sorry hope you hadn't look at it. |
@sdminonne is this ready to look at now? |
@bgrant0607 it is. Thanks |
LGTM for this round. Please rebase so tests can run. @thockin @smarterclayton Any more comments on this PR? |
} | ||
ch = l.read() | ||
} | ||
if ch == 0 { // end of the string? |
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 is a nit (just a style thing for future pulls): go encourages using a switch whenever you have this sort of pattern - it ends up reading better. Basically go hates "else if" and wants switch. If you ever are in here again later it's a minor thing to clean up if you can.
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.
@smarterclayton I'm aware of this "go preferred way" but I've to get rid of some old habits. I'll change it. Thanks.
LGTM |
@smarterclayton @bgrant0607 I'm going to rebase and push but all my PRs are always failing for Shippable. And I trying to get info via |
Integration test failed due to a pod not scheduling before the timeout, but only for Go 1.3. Probably a flake. |
Extending label.Parse method to support exact match
@bgrant0607 @smarterclayton I've a first implementation of the first step (2).
Not sure if you wish to have a look to this as a PR or you would like to
I modified labels.Parse to use an hand made recursive descendant parser. (hope it's not too much work to review it).
The previous parser was partially regexp based and it may become quickly complex to work with it.
At the same time I couldn't obtain more compact code since this "micro-language" is quite unusual:
for example it can parse something like this
x in (,)
.Exact match is obtained using "in".
x in (a)
produces the same matching ofx=a
, since internal data structure is the same.String method will produce different output:
Parse("x=a").String()
->"x=a"
Parse("x in (a)").String()
->"x in (a)"
.In testing file:
Added labels.Parse in the requireMatch method to be sure (or at least for this tests) that the behavior is the same (where the requested code was not too complex).
Some modifications:
a)
a
(with trailing whitespace) now is matched and is valid. Skipping handling heading and trailing spaces in the exact wayb)
x not in ( )
is parsed and valid asx in ( )
. (insure if I'm missing something)c)
x not (,a)
(with leading comma) now is parsed and valid. Again ifx in (abc,)
is parsable why it "x not in (,a)" should be equally parsable?d) I'm still waiting for the @thockin and @smarterclayton about 'not in' vs "NotIn" and about capitalization (not a big deal to modify)