Identity v3 Authentication With TrustID (#24)

* delete auth_results

* v3 auth with trust

* define auth errors in gophercloud pkg

* AuthOptionsBuilder interface

* combine error files in gophercloud pkg
diff --git a/openstack/client.go b/openstack/client.go
index ebad6dc..a45b538 100644
--- a/openstack/client.go
+++ b/openstack/client.go
@@ -78,7 +78,7 @@
 	case v20:
 		return v2auth(client, endpoint, options, gophercloud.EndpointOpts{})
 	case v30:
-		return v3auth(client, endpoint, options, gophercloud.EndpointOpts{})
+		return v3auth(client, endpoint, &options, gophercloud.EndpointOpts{})
 	default:
 		// The switch statement must be out of date from the versions list.
 		return fmt.Errorf("Unrecognized identity version: %s", chosen.ID)
@@ -137,11 +137,11 @@
 }
 
 // AuthenticateV3 explicitly authenticates against the identity v3 service.
-func AuthenticateV3(client *gophercloud.ProviderClient, options gophercloud.AuthOptions, eo gophercloud.EndpointOpts) error {
+func AuthenticateV3(client *gophercloud.ProviderClient, options tokens3.AuthOptionsBuilder, eo gophercloud.EndpointOpts) error {
 	return v3auth(client, "", options, eo)
 }
 
-func v3auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions, eo gophercloud.EndpointOpts) error {
+func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.AuthOptionsBuilder, eo gophercloud.EndpointOpts) error {
 	// Override the generated service endpoint with the one returned by the version endpoint.
 	v3Client, err := NewIdentityV3(client, eo)
 	if err != nil {
@@ -152,42 +152,7 @@
 		v3Client.Endpoint = endpoint
 	}
 
-	// copy the auth options to a local variable that we can change. `options`
-	// needs to stay as-is for reauth purposes
-	v3Options := options
-
-	var scope *tokens3.Scope
-	if options.TenantID != "" {
-		scope = &tokens3.Scope{
-			ProjectID: options.TenantID,
-		}
-		v3Options.TenantID = ""
-		v3Options.TenantName = ""
-	} else {
-		if options.TenantName != "" {
-			scope = &tokens3.Scope{
-				ProjectName: options.TenantName,
-				DomainID:    options.DomainID,
-				DomainName:  options.DomainName,
-			}
-			v3Options.TenantName = ""
-		}
-	}
-
-	v3Opts := tokens3.AuthOptions{
-		IdentityEndpoint: v3Options.IdentityEndpoint,
-		Username:         v3Options.Username,
-		UserID:           v3Options.UserID,
-		Password:         v3Options.Password,
-		DomainID:         v3Options.DomainID,
-		DomainName:       v3Options.DomainName,
-		TenantID:         v3Options.TenantID,
-		TenantName:       v3Options.TenantName,
-		AllowReauth:      v3Options.AllowReauth,
-		TokenID:          v3Options.TokenID,
-	}
-
-	result := tokens3.Create(v3Client, v3Opts, scope)
+	result := tokens3.Create(v3Client, opts)
 
 	token, err := result.ExtractToken()
 	if err != nil {
@@ -201,10 +166,10 @@
 
 	client.TokenID = token.ID
 
-	if options.AllowReauth {
+	if opts.CanReauth() {
 		client.ReauthFunc = func() error {
 			client.TokenID = ""
-			return v3auth(client, endpoint, options, eo)
+			return v3auth(client, endpoint, opts, eo)
 		}
 	}
 	client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {