plugin/pkg/client/auth: add openstack auth provider #39587
Conversation
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 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. |
29e35aa
to
2b0b1fc
@k8s-bot ok to test |
@anguslees: you can't LGTM a PR unless you are an assignee. In response to this comment:
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. |
@idvoretskyi sig-openstack area tag please |
|
||
// refreshToken token by authenticate with openstack again | ||
func refreshToken() (string, error) { | ||
options, err := openstack.AuthOptionsFromEnv() |
zhouhaibing089
Jan 14, 2017
Author
Contributor
@liggitt no it is not, it needs to call keystone with these env vars, and then, a token will be returned.
@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) |
liggitt
Jan 14, 2017
Member
It looks like the first time, the token will always be blank. Is that expected?
It looks like the first time, the token will always be blank. Is that expected?
zhouhaibing089
Jan 14, 2017
Author
Contributor
well, you catch it! it still works though(the auto renew). I will add a call once the round tripper is initialized.
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 { |
liggitt
Jan 14, 2017
Member
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.
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.
liggitt
Jan 14, 2017
Member
I'm also not seeing where the retrieved token is persisted.
I'm also not seeing where the retrieved token is persisted.
zhouhaibing089
Jan 14, 2017
Author
Contributor
@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.
@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.
ericchiang
Jan 14, 2017
Member
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.
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))] |
liggitt
Jan 14, 2017
Member
You need your own instance of math.Rand seeded with something actually random
You need your own instance of math.Rand seeded with something actually random
liggitt
Jan 14, 2017
Member
Well, maybe not in a test
Well, maybe not in a test
cc @kubernetes/sig-openstack-misc |
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 } |
ericchiang
Jan 14, 2017
Member
Maybe we should just remove this from the interface? Nothing implements it and there's no way to trigger it.
Maybe we should just remove this from the interface? Nothing implements it and there's no way to trigger it.
zhouhaibing089
Jan 15, 2017
Author
Contributor
well, I think it is not tied with this pr, but I am wiling to check and remove it.
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) |
ericchiang
Jan 14, 2017
Member
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
?
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
?
zhouhaibing089
Jan 15, 2017
Author
Contributor
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:
- call keystone token api, but it requires admin role(at least in our openstack deployment).
- 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.
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:
- call keystone token api, but it requires admin role(at least in our openstack deployment).
- 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.
0c95f4f
to
fcb5b2b
Well, I have no idea on why the Jenkins verification failed, I've already fixed the bazel things as I can see.. |
Alright. /lgtm |
@zhouhaibing089: you can't request testing unless you are a kubernetes member. In response to this:
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. |
/retest |
ea2acaa
to
5a4f638
updated |
5a4f638
to
f1e98c9
/ok-to-test |
/lgtm |
[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 |
f1e98c9
to
a0cebcb
just run |
/retest |
1 similar comment
/retest |
/retest Review the full test history for this PR. |
1 similar comment
/retest Review the full test history for this PR. |
Automatic merge from submit-queue (batch tested with PRs 50087, 39587, 50042, 50241, 49914) |
59b8fa3
into
kubernetes:master
…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 ```
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:
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 getkubectl
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:
domain
is another parameters which should be provided.apikey
andsecrets
, we might want to fill theUserInfo
with the real name which is not implemented for now.cc @erictune @liggitt