blob: 78c96abfaa3b96f9a2a67cf4bb60c99d433190bc [file] [log] [blame]
Jamie Hannaford548d3402014-09-18 15:50:08 +02001package ports
2
3import (
4 "strconv"
5
Jamie Hannaforda311f182014-09-19 11:19:10 +02006 "github.com/racker/perigee"
Jamie Hannaford548d3402014-09-18 15:50:08 +02007 "github.com/rackspace/gophercloud"
8 "github.com/rackspace/gophercloud/openstack/utils"
9 "github.com/rackspace/gophercloud/pagination"
10)
11
Jamie Hannaford686c4962014-09-23 10:46:20 +020012func maybeString(original string) *string {
13 if original != "" {
14 return &original
15 }
16 return nil
17}
18
19// ListOpts allows the filtering and sorting of paginated collections through
20// the API. Filtering is achieved by passing in struct field values that map to
21// the port attributes you want to see returned. SortKey allows you to sort
22// by a particular port attribute. SortDir sets the direction, and is either
23// `asc' or `desc'. Marker and Limit are used for pagination.
Jamie Hannaford548d3402014-09-18 15:50:08 +020024type ListOpts struct {
25 Status string
26 Name string
27 AdminStateUp *bool
28 NetworkID string
29 TenantID string
30 DeviceOwner string
31 MACAddress string
32 ID string
Jamie Hannaford548d3402014-09-18 15:50:08 +020033 DeviceID string
34 BindingHostID string
35 BindingVIFType string
36 BindingVNICType string
37 Limit int
Jamie Hannaford686c4962014-09-23 10:46:20 +020038 Marker string
Jamie Hannafordd0f090c2014-09-22 13:44:34 +020039 SortKey string
40 SortDir string
Jamie Hannaford548d3402014-09-18 15:50:08 +020041}
42
Jamie Hannaford686c4962014-09-23 10:46:20 +020043// List returns a Pager which allows you to iterate over a collection of
44// ports. It accepts a ListOpts struct, which allows you to filter and sort
45// the returned collection for greater efficiency.
46//
47// Default policy settings return only those ports that are owned by the tenant
48// who submits the request, unless the request is submitted by an user with
49// administrative rights.
Jamie Hannaford548d3402014-09-18 15:50:08 +020050func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
51 // Build query parameters
52 q := make(map[string]string)
53 if opts.Status != "" {
54 q["status"] = opts.Status
55 }
56 if opts.Name != "" {
57 q["name"] = opts.Name
58 }
59 if opts.AdminStateUp != nil {
60 q["admin_state_up"] = strconv.FormatBool(*opts.AdminStateUp)
61 }
62 if opts.NetworkID != "" {
63 q["network_id"] = opts.NetworkID
64 }
65 if opts.TenantID != "" {
66 q["tenant_id"] = opts.TenantID
67 }
68 if opts.DeviceOwner != "" {
69 q["device_owner"] = opts.DeviceOwner
70 }
71 if opts.MACAddress != "" {
72 q["mac_address"] = opts.MACAddress
73 }
74 if opts.ID != "" {
75 q["id"] = opts.ID
76 }
Jamie Hannaford548d3402014-09-18 15:50:08 +020077 if opts.DeviceID != "" {
78 q["device_id"] = opts.DeviceID
79 }
80 if opts.BindingHostID != "" {
81 q["binding:host_id"] = opts.BindingHostID
82 }
83 if opts.BindingVIFType != "" {
84 q["binding:vif_type"] = opts.BindingVIFType
85 }
86 if opts.BindingVNICType != "" {
87 q["binding:vnic_type"] = opts.BindingVNICType
88 }
89 if opts.NetworkID != "" {
90 q["network_id"] = opts.NetworkID
91 }
92 if opts.Limit != 0 {
93 q["limit"] = strconv.Itoa(opts.Limit)
94 }
Jamie Hannaford686c4962014-09-23 10:46:20 +020095 if opts.Marker != "" {
96 q["marker"] = opts.Marker
Jamie Hannaford548d3402014-09-18 15:50:08 +020097 }
Jamie Hannafordd0f090c2014-09-22 13:44:34 +020098 if opts.SortKey != "" {
99 q["sort_key"] = opts.SortKey
100 }
101 if opts.SortDir != "" {
102 q["sort_dir"] = opts.SortDir
103 }
Jamie Hannaford548d3402014-09-18 15:50:08 +0200104
Jamie Hannaford965ae702014-09-22 14:58:19 +0200105 u := listURL(c) + utils.BuildQuery(q)
Jamie Hannaford548d3402014-09-18 15:50:08 +0200106 return pagination.NewPager(c, u, func(r pagination.LastHTTPResponse) pagination.Page {
107 return PortPage{pagination.LinkedPageBase(r)}
108 })
109}
Jamie Hannaforda311f182014-09-19 11:19:10 +0200110
Jamie Hannaford686c4962014-09-23 10:46:20 +0200111// Get retrieves a specific port based on its unique ID.
Jamie Hannaforda311f182014-09-19 11:19:10 +0200112func Get(c *gophercloud.ServiceClient, id string) (*Port, error) {
113 var p Port
Jamie Hannaford965ae702014-09-22 14:58:19 +0200114 _, err := perigee.Request("GET", getURL(c, id), perigee.Options{
Jamie Hannaforda311f182014-09-19 11:19:10 +0200115 MoreHeaders: c.Provider.AuthenticatedHeaders(),
116 Results: &struct {
117 Port *Port `json:"port"`
118 }{&p},
119 OkCodes: []int{200},
120 })
121 if err != nil {
122 return nil, err
123 }
124 return &p, nil
125}
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200126
Jamie Hannaford686c4962014-09-23 10:46:20 +0200127// CreateOpts represents the attributes used when creating a new port.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200128type CreateOpts struct {
129 NetworkID string
130 Name string
131 AdminStateUp *bool
132 MACAddress string
133 FixedIPs interface{}
134 DeviceID string
135 DeviceOwner string
136 TenantID string
137 SecurityGroups []string
138}
139
Jamie Hannaford686c4962014-09-23 10:46:20 +0200140// Create accepts a CreateOpts struct and creates a new network using the values
141// provided. You must remember to provide a NetworkID value.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200142func Create(c *gophercloud.ServiceClient, opts CreateOpts) (*Port, error) {
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200143 type port struct {
Jamie Hannaford686c4962014-09-23 10:46:20 +0200144 NetworkID string `json:"network_id"`
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200145 Name *string `json:"name,omitempty"`
146 AdminStateUp *bool `json:"admin_state_up,omitempty"`
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200147 MACAddress *string `json:"mac_address,omitempty"`
148 FixedIPs interface{} `json:"fixed_ips,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200149 DeviceID *string `json:"device_id,omitempty"`
150 DeviceOwner *string `json:"device_owner,omitempty"`
151 TenantID *string `json:"tenant_id,omitempty"`
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200152 SecurityGroups []string `json:"security_groups,omitempty"`
153 }
154 type request struct {
155 Port port `json:"port"`
156 }
157
158 // Validate
159 if opts.NetworkID == "" {
Jamie Hannaford686c4962014-09-23 10:46:20 +0200160 return nil, errNetworkIDRequired
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200161 }
162
163 // Populate request body
164 reqBody := request{Port: port{
165 NetworkID: opts.NetworkID,
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200166 Name: maybeString(opts.Name),
167 AdminStateUp: opts.AdminStateUp,
168 TenantID: maybeString(opts.TenantID),
169 MACAddress: maybeString(opts.MACAddress),
Jamie Hannaford965ae702014-09-22 14:58:19 +0200170 DeviceID: maybeString(opts.DeviceID),
171 DeviceOwner: maybeString(opts.DeviceOwner),
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200172 }}
173
174 if opts.FixedIPs != nil {
175 reqBody.Port.FixedIPs = opts.FixedIPs
176 }
177
178 if opts.SecurityGroups != nil {
179 reqBody.Port.SecurityGroups = opts.SecurityGroups
180 }
181
182 // Response
183 type response struct {
184 Port *Port `json:"port"`
185 }
186 var res response
Jamie Hannaford965ae702014-09-22 14:58:19 +0200187 _, err := perigee.Request("POST", createURL(c), perigee.Options{
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200188 MoreHeaders: c.Provider.AuthenticatedHeaders(),
189 ReqBody: &reqBody,
190 Results: &res,
191 OkCodes: []int{201},
Jamie Hannaford2a0492a2014-09-22 12:02:11 +0200192 DumpReqJson: true,
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200193 })
194 if err != nil {
195 return nil, err
196 }
197
198 return res.Port, nil
199}
200
Jamie Hannaford686c4962014-09-23 10:46:20 +0200201// UpdateOpts represents the attributes used when updating an existing port.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200202type UpdateOpts struct {
203 Name string
204 AdminStateUp *bool
205 FixedIPs interface{}
206 DeviceID string
207 DeviceOwner string
208 SecurityGroups []string
209}
210
Jamie Hannaford686c4962014-09-23 10:46:20 +0200211// Update accepts a UpdateOpts struct and updates an existing port using the
212// values provided.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200213func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) (*Port, error) {
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200214 type port struct {
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200215 Name *string `json:"name,omitempty"`
216 AdminStateUp *bool `json:"admin_state_up,omitempty"`
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200217 FixedIPs interface{} `json:"fixed_ips,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200218 DeviceID *string `json:"device_id,omitempty"`
219 DeviceOwner *string `json:"device_owner,omitempty"`
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200220 SecurityGroups []string `json:"security_groups,omitempty"`
221 }
222 type request struct {
223 Port port `json:"port"`
224 }
225
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200226 // Populate request body
227 reqBody := request{Port: port{
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200228 Name: maybeString(opts.Name),
229 AdminStateUp: opts.AdminStateUp,
Jamie Hannaford965ae702014-09-22 14:58:19 +0200230 DeviceID: maybeString(opts.DeviceID),
231 DeviceOwner: maybeString(opts.DeviceOwner),
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200232 }}
233
234 if opts.FixedIPs != nil {
235 reqBody.Port.FixedIPs = opts.FixedIPs
236 }
237
238 if opts.SecurityGroups != nil {
239 reqBody.Port.SecurityGroups = opts.SecurityGroups
240 }
241
242 // Response
243 type response struct {
244 Port *Port `json:"port"`
245 }
246 var res response
Jamie Hannaford965ae702014-09-22 14:58:19 +0200247 _, err := perigee.Request("PUT", updateURL(c, id), perigee.Options{
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200248 MoreHeaders: c.Provider.AuthenticatedHeaders(),
249 ReqBody: &reqBody,
250 Results: &res,
251 OkCodes: []int{200, 201},
252 })
253 if err != nil {
254 return nil, err
255 }
256
257 return res.Port, nil
258}
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200259
Jamie Hannaford686c4962014-09-23 10:46:20 +0200260// Delete accepts a unique ID and deletes the port associated with it.
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200261func Delete(c *gophercloud.ServiceClient, id string) error {
Jamie Hannaford965ae702014-09-22 14:58:19 +0200262 _, err := perigee.Request("DELETE", deleteURL(c, id), perigee.Options{
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200263 MoreHeaders: c.Provider.AuthenticatedHeaders(),
264 OkCodes: []int{204},
265 })
266 return err
267}