blob: a990049e77bb8950dead866e66d747446819f26d [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.
97func List(client *gophercloud.ServiceClient, opts ListOpts) (*EndpointList, error) {
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
112 u := getListURL(client) + utils.BuildQuery(q)
113
Ash Wilson8df23c82014-09-05 14:18:20 -0400114 var respBody EndpointList
Ash Wilson32c0e8d2014-09-04 10:53:08 -0400115 _, err := perigee.Request("GET", u, perigee.Options{
116 MoreHeaders: client.Provider.AuthenticatedHeaders(),
117 Results: &respBody,
118 OkCodes: []int{200},
119 })
120 if err != nil {
121 return nil, err
122 }
123
Ash Wilson8df23c82014-09-05 14:18:20 -0400124 return &respBody, nil
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400125}
126
127// Update changes an existing endpoint with new data.
Ash Wilsonf04a74c2014-09-04 11:16:20 -0400128// All fields are optional in the provided EndpointOpts.
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400129func Update(client *gophercloud.ServiceClient, endpointID string, opts EndpointOpts) (*Endpoint, error) {
Ash Wilsonf04a74c2014-09-04 11:16:20 -0400130 type endpoint struct {
131 Interface *string `json:"interface,omitempty"`
132 Name *string `json:"name,omitempty"`
133 Region *string `json:"region,omitempty"`
134 URL *string `json:"url,omitempty"`
135 ServiceID *string `json:"service_id,omitempty"`
136 }
137
138 type request struct {
139 Endpoint endpoint `json:"endpoint"`
140 }
141
142 type response struct {
143 Endpoint Endpoint `json:"endpoint"`
144 }
145
146 reqBody := request{Endpoint: endpoint{}}
Ash Wilsonefac18b2014-09-10 14:44:42 -0400147 reqBody.Endpoint.Interface = maybeString(string(opts.Availability))
Ash Wilsonf04a74c2014-09-04 11:16:20 -0400148 reqBody.Endpoint.Name = maybeString(opts.Name)
149 reqBody.Endpoint.Region = maybeString(opts.Region)
150 reqBody.Endpoint.URL = maybeString(opts.URL)
151 reqBody.Endpoint.ServiceID = maybeString(opts.ServiceID)
152
153 var respBody response
154 _, err := perigee.Request("PATCH", getEndpointURL(client, endpointID), perigee.Options{
155 MoreHeaders: client.Provider.AuthenticatedHeaders(),
156 ReqBody: &reqBody,
157 Results: &respBody,
158 OkCodes: []int{200},
159 })
160 if err != nil {
161 return nil, err
162 }
163
164 return &respBody.Endpoint, nil
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400165}
166
167// Delete removes an endpoint from the service catalog.
168func Delete(client *gophercloud.ServiceClient, endpointID string) error {
Ash Wilson70db2ab2014-09-04 11:18:32 -0400169 _, err := perigee.Request("DELETE", getEndpointURL(client, endpointID), perigee.Options{
170 MoreHeaders: client.Provider.AuthenticatedHeaders(),
171 OkCodes: []int{204},
172 })
173 return err
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400174}