10 Replies Latest reply on Aug 2, 2017 5:47 PM by clarv02

    ImportDiscoveryResults (API)

    clarv02

      We have a Python script that does a full discovery, including Interface filters, with AutoImport=True and it works like a champ. However, we're trying to figure out how to have a two part approach:

       

      1 - Discovery with AutoImport=False

      2 - Import devices that have been discovered

       

      There aren't a lot of references out there that provide detailed examples of using 'ImportDiscoveryResults'. Here are some that I've been looking at:

       

      SolarWinds Information Service v3.0 Schema Documentation

      orionsdk-python/swisclient.py at master · solarwinds/orionsdk-python · GitHub

      From that one:

          def invoke(self, entity, verb, *args):
              return self._req(
                      "POST",
                      "Invoke/{}/{}".format(entity, verb), args).json()

       

      So it seems like I should have something like this:

      swis.invoke('Orion.Discovery', 'ImportDiscoveryResults', ??)

       

      Can I provide just the ProfileID that I already have from the previous Discovery? I've seen references about specifying Nodes, but I would like to only have to provide the ProfileID if possible.

       

      Any help would be greatly appreciated!

        • Re: ImportDiscoveryResults (API)
          tomas.vrabel

          I added description how to import discovery results at the end of page Discovery · solarwinds/OrionSDK Wiki · GitHub

           

          And simple Python example:

           

           swis = SwisClient(npm_server, username, password)
           print("Importing discovery results:")
          
          
           importConfiguration = {
             'ProfileID': 28,
             'NodeIDs': [],
             'DeleteProfileAfterImport' : True
           }
           result = swis.invoke('Orion.Discovery', 'ImportDiscoveryResults', importConfiguration)
          
          
          
          1 of 1 people found this helpful
            • Re: ImportDiscoveryResults (API)
              clarv02

              This is awesome. Thank you so much Tomas.

               

              I see the NodedIDs list is empty. So is the Nodes list optional in the importConfiguration? I assumed (and hoped) it was.

              • Re: ImportDiscoveryResults (API)
                clarv02

                Do you know why it is currently not possible to filter node child objects (e.g. import only specific node interfaces, volumes etc.)? When we invoke 'StartDiscovery', the discovery profile PluginConfigurations includes both corePluginConfig and interfacesPluginConfig. The latter includes filters for interfaces, and the AutoImport during discovery works great for us, bringing only the interfaces we need.

                 

                Is there no way for 'ImportDiscoveryResults' to utilize interfacesPluginConfig?

                 

                Thanks!

                  • Re: ImportDiscoveryResults (API)
                    tomas.vrabel

                    Try to use same approach in AutoImport = False scenario - start discovery with interface filter and AutoImport=False.

                    I would assume that only filtered interfaces will be discovered and eventually imported by ImportDiscoveryResults verb.

                     

                    If this will not work, please paste your discovery script, I will try to reproduce it.

                     

                    Discovered interfaces should be stored after discover and before import, check Orion.NPM.DiscoveredInterfaces entity.

                    However it's not possible to filter interfaces between discovery and import, you cannot remove interface from Orion.NPM.DiscoveredInterfaces entity using Orion SDK.

                      • Re: ImportDiscoveryResults (API)
                        clarv02

                        sorry for the delay...had to put this on hold for a couple days. By the way, thanks for your help with this.

                         

                        We are already trying to use the approach of running discovery with AutoImport = False. I had the same assumption, that all the information about filtered interfaces would be available to ImportDiscoveryResults. But when I invoked it, the nodes were imported with actually no interfaces at all:

                         

                        discoveryProfileID = 44

                        importConfiguration = {

                            'ProfileID': discoveryProfileID,

                            'NodeIDs': [],

                            'DeleteProfileAfterImport' : False

                        }

                        # Start Import

                        print("Running Import...")

                        result = swis.invoke('Orion.Discovery', 'ImportDiscoveryResults', importConfiguration)

                         

                        Here is the script that does the discovery:

                         

                        corePluginContext = {
                            'BulkList': bulklist_hosts,
                            'Credentials': snmp_discovery_creds,
                            'WmiRetriesCount': 0,
                            'WmiRetryIntervalMiliseconds': 1000,
                            'IsDiscoveryForVimEnabled': False
                        }
                        print("Orion EngineID: " + str(orion_engine_id))
                        corePluginConfig = swis.invoke('Orion.Discovery', 'CreateCorePluginConfiguration', corePluginContext)
                        # print(corePluginConfig)
                        interfacesPluginContext = {
                            'AutoImportStatus': ['Up'],  # Also available: Down, Shutdown
                            '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': '!Any', 'Val': 'cash'},
                                                           {'Prop': 'Alias', 'Op': '!Any', 'Val': 'vsam'},
                                                           {'Prop': 'Alias', 'Op': '!Any', 'Val': 'boh'},
                                                           {'Prop': 'Alias', 'Op': '!Any', 'Val': 'pos'},
                                                           {'Prop': 'Alias', 'Op': '!Any', 'Val': 'vendors'},
                                                           {'Prop': 'Alias', 'Op': '!Any', 'Val': 'printer'},
                                                           {'Prop': 'Alias', 'Op': '!Any', 'Val': 'pbx'},
                                                           {'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)

                         

                        DisableICMP = False

                         

                        current_datetime = datetime.datetime.now()
                        print (str(current_datetime))
                        current_dt_stripped = (current_datetime.strftime("%Y-%m-%d %H:%M:%S"))
                        print(current_dt_stripped)

                         

                        discoveryProfile = {
                            'Name': 'API Discovery '+current_dt_stripped,
                            'EngineID': orion_engine_id,
                            'JobTimeoutSeconds': 3600,
                            'SearchTimeoutMiliseconds': 2000,
                            'SnmpTimeoutMiliseconds': 3000,
                            'SnmpRetries': 1,
                            'RepeatIntervalMiliseconds': 1800,
                            'SnmpPort': 161,
                            'HopCount': 0,
                            'PreferredSnmpVersion': 'SNMP3',
                            'DisableIcmp': DisableICMP,
                            'AllowDuplicateNodes': False,
                            'IsAutoImport': False,
                            #  'IsHidden" set to True will remove the discovery profile after it completes
                            'IsHidden': False,
                            'PluginConfigurations': [{'PluginConfigurationItem': corePluginConfig},
                                                    {'PluginConfigurationItem': interfacesPluginConfig}]
                        }
                        # Start Discovery
                        print("Running discovery...")
                        discoveryProfileID = swis.invoke('Orion.Discovery', 'StartDiscovery', discoveryProfile)

                          • Re: ImportDiscoveryResults (API)
                            tomas.vrabel

                            Sorry for later reply.

                             

                            I tried your script and got same results.

                            After some testing I found out that when you provide list of NodeIDs instead of empty array for ImportDiscoveryResults verb, interfaces are imported too. This must be some bug in code but providing NodeIDs is a workaround.

                             

                            1) You can resolve NodeIDs using query:

                            SELECT NodeID, ProfileID

                            FROM Orion.DiscoveredNodes

                            WHERE ProfileID = 2  #replace with specific profileID

                             

                            2) Create array from resolved NodeIDs discovered by specific profile and resolved by query above

                            3) Pass the array to ImportDiscoveryResults verb:

                             

                                importConfiguration = {

                                    'ProfileID': 5,

                                    'NodeIDs': [ 1, 2, 3 ],

                                    'DeleteProfileAfterImport' : True

                                 }

                                result = swis.invoke('Orion.Discovery', 'ImportDiscoveryResults', importConfiguration);

                             

                             

                            Using this approach, discovered interfaces were imported too in my environment.

                              • Re: ImportDiscoveryResults (API)
                                clarv02

                                Hi Tomas,

                                 

                                This looks very promising and I should be able to get it to work. On a related note, would you know how we can check the status of the import (similar to how we check status of Discovery (by checking the Status from DiscoveryProfiles) to make sure it has completed before we continue with our script? After the devices are imported, we populate a bunch of custom properties and assign several custom pollers (UnDP). And we wouldn't want to begin doing any of that before they have been fully imported.

                                 

                                Thanks again for your help!

                                 

                                Val

                                  • Re: ImportDiscoveryResults (API)
                                    tomas.vrabel

                                    Documentation how to track import process can be found here: Discovery · solarwinds/OrionSDK Wiki · GitHub

                                    Please check end of chapter 'Importing discovery results'.

                                     

                                    I pasted below important part:

                                     

                                    The value returned from ImportDiscoveryResults is a GUID for tracking the progress of the import process. You can send this value to Orion.Discovery.GetImportDiscoveryResultsProgress to get an object with status.

                                    $status Invoke-SwisVerb $swis Orion.Discovery GetImportDiscoveryResultsProgress @($id)

                                    The status object has these properties:

                                    1. Finished - boolean indicating whether the import has completed or is still running
                                    2. OverallProgress - percent complete for the import process
                                    3. PhaseProgress - percent complete for the current import phase
                                    4. PhaseName - a string indicating what phase of the import is currently running
                                    5. NewLogText - text describing what has been imported so far. In a large discovery job, this text will be capped at 128kB and subsequent calls to GetImportDiscoveryResultsProgress will page through the complete text
                                      • Re: ImportDiscoveryResults (API)
                                        clarv02

                                        That's great, I didn't realize there was a way to check status. I'll just need to figure out how to do that in Python.

                                         

                                        And by the way, specifying the NodeIDs in importConfiguration does seem to work. It appears to have imported the nodes with the interfaces according to the filters I have in interfacesPluginContext. So this looks very promising indeed.

                                         

                                        Once again, thanks very much for all your help!

                                         

                                        Val