CG Discovery

NetAppSANtricity.NetAppSANtricity.CGDiscovery (Discovery)

Description for the new discovery.

Element properties:

TargetNetAppSANtricity.StorageArray
EnabledTrue
Frequency3600
RemotableFalse

Object Discovery Details:

Discovered Classes and their attribuets:

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.Windows.TimedPowerShell.DiscoveryProvider Default

Source Code:

<Discovery ID="NetAppSANtricity.NetAppSANtricity.CGDiscovery" Target="NetAppSANtricity.StorageArray" Enabled="true" ConfirmDelivery="false" Remotable="true" Priority="Normal">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="NetAppSANtricity.CGsGroup"/>
<DiscoveryClass TypeID="NetAppSANtricity.ConsistencyGroup"/>
<DiscoveryClass TypeID="NetAppSANtricity.ConsistencyGroupVolume"/>
</DiscoveryTypes>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedPowerShell.DiscoveryProvider">
<IntervalSeconds>3600</IntervalSeconds>
<SyncTime>06:35</SyncTime>
<ScriptName>CGDiscovery.ps1</ScriptName>
<ScriptBody><Script>##############################################################################
# Copyright (c) 2015 NetApp Inc.
# All rights reserved.
#
# CGDiscovery.ps1
# Script to run deep discovery of managed arrays.
#

param ($sourceId, $managedEntityId, [Boolean]$Trace)

##############################################################################
# Script utilities
#
function GetTrueFalseString($value)
{

if ($value -eq "true")
{
$result = "True"
}
else
{
$result = "False"
}
return $result
}

function GetPercentageString($value)
{
return ("" + $value + "%")
}

function GetFormattedSize($value)
{
$size = $value / 1KB
if ($size -lt 1)
{
$result = "" + $value + " Bytes"
}
elseif ($size -lt 1024)
{
$size = $size.ToString(".00")
$result = "" + $size + " KB"
}
else
{
$size = $value / 1MB
if ($size -lt 1024)
{
$size = $size.ToString(".00")
$result = "" + $size + " MB"
}
else
{
$size = $value / 1GB
if ($size -lt 1024)
{
$size = $size.ToString(".00")
$result = "" + $size + " GB"
}
else
{
$size = $value / 1TB
$size = $size.ToString(".00")
$result = "" + $size + " TB"
}
}
}
return $result
}

function Get-WebServerPort([string] $dir)
{

[xml]$wsConfig = Get-Content "$dir/webserver/wsconfig.xml" -ErrorAction SilentlyContinue
$val = $wsConfig.config.port
$val
}

##############################################################################

# Setup variables for deserialization if output is too big
#
Add-Type -AssemblyName System.Web.Extensions
$javaScriptSerializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer
$javaScriptSerializer.MaxJsonLength = [System.Int32]::MaxValue
$javaScriptSerializer.RecursionLimit = 99

##############################################################################
&lt;#
Target here will be StorageArray
#&gt;

# Script variables
$private:scriptName = "CGDiscovery.ps1"
$private:E_LVL_INFO = 0
$private:E_LVL_ERROR = 1
$private:E_LVL_WARNING = 2
$private:E_NBR_TRACE = 3902
$private:intPackDir = (Get-ItemProperty HKLM:\Software\NetApp\MP IntegrationPackRoot).IntegrationPackRoot

# Script varaibles for SCOM
$private:api = New-Object -ComObject 'MOM.ScriptAPI'
$discoveryData = $api.CreateDiscoveryData(0, $sourceId, $managedEntityId)

$arrayWWN = '$Target/Property[Type="NetAppSANtricity.StorageArray"]/wwn$'
$arrayName = '$Target/Property[Type="NetAppSANtricity.StorageArray"]/friendlyName$'
$arraySystem = '$Target/Property[Type="NetAppSANtricity.StorageArray"]/MonitoringSystem$'

# Common parameters used for the web service calls
$securePwd = ConvertTo-SecureString "rw" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential("rw", $securePwd)

$wsPort = Get-WebServerPort $intPackDir
if ($wsPort -eq $null)
{
$api.LogScriptEvent($ScriptName, $E_NBR_TRACE, $E_LVL_ERROR, "Error parsing wsConfig.xml in" + $intPackDir)
$wsPort = "8080" # try 8080 if we can't find anything else...
}
$baseUrl = "http://localhost:$wsPort/devmgr/v2/storage-systems/"

try
{
# Get the consistency groups for this array
$url = ""
$url = $baseUrl + $arrayWWN + "/consistency-groups/"
$allCgs = Invoke-RestMethod $url -Credential $cred

if ($allCgs.GetType().FullName -eq "System.String")
{
$allCgs = $javaScriptSerializer.DeserializeObject($allCgs)
}

$healthSvc = $discoveryData.CreateClassInstance( "$MPElement[Name='SC!Microsoft.SystemCenter.HealthService']$" )
$healthSvc.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $arraySystem )
$discoveryData.AddInstance($healthSvc)

if ($allCgs)
{
# Create Consistency Group group object to act as container for CGs
$cgGroupInstance = $discoveryData.CreateClassInstance("$MPElement[Name='NetAppSANtricity.CGsGroup']$")

# Adding properties of the CG group class
$cgGroupInstance.AddProperty("$MPElement[Name='NetAppSANtricity.CGsGroup']/arrayWwn$", $arrayWWN)
$cgGroupInstance.AddProperty("$MPElement[Name='NetAppSANtricity.CGsGroup']/arrayName$", $arrayName)
$cgGroupInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "Consistency Groups")

