blob: 7e3aa12f5feb323bb1c8a056f454a03c825c9dab [file] [log] [blame]
Jon Perritt5f4b5c22014-08-27 11:44:07 -05001package utils
Jon Perritt5eb55b12014-08-18 14:48:23 -05002
Jon Perritte1ce2982014-08-19 22:25:08 -05003import (
4 "fmt"
Ash Wilson12b3b6c2014-09-08 14:54:38 -04005
6 "github.com/rackspace/gophercloud"
Jon Perritt5f4b5c22014-08-27 11:44:07 -05007 identity "github.com/rackspace/gophercloud/openstack/identity/v2"
Jon Perritte1ce2982014-08-19 22:25:08 -05008)
9
Jon Perritt8cff5cf2014-08-19 15:44:39 -050010// Client contains information that defines a generic Openstack Client.
Jon Perritt5eb55b12014-08-18 14:48:23 -050011type Client struct {
Jon Perritt8cff5cf2014-08-19 15:44:39 -050012 // Endpoint is the URL against which to authenticate.
13 Endpoint string
14 // Authority holds the results of authenticating against the Endpoint.
Jon Perritt5f4b5c22014-08-27 11:44:07 -050015 Authority identity.AuthResults
Jon Perritt8cff5cf2014-08-19 15:44:39 -050016 // Options holds the authentication options. Useful for auto-reauthentication.
Ash Wilson12b3b6c2014-09-08 14:54:38 -040017 Options gophercloud.AuthOptions
Jon Perritt5eb55b12014-08-18 14:48:23 -050018}
19
Jon Perritt6e898782014-08-19 15:58:11 -050020// EndpointOpts contains options for finding an endpoint for an Openstack Client.
21type EndpointOpts struct {
Jon Perritt8cff5cf2014-08-19 15:44:39 -050022 // Type is the service type for the client (e.g., "compute", "object-store").
23 // Type is a required field.
24 Type string
25 // Name is the service name for the client (e.g., "nova").
26 // Name is not a required field, but it is used if present. Services can have the
27 // same Type but different Name, which is one example of when both Type and Name are needed.
28 Name string
29 // Region is the region in which the service resides.
Jon Perritt8cff5cf2014-08-19 15:44:39 -050030 Region string
31 // URLType is they type of endpoint to be returned (e.g., "public", "private").
32 // URLType is not required, and defaults to "public".
Jon Perritt5eb55b12014-08-18 14:48:23 -050033 URLType string
34}
35
Jon Perritt8cff5cf2014-08-19 15:44:39 -050036// NewClient returns a generic Openstack Client of type identity.Client. This is a helper function
37// to create a client for the various Openstack services.
38// Example (error checking omitted for brevity):
39// ao, err := utils.AuthOptions()
Jon Perrittaab1fcd2014-08-27 11:21:45 -050040// c, err := identity.NewClient(ao, identity.EndpointOpts{
Jon Perritt8cff5cf2014-08-19 15:44:39 -050041// Type: "compute",
42// Name: "nova",
43// })
44// serversClient := servers.NewClient(c.Endpoint, c.Authority, c.Options)
Ash Wilson12b3b6c2014-09-08 14:54:38 -040045func NewClient(ao gophercloud.AuthOptions, eo EndpointOpts) (Client, error) {
Jon Perritt5eb55b12014-08-18 14:48:23 -050046 client := Client{
47 Options: ao,
48 }
49
Ash Wilson9c6c9e62014-09-08 15:27:38 -040050 c := &gophercloud.ServiceClient{Endpoint: ao.IdentityEndpoint}
51 ar, err := identity.Authenticate(c, ao)
Jon Perritt5eb55b12014-08-18 14:48:23 -050052 if err != nil {
53 return client, err
54 }
55
56 client.Authority = ar
57
Jon Perritt5f4b5c22014-08-27 11:44:07 -050058 sc, err := identity.GetServiceCatalog(ar)
Jon Perritt5eb55b12014-08-18 14:48:23 -050059 if err != nil {
60 return client, err
61 }
62
63 ces, err := sc.CatalogEntries()
64 if err != nil {
65 return client, err
66 }
67
Jon Perritt5f4b5c22014-08-27 11:44:07 -050068 var eps []identity.Endpoint
Jon Perritt5eb55b12014-08-18 14:48:23 -050069
Jon Perrittaab1fcd2014-08-27 11:21:45 -050070 if eo.Name != "" {
Jon Perritt5eb55b12014-08-18 14:48:23 -050071 for _, ce := range ces {
Jon Perrittaab1fcd2014-08-27 11:21:45 -050072 if ce.Type == eo.Type && ce.Name == eo.Name {
Jon Perritt5eb55b12014-08-18 14:48:23 -050073 eps = ce.Endpoints
74 }
75 }
76 } else {
77 for _, ce := range ces {
Jon Perrittaab1fcd2014-08-27 11:21:45 -050078 if ce.Type == eo.Type {
Jon Perritt5eb55b12014-08-18 14:48:23 -050079 eps = ce.Endpoints
80 }
81 }
82 }
83
Jon Perritt5eb55b12014-08-18 14:48:23 -050084 var rep string
85 for _, ep := range eps {
Jon Perrittaab1fcd2014-08-27 11:21:45 -050086 if ep.Region == eo.Region {
87 switch eo.URLType {
Jon Perritt5eb55b12014-08-18 14:48:23 -050088 case "public":
89 rep = ep.PublicURL
90 case "private":
91 rep = ep.InternalURL
92 default:
93 rep = ep.PublicURL
94 }
95 }
96 }
97
Jon Perritte1ce2982014-08-19 22:25:08 -050098 if rep != "" {
99 client.Endpoint = rep
100 } else {
Jon Perrittaab1fcd2014-08-27 11:21:45 -0500101 return client, fmt.Errorf("No endpoint for given service type (%s) name (%s) and region (%s)", eo.Type, eo.Name, eo.Region)
Jon Perritte1ce2982014-08-19 22:25:08 -0500102 }
Jon Perritt5eb55b12014-08-18 14:48:23 -0500103
104 return client, nil
105}