Allow for listing & watching individual secrets from nodes#63469
Allow for listing & watching individual secrets from nodes#63469k8s-github-robot merged 2 commits intokubernetes:masterfrom
Conversation
b2bbe8e to
bf6c249
Compare
liggitt
left a comment
There was a problem hiding this comment.
The context for this change is to allow switching secret manager to be watch-based
does opening hundreds/thousands of distinct single-item watches actually scale on the apiserver side? did you check how the watch event multiplexer handles that case?
There was a problem hiding this comment.
No need for a new attribute, Name already holds this information
There was a problem hiding this comment.
I initially didn't want to mix information coming from two different places into single field.
But I'm fine with merging those two.
There was a problem hiding this comment.
- set the existing
requestInfo.Namefield, drop SingleName - this assumes the storage backing this resource honors a fieldSelector of
metadata.name, which is very likely to be true, but is not guaranteed. I think that's probably an ok assumption... anyone writing policy based on this should be aware of the capabilities of the resource they are policying - this does introduce the possibility for name to be set and namespace to be empty for a namespaced resource, which doesn't seem good (
/api/v1/pods?fieldSelector=metadata.name=foo). Updating ListResource to ensure a namespace is present if a name is specified in the request attributes would cover this.
There was a problem hiding this comment.
1 - done
2 - yes, this introduces such assumption (added a comment about that).
That said, won't we fail the validation later if we specify the field that is not supported?
- not yet done (though you also added a dedicated comment about that, so will rely on that) for this purpose)
There was a problem hiding this comment.
- can make this
authorizeReadNamespacedObject(...), authorize get/list/watch uniformly (must have name, namespace, no subresource) - treat configmaps the same way
There was a problem hiding this comment.
this bakes in assumptions about []string -> string conversion for parameters. the worst-case scenario is that this code determines there is a fieldSelector that limits to a single name, authorization allows that, and then the actual rest handler doesn't see or make use of that fieldSelector.
I'd like to see ListResource to get updated with the following when hasName is true:
ensure namespaced resources enforce having a non-empty namespaceedit: after consideration, you should be able to authorize watching a name across all namespaces- allow a nil fieldSelector or a non-nil fieldSelector that returns true and a matching value for
RequiresExactMatch("metadata.name")
There was a problem hiding this comment.
IIUC, "hasName" is true only if the name is passed explicitly (not via fieldSelector).
So while I agree that we need to increase validation, I'm not sure that's the correct place to do this.
There was a problem hiding this comment.
Apparently I was wrong - hasName is computed based on requestInfo:
https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/namer.go#L73
and that will be set in this PR. So this will work. Changing.
I didn't do enough tests to make it default soon. But it's completely fine to open 200.000 watches on a single apiserver - that works fine. @liggitt - thanks for comments, will take a look and address later this week |
046655c to
cf38e49
Compare
There was a problem hiding this comment.
@liggitt - how can we check here is the resource is namespaced or cluster-scoped?
There was a problem hiding this comment.
I'm actually rethinking whether we need to do that check... this works today:
$ kubectl get serviceaccounts --all-namespaces --field-selector=metadata.name=default --v=6
I0513 21:12:31.976525 16635 round_trippers.go:405] GET https://localhost:6443/api/v1/serviceaccounts?fieldSelector=metadata.name%3Ddefault&limit=500 200 OK in 10 milliseconds
NAMESPACE NAME SECRETS AGE
default default 1 14m
kube-public default 1 14m
kube-system default 1 14mThere was a problem hiding this comment.
let's ensure we have test coverage of the following API calls:
CoreV1().Secrets("").List("metadata.name=foo")only returns secrets named "foo"CoreV1().Secrets("").List("metadata.name=foo,metadata.name=other")returns no secrets (AND of conflicting name field selectors)CoreV1().Secrets("").List("metadata.name=foo,metadata.namespace=bar")only returns the secret named "foo" in the "bar" namespaceCoreV1().Secrets("bar").List("metadata.name=foo,metadata.namespace=bar")only returns the secret named "foo" in the "bar" namespaceCoreV1().Secrets("bar").List("metadata.name=foo,metadata.namespace=baz")returns no secrets (namespace field selector doesn't match namespace in path)CoreV1().Secrets("bar").List("metadata.name=foo,metadata.namespace=")returns no secrets (namespace field selector doesn't match namespace in path)
There was a problem hiding this comment.
OK. So I left this code as it was and added integration test to check those things.
e10a52c to
64a477e
Compare
There was a problem hiding this comment.
add cases to make sure a list and watch without a name is not allowed
There was a problem hiding this comment.
it doesn't make sense to ask for both specific name and a different field selector
that's not really accurate... listing fieldSelector=metadata.name=foo,otherfield=bar isn't unreasonable. imagine you are setting up a lister/watcher to get events for a particular object in a particular state
There was a problem hiding this comment.
I'm fine with changing it, but that would be relaxing compared what we had previously - previously if the name was specified we didn't allow for any fieldSelector. WDYT?
There was a problem hiding this comment.
that would be relaxing compared what we had previously
I don't think so... the only way hasName was set before was via a single-item watch, which doesn't take a fieldSelector parameter, right?
There was a problem hiding this comment.
Ahh ok - of course you're right. Changing to make logic as you expect.
64a477e to
5171841
Compare
There was a problem hiding this comment.
I'm fine with changing it, but that would be relaxing compared what we had previously - previously if the name was specified we didn't allow for any fieldSelector. WDYT?
5171841 to
5623098
Compare
I meant for the purposes of authorization, not REST handling. I guess they could grant get, list, watch for a name and this would fall through correctly. |
53a8c5c to
b2500d4
Compare
I think that treating it as "list" is cleaner - treating it as "get" would introduce confusion in the code in my opinion. |
|
/test pull-kubernetes-e2e-gce |
|
@deads2k - tests gree, comments addressed. PTAL |
I agree, I'd rather see this represented as a list/watch filtered to a single named object. |
|
@wojtek-t can you update the PR description with the scope of the change being made, some example requests and resulting RequestInfo, and a release note that list/watch can now authorize named resources? |
|
cc @kubernetes/sig-auth-pr-reviews |
|
lgtm |
ok, no strong opinion |
|
/lgtm |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: liggitt, wojtek-t The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/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. |
|
@wojtek-t your second example in the first comment has the wrong verb (should be watch). |
|
@enj - yes, thanks for pointing. Fixed. |
This PR:
metadata.namefield from fieldSelector tonamefield in RequestInfo (for list and watch requests)As an example: