| Jamie Hannaford | 89f9af2 | 2014-09-17 12:21:48 +0200 | [diff] [blame] | 1 | package subnets | 
| Jamie Hannaford | 0708c00 | 2014-09-17 16:08:49 +0200 | [diff] [blame] | 2 |  | 
|  | 3 | import ( | 
| Jon Perritt | 27249f4 | 2016-02-18 10:35:59 -0600 | [diff] [blame] | 4 | "github.com/gophercloud/gophercloud" | 
|  | 5 | "github.com/gophercloud/gophercloud/pagination" | 
| Jamie Hannaford | 0708c00 | 2014-09-17 16:08:49 +0200 | [diff] [blame] | 6 | ) | 
|  | 7 |  | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 8 | // ListOptsBuilder allows extensions to add additional parameters to the | 
|  | 9 | // List request. | 
|  | 10 | type ListOptsBuilder interface { | 
| Jon Perritt | 26780d5 | 2014-10-14 11:35:58 -0500 | [diff] [blame] | 11 | ToSubnetListQuery() (string, error) | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 12 | } | 
|  | 13 |  | 
| Jamie Hannaford | 686c496 | 2014-09-23 10:46:20 +0200 | [diff] [blame] | 14 | // 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 Hannaford | 0708c00 | 2014-09-17 16:08:49 +0200 | [diff] [blame] | 19 | type ListOpts struct { | 
| Jamie Hannaford | 5c6e996 | 2014-10-02 10:34:14 +0200 | [diff] [blame] | 20 | 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 Hannaford | 0708c00 | 2014-09-17 16:08:49 +0200 | [diff] [blame] | 32 | } | 
|  | 33 |  | 
| Jon Perritt | 26780d5 | 2014-10-14 11:35:58 -0500 | [diff] [blame] | 34 | // ToSubnetListQuery formats a ListOpts into a query string. | 
|  | 35 | func (opts ListOpts) ToSubnetListQuery() (string, error) { | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 36 | q, err := gophercloud.BuildQueryString(opts) | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 37 | return q.String(), err | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 38 | } | 
|  | 39 |  | 
| Jamie Hannaford | 686c496 | 2014-09-23 10:46:20 +0200 | [diff] [blame] | 40 | // 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 Gaynor | a6d5f9f | 2014-10-27 10:52:32 -0700 | [diff] [blame] | 45 | // who submits the request, unless the request is submitted by a user with | 
| Jamie Hannaford | 686c496 | 2014-09-23 10:46:20 +0200 | [diff] [blame] | 46 | // administrative rights. | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 47 | func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { | 
|  | 48 | url := listURL(c) | 
|  | 49 | if opts != nil { | 
| Jon Perritt | 26780d5 | 2014-10-14 11:35:58 -0500 | [diff] [blame] | 50 | query, err := opts.ToSubnetListQuery() | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 51 | if err != nil { | 
|  | 52 | return pagination.Pager{Err: err} | 
|  | 53 | } | 
|  | 54 | url += query | 
| Jamie Hannaford | 92523e3 | 2014-10-02 11:08:36 +0200 | [diff] [blame] | 55 | } | 
| Ash Wilson | b8b16f8 | 2014-10-20 10:19:49 -0400 | [diff] [blame] | 56 | return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { | 
|  | 57 | return SubnetPage{pagination.LinkedPageBase{PageResult: r}} | 
| Jamie Hannaford | 0708c00 | 2014-09-17 16:08:49 +0200 | [diff] [blame] | 58 | }) | 
|  | 59 | } | 
|  | 60 |  | 
| Jamie Hannaford | 686c496 | 2014-09-23 10:46:20 +0200 | [diff] [blame] | 61 | // Get retrieves a specific subnet based on its unique ID. | 
| Jamie Hannaford | d903642 | 2014-09-23 17:50:24 +0200 | [diff] [blame] | 62 | func Get(c *gophercloud.ServiceClient, id string) GetResult { | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 63 | var r GetResult | 
|  | 64 | _, r.Err = c.Get(getURL(c, id), &r.Body, nil) | 
|  | 65 | return r | 
| Jamie Hannaford | 0708c00 | 2014-09-17 16:08:49 +0200 | [diff] [blame] | 66 | } | 
| Jamie Hannaford | 6363143 | 2014-09-18 11:40:09 +0200 | [diff] [blame] | 67 |  | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 68 | // IPVersion is the IP address version for the subnet. Valid instances are | 
|  | 69 | // 4 and 6 | 
|  | 70 | type IPVersion int | 
|  | 71 |  | 
| Jamie Hannaford | 686c496 | 2014-09-23 10:46:20 +0200 | [diff] [blame] | 72 | // Valid IP types | 
| Jamie Hannaford | 6363143 | 2014-09-18 11:40:09 +0200 | [diff] [blame] | 73 | const ( | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 74 | IPv4 IPVersion = 4 | 
|  | 75 | IPv6 IPVersion = 6 | 
| Jamie Hannaford | 6363143 | 2014-09-18 11:40:09 +0200 | [diff] [blame] | 76 | ) | 
|  | 77 |  | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 78 | // 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. | 
|  | 82 | type CreateOptsBuilder interface { | 
|  | 83 | ToSubnetCreateMap() (map[string]interface{}, error) | 
|  | 84 | } | 
|  | 85 |  | 
| Jamie Hannaford | 686c496 | 2014-09-23 10:46:20 +0200 | [diff] [blame] | 86 | // CreateOpts represents the attributes used when creating a new subnet. | 
| Jamie Hannaford | 965ae70 | 2014-09-22 14:58:19 +0200 | [diff] [blame] | 87 | type CreateOpts struct { | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 88 | 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 Hannaford | 6363143 | 2014-09-18 11:40:09 +0200 | [diff] [blame] | 98 | } | 
|  | 99 |  | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 100 | // ToSubnetCreateMap casts a CreateOpts struct to a map. | 
|  | 101 | func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) { | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 102 | return gophercloud.BuildRequestBody(opts, "subnet") | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 103 | } | 
|  | 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. | 
|  | 107 | func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 108 | var r CreateResult | 
|  | 109 | b, err := opts.ToSubnetCreateMap() | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 110 | if err != nil { | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 111 | r.Err = err | 
|  | 112 | return r | 
| Jamie Hannaford | 965ae70 | 2014-09-22 14:58:19 +0200 | [diff] [blame] | 113 | } | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 114 | _, r.Err = c.Post(createURL(c), b, &r.Body, nil) | 
|  | 115 | return r | 
| Jamie Hannaford | 6363143 | 2014-09-18 11:40:09 +0200 | [diff] [blame] | 116 | } | 
| Jamie Hannaford | d11e20c | 2014-09-18 12:03:01 +0200 | [diff] [blame] | 117 |  | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 118 | // UpdateOptsBuilder allows extensions to add additional parameters to the | 
|  | 119 | // Update request. | 
|  | 120 | type UpdateOptsBuilder interface { | 
|  | 121 | ToSubnetUpdateMap() (map[string]interface{}, error) | 
|  | 122 | } | 
|  | 123 |  | 
| Jamie Hannaford | 686c496 | 2014-09-23 10:46:20 +0200 | [diff] [blame] | 124 | // UpdateOpts represents the attributes used when updating an existing subnet. | 
| Jamie Hannaford | 965ae70 | 2014-09-22 14:58:19 +0200 | [diff] [blame] | 125 | type UpdateOpts struct { | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 126 | 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 Hannaford | 965ae70 | 2014-09-22 14:58:19 +0200 | [diff] [blame] | 131 | } | 
| Jamie Hannaford | d11e20c | 2014-09-18 12:03:01 +0200 | [diff] [blame] | 132 |  | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 133 | // ToSubnetUpdateMap casts an UpdateOpts struct to a map. | 
|  | 134 | func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) { | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 135 | return gophercloud.BuildRequestBody(opts, "subnet") | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 136 | } | 
|  | 137 |  | 
| Jamie Hannaford | 686c496 | 2014-09-23 10:46:20 +0200 | [diff] [blame] | 138 | // Update accepts a UpdateOpts struct and updates an existing subnet using the | 
|  | 139 | // values provided. | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 140 | func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 141 | var r UpdateResult | 
|  | 142 | b, err := opts.ToSubnetUpdateMap() | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 143 | if err != nil { | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 144 | r.Err = err | 
|  | 145 | return r | 
| Jon Perritt | 04851d3 | 2014-10-14 02:07:13 -0500 | [diff] [blame] | 146 | } | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 147 | _, r.Err = c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{ | 
| Jamie Hannaford | 059e150 | 2015-03-24 16:20:32 +0100 | [diff] [blame] | 148 | OkCodes: []int{200, 201}, | 
| Jamie Hannaford | d11e20c | 2014-09-18 12:03:01 +0200 | [diff] [blame] | 149 | }) | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 150 | return r | 
| Jamie Hannaford | d11e20c | 2014-09-18 12:03:01 +0200 | [diff] [blame] | 151 | } | 
|  | 152 |  | 
| Jamie Hannaford | 686c496 | 2014-09-23 10:46:20 +0200 | [diff] [blame] | 153 | // Delete accepts a unique ID and deletes the subnet associated with it. | 
| Jamie Hannaford | d903642 | 2014-09-23 17:50:24 +0200 | [diff] [blame] | 154 | func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 155 | var r DeleteResult | 
|  | 156 | _, r.Err = c.Delete(deleteURL(c, id), nil) | 
|  | 157 | return r | 
| Jamie Hannaford | d11e20c | 2014-09-18 12:03:01 +0200 | [diff] [blame] | 158 | } | 
| Jon Perritt | 7ab1328 | 2015-06-28 18:47:19 -0600 | [diff] [blame] | 159 |  | 
| jrperritt | 5d1d835 | 2015-06-28 19:08:09 -0600 | [diff] [blame] | 160 | // IDFromName is a convenience function that returns a subnet's ID given its name. | 
| Jon Perritt | 7ab1328 | 2015-06-28 18:47:19 -0600 | [diff] [blame] | 161 | func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { | 
| Jon Perritt | e3cb7e4 | 2016-03-07 06:24:11 -0600 | [diff] [blame] | 162 | count := 0 | 
|  | 163 | id := "" | 
| Jon Perritt | e3cb7e4 | 2016-03-07 06:24:11 -0600 | [diff] [blame] | 164 | pages, err := List(client, nil).AllPages() | 
|  | 165 | if err != nil { | 
|  | 166 | return "", err | 
|  | 167 | } | 
| Jon Perritt | 7ab1328 | 2015-06-28 18:47:19 -0600 | [diff] [blame] | 168 |  | 
| Jon Perritt | e3cb7e4 | 2016-03-07 06:24:11 -0600 | [diff] [blame] | 169 | 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 Perritt | 7ab1328 | 2015-06-28 18:47:19 -0600 | [diff] [blame] | 182 | case 0: | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 183 | return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "subnet"} | 
| Jon Perritt | 7ab1328 | 2015-06-28 18:47:19 -0600 | [diff] [blame] | 184 | case 1: | 
| Jon Perritt | e3cb7e4 | 2016-03-07 06:24:11 -0600 | [diff] [blame] | 185 | return id, nil | 
| Jon Perritt | 7ab1328 | 2015-06-28 18:47:19 -0600 | [diff] [blame] | 186 | default: | 
| Jon Perritt | e1c6ceb | 2016-03-14 12:09:36 -0500 | [diff] [blame^] | 187 | return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "subnet"} | 
| Jon Perritt | 7ab1328 | 2015-06-28 18:47:19 -0600 | [diff] [blame] | 188 | } | 
|  | 189 | } |