github.com/vmware/govmomi@v0.37.2/govc/cluster/override/info.go (about)

     1  /*
     2  Copyright (c) 2017-2023 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 override
    18  
    19  import (
    20  	"context"
    21  	"flag"
    22  	"fmt"
    23  	"io"
    24  	"strings"
    25  	"text/tabwriter"
    26  	"time"
    27  
    28  	"github.com/vmware/govmomi/govc/cli"
    29  	"github.com/vmware/govmomi/govc/flags"
    30  	"github.com/vmware/govmomi/object"
    31  	"github.com/vmware/govmomi/vim25/types"
    32  )
    33  
    34  type info struct {
    35  	*flags.ClusterFlag
    36  }
    37  
    38  func init() {
    39  	cli.Register("cluster.override.info", &info{})
    40  }
    41  
    42  func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
    43  	cmd.ClusterFlag, ctx = flags.NewClusterFlag(ctx)
    44  	cmd.ClusterFlag.Register(ctx, f)
    45  }
    46  
    47  func (cmd *info) Description() string {
    48  	return `Cluster VM overrides info.
    49  
    50  Examples:
    51    govc cluster.override.info
    52    govc cluster.override.info -json`
    53  }
    54  
    55  func (cmd *info) Process(ctx context.Context) error {
    56  	return cmd.ClusterFlag.Process(ctx)
    57  }
    58  
    59  type Override struct {
    60  	id            types.ManagedObjectReference
    61  	Name          string                            `json:"name"`
    62  	Host          string                            `json:"host,omitempty"`
    63  	DRS           *types.ClusterDrsVmConfigInfo     `json:"drs,omitempty"`
    64  	DAS           *types.ClusterDasVmConfigInfo     `json:"das,omitempty"`
    65  	Orchestration *types.ClusterVmOrchestrationInfo `json:"orchestration,omitempty"`
    66  }
    67  
    68  type infoResult struct {
    69  	Overrides map[string]*Override `json:"overrides"`
    70  }
    71  
    72  func (r *infoResult) Write(w io.Writer) error {
    73  	tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
    74  
    75  	for _, entry := range r.Overrides {
    76  		behavior := fmt.Sprintf("Default (%s)", types.DrsBehaviorFullyAutomated)
    77  		if entry.DRS != nil {
    78  			if *entry.DRS.Enabled {
    79  				behavior = string(entry.DRS.Behavior)
    80  			}
    81  		}
    82  
    83  		priority := fmt.Sprintf("Default (%s)", types.DasVmPriorityMedium)
    84  		if entry.DAS != nil {
    85  			priority = entry.DAS.DasSettings.RestartPriority
    86  		}
    87  
    88  		ready := "Default (Resources allocated)"
    89  		additionalDelay := 0
    90  		if entry.Orchestration != nil {
    91  			r := entry.Orchestration.VmReadiness
    92  			if r.ReadyCondition != string(types.ClusterVmReadinessReadyConditionUseClusterDefault) {
    93  				ready = strings.Title(r.ReadyCondition)
    94  			}
    95  			additionalDelay = int(r.PostReadyDelay)
    96  		}
    97  
    98  		fmt.Fprintf(tw, "Name:\t%s\n", entry.Name)
    99  		fmt.Fprintf(tw, "  DRS Automation Level:\t%s\n", strings.Title(behavior))
   100  		fmt.Fprintf(tw, "  HA Restart Priority:\t%s\n", strings.Title(priority))
   101  		fmt.Fprintf(tw, "  HA Ready Condition:\t%s\n", strings.Title(ready))
   102  		fmt.Fprintf(tw, "  HA Additional Delay:\t%s\n", time.Duration(additionalDelay)*time.Second)
   103  		fmt.Fprintf(tw, "  Host:\t%s\n", entry.Host)
   104  	}
   105  
   106  	return tw.Flush()
   107  }
   108  
   109  func (r *infoResult) entry(id types.ManagedObjectReference) *Override {
   110  	key := id.String()
   111  	vm, ok := r.Overrides[key]
   112  	if !ok {
   113  		r.Overrides[key] = &Override{id: id}
   114  		vm = r.Overrides[key]
   115  	}
   116  	return vm
   117  }
   118  
   119  func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
   120  	cluster, err := cmd.Cluster()
   121  	if err != nil {
   122  		return err
   123  	}
   124  
   125  	config, err := cluster.Configuration(ctx)
   126  	if err != nil {
   127  		return err
   128  	}
   129  
   130  	res := &infoResult{
   131  		Overrides: make(map[string]*Override),
   132  	}
   133  
   134  	for i := range config.DasVmConfig {
   135  		vm := res.entry(config.DasVmConfig[i].Key)
   136  
   137  		vm.DAS = &config.DasVmConfig[i]
   138  	}
   139  
   140  	for i := range config.DrsVmConfig {
   141  		vm := res.entry(config.DrsVmConfig[i].Key)
   142  
   143  		vm.DRS = &config.DrsVmConfig[i]
   144  	}
   145  
   146  	for i := range config.VmOrchestration {
   147  		vm := res.entry(config.VmOrchestration[i].Vm)
   148  
   149  		vm.Orchestration = &config.VmOrchestration[i]
   150  	}
   151  
   152  	for _, o := range res.Overrides {
   153  		// TODO: can optimize to reduce round trips
   154  		vm := object.NewVirtualMachine(cluster.Client(), o.id)
   155  		o.Name, _ = vm.ObjectName(ctx)
   156  		if h, herr := vm.HostSystem(ctx); herr == nil {
   157  			o.Host, _ = h.ObjectName(ctx)
   158  		}
   159  	}
   160  
   161  	return cmd.WriteResult(res)
   162  }