blob: 186d0fcba62991fc84dacc0a6a849961eb308c74 [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 Wilson3c8cc772014-09-16 11:40:49 -04009 "github.com/rackspace/gophercloud/pagination"
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 Wilson3c8cc772014-09-16 11:40:49 -040098func List(client *gophercloud.ServiceClient, opts ListOpts) pagination.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
Ash Wilson3c8cc772014-09-16 11:40:49 -0400113 createPage := func(r pagination.LastHTTPResponse) pagination.Page {
Ash Wilsonfc55c822014-09-25 13:18:16 -0400114 return EndpointPage{pagination.LinkedPageBase{LastHTTPResponse: r}}
Ash Wilsonab6be612014-09-15 15:51:22 -0400115 }
116
Ash Wilson32c0e8d2014-09-04 10:53:08 -0400117 u := getListURL(client) + utils.BuildQuery(q)
Ash Wilsoncd95a0c2014-09-16 13:07:31 -0400118 return pagination.NewPager(client, u, createPage)
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400119}
120
121// Update changes an existing endpoint with new data.
Ash Wilsonf04a74c2014-09-04 11:16:20 -0400122// All fields are optional in the provided EndpointOpts.
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400123func Update(client *gophercloud.ServiceClient, endpointID string, opts EndpointOpts) (*Endpoint, error) {
Ash Wilsonf04a74c2014-09-04 11:16:20 -0400124 type endpoint struct {
125 Interface *string `json:"interface,omitempty"`
126 Name *string `json:"name,omitempty"`
127 Region *string `json:"region,omitempty"`
128 URL *string `json:"url,omitempty"`
129 ServiceID *string `json:"service_id,omitempty"`
130 }
131
132 type request struct {
133 Endpoint endpoint `json:"endpoint"`
134 }
135
136 type response struct {
137 Endpoint Endpoint `json:"endpoint"`
138 }
139
140 reqBody := request{Endpoint: endpoint{}}
Ash Wilsonefac18b2014-09-10 14:44:42 -0400141 reqBody.Endpoint.Interface = maybeString(string(opts.Availability))
Ash Wilsonf04a74c2014-09-04 11:16:20 -0400142 reqBody.Endpoint.Name = maybeString(opts.Name)
143 reqBody.Endpoint.Region = maybeString(opts.Region)
144 reqBody.Endpoint.URL = maybeString(opts.URL)
145 reqBody.Endpoint.ServiceID = maybeString(opts.ServiceID)
146
147 var respBody response
148 _, err := perigee.Request("PATCH", getEndpointURL(client, endpointID), perigee.Options{
149 MoreHeaders: client.Provider.AuthenticatedHeaders(),
150 ReqBody: &reqBody,
151 Results: &respBody,
152 OkCodes: []int{200},
153 })
154 if err != nil {
155 return nil, err
156 }
157
158 return &respBody.Endpoint, nil
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400159}
160
161// Delete removes an endpoint from the service catalog.
162func Delete(client *gophercloud.ServiceClient, endpointID string) error {
Ash Wilson70db2ab2014-09-04 11:18:32 -0400163 _, err := perigee.Request("DELETE", getEndpointURL(client, endpointID), perigee.Options{
164 MoreHeaders: client.Provider.AuthenticatedHeaders(),
165 OkCodes: []int{204},
166 })
167 return err
Ash Wilsonbdfc3302014-09-04 10:16:28 -0400168}