Add custom attributes for all resource types in vsphere input (#6884)

This commit is contained in:
Pontus Rydin 2020-01-13 18:15:55 -05:00 committed by Daniel Nelson
parent b908059326
commit 78a7978ea8
2 changed files with 62 additions and 38 deletions

View File

@ -84,7 +84,7 @@ type metricEntry struct {
fields map[string]interface{}
}
type objectMap map[string]objectRef
type objectMap map[string]*objectRef
type objectRef struct {
name string
@ -100,7 +100,7 @@ type objectRef struct {
func (e *Endpoint) getParent(obj *objectRef, res *resourceKind) (*objectRef, bool) {
if pKind, ok := e.resourceKinds[res.parent]; ok {
if p, ok := pKind.objects[obj.parentRef.Value]; ok {
return &p, true
return p, true
}
}
return nil, false
@ -322,7 +322,7 @@ func (e *Endpoint) getMetricNameMap(ctx context.Context) (map[int32]string, erro
return names, nil
}
func (e *Endpoint) getMetadata(ctx context.Context, obj objectRef, sampling int32) (performance.MetricList, error) {
func (e *Endpoint) getMetadata(ctx context.Context, obj *objectRef, sampling int32) (performance.MetricList, error) {
client, err := e.clientFactory.GetClient(ctx)
if err != nil {
return nil, err
@ -508,7 +508,7 @@ func (e *Endpoint) simpleMetadataSelect(ctx context.Context, client *Client, res
func (e *Endpoint) complexMetadataSelect(ctx context.Context, res *resourceKind, objects objectMap, metricNames map[int32]string) {
// We're only going to get metadata from maxMetadataSamples resources. If we have
// more resources than that, we pick maxMetadataSamples samples at random.
sampledObjects := make([]objectRef, len(objects))
sampledObjects := make([]*objectRef, len(objects))
i := 0
for _, obj := range objects {
sampledObjects[i] = obj
@ -529,7 +529,7 @@ func (e *Endpoint) complexMetadataSelect(ctx context.Context, res *resourceKind,
instInfoMux := sync.Mutex{}
te := NewThrottledExecutor(e.Parent.DiscoverConcurrency)
for _, obj := range sampledObjects {
func(obj objectRef) {
func(obj *objectRef) {
te.Run(ctx, func() {
metrics, err := e.getMetadata(ctx, obj, res.sampling)
if err != nil {
@ -573,8 +573,13 @@ func getDatacenters(ctx context.Context, e *Endpoint, filter *ResourceFilter) (o
}
m := make(objectMap, len(resources))
for _, r := range resources {
m[r.ExtensibleManagedObject.Reference().Value] = objectRef{
name: r.Name, ref: r.ExtensibleManagedObject.Reference(), parentRef: r.Parent, dcname: r.Name}
m[r.ExtensibleManagedObject.Reference().Value] = &objectRef{
name: r.Name,
ref: r.ExtensibleManagedObject.Reference(),
parentRef: r.Parent,
dcname: r.Name,
customValues: e.loadCustomAttributes(&r.ManagedEntity),
}
}
return m, nil
}
@ -613,8 +618,12 @@ func getClusters(ctx context.Context, e *Endpoint, filter *ResourceFilter) (obje
cache[r.Parent.Value] = p
}
}
m[r.ExtensibleManagedObject.Reference().Value] = objectRef{
name: r.Name, ref: r.ExtensibleManagedObject.Reference(), parentRef: p}
m[r.ExtensibleManagedObject.Reference().Value] = &objectRef{
name: r.Name,
ref: r.ExtensibleManagedObject.Reference(),
parentRef: p,
customValues: e.loadCustomAttributes(&r.ManagedEntity),
}
}
return m, nil
}
@ -627,8 +636,12 @@ func getHosts(ctx context.Context, e *Endpoint, filter *ResourceFilter) (objectM
}
m := make(objectMap)
for _, r := range resources {
m[r.ExtensibleManagedObject.Reference().Value] = objectRef{
name: r.Name, ref: r.ExtensibleManagedObject.Reference(), parentRef: r.Parent}
m[r.ExtensibleManagedObject.Reference().Value] = &objectRef{
name: r.Name,
ref: r.ExtensibleManagedObject.Reference(),
parentRef: r.Parent,
customValues: e.loadCustomAttributes(&r.ManagedEntity),
}
}
return m, nil
}
@ -693,30 +706,13 @@ func getVMs(ctx context.Context, e *Endpoint, filter *ResourceFilter) (objectMap
guest = cleanGuestID(r.Config.GuestId)
uuid = r.Config.Uuid
}
cvs := make(map[string]string)
if e.customAttrEnabled {
for _, cv := range r.Summary.CustomValue {
val := cv.(*types.CustomFieldStringValue)
if val.Value == "" {
continue
}
key, ok := e.customFields[val.Key]
if !ok {
e.Parent.Log.Warnf("Metadata for custom field %d not found. Skipping", val.Key)
continue
}
if e.customAttrFilter.Match(key) {
cvs[key] = val.Value
}
}
}
m[r.ExtensibleManagedObject.Reference().Value] = objectRef{
m[r.ExtensibleManagedObject.Reference().Value] = &objectRef{
name: r.Name,
ref: r.ExtensibleManagedObject.Reference(),
parentRef: r.Runtime.Host,
guest: guest,
altID: uuid,
customValues: cvs,
customValues: e.loadCustomAttributes(&r.ManagedEntity),
lookup: lookup,
}
}
@ -740,12 +736,40 @@ func getDatastores(ctx context.Context, e *Endpoint, filter *ResourceFilter) (ob
url = info.Url
}
}
m[r.ExtensibleManagedObject.Reference().Value] = objectRef{
name: r.Name, ref: r.ExtensibleManagedObject.Reference(), parentRef: r.Parent, altID: url}
m[r.ExtensibleManagedObject.Reference().Value] = &objectRef{
name: r.Name,
ref: r.ExtensibleManagedObject.Reference(),
parentRef: r.Parent,
altID: url,
customValues: e.loadCustomAttributes(&r.ManagedEntity),
}
}
return m, nil
}
func (e *Endpoint) loadCustomAttributes(entity *mo.ManagedEntity) map[string]string {
if !e.customAttrEnabled {
return map[string]string{}
}
cvs := make(map[string]string)
for _, v := range entity.CustomValue {
cv, ok := v.(*types.CustomFieldStringValue)
if !ok {
e.Parent.Log.Warnf("Metadata for custom field %d not of string type. Skipping", cv.Key)
continue
}
key, ok := e.customFields[cv.Key]
if !ok {
e.Parent.Log.Warnf("Metadata for custom field %d not found. Skipping", cv.Key)
continue
}
if e.customAttrFilter.Match(key) {
cvs[key] = cv.Value
}
}
return cvs
}
// Close shuts down an Endpoint and releases any resources associated with it.
func (e *Endpoint) Close() {
e.clientFactory.Close()
@ -1054,7 +1078,7 @@ func (e *Endpoint) collectChunk(ctx context.Context, pqs []types.PerfQuerySpec,
e.Parent.Log.Errorf("MOID %s not found in cache. Skipping", moid)
continue
}
e.populateTags(&objectRef, resourceType, res, t, &v)
e.populateTags(objectRef, resourceType, res, t, &v)
nValues := 0
alignedInfo, alignedValues := alignSamples(em.SampleInfo, v.Value, interval)

View File

@ -233,12 +233,12 @@ func init() {
}
addFields = map[string][]string{
"HostSystem": {"parent"},
"HostSystem": {"parent", "summary.customValue", "customValue"},
"VirtualMachine": {"runtime.host", "config.guestId", "config.uuid", "runtime.powerState",
"summary.customValue", "guest.net", "guest.hostName"},
"Datastore": {"parent", "info"},
"ClusterComputeResource": {"parent"},
"Datacenter": {"parent"},
"summary.customValue", "guest.net", "guest.hostName", "customValue"},
"Datastore": {"parent", "info", "customValue"},
"ClusterComputeResource": {"parent", "customValue"},
"Datacenter": {"parent", "customValue"},
}
containers = map[string]interface{}{