merge Jumphost, modify license
This commit is contained in:
commit
3e32aa958c
29
LICENSE
29
LICENSE
@ -1,21 +1,16 @@
|
|||||||
MIT License
|
Custom Software License
|
||||||
|
|
||||||
Copyright (c) 2022 Fede Luzzi
|
Copyright (c) 2022 Federico Luzzi
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to use, copy, and modify the Software, subject to the following conditions:
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
Commercial Use: The use of the Software for commercial purposes, including but not limited to selling, sublicensing, or generating revenue in any form, is expressly prohibited for individuals and entities other than the copyright holder.
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
Personal and Non-commercial Use: Individuals and entities are permitted to use, copy, and modify the Software for personal and non-commercial purposes.
|
||||||
|
|
||||||
|
Distribution: Redistribution of the original or modified Software is allowed, provided the Software is not sold or sublicensed and this license notice is included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
Support and Sale: The copyright holder reserves the exclusive right to sell or offer support services for the Software to any company or commercial entity.
|
||||||
|
|
||||||
|
Disclaimer: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
__version__ = "3.6.5"
|
__version__ = "3.7.0"
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ class configfile:
|
|||||||
|
|
||||||
def _createconfig(self, conf):
|
def _createconfig(self, conf):
|
||||||
#Create config file
|
#Create config file
|
||||||
defaultconfig = {'config': {'case': False, 'idletime': 30, 'fzf': False}, 'connections': {}, 'profiles': { "default": { "host":"", "protocol":"ssh", "port":"", "user":"", "password":"", "options":"", "logs":"", "tags": "" }}}
|
defaultconfig = {'config': {'case': False, 'idletime': 30, 'fzf': False}, 'connections': {}, 'profiles': { "default": { "host":"", "protocol":"ssh", "port":"", "user":"", "password":"", "options":"", "logs":"", "tags": "", "jumphost":""}}}
|
||||||
if not os.path.exists(conf):
|
if not os.path.exists(conf):
|
||||||
with open(conf, "w") as f:
|
with open(conf, "w") as f:
|
||||||
json.dump(defaultconfig, f, indent = 4)
|
json.dump(defaultconfig, f, indent = 4)
|
||||||
@ -238,14 +238,14 @@ class configfile:
|
|||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
|
|
||||||
def _connections_add(self,*, id, host, folder='', subfolder='', options='', logs='', password='', port='', protocol='', user='', tags='', type = "connection" ):
|
def _connections_add(self,*, id, host, folder='', subfolder='', options='', logs='', password='', port='', protocol='', user='', tags='', jumphost='', type = "connection" ):
|
||||||
#Add connection from config
|
#Add connection from config
|
||||||
if folder == '':
|
if folder == '':
|
||||||
self.connections[id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags,"type": type}
|
self.connections[id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags,"jumphost": jumphost,"type": type}
|
||||||
elif folder != '' and subfolder == '':
|
elif folder != '' and subfolder == '':
|
||||||
self.connections[folder][id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags, "type": type}
|
self.connections[folder][id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags, "jumphost": jumphost, "type": type}
|
||||||
elif folder != '' and subfolder != '':
|
elif folder != '' and subfolder != '':
|
||||||
self.connections[folder][subfolder][id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags, "type": type}
|
self.connections[folder][subfolder][id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags, "jumphost": jumphost, "type": type}
|
||||||
|
|
||||||
|
|
||||||
def _connections_del(self,*, id, folder='', subfolder=''):
|
def _connections_del(self,*, id, folder='', subfolder=''):
|
||||||
@ -274,9 +274,9 @@ class configfile:
|
|||||||
del self.connections[folder][subfolder]
|
del self.connections[folder][subfolder]
|
||||||
|
|
||||||
|
|
||||||
def _profiles_add(self,*, id, host = '', options='', logs='', password='', port='', protocol='', user='', tags='' ):
|
def _profiles_add(self,*, id, host = '', options='', logs='', password='', port='', protocol='', user='', tags='', jumphost='' ):
|
||||||
#Add profile from config
|
#Add profile from config
|
||||||
self.profiles[id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags}
|
self.profiles[id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags, "jumphost": jumphost}
|
||||||
|
|
||||||
|
|
||||||
def _profiles_del(self,*, id ):
|
def _profiles_del(self,*, id ):
|
||||||
|
@ -539,6 +539,7 @@ class connapp:
|
|||||||
newnode["options"] = newnodes["options"]
|
newnode["options"] = newnodes["options"]
|
||||||
newnode["logs"] = newnodes["logs"]
|
newnode["logs"] = newnodes["logs"]
|
||||||
newnode["tags"] = newnodes["tags"]
|
newnode["tags"] = newnodes["tags"]
|
||||||
|
newnode["jumphost"] = newnodes["jumphost"]
|
||||||
newnode["user"] = newnodes["user"]
|
newnode["user"] = newnodes["user"]
|
||||||
newnode["password"] = newnodes["password"]
|
newnode["password"] = newnodes["password"]
|
||||||
count +=1
|
count +=1
|
||||||
@ -992,6 +993,23 @@ class connapp:
|
|||||||
raise inquirer.errors.ValidationError("", reason="Tags should be a python dictionary.".format(current))
|
raise inquirer.errors.ValidationError("", reason="Tags should be a python dictionary.".format(current))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _jumphost_validation(self, answers, current):
|
||||||
|
#Validation for Jumphost in inquirer when managing nodes
|
||||||
|
if current.startswith("@"):
|
||||||
|
if current[1:] not in self.profiles:
|
||||||
|
raise inquirer.errors.ValidationError("", reason="Profile {} don't exist".format(current))
|
||||||
|
elif current != "":
|
||||||
|
if current not in self.nodes :
|
||||||
|
raise inquirer.errors.ValidationError("", reason="Node {} don't exist.".format(current))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _profile_jumphost_validation(self, answers, current):
|
||||||
|
#Validation for Jumphost in inquirer when managing profiles
|
||||||
|
if current != "":
|
||||||
|
if current not in self.nodes :
|
||||||
|
raise inquirer.errors.ValidationError("", reason="Node {} don't exist.".format(current))
|
||||||
|
return True
|
||||||
|
|
||||||
def _default_validation(self, answers, current):
|
def _default_validation(self, answers, current):
|
||||||
#Default validation type used in multiples questions in inquirer
|
#Default validation type used in multiples questions in inquirer
|
||||||
if current.startswith("@"):
|
if current.startswith("@"):
|
||||||
@ -1039,6 +1057,7 @@ class connapp:
|
|||||||
questions.append(inquirer.Confirm("options", message="Edit Options?"))
|
questions.append(inquirer.Confirm("options", message="Edit Options?"))
|
||||||
questions.append(inquirer.Confirm("logs", message="Edit logging path/file?"))
|
questions.append(inquirer.Confirm("logs", message="Edit logging path/file?"))
|
||||||
questions.append(inquirer.Confirm("tags", message="Edit tags?"))
|
questions.append(inquirer.Confirm("tags", message="Edit tags?"))
|
||||||
|
questions.append(inquirer.Confirm("jumphost", message="Edit jumphost?"))
|
||||||
questions.append(inquirer.Confirm("user", message="Edit User?"))
|
questions.append(inquirer.Confirm("user", message="Edit User?"))
|
||||||
questions.append(inquirer.Confirm("password", message="Edit password?"))
|
questions.append(inquirer.Confirm("password", message="Edit password?"))
|
||||||
answers = inquirer.prompt(questions)
|
answers = inquirer.prompt(questions)
|
||||||
@ -1050,11 +1069,13 @@ class connapp:
|
|||||||
defaults = self.config.getitem(unique)
|
defaults = self.config.getitem(unique)
|
||||||
if "tags" not in defaults:
|
if "tags" not in defaults:
|
||||||
defaults["tags"] = ""
|
defaults["tags"] = ""
|
||||||
|
if "jumphost" not in defaults:
|
||||||
|
defaults["jumphost"] = ""
|
||||||
except:
|
except:
|
||||||
defaults = { "host":"", "protocol":"", "port":"", "user":"", "options":"", "logs":"" , "tags":"", "password":""}
|
defaults = { "host":"", "protocol":"", "port":"", "user":"", "options":"", "logs":"" , "tags":"", "password":"", "jumphost":""}
|
||||||
node = {}
|
node = {}
|
||||||
if edit == None:
|
if edit == None:
|
||||||
edit = { "host":True, "protocol":True, "port":True, "user":True, "password": True,"options":True, "logs":True, "tags":True }
|
edit = { "host":True, "protocol":True, "port":True, "user":True, "password": True,"options":True, "logs":True, "tags":True, "jumphost":True }
|
||||||
questions = []
|
questions = []
|
||||||
if edit["host"]:
|
if edit["host"]:
|
||||||
questions.append(inquirer.Text("host", message="Add Hostname or IP", validate=self._host_validation, default=defaults["host"]))
|
questions.append(inquirer.Text("host", message="Add Hostname or IP", validate=self._host_validation, default=defaults["host"]))
|
||||||
@ -1080,6 +1101,10 @@ class connapp:
|
|||||||
questions.append(inquirer.Text("tags", message="Add tags dictionary", validate=self._tags_validation, default=str(defaults["tags"]).replace("{","{{").replace("}","}}")))
|
questions.append(inquirer.Text("tags", message="Add tags dictionary", validate=self._tags_validation, default=str(defaults["tags"]).replace("{","{{").replace("}","}}")))
|
||||||
else:
|
else:
|
||||||
node["tags"] = defaults["tags"]
|
node["tags"] = defaults["tags"]
|
||||||
|
if edit["jumphost"]:
|
||||||
|
questions.append(inquirer.Text("jumphost", message="Add Jumphost node", validate=self._jumphost_validation, default=str(defaults["jumphost"]).replace("{","{{").replace("}","}}")))
|
||||||
|
else:
|
||||||
|
node["jumphost"] = defaults["jumphost"]
|
||||||
if edit["user"]:
|
if edit["user"]:
|
||||||
questions.append(inquirer.Text("user", message="Pick username", validate=self._default_validation, default=defaults["user"]))
|
questions.append(inquirer.Text("user", message="Pick username", validate=self._default_validation, default=defaults["user"]))
|
||||||
else:
|
else:
|
||||||
@ -1118,11 +1143,13 @@ class connapp:
|
|||||||
defaults = self.config.profiles[unique]
|
defaults = self.config.profiles[unique]
|
||||||
if "tags" not in defaults:
|
if "tags" not in defaults:
|
||||||
defaults["tags"] = ""
|
defaults["tags"] = ""
|
||||||
|
if "jumphost" not in defaults:
|
||||||
|
defaults["jumphost"] = ""
|
||||||
except:
|
except:
|
||||||
defaults = { "host":"", "protocol":"", "port":"", "user":"", "options":"", "logs":"", "tags": "" }
|
defaults = { "host":"", "protocol":"", "port":"", "user":"", "options":"", "logs":"", "tags": "", "jumphost": ""}
|
||||||
profile = {}
|
profile = {}
|
||||||
if edit == None:
|
if edit == None:
|
||||||
edit = { "host":True, "protocol":True, "port":True, "user":True, "password": True,"options":True, "logs":True, "tags":True }
|
edit = { "host":True, "protocol":True, "port":True, "user":True, "password": True,"options":True, "logs":True, "tags":True, "jumphost":True }
|
||||||
questions = []
|
questions = []
|
||||||
if edit["host"]:
|
if edit["host"]:
|
||||||
questions.append(inquirer.Text("host", message="Add Hostname or IP", default=defaults["host"]))
|
questions.append(inquirer.Text("host", message="Add Hostname or IP", default=defaults["host"]))
|
||||||
@ -1148,6 +1175,10 @@ class connapp:
|
|||||||
questions.append(inquirer.Text("tags", message="Add tags dictionary", validate=self._profile_tags_validation, default=str(defaults["tags"]).replace("{","{{").replace("}","}}")))
|
questions.append(inquirer.Text("tags", message="Add tags dictionary", validate=self._profile_tags_validation, default=str(defaults["tags"]).replace("{","{{").replace("}","}}")))
|
||||||
else:
|
else:
|
||||||
profile["tags"] = defaults["tags"]
|
profile["tags"] = defaults["tags"]
|
||||||
|
if edit["jumphost"]:
|
||||||
|
questions.append(inquirer.Text("jumphost", message="Add Jumphost node", validate=self._profile_jumphost_validation, default=str(defaults["jumphost"]).replace("{","{{").replace("}","}}")))
|
||||||
|
else:
|
||||||
|
profile["jumphost"] = defaults["jumphost"]
|
||||||
if edit["user"]:
|
if edit["user"]:
|
||||||
questions.append(inquirer.Text("user", message="Pick username", default=defaults["user"]))
|
questions.append(inquirer.Text("user", message="Pick username", default=defaults["user"]))
|
||||||
else:
|
else:
|
||||||
@ -1179,6 +1210,7 @@ class connapp:
|
|||||||
questions.append(inquirer.Text("options", message="Pass extra options to protocol", validate=self._default_validation))
|
questions.append(inquirer.Text("options", message="Pass extra options to protocol", validate=self._default_validation))
|
||||||
questions.append(inquirer.Text("logs", message="Pick logging path/file ", validate=self._default_validation))
|
questions.append(inquirer.Text("logs", message="Pick logging path/file ", validate=self._default_validation))
|
||||||
questions.append(inquirer.Text("tags", message="Add tags dictionary", validate=self._tags_validation))
|
questions.append(inquirer.Text("tags", message="Add tags dictionary", validate=self._tags_validation))
|
||||||
|
questions.append(inquirer.Text("jumphost", message="Add Jumphost node", validate=self._jumphost_validation))
|
||||||
questions.append(inquirer.Text("user", message="Pick username", validate=self._default_validation))
|
questions.append(inquirer.Text("user", message="Pick username", validate=self._default_validation))
|
||||||
questions.append(inquirer.List("password", message="Password: Use a local password, no password or a list of profiles to reference?", choices=["Local Password", "Profiles", "No Password"]))
|
questions.append(inquirer.List("password", message="Password: Use a local password, no password or a list of profiles to reference?", choices=["Local Password", "Profiles", "No Password"]))
|
||||||
answer = inquirer.prompt(questions)
|
answer = inquirer.prompt(questions)
|
||||||
@ -1201,6 +1233,8 @@ class connapp:
|
|||||||
return answer
|
return answer
|
||||||
|
|
||||||
def _type_node(self, arg_value, pat=re.compile(r"^[0-9a-zA-Z_.$@#-]+$")):
|
def _type_node(self, arg_value, pat=re.compile(r"^[0-9a-zA-Z_.$@#-]+$")):
|
||||||
|
if arg_value == None:
|
||||||
|
raise ValueError("Missing argument node")
|
||||||
if not pat.match(arg_value):
|
if not pat.match(arg_value):
|
||||||
raise ValueError(f"Argument error: {arg_value}")
|
raise ValueError(f"Argument error: {arg_value}")
|
||||||
return arg_value
|
return arg_value
|
||||||
|
@ -33,7 +33,7 @@ class node:
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, unique, host, options='', logs='', password='', port='', protocol='', user='', config='', tags=''):
|
def __init__(self, unique, host, options='', logs='', password='', port='', protocol='', user='', config='', tags='', jumphost=''):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
### Parameters:
|
### Parameters:
|
||||||
@ -66,6 +66,8 @@ class node:
|
|||||||
|
|
||||||
- tags (dict) : Tags useful for automation and personal porpuse
|
- tags (dict) : Tags useful for automation and personal porpuse
|
||||||
like "os", "prompt" and "screenleght_command"
|
like "os", "prompt" and "screenleght_command"
|
||||||
|
|
||||||
|
- jumphost (str): Reference another node to be used as a jumphost
|
||||||
'''
|
'''
|
||||||
if config == '':
|
if config == '':
|
||||||
self.idletime = 0
|
self.idletime = 0
|
||||||
@ -74,7 +76,7 @@ class node:
|
|||||||
self.idletime = config.config["idletime"]
|
self.idletime = config.config["idletime"]
|
||||||
self.key = config.key
|
self.key = config.key
|
||||||
self.unique = unique
|
self.unique = unique
|
||||||
attr = {"host": host, "logs": logs, "options":options, "port": port, "protocol": protocol, "user": user, "tags": tags}
|
attr = {"host": host, "logs": logs, "options":options, "port": port, "protocol": protocol, "user": user, "tags": tags, "jumphost": jumphost}
|
||||||
for key in attr:
|
for key in attr:
|
||||||
profile = re.search("^@(.*)", str(attr[key]))
|
profile = re.search("^@(.*)", str(attr[key]))
|
||||||
if profile and config != '':
|
if profile and config != '':
|
||||||
@ -97,6 +99,45 @@ class node:
|
|||||||
self.password.append(config.profiles[profile.group(1)]["password"])
|
self.password.append(config.profiles[profile.group(1)]["password"])
|
||||||
else:
|
else:
|
||||||
self.password = [password]
|
self.password = [password]
|
||||||
|
if self.jumphost != "" and config != '':
|
||||||
|
self.jumphost = config.getitem(self.jumphost)
|
||||||
|
for key in self.jumphost:
|
||||||
|
profile = re.search("^@(.*)", str(self.jumphost[key]))
|
||||||
|
if profile:
|
||||||
|
try:
|
||||||
|
self.jumphost[key] = config.profiles[profile.group(1)][key]
|
||||||
|
except:
|
||||||
|
self.jumphost[key] = ""
|
||||||
|
elif self.jumphost[key] == '' and key == "protocol":
|
||||||
|
try:
|
||||||
|
self.jumphost[key] = config.profiles["default"][key]
|
||||||
|
except:
|
||||||
|
self.jumphost[key] = "ssh"
|
||||||
|
if isinstance(self.jumphost["password"],list):
|
||||||
|
jumphost_password = []
|
||||||
|
for i, s in enumerate(self.jumphost["password"]):
|
||||||
|
profile = re.search("^@(.*)", self.jumphost["password"][i])
|
||||||
|
if profile:
|
||||||
|
jumphost_password.append(config.profiles[profile.group(1)]["password"])
|
||||||
|
self.jumphost["password"] = jumphost_password
|
||||||
|
else:
|
||||||
|
self.jumphost["password"] = [self.jumphost["password"]]
|
||||||
|
if self.jumphost["password"] != [""]:
|
||||||
|
self.password = self.jumphost["password"] + self.password
|
||||||
|
|
||||||
|
if self.jumphost["protocol"] == "ssh":
|
||||||
|
jumphost_cmd = self.jumphost["protocol"] + " -W %h:%p"
|
||||||
|
if self.jumphost["port"] != '':
|
||||||
|
jumphost_cmd = jumphost_cmd + " -p " + self.jumphost["port"]
|
||||||
|
if self.jumphost["options"] != '':
|
||||||
|
jumphost_cmd = jumphost_cmd + " " + self.jumphost["options"]
|
||||||
|
if self.jumphost["user"] == '':
|
||||||
|
jumphost_cmd = jumphost_cmd + " {}".format(self.jumphost["host"])
|
||||||
|
else:
|
||||||
|
jumphost_cmd = jumphost_cmd + " {}".format("@".join([self.jumphost["user"],self.jumphost["host"]]))
|
||||||
|
self.jumphost = f"-o ProxyCommand=\"{jumphost_cmd}\""
|
||||||
|
else:
|
||||||
|
self.jumphost = ""
|
||||||
|
|
||||||
def _passtx(self, passwords, *, keyfile=None):
|
def _passtx(self, passwords, *, keyfile=None):
|
||||||
# decrypts passwords, used by other methdos.
|
# decrypts passwords, used by other methdos.
|
||||||
@ -431,6 +472,8 @@ class node:
|
|||||||
cmd = cmd + " " + self.options
|
cmd = cmd + " " + self.options
|
||||||
if self.logs != '':
|
if self.logs != '':
|
||||||
self.logfile = self._logfile()
|
self.logfile = self._logfile()
|
||||||
|
if self.jumphost != '':
|
||||||
|
cmd = cmd + " " + self.jumphost
|
||||||
if self.password[0] != '':
|
if self.password[0] != '':
|
||||||
passwords = self._passtx(self.password)
|
passwords = self._passtx(self.password)
|
||||||
else:
|
else:
|
||||||
@ -439,7 +482,7 @@ class node:
|
|||||||
cmd = cmd + " {}".format(self.host)
|
cmd = cmd + " {}".format(self.host)
|
||||||
else:
|
else:
|
||||||
cmd = cmd + " {}".format("@".join([self.user,self.host]))
|
cmd = cmd + " {}".format("@".join([self.user,self.host]))
|
||||||
expects = ['yes/no', 'refused', 'supported', 'Invalid|[u|U]sage:', 'ssh-keygen.*\"', 'timeout|timed.out', 'unavailable', 'closed', '[p|P]assword:|[u|U]sername:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching", "bad permissions"]
|
expects = ['yes/no', 'refused', 'supported', 'Invalid|[u|U]sage: (ssh|sftp)', 'ssh-keygen.*\"', 'timeout|timed.out', 'unavailable', 'closed', '[p|P]assword:|[u|U]sername:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching", "bad permissions"]
|
||||||
elif self.protocol == "telnet":
|
elif self.protocol == "telnet":
|
||||||
cmd = "telnet " + self.host
|
cmd = "telnet " + self.host
|
||||||
if self.port != '':
|
if self.port != '':
|
||||||
@ -452,7 +495,7 @@ class node:
|
|||||||
passwords = self._passtx(self.password)
|
passwords = self._passtx(self.password)
|
||||||
else:
|
else:
|
||||||
passwords = []
|
passwords = []
|
||||||
expects = ['[u|U]sername:', 'refused', 'supported', 'cipher', 'ssh-keygen.*\"', 'timeout|timed.out', 'unavailable', 'closed', '[p|P]assword:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching", "bad permissions"]
|
expects = ['[u|U]sername:', 'refused', 'supported', 'invalid option', 'ssh-keygen.*\"', 'timeout|timed.out', 'unavailable', 'closed', '[p|P]assword:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching", "bad permissions"]
|
||||||
else:
|
else:
|
||||||
raise ValueError("Invalid protocol: " + self.protocol)
|
raise ValueError("Invalid protocol: " + self.protocol)
|
||||||
attempts = 1
|
attempts = 1
|
||||||
|
@ -1390,7 +1390,7 @@ Categorize the user's request based on the operation they want to perform on
|
|||||||
|
|
||||||
def _createconfig(self, conf):
|
def _createconfig(self, conf):
|
||||||
#Create config file
|
#Create config file
|
||||||
defaultconfig = {'config': {'case': False, 'idletime': 30, 'fzf': False}, 'connections': {}, 'profiles': { "default": { "host":"", "protocol":"ssh", "port":"", "user":"", "password":"", "options":"", "logs":"", "tags": "" }}}
|
defaultconfig = {'config': {'case': False, 'idletime': 30, 'fzf': False}, 'connections': {}, 'profiles': { "default": { "host":"", "protocol":"ssh", "port":"", "user":"", "password":"", "options":"", "logs":"", "tags": "", "jumphost":""}}}
|
||||||
if not os.path.exists(conf):
|
if not os.path.exists(conf):
|
||||||
with open(conf, "w") as f:
|
with open(conf, "w") as f:
|
||||||
json.dump(defaultconfig, f, indent = 4)
|
json.dump(defaultconfig, f, indent = 4)
|
||||||
@ -1536,14 +1536,14 @@ Categorize the user's request based on the operation they want to perform on
|
|||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
|
|
||||||
def _connections_add(self,*, id, host, folder='', subfolder='', options='', logs='', password='', port='', protocol='', user='', tags='', type = "connection" ):
|
def _connections_add(self,*, id, host, folder='', subfolder='', options='', logs='', password='', port='', protocol='', user='', tags='', jumphost='', type = "connection" ):
|
||||||
#Add connection from config
|
#Add connection from config
|
||||||
if folder == '':
|
if folder == '':
|
||||||
self.connections[id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags,"type": type}
|
self.connections[id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags,"jumphost": jumphost,"type": type}
|
||||||
elif folder != '' and subfolder == '':
|
elif folder != '' and subfolder == '':
|
||||||
self.connections[folder][id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags, "type": type}
|
self.connections[folder][id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags, "jumphost": jumphost, "type": type}
|
||||||
elif folder != '' and subfolder != '':
|
elif folder != '' and subfolder != '':
|
||||||
self.connections[folder][subfolder][id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags, "type": type}
|
self.connections[folder][subfolder][id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags, "jumphost": jumphost, "type": type}
|
||||||
|
|
||||||
|
|
||||||
def _connections_del(self,*, id, folder='', subfolder=''):
|
def _connections_del(self,*, id, folder='', subfolder=''):
|
||||||
@ -1572,9 +1572,9 @@ Categorize the user's request based on the operation they want to perform on
|
|||||||
del self.connections[folder][subfolder]
|
del self.connections[folder][subfolder]
|
||||||
|
|
||||||
|
|
||||||
def _profiles_add(self,*, id, host = '', options='', logs='', password='', port='', protocol='', user='', tags='' ):
|
def _profiles_add(self,*, id, host = '', options='', logs='', password='', port='', protocol='', user='', tags='', jumphost='' ):
|
||||||
#Add profile from config
|
#Add profile from config
|
||||||
self.profiles[id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags}
|
self.profiles[id] = {"host": host, "options": options, "logs": logs, "password": password, "port": port, "protocol": protocol, "user": user, "tags": tags, "jumphost": jumphost}
|
||||||
|
|
||||||
|
|
||||||
def _profiles_del(self,*, id ):
|
def _profiles_del(self,*, id ):
|
||||||
@ -2332,6 +2332,7 @@ Categorize the user's request based on the operation they want to perform on
|
|||||||
newnode["options"] = newnodes["options"]
|
newnode["options"] = newnodes["options"]
|
||||||
newnode["logs"] = newnodes["logs"]
|
newnode["logs"] = newnodes["logs"]
|
||||||
newnode["tags"] = newnodes["tags"]
|
newnode["tags"] = newnodes["tags"]
|
||||||
|
newnode["jumphost"] = newnodes["jumphost"]
|
||||||
newnode["user"] = newnodes["user"]
|
newnode["user"] = newnodes["user"]
|
||||||
newnode["password"] = newnodes["password"]
|
newnode["password"] = newnodes["password"]
|
||||||
count +=1
|
count +=1
|
||||||
@ -2785,6 +2786,23 @@ Categorize the user's request based on the operation they want to perform on
|
|||||||
raise inquirer.errors.ValidationError("", reason="Tags should be a python dictionary.".format(current))
|
raise inquirer.errors.ValidationError("", reason="Tags should be a python dictionary.".format(current))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def _jumphost_validation(self, answers, current):
|
||||||
|
#Validation for Jumphost in inquirer when managing nodes
|
||||||
|
if current.startswith("@"):
|
||||||
|
if current[1:] not in self.profiles:
|
||||||
|
raise inquirer.errors.ValidationError("", reason="Profile {} don't exist".format(current))
|
||||||
|
elif current != "":
|
||||||
|
if current not in self.nodes :
|
||||||
|
raise inquirer.errors.ValidationError("", reason="Node {} don't exist.".format(current))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _profile_jumphost_validation(self, answers, current):
|
||||||
|
#Validation for Jumphost in inquirer when managing profiles
|
||||||
|
if current != "":
|
||||||
|
if current not in self.nodes :
|
||||||
|
raise inquirer.errors.ValidationError("", reason="Node {} don't exist.".format(current))
|
||||||
|
return True
|
||||||
|
|
||||||
def _default_validation(self, answers, current):
|
def _default_validation(self, answers, current):
|
||||||
#Default validation type used in multiples questions in inquirer
|
#Default validation type used in multiples questions in inquirer
|
||||||
if current.startswith("@"):
|
if current.startswith("@"):
|
||||||
@ -2832,6 +2850,7 @@ Categorize the user's request based on the operation they want to perform on
|
|||||||
questions.append(inquirer.Confirm("options", message="Edit Options?"))
|
questions.append(inquirer.Confirm("options", message="Edit Options?"))
|
||||||
questions.append(inquirer.Confirm("logs", message="Edit logging path/file?"))
|
questions.append(inquirer.Confirm("logs", message="Edit logging path/file?"))
|
||||||
questions.append(inquirer.Confirm("tags", message="Edit tags?"))
|
questions.append(inquirer.Confirm("tags", message="Edit tags?"))
|
||||||
|
questions.append(inquirer.Confirm("jumphost", message="Edit jumphost?"))
|
||||||
questions.append(inquirer.Confirm("user", message="Edit User?"))
|
questions.append(inquirer.Confirm("user", message="Edit User?"))
|
||||||
questions.append(inquirer.Confirm("password", message="Edit password?"))
|
questions.append(inquirer.Confirm("password", message="Edit password?"))
|
||||||
answers = inquirer.prompt(questions)
|
answers = inquirer.prompt(questions)
|
||||||
@ -2843,11 +2862,13 @@ Categorize the user's request based on the operation they want to perform on
|
|||||||
defaults = self.config.getitem(unique)
|
defaults = self.config.getitem(unique)
|
||||||
if "tags" not in defaults:
|
if "tags" not in defaults:
|
||||||
defaults["tags"] = ""
|
defaults["tags"] = ""
|
||||||
|
if "jumphost" not in defaults:
|
||||||
|
defaults["jumphost"] = ""
|
||||||
except:
|
except:
|
||||||
defaults = { "host":"", "protocol":"", "port":"", "user":"", "options":"", "logs":"" , "tags":"", "password":""}
|
defaults = { "host":"", "protocol":"", "port":"", "user":"", "options":"", "logs":"" , "tags":"", "password":"", "jumphost":""}
|
||||||
node = {}
|
node = {}
|
||||||
if edit == None:
|
if edit == None:
|
||||||
edit = { "host":True, "protocol":True, "port":True, "user":True, "password": True,"options":True, "logs":True, "tags":True }
|
edit = { "host":True, "protocol":True, "port":True, "user":True, "password": True,"options":True, "logs":True, "tags":True, "jumphost":True }
|
||||||
questions = []
|
questions = []
|
||||||
if edit["host"]:
|
if edit["host"]:
|
||||||
questions.append(inquirer.Text("host", message="Add Hostname or IP", validate=self._host_validation, default=defaults["host"]))
|
questions.append(inquirer.Text("host", message="Add Hostname or IP", validate=self._host_validation, default=defaults["host"]))
|
||||||
@ -2873,6 +2894,10 @@ Categorize the user's request based on the operation they want to perform on
|
|||||||
questions.append(inquirer.Text("tags", message="Add tags dictionary", validate=self._tags_validation, default=str(defaults["tags"]).replace("{","{{").replace("}","}}")))
|
questions.append(inquirer.Text("tags", message="Add tags dictionary", validate=self._tags_validation, default=str(defaults["tags"]).replace("{","{{").replace("}","}}")))
|
||||||
else:
|
else:
|
||||||
node["tags"] = defaults["tags"]
|
node["tags"] = defaults["tags"]
|
||||||
|
if edit["jumphost"]:
|
||||||
|
questions.append(inquirer.Text("jumphost", message="Add Jumphost node", validate=self._jumphost_validation, default=str(defaults["jumphost"]).replace("{","{{").replace("}","}}")))
|
||||||
|
else:
|
||||||
|
node["jumphost"] = defaults["jumphost"]
|
||||||
if edit["user"]:
|
if edit["user"]:
|
||||||
questions.append(inquirer.Text("user", message="Pick username", validate=self._default_validation, default=defaults["user"]))
|
questions.append(inquirer.Text("user", message="Pick username", validate=self._default_validation, default=defaults["user"]))
|
||||||
else:
|
else:
|
||||||
@ -2911,11 +2936,13 @@ Categorize the user's request based on the operation they want to perform on
|
|||||||
defaults = self.config.profiles[unique]
|
defaults = self.config.profiles[unique]
|
||||||
if "tags" not in defaults:
|
if "tags" not in defaults:
|
||||||
defaults["tags"] = ""
|
defaults["tags"] = ""
|
||||||
|
if "jumphost" not in defaults:
|
||||||
|
defaults["jumphost"] = ""
|
||||||
except:
|
except:
|
||||||
defaults = { "host":"", "protocol":"", "port":"", "user":"", "options":"", "logs":"", "tags": "" }
|
defaults = { "host":"", "protocol":"", "port":"", "user":"", "options":"", "logs":"", "tags": "", "jumphost": ""}
|
||||||
profile = {}
|
profile = {}
|
||||||
if edit == None:
|
if edit == None:
|
||||||
edit = { "host":True, "protocol":True, "port":True, "user":True, "password": True,"options":True, "logs":True, "tags":True }
|
edit = { "host":True, "protocol":True, "port":True, "user":True, "password": True,"options":True, "logs":True, "tags":True, "jumphost":True }
|
||||||
questions = []
|
questions = []
|
||||||
if edit["host"]:
|
if edit["host"]:
|
||||||
questions.append(inquirer.Text("host", message="Add Hostname or IP", default=defaults["host"]))
|
questions.append(inquirer.Text("host", message="Add Hostname or IP", default=defaults["host"]))
|
||||||
@ -2941,6 +2968,10 @@ Categorize the user's request based on the operation they want to perform on
|
|||||||
questions.append(inquirer.Text("tags", message="Add tags dictionary", validate=self._profile_tags_validation, default=str(defaults["tags"]).replace("{","{{").replace("}","}}")))
|
questions.append(inquirer.Text("tags", message="Add tags dictionary", validate=self._profile_tags_validation, default=str(defaults["tags"]).replace("{","{{").replace("}","}}")))
|
||||||
else:
|
else:
|
||||||
profile["tags"] = defaults["tags"]
|
profile["tags"] = defaults["tags"]
|
||||||
|
if edit["jumphost"]:
|
||||||
|
questions.append(inquirer.Text("jumphost", message="Add Jumphost node", validate=self._profile_jumphost_validation, default=str(defaults["jumphost"]).replace("{","{{").replace("}","}}")))
|
||||||
|
else:
|
||||||
|
profile["jumphost"] = defaults["jumphost"]
|
||||||
if edit["user"]:
|
if edit["user"]:
|
||||||
questions.append(inquirer.Text("user", message="Pick username", default=defaults["user"]))
|
questions.append(inquirer.Text("user", message="Pick username", default=defaults["user"]))
|
||||||
else:
|
else:
|
||||||
@ -2972,6 +3003,7 @@ Categorize the user's request based on the operation they want to perform on
|
|||||||
questions.append(inquirer.Text("options", message="Pass extra options to protocol", validate=self._default_validation))
|
questions.append(inquirer.Text("options", message="Pass extra options to protocol", validate=self._default_validation))
|
||||||
questions.append(inquirer.Text("logs", message="Pick logging path/file ", validate=self._default_validation))
|
questions.append(inquirer.Text("logs", message="Pick logging path/file ", validate=self._default_validation))
|
||||||
questions.append(inquirer.Text("tags", message="Add tags dictionary", validate=self._tags_validation))
|
questions.append(inquirer.Text("tags", message="Add tags dictionary", validate=self._tags_validation))
|
||||||
|
questions.append(inquirer.Text("jumphost", message="Add Jumphost node", validate=self._jumphost_validation))
|
||||||
questions.append(inquirer.Text("user", message="Pick username", validate=self._default_validation))
|
questions.append(inquirer.Text("user", message="Pick username", validate=self._default_validation))
|
||||||
questions.append(inquirer.List("password", message="Password: Use a local password, no password or a list of profiles to reference?", choices=["Local Password", "Profiles", "No Password"]))
|
questions.append(inquirer.List("password", message="Password: Use a local password, no password or a list of profiles to reference?", choices=["Local Password", "Profiles", "No Password"]))
|
||||||
answer = inquirer.prompt(questions)
|
answer = inquirer.prompt(questions)
|
||||||
@ -2994,6 +3026,8 @@ Categorize the user's request based on the operation they want to perform on
|
|||||||
return answer
|
return answer
|
||||||
|
|
||||||
def _type_node(self, arg_value, pat=re.compile(r"^[0-9a-zA-Z_.$@#-]+$")):
|
def _type_node(self, arg_value, pat=re.compile(r"^[0-9a-zA-Z_.$@#-]+$")):
|
||||||
|
if arg_value == None:
|
||||||
|
raise ValueError("Missing argument node")
|
||||||
if not pat.match(arg_value):
|
if not pat.match(arg_value):
|
||||||
raise ValueError(f"Argument error: {arg_value}")
|
raise ValueError(f"Argument error: {arg_value}")
|
||||||
return arg_value
|
return arg_value
|
||||||
@ -3326,7 +3360,7 @@ tasks:
|
|||||||
</dd>
|
</dd>
|
||||||
<dt id="connpy.node"><code class="flex name class">
|
<dt id="connpy.node"><code class="flex name class">
|
||||||
<span>class <span class="ident">node</span></span>
|
<span>class <span class="ident">node</span></span>
|
||||||
<span>(</span><span>unique, host, options='', logs='', password='', port='', protocol='', user='', config='', tags='')</span>
|
<span>(</span><span>unique, host, options='', logs='', password='', port='', protocol='', user='', config='', tags='', jumphost='')</span>
|
||||||
</code></dt>
|
</code></dt>
|
||||||
<dd>
|
<dd>
|
||||||
<div class="desc"><p>This class generates a node object. Containts all the information and methods to connect and interact with a device using ssh or telnet.</p>
|
<div class="desc"><p>This class generates a node object. Containts all the information and methods to connect and interact with a device using ssh or telnet.</p>
|
||||||
@ -3369,6 +3403,8 @@ tasks:
|
|||||||
|
|
||||||
- tags (dict) : Tags useful for automation and personal porpuse
|
- tags (dict) : Tags useful for automation and personal porpuse
|
||||||
like "os", "prompt" and "screenleght_command"
|
like "os", "prompt" and "screenleght_command"
|
||||||
|
|
||||||
|
- jumphost (str): Reference another node to be used as a jumphost
|
||||||
</code></pre></div>
|
</code></pre></div>
|
||||||
<details class="source">
|
<details class="source">
|
||||||
<summary>
|
<summary>
|
||||||
@ -3391,7 +3427,7 @@ tasks:
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, unique, host, options='', logs='', password='', port='', protocol='', user='', config='', tags=''):
|
def __init__(self, unique, host, options='', logs='', password='', port='', protocol='', user='', config='', tags='', jumphost=''):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
### Parameters:
|
### Parameters:
|
||||||
@ -3424,6 +3460,8 @@ tasks:
|
|||||||
|
|
||||||
- tags (dict) : Tags useful for automation and personal porpuse
|
- tags (dict) : Tags useful for automation and personal porpuse
|
||||||
like "os", "prompt" and "screenleght_command"
|
like "os", "prompt" and "screenleght_command"
|
||||||
|
|
||||||
|
- jumphost (str): Reference another node to be used as a jumphost
|
||||||
'''
|
'''
|
||||||
if config == '':
|
if config == '':
|
||||||
self.idletime = 0
|
self.idletime = 0
|
||||||
@ -3432,7 +3470,7 @@ tasks:
|
|||||||
self.idletime = config.config["idletime"]
|
self.idletime = config.config["idletime"]
|
||||||
self.key = config.key
|
self.key = config.key
|
||||||
self.unique = unique
|
self.unique = unique
|
||||||
attr = {"host": host, "logs": logs, "options":options, "port": port, "protocol": protocol, "user": user, "tags": tags}
|
attr = {"host": host, "logs": logs, "options":options, "port": port, "protocol": protocol, "user": user, "tags": tags, "jumphost": jumphost}
|
||||||
for key in attr:
|
for key in attr:
|
||||||
profile = re.search("^@(.*)", str(attr[key]))
|
profile = re.search("^@(.*)", str(attr[key]))
|
||||||
if profile and config != '':
|
if profile and config != '':
|
||||||
@ -3455,6 +3493,45 @@ tasks:
|
|||||||
self.password.append(config.profiles[profile.group(1)]["password"])
|
self.password.append(config.profiles[profile.group(1)]["password"])
|
||||||
else:
|
else:
|
||||||
self.password = [password]
|
self.password = [password]
|
||||||
|
if self.jumphost != "" and config != '':
|
||||||
|
self.jumphost = config.getitem(self.jumphost)
|
||||||
|
for key in self.jumphost:
|
||||||
|
profile = re.search("^@(.*)", str(self.jumphost[key]))
|
||||||
|
if profile:
|
||||||
|
try:
|
||||||
|
self.jumphost[key] = config.profiles[profile.group(1)][key]
|
||||||
|
except:
|
||||||
|
self.jumphost[key] = ""
|
||||||
|
elif self.jumphost[key] == '' and key == "protocol":
|
||||||
|
try:
|
||||||
|
self.jumphost[key] = config.profiles["default"][key]
|
||||||
|
except:
|
||||||
|
self.jumphost[key] = "ssh"
|
||||||
|
if isinstance(self.jumphost["password"],list):
|
||||||
|
jumphost_password = []
|
||||||
|
for i, s in enumerate(self.jumphost["password"]):
|
||||||
|
profile = re.search("^@(.*)", self.jumphost["password"][i])
|
||||||
|
if profile:
|
||||||
|
jumphost_password.append(config.profiles[profile.group(1)]["password"])
|
||||||
|
self.jumphost["password"] = jumphost_password
|
||||||
|
else:
|
||||||
|
self.jumphost["password"] = [self.jumphost["password"]]
|
||||||
|
if self.jumphost["password"] != [""]:
|
||||||
|
self.password = self.jumphost["password"] + self.password
|
||||||
|
|
||||||
|
if self.jumphost["protocol"] == "ssh":
|
||||||
|
jumphost_cmd = self.jumphost["protocol"] + " -W %h:%p"
|
||||||
|
if self.jumphost["port"] != '':
|
||||||
|
jumphost_cmd = jumphost_cmd + " -p " + self.jumphost["port"]
|
||||||
|
if self.jumphost["options"] != '':
|
||||||
|
jumphost_cmd = jumphost_cmd + " " + self.jumphost["options"]
|
||||||
|
if self.jumphost["user"] == '':
|
||||||
|
jumphost_cmd = jumphost_cmd + " {}".format(self.jumphost["host"])
|
||||||
|
else:
|
||||||
|
jumphost_cmd = jumphost_cmd + " {}".format("@".join([self.jumphost["user"],self.jumphost["host"]]))
|
||||||
|
self.jumphost = f"-o ProxyCommand=\"{jumphost_cmd}\""
|
||||||
|
else:
|
||||||
|
self.jumphost = ""
|
||||||
|
|
||||||
def _passtx(self, passwords, *, keyfile=None):
|
def _passtx(self, passwords, *, keyfile=None):
|
||||||
# decrypts passwords, used by other methdos.
|
# decrypts passwords, used by other methdos.
|
||||||
@ -3789,6 +3866,8 @@ tasks:
|
|||||||
cmd = cmd + " " + self.options
|
cmd = cmd + " " + self.options
|
||||||
if self.logs != '':
|
if self.logs != '':
|
||||||
self.logfile = self._logfile()
|
self.logfile = self._logfile()
|
||||||
|
if self.jumphost != '':
|
||||||
|
cmd = cmd + " " + self.jumphost
|
||||||
if self.password[0] != '':
|
if self.password[0] != '':
|
||||||
passwords = self._passtx(self.password)
|
passwords = self._passtx(self.password)
|
||||||
else:
|
else:
|
||||||
@ -3797,7 +3876,7 @@ tasks:
|
|||||||
cmd = cmd + " {}".format(self.host)
|
cmd = cmd + " {}".format(self.host)
|
||||||
else:
|
else:
|
||||||
cmd = cmd + " {}".format("@".join([self.user,self.host]))
|
cmd = cmd + " {}".format("@".join([self.user,self.host]))
|
||||||
expects = ['yes/no', 'refused', 'supported', 'Invalid|[u|U]sage:', 'ssh-keygen.*\"', 'timeout|timed.out', 'unavailable', 'closed', '[p|P]assword:|[u|U]sername:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching", "bad permissions"]
|
expects = ['yes/no', 'refused', 'supported', 'Invalid|[u|U]sage: (ssh|sftp)', 'ssh-keygen.*\"', 'timeout|timed.out', 'unavailable', 'closed', '[p|P]assword:|[u|U]sername:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching", "bad permissions"]
|
||||||
elif self.protocol == "telnet":
|
elif self.protocol == "telnet":
|
||||||
cmd = "telnet " + self.host
|
cmd = "telnet " + self.host
|
||||||
if self.port != '':
|
if self.port != '':
|
||||||
@ -3810,7 +3889,7 @@ tasks:
|
|||||||
passwords = self._passtx(self.password)
|
passwords = self._passtx(self.password)
|
||||||
else:
|
else:
|
||||||
passwords = []
|
passwords = []
|
||||||
expects = ['[u|U]sername:', 'refused', 'supported', 'cipher', 'ssh-keygen.*\"', 'timeout|timed.out', 'unavailable', 'closed', '[p|P]assword:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching", "bad permissions"]
|
expects = ['[u|U]sername:', 'refused', 'supported', 'invalid option', 'ssh-keygen.*\"', 'timeout|timed.out', 'unavailable', 'closed', '[p|P]assword:', r'>$|#$|\$$|>.$|#.$|\$.$', 'suspend', pexpect.EOF, pexpect.TIMEOUT, "No route to host", "resolve hostname", "no matching", "bad permissions"]
|
||||||
else:
|
else:
|
||||||
raise ValueError("Invalid protocol: " + self.protocol)
|
raise ValueError("Invalid protocol: " + self.protocol)
|
||||||
attempts = 1
|
attempts = 1
|
||||||
|
Loading…
Reference in New Issue
Block a user