blob: f89bb3bb26f2493ebefae48cd87c1587fe7b7131 [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 Hannaford686c4962014-09-23 10:46:20 +02008// AllocationPool is a sub-struct that represents an allocation pool
Jamie Hannaford0708c002014-09-17 16:08:49 +02009type AllocationPool struct {
Jamie Hannaford63631432014-09-18 11:40:09 +020010 Start string `json:"start"`
11 End string `json:"end"`
Jamie Hannaford0708c002014-09-17 16:08:49 +020012}
13
Jamie Hannaford686c4962014-09-23 10:46:20 +020014// Subnet represents a subnet. See package documentation for a top-level
15// description of what this is.
Jamie Hannaford0708c002014-09-17 16:08:49 +020016type Subnet struct {
Jamie Hannaford965ae702014-09-22 14:58:19 +020017 // UUID representing the subnet
18 ID string `mapstructure:"id" json:"id"`
19 // UUID of the parent network
20 NetworkID string `mapstructure:"network_id" json:"network_id"`
21 // Human-readable name for the subnet. Might not be unique.
22 Name string `mapstructure:"name" json:"name"`
23 // IP version, either `4' or `6'
24 IPVersion int `mapstructure:"ip_version" json:"ip_version"`
25 // CIDR representing IP range for this subnet, based on IP version
26 CIDR string `mapstructure:"cidr" json:"cidr"`
27 // Default gateway used by devices in this subnet
28 GatewayIP string `mapstructure:"gateway_ip" json:"gateway_ip"`
29 // DNS name servers used by hosts in this subnet.
30 DNSNameservers []string `mapstructure:"dns_nameservers" json:"dns_nameservers"`
31 // Sub-ranges of CIDR available for dynamic allocation to ports. See AllocationPool.
Jamie Hannaford0708c002014-09-17 16:08:49 +020032 AllocationPools []AllocationPool `mapstructure:"allocation_pools" json:"allocation_pools"`
Jamie Hannaford965ae702014-09-22 14:58:19 +020033 // Routes that should be used by devices with IPs from this subnet (not including local subnet route).
34 HostRoutes []interface{} `mapstructure:"host_routes" json:"host_routes"`
35 // Specifies whether DHCP is enabled for this subnet or not.
36 EnableDHCP bool `mapstructure:"enable_dhcp" json:"enable_dhcp"`
37 // Owner of network. Only admin users can specify a tenant_id other than its own.
38 TenantID string `mapstructure:"tenant_id" json:"tenant_id"`
Jamie Hannaford0708c002014-09-17 16:08:49 +020039}
40
Jamie Hannaford686c4962014-09-23 10:46:20 +020041// SubnetPage is the page returned by a pager when traversing over a collection
42// of subnets.
Jamie Hannaford0708c002014-09-17 16:08:49 +020043type SubnetPage struct {
44 pagination.LinkedPageBase
45}
46
Jamie Hannaford686c4962014-09-23 10:46:20 +020047// NextPageURL is invoked when a paginated collection of subnets has reached
48// the end of a page and the pager seeks to traverse over a new one. In order
49// to do this, it needs to construct the next page's URL.
50func (p SubnetPage) NextPageURL() (string, error) {
Jamie Hannaford0708c002014-09-17 16:08:49 +020051 type link struct {
52 Href string `mapstructure:"href"`
53 Rel string `mapstructure:"rel"`
54 }
55 type resp struct {
56 Links []link `mapstructure:"subnets_links"`
57 }
58
59 var r resp
Jamie Hannaford686c4962014-09-23 10:46:20 +020060 err := mapstructure.Decode(p.Body, &r)
Jamie Hannaford0708c002014-09-17 16:08:49 +020061 if err != nil {
62 return "", err
63 }
64
65 var url string
66 for _, l := range r.Links {
67 if l.Rel == "next" {
68 url = l.Href
69 }
70 }
71 if url == "" {
72 return "", nil
73 }
74
75 return url, nil
76}
77
Jamie Hannaford686c4962014-09-23 10:46:20 +020078// IsEmpty checks whether a SubnetPage struct is empty.
79func (p SubnetPage) IsEmpty() (bool, error) {
80 is, err := ExtractSubnets(p)
Jamie Hannaford0708c002014-09-17 16:08:49 +020081 if err != nil {
82 return true, nil
83 }
84 return len(is) == 0, nil
85}
86
Jamie Hannaford686c4962014-09-23 10:46:20 +020087// ExtractSubnets accepts a Page struct, specifically a SubnetPage struct,
88// and extracts the elements into a slice of Subnet structs. In other words,
89// a generic collection is mapped into a relevant slice.
Jamie Hannaford0708c002014-09-17 16:08:49 +020090func ExtractSubnets(page pagination.Page) ([]Subnet, error) {
91 var resp struct {
92 Subnets []Subnet `mapstructure:"subnets" json:"subnets"`
93 }
94
95 err := mapstructure.Decode(page.(SubnetPage).Body, &resp)
96 if err != nil {
97 return nil, err
98 }
99
100 return resp.Subnets, nil
101}