func TestClusterESX(t *testing.T) { content := esx.ServiceContent s := New(NewServiceInstance(content, esx.RootFolder)) ts := s.NewServer() defer ts.Close() ctx := context.Background() c, err := govmomi.NewClient(ctx, ts.URL, true) if err != nil { t.Fatal(err) } dc := object.NewDatacenter(c.Client, esx.Datacenter.Reference()) folders, err := dc.Folders(ctx) if err != nil { t.Fatal(err) } _, err = folders.HostFolder.CreateCluster(ctx, "cluster1", types.ClusterConfigSpecEx{}) if err == nil { t.Fatal("expected error") } }
func (f *Finder) DatacenterList(ctx context.Context, path string) ([]*object.Datacenter, error) { es, err := f.find(ctx, f.rootFolder, false, path) if err != nil { return nil, err } var dcs []*object.Datacenter for _, e := range es { ref := e.Object.Reference() if ref.Type == "Datacenter" { dcs = append(dcs, object.NewDatacenter(f.client, ref)) } } if len(dcs) == 0 { return nil, &NotFoundError{"datacenter", path} } return dcs, nil }
// Create populates the Model with the given ModelConfig func (m *Model) Create() error { m.Service = New(NewServiceInstance(m.ServiceContent, m.RootFolder)) ctx := context.Background() client := m.Service.client root := object.NewRootFolder(client) // After all hosts are created, this var is used to mount the host datastores. var hosts []*object.HostSystem // We need to defer VM creation until after the datastores are created. var vms []func() error // addHost adds a cluster host or a stanalone host. addHost := func(name string, f func(types.HostConnectSpec) (*object.Task, error)) (*object.HostSystem, error) { spec := types.HostConnectSpec{ HostName: name, } task, err := f(spec) if err != nil { return nil, err } info, err := task.WaitForResult(context.Background(), nil) if err != nil { return nil, err } host := object.NewHostSystem(client, info.Result.(types.ManagedObjectReference)) hosts = append(hosts, host) return host, nil } // addMachine returns a func to create a VM. addMachine := func(prefix string, host *object.HostSystem, pool *object.ResourcePool, folders *object.DatacenterFolders) { f := func() error { for i := 0; i < m.Machine; i++ { name := m.fmtName(prefix+"_VM", i) config := types.VirtualMachineConfigSpec{ Name: name, GuestId: string(types.VirtualMachineGuestOsIdentifierOtherGuest), Files: &types.VirtualMachineFileInfo{ VmPathName: fmt.Sprintf("[LocalDS_0] %s", name), }, } if pool == nil { pool, _ = host.ResourcePool(ctx) } task, err := folders.VmFolder.CreateVM(ctx, config, pool, host) if err != nil { return err } err = task.Wait(ctx) if err != nil { return err } } return nil } vms = append(vms, f) } for ndc := 0; ndc < m.Datacenter; ndc++ { dcName := m.fmtName("DC", ndc) dc, err := root.CreateDatacenter(ctx, dcName) if err != nil { return err } folders, err := dc.Folders(ctx) if err != nil { return err } for nhost := 0; nhost < m.Host; nhost++ { name := m.fmtName(dcName+"_H", nhost) host, err := addHost(name, func(spec types.HostConnectSpec) (*object.Task, error) { return folders.HostFolder.AddStandaloneHost(ctx, spec, true, nil, nil) }) if err != nil { return err } addMachine(name, host, nil, folders) } for ncluster := 0; ncluster < m.Cluster; ncluster++ { clusterName := m.fmtName(dcName+"_C", ncluster) cluster, err := folders.HostFolder.CreateCluster(ctx, clusterName, types.ClusterConfigSpecEx{}) if err != nil { return err } // TODO: create DistributedVirtualPortgroup for npg := 0; npg < m.Portgroup; npg++ for nhost := 0; nhost < m.ClusterHost; nhost++ { name := m.fmtName(clusterName+"_H", nhost) _, err := addHost(name, func(spec types.HostConnectSpec) (*object.Task, error) { return cluster.AddHost(ctx, spec, true, nil, nil) }) if err != nil { return err } } pool, err := cluster.ResourcePool(ctx) if err != nil { return err } prefix := clusterName + "_RP" addMachine(prefix+"0", nil, pool, folders) for npool := 1; npool <= m.Pool; npool++ { spec := NewResourceConfigSpec() _, err = pool.Create(ctx, m.fmtName(prefix, npool), spec) if err != nil { return err } } } } if m.ServiceContent.RootFolder == esx.RootFolder.Reference() { // ESX model host := object.NewHostSystem(client, esx.HostSystem.Reference()) hosts = append(hosts, host) dc := object.NewDatacenter(client, esx.Datacenter.Reference()) folders, err := dc.Folders(ctx) if err != nil { return err } addMachine(host.Reference().Value, host, nil, folders) } for i := 0; i < m.Datastore; i++ { err := m.createLocalDatastore(m.fmtName("LocalDS_", i), hosts) if err != nil { return err } } for _, createVM := range vms { err := createVM() if err != nil { return err } } return nil }
func TestResourcePool(t *testing.T) { ctx := context.Background() m := &Model{ ServiceContent: esx.ServiceContent, RootFolder: esx.RootFolder, } err := m.Create() if err != nil { t.Fatal(err) } c := m.Service.client finder := find.NewFinder(c, false) finder.SetDatacenter(object.NewDatacenter(c, esx.Datacenter.Reference())) spec := NewResourceConfigSpec() parent := object.NewResourcePool(c, esx.ResourcePool.Self) // can't destroy a root pool task, err := parent.Destroy(ctx) if err != nil { t.Fatal(err) } if err = task.Wait(ctx); err == nil { t.Fatal("expected error destroying a root pool") } // create a child pool childName := uuid.New().String() child, err := parent.Create(ctx, childName, spec) if err != nil { t.Fatal(err) } if child.Reference() == esx.ResourcePool.Self { t.Error("expected new pool Self reference") } // create a grandchild pool grandChildName := uuid.New().String() _, err = child.Create(ctx, grandChildName, spec) if err != nil { t.Fatal(err) } // create sibling (of the grand child) pool siblingName := uuid.New().String() _, err = child.Create(ctx, siblingName, spec) if err != nil { t.Fatal(err) } // finder should return the 2 grand children pools, err := finder.ResourcePoolList(ctx, "*/Resources/"+childName+"/*") if err != nil { t.Fatal(err) } if len(pools) != 2 { t.Fatalf("len(pools) == %d", len(pools)) } // destroy the child task, err = child.Destroy(ctx) if err != nil { t.Fatal(err) } err = task.Wait(ctx) if err != nil { t.Fatal(err) } // finder should error not found after destroying the child _, err = finder.ResourcePoolList(ctx, "*/Resources/"+childName+"/*") if err == nil { t.Fatal("expected not found error") } // since the child was destroyed, grand child pools should now be children of the root pool pools, err = finder.ResourcePoolList(ctx, "*/Resources/*") if err != nil { t.Fatal(err) } if len(pools) != 2 { t.Fatalf("len(pools) == %d", len(pools)) } }