blob: ff36765322cc7b1b2e37fc7dbdec79dc31b68eb3 [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
12type ListOpts struct {
13 Name string
14 EnableDHCP *bool
15 NetworkID string
16 TenantID string
17 IPVersion int
18 GatewayIP string
19 CIDR string
20 ID string
Jamie Hannafordf84171d2014-09-18 14:00:01 +020021 Limit int
22 Page string
23 PerPage string
Jamie Hannafordd0f090c2014-09-22 13:44:34 +020024 SortKey string
25 SortDir string
Jamie Hannaford0708c002014-09-17 16:08:49 +020026}
27
28func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
29 // Build query parameters
30 q := make(map[string]string)
31 if opts.Name != "" {
32 q["name"] = opts.Name
33 }
34 if opts.EnableDHCP != nil {
35 q["enable_dhcp"] = strconv.FormatBool(*opts.EnableDHCP)
36 }
37 if opts.NetworkID != "" {
38 q["network_id"] = opts.NetworkID
39 }
40 if opts.TenantID != "" {
41 q["tenant_id"] = opts.TenantID
42 }
43 if opts.IPVersion != 0 {
44 q["ip_version"] = strconv.Itoa(opts.IPVersion)
45 }
46 if opts.GatewayIP != "" {
47 q["gateway_ip"] = opts.GatewayIP
48 }
49 if opts.CIDR != "" {
50 q["cidr"] = opts.CIDR
51 }
52 if opts.ID != "" {
53 q["id"] = opts.ID
54 }
Jamie Hannafordf84171d2014-09-18 14:00:01 +020055 if opts.Limit != 0 {
56 q["limit"] = strconv.Itoa(opts.Limit)
57 }
58 if opts.Page != "" {
59 q["page"] = opts.Page
60 }
61 if opts.PerPage != "" {
62 q["per_page"] = opts.PerPage
63 }
Jamie Hannafordd0f090c2014-09-22 13:44:34 +020064 if opts.SortKey != "" {
65 q["sort_key"] = opts.SortKey
66 }
67 if opts.SortDir != "" {
68 q["sort_dir"] = opts.SortDir
69 }
Jamie Hannaford0708c002014-09-17 16:08:49 +020070
71 u := ListURL(c) + utils.BuildQuery(q)
72 return pagination.NewPager(c, u, func(r pagination.LastHTTPResponse) pagination.Page {
73 return SubnetPage{pagination.LinkedPageBase(r)}
74 })
75}
76
77func Get(c *gophercloud.ServiceClient, id string) (*Subnet, error) {
78 var s Subnet
79 _, err := perigee.Request("GET", GetURL(c, id), perigee.Options{
80 MoreHeaders: c.Provider.AuthenticatedHeaders(),
81 Results: &struct {
82 Subnet *Subnet `json:"subnet"`
83 }{&s},
84 OkCodes: []int{200},
85 })
86 if err != nil {
87 return nil, err
88 }
89 return &s, nil
90}
Jamie Hannaford63631432014-09-18 11:40:09 +020091
Jamie Hannaford965ae702014-09-22 14:58:19 +020092// maybeString returns nil for empty strings and nil for empty.
93func maybeString(original string) *string {
94 if original != "" {
95 return &original
96 }
97 return nil
98}
99
Jamie Hannaford63631432014-09-18 11:40:09 +0200100const (
101 IPv4 = 4
102 IPv6 = 6
103)
104
Jamie Hannaford965ae702014-09-22 14:58:19 +0200105type CreateOpts struct {
Jamie Hannaford63631432014-09-18 11:40:09 +0200106 // Required
107 NetworkID string
108 CIDR string
109 // Optional
110 Name string
111 TenantID string
112 AllocationPools []AllocationPool
113 GatewayIP string
114 IPVersion int
Jamie Hannaford63631432014-09-18 11:40:09 +0200115 EnableDHCP *bool
Jamie Hannaford965ae702014-09-22 14:58:19 +0200116 DNSNameservers []string
117 HostRoutes []interface{}
Jamie Hannaford63631432014-09-18 11:40:09 +0200118}
119
Jamie Hannaford965ae702014-09-22 14:58:19 +0200120func Create(c *gophercloud.ServiceClient, opts CreateOpts) (*Subnet, error) {
Jamie Hannaford63631432014-09-18 11:40:09 +0200121 // Validate required options
122 if opts.NetworkID == "" {
123 return nil, ErrNetworkIDRequired
124 }
125 if opts.CIDR == "" {
126 return nil, ErrCIDRRequired
127 }
128 if opts.IPVersion != 0 && opts.IPVersion != IPv4 && opts.IPVersion != IPv6 {
129 return nil, ErrInvalidIPType
130 }
131
132 type subnet struct {
133 NetworkID string `json:"network_id"`
134 CIDR string `json:"cidr"`
135 Name *string `json:"name,omitempty"`
136 TenantID *string `json:"tenant_id,omitempty"`
137 AllocationPools []AllocationPool `json:"allocation_pools,omitempty"`
138 GatewayIP *string `json:"gateway_ip,omitempty"`
139 IPVersion int `json:"ip_version,omitempty"`
Jamie Hannaford63631432014-09-18 11:40:09 +0200140 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200141 DNSNameservers []string `json:"dns_nameservers,omitempty"`
142 HostRoutes []interface{} `json:"host_routes,omitempty"`
Jamie Hannaford63631432014-09-18 11:40:09 +0200143 }
144 type request struct {
145 Subnet subnet `json:"subnet"`
146 }
147
148 reqBody := request{Subnet: subnet{
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200149 NetworkID: opts.NetworkID,
150 CIDR: opts.CIDR,
151 Name: maybeString(opts.Name),
152 TenantID: maybeString(opts.TenantID),
153 GatewayIP: maybeString(opts.GatewayIP),
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200154 EnableDHCP: opts.EnableDHCP,
Jamie Hannaford63631432014-09-18 11:40:09 +0200155 }}
156
Jamie Hannaford63631432014-09-18 11:40:09 +0200157 if opts.IPVersion != 0 {
158 reqBody.Subnet.IPVersion = opts.IPVersion
159 }
Jamie Hannaford63631432014-09-18 11:40:09 +0200160 if len(opts.AllocationPools) != 0 {
161 reqBody.Subnet.AllocationPools = opts.AllocationPools
162 }
Jamie Hannaford965ae702014-09-22 14:58:19 +0200163 if len(opts.DNSNameservers) != 0 {
164 reqBody.Subnet.DNSNameservers = opts.DNSNameservers
165 }
166 if len(opts.HostRoutes) != 0 {
167 reqBody.Subnet.HostRoutes = opts.HostRoutes
168 }
Jamie Hannaford63631432014-09-18 11:40:09 +0200169
170 type response struct {
171 Subnet *Subnet `json:"subnet"`
172 }
173
174 var res response
175 _, err := perigee.Request("POST", CreateURL(c), perigee.Options{
176 MoreHeaders: c.Provider.AuthenticatedHeaders(),
177 ReqBody: &reqBody,
178 Results: &res,
179 OkCodes: []int{201},
180 })
181 if err != nil {
182 return nil, err
183 }
184
185 return res.Subnet, nil
186}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200187
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 Hannaford965ae702014-09-22 14:58:19 +0200196func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) (*Subnet, error) {
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200197 type subnet struct {
Jamie Hannaford965ae702014-09-22 14:58:19 +0200198 Name *string `json:"name,omitempty"`
199 GatewayIP *string `json:"gateway_ip,omitempty"`
200 DNSNameservers []string `json:"dns_nameservers,omitempty"`
201 HostRoutes []interface{} `json:"host_routes,omitempty"`
202 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200203 }
204 type request struct {
205 Subnet subnet `json:"subnet"`
206 }
207
208 reqBody := request{Subnet: subnet{
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200209 Name: maybeString(opts.Name),
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200210 GatewayIP: maybeString(opts.GatewayIP),
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200211 EnableDHCP: opts.EnableDHCP,
212 }}
213
Jamie Hannaford965ae702014-09-22 14:58:19 +0200214 if len(opts.DNSNameservers) != 0 {
215 reqBody.Subnet.DNSNameservers = opts.DNSNameservers
216 }
217
218 if len(opts.HostRoutes) != 0 {
219 reqBody.Subnet.HostRoutes = opts.HostRoutes
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200220 }
221
222 type response struct {
223 Subnet *Subnet `json:"subnet"`
224 }
225
226 var res response
227 _, err := perigee.Request("PUT", UpdateURL(c, id), perigee.Options{
228 MoreHeaders: c.Provider.AuthenticatedHeaders(),
229 ReqBody: &reqBody,
230 Results: &res,
Jamie Hannafordf84171d2014-09-18 14:00:01 +0200231 OkCodes: []int{200, 201},
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200232 })
233 if err != nil {
234 return nil, err
235 }
236
237 return res.Subnet, nil
238}
239
240func Delete(c *gophercloud.ServiceClient, id string) error {
241 _, err := perigee.Request("DELETE", DeleteURL(c, id), perigee.Options{
242 MoreHeaders: c.Provider.AuthenticatedHeaders(),
243 OkCodes: []int{204},
244 })
245 return err
246}