blob: de880a2d20a90dc5516aa65ab654cf90804bd8cc [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 Hannafordd9036422014-09-23 17:50:24 +0200112func Get(c *gophercloud.ServiceClient, id string) GetResult {
113 var res GetResult
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(),
Jamie Hannafordd9036422014-09-23 17:50:24 +0200116 Results: &res.Resp,
117 OkCodes: []int{200},
Jamie Hannaforda311f182014-09-19 11:19:10 +0200118 })
Jamie Hannafordd9036422014-09-23 17:50:24 +0200119 res.Err = err
120 return res
Jamie Hannaforda311f182014-09-19 11:19:10 +0200121}
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200122
Jamie Hannaford686c4962014-09-23 10:46:20 +0200123// CreateOpts represents the attributes used when creating a new port.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200124type CreateOpts struct {
125 NetworkID string
126 Name string
127 AdminStateUp *bool
128 MACAddress string
129 FixedIPs interface{}
130 DeviceID string
131 DeviceOwner string
132 TenantID string
133 SecurityGroups []string
134}
135
Jamie Hannaford686c4962014-09-23 10:46:20 +0200136// Create accepts a CreateOpts struct and creates a new network using the values
137// provided. You must remember to provide a NetworkID value.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200138func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
139 var res CreateResult
140
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200141 type port struct {
Jamie Hannaford686c4962014-09-23 10:46:20 +0200142 NetworkID string `json:"network_id"`
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200143 Name *string `json:"name,omitempty"`
144 AdminStateUp *bool `json:"admin_state_up,omitempty"`
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200145 MACAddress *string `json:"mac_address,omitempty"`
146 FixedIPs interface{} `json:"fixed_ips,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200147 DeviceID *string `json:"device_id,omitempty"`
148 DeviceOwner *string `json:"device_owner,omitempty"`
149 TenantID *string `json:"tenant_id,omitempty"`
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200150 SecurityGroups []string `json:"security_groups,omitempty"`
151 }
152 type request struct {
153 Port port `json:"port"`
154 }
155
156 // Validate
157 if opts.NetworkID == "" {
Jamie Hannafordd9036422014-09-23 17:50:24 +0200158 res.Err = errNetworkIDRequired
159 return res
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200160 }
161
162 // Populate request body
163 reqBody := request{Port: port{
164 NetworkID: opts.NetworkID,
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200165 Name: maybeString(opts.Name),
166 AdminStateUp: opts.AdminStateUp,
167 TenantID: maybeString(opts.TenantID),
168 MACAddress: maybeString(opts.MACAddress),
Jamie Hannaford965ae702014-09-22 14:58:19 +0200169 DeviceID: maybeString(opts.DeviceID),
170 DeviceOwner: maybeString(opts.DeviceOwner),
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200171 }}
172
173 if opts.FixedIPs != nil {
174 reqBody.Port.FixedIPs = opts.FixedIPs
175 }
176
177 if opts.SecurityGroups != nil {
178 reqBody.Port.SecurityGroups = opts.SecurityGroups
179 }
180
181 // Response
Jamie Hannaford965ae702014-09-22 14:58:19 +0200182 _, err := perigee.Request("POST", createURL(c), perigee.Options{
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200183 MoreHeaders: c.Provider.AuthenticatedHeaders(),
184 ReqBody: &reqBody,
Jamie Hannafordd9036422014-09-23 17:50:24 +0200185 Results: &res.Resp,
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200186 OkCodes: []int{201},
Jamie Hannaford2a0492a2014-09-22 12:02:11 +0200187 DumpReqJson: true,
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200188 })
Jamie Hannafordd9036422014-09-23 17:50:24 +0200189 res.Err = err
190 return res
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200191}
192
Jamie Hannaford686c4962014-09-23 10:46:20 +0200193// UpdateOpts represents the attributes used when updating an existing port.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200194type UpdateOpts struct {
195 Name string
196 AdminStateUp *bool
197 FixedIPs interface{}
198 DeviceID string
199 DeviceOwner string
200 SecurityGroups []string
201}
202
Jamie Hannaford686c4962014-09-23 10:46:20 +0200203// Update accepts a UpdateOpts struct and updates an existing port using the
204// values provided.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200205func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult {
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200206 type port struct {
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200207 Name *string `json:"name,omitempty"`
208 AdminStateUp *bool `json:"admin_state_up,omitempty"`
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200209 FixedIPs interface{} `json:"fixed_ips,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200210 DeviceID *string `json:"device_id,omitempty"`
211 DeviceOwner *string `json:"device_owner,omitempty"`
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200212 SecurityGroups []string `json:"security_groups,omitempty"`
213 }
214 type request struct {
215 Port port `json:"port"`
216 }
217
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200218 // Populate request body
219 reqBody := request{Port: port{
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200220 Name: maybeString(opts.Name),
221 AdminStateUp: opts.AdminStateUp,
Jamie Hannaford965ae702014-09-22 14:58:19 +0200222 DeviceID: maybeString(opts.DeviceID),
223 DeviceOwner: maybeString(opts.DeviceOwner),
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200224 }}
225
226 if opts.FixedIPs != nil {
227 reqBody.Port.FixedIPs = opts.FixedIPs
228 }
229
230 if opts.SecurityGroups != nil {
231 reqBody.Port.SecurityGroups = opts.SecurityGroups
232 }
233
234 // Response
Jamie Hannafordd9036422014-09-23 17:50:24 +0200235 var res UpdateResult
Jamie Hannaford965ae702014-09-22 14:58:19 +0200236 _, err := perigee.Request("PUT", updateURL(c, id), perigee.Options{
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200237 MoreHeaders: c.Provider.AuthenticatedHeaders(),
238 ReqBody: &reqBody,
Jamie Hannafordd9036422014-09-23 17:50:24 +0200239 Results: &res.Resp,
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200240 OkCodes: []int{200, 201},
241 })
Jamie Hannafordd9036422014-09-23 17:50:24 +0200242 res.Err = err
243 return res
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200244}
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200245
Jamie Hannaford686c4962014-09-23 10:46:20 +0200246// Delete accepts a unique ID and deletes the port associated with it.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200247func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
248 var res DeleteResult
Jamie Hannaford965ae702014-09-22 14:58:19 +0200249 _, err := perigee.Request("DELETE", deleteURL(c, id), perigee.Options{
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200250 MoreHeaders: c.Provider.AuthenticatedHeaders(),
251 OkCodes: []int{204},
252 })
Jamie Hannafordd9036422014-09-23 17:50:24 +0200253 res.Err = err
254 return res
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200255}