Skip to content
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

plugin/pkg/client/auth: add openstack auth provider #39587

Merged

Conversation

zhouhaibing089
Copy link
Contributor

@zhouhaibing089 zhouhaibing089 commented Jan 9, 2017

This is an implementation of auth provider for OpenStack world, just like python-openstackclient, we read the environment variables of a list OS_*, and client will cache a token to interact with each components, we can do the same here, the client side can cache a token locally at the first time, and rotate automatically when it expires.

This requires an implementation of token authenticator at server side, refer:

  1. [made by me] [WIP] - keystone token authentication #25536, I can carry this on when it is fine to go.
  2. [made by @kfox1111] OpenStack Keystone Token Authentication #25391

The reason why I want to add this is due to the client-side nature, it will be confusing to implement it downstream, we would like to add this support here, and customers can get kubectl like they usually do(brew install kubernetes-cli), and it will just work.

When this is done, we can deprecate the password keystone authenticator as the following reasons:

  1. as mentioned at some other places, the domain is another parameters which should be provided.
  2. in case the user supplies apikey and secrets, we might want to fill the UserInfo with the real name which is not implemented for now.

cc @erictune @liggitt

add openstack auth provider

@k8s-ci-robot
Copy link
Contributor

Hi @zhouhaibing089. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with @k8s-bot ok to test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Jan 9, 2017
@k8s-reviewable
Copy link

This change is Reviewable

@k8s-github-robot k8s-github-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. release-note-label-needed labels Jan 9, 2017
@zhouhaibing089 zhouhaibing089 force-pushed the openstack-auth-provider branch 2 times, most recently from 29e35aa to 2b0b1fc Compare January 9, 2017 02:51
@liggitt liggitt added the sig/auth Categorizes an issue or PR as relevant to SIG Auth. label Jan 13, 2017
@anguslees
Copy link
Member

@k8s-bot ok to test
/lgtm

@k8s-ci-robot
Copy link
Contributor

@anguslees: you can't LGTM a PR unless you are an assignee.

In response to this comment:

@k8s-bot ok to test
/lgtm

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

@anguslees
Copy link
Member

@idvoretskyi sig-openstack area tag please

@liggitt liggitt assigned liggitt and unassigned davidopp Jan 14, 2017

// refreshToken token by authenticate with openstack again
func refreshToken() (string, error) {
options, err := openstack.AuthOptionsFromEnv()
Copy link
Member

@liggitt liggitt Jan 14, 2017

Choose a reason for hiding this comment

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

Is an openstack token ever obtained from then env directly? cc @kfox1111

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@liggitt no it is not, it needs to call keystone with these env vars, and then, a token will be returned.


// RoundTrip adds the bearer token into the request, and rotate it automatically
func (t *tokenRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
req.Header.Set("Authorization", "Bearer "+t.token)
Copy link
Member

Choose a reason for hiding this comment

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

It looks like the first time, the token will always be blank. Is that expected?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

well, you catch it! it still works though(the auto renew). I will add a call once the round tripper is initialized.

}
t.failed = true
// will need to refresh the token, and redo the request
if t.token, err = t.getToken(); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Is the same auth provider reused if a single CLI instance makes multiple API calls? I think @ericchiang just made some changes to the OIDC auth provider to avoid multiple expensive reconstructions in that case. Would be worth logging the number of times a token is requested and making sure it only happens once in the normal case.

Copy link
Member

Choose a reason for hiding this comment

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

I'm also not seeing where the retrieved token is persisted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@liggitt each call via cli(kubectl), it will be reconstructed, this is true. a better way to handle this is to cache(truly) the token into the kubeconfig, if that do makes it better.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think @ericchiang just made some changes to the OIDC auth provider to avoid multiple expensive reconstructions in that case.

To reiterate the auth provider is going to be constantly re-initialized within the span on a single kubeclt call. We remedied that by having a global cache of clients and did a lookup on initialization. If initialization is expensive, you'll need to cache the results.

func RandStringBytes(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = LetterBytes[rand.Intn(len(LetterBytes))]
Copy link
Member

Choose a reason for hiding this comment

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

You need your own instance of math.Rand seeded with something actually random

Copy link
Member

Choose a reason for hiding this comment

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

Well, maybe not in a test

@liggitt liggitt added the area/provider/openstack Issues or PRs related to openstack provider label Jan 14, 2017
@liggitt
Copy link
Member

liggitt commented Jan 14, 2017

cc @kubernetes/sig-openstack-misc

@wjun
Copy link

wjun commented Jan 14, 2017

As long as any approach cannot keep end users unaware of openstack specific information besides domain name, username, password which other systems also have, we cannot remove the current username/password authn which hide openstack specific information from end users perfectly. k8s users do not need to know openstack's information in some cases.

return &tokenRoundTripper{RoundTripper: rt, getToken: refreshToken}
}

func (c *openstackAuthProvider) Login() error { return nil }
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should just remove this from the interface? Nothing implements it and there's no way to trigger it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

well, I think it is not tied with this pr, but I am wiling to check and remove it.

// RoundTrip adds the bearer token into the request, and rotate it automatically
func (t *tokenRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
req.Header.Set("Authorization", "Bearer "+t.token)
resp, err := t.RoundTripper.RoundTrip(req)
Copy link
Contributor

Choose a reason for hiding this comment

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

We removed similar logic from the OIDC plugin. I don't think http.RoundTrippers should be retrying requests. Is there a way to determine if a token is invalid without getting back a StatusUnauthorized?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there a way to determine if a token is invalid without getting back a StatusUnauthorized?

As far as I know, there is no easy way:

  1. call keystone token api, but it requires admin role(at least in our openstack deployment).
  2. local validation, the PKI token can be validated locally by: 1) download the keystone certificate, 2) decode the token. but it only handles PKI tokens, also if it is totally local, the revocation will not be aware of.

