def main(): npm_server = 'localhost' username = '******' password = '' swis = SwisClient(npm_server, username, password) print("Add an SNMP v2c node:") # fill these in for the node you want to add! ip_address = '127.0.0.1' community = 'public' # set up property bag for the new node props = { 'IPAddress': ip_address, 'EngineID': 1, 'ObjectSubType': 'SNMP', 'SNMPVersion': 2, 'Community': community } print("Adding node {}... ".format(props['IPAddress']), end="") results = swis.create('Orion.Nodes', **props) print("DONE!") # extract the nodeID from the result nodeid = re.search('(\d+)$', results).group(0) pollers_enabled = { 'N.Status.ICMP.Native': True, 'N.Status.SNMP.Native': False, 'N.ResponseTime.ICMP.Native': True, 'N.ResponseTime.SNMP.Native': False, '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': False, 'N.Routing.SNMP.Ipv4CidrRoutingTable': False } pollers = [] for k in pollers_enabled: pollers.append( { 'PollerType': k, 'NetObject': 'N:' + nodeid, 'NetObjectType': 'N', 'NetObjectID': nodeid, 'Enabled': pollers_enabled[k] } ) for poller in pollers: print(" Adding poller type: {} with status {}... ".format(poller['PollerType'], poller['Enabled']), end="") response = swis.create('Orion.Pollers', **poller) print("DONE!")
def main(): global __SWIS__ module = AnsibleModule( argument_spec=dict(hostname=dict(required=True), username=dict(required=True, no_log=True), password=dict(required=True, no_log=True), state=dict(required=True, choices=['update']), node_id=dict(required=False), caption=dict(required=False), env=dict(required=False), fisma=dict(required=False), project_lead=dict(required=False), sme=dict(required=False))) options = { 'hostname': module.params['hostname'], 'username': module.params['username'], 'password': module.params['password'] } __SWIS__ = SwisClient(**options) try: __SWIS__.query('SELECT Uri FROM Orion.Environment') except Exception as e: module.fail_json( msg= "Failed to query Orion. Check Hostname, Username, and Password : {0}" .format(str(e))) if module.params['state'] == 'update': _custom_props(module)
def main(): npm_server = 'localhost' username = '******' password = '' swis = SwisClient(npm_server, username, password) print("Discover and add interfaces:") results = swis.invoke('Orion.NPM.Interfaces', 'DiscoverInterfacesOnNode', 1) # use the results['DiscoveredInterfaces'] for all interfaces # or get a subset of interfaces using a comprehension like below eth_only = [ x for x in results['DiscoveredInterfaces'] if x['Caption'].startswith('eth') ] print(eth_only) results2 = swis.invoke( 'Orion.NPM.Interfaces', 'AddInterfacesOnNode', 1, # use a valid nodeID! eth_only, 'AddDefaultPollers') print(results2)
def do_get_ip_ranges(self, auth_credentials, cert): username = auth_credentials["privateKeyId"] password = auth_credentials["privateKey"] hostname = self.inputs["endpoint"]["endpointProperties"]["hostName"] requests.packages.urllib3.disable_warnings() swis = SwisClient(hostname, username, password) result_ranges = [] qResult = swis.query( "SELECT DISTINCT GroupID AS id, FriendlyName AS name, Address AS addressSpaceId, CIDR AS subnetPrefixLength, Comments AS description, i.CustomProperties.Gateway as gatewayAddress, i.CustomProperties.DNS_Servers as dnsServers, i.CustomProperties.Site_ID AS siteId FROM IPAM.GroupNode i WHERE GroupTypeText LIKE 'Subnet' AND i.CustomProperties.VRA_Range = TRUE" ) for range in qResult['results']: logging.info(f"Found subnet: {str(range['name'])}") network = ipaddress.ip_network( str(range['addressSpaceId']) + '/' + str(range['subnetPrefixLength'])) range['ipVersion'] = 'IPv' + str(network.version) range['startIPAddress'] = str(network[10]) range['endIPAddress'] = str(network[-6]) range['dnsServerAddresses'] = [ server.strip() for server in str(range['dnsServers']).split(',') ] range['tags'] = [{"key": "Site", "value": range['siteId']}] result_ranges.append(range) result = {"ipRanges": result_ranges} return result
def run(job=None, *args, **kwargs): # Disable SSL errors verify = False if not verify: requests.packages.urllib3.disable_warnings(InsecureRequestWarning) # Get SolarWinds ConnectionInfo solarwinds = ConnectionInfo.objects.get(name='SolarWinds') swis = SwisClient(solarwinds.ip, solarwinds.username, solarwinds.password) if not solarwinds: return "FAILURE", "", "Missing required SolarWinds connection info. (Admin -> Connection Info -> New Connection Info)" # Get Server Info server = job.server_set.first() # Find the Uri you want to delete based on a SWQL query results = swis.query("select ipaddress, caption, uri from orion.nodes where ipaddress = '{}'".format(server.ip)) # Use as needed if len(results['results']) > 1: print('Refine your search. Found more than one node matching that criteria.') elif len(results['results']) == 1: print("Deleting {}".format(results['results'][0]['ipaddress'])) response = swis.delete(results['results'][0]['uri']) print("Done") else: print("Nothing to delete from SolarWinds") return "","",""
def main(): npm_server = 'localhost' username = '******' password = '' swis = SwisClient(npm_server, username, password) print("Discover and add interfaces:") results = swis.invoke('Orion.NPM.Interfaces', 'DiscoverInterfacesOnNode', 1) # use the results['DiscoveredInterfaces'] for all interfaces # or get a subset of interfaces using a comprehension like below eth_only = [ x for x in results['DiscoveredInterfaces'] if x['Caption'].startswith('eth')] print(eth_only) results2 = swis.invoke( 'Orion.NPM.Interfaces', 'AddInterfacesOnNode', 1, # use a valid nodeID! eth_only, 'AddDefaultPollers') print(results2)
def do_validate_endpoint(self, auth_credentials, _): """ Main function. Get inputs, create connection with IPAM server, execute test request and prepare results """ try: username = auth_credentials["privateKeyId"] password = auth_credentials["privateKey"] ignore_ssl_warning = self.inputs["endpointProperties"] \ ["ignoreSslWarning"].lower() == "true" if ignore_ssl_warning: requests.packages.urllib3.disable_warnings(InsecureRequestWarning) swis = SwisClient(self.inputs["endpointProperties"]["hostName"], \ username, password) logging.info("Start testing endpoint") query = """SELECT TOP 3 NodeID, DisplayName FROM Orion.Nodes WHERE DisplayName='test_request' """ response = swis.query(query) logging.info("Received the following response: %s", str(response)) if response: return {"message": "Validated successfully", "statusCode": "200"} except Exception as error: logging.error("Unexpected exception: %s", str(error)) raise error #return self._build_error_response("5000", str(error)) return None
def do_validate_endpoint(self, auth_credentials, cert): username = auth_credentials["privateKeyId"] password = auth_credentials["privateKey"] hostname = self.inputs["endpointProperties"]["hostName"] swis = SwisClient(hostname, username, password) requests.packages.urllib3.disable_warnings() try: response = swis.invoke( 'Metadata.Entity', 'GetAliases', 'SELECT B.Caption FROM Orion.Nodes B' ) if response != "": return { "message": "Validated successfully" } else: raise Exception("Failed to connect") except Exception as e: """ In case of SSL validation error, a InvalidCertificateException is raised. So that the IPAM SDK can go ahead and fetch the server certificate and display it to the user for manual acceptance. """ # if "SSLCertVerificationError" in str(e) or "CERTIFICATE_VERIFY_FAILED" in str(e) or 'certificate verify failed' in str(e): # raise InvalidCertificateException("certificate verify failed", self.inputs["endpointProperties"]["hostName"], 443) from e raise e
def run(job=None, *args, **kwargs): # Disable SSL errors verify = False if not verify: from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) # Get SolarWinds ConnectionInfo solarwinds = ConnectionInfo.objects.get(name='SolarWinds') swis = SwisClient(solarwinds.ip, solarwinds.username, solarwinds.password) if not solarwinds: return "FAILURE", "", "Missing required SolarWinds connection info. (Admin -> Connection Info -> New Connection Info)" # Get Server Info server = job.server_set.first() hostname = "{}.{}".format(server.hostname, server.env_domain) #ip_address = server.ip # Query Solarwinds for the FQDN & IP job.set_progress("Checking if hostname '{}' is already in SolarWinds".format(hostname)) hostname_results = swis.query("select n.ipaddress, n.nodename from orion.nodes n where nodename = '{}'".format(hostname)) #ip_results = swis.query("select n.ipaddress, status from orion.nodes n where status=2 and ipaddress ='{}'".format(ip_address)) #if len(hostname_results) | len(ip_results) > 0: if len(hostname_results.values()[0]) > 0: return 'FAILURE', '', "Found hostname '{}' in Solarwinds.".format(hostname) else: job.set_progress("'{}' not found in Solarwinds.".format(hostname)) return "","",""
def main(): npm_server = 'localhost' username = '******' password = '' swis = SwisClient(npm_server, username, password) print("Add an SNMP v2c node:") # fill these in for the node you want to add! ip_address = '127.0.0.1' community = 'public' # set up property bag for the new node props = { 'IPAddress': ip_address, 'EngineID': 1, 'ObjectSubType': 'SNMP', 'SNMPVersion': 2, 'Community': community, 'DNS': '', 'SysName': '' } print("Adding node {}... ".format(props['IPAddress']), end="") results = swis.create('Orion.Nodes', **props) print("DONE!") # extract the nodeID from the result nodeid = re.search(r'(\d+)$', results).group(0) pollers_enabled = { 'N.Status.ICMP.Native': True, 'N.Status.SNMP.Native': False, 'N.ResponseTime.ICMP.Native': True, 'N.ResponseTime.SNMP.Native': False, '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': False, 'N.Routing.SNMP.Ipv4CidrRoutingTable': False } pollers = [] for k in pollers_enabled: pollers.append({ 'PollerType': k, 'NetObject': 'N:' + nodeid, 'NetObjectType': 'N', 'NetObjectID': nodeid, 'Enabled': pollers_enabled[k] }) for poller in pollers: print(" Adding poller type: {} with status {}... ".format( poller['PollerType'], poller['Enabled']), end="") response = swis.create('Orion.Pollers', **poller) print("DONE!")
def main(): module = AnsibleModule(argument_spec=dict( api_url=dict(required=True, default=None), username=dict(required=True, default=None), password=dict(required=True, default=None, no_log=True), subnet=dict(required=True), validate_certs=dict(required=False, default=True)), required_together=[['username', 'password']], supports_check_mode=False) api_url = module.params['api_url'] username = module.params['username'] password = module.params['password'] subnet = module.params['subnet'] validate_certs = module.params['validate_certs'] requests.packages.urllib3.disable_warnings(InsecureRequestWarning) client = SwisClient(api_url, username, password, verify=validate_certs) query = "SELECT TOP 255 I.DisplayName FROM IPAM.IPNode I WHERE Status=2 AND I.Subnet.DisplayName Like '{}%'".format( subnet) response = client.query(query) available_ip_addresses = [ ip_node['DisplayName'] for ip_node in response['result'] ] module.exit_json(changed=True, available_ip_addresses=available_ip_addresses)
def solarwinds_query(npm_server, username, password): verify = False if not verify: from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) swis = SwisClient(npm_server, username, password) node_results = swis.query("SELECT IPAddress from Orion.Nodes n where n.Vendor = 'Cisco'") return node_results
def __init__(self): with open('/path/to/creds.json') as credentials: self.creds = json.load(credentials) self.npm_server = 'x.x.x.x' # Your server that's running Solarwinds self.username = self.creds['sw_username'] self.password = self.creds['sw_password'] requests.packages.urllib3.disable_warnings() self.swis = SwisClient(self.npm_server, self.username, self.password)
def __init__(self, user, pwd, url): self._user = user self._pwd = pwd self.auth = (self._user, self._pwd) if re.search('http://(.+)', url): stripped = re.search('http://(.+)', url) url = stripped.group(1) self._swis = SwisClient(url, user, pwd)
def main(): npm_server = 'localhost' username = '******' password = '' swis = SwisClient(npm_server, username, password) print("Query Test:") results = swis.query("SELECT Uri FROM Orion.Nodes WHERE NodeID=@id", id=1) # set valid NodeID! uri = results['results'][0]['Uri'] print(uri)
def __init__(self): # start the connection self.server = 'server fqdn or ip' self.username = '******' self.password = '******' self.con = SwisClient(self.server,self.username,self.password) requests.packages.urllib3.disable_warnings()
def main(): npm_server = 'localhost' username = '******' password = '' swis = SwisClient(npm_server, username, password) print("Invoke Test:") aliases = swis.invoke('Metadata.Entity', 'GetAliases', 'SELECT B.Caption FROM Orion.Nodes B') print(aliases)
def connect(self): """ Connect to the Orion server listed in the config. """ self.client = SwisClient(self.config['orion_host'], self.config['orion_user'], self.config['orion_password']) return self.config['orion_label']
def connect(self, platform): """ Connect to an Orion platform from the packs config.yaml. """ 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")
def main(): npm_server = 'localhost' username = '******' password = '' swis = SwisClient(npm_server, username, password) print("Invoke Test:") aliases = swis.invoke( 'Metadata.Entity', 'GetAliases', 'SELECT B.Caption FROM Orion.Nodes B') print(aliases)
def main(): npm_server = 'localhost' username = '******' password = '' AlertID = 1 #AlertID for which we export data in xml file. swis = SwisClient(npm_server, username, password) results = swis.invoke('Orion.AlertConfigurations', 'Export', AlertID) print(results) with open('out.xml', 'w') as f: f.write(results)
def main(): hostname = 'localhost' username = '******' password = '' swis = SwisClient(hostname, username, password) results = swis.query('SELECT TOP 1 NodeID FROM Orion.Nodes') interfaceId = results['results'][0]['NodeID'] netObjectId = 'N:{}'.format(interfaceId) now = datetime.utcnow() tomorrow = now + timedelta(days=1) swis.invoke('Orion.Nodes', 'Unmanage', netObjectId, now, tomorrow, False)
def main(): hostname = 'localhost' username = '******' password = '' swis = SwisClient(hostname, username, password) results = swis.query('SELECT TOP 1 NodeID FROM Orion.Nodes') nodeId = results['results'][0]['NodeID'] netObjectId = 'N:{}'.format(nodeId) now = datetime.utcnow() tomorrow = now + timedelta(days=1) swis.invoke('Orion.Nodes', 'Unmanage', netObjectId, now, tomorrow, False)
class Solar(): def __init__(self, npm_server, username, password): """ This class mainly aims to represent information in your Solarwinds with consuming abilities of Orion sdk """ #Creating an instance for Your solarwinds self.swis = SwisClient(npm_server, username, password) def getInterfacesByIp(self, nodeIP): """ This function get information of device in Solarwinds with ip parameter, For doing this, It get if of node, if it exists, If device exist in Solarwinds, It finds interfaces of it, and return this Solarwinds_Node with interface information and set 'True' to existence.existence variable """ #Creating a temporary Solarwinds node to collect information with proper tempNode = Solarwinds_Node(nodeIP) stepNumber = 0 try: #Step 1 is performed for taking ID information of device with ip address given as parameter to this function, if device exists in Solarwinds print("Step 1 for " + nodeIP) nodeIDGetter = self.swis.query( "SELECT n.NodeID FROM Orion.Nodes n WHERE n.IPAddress = '" + nodeIP + "'") print("NodeID of " + nodeIP + " is " + str(nodeIDGetter['results'][0]['NodeID'])) #If the above line doesn't throw an error, next line says that there is a device this ip in Solarwinds tempNode.existence = True #And step 1 is completed stepNumber = 1 #In step 2, interfaces of device are searched with device Solarwinds id print("Step 2 for " + nodeIP) queryForInterfaces = self.swis.query( "SELECT I.InterfaceID, I.Name, I.AdminStatus, I.OperStatus, I.Status FROM Orion.NPM.Interfaces I WHERE I.NodeID=" + str(nodeIDGetter['results'][0]['NodeID'])) tempNode.nodeID = str(nodeIDGetter['results'][0]['NodeID']) #print(queryForInterfaces) for interfaceInfo in queryForInterfaces['results']: tempInterface = Solarwinds_Interface(interfaceInfo['Name']) tempInterface.interfaceID = interfaceInfo['InterfaceID'] if interfaceInfo['Status'] == 1: tempInterface.adminState = 'up' tempInterface.operationalState = 'up' else: tempInterface.adminState = 'down' tempInterface.operationalState = 'down' tempNode.monitoredInterfaces.append(tempInterface) except Exception, e: print("Failed process for " + nodeIP + " on step of " + str(stepNumber)) print(str(e)) finally:
def main(): npm_server = 'localhost' username = '******' password = '' importfile = 'out.xml' #file which contain AlertConfiguration in xml format. swis = SwisClient(npm_server, username, password) with open(importfile, 'r') as f: alert = f.read() results = swis.invoke('Orion.AlertConfigurations', 'Import', alert) print(results)
def setAllTargetGroups(): #get all nodes from target server to create index for URI swis = SwisClient(TargetServer['ip'], TargetServer['username'], TargetServer['password'], TargetServer['verify']) results = swis.query("SELECT Name, Uri FROM Orion.Container") try: for row in results['results']: TargetGroups.append({row['Name']:row['Uri']}) return TargetGroups except(KeyError): try: print results['Message'] except(KeyError): print "Error"
def __init__(self, *args, verify=settings.ORION_VERIFY_SSL_CERT): """ :arg args: (host, user, password) for the orion server this is not the cleanest implementation because we are not doing any error checking. OTOH, this is not exactly aiming for production quality but for expediency """ if not args: args = SRC_DEFAULTS self.orion_connection = SwisClient(*args, verify=verify)
def getDedupGroups(): swis = SwisClient(TargetServer['ip'], TargetServer['username'], TargetServer['password'], TargetServer['verify']) results = swis.query("SELECT c.name, m.definition FROM Orion.Container c join Orion.ContainerMemberDefinition m on c.ContainerID=m.ContainerID") group=[] try: for row in results['results']: node={'name':row['name'], 'definition':row['definition']} group.append(node) except(KeyError): try: return results['Message'] except(KeyError): return "Error" return group
def getNodeGroups(server, user, pwd, verify=False): swis = SwisClient(server, user, pwd, verify=False) groups=[] #Note: this query may be need to be altered depending on the version of NPM and current configuration. results = swis.query("SELECT n.IP_Address, n.DNS, c.Name, m.Description FROM Orion.Nodes n JOIN Orion.ContainerMemberDefinition m ON m.Expression = 'Nodes.NodeID='+toString(n.NodeID) JOIN Orion.Container c ON m.ContainerID=c.ContainerID WHERE m.Entity='Orion.Nodes'") try: for row in results['results']: node={'ip':row['IP_Address'], 'hostname':row['DNS'], 'groupname':row['Name'], 'groupdesc':row['Description']} groups.append(node) except(KeyError): try: return results['Message'] except(KeyError): return "Error" return groups
def main(): npm_server = 'localhost' username = '******' password = '' swis = SwisClient(npm_server, username, password) print("Custom Property Update Test:") results = swis.query( "SELECT Uri FROM Orion.Nodes WHERE NodeID=@id", id=1) # set valid NodeID! uri = results['results'][0]['Uri'] swis.update(uri + '/CustomProperties', City='Austin') obj = swis.read(uri + '/CustomProperties') print (obj)
def __init__(self): fields = { "nodename": {"required": True, "type": "str"}, "ip_address": {"required": True, "type": "str"}, "device_func": {"default": "", "type": "str"}, "action": {"required": True, "type": "str"}, } module = AnsibleModule(argument_spec=fields) """Check if module exists before importing""" try: imp.find_module('orionsdk') from orionsdk import SwisClient except ImportError: module.fail_json(msg="'orionsdk' not found. Is the module installed?") module.exit_json(changed=True) SW_Server = 'solarwinds.nj01' SW_User = '******' SW_Passwd = 'SOLAR_5689!' self.swis = SwisClient(SW_Server, SW_User, SW_Passwd) self.node = module.params['nodename'] self.ipaddr = module.params['ip_address'] self.action = module.params['action'] self.devfunc = module.params['device_func'] self.module = module requests.packages.urllib3.disable_warnings()
def do_get_ip_ranges(self, auth_credentials, _): """ Main function. Get inputs, create connection with IPAM server, execute operation and prepare results """ username = auth_credentials["privateKeyId"] password = auth_credentials["privateKey"] ignore_ssl_warning = self.inputs["endpoint"]["endpointProperties"] \ ["ignoreSslWarning"].lower() == "true" if ignore_ssl_warning: requests.packages.urllib3.disable_warnings(InsecureRequestWarning) swis = SwisClient(self.inputs["endpoint"]["endpointProperties"] \ ["hostName"], username, password) page_token = self.inputs['pagingAndSorting'].get('pageToken', None) max_results = self.inputs['pagingAndSorting'].get('maxResults', 25) dns_servers = get_input_property(self.inputs, "SolarWinds.dnsServers") dns_domain = get_input_property(self.inputs, "SolarWinds.dnsDomain") ranges, next_page_token = collect_ranges(swis, page_token, max_results, \ dns_servers, dns_domain) result = {"ipRanges": ranges} if next_page_token is not None: result["nextPageToken"] = next_page_token return result
class APIPlugin: _headers = { "Content-Type": "application/json", "Accept": "application/json" } def __init__(self, user, pwd, url): self._user = user self._pwd = pwd self.auth = (self._user, self._pwd) if re.search('http://(.+)', url): stripped = re.search('http://(.+)', url) url = stripped.group(1) if re.search('https://(.+)', url): stripped = re.search('https://(.+)', url) url = stripped.group(1) self._swis = SwisClient(url, user, pwd) def _query(self, query, deviceName): try: response = self._swis.query(query, id=deviceName) return response except Exception as e: return str(e)
def do_allocate_ip(self, auth_credentials, _): """ Main function. Get inputs, create connection with IPAM server, execute operation and prepare results """ username = auth_credentials["privateKeyId"] password = auth_credentials["privateKey"] ignore_ssl_warning = self.inputs["endpoint"]["endpointProperties"] \ ["ignoreSslWarning"].lower() == "true" if ignore_ssl_warning: requests.packages.urllib3.disable_warnings(InsecureRequestWarning) swis = SwisClient(self.inputs["endpoint"]["endpointProperties"] \ ["hostName"], username, password) allocation_result = [] try: #resource = self.inputs["resourceInfo"] for allocation in self.inputs["ipAllocations"]: allocation_result.append(allocate(swis, allocation)) except Exception as error: try: rollback(swis, allocation_result) except Exception as rollback_e: logging.error("Error in IP deallocation %s", str(allocation_result)) logging.error(rollback_e) raise error assert len(allocation_result) > 0 return { "ipAllocations": allocation_result }
class SourceSwis(): # pylint: disable=too-few-public-methods """ wrap around the SwisClient for a cleaner look provides only methods for reading data from the server """ def __init__(self, *args, verify=settings.ORION_VERIFY_SSL_CERT, logger=LOG): """ :arg args: (host, user, password) for the orion server this is not the cleanest implementation because we are not doing any error checking. OTOH, this is not exactly aiming for production quality but for expediency """ self.logger = logger if not args: args = SRC_DEFAULTS # pylint: disable=no-value-for-parameter self.orion_connection = SwisClient(*args, verify=verify) # pylint: enable=no-value-for-parameter def query(self, query, **params): """ call the SwisClient query method and return just the results """ return self.orion_connection.query(query, **params).get('results')
def main(): npm_server = 'localhost' username = '******' password = '' target_node_ip = '1.2.3.4' snmpv3_credential_id = 3 orion_engine_id = 1 swis = SwisClient(npm_server, username, password) print("Add an SNMP v3 node:") corePluginContext = { 'BulkList': [{'Address': target_node_ip}], 'Credentials': [ { 'CredentialID': snmpv3_credential_id, 'Order': 1 } ], 'WmiRetriesCount': 0, 'WmiRetryIntervalMiliseconds': 1000 } corePluginConfig = swis.invoke('Orion.Discovery', 'CreateCorePluginConfiguration', corePluginContext) discoveryProfile = { 'Name': 'discover_one_node.py', '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': True, 'PluginConfigurations': [{'PluginConfigurationItem': corePluginConfig}] } print("Running discovery...") result = swis.invoke('Orion.Discovery', 'StartDiscovery', discoveryProfile) print("Returned discovery profile id {}".format(result))
def main(): hostname = 'localhost' username = '******' password = '' swis = SwisClient(hostname, username, password) results = swis.query('SELECT NodeID, Caption FROM Orion.Nodes WHERE IPAddress = @ip_addr', ip_addr='127.0.0.1') if results['results']: nodeId = results['results'][0]['NodeID'] caption = results['results'][0]['Caption'] netObjectId = 'N:{}'.format(nodeId) now = datetime.utcnow() tomorrow = now + timedelta(days=1) swis.invoke('Orion.Nodes', 'Unmanage', netObjectId, now, tomorrow, False) print('Done...{} will be unmanaged until {}'.format(caption, tomorrow)) else: print("Device doesn't Exist")
def main(): swis = SwisClient(npm_server, username, password) query = """ SELECT TOP 10 n.NodeID, n.Caption AS NodeName, i.InterfaceID, i.Caption AS InterfaceName FROM Orion.Nodes n JOIN Orion.NPM.Interfaces i ON n.NodeID = i.NodeID """ results = swis.query(query) for row in results['results']: print("{NodeID} [{NodeName}] : {InterfaceID} [{InterfaceName}]".format(**row))
def main(): npm_server = 'localhost' username = '******' password = '' swis = SwisClient(npm_server, username, password) ip = '10.199.252.6' data = swis.query('SELECT NodeID FROM Cirrus.Nodes WHERE AgentIP = @ip', ip=ip)['results'] nodeId = data[0]['NodeID'] script = 'show clock' swis.invoke('Cirrus.ConfigArchive', 'Execute', [nodeId], script, username) transferId = '{{{0}}}:{1}:ExecuteScript'.format(nodeId, username) status = 'Queued' while status != 'Complete' and status != 'Error': sleep(1) data = swis.query('SELECT T.Status, T.Error FROM Cirrus.TransferQueue T WHERE T.TransferID=@transfer', transfer=transferId)['results'] status = data[0]['Status'] data = swis.query('SELECT T.Log FROM Cirrus.TransferQueue T WHERE T.TransferID=@transfer', transfer=transferId)['results'] output = data[0]['Log'] print(output)
def main(): npm_server = 'localhost' username = '******' password = '' swis = SwisClient(npm_server, username, password) # # CREATING A NEW GROUP # # Creating a new group with initial Cisco and Windows devices. # swis.invoke('Orion.Container', 'CreateContainer', # group name 'Sample Python Group', # owner, must be 'Core' 'Core', # refresh frequency in seconds 60, # Status rollup mode: # 0 = Mixed status shows warning # 1 = Show worst status # 2 = Show best status 0, # group description 'Group created by the Python sample script.', # polling enabled/disabled = true/false True, # group members [ {'Name': 'Cisco Devices', 'Definition': "filter:/Orion.Nodes[Vendor='Cisco']"}, {'Name': 'Windows Devices', 'Definition': "filter:/Orion.Nodes[Vendor='Windows']"} ] )
def main(): npm_server = 'localhost' username = '******' password = '' swis = SwisClient(npm_server, username, password) r = swis.query('SELECT TOP 1 AlertObjectID FROM Orion.AlertActive ORDER BY TriggeredDateTime DESC')['results'] if len(r) == 0: print('No active alerts found.') return alertObjectId = r[0]['AlertObjectID'] alerts = [alertObjectId] # AppendNode expects a list of AlertObjectID values note = 'Python was here' success = swis.invoke('Orion.AlertActive', 'AppendNote', alerts, note) if success: print('It worked.') else: print('Something went wrong.')
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
class OrionBaseAction(Action): def __init__(self, config): super(OrionBaseAction, self).__init__(config) self.client = None if "orion_host" not in self.config: raise ValueError("Orion host details not in the config.yaml") elif "orion_user" not in self.config: raise ValueError("Orion user details not in the config.yaml") elif "orion_password" not in self.config: raise ValueError("Orion password details not in the config.yaml") def connect(self): """ Connect to the Orion server listed in the config. """ self.client = SwisClient(self.config['orion_host'], self.config['orion_user'], self.config['orion_password']) return self.config['orion_label'] def get_node(self, node): """ Get an OrionNode object """ orion_node = OrionNode() if is_ip(node): query_for_where = "IPAddress" else: query_for_where = "Caption" swql = """SELECT NodeID, Uri, IPAddress, Caption FROM Orion.Nodes WHERE {}=@query_on""".format(query_for_where) kargs = {'query_on': node} data = self.query(swql, **kargs) if 'results' not in data: msg = "No results from Orion: {}".format(data) self.logger.info(msg) raise Exception(msg) if len(data['results']) == 1: try: orion_node.npm_id = data['results'][0]['NodeID'] orion_node.uri = data['results'][0]['Uri'] orion_node.ip_address = data['results'][0]['IPAddress'] orion_node.caption = data['results'][0]['Caption'] except IndexError: pass elif len(data['results']) >= 2: self.logger.debug( "Muliple Nodes match '{}' Caption: {}".format( node, data)) raise ValueError("Muliple Nodes match '{}' Caption".format( node)) if orion_node.npm: swql = """SELECT NodeID FROM Cirrus.Nodes WHERE CoreNodeID=@CoreNodeID""" kargs = {'CoreNodeID': orion_node.npm_id} data = self.query(swql, **kargs) # Don't raise an exception if this fails. # The platform may not haev NCM installed. if 'results' not in data: msg = "No results from Orion NCM: {}".format(data) self.logger.info(msg) elif len(data['results']) == 1: try: orion_node.ncm_id = data['results'][0]['NodeID'] except IndexError: pass return orion_node def query(self, swql, **kargs): """ Run SWQL against the Orion Platform. """ return self.client.query(swql, **kargs) def invoke(self, entity, verb, *args): """ Run an Invoke against the Orion Platform. """ return self.client.invoke(entity, verb, *args) def create(self, entity, **kargs): """ Run an Create against the Orion Platform. """ return self.client.create(entity, **kargs) def read(self, uri): """ Run an Read against the Orion Platform. """ return self.client.read(uri) def update(self, uri, **kargs): """ Run an Update against the Orion Platform. """ return self.client.update(uri, **kargs) def delete(self, uri): """ Run an Delete of an URI against the Orion Platform. """ return self.client.delete(uri) def get_snmp_community(self, community): """ Return the correct SNMP comminity to use. """ if community == "customer": return self.config['snmp_customer'] elif community == "internal": return self.config['snmp_internal'] elif community is None: return self.config['snmp_default'] else: return community 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_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 get_ncm_transfer_results(self, transfer_id, sleep_delay=10): """ Gets the completed (waits until finished). NCM job transfer status from Orion. Retruns: The completed status. """ ts = {} while True: swql = """SELECT TransferID, NodeID, Action, RequestedConfigType, RequestedScript, RequestedReboot, ConfigID, TransferProtocol, Status, ErrorMessage, DeviceOutput, DateTime, UserName FROM NCM.TransferResults WHERE TransferID=@transfer_id""" kargs = {'transfer_id': transfer_id} transfer_data = self.query(swql, **kargs) status = transfer_data['results'][0]['Status'] if status == 1: time.sleep(sleep_delay) elif status == 2: ts['status'] = "Complete" break elif status == 3: ts['status'] = "Error" break else: ts['status'] = "Unknown" break ts['RequestedScript'] = transfer_data['results'][0]['RequestedScript'] ts['RequestedReboot'] = transfer_data['results'][0]['RequestedReboot'] ts['ErrorMessage'] = transfer_data['results'][0]['ErrorMessage'] ts['DeviceOutput'] = transfer_data['results'][0]['DeviceOutput'] ts['UserName'] = transfer_data['results'][0]['UserName'] return ts
import requests from orionsdk import SwisClient npm_server = 'localhost' username = '******' password = '' verify = False if not verify: from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) swis = SwisClient(npm_server, username, password) # select the top 3 nodes from the inventory results = swis.query("SELECT TOP 3 N.CustomProperties.Uri FROM Orion.Nodes N") # extract just the Uris from the results uris = [row['Uri'] for row in results['results']] # submit the request swis.bulkupdate(uris, City='Austin', DeviceType='Router', Department='Billing')
class OrionBaseAction(Action): def __init__(self, config): super(OrionBaseAction, self).__init__(config) self.client = None if "orion" not in self.config: raise ValueError("Orion host details not in the config.yaml") def connect(self, platform): """ Connect to an Orion platform from the packs config.yaml. """ 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") def query(self, swql, **kargs): """ Run SWQL against the Orion Platform. """ return self.client.query(swql, **kargs) def invoke(self, entity, verb, *args): """ Run an Invoke against the Orion Platform. """ return self.client.invoke(entity, verb, *args) def create(self, entity, **kargs): """ Run an Create against the Orion Platform. """ return self.client.create(entity, **kargs) def node_exists(self, caption, ip_address): """ Check if an Node exists (caption and or ip) on the Orion platform. Returns: True or False. """ swql = """SELECT NodeID, IPAddress FROM Orion.Nodes WHERE Caption=@caption""" kargs = {'caption': caption} caption_data = self.query(swql, **kargs) if len(caption_data['results']) >= 1: self.logger.debug( "One (or more) Nodes match '{}' Caption.".format(caption)) return True swql = """SELECT NodeID, IPAddress FROM Orion.Nodes WHERE IPAddress=@ip_address""" kargs = {'ip_address': ip_address} ip_data = self.query(swql, **kargs) if len(ip_data['results']) >= 1: self.logger.debug( "One (or more) Nodes match '{}' IP.".format(ip_address)) return True else: return False def get_node_id(self, caption): """ Gets an NodeID from the Orion platform. Raises: ValueError on muliple or no matching caption. Returns: the NodeID (int) """ swql = "SELECT NodeID FROM Orion.Nodes WHERE Caption=@caption" kargs = {'caption': caption} data = self.query(swql, **kargs) if len(data['results']) == 1: try: return data['results'][0]['NodeID'] except IndexError: raise ValueError("Invalid Node") elif len(data['results']) >= 2: self.logger.debug( "Muliple Nodes match '{}' Caption: {}".format( caption, data)) raise ValueError("Muliple Nodes match '{}' Caption".format( caption)) elif len(data['results']) == 0: self.logger.debug( "No Nodes match '{}' Caption: {}".format( caption, data)) raise ValueError("No matching Caption for '{}'".format( caption)) 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: self.send_user_error("Invalid poller name") raise ValueError("Invalid poller name") def get_ncm_node_id(self, caption): """ Queries the Network configuration Manager nodes table on the Orion platform for the NodeID of a given node name (aka NodeCaption). Raises: IndexError on Invalid number of nodes (e.g. 0 or 2+). Returns: A single node id. """ swql = "SELECT NodeID FROM Cirrus.Nodes WHERE NodeCaption=@node" kargs = {'node': caption} data = self.query(swql, **kargs) if len(data['results']) == 1: try: return data['results'][0]['NodeID'] except IndexError: raise IndexError("Invalid Node") elif len(data['results']) >= 2: raise IndexError("Muliple Nodes match '{}' NodeCaption".format( caption)) elif len(data['results']) == 0: raise IndexError("No matching NodeCaption for '{}'".format( caption)) def get_ncm_transfer_results(self, transfer_id, sleep_delay=10): """ Gets the completed (waits until finished). NCM job transfer status from Orion. Retruns: The completed status. """ ts = {} while True: swql = """SELECT TransferID, Action, Status, ErrorMessage, DeviceOutput FROM NCM.TransferResults WHERE TransferID=@transfer_id""" kargs = {'transfer_id': transfer_id} transfer_data = self.query(swql, **kargs) status = transfer_data['results'][0]['Status'] if status == 1: time.sleep(sleep_delay) elif status == 2: ts['status'] = "Complete" break elif status == 3: ts['status'] = "Error" ts['ErrorMessage'] = transfer_data['results'][0][ 'ErrorMessage'] break else: ts['status'] = "Unknown" ts['ErrorMessage'] = "Invalid stauts: {}".format(status) break return ts def status_code_to_text(self, status): """ Takes an Solarwinds Orion status code and translates it to human text and also a colour that can be used in Slack. """ if status == 0: return ("Unknown", "grey") elif status == 1: return ("Up", "good") elif status == 2: return ("Down", "danger") elif status == 3: return ("Warning", "warning") elif status == 14: return ("Critical", "danger") def send_user_error(self, message): """ Prints an user error message. """ print(message)