github.com/vmware/govmomi@v0.37.1/view/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 view_test
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"log"
    23  	"sort"
    24  	"sync"
    25  
    26  	"github.com/vmware/govmomi/find"
    27  	"github.com/vmware/govmomi/object"
    28  	"github.com/vmware/govmomi/property"
    29  	"github.com/vmware/govmomi/simulator"
    30  	"github.com/vmware/govmomi/view"
    31  	"github.com/vmware/govmomi/vim25"
    32  	"github.com/vmware/govmomi/vim25/mo"
    33  	"github.com/vmware/govmomi/vim25/types"
    34  )
    35  
    36  // Create a view of all hosts in the inventory, printing host names that belong to a cluster and excluding standalone hosts.
    37  func ExampleContainerView_Retrieve() {
    38  	model := simulator.VPX()
    39  	model.Datacenter = 2
    40  
    41  	simulator.Run(func(ctx context.Context, c *vim25.Client) error {
    42  		m := view.NewManager(c)
    43  		kind := []string{"HostSystem"}
    44  
    45  		v, err := m.CreateContainerView(ctx, c.ServiceContent.RootFolder, kind, true)
    46  		if err != nil {
    47  			log.Fatal(err)
    48  		}
    49  
    50  		var hosts []mo.HostSystem
    51  		var names []string
    52  
    53  		err = v.Retrieve(ctx, kind, []string{"summary.config.name", "parent"}, &hosts)
    54  		if err != nil {
    55  			return err
    56  		}
    57  
    58  		for _, host := range hosts {
    59  			if host.Parent.Type != "ClusterComputeResource" {
    60  				continue
    61  			}
    62  			names = append(names, host.Summary.Config.Name)
    63  		}
    64  
    65  		sort.Strings(names)
    66  		fmt.Println(names)
    67  
    68  		return v.Destroy(ctx)
    69  	}, model)
    70  	// Output: [DC0_C0_H0 DC0_C0_H1 DC0_C0_H2 DC1_C0_H0 DC1_C0_H1 DC1_C0_H2]
    71  }
    72  
    73  func ExampleContainerView_retrieveClusters() {
    74  	model := simulator.VPX()
    75  	model.Cluster = 3
    76  
    77  	simulator.Run(func(ctx context.Context, c *vim25.Client) error {
    78  		m := view.NewManager(c)
    79  		kind := []string{"ClusterComputeResource"}
    80  
    81  		v, err := m.CreateContainerView(ctx, c.ServiceContent.RootFolder, kind, true)
    82  		if err != nil {
    83  			log.Fatal(err)
    84  		}
    85  
    86  		var clusters []mo.ClusterComputeResource
    87  		var names []string
    88  
    89  		err = v.Retrieve(ctx, kind, []string{"name"}, &clusters)
    90  		if err != nil {
    91  			return err
    92  		}
    93  
    94  		for _, cluster := range clusters {
    95  			names = append(names, cluster.Name)
    96  		}
    97  
    98  		sort.Strings(names)
    99  		fmt.Println(names)
   100  
   101  		return v.Destroy(ctx)
   102  	}, model)
   103  	// Output: [DC0_C0 DC0_C1 DC0_C2]
   104  }
   105  
   106  // Create a view of all VMs in the inventory, printing VM names that end with "_VM1".
   107  func ExampleContainerView_RetrieveWithFilter() {
   108  	simulator.Run(func(ctx context.Context, c *vim25.Client) error {
   109  		m := view.NewManager(c)
   110  		kind := []string{"VirtualMachine"}
   111  
   112  		v, err := m.CreateContainerView(ctx, c.ServiceContent.RootFolder, kind, true)
   113  		if err != nil {
   114  			log.Fatal(err)
   115  		}
   116  
   117  		var vms []mo.VirtualMachine
   118  		var names []string
   119  
   120  		err = v.RetrieveWithFilter(ctx, kind, []string{"name"}, &vms, property.Match{"name": "*_VM1"})
   121  		if err != nil {
   122  			return err
   123  		}
   124  
   125  		for _, vm := range vms {
   126  			names = append(names, vm.Name)
   127  		}
   128  
   129  		sort.Strings(names)
   130  		fmt.Println(names)
   131  
   132  		return v.Destroy(ctx)
   133  	})
   134  	// Output: [DC0_C0_RP0_VM1 DC0_H0_VM1]
   135  }
   136  
   137  // Create a view of all VMs in a specific subfolder, powering off all VMs within
   138  func ExampleContainerView_Find() {
   139  	model := simulator.VPX()
   140  	model.Folder = 1 // put everything inside subfolders
   141  
   142  	simulator.Run(func(ctx context.Context, c *vim25.Client) error {
   143  		folder, err := object.NewSearchIndex(c).FindByInventoryPath(ctx, "/F0/DC0/vm/F0")
   144  		if err != nil {
   145  			return err
   146  		}
   147  
   148  		m := view.NewManager(c)
   149  		kind := []string{"VirtualMachine"} // include VMs only, ignoring other object types
   150  
   151  		// Root of the view is the subfolder moid (true == recurse into any subfolders of the root)
   152  		v, err := m.CreateContainerView(ctx, folder.Reference(), kind, true)
   153  		if err != nil {
   154  			log.Fatal(err)
   155  		}
   156  
   157  		vms, err := v.Find(ctx, kind, property.Match{})
   158  		if err != nil {
   159  			return err
   160  		}
   161  
   162  		for _, id := range vms {
   163  			vm := object.NewVirtualMachine(c, id)
   164  			task, err := vm.PowerOff(ctx)
   165  			if err != nil {
   166  				return err
   167  			}
   168  
   169  			if err = task.Wait(ctx); err != nil {
   170  				return err
   171  			}
   172  		}
   173  
   174  		fmt.Println(len(vms))
   175  
   176  		return v.Destroy(ctx)
   177  	}, model)
   178  	// Output: 4
   179  }
   180  
   181  // This example uses a single PropertyCollector with ListView for waiting on updates to N tasks
   182  func ExampleListView_tasks() {
   183  	simulator.Run(func(ctx context.Context, c *vim25.Client) error {
   184  		list, err := view.NewManager(c).CreateListView(ctx, nil)
   185  		if err != nil {
   186  			return err
   187  		}
   188  
   189  		defer list.Destroy(ctx)
   190  
   191  		vms, err := find.NewFinder(c).VirtualMachineList(ctx, "*")
   192  		if err != nil {
   193  			return err
   194  		}
   195  
   196  		result := map[types.TaskInfoState]int{}
   197  		n := len(vms)
   198  		p := property.DefaultCollector(c)
   199  
   200  		// wait for any updates to tasks in our list view
   201  		filter := new(property.WaitFilter).Add(list.Reference(), "Task", []string{"info"}, list.TraversalSpec())
   202  
   203  		var werr error
   204  		var wg sync.WaitGroup
   205  		wg.Add(1)
   206  		go func() { // WaitForUpdates blocks until func returns true
   207  			defer wg.Done()
   208  			werr = property.WaitForUpdates(ctx, p, filter, func(updates []types.ObjectUpdate) bool {
   209  				for _, update := range updates {
   210  					for _, change := range update.ChangeSet {
   211  						info := change.Val.(types.TaskInfo)
   212  
   213  						switch info.State {
   214  						case types.TaskInfoStateSuccess, types.TaskInfoStateError:
   215  							_, _ = list.Remove(ctx, []types.ManagedObjectReference{update.Obj})
   216  							result[info.State]++
   217  							n--
   218  							if n == 0 {
   219  								return true
   220  							}
   221  						}
   222  					}
   223  				}
   224  
   225  				return false
   226  			})
   227  		}()
   228  
   229  		for _, vm := range vms {
   230  			task, err := vm.PowerOff(ctx)
   231  			if err != nil {
   232  				return err
   233  			}
   234  			_, err = list.Add(ctx, []types.ManagedObjectReference{task.Reference()})
   235  			if err != nil {
   236  				return err
   237  			}
   238  		}
   239  
   240  		wg.Wait() // wait until all tasks complete and WaitForUpdates returns
   241  
   242  		for state, n := range result {
   243  			fmt.Printf("%s=%d", state, n)
   244  		}
   245  
   246  		return werr
   247  	})
   248  	// Output: success=4
   249  }