blob: ead2172fa3192c03b045f19fd242a1ba6045e331 [file] [log] [blame]
Jamie Hannaford89f9af22014-09-17 12:21:48 +02001package subnets
Jamie Hannaford0708c002014-09-17 16:08:49 +02002
3import (
4 "github.com/mitchellh/mapstructure"
5 "github.com/rackspace/gophercloud/pagination"
6)
7
Jamie Hannafordf2835402014-09-23 11:01:21 +02008// AllocationPool represents a sub-range of cidr available for dynamic
9// allocation to ports, e.g. {Start: "10.0.0.2", End: "10.0.0.254"}
Jamie Hannaford0708c002014-09-17 16:08:49 +020010type AllocationPool struct {
Jamie Hannaford63631432014-09-18 11:40:09 +020011 Start string `json:"start"`
12 End string `json:"end"`
Jamie Hannaford0708c002014-09-17 16:08:49 +020013}
14
Jamie Hannafordf2835402014-09-23 11:01:21 +020015// HostRoute represents a route that should be used by devices with IPs from
16// a subnet (not including local subnet route).
17type HostRoute struct {
18 DestinationCIDR string `json:"destination"`
19 NextHop string `json:"nexthop"`
20}
21
Jamie Hannaford686c4962014-09-23 10:46:20 +020022// Subnet represents a subnet. See package documentation for a top-level
23// description of what this is.
Jamie Hannaford0708c002014-09-17 16:08:49 +020024type Subnet struct {
Jamie Hannaford965ae702014-09-22 14:58:19 +020025 // UUID representing the subnet
26 ID string `mapstructure:"id" json:"id"`
27 // UUID of the parent network
28 NetworkID string `mapstructure:"network_id" json:"network_id"`
29 // Human-readable name for the subnet. Might not be unique.
30 Name string `mapstructure:"name" json:"name"`
31 // IP version, either `4' or `6'
32 IPVersion int `mapstructure:"ip_version" json:"ip_version"`
33 // CIDR representing IP range for this subnet, based on IP version
34 CIDR string `mapstructure:"cidr" json:"cidr"`
35 // Default gateway used by devices in this subnet
36 GatewayIP string `mapstructure:"gateway_ip" json:"gateway_ip"`
37 // DNS name servers used by hosts in this subnet.
38 DNSNameservers []string `mapstructure:"dns_nameservers" json:"dns_nameservers"`
39 // Sub-ranges of CIDR available for dynamic allocation to ports. See AllocationPool.
Jamie Hannaford0708c002014-09-17 16:08:49 +020040 AllocationPools []AllocationPool `mapstructure:"allocation_pools" json:"allocation_pools"`
Jamie Hannaford965ae702014-09-22 14:58:19 +020041 // Routes that should be used by devices with IPs from this subnet (not including local subnet route).
Jamie Hannafordf2835402014-09-23 11:01:21 +020042 HostRoutes []HostRoute `mapstructure:"host_routes" json:"host_routes"`
Jamie Hannaford965ae702014-09-22 14:58:19 +020043 // Specifies whether DHCP is enabled for this subnet or not.
44 EnableDHCP bool `mapstructure:"enable_dhcp" json:"enable_dhcp"`
45 // Owner of network. Only admin users can specify a tenant_id other than its own.
46 TenantID string `mapstructure:"tenant_id" json:"tenant_id"`
Jamie Hannaford0708c002014-09-17 16:08:49 +020047}
48
Jamie Hannaford686c4962014-09-23 10:46:20 +020049// SubnetPage is the page returned by a pager when traversing over a collection
50// of subnets.
Jamie Hannaford0708c002014-09-17 16:08:49 +020051type SubnetPage struct {
52 pagination.LinkedPageBase
53}
54
Jamie Hannaford686c4962014-09-23 10:46:20 +020055// NextPageURL is invoked when a paginated collection of subnets has reached
56// the end of a page and the pager seeks to traverse over a new one. In order
57// to do this, it needs to construct the next page's URL.
58func (p SubnetPage) NextPageURL() (string, error) {
Jamie Hannaford0708c002014-09-17 16:08:49 +020059 type link struct {
60 Href string `mapstructure:"href"`
61 Rel string `mapstructure:"rel"`
62 }
63 type resp struct {
64 Links []link `mapstructure:"subnets_links"`
65 }
66
67 var r resp
Jamie Hannaford686c4962014-09-23 10:46:20 +020068 err := mapstructure.Decode(p.Body, &r)
Jamie Hannaford0708c002014-09-17 16:08:49 +020069 if err != nil {
70 return "", err
71 }
72
73 var url string
74 for _, l := range r.Links {
75 if l.Rel == "next" {
76 url = l.Href
77 }
78 }
79 if url == "" {
80 return "", nil
81 }
82
83 return url, nil
84}
85
Jamie Hannaford686c4962014-09-23 10:46:20 +020086// IsEmpty checks whether a SubnetPage struct is empty.
87func (p SubnetPage) IsEmpty() (bool, error) {
88 is, err := ExtractSubnets(p)
Jamie Hannaford0708c002014-09-17 16:08:49 +020089 if err != nil {
90 return true, nil
91 }
92 return len(is) == 0, nil
93}
94
Jamie Hannaford686c4962014-09-23 10:46:20 +020095// ExtractSubnets accepts a Page struct, specifically a SubnetPage struct,
96// and extracts the elements into a slice of Subnet structs. In other words,
97// a generic collection is mapped into a relevant slice.
Jamie Hannaford0708c002014-09-17 16:08:49 +020098func ExtractSubnets(page pagination.Page) ([]Subnet, error) {
99 var resp struct {
100 Subnets []Subnet `mapstructure:"subnets" json:"subnets"`
101 }
102
103 err := mapstructure.Decode(page.(SubnetPage).Body, &resp)
104 if err != nil {
105 return nil, err
106 }
107
108 return resp.Subnets, nil
109}