Skip to content

Commit

Permalink
[receiver/vcenter] Fixes multiple datacenters issue (open-telemetry#3…
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanKurek authored and lalith47 committed Jul 1, 2024
1 parent d672c14 commit cdc35b0
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 26 deletions.
27 changes: 27 additions & 0 deletions .chloggen/vcenterreceiver_fix_multiple_datacenters.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: bug_fix

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: vcenterreceiver

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Fixes errors in some of the client calls for environments containing multiple datacenters.

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [33734]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: []
55 changes: 41 additions & 14 deletions receiver/vcenterreceiver/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,29 +224,56 @@ func (vc *vcenterClient) VMs(ctx context.Context, containerMoRef vt.ManagedObjec
return vms, nil
}

// ResourcePoolInventoryListObjects returns the ResourcePools (with populated InventoryLists) of the vSphere SDK
func (vc *vcenterClient) ResourcePoolInventoryListObjects(ctx context.Context) ([]*object.ResourcePool, error) {
rps, err := vc.finder.ResourcePoolList(ctx, "*")
// DatacenterInventoryListObjects returns the Datacenters (with populated InventoryLists) of the vSphere SDK
func (vc *vcenterClient) DatacenterInventoryListObjects(ctx context.Context) ([]*object.Datacenter, error) {
dcs, err := vc.finder.DatacenterList(ctx, "*")
if err != nil {
return nil, fmt.Errorf("unable to retrieve ResourcePools with InventoryLists: %w", err)
return nil, fmt.Errorf("unable to retrieve Datacenters with InventoryLists: %w", err)
}

return rps, nil
return dcs, nil
}

// VAppInventoryListObjects returns the vApps (with populated InventoryLists) of the vSphere SDK
func (vc *vcenterClient) VAppInventoryListObjects(ctx context.Context) ([]*object.VirtualApp, error) {
vApps, err := vc.finder.VirtualAppList(ctx, "*")
if err == nil {
return vApps, nil
// ResourcePoolInventoryListObjects returns the ResourcePools (with populated InventoryLists) of the vSphere SDK
func (vc *vcenterClient) ResourcePoolInventoryListObjects(
ctx context.Context,
dcs []*object.Datacenter,
) ([]*object.ResourcePool, error) {
allRPools := []*object.ResourcePool{}
for _, dc := range dcs {
vc.finder.SetDatacenter(dc)
rps, err := vc.finder.ResourcePoolList(ctx, "*")
var notFoundErr *find.NotFoundError
if err != nil && !errors.As(err, &notFoundErr) {
return nil, fmt.Errorf("unable to retrieve ResourcePools with InventoryLists for datacenter %s: %w", dc.InventoryPath, err)
}
allRPools = append(allRPools, rps...)
}

var notFoundErr *find.NotFoundError
if errors.As(err, &notFoundErr) {
return []*object.VirtualApp{}, nil
return allRPools, nil
}

// VAppInventoryListObjects returns the vApps (with populated InventoryLists) of the vSphere SDK
func (vc *vcenterClient) VAppInventoryListObjects(
ctx context.Context,
dcs []*object.Datacenter,
) ([]*object.VirtualApp, error) {
allVApps := []*object.VirtualApp{}
for _, dc := range dcs {
vc.finder.SetDatacenter(dc)
vApps, err := vc.finder.VirtualAppList(ctx, "*")
if err == nil {
allVApps = append(allVApps, vApps...)
continue
}

var notFoundErr *find.NotFoundError
if !errors.As(err, &notFoundErr) {
return nil, fmt.Errorf("unable to retrieve vApps with InventoryLists for datacenter %s: %w", dc.InventoryPath, err)
}
}

return nil, fmt.Errorf("unable to retrieve vApps with InventoryLists: %w", err)
return allVApps, nil
}

// PerfMetricsQueryResult contains performance metric related data
Expand Down
36 changes: 31 additions & 5 deletions receiver/vcenterreceiver/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,48 +219,74 @@ func TestPerfMetricsQuery(t *testing.T) {
}, esx)
}

func TestDatacenterInventoryListObjects(t *testing.T) {
vpx := simulator.VPX()
vpx.Datacenter = 2
simulator.Test(func(ctx context.Context, c *vim25.Client) {
finder := find.NewFinder(c)
client := vcenterClient{
vimDriver: c,
finder: finder,
}
dcs, err := client.DatacenterInventoryListObjects(ctx)
require.NoError(t, err)
require.Equal(t, len(dcs), 2)
}, vpx)
}

func TestResourcePoolInventoryListObjects(t *testing.T) {
vpx := simulator.VPX()
vpx.Datacenter = 2
simulator.Test(func(ctx context.Context, c *vim25.Client) {
finder := find.NewFinder(c)
client := vcenterClient{
vimDriver: c,
finder: finder,
}
rps, err := client.ResourcePoolInventoryListObjects(ctx)
dcs, err := finder.DatacenterList(ctx, "*")
require.NoError(t, err)
rps, err := client.ResourcePoolInventoryListObjects(ctx, dcs)
require.NoError(t, err)
require.NotEmpty(t, rps, 0)
})
}, vpx)
}

func TestVAppInventoryListObjects(t *testing.T) {
// Currently skipping as the Simulator has no vApps by default and setting
// vApps appears to be broken
t.Skip()
vpx := simulator.VPX()
vpx.Datacenter = 2
vpx.App = 2
simulator.Test(func(ctx context.Context, c *vim25.Client) {
finder := find.NewFinder(c)
client := vcenterClient{
vimDriver: c,
finder: finder,
}
vApps, err := client.VAppInventoryListObjects(ctx)
dcs, err := finder.DatacenterList(ctx, "*")
require.NoError(t, err)
vApps, err := client.VAppInventoryListObjects(ctx, dcs)
require.NoError(t, err)
require.NotEmpty(t, vApps, 0)
}, vpx)
}

func TestEmptyVAppInventoryListObjects(t *testing.T) {
vpx := simulator.VPX()
vpx.Datacenter = 2
simulator.Test(func(ctx context.Context, c *vim25.Client) {
finder := find.NewFinder(c)
client := vcenterClient{
vimDriver: c,
finder: finder,
}
vApps, err := client.VAppInventoryListObjects(ctx)
dcs, err := finder.DatacenterList(ctx, "*")
require.NoError(t, err)
vApps, err := client.VAppInventoryListObjects(ctx, dcs)
require.NoError(t, err)
require.Empty(t, vApps, 0)
})
}, vpx)
}

