Subscribe
Highlighted
Accepted Solution

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!!

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.

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.

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. 

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!

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. 

Re: Unified Manager 6.3 Alert scripts

[ Edited ]

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

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?

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.

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