|  | package subnets | 
|  |  | 
|  | import ( | 
|  | "github.com/rackspace/gophercloud" | 
|  | "github.com/rackspace/gophercloud/pagination" | 
|  |  | 
|  | "github.com/racker/perigee" | 
|  | ) | 
|  |  | 
|  | // AdminState gives users a solid type to work with for create and update | 
|  | // operations. It is recommended that users use the `Up` and `Down` enums. | 
|  | type AdminState *bool | 
|  |  | 
|  | // Convenience vars for AdminStateUp values. | 
|  | var ( | 
|  | iTrue  = true | 
|  | iFalse = false | 
|  |  | 
|  | Up   AdminState = &iTrue | 
|  | Down AdminState = &iFalse | 
|  | ) | 
|  |  | 
|  | // ListOptsBuilder allows extensions to add additional parameters to the | 
|  | // List request. | 
|  | type ListOptsBuilder interface { | 
|  | ToSubnetListQuery() (string, error) | 
|  | } | 
|  |  | 
|  | // ListOpts allows the filtering and sorting of paginated collections through | 
|  | // the API. Filtering is achieved by passing in struct field values that map to | 
|  | // the subnet attributes you want to see returned. SortKey allows you to sort | 
|  | // by a particular subnet attribute. SortDir sets the direction, and is either | 
|  | // `asc' or `desc'. Marker and Limit are used for pagination. | 
|  | type ListOpts struct { | 
|  | Name       string `q:"name"` | 
|  | EnableDHCP *bool  `q:"enable_dhcp"` | 
|  | NetworkID  string `q:"network_id"` | 
|  | TenantID   string `q:"tenant_id"` | 
|  | IPVersion  int    `q:"ip_version"` | 
|  | GatewayIP  string `q:"gateway_ip"` | 
|  | CIDR       string `q:"cidr"` | 
|  | ID         string `q:"id"` | 
|  | Limit      int    `q:"limit"` | 
|  | Marker     string `q:"marker"` | 
|  | SortKey    string `q:"sort_key"` | 
|  | SortDir    string `q:"sort_dir"` | 
|  | } | 
|  |  | 
|  | // ToSubnetListQuery formats a ListOpts into a query string. | 
|  | func (opts ListOpts) ToSubnetListQuery() (string, error) { | 
|  | q, err := gophercloud.BuildQueryString(opts) | 
|  | if err != nil { | 
|  | return "", err | 
|  | } | 
|  | return q.String(), nil | 
|  | } | 
|  |  | 
|  | // List returns a Pager which allows you to iterate over a collection of | 
|  | // subnets. It accepts a ListOpts struct, which allows you to filter and sort | 
|  | // the returned collection for greater efficiency. | 
|  | // | 
|  | // Default policy settings return only those subnets that are owned by the tenant | 
|  | // who submits the request, unless the request is submitted by an user with | 
|  | // administrative rights. | 
|  | func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { | 
|  | url := listURL(c) | 
|  | if opts != nil { | 
|  | query, err := opts.ToSubnetListQuery() | 
|  | if err != nil { | 
|  | return pagination.Pager{Err: err} | 
|  | } | 
|  | url += query | 
|  | } | 
|  |  | 
|  | return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { | 
|  | return SubnetPage{pagination.LinkedPageBase{PageResult: r}} | 
|  | }) | 
|  | } | 
|  |  | 
|  | // Get retrieves a specific subnet based on its unique ID. | 
|  | func Get(c *gophercloud.ServiceClient, id string) GetResult { | 
|  | var res GetResult | 
|  | _, res.Err = perigee.Request("GET", getURL(c, id), perigee.Options{ | 
|  | MoreHeaders: c.AuthenticatedHeaders(), | 
|  | Results:     &res.Body, | 
|  | OkCodes:     []int{200}, | 
|  | }) | 
|  | return res | 
|  | } | 
|  |  | 
|  | // Valid IP types | 
|  | const ( | 
|  | IPv4 = 4 | 
|  | IPv6 = 6 | 
|  | ) | 
|  |  | 
|  | // CreateOptsBuilder is the interface options structs have to satisfy in order | 
|  | // to be used in the main Create operation in this package. Since many | 
|  | // extensions decorate or modify the common logic, it is useful for them to | 
|  | // satisfy a basic interface in order for them to be used. | 
|  | type CreateOptsBuilder interface { | 
|  | ToSubnetCreateMap() (map[string]interface{}, error) | 
|  | } | 
|  |  | 
|  | // CreateOpts represents the attributes used when creating a new subnet. | 
|  | type CreateOpts struct { | 
|  | // Required | 
|  | NetworkID string | 
|  | CIDR      string | 
|  | // Optional | 
|  | Name            string | 
|  | TenantID        string | 
|  | AllocationPools []AllocationPool | 
|  | GatewayIP       string | 
|  | IPVersion       int | 
|  | EnableDHCP      *bool | 
|  | DNSNameservers  []string | 
|  | HostRoutes      []HostRoute | 
|  | } | 
|  |  | 
|  | // ToSubnetCreateMap casts a CreateOpts struct to a map. | 
|  | func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) { | 
|  | s := make(map[string]interface{}) | 
|  |  | 
|  | if opts.NetworkID == "" { | 
|  | return nil, errNetworkIDRequired | 
|  | } | 
|  | if opts.CIDR == "" { | 
|  | return nil, errCIDRRequired | 
|  | } | 
|  | if opts.IPVersion != 0 && opts.IPVersion != IPv4 && opts.IPVersion != IPv6 { | 
|  | return nil, errInvalidIPType | 
|  | } | 
|  |  | 
|  | s["network_id"] = opts.NetworkID | 
|  | s["cidr"] = opts.CIDR | 
|  |  | 
|  | if opts.EnableDHCP != nil { | 
|  | s["enable_dhcp"] = &opts.EnableDHCP | 
|  | } | 
|  | if opts.Name != "" { | 
|  | s["name"] = opts.Name | 
|  | } | 
|  | if opts.GatewayIP != "" { | 
|  | s["gateway_ip"] = opts.GatewayIP | 
|  | } | 
|  | if opts.TenantID != "" { | 
|  | s["tenant_id"] = opts.TenantID | 
|  | } | 
|  | if opts.IPVersion != 0 { | 
|  | s["ip_version"] = opts.IPVersion | 
|  | } | 
|  | if len(opts.AllocationPools) != 0 { | 
|  | s["allocation_pools"] = opts.AllocationPools | 
|  | } | 
|  | if len(opts.DNSNameservers) != 0 { | 
|  | s["dns_nameservers"] = opts.DNSNameservers | 
|  | } | 
|  | if len(opts.HostRoutes) != 0 { | 
|  | s["host_routes"] = opts.HostRoutes | 
|  | } | 
|  |  | 
|  | return map[string]interface{}{"subnet": s}, nil | 
|  | } | 
|  |  | 
|  | // Create accepts a CreateOpts struct and creates a new subnet using the values | 
|  | // provided. You must remember to provide a valid NetworkID, CIDR and IP version. | 
|  | func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { | 
|  | var res CreateResult | 
|  |  | 
|  | reqBody, err := opts.ToSubnetCreateMap() | 
|  | if err != nil { | 
|  | res.Err = err | 
|  | return res | 
|  | } | 
|  |  | 
|  | _, res.Err = perigee.Request("POST", createURL(c), perigee.Options{ | 
|  | MoreHeaders: c.AuthenticatedHeaders(), | 
|  | ReqBody:     &reqBody, | 
|  | Results:     &res.Body, | 
|  | OkCodes:     []int{201}, | 
|  | }) | 
|  |  | 
|  | return res | 
|  | } | 
|  |  | 
|  | // UpdateOptsBuilder allows extensions to add additional parameters to the | 
|  | // Update request. | 
|  | type UpdateOptsBuilder interface { | 
|  | ToSubnetUpdateMap() (map[string]interface{}, error) | 
|  | } | 
|  |  | 
|  | // UpdateOpts represents the attributes used when updating an existing subnet. | 
|  | type UpdateOpts struct { | 
|  | Name           string | 
|  | GatewayIP      string | 
|  | DNSNameservers []string | 
|  | HostRoutes     []HostRoute | 
|  | EnableDHCP     *bool | 
|  | } | 
|  |  | 
|  | // ToSubnetUpdateMap casts an UpdateOpts struct to a map. | 
|  | func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) { | 
|  | s := make(map[string]interface{}) | 
|  |  | 
|  | if opts.EnableDHCP != nil { | 
|  | s["enable_dhcp"] = &opts.EnableDHCP | 
|  | } | 
|  | if opts.Name != "" { | 
|  | s["name"] = opts.Name | 
|  | } | 
|  | if opts.GatewayIP != "" { | 
|  | s["gateway_ip"] = opts.GatewayIP | 
|  | } | 
|  | if len(opts.DNSNameservers) != 0 { | 
|  | s["dns_nameservers"] = opts.DNSNameservers | 
|  | } | 
|  | if len(opts.HostRoutes) != 0 { | 
|  | s["host_routes"] = opts.HostRoutes | 
|  | } | 
|  |  | 
|  | return map[string]interface{}{"subnet": s}, nil | 
|  | } | 
|  |  | 
|  | // Update accepts a UpdateOpts struct and updates an existing subnet using the | 
|  | // values provided. | 
|  | func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) UpdateResult { | 
|  | var res UpdateResult | 
|  |  | 
|  | reqBody, err := opts.ToSubnetUpdateMap() | 
|  | if err != nil { | 
|  | res.Err = err | 
|  | return res | 
|  | } | 
|  |  | 
|  | _, res.Err = perigee.Request("PUT", updateURL(c, id), perigee.Options{ | 
|  | MoreHeaders: c.AuthenticatedHeaders(), | 
|  | ReqBody:     &reqBody, | 
|  | Results:     &res.Body, | 
|  | OkCodes:     []int{200, 201}, | 
|  | }) | 
|  |  | 
|  | return res | 
|  | } | 
|  |  | 
|  | // Delete accepts a unique ID and deletes the subnet associated with it. | 
|  | func Delete(c *gophercloud.ServiceClient, id string) DeleteResult { | 
|  | var res DeleteResult | 
|  | _, res.Err = perigee.Request("DELETE", deleteURL(c, id), perigee.Options{ | 
|  | MoreHeaders: c.AuthenticatedHeaders(), | 
|  | OkCodes:     []int{204}, | 
|  | }) | 
|  | return res | 
|  | } |