-
Notifications
You must be signed in to change notification settings - Fork 142
Discovery
Orion's Network Sonar Discovery feature can be scripted to discover and add nodes. Using the Discovery API involves a few phases:
- Constructing the discovery context
- Running the discovery
- Tracking the progress of the discovery job
- Examining the results of the discovery
These phases will be described here. Code samples will be in PowerShell, though like all Orion APIs this can also be done using HTTP calls from any language. When working in PowerShell, some objects will be expressed in XML. When using other languages accessing the REST API, JSON would be used instead.
A discovery context is a document that describes the scope of the discovery, various options for controlling what gets discovered and how, and the credentials used for the discovery. A discovery context consists of a set of plugin configuration items and a few top-level values. Plugin configuration items are created using verb calls that produce a string that you then embed in the complete discovery context.
To create the Core plugin configuration, call the Orion.Discovery.CreateCorePluginConfiguration
verb with one argument, a CorePluginConfigurationContext
. In PowerShell, that code looks like this:
$CorePluginConfigurationContext = ([xml]"
<CorePluginConfigurationContext xmlns='http://schemas.solarwinds.com/2012/Orion/Core' xmlns:i='http://www.w3.org/2001/XMLSchema-instance'>
<BulkList>
<IpAddress>
<Address>10.199.2.5</Address>
</IpAddress>
</BulkList>
<IpRanges>
<IpAddressRange>
<StartAddress>10.199.3.10</StartAddress>
<EndAddress>10.199.3.15</EndAddress>
</IpAddressRange>
</IpRanges>
<Subnets>
<AddressSubnet>
<SubnetIP>10.199.5.0</SubnetIP>
<SubnetMask>255.255.255.0</SubnetMask>
</AddressSubnet>
</Subnets>
<Credentials>
<SharedCredentialInfo>
<CredentialID>$credentialid</CredentialID>
<Order>1</Order>
</SharedCredentialInfo>
</Credentials>
<WmiRetriesCount>1</WmiRetriesCount>
<WmiRetryIntervalMiliseconds>1000</WmiRetryIntervalMiliseconds>
</CorePluginConfigurationContext>
").DocumentElement
$CorePluginConfiguration = Invoke-SwisVerb $swis Orion.Discovery CreateCorePluginConfiguration @($CorePluginConfigurationContext)
There are three ways to specify what IP addresses to discover: individual IP addresses (<BulkList>
), ranges of IP addresses (<IpRanges>
), and subnets (<Subnets>
). Each of these is optional, though you need to include at least one of them or there will be nothing to discover.
The <BulkList>
element can contain multiple <IpAddress>
elements, though each one of those can only have one <Address>
element.
The <IpRanges>
element can contain multiple <IpAddressRange>
elements. A range can span subnets.
The <Subnets>
element can contain multiple <AddressSubnet>
elements. The size of the subnet is specified using subnet mask syntax, not CIDR. So a /24 (class C) subnet would be 255.255.255.0, a /16 (class B) subnet would be 255.255.0.0, and so on. Scanning a /8 (class A) subnet is not recommended for performance reasons.
The <Credentials>
element can contain multiple <SharedCredentialInfo>
elements. Each one must have a <CredentialID>
value. The credential IDs are integers that can be found by querying the Orion.Credential
entity. Currently there is no API for adding, changing, or removing credentials - to be used in discovery they must first be entered in the UI manually. The <Order>
element in a <SharedCredentialInfo>
indicates the order that credentials will be tested against each discovered node, in ascending order. The <Order>
values do not need to be consecutive, but there must be no duplicates.
To control how network interfaces are discovered, create an interfaces plugin configuration item and include it in the discovery context. The interfaces plugin configuration item is created by the Orion.NPM.Interfaces.CreateInterfacesPluginConfiguration
verb. In PowerShell, that code looks like this:
$InterfacesPluginConfigurationContext = ([xml]"
<InterfacesDiscoveryPluginContext xmlns='http://schemas.solarwinds.com/2008/Interfaces'
xmlns:a='http://schemas.microsoft.com/2003/10/Serialization/Arrays'>
<AutoImportStatus>
<a:string>Up</a:string>
<a:string>Down</a:string>
<a:string>Shutdown</a:string>
</AutoImportStatus>
<AutoImportVirtualTypes>
<a:string>Virtual</a:string>
<a:string>Physical</a:string>
</AutoImportVirtualTypes>
<AutoImportVlanPortTypes>
<a:string>Trunk</a:string>
<a:string>Access</a:string>
<a:string>Unknown</a:string>
</AutoImportVlanPortTypes>
<UseDefaults>false</UseDefaults>
</InterfacesDiscoveryPluginContext>
").DocumentElement
$InterfacesPluginConfiguration = Invoke-SwisVerb $swis Orion.NPM.Interfaces CreateInterfacesPluginConfiguration @($InterfacesPluginConfigurationContext)
This sample includes all available values for the AutoImportStatus
, AutoImportVirtualTypes
, and AutoImportVlanPortTypes
. Just remove the ones that describe interfaces you don't want to monitor.
The UseDefaults
option, if set to true
, will override all the other interface filter options and just use the defaults. The default behavior is to import all "Up" (active) interfaces regardless of type.
Once the plugin configuration items have been created, the next step is to combine them, along with some other important discovery parameters, into the discovery context. The plugin configuration items are XML and you must embed them into the discovery context as strings. And when you are embedding XML into other XML as a string, that means the inner XML must be quoted (<
changed to <
, &
changed to &
, and so on). PowerShell makes this pretty straightforward.
$EngineID = 1
$DeleteProfileAfterDiscoveryCompletes = "true"
$StartDiscoveryContext = ([xml]"
<StartDiscoveryContext xmlns='http://schemas.solarwinds.com/2012/Orion/Core' xmlns:i='http://www.w3.org/2001/XMLSchema-instance'>
<Name>Script Discovery $([DateTime]::Now)</Name>
<EngineId>$EngineID</EngineId>
<JobTimeoutSeconds>3600</JobTimeoutSeconds>
<SearchTimeoutMiliseconds>2000</SearchTimeoutMiliseconds>
<SnmpTimeoutMiliseconds>2000</SnmpTimeoutMiliseconds>
<SnmpRetries>1</SnmpRetries>
<RepeatIntervalMiliseconds>1500</RepeatIntervalMiliseconds>
<SnmpPort>161</SnmpPort>
<HopCount>0</HopCount>
<PreferredSnmpVersion>SNMP2c</PreferredSnmpVersion>
<DisableIcmp>false</DisableIcmp>
<AllowDuplicateNodes>false</AllowDuplicateNodes>
<IsAutoImport>true</IsAutoImport>
<IsHidden>$DeleteProfileAfterDiscoveryCompletes</IsHidden>
<PluginConfigurations>
<PluginConfiguration>
<PluginConfigurationItem>$($CorePluginConfiguration.InnerXml)</PluginConfigurationItem>
<PluginConfigurationItem>$($InterfacesPluginConfiguration.InnerXml)</PluginConfigurationItem>
</PluginConfiguration>
</PluginConfigurations>
</StartDiscoveryContext>
").DocumentElement
Discovery jobs run on a single polling engine specified in this context. The Name is just for display purposes.
If you set IsAutoImport
to false
, then the discovered nodes will not be added automatically. In that case, you can see the discovered nodes in the Network Sonar section of the Orion website and import some, all, or none of them as you choose.
Set the IsHidden
option to true
to cause the discovery profile to be removed after the discovery completes. Leave it false
for the discovery profile to stick around, which would allow you to run it again in the future from the Orion website.
Once the discovery context is prepared, starting the discovery is fairly simple:
$DiscoveryProfileID = (Invoke-SwisVerb $swis Orion.Discovery StartDiscovery @($StartDiscoveryContext)).InnerText
The discovery profile ID is an integer that comes back wrapped in an XML element. We can use .InnerText
to extract it.
Now that we have a discovery profile ID, we can query the Orion.DiscoveryProfiles
entity to see when it finishes:
do {
Start-Sleep -Seconds 1
$Status = Get-SwisData $swis "SELECT Status FROM Orion.DiscoveryProfiles WHERE ProfileID = @profileId" @{profileId = $DiscoveryProfileID}
} while ($Status -eq 1)
At this point the discovery job has finished. The Orion.DiscoveryLogs
and Orion.DiscoveryLogItems
entities have the details. First, query Orion.DiscoveryLogs
to see what the outcome was:
$Result = Get-SwisData $swis "SELECT Result, ResultDescription, ErrorMessage, BatchID FROM Orion.DiscoveryLogs WHERE ProfileID = @profileId" @{profileId = $DiscoveryProfileID}
Result
has these meanings:
Value | Description |
---|---|
0 | Unknown - something strange happened |
1 | In progress - the discovery is still running |
2 | Finished - completed successfully |
3 | Error - the discovery was aborted with an error |
4 | Not scheduled - a discovery profile that has not run and is not scheduled to run |
5 | Scheduled - this discovery profile has not run yet, but will in the future |
6 | Not completed - this discovery profile was canceled |
7 | Canceling - cancelation was requested but not yet processed |
8 | Ready for import - discovery completed, but without auto-import; go to the website to import nodes |
If the discovery completed successfully (Result = 2), then the Orion.DiscoveryLogItems
table has the list of nodes and other objects that was imported:
Get-SwisData $swis "SELECT EntityType, DisplayName, NetObjectID FROM Orion.DiscoveryLogItems WHERE BatchID = @batchId" @{batchId = $Result.BatchID}
- About SWIS
- Connecting to SWIS
- SWQL Functions
- REST
- PowerShell
- Alerts
- Creating custom properties
- Poller Types
- Network Performance Monitor
- NetFlow Traffic Analyzer
- Network Configuration Manager
- IP Address Manager
- Server & Application Monitor
- Log Analyzer
- Schema reference