blob: 436e109bc62d5c7a1fa5c55b81d4b747b424d605 [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 Hannaford0708c002014-09-17 16:08:49 +020024}
25
26func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
27 // Build query parameters
28 q := make(map[string]string)
29 if opts.Name != "" {
30 q["name"] = opts.Name
31 }
32 if opts.EnableDHCP != nil {
33 q["enable_dhcp"] = strconv.FormatBool(*opts.EnableDHCP)
34 }
35 if opts.NetworkID != "" {
36 q["network_id"] = opts.NetworkID
37 }
38 if opts.TenantID != "" {
39 q["tenant_id"] = opts.TenantID
40 }
41 if opts.IPVersion != 0 {
42 q["ip_version"] = strconv.Itoa(opts.IPVersion)
43 }
44 if opts.GatewayIP != "" {
45 q["gateway_ip"] = opts.GatewayIP
46 }
47 if opts.CIDR != "" {
48 q["cidr"] = opts.CIDR
49 }
50 if opts.ID != "" {
51 q["id"] = opts.ID
52 }
Jamie Hannafordf84171d2014-09-18 14:00:01 +020053 if opts.Limit != 0 {
54 q["limit"] = strconv.Itoa(opts.Limit)
55 }
56 if opts.Page != "" {
57 q["page"] = opts.Page
58 }
59 if opts.PerPage != "" {
60 q["per_page"] = opts.PerPage
61 }
Jamie Hannaford0708c002014-09-17 16:08:49 +020062
63 u := ListURL(c) + utils.BuildQuery(q)
64 return pagination.NewPager(c, u, func(r pagination.LastHTTPResponse) pagination.Page {
65 return SubnetPage{pagination.LinkedPageBase(r)}
66 })
67}
68
69func Get(c *gophercloud.ServiceClient, id string) (*Subnet, error) {
70 var s Subnet
71 _, err := perigee.Request("GET", GetURL(c, id), perigee.Options{
72 MoreHeaders: c.Provider.AuthenticatedHeaders(),
73 Results: &struct {
74 Subnet *Subnet `json:"subnet"`
75 }{&s},
76 OkCodes: []int{200},
77 })
78 if err != nil {
79 return nil, err
80 }
81 return &s, nil
82}
Jamie Hannaford63631432014-09-18 11:40:09 +020083
84const (
85 IPv4 = 4
86 IPv6 = 6
87)
88
89type SubnetOpts struct {
90 // Required
91 NetworkID string
92 CIDR string
93 // Optional
94 Name string
95 TenantID string
96 AllocationPools []AllocationPool
97 GatewayIP string
98 IPVersion int
99 ID string
100 EnableDHCP *bool
101}
102
103// maybeString returns nil for empty strings and nil for empty.
104func maybeString(original string) *string {
105 if original != "" {
106 return &original
107 }
108 return nil
109}
110
111func Create(c *gophercloud.ServiceClient, opts SubnetOpts) (*Subnet, error) {
112 // Validate required options
113 if opts.NetworkID == "" {
114 return nil, ErrNetworkIDRequired
115 }
116 if opts.CIDR == "" {
117 return nil, ErrCIDRRequired
118 }
119 if opts.IPVersion != 0 && opts.IPVersion != IPv4 && opts.IPVersion != IPv6 {
120 return nil, ErrInvalidIPType
121 }
122
123 type subnet struct {
124 NetworkID string `json:"network_id"`
125 CIDR string `json:"cidr"`
126 Name *string `json:"name,omitempty"`
127 TenantID *string `json:"tenant_id,omitempty"`
128 AllocationPools []AllocationPool `json:"allocation_pools,omitempty"`
129 GatewayIP *string `json:"gateway_ip,omitempty"`
130 IPVersion int `json:"ip_version,omitempty"`
131 ID *string `json:"id,omitempty"`
132 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
133 }
134 type request struct {
135 Subnet subnet `json:"subnet"`
136 }
137
138 reqBody := request{Subnet: subnet{
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200139 NetworkID: opts.NetworkID,
140 CIDR: opts.CIDR,
141 Name: maybeString(opts.Name),
142 TenantID: maybeString(opts.TenantID),
143 GatewayIP: maybeString(opts.GatewayIP),
144 ID: maybeString(opts.ID),
145 EnableDHCP: opts.EnableDHCP,
Jamie Hannaford63631432014-09-18 11:40:09 +0200146 }}
147
Jamie Hannaford63631432014-09-18 11:40:09 +0200148 if opts.IPVersion != 0 {
149 reqBody.Subnet.IPVersion = opts.IPVersion
150 }
151
152 if len(opts.AllocationPools) != 0 {
153 reqBody.Subnet.AllocationPools = opts.AllocationPools
154 }
155
156 type response struct {
157 Subnet *Subnet `json:"subnet"`
158 }
159
160 var res response
161 _, err := perigee.Request("POST", CreateURL(c), perigee.Options{
162 MoreHeaders: c.Provider.AuthenticatedHeaders(),
163 ReqBody: &reqBody,
164 Results: &res,
165 OkCodes: []int{201},
166 })
167 if err != nil {
168 return nil, err
169 }
170
171 return res.Subnet, nil
172}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200173
174func Update(c *gophercloud.ServiceClient, id string, opts SubnetOpts) (*Subnet, error) {
175 if opts.CIDR != "" {
176 return nil, ErrCIDRNotUpdatable
177 }
178 if opts.IPVersion != 0 {
179 return nil, ErrIPVersionNotUpdatable
180 }
181
182 type subnet struct {
183 NetworkID string `json:"network_id,omitempty"`
184 Name *string `json:"name,omitempty"`
185 TenantID *string `json:"tenant_id,omitempty"`
186 AllocationPools []AllocationPool `json:"allocation_pools,omitempty"`
187 GatewayIP *string `json:"gateway_ip,omitempty"`
188 ID *string `json:"id,omitempty"`
189 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
190 }
191 type request struct {
192 Subnet subnet `json:"subnet"`
193 }
194
195 reqBody := request{Subnet: subnet{
196 NetworkID: opts.NetworkID,
197 Name: maybeString(opts.Name),
198 TenantID: maybeString(opts.TenantID),
199 GatewayIP: maybeString(opts.GatewayIP),
200 ID: maybeString(opts.ID),
201 EnableDHCP: opts.EnableDHCP,
202 }}
203
204 if len(opts.AllocationPools) != 0 {
205 reqBody.Subnet.AllocationPools = opts.AllocationPools
206 }
207
208 type response struct {
209 Subnet *Subnet `json:"subnet"`
210 }
211
212 var res response
213 _, err := perigee.Request("PUT", UpdateURL(c, id), perigee.Options{
214 MoreHeaders: c.Provider.AuthenticatedHeaders(),
215 ReqBody: &reqBody,
216 Results: &res,
Jamie Hannafordf84171d2014-09-18 14:00:01 +0200217 OkCodes: []int{200, 201},
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200218 })
219 if err != nil {
220 return nil, err
221 }
222
223 return res.Subnet, nil
224}
225
226func Delete(c *gophercloud.ServiceClient, id string) error {
227 _, err := perigee.Request("DELETE", DeleteURL(c, id), perigee.Options{
228 MoreHeaders: c.Provider.AuthenticatedHeaders(),
229 OkCodes: []int{204},
230 })
231 return err
232}