blob: bf6040629ac687d6162b566bb2972cc912385675 [file] [log] [blame]
Ash Wilson0a997f82014-09-03 15:50:52 -04001package endpoints
Ash Wilsonbdfc3302014-09-04 10:16:28 -04002
3import (
Ash Wilson989ce542014-09-04 10:52:49 -04004 "strconv"
Ash Wilsonbdfc3302014-09-04 10:16:28 -04005
Ash Wilson989ce542014-09-04 10:52:49 -04006 "github.com/racker/perigee"
Ash Wilsonbdfc3302014-09-04 10:16:28 -04007 "github.com/rackspace/gophercloud"
Ash Wilson989ce542014-09-04 10:52:49 -04008 "github.com/rackspace/gophercloud/openstack/utils"
Ash Wilsonbdfc3302014-09-04 10:16:28 -04009)
10
Ash Wilsonf04a74c2014-09-04 11:16:20 -040011// maybeString returns nil for empty strings and nil for empty.
12func maybeString(original string) *string {
13 if original != "" {
14 return &original
15 }
16 return nil
17}
18
Ash Wilsonbdfc3302014-09-04 10:16:28 -040019// EndpointOpts contains the subset of Endpoint attributes that should be used to create or update an Endpoint.
20type EndpointOpts struct {
Ash Wilsonefac18b2014-09-10 14:44:42 -040021 Availability gophercloud.Availability
22 Name string
23 Region string
24 URL string
25 ServiceID string
Ash Wilsonbdfc3302014-09-04 10:16:28 -040026}
27
28// Create inserts a new Endpoint into the service catalog.
Ash Wilson989ce542014-09-04 10:52:49 -040029// Within EndpointOpts, Region may be omitted by being left as "", but all other fields are required.
Ash Wilsonbdfc3302014-09-04 10:16:28 -040030func Create(client *gophercloud.ServiceClient, opts EndpointOpts) (*Endpoint, error) {
Ash Wilson989ce542014-09-04 10:52:49 -040031 // Redefined so that Region can be re-typed as a *string, which can be omitted from the JSON output.
32 type endpoint struct {
33 Interface string `json:"interface"`
34 Name string `json:"name"`
35 Region *string `json:"region,omitempty"`
36 URL string `json:"url"`
37 ServiceID string `json:"service_id"`
38 }
39
40 type request struct {
41 Endpoint endpoint `json:"endpoint"`
42 }
43
44 type response struct {
45 Endpoint Endpoint `json:"endpoint"`
46 }
47
48 // Ensure that EndpointOpts is fully populated.
Ash Wilsonefac18b2014-09-10 14:44:42 -040049 if opts.Availability == "" {
50 return nil, ErrAvailabilityRequired
Ash Wilson989ce542014-09-04 10:52:49 -040051 }
52 if opts.Name == "" {
53 return nil, ErrNameRequired
54 }
55 if opts.URL == "" {
56 return nil, ErrURLRequired
57 }
58 if opts.ServiceID == "" {
59 return nil, ErrServiceIDRequired
60 }
61
62 // Populate the request body.
63 reqBody := request{
64 Endpoint: endpoint{
Ash Wilsonefac18b2014-09-10 14:44:42 -040065 Interface: string(opts.Availability),
Ash Wilson989ce542014-09-04 10:52:49 -040066 Name: opts.Name,
67 URL: opts.URL,
68 ServiceID: opts.ServiceID,
69 },
70 }
Ash Wilsonf04a74c2014-09-04 11:16:20 -040071 reqBody.Endpoint.Region = maybeString(opts.Region)
Ash Wilson989ce542014-09-04 10:52:49 -040072
73 var respBody response
74 _, err := perigee.Request("POST", getListURL(client), perigee.Options{
75 MoreHeaders: client.Provider.AuthenticatedHeaders(),
76 ReqBody: &reqBody,
77 Results: &respBody,
78 OkCodes: []int{201},
79 })
80 if err != nil {
81 return nil, err
82 }
83
84 return &respBody.Endpoint, nil
Ash Wilsonbdfc3302014-09-04 10:16:28 -040085}
86
87// ListOpts allows finer control over the the endpoints returned by a List call.
88// All fields are optional.
89type ListOpts struct {
Ash Wilsonefac18b2014-09-10 14:44:42 -040090 Availability gophercloud.Availability
91 ServiceID string
92 Page int
93 PerPage int
Ash Wilsonbdfc3302014-09-04 10:16:28 -040094}
95
96// List enumerates endpoints in a paginated collection, optionally filtered by ListOpts criteria.
Ash Wilson6269f252014-09-12 14:33:56 -040097func List(client *gophercloud.ServiceClient, opts ListOpts) gophercloud.Pager {
Ash Wilson32c0e8d2014-09-04 10:53:08 -040098 q := make(map[string]string)
Ash Wilsonefac18b2014-09-10 14:44:42 -040099 if opts.Availability != "" {
100 q["interface"] = string(opts.Availability)
Ash Wilson32c0e8d2014-09-04 10:53:08 -0400101 }
102 if opts.ServiceID != "" {
103 q["service_id"] = opts.ServiceID
104 }
105 if opts.Page != 0 {
106 q["page"] = strconv.Itoa(opts.Page)
107 }
108 if opts.PerPage != 0 {
109 q["per_page"] = strconv.Itoa(opts.Page)
110 }
111
Ash Wilsonab6be612014-09-15 15:51:22 -0400112 countPage := func(p gophercloud.Page) (int, error) {
113 es, err := ExtractEndpoints(p)
114 if err != nil {
115 return 0, err
116 }
117 return len(es), nil
118 }
119
Ash Wilson32c0e8d2014-09-04 10:53:08 -0400120 u := getListURL(client) + utils.BuildQuery(q)
Ash Wilsonab6be612014-09-15 15:51:22 -0400121 return gophercloud.NewLinkedPager(client, u, countPage)
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400122}
123
124// Update changes an existing endpoint with new data.
Ash Wilsonf04a74c2014-09-04 11:16:20 -0400125// All fields are optional in the provided EndpointOpts.
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400126func Update(client *gophercloud.ServiceClient, endpointID string, opts EndpointOpts) (*Endpoint, error) {
Ash Wilsonf04a74c2014-09-04 11:16:20 -0400127 type endpoint struct {
128 Interface *string `json:"interface,omitempty"`
129 Name *string `json:"name,omitempty"`
130 Region *string `json:"region,omitempty"`
131 URL *string `json:"url,omitempty"`
132 ServiceID *string `json:"service_id,omitempty"`
133 }
134
135 type request struct {
136 Endpoint endpoint `json:"endpoint"`
137 }
138
139 type response struct {
140 Endpoint Endpoint `json:"endpoint"`
141 }
142
143 reqBody := request{Endpoint: endpoint{}}
Ash Wilsonefac18b2014-09-10 14:44:42 -0400144 reqBody.Endpoint.Interface = maybeString(string(opts.Availability))
Ash Wilsonf04a74c2014-09-04 11:16:20 -0400145 reqBody.Endpoint.Name = maybeString(opts.Name)
146 reqBody.Endpoint.Region = maybeString(opts.Region)
147 reqBody.Endpoint.URL = maybeString(opts.URL)
148 reqBody.Endpoint.ServiceID = maybeString(opts.ServiceID)
149
150 var respBody response
151 _, err := perigee.Request("PATCH", getEndpointURL(client, endpointID), perigee.Options{
152 MoreHeaders: client.Provider.AuthenticatedHeaders(),
153 ReqBody: &reqBody,
154 Results: &respBody,
155 OkCodes: []int{200},
156 })
157 if err != nil {
158 return nil, err
159 }
160
161 return &respBody.Endpoint, nil
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400162}
163
164// Delete removes an endpoint from the service catalog.
165func Delete(client *gophercloud.ServiceClient, endpointID string) error {
Ash Wilson70db2ab2014-09-04 11:18:32 -0400166 _, err := perigee.Request("DELETE", getEndpointURL(client, endpointID), perigee.Options{
167 MoreHeaders: client.Provider.AuthenticatedHeaders(),
168 OkCodes: []int{204},
169 })
170 return err
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400171}