change yaml to json for speed. Add completion
This commit is contained in:
parent
9f3cb6f6d9
commit
8f13b0b2bf
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
#Imports
|
||||
import yaml
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
from Crypto.PublicKey import RSA
|
||||
@ -14,7 +14,7 @@ class configfile:
|
||||
def __init__(self, conf = None, *, key = None):
|
||||
home = os.path.expanduser("~")
|
||||
self.defaultdir = home + '/.config/conn'
|
||||
self.defaultfile = self.defaultdir + '/config.yaml'
|
||||
self.defaultfile = self.defaultdir + '/config.json'
|
||||
self.defaultkey = self.defaultdir + '/.osk'
|
||||
Path(self.defaultdir).mkdir(parents=True, exist_ok=True)
|
||||
if conf == None:
|
||||
@ -39,18 +39,18 @@ class configfile:
|
||||
|
||||
|
||||
def loadconfig(self, conf):
|
||||
ymlconf = open(conf)
|
||||
return yaml.load(ymlconf.read(), Loader=yaml.CLoader)
|
||||
jsonconf = open(conf)
|
||||
return json.load(jsonconf)
|
||||
|
||||
def createconfig(self, conf):
|
||||
defaultconfig = {'config': {'case': False, 'idletime': 30}, 'connections': {}, 'profiles': { "default": { "host":"", "protocol":"ssh", "port":"", "user":"", "password":"", "options":"", "logs":"" }}}
|
||||
if not os.path.exists(conf):
|
||||
with open(conf, "w") as f:
|
||||
yaml.dump(defaultconfig, f, explicit_start=True, Dumper=yaml.CDumper)
|
||||
json.dump(defaultconfig, f, indent = 4)
|
||||
f.close()
|
||||
os.chmod(conf, 0o600)
|
||||
ymlconf = open(conf)
|
||||
return yaml.load(ymlconf.read(), Loader=yaml.CLoader)
|
||||
jsonconf = open(conf)
|
||||
return json.load(jsonconf)
|
||||
|
||||
def saveconfig(self, conf):
|
||||
newconfig = {"config":{}, "connections": {}, "profiles": {}}
|
||||
@ -58,7 +58,7 @@ class configfile:
|
||||
newconfig["connections"] = self.connections
|
||||
newconfig["profiles"] = self.profiles
|
||||
with open(conf, "w") as f:
|
||||
yaml.dump(newconfig, f, explicit_start=True, Dumper=yaml.CDumper)
|
||||
json.dump(newconfig, f, indent = 4)
|
||||
f.close()
|
||||
|
||||
def createkey(self, keyfile):
|
||||
|
@ -8,7 +8,7 @@ import ast
|
||||
import argparse
|
||||
import sys
|
||||
import inquirer
|
||||
import yaml
|
||||
import json
|
||||
|
||||
#functions and classes
|
||||
|
||||
@ -63,6 +63,7 @@ class connapp:
|
||||
configparser = subparsers.add_parser("config", help="Manage app config")
|
||||
configparser.add_argument("--allow-uppercase", dest="case", nargs=1, action=self.store_type, help="Allow case sensitive names", choices=["true","false"])
|
||||
configparser.add_argument("--keepalive", dest="idletime", nargs=1, action=self.store_type, help="Set keepalive time in seconds, 0 to disable", type=int, metavar="INT")
|
||||
configparser.add_argument("--completion", dest="completion", nargs=0, action=self.store_type, help="Get bash completion configuration for conn")
|
||||
configparser.set_defaults(func=self._func_others)
|
||||
#Set default subparser and tune arguments
|
||||
commands = ["node", "profile", "mv", "move","copy", "cp", "bulk", "ls", "list", "config"]
|
||||
@ -188,7 +189,13 @@ class connapp:
|
||||
print("{} not found".format(args.data))
|
||||
exit(2)
|
||||
node = self.config.getitem(matches[0])
|
||||
print(yaml.dump(node, Dumper=yaml.CDumper))
|
||||
for k, v in node.items():
|
||||
if isinstance(v, str):
|
||||
print(k + ": " + v)
|
||||
else:
|
||||
print(k + ":")
|
||||
for i in v:
|
||||
print(" - " + i)
|
||||
elif args.action == "mod":
|
||||
if args.data == None:
|
||||
print("Missing argument node")
|
||||
@ -243,7 +250,13 @@ class connapp:
|
||||
print("{} not found".format(args.data[0]))
|
||||
exit(2)
|
||||
profile = self.config.profiles[matches[0]]
|
||||
print(yaml.dump(profile, Dumper=yaml.CDumper))
|
||||
for k, v in profile.items():
|
||||
if isinstance(v, str):
|
||||
print(k + ": " + v)
|
||||
else:
|
||||
print(k + ":")
|
||||
for i in v:
|
||||
print(" - " + i)
|
||||
elif args.action == "add":
|
||||
matches = list(filter(lambda k: k == args.data[0], self.profiles))
|
||||
if len(matches) > 0:
|
||||
@ -355,6 +368,9 @@ class connapp:
|
||||
print("Succesfully added {} nodes".format(count))
|
||||
else:
|
||||
print("0 nodes added")
|
||||
else:
|
||||
if args.command == "completion":
|
||||
print(self._help("completion"))
|
||||
else:
|
||||
if args.command == "case":
|
||||
if args.data[0] == "true":
|
||||
@ -627,6 +643,53 @@ class connapp:
|
||||
return "conn [-h] [--add | --del | --mod | --show | --debug] [node|folder]\n conn {profile,move,mv,copy,cp,list,ls,bulk,config} ..."
|
||||
if type == "end":
|
||||
return "Commands:\n profile Manage profiles\n move (mv) Move node\n copy (cp) Copy node\n list (ls) List profiles, nodes or folders\n bulk Add nodes in bulk\n config Manage app config"
|
||||
if type == "completion":
|
||||
return '''
|
||||
#Here starts bash completion for conn
|
||||
#You need jq installed in order to use this
|
||||
_conn()
|
||||
{
|
||||
|
||||
DATADIR=$HOME/.config/conn
|
||||
mapfile -t connections < <(jq -r ' .["connections"] | paths as $path | select(getpath($path) == "connection") | $path | [map(select(. != "type"))[-1,-2,-3]] | map(select(. !=null)) | join("@")' $DATADIR/config.json)
|
||||
mapfile -t folders < <(jq -r ' .["connections"] | paths as $path | select(getpath($path) == "folder" or getpath($path) == "subfolder") | $path | [map(select(. != "type"))[-1,-2]] | map(select(. !=null)) | join("@")' $DATADIR/config.json)
|
||||
mapfile -t profiles < <(jq -r '.["profiles"] | keys[]' $DATADIR/config.json)
|
||||
if [ "${#COMP_WORDS[@]}" = "2" ]; then
|
||||
strings="--add --del --rm --edit --mod mv --show ls cp profile bulk config --help"
|
||||
strings="$strings ${connections[@]} ${folders[@]/#/@}"
|
||||
COMPREPLY=($(compgen -W "$strings" -- "${COMP_WORDS[1]}"))
|
||||
fi
|
||||
if [ "${#COMP_WORDS[@]}" = "3" ]; then
|
||||
strings=""
|
||||
if [ "${COMP_WORDS[1]}" = "profile" ]; then strings="--add --rm --del --edit --mod --show --help"; fi
|
||||
if [ "${COMP_WORDS[1]}" = "config" ]; then strings="--allow-uppercase --keepalive --completion --help"; fi
|
||||
if [[ "${COMP_WORDS[1]}" =~ ^--mod|--edit|--show|--add|--rm|--del$ ]]; then strings="profile"; fi
|
||||
if [[ "${COMP_WORDS[1]}" =~ ^list|ls$ ]]; then strings="profiles nodes folders"; fi
|
||||
if [[ "${COMP_WORDS[1]}" =~ ^bulk|mv|move|cp|copy$$ ]]; then strings="--help"; fi
|
||||
if [[ "${COMP_WORDS[1]}" =~ ^--rm|--del$ ]]; then strings="$strings ${folders[@]/#/@}"; fi
|
||||
if [[ "${COMP_WORDS[1]}" =~ ^--rm|--del|--mod|--edit|mv|move|cp|copy|--show$ ]]; then
|
||||
strings="$strings ${connections[@]}"
|
||||
fi
|
||||
COMPREPLY=($(compgen -W "$strings" -- "${COMP_WORDS[2]}"))
|
||||
fi
|
||||
if [ "${#COMP_WORDS[@]}" = "4" ]; then
|
||||
strings=""
|
||||
if [ "${COMP_WORDS[1]}" = "profile" ]; then
|
||||
if [[ "${COMP_WORDS[2]}" =~ ^--rm|--del|--mod|--edit|--show$ ]] ; then
|
||||
strings="$strings ${profiles[@]}"
|
||||
fi
|
||||
fi
|
||||
if [ "${COMP_WORDS[2]}" = "profile" ]; then
|
||||
if [[ "${COMP_WORDS[1]}" =~ ^--rm|--remove|--del|--mod|--edit|--show$ ]] ; then
|
||||
strings="$strings ${profiles[@]}"
|
||||
fi
|
||||
fi
|
||||
COMPREPLY=($(compgen -W "$strings" -- "${COMP_WORDS[3]}"))
|
||||
fi
|
||||
}
|
||||
complete -o nosort -F _conn conn
|
||||
|
||||
'''
|
||||
|
||||
def _getallnodes(self):
|
||||
nodes = []
|
||||
@ -672,4 +735,4 @@ class connapp:
|
||||
publickey = key.publickey()
|
||||
encryptor = PKCS1_OAEP.new(publickey)
|
||||
password = encryptor.encrypt(password.encode("utf-8"))
|
||||
return password
|
||||
return str(password)
|
||||
|
@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#Imports
|
||||
import yaml
|
||||
import os
|
||||
import re
|
||||
import pexpect
|
||||
@ -52,11 +51,11 @@ class node:
|
||||
key = RSA.import_key(open(keyfile).read())
|
||||
decryptor = PKCS1_OAEP.new(key)
|
||||
for passwd in passwords:
|
||||
if isinstance(passwd, str):
|
||||
if not re.match('^b[\"\'].+[\"\']$', passwd):
|
||||
dpass.append(passwd)
|
||||
else:
|
||||
try:
|
||||
decrypted = decryptor.decrypt(ast.literal_eval(str(passwd))).decode("utf-8")
|
||||
decrypted = decryptor.decrypt(ast.literal_eval(passwd)).decode("utf-8")
|
||||
dpass.append(decrypted)
|
||||
except:
|
||||
raise ValueError("Missing or corrupted key")
|
||||
|
@ -1,4 +1,4 @@
|
||||
inquirer~=2.9.2
|
||||
pexpect~=4.8.0
|
||||
pycryptodome~=3.14.1
|
||||
PyYAML~=6.0
|
||||
setuptools~=59.4.0
|
||||
|
2
setup.py
2
setup.py
@ -18,7 +18,7 @@ setup(
|
||||
long_description_content_type="text/markdown",
|
||||
url="https://github.com/fluzzi/connpy",
|
||||
packages=find_packages(),
|
||||
install_requires=["inquirer","pexpect","pycryptodome","PyYAML"], # add any additional packages that
|
||||
install_requires=["inquirer","pexpect","pycryptodome"], # add any additional packages that
|
||||
keywords=['networking', 'automation', 'ssh', 'telnet', 'connection manager'],
|
||||
classifiers= [
|
||||
"Development Status :: 4 - Beta",
|
||||
|
Loading…
Reference in New Issue
Block a user