add PasteDeploy dependency, remove pudge dependency
* upgrade migrate repository structure (fixes #32, #27) * switch to PasteDeploy (fixes #31) * update for SQLAlchemy 0.5 compatibility * add python-gnutls dependency (addresses #35)
This commit is contained in:
parent
483c1f9038
commit
222b35b033
24 changed files with 247 additions and 177 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
|||
*.pyc
|
||||
*.egg/
|
||||
*.log
|
||||
gva.db
|
||||
|
|
50
bin/gva
50
bin/gva
|
@ -21,42 +21,20 @@
|
|||
#
|
||||
# Version: $Id$
|
||||
|
||||
import gnuviechadmin.cli.client
|
||||
import gnuviechadmin.cli.sysuser
|
||||
import gnuviechadmin.cli.domain
|
||||
import gnuviechadmin.cli.record
|
||||
import sys, os, logging.config
|
||||
from paste.deploy import appconfig
|
||||
from sys import argv
|
||||
from os import getcwd
|
||||
from os.path import isfile
|
||||
from logging.config import fileConfig
|
||||
from gnuviechadmin.cli import CommandLineInterface
|
||||
|
||||
logcfgs = ('gnuviechadmin/logging.cfg', '/etc/gnuviechadmin/logging.cfg',
|
||||
os.path.expanduser('~/.gva-logging.cfg'))
|
||||
for cfg in [x for x in logcfgs if os.path.exists(x)]:
|
||||
logging.config.fileConfig(cfg)
|
||||
if len(argv) > 1 and isfile(argv[1]):
|
||||
configfile = argv[1]
|
||||
del argv[1]
|
||||
else:
|
||||
configfile = 'development.ini'
|
||||
|
||||
commands = [gnuviechadmin.cli.client.ClientCli,
|
||||
gnuviechadmin.cli.sysuser.SysuserCli,
|
||||
gnuviechadmin.cli.domain.DomainCli,
|
||||
gnuviechadmin.cli.record.RecordCli]
|
||||
config = appconfig('config:%s' % configfile, relative_to=getcwd())
|
||||
fileConfig(configfile, config)
|
||||
|
||||
def usage():
|
||||
print """%s <command> [commandargs]
|
||||
|
||||
where command is one of
|
||||
""" % sys.argv[0]
|
||||
for command in commands:
|
||||
print "%10s - %s" % (command.name, command.description)
|
||||
|
||||
def main():
|
||||
if (sys.argv.__len__() < 2):
|
||||
usage()
|
||||
sys.exit()
|
||||
command = sys.argv[1]
|
||||
commargs = sys.argv[2:]
|
||||
if command in [cmd.name for cmd in commands]:
|
||||
for cmd in commands:
|
||||
if cmd.name == command:
|
||||
cmd(commargs)
|
||||
else:
|
||||
usage()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
CommandLineInterface(config, argv).run()
|
||||
|
|
62
development.ini
Normal file
62
development.ini
Normal file
|
@ -0,0 +1,62 @@
|
|||
[DEFAULT]
|
||||
mailfrom = gva@gnuviech.info
|
||||
mailto = jan@dittberner.info
|
||||
|
||||
suwrapper = sudo
|
||||
backupdir = /var/backups/gnuviechadmin
|
||||
|
||||
[app:main]
|
||||
use = egg:gnuviechadmin#cli
|
||||
|
||||
# The database connection string in a format usable for
|
||||
# sqlalchemy. The default is an sqlite in memory database which is not
|
||||
# very usable for a real installation.
|
||||
#
|
||||
sqlalchemy.uri = sqlite:///%(here)s/gva.db
|
||||
sqlalchemy.echo = false
|
||||
|
||||
database.repository = %(here)s/data/dbrepo
|
||||
migrate.required_version = 3
|
||||
templatedir = %(here)s/data/templates
|
||||
mailtemplates = %(templatedir)s/mails
|
||||
|
||||
client.defaultcountry = de
|
||||
client.create.mail = create_client.txt
|
||||
client.create_subject = A new client ${firstname} ${lastname} has been created.
|
||||
|
||||
# Logging configuration
|
||||
[loggers]
|
||||
keys = root, gnuviechadmin, sqlalchemy
|
||||
|
||||
[handlers]
|
||||
keys = console
|
||||
|
||||
[formatters]
|
||||
keys = generic
|
||||
|
||||
[logger_root]
|
||||
level = INFO
|
||||
handlers = console
|
||||
|
||||
[logger_gnuviechadmin]
|
||||
level = DEBUG
|
||||
handlers =
|
||||
qualname = gnuviechadmin
|
||||
|
||||
[logger_sqlalchemy]
|
||||
level = WARN
|
||||
handlers =
|
||||
qualname = sqlalchemy.engine
|
||||
# "level = INFO" logs SQL queries.
|
||||
# "level = DEBUG" logs SQL queries and results.
|
||||
# "level = WARN" logs neither. (Recommended for production systems.)
|
||||
|
||||
[handler_console]
|
||||
class = StreamHandler
|
||||
args = (sys.stderr,)
|
||||
level = NOTSET
|
||||
formatter = generic
|
||||
|
||||
[formatter_generic]
|
||||
format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
|
||||
datefmt = %H:%M:%S
|
|
@ -1,6 +1,6 @@
|
|||
Metadata-Version: 1.0
|
||||
Name: gnuviechadmin
|
||||
Version: 0.1.dev-20090718
|
||||
Version: 0.1.dev-20090719
|
||||
Summary: gnuviechadmin server administration suite
|
||||
Home-page: http://www.gnuviech-server.de/projects/gnuviechadmin
|
||||
Author: Jan Dittberner
|
||||
|
|
|
@ -7,6 +7,7 @@ gnuviechadmin/exceptions.py
|
|||
gnuviechadmin.egg-info/PKG-INFO
|
||||
gnuviechadmin.egg-info/SOURCES.txt
|
||||
gnuviechadmin.egg-info/dependency_links.txt
|
||||
gnuviechadmin.egg-info/entry_points.txt
|
||||
gnuviechadmin.egg-info/requires.txt
|
||||
gnuviechadmin.egg-info/top_level.txt
|
||||
gnuviechadmin/backend/BackendEntity.py
|
||||
|
|
3
gnuviechadmin.egg-info/entry_points.txt
Normal file
3
gnuviechadmin.egg-info/entry_points.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
[paste.app_factory]
|
||||
cli = gnuviechadmin.cli.client
|
|
@ -1,3 +1,5 @@
|
|||
SQLAlchemy>=0.5
|
||||
sqlalchemy-migrate>=0.5
|
||||
AuthKit>=0.4
|
||||
AuthKit>=0.4
|
||||
PasteDeploy>=1.3.3
|
||||
python-gnutls>=1.1
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2007, 2008 by Jan Dittberner.
|
||||
# Copyright (C) 2007, 2008, 2009 by Jan Dittberner.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,7 +25,6 @@ import logging
|
|||
import tempfile
|
||||
|
||||
from gnuviechadmin.exceptions import MissingFieldsError
|
||||
from gnuviechadmin.backend.settings import config
|
||||
from gnuviechadmin.util import gpgmail
|
||||
from subprocess import Popen, PIPE
|
||||
from sqlalchemy.orm import object_mapper
|
||||
|
@ -34,9 +33,10 @@ from sqlalchemy.orm import object_mapper
|
|||
class BackendEntity(object):
|
||||
"""This is the abstract base class for all backend entity classes."""
|
||||
|
||||
def __init__(self, delegateto, verbose = False):
|
||||
def __init__(self, config, delegateto, verbose = False):
|
||||
self.logger = logging.getLogger("%s.%s" % (
|
||||
self.__class__.__module__, self.__class__.__name__))
|
||||
self.config = config
|
||||
self.delegateto = delegateto
|
||||
self.verbose = verbose
|
||||
|
||||
|
@ -49,7 +49,7 @@ class BackendEntity(object):
|
|||
subprocess."""
|
||||
self.logger.debug("sucommand called: %s (pipedata=%s)", cmdline,
|
||||
str(pipedata))
|
||||
suwrapper = config.get('common', 'suwrapper')
|
||||
suwrapper = self.config['suwrapper']
|
||||
toexec = "%s %s" % (suwrapper, cmdline)
|
||||
if pipedata:
|
||||
pipeproc = Popen(toexec, shell = True, stdin=PIPE)
|
||||
|
@ -72,7 +72,7 @@ class BackendEntity(object):
|
|||
"""Executes multiple commands as root and pipes the output of
|
||||
the commands to the input of the next commands."""
|
||||
self.logger.debug("supipe called: %s", " | ".join(cmdlines))
|
||||
suwrapper = config.get('common', 'suwrapper')
|
||||
suwrapper = self.config['suwrapper']
|
||||
predecessor = None
|
||||
for cmdline in cmdlines:
|
||||
toexec = "%s %s" % (suwrapper, cmdline)
|
||||
|
@ -89,7 +89,7 @@ class BackendEntity(object):
|
|||
"""This method sends a mail with the given text and subject
|
||||
and signs it usign GnuPG. If a public key of the recipient is
|
||||
available the mail is encrypted."""
|
||||
gpgmail.send_mail(subject, text)
|
||||
gpgmail.send_mail(self.config, subject, text)
|
||||
|
||||
def validate(self):
|
||||
"""Validates whether all mandatory fields of the entity have
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2007, 2008 by Jan Dittberner.
|
||||
# Copyright (C) 2007, 2008, 2009 by Jan Dittberner.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -21,38 +21,41 @@
|
|||
"""This module defines the BackendEntityHandler class."""
|
||||
|
||||
import logging
|
||||
from sqlalchemy.orm import create_session
|
||||
from sqlalchemy.orm import create_session, mapper, relation
|
||||
from gnuviechadmin.backend.tables import dbsetup
|
||||
|
||||
|
||||
class BackendEntityHandler(object):
|
||||
"""This class is a handler for BackendEntity instances."""
|
||||
|
||||
def __init__(self, entityclass, toclass, verbose = False):
|
||||
def __init__(self, entityclass, toclass, config, verbose = False):
|
||||
"""Initialize the handler with a specific entity class,
|
||||
transfer object class and verbosity flag."""
|
||||
self.logger = logging.getLogger("%s.%s" % (
|
||||
self.__class__.__module__, self.__class__.__name__))
|
||||
dbsetup(config)
|
||||
|
||||
self.entityclass = entityclass
|
||||
self.toclass = toclass
|
||||
self.config = config
|
||||
self.verbose = verbose
|
||||
|
||||
def create(self, **kwargs):
|
||||
"""Create a new entity of the managed type with the fields set
|
||||
to the values in kwargs."""
|
||||
self.logger.debug("create with params %s", str(kwargs))
|
||||
delegate = self.toclass(self.config, **kwargs)
|
||||
entity = self.entityclass(self.config, delegate, self.verbose)
|
||||
sess = create_session()
|
||||
transaction = sess.create_transaction()
|
||||
delegate = self.toclass(**kwargs)
|
||||
entity = self.entityclass(delegate, self.verbose)
|
||||
try:
|
||||
sess.save(delegate)
|
||||
sess.begin()
|
||||
sess.add(delegate)
|
||||
sess.flush()
|
||||
sess.refresh(delegate)
|
||||
entity.create_hook(sess)
|
||||
sess.flush()
|
||||
transaction.commit()
|
||||
sess.commit()
|
||||
except:
|
||||
transaction.rollback()
|
||||
sess.rollback()
|
||||
self.logger.exception("Exception in create.")
|
||||
raise
|
||||
|
||||
|
@ -65,7 +68,7 @@ class BackendEntityHandler(object):
|
|||
allentities = query.filter_by(**kwargs).all()
|
||||
else:
|
||||
allentities = query.all()
|
||||
return [self.entityclass(entity, self.verbose) \
|
||||
return [self.entityclass(self.config, entity, self.verbose) \
|
||||
for entity in allentities]
|
||||
|
||||
def delete(self, pkvalue):
|
||||
|
@ -73,19 +76,18 @@ class BackendEntityHandler(object):
|
|||
specified primary key value."""
|
||||
self.logger.debug("delete with primary key %s", str(pkvalue))
|
||||
sess = create_session()
|
||||
transaction = sess.create_transaction()
|
||||
try:
|
||||
sess.begin()
|
||||
tobj = sess.query(self.toclass).get(pkvalue)
|
||||
if tobj:
|
||||
entity = self.entityclass(tobj, self.verbose)
|
||||
entity = self.entityclass(self.config, tobj, self.verbose)
|
||||
self.logger.info("delete %s", str(entity))
|
||||
if self.verbose:
|
||||
print "delete %s" % (str(entity))
|
||||
entity.delete_hook(sess)
|
||||
sess.delete(tobj)
|
||||
sess.flush()
|
||||
transaction.commit()
|
||||
sess.commit()
|
||||
except Exception:
|
||||
transaction.rollback()
|
||||
sess.rollback()
|
||||
self.logger.exception("Exception in delete.")
|
||||
raise
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2007, 2008 by Jan Dittberner.
|
||||
# Copyright (C) 2007, 2008, 2009 by Jan Dittberner.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,16 +19,15 @@
|
|||
#
|
||||
# Version: $Id$
|
||||
|
||||
from sqlalchemy.orm import object_mapper, mapper, relation
|
||||
from tables import *
|
||||
from sqlalchemy.orm import object_mapper
|
||||
|
||||
|
||||
class BackendTo(object):
|
||||
"""Backend transfer object class."""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
def __init__(self, config, **kwargs):
|
||||
for (key, value) in kwargs.items():
|
||||
self.__setattr__(key, value)
|
||||
self.__setattr__(key, unicode(value, 'utf8'))
|
||||
|
||||
def __repr__(self, **kwargs):
|
||||
if 'verbose' in kwargs and kwargs['verbose']:
|
||||
|
@ -64,12 +63,3 @@ class Domain(BackendTo):
|
|||
class Record(BackendTo):
|
||||
"""Transfer object class for DNS domain records."""
|
||||
_shortkeys = ("recordid", "domainid", "name", "type", "content")
|
||||
|
||||
|
||||
client_mapper = mapper(Client, client_table, {
|
||||
'sysusers': relation(Sysuser, backref = 'client')})
|
||||
sysuser_mapper = mapper(Sysuser, sysuser_table, {
|
||||
'domains': relation(Domain, backref = 'sysuser')})
|
||||
domain_mapper = mapper(Domain, domain_table, {
|
||||
'records': relation(Record, cascade = 'all', backref = 'domain')})
|
||||
record_mapper = mapper(Record, record_table)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2007, 2008 by Jan Dittberner.
|
||||
# Copyright (C) 2007, 2008, 2009 by Jan Dittberner.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,8 +20,7 @@
|
|||
# Version: $Id$
|
||||
"""This module defines the ClientEntity class."""
|
||||
|
||||
from gnuviechadmin.backend.settings import config, get_template, \
|
||||
get_template_string
|
||||
from gnuviechadmin.backend.settings import get_template, get_template_string
|
||||
from gnuviechadmin.exceptions import CannotDeleteError
|
||||
from gnuviechadmin.backend.BackendTo import Client
|
||||
from gnuviechadmin.backend.BackendEntity import BackendEntity
|
||||
|
@ -31,9 +30,9 @@ from gnuviechadmin.backend.BackendEntityHandler import BackendEntityHandler
|
|||
class ClientEntity(BackendEntity):
|
||||
"""Entity class for clients."""
|
||||
|
||||
def __init__(self, delegate, verbose = False, **kwargs):
|
||||
def __init__(self, config, delegate, verbose = False, **kwargs):
|
||||
"""Initializes the client entity instance."""
|
||||
BackendEntity.__init__(self, delegate, verbose)
|
||||
BackendEntity.__init__(self, config, delegate, verbose)
|
||||
for (key, value) in kwargs.items():
|
||||
self.__setattr__(key, value)
|
||||
if not self.delegateto.country:
|
||||
|
@ -42,8 +41,8 @@ class ClientEntity(BackendEntity):
|
|||
|
||||
def _client_mail(self):
|
||||
"""Mails a summary about the creation of the client."""
|
||||
text = get_template(config.get('common', 'mailtemplates'),
|
||||
config.get('client', 'create.mail')).substitute({
|
||||
text = get_template(self.config['mailtemplates'],
|
||||
self.config['client.create.mail']).substitute({
|
||||
'firstname': self.delegateto.firstname,
|
||||
'lastname': self.delegateto.lastname,
|
||||
'email': self.delegateto.email,
|
||||
|
@ -52,11 +51,11 @@ class ClientEntity(BackendEntity):
|
|||
'city': self.delegateto.city,
|
||||
'phone': self.delegateto.phone})
|
||||
subject = get_template_string(
|
||||
config.get('client', 'create_subject')).substitute({
|
||||
self.config['client.create_subject']).substitute({
|
||||
'firstname': self.delegateto.firstname,
|
||||
'lastname': self.delegateto.lastname})
|
||||
self.send_mail(subject, text)
|
||||
|
||||
|
||||
def create_hook(self, session):
|
||||
"""Actions to perform when a client is created."""
|
||||
self._client_mail()
|
||||
|
@ -72,11 +71,12 @@ class ClientEntity(BackendEntity):
|
|||
|
||||
def _get_default_country(self):
|
||||
"""Gets the default country."""
|
||||
return config.get('common', 'defaultcountry')
|
||||
return self.config['client.defaultcountry']
|
||||
|
||||
|
||||
class ClientHandler(BackendEntityHandler):
|
||||
"""BackendEntityHandler for Client entities."""
|
||||
|
||||
def __init__(self, verbose = False):
|
||||
BackendEntityHandler.__init__(self, ClientEntity, Client, verbose)
|
||||
def __init__(self, config, verbose = False):
|
||||
BackendEntityHandler.__init__(self, ClientEntity, Client, config,
|
||||
verbose)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2007, 2008 by Jan Dittberner.
|
||||
# Copyright (C) 2007, 2008, 2009 by Jan Dittberner.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,32 +25,13 @@ This module handles all central configuration of Gnuviech Admin. It
|
|||
parses configuration files and provides functions for reading
|
||||
templates."""
|
||||
|
||||
import ConfigParser
|
||||
import os
|
||||
from string import Template
|
||||
|
||||
# global settings which must not be user configurable
|
||||
required_version = 3
|
||||
|
||||
# load user configuration
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.readfp(open('gnuviechadmin/defaults.cfg'))
|
||||
config.read(['gnuviechadmin/gva.cfg', os.path.expanduser('~/.gva.cfg')])
|
||||
|
||||
dbschema = None
|
||||
if config.get('database', 'uri').startswith('postgres://'):
|
||||
dbschema = 'gva'
|
||||
|
||||
|
||||
def get_template_dir(dirname):
|
||||
"""Returns the template directory for the given directory."""
|
||||
templatepath = config.get('common', 'templatedir')
|
||||
return os.path.join(templatepath, dirname)
|
||||
|
||||
|
||||
def get_template(dirname, filename):
|
||||
def get_template(templatedir, filename):
|
||||
"""Returns the template data from the given template file."""
|
||||
templatefile = file(os.path.join(get_template_dir(dirname),
|
||||
templatefile = file(os.path.join(templatedir,
|
||||
filename))
|
||||
templatedata = templatefile.read()
|
||||
return Template(templatedata.decode('utf_8'))
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2007, 2008 by Jan Dittberner.
|
||||
# Copyright (C) 2007, 2008, 2009 by Jan Dittberner.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -19,57 +19,69 @@
|
|||
#
|
||||
# Version: $Id$
|
||||
|
||||
from sqlalchemy import *
|
||||
from sqlalchemy import MetaData, Table
|
||||
from sqlalchemy.orm import mapper, relation
|
||||
from sqlalchemy.exceptions import NoSuchTableError
|
||||
import sys
|
||||
import migrate.versioning.api
|
||||
from settings import *
|
||||
import logging
|
||||
from gnuviechadmin.backend.BackendTo import Client, Sysuser, Domain, Record
|
||||
|
||||
try:
|
||||
dbversion = migrate.versioning.api.db_version(
|
||||
config.get('database', 'uri'),
|
||||
config.get('database', 'repository'))
|
||||
if dbversion < required_version:
|
||||
print("""Database version is %d but required version is %d. Trying
|
||||
automatic upgrade.""" %
|
||||
(dbversion, required_version))
|
||||
|
||||
def dbsetup(config):
|
||||
logger = logging.getLogger(__name__)
|
||||
required_version = int(config['migrate.required_version'])
|
||||
try:
|
||||
dbversion = migrate.versioning.api.db_version(
|
||||
config['sqlalchemy.uri'], config['database.repository'])
|
||||
if dbversion < required_version:
|
||||
logger.info("""Database version is %d but required version \
|
||||
is %d. Trying automatic upgrade.""" % (dbversion, required_version))
|
||||
try:
|
||||
migrate.versioning.api.upgrade(
|
||||
config['sqlalchemy.uri'], config['database.repository'],
|
||||
required_version)
|
||||
except e:
|
||||
logger.error("Automatic upgrade failed.", e)
|
||||
raise
|
||||
elif dbversion > required_version:
|
||||
logger.error("""Database version is %d which is higher than \
|
||||
the required version %d. I cannot handle this situation without possible \
|
||||
data loss.""" % (dbversion, required_version))
|
||||
sys.exit(1)
|
||||
except NoSuchTableError, nste:
|
||||
logger.info("""The database is not versioned. \
|
||||
Trying automatic versioning.""")
|
||||
try:
|
||||
migrate.versioning.api.version_control(
|
||||
config['sqlalchemy.uri'], config['database.repository'])
|
||||
migrate.versioning.api.upgrade(
|
||||
config.get('database', 'uri'),
|
||||
config.get('database', 'repository'),
|
||||
config['sqlalchemy.uri'], config['database.repository'],
|
||||
required_version)
|
||||
except:
|
||||
print "Automatic upgrade failed."
|
||||
logger.error("Automatic setup failed.")
|
||||
raise
|
||||
elif dbversion > required_version:
|
||||
print("""Database version is %d which is higher than the required
|
||||
version %d. I cannot handle this situation without possible data loss.""" %
|
||||
(dbversion, required_version))
|
||||
sys.exit(1)
|
||||
except NoSuchTableError, nste:
|
||||
print """The database is not versioned. Trying automatic versioning."""
|
||||
try:
|
||||
migrate.versioning.api.version_control(
|
||||
config.get('database', 'uri'),
|
||||
config.get('database', 'repository'))
|
||||
migrate.versioning.api.upgrade(
|
||||
config.get('database', 'uri'),
|
||||
config.get('database', 'repository', required_version))
|
||||
except:
|
||||
print "Automatic setup failed."
|
||||
raise
|
||||
|
||||
meta = MetaData(config.get('database', 'uri'))
|
||||
#meta.engine.echo = True
|
||||
client_table = Table('client', meta, schema = dbschema, autoload = True)
|
||||
sysuser_table = Table('sysuser', meta, schema = dbschema, autoload = True)
|
||||
domain_table = Table('domain', meta, schema = dbschema, autoload = True)
|
||||
record_table = Table('record', meta, schema = dbschema, autoload = True)
|
||||
supermaster_table = Table('supermaster', meta, schema = dbschema,
|
||||
autoload = True)
|
||||
mailaccount_table = Table('mailaccount', meta, schema = dbschema,
|
||||
autoload = True)
|
||||
mailaddress_table = Table('mailaddress', meta, schema = dbschema,
|
||||
autoload = True)
|
||||
mailtarget_table = Table('mailtarget', meta, schema = dbschema,
|
||||
autoload = True)
|
||||
meta = MetaData(config['sqlalchemy.uri'])
|
||||
meta.bind.engine.echo = config['sqlalchemy.echo']
|
||||
|
||||
dbschema = None
|
||||
if 'database.schema' in config:
|
||||
dbschema = config['database.schema']
|
||||
|
||||
(client_table, sysuser_table, domain_table, \
|
||||
record_table, supermaster_table, mailaccount_table, \
|
||||
mailaddress_table, mailtarget_table) = \
|
||||
[Table(tabname, meta, schema = dbschema,
|
||||
autoload = True) for tabname in \
|
||||
('client', 'sysuser', 'domain', 'record',
|
||||
'supermaster', 'mailaccount', 'mailaddress', 'mailtarget')]
|
||||
|
||||
client_mapper = mapper(Client, client_table, {
|
||||
'sysusers': relation(Sysuser, backref = 'client')})
|
||||
sysuser_mapper = mapper(Sysuser, sysuser_table, {
|
||||
'domains': relation(Domain, backref = 'sysuser')})
|
||||
domain_mapper = mapper(Domain, domain_table, {
|
||||
'records': relation(Record, cascade = 'all',
|
||||
backref = 'domain')})
|
||||
record_mapper = mapper(Record, record_table)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2007, 2008 by Jan Dittberner.
|
||||
# Copyright (C) 2007, 2008, 2009 by Jan Dittberner.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -197,9 +197,10 @@ Common options:
|
|||
sys.exit()
|
||||
self._handleoption(subcommand, o, a)
|
||||
|
||||
def __init__(self, args):
|
||||
def __init__(self, args, config):
|
||||
"""This initializes the command with the given command line
|
||||
arguments and executes it."""
|
||||
self.config = config
|
||||
self.logger = logging.getLogger("%s.%s" % (
|
||||
self.__class__.__module__, self.__class__.__name__))
|
||||
self._data = {}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2007, 2008 by Jan Dittberner.
|
||||
# Copyright (C) 2007, 2008, 2009 by Jan Dittberner.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -24,3 +24,39 @@ This package provides modules for the command line interface of the
|
|||
gnuviechadmin server administration suite."""
|
||||
|
||||
__all__ = ["client", "sysuser", "domain", "record"]
|
||||
|
||||
from logging import getLogger
|
||||
from sys import exit
|
||||
|
||||
|
||||
class CommandLineInterface(object):
|
||||
|
||||
def __init__(self, config, args):
|
||||
self.log = getLogger(__name__)
|
||||
self.config = config
|
||||
if len(args) < 2:
|
||||
self._usage(args[0])
|
||||
exit(1)
|
||||
self.commands = [command for command in self._get_commands() \
|
||||
if command.name == args[1]]
|
||||
self.cmdargs = args[2:]
|
||||
|
||||
|
||||
def _usage(self, callee):
|
||||
print """%s <command> [commandargs]
|
||||
|
||||
where command is one of
|
||||
""" % callee
|
||||
for command in self._get_commands():
|
||||
print "%10s - %s" % (command.name, command.description)
|
||||
|
||||
def run(self):
|
||||
for cmd in self.commands:
|
||||
cmd(self.cmdargs, self.config)
|
||||
|
||||
def _get_commands(self):
|
||||
from gnuviechadmin.cli.client import ClientCli
|
||||
from gnuviechadmin.cli.sysuser import SysuserCli
|
||||
from gnuviechadmin.cli.domain import DomainCli
|
||||
from gnuviechadmin.cli.record import RecordCli
|
||||
return [ClientCli, SysuserCli, DomainCli, RecordCli]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2007, 2008 by Jan Dittberner.
|
||||
# Copyright (C) 2007, 2008, 2009 by Jan Dittberner.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -61,24 +61,25 @@ class ClientCli(CliCommand.CliCommand):
|
|||
def _execute(self, subcommand):
|
||||
self.logger.debug("execute %s with data %s", subcommand,
|
||||
str(self._data))
|
||||
from gnuviechadmin.backend import client
|
||||
from gnuviechadmin import exceptions
|
||||
from gnuviechadmin.backend.client import ClientHandler
|
||||
from gnuviechadmin.exceptions import CreationFailedError
|
||||
if subcommand == "create":
|
||||
try:
|
||||
myclient = client.ClientHandler(self._verbose).create(
|
||||
**self._data)
|
||||
myclient = ClientHandler(self.config,
|
||||
self._verbose).create(**self._data)
|
||||
if self._verbose:
|
||||
print myclient
|
||||
except exceptions.CreationFailedError, cfe:
|
||||
except CreationFailedError, cfe:
|
||||
self._usage()
|
||||
print cfe
|
||||
sys.exit(2)
|
||||
elif subcommand == "list":
|
||||
clients = client.ClientHandler(self._verbose).fetchall()
|
||||
clients = ClientHandler(self.config, self._verbose).fetchall()
|
||||
for client in clients:
|
||||
print client
|
||||
elif subcommand == "delete":
|
||||
client.ClientHandler(self._verbose).delete(self._data["clientid"])
|
||||
ClientHandler(self.config,
|
||||
self._verbose).delete(self._data["clientid"])
|
||||
|
||||
def __init__(self, argv):
|
||||
CliCommand.CliCommand.__init__(self, argv)
|
||||
def __init__(self, argv, config):
|
||||
CliCommand.CliCommand.__init__(self, argv, config)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2007, 2008 by Jan Dittberner.
|
||||
# Copyright (C) 2007, 2008, 2009 by Jan Dittberner.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@ -30,10 +30,8 @@ from email.MIMEText import MIMEText
|
|||
from pyme import core
|
||||
from pyme.constants.sig import mode
|
||||
|
||||
from gnuviechadmin.backend.settings import config
|
||||
|
||||
|
||||
def send_mail(subject, text):
|
||||
def send_mail(config, subject, text):
|
||||
"""Send a signed and possibly encrypted mail.
|
||||
|
||||
This method sends a mail with the given text and subject and signs
|
||||
|
@ -52,8 +50,8 @@ def send_mail(subject, text):
|
|||
cipher = core.Data()
|
||||
c = core.Context()
|
||||
c.set_armor(1)
|
||||
signer = config.get('common', 'mailfrom')
|
||||
rcpt = config.get('common', 'mailto')
|
||||
signer = config['mailfrom']
|
||||
rcpt = config['mailto']
|
||||
c.signers_clear()
|
||||
for sigkey in [x for x in c.op_keylist_all(signer, 1)]:
|
||||
if sigkey.can_sign:
|
||||
|
@ -64,14 +62,12 @@ def send_mail(subject, text):
|
|||
keylist = []
|
||||
for key in c.op_keylist_all(rcpt, 0):
|
||||
valid = 0
|
||||
subkey = key.subkeys
|
||||
while subkey:
|
||||
for subkey in key.subkeys:
|
||||
keyid = subkey.keyid
|
||||
if keyid == None:
|
||||
break
|
||||
can_encrypt = subkey.can_encrypt
|
||||
valid += can_encrypt
|
||||
subkey = subkey.next
|
||||
if valid:
|
||||
keylist.append(key)
|
||||
if keylist:
|
||||
|
|
8
setup.py
8
setup.py
|
@ -22,7 +22,6 @@
|
|||
from setuptools import setup, find_packages
|
||||
|
||||
try:
|
||||
import pudge
|
||||
import buildutils
|
||||
except ImportError:
|
||||
pass
|
||||
|
@ -35,7 +34,8 @@ setup(
|
|||
author_email = 'jan@dittberner.info',
|
||||
url = 'http://www.gnuviech-server.de/projects/gnuviechadmin',
|
||||
install_requires = ['SQLAlchemy>=0.5', 'sqlalchemy-migrate>=0.5',
|
||||
'AuthKit>=0.4'],
|
||||
'AuthKit>=0.4', 'PasteDeploy>=1.3.3',
|
||||
'python-gnutls>=1.1'],
|
||||
packages = find_packages(),
|
||||
include_package_data = True,
|
||||
exclude_package_data = {'': ['gva.cfg']},
|
||||
|
@ -46,4 +46,8 @@ it contains tools for maintaining e.g. clients, domains, users, mail
|
|||
accounts""",
|
||||
license = 'GPL',
|
||||
keywords = 'administration backend frontend',
|
||||
entry_points = """
|
||||
[paste.app_factory]
|
||||
cli = gnuviechadmin.cli.client
|
||||
""",
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue