Update Subnet Gateway Behavior (#102)
This commit enables all three behaviors of a gateway during subnet creation and
updating.
If a GatewayIP is omitted, Neutron will provision a default gateway.
If a GatewayIP is set to an empty string, no gateway will be provisioned.
If a GatewayIP is specified, it will be used as the gateway IP.
diff --git a/acceptance/openstack/networking/v2/networking.go b/acceptance/openstack/networking/v2/networking.go
index 9432dda..cc5befb 100644
--- a/acceptance/openstack/networking/v2/networking.go
+++ b/acceptance/openstack/networking/v2/networking.go
@@ -72,13 +72,12 @@
subnetOctet := tools.RandomInt(1, 250)
subnetCIDR := fmt.Sprintf("192.168.%d.0/24", subnetOctet)
subnetGateway := fmt.Sprintf("192.168.%d.1", subnetOctet)
- iFalse := false
createOpts := subnets.CreateOpts{
NetworkID: networkID,
CIDR: subnetCIDR,
IPVersion: 4,
Name: subnetName,
- EnableDHCP: &iFalse,
+ EnableDHCP: gophercloud.Disabled,
GatewayIP: &subnetGateway,
}
@@ -93,6 +92,68 @@
return subnet, nil
}
+// CreateSubnetWithDefaultGateway will create a subnet on the specified Network
+// ID and have Neutron set the gateway by default An error will be returned if
+// the subnet could not be created.
+func CreateSubnetWithDefaultGateway(t *testing.T, client *gophercloud.ServiceClient, networkID string) (*subnets.Subnet, error) {
+ subnetName := tools.RandomString("TESTACC-", 8)
+ subnetOctet := tools.RandomInt(1, 250)
+ subnetCIDR := fmt.Sprintf("192.168.%d.0/24", subnetOctet)
+ createOpts := subnets.CreateOpts{
+ NetworkID: networkID,
+ CIDR: subnetCIDR,
+ IPVersion: 4,
+ Name: subnetName,
+ EnableDHCP: gophercloud.Disabled,
+ }
+
+ t.Logf("Attempting to create subnet: %s", subnetName)
+
+ subnet, err := subnets.Create(client, createOpts).Extract()
+ if err != nil {
+ return subnet, err
+ }
+
+ t.Logf("Successfully created subnet.")
+ return subnet, nil
+}
+
+// CreateSubnetWithNoGateway will create a subnet with no gateway on the
+// specified Network ID. An error will be returned if the subnet could not be
+// created.
+func CreateSubnetWithNoGateway(t *testing.T, client *gophercloud.ServiceClient, networkID string) (*subnets.Subnet, error) {
+ var noGateway = ""
+ subnetName := tools.RandomString("TESTACC-", 8)
+ subnetOctet := tools.RandomInt(1, 250)
+ subnetCIDR := fmt.Sprintf("192.168.%d.0/24", subnetOctet)
+ dhcpStart := fmt.Sprintf("192.168.%d.10", subnetOctet)
+ dhcpEnd := fmt.Sprintf("192.168.%d.200", subnetOctet)
+ createOpts := subnets.CreateOpts{
+ NetworkID: networkID,
+ CIDR: subnetCIDR,
+ IPVersion: 4,
+ Name: subnetName,
+ EnableDHCP: gophercloud.Disabled,
+ GatewayIP: &noGateway,
+ AllocationPools: []subnets.AllocationPool{
+ {
+ Start: dhcpStart,
+ End: dhcpEnd,
+ },
+ },
+ }
+
+ t.Logf("Attempting to create subnet: %s", subnetName)
+
+ subnet, err := subnets.Create(client, createOpts).Extract()
+ if err != nil {
+ return subnet, err
+ }
+
+ t.Logf("Successfully created subnet.")
+ return subnet, nil
+}
+
// DeleteNetwork will delete a network with a specified ID. A fatal error will
// occur if the delete was not successful. This works best when used as a
// deferred function.
diff --git a/acceptance/openstack/networking/v2/subnets_test.go b/acceptance/openstack/networking/v2/subnets_test.go
index 49c970a..1d7696c 100644
--- a/acceptance/openstack/networking/v2/subnets_test.go
+++ b/acceptance/openstack/networking/v2/subnets_test.go
@@ -3,6 +3,8 @@
package v2
import (
+ "fmt"
+ "strings"
"testing"
"github.com/gophercloud/gophercloud/acceptance/clients"
@@ -71,3 +73,86 @@
PrintSubnet(t, newSubnet)
}
+
+func TestSubnetsDefaultGateway(t *testing.T) {
+ client, err := clients.NewNetworkV2Client()
+ if err != nil {
+ t.Fatalf("Unable to create a network client: %v", err)
+ }
+
+ // Create Network
+ network, err := CreateNetwork(t, client)
+ if err != nil {
+ t.Fatalf("Unable to create network: %v", err)
+ }
+ defer DeleteNetwork(t, client, network.ID)
+
+ // Create Subnet
+ subnet, err := CreateSubnetWithDefaultGateway(t, client, network.ID)
+ if err != nil {
+ t.Fatalf("Unable to create subnet: %v", err)
+ }
+ defer DeleteSubnet(t, client, subnet.ID)
+
+ PrintSubnet(t, subnet)
+
+ if subnet.GatewayIP == "" {
+ t.Fatalf("A default gateway was not created.")
+ }
+
+ var noGateway = ""
+ updateOpts := subnets.UpdateOpts{
+ GatewayIP: &noGateway,
+ }
+
+ newSubnet, err := subnets.Update(client, subnet.ID, updateOpts).Extract()
+ if err != nil {
+ t.Fatalf("Unable to update subnet")
+ }
+
+ if newSubnet.GatewayIP != "" {
+ t.Fatalf("Gateway was not updated correctly")
+ }
+}
+
+func TestSubnetsNoGateway(t *testing.T) {
+ client, err := clients.NewNetworkV2Client()
+ if err != nil {
+ t.Fatalf("Unable to create a network client: %v", err)
+ }
+
+ // Create Network
+ network, err := CreateNetwork(t, client)
+ if err != nil {
+ t.Fatalf("Unable to create network: %v", err)
+ }
+ defer DeleteNetwork(t, client, network.ID)
+
+ // Create Subnet
+ subnet, err := CreateSubnetWithNoGateway(t, client, network.ID)
+ if err != nil {
+ t.Fatalf("Unable to create subnet: %v", err)
+ }
+ defer DeleteSubnet(t, client, subnet.ID)
+
+ PrintSubnet(t, subnet)
+
+ if subnet.GatewayIP != "" {
+ t.Fatalf("A gateway exists when it shouldn't.")
+ }
+
+ subnetParts := strings.Split(subnet.CIDR, ".")
+ newGateway := fmt.Sprintf("%s.%s.%s.1", subnetParts[0], subnetParts[1], subnetParts[2])
+ updateOpts := subnets.UpdateOpts{
+ GatewayIP: &newGateway,
+ }
+
+ newSubnet, err := subnets.Update(client, subnet.ID, updateOpts).Extract()
+ if err != nil {
+ t.Fatalf("Unable to update subnet")
+ }
+
+ if newSubnet.GatewayIP == "" {
+ t.Fatalf("Gateway was not updated correctly")
+ }
+}