plugins/Invoke-IcingaCheckClusterHealth.psm1
<# .SYNOPSIS Checks the state and availability of a Cluster Service .DESCRIPTION Invoke-IcingaCheckClusterHealth checks generally for the state of the Cluster, i.e. it checks if the Cluster service is running properly, the state of all Cluster Nodes and all Cluster Resources like "Task scheduler", "Clustername" etc. If the Cluster Main Server fails, the check is automatically CRITICAL, because then the cluster is no longer available and the cluster service is Stopped. .ROLE ### WMI Permissions * Root\MSCluster * Root\Cimv2 ### Cluster Permissions * Read-Only access on cluster ressource .PARAMETER Exclude Used to specify an array of nodes to exclude, allows '*' wildcard .PARAMETER Include Used to specify an array of nodes to include, allows '*' wildcard .PARAMETER WarningState Allows to specify for which node state the check will throw a warning .PARAMETER CriticalState Allows to specify for which node state the check will throw a critical .PARAMETER SkipClusterRessource Removes the Cluster Resources package from the check output if set to true .PARAMETER NoPerfData Disables the performance data output of this plugin .PARAMETER Verbosity Changes the behavior of the plugin output which check states are printed: 0 (default): Only service checks/packages with state not OK will be printed 1: Only services with not OK will be printed including OK checks of affected check packages including Package config 2: Everything will be printed regardless of the check state 3: Identical to Verbose 2, but prints in addition the check package configuration e.g (All must be [OK]) .EXAMPLE PS> icinga { Invoke-IcingaCheckClusterHealth -Verbosity 2 } [OK] Check package "Cluster Services" (Match All) \_ [OK] ClusSvc Status: Running \_ [OK] Check package "Cluster Nodes" (Match All) \_ [OK] Check package "lcontreras-wind" (Match All) \_ [OK] #1 State: Up \_ [OK] #1 Status Information: Normal \_ [OK] Check package "yhabteab-window" (Match All) \_ [OK] #2 State: Up \_ [OK] #2 Status Information: Normal \_ [OK] Check package "Cluster Resources" (Match All) \_ [OK] Cluster-IP-Adresse Status: Online \_ [OK] Clustername Status: Online \_ [OK] Task Scheduler Status: Online | 'clussvc_status'=4;;4 'clusteripadresse_status'=2;3;4 'clustername_status'=2;3;4 'task_scheduler_status'=2;3;4 '2_status_information'=0;;2 '2_state'=0;-1;2 '1_state'=0;-1;2 '1_status_information'=0;;2 0 .LINK https://github.com/Icinga/icinga-powershell-cluster #> function Invoke-IcingaCheckClusterHealth() { param ( [array]$Include = @(), [array]$Exclude = @(), [ValidateSet('Unknown', 'Up', 'Down', 'Paused', 'Joining')] [array]$WarningState = @(), [ValidateSet('Unknown', 'Up', 'Down', 'Paused', 'Joining')] [array]$CriticalState = @(), [switch]$SkipClusterRessource = $FALSE, [switch]$NoPerfData = $FALSE, [ValidateSet(0, 1, 2, 3)] $Verbosity = 0 ); # Create a main CheckPackage under which all other checks will be placed $CheckPackage = New-IcingaCheckPackage -Name 'Cluster Services' -OperatorAnd -Verbose $Verbosity -AddSummaryHeader; $ClusterServiceInfo = Get-IcingaClusterInfo; # Test Whether or not the cluster Service is Running, otherwise we can't get any infos about the cluster if ($ClusterServiceInfo.ContainsKey('Exception') -eq $FALSE) { # Create CheckPackages and get cluster infos from the provider $ResourceCheckPackage = New-IcingaCheckPackage -Name 'Cluster Resources' -OperatorAnd -Verbose $Verbosity; $ClusterNodesCheckPackage = New-IcingaCheckPackage -Name 'Cluster Nodes' -OperatorAnd -Verbose $Verbosity; $GetClusServices = Get-IcingaServices -Service 'ClusSvc'; # Check for the cluster Service status $CheckPackage.AddCheck( ( New-IcingaCheck ` -Name 'Cluster Service Status' ` -Value $GetClusServices.Values.configuration.Status.raw ` -Translation $ProviderEnums.ServiceStatusName ).CritIfNotMatch( $ProviderEnums.ServiceStatus.Running ) ); # We go through all keys, which have fetched us from the provider foreach ($service in $ClusterServiceInfo.Keys) { $ClusterResource = $ClusterServiceInfo[$service]; # Check whether or not the Key "Node" is available at the provider information if ($service -eq 'Nodes') { # Iterate through all Cluster nodes and get their states foreach ($node in $ClusterServiceInfo.Nodes.Keys) { $ProcessNode = $TRUE; foreach ($entry in $Include) { $ProcessNode = $FALSE; if ($node.ToLower() -Like $entry.ToLower()) { $ProcessNode = $TRUE; break; } } foreach ($entry in $Exclude) { if ($node.ToLower() -Like $entry.ToLower()) { $ProcessNode = $FALSE; break; } } if ($ProcessNode -eq $FALSE) { continue; } $ClusterNode = $ClusterServiceInfo.Nodes[$node]; $NodeCheckPackage = New-IcingaCheckPackage -Name $node -OperatorAnd -Verbose $Verbosity; $NodeCheckPackage.AddCheck( ( New-IcingaCheck ` -Name ([string]::Format('#{0} Status Information', $ClusterNode.Id)) ` -Value $ClusterNode.StatusInformation ` -Translation $ClusterProviderEnums.ClusterNodeStatusInfo ).CritIfMatch( $ClusterProviderEnums.ClusterNodeStatusInfoName.Quarantined ) ); $ClusterStateCheck = New-IcingaCheck ` -Name ([string]::Format('#{0} State', $ClusterNode.Id)) ` -Value $ClusterNode.State ` -Translation $ClusterProviderEnums.ClusterNodeState; foreach ($entry in $WarningState) { $WarningClusterState = $ClusterProviderEnums.ClusterNodeStateName[$entry]; if ($ClusterNode.State -eq $WarningClusterState) { $ClusterStateCheck.SetWarning( [string]::Format( 'Value {0} is matching values {1}', ($ClusterProviderEnums.ClusterNodeState[$ClusterNode.State]), [string]::Join(', ', $WarningState), $TRUE ) ) | Out-Null; break; } } foreach ($entry in $CriticalState) { $CriticalClusterState = $ClusterProviderEnums.ClusterNodeStateName[$entry]; if ($ClusterNode.State -eq $CriticalClusterState) { $ClusterStateCheck.SetCritical( [string]::Format( 'Value {0} is matching values {1}', ($ClusterProviderEnums.ClusterNodeState[$ClusterNode.State]), [string]::Join(', ', $CriticalState), $TRUE ) ) | Out-Null; break; } } $NodeCheckPackage.AddCheck($ClusterStateCheck); $ClusterNodesCheckPackage.AddCheck($NodeCheckPackage); } continue; } if ($SkipClusterRessource) { continue; } # CheckPackage for the Cluster Resources e.g. (Cluster-IP-Adresse Status: ) $ResourceCheckPackage.AddCheck( ( New-IcingaCheck ` -Name ([string]::Format('{0} Status', $service)) ` -Value $ClusterResource.State ` -Translation $ClusterProviderEnums.ClusterServiceStateName ).WarnIfMatch( $ClusterProviderEnums.ClusterServiceState.Offline ).CritIfMatch( $ClusterProviderEnums.ClusterServiceState.Failed ) ); } # Check whether we added a Cluster Resource Checks # if not we don't have to add the empty check to the main CheckPackage if ($ResourceCheckPackage.HasChecks()) { $CheckPackage.AddCheck($ResourceCheckPackage); } # Check whether we added a Cluster Node Checks if ($ClusterNodesCheckPackage.HasChecks()) { $CheckPackage.AddCheck($ClusterNodesCheckPackage); } } else { $IcingaCheck = 'Cluster Health: '; if ($ClusterProviderEnums.ClusterExceptionIds.ContainsKey($ClusterServiceInfo.Exception)) { $IcingaCheck = ([string]::Format('Exception: {0}', $ClusterProviderEnums.ClusterExceptionMessages[$ClusterServiceInfo.Exception])); } else { $IcingaCheck += $TestIcingaWindowsInfoEnums.TestIcingaWindowsInfoText[[int]$ClusterServiceInfo.Exception]; } # Enforce the checks to critical in case the cluster service should be stopped $CheckPackage.AddCheck( ( New-IcingaCheck ` -Name $IcingaCheck ` -NoPerfData ).SetCritical() ); } return (New-IcingaCheckResult -Check $CheckPackage -NoPerfData $NoPerfData -Compile); } |