8 Replies Latest reply on Feb 8, 2017 9:02 AM by pvaysberg

    Setting CreateCorePluginConfiguration details for Orion.Discovery in python

    pvaysberg

      I've been trying to manage adding and removing nodes using the API.  My language of choice is python.  I have most of the discovery profile details figured out, but am not able to understand how to set things linke the Volume Types, Vlan Port Types, etc...

       

      I'm not able to figure out how to specify that I only want Flash and Ram volume types. Only Access and Trunk interfaces.

      I've tried various permutations of (Look at the code for the details of where this is applied):

          'AutoImportStatus': [{'IfAutoImportStatus':'Up'}],
          'AutoImportVlanPortTypes': [{'Trunk': False}, {'Access':False}]
          'AutoImportVlanPortTypes': [{'VlanPortType':'Trunk'}, {'VlanPortType':'Access'}],
          'AutoImportVolumeTypes': [{'VolumeType': 'FlashMemory'},{'VolumeType': 'RAM'}]
      

       

       

      Here is the python code I have so far:

      from __future__ import print_function
      import re
      import requests
      from orionsdk import SwisClient
      
      
      def main():
          npm_server = 'MyServer'
          username = 'MyUser'
          password = 'MyPass'
          names = ['MyDev1','MyDev2','MyDev3']
          bulkList_names = []
          for name in names:
              bulkList_names.append({'Address': name})
          print (bulkList_names)
      
      
          orion_engine_id = 1
      
      
          swis = SwisClient(npm_server, username, password)
      
      
          corePluginContext = {
          'BulkList': bulkList_names,
          'Credentials': [
          {
          'CredentialID': 5,
          'Order': 1
          }
          ],
          'WmiRetriesCount': 0,
          'WmiRetryIntervalMiliseconds': 1000,
          'IsDiscoveryForVimEnabled': False,
      #    'AutoImportStatus': [{'IfAutoImportStatus':'Up'}],
      #    'AutoImportVlanPortTypes': [{'Trunk': False}, {'Access':False}]
      #    'AutoImportVlanPortTypes': [{'VlanPortType':'Trunk'}, {'VlanPortType':'Access'}],
      #    'AutoImportVolumeTypes': [{'VolumeType': 'FlashMemory'},{'VolumeType': 'RAM'}]
          }
      
      
          corePluginConfig = swis.invoke('Orion.Discovery', 'CreateCorePluginConfiguration', corePluginContext)
      
      
          discoveryProfile = {
          'Name': 'API discovery',
          'EngineID': orion_engine_id,
          'JobTimeoutSeconds': 3600,
          'SearchTimeoutMiliseconds': 5000,
          'SnmpTimeoutMiliseconds': 5000,
          'SnmpRetries': 2,
          'RepeatIntervalMiliseconds': 1800,
          'SnmpPort': 161,
          'HopCount': 0,
          'PreferredSnmpVersion': 'SNMP2c',
          'DisableIcmp': False,
          'AllowDuplicateNodes': False,
          'IsAutoImport': True,
          'IsHidden': False,
          'PluginConfigurations': [{'PluginConfigurationItem': corePluginConfig}]
          }
      
      
          print("Running discovery...")
          result = swis.invoke('Orion.Discovery', 'StartDiscovery', discoveryProfile)
          print("Returned discovery profile id {}".format(result))
      
      
      requests.packages.urllib3.disable_warnings()
      
      
      if __name__ == '__main__':
          main()
      
        • Re: Setting CreateCorePluginConfiguration details for Orion.Discovery in python
          pvaysberg

          I should mention that I'm working from a XML dump of a manually created discovery profile that has these parts:

          <pluginItem>
             <ArrayOfDiscoveryPluginConfigurationBase xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
             xmlns="http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Models.Discovery">
             <DiscoveryPluginConfigurationBase xmlns:d2p1="http://schemas.solarwinds.com/2008/Orion"
             i:type="d2p1:CoreDiscoveryPluginConfiguration">
             <d2p1:ActiveDirectoryList/>
             <d2p1:AddressRange/>
             <d2p1:AgentsAddresses xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"/>
             <d2p1:AutoImportVolumeTypes xmlns:d3p1="http://schemas.datacontract.org/2004/07/SolarWinds.Common.Snmp">
             <d3p1:VolumeType>FlashMemory</d3p1:VolumeType>
             <d3p1:VolumeType>RAM</d3p1:VolumeType>
             </d2p1:AutoImportVolumeTypes>
          
          <DiscoveryPluginConfigurationBase xmlns:d2p1="http://schemas.solarwinds.com/2008/Interfaces"
             i:type="d2p1:InterfacesDiscoveryPluginConfiguration">
             <d2p1:AutoImportExpressionFilter xmlns:d3p1="http://schemas.datacontract.org/2004/07/"/>
             <d2p1:AutoImportStatus
             xmlns:d3p1="http://schemas.datacontract.org/2004/07/SolarWinds.Interfaces.Common.Enums">
             <d3p1:IfAutoImportStatus>Up</d3p1:IfAutoImportStatus>
             </d2p1:AutoImportStatus>
             <d2p1:AutoImportVirtualTypes xmlns:d3p1="http://schemas.datacontract.org/2004/07/System">
             <d3p1:boolean>false</d3p1:boolean>
             <d3p1:boolean>true</d3p1:boolean>
             <d3p1:boolean i:nil="true"/>
             </d2p1:AutoImportVirtualTypes>
             <d2p1:AutoImportVlanPortTypes
             xmlns:d3p1="http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Models.Enums">
             <d3p1:VlanPortType>Trunk</d3p1:VlanPortType>
             <d3p1:VlanPortType>Access</d3p1:VlanPortType>
             <d3p1:VlanPortType>Unknown</d3p1:VlanPortType>
             </d2p1:AutoImportVlanPortTypes>
             <d2p1:DiscoverVLANs>false</d2p1:DiscoverVLANs>
          </DiscoveryPluginConfigurationBase>
          </ArrayOfDiscoveryPluginConfigurationBase>
          </pluginItem>
          
            • Re: Setting CreateCorePluginConfiguration details for Orion.Discovery in python
              tdanner

              To control what interfaces are imported, you need to create a configuration object for the discovery plugin that handles interfaces by calling Orion.NPM.Interfaces.CreateInterfacesPluginConfiguration. Like this:

               

              interfacesPluginContext = {
                'AutoImportStatus': ['Up'], # Also available: Down, Shutdown
                'AutoImportVlanPortTypes': ['Trunk', 'Access'], # Also available: Unknown
                #'AutoImportVirtualTypes': ['Physical', 'Virtual', 'Unknown'],
              
                #'AutoImportExpressionFilter': [{'Prop': 'Alias', 'Op': 'Regex', 'Val': '.*Nortel.*'}]
                # 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)
              

               

              Then include this config object in the list of plugin configurations when you create the discovery profile, like this:

               

              discoveryProfile = {
                'Name': 'API discovery',
                'EngineID': orion_engine_id,
                'JobTimeoutSeconds': 3600,
                'SearchTimeoutMiliseconds': 5000,
                'SnmpTimeoutMiliseconds': 5000,
                'SnmpRetries': 2,
                'RepeatIntervalMiliseconds': 1800,
                'SnmpPort': 161,
                'HopCount': 0,
                'PreferredSnmpVersion': 'SNMP2c',
                'DisableIcmp': False,
                'AllowDuplicateNodes': True,
                'IsAutoImport': True,
                'IsHidden': False,
                'PluginConfigurations': [
                     {'PluginConfigurationItem': corePluginConfig},
                     {'PluginConfigurationItem': interfacesPluginConfig},  # Add your interfaces plugin config here
                ]
              }
              

               

              It is not currently possible to control the set of volumes that get imported during discovery through the API. I recommend you just let it discover all of them and then delete the ones you don't want. To track the discovery and wait for it to complete so you can clean up the volumes, follow the example here: https://github.com/solarwinds/OrionSDK/blob/master/Samples/PowerShell/DiscoverSnmpV3Node.ps1 .

              1 of 1 people found this helpful
            • Re: Setting CreateCorePluginConfiguration details for Orion.Discovery in python
              pvaysberg

              tdanner Thanks for the help.  This worked great to wait for the discovery to finish and report on what was discovered. 

               

              Now to get the remove un-needed stuff to work correctly.  I assume that there is some way to remove an entity based on it's NetObjectID. Are there any examples that you can point me to that do this for volumes and interfaces?

               

              Once I'm done doing this I'll post my complete product here so that it hopefully helps others work through these issues.

                • Re: Setting CreateCorePluginConfiguration details for Orion.Discovery in python
                  pvaysberg

                  I haven't posted anything back on this

                  Here is what I've been using for a couple months:

                  def solarwindsDiscovery(hosts):
                      # Init SWIS API
                      npm_server = 'solarwinds-hostname'
                      username = 'solarwinds-username'
                      password = 'solarwinds-password'
                      swis = SwisClient(npm_server, username, password)
                      bulkList_hosts = []
                      for host in hosts:
                          bulkList_hosts.append({'Address': host})
                      pprint.pprint(bulkList_hosts)
                      # Make Discovery Profile
                      orion_engine_id = 1
                      corePluginContext = {
                          'BulkList': bulkList_hosts,
                          'Credentials': [
                              {
                                  'CredentialID': 5,
                                  'Order': 1
                              }
                          ],
                          'WmiRetriesCount': 0,
                          'WmiRetryIntervalMiliseconds': 1000,
                          'IsDiscoveryForVimEnabled': False
                      }
                      corePluginConfig = swis.invoke('Orion.Discovery', 'CreateCorePluginConfiguration', corePluginContext)
                      interfacesPluginContext = {
                          'AutoImportStatus': ['Up'],  # Also available: Down, Shutdown
                          'AutoImportVlanPortTypes': ['Trunk', 'Access', 'Unknown'],  # Also available: Unknown
                          # 'AutoImportVirtualTypes': ['Physical', 'Virtual', 'Unknown'],
                          # 'AutoImportExpressionFilter': [{'Prop': 'Alias', 'Op': 'Regex', 'Val': '.*Nortel.*'}]
                          # 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': 'API discovery',
                          'EngineID': orion_engine_id,
                          'JobTimeoutSeconds': 3600,
                          'SearchTimeoutMiliseconds': 2000,
                          'SnmpTimeoutMiliseconds': 3000,
                          'SnmpRetries': 1,
                          'RepeatIntervalMiliseconds': 1800,
                          'SnmpPort': 161,
                          'HopCount': 0,
                          'PreferredSnmpVersion': 'SNMP2c',
                          'DisableIcmp': False,
                          'AllowDuplicateNodes': False,
                          'IsAutoImport': True,
                          '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
                      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)
                          if len(result['results']) < 1:
                              running = False
                          time.sleep(5)
                      print(' ')
                      print('Done with discovery')
                      query = "SELECT Result, ResultDescription, ErrorMessage, BatchID FROM Orion.DiscoveryLogs WHERE ProfileID = '" + str(
                          discoveryProfileID) + "'"
                      result = swis.query(query)['results'][0]
                      print(result)
                      time.sleep(5)
                      if result['Result'] == 2:  # if discovery completed sucessfully
                          #  Find out what objects were discovered
                          query = "SELECT EntityType, DisplayName, NetObjectID FROM Orion.DiscoveryLogItems WHERE BatchID = '" + result[
                              'BatchID'] + "'"
                          print(query)
                          discovered = swis.query(query)
                          pprint.pprint(discovered)
                          discoveredNodes = []
                          discoveredVolumes = []
                          discoveredInterfaces = []
                          if len(discovered['results']) > 0:  # dSomething new was discovered
                              discoveredItems = discovered['results']
                              discoveredNodes = []
                              discoveredVolumes = []
                              discoveredInterfaces = []
                              pprint.pprint(discoveredItems)
                              for entry in discoveredItems:
                                  if entry['EntityType'] == 'Orion.Nodes':
                                      discoveredNodes.append(entry)
                                  if entry['EntityType'] == 'Orion.Volumes':
                                      discoveredVolumes.append(entry)
                                  if entry['EntityType'] == 'Orion.Interfaces':
                                      discoveredInterfaces.append(entry)
                                      # Remove un-needed stuff
                                      # removeVolumes = []
                                      # for volume in discoveredVolumes:
                                      #    if volume['NetObjectID']
                              #removeVolumes.append(volume['NetObjectID'])
                              # pprint.pprint(removeVolumes)
                              # Perform swis volume removal somehow
                              # swis.delete()