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

     1  //go:build network || functional || openapi || vdcGroup || nsxt || gateway || ALL
     2  
     3  /*
     4   * Copyright 2022 VMware, Inc.  All rights reserved.  Licensed under the Apache v2 License.
     5   */
     6  
     7  package govcd
     8  
     9  import (
    10  	"fmt"
    11  	"net/url"
    12  
    13  	"github.com/vmware/go-vcloud-director/v2/types/v56"
    14  	. "gopkg.in/check.v1"
    15  )
    16  
    17  func (vcd *TestVCD) Test_NsxtVdcGroupOrgNetworks(check *C) {
    18  	skipNoNsxtConfiguration(vcd, check)
    19  	skipOpenApiEndpointTest(vcd, check, types.OpenApiPathVersion1_0_0+types.OpenApiEndpointEdgeGateways)
    20  	vcd.skipIfNotSysAdmin(check)
    21  
    22  	adminOrg, err := vcd.client.GetAdminOrgByName(vcd.config.VCD.Org)
    23  	check.Assert(adminOrg, NotNil)
    24  	check.Assert(err, IsNil)
    25  
    26  	org, err := vcd.client.GetOrgByName(vcd.config.VCD.Org)
    27  	check.Assert(org, NotNil)
    28  	check.Assert(err, IsNil)
    29  
    30  	nsxtExternalNetwork, err := GetExternalNetworkV2ByName(vcd.client, vcd.config.VCD.Nsxt.ExternalNetwork)
    31  	check.Assert(err, IsNil)
    32  	check.Assert(nsxtExternalNetwork, NotNil)
    33  
    34  	vdc, vdcGroup := test_CreateVdcGroup(check, adminOrg, vcd)
    35  	check.Assert(vdc, NotNil)
    36  	check.Assert(vdcGroup, NotNil)
    37  
    38  	egwDefinition := &types.OpenAPIEdgeGateway{
    39  		Name:        "nsx-t-edge",
    40  		Description: "nsx-t-edge-description",
    41  		OwnerRef: &types.OpenApiReference{
    42  			ID: vdc.Vdc.ID,
    43  		},
    44  		EdgeGatewayUplinks: []types.EdgeGatewayUplinks{{
    45  			UplinkID: nsxtExternalNetwork.ExternalNetwork.ID,
    46  			Subnets: types.OpenAPIEdgeGatewaySubnets{Values: []types.OpenAPIEdgeGatewaySubnetValue{{
    47  				Gateway:      "1.1.1.1",
    48  				PrefixLength: 24,
    49  				Enabled:      true,
    50  			}}},
    51  			Connected: true,
    52  			Dedicated: false,
    53  		}},
    54  	}
    55  
    56  	// Create Edge Gateway in VDC
    57  	createdEdge, err := adminOrg.CreateNsxtEdgeGateway(egwDefinition)
    58  	check.Assert(err, IsNil)
    59  	check.Assert(createdEdge, NotNil)
    60  	check.Assert(createdEdge.EdgeGateway.OwnerRef.ID, Matches, `^urn:vcloud:vdc:.*`)
    61  	openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointEdgeGateways + createdEdge.EdgeGateway.ID
    62  	PrependToCleanupListOpenApi(createdEdge.EdgeGateway.Name, check.TestName(), openApiEndpoint)
    63  
    64  	// Move Edge Gateway to VDC Group
    65  	movedGateway, err := createdEdge.MoveToVdcOrVdcGroup(vdcGroup.VdcGroup.Id)
    66  	check.Assert(err, IsNil)
    67  	check.Assert(movedGateway, NotNil)
    68  	check.Assert(movedGateway.EdgeGateway.OwnerRef.ID, Equals, vdcGroup.VdcGroup.Id)
    69  	check.Assert(movedGateway.EdgeGateway.OwnerRef.ID, Matches, `^urn:vcloud:vdcGroup:.*`)
    70  
    71  	mapOfNetworkConfigs := make(map[string]*types.OpenApiOrgVdcNetwork, 3)
    72  	mapOfNetworkConfigs["isolated"] = buildIsolatedOrgVdcNetworkConfig(check, vcd, vdcGroup.VdcGroup.Id)
    73  	mapOfNetworkConfigs["imported"] = buildImportedOrgVdcNetworkConfig(check, vcd, vdcGroup.VdcGroup.Id)
    74  	mapOfNetworkConfigs["routed"] = buildRoutedOrgVdcNetworkConfig(check, vcd, movedGateway, vdcGroup.VdcGroup.Id)
    75  
    76  	sliceOfCreatedNetworkConfigs := make(map[string]*OpenApiOrgVdcNetwork, 3)
    77  	for index, orgVdcNetworkConfig := range mapOfNetworkConfigs {
    78  		orgVdcNet, err := org.CreateOpenApiOrgVdcNetwork(orgVdcNetworkConfig)
    79  		check.Assert(err, IsNil)
    80  		check.Assert(orgVdcNet, NotNil)
    81  		check.Assert(orgVdcNet.OpenApiOrgVdcNetwork.OwnerRef.ID, Equals, vdcGroup.VdcGroup.Id)
    82  
    83  		sliceOfCreatedNetworkConfigs[index] = orgVdcNet
    84  
    85  		// Use generic "OpenApiEntity" resource cleanup type
    86  		openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointOrgVdcNetworks + orgVdcNet.OpenApiOrgVdcNetwork.ID
    87  		PrependToCleanupListOpenApi(orgVdcNet.OpenApiOrgVdcNetwork.Name, check.TestName(), openApiEndpoint)
    88  
    89  		check.Assert(orgVdcNet.GetType(), Equals, orgVdcNetworkConfig.NetworkType)
    90  	}
    91  
    92  	// Move Edge Gateway back to VDC
    93  	movedBackToVdcEdge, err := movedGateway.MoveToVdcOrVdcGroup(vdc.Vdc.ID)
    94  	check.Assert(err, IsNil)
    95  	check.Assert(movedBackToVdcEdge, NotNil)
    96  	check.Assert(movedBackToVdcEdge.EdgeGateway.OwnerRef.ID, Matches, `^urn:vcloud:vdc:.*`)
    97  
    98  	// Routed networks migrate to/from VDC Groups together with Edge Gateway therefore we need to
    99  	// check that routed network owner ID is the same as Edge Gateway. Routed network must be
   100  	// retrieved again so that it reflects latest information.
   101  	routedOrgNetwork, err := org.GetOpenApiOrgVdcNetworkById(sliceOfCreatedNetworkConfigs["routed"].OpenApiOrgVdcNetwork.ID)
   102  	check.Assert(err, IsNil)
   103  	check.Assert(routedOrgNetwork, NotNil)
   104  	check.Assert(routedOrgNetwork.OpenApiOrgVdcNetwork.OwnerRef.ID, Equals, movedBackToVdcEdge.EdgeGateway.OwnerRef.ID)
   105  
   106  	// Remove all created networks
   107  	for _, network := range sliceOfCreatedNetworkConfigs {
   108  		err = network.Delete()
   109  		check.Assert(err, IsNil)
   110  	}
   111  
   112  	// Remove Edge Gateway
   113  	err = movedGateway.Delete()
   114  	check.Assert(err, IsNil)
   115  
   116  	// Remove VDC group and VDC
   117  	err = vdcGroup.Delete()
   118  	check.Assert(err, IsNil)
   119  	task, err := vdc.Delete(true, true)
   120  	check.Assert(err, IsNil)
   121  	err = task.WaitTaskCompletion()
   122  	check.Assert(err, IsNil)
   123  }
   124  
   125  func buildIsolatedOrgVdcNetworkConfig(check *C, vcd *TestVCD, ownerId string) *types.OpenApiOrgVdcNetwork {
   126  	isolatedOrgVdcNetworkConfig := &types.OpenApiOrgVdcNetwork{
   127  		Name:        check.TestName() + "-isolated",
   128  		Description: check.TestName() + "-description",
   129  
   130  		OwnerRef: &types.OpenApiReference{ID: ownerId},
   131  
   132  		NetworkType: types.OrgVdcNetworkTypeIsolated,
   133  		Subnets: types.OrgVdcNetworkSubnets{
   134  			Values: []types.OrgVdcNetworkSubnetValues{
   135  				{
   136  					Gateway:      "4.1.1.1",
   137  					PrefixLength: 25,
   138  					DNSServer1:   "8.8.8.8",
   139  					DNSServer2:   "8.8.4.4",
   140  					DNSSuffix:    "bar.foo",
   141  					IPRanges: types.OrgVdcNetworkSubnetIPRanges{
   142  						Values: []types.OrgVdcNetworkSubnetIPRangeValues{
   143  							{
   144  								StartAddress: "4.1.1.20",
   145  								EndAddress:   "4.1.1.30",
   146  							},
   147  							{
   148  								StartAddress: "4.1.1.40",
   149  								EndAddress:   "4.1.1.50",
   150  							},
   151  							{
   152  								StartAddress: "4.1.1.88",
   153  								EndAddress:   "4.1.1.92",
   154  							},
   155  						}},
   156  				},
   157  			},
   158  		},
   159  	}
   160  
   161  	return isolatedOrgVdcNetworkConfig
   162  }
   163  
   164  func buildImportedOrgVdcNetworkConfig(check *C, vcd *TestVCD, ownerId string) *types.OpenApiOrgVdcNetwork {
   165  	logicalSwitch, err := vcd.nsxtVdc.GetNsxtImportableSwitchByName(vcd.config.VCD.Nsxt.NsxtImportSegment)
   166  	check.Assert(err, IsNil)
   167  
   168  	importedOrgVdcNetworkConfig := &types.OpenApiOrgVdcNetwork{
   169  		Name:        check.TestName() + "-imported",
   170  		Description: check.TestName() + "-description",
   171  
   172  		OwnerRef: &types.OpenApiReference{ID: ownerId},
   173  
   174  		NetworkType: types.OrgVdcNetworkTypeOpaque,
   175  		// BackingNetworkId contains NSX-T logical switch ID for Imported networks
   176  		BackingNetworkId: logicalSwitch.NsxtImportableSwitch.ID,
   177  
   178  		Subnets: types.OrgVdcNetworkSubnets{
   179  			Values: []types.OrgVdcNetworkSubnetValues{
   180  				{
   181  					Gateway:      "2.1.1.1",
   182  					PrefixLength: 24,
   183  					DNSServer1:   "8.8.8.8",
   184  					DNSServer2:   "8.8.4.4",
   185  					DNSSuffix:    "foo.bar",
   186  					IPRanges: types.OrgVdcNetworkSubnetIPRanges{
   187  						Values: []types.OrgVdcNetworkSubnetIPRangeValues{
   188  							{
   189  								StartAddress: "2.1.1.20",
   190  								EndAddress:   "2.1.1.30",
   191  							},
   192  							{
   193  								StartAddress: "2.1.1.40",
   194  								EndAddress:   "2.1.1.50",
   195  							},
   196  						}},
   197  				},
   198  			},
   199  		},
   200  	}
   201  
   202  	return importedOrgVdcNetworkConfig
   203  }
   204  
   205  func buildRoutedOrgVdcNetworkConfig(check *C, vcd *TestVCD, edgeGateway *NsxtEdgeGateway, ownerId string) *types.OpenApiOrgVdcNetwork {
   206  	routedOrgVdcNetworkConfig := &types.OpenApiOrgVdcNetwork{
   207  		Name:        check.TestName() + "-routed",
   208  		Description: check.TestName() + "-description",
   209  
   210  		OwnerRef: &types.OpenApiReference{ID: ownerId},
   211  
   212  		NetworkType: types.OrgVdcNetworkTypeRouted,
   213  
   214  		// Connection is used for "routed" network
   215  		Connection: &types.Connection{
   216  			RouterRef: types.OpenApiReference{
   217  				ID: edgeGateway.EdgeGateway.ID,
   218  			},
   219  			ConnectionType: "INTERNAL",
   220  		},
   221  		Subnets: types.OrgVdcNetworkSubnets{
   222  			Values: []types.OrgVdcNetworkSubnetValues{
   223  				{
   224  					Gateway:      "3.1.1.1",
   225  					PrefixLength: 24,
   226  					DNSServer1:   "8.8.8.8",
   227  					DNSServer2:   "8.8.4.4",
   228  					DNSSuffix:    "foo.bar",
   229  					IPRanges: types.OrgVdcNetworkSubnetIPRanges{
   230  						Values: []types.OrgVdcNetworkSubnetIPRangeValues{
   231  							{
   232  								StartAddress: "3.1.1.20",
   233  								EndAddress:   "3.1.1.30",
   234  							},
   235  							{
   236  								StartAddress: "3.1.1.40",
   237  								EndAddress:   "3.1.1.50",
   238  							},
   239  							{
   240  								StartAddress: "3.1.1.60",
   241  								EndAddress:   "3.1.1.62",
   242  							}, {
   243  								StartAddress: "3.1.1.72",
   244  								EndAddress:   "3.1.1.74",
   245  							}, {
   246  								StartAddress: "3.1.1.84",
   247  								EndAddress:   "3.1.1.85",
   248  							},
   249  						}},
   250  				},
   251  			},
   252  		},
   253  	}
   254  
   255  	return routedOrgVdcNetworkConfig
   256  }
   257  
   258  func test_CreateVdcGroup(check *C, adminOrg *AdminOrg, vcd *TestVCD) (*Vdc, *VdcGroup) {
   259  	createdVdc := createNewVdc(vcd, check, check.TestName())
   260  
   261  	createdVdcAsCandidate, err := adminOrg.GetAllNsxtVdcGroupCandidates(createdVdc.vdcId(),
   262  		map[string][]string{"filter": []string{fmt.Sprintf("name==%s", url.QueryEscape(createdVdc.vdcName()))}})
   263  	check.Assert(err, IsNil)
   264  	check.Assert(createdVdcAsCandidate, NotNil)
   265  	check.Assert(len(createdVdcAsCandidate) == 1, Equals, true)
   266  
   267  	existingVdcAsCandidate, err := adminOrg.GetAllNsxtVdcGroupCandidates(createdVdc.vdcId(),
   268  		map[string][]string{"filter": []string{fmt.Sprintf("name==%s", url.QueryEscape(vcd.nsxtVdc.vdcName()))}})
   269  	check.Assert(err, IsNil)
   270  	check.Assert(existingVdcAsCandidate, NotNil)
   271  	check.Assert(len(existingVdcAsCandidate) == 1, Equals, true)
   272  
   273  	vdcGroupConfig := &types.VdcGroup{
   274  		Name:  check.TestName() + "Group",
   275  		OrgId: adminOrg.orgId(),
   276  		ParticipatingOrgVdcs: []types.ParticipatingOrgVdcs{
   277  			types.ParticipatingOrgVdcs{
   278  				VdcRef: types.OpenApiReference{
   279  					ID: createdVdc.vdcId(),
   280  				},
   281  				SiteRef: (createdVdcAsCandidate)[0].SiteRef,
   282  				OrgRef:  (createdVdcAsCandidate)[0].OrgRef,
   283  			},
   284  			types.ParticipatingOrgVdcs{
   285  				VdcRef: types.OpenApiReference{
   286  					ID: vcd.nsxtVdc.vdcId(),
   287  				},
   288  				SiteRef: (existingVdcAsCandidate)[0].SiteRef,
   289  				OrgRef:  (existingVdcAsCandidate)[0].OrgRef,
   290  			},
   291  		},
   292  		LocalEgress:                false,
   293  		UniversalNetworkingEnabled: false,
   294  		NetworkProviderType:        "NSX_T",
   295  		Type:                       "LOCAL",
   296  		//DfwEnabled: true, // ignored by API
   297  	}
   298  
   299  	vdcGroup, err := adminOrg.CreateVdcGroup(vdcGroupConfig)
   300  	check.Assert(err, IsNil)
   301  	check.Assert(vdcGroup, NotNil)
   302  	check.Assert(vdcGroup.IsNsxt(), Equals, true)
   303  
   304  	openApiEndpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVdcGroups + vdcGroup.VdcGroup.Id
   305  	PrependToCleanupListOpenApi(vdcGroup.VdcGroup.Name, check.TestName(), openApiEndpoint)
   306  
   307  	return createdVdc, vdcGroup
   308  }
   309  
   310  func createNewVdc(vcd *TestVCD, check *C, vdcName string) *Vdc {
   311  	adminOrg, err := vcd.client.GetAdminOrgByName(vcd.org.Org.Name)
   312  	check.Assert(err, IsNil)
   313  	check.Assert(adminOrg, NotNil)
   314  
   315  	pVdcs, err := QueryProviderVdcByName(vcd.client, vcd.config.VCD.NsxtProviderVdc.Name)
   316  	check.Assert(err, IsNil)
   317  
   318  	if len(pVdcs) == 0 {
   319  		check.Skip(fmt.Sprintf("No NSX-T Provider VDC found with name '%s'", vcd.config.VCD.NsxtProviderVdc.Name))
   320  	}
   321  	providerVdcHref := pVdcs[0].HREF
   322  	pvdcStorageProfile, err := vcd.client.QueryProviderVdcStorageProfileByName(vcd.config.VCD.NsxtProviderVdc.StorageProfile, providerVdcHref)
   323  	check.Assert(err, IsNil)
   324  	check.Assert(pvdcStorageProfile, NotNil)
   325  	providerVdcStorageProfileHref := pvdcStorageProfile.HREF
   326  
   327  	networkPools, err := QueryNetworkPoolByName(vcd.client, vcd.config.VCD.NsxtProviderVdc.NetworkPool)
   328  	check.Assert(err, IsNil)
   329  	if len(networkPools) == 0 {
   330  		check.Skip(fmt.Sprintf("No network pool found with name '%s'", vcd.config.VCD.NsxtProviderVdc.NetworkPool))
   331  	}
   332  
   333  	networkPoolHref := networkPools[0].HREF
   334  	trueValue := true
   335  	vdcConfiguration := &types.VdcConfiguration{
   336  		Name:            vdcName,
   337  		Xmlns:           types.XMLNamespaceVCloud,
   338  		AllocationModel: "Flex",
   339  		ComputeCapacity: []*types.ComputeCapacity{
   340  			&types.ComputeCapacity{
   341  				CPU: &types.CapacityWithUsage{
   342  					Units:     "MHz",
   343  					Allocated: 1024,
   344  					Limit:     1024,
   345  				},
   346  				Memory: &types.CapacityWithUsage{
   347  					Allocated: 1024,
   348  					Limit:     1024,
   349  					Units:     "MB",
   350  				},
   351  			},
   352  		},
   353  		VdcStorageProfile: []*types.VdcStorageProfileConfiguration{&types.VdcStorageProfileConfiguration{
   354  			Enabled: addrOf(true),
   355  			Units:   "MB",
   356  			Limit:   1024,
   357  			Default: true,
   358  			ProviderVdcStorageProfile: &types.Reference{
   359  				HREF: providerVdcStorageProfileHref,
   360  			},
   361  		},
   362  		},
   363  		NetworkPoolReference: &types.Reference{
   364  			HREF: networkPoolHref,
   365  		},
   366  		ProviderVdcReference: &types.Reference{
   367  			HREF: providerVdcHref,
   368  		},
   369  		IsEnabled:             true,
   370  		IsThinProvision:       true,
   371  		UsesFastProvisioning:  true,
   372  		IsElastic:             &trueValue,
   373  		IncludeMemoryOverhead: &trueValue,
   374  	}
   375  
   376  	vdc, err := adminOrg.CreateOrgVdc(vdcConfiguration)
   377  	check.Assert(err, IsNil)
   378  	check.Assert(vdc, NotNil)
   379  
   380  	AddToCleanupList(vdcConfiguration.Name, "vdc", vcd.org.Org.Name, check.TestName())
   381  	return vdc
   382  }