blob: a782cf5b7f80926785f6a58dc50cf43a2da81088 [file] [log] [blame]
Jamie Hannaford89f9af22014-09-17 12:21:48 +02001package subnets
Jamie Hannaford0708c002014-09-17 16:08:49 +02002
3import (
Jon Perritt27249f42016-02-18 10:35:59 -06004 "github.com/gophercloud/gophercloud"
5 "github.com/gophercloud/gophercloud/pagination"
Jamie Hannaford0708c002014-09-17 16:08:49 +02006)
7
Jon Perritt04851d32014-10-14 02:07:13 -05008// ListOptsBuilder allows extensions to add additional parameters to the
9// List request.
10type ListOptsBuilder interface {
Jon Perritt26780d52014-10-14 11:35:58 -050011 ToSubnetListQuery() (string, error)
Jon Perritt04851d32014-10-14 02:07:13 -050012}
13
Jamie Hannaford686c4962014-09-23 10:46:20 +020014// ListOpts allows the filtering and sorting of paginated collections through
15// the API. Filtering is achieved by passing in struct field values that map to
16// the subnet attributes you want to see returned. SortKey allows you to sort
17// by a particular subnet attribute. SortDir sets the direction, and is either
18// `asc' or `desc'. Marker and Limit are used for pagination.
Jamie Hannaford0708c002014-09-17 16:08:49 +020019type ListOpts struct {
Jamie Hannaford5c6e9962014-10-02 10:34:14 +020020 Name string `q:"name"`
21 EnableDHCP *bool `q:"enable_dhcp"`
22 NetworkID string `q:"network_id"`
23 TenantID string `q:"tenant_id"`
24 IPVersion int `q:"ip_version"`
25 GatewayIP string `q:"gateway_ip"`
26 CIDR string `q:"cidr"`
27 ID string `q:"id"`
28 Limit int `q:"limit"`
29 Marker string `q:"marker"`
30 SortKey string `q:"sort_key"`
31 SortDir string `q:"sort_dir"`
Jamie Hannaford0708c002014-09-17 16:08:49 +020032}
33
Jon Perritt26780d52014-10-14 11:35:58 -050034// ToSubnetListQuery formats a ListOpts into a query string.
35func (opts ListOpts) ToSubnetListQuery() (string, error) {
Jon Perritt04851d32014-10-14 02:07:13 -050036 q, err := gophercloud.BuildQueryString(opts)
Jon Perritte1c6ceb2016-03-14 12:09:36 -050037 return q.String(), err
Jon Perritt04851d32014-10-14 02:07:13 -050038}
39
Jamie Hannaford686c4962014-09-23 10:46:20 +020040// List returns a Pager which allows you to iterate over a collection of
41// subnets. It accepts a ListOpts struct, which allows you to filter and sort
42// the returned collection for greater efficiency.
43//
44// Default policy settings return only those subnets that are owned by the tenant
Alex Gaynora6d5f9f2014-10-27 10:52:32 -070045// who submits the request, unless the request is submitted by a user with
Jamie Hannaford686c4962014-09-23 10:46:20 +020046// administrative rights.
Jon Perritt04851d32014-10-14 02:07:13 -050047func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
48 url := listURL(c)
49 if opts != nil {
Jon Perritt26780d52014-10-14 11:35:58 -050050 query, err := opts.ToSubnetListQuery()
Jon Perritt04851d32014-10-14 02:07:13 -050051 if err != nil {
52 return pagination.Pager{Err: err}
53 }
54 url += query
Jamie Hannaford92523e32014-10-02 11:08:36 +020055 }
Ash Wilsonb8b16f82014-10-20 10:19:49 -040056 return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
57 return SubnetPage{pagination.LinkedPageBase{PageResult: r}}
Jamie Hannaford0708c002014-09-17 16:08:49 +020058 })
59}
60
Jamie Hannaford686c4962014-09-23 10:46:20 +020061// Get retrieves a specific subnet based on its unique ID.
Jamie Hannafordd9036422014-09-23 17:50:24 +020062func Get(c *gophercloud.ServiceClient, id string) GetResult {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050063 var r GetResult
64 _, r.Err = c.Get(getURL(c, id), &r.Body, nil)
65 return r
Jamie Hannaford0708c002014-09-17 16:08:49 +020066}
Jamie Hannaford63631432014-09-18 11:40:09 +020067
Jon Perritte1c6ceb2016-03-14 12:09:36 -050068// IPVersion is the IP address version for the subnet. Valid instances are
69// 4 and 6
70type IPVersion int
71
Jamie Hannaford686c4962014-09-23 10:46:20 +020072// Valid IP types
Jamie Hannaford63631432014-09-18 11:40:09 +020073const (
Jon Perritte1c6ceb2016-03-14 12:09:36 -050074 IPv4 IPVersion = 4
75 IPv6 IPVersion = 6
Jamie Hannaford63631432014-09-18 11:40:09 +020076)
77
Jon Perritt04851d32014-10-14 02:07:13 -050078// CreateOptsBuilder is the interface options structs have to satisfy in order
79// to be used in the main Create operation in this package. Since many
80// extensions decorate or modify the common logic, it is useful for them to
81// satisfy a basic interface in order for them to be used.
82type CreateOptsBuilder interface {
83 ToSubnetCreateMap() (map[string]interface{}, error)
84}
85
Jamie Hannaford686c4962014-09-23 10:46:20 +020086// CreateOpts represents the attributes used when creating a new subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +020087type CreateOpts struct {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050088 NetworkID string `json:"network_id" required:"true"`
89 CIDR string `json:"cidr" required:"true"`
90 Name string `json:"name,omitempty"`
91 TenantID string `json:"tenant_id,omitempty"`
92 AllocationPools []AllocationPool `json:"allocation_pools,omitempty"`
93 GatewayIP string `json:"gateway_ip,omitempty"`
94 IPVersion IPVersion `json:"ip_version,omitempty"`
95 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
96 DNSNameservers []string `json:"dns_nameservers,omitempty"`
97 HostRoutes []HostRoute `json:"host_routes,omitempty"`
Jamie Hannaford63631432014-09-18 11:40:09 +020098}
99
Jon Perritt04851d32014-10-14 02:07:13 -0500100// ToSubnetCreateMap casts a CreateOpts struct to a map.
101func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500102 return gophercloud.BuildRequestBody(opts, "subnet")
Jon Perritt04851d32014-10-14 02:07:13 -0500103}
104
105// Create accepts a CreateOpts struct and creates a new subnet using the values
106// provided. You must remember to provide a valid NetworkID, CIDR and IP version.
107func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500108 var r CreateResult
109 b, err := opts.ToSubnetCreateMap()
Jon Perritt04851d32014-10-14 02:07:13 -0500110 if err != nil {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500111 r.Err = err
112 return r
Jamie Hannaford965ae702014-09-22 14:58:19 +0200113 }
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500114 _, r.Err = c.Post(createURL(c), b, &r.Body, nil)
115 return r
Jamie Hannaford63631432014-09-18 11:40:09 +0200116}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200117
Jon Perritt04851d32014-10-14 02:07:13 -0500118// UpdateOptsBuilder allows extensions to add additional parameters to the
119// Update request.
120type UpdateOptsBuilder interface {
121 ToSubnetUpdateMap() (map[string]interface{}, error)
122}
123
Jamie Hannaford686c4962014-09-23 10:46:20 +0200124// UpdateOpts represents the attributes used when updating an existing subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200125type UpdateOpts struct {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500126 Name string `json:"name,omitempty"`
127 GatewayIP string `json:"gateway_ip,omitempty"`
128 DNSNameservers []string `json:"dns_nameservers,omitempty"`
129 HostRoutes []HostRoute `json:"host_routes,omitempty"`
130 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200131}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200132
Jon Perritt04851d32014-10-14 02:07:13 -0500133// ToSubnetUpdateMap casts an UpdateOpts struct to a map.
134func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500135 return gophercloud.BuildRequestBody(opts, "subnet")
Jon Perritt04851d32014-10-14 02:07:13 -0500136}
137
Jamie Hannaford686c4962014-09-23 10:46:20 +0200138// Update accepts a UpdateOpts struct and updates an existing subnet using the
139// values provided.
Jon Perritt04851d32014-10-14 02:07:13 -0500140func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500141 var r UpdateResult
142 b, err := opts.ToSubnetUpdateMap()
Jon Perritt04851d32014-10-14 02:07:13 -0500143 if err != nil {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500144 r.Err = err
145 return r
Jon Perritt04851d32014-10-14 02:07:13 -0500146 }
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500147 _, r.Err = c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
Jamie Hannaford059e1502015-03-24 16:20:32 +0100148 OkCodes: []int{200, 201},
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200149 })
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500150 return r
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200151}
152
Jamie Hannaford686c4962014-09-23 10:46:20 +0200153// Delete accepts a unique ID and deletes the subnet associated with it.
Jamie Hannafordd9036422014-09-23 17:50:24 +0200154func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500155 var r DeleteResult
156 _, r.Err = c.Delete(deleteURL(c, id), nil)
157 return r
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200158}
Jon Perritt7ab13282015-06-28 18:47:19 -0600159
jrperritt5d1d8352015-06-28 19:08:09 -0600160// IDFromName is a convenience function that returns a subnet's ID given its name.
Jon Perritt7ab13282015-06-28 18:47:19 -0600161func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
Jon Perritte3cb7e42016-03-07 06:24:11 -0600162 count := 0
163 id := ""
Jon Perritte3cb7e42016-03-07 06:24:11 -0600164 pages, err := List(client, nil).AllPages()
165 if err != nil {
166 return "", err
167 }
Jon Perritt7ab13282015-06-28 18:47:19 -0600168
Jon Perritte3cb7e42016-03-07 06:24:11 -0600169 all, err := ExtractSubnets(pages)
170 if err != nil {
171 return "", err
172 }
173
174 for _, s := range all {
175 if s.Name == name {
176 count++
177 id = s.ID
178 }
179 }
180
181 switch count {
Jon Perritt7ab13282015-06-28 18:47:19 -0600182 case 0:
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500183 return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "subnet"}
Jon Perritt7ab13282015-06-28 18:47:19 -0600184 case 1:
Jon Perritte3cb7e42016-03-07 06:24:11 -0600185 return id, nil
Jon Perritt7ab13282015-06-28 18:47:19 -0600186 default:
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500187 return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "subnet"}
Jon Perritt7ab13282015-06-28 18:47:19 -0600188 }
189}