def orion_add_device(name, ip, instance, email, type, rhm, region, sn_group, description, consumer=None): host = orion_api.connect_info[instance]['host'] user = orion_api.connect_info[instance]['user'] password = orion_api.connect_info[instance]['password'] engine = orion_preferred_engine(instance) if not ('EngineID' in engine.keys() and 'ServerName' in engine.keys()): if consumer != None: details = 'Device Add Failed - Error finding preferred Orion polling engine' consumer.send_update(details) return {'status': 'Failure'}, {'details': details} engine_id = engine['EngineID'] engine_name = engine['ServerName'] swis = SwisClient(host, user, password) query = 'SELECT NodeID, IP_Address, DisplayName, DetailsUrl FROM Orion.Nodes WHERE IP_Address = \'%s\'' % ip results = swis.query(query) if len(results['results']) > 0: url = 'https://' + host + results['results'][0]['DetailsUrl'] return {'status': 'Failure'}, {'details': 'Duplicate Device: %s - %s (%s)' % (results['results'][0]['DisplayName'], ip, url)} snmpv3credential_poll_query = swis.query ('SELECT ID FROM Orion.Credential WHERE Name = \'nmspoll\'') snmpv3credential_write_query = swis.query ('SELECT ID FROM Orion.Credential WHERE Name = \'nmswrite\'') snmpv3credential_poll = snmpv3credential_poll_query['results'][0]['ID'] snmpv3credential_write = snmpv3credential_write_query['results'][0]['ID'] corePluginContext = { 'BulkList': [{'Address': name}], 'Credentials': [ { 'CredentialID': snmpv3credential_poll, 'Order': 1 } ], 'WmiRetriesCount': 0, 'WmiRetryIntervalMiliseconds': 1000 } interfacesPluginContext = { 'AutoImportStatus': ['Up','Down','Shutdown'], # 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 'AutoImportExpressionFilter': [ {'Prop': 'All','Op': '!Regex','Val':'^*null*'}, {'Prop': 'All','Op': '!Regex','Val':'^*backplane*'}, {'Prop': 'All','Op': '!Regex','Val':'^*unrout*'}, {'Prop': 'All','Op': '!Regex','Val':'^*controlled*'}, {'Prop': 'All','Op': '!Regex','Val':'^*pim register*'} ] } interfacesPluginConfig = swis.invoke('Orion.NPM.Interfaces', 'CreateInterfacesPluginConfiguration', interfacesPluginContext) corePluginConfig = swis.invoke('Orion.Discovery', 'CreateCorePluginConfiguration', corePluginContext) discoveryProfile = { 'Name': 'discover_node.py', 'EngineID': engine_id, 'JobTimeoutSeconds': 3600, 'SearchTimeoutMiliseconds': 5000, 'SnmpTimeoutMiliseconds': 5000, 'SnmpRetries': 2, 'RepeatIntervalMiliseconds': 1800, 'SnmpPort': 161, 'HopCount': 0, 'PreferredSnmpVersion': 'SNMP3', 'DisableIcmp': True, 'AllowDuplicateNodes': True, 'IsAutoImport': True, 'IsHidden': True, 'PluginConfigurations': [ {'PluginConfigurationItem': corePluginConfig}, {'PluginConfigurationItem': interfacesPluginConfig} ] } if consumer != None: consumer.send_update('Running discovery on Orion Engine %s...' % engine_name) discoveryProfileID = swis.invoke('Orion.Discovery', 'StartDiscovery', discoveryProfile) # 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: if consumer != None: consumer.send_update('!', newline=False) query = "SELECT Status FROM Orion.DiscoveryProfiles WHERE ProfileID = " + str(discoveryProfileID) result = swis.query(query) #print(result['results']) if len(result['results']) < 1: running = False break # Get out of the loop wihtout waiting the last 5 seconds time.sleep(5) # if consumer != None: # consumer.send_update('\nDiscovery Step Complete') query = "SELECT Result, ResultDescription, ErrorMessage, BatchID FROM Orion.DiscoveryLogs WHERE ProfileID = '" + str(discoveryProfileID) + "'" result = swis.query(query)['results'] result = result[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 EntityType = 'Orion.Nodes' and BatchID = '" + result['BatchID'] + "'" discovered = swis.query(query) if len(discovered['results']) < 1: return {'status': 'Failure'}, {'details': 'Discovery returned no results, your guess is as good as mine!'} nodeid = discovered['results'][0].get('NetObjectID', '')[2:] display_name = discovered['results'][0].get('DisplayName', '') ##following section is to set custom properties # if consumer != None: # consumer.send_update('Custom Property Update Test:') results = swis.query('SELECT Uri FROM Orion.Nodes WHERE NodeID=' + nodeid) # set valid NodeID! uri = results['results'][0]['Uri'] swis.update(uri + '/CustomProperties', Alerting_Email=email, Region=region, RHM=rhm, ServiceNowOwnerGroup=sn_group, DeviceType=type) # results = swis.read(uri + '/CustomProperties') # if consumer != None: # consumer.send_update(json.dumps(results, indent=4)) if consumer != None: # consumer.send_update(discovered) consumer.send_update('\nDiscovery Complete') if display_name != name and not name.startswith(display_name): consumer.send_update('\nERROR - Configured node name does not match Discovery: %s vs Add Request: %s' % (display_name, name)) return {'status': 'OK'}, {'nodeid': nodeid, 'displayname': display_name} else: if consumer != None: consumer.send_update('Discovery Failed\nERROR - check logs on Orion Engine - C:\ProgramData\SolarWinds\Discovery Engine') consumer.send_update(json.dumps(result, indent=4)) return {'status': 'Failure'}, {'details': result} |