diff --git a/README.md b/README.md index 9411239..8353ffc 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,29 @@ for i in result: # Or for one specific node mynodes.router1.run(["term len 0". "show run"], folder = "/home/user/logs") ``` +### Using variables +``` +import connpy +config = connpy.configfile() +nodes = config.getitem("@office", ["router1", "router2", "router3"]) +commands = [] +commands.append("config t") +commands.append("interface lo {id}") +commands.append("ip add {ip} {mask}") +commands.append("end") +variables = {} +variables["router1"] = {"ip": "10.57.57.1"} +variables["router2"] = {"ip": "10.57.57.2"} +variables["router3"] = {"ip": "10.57.57.3"} +variables["__global__"] = {"id": "57"} +variables["__global__"]["mask"] = "255.255.255.255" +expected = "!" +routers = connpy.nodes(nodes, config = config) +routers.run(commands, variables) +routers.test("ping {ip}", expected, variables) +for key in routers.result: + print(key, ' ---> ', ("pass" if routers.result[key] else "fail")) +``` ## Connection manager ### Features diff --git a/connpy/__init__.py b/connpy/__init__.py index 3b3424f..17e528a 100644 --- a/connpy/__init__.py +++ b/connpy/__init__.py @@ -121,7 +121,29 @@ for i in result: # Or for one specific node mynodes.router1.run(["term len 0". "show run"], folder = "/home/user/logs") ``` - +### Using variables +``` +import connpy +config = connpy.configfile() +nodes = config.getitem("@office", ["router1", "router2", "router3"]) +commands = [] +commands.append("config t") +commands.append("interface lo {id}") +commands.append("ip add {ip} {mask}") +commands.append("end") +variables = {} +variables["router1"] = {"ip": "10.57.57.1"} +variables["router2"] = {"ip": "10.57.57.2"} +variables["router3"] = {"ip": "10.57.57.3"} +variables["__global__"] = {"id": "57"} +variables["__global__"]["mask"] = "255.255.255.255" +expected = "!" +routers = connpy.nodes(nodes, config = config) +routers.run(commands, variables) +routers.test("ping {ip}", expected, variables) +for key in routers.result: + print(key, ' ---> ', ("pass" if routers.result[key] else "fail")) +``` ''' from .core import node,nodes from .configfile import configfile diff --git a/docs/connpy/index.html b/docs/connpy/index.html index baa6821..92ec901 100644 --- a/docs/connpy/index.html +++ b/docs/connpy/index.html @@ -130,6 +130,28 @@ for i in result: # Or for one specific node mynodes.router1.run(["term len 0". "show run"], folder = "/home/user/logs") +
import connpy
+config = connpy.configfile()
+nodes = config.getitem("@office", ["router1", "router2", "router3"])
+commands = []
+commands.append("config t")
+commands.append("interface lo {id}")
+commands.append("ip add {ip} {mask}")
+commands.append("end")
+variables = {}
+variables["router1"] = {"ip": "10.57.57.1"}
+variables["router2"] = {"ip": "10.57.57.2"}
+variables["router3"] = {"ip": "10.57.57.3"}
+variables["__global__"] = {"id": "57"}
+variables["__global__"]["mask"] = "255.255.255.255"
+expected = "!"
+routers = connpy.nodes(nodes, config = config)
+routers.run(commands, variables)
+routers.test("ping {ip}", expected, variables)
+for key in routers.result:
+ print(key, ' ---> ', ("pass" if routers.result[key] else "fail"))
+
- unique (str): Unique name to assign to the node.
@@ -1515,6 +1563,11 @@ compdef _conn connpy
- result(bool): True if expected value is found after running
the commands using test method.
+
+ - status (int): 0 if the method run or test run succesfully.
+ 1 if connection failed.
+ 2 if expect timeouts without prompt or EOF.
+
'''
def __init__(self, unique, host, options='', logs='', password='', port='', protocol='', user='', config=''):
@@ -1663,14 +1716,23 @@ compdef _conn connpy
print(connect)
exit(1)
- def run(self, commands,*, folder = '', prompt = r'>$|#$|\$$|>.$|#.$|\$.$', stdout = False):
+ 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.
### Parameters:
- commands (str/list): Commands to run on the node. Should be
- str or a list of str.
+ str or a list of str. You can use variables
+ as {varname} and defining them in optional
+ parameter vars.
+
+ ### Optional Parameters:
+
+ - vars (dict): Dictionary containing the definition of variables
+ used in commands parameter.
+ Keys: Variable names.
+ Values: strings.
### Optional Named Parameters:
@@ -1686,35 +1748,42 @@ compdef _conn connpy
- stdout (bool):Set True to send the command output to stdout.
default False.
+ - timeout (int):Time in seconds for expect to wait for prompt/EOF.
+ default 10.
+
### Returns:
str: Output of the commands you ran on the node.
'''
- connect = self._connect()
+ connect = self._connect(timeout = timeout)
if connect == True:
- expects = [prompt, pexpect.EOF]
+ expects = [prompt, pexpect.EOF, pexpect.TIMEOUT]
output = ''
- if isinstance(commands, list):
- for c in commands:
- result = self.child.expect(expects)
- self.child.sendline(c)
- if result == 0:
- output = output + self.child.before.decode() + self.child.after.decode()
- if result == 1:
- output = output + self.child.before.decode()
- else:
- result = self.child.expect(expects)
- self.child.sendline(commands)
+ if not isinstance(commands, list):
+ commands = [commands]
+ for c in commands:
+ if vars is not None:
+ c = c.format(**vars)
+ result = self.child.expect(expects, timeout = timeout)
+ self.child.sendline(c)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
- result = self.child.expect(expects)
+ if result == 2:
+ self.output = output + self.child.before.decode()
+ self.status = 2
+ return self.output
+ result = self.child.expect(expects, timeout = timeout)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
+ if result == 2:
+ self.output = output + self.child.before.decode()
+ self.status = 2
+ return self.output
self.child.close()
output = output.lstrip()
if stdout == True:
@@ -1725,22 +1794,35 @@ compdef _conn connpy
f.close()
self._logclean(folder + "/" + self.unique)
self.output = output
+ self.status = 0
return output
else:
self.output = connect
+ self.status = 1
return connect
- def test(self, commands, expected, *, prompt = r'>$|#$|\$$|>.$|#.$|\$.$'):
+ 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.
### Parameters:
- commands (str/list): Commands to run on the node. Should be
- str or list of str.
+ str or a list of str. You can use variables
+ as {varname} and defining them in optional
+ parameter vars.
- expected (str) : Expected text to appear after running
- all the commands on the node.
+ all the commands on the node.You can use
+ variables as {varname} and defining them
+ in optional parameter vars.
+
+ ### Optional Parameters:
+
+ - vars (dict): Dictionary containing the definition of variables
+ used in commands and expected parameters.
+ Keys: Variable names.
+ Values: strings.
### Optional Named Parameters:
@@ -1750,38 +1832,47 @@ compdef _conn connpy
work for most nodes. Change it if your connection
need some special symbol.
+ - timeout (int):Time in seconds for expect to wait for prompt/EOF.
+ default 10.
+
### Returns:
bool: true if expected value is found after running the commands
false if prompt is found before.
'''
- connect = self._connect()
+ connect = self._connect(timeout = timeout)
if connect == True:
- expects = [prompt, pexpect.EOF]
+ expects = [prompt, pexpect.EOF, pexpect.TIMEOUT]
output = ''
- if isinstance(commands, list):
- for c in commands:
- result = self.child.expect(expects)
- self.child.sendline(c)
- if result == 0:
- output = output + self.child.before.decode() + self.child.after.decode()
- if result == 1:
- output = output + self.child.before.decode()
- else:
- self.child.expect(expects)
- self.child.sendline(commands)
- output = output + self.child.before.decode() + self.child.after.decode()
- expects = [expected, prompt, pexpect.EOF]
- results = self.child.expect(expects)
+ if not isinstance(commands, list):
+ commands = [commands]
+ for c in commands:
+ if vars is not None:
+ c = c.format(**vars)
+ result = self.child.expect(expects, timeout = timeout)
+ self.child.sendline(c)
+ if result == 0:
+ output = output + self.child.before.decode() + self.child.after.decode()
+ if result == 1:
+ output = output + self.child.before.decode()
+ if result == 2:
+ self.result = None
+ self.output = output + self.child.before.decode()
+ self.status = 2
+ return self.output
+ if vars is not None:
+ expected = expected.format(**vars)
+ expects = [expected, prompt, pexpect.EOF, pexpect.TIMEOUT]
+ results = self.child.expect(expects, timeout = timeout)
+ self.child.close()
if results == 0:
- self.child.close()
self.result = True
output = output + self.child.before.decode() + self.child.after.decode()
output = output.lstrip()
self.output = output
+ self.status = 0
return True
if results in [1, 2]:
- self.child.close()
self.result = False
if results == 1:
output = output + self.child.before.decode() + self.child.after.decode()
@@ -1789,13 +1880,22 @@ compdef _conn connpy
output = output + self.child.before.decode()
output = output.lstrip()
self.output = output
+ self.status = 0
return False
+ if results == 3:
+ self.result = None
+ output = output + self.child.before.decode()
+ output = output.lstrip()
+ self.output = output
+ self.status = 2
+ return output
else:
self.result = None
self.output = connect
+ self.status = 1
return connect
- def _connect(self, debug = False):
+ def _connect(self, debug = False, timeout = 10):
# 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"
@@ -1815,7 +1915,7 @@ compdef _conn connpy
passwords = self.__passtx(self.password)
else:
passwords = []
- expects = ['yes/no', 'refused', 'supported', 'cipher', 'sage', 'timeout', 'unavailable', 'closed', '[p|P]assword:|[u|U]sername:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, "No route to host", "resolve hostname", "no matching host key"]
+ expects = ['yes/no', 'refused', 'supported', 'cipher', 'sage', '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 != '':
@@ -1828,11 +1928,12 @@ compdef _conn connpy
passwords = self.__passtx(self.password)
else:
passwords = []
- expects = ['[u|U]sername:', 'refused', 'supported', 'cipher', 'sage', 'timeout', 'unavailable', 'closed', '[p|P]assword:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, "No route to host", "resolve hostname", "no matching host key"]
+ expects = ['[u|U]sername:', 'refused', 'supported', 'cipher', 'sage', '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)
child.logfile_read = sys.stdout.buffer
if len(passwords) > 0:
loops = len(passwords)
@@ -1841,7 +1942,7 @@ compdef _conn connpy
endloop = False
for i in range(0, loops):
while True:
- results = child.expect(expects)
+ results = child.expect(expects, timeout=timeout)
if results == 0:
if self.protocol == "ssh":
child.sendline('yes')
@@ -1851,7 +1952,7 @@ compdef _conn connpy
else:
self.missingtext = True
break
- if results in [1, 2, 3, 4, 5, 6, 7, 12, 13, 14]:
+ 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:
@@ -1917,13 +2018,21 @@ compdef _conn connpy
-def run(self, commands, *, folder='', prompt='>$|#$|\\$$|>.$|#.$|\\$.$', stdout=False)
+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.
- commands (str/list): Commands to run on the node. Should be
- str or a list of str.
+ str or a list of str. You can use variables
+ as {varname} and defining them in optional
+ parameter vars.
+
+- vars (dict): Dictionary containing the definition of variables
+ used in commands parameter.
+ Keys: Variable names.
+ Values: strings.
- folder (str): Path where output log should be stored, leave
@@ -1937,6 +2046,9 @@ compdef _conn connpy
- stdout (bool):Set True to send the command output to stdout.
default False.
+
+- timeout (int):Time in seconds for expect to wait for prompt/EOF.
+ default 10.
str: Output of the commands you ran on the node.
@@ -1945,14 +2057,23 @@ compdef _conn connpy
Expand source code
-def run(self, commands,*, folder = '', prompt = r'>$|#$|\$$|>.$|#.$|\$.$', stdout = False):
+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.
### Parameters:
- commands (str/list): Commands to run on the node. Should be
- str or a list of str.
+ str or a list of str. You can use variables
+ as {varname} and defining them in optional
+ parameter vars.
+
+ ### Optional Parameters:
+
+ - vars (dict): Dictionary containing the definition of variables
+ used in commands parameter.
+ Keys: Variable names.
+ Values: strings.
### Optional Named Parameters:
@@ -1968,35 +2089,42 @@ compdef _conn connpy
- stdout (bool):Set True to send the command output to stdout.
default False.
+ - timeout (int):Time in seconds for expect to wait for prompt/EOF.
+ default 10.
+
### Returns:
str: Output of the commands you ran on the node.
'''
- connect = self._connect()
+ connect = self._connect(timeout = timeout)
if connect == True:
- expects = [prompt, pexpect.EOF]
+ expects = [prompt, pexpect.EOF, pexpect.TIMEOUT]
output = ''
- if isinstance(commands, list):
- for c in commands:
- result = self.child.expect(expects)
- self.child.sendline(c)
- if result == 0:
- output = output + self.child.before.decode() + self.child.after.decode()
- if result == 1:
- output = output + self.child.before.decode()
- else:
- result = self.child.expect(expects)
- self.child.sendline(commands)
+ if not isinstance(commands, list):
+ commands = [commands]
+ for c in commands:
+ if vars is not None:
+ c = c.format(**vars)
+ result = self.child.expect(expects, timeout = timeout)
+ self.child.sendline(c)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
- result = self.child.expect(expects)
+ if result == 2:
+ self.output = output + self.child.before.decode()
+ self.status = 2
+ return self.output
+ result = self.child.expect(expects, timeout = timeout)
if result == 0:
output = output + self.child.before.decode() + self.child.after.decode()
if result == 1:
output = output + self.child.before.decode()
+ if result == 2:
+ self.output = output + self.child.before.decode()
+ self.status = 2
+ return self.output
self.child.close()
output = output.lstrip()
if stdout == True:
@@ -2007,23 +2135,35 @@ compdef _conn connpy
f.close()
self._logclean(folder + "/" + self.unique)
self.output = output
+ self.status = 0
return output
else:
self.output = connect
+ self.status = 1
return connect
-def test(self, commands, expected, *, prompt='>$|#$|\\$$|>.$|#.$|\\$.$')
+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.
Parameters:
- commands (str/list): Commands to run on the node. Should be
- str or list of str.
+ str or a list of str. You can use variables
+ as {varname} and defining them in optional
+ parameter vars.
- expected (str) : Expected text to appear after running
- all the commands on the node.
+ all the commands on the node.You can use
+ variables as {varname} and defining them
+ in optional parameter vars.
+
+Optional Parameters:
+- vars (dict): Dictionary containing the definition of variables
+ used in commands and expected parameters.
+ Keys: Variable names.
+ Values: strings.
Optional Named Parameters:
- prompt (str): Prompt to be expected after a command is finished
@@ -2031,6 +2171,9 @@ compdef _conn connpy
routers use ">" or "#". The default value should
work for most nodes. Change it if your connection
need some special symbol.
+
+- timeout (int):Time in seconds for expect to wait for prompt/EOF.
+ default 10.
Returns:
bool: true if expected value is found after running the commands
@@ -2040,17 +2183,28 @@ compdef _conn connpy
Expand source code
-def test(self, commands, expected, *, prompt = r'>$|#$|\$$|>.$|#.$|\$.$'):
+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.
### Parameters:
- commands (str/list): Commands to run on the node. Should be
- str or list of str.
+ str or a list of str. You can use variables
+ as {varname} and defining them in optional
+ parameter vars.
- expected (str) : Expected text to appear after running
- all the commands on the node.
+ all the commands on the node.You can use
+ variables as {varname} and defining them
+ in optional parameter vars.
+
+ ### Optional Parameters:
+
+ - vars (dict): Dictionary containing the definition of variables
+ used in commands and expected parameters.
+ Keys: Variable names.
+ Values: strings.
### Optional Named Parameters:
@@ -2060,38 +2214,47 @@ compdef _conn connpy
work for most nodes. Change it if your connection
need some special symbol.
+ - timeout (int):Time in seconds for expect to wait for prompt/EOF.
+ default 10.
+
### Returns:
bool: true if expected value is found after running the commands
false if prompt is found before.
'''
- connect = self._connect()
+ connect = self._connect(timeout = timeout)
if connect == True:
- expects = [prompt, pexpect.EOF]
+ expects = [prompt, pexpect.EOF, pexpect.TIMEOUT]
output = ''
- if isinstance(commands, list):
- for c in commands:
- result = self.child.expect(expects)
- self.child.sendline(c)
- if result == 0:
- output = output + self.child.before.decode() + self.child.after.decode()
- if result == 1:
- output = output + self.child.before.decode()
- else:
- self.child.expect(expects)
- self.child.sendline(commands)
- output = output + self.child.before.decode() + self.child.after.decode()
- expects = [expected, prompt, pexpect.EOF]
- results = self.child.expect(expects)
+ if not isinstance(commands, list):
+ commands = [commands]
+ for c in commands:
+ if vars is not None:
+ c = c.format(**vars)
+ result = self.child.expect(expects, timeout = timeout)
+ self.child.sendline(c)
+ if result == 0:
+ output = output + self.child.before.decode() + self.child.after.decode()
+ if result == 1:
+ output = output + self.child.before.decode()
+ if result == 2:
+ self.result = None
+ self.output = output + self.child.before.decode()
+ self.status = 2
+ return self.output
+ if vars is not None:
+ expected = expected.format(**vars)
+ expects = [expected, prompt, pexpect.EOF, pexpect.TIMEOUT]
+ results = self.child.expect(expects, timeout = timeout)
+ self.child.close()
if results == 0:
- self.child.close()
self.result = True
output = output + self.child.before.decode() + self.child.after.decode()
output = output.lstrip()
self.output = output
+ self.status = 0
return True
if results in [1, 2]:
- self.child.close()
self.result = False
if results == 1:
output = output + self.child.before.decode() + self.child.after.decode()
@@ -2099,10 +2262,19 @@ compdef _conn connpy
output = output + self.child.before.decode()
output = output.lstrip()
self.output = output
+ self.status = 0
return False
+ if results == 3:
+ self.result = None
+ output = output + self.child.before.decode()
+ output = output.lstrip()
+ self.output = output
+ self.status = 2
+ return output
else:
self.result = None
self.output = connect
+ self.status = 1
return connect
@@ -2127,6 +2299,11 @@ compdef _conn connpy
the commands, False if prompt is found before.
Created after running method test.
+- status (dict): Dictionary formed by nodes unique as keys, value:
+ 0 if method run or test ended succesfully.
+ 1 if connection failed.
+ 2 if expect timeouts without prompt or EOF.
+
- <unique> (obj): For each item in nodelist, there is an attribute
generated with the node unique.
@@ -2164,6 +2341,11 @@ compdef _conn connpy
the commands, False if prompt is found before.
Created after running method test.
+ - status (dict): Dictionary formed by nodes unique as keys, value:
+ 0 if method run or test ended succesfully.
+ 1 if connection failed.
+ 2 if expect timeouts without prompt or EOF.
+
- <unique> (obj): For each item in nodelist, there is an attribute
generated with the node unique.
'''
@@ -2199,33 +2381,46 @@ compdef _conn connpy
yield lst[i:i + n]
- def run(self, commands,*, folder = None, prompt = None, stdout = None, parallel = 10):
+ def run(self, commands, vars = None,*, folder = None, prompt = None, stdout = None, parallel = 10, timeout = None):
'''
Run a command or list of commands on all the nodes in nodelist.
### Parameters:
- commands (str/list): Commands to run on the node. Should be str or
- list of str.
+ - commands (str/list): Commands to run on the nodes. Should be str or
+ list of str. You can use variables as {varname}
+ and defining them in optional parameter vars.
+
+ ### Optional Parameters:
+
+ - vars (dict): Dictionary containing the definition of variables for
+ each node, used in commands parameter.
+ Keys should be formed by nodes unique names. Use
+ special key name __global__ for global variables.
+ Subkeys: Variable names.
+ Values: strings.
### Optional Named Parameters:
- folder (str): Path where output log should be stored, leave empty
- to disable logging.
+ - folder (str): Path where output log should be stored, leave empty
+ to disable logging.
- prompt (str): Prompt to be expected after a command is finished
- running. Usually linux uses ">" or EOF while routers
- use ">" or "#". The default value should work for
- most nodes. Change it if your connection need some
- special symbol.
+ - prompt (str): Prompt to be expected after a command is finished
+ running. Usually linux uses ">" or EOF while routers
+ use ">" or "#". The default value should work for
+ most nodes. Change it if your connection need some
+ special symbol.
- stdout (bool): Set True to send the command output to stdout.
- Default False.
+ - stdout (bool): Set True to send the command output to stdout.
+ Default False.
- parallel (int): Number of nodes to run the commands simultaneously.
- Default is 10, if there are more nodes that this
- value, nodes are groups in groups with max this
- number of members.
+ - parallel (int): Number of nodes to run the commands simultaneously.
+ Default is 10, if there are more nodes that this
+ value, nodes are groups in groups with max this
+ number of members.
+
+ - timeout (int): Time in seconds for expect to wait for prompt/EOF.
+ default 10.
###Returns:
@@ -2234,6 +2429,7 @@ compdef _conn connpy
'''
args = {}
+ nodesargs = {}
args["commands"] = commands
if folder != None:
args["folder"] = folder
@@ -2241,10 +2437,20 @@ compdef _conn connpy
args["prompt"] = prompt
if stdout != None:
args["stdout"] = stdout
+ if timeout != None:
+ args["timeout"] = timeout
output = {}
+ status = {}
tasks = []
for n in self.nodelist:
- tasks.append(threading.Thread(target=n.run, kwargs=args))
+ nodesargs[n.unique] = args.copy()
+ if vars != None:
+ nodesargs[n.unique]["vars"] = {}
+ if "__global__" in vars.keys():
+ nodesargs[n.unique]["vars"].update(vars["__global__"])
+ if n.unique in vars.keys():
+ nodesargs[n.unique]["vars"].update(vars[n.unique])
+ tasks.append(threading.Thread(target=n.run, kwargs=nodesargs[n.unique]))
taskslist = list(self._splitlist(tasks, parallel))
for t in taskslist:
for i in t:
@@ -2253,28 +2459,48 @@ compdef _conn connpy
i.join()
for i in self.nodelist:
output[i.unique] = i.output
+ status[i.unique] = i.status
self.output = output
+ self.status = status
return output
- def test(self, commands, expected, *, prompt = None, parallel = 10):
+ def test(self, commands, expected, vars = None,*, prompt = None, parallel = 10, timeout = None):
'''
Run a command or list of commands on all the nodes in nodelist, then check if expected value appears on the output after the last command.
### Parameters:
- commands (str/list): Commands to run on the node. Should be str or
- list of str.
+ - commands (str/list): Commands to run on the node. Should be str or
+ list of str.
- expected (str) : Expected text to appear after running all the
- commands on the node.
+ - expected (str) : Expected text to appear after running all the
+ commands on the node.
+
+ ### Optional Parameters:
+
+ - vars (dict): Dictionary containing the definition of variables for
+ each node, used in commands and expected parameters.
+ Keys should be formed by nodes unique names. Use
+ special key name __global__ for global variables.
+ Subkeys: Variable names.
+ Values: strings.
### Optional Named Parameters:
- prompt (str): Prompt to be expected after a command is finished
- running. Usually linux uses ">" or EOF while
- routers use ">" or "#". The default value should
- work for most nodes. Change it if your connection
- need some special symbol.
+ - prompt (str): Prompt to be expected after a command is finished
+ running. Usually linux uses ">" or EOF while
+ routers use ">" or "#". The default value should
+ work for most nodes. Change it if your connection
+ need some special symbol.
+
+
+ - parallel (int): Number of nodes to run the commands simultaneously.
+ Default is 10, if there are more nodes that this
+ value, nodes are groups in groups with max this
+ number of members.
+
+ - timeout (int): Time in seconds for expect to wait for prompt/EOF.
+ default 10.
### Returns:
@@ -2284,15 +2510,26 @@ compdef _conn connpy
'''
args = {}
+ nodesargs = {}
args["commands"] = commands
args["expected"] = expected
if prompt != None:
args["prompt"] = prompt
+ if timeout != None:
+ args["timeout"] = timeout
output = {}
result = {}
+ status = {}
tasks = []
for n in self.nodelist:
- tasks.append(threading.Thread(target=n.test, kwargs=args))
+ nodesargs[n.unique] = args.copy()
+ if vars != None:
+ nodesargs[n.unique]["vars"] = {}
+ if "__global__" in vars.keys():
+ nodesargs[n.unique]["vars"].update(vars["__global__"])
+ if n.unique in vars.keys():
+ nodesargs[n.unique]["vars"].update(vars[n.unique])
+ tasks.append(threading.Thread(target=n.test, kwargs=nodesargs[n.unique]))
taskslist = list(self._splitlist(tasks, parallel))
for t in taskslist:
for i in t:
@@ -2302,38 +2539,52 @@ compdef _conn connpy
for i in self.nodelist:
result[i.unique] = i.result
output[i.unique] = i.output
+ status[i.unique] = i.status
self.output = output
self.result = result
+ self.status = status
return result
Methods
-def run(self, commands, *, folder=None, prompt=None, stdout=None, parallel=10)
+def run(self, commands, vars=None, *, folder=None, prompt=None, stdout=None, parallel=10, timeout=None)
-
Run a command or list of commands on all the nodes in nodelist.
Parameters:
-commands (str/list): Commands to run on the node. Should be str or
- list of str.
+- commands (str/list): Commands to run on the nodes. Should be str or
+ list of str. You can use variables as {varname}
+ and defining them in optional parameter vars.
+
+Optional Parameters:
+- vars (dict): Dictionary containing the definition of variables for
+ each node, used in commands parameter.
+ Keys should be formed by nodes unique names. Use
+ special key name __global__ for global variables.
+ Subkeys: Variable names.
+ Values: strings.
Optional Named Parameters:
-folder (str): Path where output log should be stored, leave empty
- to disable logging.
+- folder (str): Path where output log should be stored, leave empty
+ to disable logging.
-prompt (str): Prompt to be expected after a command is finished
- running. Usually linux uses ">" or EOF while routers
- use ">" or "#". The default value should work for
- most nodes. Change it if your connection need some
- special symbol.
+- prompt (str): Prompt to be expected after a command is finished
+ running. Usually linux uses ">" or EOF while routers
+ use ">" or "#". The default value should work for
+ most nodes. Change it if your connection need some
+ special symbol.
-stdout (bool): Set True to send the command output to stdout.
- Default False.
+- stdout (bool): Set True to send the command output to stdout.
+ Default False.
-parallel (int): Number of nodes to run the commands simultaneously.
- Default is 10, if there are more nodes that this
- value, nodes are groups in groups with max this
- number of members.
+- parallel (int): Number of nodes to run the commands simultaneously.
+ Default is 10, if there are more nodes that this
+ value, nodes are groups in groups with max this
+ number of members.
+
+- timeout (int): Time in seconds for expect to wait for prompt/EOF.
+ default 10.
Returns:
dict: Dictionary formed by nodes unique as keys, Output of the
@@ -2343,33 +2594,46 @@ parallel (int): Number of nodes to run the commands simultaneously.
Expand source code
-def run(self, commands,*, folder = None, prompt = None, stdout = None, parallel = 10):
+def run(self, commands, vars = None,*, folder = None, prompt = None, stdout = None, parallel = 10, timeout = None):
'''
Run a command or list of commands on all the nodes in nodelist.
### Parameters:
- commands (str/list): Commands to run on the node. Should be str or
- list of str.
+ - commands (str/list): Commands to run on the nodes. Should be str or
+ list of str. You can use variables as {varname}
+ and defining them in optional parameter vars.
+
+ ### Optional Parameters:
+
+ - vars (dict): Dictionary containing the definition of variables for
+ each node, used in commands parameter.
+ Keys should be formed by nodes unique names. Use
+ special key name __global__ for global variables.
+ Subkeys: Variable names.
+ Values: strings.
### Optional Named Parameters:
- folder (str): Path where output log should be stored, leave empty
- to disable logging.
+ - folder (str): Path where output log should be stored, leave empty
+ to disable logging.
- prompt (str): Prompt to be expected after a command is finished
- running. Usually linux uses ">" or EOF while routers
- use ">" or "#". The default value should work for
- most nodes. Change it if your connection need some
- special symbol.
+ - prompt (str): Prompt to be expected after a command is finished
+ running. Usually linux uses ">" or EOF while routers
+ use ">" or "#". The default value should work for
+ most nodes. Change it if your connection need some
+ special symbol.
- stdout (bool): Set True to send the command output to stdout.
- Default False.
+ - stdout (bool): Set True to send the command output to stdout.
+ Default False.
- parallel (int): Number of nodes to run the commands simultaneously.
- Default is 10, if there are more nodes that this
- value, nodes are groups in groups with max this
- number of members.
+ - parallel (int): Number of nodes to run the commands simultaneously.
+ Default is 10, if there are more nodes that this
+ value, nodes are groups in groups with max this
+ number of members.
+
+ - timeout (int): Time in seconds for expect to wait for prompt/EOF.
+ default 10.
###Returns:
@@ -2378,6 +2642,7 @@ parallel (int): Number of nodes to run the commands simultaneously.
'''
args = {}
+ nodesargs = {}
args["commands"] = commands
if folder != None:
args["folder"] = folder
@@ -2385,10 +2650,20 @@ parallel (int): Number of nodes to run the commands simultaneously.
args["prompt"] = prompt
if stdout != None:
args["stdout"] = stdout
+ if timeout != None:
+ args["timeout"] = timeout
output = {}
+ status = {}
tasks = []
for n in self.nodelist:
- tasks.append(threading.Thread(target=n.run, kwargs=args))
+ nodesargs[n.unique] = args.copy()
+ if vars != None:
+ nodesargs[n.unique]["vars"] = {}
+ if "__global__" in vars.keys():
+ nodesargs[n.unique]["vars"].update(vars["__global__"])
+ if n.unique in vars.keys():
+ nodesargs[n.unique]["vars"].update(vars[n.unique])
+ tasks.append(threading.Thread(target=n.run, kwargs=nodesargs[n.unique]))
taskslist = list(self._splitlist(tasks, parallel))
for t in taskslist:
for i in t:
@@ -2397,28 +2672,47 @@ parallel (int): Number of nodes to run the commands simultaneously.
i.join()
for i in self.nodelist:
output[i.unique] = i.output
+ status[i.unique] = i.status
self.output = output
+ self.status = status
return output
-def test(self, commands, expected, *, prompt=None, parallel=10)
+def test(self, commands, expected, vars=None, *, prompt=None, parallel=10, timeout=None)
-
Run a command or list of commands on all the nodes in nodelist, then check if expected value appears on the output after the last command.
Parameters:
-commands (str/list): Commands to run on the node. Should be str or
- list of str.
+- commands (str/list): Commands to run on the node. Should be str or
+ list of str.
-expected (str) : Expected text to appear after running all the
- commands on the node.
+- expected (str) : Expected text to appear after running all the
+ commands on the node.
+
+Optional Parameters:
+- vars (dict): Dictionary containing the definition of variables for
+ each node, used in commands and expected parameters.
+ Keys should be formed by nodes unique names. Use
+ special key name __global__ for global variables.
+ Subkeys: Variable names.
+ Values: strings.
Optional Named Parameters:
-prompt (str): Prompt to be expected after a command is finished
- running. Usually linux uses ">" or EOF while
- routers use ">" or "#". The default value should
- work for most nodes. Change it if your connection
- need some special symbol.
+- prompt (str): Prompt to be expected after a command is finished
+ running. Usually linux uses ">" or EOF while
+ routers use ">" or "#". The default value should
+ work for most nodes. Change it if your connection
+ need some special symbol.
+
+
+- parallel (int): Number of nodes to run the commands simultaneously.
+ Default is 10, if there are more nodes that this
+ value, nodes are groups in groups with max this
+ number of members.
+
+- timeout (int): Time in seconds for expect to wait for prompt/EOF.
+ default 10.
Returns:
dict: Dictionary formed by nodes unique as keys, value is True if
@@ -2429,25 +2723,43 @@ expected (str) : Expected text to appear after running all the
Expand source code
-def test(self, commands, expected, *, prompt = None, parallel = 10):
+def test(self, commands, expected, vars = None,*, prompt = None, parallel = 10, timeout = None):
'''
Run a command or list of commands on all the nodes in nodelist, then check if expected value appears on the output after the last command.
### Parameters:
- commands (str/list): Commands to run on the node. Should be str or
- list of str.
+ - commands (str/list): Commands to run on the node. Should be str or
+ list of str.
- expected (str) : Expected text to appear after running all the
- commands on the node.
+ - expected (str) : Expected text to appear after running all the
+ commands on the node.
+
+ ### Optional Parameters:
+
+ - vars (dict): Dictionary containing the definition of variables for
+ each node, used in commands and expected parameters.
+ Keys should be formed by nodes unique names. Use
+ special key name __global__ for global variables.
+ Subkeys: Variable names.
+ Values: strings.
### Optional Named Parameters:
- prompt (str): Prompt to be expected after a command is finished
- running. Usually linux uses ">" or EOF while
- routers use ">" or "#". The default value should
- work for most nodes. Change it if your connection
- need some special symbol.
+ - prompt (str): Prompt to be expected after a command is finished
+ running. Usually linux uses ">" or EOF while
+ routers use ">" or "#". The default value should
+ work for most nodes. Change it if your connection
+ need some special symbol.
+
+
+ - parallel (int): Number of nodes to run the commands simultaneously.
+ Default is 10, if there are more nodes that this
+ value, nodes are groups in groups with max this
+ number of members.
+
+ - timeout (int): Time in seconds for expect to wait for prompt/EOF.
+ default 10.
### Returns:
@@ -2457,15 +2769,26 @@ expected (str) : Expected text to appear after running all the
'''
args = {}
+ nodesargs = {}
args["commands"] = commands
args["expected"] = expected
if prompt != None:
args["prompt"] = prompt
+ if timeout != None:
+ args["timeout"] = timeout
output = {}
result = {}
+ status = {}
tasks = []
for n in self.nodelist:
- tasks.append(threading.Thread(target=n.test, kwargs=args))
+ nodesargs[n.unique] = args.copy()
+ if vars != None:
+ nodesargs[n.unique]["vars"] = {}
+ if "__global__" in vars.keys():
+ nodesargs[n.unique]["vars"].update(vars["__global__"])
+ if n.unique in vars.keys():
+ nodesargs[n.unique]["vars"].update(vars[n.unique])
+ tasks.append(threading.Thread(target=n.test, kwargs=nodesargs[n.unique]))
taskslist = list(self._splitlist(tasks, parallel))
for t in taskslist:
for i in t:
@@ -2475,8 +2798,10 @@ expected (str) : Expected text to appear after running all the
for i in self.nodelist:
result[i.unique] = i.result
output[i.unique] = i.output
+ status[i.unique] = i.status
self.output = output
self.result = result
+ self.status = status
return result
@@ -2500,6 +2825,7 @@ expected (str) : Expected text to appear after running all the
- Standalone module
- Using manager configuration
- Running parallel tasks
+- Using variables