5 Replies Latest reply on Dec 5, 2017 4:23 AM by lore.phoenix

    Python Orion SDK - Q: HowTo discover new device into NPM BUT disabling some standard pollers

    lore.phoenix

      I am busy to rewrite my scripts with Python and to move away from SOAP/Perl.

      We found some information on the web that advise to add new devices into the auto discovery. As result that each discovered node enabled some resources that I don't want to have like:

      * Hardware Health Hardware

      * EnergyWise

      * VLAN

      * Topology: Layer 2

      * Topology: Layer 3

       

      The idea was to create a profile/template which disabled those items but so far I found was to create/use a template for interfaces and interface types.

       

      When the discovery has completed then I found out that this is added into the table [Solarwinds_Dev].[dbo].[Pollers]

      Columns : [PollerID],[PollerType],[NetObject],[NetObjectType],[NetObjectID],[Enabled]

      The column NetObjectID is actualy the NodeID of our device.

      PollerIDPollerType                          NetObject NetObjectType   NetObjectID Enabled

      22065   N.ResponseTime.ICMP.Native          N:588     N               588         1

      22066   N.Status.ICMP.Native                N:588     N               588         1

      22067   N.ResponseTime.SNMP.Native          N:588     N               588         0

      22068   N.Status.SNMP.Native                N:588     N               588         0

      22069   N.Details.SNMP.Generic              N:588     N               588         1

      22070   N.Uptime.SNMP.Generi                N:588     N               588         1

      22071   N.Cpu.SNMP.CiscoGen3                N:588     N               588         1

      22072   N.Memory.SNMP.CiscoGen3             N:588     N               588         1

      22073   N.Topology_Vlans.SNMP.VtpVlan       N:588     N               588         1

      22074   N.Topology_Layer2.SNMP.Dot1dTpFdb   N:588     N               588         1

      22075   N.Topology_CDP.SNMP.cdpCacheTable   N:588     N               588         1

      22076   N.Topology_LLDP.SNMP.lldpRemoteSystemsData  N:588   N         588         1

      22077   N.Topology_PortsMap.SNMP.Dot1dBase  N:588     N               588         1

      22078   N.Topology_Layer3.SNMP.ipNetToMedia N:588     N               588         1

      22079   N.EnergyWise.SNMP.Cisco             N:588     N               588         1

      22080   N.SwitchStack.SNMP.Cisco            N:588     N               588         1

      22081   N.HardwareHealthMonitoring.SNMP.NPM.Cisco   N:588   N         588         1

       

      On THWACK I have found a solution to create pollers for a Node but this creates additional entries on the table [Solarwinds_Dev].[dbo].[Pollers] for that Node.

      It doesn't update or delete unselected PollerTypes but only adding the same pollers with a different Enabled value.

      This creates duplicate PollerTypes for the same Node but with a different Enabled value.

      As result it keeps using the old settings.

       

      Updating entries directly on the database is something I don't like to do but I did a test.

      Change the entries on the Enabled column to value seems to work for :

       

                          : N.Topology_CDP.SNMP.cdpCacheTable

                          : N.Topology_LLDP.SNMP.lldpRemoteSystemsData

      Topology Layer 3    : N.Topology_Layer3.SNMP.ipNetToMedia

      Topology Layer 2    : N.Topology_Layer2.SNMP.Dot1dTpFdb

      EnergyWise          : PollerType N.EnergyWise.SNMP.Cisco

       

      But it doesn't seems to work for which I conclude that there some other hidden entries somewhere on the database.

      Hardware Health Hardware    : N.HardwareHealthMonitoring.SNMP.NPM.Cisco

      VLAN                        : N.Topology_Vlans.SNMP.VtpVlan

       

       

      ##### script discover.py #####

      import sys

      import time

      from orionsdk import SwisClient

      from pprint import pprint

       

      def solarwindsDiscovery(hosts):

          # Init SWIS API

          npm_server = 'solarwinds-dev.example.com'

          username = 'scripting'

          password = 'somesecretpassword'

       

          verify = False

          if not verify:

              from requests.packages.urllib3.exceptions import InsecureRequestWarning

              requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

       

          swis = SwisClient(npm_server, username, password)

       

          bulkList_hosts = []

          for host in hosts:

              bulkList_hosts.append({'Address': host})

         

          snmpv3_credential_id = 12

          snmpv2_credential_id = 6

          snmpv2_oldcredential_id = 3

       

          # make Discovery Profile

          orion_engine_id = 2

          corePluginContext = {

              'BulkList':  bulkList_hosts,

              'Credentials': [

                  {

                      'CredentialID': snmpv3_credential_id,

                      'Order': 1

                  },

                  {

                      'CredentialID': snmpv2_credential_id,

                      'Order': 2

                  },

                  {

                      'CredentialID': snmpv2_oldcredential_id,

                      'Order': 3

                  }

              ],

              'WmiRetriesCount': 0,

              'WmiRetryIntervalMiliseconds': 1000,

              'IsDiscoveryForVimEnabled': False

          }

          corePluginConfig = swis.invoke('Orion.Discovery', 'CreateCorePluginConfiguration', corePluginContext)

       

          interfacesPluginContext = {

              'AutoImportStatus': [],  # Also available: Down, Shutdown, Up

              'AutoImportVlanPortTypes': ['Trunk', 'Access', 'Unknown'],

              'AutoImportVirtualTypes': ['Physical', 'Virtual'],  # Also available: Unknown

              'AutoImportExpressionFilter':

                                         [{'Prop': 'Descr', 'Op': '!Any', 'Val': 'null'},

                                         {'Prop': 'Descr', 'Op': '!Any', 'Val': 'vlan'},

                                         {'Prop': 'Descr', 'Op': '!Any', 'Val': 'loopback'},

                                         {'Prop': 'Alias', 'Op': '!Regex', 'Val': '^$'},

                                         {'Prop': 'Name', 'Op': '!Regex', 'Val': '^t1'}]

              # Available values for Prop: Type, Name, Descr, Alias, Node, All, Vlan

              # Available values for Op: All, !All, Any, !Any, Equals, !Equals, Regex, !Regex, #All, !#All, #Any, !#Any

              # Val is the literal value to compare Prop to

              # If more than one expression is provided, the interface must match all of the expressions to be imported

              # To specify more than one number or string for the All and Any operators (including variants), separate them by spaces

          }

          interfacesPluginConfig = swis.invoke('Orion.NPM.Interfaces', 'CreateInterfacesPluginConfiguration', interfacesPluginContext)

       

          discoveryProfile = {

              'Name': 'discover_one_node.py',

              'EngineID': orion_engine_id,

              'JobTimeoutSeconds': 3600,

              'SearchTimeoutMiliseconds': 5000,

              'SnmpTimeoutMiliseconds': 5000,

              'SnmpRetries': 2,

              'RepeatIntervalMiliseconds': 1800,

              'SnmpPort': 161,

              'HopCount': 0,

              'PreferredSnmpVersion': 'SNMP3',

              'DisableIcmp': False,

              'ImportDownInterface': False,

              'ImportUpInterface': False,

              'ImportShutdownInterface': False,

              'AllowDuplicateNodes': False,

              'IsAutoImport': True,

              #  'IsHidden" set to True will remove the discovery profile after it completes

              'IsHidden': True,

              'PluginConfigurations': [{'PluginConfigurationItem': corePluginConfig}, {'PluginConfigurationItem': interfacesPluginConfig}]

          }

       

          # Start Discovery

          print("Running discovery...")

          discoveryProfileID = swis.invoke('Orion.Discovery', 'StartDiscovery', discoveryProfile)

          print("Returned discovery profile id {}".format(discoveryProfileID))

       

          '''

              discoveryStatusState = {0: "Unknown", 1: "InProgress", 2: "Finished", 3: "Error", 4: "NotScheduled", 5: "Scheduled",

                                  6: "NotCompleted", 7: "Canceling", 8: "ReadyForImport"}

          '''

          # Wait until it's done with discovery before we start assigning custom pollers or populating custom properties

          running = True  # InProgress

          while running:

              sys.stdout.write('.')

              sys.stdout.flush()

              query = "SELECT Status FROM Orion.DiscoveryProfiles WHERE ProfileID = " + str(discoveryProfileID)

              result = swis.query(query)

              # pprint(result)

              # Example output .{'results': [{'Status': <discoveryStatusState>}]}

       

              if len(result['results']) < 1:

                  # When we don't have any records from the Orion.DiscoveryProfiles

                  # This will results to an empty list

                  running = False

              else:

                  time.sleep(5)       # wait 5 seconds

       

          print(' ')

          print('Done with discovery')

       

          query = "SELECT Result, ResultDescription, ErrorMessage, BatchID FROM Orion.DiscoveryLogs WHERE ProfileID = '" + str(discoveryProfileID) + "' "

          discovered = swis.query(query)

       

          if (discovered['results'][0]['Result']) != 2:

              print(discovered['results'][0]['ResultDescription'])

              print(discovered['results'][0]['ErrorMessage'])

          else:

              # Import finished

              print(discovered['results'][0]['ResultDescription'])

       

      requests.packages.urllib3.disable_warnings()

       

      if __name__ == '__main__':

          hosts = [ '192.168.0.1' , '192.168.0.2']

          solarwindsDiscovery(hosts)

       

      ##### end script discover.py #####

       

       

      ##### script add_poller.py #####

      from __future__ import print_function

      import re

      import requests

      from orionsdk import SwisClient

      from pprint import pprint

       

      def main():

      # Init SWIS API

          npm_server = 'solarwinds-dev.example.com'

          username = 'scripting'

          password = 'somesecretpassword'

          nodeid = '588'

       

          verify = False

          if not verify:

              from requests.packages.urllib3.exceptions import InsecureRequestWarning

              requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

       

          swis = SwisClient(npm_server, username, password)

          print("Add pollers into node:")

       

          pollers_enabled = {

              'N.Status.ICMP.Native': True,

              'N.Status.SNMP.Native': False,

              'N.ResponseTime.ICMP.Native': True,

              'N.ResponseTime.SNMP.Native': False,

              'N.Details.SNMP.Generic': True,

              'N.Uptime.SNMP.Generic': True,

              'N.Cpu.SNMP.HrProcessorLoad': True,

              'N.Memory.SNMP.NetSnmpReal': True,

              'N.AssetInventory.Snmp.Generic': True,

              'N.Topology_CDP.SNMP.cdpCacheTable': False,

              'N.Topology_LLDP.SNMP.lldpRemoteSystemsData': False,

              'N.Topology_Layer3.SNMP.ipNetToMedia': False,

              'N.Routing.SNMP.Ipv4CidrRoutingTable': False,

              'N.Routing.SNMP.Ipv4RoutingTable': False,

              'N.EnergyWise.SNMP.Cisco': False,

              'N.Topology_Vlans.SNMP.VtpVlan': False,

              'N.Topology_PortsMap.SNMP.Dot1dBaseNoVLANs': False,

              'N.HardwareHealthMonitoring.SNMP.NPM.Cisco': False,

              'N.EnergyWise.SNMP.Cisco' : False,

              'N.Topology_Layer2.SNMP.Dot1dTpFdb' : False,

              'N.Topology_Layer3.SNMP.Dot1dTpFdb' : False

          }

       

          pollers = []

          for k in pollers_enabled:

              pollers.append(

              {

              'PollerType': k,

              'NetObject': 'N:' + nodeid,

              'NetObjectType': 'N',

              'NetObjectID': nodeid,

              'Enabled': pollers_enabled[k]

              }

          )

       

          for poller in pollers:

              print(" Adding poller type: {} with status {}... ".format(poller['PollerType'], poller['Enabled']), end="")

              response = swis.create('Orion.Pollers', **poller)

              print("DONE!")

       

       

          response = swis.invoke('Orion.Nodes', 'PollNow', 'N:' + nodeid)

       

      requests.packages.urllib3.disable_warnings()

       

      if __name__ == '__main__':

          main()

       

       

      ##### end script add_poller.py #####

       

      If this is possible, can you some provide me how I can do this ?

        • Re: Python Orion SDK - Q: HowTo discover new device into NPM BUT disabling some standard pollers
          tdanner

          You can disable pollers through the API. Get the Uris for the pollers to disable, then call bulkupdate to turn them off.

           

          nodeid = 588  # Get the NodeID from somewhere
          pollerdata = swis.query("SELECT Uri FROM Orion.Pollers WHERE NetObjectID=@nodeid AND (PollerType LIKE '%Topology%' OR PollerType LIKE '%EnergyWise%')", nodeid=nodeid)
          uris = [row['Uri'] for row in pollerdata['results']]
          swis.bulkupdate(uris, Enabled=0)

           

          I don't know why this didn't work for hardware health and vlans. I'll look into that and follow up here.

          1 of 1 people found this helpful
            • Re: Python Orion SDK - Q: HowTo discover new device into NPM BUT disabling some standard pollers
              tdanner

              After reading your message again I realized it was not quite clear what you meant by "But it doesn't seems to work for which I conclude that there some other hidden entries somewhere on the database." Is it just that you are still seeing the hardware and vlan data that was collected before you disabled that collection?

                • Re: Python Orion SDK - Q: HowTo discover new device into NPM BUT disabling some standard pollers
                  lore.phoenix

                  Hello tdanner

                   

                  Your solution with the bulkupdate did fix my issue for the Topology and EnergyWise. Many thanks for that.
                  I also learned that I didn't had the latest swisclient.py file while the __init__.py mention I had version 0.0.6.
                  My original swisclient.py didn't had the def bulkupdate which I fixed now on my server  :-)

                   

                  ### my code

                  swis = SwisClient(npm_server, username, password)

                  nodeid = 589  # Get the NodeID from somewhere

                  pollerdata = swis.query("SELECT Uri FROM Orion.Pollers WHERE NetObjectID=@nodeid AND    \

                                                                   (PollerType LIKE '%HardwareHealthMonitoring%'                           \

                                                                               OR PollerType LIKE '%Topology%'                                     \

                                                                               OR PollerType LIKE '%EnergyWise%')", nodeid=nodeid)

                  uris = [row['Uri'] for row in pollerdata['results']]

                  swis.bulkupdate(uris, Enabled=0)

                   

                   

                  I meant that the resource "Hardware Health Sensors" is still enabled on GUI after I tried to disable this.

                   

                  I checked this on the database and I notice that the value is changed to "0".

                  If I disable the Hardware Health Sensors on the GUI then I am looking on the same table for the same Nodeid and I notice that the PollerType '%HardwareHealthMonitoring% is removed and a new PollerType was added 'N.Routing.SNMP.ipv4RoutingTable' with Enabled value 0.

                   

                  As test I enabled the Hardware Health Sensors on the GUI and I notice that the PollerType '%HardwareHealthMonitoring% won't be added into the table [Solarwinds_Dev].[dbo].[Pollers] for the NodeId that I am testing this. Nevertheless on the GUI I see that the Hardware Health Sensors is enabled. Therefore my idea of an hidden entry on a different table because the GUI doesn't seems to look at the table [Solarwinds_Dev].[dbo].[Pollers] for the Hardware Health Sensors.

                   

                  Kind regards,