Saturday, 15 October 2016

Faking vCenter alarms

Larger environments tend to integrate their monitoring and ticketing systems. Some also add automated workflows based on alarms. The problem when setting up these workflows is how do you test the workflow is triggered based on specific alarms?

With thanks to William Lam for the tips, it's possible to trigger specific events that make up alarms. It's not a simple task (for someone who's not a developer), but you can do some trial and error to work out how to trigger each event.

You need to find the event you want to trigger from the API at http://pubs.vmware.com/vsphere-60/index.jsp#com.vmware.wssdk.apiref.doc/index-do_types.html. Pretty much anything ending in 'Event'.

A list of events can be viewed with PowerCLI by connecting to vCenter:
$evt = get-view eventManager
$evt.Description.eventinfo

Lets choose HostConnectionLostEvent. The description says "This event records the loss of a host connection".

The PowerCLI script below will trigger the HostConnectionLostEvent event, and in turn triggers an alarm.


# Usual load modules and connections
import-module VMware.VimAutomation.Core
connect-viserver 192.168.10.99
$server = $global:DefaultVIServer
$entity = Get-View (Get-VMHost -Name 192.168.10.240)
$eventMgr = Get-View $server.ExtensionData.Content.EventManager
# Subsitute your event to trigger
$event = New-Object VMware.Vim.HostConnectionLostEvent
# This property is specific to this event, and is required. This domain and user doesn't have to be an existing account.
$event.UserName = "CAGE.LOCAL\Chaos Monkey"
$hostEventArg = New-Object VMware.Vim.HostEventArgument
$hostEventArg.Host = $entity.MoRef
$hostEventArg.Name = "Host-is-a-label"
$event.Host = $HostEventArg
# Sends the event to vCenter
$eventMgr.PostEvent($event,$null)



When trying different events, the main line is:

$event = New-Object VMware.Vim.HostConnectionLostEvent

If you view $event now, you'll see it's properties:
Key                  : 0
ChainId              : 0
CreatedTime          : 1/01/0001 12:00:00 AM
UserName             : 
Datacenter           : 
ComputeResource      : 
Host                 : 
Vm                   : 
Ds                   : 
Net                  : 
Dvs                  : 
FullFormattedMessage : 
ChangeTag            : 

You'll see other events have different properties. Some of these properties are required. It's a bit hit and miss.

Lets try using UplinkPortVlanUntrunkedEvent.

Substitute this line - $event = New-Object VMware.Vim.UplinkPortVlanUntrunkedEvent

Initially you'll get an error:
Exception calling "PostEvent" with "2" argument(s): "
Required property switchUuid is missing from data object of type UplinkPortVlanUntrunkedEvent
while parsing serialized DataObject of type vim.event.UplinkPortVlanUntrunkedEvent

So we are missing a required input of switchUuid. View the properties of $event:

SwitchUuid           : 
HealthResult         : 
Key                  : 0
ChainId              : 0
CreatedTime          : 1/01/0001 12:00:00 AM
UserName             : CAGE.LOCAL\Chaos Monkey
Datacenter           : 
ComputeResource      : 
Host                 : VMware.Vim.HostEventArgument
Vm                   : 
Ds                   : 
Net                  : 
Dvs                  : 
FullFormattedMessage : 
ChangeTag            : 

So add in a value for SwitchUuid:

$event.SwitchUuid = "Fake UUID"

and execute the remaining lines, and it triggers the alarm.


From there it was trial and error to to see which properties were mandatory for each event.

This was a quick hack to demonstrate the ability to trigger alarms for a customer. 

It also has other use cases:
Feeling lonely and on-call? Trigger an alarm and hopefully you'll receive a call.
Convince a co-worker they are causing errors by using their username.

Have fun.