11 Replies Latest reply on Jan 17, 2018 7:28 PM by clarv02

    ImportDiscoveryResults (API)


      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(
                      "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)

          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)

              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)

                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?



                  • Re: ImportDiscoveryResults (API)

                    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)

                        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',


                        DisableICMP = False


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


                        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)

                            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)

                                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!



                                  • Re: ImportDiscoveryResults (API)

                                    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)

                                        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!



                                          • Re: ImportDiscoveryResults (API)

                                            hello Tomas,


                                            I'm finally getting back to this, trying to get the Python code to import previously discovered nodes + interfaces. Since it's been a long time, I'm starting out by re-visiting this thread and trying to validate that when I provide list of NodeIDs instead of empty array for ImportDiscoveryResults verb, interfaces are imported too. And I'm finding that the interfaces do get imported (which is great), but for some reason ALL interfaces are being imported. In my last reply in this thread, I reported that interfaces were being imported per the filters in my interfacesPluginContext. So now I'm confused and don't understand why I thought the filters worked back in August but do not work now. (too bad my memory isn't better )


                                            What I'm finding is that when I run a discovery with AutoImport is True, then the filters in interfacesPluginContext are applied as the nodes are imported. But when I run ImportDiscoveryResults against a previous discovery (that had AutoImport = False), I get all interfaces with no filters applied. Can you think of what I might be missing? I have no idea how the interface filters could have worked back in August, since I'm doing the same thing now as I was then. Who knows...maybe I just wasn't looking close enough back then.


                                            discoveryProfileID = 240

                                            discovered_nodes = swis.query("SELECT NodeID FROM Orion.DiscoveredNodes "
                                                                          " WHERE ProfileID = " + str(discoveryProfileID))

                                            discovered_node_ids = []
                                            for i in discovered_nodes['results']:

                                            importConfiguration = {
                                                'ProfileID': discoveryProfileID,
                                                'NodeIDs': discovered_node_ids,
                                                'DeleteProfileAfterImport': False

                                            # Start Import
                                            print('Running Import...')
                                            result = swis.invoke('Orion.Discovery', 'ImportDiscoveryResults', importConfiguration)



                                            Thanks in advance!!!