diff --git a/connpy/_version.py b/connpy/_version.py index 9389d35..c8afb1d 100644 --- a/connpy/_version.py +++ b/connpy/_version.py @@ -1,2 +1,2 @@ -__version__ = "2.1.6" +__version__ = "2.1.7" diff --git a/connpy/connapp.py b/connpy/connapp.py index 2468b90..f19521a 100755 --- a/connpy/connapp.py +++ b/connpy/connapp.py @@ -96,7 +96,7 @@ class connapp: bulkparser.set_defaults(func=self._func_others) #RUNPARSER runparser = subparsers.add_parser("run", help="Run scripts or commands on nodes", formatter_class=argparse.RawTextHelpFormatter) - runparser.add_argument("run", nargs='+', action=self._store_type, help=self._help("run"), default="run", type=self._type_node) + runparser.add_argument("run", nargs='+', action=self._store_type, help=self._help("run"), default="run") runparser.add_argument("-g","--generate", dest="action", action="store_const", help="Generate yaml file template", const="generate", default="run") runparser.set_defaults(func=self._func_run) #CONFIGPARSER diff --git a/connpy/core.py b/connpy/core.py index 094d5cc..e8c9489 100755 --- a/connpy/core.py +++ b/connpy/core.py @@ -208,7 +208,7 @@ class node: print(connect) exit(1) - def run(self, commands, vars = None,*, folder = '', prompt = r'>$|#$|\$$|>.$|#.$|\$.$', stdout = False, timeout = 20): + def run(self, commands, vars = None,*, folder = '', prompt = r'>$|#$|\$$|>.$|#.$|\$.$', stdout = False, timeout = 10): ''' Run a command or list of commands on the node and return the output. @@ -292,7 +292,7 @@ class node: f.close() return connect - def test(self, commands, expected, vars = None,*, prompt = r'>$|#$|\$$|>.$|#.$|\$.$', timeout = 20): + def test(self, commands, expected, vars = None,*, prompt = r'>$|#$|\$$|>.$|#.$|\$.$', timeout = 10): ''' Run a command or list of commands on the node, then check if expected value appears on the output after the last command. @@ -373,7 +373,7 @@ class node: self.status = 1 return connect - def _connect(self, debug = False, timeout = 20): + def _connect(self, debug = False, timeout = 10, max_attempts = 3): # Method to connect to the node, it parse all the information, create the ssh/telnet command and login to the node. if self.protocol == "ssh": cmd = "ssh" @@ -393,7 +393,7 @@ class node: passwords = self._passtx(self.password) else: passwords = [] - expects = ['yes/no', 'refused', 'supported', 'cipher', 'sagenotinuse', 'timeout', 'unavailable', 'closed', '[p|P]assword:|[u|U]sername:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching host key"] + expects = ['yes/no', 'refused', 'supported', 'cipher', 'ssh-keygen.*\"', 'timeout', 'unavailable', 'closed', '[p|P]assword:|[u|U]sername:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching host key"] elif self.protocol == "telnet": cmd = "telnet " + self.host if self.port != '': @@ -406,48 +406,62 @@ class node: passwords = self._passtx(self.password) else: passwords = [] - expects = ['[u|U]sername:', 'refused', 'supported', 'cipher', 'sagenotinuse', 'timeout', 'unavailable', 'closed', '[p|P]assword:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching host key"] + expects = ['[u|U]sername:', 'refused', 'supported', 'cipher', 'ssh-keygen.*\"', 'timeout', 'unavailable', 'closed', '[p|P]assword:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching host key"] else: raise ValueError("Invalid protocol: " + self.protocol) - child = pexpect.spawn(cmd) - if debug: - print(cmd) - self.mylog = io.BytesIO() - child.logfile_read = self.mylog - if len(passwords) > 0: - loops = len(passwords) - else: - loops = 1 - endloop = False - for i in range(0, loops): - while True: - results = child.expect(expects, timeout=timeout) - if results == 0: - if self.protocol == "ssh": - child.sendline('yes') - elif self.protocol == "telnet": - if self.user != '': - child.sendline(self.user) + attempts = 1 + while attempts <= max_attempts: + child = pexpect.spawn(cmd) + if debug: + print(cmd) + self.mylog = io.BytesIO() + child.logfile_read = self.mylog + if len(passwords) > 0: + loops = len(passwords) + else: + loops = 1 + endloop = False + for i in range(0, loops): + while True: + results = child.expect(expects, timeout=timeout) + if results == 0: + if self.protocol == "ssh": + child.sendline('yes') + elif self.protocol == "telnet": + if self.user != '': + child.sendline(self.user) + else: + self.missingtext = True + break + if results == 4: + child.terminate() + return "Connection failed code:" + str(results) + "\n" + child.after.decode() + if results in [1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15]: + child.terminate() + if results == 12 and attempts != max_attempts: + attempts += 1 + endloop = True + break + else: + return "Connection failed code:" + str(results) + if results == 8: + if len(passwords) > 0: + child.sendline(passwords[i]) else: self.missingtext = True - break - if results in [1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15]: - child.close() - return "Connection failed code:" + str(results) - if results == 8: - if len(passwords) > 0: - child.sendline(passwords[i]) - else: - self.missingtext = True + break + if results in [9, 11]: + endloop = True + child.sendline() + break + if results == 10: + child.sendline("\r") + sleep(2) + if endloop: break - if results in [9, 11]: - endloop = True - child.sendline() - break - if results == 10: - child.sendline("\r") - sleep(2) - if endloop: + if results == 12: + continue + else: break child.readline(0) self.child = child diff --git a/docs/connpy/index.html b/docs/connpy/index.html index c0891d3..7ed8b51 100644 --- a/docs/connpy/index.html +++ b/docs/connpy/index.html @@ -8,7 +8,7 @@ - + @@ -763,7 +763,7 @@ __pdoc__ = { bulkparser.set_defaults(func=self._func_others) #RUNPARSER runparser = subparsers.add_parser("run", help="Run scripts or commands on nodes", formatter_class=argparse.RawTextHelpFormatter) - runparser.add_argument("run", nargs='+', action=self._store_type, help=self._help("run"), default="run", type=self._type_node) + runparser.add_argument("run", nargs='+', action=self._store_type, help=self._help("run"), default="run") runparser.add_argument("-g","--generate", dest="action", action="store_const", help="Generate yaml file template", const="generate", default="run") runparser.set_defaults(func=self._func_run) #CONFIGPARSER @@ -1749,7 +1749,7 @@ tasks:
-def start(self, argv=['-f', '-o', 'docs', '-c', "hljs_style='greyscale'", 'connpy', '--html']) +def start(self, argv=['-f', '-o', 'docs/', '--html', 'connpy'])

