blob: afa37f5121386e43f8bb9f35687295de86f7d083 [file] [log] [blame]
Jamie Hannaford548d3402014-09-18 15:50:08 +02001package ports
2
3import (
Jamie Hannaford548d3402014-09-18 15:50:08 +02004 "github.com/rackspace/gophercloud"
Jamie Hannaford548d3402014-09-18 15:50:08 +02005 "github.com/rackspace/gophercloud/pagination"
Jon Perritt04851d32014-10-14 02:07:13 -05006
7 "github.com/racker/perigee"
Jamie Hannaford548d3402014-09-18 15:50:08 +02008)
9
Jamie Hannafordc98f59b2014-10-09 10:32:50 +020010// AdminState gives users a solid type to work with for create and update
11// operations. It is recommended that users use the `Up` and `Down` enums.
12type AdminState *bool
13
14// Convenience vars for AdminStateUp values.
15var (
16 iTrue = true
17 iFalse = false
18
19 Up AdminState = &iTrue
20 Down AdminState = &iFalse
21)
22
Jon Perritt04851d32014-10-14 02:07:13 -050023// ListOptsBuilder allows extensions to add additional parameters to the
24// List request.
25type ListOptsBuilder interface {
26 ToPortListString() (string, error)
27}
28
Jamie Hannaford686c4962014-09-23 10:46:20 +020029// ListOpts allows the filtering and sorting of paginated collections through
30// the API. Filtering is achieved by passing in struct field values that map to
31// the port attributes you want to see returned. SortKey allows you to sort
32// by a particular port attribute. SortDir sets the direction, and is either
33// `asc' or `desc'. Marker and Limit are used for pagination.
Jamie Hannaford548d3402014-09-18 15:50:08 +020034type ListOpts struct {
Jamie Hannaford92523e32014-10-02 11:08:36 +020035 Status string `q:"status"`
36 Name string `q:"name"`
37 AdminStateUp *bool `q:"admin_state_up"`
38 NetworkID string `q:"network_id"`
39 TenantID string `q:"tenant_id"`
40 DeviceOwner string `q:"device_owner"`
41 MACAddress string `q:"mac_address"`
42 ID string `q:"id"`
43 DeviceID string `q:"device_id"`
44 Limit int `q:"limit"`
45 Marker string `q:"marker"`
46 SortKey string `q:"sort_key"`
47 SortDir string `q:"sort_dir"`
Jamie Hannaford548d3402014-09-18 15:50:08 +020048}
49
Jon Perritt04851d32014-10-14 02:07:13 -050050// ToPortListString formats a ListOpts into a query string.
51func (opts ListOpts) ToPortListString() (string, error) {
52 q, err := gophercloud.BuildQueryString(opts)
53 if err != nil {
54 return "", err
55 }
56 return q.String(), nil
57}
58
Jamie Hannaford686c4962014-09-23 10:46:20 +020059// List returns a Pager which allows you to iterate over a collection of
60// ports. It accepts a ListOpts struct, which allows you to filter and sort
61// the returned collection for greater efficiency.
62//
63// Default policy settings return only those ports that are owned by the tenant
64// who submits the request, unless the request is submitted by an user with
65// administrative rights.
Jon Perritt04851d32014-10-14 02:07:13 -050066func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
67 url := listURL(c)
68 if opts != nil {
69 query, err := opts.ToPortListString()
70 if err != nil {
71 return pagination.Pager{Err: err}
72 }
73 url += query
Jamie Hannaford548d3402014-09-18 15:50:08 +020074 }
Jamie Hannaford548d3402014-09-18 15:50:08 +020075
Jon Perritt04851d32014-10-14 02:07:13 -050076 return pagination.NewPager(c, url, func(r pagination.LastHTTPResponse) pagination.Page {
Ash Wilsonfc55c822014-09-25 13:18:16 -040077 return PortPage{pagination.LinkedPageBase{LastHTTPResponse: r}}
Jamie Hannaford548d3402014-09-18 15:50:08 +020078 })
79}
Jamie Hannaforda311f182014-09-19 11:19:10 +020080
Jamie Hannaford686c4962014-09-23 10:46:20 +020081// Get retrieves a specific port based on its unique ID.
Jamie Hannafordd9036422014-09-23 17:50:24 +020082func Get(c *gophercloud.ServiceClient, id string) GetResult {
83 var res GetResult
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +020084 _, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{
Jamie Hannaforda311f182014-09-19 11:19:10 +020085 MoreHeaders: c.Provider.AuthenticatedHeaders(),
Jamie Hannafordd9036422014-09-23 17:50:24 +020086 Results: &res.Resp,
87 OkCodes: []int{200},
Jamie Hannaforda311f182014-09-19 11:19:10 +020088 })
Jamie Hannafordd9036422014-09-23 17:50:24 +020089 return res
Jamie Hannaforda311f182014-09-19 11:19:10 +020090}
Jamie Hannaforda5fb7822014-09-19 15:07:02 +020091
Jon Perritt04851d32014-10-14 02:07:13 -050092// CreateOptsBuilder is the interface options structs have to satisfy in order
93// to be used in the main Create operation in this package. Since many
94// extensions decorate or modify the common logic, it is useful for them to
95// satisfy a basic interface in order for them to be used.
96type CreateOptsBuilder interface {
97 ToPortCreateMap() (map[string]interface{}, error)
98}
99
Jamie Hannaford686c4962014-09-23 10:46:20 +0200100// CreateOpts represents the attributes used when creating a new port.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200101type CreateOpts struct {
102 NetworkID string
103 Name string
104 AdminStateUp *bool
105 MACAddress string
106 FixedIPs interface{}
107 DeviceID string
108 DeviceOwner string
109 TenantID string
110 SecurityGroups []string
111}
112
Jon Perritt04851d32014-10-14 02:07:13 -0500113// ToPortCreateMap casts a CreateOpts struct to a map.
114func (opts CreateOpts) ToPortCreateMap() (map[string]interface{}, error) {
115 p := make(map[string]interface{})
116
117 if opts.NetworkID == "" {
118 return nil, errNetworkIDRequired
119 }
120 p["network_id"] = opts.NetworkID
121
122 if opts.DeviceID != "" {
123 p["device_id"] = opts.DeviceID
124 }
125 if opts.DeviceOwner != "" {
126 p["device_owner"] = opts.DeviceOwner
127 }
128 if opts.FixedIPs != nil {
129 p["fixed_ips"] = opts.FixedIPs
130 }
131 if opts.SecurityGroups != nil {
132 p["security_groups"] = opts.SecurityGroups
133 }
134 if opts.TenantID != "" {
135 p["tenant_id"] = opts.TenantID
136 }
137 if opts.AdminStateUp != nil {
138 p["admin_state_up"] = &opts.AdminStateUp
139 }
140 if opts.Name != "" {
141 p["name"] = opts.Name
142 }
143 if opts.MACAddress != "" {
144 p["mac_address"] = opts.MACAddress
145 }
146
147 return map[string]interface{}{"port": p}, nil
148}
149
Jamie Hannaford686c4962014-09-23 10:46:20 +0200150// Create accepts a CreateOpts struct and creates a new network using the values
151// provided. You must remember to provide a NetworkID value.
Jon Perritt04851d32014-10-14 02:07:13 -0500152func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
Jamie Hannafordd9036422014-09-23 17:50:24 +0200153 var res CreateResult
154
Jon Perritt04851d32014-10-14 02:07:13 -0500155 reqBody, err := opts.ToPortCreateMap()
156 if err != nil {
157 res.Err = err
Jamie Hannafordd9036422014-09-23 17:50:24 +0200158 return res
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200159 }
160
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200161 // Response
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +0200162 _, res.Err = perigee.Request("POST", createURL(c), perigee.Options{
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200163 MoreHeaders: c.Provider.AuthenticatedHeaders(),
164 ReqBody: &reqBody,
Jamie Hannafordd9036422014-09-23 17:50:24 +0200165 Results: &res.Resp,
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200166 OkCodes: []int{201},
Jamie Hannaford2a0492a2014-09-22 12:02:11 +0200167 DumpReqJson: true,
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200168 })
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +0200169
Jamie Hannafordd9036422014-09-23 17:50:24 +0200170 return res
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200171}
172
Jon Perritt04851d32014-10-14 02:07:13 -0500173// UpdateOptsBuilder is the interface options structs have to satisfy in order
174// to be used in the main Update operation in this package. Since many
175// extensions decorate or modify the common logic, it is useful for them to
176// satisfy a basic interface in order for them to be used.
177type UpdateOptsBuilder interface {
178 ToPortUpdateMap() (map[string]interface{}, error)
179}
180
Jamie Hannaford686c4962014-09-23 10:46:20 +0200181// UpdateOpts represents the attributes used when updating an existing port.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200182type UpdateOpts struct {
183 Name string
184 AdminStateUp *bool
185 FixedIPs interface{}
186 DeviceID string
187 DeviceOwner string
188 SecurityGroups []string
189}
190
Jon Perritt04851d32014-10-14 02:07:13 -0500191// ToPortUpdateMap casts an UpdateOpts struct to a map.
192func (opts UpdateOpts) ToPortUpdateMap() (map[string]interface{}, error) {
193 p := make(map[string]interface{})
194
195 if opts.DeviceID != "" {
196 p["device_id"] = opts.DeviceID
197 }
198 if opts.DeviceOwner != "" {
199 p["device_owner"] = opts.DeviceOwner
200 }
201 if opts.FixedIPs != nil {
202 p["fixed_ips"] = opts.FixedIPs
203 }
204 if opts.SecurityGroups != nil {
205 p["security_groups"] = opts.SecurityGroups
206 }
207 if opts.AdminStateUp != nil {
208 p["admin_state_up"] = &opts.AdminStateUp
209 }
210 if opts.Name != "" {
211 p["name"] = opts.Name
212 }
213
214 return map[string]interface{}{"port": p}, nil
215}
216
Jamie Hannaford686c4962014-09-23 10:46:20 +0200217// Update accepts a UpdateOpts struct and updates an existing port using the
218// values provided.
Jon Perritt04851d32014-10-14 02:07:13 -0500219func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult {
Jamie Hannafordd9036422014-09-23 17:50:24 +0200220 var res UpdateResult
Jon Perritt04851d32014-10-14 02:07:13 -0500221
222 reqBody, err := opts.ToPortUpdateMap()
223 if err != nil {
224 res.Err = err
225 return res
226 }
227
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +0200228 _, res.Err = perigee.Request("PUT", updateURL(c, id), perigee.Options{
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200229 MoreHeaders: c.Provider.AuthenticatedHeaders(),
230 ReqBody: &reqBody,
Jamie Hannafordd9036422014-09-23 17:50:24 +0200231 Results: &res.Resp,
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200232 OkCodes: []int{200, 201},
233 })
Jamie Hannafordd9036422014-09-23 17:50:24 +0200234 return res
Jamie Hannaforda5fb7822014-09-19 15:07:02 +0200235}
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200236
Jamie Hannaford686c4962014-09-23 10:46:20 +0200237// Delete accepts a unique ID and deletes the port associated with it.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200238func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
239 var res DeleteResult
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +0200240 _, res.Err = perigee.Request("DELETE", deleteURL(c, id), perigee.Options{
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200241 MoreHeaders: c.Provider.AuthenticatedHeaders(),
242 OkCodes: []int{204},
243 })
Jamie Hannafordd9036422014-09-23 17:50:24 +0200244 return res
Jamie Hannafordd444b7a2014-09-19 15:08:27 +0200245}