func TestSessionReestablish(t *testing.T) {
Expand Down
37 changes: 30 additions & 7 deletions receiver/vcenterreceiver/scraper.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"fmt"

"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/performance"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
Expand Down Expand Up @@ -108,8 +109,9 @@ func (v *vcenterMetricScraper) scrape(ctx context.Context) (pmetric.Metrics, err
// scrapeAndProcessAllMetrics collects & converts all relevant resources managed by vCenter to OTEL resources & metrics
func (v *vcenterMetricScraper) scrapeAndProcessAllMetrics(ctx context.Context, errs *scrapererror.ScrapeErrors) error {
v.scrapeData = newVcenterScrapeData()
v.scrapeResourcePoolInventoryListObjects(ctx, errs)
v.scrapeVAppInventoryListObjects(ctx, errs)
dcObjects := v.scrapeDatacenterInventoryListObjects(ctx, errs)
v.scrapeResourcePoolInventoryListObjects(ctx, dcObjects, errs)
v.scrapeVAppInventoryListObjects(ctx, dcObjects, errs)
v.scrapeDatacenters(ctx, errs)

for _, dc := range v.scrapeData.datacenters {
Expand All @@ -128,13 +130,30 @@ func (v *vcenterMetricScraper) scrapeAndProcessAllMetrics(ctx context.Context, e
return errs.Combine()
}

// scrapeResourcePoolInventoryListObjects scrapes and store all ResourcePool objects with their InventoryLists
func (v *vcenterMetricScraper) scrapeResourcePoolInventoryListObjects(ctx context.Context, errs *scrapererror.ScrapeErrors) {
// scrapeDatacenterInventoryListObjects scrapes and stores all Datacenter objects with their InventoryLists
func (v *vcenterMetricScraper) scrapeDatacenterInventoryListObjects(
ctx context.Context,
errs *scrapererror.ScrapeErrors,
) []*object.Datacenter {
// Get Datacenters with InventoryLists and store for later retrieval
dcs, err := v.client.DatacenterInventoryListObjects(ctx)
if err != nil {
errs.AddPartial(1, err)
}
return dcs
}

// scrapeResourcePoolInventoryListObjects scrapes and stores all ResourcePool objects with their InventoryLists
func (v *vcenterMetricScraper) scrapeResourcePoolInventoryListObjects(
ctx context.Context,
dcs []*object.Datacenter,
errs *scrapererror.ScrapeErrors,
) {
// Init for current collection
v.scrapeData.rPoolIPathsByRef = make(map[string]*string)

// Get ResourcePools with InventoryLists and store for later retrieval
rPools, err := v.client.ResourcePoolInventoryListObjects(ctx)
rPools, err := v.client.ResourcePoolInventoryListObjects(ctx, dcs)
if err != nil {
errs.AddPartial(1, err)
return
Expand All @@ -145,12 +164,16 @@ func (v *vcenterMetricScraper) scrapeResourcePoolInventoryListObjects(ctx contex
}

// scrapeVAppInventoryListObjects scrapes and stores all vApp objects with their InventoryLists
func (v *vcenterMetricScraper) scrapeVAppInventoryListObjects(ctx context.Context, errs *scrapererror.ScrapeErrors) {
func (v *vcenterMetricScraper) scrapeVAppInventoryListObjects(
ctx context.Context,
dcs []*object.Datacenter,
errs *scrapererror.ScrapeErrors,
) {
// Init for current collection
v.scrapeData.vAppIPathsByRef = make(map[string]*string)

// Get vApps with InventoryLists and store for later retrieval
vApps, err := v.client.VAppInventoryListObjects(ctx)
vApps, err := v.client.VAppInventoryListObjects(ctx, dcs)
if err != nil {
errs.AddPartial(1, err)
return
Expand Down

0 comments on commit cdc35b0

Please sign in to comment.