1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
package subnets
import (
"github.com/mitchellh/mapstructure"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
type commonResult struct {
gophercloud.Result
}
// Extract is a function that accepts a result and extracts a subnet resource.
func (r commonResult) Extract() (*Subnet, error) {
if r.Err != nil {
return nil, r.Err
}
var res struct {
Subnet *Subnet `json:"subnet"`
}
err := mapstructure.Decode(r.Body, &res)
return res.Subnet, err
}
// CreateResult represents the result of a create operation.
type CreateResult struct {
commonResult
}
// GetResult represents the result of a get operation.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
type UpdateResult struct {
commonResult
}
// DeleteResult represents the result of a delete operation.
type DeleteResult struct {
gophercloud.ErrResult
}
// AllocationPool represents a sub-range of cidr available for dynamic
// allocation to ports, e.g. {Start: "10.0.0.2", End: "10.0.0.254"}
type AllocationPool struct {
Start string `json:"start"`
End string `json:"end"`
}
// HostRoute represents a route that should be used by devices with IPs from
// a subnet (not including local subnet route).
type HostRoute struct {
DestinationCIDR string `mapstructure:"destination" json:"destination"`
NextHop string `mapstructure:"nexthop" json:"nexthop"`
}
// Subnet represents a subnet. See package documentation for a top-level
// description of what this is.
type Subnet struct {
// UUID representing the subnet
ID string `mapstructure:"id" json:"id"`
// UUID of the parent network
NetworkID string `mapstructure:"network_id" json:"network_id"`
// Human-readable name for the subnet. Might not be unique.
Name string `mapstructure:"name" json:"name"`
// IP version, either `4' or `6'
IPVersion int `mapstructure:"ip_version" json:"ip_version"`
// CIDR representing IP range for this subnet, based on IP version
CIDR string `mapstructure:"cidr" json:"cidr"`
// Default gateway used by devices in this subnet
GatewayIP string `mapstructure:"gateway_ip" json:"gateway_ip"`
// DNS name servers used by hosts in this subnet.
DNSNameservers []string `mapstructure:"dns_nameservers" json:"dns_nameservers"`
// Sub-ranges of CIDR available for dynamic allocation to ports. See AllocationPool.
AllocationPools []AllocationPool `mapstructure:"allocation_pools" json:"allocation_pools"`
// Routes that should be used by devices with IPs from this subnet (not including local subnet route).
HostRoutes []HostRoute `mapstructure:"host_routes" json:"host_routes"`
// Specifies whether DHCP is enabled for this subnet or not.
EnableDHCP bool `mapstructure:"enable_dhcp" json:"enable_dhcp"`
// Owner of network. Only admin users can specify a tenant_id other than its own.
TenantID string `mapstructure:"tenant_id" json:"tenant_id"`
}
// SubnetPage is the page returned by a pager when traversing over a collection
// of subnets.
type SubnetPage struct {
pagination.LinkedPageBase
}
// NextPageURL is invoked when a paginated collection of subnets has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
func (p SubnetPage) NextPageURL() (string, error) {
type resp struct {
Links []gophercloud.Link `mapstructure:"subnets_links"`
}
var r resp
err := mapstructure.Decode(p.Body, &r)
if err != nil {
return "", err
}
return gophercloud.ExtractNextURL(r.Links)
}
// IsEmpty checks whether a SubnetPage struct is empty.
func (p SubnetPage) IsEmpty() (bool, error) {
is, err := ExtractSubnets(p)
if err != nil {
return true, nil
}
return len(is) == 0, nil
}
// ExtractSubnets accepts a Page struct, specifically a SubnetPage struct,
// and extracts the elements into a slice of Subnet structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractSubnets(page pagination.Page) ([]Subnet, error) {
var resp struct {
Subnets []Subnet `mapstructure:"subnets" json:"subnets"`
}
err := mapstructure.Decode(page.(SubnetPage).Body, &resp)
return resp.Subnets, err
}
|