def shell_cli_command_executor(self, **kvargs): # Checking if connection is alive self._is_connection_alive() command = "" if 'command' in kvargs: command = kvargs.get('command') if 'shelltimeout' in kvargs: shelltimeout = kvargs.get('shelltimeout') else: shelltimeout = 30 if 'timeout' in kvargs: timeout = kvargs.get('timeout') else: timeout = 30 shell = StartShell(self._conn, timeout=int(shelltimeout)) shell.open() got = shell.run("cli -c '" + command + " | no-more'", timeout=int(timeout)) shell.close() if not got[0]: print("*WARN* %s" % (str(got[1]))) # raise FatalError("Error executing CLI command, exiting...") line = re.sub('(\r\n)+', '\n', got[1]) line = re.sub('(\r)+', '\n', line) line = re.sub('(\n)+', '\n', line) return line
def get_fpc_shell(dev): ss=StartShell(dev) ss.open() fpcs=ss.run('cli -c "show chassis fpc"') print(fpcs) for fpc in fpcs[1].strip().split('\n')[1:]: print(fpc) ss.close()
def set_rescue_config(self): """Runs the :code:`request system configuration rescue save` command for the current Juniper instance """ dev = self.initialize_device() ss = StartShell(dev) ss.open() print("Setting rescue configuration for {}".format(self.host_name)) cmd = ss.run('cli -c "request system configuration rescue save"') ss.close()
def execute_shell(self, command): shell = StartShell(self.device) try: shell.open() result = shell.run("cli -c " + "\"" + command + "\"") shell.close() except Exception as err: return False, err.args.__str__() else: return result[0], result[1]
def save_config_to_file(self, **kvargs): directory = kvargs['directory'] + '/' + timestamp4 print("*INFO* Saving current configuration...") file_obj = StartShell(self._conn) file_obj.open() got = file_obj.run("cli -c 'show configuration | save " + directory + "_config.txt' ") file_obj.close() print("*INFO* %s" % (got)) return got[-2].split("'")[1]
def run_shell(dev, cmd): dev_shell = StartShell(dev) dev_shell.open() if type(cmd) == str: dev_shell.run('{}'.format(cmd)) logging.log(25, 'Sending shell: [{}] to [{}].'.format(cmd, dev.facts['hostname'])) elif type(cmd) == list: for entry in cmd: dev_shell.run('{}'.format(entry)) logging.log(25, 'Sending shell: [{}] to [{}].'.format(entry, dev.facts['hostname'])) dev_shell.close()
def listnumcores(str1): if not str1:return None dev = Device(host = str1, user='******', password='******') dev.open() ss = StartShell(dev) ss.open() x=ss.run('cli -c "show system core-dumps |match root "') ss.close() dev.close() k=str(x[-1]).replace("%","") return k[44:]
class TestStartShell(unittest.TestCase): @patch('paramiko.SSHClient') def setUp(self, mock_connect): self.dev = Device(host='1.1.1.1') self.shell = StartShell(self.dev) @patch('paramiko.SSHClient') @patch('jnpr.junos.utils.start_shell.StartShell.wait_for') def test_startshell_open(self, mock_connect, mock_wait): self.shell.open() mock_connect.assert_called_with('(%|>)') @patch('paramiko.SSHClient') def test_startshell_close(self, mock_connect): self.shell._chan = MagicMock() self.shell._client = MagicMock() self.shell.close() self.shell._client.close.assert_called_once() @patch('jnpr.junos.utils.start_shell.StartShell.wait_for') def test_startshell_run(self, mock_wait): self.shell._chan = MagicMock() self.shell.run('ls') self.assertTrue(call.send('echo $?') in self.shell._chan.mock_calls) @patch('jnpr.junos.utils.start_shell.select') def test_startshell_wait_for(self, mock_select): mock_select.return_value = ['> ', 2, 3] self.shell._chan = MagicMock() self.shell._chan.recv.return_value = '> ' self.assertTrue(self.shell.wait_for('> ')[0].endswith('> ')) @patch('jnpr.junos.utils.start_shell.select') def test_startshell_wait_for_regex(self, mock_select): mock_select.return_value = ['> ', 2, 3] self.shell._chan = MagicMock() #output from command: cli -c "show version" self.shell._chan.recv.return_value = \ """ ------------ JUNOS Services Deep Packet Inspection package [15.1 ---(more)--- """ self.assertTrue( self.shell.wait_for('---\(more\s?\d*%?\)---\n\s*|%')[0] in self.shell._chan.recv.return_value) @patch('jnpr.junos.utils.start_shell.StartShell.open') @patch('jnpr.junos.utils.start_shell.StartShell.close') def test_startshell_context(self, mock_open, mock_close): with StartShell(self.dev) as shell: shell._chan = MagicMock() shell.send('test') mock_close.assert_called_once(call())
class TestStartShell(unittest.TestCase): @patch('paramiko.SSHClient') def setUp(self, mock_connect): self.dev = Device(host='1.1.1.1') self.shell = StartShell(self.dev) @patch('paramiko.SSHClient') @patch('jnpr.junos.utils.start_shell.StartShell.wait_for') def test_startshell_open(self, mock_connect, mock_wait): self.shell.open() mock_connect.assert_called_with('(%|>)') @patch('paramiko.SSHClient') def test_startshell_close(self, mock_connect): self.shell._chan = MagicMock() self.shell._client = MagicMock() self.shell.close() self.shell._client.close.assert_called_once() @patch('jnpr.junos.utils.start_shell.StartShell.wait_for') def test_startshell_run(self, mock_wait): self.shell._chan = MagicMock() self.shell.run('ls') self.assertTrue(call.send('echo $?') in self.shell._chan.mock_calls) @patch('jnpr.junos.utils.start_shell.select') def test_startshell_wait_for(self, mock_select): mock_select.return_value = ['> ', 2, 3] self.shell._chan = MagicMock() self.shell._chan.recv.return_value = '> ' self.assertTrue(self.shell.wait_for('> ')[0].endswith('> ')) @patch('jnpr.junos.utils.start_shell.select') def test_startshell_wait_for_regex(self, mock_select): mock_select.return_value = ['> ', 2, 3] self.shell._chan = MagicMock() #output from command: cli -c "show version" self.shell._chan.recv.return_value = \ """ ------------ JUNOS Services Deep Packet Inspection package [15.1 ---(more)--- """ self.assertTrue(self.shell.wait_for('---\(more\s?\d*%?\)---\n\s*|%')[0] in self.shell._chan.recv.return_value) @patch('jnpr.junos.utils.start_shell.StartShell.open') @patch('jnpr.junos.utils.start_shell.StartShell.close') def test_startshell_context(self, mock_open, mock_close): with StartShell(self.dev) as shell: shell._chan = MagicMock() shell.send('test') mock_close.assert_called_once(call())
def get_hardware(host): dev = Device(host=host, user="******", passwd="MaRtInI", port=22) try: ss = StartShell(dev) except Exception as err: logging.error('Cannot connect to device: {0}\n'.format(err)) return try: ss.open() except Exception as err: logging.error('Cannot open to device: {0}\n'.format(err)) return cli_conf = 'cli -c "show configuration | save /var/tmp/"' + host + '.conf' cli_hw = 'cli -c "show chassis hardware | save /var/tmp/"' + host + '.hw' ss.run(cli_conf) ss.run(cli_hw) ss.close() remote_conf = '/var/tmp/' + host + '.conf' remote_hw = '/var/tmp/' + host + '.hw' ssh = createSSHClient(host, 22, "regress", "MaRtInI") scp = SCPClient(ssh.get_transport()) scp.get(remote_conf) scp.get(remote_hw) ''' hw = dev.rpc.get_chassis_inventory({'format':'text'}, dev_timeout=120) hw_filename = "hw_" + host file = open(hw_filename, "w") file.write(etree.tostring(hw)) file.close() try: #config = dev.rpc.get_config(dev_timeout=timeout, options={'format':'set'}) config = dev.rpc.get_config(dev_timeout=timeout) except Exception as err: logging.error('Get config error {0}\n'.format(err)) return config_filename = "config_" + host file = open(config_filename, "w") file.write(etree.tostring(config, encoding='unicode', pretty_print=True)) file.close() ''' # End the NETCONF session and close the connection dev.close()
def run_cli(dev, cmd): dev_shell = StartShell(dev) dev_shell.open() output = str() if type(cmd) == str: output = dev_shell.run('cli -c "{}"'.format(cmd))[1] logging.log(25, 'Sending CLI: [{}] to [{}].'.format(cmd, dev.facts['hostname'])) elif type(cmd) == list: for entry in cmd: output += dev_shell.run('cli -c "{}"'.format(entry))[1] logging.log(25, 'Sending CLI: [{}] to [{}].'.format(entry, dev.facts['hostname'])) dev_shell.close() return output
def load_baseline_config(router, router_name, current_re_only): shellSession = StartShell(router) shellSession.open() with open('baseline_from_router.set', 'w') as base_config: for group in baseline_groups: shell_output = shellSession.run( 'cli -c "show configuration groups ' + group + '| display set| no-more"') config = ( shell_output[1].split('\n') )[1: -1] # Use second element of shell_ouput list. Remove first and last line. First line is the command executed and last line is cli prompt. if len(config) > 0: for config_command in config: base_config.write(config_command) base_config.write('set apply-groups ' + group + '\n') base_config.write(' set system services netconf ssh' + '\n') shellSession.close() router.open() facts = dict((router.facts)) syncrhonize = False if not current_re_only: if 're0' in list(facts['current_re']): if facts['RE1']: if (str(facts['RE1']['status']) == 'OK'): syncrhonize = True elif 're1' in list(facts['current_re']): if facts['RE0']: if (str(facts['RE0']['status']) == 'OK'): syncrhonize = True with Config(router) as cu: try: cu.load('', overwrite=True, format="text", ignore_warning=True) cu.load(path='baseline_from_router.set', format="set", ignore_warning=True) cu.commit(force_sync=syncrhonize, timeout=360) print("Applied baseline config on ", router_name, "\n") router.close() return 0 except Exception as e: print(str(e)) print("\n\nFailed to load basedline config to ", router_name, "\n\n") router.close() return 1
def healthCheck(self, A,users,password): if not A: print "not valid" dev = Device(host=A, user=users, passwd=password) try: dev.open() except Exception as err: self.err_list.append([A,err]) print err sys.exit(1) self.healthcheck_list.append(dev.facts) ss=StartShell(dev) ss.open() ss.run('cli -c "request support information | save /var/tmp/information.txt" &') ss.close() dev.close()
def get_vmhost_shell(dev): '''Login to shell mode''' ss = StartShell(dev) ss.open() '''Different ways to collect host output''' #vmhost_shell = ss.run('cli -c \'request vmhost exec "df -i"\'') ###Use ">show interfaces terse routing-instance all" to find out virtual instance and IP to connect to Host OS #vmhost_shell = ss.run('rsh -JU __juniper_private4__ 192.168.1.1 "df -i"') #vmhost_shell = ss.run('rsh -JU __juniper_private5__ 192.168.1.2 "df -i"') vmhost_shell = ss.run('vhclient "df -i"') #print(vmhost_shell) '''Print output''' for line in vmhost_shell[1].strip().split('\n')[1:]: print(line) '''Logout from shell mode''' ss.close()
def getlog(str1): if not str1:return None try: dev = Device(host = str1, user='******', password='******') dev.open() ss = StartShell(dev) ss.open() x=ss.run('cli -c "show log messages|no-more "') ss.close() dev.close() with open(str1 + "log" + ".csv", 'w') as csv_file: csv_writer = csv.writer(csv_file, delimiter=',') for i in x[-1].split("\n"): csv_writer.writerow([i.replace("\n","")]) except: print str1+" is not reachable" pass return
def get_rsi(equipment): try: print( "Gathering RSI...(This takes a bit - give it time. Timeout is 10 minutes.)" ) ss = StartShell(equipment) ss.open() ss.run('cli request support information \\| save /var/tmp/' + current_date + '_py_rsi.txt', this="%", timeout=600) print("RSI Done, copying it and deleting it...\n") ss.close() with SCP(equipment, progress=True) as scp: scp.get('/var/tmp/' + current_date + "_py_rsi.txt", full_file + "_" + current_date + "_rsi.txt") fileSystem = FS(equipment) fileSystem.rm('/var/tmp/*_py_rsi.txt') except Exception as err: missedEquipment[equipment] = "Error getting RSI - " + str(err)
class TestStartShell(unittest.TestCase): @patch('paramiko.SSHClient') def setUp(self, mock_connect): self.dev = Device(host='1.1.1.1') self.shell = StartShell(self.dev) @patch('paramiko.SSHClient') @patch('jnpr.junos.utils.start_shell.StartShell.wait_for') def test_startshell_open(self, mock_connect, mock_wait): self.shell.open() mock_connect.assert_called_with('% ') @patch('paramiko.SSHClient') def test_startshell_close(self, mock_connect): self.shell._chan = MagicMock() self.shell._client = MagicMock() self.shell.close() self.shell._client.close.assert_called_once() @patch('jnpr.junos.utils.start_shell.StartShell.wait_for') def test_startshell_run(self, mock_wait): self.shell._chan = MagicMock() self.shell.run('ls') self.assertTrue(call.send('echo $?') in self.shell._chan.mock_calls) @patch('jnpr.junos.utils.start_shell.select') def test_startshell_wait_for(self, mock_select): mock_select.return_value = ['> ', 2, 3] self.shell._chan = MagicMock() self.assertTrue( call.endswith('> ') in self.shell.wait_for('> ')[0].mock_calls) @patch('jnpr.junos.utils.start_shell.StartShell.open') @patch('jnpr.junos.utils.start_shell.StartShell.close') def test_startshell_context(self, mock_open, mock_close): with StartShell(self.dev) as shell: shell._chan = MagicMock() shell.send('test') mock_close.assert_called_once(call())
class TestStartShell(unittest.TestCase): @patch('paramiko.SSHClient') def setUp(self, mock_connect): self.dev = Device(host='1.1.1.1') self.shell = StartShell(self.dev) @patch('paramiko.SSHClient') @patch('jnpr.junos.utils.start_shell.StartShell.wait_for') def test_startshell_open(self, mock_connect, mock_wait): self.shell.open() mock_connect.assert_called_with('% ') @patch('paramiko.SSHClient') def test_startshell_close(self, mock_connect): self.shell._chan = MagicMock() self.shell._client = MagicMock() self.shell.close() self.shell._client.close.assert_called_once() @patch('jnpr.junos.utils.start_shell.StartShell.wait_for') def test_startshell_run(self, mock_wait): self.shell._chan = MagicMock() self.shell.run('ls') self.assertTrue(call.send('echo $?') in self.shell._chan.mock_calls) @patch('jnpr.junos.utils.start_shell.select') def test_startshell_wait_for(self, mock_select): mock_select.return_value = ['> ', 2, 3] self.shell._chan = MagicMock() self.assertTrue(call.endswith('> ') in self.shell.wait_for('> ')[0].mock_calls) @patch('jnpr.junos.utils.start_shell.StartShell.open') @patch('jnpr.junos.utils.start_shell.StartShell.close') def test_startshell_context(self, mock_open, mock_close): with StartShell(self.dev) as shell: shell._chan = MagicMock() shell.send('test') mock_close.assert_called_once(call())
def add_routes_using_rtgen_mx_side(self, logicalsystem, table, subnet, count): ''' Description: Routes are pumped on mx side referring to logical system and routing table, using rtgen tool. Count takes integer value of number of routes. ''' rtgen_cmd = 'rtgen --op add --logical-system --table --prefix --count --next-hop-type reject' index_words = ['--logical-system', '--table', '--prefix', '--count'] substring_list = [] for i in range(len(index_words)): substring_list.append(rtgen_cmd.find( index_words[i]) + len(index_words[i])) updated_rtgen_cmd = rtgen_cmd[:substring_list[0] + 1] + logicalsystem + rtgen_cmd[substring_list[0]:substring_list[1] + 1] + table + \ rtgen_cmd[substring_list[1]:substring_list[2] + 1] + subnet + \ rtgen_cmd[substring_list[2]:substring_list[3] + 1] + \ count + rtgen_cmd[substring_list[3]:] mx_params = list(self.inputs.physical_routers_data.values())[0] dev = Device( host=mx_params['mgmt_ip'], user=mx_params['ssh_username'], password=mx_params['ssh_password']) ss = StartShell(dev) ss.open() updated_rtgen_cmd_result = ss.run(updated_rtgen_cmd) self.logger.debug('routes are added') ss.close()
def get_enabled_interfaces(self): """ :return: list of Physical Interfaces which read :code:`Enabled, Physical link is Down` :rtype: list """ dev = self.initialize_device() ss = StartShell(dev) ss.open() cmd = ss.run('cli -c "show interfaces | match Physical | no-more"') ss.close() enabled_interfaces = [] unchecked_interfaces = [ 'ae0', 'ae1', 'ae2', 'ae3', 'ae4', 'me0', 'vme' ] for line in cmd[1].splitlines(): if "Enabled, Physical link is Down" in line: val = line.split("Physical interface: ")[1] val = val.split(", Enabled, Physical link is Down")[0] if val not in unchecked_interfaces: enabled_interfaces.append(val + '.0') return enabled_interfaces
def get_max_connections(self): """Use shell commands to find maximum allowed connection-limit.""" # the list of commands that will: # - exit from the command shell to the Junos CLI # - enter configuration mode # - issue the command "set system services ssh connection-limit ?", # which will return help information we want to process # - exit configuration mode shell_commands = [{ 'command': 'exit', 'prompt': '> ', 'max': False }, { 'command': 'configure', 'prompt': '# ', 'max': False }, { 'command': 'set system services ssh connection-limit ?', 'prompt': '# ', 'max': True }, { 'command': 'exit', 'prompt': '> ', 'max': False }] # open a command shell on the device shell = StartShell(self.dev) shell.open() # iterate over the list of commands, capturing the output from # the command in whose results we are interested ('max' = True) max_msg = None for shellcmd in shell_commands: shellout = shell.run(shellcmd['command'], shellcmd['prompt']) self.results['shell_results'].append(shellout) if shellout[0] is False: msg = 'Shell command "%s" did not complete as expected: %s' \ % (shellcmd['command'], shellout[1]) raise RuntimeError(msg) if shellcmd['max']: max_msg = shellout[1] shell.close() # process the command output to find the max allowed value if max_msg is not None: max_arr = max_msg.splitlines() regex = r'connection-limit[^\(\[]*[\(\[]\d+\.\.(\d+)' max_str = None for line in max_arr: m = re.search(regex, line, flags=re.IGNORECASE) if m is not None: max_str = m.group(1) break if max_str is not None: reported_max = int(max_str) self.results['connection_max'] = reported_max if reported_max < self.desired_connection_limit: self.results['connection_limit'] = reported_max else: self.results['connection_limit'] = \ self.desired_connection_limit else: msg = 'Regex match expected but not found in command results' raise ValueError(msg) else: msg = 'Missing expected results from shell commands.' raise ValueError(msg)
class TestStartShell(unittest.TestCase): @patch("paramiko.SSHClient") def setUp(self, mock_connect): self.dev = Device(host="1.1.1.1") self.shell = StartShell(self.dev) @patch("paramiko.SSHClient") @patch("jnpr.junos.utils.start_shell.StartShell.wait_for") def test_startshell_open_with_shell_term(self, mock_wait, mock_connect): mock_wait.return_value = ["user # "] self.shell.open() mock_wait.assert_called_with("(%|>|#|\\$)") @patch("paramiko.SSHClient") @patch("jnpr.junos.utils.start_shell.StartShell.wait_for") def test_startshell_open_with_junos_term(self, mock_wait, mock_connect): mock_wait.return_value = ["user > "] self.shell.open() mock_wait.assert_called_with("(%|#|\\$)\\s") @patch("paramiko.SSHClient") @patch("jnpr.junos.utils.start_shell.StartShell.wait_for") def test_startshell_open_with_bourne_shell(self, mock_wait, mock_connect): mock_wait.return_value = ["foo@bar:~$ "] self.shell.open() mock_wait.assert_called_with("(%|>|#|\\$)") @patch("paramiko.SSHClient") def test_startshell_close(self, mock_connect): self.shell._chan = MagicMock() self.shell._client = MagicMock() self.shell.close() self.shell._client.close.assert_called_once() @patch("jnpr.junos.utils.start_shell.StartShell.wait_for") def test_startshell_run(self, mock_wait): self.shell._chan = MagicMock() mock_wait.return_value = ["user % "] self.shell.run("ls") self.assertTrue(call.send("echo $?") in self.shell._chan.mock_calls) @patch("jnpr.junos.utils.start_shell.select") def test_startshell_wait_for(self, mock_select): mock_select.return_value = ["> ", 2, 3] self.shell._chan = MagicMock() self.shell._chan.recv.return_value = "> " self.assertTrue(self.shell.wait_for("> ")[0].endswith("> ")) @patch("jnpr.junos.utils.start_shell.select") def test_startshell_wait_for_regex(self, mock_select): mock_select.return_value = ["> ", 2, 3] self.shell._chan = MagicMock() # output from command: cli -c "show version" self.shell._chan.recv.return_value = """ ------------ JUNOS Services Deep Packet Inspection package [15.1 ---(more)--- """ self.assertTrue( self.shell.wait_for("---\(more\s?\d*%?\)---\n\s*|%")[0] in self.shell._chan.recv.return_value) @patch("jnpr.junos.utils.start_shell.StartShell.open") @patch("jnpr.junos.utils.start_shell.StartShell.close") def test_startshell_context(self, mock_close, mock_open): with StartShell(self.dev) as shell: shell._chan = MagicMock() shell.send("test") mock_close.assert_called_once_with() @patch("jnpr.junos.utils.start_shell.StartShell.wait_for") def test_startshell_run_regex(self, mock_wait_for): self.shell._chan = MagicMock() mock_wait_for.return_value = [ """ ------------ JUNOS Services Deep Packet Inspection package [15.1 ---(more)--- """ ] self.assertTrue( self.shell.run("show version", "---\(more\s?\d*%?\)---\n\s*|%")[0]) @patch("jnpr.junos.utils.start_shell.StartShell.wait_for") def test_startshell_run_this_None(self, mock_wait_for): self.shell._chan = MagicMock() mock_wait_for.return_value = [ """ ------------ JUNOS Services Deep Packet Inspection package [15.1 """ ] self.assertTrue(self.shell.run("show version", this=None)[0])
from jnpr.junos.utils.start_shell import StartShell from jnpr.junos import Device from jnpr.junos.utils.scp import SCP dev = Device(host='xxxx', user='******', password='******') dev.open() ss = StartShell(dev) ss.open() ss.run('cli -c "request support information | save /var/tmp/information.txt"') with SCP(dev) as scp: scp.get('/var/tmp/information.txt','info.txt') ss.close()
def save_data(dev, step, **options): from jnpr.junos.utils.fs import FS from jnpr.junos.utils.start_shell import StartShell if not dev.connected: reconnect = reconnect_dev(dev, 2) if not reconnect: logging.info("Connection Failed to {}\n".format(dev.hostname)) return if options.has_key('script_name'): script_name = options['script_name'] else: script_name = False if options.has_key('rsi'): rsi = True if options['rsi'] == 'brief': brief = True else: brief = False else: rsi = False if options.has_key('folder'): dst_dir = options['folder'] else: dst_dir = '/var/tmp' if options.has_key('save_config'): save_config = options['save_config'] else: save_config = False # Start Shell dev_shell = StartShell(dev) dev_shell.open() # Get RSI if rsi: logging.info( 'Running "request support information", this may take a while') if brief: rsi_cli = dev_shell.run( 'cli -c "request support information brief | save {}/{}_rsi.txt"' .format(dst_dir, step)) else: rsi_cli = dev_shell.run( 'cli -c "request support information | save {}/{}_rsi.txt"'. format(dst_dir, step)) # Run OP Script if script_name: logging.info("Running op script: '{}' ... ".format(script_name)) op_script = dev_shell.run('cli -c "op {} | save {}/{}_{}.txt"'.format( script_name, dst_dir, step, script_name)) # Save Configuration if save_config: logging.info("Saving Configuration backup") cfg = dev_shell.run( 'cli -c "show configuration | save {}/{}_backup_config.txt"'. format(dst_dir, step)) dev_shell.close() logging.info('Verifying stored files') dev_fs = FS(dev) tmp_list = dev_fs.ls(dst_dir) if rsi: if tmp_list['files'].has_key('{}_rsi.txt'.format(step)): logging.info("Compressing RSI") dev_fs.tgz( '{}/{}_rsi.txt'.format(dst_dir, step), '{}/{}_Upgrade-MOP-support-information.tgz'.format( dst_dir, step)) dev_fs.rm('{}/{}_rsi.txt'.format(dst_dir, step)) if tmp_list['files'].has_key( '{}_Upgrade-MOP-support-information.tgz'.format(step)): logging.info("RSI file saved in {}".format(dst_dir)) rsi_complete = True else: logging.info("RSI collection did not complete in time\n") if save_config: if tmp_list['files'].has_key('{}_backup_config.txt'.format(step)): config_saved = True logging.info( "Backup configuration saved to {}/{}_backup_config.txt".format( dst_dir, step)) else: logging.info("Failed to save backup config") if script_name: if tmp_list['files'].has_key('{}_{}.txt'.format(step, script_name)): op_complete = True logging.info("OP {} script output saved in {}".format( script_name, dst_dir)) else: logging.info("OP {} script did not complete Successfully".format( script_name))
from jnpr.junos.utils.start_shell import StartShell from jnpr.junos import Device dev=Device('192.168.56.151', user='******', passwd='Juniper') ss = StartShell(dev) ss.open() ss.run('pwd') ss.run('cli -c "show version"') ss.run('cli -c "show configuration | save localfile.txt"') ss.close()
def script2(hostname): ######### Prologue stuff # Remove old log file if one exists for the given hostname if os.path.exists('./logs/' + hostname): os.remove('./logs/' + hostname) # Start a new log file log(hostname, "------------------------") # Variables we'll use in different places. Same quick method for assigning username and password in one line (username, password) = open('./config/credentials.txt').read().splitlines()[:2] root_password = open('./config/root_password.txt').readline() rc_file_location = '/etc/rc.mount.platform' rc_md5 = 'e4e17e0aa795f4dd790ed3f15f18859b' # Can't use context managers here since we're rebooting # Attempt to connect to the given hostname try: dev = Device(host=hostname, user=username, passwd=password) dev.open() except Exception as e: log(hostname, 'Failed to connect for Device()') return {'success': 0, 'message': 'Failed to connect to Device()'} # Attempt to create a shell connection to the given hostname try: shell = StartShell(dev) shell.open() except: log(hostname, 'Failed to connect for StartShell()') return {'success': 0, 'message': 'Failed to connect to StartShell()'} # RC file check - We do this using Junos's RPC for "file list" op command, this is exactly # like sending "file list /etc/rc.mount.platform" from the command-line file_show = dev.rpc.file_list(path=rc_file_location) file_show = file_show.xpath('//total-files') # If the length of file_show variable is 0, that means the file wasn't found if len(file_show) < 1: return { 'success': 0, 'message': 'RC file not found in /etc/rc.mount.platform, didn\'t show in ls listing' } file_show = str(file_show[0].text).strip() log(hostname, 'file_show: ' + file_show) # Excessive check most likely, but I wanted to be certain. Pretty much the same check as the previous check if file_show != "1": return { 'success': 0, 'message': 'RC file not found in /etc/rc.mount.platform' } ############################################ # MD5 file check - We do this using Junos's RPC for "file checksum md5" md5_rc_check = dev.rpc.get_checksum_information(path=rc_file_location) md5_rc_check = md5_rc_check.xpath('//checksum') # If the length of md5_rc_check is less than 0, that means no checksum XML node was found, which means something # went wrong, or that the file didn't exist. Realistically we probably don't need this here because execution would # not make it this far due to our previous checks, but I wanted to be explicit about the checks we're doing and # follow the MOP as exact as I could if len(md5_rc_check) < 1: return { 'success': 0, 'message': 'MD5 check on RC file unable to be executed' } md5_rc_check = str(md5_rc_check[0].text).strip() # Log / print information about the step we're on so the user is aware of where the script is currently at in its # execution log(hostname, 'md5 of rc file: ' + md5_rc_check + ' compared to: ' + rc_md5) # If the checksum doesn't match our hard-coded/expected checksum of the file, we report a failure back to master.py # in the form of a dict if md5_rc_check != rc_md5: return { 'success': 0, 'message': 'MD5 check FAILED. RC on device is corrupted, did not match ' + rc_md5 } ############################################ # Switch StartShell with su root - We need this to run some of the commands later on. StartShell() is an # "extension" for PyEZ that allows us simple access to shell shell.run('su root', this='Password:'******'whoami') if 'whoami\r\r\nroot\r\n' not in whoami[1]: log(hostname, 'INVALID ROOT PASSWORD GIVEN, COULD NOT SU TO ROOT. EXITING.') return { 'success': 0, 'message': 'Invalid root password given. Exiting.' } # c. Run fsck utility on the Unmounted partition to make sure its clean # Check which is backup partition (/dev/da0s1a or /dev/da0s2a) using "show system snapshot media internal" RPC show_system_snapshot = dev.rpc.get_snapshot_information(media='internal') snapshot_information = show_system_snapshot.xpath('//snapshot-information') if len(snapshot_information) < 1: return { 'success': 0, 'message': 'Unable to retrieve "show system snapshot media internal" output' } snapshot_information = snapshot_information[0] snapshot_medium = snapshot_information.xpath('//snapshot-medium') partitions = {} for medium in snapshot_medium: temp = str(medium.text).split('internal (')[1] if 'primary' in temp: temp = temp.split(') (primary)')[0] partitions['primary'] = temp else: temp = temp.split(') (backup)')[0] partitions['backup'] = temp log(hostname, 'partitions: ' + json.dumps(partitions)) fsck_output = shell.run('fsck -f -y ' + partitions['backup']) log(hostname, "fsck -f -y " + partitions['backup'] + "\n" + fsck_output[1]) # d. Perform snapshot slice alternate and save rescue configuration ########## Save rescue configuration - request system configuration rescue save log(hostname, "request configuration rescue save - Starting") request_rescue_configuration_save = dev.rpc.request_save_rescue_configuration( dev_timeout=500) log(hostname, "request configuration rescue save - Completed") #@TODO: Not sure if there's error-handling we need to do here. There is a //success xpath we can check for log(hostname, "request system snapshot slice alternate - Starting") request_system_snapshot_slice_alternate = dev.rpc.request_snapshot( slice="alternate", dev_timeout=500) log(hostname, "request system snapshot slice alternate - Completed") ########### REBOOT THE DEVICE request_system_reboot = dev.rpc.request_reboot() log( hostname, "REBOOTING - Initializing sleep to give device time to actually reboot" ) # Need to kill the dev and shell connections or it'll error out. # Need to sleep to give device time to reboot. Junos waits 60 seconds before initiating shutdown process, so # I pad 30 seconds on to give it time to actually shutdown. shell.close() dev.close() time.sleep(90) # While loop to reconnect to rebooted device, attemptToConnectToRebootedDevice() returns a Device() instantiation log(hostname, "Beginning post-reboot reconnect attempts") reconnDev = attemptToConnectToRebootedDevice(hostname, username, password) # this means we timed out... device needs manual intervention if reconnDev == False: log( hostname, "Post-reboot FAILED. Device failed to come back up - Manual intervention required" ) return { 'success': 0, 'message': "Post-reboot FAILED. Device failed to come back up - Manual intervention required" } log(hostname, "Post-reboot reconnection successful!") log( hostname, "Checking if we booted from backup partition - show system storage partitions" ) # Check if backup partition was booted partition_check = reconnDev.rpc.get_system_storage_partitions() partition_check = partition_check.xpath('//partitions/booted-from') if len(partition_check) > 1: return { 'success': 0, 'message': "Couldn't determine active/backup partition from 'show system storage partitions'" } partition_check = str(partition_check[0].text).strip() log(hostname, 'show system storage partitions: booted from ' + partition_check) ################################################################################ ################################################################################ ################################################################################ ################################################################################ # If we booted from backup, COMMENCE THE "OTHER" SCRIPT (MOP-Clean-Primary-partition.pdf). # I should probably extract this out into a separate function, but I don't want to deal with figuring out what # variables I need to pass-thru if partition_check == "backup": ########### Check which is backup partition (/dev/da0s1a or /dev/da0s2a) show_system_snapshot = reconnDev.rpc.get_snapshot_information( media='internal') snapshot_information = show_system_snapshot.xpath( '//snapshot-information') if len(snapshot_information) < 1: return { 'success': 0, 'message': 'Unable to retrieve "show system snapshot media internal" output' } snapshot_information = snapshot_information[0] snapshot_medium = snapshot_information.xpath('//snapshot-medium') partitions = {} for medium in snapshot_medium: temp = str(medium.text).split('internal (')[1] if 'primary' in temp: temp = temp.split(') (primary)')[0] partitions['primary'] = temp else: temp = temp.split(') (backup)')[0] partitions['backup'] = temp log(hostname, 'partitions: ' + json.dumps(partitions)) fsck_output = shell.run('fsck -f -y ' + partitions['backup']) log(hostname, "fsck -f -y " + partitions['backup'] + "\n" + fsck_output[1]) # 3. Take a snapshot to the alternate partition (this is a hidden command), then compare "show system snapshot media internal" to ensure # both partitions have the same versions log( hostname, 'request system snapshot media internal slice alternate - Starting' ) request_system_snapshot_media_internal_slice_alternate = reconnDev.rpc.request_snapshot( slice='alternate', media='internal', dev_timeout=500) log( hostname, 'request system snapshot media internal slice alternate - Completed' ) # 3a. Packages should be the same on both slices log(hostname, 'show system snapshot media internal - Started') show_system_snapshot_media_internal = reconnDev.rpc.get_snapshot_information( media='internal') show_system_snapshot_media_internal = show_system_snapshot_media_internal.xpath( '//software-version') log( hostname, 'show system snapshot media internal - Comparing packages between slices' ) software_versions = {} for software_index, software_version in enumerate( show_system_snapshot_media_internal): packages = software_version.xpath('./package') software_versions.setdefault(software_index, {}) for package_index, package in enumerate(packages): package_name = str( package.xpath('./package-name')[0].text).strip() package_version = str( package.xpath('./package-version')[0].text).strip() software_versions[software_index][ package_name] = package_version packages_match = True for package_name in software_versions[0].keys(): if software_versions[0][package_name] != software_versions[1][ package_name]: packages_match = False break if packages_match != True: log( hostname, "Packages from 'show system snapshot media internal' do not match" ) return { 'success': 0, 'message': "Packages from 'show system snapshot media internal' do not match" } log(hostname, 'show system snapshot media internal - Comparison completed') ####################### # 4. show system storage partitions - The MOP doesn't really explain what we're looking for with this command. Skipping for now. # 5. show system alarms - Check for alarm-description containing "Boot from backup root", if we find one, run "request system reboot slice alternate media internal" show_system_alarms = reconnDev.rpc.get_system_alarm_information() show_system_alarms = show_system_alarms.xpath('//alarm-description') for alarm_description in show_system_alarms: alarm_description = str(alarm_description.text).strip() # If we see the backup root alarm, we need to reboot AGAIN if "Boot from backup root" in alarm_description: log( hostname, 'REBOOTING - Backup root alarm FOUND - request system reboot slice alternate media internal' ) reconnDev.rpc.request_reboot(media='internal', slice='alternate') reconnDev.close() time.sleep(90) # While loop to reconnect to rebooted device, attemptToConnectToRebootedDevice() returns a Device instantation log(hostname, "Beginning second post-reboot reconnect attempts") secondReconnDev = attemptToConnectToRebootedDevice( hostname, username, password) # this means we timed out... device needs manual intervention if secondReconnDev == False: log( hostname, "SECOND Post-reboot FAILED. Device failed to come back up - Manual intervention required" ) return { 'success': 0, 'message': "SECOND Post-reboot FAILED. Device failed to come back up - Manual intervention required" } log(hostname, "Second post-reboot reconnection successful!") log( hostname, "Checking if we booted from backup partition - show system storage partitions" ) # Check if backup partition was booted partition_check = secondReconnDev.rpc.get_system_storage_partitions( ) partition_check = partition_check.xpath( '//partitions/booted-from') if len(partition_check) > 1: return { 'success': 0, 'message': "Couldn't determine active/backup partition from 'show system storage partitions'" } partition_check = str(partition_check[0].text).strip() if partition_check == "backup": log( hostname, "PROCEDURE FAILED, DEVICE STILL BOOTING FROM BACKUP PARTITION, DEVICE NEEDS TO BE RMA'D" ) return { 'success': 0, 'message': "PROCEDURE FAILED, DEVICE STILL BOOTING FROM BACKUP PARTITION, DEVICE NEEDS TO BE RMA'D" } # 3. Run the NAND media check after boot up with StartShell(reconnDev) as reconnShell: reconnShell.run('su root', this='Password:'******'nand-mediack -C') log(hostname, 'Running nand-mediack -C') if "nand-mediack -C\r\r\nMedia check on da0 on ex platforms\r\nroot@" not in nand_mediack[ 1]: log(hostname, 'nand-mediack check FAILED: ' + nand_mediack[1]) return {'success': 0, 'message': 'nand-mediack check FAILED'} else: log(hostname, 'nand-mediack check PASSED: ' + nand_mediack[1]) reconnDev.close() log(hostname, "Completed execution") log(hostname, "------------------------") return {'success': 1, 'message': 'SCRIPT COMPLETED EXECUTION'}