mirror of
https://github.com/kubernetes/client-go.git
synced 2026-01-16 23:16:12 +00:00
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] https://github.com/kubernetes/kubernetes/pull/25536, I can carry this on when it is fine to go. 2. [made by @kfox1111] https://github.com/kubernetes/kubernetes/pull/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 ``` Kubernetes-commit: 59b8fa32f129be29f146bfd4888a5d1ab7e71ca5
103 lines
2.7 KiB
Go
103 lines
2.7 KiB
Go
package gophercloud
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// WaitFor polls a predicate function, once per second, up to a timeout limit.
|
|
// This is useful to wait for a resource to transition to a certain state.
|
|
// To handle situations when the predicate might hang indefinitely, the
|
|
// predicate will be prematurely cancelled after the timeout.
|
|
// Resource packages will wrap this in a more convenient function that's
|
|
// specific to a certain resource, but it can also be useful on its own.
|
|
func WaitFor(timeout int, predicate func() (bool, error)) error {
|
|
type WaitForResult struct {
|
|
Success bool
|
|
Error error
|
|
}
|
|
|
|
start := time.Now().Unix()
|
|
|
|
for {
|
|
// If a timeout is set, and that's been exceeded, shut it down.
|
|
if timeout >= 0 && time.Now().Unix()-start >= int64(timeout) {
|
|
return fmt.Errorf("A timeout occurred")
|
|
}
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
var result WaitForResult
|
|
ch := make(chan bool, 1)
|
|
go func() {
|
|
defer close(ch)
|
|
satisfied, err := predicate()
|
|
result.Success = satisfied
|
|
result.Error = err
|
|
}()
|
|
|
|
select {
|
|
case <-ch:
|
|
if result.Error != nil {
|
|
return result.Error
|
|
}
|
|
if result.Success {
|
|
return nil
|
|
}
|
|
// If the predicate has not finished by the timeout, cancel it.
|
|
case <-time.After(time.Duration(timeout) * time.Second):
|
|
return fmt.Errorf("A timeout occurred")
|
|
}
|
|
}
|
|
}
|
|
|
|
// NormalizeURL is an internal function to be used by provider clients.
|
|
//
|
|
// It ensures that each endpoint URL has a closing `/`, as expected by
|
|
// ServiceClient's methods.
|
|
func NormalizeURL(url string) string {
|
|
if !strings.HasSuffix(url, "/") {
|
|
return url + "/"
|
|
}
|
|
return url
|
|
}
|
|
|
|
// NormalizePathURL is used to convert rawPath to a fqdn, using basePath as
|
|
// a reference in the filesystem, if necessary. basePath is assumed to contain
|
|
// either '.' when first used, or the file:// type fqdn of the parent resource.
|
|
// e.g. myFavScript.yaml => file://opt/lib/myFavScript.yaml
|
|
func NormalizePathURL(basePath, rawPath string) (string, error) {
|
|
u, err := url.Parse(rawPath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
// if a scheme is defined, it must be a fqdn already
|
|
if u.Scheme != "" {
|
|
return u.String(), nil
|
|
}
|
|
// if basePath is a url, then child resources are assumed to be relative to it
|
|
bu, err := url.Parse(basePath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
var basePathSys, absPathSys string
|
|
if bu.Scheme != "" {
|
|
basePathSys = filepath.FromSlash(bu.Path)
|
|
absPathSys = filepath.Join(basePathSys, rawPath)
|
|
bu.Path = filepath.ToSlash(absPathSys)
|
|
return bu.String(), nil
|
|
}
|
|
|
|
absPathSys = filepath.Join(basePath, rawPath)
|
|
u.Path = filepath.ToSlash(absPathSys)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
u.Scheme = "file"
|
|
return u.String(), nil
|
|
|
|
}
|