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…
	
	Add table
		Add a link
		
	
		Reference in a new issue