blob: 63ac2901b7b5a50f613c89d37ed96f77d0142e0a [file] [log] [blame]
Jamie Hannaford89f9af22014-09-17 12:21:48 +02001package subnets
Jamie Hannaford0708c002014-09-17 16:08:49 +02002
3import (
Jamie Hannaford0708c002014-09-17 16:08:49 +02004 "github.com/rackspace/gophercloud"
Jamie Hannaford0708c002014-09-17 16:08:49 +02005 "github.com/rackspace/gophercloud/pagination"
6)
7
Jamie Hannaforda2976ab2014-10-09 10:32:58 +02008// AdminState gives users a solid type to work with for create and update
9// operations. It is recommended that users use the `Up` and `Down` enums.
10type AdminState *bool
11
12// Convenience vars for AdminStateUp values.
13var (
14 iTrue = true
15 iFalse = false
16
17 Up AdminState = &iTrue
18 Down AdminState = &iFalse
19)
20
Jon Perritt04851d32014-10-14 02:07:13 -050021// ListOptsBuilder allows extensions to add additional parameters to the
22// List request.
23type ListOptsBuilder interface {
Jon Perritt26780d52014-10-14 11:35:58 -050024 ToSubnetListQuery() (string, error)
Jon Perritt04851d32014-10-14 02:07:13 -050025}
26
Jamie Hannaford686c4962014-09-23 10:46:20 +020027// ListOpts allows the filtering and sorting of paginated collections through
28// the API. Filtering is achieved by passing in struct field values that map to
29// the subnet attributes you want to see returned. SortKey allows you to sort
30// by a particular subnet attribute. SortDir sets the direction, and is either
31// `asc' or `desc'. Marker and Limit are used for pagination.
Jamie Hannaford0708c002014-09-17 16:08:49 +020032type ListOpts struct {
Jamie Hannaford5c6e9962014-10-02 10:34:14 +020033 Name string `q:"name"`
34 EnableDHCP *bool `q:"enable_dhcp"`
35 NetworkID string `q:"network_id"`
36 TenantID string `q:"tenant_id"`
37 IPVersion int `q:"ip_version"`
38 GatewayIP string `q:"gateway_ip"`
39 CIDR string `q:"cidr"`
40 ID string `q:"id"`
41 Limit int `q:"limit"`
42 Marker string `q:"marker"`
43 SortKey string `q:"sort_key"`
44 SortDir string `q:"sort_dir"`
Jamie Hannaford0708c002014-09-17 16:08:49 +020045}
46
Jon Perritt26780d52014-10-14 11:35:58 -050047// ToSubnetListQuery formats a ListOpts into a query string.
48func (opts ListOpts) ToSubnetListQuery() (string, error) {
Jon Perritt04851d32014-10-14 02:07:13 -050049 q, err := gophercloud.BuildQueryString(opts)
50 if err != nil {
51 return "", err
52 }
53 return q.String(), nil
54}
55
Jamie Hannaford686c4962014-09-23 10:46:20 +020056// List returns a Pager which allows you to iterate over a collection of
57// subnets. It accepts a ListOpts struct, which allows you to filter and sort
58// the returned collection for greater efficiency.
59//
60// Default policy settings return only those subnets that are owned by the tenant
Alex Gaynora6d5f9f2014-10-27 10:52:32 -070061// who submits the request, unless the request is submitted by a user with
Jamie Hannaford686c4962014-09-23 10:46:20 +020062// administrative rights.
Jon Perritt04851d32014-10-14 02:07:13 -050063func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
64 url := listURL(c)
65 if opts != nil {
Jon Perritt26780d52014-10-14 11:35:58 -050066 query, err := opts.ToSubnetListQuery()
Jon Perritt04851d32014-10-14 02:07:13 -050067 if err != nil {
68 return pagination.Pager{Err: err}
69 }
70 url += query
Jamie Hannaford92523e32014-10-02 11:08:36 +020071 }
Jamie Hannaford0708c002014-09-17 16:08:49 +020072
Ash Wilsonb8b16f82014-10-20 10:19:49 -040073 return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
74 return SubnetPage{pagination.LinkedPageBase{PageResult: r}}
Jamie Hannaford0708c002014-09-17 16:08:49 +020075 })
76}
77
Jamie Hannaford686c4962014-09-23 10:46:20 +020078// Get retrieves a specific subnet based on its unique ID.
Jamie Hannafordd9036422014-09-23 17:50:24 +020079func Get(c *gophercloud.ServiceClient, id string) GetResult {
80 var res GetResult
Ash Wilson59fb6c42015-02-12 16:21:13 -050081 _, res.Err = c.Request("GET", getURL(c, id), gophercloud.RequestOpts{
82 JSONResponse: &res.Body,
83 OkCodes: []int{200},
Jamie Hannaford0708c002014-09-17 16:08:49 +020084 })
Jamie Hannafordd9036422014-09-23 17:50:24 +020085 return res
Jamie Hannaford0708c002014-09-17 16:08:49 +020086}
Jamie Hannaford63631432014-09-18 11:40:09 +020087
Jamie Hannaford686c4962014-09-23 10:46:20 +020088// Valid IP types
Jamie Hannaford63631432014-09-18 11:40:09 +020089const (
90 IPv4 = 4
91 IPv6 = 6
92)
93
Jon Perritt04851d32014-10-14 02:07:13 -050094// CreateOptsBuilder is the interface options structs have to satisfy in order
95// to be used in the main Create operation in this package. Since many
96// extensions decorate or modify the common logic, it is useful for them to
97// satisfy a basic interface in order for them to be used.
98type CreateOptsBuilder interface {
99 ToSubnetCreateMap() (map[string]interface{}, error)
100}
101
Jamie Hannaford686c4962014-09-23 10:46:20 +0200102// CreateOpts represents the attributes used when creating a new subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200103type CreateOpts struct {
Jamie Hannaford63631432014-09-18 11:40:09 +0200104 // Required
105 NetworkID string
106 CIDR string
107 // Optional
108 Name string
109 TenantID string
110 AllocationPools []AllocationPool
111 GatewayIP string
112 IPVersion int
Jamie Hannaford63631432014-09-18 11:40:09 +0200113 EnableDHCP *bool
Jamie Hannaford965ae702014-09-22 14:58:19 +0200114 DNSNameservers []string
Jamie Hannaford5d93f562014-10-09 10:53:32 +0200115 HostRoutes []HostRoute
Jamie Hannaford63631432014-09-18 11:40:09 +0200116}
117
Jon Perritt04851d32014-10-14 02:07:13 -0500118// ToSubnetCreateMap casts a CreateOpts struct to a map.
119func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) {
120 s := make(map[string]interface{})
Jamie Hannafordd9036422014-09-23 17:50:24 +0200121
Jamie Hannaford63631432014-09-18 11:40:09 +0200122 if opts.NetworkID == "" {
Jon Perritt04851d32014-10-14 02:07:13 -0500123 return nil, errNetworkIDRequired
Jamie Hannaford63631432014-09-18 11:40:09 +0200124 }
125 if opts.CIDR == "" {
Jon Perritt04851d32014-10-14 02:07:13 -0500126 return nil, errCIDRRequired
Jamie Hannaford63631432014-09-18 11:40:09 +0200127 }
128 if opts.IPVersion != 0 && opts.IPVersion != IPv4 && opts.IPVersion != IPv6 {
Jon Perritt04851d32014-10-14 02:07:13 -0500129 return nil, errInvalidIPType
Jamie Hannaford63631432014-09-18 11:40:09 +0200130 }
131
Jon Perritt04851d32014-10-14 02:07:13 -0500132 s["network_id"] = opts.NetworkID
133 s["cidr"] = opts.CIDR
Jamie Hannaford63631432014-09-18 11:40:09 +0200134
Jon Perritt04851d32014-10-14 02:07:13 -0500135 if opts.EnableDHCP != nil {
136 s["enable_dhcp"] = &opts.EnableDHCP
137 }
138 if opts.Name != "" {
139 s["name"] = opts.Name
140 }
141 if opts.GatewayIP != "" {
142 s["gateway_ip"] = opts.GatewayIP
143 }
144 if opts.TenantID != "" {
145 s["tenant_id"] = opts.TenantID
146 }
Jamie Hannaford63631432014-09-18 11:40:09 +0200147 if opts.IPVersion != 0 {
Jon Perritt04851d32014-10-14 02:07:13 -0500148 s["ip_version"] = opts.IPVersion
Jamie Hannaford63631432014-09-18 11:40:09 +0200149 }
Jamie Hannaford63631432014-09-18 11:40:09 +0200150 if len(opts.AllocationPools) != 0 {
Jon Perritt04851d32014-10-14 02:07:13 -0500151 s["allocation_pools"] = opts.AllocationPools
Jamie Hannaford63631432014-09-18 11:40:09 +0200152 }
Jamie Hannaford965ae702014-09-22 14:58:19 +0200153 if len(opts.DNSNameservers) != 0 {
Jon Perritt04851d32014-10-14 02:07:13 -0500154 s["dns_nameservers"] = opts.DNSNameservers
Jamie Hannaford965ae702014-09-22 14:58:19 +0200155 }
156 if len(opts.HostRoutes) != 0 {
Jon Perritt04851d32014-10-14 02:07:13 -0500157 s["host_routes"] = opts.HostRoutes
158 }
159
160 return map[string]interface{}{"subnet": s}, nil
161}
162
163// Create accepts a CreateOpts struct and creates a new subnet using the values
164// provided. You must remember to provide a valid NetworkID, CIDR and IP version.
165func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
166 var res CreateResult
167
168 reqBody, err := opts.ToSubnetCreateMap()
169 if err != nil {
170 res.Err = err
171 return res
Jamie Hannaford965ae702014-09-22 14:58:19 +0200172 }
Jamie Hannaford63631432014-09-18 11:40:09 +0200173
Ash Wilson4bf41a32015-02-12 15:52:44 -0500174 _, res.Err = c.Request("POST", createURL(c), gophercloud.RequestOpts{
175 JSONBody: &reqBody,
176 JSONResponse: &res.Body,
177 OkCodes: []int{201},
Jamie Hannaford63631432014-09-18 11:40:09 +0200178 })
Jamie Hannaford63631432014-09-18 11:40:09 +0200179
Jamie Hannafordd9036422014-09-23 17:50:24 +0200180 return res
Jamie Hannaford63631432014-09-18 11:40:09 +0200181}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200182
Jon Perritt04851d32014-10-14 02:07:13 -0500183// UpdateOptsBuilder allows extensions to add additional parameters to the
184// Update request.
185type UpdateOptsBuilder interface {
186 ToSubnetUpdateMap() (map[string]interface{}, error)
187}
188
Jamie Hannaford686c4962014-09-23 10:46:20 +0200189// UpdateOpts represents the attributes used when updating an existing subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200190type UpdateOpts struct {
191 Name string
192 GatewayIP string
193 DNSNameservers []string
Jamie Hannaford5d93f562014-10-09 10:53:32 +0200194 HostRoutes []HostRoute
Jamie Hannaford965ae702014-09-22 14:58:19 +0200195 EnableDHCP *bool
196}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200197
Jon Perritt04851d32014-10-14 02:07:13 -0500198// ToSubnetUpdateMap casts an UpdateOpts struct to a map.
199func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) {
200 s := make(map[string]interface{})
201
202 if opts.EnableDHCP != nil {
203 s["enable_dhcp"] = &opts.EnableDHCP
204 }
205 if opts.Name != "" {
206 s["name"] = opts.Name
207 }
208 if opts.GatewayIP != "" {
209 s["gateway_ip"] = opts.GatewayIP
210 }
211 if len(opts.DNSNameservers) != 0 {
212 s["dns_nameservers"] = opts.DNSNameservers
213 }
214 if len(opts.HostRoutes) != 0 {
215 s["host_routes"] = opts.HostRoutes
216 }
217
218 return map[string]interface{}{"subnet": s}, nil
219}
220
Jamie Hannaford686c4962014-09-23 10:46:20 +0200221// Update accepts a UpdateOpts struct and updates an existing subnet using the
222// values provided.
Jon Perritt04851d32014-10-14 02:07:13 -0500223func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult {
Jamie Hannafordd9036422014-09-23 17:50:24 +0200224 var res UpdateResult
Jon Perritt04851d32014-10-14 02:07:13 -0500225
226 reqBody, err := opts.ToSubnetUpdateMap()
227 if err != nil {
228 res.Err = err
229 return res
230 }
231
Ash Wilson59fb6c42015-02-12 16:21:13 -0500232 _, res.Err = c.Request("PUT", updateURL(c, id), gophercloud.RequestOpts{
233 JSONBody: &reqBody,
234 JSONResponse: &res.Body,
235 OkCodes: []int{200, 201},
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200236 })
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200237
Jamie Hannafordd9036422014-09-23 17:50:24 +0200238 return res
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200239}
240
Jamie Hannaford686c4962014-09-23 10:46:20 +0200241// Delete accepts a unique ID and deletes the subnet associated with it.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200242func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
243 var res DeleteResult
Ash Wilson59fb6c42015-02-12 16:21:13 -0500244 _, res.Err = c.Request("DELETE", deleteURL(c, id), gophercloud.RequestOpts{
245 OkCodes: []int{204},
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200246 })
Jamie Hannafordd9036422014-09-23 17:50:24 +0200247 return res
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200248}