client.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package vcenterreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/vcenterreceiver"
  4. import (
  5. "context"
  6. "fmt"
  7. "net/url"
  8. "github.com/vmware/govmomi"
  9. "github.com/vmware/govmomi/find"
  10. "github.com/vmware/govmomi/object"
  11. "github.com/vmware/govmomi/performance"
  12. "github.com/vmware/govmomi/property"
  13. "github.com/vmware/govmomi/vim25"
  14. vt "github.com/vmware/govmomi/vim25/types"
  15. )
  16. // vcenterClient is a client that
  17. type vcenterClient struct {
  18. moClient *govmomi.Client
  19. vimDriver *vim25.Client
  20. finder *find.Finder
  21. pc *property.Collector
  22. pm *performance.Manager
  23. cfg *Config
  24. }
  25. var newVcenterClient = defaultNewVcenterClient
  26. func defaultNewVcenterClient(c *Config) *vcenterClient {
  27. return &vcenterClient{
  28. cfg: c,
  29. }
  30. }
  31. // EnsureConnection will establish a connection to the vSphere SDK if not already established
  32. func (vc *vcenterClient) EnsureConnection(ctx context.Context) error {
  33. if vc.moClient != nil {
  34. sessionActive, _ := vc.moClient.SessionManager.SessionIsActive(ctx)
  35. if sessionActive {
  36. return nil
  37. }
  38. }
  39. sdkURL, err := vc.cfg.SDKUrl()
  40. if err != nil {
  41. return err
  42. }
  43. client, err := govmomi.NewClient(ctx, sdkURL, vc.cfg.Insecure)
  44. if err != nil {
  45. return fmt.Errorf("unable to connect to vSphere SDK on listed endpoint: %w", err)
  46. }
  47. tlsCfg, err := vc.cfg.LoadTLSConfig()
  48. if err != nil {
  49. return err
  50. }
  51. if tlsCfg != nil {
  52. client.DefaultTransport().TLSClientConfig = tlsCfg
  53. }
  54. user := url.UserPassword(vc.cfg.Username, string(vc.cfg.Password))
  55. err = client.Login(ctx, user)
  56. if err != nil {
  57. return fmt.Errorf("unable to login to vcenter sdk: %w", err)
  58. }
  59. vc.moClient = client
  60. vc.vimDriver = client.Client
  61. vc.pc = property.DefaultCollector(vc.vimDriver)
  62. vc.finder = find.NewFinder(vc.vimDriver)
  63. vc.pm = performance.NewManager(vc.vimDriver)
  64. return nil
  65. }
  66. // Disconnect will logout of the autenticated session
  67. func (vc *vcenterClient) Disconnect(ctx context.Context) error {
  68. if vc.moClient != nil {
  69. return vc.moClient.Logout(ctx)
  70. }
  71. return nil
  72. }
  73. // Clusters returns the clusterComputeResources of the vSphere SDK
  74. func (vc *vcenterClient) Datacenters(ctx context.Context) ([]*object.Datacenter, error) {
  75. datacenters, err := vc.finder.DatacenterList(ctx, "*")
  76. if err != nil {
  77. return []*object.Datacenter{}, fmt.Errorf("unable to get datacenter lists: %w", err)
  78. }
  79. return datacenters, nil
  80. }
  81. // Clusters returns the clusterComputeResources of the vSphere SDK
  82. func (vc *vcenterClient) Clusters(ctx context.Context, datacenter *object.Datacenter) ([]*object.ClusterComputeResource, error) {
  83. vc.finder = vc.finder.SetDatacenter(datacenter)
  84. clusters, err := vc.finder.ClusterComputeResourceList(ctx, "*")
  85. if err != nil {
  86. return []*object.ClusterComputeResource{}, fmt.Errorf("unable to get cluster lists: %w", err)
  87. }
  88. return clusters, nil
  89. }
  90. // ResourcePools returns the resourcePools in the vSphere SDK
  91. func (vc *vcenterClient) ResourcePools(ctx context.Context) ([]*object.ResourcePool, error) {
  92. rps, err := vc.finder.ResourcePoolList(ctx, "*")
  93. if err != nil {
  94. return nil, fmt.Errorf("unable to retrieve resource pools: %w", err)
  95. }
  96. return rps, err
  97. }
  98. func (vc *vcenterClient) VMs(ctx context.Context) ([]*object.VirtualMachine, error) {
  99. vms, err := vc.finder.VirtualMachineList(ctx, "*")
  100. if err != nil {
  101. return nil, fmt.Errorf("unable to retrieve vms: %w", err)
  102. }
  103. return vms, err
  104. }
  105. type perfSampleResult struct {
  106. counters map[string]*vt.PerfCounterInfo
  107. results []performance.EntityMetric
  108. }
  109. func (vc *vcenterClient) performanceQuery(
  110. ctx context.Context,
  111. spec vt.PerfQuerySpec,
  112. names []string,
  113. objs []vt.ManagedObjectReference,
  114. ) (*perfSampleResult, error) {
  115. if vc.pm == nil {
  116. return &perfSampleResult{}, nil
  117. }
  118. vc.pm.Sort = true
  119. sample, err := vc.pm.SampleByName(ctx, spec, names, objs)
  120. if err != nil {
  121. return nil, err
  122. }
  123. result, err := vc.pm.ToMetricSeries(ctx, sample)
  124. if err != nil {
  125. return nil, err
  126. }
  127. counterInfoByName, err := vc.pm.CounterInfoByName(ctx)
  128. if err != nil {
  129. return nil, err
  130. }
  131. return &perfSampleResult{
  132. counters: counterInfoByName,
  133. results: result,
  134. }, nil
  135. }