github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/lbvirtualserver_test.go (about)

     1  //go:build lb || lbVirtualServer || nsxv || functional || ALL
     2  
     3  /*
     4   * Copyright 2019 VMware, Inc.  All rights reserved.  Licensed under the Apache v2 License.
     5   */
     6  
     7  package govcd
     8  
     9  import (
    10  	"fmt"
    11  
    12  	"github.com/vmware/go-vcloud-director/v2/types/v56"
    13  	. "gopkg.in/check.v1"
    14  )
    15  
    16  // Test_LBVirtualServer tests CRUD methods for load balancer virtual server.
    17  // With help of function buildTestLBVirtualServerPrereqs such prerequisite components are created:
    18  // service monitor, server pool, application profile and application rule.
    19  // The following things are tested if prerequisites are met:
    20  // 1. Creation of load balancer virtual server
    21  // 2. Get load balancer virtual server by both ID and Name (virtual server name must be unique in
    22  // single edge gateway)
    23  // 3. Update - change a single field and compare that configuration and result objects are deeply
    24  // equal
    25  // 4. Update - try and fail to update without mandatory field
    26  // 5. Delete
    27  func (vcd *TestVCD) Test_LBVirtualServer(check *C) {
    28  	if vcd.config.VCD.EdgeGateway == "" {
    29  		check.Skip("Skipping test because no edge gateway given")
    30  	}
    31  	if vcd.config.VCD.ExternalIp == "" {
    32  		check.Skip("Skipping test because no edge gateway external IP given")
    33  	}
    34  
    35  	edge, err := vcd.vdc.GetEdgeGatewayByName(vcd.config.VCD.EdgeGateway, false)
    36  	check.Assert(err, IsNil)
    37  	check.Assert(edge.EdgeGateway.Name, Equals, vcd.config.VCD.EdgeGateway)
    38  
    39  	if !edge.HasAdvancedNetworking() {
    40  		check.Skip("Skipping test because the edge gateway does not have advanced networking enabled")
    41  	}
    42  
    43  	serviceMonitorId, serverPoolId, appProfileId, appRuleId := buildTestLBVirtualServerPrereqs("1.1.1.1", "2.2.2.2",
    44  		TestLbVirtualServer, check, vcd, *edge)
    45  
    46  	// Configure creation object including reference to service monitor
    47  	lbVirtualServerConfig := &types.LbVirtualServer{
    48  		Name:                 TestLbVirtualServer,
    49  		IpAddress:            vcd.config.VCD.ExternalIp, // Load balancer virtual server serves on Edge gw IP
    50  		Enabled:              false,
    51  		AccelerationEnabled:  false,
    52  		Protocol:             "http",
    53  		Port:                 8888,
    54  		ConnectionLimit:      5,
    55  		ConnectionRateLimit:  10,
    56  		ApplicationProfileId: appProfileId,
    57  		ApplicationRuleIds:   []string{appRuleId},
    58  		DefaultPoolId:        serverPoolId,
    59  	}
    60  
    61  	err = deleteLbVirtualServerIfExists(*edge, lbVirtualServerConfig.Name)
    62  	check.Assert(err, IsNil)
    63  	createdLbVirtualServer, err := edge.CreateLbVirtualServer(lbVirtualServerConfig)
    64  	check.Assert(err, IsNil)
    65  	check.Assert(createdLbVirtualServer.ID, Not(IsNil))
    66  	check.Assert(createdLbVirtualServer.IpAddress, Equals, lbVirtualServerConfig.IpAddress)
    67  	check.Assert(createdLbVirtualServer.Protocol, Equals, lbVirtualServerConfig.Protocol)
    68  	check.Assert(createdLbVirtualServer.Port, Equals, lbVirtualServerConfig.Port)
    69  	check.Assert(createdLbVirtualServer.ConnectionLimit, Equals, lbVirtualServerConfig.ConnectionLimit)
    70  	check.Assert(createdLbVirtualServer.ConnectionRateLimit, Equals, lbVirtualServerConfig.ConnectionRateLimit)
    71  	check.Assert(createdLbVirtualServer.Enabled, Equals, lbVirtualServerConfig.Enabled)
    72  	check.Assert(createdLbVirtualServer.AccelerationEnabled, Equals, lbVirtualServerConfig.AccelerationEnabled)
    73  	check.Assert(createdLbVirtualServer.ApplicationRuleIds, DeepEquals, lbVirtualServerConfig.ApplicationRuleIds)
    74  	check.Assert(createdLbVirtualServer.DefaultPoolId, Equals, lbVirtualServerConfig.DefaultPoolId)
    75  
    76  	// Try to delete child components and expect a well parsed NSX error
    77  	err = edge.DeleteLbServiceMonitorById(serviceMonitorId)
    78  	check.Assert(err, ErrorMatches, `.*Fail to delete objectId .*\S+.* for it is used by .*`)
    79  	err = edge.DeleteLbServerPoolById(serverPoolId)
    80  	check.Assert(err, ErrorMatches, `.*Fail to delete objectId .*\S+.* for it is used by .*`)
    81  	err = edge.DeleteLbAppProfileById(appProfileId)
    82  	check.Assert(err, ErrorMatches, `.*Fail to delete objectId .*\S+.* for it is used by .*`)
    83  	err = edge.DeleteLbAppRuleById(appRuleId)
    84  	check.Assert(err, ErrorMatches, `.*Fail to delete objectId .*\S+.* for it is used by .*`)
    85  
    86  	// We created virtual server successfully therefore let's prepend it to cleanup list so that it
    87  	// is deleted before the child components
    88  	parentEntity := vcd.org.Org.Name + "|" + vcd.vdc.Vdc.Name + "|" + vcd.config.VCD.EdgeGateway
    89  	PrependToCleanupList(TestLbVirtualServer, "lbVirtualServer", parentEntity, check.TestName())
    90  
    91  	// Lookup by both name and ID and compare that these are equal values
    92  	lbVirtualServerById, err := edge.getLbVirtualServer(&types.LbVirtualServer{ID: createdLbVirtualServer.ID})
    93  	check.Assert(err, IsNil)
    94  	check.Assert(lbVirtualServerById, Not(IsNil))
    95  
    96  	lbVirtualServerByName, err := edge.getLbVirtualServer(&types.LbVirtualServer{Name: createdLbVirtualServer.Name})
    97  	check.Assert(err, IsNil)
    98  	check.Assert(lbVirtualServerByName, Not(IsNil))
    99  	check.Assert(createdLbVirtualServer.ID, Equals, lbVirtualServerByName.ID)
   100  	check.Assert(lbVirtualServerById.ID, Equals, lbVirtualServerByName.ID)
   101  	check.Assert(lbVirtualServerById.Name, Equals, lbVirtualServerByName.Name)
   102  
   103  	// GetLbVirtualServers should return at least one vs which is ours.
   104  	servers, err := edge.GetLbVirtualServers()
   105  	check.Assert(err, IsNil)
   106  	check.Assert(servers, Not(HasLen), 0)
   107  
   108  	// Test updating fields
   109  	// Update algorithm
   110  	lbVirtualServerById.Port = 8889
   111  	updatedLBPool, err := edge.UpdateLbVirtualServer(lbVirtualServerById)
   112  	check.Assert(err, IsNil)
   113  	check.Assert(updatedLBPool.Port, Equals, lbVirtualServerById.Port)
   114  
   115  	// Update boolean value fields
   116  	lbVirtualServerById.Enabled = true
   117  	lbVirtualServerById.AccelerationEnabled = true
   118  	updatedLBPool, err = edge.UpdateLbVirtualServer(lbVirtualServerById)
   119  	check.Assert(err, IsNil)
   120  	check.Assert(updatedLBPool.Enabled, Equals, lbVirtualServerById.Enabled)
   121  	check.Assert(updatedLBPool.AccelerationEnabled, Equals, lbVirtualServerById.AccelerationEnabled)
   122  
   123  	// Verify that updated pool and its configuration are identical
   124  	check.Assert(updatedLBPool, DeepEquals, lbVirtualServerById)
   125  
   126  	// Try to set invalid protocol and expect API to return error:
   127  	// vShield Edge [LoadBalancer] Invalid protocol invalid_protocol. Valid protocols are: HTTP|HTTPS|TCP|UDP. (API error: 14542)
   128  	lbVirtualServerById.Protocol = "invalid_protocol"
   129  	updatedLBPool, err = edge.UpdateLbVirtualServer(lbVirtualServerById)
   130  	check.Assert(updatedLBPool, IsNil)
   131  	check.Assert(err, ErrorMatches, ".*Invalid protocol.*Valid protocols are:.*")
   132  
   133  	// Update should fail without name
   134  	lbVirtualServerById.Name = ""
   135  	_, err = edge.UpdateLbVirtualServer(lbVirtualServerById)
   136  	check.Assert(err.Error(), Equals, "load balancer virtual server Name cannot be empty")
   137  
   138  	// Delete / cleanup
   139  	err = edge.DeleteLbVirtualServer(&types.LbVirtualServer{ID: createdLbVirtualServer.ID})
   140  	check.Assert(err, IsNil)
   141  
   142  	// Ensure it is deleted
   143  	_, err = edge.GetLbVirtualServerById(createdLbVirtualServer.ID)
   144  	check.Assert(IsNotFound(err), Equals, true)
   145  }
   146  
   147  // buildTestLBVirtualServerPrereqs creates all load balancer components which are consumed by
   148  // load balanver virtual server and ads them to cleanup in correct order to avoid deletion of used
   149  // resources
   150  func buildTestLBVirtualServerPrereqs(node1Ip, node2Ip, componentsName string, check *C, vcd *TestVCD, edge EdgeGateway) (serviceMonitorId, serverPoolId, appProfileId, appRuleId string) {
   151  	// Create prerequisites - service monitor
   152  	lbMon := &types.LbMonitor{
   153  		Name:       componentsName,
   154  		Interval:   10,
   155  		Timeout:    10,
   156  		MaxRetries: 3,
   157  		Type:       "http",
   158  	}
   159  	err := deleteLbServiceMonitorIfExists(edge, lbMon.Name)
   160  	check.Assert(err, IsNil)
   161  	lbMonitor, err := edge.CreateLbServiceMonitor(lbMon)
   162  	check.Assert(err, IsNil)
   163  
   164  	// Create prerequisites - server pool
   165  	lbPoolConfig := &types.LbPool{
   166  		Name:      componentsName,
   167  		Algorithm: "round-robin",
   168  		MonitorId: lbMonitor.ID,
   169  		Members: types.LbPoolMembers{
   170  			types.LbPoolMember{
   171  				Name:      "Server_one",
   172  				IpAddress: node1Ip,
   173  				Port:      8000,
   174  				Weight:    1,
   175  				Condition: "enabled",
   176  			},
   177  			types.LbPoolMember{
   178  				Name:      "Server_two",
   179  				IpAddress: node2Ip,
   180  				Port:      8000,
   181  				Weight:    1,
   182  				Condition: "enabled",
   183  			},
   184  		},
   185  	}
   186  
   187  	err = deleteLbServerPoolIfExists(edge, lbPoolConfig.Name)
   188  	check.Assert(err, IsNil)
   189  	lbPool, err := edge.CreateLbServerPool(lbPoolConfig)
   190  	check.Assert(err, IsNil)
   191  
   192  	// Create prerequisites - application profile
   193  	lbAppProfileConfig := &types.LbAppProfile{
   194  		Name:     componentsName,
   195  		Template: "HTTP",
   196  	}
   197  
   198  	err = deleteLbAppProfileIfExists(edge, lbAppProfileConfig.Name)
   199  	check.Assert(err, IsNil)
   200  	lbAppProfile, err := edge.CreateLbAppProfile(lbAppProfileConfig)
   201  	check.Assert(err, IsNil)
   202  
   203  	lbAppRuleConfig := &types.LbAppRule{
   204  		Name:   componentsName,
   205  		Script: "acl vmware_page url_beg / vmware redirect location https://www.vmware.com/ ifvmware_page",
   206  	}
   207  
   208  	// Create prerequisites - application rule
   209  	err = deleteLbAppRuleIfExists(edge, lbAppRuleConfig.Name)
   210  	check.Assert(err, IsNil)
   211  	lbAppRule, err := edge.CreateLbAppRule(lbAppRuleConfig)
   212  	check.Assert(err, IsNil)
   213  
   214  	parentEntity := vcd.org.Org.Name + "|" + vcd.vdc.Vdc.Name + "|" + vcd.config.VCD.EdgeGateway
   215  	AddToCleanupList(lbAppRule.Name, "lbAppRule", parentEntity, check.TestName())
   216  	AddToCleanupList(lbAppProfile.Name, "lbAppProfile", parentEntity, check.TestName())
   217  	AddToCleanupList(lbPool.Name, "lbServerPool", parentEntity, check.TestName())
   218  	AddToCleanupList(lbMon.Name, "lbServiceMonitor", parentEntity, check.TestName())
   219  
   220  	return lbMonitor.ID, lbPool.ID, lbAppProfile.ID, lbAppRule.ID
   221  }
   222  
   223  // deleteLbVirtualServerIfExists is used to cleanup before creation of component. It returns error only if there was
   224  // other error than govcd.ErrorEntityNotFound
   225  func deleteLbVirtualServerIfExists(edge EdgeGateway, name string) error {
   226  	err := edge.DeleteLbVirtualServerByName(name)
   227  	if err != nil && !ContainsNotFound(err) {
   228  		return err
   229  	}
   230  	if err != nil && ContainsNotFound(err) {
   231  		return nil
   232  	}
   233  
   234  	fmt.Printf("# Removed leftover LB virtual server '%s'\n", name)
   235  	return nil
   236  }