github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/internal/acceptance/openstack/networking/v2/ports_test.go (about)

     1  //go:build acceptance || networking || ports
     2  
     3  package v2
     4  
     5  import (
     6  	"context"
     7  	"fmt"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/clients"
    12  	extensions "github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/openstack/networking/v2/extensions"
    13  	"github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/tools"
    14  	"github.com/vnpaycloud-console/gophercloud/v2/openstack/networking/v2/extensions/extradhcpopts"
    15  	"github.com/vnpaycloud-console/gophercloud/v2/openstack/networking/v2/extensions/portsecurity"
    16  	"github.com/vnpaycloud-console/gophercloud/v2/openstack/networking/v2/ports"
    17  	th "github.com/vnpaycloud-console/gophercloud/v2/testhelper"
    18  )
    19  
    20  func TestPortsCRUD(t *testing.T) {
    21  	client, err := clients.NewNetworkV2Client()
    22  	th.AssertNoErr(t, err)
    23  
    24  	// Create Network
    25  	network, err := CreateNetwork(t, client)
    26  	th.AssertNoErr(t, err)
    27  	defer DeleteNetwork(t, client, network.ID)
    28  
    29  	// Create Subnet
    30  	subnet, err := CreateSubnet(t, client, network.ID)
    31  	th.AssertNoErr(t, err)
    32  	defer DeleteSubnet(t, client, subnet.ID)
    33  
    34  	// Create port
    35  	port, err := CreatePort(t, client, network.ID, subnet.ID)
    36  	th.AssertNoErr(t, err)
    37  	defer DeletePort(t, client, port.ID)
    38  
    39  	if len(port.SecurityGroups) != 1 {
    40  		t.Logf("WARNING: Port did not have a default security group applied")
    41  	}
    42  
    43  	tools.PrintResource(t, port)
    44  
    45  	// Update port
    46  	newPortName := ""
    47  	newPortDescription := ""
    48  	updateOpts := ports.UpdateOpts{
    49  		Name:        &newPortName,
    50  		Description: &newPortDescription,
    51  	}
    52  	newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract()
    53  	th.AssertNoErr(t, err)
    54  
    55  	tools.PrintResource(t, newPort)
    56  
    57  	th.AssertEquals(t, newPort.Name, newPortName)
    58  	th.AssertEquals(t, newPort.Description, newPortDescription)
    59  
    60  	allPages, err := ports.List(client, nil).AllPages(context.TODO())
    61  	th.AssertNoErr(t, err)
    62  
    63  	allPorts, err := ports.ExtractPorts(allPages)
    64  	th.AssertNoErr(t, err)
    65  
    66  	var found bool
    67  	for _, port := range allPorts {
    68  		if port.ID == newPort.ID {
    69  			found = true
    70  		}
    71  	}
    72  
    73  	th.AssertEquals(t, found, true)
    74  
    75  	ipAddress := port.FixedIPs[0].IPAddress
    76  	t.Logf("Port has IP address: %s", ipAddress)
    77  
    78  	// List ports by fixed IP
    79  	// All of the following listOpts should return the port
    80  	for _, tt := range []struct {
    81  		name          string
    82  		opts          ports.ListOpts
    83  		expectedPorts int
    84  	}{
    85  		{
    86  			name: "Port ID",
    87  			opts: ports.ListOpts{
    88  				ID: port.ID,
    89  			},
    90  			expectedPorts: 1,
    91  		},
    92  		{
    93  			name: "Network ID",
    94  			opts: ports.ListOpts{
    95  				NetworkID: port.NetworkID,
    96  			},
    97  			expectedPorts: 2, // Will also return DHCP port
    98  		},
    99  		{
   100  			name: "Subnet ID",
   101  			opts: ports.ListOpts{
   102  				FixedIPs: []ports.FixedIPOpts{
   103  					{SubnetID: subnet.ID},
   104  				},
   105  			},
   106  			expectedPorts: 1,
   107  		},
   108  		{
   109  			name: "IP Address",
   110  			opts: ports.ListOpts{
   111  				FixedIPs: []ports.FixedIPOpts{
   112  					{IPAddress: ipAddress},
   113  				},
   114  			},
   115  			expectedPorts: 1,
   116  		},
   117  		{
   118  			name: "Subnet ID and IP Address",
   119  			opts: ports.ListOpts{
   120  				FixedIPs: []ports.FixedIPOpts{
   121  					{SubnetID: subnet.ID, IPAddress: ipAddress},
   122  				},
   123  			},
   124  			expectedPorts: 1,
   125  		},
   126  	} {
   127  		t.Run(fmt.Sprintf("List ports by %s", tt.name), func(t *testing.T) {
   128  			allPages, err := ports.List(client, tt.opts).AllPages(context.TODO())
   129  			th.AssertNoErr(t, err)
   130  
   131  			allPorts, err := ports.ExtractPorts(allPages)
   132  			th.AssertNoErr(t, err)
   133  
   134  			logPorts := func() {
   135  				for _, port := range allPorts {
   136  					tools.PrintResource(t, port)
   137  				}
   138  			}
   139  
   140  			if len(allPorts) != tt.expectedPorts {
   141  				if len(allPorts) == 0 {
   142  					t.Fatalf("Port not found")
   143  				}
   144  				if len(allPorts) > 1 {
   145  					logPorts()
   146  					t.Fatalf("Expected %d port but got %d", tt.expectedPorts, len(allPorts))
   147  				}
   148  			}
   149  			func() {
   150  				for _, port := range allPorts {
   151  					if port.ID == newPort.ID {
   152  						return
   153  					}
   154  				}
   155  				logPorts()
   156  				t.Fatalf("Returned ports did not contain expected port")
   157  			}()
   158  		})
   159  	}
   160  }
   161  
   162  func TestPortsRemoveSecurityGroups(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 Subnet
   172  	subnet, err := CreateSubnet(t, client, network.ID)
   173  	th.AssertNoErr(t, err)
   174  	defer DeleteSubnet(t, client, subnet.ID)
   175  
   176  	// Create port
   177  	port, err := CreatePort(t, client, network.ID, subnet.ID)
   178  	th.AssertNoErr(t, err)
   179  	defer DeletePort(t, client, port.ID)
   180  
   181  	tools.PrintResource(t, port)
   182  
   183  	// Create a Security Group
   184  	group, err := extensions.CreateSecurityGroup(t, client)
   185  	th.AssertNoErr(t, err)
   186  	defer extensions.DeleteSecurityGroup(t, client, group.ID)
   187  
   188  	// Add the group to the port
   189  	updateOpts := ports.UpdateOpts{
   190  		SecurityGroups: &[]string{group.ID},
   191  	}
   192  	_, err = ports.Update(context.TODO(), client, port.ID, updateOpts).Extract()
   193  	th.AssertNoErr(t, err)
   194  
   195  	// Remove the group
   196  	updateOpts = ports.UpdateOpts{
   197  		SecurityGroups: &[]string{},
   198  	}
   199  	newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract()
   200  	th.AssertNoErr(t, err)
   201  
   202  	tools.PrintResource(t, newPort)
   203  
   204  	if len(newPort.SecurityGroups) > 0 {
   205  		t.Fatalf("Unable to remove security group from port")
   206  	}
   207  }
   208  
   209  func TestPortsDontAlterSecurityGroups(t *testing.T) {
   210  	client, err := clients.NewNetworkV2Client()
   211  	th.AssertNoErr(t, err)
   212  
   213  	// Create Network
   214  	network, err := CreateNetwork(t, client)
   215  	th.AssertNoErr(t, err)
   216  	defer DeleteNetwork(t, client, network.ID)
   217  
   218  	// Create Subnet
   219  	subnet, err := CreateSubnet(t, client, network.ID)
   220  	th.AssertNoErr(t, err)
   221  	defer DeleteSubnet(t, client, subnet.ID)
   222  
   223  	// Create a Security Group
   224  	group, err := extensions.CreateSecurityGroup(t, client)
   225  	th.AssertNoErr(t, err)
   226  	defer extensions.DeleteSecurityGroup(t, client, group.ID)
   227  
   228  	// Create port
   229  	port, err := CreatePort(t, client, network.ID, subnet.ID)
   230  	th.AssertNoErr(t, err)
   231  	defer DeletePort(t, client, port.ID)
   232  
   233  	tools.PrintResource(t, port)
   234  
   235  	// Add the group to the port
   236  	updateOpts := ports.UpdateOpts{
   237  		SecurityGroups: &[]string{group.ID},
   238  	}
   239  	_, err = ports.Update(context.TODO(), client, port.ID, updateOpts).Extract()
   240  	th.AssertNoErr(t, err)
   241  
   242  	// Update the port again
   243  	var name = "some_port"
   244  	updateOpts = ports.UpdateOpts{
   245  		Name: &name,
   246  	}
   247  	newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract()
   248  	th.AssertNoErr(t, err)
   249  
   250  	tools.PrintResource(t, newPort)
   251  
   252  	if len(newPort.SecurityGroups) == 0 {
   253  		t.Fatalf("Port had security group updated")
   254  	}
   255  }
   256  
   257  func TestPortsWithNoSecurityGroup(t *testing.T) {
   258  	client, err := clients.NewNetworkV2Client()
   259  	th.AssertNoErr(t, err)
   260  
   261  	// Create Network
   262  	network, err := CreateNetwork(t, client)
   263  	th.AssertNoErr(t, err)
   264  	defer DeleteNetwork(t, client, network.ID)
   265  
   266  	// Create Subnet
   267  	subnet, err := CreateSubnet(t, client, network.ID)
   268  	th.AssertNoErr(t, err)
   269  	defer DeleteSubnet(t, client, subnet.ID)
   270  
   271  	// Create port
   272  	port, err := CreatePortWithNoSecurityGroup(t, client, network.ID, subnet.ID)
   273  	th.AssertNoErr(t, err)
   274  	defer DeletePort(t, client, port.ID)
   275  
   276  	tools.PrintResource(t, port)
   277  
   278  	if len(port.SecurityGroups) != 0 {
   279  		t.Fatalf("Port was created with security groups")
   280  	}
   281  }
   282  
   283  func TestPortsRemoveAddressPair(t *testing.T) {
   284  	client, err := clients.NewNetworkV2Client()
   285  	th.AssertNoErr(t, err)
   286  
   287  	// Create Network
   288  	network, err := CreateNetwork(t, client)
   289  	th.AssertNoErr(t, err)
   290  	defer DeleteNetwork(t, client, network.ID)
   291  
   292  	// Create Subnet
   293  	subnet, err := CreateSubnet(t, client, network.ID)
   294  	th.AssertNoErr(t, err)
   295  	defer DeleteSubnet(t, client, subnet.ID)
   296  
   297  	// Create port
   298  	port, err := CreatePort(t, client, network.ID, subnet.ID)
   299  	th.AssertNoErr(t, err)
   300  	defer DeletePort(t, client, port.ID)
   301  
   302  	tools.PrintResource(t, port)
   303  
   304  	// Add an address pair to the port
   305  	updateOpts := ports.UpdateOpts{
   306  		AllowedAddressPairs: &[]ports.AddressPair{
   307  			{IPAddress: "192.168.255.10", MACAddress: "aa:bb:cc:dd:ee:ff"},
   308  		},
   309  	}
   310  	_, err = ports.Update(context.TODO(), client, port.ID, updateOpts).Extract()
   311  	th.AssertNoErr(t, err)
   312  
   313  	// Remove the address pair
   314  	updateOpts = ports.UpdateOpts{
   315  		AllowedAddressPairs: &[]ports.AddressPair{},
   316  	}
   317  	newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract()
   318  	th.AssertNoErr(t, err)
   319  
   320  	tools.PrintResource(t, newPort)
   321  
   322  	if len(newPort.AllowedAddressPairs) > 0 {
   323  		t.Fatalf("Unable to remove the address pair")
   324  	}
   325  }
   326  
   327  func TestPortsDontUpdateAllowedAddressPairs(t *testing.T) {
   328  	client, err := clients.NewNetworkV2Client()
   329  	th.AssertNoErr(t, err)
   330  
   331  	// Create Network
   332  	network, err := CreateNetwork(t, client)
   333  	th.AssertNoErr(t, err)
   334  	defer DeleteNetwork(t, client, network.ID)
   335  
   336  	// Create Subnet
   337  	subnet, err := CreateSubnet(t, client, network.ID)
   338  	th.AssertNoErr(t, err)
   339  	defer DeleteSubnet(t, client, subnet.ID)
   340  
   341  	// Create port
   342  	port, err := CreatePort(t, client, network.ID, subnet.ID)
   343  	th.AssertNoErr(t, err)
   344  	defer DeletePort(t, client, port.ID)
   345  
   346  	tools.PrintResource(t, port)
   347  
   348  	// Add an address pair to the port
   349  	updateOpts := ports.UpdateOpts{
   350  		AllowedAddressPairs: &[]ports.AddressPair{
   351  			{IPAddress: "192.168.255.10", MACAddress: "aa:bb:cc:dd:ee:ff"},
   352  		},
   353  	}
   354  	newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract()
   355  	th.AssertNoErr(t, err)
   356  
   357  	tools.PrintResource(t, newPort)
   358  
   359  	// Remove the address pair
   360  	var name = "some_port"
   361  	updateOpts = ports.UpdateOpts{
   362  		Name: &name,
   363  	}
   364  	newPort, err = ports.Update(context.TODO(), client, port.ID, updateOpts).Extract()
   365  	th.AssertNoErr(t, err)
   366  
   367  	tools.PrintResource(t, newPort)
   368  
   369  	if len(newPort.AllowedAddressPairs) == 0 {
   370  		t.Fatalf("Address Pairs were removed")
   371  	}
   372  }
   373  
   374  func TestPortsPortSecurityCRUD(t *testing.T) {
   375  	client, err := clients.NewNetworkV2Client()
   376  	th.AssertNoErr(t, err)
   377  
   378  	// Create Network
   379  	network, err := CreateNetwork(t, client)
   380  	th.AssertNoErr(t, err)
   381  	defer DeleteNetwork(t, client, network.ID)
   382  
   383  	// Create Subnet
   384  	subnet, err := CreateSubnet(t, client, network.ID)
   385  	th.AssertNoErr(t, err)
   386  	defer DeleteSubnet(t, client, subnet.ID)
   387  
   388  	// Create port
   389  	port, err := CreatePortWithoutPortSecurity(t, client, network.ID, subnet.ID)
   390  	th.AssertNoErr(t, err)
   391  	defer DeletePort(t, client, port.ID)
   392  
   393  	var portWithExt struct {
   394  		ports.Port
   395  		portsecurity.PortSecurityExt
   396  	}
   397  
   398  	err = ports.Get(context.TODO(), client, port.ID).ExtractInto(&portWithExt)
   399  	th.AssertNoErr(t, err)
   400  
   401  	tools.PrintResource(t, portWithExt)
   402  
   403  	iTrue := true
   404  	portUpdateOpts := ports.UpdateOpts{}
   405  	updateOpts := portsecurity.PortUpdateOptsExt{
   406  		UpdateOptsBuilder:   portUpdateOpts,
   407  		PortSecurityEnabled: &iTrue,
   408  	}
   409  
   410  	err = ports.Update(context.TODO(), client, port.ID, updateOpts).ExtractInto(&portWithExt)
   411  	th.AssertNoErr(t, err)
   412  
   413  	tools.PrintResource(t, portWithExt)
   414  }
   415  
   416  func TestPortsWithExtraDHCPOptsCRUD(t *testing.T) {
   417  	client, err := clients.NewNetworkV2Client()
   418  	th.AssertNoErr(t, err)
   419  
   420  	// Create a Network
   421  	network, err := CreateNetwork(t, client)
   422  	th.AssertNoErr(t, err)
   423  	defer DeleteNetwork(t, client, network.ID)
   424  
   425  	// Create a Subnet
   426  	subnet, err := CreateSubnet(t, client, network.ID)
   427  	th.AssertNoErr(t, err)
   428  	defer DeleteSubnet(t, client, subnet.ID)
   429  
   430  	// Create a port with extra DHCP options.
   431  	port, err := CreatePortWithExtraDHCPOpts(t, client, network.ID, subnet.ID)
   432  	th.AssertNoErr(t, err)
   433  	defer DeletePort(t, client, port.ID)
   434  
   435  	tools.PrintResource(t, port)
   436  
   437  	// Update the port with extra DHCP options.
   438  	newPortName := tools.RandomString("TESTACC-", 8)
   439  	portUpdateOpts := ports.UpdateOpts{
   440  		Name: &newPortName,
   441  	}
   442  
   443  	existingOpt := port.ExtraDHCPOpts[0]
   444  	newOptValue := "test_value_2"
   445  
   446  	updateOpts := extradhcpopts.UpdateOptsExt{
   447  		UpdateOptsBuilder: portUpdateOpts,
   448  		ExtraDHCPOpts: []extradhcpopts.UpdateExtraDHCPOpt{
   449  			{
   450  				OptName:  existingOpt.OptName,
   451  				OptValue: nil,
   452  			},
   453  			{
   454  				OptName:  "test_option_2",
   455  				OptValue: &newOptValue,
   456  			},
   457  		},
   458  	}
   459  
   460  	newPort := &PortWithExtraDHCPOpts{}
   461  	err = ports.Update(context.TODO(), client, port.ID, updateOpts).ExtractInto(newPort)
   462  	th.AssertNoErr(t, err)
   463  
   464  	tools.PrintResource(t, newPort)
   465  }
   466  
   467  func TestPortsRevision(t *testing.T) {
   468  	client, err := clients.NewNetworkV2Client()
   469  	th.AssertNoErr(t, err)
   470  
   471  	// Create Network
   472  	network, err := CreateNetwork(t, client)
   473  	th.AssertNoErr(t, err)
   474  	defer DeleteNetwork(t, client, network.ID)
   475  
   476  	// Create Subnet
   477  	subnet, err := CreateSubnet(t, client, network.ID)
   478  	th.AssertNoErr(t, err)
   479  	defer DeleteSubnet(t, client, subnet.ID)
   480  
   481  	// Create port
   482  	port, err := CreatePort(t, client, network.ID, subnet.ID)
   483  	th.AssertNoErr(t, err)
   484  	defer DeletePort(t, client, port.ID)
   485  
   486  	tools.PrintResource(t, port)
   487  
   488  	// Add an address pair to the port
   489  	// Use the RevisionNumber to test the revision / If-Match logic.
   490  	updateOpts := ports.UpdateOpts{
   491  		AllowedAddressPairs: &[]ports.AddressPair{
   492  			{IPAddress: "192.168.255.10", MACAddress: "aa:bb:cc:dd:ee:ff"},
   493  		},
   494  		RevisionNumber: &port.RevisionNumber,
   495  	}
   496  	newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract()
   497  	th.AssertNoErr(t, err)
   498  
   499  	tools.PrintResource(t, newPort)
   500  
   501  	// Remove the address pair - this should fail due to old revision number.
   502  	updateOpts = ports.UpdateOpts{
   503  		AllowedAddressPairs: &[]ports.AddressPair{},
   504  		RevisionNumber:      &port.RevisionNumber,
   505  	}
   506  	_, err = ports.Update(context.TODO(), client, port.ID, updateOpts).Extract()
   507  	th.AssertErr(t, err)
   508  	if !strings.Contains(err.Error(), "RevisionNumberConstraintFailed") {
   509  		t.Fatalf("expected to see an error of type RevisionNumberConstraintFailed, but got the following error instead: %v", err)
   510  	}
   511  
   512  	// The previous ports.Update returns an empty object, so get the port again.
   513  	newPort, err = ports.Get(context.TODO(), client, port.ID).Extract()
   514  	th.AssertNoErr(t, err)
   515  	tools.PrintResource(t, newPort)
   516  
   517  	// When not specifying  a RevisionNumber, then the If-Match mechanism
   518  	// should be bypassed.
   519  	updateOpts = ports.UpdateOpts{
   520  		AllowedAddressPairs: &[]ports.AddressPair{},
   521  	}
   522  	newPort, err = ports.Update(context.TODO(), client, port.ID, updateOpts).Extract()
   523  	th.AssertNoErr(t, err)
   524  
   525  	tools.PrintResource(t, newPort)
   526  
   527  	if len(newPort.AllowedAddressPairs) > 0 {
   528  		t.Fatalf("Unable to remove the address pair")
   529  	}
   530  }