Updated gophercloud to revision with app creds
This commit is contained in:
parent
349c0beb7b
commit
4025d1da2e
2
go.mod
2
go.mod
|
@ -61,7 +61,7 @@ require (
|
|||
github.com/google/go-querystring v0.0.0-20151028211038-2a60fc2ba6c1 // indirect
|
||||
github.com/google/shlex v0.0.0-20150127133951-6f45313302b9
|
||||
github.com/google/uuid v0.0.0-20171129191014-dec09d789f3d
|
||||
github.com/gophercloud/gophercloud v0.0.0-20190112023249-80c596f406a3
|
||||
github.com/gophercloud/gophercloud v0.0.0-20180903124057-ea7289ebdf06
|
||||
github.com/gophercloud/utils v0.0.0-20180806215700-d6e28a8b3199
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect
|
||||
github.com/gorilla/websocket v0.0.0-20170319172727-a91eba7f9777 // indirect
|
||||
|
|
4
go.sum
4
go.sum
|
@ -133,8 +133,8 @@ github.com/google/shlex v0.0.0-20150127133951-6f45313302b9 h1:JM174NTeGNJ2m/oLH3
|
|||
github.com/google/shlex v0.0.0-20150127133951-6f45313302b9/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
|
||||
github.com/google/uuid v0.0.0-20171129191014-dec09d789f3d h1:rXQlD9GXkjA/PQZhmEaF/8Pj/sJfdZJK7GJG0gkS8I0=
|
||||
github.com/google/uuid v0.0.0-20171129191014-dec09d789f3d/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gophercloud/gophercloud v0.0.0-20190112023249-80c596f406a3 h1:3v50aN5I1XldxFQRT/oZwJMRYt0Edhs7rPVXXWPihKI=
|
||||
github.com/gophercloud/gophercloud v0.0.0-20190112023249-80c596f406a3/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
|
||||
github.com/gophercloud/gophercloud v0.0.0-20180903124057-ea7289ebdf06 h1:m7Rt/8En7PLrM7PQpykdZBPKUdgZWN6MwiA/ChVIoxs=
|
||||
github.com/gophercloud/gophercloud v0.0.0-20180903124057-ea7289ebdf06/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
|
||||
github.com/gophercloud/utils v0.0.0-20180806215700-d6e28a8b3199 h1:mmwryCmmFkCxL3t5r6syrbk1eyP6tP9q/whDdAiM9Mw=
|
||||
github.com/gophercloud/utils v0.0.0-20180806215700-d6e28a8b3199/go.mod h1:wjDF8z83zTeg5eMLml5EBSlAhbF7G8DobyI1YsMuyzw=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
|
||||
|
|
|
@ -140,7 +140,7 @@ See the [contributing guide](./.github/CONTRIBUTING.md).
|
|||
## Help and feedback
|
||||
|
||||
If you're struggling with something or have spotted a potential bug, feel free
|
||||
to submit an issue to our [bug tracker](/issues).
|
||||
to submit an issue to our [bug tracker](https://github.com/gophercloud/gophercloud/issues).
|
||||
|
||||
## Thank You
|
||||
|
||||
|
|
|
@ -84,6 +84,12 @@ type AuthOptions struct {
|
|||
|
||||
// Scope determines the scoping of the authentication request.
|
||||
Scope *AuthScope `json:"-"`
|
||||
|
||||
// Authentication through Application Credentials requires supplying name, project and secret
|
||||
// For project we can use TenantID
|
||||
ApplicationCredentialID string `json:"-"`
|
||||
ApplicationCredentialName string `json:"-"`
|
||||
ApplicationCredentialSecret string `json:"-"`
|
||||
}
|
||||
|
||||
// AuthScope allows a created token to be limited to a specific domain or project.
|
||||
|
@ -142,7 +148,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
type userReq struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Password string `json:"password"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Domain *domainReq `json:"domain,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -154,10 +160,18 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
type applicationCredentialReq struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
User *userReq `json:"user,omitempty"`
|
||||
Secret *string `json:"secret,omitempty"`
|
||||
}
|
||||
|
||||
type identityReq struct {
|
||||
Methods []string `json:"methods"`
|
||||
Password *passwordReq `json:"password,omitempty"`
|
||||
Token *tokenReq `json:"token,omitempty"`
|
||||
Methods []string `json:"methods"`
|
||||
Password *passwordReq `json:"password,omitempty"`
|
||||
Token *tokenReq `json:"token,omitempty"`
|
||||
ApplicationCredential *applicationCredentialReq `json:"application_credential,omitempty"`
|
||||
}
|
||||
|
||||
type authReq struct {
|
||||
|
@ -171,6 +185,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
// Populate the request structure based on the provided arguments. Create and return an error
|
||||
// if insufficient or incompatible information is present.
|
||||
var req request
|
||||
var userRequest userReq
|
||||
|
||||
if opts.Password == "" {
|
||||
if opts.TokenID != "" {
|
||||
|
@ -194,8 +209,49 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
|
|||
req.Auth.Identity.Token = &tokenReq{
|
||||
ID: opts.TokenID,
|
||||
}
|
||||
|
||||
} else if opts.ApplicationCredentialID != "" {
|
||||
// Configure the request for ApplicationCredentialID authentication.
|
||||
// https://github.com/openstack/keystoneauth/blob/stable/rocky/keystoneauth1/identity/v3/application_credential.py#L48-L67
|
||||
// There are three kinds of possible application_credential requests
|
||||
// 1. application_credential id + secret
|
||||
// 2. application_credential name + secret + user_id
|
||||
// 3. application_credential name + secret + username + domain_id / domain_name
|
||||
if opts.ApplicationCredentialSecret == "" {
|
||||
return nil, ErrAppCredMissingSecret{}
|
||||
}
|
||||
req.Auth.Identity.Methods = []string{"application_credential"}
|
||||
req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{
|
||||
ID: &opts.ApplicationCredentialID,
|
||||
Secret: &opts.ApplicationCredentialSecret,
|
||||
}
|
||||
} else if opts.ApplicationCredentialName != "" {
|
||||
if opts.ApplicationCredentialSecret == "" {
|
||||
return nil, ErrAppCredMissingSecret{}
|
||||
}
|
||||
// make sure that only one of DomainName or DomainID were provided
|
||||
if opts.DomainID == "" && opts.DomainName == "" {
|
||||
return nil, ErrDomainIDOrDomainName{}
|
||||
}
|
||||
req.Auth.Identity.Methods = []string{"application_credential"}
|
||||
if opts.DomainID != "" {
|
||||
userRequest = userReq{
|
||||
Name: &opts.Username,
|
||||
Domain: &domainReq{ID: &opts.DomainID},
|
||||
}
|
||||
} else if opts.DomainName != "" {
|
||||
userRequest = userReq{
|
||||
Name: &opts.Username,
|
||||
Domain: &domainReq{Name: &opts.DomainName},
|
||||
}
|
||||
}
|
||||
req.Auth.Identity.ApplicationCredential = &applicationCredentialReq{
|
||||
Name: &opts.ApplicationCredentialName,
|
||||
User: &userRequest,
|
||||
Secret: &opts.ApplicationCredentialSecret,
|
||||
}
|
||||
} else {
|
||||
// If no password or token ID are available, authentication can't continue.
|
||||
// If no password or token ID or ApplicationCredential are available, authentication can't continue.
|
||||
return nil, ErrMissingPassword{}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -451,3 +451,10 @@ type ErrScopeEmpty struct{ BaseError }
|
|||
func (e ErrScopeEmpty) Error() string {
|
||||
return "You must provide either a Project or Domain in a Scope"
|
||||
}
|
||||
|
||||
// ErrAppCredMissingSecret indicates that no Application Credential Secret was provided with Application Credential ID or Name
|
||||
type ErrAppCredMissingSecret struct{ BaseError }
|
||||
|
||||
func (e ErrAppCredMissingSecret) Error() string {
|
||||
return "You must provide an Application Credential Secret"
|
||||
}
|
||||
|
|
|
@ -295,7 +295,11 @@ func (client *ProviderClient) Request(method, url string, options *RequestOpts)
|
|||
seeker.Seek(0, 0)
|
||||
}
|
||||
}
|
||||
// make a new call to request with a nil reauth func in order to avoid infinite loop
|
||||
reauthFunc := client.ReauthFunc
|
||||
client.ReauthFunc = nil
|
||||
resp, err = client.Request(method, url, options)
|
||||
client.ReauthFunc = reauthFunc
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *ErrUnexpectedResponseCode:
|
||||
|
@ -378,7 +382,7 @@ func defaultOkCodes(method string) []int {
|
|||
case method == "PUT":
|
||||
return []int{201, 202}
|
||||
case method == "PATCH":
|
||||
return []int{200, 204}
|
||||
return []int{200, 202, 204}
|
||||
case method == "DELETE":
|
||||
return []int{202, 204}
|
||||
}
|
||||
|
|
|
@ -89,23 +89,45 @@ func (r Result) extractIntoPtr(to interface{}, label string) error {
|
|||
if typeOfV.Kind() == reflect.Struct {
|
||||
if typeOfV.NumField() > 0 && typeOfV.Field(0).Anonymous {
|
||||
newSlice := reflect.MakeSlice(reflect.SliceOf(typeOfV), 0, 0)
|
||||
newType := reflect.New(typeOfV).Elem()
|
||||
|
||||
for _, v := range m[label].([]interface{}) {
|
||||
// For each iteration of the slice, we create a new struct.
|
||||
// This is to work around a bug where elements of a slice
|
||||
// are reused and not overwritten when the same copy of the
|
||||
// struct is used:
|
||||
//
|
||||
// https://github.com/golang/go/issues/21092
|
||||
// https://github.com/golang/go/issues/24155
|
||||
// https://play.golang.org/p/NHo3ywlPZli
|
||||
newType := reflect.New(typeOfV).Elem()
|
||||
|
||||
b, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// This is needed for structs with an UnmarshalJSON method.
|
||||
// Technically this is just unmarshalling the response into
|
||||
// a struct that is never used, but it's good enough to
|
||||
// trigger the UnmarshalJSON method.
|
||||
for i := 0; i < newType.NumField(); i++ {
|
||||
s := newType.Field(i).Addr().Interface()
|
||||
err = json.NewDecoder(bytes.NewReader(b)).Decode(s)
|
||||
|
||||
// Unmarshal is used rather than NewDecoder to also work
|
||||
// around the above-mentioned bug.
|
||||
err = json.Unmarshal(b, s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
newSlice = reflect.Append(newSlice, newType)
|
||||
}
|
||||
|
||||
// "to" should now be properly modeled to receive the
|
||||
// JSON response body and unmarshal into all the correct
|
||||
// fields of the struct or composed extension struct
|
||||
// at the end of this method.
|
||||
toValue.Set(newSlice)
|
||||
}
|
||||
}
|
||||
|
@ -366,6 +388,27 @@ func (jt *JSONRFC3339ZNoT) UnmarshalJSON(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// RFC3339ZNoTNoZ is another time format used in Zun (Containers Service).
|
||||
const RFC3339ZNoTNoZ = "2006-01-02 15:04:05"
|
||||
|
||||
type JSONRFC3339ZNoTNoZ time.Time
|
||||
|
||||
func (jt *JSONRFC3339ZNoTNoZ) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(data, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
if s == "" {
|
||||
return nil
|
||||
}
|
||||
t, err := time.Parse(RFC3339ZNoTNoZ, s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*jt = JSONRFC3339ZNoTNoZ(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
Link is an internal type to be used in packages of collection resources that are
|
||||
paginated in a certain way.
|
||||
|
|
|
@ -811,10 +811,10 @@
|
|||
"revisionTime": "2017-11-29T19:10:14Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "qduT9GZUhXc00XoHEwLx16Xn9gM=",
|
||||
"checksumSHA1": "90HfuOdlP9yK6xUnJCAnCrL73DQ=",
|
||||
"path": "github.com/gophercloud/gophercloud",
|
||||
"revision": "7112fcd50da4ea27e8d4d499b30f04eea143bec2",
|
||||
"revisionTime": "2018-05-31T02:06:30Z"
|
||||
"revision": "ea7289ebdf06687b792c087e2516317579d3003b",
|
||||
"revisionTime": "2018-09-03T13:40:57Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "b7g9TcU1OmW7e2UySYeOAmcfHpY=",
|
||||
|
@ -1487,18 +1487,18 @@
|
|||
"revision": "2d205ac6ec17a839a94bdbfd16d2fa6c6dada2e0",
|
||||
"revisionTime": "2016-03-31T20:48:55Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "6JP37UqrI0H80Gpk0Y2P+KXgn5M=",
|
||||
"path": "github.com/ryanuber/go-glob",
|
||||
"revision": "256dc444b735e061061cf46c809487313d5b0065",
|
||||
"revisionTime": "2017-01-28T01:21:29Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "4gVuzkHbQoznf+lCSJhIJnvS5tc=",
|
||||
"path": "github.com/rwtodd/Go.Sed/sed",
|
||||
"revision": "d6d5d585814e4c3560c684f52e3d8aeed721313d",
|
||||
"revisionTime": "2017-05-07T04:53:31Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "6JP37UqrI0H80Gpk0Y2P+KXgn5M=",
|
||||
"path": "github.com/ryanuber/go-glob",
|
||||
"revision": "256dc444b735e061061cf46c809487313d5b0065",
|
||||
"revisionTime": "2017-01-28T01:21:29Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "zmC8/3V4ls53DJlNTKDZwPSC/dA=",
|
||||
"path": "github.com/satori/go.uuid",
|
||||
|
|
Loading…
Reference in New Issue