Skip to content

Allow for listing & watching individual secrets from nodes#63469

Merged
k8s-github-robot merged 2 commits intokubernetes:masterfrom
wojtek-t:allow_list_and_watch_secrets
May 17, 2018
Merged

Allow for listing & watching individual secrets from nodes#63469
k8s-github-robot merged 2 commits intokubernetes:masterfrom
wojtek-t:allow_list_and_watch_secrets

Conversation

@wojtek-t
Copy link
Copy Markdown
Member

@wojtek-t wojtek-t commented May 6, 2018

This PR:

  • propagates value of metadata.name field from fieldSelector to name field in RequestInfo (for list and watch requests)
  • authorizes list/watch for requests for single secrets/configmaps coming from nodes

As an example:

/api/v1/secrets/namespaces/ns?fieldSelector=metadata.name=foo =>
  requestInfo.Name = "foo",
  requestInfo.Verb = "list"
/api/v1/secrets/namespaces/ns?fieldSelector=metadata.name=foo&watch=true =>
  requestInfo.Name = "foo",
  requestInfo.Verb = "watch"
list/watch API requests with a fieldSelector that specifies `metadata.name` can now be authorized as requests for an individual named resource

@wojtek-t wojtek-t added the release-note-none Denotes a PR that doesn't merit a release note. label May 6, 2018
@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. approved Indicates a PR has been approved by an approver from all required OWNERS files. and removed release-note-none Denotes a PR that doesn't merit a release note. labels May 6, 2018
@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label May 6, 2018
@wojtek-t wojtek-t added release-note-none Denotes a PR that doesn't merit a release note. and removed do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels May 6, 2018
@wojtek-t wojtek-t force-pushed the allow_list_and_watch_secrets branch from b2bbe8e to bf6c249 Compare May 6, 2018 14:25
Copy link
Copy Markdown
Member

@liggitt liggitt left a comment

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No need for a new attribute, Name already holds this information

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I initially didn't want to mix information coming from two different places into single field.
But I'm fine with merging those two.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. set the existing requestInfo.Name field, drop SingleName
  2. 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
  3. 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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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?

  1. not yet done (though you also added a dedicated comment about that, so will rely on that) for this purpose)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. can make this authorizeReadNamespacedObject(...), authorize get/list/watch uniformly (must have name, namespace, no subresource)
  2. treat configmaps the same way

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

Copy link
Copy Markdown
Member

@liggitt liggitt May 7, 2018

Choose a reason for hiding this comment

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

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:

  1. ensure namespaced resources enforce having a non-empty namespace edit: after consideration, you should be able to authorize watching a name across all namespaces
  2. allow a nil fieldSelector or a non-nil fieldSelector that returns true and a matching value for RequiresExactMatch("metadata.name")

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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.

@wojtek-t
Copy link
Copy Markdown
Member Author

wojtek-t commented May 7, 2018

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?

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

@wojtek-t wojtek-t force-pushed the allow_list_and_watch_secrets branch 4 times, most recently from 046655c to cf38e49 Compare May 8, 2018 12:45
Copy link
Copy Markdown
Member Author

@wojtek-t wojtek-t left a comment

Choose a reason for hiding this comment

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

@liggitt - thanks a lot for comments - they should be now applied (except from one where I added a questions). Tests are coming...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@liggitt - how can we check here is the resource is namespaced or cluster-scoped?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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         14m

Copy link
Copy Markdown
Member

@liggitt liggitt May 14, 2018

Choose a reason for hiding this comment

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

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" namespace
  • CoreV1().Secrets("bar").List("metadata.name=foo,metadata.namespace=bar") only returns the secret named "foo" in the "bar" namespace
  • CoreV1().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)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

OK. So I left this code as it was and added integration test to check those things.

@wojtek-t wojtek-t force-pushed the allow_list_and_watch_secrets branch 2 times, most recently from e10a52c to 64a477e Compare May 8, 2018 13:52
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

add cases to make sure a list and watch without a name is not allowed

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

Copy link
Copy Markdown
Member

@liggitt liggitt May 8, 2018

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ahh ok - of course you're right. Changing to make logic as you expect.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

@wojtek-t wojtek-t force-pushed the allow_list_and_watch_secrets branch from 64a477e to 5171841 Compare May 8, 2018 20:00
Copy link
Copy Markdown
Member Author

@wojtek-t wojtek-t left a comment

Choose a reason for hiding this comment

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

PTAL

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

@wojtek-t wojtek-t force-pushed the allow_list_and_watch_secrets branch from 5171841 to 5623098 Compare May 8, 2018 20:19
@deads2k
Copy link
Copy Markdown
Contributor

deads2k commented May 15, 2018

already hash that out?

It's a list (i.e. it returns SecretList for example), but with just a single element in Items.

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.

@wojtek-t wojtek-t force-pushed the allow_list_and_watch_secrets branch from 53a8c5c to b2500d4 Compare May 15, 2018 12:19
@wojtek-t
Copy link
Copy Markdown
Member Author

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.

I think that treating it as "list" is cleaner - treating it as "get" would introduce confusion in the code in my opinion.

@wojtek-t
Copy link
Copy Markdown
Member Author

/test pull-kubernetes-e2e-gce

@wojtek-t
Copy link
Copy Markdown
Member Author

@deads2k - tests gree, comments addressed. PTAL

@liggitt
Copy link
Copy Markdown
Member

liggitt commented May 15, 2018

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.

I think that treating it as "list" is cleaner - treating it as "get" would introduce confusion in the code in my opinion.

I agree, I'd rather see this represented as a list/watch filtered to a single named object.

@liggitt
Copy link
Copy Markdown
Member

liggitt commented May 15, 2018

@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?

@liggitt
Copy link
Copy Markdown
Member

liggitt commented May 15, 2018

cc @kubernetes/sig-auth-pr-reviews

@k8s-ci-robot k8s-ci-robot added sig/auth Categorizes an issue or PR as relevant to SIG Auth. release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed release-note-none Denotes a PR that doesn't merit a release note. labels May 15, 2018
@wojtek-t
Copy link
Copy Markdown
Member Author

@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?

@liggitt - done PTAL

@deads2k
Copy link
Copy Markdown
Contributor

deads2k commented May 15, 2018

lgtm

@deads2k
Copy link
Copy Markdown
Contributor

deads2k commented May 15, 2018

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.

I think that treating it as "list" is cleaner - treating it as "get" would introduce confusion in the code in my opinion.

ok, no strong opinion

@liggitt
Copy link
Copy Markdown
Member

liggitt commented May 17, 2018

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label May 17, 2018
@k8s-ci-robot
Copy link
Copy Markdown
Contributor

[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

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-github-robot
Copy link
Copy Markdown

/test all [submit-queue is verifying that this PR is safe to merge]

@k8s-github-robot
Copy link
Copy Markdown

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions here.

@k8s-github-robot k8s-github-robot merged commit b3837d0 into kubernetes:master May 17, 2018
@enj
Copy link
Copy Markdown
Member

enj commented May 17, 2018

@wojtek-t your second example in the first comment has the wrong verb (should be watch).

@wojtek-t
Copy link
Copy Markdown
Member Author

@enj - yes, thanks for pointing. Fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/auth Categorizes an issue or PR as relevant to SIG Auth. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants