blob: 591af2490f859b7787649707d042ba3d2d2f302c [file] [log] [blame]
Jamie Hannaford89f9af22014-09-17 12:21:48 +02001package subnets
Jamie Hannaford0708c002014-09-17 16:08:49 +02002
3import (
4 "strconv"
5
6 "github.com/racker/perigee"
7 "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 +020012// ListOpts allows the filtering and sorting of paginated collections through
13// the API. Filtering is achieved by passing in struct field values that map to
14// the subnet attributes you want to see returned. SortKey allows you to sort
15// by a particular subnet attribute. SortDir sets the direction, and is either
16// `asc' or `desc'. Marker and Limit are used for pagination.
Jamie Hannaford0708c002014-09-17 16:08:49 +020017type ListOpts struct {
18 Name string
19 EnableDHCP *bool
20 NetworkID string
21 TenantID string
22 IPVersion int
23 GatewayIP string
24 CIDR string
25 ID string
Jamie Hannafordf84171d2014-09-18 14:00:01 +020026 Limit int
Jamie Hannaford686c4962014-09-23 10:46:20 +020027 Marker string
Jamie Hannafordd0f090c2014-09-22 13:44:34 +020028 SortKey string
29 SortDir string
Jamie Hannaford0708c002014-09-17 16:08:49 +020030}
31
Jamie Hannaford686c4962014-09-23 10:46:20 +020032// List returns a Pager which allows you to iterate over a collection of
33// subnets. It accepts a ListOpts struct, which allows you to filter and sort
34// the returned collection for greater efficiency.
35//
36// Default policy settings return only those subnets that are owned by the tenant
37// who submits the request, unless the request is submitted by an user with
38// administrative rights.
Jamie Hannaford0708c002014-09-17 16:08:49 +020039func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
40 // Build query parameters
41 q := make(map[string]string)
42 if opts.Name != "" {
43 q["name"] = opts.Name
44 }
45 if opts.EnableDHCP != nil {
46 q["enable_dhcp"] = strconv.FormatBool(*opts.EnableDHCP)
47 }
48 if opts.NetworkID != "" {
49 q["network_id"] = opts.NetworkID
50 }
51 if opts.TenantID != "" {
52 q["tenant_id"] = opts.TenantID
53 }
54 if opts.IPVersion != 0 {
55 q["ip_version"] = strconv.Itoa(opts.IPVersion)
56 }
57 if opts.GatewayIP != "" {
58 q["gateway_ip"] = opts.GatewayIP
59 }
60 if opts.CIDR != "" {
61 q["cidr"] = opts.CIDR
62 }
63 if opts.ID != "" {
64 q["id"] = opts.ID
65 }
Jamie Hannafordf84171d2014-09-18 14:00:01 +020066 if opts.Limit != 0 {
67 q["limit"] = strconv.Itoa(opts.Limit)
68 }
Jamie Hannaford686c4962014-09-23 10:46:20 +020069 if opts.Marker != "" {
70 q["marker"] = opts.Marker
Jamie Hannafordf84171d2014-09-18 14:00:01 +020071 }
Jamie Hannafordd0f090c2014-09-22 13:44:34 +020072 if opts.SortKey != "" {
73 q["sort_key"] = opts.SortKey
74 }
75 if opts.SortDir != "" {
76 q["sort_dir"] = opts.SortDir
77 }
Jamie Hannaford0708c002014-09-17 16:08:49 +020078
Jamie Hannaford686c4962014-09-23 10:46:20 +020079 u := listURL(c) + utils.BuildQuery(q)
Jamie Hannaford0708c002014-09-17 16:08:49 +020080 return pagination.NewPager(c, u, func(r pagination.LastHTTPResponse) pagination.Page {
Ash Wilsonfc55c822014-09-25 13:18:16 -040081 return SubnetPage{pagination.LinkedPageBase{LastHTTPResponse: r}}
Jamie Hannaford0708c002014-09-17 16:08:49 +020082 })
83}
84
Jamie Hannaford686c4962014-09-23 10:46:20 +020085// Get retrieves a specific subnet based on its unique ID.
Jamie Hannafordd9036422014-09-23 17:50:24 +020086func Get(c *gophercloud.ServiceClient, id string) GetResult {
87 var res GetResult
Jamie Hannaford686c4962014-09-23 10:46:20 +020088 _, err := perigee.Request("GET", getURL(c, id), perigee.Options{
Jamie Hannaford0708c002014-09-17 16:08:49 +020089 MoreHeaders: c.Provider.AuthenticatedHeaders(),
Jamie Hannafordd9036422014-09-23 17:50:24 +020090 Results: &res.Resp,
91 OkCodes: []int{200},
Jamie Hannaford0708c002014-09-17 16:08:49 +020092 })
Jamie Hannafordd9036422014-09-23 17:50:24 +020093 res.Err = err
94 return res
Jamie Hannaford0708c002014-09-17 16:08:49 +020095}
Jamie Hannaford63631432014-09-18 11:40:09 +020096
Jamie Hannaford686c4962014-09-23 10:46:20 +020097// Valid IP types
Jamie Hannaford63631432014-09-18 11:40:09 +020098const (
99 IPv4 = 4
100 IPv6 = 6
101)
102
Jamie Hannaford686c4962014-09-23 10:46:20 +0200103// CreateOpts represents the attributes used when creating a new subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200104type CreateOpts struct {
Jamie Hannaford63631432014-09-18 11:40:09 +0200105 // Required
106 NetworkID string
107 CIDR string
108 // Optional
109 Name string
110 TenantID string
111 AllocationPools []AllocationPool
112 GatewayIP string
113 IPVersion int
Jamie Hannaford63631432014-09-18 11:40:09 +0200114 EnableDHCP *bool
Jamie Hannaford965ae702014-09-22 14:58:19 +0200115 DNSNameservers []string
116 HostRoutes []interface{}
Jamie Hannaford63631432014-09-18 11:40:09 +0200117}
118
Jamie Hannaford686c4962014-09-23 10:46:20 +0200119// Create accepts a CreateOpts struct and creates a new subnet using the values
120// provided. You must remember to provide a valid NetworkID, CIDR and IP version.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200121func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
122 var res CreateResult
123
Jamie Hannaford63631432014-09-18 11:40:09 +0200124 // Validate required options
125 if opts.NetworkID == "" {
Jamie Hannafordd9036422014-09-23 17:50:24 +0200126 res.Err = errNetworkIDRequired
127 return res
Jamie Hannaford63631432014-09-18 11:40:09 +0200128 }
129 if opts.CIDR == "" {
Jamie Hannafordd9036422014-09-23 17:50:24 +0200130 res.Err = errCIDRRequired
131 return res
Jamie Hannaford63631432014-09-18 11:40:09 +0200132 }
133 if opts.IPVersion != 0 && opts.IPVersion != IPv4 && opts.IPVersion != IPv6 {
Jamie Hannafordd9036422014-09-23 17:50:24 +0200134 res.Err = errInvalidIPType
135 return res
Jamie Hannaford63631432014-09-18 11:40:09 +0200136 }
137
138 type subnet struct {
139 NetworkID string `json:"network_id"`
140 CIDR string `json:"cidr"`
141 Name *string `json:"name,omitempty"`
142 TenantID *string `json:"tenant_id,omitempty"`
143 AllocationPools []AllocationPool `json:"allocation_pools,omitempty"`
144 GatewayIP *string `json:"gateway_ip,omitempty"`
145 IPVersion int `json:"ip_version,omitempty"`
Jamie Hannaford63631432014-09-18 11:40:09 +0200146 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200147 DNSNameservers []string `json:"dns_nameservers,omitempty"`
148 HostRoutes []interface{} `json:"host_routes,omitempty"`
Jamie Hannaford63631432014-09-18 11:40:09 +0200149 }
150 type request struct {
151 Subnet subnet `json:"subnet"`
152 }
153
154 reqBody := request{Subnet: subnet{
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200155 NetworkID: opts.NetworkID,
156 CIDR: opts.CIDR,
Jamie Hannaford6abf9282014-09-24 10:54:13 +0200157 Name: gophercloud.MaybeString(opts.Name),
158 TenantID: gophercloud.MaybeString(opts.TenantID),
159 GatewayIP: gophercloud.MaybeString(opts.GatewayIP),
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200160 EnableDHCP: opts.EnableDHCP,
Jamie Hannaford63631432014-09-18 11:40:09 +0200161 }}
162
Jamie Hannaford63631432014-09-18 11:40:09 +0200163 if opts.IPVersion != 0 {
164 reqBody.Subnet.IPVersion = opts.IPVersion
165 }
Jamie Hannaford63631432014-09-18 11:40:09 +0200166 if len(opts.AllocationPools) != 0 {
167 reqBody.Subnet.AllocationPools = opts.AllocationPools
168 }
Jamie Hannaford965ae702014-09-22 14:58:19 +0200169 if len(opts.DNSNameservers) != 0 {
170 reqBody.Subnet.DNSNameservers = opts.DNSNameservers
171 }
172 if len(opts.HostRoutes) != 0 {
173 reqBody.Subnet.HostRoutes = opts.HostRoutes
174 }
Jamie Hannaford63631432014-09-18 11:40:09 +0200175
Jamie Hannaford686c4962014-09-23 10:46:20 +0200176 _, err := perigee.Request("POST", createURL(c), perigee.Options{
Jamie Hannaford63631432014-09-18 11:40:09 +0200177 MoreHeaders: c.Provider.AuthenticatedHeaders(),
178 ReqBody: &reqBody,
Jamie Hannafordd9036422014-09-23 17:50:24 +0200179 Results: &res.Resp,
Jamie Hannaford63631432014-09-18 11:40:09 +0200180 OkCodes: []int{201},
181 })
Jamie Hannafordd9036422014-09-23 17:50:24 +0200182 res.Err = err
Jamie Hannaford63631432014-09-18 11:40:09 +0200183
Jamie Hannafordd9036422014-09-23 17:50:24 +0200184 return res
Jamie Hannaford63631432014-09-18 11:40:09 +0200185}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200186
Jamie Hannaford686c4962014-09-23 10:46:20 +0200187// UpdateOpts represents the attributes used when updating an existing subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200188type UpdateOpts struct {
189 Name string
190 GatewayIP string
191 DNSNameservers []string
192 HostRoutes []interface{}
193 EnableDHCP *bool
194}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200195
Jamie Hannaford686c4962014-09-23 10:46:20 +0200196// Update accepts a UpdateOpts struct and updates an existing subnet using the
197// values provided.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200198func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult {
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200199 type subnet struct {
Jamie Hannaford965ae702014-09-22 14:58:19 +0200200 Name *string `json:"name,omitempty"`
201 GatewayIP *string `json:"gateway_ip,omitempty"`
202 DNSNameservers []string `json:"dns_nameservers,omitempty"`
203 HostRoutes []interface{} `json:"host_routes,omitempty"`
204 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200205 }
206 type request struct {
207 Subnet subnet `json:"subnet"`
208 }
209
210 reqBody := request{Subnet: subnet{
Jamie Hannaford6abf9282014-09-24 10:54:13 +0200211 Name: gophercloud.MaybeString(opts.Name),
212 GatewayIP: gophercloud.MaybeString(opts.GatewayIP),
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200213 EnableDHCP: opts.EnableDHCP,
214 }}
215
Jamie Hannaford965ae702014-09-22 14:58:19 +0200216 if len(opts.DNSNameservers) != 0 {
217 reqBody.Subnet.DNSNameservers = opts.DNSNameservers
218 }
219
220 if len(opts.HostRoutes) != 0 {
221 reqBody.Subnet.HostRoutes = opts.HostRoutes
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200222 }
223
Jamie Hannafordd9036422014-09-23 17:50:24 +0200224 var res UpdateResult
Jamie Hannaford686c4962014-09-23 10:46:20 +0200225 _, err := perigee.Request("PUT", updateURL(c, id), perigee.Options{
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200226 MoreHeaders: c.Provider.AuthenticatedHeaders(),
227 ReqBody: &reqBody,
Jamie Hannafordd9036422014-09-23 17:50:24 +0200228 Results: &res.Resp,
Jamie Hannafordf84171d2014-09-18 14:00:01 +0200229 OkCodes: []int{200, 201},
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200230 })
Jamie Hannafordd9036422014-09-23 17:50:24 +0200231 res.Err = err
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200232
Jamie Hannafordd9036422014-09-23 17:50:24 +0200233 return res
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200234}
235
Jamie Hannaford686c4962014-09-23 10:46:20 +0200236// Delete accepts a unique ID and deletes the subnet associated with it.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200237func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
238 var res DeleteResult
Jamie Hannaford686c4962014-09-23 10:46:20 +0200239 _, err := perigee.Request("DELETE", deleteURL(c, id), perigee.Options{
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200240 MoreHeaders: c.Provider.AuthenticatedHeaders(),
241 OkCodes: []int{204},
242 })
Jamie Hannafordd9036422014-09-23 17:50:24 +0200243 res.Err = err
244 return res
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200245}