OpenStack/Rackspace reauth functionality
diff --git a/openstack/client.go b/openstack/client.go
index 63e07b8..876df74 100644
--- a/openstack/client.go
+++ b/openstack/client.go
@@ -58,6 +58,7 @@
if err != nil {
return nil, err
}
+
return client, nil
}
@@ -107,6 +108,10 @@
return err
}
+ if options.AllowReauth {
+ client.ReauthFunc = AuthenticateV2
+ }
+ client.AuthOptions = options
client.TokenID = token.ID
client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
return V2EndpointURL(catalog, opts)
@@ -133,6 +138,10 @@
}
client.TokenID = token.ID
+ if options.AllowReauth {
+ client.ReauthFunc = AuthenticateV3
+ }
+ client.AuthOptions = options
client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
return V3EndpointURL(v3Client, opts)
}
diff --git a/provider_client.go b/provider_client.go
index 3c65984..9dea5af 100644
--- a/provider_client.go
+++ b/provider_client.go
@@ -63,6 +63,15 @@
// UserAgent represents the User-Agent header in the HTTP request.
UserAgent UserAgent
+
+ // AuthOptions is the user-provided options for authentication. These will be
+ // passed to ReauthFunc for re-authenticating if the user requests it.
+ AuthOptions AuthOptions
+
+ // ReauthFunc is the function used to re-authenticate the user if the request
+ // fails with a 401 HTTP response code. This a needed because there may be multiple
+ // authentication functions for different Identity service versions.
+ ReauthFunc func(client *ProviderClient, options AuthOptions) error
}
// AuthenticatedHeaders returns a map of HTTP headers that are common for all
@@ -179,6 +188,19 @@
return nil, err
}
+ if resp.StatusCode == 401 {
+ if client.AuthOptions.AllowReauth {
+ err = client.ReauthFunc(client, client.AuthOptions)
+ if err != nil {
+ return nil, fmt.Errorf("Error trying to re-authenticate: %s", err)
+ }
+ resp, err = client.Request(method, url, options)
+ if err != nil {
+ return nil, fmt.Errorf("Successfully re-authenticated, but got error executing request: %s", err)
+ }
+ }
+ }
+
// Validate the response code, if requested to do so.
if options.OkCodes != nil {
var ok bool
diff --git a/rackspace/client.go b/rackspace/client.go
index 039f446..4892802 100644
--- a/rackspace/client.go
+++ b/rackspace/client.go
@@ -49,6 +49,7 @@
if err != nil {
return nil, err
}
+
return client, nil
}
@@ -96,6 +97,10 @@
return err
}
+ if options.AllowReauth {
+ client.ReauthFunc = AuthenticateV2
+ }
+ client.AuthOptions = options
client.TokenID = token.ID
client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
return os.V2EndpointURL(catalog, opts)