blob: a7e6b53333ab8053dd423adabc286de48b1d5eb9 [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/racker/perigee"
5 "github.com/rackspace/gophercloud"
Jamie Hannaford0708c002014-09-17 16:08:49 +02006 "github.com/rackspace/gophercloud/pagination"
7)
8
Jamie Hannaforda2976ab2014-10-09 10:32:58 +02009// AdminState gives users a solid type to work with for create and update
10// operations. It is recommended that users use the `Up` and `Down` enums.
11type AdminState *bool
12
13// Convenience vars for AdminStateUp values.
14var (
15 iTrue = true
16 iFalse = false
17
18 Up AdminState = &iTrue
19 Down AdminState = &iFalse
20)
21
Jamie Hannaford686c4962014-09-23 10:46:20 +020022// ListOpts allows the filtering and sorting of paginated collections through
23// the API. Filtering is achieved by passing in struct field values that map to
24// the subnet attributes you want to see returned. SortKey allows you to sort
25// by a particular subnet attribute. SortDir sets the direction, and is either
26// `asc' or `desc'. Marker and Limit are used for pagination.
Jamie Hannaford0708c002014-09-17 16:08:49 +020027type ListOpts struct {
Jamie Hannaford5c6e9962014-10-02 10:34:14 +020028 Name string `q:"name"`
29 EnableDHCP *bool `q:"enable_dhcp"`
30 NetworkID string `q:"network_id"`
31 TenantID string `q:"tenant_id"`
32 IPVersion int `q:"ip_version"`
33 GatewayIP string `q:"gateway_ip"`
34 CIDR string `q:"cidr"`
35 ID string `q:"id"`
36 Limit int `q:"limit"`
37 Marker string `q:"marker"`
38 SortKey string `q:"sort_key"`
39 SortDir string `q:"sort_dir"`
Jamie Hannaford0708c002014-09-17 16:08:49 +020040}
41
Jamie Hannaford686c4962014-09-23 10:46:20 +020042// List returns a Pager which allows you to iterate over a collection of
43// subnets. It accepts a ListOpts struct, which allows you to filter and sort
44// the returned collection for greater efficiency.
45//
46// Default policy settings return only those subnets that are owned by the tenant
47// who submits the request, unless the request is submitted by an user with
48// administrative rights.
Jamie Hannaford0708c002014-09-17 16:08:49 +020049func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
50 // Build query parameters
Jamie Hannaford92523e32014-10-02 11:08:36 +020051 query, err := gophercloud.BuildQueryString(&opts)
52 if err != nil {
53 return pagination.Pager{Err: err}
54 }
55 url := listURL(c) + query.String()
Jamie Hannaford0708c002014-09-17 16:08:49 +020056
Jamie Hannaford92523e32014-10-02 11:08:36 +020057 return pagination.NewPager(c, url, func(r pagination.LastHTTPResponse) pagination.Page {
Ash Wilsonfc55c822014-09-25 13:18:16 -040058 return SubnetPage{pagination.LinkedPageBase{LastHTTPResponse: r}}
Jamie Hannaford0708c002014-09-17 16:08:49 +020059 })
60}
61
Jamie Hannaford686c4962014-09-23 10:46:20 +020062// Get retrieves a specific subnet based on its unique ID.
Jamie Hannafordd9036422014-09-23 17:50:24 +020063func Get(c *gophercloud.ServiceClient, id string) GetResult {
64 var res GetResult
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +020065 _, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{
Jamie Hannaford0708c002014-09-17 16:08:49 +020066 MoreHeaders: c.Provider.AuthenticatedHeaders(),
Jamie Hannafordd9036422014-09-23 17:50:24 +020067 Results: &res.Resp,
68 OkCodes: []int{200},
Jamie Hannaford0708c002014-09-17 16:08:49 +020069 })
Jamie Hannafordd9036422014-09-23 17:50:24 +020070 return res
Jamie Hannaford0708c002014-09-17 16:08:49 +020071}
Jamie Hannaford63631432014-09-18 11:40:09 +020072
Jamie Hannaford686c4962014-09-23 10:46:20 +020073// Valid IP types
Jamie Hannaford63631432014-09-18 11:40:09 +020074const (
75 IPv4 = 4
76 IPv6 = 6
77)
78
Jamie Hannaford686c4962014-09-23 10:46:20 +020079// CreateOpts represents the attributes used when creating a new subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +020080type CreateOpts struct {
Jamie Hannaford63631432014-09-18 11:40:09 +020081 // Required
82 NetworkID string
83 CIDR string
84 // Optional
85 Name string
86 TenantID string
87 AllocationPools []AllocationPool
88 GatewayIP string
89 IPVersion int
Jamie Hannaford63631432014-09-18 11:40:09 +020090 EnableDHCP *bool
Jamie Hannaford965ae702014-09-22 14:58:19 +020091 DNSNameservers []string
Jamie Hannaford5d93f562014-10-09 10:53:32 +020092 HostRoutes []HostRoute
Jamie Hannaford63631432014-09-18 11:40:09 +020093}
94
Jamie Hannaford686c4962014-09-23 10:46:20 +020095// Create accepts a CreateOpts struct and creates a new subnet using the values
96// provided. You must remember to provide a valid NetworkID, CIDR and IP version.
Jamie Hannafordd9036422014-09-23 17:50:24 +020097func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
98 var res CreateResult
99
Jamie Hannaford63631432014-09-18 11:40:09 +0200100 // Validate required options
101 if opts.NetworkID == "" {
Jamie Hannafordd9036422014-09-23 17:50:24 +0200102 res.Err = errNetworkIDRequired
103 return res
Jamie Hannaford63631432014-09-18 11:40:09 +0200104 }
105 if opts.CIDR == "" {
Jamie Hannafordd9036422014-09-23 17:50:24 +0200106 res.Err = errCIDRRequired
107 return res
Jamie Hannaford63631432014-09-18 11:40:09 +0200108 }
109 if opts.IPVersion != 0 && opts.IPVersion != IPv4 && opts.IPVersion != IPv6 {
Jamie Hannafordd9036422014-09-23 17:50:24 +0200110 res.Err = errInvalidIPType
111 return res
Jamie Hannaford63631432014-09-18 11:40:09 +0200112 }
113
114 type subnet struct {
115 NetworkID string `json:"network_id"`
116 CIDR string `json:"cidr"`
117 Name *string `json:"name,omitempty"`
118 TenantID *string `json:"tenant_id,omitempty"`
119 AllocationPools []AllocationPool `json:"allocation_pools,omitempty"`
120 GatewayIP *string `json:"gateway_ip,omitempty"`
121 IPVersion int `json:"ip_version,omitempty"`
Jamie Hannaford63631432014-09-18 11:40:09 +0200122 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200123 DNSNameservers []string `json:"dns_nameservers,omitempty"`
Jamie Hannaford5d93f562014-10-09 10:53:32 +0200124 HostRoutes []HostRoute `json:"host_routes,omitempty"`
Jamie Hannaford63631432014-09-18 11:40:09 +0200125 }
126 type request struct {
127 Subnet subnet `json:"subnet"`
128 }
129
130 reqBody := request{Subnet: subnet{
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200131 NetworkID: opts.NetworkID,
132 CIDR: opts.CIDR,
Jamie Hannaford6abf9282014-09-24 10:54:13 +0200133 Name: gophercloud.MaybeString(opts.Name),
134 TenantID: gophercloud.MaybeString(opts.TenantID),
135 GatewayIP: gophercloud.MaybeString(opts.GatewayIP),
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200136 EnableDHCP: opts.EnableDHCP,
Jamie Hannaford63631432014-09-18 11:40:09 +0200137 }}
138
Jamie Hannaford63631432014-09-18 11:40:09 +0200139 if opts.IPVersion != 0 {
140 reqBody.Subnet.IPVersion = opts.IPVersion
141 }
Jamie Hannaford63631432014-09-18 11:40:09 +0200142 if len(opts.AllocationPools) != 0 {
143 reqBody.Subnet.AllocationPools = opts.AllocationPools
144 }
Jamie Hannaford965ae702014-09-22 14:58:19 +0200145 if len(opts.DNSNameservers) != 0 {
146 reqBody.Subnet.DNSNameservers = opts.DNSNameservers
147 }
148 if len(opts.HostRoutes) != 0 {
149 reqBody.Subnet.HostRoutes = opts.HostRoutes
150 }
Jamie Hannaford63631432014-09-18 11:40:09 +0200151
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +0200152 _, res.Err = perigee.Request("POST", createURL(c), perigee.Options{
Jamie Hannaford63631432014-09-18 11:40:09 +0200153 MoreHeaders: c.Provider.AuthenticatedHeaders(),
154 ReqBody: &reqBody,
Jamie Hannafordd9036422014-09-23 17:50:24 +0200155 Results: &res.Resp,
Jamie Hannaford63631432014-09-18 11:40:09 +0200156 OkCodes: []int{201},
157 })
Jamie Hannaford63631432014-09-18 11:40:09 +0200158
Jamie Hannafordd9036422014-09-23 17:50:24 +0200159 return res
Jamie Hannaford63631432014-09-18 11:40:09 +0200160}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200161
Jamie Hannaford686c4962014-09-23 10:46:20 +0200162// UpdateOpts represents the attributes used when updating an existing subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200163type UpdateOpts struct {
164 Name string
165 GatewayIP string
166 DNSNameservers []string
Jamie Hannaford5d93f562014-10-09 10:53:32 +0200167 HostRoutes []HostRoute
Jamie Hannaford965ae702014-09-22 14:58:19 +0200168 EnableDHCP *bool
169}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200170
Jamie Hannaford686c4962014-09-23 10:46:20 +0200171// Update accepts a UpdateOpts struct and updates an existing subnet using the
172// values provided.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200173func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult {
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200174 type subnet struct {
Jamie Hannaford5d93f562014-10-09 10:53:32 +0200175 Name *string `json:"name,omitempty"`
176 GatewayIP *string `json:"gateway_ip,omitempty"`
177 DNSNameservers []string `json:"dns_nameservers,omitempty"`
178 HostRoutes []HostRoute `json:"host_routes,omitempty"`
179 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200180 }
181 type request struct {
182 Subnet subnet `json:"subnet"`
183 }
184
185 reqBody := request{Subnet: subnet{
Jamie Hannaford6abf9282014-09-24 10:54:13 +0200186 Name: gophercloud.MaybeString(opts.Name),
187 GatewayIP: gophercloud.MaybeString(opts.GatewayIP),
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200188 EnableDHCP: opts.EnableDHCP,
189 }}
190
Jamie Hannaford965ae702014-09-22 14:58:19 +0200191 if len(opts.DNSNameservers) != 0 {
192 reqBody.Subnet.DNSNameservers = opts.DNSNameservers
193 }
194
195 if len(opts.HostRoutes) != 0 {
196 reqBody.Subnet.HostRoutes = opts.HostRoutes
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200197 }
198
Jamie Hannafordd9036422014-09-23 17:50:24 +0200199 var res UpdateResult
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +0200200 _, res.Err = perigee.Request("PUT", updateURL(c, id), perigee.Options{
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200201 MoreHeaders: c.Provider.AuthenticatedHeaders(),
202 ReqBody: &reqBody,
Jamie Hannafordd9036422014-09-23 17:50:24 +0200203 Results: &res.Resp,
Jamie Hannafordf84171d2014-09-18 14:00:01 +0200204 OkCodes: []int{200, 201},
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200205 })
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200206
Jamie Hannafordd9036422014-09-23 17:50:24 +0200207 return res
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200208}
209
Jamie Hannaford686c4962014-09-23 10:46:20 +0200210// Delete accepts a unique ID and deletes the subnet associated with it.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200211func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
212 var res DeleteResult
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +0200213 _, res.Err = perigee.Request("DELETE", deleteURL(c, id), perigee.Options{
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200214 MoreHeaders: c.Provider.AuthenticatedHeaders(),
215 OkCodes: []int{204},
216 })
Jamie Hannafordd9036422014-09-23 17:50:24 +0200217 return res
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200218}