blob: 98092c8067f359a7bad24937f656425876ef66d5 [file] [log] [blame]
Ash Wilson8ba82242014-08-28 15:38:55 -04001package openstack
2
3import (
Ash Wilson4dee1b82014-08-29 14:56:45 -04004 "errors"
5
Ash Wilson8ba82242014-08-28 15:38:55 -04006 "github.com/rackspace/gophercloud"
7 identity3 "github.com/rackspace/gophercloud/openstack/identity/v3"
Ash Wilson4dee1b82014-08-29 14:56:45 -04008 "github.com/rackspace/gophercloud/openstack/utils"
Ash Wilson8ba82242014-08-28 15:38:55 -04009)
10
11// Client provides access to service clients for this OpenStack cloud.
Ash Wilson4dee1b82014-08-29 14:56:45 -040012type Client struct {
13 gophercloud.ProviderClient
14}
15
16const (
17 v20 = "v2.0"
18 v30 = "v3.0"
19)
Ash Wilson8ba82242014-08-28 15:38:55 -040020
Ash Wilsonccd020b2014-09-02 10:40:54 -040021// AuthenticatedClient logs in to an OpenStack cloud found at the identity endpoint specified by authOptions, acquires a token, and
22// returns a Client instance that's ready to operate.
Ash Wilson8ba82242014-08-28 15:38:55 -040023// It first queries the root identity endpoint to determine which versions of the identity service are supported, then chooses
24// the most recent identity service available to proceed.
Ash Wilsonccd020b2014-09-02 10:40:54 -040025func AuthenticatedClient(authOptions gophercloud.AuthOptions) (*Client, error) {
26 client := NewClient(authOptions)
27 err := client.Authenticate()
28 if err != nil {
29 return nil, err
30 }
31 return client, nil
32}
33
34// NewClient prepares an unauthenticated Client instance.
35// Most users will probably prefer using the AuthenticatedClient function instead.
36// This is useful if you wish to explicitly control the version of the identity service that's used for authentication explicitly,
37// for example.
38func NewClient(authOptions gophercloud.AuthOptions) *Client {
39 return &Client{
40 ProviderClient: gophercloud.ProviderClient{
41 Options: authOptions,
42 },
43 }
44}
45
46// Authenticate or re-authenticate against the most recent identity service supported at the provided endpoint.
47func (client *Client) Authenticate() error {
Ash Wilson4dee1b82014-08-29 14:56:45 -040048 versions := []*utils.Version{
49 &utils.Version{ID: v20, Priority: 20},
50 &utils.Version{ID: v30, Priority: 30},
51 }
52
Ash Wilsonccd020b2014-09-02 10:40:54 -040053 chosen, endpoint, err := utils.ChooseVersion(client.ProviderClient.Options.IdentityEndpoint, versions)
Ash Wilson4dee1b82014-08-29 14:56:45 -040054 if err != nil {
Ash Wilsonccd020b2014-09-02 10:40:54 -040055 return err
Ash Wilson4dee1b82014-08-29 14:56:45 -040056 }
57
58 switch chosen.ID {
59 case v20:
Ash Wilsonccd020b2014-09-02 10:40:54 -040060 return client.authenticateV2(endpoint)
Ash Wilson4dee1b82014-08-29 14:56:45 -040061 case v30:
Ash Wilsonccd020b2014-09-02 10:40:54 -040062 return client.authenticateV3(endpoint)
Ash Wilson4dee1b82014-08-29 14:56:45 -040063 default:
Ash Wilsonccd020b2014-09-02 10:40:54 -040064 // The switch statement must be out of date from the versions list.
65 return errors.New("Wat")
66 }
67}
68
69// AuthenticateV2 acquires a token explicitly from the v2.0 identity API.
70func (client *Client) AuthenticateV2() error {
71 endpoint := client.ProviderClient.Options.IdentityEndpoint + "/v2.0"
72 return client.authenticateV2(endpoint)
73}
74
75func (client *Client) authenticateV2(endpoint string) error {
76 return errors.New("Not implemented yet.")
77}
78
79// AuthenticateV3 acquires a token explicitly from the v3.0 identity API.
80func (client *Client) AuthenticateV3() error {
81 endpoint := client.ProviderClient.Options.IdentityEndpoint + "/v3"
82 return client.authenticateV3(endpoint)
83}
84
85func (client *Client) authenticateV3(endpoint string) error {
86 identityClient := identity3.NewClient(&client.ProviderClient, endpoint)
87 token, err := identityClient.GetToken(client.ProviderClient.Options)
88 if err != nil {
89 return err
Ash Wilson4dee1b82014-08-29 14:56:45 -040090 }
91
Ash Wilsonccd020b2014-09-02 10:40:54 -040092 client.ProviderClient.TokenID = token.ID
93
94 return nil
Ash Wilson8ba82242014-08-28 15:38:55 -040095}
96
Ash Wilson773e6c32014-09-02 08:38:07 -040097// NewIdentityV3 explicitly accesses the v3 identity service.
98func (client *Client) NewIdentityV3() (*identity3.Client, error) {
Ash Wilsonccd020b2014-09-02 10:40:54 -040099 endpoint := client.ProviderClient.Options.IdentityEndpoint + "/v3"
100 return identity3.NewClient(&client.ProviderClient, endpoint), nil
Ash Wilson8ba82242014-08-28 15:38:55 -0400101}