Parameters:

@@ -1810,7 +1810,7 @@ tasks: bulkparser.set_defaults(func=self._func_others) #RUNPARSER runparser = subparsers.add_parser("run", help="Run scripts or commands on nodes", formatter_class=argparse.RawTextHelpFormatter) - runparser.add_argument("run", nargs='+', action=self._store_type, help=self._help("run"), default="run", type=self._type_node) + runparser.add_argument("run", nargs='+', action=self._store_type, help=self._help("run"), default="run") runparser.add_argument("-g","--generate", dest="action", action="store_const", help="Generate yaml file template", const="generate", default="run") runparser.set_defaults(func=self._func_run) #CONFIGPARSER @@ -2074,7 +2074,7 @@ tasks: print(connect) exit(1) - def run(self, commands, vars = None,*, folder = '', prompt = r'>$|#$|\$$|>.$|#.$|\$.$', stdout = False, timeout = 20): + def run(self, commands, vars = None,*, folder = '', prompt = r'>$|#$|\$$|>.$|#.$|\$.$', stdout = False, timeout = 10): ''' Run a command or list of commands on the node and return the output. @@ -2158,7 +2158,7 @@ tasks: f.close() return connect - def test(self, commands, expected, vars = None,*, prompt = r'>$|#$|\$$|>.$|#.$|\$.$', timeout = 20): + def test(self, commands, expected, vars = None,*, prompt = r'>$|#$|\$$|>.$|#.$|\$.$', timeout = 10): ''' Run a command or list of commands on the node, then check if expected value appears on the output after the last command. @@ -2239,7 +2239,7 @@ tasks: self.status = 1 return connect - def _connect(self, debug = False, timeout = 20): + def _connect(self, debug = False, timeout = 10, max_attempts = 3): # Method to connect to the node, it parse all the information, create the ssh/telnet command and login to the node. if self.protocol == "ssh": cmd = "ssh" @@ -2259,7 +2259,7 @@ tasks: passwords = self._passtx(self.password) else: passwords = [] - expects = ['yes/no', 'refused', 'supported', 'cipher', 'sagenotinuse', 'timeout', 'unavailable', 'closed', '[p|P]assword:|[u|U]sername:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching host key"] + expects = ['yes/no', 'refused', 'supported', 'cipher', 'ssh-keygen.*\"', 'timeout', 'unavailable', 'closed', '[p|P]assword:|[u|U]sername:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching host key"] elif self.protocol == "telnet": cmd = "telnet " + self.host if self.port != '': @@ -2272,48 +2272,62 @@ tasks: passwords = self._passtx(self.password) else: passwords = [] - expects = ['[u|U]sername:', 'refused', 'supported', 'cipher', 'sagenotinuse', 'timeout', 'unavailable', 'closed', '[p|P]assword:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching host key"] + expects = ['[u|U]sername:', 'refused', 'supported', 'cipher', 'ssh-keygen.*\"', 'timeout', 'unavailable', 'closed', '[p|P]assword:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching host key"] else: raise ValueError("Invalid protocol: " + self.protocol) - child = pexpect.spawn(cmd) - if debug: - print(cmd) - self.mylog = io.BytesIO() - child.logfile_read = self.mylog - if len(passwords) > 0: - loops = len(passwords) - else: - loops = 1 - endloop = False - for i in range(0, loops): - while True: - results = child.expect(expects, timeout=timeout) - if results == 0: - if self.protocol == "ssh": - child.sendline('yes') - elif self.protocol == "telnet": - if self.user != '': - child.sendline(self.user) + attempts = 1 + while attempts <= max_attempts: + child = pexpect.spawn(cmd) + if debug: + print(cmd) + self.mylog = io.BytesIO() + child.logfile_read = self.mylog + if len(passwords) > 0: + loops = len(passwords) + else: + loops = 1 + endloop = False + for i in range(0, loops): + while True: + results = child.expect(expects, timeout=timeout) + if results == 0: + if self.protocol == "ssh": + child.sendline('yes') + elif self.protocol == "telnet": + if self.user != '': + child.sendline(self.user) + else: + self.missingtext = True + break + if results == 4: + child.terminate() + return "Connection failed code:" + str(results) + "\n" + child.after.decode() + if results in [1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15]: + child.terminate() + if results == 12 and attempts != max_attempts: + attempts += 1 + endloop = True + break + else: + return "Connection failed code:" + str(results) + if results == 8: + if len(passwords) > 0: + child.sendline(passwords[i]) else: self.missingtext = True - break - if results in [1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15]: - child.close() - return "Connection failed code:" + str(results) - if results == 8: - if len(passwords) > 0: - child.sendline(passwords[i]) - else: - self.missingtext = True + break + if results in [9, 11]: + endloop = True + child.sendline() + break + if results == 10: + child.sendline("\r") + sleep(2) + if endloop: break - if results in [9, 11]: - endloop = True - child.sendline() - break - if results == 10: - child.sendline("\r") - sleep(2) - if endloop: + if results == 12: + continue + else: break child.readline(0) self.child = child @@ -2373,7 +2387,7 @@ tasks:
-def run(self, commands, vars=None, *, folder='', prompt='>$|#$|\\$$|>.$|#.$|\\$.$', stdout=False, timeout=20) +def run(self, commands, vars=None, *, folder='', prompt='>$|#$|\\$$|>.$|#.$|\\$.$', stdout=False, timeout=10)

