blob: 2706a5efba00f15cd9c1b4bb851ca3c1ae338d85 [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.
Jon Perritt3860b512016-03-29 12:01:48 -050062func Get(c *gophercloud.ServiceClient, id string) (r GetResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050063 _, r.Err = c.Get(getURL(c, id), &r.Body, nil)
jrperritt29ae6b32016-04-13 12:59:37 -050064 return
Jamie Hannaford0708c002014-09-17 16:08:49 +020065}
Jamie Hannaford63631432014-09-18 11:40:09 +020066
Jon Perritte1c6ceb2016-03-14 12:09:36 -050067// IPVersion is the IP address version for the subnet. Valid instances are
68// 4 and 6
69type IPVersion int
70
Jamie Hannaford686c4962014-09-23 10:46:20 +020071// Valid IP types
Jamie Hannaford63631432014-09-18 11:40:09 +020072const (
Jon Perritte1c6ceb2016-03-14 12:09:36 -050073 IPv4 IPVersion = 4
74 IPv6 IPVersion = 6
Jamie Hannaford63631432014-09-18 11:40:09 +020075)
76
Jon Perritt04851d32014-10-14 02:07:13 -050077// CreateOptsBuilder is the interface options structs have to satisfy in order
78// to be used in the main Create operation in this package. Since many
79// extensions decorate or modify the common logic, it is useful for them to
80// satisfy a basic interface in order for them to be used.
81type CreateOptsBuilder interface {
82 ToSubnetCreateMap() (map[string]interface{}, error)
83}
84
Jamie Hannaford686c4962014-09-23 10:46:20 +020085// CreateOpts represents the attributes used when creating a new subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +020086type CreateOpts struct {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050087 NetworkID string `json:"network_id" required:"true"`
88 CIDR string `json:"cidr" required:"true"`
89 Name string `json:"name,omitempty"`
90 TenantID string `json:"tenant_id,omitempty"`
91 AllocationPools []AllocationPool `json:"allocation_pools,omitempty"`
92 GatewayIP string `json:"gateway_ip,omitempty"`
93 IPVersion IPVersion `json:"ip_version,omitempty"`
94 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
95 DNSNameservers []string `json:"dns_nameservers,omitempty"`
96 HostRoutes []HostRoute `json:"host_routes,omitempty"`
Jamie Hannaford63631432014-09-18 11:40:09 +020097}
98
Jon Perritt04851d32014-10-14 02:07:13 -050099// ToSubnetCreateMap casts a CreateOpts struct to a map.
100func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500101 return gophercloud.BuildRequestBody(opts, "subnet")
Jon Perritt04851d32014-10-14 02:07:13 -0500102}
103
104// Create accepts a CreateOpts struct and creates a new subnet using the values
105// provided. You must remember to provide a valid NetworkID, CIDR and IP version.
Jon Perritt3860b512016-03-29 12:01:48 -0500106func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500107 b, err := opts.ToSubnetCreateMap()
Jon Perritt04851d32014-10-14 02:07:13 -0500108 if err != nil {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500109 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500110 return
Jamie Hannaford965ae702014-09-22 14:58:19 +0200111 }
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500112 _, r.Err = c.Post(createURL(c), b, &r.Body, nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500113 return
Jamie Hannaford63631432014-09-18 11:40:09 +0200114}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200115
Jon Perritt04851d32014-10-14 02:07:13 -0500116// UpdateOptsBuilder allows extensions to add additional parameters to the
117// Update request.
118type UpdateOptsBuilder interface {
119 ToSubnetUpdateMap() (map[string]interface{}, error)
120}
121
Jamie Hannaford686c4962014-09-23 10:46:20 +0200122// UpdateOpts represents the attributes used when updating an existing subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200123type UpdateOpts struct {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500124 Name string `json:"name,omitempty"`
125 GatewayIP string `json:"gateway_ip,omitempty"`
126 DNSNameservers []string `json:"dns_nameservers,omitempty"`
127 HostRoutes []HostRoute `json:"host_routes,omitempty"`
128 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200129}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200130
Jon Perritt04851d32014-10-14 02:07:13 -0500131// ToSubnetUpdateMap casts an UpdateOpts struct to a map.
132func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500133 return gophercloud.BuildRequestBody(opts, "subnet")
Jon Perritt04851d32014-10-14 02:07:13 -0500134}
135
Jamie Hannaford686c4962014-09-23 10:46:20 +0200136// Update accepts a UpdateOpts struct and updates an existing subnet using the
137// values provided.
Jon Perritt3860b512016-03-29 12:01:48 -0500138func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500139 b, err := opts.ToSubnetUpdateMap()
Jon Perritt04851d32014-10-14 02:07:13 -0500140 if err != nil {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500141 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500142 return
Jon Perritt04851d32014-10-14 02:07:13 -0500143 }
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500144 _, r.Err = c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
Jamie Hannaford059e1502015-03-24 16:20:32 +0100145 OkCodes: []int{200, 201},
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200146 })
jrperritt29ae6b32016-04-13 12:59:37 -0500147 return
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200148}
149
Jamie Hannaford686c4962014-09-23 10:46:20 +0200150// Delete accepts a unique ID and deletes the subnet associated with it.
Jon Perritt3860b512016-03-29 12:01:48 -0500151func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500152 _, r.Err = c.Delete(deleteURL(c, id), nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500153 return
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200154}
Jon Perritt7ab13282015-06-28 18:47:19 -0600155
jrperritt5d1d8352015-06-28 19:08:09 -0600156// IDFromName is a convenience function that returns a subnet's ID given its name.
Jon Perritt7ab13282015-06-28 18:47:19 -0600157func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
Jon Perritte3cb7e42016-03-07 06:24:11 -0600158 count := 0
159 id := ""
Jon Perritte3cb7e42016-03-07 06:24:11 -0600160 pages, err := List(client, nil).AllPages()
161 if err != nil {
162 return "", err
163 }
Jon Perritt7ab13282015-06-28 18:47:19 -0600164
Jon Perritte3cb7e42016-03-07 06:24:11 -0600165 all, err := ExtractSubnets(pages)
166 if err != nil {
167 return "", err
168 }
169
170 for _, s := range all {
171 if s.Name == name {
172 count++
173 id = s.ID
174 }
175 }
176
177 switch count {
Jon Perritt7ab13282015-06-28 18:47:19 -0600178 case 0:
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500179 return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "subnet"}
Jon Perritt7ab13282015-06-28 18:47:19 -0600180 case 1:
Jon Perritte3cb7e42016-03-07 06:24:11 -0600181 return id, nil
Jon Perritt7ab13282015-06-28 18:47:19 -0600182 default:
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500183 return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "subnet"}
Jon Perritt7ab13282015-06-28 18:47:19 -0600184 }
185}