Skip to content

Commit 12ad456

Browse files
authored
Merge pull request vmware-tanzu#66 from bryanv/bryanv/fix-nsxt-lsuuid-check
Fix NSX-T LogicalSwitchUUID to DVPG lookup
2 parents 439c8f6 + 7c8b2e6 commit 12ad456

File tree

2 files changed

+34
-90
lines changed

2 files changed

+34
-90
lines changed

pkg/vmprovider/providers/vsphere/network/network_provider.go

Lines changed: 33 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/pkg/errors"
2020
"github.com/vmware/govmomi/find"
2121
"github.com/vmware/govmomi/object"
22+
"github.com/vmware/govmomi/property"
2223
"github.com/vmware/govmomi/vim25"
2324
"github.com/vmware/govmomi/vim25/mo"
2425
vimtypes "github.com/vmware/govmomi/vim25/types"
@@ -367,7 +368,7 @@ func (np *netOpNetworkProvider) getNetworkRef(ctx goctx.Context, networkType, ne
367368
case VdsNetworkType:
368369
return np.networkForPortGroupID(networkID)
369370
case NsxtNetworkType:
370-
return searchNsxtNetworkReference(ctx, np.finder, np.cluster, networkID)
371+
return searchNsxtNetworkReference(ctx, np.cluster, networkID)
371372
default:
372373
return nil, fmt.Errorf("unsupported NetOP network type %s", networkType)
373374
}
@@ -603,7 +604,7 @@ func (np *nsxtNetworkProvider) createEthernetCard(
603604
return nil, err
604605
}
605606

