We are automating the hydration of assets in Orion, and after adding a node, we know how to discover the interfaces, but how do we programmatically discover the non-interface properties and enable them like the sample below?
Thanks,
Scott F.
for all except hardware health you add the right set of pollers for the device.
$swis->Create("Orion.Pollers", {
'PollerType'=>$poller,
'NetObject'=>"N:$node",
'NetObjectType'=>'N',
'NetObjectID'=>$node
});
Here's a list of the (current) pollers.
N.MulticastRouting.SNMP.MulticastRoutingTable
N.Routing.SNMP.Ipv4CidrRoutingTable
N.Routing.SNMP.Ipv4RoutingTable
N.Routing.SNMP.Ipv6RoutingTable
N.RoutingNeighbor.SNMP.BGP
N.RoutingNeighbor.SNMP.OSPF
N.RoutingNeighbor.SNMP.OSPFv3
N.RoutingNeighbor.SNMP.OSPFv3Juniper
N.Topology_CDP.SNMP.cdpCacheTable
N.Topology_Layer2.SNMP.Dot1dTpFdb
N.Topology_Layer2.SNMP.Dot1dTpFdbNoVLANs
N.Topology_Layer2.SNMP.Dot1qTpFdbNoVLANs
N.Topology_Layer3.SNMP.ipNetToMedia
N.Topology_Layer3_IpRouting.SNMP.ipCidrRouter
N.Topology_Layer3_IpRouting.SNMP.rolesRouter
N.Topology_LLDP.SNMP.lldpRemoteSystemsData
N.Topology_PortsMap.SNMP.Dot1dBase
N.Topology_PortsMap.SNMP.Dot1dBaseNoVLANs
N.Topology_PortsMap.SNMP.Dot1qVlanEgressPorts
N.Topology_PortsMap.SNMP.JuniperExVlan
N.Topology_STP.SNMP.Dot1dStp
N.Topology_Vlans.SNMP.Dot1q
N.Topology_Vlans.SNMP.JuniperExVlan
N.Topology_Vlans.SNMP.VmMembershipSummary
N.Topology_Vlans.SNMP.VtpVlan
N.VRFRouting.SNMP.JuniperObsolete
N.VRFRouting.SNMP.JuniperStandard
N.VRFRouting.SNMP.MPLSVPNObsolete
N.VRFRouting.SNMP.MPLSVPNStandard
[I haven't found a way to determine which pollers should be added, I turn up what I need for a node, then look to see what pollers got added]
as long as snmp is configured on the device(s) properly, a network discovery (which can be ran on a scheduled basis) will pick these up.
There is no way to programmatically control any aspect of the discovery process.
(oh, and no, network sonar discovery will not pick those all up for existing nodes)
Wow, do I have to add each one of those in a separate call?
Also, can you show me what that looks like as a REST call? (What the json body/data needs to look like.)
Actually, I went back to the PDF docs and I see body data that looks like this: {"PollerType":"hi from curl 2", "NetObject":"N:123", "NetObjectType":"N", "NetObjectID":123} Although, "hi from curl 2" doesn't make much sense if I'm trying to specify one of the pollers in the list. Can I assume that "$poller" in your example somehow represents, for instance, "N.Routing.SNMP.Ipv4CidrRoutingTable" ? And if so, is that the string that goes in there, or... ?
Oh, also, in the documentation it appears that if my poller addition is successful, I get back the swis:// uri of the poller along with it's ID number. Is that correct? And if my call fails, what should I be looking for as a return value?
Thanks again,
Scott Fraley
[I use perl + SWIS because the API just works, I've been writing perl code for over 20 years, ]
yes, separate calls. :-(
$poller is one of the strings
I've never had AddPoller fail -- it feels like there is no error checking on the server-side for Create operations given a valid nodeid.
I seem to remember that it will add duplicate pollers, and pollers that do not actually exist.
In my code, this is called immediately after Creating a Node, so I know that there are no node-pollers assigned yet.
I have a chunk of code that matches the OID of the device, and adds the pollers to it.
e.g.
if (index($oid,"1.3.6.1.4.1.2636")==0) {
&add_poller($AddedNode,"N.Cpu.SNMP.JuniperJunOS");
&add_poller($AddedNode,"N.Memory.SNMP.JuniperJunOS");
&add_poller($AddedNode,'N.Topology_Layer3.SNMP.ipNetToMedia') if (index($oid,'1.3.6.1.4.1.2636.1.1.1.2.18')==0);
&add_poller($AddedNode,'N.Topology_Layer3.SNMP.ipNetToMedia') if (index($oid,'1.3.6.1.4.1.2636.1.1.1.2.24')==0);
&add_poller($AddedNode,'N.Topology_Layer3.SNMP.ipNetToMedia') if (index($oid,'1.3.6.1.4.1.2636.1.1.1.2.25')==0);
&add_poller($AddedNode,'N.Topology_Layer3.SNMP.ipNetToMedia') if (index($oid,'1.3.6.1.4.1.2636.1.1.1.2.57')==0);
};
In another universe I'd pass an array of pollers to the system and it would do that for me, or have an asynchronous API where I just stream requests a-la-SNMP and match the replies up with them...
We use something like this SQL Query to programmatically turn off pollers we do not want to use. We flag devices to apply this script against based on their membership in a group that uses a dynamic query. You could use this to do the opposite I think. However, if the node/pollers have not been discovered yet then you will have to work with the discovered nodes. I am just beginning to look at the schema for the discovery tables, so if you have gain insights into how they work, please post. thanks
UPDATE Pollers SET Enabled = 0
WHERE (NetObjectType = 'N') AND
(PollerType LIKE '%Routing%'
OR PollerType LIKE '%Topology%'
OR PollerType LIKE '%VRFRouting%')
AND (Enabled = 1)
AND
(EXISTS (SELECT S.EntityID
FROM [ContainerMemberSnapshots] S
JOIN [Containers] C ON S.ContainerID = C.ContainerID
WHERE S.EntityDisplayName = 'Node' AND C.IsDeleted = '0' AND S.ContainerID = '8'))
(NetObjectID IN (SELECT S.EntityID
That's interesting. I was under the impression that you couldn't directly UPDATE the SWQL / Orion tables, which is why I use the REST API. (Well, that and I really dislike the SOAP experience.)
After talking with the boss, the question we're really trying to ask is, when I hit the List Resources button from the Management pane of a Node Details screen, what's going on in the background, and more importantly, do we have the ability, via the SDK/API, to do the same thing(s) ?
For instance, we don't want to add 58+ pollers to any one device just because we don't know which ones go with said device. It seems like List Resources knows how to get just those interfaces/VLANs/etc. that go with the selected Node/device.
Thanks!
What the "List Resources" process actually does is somewhat complicated and, unfortunately, not directly exposed through anything you could call.
We are testing a possible solution that might give you what you need. I should be able to let you know soon if it works out or not.
Hi,
Provided below the powershell script to discover and import results. This is for automatic discovery.
In order to add a node via SDK and all the resources of it needs to be discovered and added automatically, follow the below provided steps.
In case you need to add a resource that is not found in discovery (like non interface resources), you can added the specific poller to the node and rediscover to see that resource on the UI (As mentioned by Richard Letts).
#Step 1) Create Core plugin Configuration - IP ranges, subnets, IP bulk list, credentials
# You can provide the desired IPs or IP Ranges or Subnets as in the UI with already configured credentials.
# Query Orion.Credential to get the desired Credential ID
$xmlParam = ([xml]"
<CorePluginConfigurationContext xmlns:i='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://schemas.solarwinds.com/2012/Orion/Core'>
<BulkList>
<IpAddress>
<Address>10.199.3.1</Address>
</IpAddress>
<Address>10.199.2.22</Address>
<Address>2001:1:0:104:250:56ff:fe90:68dd</Address>
</BulkList>
<IpRanges>
<IpAddressRange>
<StartAddress>10.199.1.1</StartAddress>
<EndAddress>10.199.2.1</EndAddress>
</IpAddressRange>
</IpRanges>
<Subnets/>
<Credentials>
<SharedCredentialInfo>
<CredentialID>4</CredentialID>
<Order>1</Order>
</SharedCredentialInfo>
<CredentialID>2</CredentialID>
<Order>2</Order>
<CredentialID>1</CredentialID>
<Order>3</Order>
<CredentialID>5</CredentialID>
<Order>4</Order>
</Credentials>
<WmiRetriesCount>1</WmiRetriesCount>
<WmiRetryIntervalMiliseconds>1000</WmiRetryIntervalMiliseconds>
</CorePluginConfigurationContext>"
).DocumentElement
$coreCfg = Invoke-SwisVerb $SWIS_Connection "Orion.Discovery" "CreateCorePluginConfiguration" @($xmlParam)
$coreCfgText = $coreCfg.InnerXml
#--------------------------------------------------------------------------------------------------
#Step 2) Create VIM plugin Configuration
$vimParam = ([xml]"
<VimPluginConfigurationContext xmlns:i='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://schemas.solarwinds.com/2012/Orion/VIM'>
<Enabled>true</Enabled>
<CredentialID>3</CredentialID>
</VimPluginConfigurationContext>"
$vimCfg = Invoke-SwisVerb $SWIS_Connection "Orion.VIM.Discovery" "CreateVimPluginConfiguration" @($vimParam)
$vimCfgText = $vimCfg.InnerXml
#Step 3) Create Discovery Configuration
# You can modify various parameters like Engine ID, SNMPPort,.. based on your environment
$startDiscoveryParam = ([xml]@("
<StartDiscoveryContext xmlns:i='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://schemas.solarwinds.com/2012/Orion/Core'>
<Name>AutomaticDiscovery1</Name>
<EngineId>1</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>false</IsHidden>
<PluginConfigurations>",
"<PluginConfiguration>
<PluginConfigurationItem>$coreCfgText</PluginConfigurationItem>
</PluginConfiguration>",
<PluginConfigurationItem>$vimCfgText</PluginConfigurationItem>
"</PluginConfigurations>
</StartDiscoveryContext>"
)).DocumentElement
Invoke-SwisVerb $SWIS_Connection "Orion.Discovery" "StartDiscovery" @($startDiscoveryParam) | Out-Null
Hey Tim,
Can you give me a time frame as to when you might have a go / no go on this solution you mention? In other words, when is 'soon' ? I realize you probably can't give me an exact date, but any narrowing down of the time frame would be helpful for our planning.
Little bit of an old post I know, and also excuse my lack of knowledge as I am still quite new to the SDK and don't have a ton of scripting/programming experience in my background. I'm trying to find a way to automate cleaning up orphaned volumes. There seem to be helpful verbs and swql data for cleaning up interfaces, but not a lot for volumes.
I write all of the below out not because you necessarily need to know all of it, but because I wanted to not only document the basic steps that I think should be taken for my own reference, but also to have others weigh in on whether or not this is the best, most efficient approach and maybe make suggestions on how to improve one or many of these steps.
Mostly, I originally replied to ask a single question though. madhavan, in your reply above that contains the "powershell script to discover and import results" I don't actually see how the script imports the results? It creates and starts a discovery, but then the script just ends. Did it get cut off or is there something obvious I'm missing?
Anyways, I came across this post while researching the automation of fixing orphaned volumes, mostly because my thinking is that I will need to do the following (I will be using powershell to accomplish this):
Sorry for the length of this, like I said, this was mostly just to ask a question (at first) and then to document the steps while I was thinking about them, and if it helps someone else that needs the same thing, then cool, that's a bonus.
Jordan
Hi @madhavan,
Question about using these discovery verbs in NPM 11.5.2. Do you have to provide all of the xml information you list above even if the discovery is already present in the Discovery Profiles table? I am just trying to automate running a discovery but powershell keeps throwing an error saying "StartDiscovery cannot unpackage parameter 0". Here s a subset of my script:
$uri= Get-swisdata $swis "SELECT v.URI FROM Orion.DiscoveryProfiles AS V WHERE ProfileID= '146' "
$out=Invoke-SwisVerb $swis "Orion.Discovery" "StartDiscovery" @($uri) | out-null
I also may need another arguement for this verb but I can't find documentation on this verb to verify for sure.
thanks
Hi @madhavan ,
I have two questions:1. When I am trying to get the resources list of a node, I was unable to get the resources list of a node.
Below is the script that I tried to get resources list of a node
jobid = swis.invoke('Orion.Nodes', 'ScheduleListResources',NodeID)
print(jobid) time.sleep(60)
while True:
results = swis.invoke('Orion.Nodes', 'GetScheduledListResourcesStatus', jobid,NodeID)
print(results)
if(results=='ReadyForImport'):
break
results = swis.invoke('Orion.Nodes', 'ImportListResourcesResult', jobid,NodeID)
Error when I run the script:
requests.exceptions.HTTPError: 400 Client Error: Could not load file or assembly 'SolarWinds.Interfaces.Discovery.Strings, Version=3.5.0.638, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. for url: https://solarwinds_url:17778/SolarWinds/InformationService/v3/Json/Invoke/Orion.Nodes/ImportListResourcesResult
2. Is there a way to Enable monitoring for a specific volume of a node?