github.com/gophercloud/gophercloud@v1.11.0/internal/acceptance/openstack/networking/v2/subnets_test.go (about)

     1  //go:build acceptance || networking
     2  // +build acceptance networking
     3  
     4  package v2
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/gophercloud/gophercloud/internal/acceptance/clients"
    12  	subnetpools "github.com/gophercloud/gophercloud/internal/acceptance/openstack/networking/v2/extensions/subnetpools"
    13  	"github.com/gophercloud/gophercloud/internal/acceptance/tools"
    14  	"github.com/gophercloud/gophercloud/openstack/networking/v2/subnets"
    15  	th "github.com/gophercloud/gophercloud/testhelper"
    16  )
    17  
    18  func TestSubnetCRUD(t *testing.T) {
    19  	client, err := clients.NewNetworkV2Client()
    20  	th.AssertNoErr(t, err)
    21  
    22  	// Create Network
    23  	network, err := CreateNetwork(t, client)
    24  	th.AssertNoErr(t, err)
    25  	defer DeleteNetwork(t, client, network.ID)
    26  
    27  	// Create Subnet
    28  	subnet, err := CreateSubnet(t, client, network.ID)
    29  	th.AssertNoErr(t, err)
    30  	defer DeleteSubnet(t, client, subnet.ID)
    31  
    32  	tools.PrintResource(t, subnet)
    33  
    34  	// Update Subnet
    35  	newSubnetName := tools.RandomString("TESTACC-", 8)
    36  	newSubnetDescription := ""
    37  	updateOpts := subnets.UpdateOpts{
    38  		Name:        &newSubnetName,
    39  		Description: &newSubnetDescription,
    40  	}
    41  	_, err = subnets.Update(client, subnet.ID, updateOpts).Extract()
    42  	th.AssertNoErr(t, err)
    43  
    44  	// Get subnet
    45  	newSubnet, err := subnets.Get(client, subnet.ID).Extract()
    46  	th.AssertNoErr(t, err)
    47  
    48  	tools.PrintResource(t, newSubnet)
    49  	th.AssertEquals(t, newSubnet.Name, newSubnetName)
    50  	th.AssertEquals(t, newSubnet.Description, newSubnetDescription)
    51  
    52  	allPages, err := subnets.List(client, nil).AllPages()
    53  	th.AssertNoErr(t, err)
    54  
    55  	allSubnets, err := subnets.ExtractSubnets(allPages)
    56  	th.AssertNoErr(t, err)
    57  
    58  	var found bool
    59  	for _, subnet := range allSubnets {
    60  		if subnet.ID == newSubnet.ID {
    61  			found = true
    62  		}
    63  	}
    64  
    65  	th.AssertEquals(t, found, true)
    66  }
    67  
    68  func TestSubnetsServiceType(t *testing.T) {
    69  	client, err := clients.NewNetworkV2Client()
    70  	th.AssertNoErr(t, err)
    71  
    72  	// Create Network
    73  	network, err := CreateNetwork(t, client)
    74  	th.AssertNoErr(t, err)
    75  	defer DeleteNetwork(t, client, network.ID)
    76  
    77  	// Create Subnet
    78  	subnet, err := CreateSubnetWithServiceTypes(t, client, network.ID)
    79  	th.AssertNoErr(t, err)
    80  	defer DeleteSubnet(t, client, subnet.ID)
    81  
    82  	tools.PrintResource(t, subnet)
    83  
    84  	serviceTypes := []string{"network:floatingip"}
    85  	updateOpts := subnets.UpdateOpts{
    86  		ServiceTypes: &serviceTypes,
    87  	}
    88  
    89  	newSubnet, err := subnets.Update(client, subnet.ID, updateOpts).Extract()
    90  	th.AssertNoErr(t, err)
    91  
    92  	th.AssertDeepEquals(t, newSubnet.ServiceTypes, serviceTypes)
    93  }
    94  
    95  func TestSubnetsDefaultGateway(t *testing.T) {
    96  	client, err := clients.NewNetworkV2Client()
    97  	th.AssertNoErr(t, err)
    98  
    99  	// Create Network
   100  	network, err := CreateNetwork(t, client)
   101  	th.AssertNoErr(t, err)
   102  	defer DeleteNetwork(t, client, network.ID)
   103  
   104  	// Create Subnet
   105  	subnet, err := CreateSubnetWithDefaultGateway(t, client, network.ID)
   106  	th.AssertNoErr(t, err)
   107  	defer DeleteSubnet(t, client, subnet.ID)
   108  
   109  	tools.PrintResource(t, subnet)
   110  
   111  	if subnet.GatewayIP == "" {
   112  		t.Fatalf("A default gateway was not created.")
   113  	}
   114  
   115  	var noGateway = ""
   116  	updateOpts := subnets.UpdateOpts{
   117  		GatewayIP: &noGateway,
   118  	}
   119  
   120  	newSubnet, err := subnets.Update(client, subnet.ID, updateOpts).Extract()
   121  	th.AssertNoErr(t, err)
   122  
   123  	if newSubnet.GatewayIP != "" {
   124  		t.Fatalf("Gateway was not updated correctly")
   125  	}
   126  }
   127  
   128  func TestSubnetsNoGateway(t *testing.T) {
   129  	client, err := clients.NewNetworkV2Client()
   130  	th.AssertNoErr(t, err)
   131  
   132  	// Create Network
   133  	network, err := CreateNetwork(t, client)
   134  	th.AssertNoErr(t, err)
   135  	defer DeleteNetwork(t, client, network.ID)
   136  
   137  	// Create Subnet
   138  	subnet, err := CreateSubnetWithNoGateway(t, client, network.ID)
   139  	th.AssertNoErr(t, err)
   140  	defer DeleteSubnet(t, client, subnet.ID)
   141  
   142  	tools.PrintResource(t, subnet)
   143  
   144  	if subnet.GatewayIP != "" {
   145  		t.Fatalf("A gateway exists when it shouldn't.")
   146  	}
   147  
   148  	subnetParts := strings.Split(subnet.CIDR, ".")
   149  	newGateway := fmt.Sprintf("%s.%s.%s.1", subnetParts[0], subnetParts[1], subnetParts[2])
   150  	updateOpts := subnets.UpdateOpts{
   151  		GatewayIP: &newGateway,
   152  	}
   153  
   154  	newSubnet, err := subnets.Update(client, subnet.ID, updateOpts).Extract()
   155  	th.AssertNoErr(t, err)
   156  
   157  	if newSubnet.GatewayIP == "" {
   158  		t.Fatalf("Gateway was not updated correctly")
   159  	}
   160  }
   161  
   162  func TestSubnetsWithSubnetPool(t *testing.T) {
   163  	client, err := clients.NewNetworkV2Client()
   164  	th.AssertNoErr(t, err)
   165  
   166  	// Create Network
   167  	network, err := CreateNetwork(t, client)
   168  	th.AssertNoErr(t, err)
   169  	defer DeleteNetwork(t, client, network.ID)
   170  
   171  	// Create SubnetPool
   172  	subnetPool, err := subnetpools.CreateSubnetPool(t, client)
   173  	th.AssertNoErr(t, err)
   174  	defer subnetpools.DeleteSubnetPool(t, client, subnetPool.ID)
   175  
   176  	// Create Subnet
   177  	subnet, err := CreateSubnetWithSubnetPool(t, client, network.ID, subnetPool.ID)
   178  	th.AssertNoErr(t, err)
   179  	defer DeleteSubnet(t, client, subnet.ID)
   180  
   181  	tools.PrintResource(t, subnet)
   182  
   183  	if subnet.GatewayIP == "" {
   184  		t.Fatalf("A subnet pool was not associated.")
   185  	}
   186  }
   187  
   188  func TestSubnetsWithSubnetPoolNoCIDR(t *testing.T) {
   189  	client, err := clients.NewNetworkV2Client()
   190  	th.AssertNoErr(t, err)
   191  
   192  	// Create Network
   193  	network, err := CreateNetwork(t, client)
   194  	th.AssertNoErr(t, err)
   195  	defer DeleteNetwork(t, client, network.ID)
   196  
   197  	// Create SubnetPool
   198  	subnetPool, err := subnetpools.CreateSubnetPool(t, client)
   199  	th.AssertNoErr(t, err)
   200  	defer subnetpools.DeleteSubnetPool(t, client, subnetPool.ID)
   201  
   202  	// Create Subnet
   203  	subnet, err := CreateSubnetWithSubnetPoolNoCIDR(t, client, network.ID, subnetPool.ID)
   204  	th.AssertNoErr(t, err)
   205  	defer DeleteSubnet(t, client, subnet.ID)
   206  
   207  	tools.PrintResource(t, subnet)
   208  
   209  	if subnet.GatewayIP == "" {
   210  		t.Fatalf("A subnet pool was not associated.")
   211  	}
   212  }
   213  
   214  func TestSubnetsWithSubnetPoolPrefixlen(t *testing.T) {
   215  	client, err := clients.NewNetworkV2Client()
   216  	th.AssertNoErr(t, err)
   217  
   218  	// Create Network
   219  	network, err := CreateNetwork(t, client)
   220  	th.AssertNoErr(t, err)
   221  	defer DeleteNetwork(t, client, network.ID)
   222  
   223  	// Create SubnetPool
   224  	subnetPool, err := subnetpools.CreateSubnetPool(t, client)
   225  	th.AssertNoErr(t, err)
   226  	defer subnetpools.DeleteSubnetPool(t, client, subnetPool.ID)
   227  
   228  	// Create Subnet
   229  	subnet, err := CreateSubnetWithSubnetPoolPrefixlen(t, client, network.ID, subnetPool.ID)
   230  	th.AssertNoErr(t, err)
   231  	defer DeleteSubnet(t, client, subnet.ID)
   232  
   233  	tools.PrintResource(t, subnet)
   234  
   235  	if subnet.GatewayIP == "" {
   236  		t.Fatalf("A subnet pool was not associated.")
   237  	}
   238  
   239  	cidrParts := strings.Split(subnet.CIDR, "/")
   240  	if len(cidrParts) != 2 {
   241  		t.Fatalf("Got invalid CIDR for subnet '%s': %s", subnet.ID, subnet.CIDR)
   242  	}
   243  
   244  	if cidrParts[1] != "12" {
   245  		t.Fatalf("Got invalid prefix length for subnet '%s': wanted 12 but got '%s'", subnet.ID, cidrParts[1])
   246  	}
   247  }
   248  
   249  func TestSubnetDNSNameservers(t *testing.T) {
   250  	client, err := clients.NewNetworkV2Client()
   251  	th.AssertNoErr(t, err)
   252  
   253  	// Create Network
   254  	network, err := CreateNetwork(t, client)
   255  	th.AssertNoErr(t, err)
   256  	defer DeleteNetwork(t, client, network.ID)
   257  
   258  	// Create Subnet
   259  	subnet, err := CreateSubnet(t, client, network.ID)
   260  	th.AssertNoErr(t, err)
   261  	defer DeleteSubnet(t, client, subnet.ID)
   262  
   263  	tools.PrintResource(t, subnet)
   264  
   265  	// Update Subnet
   266  	dnsNameservers := []string{"1.1.1.1"}
   267  	updateOpts := subnets.UpdateOpts{
   268  		DNSNameservers: &dnsNameservers,
   269  	}
   270  	_, err = subnets.Update(client, subnet.ID, updateOpts).Extract()
   271  	th.AssertNoErr(t, err)
   272  
   273  	// Get subnet
   274  	newSubnet, err := subnets.Get(client, subnet.ID).Extract()
   275  	th.AssertNoErr(t, err)
   276  
   277  	tools.PrintResource(t, newSubnet)
   278  	th.AssertEquals(t, len(newSubnet.DNSNameservers), 1)
   279  
   280  	// Update Subnet again
   281  	dnsNameservers = []string{}
   282  	updateOpts = subnets.UpdateOpts{
   283  		DNSNameservers: &dnsNameservers,
   284  	}
   285  	_, err = subnets.Update(client, subnet.ID, updateOpts).Extract()
   286  	th.AssertNoErr(t, err)
   287  
   288  	// Get subnet
   289  	newSubnet, err = subnets.Get(client, subnet.ID).Extract()
   290  	th.AssertNoErr(t, err)
   291  
   292  	tools.PrintResource(t, newSubnet)
   293  	th.AssertEquals(t, len(newSubnet.DNSNameservers), 0)
   294  }
   295  
   296  func TestSubnetsRevision(t *testing.T) {
   297  	client, err := clients.NewNetworkV2Client()
   298  	th.AssertNoErr(t, err)
   299  
   300  	// Create Network
   301  	network, err := CreateNetwork(t, client)
   302  	th.AssertNoErr(t, err)
   303  	defer DeleteNetwork(t, client, network.ID)
   304  
   305  	// Create Subnet
   306  	subnet, err := CreateSubnet(t, client, network.ID)
   307  	th.AssertNoErr(t, err)
   308  	defer DeleteSubnet(t, client, subnet.ID)
   309  
   310  	tools.PrintResource(t, subnet)
   311  
   312  	// Store the current revision number.
   313  	oldRevisionNumber := subnet.RevisionNumber
   314  
   315  	// Update Subnet without revision number.
   316  	// This should work.
   317  	newSubnetName := tools.RandomString("TESTACC-", 8)
   318  	newSubnetDescription := ""
   319  	updateOpts := &subnets.UpdateOpts{
   320  		Name:        &newSubnetName,
   321  		Description: &newSubnetDescription,
   322  	}
   323  	subnet, err = subnets.Update(client, subnet.ID, updateOpts).Extract()
   324  	th.AssertNoErr(t, err)
   325  
   326  	tools.PrintResource(t, subnet)
   327  
   328  	// This should fail due to an old revision number.
   329  	newSubnetDescription = "new description"
   330  	updateOpts = &subnets.UpdateOpts{
   331  		Name:           &newSubnetName,
   332  		Description:    &newSubnetDescription,
   333  		RevisionNumber: &oldRevisionNumber,
   334  	}
   335  	_, err = subnets.Update(client, subnet.ID, updateOpts).Extract()
   336  	th.AssertErr(t, err)
   337  	if !strings.Contains(err.Error(), "RevisionNumberConstraintFailed") {
   338  		t.Fatalf("expected to see an error of type RevisionNumberConstraintFailed, but got the following error instead: %v", err)
   339  	}
   340  
   341  	// Reread the subnet to show that it did not change.
   342  	subnet, err = subnets.Get(client, subnet.ID).Extract()
   343  	th.AssertNoErr(t, err)
   344  
   345  	tools.PrintResource(t, subnet)
   346  
   347  	// This should work because now we do provide a valid revision number.
   348  	newSubnetDescription = "new description"
   349  	updateOpts = &subnets.UpdateOpts{
   350  		Name:           &newSubnetName,
   351  		Description:    &newSubnetDescription,
   352  		RevisionNumber: &subnet.RevisionNumber,
   353  	}
   354  	subnet, err = subnets.Update(client, subnet.ID, updateOpts).Extract()
   355  	th.AssertNoErr(t, err)
   356  
   357  	tools.PrintResource(t, subnet)
   358  
   359  	th.AssertEquals(t, subnet.Name, newSubnetName)
   360  	th.AssertEquals(t, subnet.Description, newSubnetDescription)
   361  }