github.com/netdata/go.d.plugin@v0.58.1/modules/vsphere/discover/discover.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package discover
     4  
     5  import (
     6  	"fmt"
     7  	"strings"
     8  	"time"
     9  
    10  	"github.com/netdata/go.d.plugin/modules/vsphere/match"
    11  	rs "github.com/netdata/go.d.plugin/modules/vsphere/resources"
    12  
    13  	"github.com/netdata/go.d.plugin/logger"
    14  	"github.com/vmware/govmomi/vim25/mo"
    15  	"github.com/vmware/govmomi/vim25/types"
    16  )
    17  
    18  type Client interface {
    19  	Datacenters(pathSet ...string) ([]mo.Datacenter, error)
    20  	Folders(pathSet ...string) ([]mo.Folder, error)
    21  	ComputeResources(pathSet ...string) ([]mo.ComputeResource, error)
    22  	Hosts(pathSet ...string) ([]mo.HostSystem, error)
    23  	VirtualMachines(pathSet ...string) ([]mo.VirtualMachine, error)
    24  
    25  	CounterInfoByName() (map[string]*types.PerfCounterInfo, error)
    26  }
    27  
    28  func New(client Client) *Discoverer {
    29  	return &Discoverer{
    30  		Client: client,
    31  	}
    32  }
    33  
    34  type Discoverer struct {
    35  	*logger.Logger
    36  	Client
    37  	match.HostMatcher
    38  	match.VMMatcher
    39  }
    40  
    41  type resources struct {
    42  	dcs      []mo.Datacenter
    43  	folders  []mo.Folder
    44  	clusters []mo.ComputeResource
    45  	hosts    []mo.HostSystem
    46  	vms      []mo.VirtualMachine
    47  }
    48  
    49  func (d Discoverer) Discover() (*rs.Resources, error) {
    50  	startTime := time.Now()
    51  	raw, err := d.discover()
    52  	if err != nil {
    53  		return nil, fmt.Errorf("discovering resources : %v", err)
    54  	}
    55  
    56  	res := d.build(raw)
    57  
    58  	err = d.setHierarchy(res)
    59  	if err != nil {
    60  		// TODO: handle objects w/o hier?
    61  		d.Error(err)
    62  	}
    63  
    64  	numH := len(res.Hosts)
    65  	numV := len(res.VMs)
    66  	removed := d.removeUnmatched(res)
    67  	if removed == (numH + numV) {
    68  		return nil, fmt.Errorf("all resoursces were filtered (%d hosts, %d vms)", numH, numV)
    69  	}
    70  
    71  	err = d.collectMetricLists(res)
    72  	if err != nil {
    73  		return nil, fmt.Errorf("collecting metric lists : %v", err)
    74  	}
    75  
    76  	d.Infof("discovering : discovered %d/%d hosts, %d/%d vms, the whole process took %s",
    77  		len(res.Hosts),
    78  		len(raw.hosts),
    79  		len(res.VMs),
    80  		len(raw.vms),
    81  		time.Since(startTime))
    82  
    83  	return res, nil
    84  }
    85  
    86  var (
    87  	// properties to set
    88  	datacenterPathSet = []string{"name", "parent"}
    89  	folderPathSet     = []string{"name", "parent"}
    90  	clusterPathSet    = []string{"name", "parent"}
    91  	hostPathSet       = []string{"name", "parent", "runtime.powerState", "summary.overallStatus"}
    92  	vmPathSet         = []string{"name", "runtime.host", "runtime.powerState", "summary.overallStatus"}
    93  )
    94  
    95  func (d Discoverer) discover() (*resources, error) {
    96  	d.Debug("discovering : starting resource discovering process")
    97  
    98  	start := time.Now()
    99  	t := start
   100  	datacenters, err := d.Datacenters(datacenterPathSet...)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	d.Debugf("discovering : found %d dcs, process took %s", len(datacenters), time.Since(t))
   105  
   106  	t = time.Now()
   107  	folders, err := d.Folders(folderPathSet...)
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  	d.Debugf("discovering : found %d folders, process took %s", len(folders), time.Since(t))
   112  
   113  	t = time.Now()
   114  	clusters, err := d.ComputeResources(clusterPathSet...)
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  	d.Debugf("discovering : found %d clusters, process took %s", len(clusters), time.Since(t))
   119  
   120  	t = time.Now()
   121  	hosts, err := d.Hosts(hostPathSet...)
   122  	if err != nil {
   123  		return nil, err
   124  	}
   125  	d.Debugf("discovering : found %d hosts, process took %s", len(hosts), time.Since(t))
   126  
   127  	t = time.Now()
   128  	vms, err := d.VirtualMachines(vmPathSet...)
   129  	if err != nil {
   130  		return nil, err
   131  	}
   132  	d.Debugf("discovering : found %d vms, process took %s", len(hosts), time.Since(t))
   133  
   134  	raw := resources{
   135  		dcs:      datacenters,
   136  		folders:  folders,
   137  		clusters: clusters,
   138  		hosts:    hosts,
   139  		vms:      vms,
   140  	}
   141  
   142  	d.Infof("discovering : found %d dcs, %d folders, %d clusters (%d dummy), %d hosts, %d vms, process took %s",
   143  		len(raw.dcs),
   144  		len(raw.folders),
   145  		len(clusters),
   146  		numOfDummyClusters(clusters),
   147  		len(raw.hosts),
   148  		len(raw.vms),
   149  		time.Since(start),
   150  	)
   151  
   152  	return &raw, nil
   153  }
   154  
   155  func numOfDummyClusters(clusters []mo.ComputeResource) (num int) {
   156  	for _, c := range clusters {
   157  		// domain-s61 | domain-c52
   158  		if strings.HasPrefix(c.Reference().Value, "domain-s") {
   159  			num++
   160  		}
   161  	}
   162  	return num
   163  }