Updated gophercloud to revision with app creds

This commit is contained in:
Kevin Bulebush 2019-01-11 22:52:50 -05:00
parent 349c0beb7b
commit 4025d1da2e
8 changed files with 131 additions and 21 deletions

2
go.mod
View File

@ -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
View File

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

View File

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

View File

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

View File

@ -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"
}

View File

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

View File

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

18
vendor/vendor.json vendored
View File

@ -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",