blob: 5491f3c75412070debb63cfdbcbd559507e21786 [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)
Jamie Hannaford0708c002014-09-17 16:08:49 +020064}
Jamie Hannaford63631432014-09-18 11:40:09 +020065
Jon Perritte1c6ceb2016-03-14 12:09:36 -050066// IPVersion is the IP address version for the subnet. Valid instances are
67// 4 and 6
68type IPVersion int
69
Jamie Hannaford686c4962014-09-23 10:46:20 +020070// Valid IP types
Jamie Hannaford63631432014-09-18 11:40:09 +020071const (
Jon Perritte1c6ceb2016-03-14 12:09:36 -050072 IPv4 IPVersion = 4
73 IPv6 IPVersion = 6
Jamie Hannaford63631432014-09-18 11:40:09 +020074)
75
Jon Perritt04851d32014-10-14 02:07:13 -050076// CreateOptsBuilder is the interface options structs have to satisfy in order
77// to be used in the main Create operation in this package. Since many
78// extensions decorate or modify the common logic, it is useful for them to
79// satisfy a basic interface in order for them to be used.
80type CreateOptsBuilder interface {
81 ToSubnetCreateMap() (map[string]interface{}, error)
82}
83
Jamie Hannaford686c4962014-09-23 10:46:20 +020084// CreateOpts represents the attributes used when creating a new subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +020085type CreateOpts struct {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050086 NetworkID string `json:"network_id" required:"true"`
87 CIDR string `json:"cidr" required:"true"`
88 Name string `json:"name,omitempty"`
89 TenantID string `json:"tenant_id,omitempty"`
90 AllocationPools []AllocationPool `json:"allocation_pools,omitempty"`
91 GatewayIP string `json:"gateway_ip,omitempty"`
92 IPVersion IPVersion `json:"ip_version,omitempty"`
93 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
94 DNSNameservers []string `json:"dns_nameservers,omitempty"`
95 HostRoutes []HostRoute `json:"host_routes,omitempty"`
Jamie Hannaford63631432014-09-18 11:40:09 +020096}
97
Jon Perritt04851d32014-10-14 02:07:13 -050098// ToSubnetCreateMap casts a CreateOpts struct to a map.
99func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500100 return gophercloud.BuildRequestBody(opts, "subnet")
Jon Perritt04851d32014-10-14 02:07:13 -0500101}
102
103// Create accepts a CreateOpts struct and creates a new subnet using the values
104// provided. You must remember to provide a valid NetworkID, CIDR and IP version.
Jon Perritt3860b512016-03-29 12:01:48 -0500105func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500106 b, err := opts.ToSubnetCreateMap()
Jon Perritt04851d32014-10-14 02:07:13 -0500107 if err != nil {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500108 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500109 return
Jamie Hannaford965ae702014-09-22 14:58:19 +0200110 }
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500111 _, r.Err = c.Post(createURL(c), b, &r.Body, nil)
Jamie Hannaford63631432014-09-18 11:40:09 +0200112}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200113
Jon Perritt04851d32014-10-14 02:07:13 -0500114// UpdateOptsBuilder allows extensions to add additional parameters to the
115// Update request.
116type UpdateOptsBuilder interface {
117 ToSubnetUpdateMap() (map[string]interface{}, error)
118}
119
Jamie Hannaford686c4962014-09-23 10:46:20 +0200120// UpdateOpts represents the attributes used when updating an existing subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200121type UpdateOpts struct {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500122 Name string `json:"name,omitempty"`
123 GatewayIP string `json:"gateway_ip,omitempty"`
124 DNSNameservers []string `json:"dns_nameservers,omitempty"`
125 HostRoutes []HostRoute `json:"host_routes,omitempty"`
126 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200127}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200128
Jon Perritt04851d32014-10-14 02:07:13 -0500129// ToSubnetUpdateMap casts an UpdateOpts struct to a map.
130func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500131 return gophercloud.BuildRequestBody(opts, "subnet")
Jon Perritt04851d32014-10-14 02:07:13 -0500132}
133
Jamie Hannaford686c4962014-09-23 10:46:20 +0200134// Update accepts a UpdateOpts struct and updates an existing subnet using the
135// values provided.
Jon Perritt3860b512016-03-29 12:01:48 -0500136func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500137 b, err := opts.ToSubnetUpdateMap()
Jon Perritt04851d32014-10-14 02:07:13 -0500138 if err != nil {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500139 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500140 return
Jon Perritt04851d32014-10-14 02:07:13 -0500141 }
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500142 _, r.Err = c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
Jamie Hannaford059e1502015-03-24 16:20:32 +0100143 OkCodes: []int{200, 201},
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200144 })
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200145}
146
Jamie Hannaford686c4962014-09-23 10:46:20 +0200147// Delete accepts a unique ID and deletes the subnet associated with it.
Jon Perritt3860b512016-03-29 12:01:48 -0500148func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500149 _, r.Err = c.Delete(deleteURL(c, id), nil)
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200150}
Jon Perritt7ab13282015-06-28 18:47:19 -0600151
jrperritt5d1d8352015-06-28 19:08:09 -0600152// IDFromName is a convenience function that returns a subnet's ID given its name.
Jon Perritt7ab13282015-06-28 18:47:19 -0600153func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
Jon Perritte3cb7e42016-03-07 06:24:11 -0600154 count := 0
155 id := ""
Jon Perritte3cb7e42016-03-07 06:24:11 -0600156 pages, err := List(client, nil).AllPages()
157 if err != nil {
158 return "", err
159 }
Jon Perritt7ab13282015-06-28 18:47:19 -0600160
Jon Perritte3cb7e42016-03-07 06:24:11 -0600161 all, err := ExtractSubnets(pages)
162 if err != nil {
163 return "", err
164 }
165
166 for _, s := range all {
167 if s.Name == name {
168 count++
169 id = s.ID
170 }
171 }
172
173 switch count {
Jon Perritt7ab13282015-06-28 18:47:19 -0600174 case 0:
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500175 return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "subnet"}
Jon Perritt7ab13282015-06-28 18:47:19 -0600176 case 1:
Jon Perritte3cb7e42016-03-07 06:24:11 -0600177 return id, nil
Jon Perritt7ab13282015-06-28 18:47:19 -0600178 default:
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500179 return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "subnet"}
Jon Perritt7ab13282015-06-28 18:47:19 -0600180 }
181}