Merge branch 'remote_sync'
This commit is contained in:
commit
0d5032352a
8 changed files with 111 additions and 11 deletions
3
TODO
3
TODO
|
@ -37,3 +37,6 @@ index 6ba2a6e..6486e11 100755
|
||||||
parser.add_argument('fname', nargs='?', default=None,
|
parser.add_argument('fname', nargs='?', default=None,
|
||||||
help="Nom du fichier à afficher")
|
help="Nom du fichier à afficher")
|
||||||
|
|
||||||
|
ssh-keygen -y -f ~/test_agent > test_agent.pub
|
||||||
|
ssh-add ma_cle_prive
|
||||||
|
ssh-add -d ma_cle_publique
|
||||||
|
|
|
@ -33,12 +33,14 @@ try:
|
||||||
sys.path.append(os.path.expanduser("~/.config/%s/" % (bootstrap_cmd_name,)))
|
sys.path.append(os.path.expanduser("~/.config/%s/" % (bootstrap_cmd_name,)))
|
||||||
import clientconfig as config
|
import clientconfig as config
|
||||||
except ImportError:
|
except ImportError:
|
||||||
ducktape_display_error = sys.stderr.isatty() and not any([opt in sys.argv for opt in ["-q", "--quiet"]])
|
ducktape_display_error = sys.stderr.isatty() and \
|
||||||
|
not any([opt in sys.argv for opt in ["-q", "--quiet"]]) and \
|
||||||
|
__name__ == '__main__'
|
||||||
envspecified = os.getenv(envvar, None)
|
envspecified = os.getenv(envvar, None)
|
||||||
if envspecified is None:
|
if envspecified is None:
|
||||||
if ducktape_display_error:
|
if ducktape_display_error:
|
||||||
sys.stderr.write(u"Va lire le fichier README.\n".encode("utf-8"))
|
sys.stderr.write(u"Va lire le fichier README.\n".encode("utf-8"))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
# On a spécifié à la main le dossier de conf
|
# On a spécifié à la main le dossier de conf
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,9 +1,32 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
""" Configuration du client cranspasswords """
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
#: Liste des serveurs sur lesquels ont peut récupérer des mots de passe.
|
||||||
|
#:
|
||||||
|
#: Sans précision du paramètre --server, la clé ``'default'`` sera utilisée.
|
||||||
|
#:
|
||||||
|
#: * ``'server_cmd'`` : La commande exécutée sur le client pour appeler
|
||||||
|
#: le script sur le serveur distant.
|
||||||
servers = {
|
servers = {
|
||||||
'default': {
|
'default': {
|
||||||
'server_cmd': ['/home/dstan/cranspasswords/serverconfigs/tudor/cpasswords-server', ],
|
'server_cmd': ['/home/dstan/cranspasswords/serverconfigs/tudor/cpasswords-server', ],
|
||||||
'keep-alive': True, # <-- experimental, n'ouvre qu'une connexion
|
'keep-alive': True,
|
||||||
}
|
},
|
||||||
|
'gladys': {
|
||||||
|
'server_cmd': ['/usr/bin/ssh', 'home.b2moo.fr', '/home/dstan/cranspasswords/serverconfigs/tudor/cpasswords-server', ],
|
||||||
|
'keep-alive': True,
|
||||||
|
},
|
||||||
|
'gladys-home': {
|
||||||
|
'server_cmd': ['/usr/bin/ssh', 'gladys.home', '/home/dstan/cranspasswords/serverconfigs/tudor/cpasswords-server', ],
|
||||||
|
'keep-alive': True,
|
||||||
|
},
|
||||||
|
'pimeys': {
|
||||||
|
'server_cmd': ['/usr/bin/ssh', 'pimeys.fr', 'sudo', '-n', '/usr/local/bin/cranspasswords-server', ],
|
||||||
|
'keep-alive': True,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
25
cpasswords/clientlib.py
Normal file
25
cpasswords/clientlib.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Client class definition for cpasswords protocol.
|
||||||
|
|
||||||
|
(WIP)
|
||||||
|
"""
|
||||||
|
|
||||||
|
from cpasswords import client as _old_client
|
||||||
|
|
||||||
|
class Client(object):
|
||||||
|
"""A client connection."""
|
||||||
|
|
||||||
|
verbose = False
|
||||||
|
|
||||||
|
def __init__(self, serverdata):
|
||||||
|
"""
|
||||||
|
serverdata should be a classic dict object (from eg a clientconfig
|
||||||
|
module)
|
||||||
|
"""
|
||||||
|
self.serverdata = serverdata
|
||||||
|
|
||||||
|
def put_file(self, data):
|
||||||
|
"""Send file to server"""
|
||||||
|
# TODO put code here
|
||||||
|
_old_client.put_files(self, [data])
|
30
server.py
30
server.py
|
@ -17,10 +17,19 @@ import itertools
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
from email.mime.multipart import MIMEMultipart
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
|
||||||
|
try:
|
||||||
|
from cpasswords import clientlib
|
||||||
|
except ImportError:
|
||||||
|
print("Couldn't import clientlib. Remote sync may not work")
|
||||||
|
|
||||||
# Même problème que pour le client, il faut bootstraper le nom de la commande
|
# Même problème que pour le client, il faut bootstraper le nom de la commande
|
||||||
# Pour accéder à la config
|
# Pour accéder à la config
|
||||||
cmd_name = os.path.split(sys.argv[0])[1].replace("-server", "")
|
conf_path = os.getenv('CRANSPASSWORDS_SERVER_CONFIG_DIR', None)
|
||||||
sys.path.append("/etc/%s/" % (cmd_name,))
|
if not conf_path:
|
||||||
|
cmd_name = os.path.split(sys.argv[0])[1].replace("-server", "")
|
||||||
|
conf_path = "/etc/%s/" % (cmd_name,)
|
||||||
|
|
||||||
|
sys.path.append(conf_path)
|
||||||
import serverconfig
|
import serverconfig
|
||||||
|
|
||||||
MYUID = pwd.getpwuid(os.getuid())[0]
|
MYUID = pwd.getpwuid(os.getuid())[0]
|
||||||
|
@ -190,6 +199,11 @@ def _putfile(filename, roles, contents):
|
||||||
# Or fuck yourself
|
# Or fuck yourself
|
||||||
|
|
||||||
writefile(filepath, json.dumps({'roles': roles, 'contents': contents}))
|
writefile(filepath, json.dumps({'roles': roles, 'contents': contents}))
|
||||||
|
|
||||||
|
data = {'filename': filename, 'roles': roles, 'contents': contents}
|
||||||
|
for client in _list_to_replicate(data):
|
||||||
|
client.put_file(data)
|
||||||
|
|
||||||
return [True, u"Modification effectuée."]
|
return [True, u"Modification effectuée."]
|
||||||
|
|
||||||
@server_command('putfile', stdin_input=True, write=True)
|
@server_command('putfile', stdin_input=True, write=True)
|
||||||
|
@ -228,7 +242,7 @@ def rmfile(filename):
|
||||||
if validate(roles, 'w'):
|
if validate(roles, 'w'):
|
||||||
corps = u"Le fichier %s a été supprimé par %s." % (filename, MYUID)
|
corps = u"Le fichier %s a été supprimé par %s." % (filename, MYUID)
|
||||||
backup(corps, filename, old)
|
backup(corps, filename, old)
|
||||||
notification(u"Suppression", fname, MYUID)
|
notification(u"Suppression", filename, MYUID)
|
||||||
os.remove(getpath(filename))
|
os.remove(getpath(filename))
|
||||||
else:
|
else:
|
||||||
return u"Vous n'avez pas les droits d'écriture sur le fichier %s." % filename
|
return u"Vous n'avez pas les droits d'écriture sur le fichier %s." % filename
|
||||||
|
@ -245,6 +259,16 @@ def backup(corps, fname, old):
|
||||||
back.write((u'* %s: %s\n' % (str(datetime.datetime.now()), corps)).encode("utf-8"))
|
back.write((u'* %s: %s\n' % (str(datetime.datetime.now()), corps)).encode("utf-8"))
|
||||||
back.close()
|
back.close()
|
||||||
|
|
||||||
|
def _list_to_replicate(data):
|
||||||
|
"""Renvoie une liste d'options clients sur lesquels appliquer relancer
|
||||||
|
la procédure (pour réplication auto)"""
|
||||||
|
roles = data.get('roles', [])
|
||||||
|
backups = getattr(serverconfig, 'BACKUP_ROLES', {})
|
||||||
|
servers = getattr(serverconfig, 'BACKUP_SERVERS', {})
|
||||||
|
|
||||||
|
configs = set(name for role in roles for name in backups.get(role, []))
|
||||||
|
return [ clientlib.Client(servers[name]) for name in configs ]
|
||||||
|
|
||||||
_notif_todo = []
|
_notif_todo = []
|
||||||
def notification(action, fname, actor):
|
def notification(action, fname, actor):
|
||||||
"""Enregistre une notification"""
|
"""Enregistre une notification"""
|
||||||
|
|
1
serverconfigs/tudor/.gitignore
vendored
1
serverconfigs/tudor/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
cpasswords-server
|
|
12
serverconfigs/tudor/cpasswords-server
Executable file
12
serverconfigs/tudor/cpasswords-server
Executable file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Où trouver le paquet python
|
||||||
|
PKG_DIR=~/cranspasswords
|
||||||
|
|
||||||
|
# Où trouver la conf serveur
|
||||||
|
CONF=$PKG_DIR/serverconfigs/tudor
|
||||||
|
|
||||||
|
# Binaire python
|
||||||
|
PYTHON=/usr/bin/python
|
||||||
|
|
||||||
|
/usr/bin/env PYTHONPATH=$PKG_DIR CRANSPASSWORDS_SERVER_CONFIG_DIR=$CONF $PYTHON $PKG_DIR/cpasswords/server.py "$@"
|
|
@ -30,10 +30,22 @@ KEYS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ME = [u'dstan']
|
_ME = [u'dstan']
|
||||||
|
|
||||||
#: Les roles utilisés pour savoir qui a le droit le lire/écrire quoi
|
#: Les roles utilisés pour savoir qui a le droit le lire/écrire quoi
|
||||||
ROLES = {
|
ROLES = {
|
||||||
'moi': ME,
|
'moi': _ME,
|
||||||
'moi-w': ME,
|
'moi-w': _ME,
|
||||||
|
}
|
||||||
|
|
||||||
|
BACKUP_SERVERS = {
|
||||||
|
'gladys': {
|
||||||
|
'server_cmd': ['/usr/bin/ssh', 'home.b2moo.fr', '/home/dstan/cranspasswords/serverconfigs/tudor/cpasswords-server', ],
|
||||||
|
'keep-alive': True,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BACKUP_ROLES = {
|
||||||
|
'moi': ['gladys'],
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue