blob: 769474dfa1187f71a625e9f63b44bdf9a505654e [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 Perritt04851d32014-10-14 02:07:13 -050067// CreateOptsBuilder is the interface options structs have to satisfy in order
68// to be used in the main Create operation in this package. Since many
69// extensions decorate or modify the common logic, it is useful for them to
70// satisfy a basic interface in order for them to be used.
71type CreateOptsBuilder interface {
72 ToSubnetCreateMap() (map[string]interface{}, error)
73}
74
Jamie Hannaford686c4962014-09-23 10:46:20 +020075// CreateOpts represents the attributes used when creating a new subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +020076type CreateOpts struct {
jrperrittbc548612016-04-13 17:03:59 -050077 NetworkID string `json:"network_id" required:"true"`
78 CIDR string `json:"cidr" required:"true"`
79 Name string `json:"name,omitempty"`
80 TenantID string `json:"tenant_id,omitempty"`
81 AllocationPools []AllocationPool `json:"allocation_pools,omitempty"`
82 GatewayIP *string `json:"gateway_ip"`
83 IPVersion gophercloud.IPVersion `json:"ip_version,omitempty"`
84 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
85 DNSNameservers []string `json:"dns_nameservers,omitempty"`
86 HostRoutes []HostRoute `json:"host_routes,omitempty"`
Jamie Hannaford63631432014-09-18 11:40:09 +020087}
88
Jon Perritt04851d32014-10-14 02:07:13 -050089// ToSubnetCreateMap casts a CreateOpts struct to a map.
90func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050091 return gophercloud.BuildRequestBody(opts, "subnet")
Jon Perritt04851d32014-10-14 02:07:13 -050092}
93
94// Create accepts a CreateOpts struct and creates a new subnet using the values
95// provided. You must remember to provide a valid NetworkID, CIDR and IP version.
Jon Perritt3860b512016-03-29 12:01:48 -050096func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050097 b, err := opts.ToSubnetCreateMap()
Jon Perritt04851d32014-10-14 02:07:13 -050098 if err != nil {
Jon Perritte1c6ceb2016-03-14 12:09:36 -050099 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500100 return
Jamie Hannaford965ae702014-09-22 14:58:19 +0200101 }
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500102 _, r.Err = c.Post(createURL(c), b, &r.Body, nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500103 return
Jamie Hannaford63631432014-09-18 11:40:09 +0200104}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200105
Jon Perritt04851d32014-10-14 02:07:13 -0500106// UpdateOptsBuilder allows extensions to add additional parameters to the
107// Update request.
108type UpdateOptsBuilder interface {
109 ToSubnetUpdateMap() (map[string]interface{}, error)
110}
111
Jamie Hannaford686c4962014-09-23 10:46:20 +0200112// UpdateOpts represents the attributes used when updating an existing subnet.
Jamie Hannaford965ae702014-09-22 14:58:19 +0200113type UpdateOpts struct {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500114 Name string `json:"name,omitempty"`
115 GatewayIP string `json:"gateway_ip,omitempty"`
116 DNSNameservers []string `json:"dns_nameservers,omitempty"`
117 HostRoutes []HostRoute `json:"host_routes,omitempty"`
118 EnableDHCP *bool `json:"enable_dhcp,omitempty"`
Jamie Hannaford965ae702014-09-22 14:58:19 +0200119}
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200120
Jon Perritt04851d32014-10-14 02:07:13 -0500121// ToSubnetUpdateMap casts an UpdateOpts struct to a map.
122func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500123 return gophercloud.BuildRequestBody(opts, "subnet")
Jon Perritt04851d32014-10-14 02:07:13 -0500124}
125
Jamie Hannaford686c4962014-09-23 10:46:20 +0200126// Update accepts a UpdateOpts struct and updates an existing subnet using the
127// values provided.
Jon Perritt3860b512016-03-29 12:01:48 -0500128func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500129 b, err := opts.ToSubnetUpdateMap()
Jon Perritt04851d32014-10-14 02:07:13 -0500130 if err != nil {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500131 r.Err = err
Jon Perritt3860b512016-03-29 12:01:48 -0500132 return
Jon Perritt04851d32014-10-14 02:07:13 -0500133 }
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500134 _, r.Err = c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
Jamie Hannaford059e1502015-03-24 16:20:32 +0100135 OkCodes: []int{200, 201},
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200136 })
jrperritt29ae6b32016-04-13 12:59:37 -0500137 return
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200138}
139
Jamie Hannaford686c4962014-09-23 10:46:20 +0200140// Delete accepts a unique ID and deletes the subnet associated with it.
Jon Perritt3860b512016-03-29 12:01:48 -0500141func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500142 _, r.Err = c.Delete(deleteURL(c, id), nil)
jrperritt29ae6b32016-04-13 12:59:37 -0500143 return
Jamie Hannafordd11e20c2014-09-18 12:03:01 +0200144}
Jon Perritt7ab13282015-06-28 18:47:19 -0600145
jrperritt5d1d8352015-06-28 19:08:09 -0600146// IDFromName is a convenience function that returns a subnet's ID given its name.
Jon Perritt7ab13282015-06-28 18:47:19 -0600147func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
Jon Perritte3cb7e42016-03-07 06:24:11 -0600148 count := 0
149 id := ""
Jon Perritte3cb7e42016-03-07 06:24:11 -0600150 pages, err := List(client, nil).AllPages()
151 if err != nil {
152 return "", err
153 }
Jon Perritt7ab13282015-06-28 18:47:19 -0600154
Jon Perritte3cb7e42016-03-07 06:24:11 -0600155 all, err := ExtractSubnets(pages)
156 if err != nil {
157 return "", err
158 }
159
160 for _, s := range all {
161 if s.Name == name {
162 count++
163 id = s.ID
164 }
165 }
166
167 switch count {
Jon Perritt7ab13282015-06-28 18:47:19 -0600168 case 0:
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500169 return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "subnet"}
Jon Perritt7ab13282015-06-28 18:47:19 -0600170 case 1:
Jon Perritte3cb7e42016-03-07 06:24:11 -0600171 return id, nil
Jon Perritt7ab13282015-06-28 18:47:19 -0600172 default:
Jon Perritte1c6ceb2016-03-14 12:09:36 -0500173 return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "subnet"}
Jon Perritt7ab13282015-06-28 18:47:19 -0600174 }
175}