func NewComputeV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
	eo.ApplyDefaults("compute")
	url, err := client.EndpointLocator(eo)
	if err != nil {
		return nil, err
	}
	return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
}
NewComputeV2 creates a ServiceClient that may be used with the v2 compute package.
package openstack
import (
	"fmt"
	"net/url"
	"reflect"
	"github.com/gophercloud/gophercloud"
	tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens"
	tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
	"github.com/gophercloud/gophercloud/openstack/utils"
)
const (
	v20 = "v2.0"
	v30 = "v3.0"
)
func NewClient(endpoint string) (*gophercloud.ProviderClient, error) {
	u, err := url.Parse(endpoint)
	if err != nil {
		return nil, err
	}
	hadPath := u.Path != ""
	u.Path, u.RawQuery, u.Fragment = "", "", ""
	base := u.String()
	endpoint = gophercloud.NormalizeURL(endpoint)
	base = gophercloud.NormalizeURL(base)
	if hadPath {
		return &gophercloud.ProviderClient{
			IdentityBase:     base,
			IdentityEndpoint: endpoint,
		}, nil
	}
	return &gophercloud.ProviderClient{
		IdentityBase:     base,
		IdentityEndpoint: "",
	}, nil
}
func AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.ProviderClient, error) {
	client, err := NewClient(options.IdentityEndpoint)
	if err != nil {
		return nil, err
	}
	err = Authenticate(client, options)
	if err != nil {
		return nil, err
	}
	return client, nil
}
func Authenticate(client *gophercloud.ProviderClient, options gophercloud.AuthOptions) error {
	versions := []*utils.Version{
		{ID: v20, Priority: 20, Suffix: "/v2.0/"},
		{ID: v30, Priority: 30, Suffix: "/v3/"},
	}
	chosen, endpoint, err := utils.ChooseVersion(client, versions)
	if err != nil {
		return err
	}
	switch chosen.ID {
	case v20:
		return v2auth(client, endpoint, options, gophercloud.EndpointOpts{})
	case v30:
		return v3auth(client, endpoint, options, gophercloud.EndpointOpts{})
	default:
		return fmt.Errorf("Unrecognized identity version: %s", chosen.ID)
	}
}
func AuthenticateV2(client *gophercloud.ProviderClient, options gophercloud.AuthOptions, eo gophercloud.EndpointOpts) error {
	return v2auth(client, "", options, eo)
}
func v2auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions, eo gophercloud.EndpointOpts) error {
	v2Client, err := NewIdentityV2(client, eo)
	if err != nil {
		return err
	}
	if endpoint != "" {
		v2Client.Endpoint = endpoint
	}
	v2Opts := tokens2.AuthOptions{
		IdentityEndpoint: options.IdentityEndpoint,
		Username:         options.Username,
		Password:         options.Password,
		TenantID:         options.TenantID,
		TenantName:       options.TenantName,
		AllowReauth:      options.AllowReauth,
		TokenID:          options.TokenID,
	}
	result := tokens2.Create(v2Client, v2Opts)
	token, err := result.ExtractToken()
	if err != nil {
		return err
	}
	catalog, err := result.ExtractServiceCatalog()
	if err != nil {
		return err
	}
	if options.AllowReauth {
		client.ReauthFunc = func() error {
			client.TokenID = ""
			return v2auth(client, endpoint, options, eo)
		}
	}
	client.TokenID = token.ID
	client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
		return V2EndpointURL(catalog, opts)
	}
	return nil
}
func AuthenticateV3(client *gophercloud.ProviderClient, options gophercloud.AuthOptions, eo gophercloud.EndpointOpts) error {
	return v3auth(client, "", options, eo)
}
func v3auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions, eo gophercloud.EndpointOpts) error {
	v3Client, err := NewIdentityV3(client, eo)
	if err != nil {
		return err
	}
	if endpoint != "" {
		v3Client.Endpoint = endpoint
	}
	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)
	token, err := result.ExtractToken()
	if err != nil {
		return err
	}
	catalog, err := result.ExtractServiceCatalog()
	if err != nil {
		return err
	}
	client.TokenID = token.ID
	if options.AllowReauth {
		client.ReauthFunc = func() error {
			client.TokenID = ""
			return v3auth(client, endpoint, options, eo)
		}
	}
	client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
		return V3EndpointURL(catalog, opts)
	}
	return nil
}
func NewIdentityV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
	endpoint := client.IdentityBase + "v2.0/"
	var err error
	if !reflect.DeepEqual(eo, gophercloud.EndpointOpts{}) {
		eo.ApplyDefaults("identity")
		endpoint, err = client.EndpointLocator(eo)
		if err != nil {
			return nil, err
		}
	}
	return &gophercloud.ServiceClient{
		ProviderClient: client,
		Endpoint:       endpoint,
	}, nil
}
func NewIdentityV3(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
	endpoint := client.IdentityBase + "v3/"
	var err error
	if !reflect.DeepEqual(eo, gophercloud.EndpointOpts{}) {
		eo.ApplyDefaults("identity")
		endpoint, err = client.EndpointLocator(eo)
		if err != nil {
			return nil, err
		}
	}
	return &gophercloud.ServiceClient{
		ProviderClient: client,
		Endpoint:       endpoint,
	}, nil
}
func NewObjectStorageV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
	eo.ApplyDefaults("object-store")
	url, err := client.EndpointLocator(eo)
	if err != nil {
		return nil, err
	}
	return &gophercloud.ServiceClient{ProviderClient: client, Endpoint: url}, nil
}