github.com/openshift/installer@v1.4.17/pkg/asset/installconfig/vsphere/client.go (about) 1 package vsphere 2 3 import ( 4 "context" 5 "net/url" 6 "time" 7 8 "github.com/pkg/errors" 9 "github.com/vmware/govmomi" 10 "github.com/vmware/govmomi/find" 11 "github.com/vmware/govmomi/object" 12 "github.com/vmware/govmomi/vapi/rest" 13 "github.com/vmware/govmomi/vim25" 14 "github.com/vmware/govmomi/vim25/mo" 15 "github.com/vmware/govmomi/vim25/soap" 16 "github.com/vmware/govmomi/vim25/types" 17 ) 18 19 // Finder interface represents the client that is used to connect to VSphere to get specific 20 // information from the resources in the VCenter. This interface just describes all the useful 21 // functions used by the installer from the finder function in vmware govmomi package and is 22 // mostly used to create a mock client that can be used for testing. 23 type Finder interface { 24 Datacenter(ctx context.Context, path string) (*object.Datacenter, error) 25 DatacenterList(ctx context.Context, path string) ([]*object.Datacenter, error) 26 DatastoreList(ctx context.Context, path string) ([]*object.Datastore, error) 27 ClusterComputeResource(ctx context.Context, path string) (*object.ClusterComputeResource, error) 28 ClusterComputeResourceList(ctx context.Context, path string) ([]*object.ClusterComputeResource, error) 29 Folder(ctx context.Context, path string) (*object.Folder, error) 30 NetworkList(ctx context.Context, path string) ([]object.NetworkReference, error) 31 Network(ctx context.Context, path string) (object.NetworkReference, error) 32 ResourcePool(ctx context.Context, path string) (*object.ResourcePool, error) 33 VirtualMachine(ctx context.Context, path string) (*object.VirtualMachine, error) 34 VirtualMachineList(ctx context.Context, path string) ([]*object.VirtualMachine, error) 35 HostSystemList(ctx context.Context, path string) ([]*object.HostSystem, error) 36 ObjectReference(ctx context.Context, ref types.ManagedObjectReference) (object.Reference, error) 37 } 38 39 // NewFinder creates a new client that conforms with the Finder interface and returns a 40 // vmware govmomi finder object that can be used to search for resources in vsphere. 41 func NewFinder(client *vim25.Client, all ...bool) Finder { 42 return find.NewFinder(client, all...) 43 } 44 45 // ClientLogout is empty function that logs out of vSphere clients 46 type ClientLogout func() 47 48 // CreateVSphereClients creates the SOAP and REST client to access 49 // different portions of the vSphere API 50 // e.g. tags are only available in REST 51 func CreateVSphereClients(ctx context.Context, vcenter, username, password string) (*vim25.Client, *rest.Client, ClientLogout, error) { 52 ctx, cancel := context.WithTimeout(ctx, 60*time.Second) 53 defer cancel() 54 55 u, err := soap.ParseURL(vcenter) 56 if err != nil { 57 return nil, nil, nil, err 58 } 59 u.User = url.UserPassword(username, password) 60 c, err := govmomi.NewClient(ctx, u, false) 61 62 if err != nil { 63 return nil, nil, nil, err 64 } 65 66 restClient := rest.NewClient(c.Client) 67 err = restClient.Login(ctx, u.User) 68 if err != nil { 69 logoutErr := c.Logout(context.TODO()) 70 if logoutErr != nil { 71 err = logoutErr 72 } 73 return nil, nil, nil, err 74 } 75 76 return c.Client, restClient, func() { 77 c.Logout(context.TODO()) 78 restClient.Logout(context.TODO()) 79 }, nil 80 } 81 82 // getNetworks returns a slice of Managed Object references for networks in the given vSphere Cluster. 83 func getNetworks(ctx context.Context, ccr *object.ClusterComputeResource) ([]types.ManagedObjectReference, error) { 84 ctx, cancel := context.WithTimeout(ctx, 60*time.Second) 85 defer cancel() 86 var ccrMo mo.ClusterComputeResource 87 88 err := ccr.Properties(ctx, ccr.Reference(), []string{"network"}, &ccrMo) 89 if err != nil { 90 return nil, errors.Wrap(err, "could not get properties of cluster") 91 } 92 return ccrMo.Network, nil 93 } 94 95 // GetClusterNetworks returns a slice of Managed Object references for vSphere networks in the given Datacenter 96 // and Cluster. 97 func GetClusterNetworks(ctx context.Context, finder Finder, datacenter, cluster string) ([]types.ManagedObjectReference, error) { 98 ctx, cancel := context.WithTimeout(ctx, 60*time.Second) 99 defer cancel() 100 101 ccr, err := finder.ClusterComputeResource(context.TODO(), cluster) 102 if err != nil { 103 return nil, errors.Wrapf(err, "could not find vSphere cluster at %s", cluster) 104 } 105 106 // Get list of Networks inside vSphere Cluster 107 networks, err := getNetworks(ctx, ccr) 108 if err != nil { 109 return nil, err 110 } 111 112 return networks, nil 113 } 114 115 // GetNetworkName returns the name of a vSphere network given its Managed Object reference. 116 func GetNetworkName(ctx context.Context, client *vim25.Client, ref types.ManagedObjectReference) (string, error) { 117 ctx, cancel := context.WithTimeout(ctx, 60*time.Second) 118 defer cancel() 119 120 netObj := object.NewNetwork(client, ref) 121 name, err := netObj.ObjectName(ctx) 122 if err != nil { 123 return "", errors.Wrapf(err, "could not get network name for %s", ref.String()) 124 } 125 return name, nil 126 } 127 128 // GetNetworkMo returns the unique Managed Object for given network name inside of the given Datacenter 129 // and Cluster. 130 func GetNetworkMo(ctx context.Context, client *vim25.Client, finder Finder, datacenter, cluster, network string) (*types.ManagedObjectReference, error) { 131 networks, err := GetClusterNetworks(ctx, finder, datacenter, cluster) 132 if err != nil { 133 return nil, err 134 } 135 for _, net := range networks { 136 name, err := GetNetworkName(ctx, client, net) 137 if err != nil { 138 return nil, err 139 } 140 if name == network { 141 return &net, nil 142 } 143 } 144 145 return nil, errors.Errorf("unable to find network provided") 146 } 147 148 // GetNetworkMoID returns the unique Managed Object ID for given network name inside of the given Datacenter 149 // and Cluster. 150 func GetNetworkMoID(ctx context.Context, client *vim25.Client, finder Finder, datacenter, cluster, network string) (string, error) { 151 mo, err := GetNetworkMo(ctx, client, finder, datacenter, cluster, network) 152 if err != nil { 153 return "", err 154 } 155 return mo.Value, nil 156 }