blob: fbbdf0768056954767e07427bcc1373885b83425 [file] [log] [blame]
Ash Wilson0a997f82014-09-03 15:50:52 -04001package endpoints
Ash Wilsonbdfc3302014-09-04 10:16:28 -04002
3import (
Ash Wilson6269f252014-09-12 14:33:56 -04004 "net/http"
Ash Wilson989ce542014-09-04 10:52:49 -04005 "strconv"
Ash Wilsonbdfc3302014-09-04 10:16:28 -04006
Ash Wilson989ce542014-09-04 10:52:49 -04007 "github.com/racker/perigee"
Ash Wilsonbdfc3302014-09-04 10:16:28 -04008 "github.com/rackspace/gophercloud"
Ash Wilson989ce542014-09-04 10:52:49 -04009 "github.com/rackspace/gophercloud/openstack/utils"
Ash Wilsonbdfc3302014-09-04 10:16:28 -040010)
11
Ash Wilsonf04a74c2014-09-04 11:16:20 -040012// maybeString returns nil for empty strings and nil for empty.
13func maybeString(original string) *string {
14 if original != "" {
15 return &original
16 }
17 return nil
18}
19
Ash Wilsonbdfc3302014-09-04 10:16:28 -040020// EndpointOpts contains the subset of Endpoint attributes that should be used to create or update an Endpoint.
21type EndpointOpts struct {
Ash Wilsonefac18b2014-09-10 14:44:42 -040022 Availability gophercloud.Availability
23 Name string
24 Region string
25 URL string
26 ServiceID string
Ash Wilsonbdfc3302014-09-04 10:16:28 -040027}
28
29// Create inserts a new Endpoint into the service catalog.
Ash Wilson989ce542014-09-04 10:52:49 -040030// Within EndpointOpts, Region may be omitted by being left as "", but all other fields are required.
Ash Wilsonbdfc3302014-09-04 10:16:28 -040031func Create(client *gophercloud.ServiceClient, opts EndpointOpts) (*Endpoint, error) {
Ash Wilson989ce542014-09-04 10:52:49 -040032 // Redefined so that Region can be re-typed as a *string, which can be omitted from the JSON output.
33 type endpoint struct {
34 Interface string `json:"interface"`
35 Name string `json:"name"`
36 Region *string `json:"region,omitempty"`
37 URL string `json:"url"`
38 ServiceID string `json:"service_id"`
39 }
40
41 type request struct {
42 Endpoint endpoint `json:"endpoint"`
43 }
44
45 type response struct {
46 Endpoint Endpoint `json:"endpoint"`
47 }
48
49 // Ensure that EndpointOpts is fully populated.
Ash Wilsonefac18b2014-09-10 14:44:42 -040050 if opts.Availability == "" {
51 return nil, ErrAvailabilityRequired
Ash Wilson989ce542014-09-04 10:52:49 -040052 }
53 if opts.Name == "" {
54 return nil, ErrNameRequired
55 }
56 if opts.URL == "" {
57 return nil, ErrURLRequired
58 }
59 if opts.ServiceID == "" {
60 return nil, ErrServiceIDRequired
61 }
62
63 // Populate the request body.
64 reqBody := request{
65 Endpoint: endpoint{
Ash Wilsonefac18b2014-09-10 14:44:42 -040066 Interface: string(opts.Availability),
Ash Wilson989ce542014-09-04 10:52:49 -040067 Name: opts.Name,
68 URL: opts.URL,
69 ServiceID: opts.ServiceID,
70 },
71 }
Ash Wilsonf04a74c2014-09-04 11:16:20 -040072 reqBody.Endpoint.Region = maybeString(opts.Region)
Ash Wilson989ce542014-09-04 10:52:49 -040073
74 var respBody response
75 _, err := perigee.Request("POST", getListURL(client), perigee.Options{
76 MoreHeaders: client.Provider.AuthenticatedHeaders(),
77 ReqBody: &reqBody,
78 Results: &respBody,
79 OkCodes: []int{201},
80 })
81 if err != nil {
82 return nil, err
83 }
84
85 return &respBody.Endpoint, nil
Ash Wilsonbdfc3302014-09-04 10:16:28 -040086}
87
88// ListOpts allows finer control over the the endpoints returned by a List call.
89// All fields are optional.
90type ListOpts struct {
Ash Wilsonefac18b2014-09-10 14:44:42 -040091 Availability gophercloud.Availability
92 ServiceID string
93 Page int
94 PerPage int
Ash Wilsonbdfc3302014-09-04 10:16:28 -040095}
96
97// List enumerates endpoints in a paginated collection, optionally filtered by ListOpts criteria.
Ash Wilson6269f252014-09-12 14:33:56 -040098func List(client *gophercloud.ServiceClient, opts ListOpts) gophercloud.Pager {
Ash Wilson32c0e8d2014-09-04 10:53:08 -040099 q := make(map[string]string)
Ash Wilsonefac18b2014-09-10 14:44:42 -0400100 if opts.Availability != "" {
101 q["interface"] = string(opts.Availability)
Ash Wilson32c0e8d2014-09-04 10:53:08 -0400102 }
103 if opts.ServiceID != "" {
104 q["service_id"] = opts.ServiceID
105 }
106 if opts.Page != 0 {
107 q["page"] = strconv.Itoa(opts.Page)
108 }
109 if opts.PerPage != 0 {
110 q["per_page"] = strconv.Itoa(opts.Page)
111 }
112
113 u := getListURL(client) + utils.BuildQuery(q)
Ash Wilson6269f252014-09-12 14:33:56 -0400114 return gophercloud.NewLinkedPager(u, func(next string) (http.Response, error) {
115 r, err := perigee.Request("GET", u, perigee.Options{
116 MoreHeaders: client.Provider.AuthenticatedHeaders(),
117 OkCodes: []int{200},
118 })
119 if err != nil {
120 return http.Response{}, err
121 }
122 return r.HttpResponse, nil
Ash Wilson32c0e8d2014-09-04 10:53:08 -0400123 })
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400124}
125
126// Update changes an existing endpoint with new data.
Ash Wilsonf04a74c2014-09-04 11:16:20 -0400127// All fields are optional in the provided EndpointOpts.
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400128func Update(client *gophercloud.ServiceClient, endpointID string, opts EndpointOpts) (*Endpoint, error) {
Ash Wilsonf04a74c2014-09-04 11:16:20 -0400129 type endpoint struct {
130 Interface *string `json:"interface,omitempty"`
131 Name *string `json:"name,omitempty"`
132 Region *string `json:"region,omitempty"`
133 URL *string `json:"url,omitempty"`
134 ServiceID *string `json:"service_id,omitempty"`
135 }
136
137 type request struct {
138 Endpoint endpoint `json:"endpoint"`
139 }
140
141 type response struct {
142 Endpoint Endpoint `json:"endpoint"`
143 }
144
145 reqBody := request{Endpoint: endpoint{}}
Ash Wilsonefac18b2014-09-10 14:44:42 -0400146 reqBody.Endpoint.Interface = maybeString(string(opts.Availability))
Ash Wilsonf04a74c2014-09-04 11:16:20 -0400147 reqBody.Endpoint.Name = maybeString(opts.Name)
148 reqBody.Endpoint.Region = maybeString(opts.Region)
149 reqBody.Endpoint.URL = maybeString(opts.URL)
150 reqBody.Endpoint.ServiceID = maybeString(opts.ServiceID)
151
152 var respBody response
153 _, err := perigee.Request("PATCH", getEndpointURL(client, endpointID), perigee.Options{
154 MoreHeaders: client.Provider.AuthenticatedHeaders(),
155 ReqBody: &reqBody,
156 Results: &respBody,
157 OkCodes: []int{200},
158 })
159 if err != nil {
160 return nil, err
161 }
162
163 return &respBody.Endpoint, nil
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400164}
165
166// Delete removes an endpoint from the service catalog.
167func Delete(client *gophercloud.ServiceClient, endpointID string) error {
Ash Wilson70db2ab2014-09-04 11:18:32 -0400168 _, err := perigee.Request("DELETE", getEndpointURL(client, endpointID), perigee.Options{
169 MoreHeaders: client.Provider.AuthenticatedHeaders(),
170 OkCodes: []int{204},
171 })
172 return err
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400173}