Data Infrastructure Management Software Discussions

Highlighted

Unified Manager 6.3 Alert scripts

Has anyone had any luck in passing environment variables from OCUM 6.3 to a script? Long story short, I am working with BPPM Msend.exe to create incident tickets when we have alerts. In DFM 5.2 I was able to pass the DFM_EVENT_SEVERITY, DFM_SOURCE_TYPE, and so forth to the script. This allowed me to set the priority of incident tickets and also customize the alert messages. In 6.3, I found a very short piece of information, but it has very limited items passed and does not state if they are always passed with the same ARGV[x] number. 

 

 

This is what I have found so far. 

 

Arguments

-eventID

-eventSourceID

-eventSourceName

-eventSourceType

-eventState-eventArgs

 

Example for obtaining arguments from scripts

print "$ARGV[0] : $ARGV[1]\n"

print "$ARGV[2] : $ARGV[3]\n"

 

When an alert is generated, this script is executed and the following output is displayed:

 

-eventID : 290 

-eventSourceID : 4138

 

Unfortunately, this is not telling me (or anyone else) much of anything. I have communications in with the OCUM developers, but not sure how long that will take. As of right now, we have 8.3.1 Systems that are not being alerted on when we have issues. 

 

My current 5.2 script is in powershell, and although I do not like powershell, I would like to keep the 6.3 script in the same.

 

Any help or sample scripts would be greatly appreciated!!

13 REPLIES 13

Re: Unified Manager 6.3 Alert scripts

Hi,

 

Check the "event-iter" API in the NMSDK 5.4 for ocum. You need to load the "ManageOntap.dll" and create a connection to the OCUM server. Here is a code snippet to list the events:

 

#'------------------------------------------------------------------------------
Try{
   $naElement   = New-Object NetApp.Manage.naElement("event-iter")
   [Xml]$output = $naServer.InvokeElem($naElement)
}Catch{
   Write-Warning -Message $("Failed enumerating OnCommand Unified Manager Events on ""$HostName"". Error " + $_.Exception.Message)
   Exit
}

Write-Host $("There are " + $output.results.'num-records' + " events")
$events = $output.results.'records'.'event-info'
ForEach($event In $events){
   $event.'event-info'.'event-id'
}
#'------------------------------------------------------------------------------

Here is an example of the properties values that can be enumerated about each event.

 

event-about               : Aggregate Renamed
event-arguments           : event-arguments
event-category            : Others
event-condition           : Aggregate aggr0 is renamed to testc1n1_aggr0.
event-id                  : 20
event-impact-area         : configuration
event-impact-level        : event
event-name                : Aggregate Renamed
event-severity            : information
event-source-name         : testc1n1:testc1n1_aggr0
event-source-resource-key : 4da6250c-8d16-11e5-94f9-005056ac2b80:type=aggregate,uuid=809a94ec-3747-48a8-9b54-12a8c741b482
event-source-type         : aggregate
event-state               : NEW
event-time                : 1447758913
event-type                : aggregate.renamed

Given you know the event ID it's possible to enumerate all property values for that event. Is this the type of detail you are looking for? Let me know i can send you my code.

 

/matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Highlighted

Re: Unified Manager 6.3 Alert scripts

Hi,

 

I've a had a closer look and totally agree with you that this is very poorly implemented and documented in OCUM 6.X compared with environment variable flexibilty and simplicity available in DFM 5.X. EG:

 

https://kb.netapp.com/support/index?page=content&id=3012180

 

Note: I tried using environment variables in this method for OCUM6.X but it's not implemented (Adding to my list for engineering developement requests).

 

From a powershell perspective the "-eventID" parameter value is $args[1]. EG the parameter name "eventID" = $args[0] and the parameter value is $args[1] (eventID = X)

So with this in mind i had a look at what you might be able to do if you get the script which is attached to your alarm to invoke a MySQL using the EventID as basis. Something like...

 

 

SELECT
   event.id AS 'event_id',
   event.eventTimeStamp AS 'event_time_stamp',
   event.impactArea AS 'event_impact',
   event.source_type,
   event.source_fullName AS 'source_full_name',
   eventtypevalue.internalName AS 'internal_name',
   vserverlivelistdtoview.clusterName AS 'cluster_name',
   vserverlivelistdtoview.name AS 'vserver_name'