Run a command or list of commands on the node and return the output.

@@ -2412,7 +2426,7 @@ tasks: Expand source code -
def run(self, commands, vars = None,*, folder = '', prompt = r'>$|#$|\$$|>.$|#.$|\$.$', stdout = False, timeout = 20):
+
def run(self, commands, vars = None,*, folder = '', prompt = r'>$|#$|\$$|>.$|#.$|\$.$', stdout = False, timeout = 10):
     '''
     Run a command or list of commands on the node and return the output.
 
@@ -2498,7 +2512,7 @@ tasks:
 
 
-def test(self, commands, expected, vars=None, *, prompt='>$|#$|\\$$|>.$|#.$|\\$.$', timeout=20) +def test(self, commands, expected, vars=None, *, prompt='>$|#$|\\$$|>.$|#.$|\\$.$', timeout=10)

Run a command or list of commands on the node, then check if expected value appears on the output after the last command.

@@ -2537,7 +2551,7 @@ tasks: Expand source code -
def test(self, commands, expected, vars = None,*, prompt = r'>$|#$|\$$|>.$|#.$|\$.$', timeout = 20):
+
def test(self, commands, expected, vars = None,*, prompt = r'>$|#$|\$$|>.$|#.$|\$.$', timeout = 10):
     '''
     Run a command or list of commands on the node, then check if expected value appears on the output after the last command.