def getvendor(self): """ """ vendor = None for commandset in self.commandsets: if not (hasstring(commandset['command']) and (hasstring(commandset['result']) or haslist(commandset['result']))): continue lines = self.command(commandset['command']) if hasstring(commandset['result']): for line in lines: if line == commandset['result']: vendor = commandset['vendor'] break elif haslist(commandset['result']): for line in lines: if line in commandset['result']: vendor = commandset['vendor'] break if vendor: break if not vendor: vendor = 'unknown' return vendor
def csv_to_listdict(properties, lines, branch, iid=False): """Converts Mikrotik's CSV output to dictionary. :param properties: (list) Practically the CSV header. :param lines: (list) Comma delimeted lines. :param branch: (dict) Mikrotik's command structure. :param iid: (bool) Adds $id to output. :return: (list) Variables-Values dictionary. Example: [ { results"variable1": "value1", ... } ... ] """ results = [] if not haslist(properties): return None if not haslist(lines): return None if not hasdict(branch): return None properties_c = len(properties) reader = csv.reader(lines, delimiter=',', quotechar='"') if branch['class'] == 'list' and iid: for values in reader: result = {'.id': values[0]} for i in range(0, properties_c): result[properties[i]] = values[i + 1].replace(';', ',') results.append(result) else: for values in reader: result = {} for i in range(0, properties_c): result[properties[i]] = values[i].replace(';', ',') results.append(result) return results
def properties_to_list(data): """Converts array of properties to list. :param data: (str / list) List or Comma/Space seperated properties. :return: (list) List of properties. """ if haslist(data): return data if hasstring(data): return wtrim(data.replace(',', ' ')).split(' ') return []
def csv_parse(lines): """Converts the CSV-expected input to array. :param lines: (str / [str]) CSV input - it can either linefeeded string or list. :return: ([str]) String Array or None on error. """ if not lines: return None if not haslist(lines): if hasstring(lines): lines = lines.split('\n') else: return None try: return list(csv.reader(lines, delimiter=',', quotechar='"')) except Exception: getexcept() return None
def commands(self, commands, raw=False, connect=True): """Executes a list of command on the remote host using the self.command() method. :param commands: (list) The list of commands to be executed. :param raw: (bool) Returns all results without filtering lines that start with #. :param connect: (bool) Connects to host, if it is not connected already. :return: (list) The execution result. """ status = 0 if hasstring(commands): commands = [commands] # maybe if it is only one command, exec it and skip to end elif not haslist(commands): self.err(1) return None if self.status < 1 and connect: if self.connect(): status = 1 if self.status < 1: self.err(2, self.status) return None results = [] for index, command in enumerate(commands): if not command: continue result = self.command(command, raw, hasstdout=False) results.append(result) if self.errc(): return self.err(2, 'commands[{}]: {}'.format(index, command)) if status == 1: self.disconnect() return results
def writefile(filename, lines): """Saves lines to file. :param filename: (str) File to write. :param lines: (list) List of lines to write. :return: (bool) True on success, False on failure. """ if not isdir('/'.join(filename.split('/')[:-1]), True): return False if not haslist(lines): return False try: handler = open(filename, 'w') for line in lines: handler.write(line + '\n') handler.close() return True except Exception: return getexcept() return False
def command(self, command, raw=False, connect=True, hasstdout=True): """Executes the <command> on the remote host and returns the results. :param command: (str) The command that has to be executed. :param raw: (bool) Returns all results without filtering lines that start with #. :param connect: (bool) Connects to host, if it is not connected already. :param hasstdout: (bool) Is it expected the command to give output? :return: (list) The execution result. """ results = super(Router, self).command(command, raw, connect, hasstdout) if not haslist(results): self.err(5, command) return None if not self.checkline(results[0]): self.err(6, command) return results
def exportfix(data): """Converts the multilined exported configuration of a router to single line. :param data: (str) Exported configuration. :return: (str) Configuration. """ if not haslist(data): return [] results = [] buf = '' for line in data: if line[-2] == '\\': buf += line[:-2] else: results.append(buf + line) buf = '' return results
def propvals_diff_getvalues(propvals, getvalues): """Compares two different sets of properties and values. :param propvals: (dict) 1st set. :param getvalues: (dict) 2nd set. :return: (bool) True if they are same, False if not. """ if not hasdict(propvals): return None if not haslist(getvalues): return True for prop in propvals: for getvalue in getvalues: if haskey(getvalue, prop): if propvals[prop] != getvalue[prop]: return True else: return True return False
def test_haslist(self): """Test if input is list. """ none0 = None int0 = 0 int1 = 1 int2 = -1 str0 = '' str1 = 'abcd' list0 = [] list1 = ['ab', 'cd'] dict0 = {} dict1 = {'ab': 'cd'} set0 = set() set1 = set(['a', 'b', 1, 2]) tuple0 = () tuple1 = ('a', 'b', 1, 2) self.assertFalse(valid.haslist(none0)) self.assertFalse(valid.haslist(int0)) self.assertFalse(valid.haslist(int1)) self.assertFalse(valid.haslist(int2)) self.assertFalse(valid.haslist(str0)) self.assertFalse(valid.haslist(str1)) self.assertFalse(valid.haslist(list0)) self.assertTrue(valid.haslist(list1)) # assertTrue self.assertFalse(valid.haslist(dict0)) self.assertFalse(valid.haslist(dict1)) self.assertFalse(valid.haslist(set0)) self.assertFalse(valid.haslist(set1)) self.assertFalse(valid.haslist(tuple0)) self.assertFalse(valid.haslist(tuple1))
def command(self, command, raw=False, connect=True, hasstdout=True): """Executes the <command> on the remote host and returns the results. :param command: (str) The command that has to be executed. :param raw: (bool) Returns all results without filtering lines that start with #. :param connect: (bool) Connects to host, if it is not connected already. :param hasstdout: (bool) Is it expected the command to give output? :return: (list) The execution result. """ status = 0 self.history.append(command) if not hasstring(command): self.err(1) return None if self.status < 1 and connect: if self.connect(): status = 1 if self.status < 1: self.err(2, self.status) return None if self.reseterrors: self.err0() lines = [] try: # stdin, stdout, stderr = ... _, stdout, stderr = self.connection.exec_command(command) lines = stdout.read().replace('\r', '').split('\n') # Mikrotik CLI is not producing stderr. Linux does. if not (hasstring(lines) or haslist(lines)): lines = stderr.read().replace('\r', '').split('\n') except Exception: _, message = getexcept() self.err(3, message) finally: if status == 1: self.disconnect() ##### fix the logic ^^^ \/\/\/\ of get/except/disconnect results = [] if raw: for line in lines: results.append(line) elif lines: for line in lines: if line: if line[0] != '#': results.append(line.strip()) if not haslist(results) and hasstdout: self.err(4, command) return results
def getvalues(self, branch, properties, find='', csvout=False, iid=False): """Retrieves requested values from remote host. :param branch: (str) Branch of commands. :param properties: (str / list) List or Comma / Space separated properties. :param find: (str) Mikrotik CLI filter. :param csvout: (bool) Output in CSV File. :param iid: (bool) Adds $id to output. :return: (list) CSV formatted output. Example output if <csvout=True>: Return of <self.command>: [ "value1,value2,value3,...", "value1,value2,value3,...", ... ] Example output if <csvout=False>: Return of <csv_to_list_dict>: [ { results"variable1": "value1", ... } ... ] """ results = [] if not hasstring(branch): self.err(1) return None branch = branchfix(branch) if not haskey(self.branch, branch, dict): self.err(2, branch) return None properties = properties_to_list(properties) if not haslist(properties): self.err(3) return None command = '' commands = [] if (self.branch[branch]['class'] == 'settings' or (self.branch[branch]['class'] == 'list' and find and find.find('=') < 1)): for prop in properties: commands.append('[{} get {} {}]'.format(branch, find, prop)) command = ':put ({})'.format('.",".'.join(commands)) elif self.branch[branch]['class'] == 'list': if iid: commands.append('$i') for prop in properties: commands.append('[{} get $i {}]'.format(branch, prop)) command = (':foreach i in=[' + branch + ' find ' + find + '] ' 'do={:put (' + '.",".'.join(commands) + ')}') else: self.err(4, branch) return None lines = self.command(command) if not lines or self.errc(): self.err(5, command) return None if csvout: results = lines else: results = csv_to_listdict(properties, lines, self.branch[branch], iid) return results