FROM
   ocum.event,
   ocum.eventtypevalue,
   ocum.vserverlivelistdtoview
WHERE
   event.id = 20006
AND
   vserverlivelistdtoview.clusterId = event.cluster_id
AND
   vserverlivelistdtoview.id = event.vserver_id
AND
   eventtypevalue.id = event.value_id

(where event.id = 20006 in the powershell code would be "event.id = $eventID" or "event.id = $args[1]")

 

With a some modification this will probably return the type of detail are looking for. The above SQL query was for a test i put together for an alert setting a volume state to offline. EG:

 

event_id,event_time_stamp,event_impact,source_type,source_full_name,internal_name,cluster_name,vserver_name
20006,2016-03-03 17:03:29,AVAILABILITY,inventory.ontap.storage.FlexVol,vserver1/volume_001,offline,cluster1,vserver1

Hope that gives you some ideas. When i get some time i'll post a more comprehsive example in powershell.

 

/matt

 

 

 

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

View solution in original post

Highlighted

Re: Unified Manager 6.3 Alert scripts

Matt, 

 

Thanks for the info and details example. This will definately help me out some. Although it may take a bit more time to re-write the script, I think it is a viable solution at least for the time being. 

Highlighted

Re: Unified Manager 6.3 Alert scripts

Hi,

 

This information is great, however they seem to have changed the MYSQL table layout in OCUM 6.4. Have you had time to look at OCUM 6.4? have any updated MYSQL queries which would do the same as above for example?

 

Thanks!

Highlighted

Re: Unified Manager 6.3 Alert scripts

I am currently looking for the same information. I need to update our scripts as well, but have not had time to find out what the new layout is. 

Highlighted

Re: Unified Manager 6.3 Alert scripts

it looks like it is $args that is the variable that is passed out

Highlighted

Re: Unified Manager 6.3 Alert scripts

What I am actually trying to do is replicate the pre canned email alert from OCUM but from PowerShell/MYSQL:

 

Risk          - Cluster Lacks Spare Disks

Impact Area   - Availability

Severity      - Warning

State         - New

Source        - xxxxxx

Trigger Condition - The cluster lacks spare disks on nodes -xxxxxxx.

 

PowerShell can then send it via REST to our incident tracking system. 

 

Any ideas?

Highlighted

Re: Unified Manager 6.3 Alert scripts

Hi,

 

Yes it is possible to enumerate the event information (by ID) in OCUM using the SDK. The database schema between OCUM6.3\6.4 has changed so you would need to modify the query. I'd recommend invoking a ZAPI call rather than a SQL query to enumerate the event information as the schema might change in future. To do this you will need to download the SDK as the "ManageOntap.dll" file is required. This file is located in the "netapp-manageability-sdk-5.6\lib\DotNet" folder when you extract the download.

 

Note that if you are using WFA you can also copy the file from the "\PoSH\Modules\WFAWrapper" folder in your WFA installation directory (default "C:\Program Files\NetApp\WFA\PoSH\Modules\WFAWrapper"). Although I'd recommend using the latest "ManageOntap.dll" file from the NMSDK though to ensure the ZAPI's work with OCUM6.4\7.0. You can download the NMSDK here:

 

http://mysupport.netapp.com/NOW/download/software/nmsdk/5.6/

 

Here is some "example" source code that enumerates OCUM event information by Event ID. If you are attaching a script to an alarm then the Event ID is $args[1].

 

Example Event (OCUM GUI)

 

ocum_event.png

 

Example Output:

 

PS C:\Scripts\PowerShell\Projects\OCUM> .\ocum.ps1 -EventId 7
Loaded file "C:\Scripts\PowerShell\Projects\OCUM\ManageOntap.dll"
Invoking API "dfm-about" to check connectivity to "TESTOC64" using the "HTTPS" protocol
Event About: Availability of spare disks for aggregates in a cluster
Event Category: Cluster with Low Spare Disks
Event Condition: The cluster lacks spare disks on nodes - testc2n1.
Event Impact Area: availability
Event Impact Area: risk
Event Name: Cluster Lacks Spare Disks
Event Type: cluster.spares
Event Source Type: cluster
Event Source Name: cluster2
Event Source Resource Key: b3e53f0a-dc85-11e6-acfc-005056ac4ac8:type=cluster,uuid=b3e53f0a-dc85-11e6-acfc-005056ac4ac8
Event State: NEW
Event Time: 01/18/2017 11:09:28