@zhouhaibing089 zhouhaibing089 force-pushed the openstack-auth-provider branch 4 times, most recently from 0c95f4f to fcb5b2b Compare January 15, 2017 07:36
@zhouhaibing089
Copy link
Contributor Author

Well, I have no idea on why the Jenkins verification failed, I've already fixed the bazel things as I can see..

@zhouhaibing089
Copy link
Contributor Author

@sttts I think @liggitt and @ericchiang and folks in sig-openstack already give it a review.

@sttts
Copy link
Contributor

sttts commented Aug 3, 2017

Alright.

/lgtm
/approve no-issue

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 3, 2017
@k8s-github-robot k8s-github-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 3, 2017
@k8s-ci-robot
Copy link
Contributor

@zhouhaibing089: you can't request testing unless you are a kubernetes member.

In response to this:

/retest

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@sttts
Copy link
Contributor

sttts commented Aug 3, 2017

/retest

@zhouhaibing089
Copy link
Contributor Author

updated BUILD file.

@k8s-github-robot k8s-github-robot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. and removed lgtm "Looks good to me", indicates that a PR is ready to be merged. labels Aug 4, 2017
@k8s-github-robot k8s-github-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 5, 2017
@dims
Copy link
Member

dims commented Aug 6, 2017

/ok-to-test

@dims
Copy link
Member

dims commented Aug 6, 2017

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 6, 2017
@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: anguslees, dims, sttts, zhouhaibing089

Associated issue requirement bypassed by: sttts

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 /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@k8s-github-robot k8s-github-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 6, 2017
@zhouhaibing089
Copy link
Contributor Author

just run ./hack/update-staging-godeps.sh..

@dims
Copy link
Member

dims commented Aug 6, 2017

/retest

1 similar comment
@sttts
Copy link
Contributor

sttts commented Aug 7, 2017

/retest

@sttts sttts added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 7, 2017
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

1 similar comment
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to @fejta).

Review the full test history for this PR.

@k8s-github-robot
Copy link

Automatic merge from submit-queue (batch tested with PRs 50087, 39587, 50042, 50241, 49914)

@k8s-github-robot k8s-github-robot merged commit 59b8fa3 into kubernetes:master Aug 7, 2017
dims pushed a commit to dims/kubernetes that referenced this pull request Feb 8, 2018
…h-provider

Automatic merge from submit-queue (batch tested with PRs 50087, 39587, 50042, 50241, 49914)

plugin/pkg/client/auth: add openstack auth provider

This is an implementation of auth provider for OpenStack world, just like python-openstackclient, we read the environment variables of a list `OS_*`, and client will cache a token to interact with each components, we can do the same here, the client side can cache a token locally at the first time, and rotate automatically when it expires.

This requires an implementation of token authenticator at server side, refer:

1.  [made by me] kubernetes#25536, I can carry this on when it is fine to go.
2.  [made by @kfox1111] kubernetes#25391

The reason why I want to add this is due to the `client-side` nature, it will be confusing to implement it downstream, we would like to add this support here, and customers can get `kubectl` like they usually do(`brew install kubernetes-cli`), and it will just work.

When this is done, we can deprecate the password keystone authenticator as the following reasons:

1.  as mentioned at some other places, the `domain` is another parameters which should be provided.
2.  in case the user supplies `apikey` and `secrets`, we might want to fill the `UserInfo` with the real name which is not implemented for now.

cc @erictune @liggitt 

```
add openstack auth provider
```
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. area/provider/openstack Issues or PRs related to openstack provider 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/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.

None yet