def run(self, node): """ Query Solarwinds Orion. """ # Set up the results results = {} results['status'] = None results['color'] = None self.connect() orion_node = self.get_node(node) if not orion_node.npm: error_msg = "Node not found" send_user_error(error_msg) raise ValueError(error_msg) swql = "SELECT Status FROM Orion.Nodes WHERE NodeID=@NodeID" kargs = {'NodeID': orion_node.npm_id} orion_data = self.query(swql, **kargs) (results['status'], results['color']) = status_code_to_text( orion_data['results'][0]['Status']) results['node'] = str(orion_node) return results
def run(self, node, ipaddress): """ Update the IP address configured on an Orion Node. Args: - node: The caption in Orion of the node to poll. - ipaddress: The new IP address to assign to the Node. Returns - True: As PollNow does not return any data. Raises: - ValueError: When a node is not found. """ self.connect() orion_node = self.get_node(node) if not orion_node.npm: error_msg = "Node not found" send_user_error(error_msg) raise ValueError(error_msg) kargs = {"IPAddress": ipaddress} orion_data = self.update(orion_node.uri, **kargs) # This Invoke always returns None, so check and return True if orion_data is None: return True else: return orion_data
def run(self, platform, node, custom_property, value): """ Update a nodes Cutom Properties. """ self.connect(platform) orion_node = self.get_node(node) if not orion_node.npm: msg = "Node ({}) does not exist".format(node) send_user_error(msg) raise ValueError(msg) current_properties = self.read(orion_node.uri + '/CustomProperties') if custom_property not in current_properties: msg = "custom property {} does not exist!".format(custom_property) send_user_error(msg) raise ValueError(msg) kargs = {custom_property: value} orion_data = self.update(orion_node.uri + '/CustomProperties', **kargs) # This update returns None, so check just in case. # This happens even if the custom_property does not exist! if orion_data is None: return True else: return orion_data
def run(self, node, poller): """ Change the poller for an Orion Node. Args: - node: The caption in Orion of the node to poll. - poller: The poller to change the node too. Returns - True: As PollNow does not return any data. Raises: - ValueError: When a node is not found. """ self.connect() orion_node = self.get_node(node) if not orion_node.npm: error_msg = "Node not found" send_user_error(error_msg) raise ValueError(error_msg) engine_id = self.get_engine_id(poller) kargs = {"EngineID": engine_id} orion_data = self.update(orion_node.uri, **kargs) # This Invoke always returns None, so check and return True if orion_data is None: return True else: return orion_data
def run(self, node): """ Lists the Orion Custom Properties on an Node. Args: node: The caption in Orion of the node to poll. Returns: dict: Of data from Orion. Raises: UserWarning: If node does not exist. """ self.connect() orion_node = self.get_node(node) if not orion_node.npm: msg = "Node not in Orion NPM: {}".format(node) send_user_error(msg) raise UserWarning(msg) orion_data = self.read(orion_node.uri + '/CustomProperties') return orion_data
def run(self, node, custom_property): """ Gets a specific Node Custom Property. """ self.connect() orion_node = self.get_node(node) if not orion_node.npm: msg = "Node ({}) does not exist".format(node) send_user_error(msg) raise ValueError(msg) swql = """SELECT {1} FROM Orion.NodesCustomProperties WHERE NodeID={0}""".format(orion_node.npm_id, custom_property) data = self.query(swql) if 'results' not in data: msg = "No results from Orion: {}".format(data) self.logger.info(msg) raise Exception(msg) if len(data['results']) == 1: results = data['results'][0] return results.get(custom_property) elif len(data['results']) >= 2: self.logger.debug("Muliple Properties match '{}'".format(node)) raise ValueError("Muliple Properties match '{}'".format(node))
def run(self, node, platform): """ Query Solarwinds Orion. """ # Set up the results results = {} results["status"] = None results["color"] = None self.connect(platform) orion_node = self.get_node(node) if not orion_node.npm: error_msg = "Node not found" send_user_error(error_msg) raise ValueError(error_msg) swql = "SELECT Status FROM Orion.Nodes WHERE NodeID=@NodeID" kargs = {"NodeID": orion_node.npm_id} orion_data = self.query(swql, **kargs) (results["status"], results["color"]) = status_code_to_text(orion_data["results"][0]["Status"]) results["node"] = str(orion_node) return results
def run(self, node, custom_property, value): """ Update a nodes Cutom Properties. """ self.connect() orion_node = self.get_node(node) if not orion_node.npm: msg = "Node ({}) does not exist".format(node) send_user_error(msg) raise ValueError(msg) current_properties = self.read(orion_node.uri + "/CustomProperties") if custom_property not in current_properties: msg = "custom property {} does not exist!".format(custom_property) send_user_error(msg) raise ValueError(msg) kargs = {custom_property: value} orion_data = self.update(orion_node.uri + "/CustomProperties", **kargs) # This update returns None, so check just in case. # This happens even if the custom_property does not exist! if orion_data is None: return True else: return orion_data
def run(self, node, platform): """ Invoke a PollNow verb against a Orion Node. Args: node: The caption in Orion of the node to poll. platform: The orion platform to act on. Returns True: As PollNow does not return any data. Raises: IndexError: When a node is not found. """ self.connect(platform) orion_node = self.get_node(node) if not orion_node.npm: error_msg = "Node not found" send_user_error(error_msg) raise ValueError(error_msg) orion_data = self.invoke("Orion.Nodes", "PollNow", orion_node.npm_id) # This Invoke always returns None, so check and return True if orion_data is None: return True else: return orion_data
def run(self, maintenance_mode_enabled, node): """ Enable/disable maintenance mode in Solarwinds Orion to suppress/resume alerts for a given node """ self.connect() orion_node = self.get_node(node) if not orion_node.uri: error_msg = "Node not found for " + node send_user_error(error_msg) raise ValueError(error_msg) # Check if maintenance mode should be enabled or not if maintenance_mode_enabled: alert_action = "SuppressAlerts" else: alert_action = "ResumeAlerts" result = self.invoke("Orion.AlertSuppression", alert_action, [orion_node.uri]) return result
def get_snmp_cred_id(self, community): """ Look up an SNMP community in the config and then look up the Orion ID for the Credential. """ # Check if the community should be replaced. name = self.get_snmp_community(community) swql = """SELECT ID FROM Orion.Credential WHERE CredentialType=@CredentialType and Name=@name""" kargs = { 'CredentialType': 'SolarWinds.Orion.Core.Models.Credentials.SnmpCredentialsV2', 'name': name } orion_data = self.query(swql, **kargs) if len(orion_data['results']) == 1: return orion_data['results'][0]['ID'] else: msg = "Could not get ID for community in Orion.Credential: {}".format( community) send_user_error(msg) raise ValueError(msg)
def get_snmp_cred_id(self, community): """ Look up an SNMP community in the config and then look up the Orion ID for the Credential. """ # Check if community is a know standard, otherwise # use it as the community. try: name = self.get_snmp_community(None, community) except ValueError: name = community swql = """SELECT ID FROM Orion.Credential WHERE CredentialType=@CredentialType and Name=@name""" kargs = {'CredentialType': 'SolarWinds.Orion.Core.Models.Credentials.SnmpCredentialsV2', 'name': name} orion_data = self.query(swql, **kargs) if len(orion_data['results']) == 1: return orion_data['results'][0]['ID'] else: msg = "Could not get ID for community in Orion.Credential: {}".format( community) send_user_error(msg) raise ValueError(msg)
def run(self, nodes, count, pause): """ Invoke a PollNow verb against a Orion Node. Args: - node: The caption in Orion of the node to poll. - count: Number of polls to complete. - pause: Number of seconds to wait between each cycle. Returns True: As PollNow does not return any data. Raises: IndexError: When a nodes is not found. """ self.results = {'down': [], 'up': [], 'extra_count': False} self.connect() self.orion_nodes = [] for node in nodes: orion_node = self.get_node(node) if orion_node.npm: self.orion_nodes.append(orion_node.npm_id) else: error_msg = "Node not found" send_user_error(error_msg) raise ValueError(error_msg) for c in range(count): self._pollnow_nodes(count, pause) if len(self.orion_nodes) == 0: self.results['last_count'] = c break else: self.results['last_count'] = count if len(self.orion_nodes) > 0: self.results['extra_pass'] = True for c in range(count): self._pollnow_nodes(count, pause) else: self.results['left'] = self.orion_nodes # These Invoke's return None, so we just return True return self.results
def run(self, node, platform, configs): """ Download configurations via Solarwinds Orion NCM. see https://github.com/solarwinds/OrionSDK/wiki/NCM-Config-Transfer for more information. Args: node: platform: configs: Array of Configs to download. Returns: dict: Raises: Exception: If Node is not in NPM or NCM. """ results = {} node_ids = [] self.connect(platform) orion_node = self.get_node(node) if not orion_node.npm: error_msg = "Node not in NPM: {}".format(node) send_user_error(error_msg) raise Exception(error_msg) if not orion_node.ncm: error_msg = "Node not in NCM: {} ({})".format(node, orion_node.npm_id) send_user_error(error_msg) raise Exception(error_msg) node_ids.append(orion_node.ncm_id) for config in configs: orion_data = self.invoke("Cirrus.ConfigArchive", "DownloadConfig", node_ids, config) transfer_id = orion_data[0] results[config] = self.get_ncm_transfer_results(transfer_id) return results
def run(self, node, configs): """ Download configurations via Solarwinds Orion NCM. see https://github.com/solarwinds/OrionSDK/wiki/NCM-Config-Transfer for more information. Args: node: configs: Array of Configs to download. Returns: dict: Raises: Exception: If Node is not in NPM or NCM. """ results = {} node_ids = [] self.connect() orion_node = self.get_node(node) if not orion_node.npm: error_msg = "Node not in NPM: {}".format(node) send_user_error(error_msg) raise Exception(error_msg) if not orion_node.ncm: error_msg = "Node not in NCM: {} ({})".format(node, orion_node.npm_id) send_user_error(error_msg) raise Exception(error_msg) node_ids.append(orion_node.ncm_id) for config in configs: orion_data = self.invoke("Cirrus.ConfigArchive", "DownloadConfig", node_ids, config) transfer_id = orion_data[0] results[config] = self.get_ncm_transfer_results(transfer_id) return results
def connect(self, platform): """ Connect to an Orion platform from the packs config.yaml. """ if platform is None: try: platform = self.config['defaults']['platform'] except IndexError: send_user_error("No default Orion platform.") raise ValueError("No default Orion platform.") self.logger.debug("Connecting to Orion platform: {}".format(platform)) try: self.client = SwisClient( self.config['orion'][platform]['host'], self.config['orion'][platform]['user'], self.config['orion'][platform]['password']) except KeyError: raise ValueError("Orion host details not in the config.yaml") return platform
def run(self, node, interface, property, value): """ Update the Custom Properties of an Interface on a Node in Solarwinds. Args: node: Name of the Node to apply the changes to interface: Name of the interface to be updated property: Name of the NPM.interface table property to be updated value: The new value to apply to the interface custom property """ self.connect() orion_node = self.get_node(node) if not orion_node.npm: msg = "Node ({}) does not exist".format(node) send_user_error(msg) raise ValueError(msg) query = 'SELECT Uri FROM Orion.NPM.Interfaces WHERE NodeID=' \ + str(orion_node.npm_id) + 'AND IfName=\'' + interface + '\'' interface_uri = self.query(query) if not interface_uri['results']: msg = "Interface ({}) does not exist".format(interface) send_user_error(msg) raise ValueError(msg) if len(interface_uri['results']) > 1: msg = "Interface ({}) matches multiple entries on Node: {}".format(interface, node) send_user_error(msg) raise ValueError(msg) # Orquestra casts the string "True" to a boolean when sent to this action # as input. Check the input data for the str__ prefix and remove it # before passing it to Orion in the update function if value[0:5] == 'str__': # Split the text on the double underscore and reset the value variable # to the second part of the string value = value.split('__')[1] kargs = {property: value} self.logger.info('Updating Node: {} (Interface: {} Property: {} ' 'Value: {})'.format(node, interface, property, value)) orion_data = self.update(interface_uri['results'][0]['Uri'], **kargs) # This update returns None, so check just in case. # This happens even if the custom_property does not exist! if orion_data is None: return True else: return orion_data
def get_engine_id(self, poller): """ Takes a poller name (or primary) and returns the EngineID for the poller. Raises: ValueError on an invaild poller. Returns: The EngineID (int) """ if poller == "primary": return 1 else: swql = """SELECT EngineID, ServerName, IP, ServerType FROM Orion.Engines WHERE ServerName=@poller""" kargs = {'poller': poller} data = self.query(swql, **kargs) if len(data['results']) == 1: return data['results'][0]['EngineID'] else: send_user_error("Invalid poller name") raise ValueError("Invalid poller name")
def run(self, node, custompollers): """ Add list of SNMP Pollers to Node Args: - node: The caption in Orion of the node to poll. - custompollers: The list of Orion Custom SNMP pollers to add to the Node Returns - List of custom pollers that were added to the Node, a list of Custom pollers that were already assigned to the Node, and a list of Custom pollers that were not found in the system Raises: - ValueError: When a node is not found. """ # Create empty results dict to hold action output data results = {'added': [], 'existing': [], 'not_found': []} # Establish a connection to the Orion Server self.connect() # Find the Node in the system orion_node = self.get_node(node) if not orion_node.npm: error_msg = "Node not found" send_user_error(error_msg) raise ValueError(error_msg) # Create a query string needed to pull the custom poller data assigned to the Node # from the Orion DB self.logger.info( 'Querying list of custom pollers already configured on Node...') nodequery = 'SELECT NodeID, CustomPollerID FROM Orion.NPM.CustomPollerAssignmentOnNode ' \ 'WHERE NodeID=' + str(orion_node.npm_id) # Execute the query for the custom Node pollers nodeassignedpollers = self.query(nodequery) # Create an empty list of CustomPollerIDs used to hold the ID for each of the pollers # passed as input to the action custompollerids = [] # Loop through all the pollers provided as input to the action and query the Orion DB # for the CustomPollerID. for entry in custompollers: pollerquery = 'SELECT CustomPollerID, UniqueName FROM Orion.NPM.CustomPollers where ' \ 'UniqueName=\'' + str(entry) + '\'' entrypollerid = self.query(pollerquery) # Check if the Custom Poller query returned exactly 1 result as expected if len(entrypollerid['results']) == 1: # Check if Custom Poller ID is included in the list returned from the existing # poller query if any(element for element in nodeassignedpollers['results'] if element['CustomPollerID'] == entrypollerid['results'] [0]['CustomPollerID']): self.logger.info( 'Custom Poller {} already assigned to Node. Skipping...' ''.format(entry)) # Update results data with matching poller name results['existing'].append(entry) else: # Add Custom Poller ID to list if not found to have already been assigned to the # Node custompollerids.append(entrypollerid['results'][0]) # Check if the Custom poller query returned either 0 or more than the expected 1 if len(entrypollerid['results']) > 1 or len( entrypollerid['results']) == 0: self.logger.info( 'Custom poller {} not found in Orion DB or the text query returned' ' multiple entries and will be ignored...'.format(entry)) results['not_found'].append(entry) # After validating all the pollers have not already been assigned to the Node, loop # through all the entries and assign them to the Node for entry in custompollerids: entrydata = { "NodeID": str(orion_node.npm_id), "CustomPollerID": entry['CustomPollerID'] } response = self.create('Orion.NPM.CustomPollerAssignmentOnNode', **entrydata) self.logger.info( 'Custom poller {} successfully assigned to Node: {}'.format( entry['UniqueName'], response)) # Update results data with matching poller name results['added'].append(entry['UniqueName']) return results
def run(self, node, ip_address, poller, mon_protocol, community, status): """ Create an node in Orion. """ results = {} results['label'] = self.connect() self.logger.info("Connecting to Orion: {}".format( results['label'])) orion_node = self.get_node(node) if orion_node.npm: self.logger.error( "Node ({}) already in Orion: {}".format(orion_node, results['label'])) send_user_error("Node and/or IP is already in Orion!") raise ValueError("Node and/or IP already exists!") orion_ip_address = self.get_node(ip_address) if orion_ip_address.npm: self.logger.error( "IP ({}) already in Orion: {}".format( orion_ip_address, results['label'])) send_user_error("IP is already in Orion!") raise ValueError("IP already exists!") self.logger.info( "Checking node ({}) is not in Orion: {}".format( node, results['label'])) # engineID if happens to be None, default to the primary. if poller is not None: engineID = self.get_engine_id(poller) else: engineID = 1 kargs = {'Caption': node, 'EngineID': engineID, 'IPAddress': ip_address } if mon_protocol == "snmpv2": kargs['ObjectSubType'] = "SNMP" kargs['SNMPVersion'] = 2 # Check if the community should be replaced. kargs['Community'] = self.get_snmp_community(community) self.logger.info("Creating Orion Node: {}".format(kargs)) orion_data = self.create('Orion.Nodes', **kargs) self.logger.info("orion_data: {}".format(orion_data)) node_id = re.search('(\d+)$', orion_data).group(0) results['node_id'] = node_id self.logger.info("Created Orion Node: {}".format(results['node_id'])) pollers_to_add = { '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_Layer3.SNMP.ipNetToMedia': True, 'N.Routing.SNMP.Ipv4CidrRoutingTable': False } if status == 'icmp': pollers_to_add['N.Status.ICMP.Native'] = True pollers_to_add['N.Status.SNMP.Native'] = False pollers_to_add['N.ResponseTime.ICMP.Native'] = True pollers_to_add['N.ResponseTime.SNMP.Native'] = False elif status == 'snmp': pollers_to_add['N.Status.ICMP.Native'] = False pollers_to_add['N.Status.SNMP.Native'] = True pollers_to_add['N.ResponseTime.ICMP.Native'] = False pollers_to_add['N.ResponseTime.SNMP.Native'] = True pollers = [] for p in pollers_to_add: pollers.append({ 'PollerType': p, 'NetObject': 'N:{}'.format(node_id), 'NetObjectType': 'N', 'NetObjectID': node_id, 'Enabled': pollers_to_add[p] }) for poller in pollers: response = self.create('Orion.Pollers', **poller) self.logger.info("Added {} ({}) poller: {}".format( poller['PollerType'], poller['Enabled'], response)) return results
def run(self, name, poller, snmp_communities, nodes=None, subnets=None, ip_ranges=None, no_icmp_only=True, auto_import=False): """ Create and Start Discovery process in Orion. Returns: - ProfileID that was created (or error from Orion). """ results = {} # Orion must have the un-used varabiles to be certain values. BulkList = None IpRanges = [] Subnets = None results['label'] = self.connect() if not only_one(nodes, subnets, ip_ranges): msg = "Need only one out of nodes, ip_ranges or subnets!" send_user_error(msg) raise ValueError(msg) if nodes is not None: BulkList = [] for node in nodes: BulkList.append({'Address': node}) elif ip_ranges is not None: for ip_range in ip_ranges: (start_ip, end_ip) = ip_range.split(':') IpRanges.append({ 'StartAddress': start_ip, 'EndAddress': end_ip }) elif subnets is not None: Subnets = [] for subnet in subnets: (SubnetIP, SubnetMask) = subnet.split('/') Subnets.append({ 'SubnetIP': SubnetIP, 'SubnetMask': SubnetMask }) CredID_order = 1 CredIDs = [] for snmp in snmp_communities: CredIDs.append({ 'CredentialID': self.get_snmp_cred_id(snmp), 'Order': CredID_order }) CredID_order += 1 CorePluginConfiguration = self.invoke( 'Orion.Discovery', 'CreateCorePluginConfiguration', { 'BulkList': BulkList, 'IpRanges': IpRanges, 'Subnets': Subnets, 'Credentials': CredIDs, 'WmiRetriesCount': 0, 'WmiRetryIntervalMiliseconds': 1000 }) # engineID if happens to be None, default to the primary (aka 1). if poller is not None: engineID = self.get_engine_id(poller) else: engineID = 1 self.logger.info("Adding '{}' Discovery profile to Orion: {}".format( name, results['label'])) disco = self.invoke( 'Orion.Discovery', 'StartDiscovery', { 'Name': name, 'EngineId': engineID, 'JobTimeoutSeconds': 3600, 'SearchTimeoutMiliseconds': 2000, 'SnmpTimeoutMiliseconds': 2000, 'SnmpRetries': 4, 'RepeatIntervalMiliseconds': 1800, 'SnmpPort': 161, 'HopCount': 0, 'PreferredSnmpVersion': 'SNMP2c', 'DisableIcmp': no_icmp_only, 'AllowDuplicateNodes': False, 'IsAutoImport': auto_import, 'IsHidden': False, 'PluginConfigurations': [{ 'PluginConfigurationItem': CorePluginConfiguration }] }) # FIX ME Check job created.... return disco
def run(self, node, ip_address, poller, mon_protocol, community, status): """ Create an node in Orion. """ results = {} results['label'] = self.connect() self.logger.info("Connecting to Orion: {}".format(results['label'])) orion_node = self.get_node(node) if orion_node.npm: self.logger.error("Node ({}) already in Orion: {}".format( orion_node, results['label'])) send_user_error("Node and/or IP is already in Orion!") raise ValueError("Node and/or IP already exists!") orion_ip_address = self.get_node(ip_address) if orion_ip_address.npm: self.logger.error("IP ({}) already in Orion: {}".format( orion_ip_address, results['label'])) send_user_error("IP is already in Orion!") raise ValueError("IP already exists!") self.logger.info("Checking node ({}) is not in Orion: {}".format( node, results['label'])) # engineID if happens to be None, default to the primary. if poller is not None: engineID = self.get_engine_id(poller) else: engineID = 1 kargs = { 'Caption': node, 'EngineID': engineID, 'IPAddress': ip_address } if mon_protocol == "snmpv2": kargs['ObjectSubType'] = "SNMP" kargs['SNMPVersion'] = 2 # Check if the community should be replaced. kargs['Community'] = self.get_snmp_community(community) self.logger.info("Creating Orion Node: {}".format(kargs)) orion_data = self.create('Orion.Nodes', **kargs) self.logger.info("orion_data: {}".format(orion_data)) node_id = re.search('(\d+)$', orion_data).group(0) results['node_id'] = node_id self.logger.info("Created Orion Node: {}".format(results['node_id'])) pollers_to_add = { '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_Layer3.SNMP.ipNetToMedia': True, 'N.Routing.SNMP.Ipv4CidrRoutingTable': False } if status == 'icmp': pollers_to_add['N.Status.ICMP.Native'] = True pollers_to_add['N.Status.SNMP.Native'] = False pollers_to_add['N.ResponseTime.ICMP.Native'] = True pollers_to_add['N.ResponseTime.SNMP.Native'] = False elif status == 'snmp': pollers_to_add['N.Status.ICMP.Native'] = False pollers_to_add['N.Status.SNMP.Native'] = True pollers_to_add['N.ResponseTime.ICMP.Native'] = False pollers_to_add['N.ResponseTime.SNMP.Native'] = True pollers = [] for p in pollers_to_add: pollers.append({ 'PollerType': p, 'NetObject': 'N:{}'.format(node_id), 'NetObjectType': 'N', 'NetObjectID': node_id, 'Enabled': pollers_to_add[p] }) for poller in pollers: response = self.create('Orion.Pollers', **poller) self.logger.info("Added {} ({}) poller: {}".format( poller['PollerType'], poller['Enabled'], response)) return results
def run(self, node, ip_address, poller, snmpv3_username, privacy_protocol, privacy_password, auth_protocol, auth_password, status): """ Create an node in Orion. """ results = {} results['label'] = self.connect() self.logger.info("Connecting to Orion: {}".format(results['label'])) orion_node = self.get_node(node) if orion_node.npm: self.logger.error("Node ({}) already in Orion: {}".format( orion_node, results['label'])) send_user_error("Node and/or IP is already in Orion!") raise ValueError("Node and/or IP already exists!") orion_ip_address = self.get_node(ip_address) if orion_ip_address.npm: self.logger.error("IP ({}) already in Orion: {}".format( orion_ip_address, results['label'])) send_user_error("IP is already in Orion!") raise ValueError("IP already exists!") self.logger.info("Checking node ({}) is not in Orion: {}".format( node, results['label'])) # Set EngineID to 1/Primary by default engineID = 1 # If a poller value has been included in the Action input if poller: engineID = self.get_engine_id(poller) kargs = { 'Caption': node, 'EngineID': engineID, 'IPAddress': ip_address, 'ObjectSubType': 'SNMP', 'SNMPVersion': 3, 'SNMPV3Username': snmpv3_username, 'SNMPV3PrivMethod': privacy_protocol, 'SNMPV3PrivKeyIsPwd': True, 'SNMPV3PrivKey': privacy_password, 'SNMPV3AuthMethod': auth_protocol, 'SNMPV3AuthKeyIsPwd': True, 'SNMPV3AuthKey': auth_password, 'DNS': '', 'SysName': '' } self.logger.info("Creating Orion Node: {}".format(kargs)) orion_data = self.create('Orion.Nodes', **kargs) self.logger.info("orion_data: {}".format(orion_data)) node_id = re.search(r'(\d+)$', orion_data).group(0) results['node_id'] = node_id self.logger.info("Created Orion Node: {}".format(results['node_id'])) pollers_to_add = { 'N.Details.SNMP.Generic': True, 'N.Uptime.SNMP.Generic': True, 'N.Cpu.SNMP.HrProcessorLoad': False, 'N.Memory.SNMP.NetSnmpReal': False, 'N.AssetInventory.Snmp.Generic': False, 'N.Topology_Layer3.SNMP.ipNetToMedia': False, 'N.Routing.SNMP.Ipv4CidrRoutingTable': False } if status == 'icmp': pollers_to_add['N.Status.ICMP.Native'] = True pollers_to_add['N.Status.SNMP.Native'] = False pollers_to_add['N.ResponseTime.ICMP.Native'] = True pollers_to_add['N.ResponseTime.SNMP.Native'] = False elif status == 'snmp': pollers_to_add['N.Status.ICMP.Native'] = False pollers_to_add['N.Status.SNMP.Native'] = True pollers_to_add['N.ResponseTime.ICMP.Native'] = False pollers_to_add['N.ResponseTime.SNMP.Native'] = True pollers = [] for p in pollers_to_add: pollers.append({ 'PollerType': p, 'NetObject': 'N:{}'.format(node_id), 'NetObjectType': 'N', 'NetObjectID': node_id, 'Enabled': pollers_to_add[p] }) for poller in pollers: response = self.create('Orion.Pollers', **poller) self.logger.info("Added {} ({}) poller: {}".format( poller['PollerType'], poller['Enabled'], response)) return results
def run(self, name, platform, poller, snmp_communities, nodes=None, subnets=None, ip_ranges=None, no_icmp_only=True, auto_import=False): """ Create and Start Discovery process in Orion. Returns: - ProfileID that was created (or error from Orion). """ results = {} # Orion must have the un-used varabiles to be certain values. BulkList = None IpRanges = [] Subnets = None results['platform'] = self.connect(platform) if not only_one(nodes, subnets, ip_ranges): msg = "Need only one out of nodes, ip_ranges or subnets!" send_user_error(msg) raise ValueError(msg) if nodes is not None: BulkList = [] for node in nodes: BulkList.append({'Address': node}) elif ip_ranges is not None: for ip_range in ip_ranges: (start_ip, end_ip) = ip_range.split(':') IpRanges.append({'StartAddress': start_ip, 'EndAddress': end_ip}) elif subnets is not None: Subnets = [] for subnet in subnets: (SubnetIP, SubnetMask) = subnet.split('/') Subnets.append({'SubnetIP': SubnetIP, 'SubnetMask': SubnetMask}) CredID_order = 1 CredIDs = [] for snmp in snmp_communities: CredIDs.append( {'CredentialID': self.get_snmp_cred_id(snmp), 'Order': CredID_order} ) CredID_order += 1 CorePluginConfiguration = self.invoke('Orion.Discovery', 'CreateCorePluginConfiguration', {'BulkList': BulkList, 'IpRanges': IpRanges, 'Subnets': Subnets, 'Credentials': CredIDs, 'WmiRetriesCount': 0, 'WmiRetryIntervalMiliseconds': 1000}) # engineID if happens to be None, default to the primary (aka 1). if poller is not None: engineID = self.get_engine_id(poller) else: engineID = 1 self.logger.info( "Adding '{}' Discovery profile to Orion Platform {}".format( name, platform)) disco = self.invoke('Orion.Discovery', 'StartDiscovery', { 'Name': name, 'EngineId': engineID, 'JobTimeoutSeconds': 3600, 'SearchTimeoutMiliseconds': 2000, 'SnmpTimeoutMiliseconds': 2000, 'SnmpRetries': 4, 'RepeatIntervalMiliseconds': 1800, 'SnmpPort': 161, 'HopCount': 0, 'PreferredSnmpVersion': 'SNMP2c', 'DisableIcmp': no_icmp_only, 'AllowDuplicateNodes': False, 'IsAutoImport': auto_import, 'IsHidden': False, 'PluginConfigurations': [ {'PluginConfigurationItem': CorePluginConfiguration} ] }) # FIX ME Check job created.... return disco