blob: 6dda38f4c3b28a44f2019e468f5b230bb8dc90a4 [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
Jon Perritt5f4b5c22014-08-27 11:44:07 -050050 ar, err := identity.Authenticate(ao)
Jon Perritt5eb55b12014-08-18 14:48:23 -050051 if err != nil {
52 return client, err
53 }
54
55 client.Authority = ar
56
Jon Perritt5f4b5c22014-08-27 11:44:07 -050057 sc, err := identity.GetServiceCatalog(ar)
Jon Perritt5eb55b12014-08-18 14:48:23 -050058 if err != nil {
59 return client, err
60 }
61
62 ces, err := sc.CatalogEntries()
63 if err != nil {
64 return client, err
65 }
66
Jon Perritt5f4b5c22014-08-27 11:44:07 -050067 var eps []identity.Endpoint
Jon Perritt5eb55b12014-08-18 14:48:23 -050068
Jon Perrittaab1fcd2014-08-27 11:21:45 -050069 if eo.Name != "" {
Jon Perritt5eb55b12014-08-18 14:48:23 -050070 for _, ce := range ces {
Jon Perrittaab1fcd2014-08-27 11:21:45 -050071 if ce.Type == eo.Type && ce.Name == eo.Name {
Jon Perritt5eb55b12014-08-18 14:48:23 -050072 eps = ce.Endpoints
73 }
74 }
75 } else {
76 for _, ce := range ces {
Jon Perrittaab1fcd2014-08-27 11:21:45 -050077 if ce.Type == eo.Type {
Jon Perritt5eb55b12014-08-18 14:48:23 -050078 eps = ce.Endpoints
79 }
80 }
81 }
82
Jon Perritt5eb55b12014-08-18 14:48:23 -050083 var rep string
84 for _, ep := range eps {
Jon Perrittaab1fcd2014-08-27 11:21:45 -050085 if ep.Region == eo.Region {
86 switch eo.URLType {
Jon Perritt5eb55b12014-08-18 14:48:23 -050087 case "public":
88 rep = ep.PublicURL
89 case "private":
90 rep = ep.InternalURL
91 default:
92 rep = ep.PublicURL
93 }
94 }
95 }
96
Jon Perritte1ce2982014-08-19 22:25:08 -050097 if rep != "" {
98 client.Endpoint = rep
99 } else {
Jon Perrittaab1fcd2014-08-27 11:21:45 -0500100 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 -0500101 }
Jon Perritt5eb55b12014-08-18 14:48:23 -0500102
103 return client, nil
104}