Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add empty hostname workaround #19393

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions vsphere/changelog.d/19393.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Submit non-VM or ESXI events with an empty hostname.
1 change: 1 addition & 0 deletions vsphere/datadog_checks/vsphere/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def __init__(self, instance, init_config, log):
self.collect_vsan = is_affirmative(instance.get("collect_vsan_data", False))
self.attr_prefix = instance.get("attributes_prefix", DEFAULT_VSPHERE_ATTR_PREFIX)
self.excluded_host_tags = instance.get("excluded_host_tags", [])
self.empty_default_hostname = instance.get("empty_default_hostname", False)
self.base_tags = instance.get("tags", []) + ["vcenter_server:{}".format(self.hostname)]
self.refresh_infrastructure_cache_interval = instance.get(
'refresh_infrastructure_cache_interval', DEFAULT_REFRESH_INFRASTRUCTURE_CACHE_INTERVAL
Expand Down
15 changes: 11 additions & 4 deletions vsphere/datadog_checks/vsphere/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@

class VSphereEvent(object):
UNKNOWN = 'unknown'
EMPTY_HOSTNAME = "AGENT_INT_EMPTY_HOSTNAME"

def __init__(self, raw_event, event_config, tags, event_resource_filters, exclude_filters=EXCLUDE_FILTERS):
def __init__(
self, raw_event, event_config, tags, event_resource_filters, exclude_filters=EXCLUDE_FILTERS, hostname=None
):
self.raw_event = raw_event
if self.raw_event and self.raw_event.__class__.__name__.startswith('vim.event'):
self.event_type = self.raw_event.__class__.__name__[10:]
Expand All @@ -44,6 +47,7 @@ def __init__(self, raw_event, event_config, tags, event_resource_filters, exclud
self.event_config = event_config
self.exclude_filters = exclude_filters
self.event_resource_filters = event_resource_filters
self.hostname = hostname

def _is_filtered(self):
# Filter the unwanted types
Expand Down Expand Up @@ -145,7 +149,11 @@ def get_agg_key(alarm_event):
md5(alarm_event.alarm.name.encode('utf-8')).hexdigest()[:10],
)

host_name = None
# workaround to send empty hostname
if self.hostname is None:
host_name = VSphereEvent.EMPTY_HOSTNAME
else:
host_name = self.hostname
Comment on lines -148 to +156
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since EMPTY_HOSTNAME is a string, we could just use that as a default value. That'll simplify things here.

entity_name = self.raw_event.entity.name

# for backwards compatibility, vm host type is capitalized
Expand Down Expand Up @@ -178,8 +186,7 @@ def get_agg_key(alarm_event):
"vCenter monitor status changed on this alarm, "
"it was {before} and it's now {after}.".format(before=trans_before, after=trans_after)
)
if host_name is not None:
self.payload['host'] = host_name
self.payload['host'] = host_name

# VMs and hosts submit these as host tags
if self.host_type.lower() not in DEFAULT_EVENT_RESOURCES:
Expand Down
2 changes: 2 additions & 0 deletions vsphere/datadog_checks/vsphere/vsphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -784,12 +784,14 @@ def collect_events(self):
self.log.debug(
"Processing event with id:%s, type:%s: msg:%s", event.key, type(event), event.fullFormattedMessage
)
event_default_hostname = None if self._config.empty_default_hostname else self._hostname
normalized_event = VSphereEvent(
event,
event_config,
self._config.base_tags,
self._config.event_resource_filters,
self._config.exclude_filters,
event_default_hostname,
)
# Can return None if the event if filtered out
event_payload = normalized_event.get_datadog_payload()
Expand Down
39 changes: 39 additions & 0 deletions vsphere/tests/test_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -585,3 +585,42 @@ def test_vsan_event_include_events_filter_set(aggregator, realtime_instance, dd_

dd_run_check(check)
assert len(aggregator.events) == 1


@pytest.mark.parametrize(
'empty_default_hostname, event_hostname',
[
(True, "AGENT_INT_EMPTY_HOSTNAME"),
(False, "stubbed.hostname"),
],
)
@pytest.mark.usefixtures('mock_type', 'mock_threadpool', 'mock_rest_api')
def test_empty_hostname_for_events(
aggregator, realtime_instance, dd_run_check, mock_api, empty_default_hostname, event_hostname
):
realtime_instance['event_resource_filters'] = ['datacenter', 'cluster', 'datastore']
realtime_instance['empty_default_hostname'] = empty_default_hostname

check = VSphereCheck('vsphere', {}, [realtime_instance])
time1 = dt.datetime.now()
event4 = vim.event.AlarmStatusChangedEvent()
event4.createdTime = time1
event4.entity = vim.event.ManagedEntityEventArgument()
event4.entity.entity = vim.ClusterComputeResource(moId="c1")
event4.entity.name = "c1"
event4.alarm = vim.event.AlarmEventArgument()
event4.alarm.name = "alarm1"
setattr(event4, 'from', 'red')
event4.to = 'green'
event4.datacenter = vim.event.DatacenterEventArgument()
event4.datacenter.name = "dc1"
event4.fullFormattedMessage = "Red to Green"
mock_api.side_effect = mock_api_with_events([event4])
dd_run_check(check)
aggregator.assert_event(
"vCenter monitor status changed on this alarm, it was red and it's now green.",
tags=['vsphere_type:cluster', 'vsphere_resource:c1', 'vcenter_server:FAKE'],
count=1,
)
assert len(aggregator.events) == 1
assert aggregator.events[0]['host'] == event_hostname
Loading