blob: c2b344b5fb6a46e0476df15c93308ee479621675 [file] [log] [blame]
Jon Perritt5eb55b12014-08-18 14:48:23 -05001package identity
2
Jon Perritte1ce2982014-08-19 22:25:08 -05003import (
4 "fmt"
5)
6
Jon Perritt8cff5cf2014-08-19 15:44:39 -05007// Client contains information that defines a generic Openstack Client.
Jon Perritt5eb55b12014-08-18 14:48:23 -05008type Client struct {
Jon Perritt8cff5cf2014-08-19 15:44:39 -05009 // Endpoint is the URL against which to authenticate.
10 Endpoint string
11 // Authority holds the results of authenticating against the Endpoint.
Jon Perritt5eb55b12014-08-18 14:48:23 -050012 Authority AuthResults
Jon Perritt8cff5cf2014-08-19 15:44:39 -050013 // Options holds the authentication options. Useful for auto-reauthentication.
14 Options AuthOptions
Jon Perritt5eb55b12014-08-18 14:48:23 -050015}
16
Jon Perritt6e898782014-08-19 15:58:11 -050017// EndpointOpts contains options for finding an endpoint for an Openstack Client.
18type EndpointOpts struct {
Jon Perritt8cff5cf2014-08-19 15:44:39 -050019 // Type is the service type for the client (e.g., "compute", "object-store").
20 // Type is a required field.
21 Type string
22 // Name is the service name for the client (e.g., "nova").
23 // Name is not a required field, but it is used if present. Services can have the
24 // same Type but different Name, which is one example of when both Type and Name are needed.
25 Name string
26 // Region is the region in which the service resides.
Jon Perritt8cff5cf2014-08-19 15:44:39 -050027 Region string
28 // URLType is they type of endpoint to be returned (e.g., "public", "private").
29 // URLType is not required, and defaults to "public".
Jon Perritt5eb55b12014-08-18 14:48:23 -050030 URLType string
31}
32
Jon Perritt8cff5cf2014-08-19 15:44:39 -050033// NewClient returns a generic Openstack Client of type identity.Client. This is a helper function
34// to create a client for the various Openstack services.
35// Example (error checking omitted for brevity):
36// ao, err := utils.AuthOptions()
Jon Perritt6e898782014-08-19 15:58:11 -050037// c, err := ao.NewClient(identity.EndpointOpts{
Jon Perritt8cff5cf2014-08-19 15:44:39 -050038// Type: "compute",
39// Name: "nova",
40// })
41// serversClient := servers.NewClient(c.Endpoint, c.Authority, c.Options)
Jon Perritt6e898782014-08-19 15:58:11 -050042func (ao AuthOptions) NewClient(opts EndpointOpts) (Client, error) {
Jon Perritt5eb55b12014-08-18 14:48:23 -050043 client := Client{
44 Options: ao,
45 }
46
47 ar, err := Authenticate(ao)
48 if err != nil {
49 return client, err
50 }
51
52 client.Authority = ar
53
54 sc, err := GetServiceCatalog(ar)
55 if err != nil {
56 return client, err
57 }
58
59 ces, err := sc.CatalogEntries()
60 if err != nil {
61 return client, err
62 }
63
64 var eps []Endpoint
65
66 if opts.Name != "" {
67 for _, ce := range ces {
68 if ce.Type == opts.Type && ce.Name == opts.Name {
69 eps = ce.Endpoints
70 }
71 }
72 } else {
73 for _, ce := range ces {
74 if ce.Type == opts.Type {
75 eps = ce.Endpoints
76 }
77 }
78 }
79
Jon Perritt5eb55b12014-08-18 14:48:23 -050080 var rep string
81 for _, ep := range eps {
Jon Perritta8c3b812014-08-19 22:02:31 -050082 if ep.Region == opts.Region {
Jon Perritt5eb55b12014-08-18 14:48:23 -050083 switch opts.URLType {
84 case "public":
85 rep = ep.PublicURL
86 case "private":
87 rep = ep.InternalURL
88 default:
89 rep = ep.PublicURL
90 }
91 }
92 }
93
Jon Perritte1ce2982014-08-19 22:25:08 -050094 if rep != "" {
95 client.Endpoint = rep
96 } else {
97 return client, fmt.Errorf("No endpoint for given service type (%s) name (%s) and region (%s)", opts.Type, opts.Name, opts.Region)
98 }
Jon Perritt5eb55b12014-08-18 14:48:23 -050099
100 return client, nil
101}