#Adding key properties of parent Storage Array
$cgGroupInstance.AddProperty("$MPElement[Name='NetAppSANtricity.StorageArray']/wwn$", $arrayWWN)
$cgGroupInstance.AddProperty("$MPElement[Name='NetAppSANtricity.StorageArray']/MonitoringSystem$", $arraySystem)

$discoveryData.AddInstance($cgGroupInstance)

foreach ($cg in $allCgs)
{
# Create consistency group object
$cgInstance = $discoveryData.CreateClassInstance("$MPElement[Name='NetAppSANtricity.ConsistencyGroup']$")
$cgInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $cg.label)
$cgInstance.AddProperty("$MPElement[Name='NetAppSANtricity.ConsistencyGroup']/cgRef$", $cg.cgRef)
$cgInstance.AddProperty("$MPElement[Name='NetAppSANtricity.ConsistencyGroup']/fullWarnThreshold$", (GetPercentageString $cg.fullWarnThreshold))
$cgInstance.AddProperty("$MPElement[Name='NetAppSANtricity.ConsistencyGroup']/storageArrayName$", $arrayName)

# Add consistency group to discovery data
$discoveryData.AddInstance($cgInstance)

# Create relationship between consistency group and CGGroup
$relationshipInstance = $discoveryData.CreateRelationshipInstance("$MPElement[Name='NetAppSANtricity.ConsistencyGroupRelationship']$")
$relationshipInstance.Source = $cgGroupInstance
$relationshipInstance.Target = $cgInstance
$discoveryData.AddInstance($relationshipInstance)

#Create health service associated with consistency group
$hsvcManagesSSubsystemRel = $discoveryData.CreateRelationshipInstance("$MPElement[Name='SC!Microsoft.SystemCenter.HealthServiceShouldManageEntity']$")
$hsvcManagesSSubsystemRel.Source = $healthSvc
$hsvcManagesSSubsystemRel.Target = $cgInstance
$discoveryData.AddInstance($hsvcManagesSSubsystemRel)

# Get the consistency group volumes that are associated with this consistency group
$url = ""
$url = $baseUrl + $arrayWWN + "/consistency-groups/" + $cg.cgRef + "/member-volumes/"
$cgVolumes = Invoke-RestMethod $url -Credential $cred
foreach ($cgv in $cgVolumes)
{
# Create consistency group volume
$cgvInstance = $discoveryData.CreateClassInstance("$MPElement[Name='NetAppSANtricity.ConsistencyGroupVolume']$")
$cgvInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $cgv.baseVolumeName)
$cgvInstance.AddProperty("$MPElement[Name='NetAppSANtricity.ConsistencyGroupVolume']/volumeWwn$", $cgv.volumeWwn)
$cgvInstance.AddProperty("$MPElement[Name='NetAppSANtricity.ConsistencyGroupVolume']/totalRepositoryVolumes$", $cgv.totalRepositoryVolumes)
$cgvInstance.AddProperty("$MPElement[Name='NetAppSANtricity.ConsistencyGroupVolume']/totalRepositoryCapacity$", (GetFormattedSize $cgv.totalRepositoryCapacity))
$cgvInstance.AddProperty("$MPElement[Name='NetAppSANtricity.ConsistencyGroupVolume']/usedRepositoryCapacity$", (GetFormattedSize $cgv.usedRepositoryCapacity))
$cgvInstance.AddProperty("$MPElement[Name='NetAppSANtricity.ConsistencyGroupVolume']/totalSnapshotImages$", $cgv.totalSnapshotImages)
$cgvInstance.AddProperty("$MPElement[Name='NetAppSANtricity.ConsistencyGroupVolume']/autoDeleteSnapshots$", (GetTrueFalseString $cgv.autoDeleteSnapshots))
$cgvInstance.AddProperty("$MPElement[Name='NetAppSANtricity.ConsistencyGroupVolume']/autoDeleteLimit$", $cgv.autoDeleteLimit)
$cgvInstance.AddProperty("$MPElement[Name='NetAppSANtricity.ConsistencyGroupVolume']/storageArrayName$", $arrayName)

# Adding properties that associate this ConsistencyGroupVolume with its parent ConsistencyGroup
$cgvInstance.AddProperty("$MPElement[Name='NetAppSANtricity.ConsistencyGroup']/cgRef$", $cg.cgRef)

$discoveryData.AddInstance($cgvInstance)

#Create health service associated to CGV
$hsvcManagesSSubsystemRel = $discoveryData.CreateRelationshipInstance("$MPElement[Name='SC!Microsoft.SystemCenter.HealthServiceShouldManageEntity']$")
$hsvcManagesSSubsystemRel.Source = $healthSvc
$hsvcManagesSSubsystemRel.Target = $cgvInstance
$discoveryData.AddInstance($hsvcManagesSSubsystemRel)
} # foreach ($cgv in $cgVolumes)

} # foreach ($cg in $cgs)
} # if ($cgs)

}
catch
{
# If the array is offline/unreachable then trying to get the CGs causes an error.
}

if ( $Trace )
{
$logString = "CGs and CGVs Discovery for array: " + $arrayName + " Completed. CGs processed: " + $cgs.Count
$api.LogScriptEvent($ScriptName, $E_NBR_TRACE, $E_LVL_INFO, $logString)
}

#Send Discovery.Data to the output pipeline.
$discoveryData
</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>sourceId</Name>
<Value>$MPElement$</Value>
</Parameter>
<Parameter>
<Name>managedEntityId</Name>
<Value>$Target/Id$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>420</TimeoutSeconds>
</DataSource>
</Discovery>