606-
networkRef, err := searchNsxtNetworkReference(vmCtx, np.finder, np.cluster, vnetIf.Status.ProviderStatus.NsxLogicalSwitchID)
607+
networkRef, err := searchNsxtNetworkReference(vmCtx, np.cluster, vnetIf.Status.ProviderStatus.NsxLogicalSwitchID)
607608
if err != nil {
608609
// Log message used by VMC LINT. Refer to before making changes
609610
vmCtx.Logger.Error(err, "Failed to search for nsx-t network associated with vnetIf", "vnetIf", vnetIf)
@@ -727,108 +728,51 @@ func (np *nsxtNetworkProvider) getNetplanEthernet(vnetIf *ncpv1alpha1.VirtualNet
727728
return eth
728729
}
729730

730-
// matchOpaqueNetwork takes the network ID, returns whether the opaque network matches the networkID.
731-
func matchOpaqueNetwork(ctx goctx.Context, network object.NetworkReference, networkID string) bool {
732-
obj, ok := network.(*object.OpaqueNetwork)
733-
if !ok {
734-
return false
735-
}
736-
737-
var opaqueNet mo.OpaqueNetwork
738-
if err := obj.Properties(ctx, obj.Reference(), []string{"summary"}, &opaqueNet); err != nil {
739-
return false
740-
}
741-
742-
summary, _ := opaqueNet.Summary.(*vimtypes.OpaqueNetworkSummary)
743-
return summary.OpaqueNetworkId == networkID
744-
}
745-
746-
// matchDistributedPortGroup takes the network ID, returns whether the distributed port group matches the networkID.
747-
func matchDistributedPortGroup(
731+
// searchNsxtNetworkReference takes in nsx-t logical switch UUID and returns the reference of the network.
732+
func searchNsxtNetworkReference(
748733
ctx goctx.Context,
749-
network object.NetworkReference,
750-
networkID string,
751-
hostMoIDs []vimtypes.ManagedObjectReference) bool {
734+
ccr *object.ClusterComputeResource,
735+
networkID string) (object.NetworkReference, error) {
752736

753-
obj, ok := network.(*object.DistributedVirtualPortgroup)
754-
if !ok {
755-
return false
756-
}
757-
758-
var configInfo []vimtypes.ObjectContent
759-
err := obj.Properties(ctx, obj.Reference(), []string{"config.logicalSwitchUuid", "host"}, &configInfo)
760-
if err != nil {
761-
return false
737+
var obj mo.ClusterComputeResource
738+
if err := ccr.Properties(ctx, ccr.Reference(), []string{"network"}, &obj); err != nil {
739+
return nil, err
762740
}
763741

764-
if len(configInfo) > 0 {
765-
// Check "logicalSwitchUuid" property
766-
lsIDMatch := false
767-
for _, dynamicProperty := range configInfo[0].PropSet {
768-
if dynamicProperty.Name == "config.logicalSwitchUuid" && dynamicProperty.Val == networkID {
769-
lsIDMatch = true
770-
break
771-
}
772-
}
773-
774-
// logicalSwitchUuid did not match
775-
if !lsIDMatch {
776-
return false
777-
}
778-
779-
foundAllHosts := false
780-
for _, dynamicProperty := range configInfo[0].PropSet {
781-
// In the case of a single NSX Overlay Transport Zone for all the clusters and DVS's,
782-
// multiple DVPGs(associated with different DVS's) will have the same "logicalSwitchUuid".
783-
// So matching "logicalSwitchUuid" is necessary condition, but not sufficient.
784-
// Checking if the DPVG has all the hosts in the cluster, along with the above would be sufficient
785-
if dynamicProperty.Name == "host" {
786-
if hosts, ok := dynamicProperty.Val.(vimtypes.ArrayOfManagedObjectReference); ok {
787-
foundAllHosts = true
788-
dvsHostSet := make(map[string]bool, len(hosts.ManagedObjectReference))
789-
for _, dvsHost := range hosts.ManagedObjectReference {
790-
dvsHostSet[dvsHost.Value] = true
791-
}
792-
793-
for _, hostMoRef := range hostMoIDs {
794-
if _, ok := dvsHostSet[hostMoRef.Value]; !ok {
795-
foundAllHosts = false
796-
break
797-
}
798-
}
799-
}
800-
}
742+
var dvpgsMoRefs []vimtypes.ManagedObjectReference
743+
for _, n := range obj.Network {
744+
if n.Type == "DistributedVirtualPortgroup" {
745+
dvpgsMoRefs = append(dvpgsMoRefs, n.Reference())
801746
}
747+
}
802748

803-
// Implicit that lsID Matches at this point
804-
return foundAllHosts
749+
if len(dvpgsMoRefs) == 0 {
750+
return nil, fmt.Errorf("ClusterComputeResource %s has no DVPGs", ccr.Reference().Value)
805751
}
806-
return false
807-
}
808752

809-
// searchNsxtNetworkReference takes in nsx-t logical switch UUID and returns the reference of the network.
810-
func searchNsxtNetworkReference(ctx goctx.Context, finder *find.Finder, cluster *object.ClusterComputeResource, networkID string) (object.NetworkReference, error) {
811-
networks, err := finder.NetworkList(ctx, "*")
753+
var dvpgs []mo.DistributedVirtualPortgroup
754+
err := property.DefaultCollector(ccr.Client()).Retrieve(ctx, dvpgsMoRefs, []string{"config.logicalSwitchUuid"}, &dvpgs)
812755
if err != nil {
813756
return nil, err
814757
}
815758

816-
// Get the list of ESX host moRef objects for this cluster
817-
// TODO: ps: []string{"host"} instead of nil?
818-
var computeResource mo.ComputeResource
819-
if err := cluster.Properties(ctx, cluster.Reference(), nil, &computeResource); err != nil {
820-
return nil, err
759+
var dvpgMoRefs []vimtypes.ManagedObjectReference
760+
for _, dvpg := range dvpgs {
761+
if dvpg.Config.LogicalSwitchUuid == networkID {
762+
dvpgMoRefs = append(dvpgMoRefs, dvpg.Reference())
763+
}
821764
}
822765

823-
for _, network := range networks {
824-
if matchDistributedPortGroup(ctx, network, networkID, computeResource.Host) {
825-
return network, nil
826-
}
827-
if matchOpaqueNetwork(ctx, network, networkID) {
828-
return network, nil
829-
}
766+
switch len(dvpgMoRefs) {
767+
case 1:
768+
return object.NewDistributedVirtualPortgroup(ccr.Client(), dvpgMoRefs[0]), nil
769+
case 0:
770+
return nil, fmt.Errorf("no DVPG with NSX-T network ID %q found", networkID)
771+
default:
772+
// The LogicalSwitchUuid is supposed to be unique per CCR, so this is likely an NCP
773+
// misconfiguration, and we don't know which one to pick.
774+
return nil, fmt.Errorf("multiple DVPGs (%d) with NSX-T network ID %q found", len(dvpgMoRefs), networkID)
830775
}
831-
return nil, fmt.Errorf("opaque network with ID '%s' not found", networkID)
832776
}
833777

834778
// ToCidrNotation takes ip and mask as ip addresses and returns a cidr notation.

pkg/vmprovider/providers/vsphere/network/network_provider_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ var _ = Describe("NetworkProvider", func() {
578578

579579
It("should return an error", func() {
580580
_, err := np.EnsureNetworkInterface(vmCtx, &vmCtx.VM.Spec.NetworkInterfaces[0])
581-
Expect(err).To(MatchError(fmt.Sprintf("opaque network with ID '%s' not found", doesNotExist)))
581+
Expect(err).To(MatchError(fmt.Sprintf("no DVPG with NSX-T network ID %q found", doesNotExist)))
582582
})
583583
})
584584

0 commit comments

Comments
 (0)