Note: You need to save the "ManageOntap.dll" file in the same folder as the script. EG:

 

C:\Scripts\PowerShell\Projects\OCUM>dir /b
ManageOntap.dll
ocum.ps1

It the code below you will be securely prompted for credentials for the admin OCUM user. If you want to automate the process you will need to cache\encrypt administrative credentials on your OCUM server (IE to a file or registry key)

 

Source Code:

 

Param(
   [Parameter(Mandatory = $True, HelpMessage = "The OCUM Event ID to enumerate")]
   [Int]$EventId
)
#'------------------------------------------------------------------------------
Function ConvertFrom-UnixTimestamp{
   [CmdletBinding()]
   Param(
      [Parameter(Position=0,
         Mandatory=$True,
         ValueFromPipeLine=$True,
         ValueFromPipeLineByPropertyName=$True)]
      [String]$Timestamp
   )
   [TimeZone]::CurrentTimeZone.ToLocalTime(([DateTime]'1/1/1970').AddSeconds($Timestamp))
}#End Function
#'------------------------------------------------------------------------------
Function New-ZapiServer{
   <#
   .SYNOPSIS
   Cmdlet to create a new ZAPI server object.
   .DESCRIPTION
   The cmdlet creates a ZAPI object from which Data ONTAP or Unified Manager ZAPIs can be called.
   .PARAMETER Host
   The server hostname or IP address
   .PARAMETER Port
   The port number to connet to. For HTTPS, use 443
   .PARAMETER Type
   The connecting server type. Valid values are FILER for Data ONTAP and
   DFM for a Unified Manager server.
   .PARAMETER VFiler
   The vFiler unit name in the Filer. Used with the type "FILER" for running ZAPIs on the
   specified vFiler unit.
   .EXAMPLE
   New-ZapiServer -Host $DFMServerName -Type DFM -Credentials $credentials
   #>
   Param(
      [Parameter(Mandatory = $True)]
      [String]$HostName,
      [Parameter(Mandatory = $False)]
      [Int]$PortNumber,
      [Parameter(Mandatory = $True)]
      [ValidateSet("FILER", "DFM")]
      [String]$ZapiType,
      [Parameter(Mandatory = $True)]
      [System.Management.Automation.PSCredential]$Credentials,
      [Parameter(Mandatory = $False)]
      [String]$VFiler
   )
   #'---------------------------------------------------------------------------
   #'Create the NaServer server object based on the ZAPI type.
   #'---------------------------------------------------------------------------
   If($ZapiType -eq "DFM"){
      [NetApp.Manage.NaServer]$zapiServer = New-Object NetApp.Manage.NaServer($HostName, "1", "0")
   }Else{
      [NetApp.Manage.NaServer]$zapiServer = New-Object NetApp.Manage.NaServer($HostName, "1", "14")
      If($VFiler -And $VFiler.Length -gt 0){
         $zapiServer.SetVfilerTunneling($VFiler)
      }
   }
   #'---------------------------------------------------------------------------
   #'Enumerate the username and password from the credential object.
   #'---------------------------------------------------------------------------
   [String]$domain    = $credentials.GetNetworkCredential().domain
   [String]$user      = $credentials.GetNetworkCredential().username
   [String]$password  = $credentials.GetNetworkCredential().password
   If($domain -ne "" -Or $domain -ne $Null){
      If($domain.Contains(".")){
         [String]$userName = "$user`@$domain"
      }Else{
         If($credentials.UserName.Contains("\") -And $credentials.UserName.SubString(0, 1) -ne "\"){
            [String]$userName = $credentials.UserName
         }Else{
            [String]$userName = $user
         }
      }
   }
   #'---------------------------------------------------------------------------
   #'Set the username and password for the NaServer object.
   #'---------------------------------------------------------------------------
   $zapiServer.SetAdminUser($userName, $password)
   $zapiServer.ServerType = $ZapiType
   If($PortNumber){
      $zapiServer.port = $PortNumber
   }
   #'---------------------------------------------------------------------------
   #'Check connectivity using HTTPS
   #'---------------------------------------------------------------------------
   $zapiServer.TransportType = 'HTTPS'
   $result = Check-ZapiConnection -ZapiServer $zapiServer -ZapiType $ZapiType -HostName $HostName -ProtocolName "HTTPS"
   If($result -eq -1){
      Write-Host "Failed connecting to ""$HostName"" using the ""HTTPS"" protocol"
      #'------------------------------------------------------------------------
      #'Check connectivity using HTTP
      #'------------------------------------------------------------------------      
      $zapiServer.TransportType = 'HTTP'
      $result = Check-ZapiConnection -ZapiServer $zapiServer -ZapiType $ZapiType -HostName $HostName -ProtocolName "HTTP"
      If($result -eq -1){
         Write-Warning -Message $("Failed connecting to ""$HostName"" using the ""HTTP"" protocol")
         Return -1;
      }
   }
   Return $zapiServer;
}#End Function
#'------------------------------------------------------------------------------
Function Check-ZapiConnection{
   Param(
      [Parameter(Mandatory = $True)]
      [NetApp.Manage.NaServer]$ZapiServer,
      [Parameter(Mandatory = $True)]
      [ValidateSet("FILER", "DFM")]
      [String]$ZapiType,
      [Parameter(Mandatory = $True)]
      [String]$HostName,
      [Parameter(Mandatory = $True)]
      [String]$ProtocolName         
   )
   #'---------------------------------------------------------------------------  
   #'invoke the API based on the ZAPI type.
   #'---------------------------------------------------------------------------   
   If($ZapiType -eq "DFM"){
      Try{
         [String]$apiName = "dfm-about"
         Write-Host "Invoking API ""$apiName"" to check connectivity to ""$HostName"" using the ""$ProtocolName"" protocol"
         $output = $ZapiServer.Invoke($apiName)
      }Catch{
         Return -1
      }
   }Else{
      Try{
         [String]$apiName = "system-get-version"
         Write-Host "Invoking API ""$apiName"" to check connectivity to ""$HostName"" using the ""$ProtocolName"" protocol"
         $output = $ZapiServer.Invoke($apiName)
      }Catch{
         Return -1
      }
   }
   Return 0;
}#End Function
#'------------------------------------------------------------------------------
#'Initialization Section. Define Global Variables.
#'------------------------------------------------------------------------------
[String]$scriptPath     = Split-Path($MyInvocation.MyCommand.Path)
[String]$scriptSpec     = $MyInvocation.MyCommand.Definition
[String]$scriptBaseName = (Get-Item $scriptSpec).BaseName
[String]$scriptName     = (Get-Item $scriptSpec).Name
[String]$fileSpec       = "$scriptPath\ManageOntap.dll"
[String]$zapiType       = "DFM"
[Int]$zapiPortNumber    = 443
[String]$hostname       = $env:computername
#'------------------------------------------------------------------------------
#'Load the "ManageONTAP.dll" file
#'------------------------------------------------------------------------------
Try{
   [Reflection.Assembly]::LoadFile($fileSpec) | Out-Null
   Write-Host "Loaded file ""$fileSpec"""
}Catch{
   Write-Warning -Message $("Failed loading file ""$fileSpec"". Error " + $_.Exception.Message)
   Break;;
}
#'------------------------------------------------------------------------------
#'Prompt for OCUM credentials.
#'------------------------------------------------------------------------------
[System.Management.Automation.PSCredential]$ocumCredentials = Get-Credential -Credential admin
#'------------------------------------------------------------------------------
#'Create a ZAPI connection to the DFM server.
#'------------------------------------------------------------------------------
$naServer = New-ZapiServer -HostName $hostName -PortNumber $zapiPortNumber -ZapiType $zapiType -Credentials $ocumCredentials
#'------------------------------------------------------------------------------
If($naServer -eq -1){
   Write-Warning -Message "Failed creating ZAPI connection to ""$HostName"""
   Break;
}
#'------------------------------------------------------------------------------
#'Invoke the ZAPI.
#'------------------------------------------------------------------------------
Try{
   $naElement = New-Object NetApp.Manage.naElement("event-iter")
   $naElement.AddNewChild("event-id", $eventID)
   $naElement.AddNewChild("max-records", "1");
   [Xml]$output = $naServer.InvokeElem($naElement)
}Catch{
   Write-Warning -Message $("Failed invoking ZAPI on ""$HostName"". Error " + $_.Exception.Message)
   Break;
}
#'------------------------------------------------------------------------------
#'Set variables from ZAPI results.
#'------------------------------------------------------------------------------
$events = $output.results.'records'.'event-info'
ForEach($event In $events){
   [String]$eventAbout             = $event.'event-about'
   [String]$eventCategory          = $event.'event-category'
   [String]$eventCondition         = $event.'event-condition'
   [String]$eventImpactArea        = $event.'event-impact-area'
   [String]$eventImpactLevel       = $event.'event-impact-level'
   [String]$eventName              = $event.'event-name'
   [String]$eventType              = $event.'event-type'
   [String]$eventSeverity          = $event.'event-severity'
   [String]$eventSourceType        = $event.'event-source-type'
   [String]$eventSourceName        = $event.'event-source-name'
   [String]$eventSourceResourceKey = $event.'event-source-resource-key'
   [String]$eventState             = $event.'event-state'
   [String]$eventTime              = ConvertFrom-UnixTimestamp -TimeStamp $($event.'event-time')
}
#'------------------------------------------------------------------------------
#'Display the event information.
#'------------------------------------------------------------------------------
Write-Host "Event About: $eventAbout"
Write-Host "Event Category: $eventCategory"
Write-Host "Event Condition: $eventCondition"
Write-Host "Event Impact Area: $eventImpactArea"
Write-Host "Event Impact Area: $eventImpactLevel"
Write-Host "Event Name: $eventName"
Write-Host "Event Type: $eventType"
Write-Host "Event Source Type: $eventSourceType"
Write-Host "Event Source Name: $eventSourceName"
Write-Host "Event Source Resource Key: $eventSourceResourceKey"
Write-Host "Event State: $eventState"
Write-Host "Event Time: $eventTime"
#'------------------------------------------------------------------------------

Hope that helps

 

/Matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Highlighted

Re: Unified Manager 6.3 Alert scripts

Hi

 

This script is excellent, but I cannot seem to find a way to integrate it into OCUM 7.1 as you have to upload the script within the 'Manage Scripts' and then select the script within the alarm.

 

Regards

Highlighted

Re: Unified Manager 6.3 Alert scripts

I have got the script to execute, but am having trouble passing the email address configured for the alert to the script. Currently I get the default OCUM script sent to me as well as the custom script which has my email address hardcoded into the script.

 

Any ideas?

Highlighted

Re: Unified Manager 6.3 Alert scripts

I have this mostly working for version 7.1 but have run into a snag. When I run the script outside of Unified Manager it picks up all the event information just fine and will pass it to msend and create a ticket in our remedy system. 

 

However when the script runs automatically based on a triggered event it doesn't look like the script is ever actually running as no ticket gets created. Any thoughts?

 

Is the event ID no longer $args[1]?

 

Thanks.

Highlighted

Re: Unified Manager 6.3 Alert scripts

Hi Taber,

 

The $args[1] variable is definately the EventID however there does appear to be a discrepancy in the documentation.

I'm not sure if it's an error in the documentation or the variable order has changed between OCUM 6.X and 7.X

 

https://library.netapp.com/ecm/ecm_download_file/ECMLP2553757 (Page 81-82).

In the documented example:

 

$args[3] = EventSourceID

 

(That is incorrect, in OCUM 7.1 the "EventSourceID" is $args[8]). If

 

If you are ever in any doubt as to what the argument parameter names and values are...

I recommend logging them in your OCUM alarm script using the following powershell code:

 

$fileSpec = "C:\Program Files\NetApp\ocum\scriptPlugin\output.log"
$("OCUM Event Argument 0`: " + $args[0])   | Out-File -FilePath $fileSpec -encoding ASCII -Append
$("OCUM Event Argument 1`: " + $args[1])   | Out-File -FilePath $fileSpec -encoding ASCII -Append
$("OCUM Event Argument 2`: " + $args[2])   | Out-File -FilePath $fileSpec -encoding ASCII -Append
$("OCUM Event Argument 3`: " + $args[3])   | Out-File -FilePath $fileSpec -encoding ASCII -Append
$("OCUM Event Argument 4`: " + $args[4])   | Out-File -FilePath $fileSpec -encoding ASCII -Append
$("OCUM Event Argument 5`: " + $args[5])   | Out-File -FilePath $fileSpec -encoding ASCII -Append
$("OCUM Event Argument 6`: " + $args[6])   | Out-File -FilePath $fileSpec -encoding ASCII -Append
$("OCUM Event Argument 7`: " + $args[7])   | Out-File -FilePath $fileSpec -encoding ASCII -Append
$("OCUM Event Argument 8`: " + $args[8])   | Out-File -FilePath $fileSpec -encoding ASCII -Append
$("OCUM Event Argument 9`: " + $args[9])   | Out-File -FilePath $fileSpec -encoding ASCII -Append
$("OCUM Event Argument 10`: " + $args[10]) | Out-File -FilePath $fileSpec -encoding ASCII -Append
$("OCUM Event Argument 11`: " + $args[11]) | Out-File -FilePath $fileSpec -encoding ASCII -Append

Example output:

OCUM Event Argument 0: -eventID
OCUM Event Argument 1: 54
OCUM Event Argument 2: -eventName
OCUM Event Argument 3: LUN
OCUM Event Argument 4: Offline
OCUM Event Argument 5: -eventSeverity
OCUM Event Argument 6: critical
OCUM Event Argument 7: -eventSourceID
OCUM Event Argument 8: 224
OCUM Event Argument 9: -eventSourceName
OCUM Event Argument 10: vserver4:/volume_002/lun_001
OCUM Event Argument 11: -eventSourceType
OCUM Event Argument 12: LUN

 

 

/Matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Highlighted

Re: Unified Manager 6.3 Alert scripts

Hi Uber,

 

You could try invoking a SQL query in your script to enumerate the email address matching the Script name. EG:

 

SELECT
   alert_emailaddressrecipients.emailAddress AS 'email_address'
FROM
   ocum.alert,
   ocum.alert_emailaddressrecipients,
   ocum.script
WHERE
   alert_emailaddressrecipients.alert_id = alert.id
AND
   alert.scriptId = script.id
AND
   script.name = '$scriptName'

You can dynamically determine what the script name that is running is within your OCUM script plugin directory using powershell scirpt. EG:

 

#'------------------------------------------------------------------------------
#'Initialization Section. Define Global Variables.
#'------------------------------------------------------------------------------
[String]$scriptPath     = Split-Path($MyInvocation.MyCommand.Path)
[String]$scriptSpec     = $MyInvocation.MyCommand.Definition
[String]$scriptBaseName = (Get-Item $scriptSpec).BaseName
[String]$scriptName     = (Get-Item $scriptSpec).Name
#'------------------------------------------------------------------------------
#'Display variables.
#'------------------------------------------------------------------------------
Write-Host "Script Path`: $scriptPath"
Write-Host "Script Spec`: $scriptSpec"
Write-Host "Script Base Name`: $scriptBaseName"
Write-Host "Script Name`: $scriptName"
#'------------------------------------------------------------------------------

 

Example output:

 

PS C:\Program Files\NetApp\ocum\scriptPlugin> .\test.ps1
Script Path: C:\Program Files\NetApp\ocum\scriptPlugin
Script Spec: C:\Program Files\NetApp\ocum\scriptPlugin\test.ps1
Script Base Name: test
Script Name: test.ps1

This way you wouldn't have to hard code email addresses in your script if you have already configured email address in OCUM.

 

/Matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Check out the KB!
Knowledge Base
All Community Forums