github.com/vmware/govmomi@v0.43.0/object/example_test.go (about) 1 /* 2 Copyright (c) 2019 VMware, Inc. All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package object_test 18 19 import ( 20 "context" 21 "fmt" 22 "log" 23 24 "github.com/vmware/govmomi/find" 25 "github.com/vmware/govmomi/object" 26 "github.com/vmware/govmomi/property" 27 "github.com/vmware/govmomi/simulator" 28 "github.com/vmware/govmomi/view" 29 "github.com/vmware/govmomi/vim25" 30 "github.com/vmware/govmomi/vim25/mo" 31 "github.com/vmware/govmomi/vim25/types" 32 ) 33 34 func ExampleResourcePool_Owner() { 35 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 36 finder := find.NewFinder(c) 37 38 for _, name := range []string{"DC0_H0_VM0", "DC0_C0_RP0_VM0"} { 39 vm, err := finder.VirtualMachine(ctx, name) 40 if err != nil { 41 return err 42 } 43 44 pool, err := vm.ResourcePool(ctx) 45 if err != nil { 46 return err 47 } 48 49 owner, err := pool.Owner(ctx) 50 if err != nil { 51 return err 52 } 53 54 fmt.Printf("%s owner is a %T\n", name, owner) 55 } 56 57 return nil 58 }) 59 // Output: 60 // DC0_H0_VM0 owner is a *object.ComputeResource 61 // DC0_C0_RP0_VM0 owner is a *object.ClusterComputeResource 62 } 63 64 func ExampleVirtualMachine_CreateSnapshot() { 65 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 66 vm, err := find.NewFinder(c).VirtualMachine(ctx, "DC0_H0_VM0") 67 if err != nil { 68 return err 69 } 70 71 task, err := vm.CreateSnapshot(ctx, "backup", "Backup", false, false) 72 if err != nil { 73 return err 74 } 75 if err = task.Wait(ctx); err != nil { 76 return err 77 } 78 79 id, err := vm.FindSnapshot(ctx, "backup") 80 if err != nil { 81 return err 82 } 83 84 var snapshot mo.VirtualMachineSnapshot 85 err = vm.Properties(ctx, *id, []string{"config.hardware.device"}, &snapshot) 86 if err != nil { 87 return err 88 } 89 90 fmt.Printf("%d devices", len(snapshot.Config.Hardware.Device)) 91 92 return nil 93 }) 94 // Output: 13 devices 95 } 96 97 func ExampleVirtualMachine_Customize() { 98 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 99 vm, err := find.NewFinder(c).VirtualMachine(ctx, "DC0_H0_VM0") 100 if err != nil { 101 return err 102 } 103 task, err := vm.PowerOff(ctx) 104 if err != nil { 105 return err 106 } 107 if err = task.Wait(ctx); err != nil { 108 return err 109 } 110 111 spec := types.CustomizationSpec{ 112 NicSettingMap: []types.CustomizationAdapterMapping{ 113 types.CustomizationAdapterMapping{ 114 Adapter: types.CustomizationIPSettings{ 115 Ip: &types.CustomizationFixedIp{ 116 IpAddress: "192.168.1.100", 117 }, 118 SubnetMask: "255.255.255.0", 119 Gateway: []string{"192.168.1.1"}, 120 DnsServerList: []string{"192.168.1.1"}, 121 DnsDomain: "ad.domain", 122 }, 123 }, 124 }, 125 Identity: &types.CustomizationLinuxPrep{ 126 HostName: &types.CustomizationFixedName{ 127 Name: "hostname", 128 }, 129 Domain: "ad.domain", 130 TimeZone: "Etc/UTC", 131 HwClockUTC: types.NewBool(true), 132 }, 133 GlobalIPSettings: types.CustomizationGlobalIPSettings{ 134 DnsSuffixList: []string{"ad.domain"}, 135 DnsServerList: []string{"192.168.1.1"}, 136 }, 137 } 138 139 task, err = vm.Customize(ctx, spec) 140 if err != nil { 141 return err 142 } 143 if err = task.Wait(ctx); err != nil { 144 return err 145 } 146 147 task, err = vm.PowerOn(ctx) 148 if err != nil { 149 return err 150 } 151 if err = task.Wait(ctx); err != nil { 152 return err 153 } 154 155 ip, err := vm.WaitForIP(ctx) 156 if err != nil { 157 return err 158 } 159 160 fmt.Println(ip) 161 162 return nil 163 }) 164 // Output: 192.168.1.100 165 } 166 167 func ExampleVirtualMachine_HostSystem() { 168 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 169 vm, err := find.NewFinder(c).VirtualMachine(ctx, "DC0_H0_VM0") 170 if err != nil { 171 return err 172 } 173 174 host, err := vm.HostSystem(ctx) 175 if err != nil { 176 return err 177 } 178 179 name, err := host.ObjectName(ctx) 180 if err != nil { 181 return err 182 } 183 184 fmt.Println(name) 185 186 return nil 187 }) 188 // Output: DC0_H0 189 } 190 191 func ExampleVirtualMachine_ResourcePool() { 192 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 193 finder := find.NewFinder(c) 194 vm, err := finder.VirtualMachine(ctx, "DC0_C0_RP0_VM0") 195 if err != nil { 196 return err 197 } 198 199 pool, err := vm.ResourcePool(ctx) 200 if err != nil { 201 return err 202 } 203 204 name, err := pool.ObjectName(ctx) 205 if err != nil { 206 return err 207 } 208 209 fmt.Println(name) 210 211 // The InventoryPath field not populated unless Finder.ResourcePool() or 212 // Finder.ResourcePoolList() was used. But we can populate it explicity. 213 pool.InventoryPath, err = find.InventoryPath(ctx, c, pool.Reference()) 214 if err != nil { 215 return err 216 } 217 218 fmt.Println(pool.InventoryPath) 219 220 return nil 221 }) 222 // Output: 223 // Resources 224 // /DC0/host/DC0_C0/Resources 225 } 226 227 func ExampleVirtualMachine_Clone() { 228 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 229 finder := find.NewFinder(c) 230 dc, err := finder.Datacenter(ctx, "DC0") 231 if err != nil { 232 return err 233 } 234 235 finder.SetDatacenter(dc) 236 237 vm, err := finder.VirtualMachine(ctx, "DC0_H0_VM0") 238 if err != nil { 239 return err 240 } 241 242 folders, err := dc.Folders(ctx) 243 if err != nil { 244 return err 245 } 246 247 spec := types.VirtualMachineCloneSpec{ 248 PowerOn: false, 249 } 250 251 task, err := vm.Clone(ctx, folders.VmFolder, "example-clone", spec) 252 if err != nil { 253 return err 254 } 255 256 info, err := task.WaitForResult(ctx) 257 if err != nil { 258 return err 259 } 260 261 clone := object.NewVirtualMachine(c, info.Result.(types.ManagedObjectReference)) 262 name, err := clone.ObjectName(ctx) 263 if err != nil { 264 return err 265 } 266 267 fmt.Println(name) 268 269 return nil 270 }) 271 // Output: example-clone 272 } 273 274 func ExampleFolder_CreateVM() { 275 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 276 finder := find.NewFinder(c) 277 dc, err := finder.Datacenter(ctx, "DC0") 278 if err != nil { 279 return err 280 } 281 282 finder.SetDatacenter(dc) 283 284 folders, err := dc.Folders(ctx) 285 if err != nil { 286 return err 287 } 288 289 pool, err := finder.ResourcePool(ctx, "DC0_C0/Resources") 290 if err != nil { 291 return err 292 } 293 294 spec := types.VirtualMachineConfigSpec{ 295 Name: "example-vm", 296 GuestId: string(types.VirtualMachineGuestOsIdentifierOtherGuest), 297 Files: &types.VirtualMachineFileInfo{ 298 VmPathName: "[LocalDS_0]", 299 }, 300 } 301 302 task, err := folders.VmFolder.CreateVM(ctx, spec, pool, nil) 303 if err != nil { 304 return err 305 } 306 307 info, err := task.WaitForResult(ctx) 308 if err != nil { 309 return err 310 } 311 312 vm := object.NewVirtualMachine(c, info.Result.(types.ManagedObjectReference)) 313 name, err := vm.ObjectName(ctx) 314 if err != nil { 315 return err 316 } 317 318 fmt.Println(name) 319 320 return nil 321 }) 322 // Output: example-vm 323 } 324 325 func ExampleVirtualMachine_Reconfigure() { 326 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 327 vm, err := find.NewFinder(c).VirtualMachine(ctx, "DC0_H0_VM0") 328 if err != nil { 329 return err 330 } 331 332 spec := types.VirtualMachineConfigSpec{Annotation: "example reconfig"} 333 334 task, err := vm.Reconfigure(ctx, spec) 335 if err != nil { 336 return err 337 } 338 339 err = task.Wait(ctx) 340 if err != nil { 341 return err 342 } 343 344 var obj mo.VirtualMachine 345 err = vm.Properties(ctx, vm.Reference(), []string{"config.annotation"}, &obj) 346 if err != nil { 347 return err 348 } 349 350 fmt.Println(obj.Config.Annotation) 351 352 return nil 353 }) 354 // Output: example reconfig 355 } 356 357 func ExampleCommon_Destroy() { 358 model := simulator.VPX() 359 model.Datastore = 2 360 361 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 362 // Change to "LocalDS_0" will cause ResourceInUse error, 363 // as simulator VMs created by the VPX model use "LocalDS_0". 364 ds, err := find.NewFinder(c).Datastore(ctx, "LocalDS_1") 365 if err != nil { 366 return err 367 } 368 369 task, err := ds.Destroy(ctx) 370 if err != nil { 371 return err 372 } 373 374 if err = task.Wait(ctx); err != nil { 375 return err 376 } 377 378 fmt.Println("destroyed", ds.InventoryPath) 379 return nil 380 }, model) 381 // Output: destroyed /DC0/datastore/LocalDS_1 382 } 383 384 func ExampleCommon_Rename() { 385 model := simulator.VPX() 386 387 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 388 dc, err := find.NewFinder(c).Datacenter(ctx, "DC0") 389 if err != nil { 390 return err 391 } 392 393 task, err := dc.Rename(ctx, "MyDC") 394 if err != nil { 395 return err 396 } 397 398 if err = task.Wait(ctx); err != nil { 399 return err 400 } 401 402 name, err := dc.ObjectName(ctx) 403 if err != nil { 404 return err 405 } 406 407 fmt.Println(name) 408 return nil 409 }, model) 410 // Output: MyDC 411 } 412 413 func ExampleCustomFieldsManager_Set() { 414 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 415 m, err := object.GetCustomFieldsManager(c) 416 if err != nil { 417 return err 418 } 419 420 any := []string{"ManagedEntity"} 421 field, err := m.Add(ctx, "backup", any[0], nil, nil) // adds the custom field "backup" to all types 422 if err != nil { 423 return err 424 } 425 426 v, err := view.NewManager(c).CreateContainerView(ctx, c.ServiceContent.RootFolder, any, true) 427 if err != nil { 428 log.Fatal(err) 429 } 430 431 all, err := v.Find(ctx, any, nil) // gives us the count of all objects in the inventory 432 if err != nil { 433 return err 434 } 435 436 refs, err := v.Find(ctx, []string{"VirtualMachine", "Datastore"}, nil) 437 if err != nil { 438 return err 439 } 440 441 for _, ref := range refs { 442 err = m.Set(ctx, ref, field.Key, "true") // sets the custom value "backup=true" on specific types 443 if err != nil { 444 return err 445 } 446 } 447 448 // filter used to find objects with "backup=true" 449 filter := property.Match{"customValue": &types.CustomFieldStringValue{ 450 CustomFieldValue: types.CustomFieldValue{Key: field.Key}, 451 Value: "true", 452 }} 453 454 var objs []mo.ManagedEntity 455 err = v.RetrieveWithFilter(ctx, any, []string{"name", "customValue"}, &objs, filter) 456 if err != nil { 457 return err 458 } 459 460 fmt.Printf("backup %d of %d objects", len(objs), len(all)) 461 return v.Destroy(ctx) 462 }) 463 // Output: backup 5 of 22 objects 464 } 465 466 func ExampleCustomizationSpecManager_Info() { 467 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 468 m := object.NewCustomizationSpecManager(c) 469 info, err := m.Info(ctx) 470 if err != nil { 471 return err 472 } 473 474 for i := range info { 475 item, err := m.GetCustomizationSpec(ctx, info[i].Name) 476 if err != nil { 477 return err 478 } 479 fmt.Printf("%s=%T\n", item.Info.Name, item.Spec.Identity) 480 } 481 return nil 482 }) 483 // Output: 484 // vcsim-linux=*types.CustomizationLinuxPrep 485 // vcsim-linux-static=*types.CustomizationLinuxPrep 486 // vcsim-windows-static=*types.CustomizationSysprep 487 // vcsim-windows-domain=*types.CustomizationSysprep 488 } 489 490 func ExampleNetworkReference_EthernetCardBackingInfo() { 491 model := simulator.VPX() 492 model.OpaqueNetwork = 1 // Create 1 NSX backed OpaqueNetwork per DC 493 494 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 495 finder := find.NewFinder(c) 496 vm, err := finder.VirtualMachine(ctx, "DC0_H0_VM0") 497 if err != nil { 498 return err 499 } 500 501 // finder.Network returns an object.NetworkReference 502 net, err := finder.Network(ctx, "DC0_NSX0") 503 if err != nil { 504 return err 505 } 506 507 // EthernetCardBackingInfo creates the backing for any network type: 508 // "Network", "DistributedVirtualPortgroup" or "OpaqueNetwork" 509 backing, err := net.EthernetCardBackingInfo(ctx) 510 if err != nil { 511 return err 512 } 513 514 device, err := object.EthernetCardTypes().CreateEthernetCard("e1000", backing) 515 if err != nil { 516 return err 517 } 518 519 err = vm.AddDevice(ctx, device) 520 if err != nil { 521 return err 522 } 523 524 list, err := vm.Device(ctx) 525 if err != nil { 526 return err 527 } 528 529 nics := list.SelectByType((*types.VirtualEthernetCard)(nil)) // All VM NICs (DC0_DVPG0 + DC0_NSX0) 530 match := list.SelectByBackingInfo(backing) // VM NIC with DC0_NSX0 backing 531 532 fmt.Printf("%d of %d NICs match backing\n", len(match), len(nics)) 533 534 return nil 535 }, model) 536 // Output: 1 of 2 NICs match backing 537 } 538 539 func ExampleVirtualDeviceList_SelectByBackingInfo() { 540 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 541 finder := find.NewFinder(c) 542 vm, err := finder.VirtualMachine(ctx, "DC0_H0_VM0") 543 if err != nil { 544 return err 545 } 546 547 backing := &types.VirtualPCIPassthroughVmiopBackingInfo{ 548 Vgpu: "grid_v100-4q", 549 } 550 551 gpu := &types.VirtualPCIPassthrough{ 552 VirtualDevice: types.VirtualDevice{Backing: backing}, 553 } 554 555 err = vm.AddDevice(ctx, gpu) // add a GPU to this VM 556 if err != nil { 557 return err 558 } 559 560 device, err := vm.Device(ctx) // get the VM's virtual device list 561 if err != nil { 562 return err 563 } 564 565 // find the device with the given backing info 566 gpus := device.SelectByBackingInfo(backing) 567 568 name := gpus[0].(*types.VirtualPCIPassthrough).Backing.(*types.VirtualPCIPassthroughVmiopBackingInfo).Vgpu 569 570 fmt.Println(name) 571 572 // example alternative to using SelectByBackingInfo for the use-case above: 573 for i := range device { 574 switch d := device[i].(type) { 575 case *types.VirtualPCIPassthrough: 576 switch b := d.Backing.(type) { 577 case *types.VirtualPCIPassthroughVmiopBackingInfo: 578 if b.Vgpu == backing.Vgpu { 579 fmt.Println(b.Vgpu) 580 } 581 } 582 } 583 } 584 585 return nil 586 }) 587 588 // Output: 589 // grid_v100-4q 590 // grid_v100-4q 591 } 592 593 // Find a VirtualMachine's Cluster 594 func ExampleVirtualMachine_resourcePoolOwner() { 595 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 596 obj, err := find.NewFinder(c).VirtualMachine(ctx, "DC0_C0_RP0_VM0") 597 if err != nil { 598 return err 599 } 600 601 pool, err := obj.ResourcePool(ctx) 602 if err != nil { 603 return err 604 } 605 606 // ResourcePool owner will be a ComputeResource or ClusterComputeResource 607 cluster, err := pool.Owner(ctx) 608 if err != nil { 609 return err 610 } 611 612 fmt.Printf("%s", cluster.Reference().Type) 613 614 return nil 615 }) 616 // Output: ClusterComputeResource 617 } 618 619 func ExampleHostConfigManager_OptionManager() { 620 simulator.Run(func(ctx context.Context, c *vim25.Client) error { 621 m := view.NewManager(c) 622 kind := []string{"HostSystem"} 623 624 v, err := m.CreateContainerView(ctx, c.ServiceContent.RootFolder, kind, true) 625 if err != nil { 626 log.Fatal(err) 627 } 628 629 refs, err := v.Find(ctx, kind, nil) 630 if err != nil { 631 return err 632 } 633 634 setting := "" 635 636 for _, ref := range refs { 637 host := object.NewHostSystem(c, ref) 638 m, err := host.ConfigManager().OptionManager(ctx) 639 if err != nil { 640 return err 641 } 642 643 opt := []types.BaseOptionValue{&types.OptionValue{ 644 Key: "vcrun", 645 Value: "Config.HostAgent.plugins.hostsvc.esxAdminsGroup", 646 }} 647 648 err = m.Update(ctx, opt) 649 if err != nil { 650 return err 651 } 652 653 opt, err = m.Query(ctx, "vcrun") 654 if err != nil { 655 return err 656 } 657 setting = opt[0].GetOptionValue().Value.(string) 658 } 659 660 fmt.Println(setting) 661 662 return v.Destroy(ctx) 663 }) 664 // Output: Config.HostAgent.plugins.hostsvc.esxAdminsGroup 665 }