mirror of https://github.com/hashicorp/packer
Merge pull request #8279 from andreykaipov/feature/builder/openstack-network-discovery
[builder/openstack] adds option to discover provisioning networkpull/8293/head
commit
811f2cb8a7
@ -0,0 +1,54 @@
|
||||
package openstack
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testYes(t *testing.T, a, b string) {
|
||||
var m, n *net.IPNet
|
||||
_, m, _ = net.ParseCIDR(a)
|
||||
_, n, _ = net.ParseCIDR(b)
|
||||
if !containsNet(m, n) {
|
||||
t.Errorf("%s expected to contain %s", m, n)
|
||||
}
|
||||
}
|
||||
|
||||
func testNot(t *testing.T, a, b string) {
|
||||
var m, n *net.IPNet
|
||||
_, m, _ = net.ParseCIDR(a)
|
||||
_, n, _ = net.ParseCIDR(b)
|
||||
if containsNet(m, n) {
|
||||
t.Errorf("%s expected to not contain %s", m, n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNetworkDiscovery_SubnetContainsGood_IPv4(t *testing.T) {
|
||||
testYes(t, "192.168.0.0/23", "192.168.0.0/24")
|
||||
testYes(t, "192.168.0.0/24", "192.168.0.0/24")
|
||||
testNot(t, "192.168.0.0/25", "192.168.0.0/24")
|
||||
|
||||
testYes(t, "192.168.101.202/16", "192.168.202.101/16")
|
||||
testNot(t, "192.168.101.202/24", "192.168.202.101/24")
|
||||
testNot(t, "192.168.202.101/24", "192.168.101.202/24")
|
||||
|
||||
testYes(t, "0.0.0.0/0", "192.168.0.0/24")
|
||||
testYes(t, "0.0.0.0/0", "0.0.0.0/1")
|
||||
testNot(t, "192.168.0.0/24", "0.0.0.0/0")
|
||||
testNot(t, "0.0.0.0/1", "0.0.0.0/0")
|
||||
}
|
||||
|
||||
func TestNetworkDiscovery_SubnetContainsGood_IPv6(t *testing.T) {
|
||||
testYes(t, "2001:db8::/63", "2001:db8::/64")
|
||||
testYes(t, "2001:db8::/64", "2001:db8::/64")
|
||||
testNot(t, "2001:db8::/65", "2001:db8::/64")
|
||||
|
||||
testYes(t, "2001:db8:fefe:b00b::/32", "2001:db8:b00b:fefe::/32")
|
||||
testNot(t, "2001:db8:fefe:b00b::/64", "2001:db8:b00b:fefe::/64")
|
||||
testNot(t, "2001:db8:b00b:fefe::/64", "2001:db8:fefe:b00b::/64")
|
||||
|
||||
testYes(t, "::/0", "2001:db8::/64")
|
||||
testYes(t, "::/0", "::/1")
|
||||
testNot(t, "2001:db8::/64", "::/0")
|
||||
testNot(t, "::/1", "::/0")
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package openstack
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
|
||||
"github.com/hashicorp/packer/helper/multistep"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
)
|
||||
|
||||
type StepDiscoverNetwork struct {
|
||||
Networks []string
|
||||
NetworkDiscoveryCIDRs []string
|
||||
Ports []string
|
||||
}
|
||||
|
||||
func (s *StepDiscoverNetwork) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(*Config)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
networkClient, err := config.networkV2Client()
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Error initializing network client: %s", err)
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
networks := []servers.Network{}
|
||||
for _, port := range s.Ports {
|
||||
networks = append(networks, servers.Network{Port: port})
|
||||
}
|
||||
for _, uuid := range s.Networks {
|
||||
networks = append(networks, servers.Network{UUID: uuid})
|
||||
}
|
||||
|
||||
cidrs := s.NetworkDiscoveryCIDRs
|
||||
if len(networks) == 0 && len(cidrs) > 0 {
|
||||
ui.Say(fmt.Sprintf("Discovering provisioning network..."))
|
||||
|
||||
networkID, err := DiscoverProvisioningNetwork(networkClient, cidrs)
|
||||
if err != nil {
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
ui.Message(fmt.Sprintf("Found network ID: %s", networkID))
|
||||
networks = append(networks, servers.Network{UUID: networkID})
|
||||
}
|
||||
|
||||
state.Put("networks", networks)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *StepDiscoverNetwork) Cleanup(state multistep.StateBag) {}
|
||||
135
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/doc.go
generated
vendored
135
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/doc.go
generated
vendored
@ -0,0 +1,135 @@
|
||||
/*
|
||||
Package subnets contains functionality for working with Neutron subnet
|
||||
resources. A subnet represents an IP address block that can be used to
|
||||
assign IP addresses to virtual instances. Each subnet must have a CIDR and
|
||||
must be associated with a network. IPs can either be selected from the whole
|
||||
subnet CIDR or from allocation pools specified by the user.
|
||||
|
||||
A subnet can also have a gateway, a list of DNS name servers, and host routes.
|
||||
This information is pushed to instances whose interfaces are associated with
|
||||
the subnet.
|
||||
|
||||
Example to List Subnets
|
||||
|
||||
listOpts := subnets.ListOpts{
|
||||
IPVersion: 4,
|
||||
}
|
||||
|
||||
allPages, err := subnets.List(networkClient, listOpts).AllPages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
allSubnets, err := subnets.ExtractSubnets(allPages)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, subnet := range allSubnets {
|
||||
fmt.Printf("%+v\n", subnet)
|
||||
}
|
||||
|
||||
Example to Create a Subnet With Specified Gateway
|
||||
|
||||
var gatewayIP = "192.168.199.1"
|
||||
createOpts := subnets.CreateOpts{
|
||||
NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a22",
|
||||
IPVersion: 4,
|
||||
CIDR: "192.168.199.0/24",
|
||||
GatewayIP: &gatewayIP,
|
||||
AllocationPools: []subnets.AllocationPool{
|
||||
{
|
||||
Start: "192.168.199.2",
|
||||
End: "192.168.199.254",
|
||||
},
|
||||
},
|
||||
DNSNameservers: []string{"foo"},
|
||||
}
|
||||
|
||||
subnet, err := subnets.Create(networkClient, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create a Subnet With No Gateway
|
||||
|
||||
var noGateway = ""
|
||||
|
||||
createOpts := subnets.CreateOpts{
|
||||
NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a23",
|
||||
IPVersion: 4,
|
||||
CIDR: "192.168.1.0/24",
|
||||
GatewayIP: &noGateway,
|
||||
AllocationPools: []subnets.AllocationPool{
|
||||
{
|
||||
Start: "192.168.1.2",
|
||||
End: "192.168.1.254",
|
||||
},
|
||||
},
|
||||
DNSNameservers: []string{},
|
||||
}
|
||||
|
||||
subnet, err := subnets.Create(networkClient, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Create a Subnet With a Default Gateway
|
||||
|
||||
createOpts := subnets.CreateOpts{
|
||||
NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a23",
|
||||
IPVersion: 4,
|
||||
CIDR: "192.168.1.0/24",
|
||||
AllocationPools: []subnets.AllocationPool{
|
||||
{
|
||||
Start: "192.168.1.2",
|
||||
End: "192.168.1.254",
|
||||
},
|
||||
},
|
||||
DNSNameservers: []string{},
|
||||
}
|
||||
|
||||
subnet, err := subnets.Create(networkClient, createOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Update a Subnet
|
||||
|
||||
subnetID := "db77d064-e34f-4d06-b060-f21e28a61c23"
|
||||
dnsNameservers := []string{"8.8.8.8"}
|
||||
name := "new_name"
|
||||
|
||||
updateOpts := subnets.UpdateOpts{
|
||||
Name: &name,
|
||||
DNSNameservers: &dnsNameservers,
|
||||
}
|
||||
|
||||
subnet, err := subnets.Update(networkClient, subnetID, updateOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Remove a Gateway From a Subnet
|
||||
|
||||
var noGateway = ""
|
||||
subnetID := "db77d064-e34f-4d06-b060-f21e28a61c23"
|
||||
|
||||
updateOpts := subnets.UpdateOpts{
|
||||
GatewayIP: &noGateway,
|
||||
}
|
||||
|
||||
subnet, err := subnets.Update(networkClient, subnetID, updateOpts).Extract()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Example to Delete a Subnet
|
||||
|
||||
subnetID := "db77d064-e34f-4d06-b060-f21e28a61c23"
|
||||
err := subnets.Delete(networkClient, subnetID).ExtractErr()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
package subnets
|
||||
269
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/requests.go
generated
vendored
269
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/requests.go
generated
vendored
@ -0,0 +1,269 @@
|
||||
package subnets
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// 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"`
|
||||
Description string `q:"description"`
|
||||
EnableDHCP *bool `q:"enable_dhcp"`
|
||||
NetworkID string `q:"network_id"`
|
||||
TenantID string `q:"tenant_id"`
|
||||
ProjectID string `q:"project_id"`
|
||||
IPVersion int `q:"ip_version"`
|
||||
GatewayIP string `q:"gateway_ip"`
|
||||
CIDR string `q:"cidr"`
|
||||
IPv6AddressMode string `q:"ipv6_address_mode"`
|
||||
IPv6RAMode string `q:"ipv6_ra_mode"`
|
||||
ID string `q:"id"`
|
||||
SubnetPoolID string `q:"subnetpool_id"`
|
||||
Limit int `q:"limit"`
|
||||
Marker string `q:"marker"`
|
||||
SortKey string `q:"sort_key"`
|
||||
SortDir string `q:"sort_dir"`
|
||||
Tags string `q:"tags"`
|
||||
TagsAny string `q:"tags-any"`
|
||||
NotTags string `q:"not-tags"`
|
||||
NotTagsAny string `q:"not-tags-any"`
|
||||
}
|
||||
|
||||
// ToSubnetListQuery formats a ListOpts into a query string.
|
||||
func (opts ListOpts) ToSubnetListQuery() (string, error) {
|
||||
q, err := gophercloud.BuildQueryString(opts)
|
||||
return q.String(), err
|
||||
}
|
||||
|
||||
// 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 a 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) (r GetResult) {
|
||||
_, r.Err = c.Get(getURL(c, id), &r.Body, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOptsBuilder allows extensions to add additional parameters to the
|
||||
// List request.
|
||||
type CreateOptsBuilder interface {
|
||||
ToSubnetCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateOpts represents the attributes used when creating a new subnet.
|
||||
type CreateOpts struct {
|
||||
// NetworkID is the UUID of the network the subnet will be associated with.
|
||||
NetworkID string `json:"network_id" required:"true"`
|
||||
|
||||
// CIDR is the address CIDR of the subnet.
|
||||
CIDR string `json:"cidr,omitempty"`
|
||||
|
||||
// Name is a human-readable name of the subnet.
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// Description of the subnet.
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
// The UUID of the project who owns the Subnet. Only administrative users
|
||||
// can specify a project UUID other than their own.
|
||||
TenantID string `json:"tenant_id,omitempty"`
|
||||
|
||||
// The UUID of the project who owns the Subnet. Only administrative users
|
||||
// can specify a project UUID other than their own.
|
||||
ProjectID string `json:"project_id,omitempty"`
|
||||
|
||||
// AllocationPools are IP Address pools that will be available for DHCP.
|
||||
AllocationPools []AllocationPool `json:"allocation_pools,omitempty"`
|
||||
|
||||
// GatewayIP sets gateway information for the subnet. Setting to nil will
|
||||
// cause a default gateway to automatically be created. Setting to an empty
|
||||
// string will cause the subnet to be created with no gateway. Setting to
|
||||
// an explicit address will set that address as the gateway.
|
||||
GatewayIP *string `json:"gateway_ip,omitempty"`
|
||||
|
||||
// IPVersion is the IP version for the subnet.
|
||||
IPVersion gophercloud.IPVersion `json:"ip_version,omitempty"`
|
||||
|
||||
// EnableDHCP will either enable to disable the DHCP service.
|
||||
EnableDHCP *bool `json:"enable_dhcp,omitempty"`
|
||||
|
||||
// DNSNameservers are the nameservers to be set via DHCP.
|
||||
DNSNameservers []string `json:"dns_nameservers,omitempty"`
|
||||
|
||||
// HostRoutes are any static host routes to be set via DHCP.
|
||||
HostRoutes []HostRoute `json:"host_routes,omitempty"`
|
||||
|
||||
// The IPv6 address modes specifies mechanisms for assigning IPv6 IP addresses.
|
||||
IPv6AddressMode string `json:"ipv6_address_mode,omitempty"`
|
||||
|
||||
// The IPv6 router advertisement specifies whether the networking service
|
||||
// should transmit ICMPv6 packets.
|
||||
IPv6RAMode string `json:"ipv6_ra_mode,omitempty"`
|
||||
|
||||
// SubnetPoolID is the id of the subnet pool that subnet should be associated to.
|
||||
SubnetPoolID string `json:"subnetpool_id,omitempty"`
|
||||
|
||||
// Prefixlen is used when user creates a subnet from the subnetpool. It will
|
||||
// overwrite the "default_prefixlen" value of the referenced subnetpool.
|
||||
Prefixlen int `json:"prefixlen,omitempty"`
|
||||
}
|
||||
|
||||
// ToSubnetCreateMap builds a request body from CreateOpts.
|
||||
func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) {
|
||||
b, err := gophercloud.BuildRequestBody(opts, "subnet")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if m := b["subnet"].(map[string]interface{}); m["gateway_ip"] == "" {
|
||||
m["gateway_ip"] = nil
|
||||
}
|
||||
|
||||
return b, 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) (r CreateResult) {
|
||||
b, err := opts.ToSubnetCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Post(createURL(c), b, &r.Body, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// 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 is a human-readable name of the subnet.
|
||||
Name *string `json:"name,omitempty"`
|
||||
|
||||
// Description of the subnet.
|
||||
Description *string `json:"description,omitempty"`
|
||||
|
||||
// AllocationPools are IP Address pools that will be available for DHCP.
|
||||
AllocationPools []AllocationPool `json:"allocation_pools,omitempty"`
|
||||
|
||||
// GatewayIP sets gateway information for the subnet. Setting to nil will
|
||||
// cause a default gateway to automatically be created. Setting to an empty
|
||||
// string will cause the subnet to be created with no gateway. Setting to
|
||||
// an explicit address will set that address as the gateway.
|
||||
GatewayIP *string `json:"gateway_ip,omitempty"`
|
||||
|
||||
// DNSNameservers are the nameservers to be set via DHCP.
|
||||
DNSNameservers *[]string `json:"dns_nameservers,omitempty"`
|
||||
|
||||
// HostRoutes are any static host routes to be set via DHCP.
|
||||
HostRoutes *[]HostRoute `json:"host_routes,omitempty"`
|
||||
|
||||
// EnableDHCP will either enable to disable the DHCP service.
|
||||
EnableDHCP *bool `json:"enable_dhcp,omitempty"`
|
||||
}
|
||||
|
||||
// ToSubnetUpdateMap builds a request body from UpdateOpts.
|
||||
func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) {
|
||||
b, err := gophercloud.BuildRequestBody(opts, "subnet")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if m := b["subnet"].(map[string]interface{}); m["gateway_ip"] == "" {
|
||||
m["gateway_ip"] = nil
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Update accepts a UpdateOpts struct and updates an existing subnet using the
|
||||
// values provided.
|
||||
func Update(c *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) {
|
||||
b, err := opts.ToSubnetUpdateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = c.Put(updateURL(c, id), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200, 201},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Delete accepts a unique ID and deletes the subnet associated with it.
|
||||
func Delete(c *gophercloud.ServiceClient, id string) (r DeleteResult) {
|
||||
_, r.Err = c.Delete(deleteURL(c, id), nil)
|
||||
return
|
||||
}
|
||||
|
||||
// IDFromName is a convenience function that returns a subnet's ID,
|
||||
// given its name.
|
||||
func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
|
||||
count := 0
|
||||
id := ""
|
||||
|
||||
listOpts := ListOpts{
|
||||
Name: name,
|
||||
}
|
||||
|
||||
pages, err := List(client, listOpts).AllPages()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
all, err := ExtractSubnets(pages)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, s := range all {
|
||||
if s.Name == name {
|
||||
count++
|
||||
id = s.ID
|
||||
}
|
||||
}
|
||||
|
||||
switch count {
|
||||
case 0:
|
||||
return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "subnet"}
|
||||
case 1:
|
||||
return id, nil
|
||||
default:
|
||||
return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "subnet"}
|
||||
}
|
||||
}
|
||||
152
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/results.go
generated
vendored
152
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/results.go
generated
vendored
@ -0,0 +1,152 @@
|
||||
package subnets
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/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) {
|
||||
var s struct {
|
||||
Subnet *Subnet `json:"subnet"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.Subnet, err
|
||||
}
|
||||
|
||||
// CreateResult represents the result of a create operation. Call its Extract
|
||||
// method to interpret it as a Subnet.
|
||||
type CreateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// GetResult represents the result of a get operation. Call its Extract
|
||||
// method to interpret it as a Subnet.
|
||||
type GetResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// UpdateResult represents the result of an update operation. Call its Extract
|
||||
// method to interpret it as a Subnet.
|
||||
type UpdateResult struct {
|
||||
commonResult
|
||||
}
|
||||
|
||||
// DeleteResult represents the result of a delete operation. Call its
|
||||
// ExtractErr method to determine if the request succeeded or failed.
|
||||
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 `json:"destination"`
|
||||
NextHop string `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 `json:"id"`
|
||||
|
||||
// UUID of the parent network.
|
||||
NetworkID string `json:"network_id"`
|
||||
|
||||
// Human-readable name for the subnet. Might not be unique.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Description for the subnet.
|
||||
Description string `json:"description"`
|
||||
|
||||
// IP version, either `4' or `6'.
|
||||
IPVersion int `json:"ip_version"`
|
||||
|
||||
// CIDR representing IP range for this subnet, based on IP version.
|
||||
CIDR string `json:"cidr"`
|
||||
|
||||
// Default gateway used by devices in this subnet.
|
||||
GatewayIP string `json:"gateway_ip"`
|
||||
|
||||
// DNS name servers used by hosts in this subnet.
|
||||
DNSNameservers []string `json:"dns_nameservers"`
|
||||
|
||||
// Sub-ranges of CIDR available for dynamic allocation to ports.
|
||||
// See AllocationPool.
|
||||
AllocationPools []AllocationPool `json:"allocation_pools"`
|
||||
|
||||
// Routes that should be used by devices with IPs from this subnet
|
||||
// (not including local subnet route).
|
||||
HostRoutes []HostRoute `json:"host_routes"`
|
||||
|
||||
// Specifies whether DHCP is enabled for this subnet or not.
|
||||
EnableDHCP bool `json:"enable_dhcp"`
|
||||
|
||||
// TenantID is the project owner of the subnet.
|
||||
TenantID string `json:"tenant_id"`
|
||||
|
||||
// ProjectID is the project owner of the subnet.
|
||||
ProjectID string `json:"project_id"`
|
||||
|
||||
// The IPv6 address modes specifies mechanisms for assigning IPv6 IP addresses.
|
||||
IPv6AddressMode string `json:"ipv6_address_mode"`
|
||||
|
||||
// The IPv6 router advertisement specifies whether the networking service
|
||||
// should transmit ICMPv6 packets.
|
||||
IPv6RAMode string `json:"ipv6_ra_mode"`
|
||||
|
||||
// SubnetPoolID is the id of the subnet pool associated with the subnet.
|
||||
SubnetPoolID string `json:"subnetpool_id"`
|
||||
|
||||
// Tags optionally set via extensions/attributestags
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
// 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 (r SubnetPage) NextPageURL() (string, error) {
|
||||
var s struct {
|
||||
Links []gophercloud.Link `json:"subnets_links"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return gophercloud.ExtractNextURL(s.Links)
|
||||
}
|
||||
|
||||
// IsEmpty checks whether a SubnetPage struct is empty.
|
||||
func (r SubnetPage) IsEmpty() (bool, error) {
|
||||
is, err := ExtractSubnets(r)
|
||||
return len(is) == 0, err
|
||||
}
|
||||
|
||||
// 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(r pagination.Page) ([]Subnet, error) {
|
||||
var s struct {
|
||||
Subnets []Subnet `json:"subnets"`
|
||||
}
|
||||
err := (r.(SubnetPage)).ExtractInto(&s)
|
||||
return s.Subnets, err
|
||||
}
|
||||
31
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/urls.go
generated
vendored
31
vendor/github.com/gophercloud/gophercloud/openstack/networking/v2/subnets/urls.go
generated
vendored
@ -0,0 +1,31 @@
|
||||
package subnets
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
func resourceURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return c.ServiceURL("subnets", id)
|
||||
}
|
||||
|
||||
func rootURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL("subnets")
|
||||
}
|
||||
|
||||
func listURL(c *gophercloud.ServiceClient) string {
|
||||
return rootURL(c)
|
||||
}
|
||||
|
||||
func getURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return resourceURL(c, id)
|
||||
}
|
||||
|
||||
func createURL(c *gophercloud.ServiceClient) string {
|
||||
return rootURL(c)
|
||||
}
|
||||
|
||||
func updateURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return resourceURL(c, id)
|
||||
}
|
||||
|
||||
func deleteURL(c *gophercloud.ServiceClient, id string) string {
|
||||
return resourceURL(c, id)
|
||||
}
|
||||
Loading…
Reference in new issue