blob: 092c91487196b7d32576f8ca84588ae7a67fbe15 [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 Hannaford686c4962014-09-23 10:46:20 +02009// ListOpts allows the filtering and sorting of paginated collections through
10// the API. Filtering is achieved by passing in struct field values that map to
11// the subnet attributes you want to see returned. SortKey allows you to sort
12// by a particular subnet attribute. SortDir sets the direction, and is either
13// `asc' or `desc'. Marker and Limit are used for pagination.
Jamie Hannaford0708c002014-09-17 16:08:49 +020014type ListOpts struct {
Jamie Hannaford5c6e9962014-10-02 10:34:14 +020015 Name string `q:"name"`
16 EnableDHCP *bool `q:"enable_dhcp"`
17 NetworkID string `q:"network_id"`
18 TenantID string `q:"tenant_id"`
19 IPVersion int `q:"ip_version"`
20 GatewayIP string `q:"gateway_ip"`
21 CIDR string `q:"cidr"`
22 ID string `q:"id"`
23 Limit int `q:"limit"`
24 Marker string `q:"marker"`
25 SortKey string `q:"sort_key"`
26 SortDir string `q:"sort_dir"`
Jamie Hannaford0708c002014-09-17 16:08:49 +020027}
28
Jamie Hannaford686c4962014-09-23 10:46:20 +020029// List returns a Pager which allows you to iterate over a collection of
30// subnets. It accepts a ListOpts struct, which allows you to filter and sort
31// the returned collection for greater efficiency.
32//
33// Default policy settings return only those subnets that are owned by the tenant
34// who submits the request, unless the request is submitted by an user with
35// administrative rights.
Jamie Hannaford0708c002014-09-17 16:08:49 +020036func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
37 // Build query parameters
Jamie Hannaford92523e32014-10-02 11:08:36 +020038 query, err := gophercloud.BuildQueryString(&opts)
39 if err != nil {
40 return pagination.Pager{Err: err}
41 }
42 url := listURL(c) + query.String()
Jamie Hannaford0708c002014-09-17 16:08:49 +020043
Jamie Hannaford92523e32014-10-02 11:08:36 +020044 return pagination.NewPager(c, url, func(r pagination.LastHTTPResponse) pagination.Page {
Ash Wilsonfc55c822014-09-25 13:18:16 -040045 return SubnetPage{pagination.LinkedPageBase{LastHTTPResponse: r}}
Jamie Hannaford0708c002014-09-17 16:08:49 +020046 })
47}
48
Jamie Hannaford686c4962014-09-23 10:46:20 +020049// Get retrieves a specific subnet based on its unique ID.
Jamie Hannafordd9036422014-09-23 17:50:24 +020050func Get(c *gophercloud.ServiceClient, id string) GetResult {
51 var res GetResult
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +020052 _, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{
Jamie Hannaford0708c002014-09-17 16:08:49 +020053 MoreHeaders: c.Provider.AuthenticatedHeaders(),
Jamie Hannafordd9036422014-09-23 17:50:24 +020054 Results: &res.Resp,
55 OkCodes: []int{200},
Jamie Hannaford0708c002014-09-17 16:08:49 +020056 })
Jamie Hannafordd9036422014-09-23 17:50:24 +020057 return res
Jamie Hannaford0708c002014-09-17 16:08:49 +020058}
Jamie Hannaford63631432014-09-18 11:40:09 +020059
Jamie Hannaford686c4962014-09-23 10:46:20 +020060// Valid IP types
Jamie Hannaford63631432014-09-18 11:40:09 +020061const (
62 IPv4 = 4
63 IPv6 = 6
64)
65
Jamie Hannaford686c4962014-09-23 10:46:20 +020066// CreateOpts represents the attributes used when creating a new subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +020067type CreateOpts struct {
Jamie Hannaford63631432014-09-18 11:40:09 +020068 // Required
69 NetworkID string
70 CIDR string
71 // Optional
72 Name string
73 TenantID string
74 AllocationPools []AllocationPool
75 GatewayIP string
76 IPVersion int
Jamie Hannaford63631432014-09-18 11:40:09 +020077 EnableDHCP *bool
Jamie Hannaford965ae702014-09-22 14:58:19 +020078 DNSNameservers []string
79 HostRoutes []interface{}
Jamie Hannaford63631432014-09-18 11:40:09 +020080}
81
Jamie Hannaford686c4962014-09-23 10:46:20 +020082// Create accepts a CreateOpts struct and creates a new subnet using the values
83// provided. You must remember to provide a valid NetworkID, CIDR and IP version.
Jamie Hannafordd9036422014-09-23 17:50:24 +020084func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
85 var res CreateResult
86
Jamie Hannaford63631432014-09-18 11:40:09 +020087 // Validate required options
88 if opts.NetworkID == "" {
Jamie Hannafordd9036422014-09-23 17:50:24 +020089 res.Err = errNetworkIDRequired
90 return res
Jamie Hannaford63631432014-09-18 11:40:09 +020091 }
92 if opts.CIDR == "" {
Jamie Hannafordd9036422014-09-23 17:50:24 +020093 res.Err = errCIDRRequired
94 return res
Jamie Hannaford63631432014-09-18 11:40:09 +020095 }
96 if opts.IPVersion != 0 && opts.IPVersion != IPv4 && opts.IPVersion != IPv6 {
Jamie Hannafordd9036422014-09-23 17:50:24 +020097 res.Err = errInvalidIPType
98 return res
Jamie Hannaford63631432014-09-18 11:40:09 +020099 }
100
101 type subnet struct {
102 NetworkID string `json:"network_id"`
103 CIDR string `json:"cidr"`
104 Name *string `json:"name,omitempty"`
105 TenantID *string `json:"tenant_id,omitempty"`
106 AllocationPools []AllocationPool `json:"allocation_pools,omitempty"`
107 GatewayIP *string `json:"gateway_ip,omitempty"`
108 IPVersion int `json:"ip_version,omitempty"`
Jamie Hannaford63631432014-09-18 11:40:09 +0200109 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200110 DNSNameservers []string `json:"dns_nameservers,omitempty"`
111 HostRoutes []interface{} `json:"host_routes,omitempty"`
Jamie Hannaford63631432014-09-18 11:40:09 +0200112 }
113 type request struct {
114 Subnet subnet `json:"subnet"`
115 }
116
117 reqBody := request{Subnet: subnet{
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200118 NetworkID: opts.NetworkID,
119 CIDR: opts.CIDR,
Jamie Hannaford6abf9282014-09-24 10:54:13 +0200120 Name: gophercloud.MaybeString(opts.Name),
121 TenantID: gophercloud.MaybeString(opts.TenantID),
122 GatewayIP: gophercloud.MaybeString(opts.GatewayIP),
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200123 EnableDHCP: opts.EnableDHCP,
Jamie Hannaford63631432014-09-18 11:40:09 +0200124 }}
125
Jamie Hannaford63631432014-09-18 11:40:09 +0200126 if opts.IPVersion != 0 {
127 reqBody.Subnet.IPVersion = opts.IPVersion
128 }
Jamie Hannaford63631432014-09-18 11:40:09 +0200129 if len(opts.AllocationPools) != 0 {
130 reqBody.Subnet.AllocationPools = opts.AllocationPools
131 }
Jamie Hannaford965ae702014-09-22 14:58:19 +0200132 if len(opts.DNSNameservers) != 0 {
133 reqBody.Subnet.DNSNameservers = opts.DNSNameservers
134 }
135 if len(opts.HostRoutes) != 0 {
136 reqBody.Subnet.HostRoutes = opts.HostRoutes
137 }
Jamie Hannaford63631432014-09-18 11:40:09 +0200138
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +0200139 _, res.Err = perigee.Request("POST", createURL(c), perigee.Options{
Jamie Hannaford63631432014-09-18 11:40:09 +0200140 MoreHeaders: c.Provider.AuthenticatedHeaders(),
141 ReqBody: &reqBody,
Jamie Hannafordd9036422014-09-23 17:50:24 +0200142 Results: &res.Resp,
Jamie Hannaford63631432014-09-18 11:40:09 +0200143 OkCodes: []int{201},
144 })
Jamie Hannaford63631432014-09-18 11:40:09 +0200145
Jamie Hannafordd9036422014-09-23 17:50:24 +0200146 return res
Jamie Hannaford63631432014-09-18 11:40:09 +0200147}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200148
Jamie Hannaford686c4962014-09-23 10:46:20 +0200149// UpdateOpts represents the attributes used when updating an existing subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200150type UpdateOpts struct {
151 Name string
152 GatewayIP string
153 DNSNameservers []string
154 HostRoutes []interface{}
155 EnableDHCP *bool
156}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200157
Jamie Hannaford686c4962014-09-23 10:46:20 +0200158// Update accepts a UpdateOpts struct and updates an existing subnet using the
159// values provided.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200160func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult {
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200161 type subnet struct {
Jamie Hannaford965ae702014-09-22 14:58:19 +0200162 Name *string `json:"name,omitempty"`
163 GatewayIP *string `json:"gateway_ip,omitempty"`
164 DNSNameservers []string `json:"dns_nameservers,omitempty"`
165 HostRoutes []interface{} `json:"host_routes,omitempty"`
166 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200167 }
168 type request struct {
169 Subnet subnet `json:"subnet"`
170 }
171
172 reqBody := request{Subnet: subnet{
Jamie Hannaford6abf9282014-09-24 10:54:13 +0200173 Name: gophercloud.MaybeString(opts.Name),
174 GatewayIP: gophercloud.MaybeString(opts.GatewayIP),
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200175 EnableDHCP: opts.EnableDHCP,
176 }}
177
Jamie Hannaford965ae702014-09-22 14:58:19 +0200178 if len(opts.DNSNameservers) != 0 {
179 reqBody.Subnet.DNSNameservers = opts.DNSNameservers
180 }
181
182 if len(opts.HostRoutes) != 0 {
183 reqBody.Subnet.HostRoutes = opts.HostRoutes
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200184 }
185
Jamie Hannafordd9036422014-09-23 17:50:24 +0200186 var res UpdateResult
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +0200187 _, res.Err = perigee.Request("PUT", updateURL(c, id), perigee.Options{
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200188 MoreHeaders: c.Provider.AuthenticatedHeaders(),
189 ReqBody: &reqBody,
Jamie Hannafordd9036422014-09-23 17:50:24 +0200190 Results: &res.Resp,
Jamie Hannafordf84171d2014-09-18 14:00:01 +0200191 OkCodes: []int{200, 201},
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200192 })
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200193
Jamie Hannafordd9036422014-09-23 17:50:24 +0200194 return res
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200195}
196
Jamie Hannaford686c4962014-09-23 10:46:20 +0200197// Delete accepts a unique ID and deletes the subnet associated with it.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200198func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
199 var res DeleteResult
Jamie Hannaford6f57e9e2014-10-02 10:27:28 +0200200 _, res.Err = perigee.Request("DELETE", deleteURL(c, id), perigee.Options{
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200201 MoreHeaders: c.Provider.AuthenticatedHeaders(),
202 OkCodes: []int{204},
203 })
Jamie Hannafordd9036422014-09-23 17:50:24 +0200204 return res
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200205}