@@ -26,6 +26,7 @@ import (
26
26
"github.com/vmware/govmomi/list"
27
27
"github.com/vmware/govmomi/object"
28
28
"github.com/vmware/govmomi/property"
29
+ "github.com/vmware/govmomi/view"
29
30
"github.com/vmware/govmomi/vim25"
30
31
"github.com/vmware/govmomi/vim25/mo"
31
32
"github.com/vmware/govmomi/vim25/types"
@@ -789,9 +790,26 @@ func (f *Finder) NetworkList(ctx context.Context, path string) ([]object.Network
789
790
return ns , nil
790
791
}
791
792
793
+ // Network finds a NetworkReference using a Name, Inventory Path, ManagedObject ID, Logical Switch UUID or Segment ID.
794
+ // With standard vSphere networking, Portgroups cannot have the same name within the same network folder.
795
+ // With NSX, Portgroups can have the same name, even within the same Switch. In this case, using an inventory path
796
+ // results in a MultipleFoundError. A MOID, switch UUID or segment ID can be used instead, as both are unique.
797
+ // See also: https://kb.vmware.com/s/article/79872#Duplicate_names
798
+ // Examples:
799
+ // - Name: "dvpg-1"
800
+ // - Inventory Path: "vds-1/dvpg-1"
801
+ // - ManagedObject ID: "DistributedVirtualPortgroup:dvportgroup-53"
802
+ // - Logical Switch UUID: "da2a59b8-2450-4cb2-b5cc-79c4c1d2144c"
803
+ // - Segment ID: "/infra/segments/vnet_ce50e69b-1784-4a14-9206-ffd7f1f146f7"
792
804
func (f * Finder ) Network (ctx context.Context , path string ) (object.NetworkReference , error ) {
793
805
networks , err := f .NetworkList (ctx , path )
794
806
if err != nil {
807
+ if _ , ok := err .(* NotFoundError ); ok {
808
+ net , nerr := f .networkByID (ctx , path )
809
+ if nerr == nil {
810
+ return net , nil
811
+ }
812
+ }
795
813
return nil , err
796
814
}
797
815
@@ -802,6 +820,41 @@ func (f *Finder) Network(ctx context.Context, path string) (object.NetworkRefere
802
820
return networks [0 ], nil
803
821
}
804
822
823
+ func (f * Finder ) networkByID (ctx context.Context , path string ) (object.NetworkReference , error ) {
824
+ if ref := object .ReferenceFromString (path ); ref != nil {
825
+ // This is a MOID
826
+ return object .NewReference (f .client , * ref ).(object.NetworkReference ), nil
827
+ }
828
+
829
+ kind := []string {"DistributedVirtualPortgroup" }
830
+
831
+ m := view .NewManager (f .client )
832
+ v , err := m .CreateContainerView (ctx , f .client .ServiceContent .RootFolder , kind , true )
833
+ if err != nil {
834
+ return nil , err
835
+ }
836
+ defer v .Destroy (ctx )
837
+
838
+ filter := property.Filter {
839
+ "config.logicalSwitchUuid" : path ,
840
+ "config.segmentId" : path ,
841
+ }
842
+
843
+ refs , err := v .FindAny (ctx , kind , filter )
844
+ if err != nil {
845
+ return nil , err
846
+ }
847
+
848
+ if len (refs ) == 0 {
849
+ return nil , & NotFoundError {"network" , path }
850
+ }
851
+ if len (refs ) > 1 {
852
+ return nil , & MultipleFoundError {"network" , path }
853
+ }
854
+
855
+ return object .NewReference (f .client , refs [0 ]).(object.NetworkReference ), nil
856
+ }
857
+
805
858
func (f * Finder ) DefaultNetwork (ctx context.Context ) (object.NetworkReference , error ) {
806
859
network , err := f .Network (ctx , "*" )
807
860
if err != nil {
0 commit comments