-
Notifications
You must be signed in to change notification settings - Fork 39.7k
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
Support field selectors for CRDs #53345
Support field selectors for CRDs #53345
Conversation
@deads2k where in the apiextensions-apiserver integration tests would you recommend testing this? In |
Can you add a test in |
@Kargakis I'd rather put it in the integration tests |
I just pushed an integration test in a separate commit. It's largely a copy of |
/retest |
t.Errorf("expected %v, got %v", e, a) | ||
} | ||
|
||
listWithItem, err := noxuResourceClient.List(metav1.ListOptions{FieldSelector: "metadata.name=foo"}) |
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.
Could you arrange for the objects to differ in a custom spec field, and select for that here? It would be good to test that it works for fields outside metadata.
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.
That doesn't work. I believe it's because of
kubernetes/staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/strategy.go
Lines 98 to 109 in 2bf7a20
// objectMetaFieldsSet returns a fields that represent the ObjectMeta. | |
func objectMetaFieldsSet(objectMeta metav1.Object, namespaceScoped bool) fields.Set { | |
if namespaceScoped { | |
return fields.Set{ | |
"metadata.name": objectMeta.GetName(), | |
"metadata.namespace": objectMeta.GetNamespace(), | |
} | |
} | |
return fields.Set{ | |
"metadata.name": objectMeta.GetName(), | |
} | |
} |
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 could write some code that creates a fields.Set
of every possible field leaf (excluding slices); e.g., if we have this:
a: b
c: 1
d:
- a
- b
e:
f: g
h:
i: j
the field set would be
a: b
c: 1
e.f: g
e.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.
I think you're right. I must have misremembered that it worked for other fields in my earlier experiment. Should we specify in the release note that CRD field selectors only support name and namespace?
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.
Sample code that works: https://gist.github.com/ncdc/edc1ed3abefa36d9650a524ebd5f3f8c
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.
@Kargakis I don't have any concerns with the UX of allowing arbitrary fields; that was my plan when I thought all we needed to do was stop blocking it. However, it turns out we also have to recursively flatten the whole custom object into a map, for every object returned by a list, in order to make filtering work for arbitrary fields.
That seems extreme given how conservative other objects are with their supported field selectors. For example, Pod only picks out 3 fields from spec that you're allowed to use in fieldSelector.
If you have a use case for filtering on arbitrary fields, would you be ok with having to specify a whitelist in the CRD spec, so we don't have to export every field regardless of whether anyone wants it?
We could discuss that on a separate feature request issue. Either way I think we should go ahead and merge this fix for metadata.name, since that's important for watching single objects.
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.
Agreeing to go ahead with this PR before discussing abritrary keys in a follow-up.
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.
@enisoc yeah, a whitelist would be great to have. Please cc me one the new issue when one is made.
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.
@Kargakis I think it's better if you file the issue. I don't actually have any use case in mind for needing arbitrary field selectors, so I can't explain why the feature is being requested.
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.
Opened #53459
} | ||
|
||
func (crdObjectConverter) ConvertFieldLabel(version, kind, label, value string) (string, string, error) { | ||
// Just return the passed-in label and value, as CRDs only support a single version currently. |
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.
For other types, we return an error at this point if the field label isn't in a whitelist:
kubernetes/pkg/api/v1/conversion.go
Line 177 in 2bf7a20
return "", "", fmt.Errorf("field label not supported: %s", label) |
If we don't error out, it just comes back as an empty list, which is misleading.
Whitelisting metadata.name and metadata.namespace would also mean we can remove the caveat about this only working because CRD currently supports only one version -- at least until ObjectMeta v2.
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.
@enisoc are you saying this should just return the result of k8s.io/apimachinery/pkg/runtime/conversion.go#DefaultMetaV1FieldSelectorConversion()?
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.
Hm the behavior there seems reasonable, although it's slightly different than what other resources do. Other cluster-scoped resources seem to error out on metadata.namespace
:
kubernetes/pkg/api/v1/conversion.go
Lines 184 to 195 in 31697a2
err = scheme.AddFieldLabelConversionFunc("v1", "Node", | |
func(label, value string) (string, string, error) { | |
switch label { | |
case "metadata.name": | |
return label, value, nil | |
case "spec.unschedulable": | |
return label, value, nil | |
default: | |
return "", "", fmt.Errorf("field label not supported: %s", label) | |
} | |
}, | |
) |
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.
We know if it's cluster-scoped or not, so I'll just write a custom function
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.
@enisoc just pushed an update - ptal!
/lgtm BTW I updated the release note to specifically call out the fields that are supported. |
Ok thanks. I need to squash, so it'll need 1 more round of lgtm. Will ping in a few. |
Signed-off-by: Andy Goldstein <[email protected]>
cd3119c
to
2ff8730
Compare
Squashed |
/lgtm |
} | ||
|
||
case <-time.After(5 * time.Second): | ||
t.Errorf("missing watch event") |
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.
is 5 seconds enough to avoid flakes?
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.
Perhaps not, but this is not net new (I copied an existing test)
Re-applying lgtm b/c the only new commit was to update bazel. |
/approve |
Gah I had an extra .go file in the repo root that caused bazel to do stuff it shouldn't have. Fixing. |
Signed-off-by: Andy Goldstein <[email protected]>
283ad90
to
74b4db2
Compare
Ok, that's better. @deads2k mind giving it a quick glance again and tagging? |
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: deads2k, enisoc, ncdc Associated issue: 51046 The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
/retest |
/test all [submit-queue is verifying that this PR is safe to merge] |
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions here. |
In case anyone is listening, this used to work with TPRs and was broken when we moved to CRDs. |
@Kargakis : it should be RED! |
In all seriousness, @tamalsaha if there is a backport that needs to be done or what you mention is still an issue, consider opening a separate issue. |
@Kargakis , as a workaround, we now watch everything in a namespace and skip with an |
@ncdc Great work! This is included in 1.9 release right? |
Yes. :) |
Signed-off-by: Andy Goldstein [email protected]
What this PR does / why we need it: allow field selectors to be used with custom resources
Which issue this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close that issue when PR gets merged): fixes #51046, fixes #49424Special notes for your reviewer:
Release note: