Finishing documentation :pencil2:
diff --git a/openstack/networking/v2/extensions/layer3/floatingips/results.go b/openstack/networking/v2/extensions/layer3/floatingips/results.go
index f9c7a08..4857c92 100644
--- a/openstack/networking/v2/extensions/layer3/floatingips/results.go
+++ b/openstack/networking/v2/extensions/layer3/floatingips/results.go
@@ -79,10 +79,15 @@
// DeleteResult represents the result of an update operation.
type DeleteResult commonResult
+// FloatingIPPage is the page returned by a pager when traversing over a
+// collection of floating IPs.
type FloatingIPPage struct {
pagination.LinkedPageBase
}
+// NextPageURL is invoked when a paginated collection of floating IPs 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 FloatingIPPage) NextPageURL() (string, error) {
type link struct {
Href string `mapstructure:"href"`
@@ -111,6 +116,7 @@
return url, nil
}
+// IsEmpty checks whether a NetworkPage struct is empty.
func (p FloatingIPPage) IsEmpty() (bool, error) {
is, err := ExtractFloatingIPs(p)
if err != nil {
@@ -119,6 +125,9 @@
return len(is) == 0, nil
}
+// ExtractFloatingIPs accepts a Page struct, specifically a FloatingIPPage struct,
+// and extracts the elements into a slice of FloatingIP structs. In other words,
+// a generic collection is mapped into a relevant slice.
func ExtractFloatingIPs(page pagination.Page) ([]FloatingIP, error) {
var resp struct {
FloatingIPs []FloatingIP `mapstructure:"floatingips" json:"floatingips"`
diff --git a/openstack/networking/v2/extensions/layer3/routers/requests.go b/openstack/networking/v2/extensions/layer3/routers/requests.go
index c432e19..5890989 100755
--- a/openstack/networking/v2/extensions/layer3/routers/requests.go
+++ b/openstack/networking/v2/extensions/layer3/routers/requests.go
@@ -10,6 +10,11 @@
"github.com/rackspace/gophercloud/pagination"
)
+// 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 floating IP attributes you want to see returned. SortKey allows you to
+// sort by a particular network attribute. SortDir sets the direction, and is
+// either `asc' or `desc'. Marker and Limit are used for pagination.
type ListOpts struct {
ID string
Name string
@@ -22,6 +27,12 @@
SortDir string
}
+// List returns a Pager which allows you to iterate over a collection of
+// routers. It accepts a ListOpts struct, which allows you to filter and sort
+// the returned collection for greater efficiency.
+//
+// Default policy settings return only those routers that are owned by the
+// tenant who submits the request, unless an admin user submits the request.
func List(c *gophercloud.ServiceClient, opts ListOpts) pagination.Pager {
q := make(map[string]string)
if opts.ID != "" {
@@ -58,6 +69,8 @@
})
}
+// CreateOpts contains all the values needed to create a new router. There are
+// no required values.
type CreateOpts struct {
Name string
AdminStateUp *bool
@@ -65,6 +78,14 @@
GatewayInfo *GatewayInfo
}
+// Create accepts a CreateOpts struct and uses the values to create a new
+// logical router. When it is created, the router does not have an internal
+// interface - it is not associated to any subnet.
+//
+// You can optionally specify an external gateway for a router using the
+// GatewayInfo struct. The external gateway for the router must be plugged into
+// an external network (it is external if its `router:external' field is set to
+// true).
func Create(c *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
type router struct {
Name *string `json:"name,omitempty"`
@@ -98,6 +119,7 @@
return res
}
+// Get retrieves a particular router based on its unique ID.
func Get(c *gophercloud.ServiceClient, id string) GetResult {
var res GetResult
_, err := perigee.Request("GET", resourceURL(c, id), perigee.Options{
@@ -109,12 +131,18 @@
return res
}
+// UpdateOpts contains the values used when updating a router.
type UpdateOpts struct {
Name string
AdminStateUp *bool
GatewayInfo *GatewayInfo
}
+// Update allows routers to be updated. You can update the name, administrative
+// state, and the external gateway. For more information about how to set the
+// external gateway for a router, see Create. This operation does not enable
+// the update of router interfaces. To do this, use the AddInterface and
+// RemoveInterface functions.
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult {
type router struct {
Name *string `json:"name,omitempty"`
@@ -147,6 +175,7 @@
return res
}
+// Delete will permanently delete a particular router based on its unique ID.
func Delete(c *gophercloud.ServiceClient, id string) DeleteResult {
var res DeleteResult
_, err := perigee.Request("DELETE", resourceURL(c, id), perigee.Options{
@@ -159,11 +188,34 @@
var errInvalidInterfaceOpts = fmt.Errorf("When adding a router interface you must provide either a subnet ID or a port ID")
+// InterfaceOpts allow you to work with operations that either add or remote
+// an internal interface from a router.
type InterfaceOpts struct {
SubnetID string
PortID string
}
+// AddInterface attaches a subnet to an internal router interface. You must
+// specify either a SubnetID or PortID in the request body. If you specify both,
+// the operation will fail and an error will be returned.
+//
+// If you specify a SubnetID, the gateway IP address for that particular subnet
+// is used to create the router interface. Alternatively, if you specify a
+// PortID, the IP address associated with the port is used to create the router
+// interface.
+//
+// If you reference a port that is associated with multiple IP addresses, or
+// if the port is associated with zero IP addresses, the operation will fail and
+// a 400 Bad Request error will be returned.
+//
+// If you reference a port already in use, the operation will fail and a 409
+// Conflict error will be returned.
+//
+// The PortID that is returned after using Extract() on the result of this
+// operation can either be the same PortID passed in or, on the other hand, the
+// identifier of a new port created by this operation. After the operation
+// completes, the device ID of the port is set to the router ID, and the
+// device owner attribute is set to `network:router_interface'.
func AddInterface(c *gophercloud.ServiceClient, id string, opts InterfaceOpts) InterfaceResult {
var res InterfaceResult
@@ -189,14 +241,22 @@
return res
}
+// RemoveInterface removes an internal router interface, which detaches a
+// subnet from the router. You must specify either a SubnetID or PortID, since
+// these values are used to identify the router interface to remove.
+//
+// Unlike AddInterface, you can also specify both a SubnetID and PortID. If you
+// choose to specify both, the subnet ID must correspond to the subnet ID of
+// the first IP address on the port specified by the port ID. Otherwise, the
+// operation will fail and return a 409 Conflict error.
+//
+// If the router, subnet or port which are referenced do not exist or are not
+// visible to you, the operation will fail and a 404 Not Found error will be
+// returned. After this operation completes, the port connecting the router
+// with the subnet is removed from the subnet for the network.
func RemoveInterface(c *gophercloud.ServiceClient, id string, opts InterfaceOpts) InterfaceResult {
var res InterfaceResult
- // Validate
- if (opts.SubnetID == "" && opts.PortID == "") || (opts.SubnetID != "" && opts.PortID != "") {
- res.Err = errInvalidInterfaceOpts
- }
-
type request struct {
SubnetID string `json:"subnet_id,omitempty"`
PortID string `json:"port_id,omitempty"`
diff --git a/openstack/networking/v2/extensions/layer3/routers/results.go b/openstack/networking/v2/extensions/layer3/routers/results.go
index 9067366..b7eb42d 100755
--- a/openstack/networking/v2/extensions/layer3/routers/results.go
+++ b/openstack/networking/v2/extensions/layer3/routers/results.go
@@ -8,23 +8,50 @@
"github.com/rackspace/gophercloud/pagination"
)
+// GatewayInfo represents the information of an external gateway for any
+// particular network router.
type GatewayInfo struct {
NetworkID string `json:"network_id" mapstructure:"network_id"`
}
+// Router represents a Neutron router. A router is a logical entity that
+// forwards packets across internal subnets and NATs them on external networks
+// through an appropriate external gateway.
+//
+// A router has an interface for each subnet with which it is associated. By
+// default, the IP address of such interface is the subnet's gateway IP. Also,
+// whenever a router is associated with a subnet, a port for that router
+// interface is added to the subnet's network.
type Router struct {
- Status string `json:"status" mapstructure:"status"`
- GatewayInfo GatewayInfo `json:"external_gateway_info" mapstructure:"external_gateway_info"`
- AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"`
- Name string `json:"name" mapstructure:"name"`
- ID string `json:"id" mapstructure:"id"`
- TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
+ // Indicates whether or not a router is currently operational.
+ Status string `json:"status" mapstructure:"status"`
+
+ // Information on external gateway for the router.
+ GatewayInfo GatewayInfo `json:"external_gateway_info" mapstructure:"external_gateway_info"`
+
+ // Administrative state of the router.
+ AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"`
+
+ // Human readable name for the router. Does not have to be unique.
+ Name string `json:"name" mapstructure:"name"`
+
+ // Unique identifier for the router.
+ ID string `json:"id" mapstructure:"id"`
+
+ // Owner of the router. Only admin users can specify a tenant identifier
+ // other than its own.
+ TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
}
+// RouterPage is the page returned by a pager when traversing over a
+// collection of routers.
type RouterPage struct {
pagination.LinkedPageBase
}
+// NextPageURL is invoked when a paginated collection of routers 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 RouterPage) NextPageURL() (string, error) {
type link struct {
Href string `mapstructure:"href"`
@@ -53,6 +80,7 @@
return url, nil
}
+// IsEmpty checks whether a RouterPage struct is empty.
func (p RouterPage) IsEmpty() (bool, error) {
is, err := ExtractRouters(p)
if err != nil {
@@ -61,6 +89,9 @@
return len(is) == 0, nil
}
+// ExtractRouters accepts a Page struct, specifically a RouterPage struct,
+// and extracts the elements into a slice of Router structs. In other words,
+// a generic collection is mapped into a relevant slice.
func ExtractRouters(page pagination.Page) ([]Router, error) {
var resp struct {
Routers []Router `mapstructure:"routers" json:"routers"`
@@ -78,7 +109,7 @@
gophercloud.CommonResult
}
-// Extract is a function that accepts a result and extracts a network resource.
+// Extract is a function that accepts a result and extracts a router.
func (r commonResult) Extract() (*Router, error) {
if r.Err != nil {
return nil, r.Err
@@ -111,19 +142,33 @@
commonResult
}
+// DeleteResult represents the result of a delete operation.
type DeleteResult commonResult
+// InterfaceInfo represents information about a particular router interface. As
+// mentioned above, in order for a router to forward to a subnet, it needs an
+// interface.
type InterfaceInfo struct {
+ // The ID of the subnet which this interface is associated with.
SubnetID string `json:"subnet_id" mapstructure:"subnet_id"`
- PortID string `json:"port_id" mapstructure:"port_id"`
- ID string `json:"id" mapstructure:"id"`
+
+ // The ID of the port that is a part of the subnet.
+ PortID string `json:"port_id" mapstructure:"port_id"`
+
+ // The UUID of the interface.
+ ID string `json:"id" mapstructure:"id"`
+
+ // Owner of the interface.
TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
}
+// DeleteResult represents the result of interface operations, such as
+// AddInterface() and RemoveInterface().
type InterfaceResult struct {
gophercloud.CommonResult
}
+// Extract is a function that accepts a result and extracts an information struct.
func (r InterfaceResult) Extract() (*InterfaceInfo, error) {
if r.Err != nil {
return nil, r.Err