blob: d1f0359b67920209c8eb332b97b9e4869bbf7bec [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"
Jon Perritt5f4b5c22014-08-27 11:44:07 -05005 identity "github.com/rackspace/gophercloud/openstack/identity/v2"
Jon Perritte1ce2982014-08-19 22:25:08 -05006)
7
Jon Perritt8cff5cf2014-08-19 15:44:39 -05008// Client contains information that defines a generic Openstack Client.
Jon Perritt5eb55b12014-08-18 14:48:23 -05009type Client struct {
Jon Perritt8cff5cf2014-08-19 15:44:39 -050010 // Endpoint is the URL against which to authenticate.
11 Endpoint string
12 // Authority holds the results of authenticating against the Endpoint.
Jon Perritt5f4b5c22014-08-27 11:44:07 -050013 Authority identity.AuthResults
Jon Perritt8cff5cf2014-08-19 15:44:39 -050014 // Options holds the authentication options. Useful for auto-reauthentication.
Jon Perritt5f4b5c22014-08-27 11:44:07 -050015 Options identity.AuthOptions
Jon Perritt5eb55b12014-08-18 14:48:23 -050016}
17
Jon Perritt6e898782014-08-19 15:58:11 -050018// EndpointOpts contains options for finding an endpoint for an Openstack Client.
19type EndpointOpts struct {
Jon Perritt8cff5cf2014-08-19 15:44:39 -050020 // Type is the service type for the client (e.g., "compute", "object-store").
21 // Type is a required field.
22 Type string
23 // Name is the service name for the client (e.g., "nova").
24 // Name is not a required field, but it is used if present. Services can have the
25 // same Type but different Name, which is one example of when both Type and Name are needed.
26 Name string
27 // Region is the region in which the service resides.
Jon Perritt8cff5cf2014-08-19 15:44:39 -050028 Region string
29 // URLType is they type of endpoint to be returned (e.g., "public", "private").
30 // URLType is not required, and defaults to "public".
Jon Perritt5eb55b12014-08-18 14:48:23 -050031 URLType string
32}
33
Jon Perritt8cff5cf2014-08-19 15:44:39 -050034// NewClient returns a generic Openstack Client of type identity.Client. This is a helper function
35// to create a client for the various Openstack services.
36// Example (error checking omitted for brevity):
37// ao, err := utils.AuthOptions()
Jon Perrittaab1fcd2014-08-27 11:21:45 -050038// c, err := identity.NewClient(ao, identity.EndpointOpts{
Jon Perritt8cff5cf2014-08-19 15:44:39 -050039// Type: "compute",
40// Name: "nova",
41// })
42// serversClient := servers.NewClient(c.Endpoint, c.Authority, c.Options)
Jon Perritt5f4b5c22014-08-27 11:44:07 -050043func NewClient(ao identity.AuthOptions, eo EndpointOpts) (Client, error) {
Jon Perritt5eb55b12014-08-18 14:48:23 -050044 client := Client{
45 Options: ao,
46 }
47
Jon Perritt5f4b5c22014-08-27 11:44:07 -050048 ar, err := identity.Authenticate(ao)
Jon Perritt5eb55b12014-08-18 14:48:23 -050049 if err != nil {
50 return client, err
51 }
52
53 client.Authority = ar
54
Jon Perritt5f4b5c22014-08-27 11:44:07 -050055 sc, err := identity.GetServiceCatalog(ar)
Jon Perritt5eb55b12014-08-18 14:48:23 -050056 if err != nil {
57 return client, err
58 }
59
60 ces, err := sc.CatalogEntries()
61 if err != nil {
62 return client, err
63 }
64
Jon Perritt5f4b5c22014-08-27 11:44:07 -050065 var eps []identity.Endpoint
Jon Perritt5eb55b12014-08-18 14:48:23 -050066
Jon Perrittaab1fcd2014-08-27 11:21:45 -050067 if eo.Name != "" {
Jon Perritt5eb55b12014-08-18 14:48:23 -050068 for _, ce := range ces {
Jon Perrittaab1fcd2014-08-27 11:21:45 -050069 if ce.Type == eo.Type && ce.Name == eo.Name {
Jon Perritt5eb55b12014-08-18 14:48:23 -050070 eps = ce.Endpoints
71 }
72 }
73 } else {
74 for _, ce := range ces {
Jon Perrittaab1fcd2014-08-27 11:21:45 -050075 if ce.Type == eo.Type {
Jon Perritt5eb55b12014-08-18 14:48:23 -050076 eps = ce.Endpoints
77 }
78 }
79 }
80
Jon Perritt5eb55b12014-08-18 14:48:23 -050081 var rep string
82 for _, ep := range eps {
Jon Perrittaab1fcd2014-08-27 11:21:45 -050083 if ep.Region == eo.Region {
84 switch eo.URLType {
Jon Perritt5eb55b12014-08-18 14:48:23 -050085 case "public":
86 rep = ep.PublicURL
87 case "private":
88 rep = ep.InternalURL
89 default:
90 rep = ep.PublicURL
91 }
92 }
93 }
94
Jon Perritte1ce2982014-08-19 22:25:08 -050095 if rep != "" {
96 client.Endpoint = rep
97 } else {
Jon Perrittaab1fcd2014-08-27 11:21:45 -050098 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 -050099 }
Jon Perritt5eb55b12014-08-18 14:48:23 -0500100
101 return client, nil
102}