From daf9517a83074edcab547af1d93214e82b6bbac0 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Sat, 7 Jun 2008 21:25:35 +0000 Subject: [PATCH] * some pylint fixes (addresses #24) * add pydoc in client and domain backend classes * add support for buildutils in setup.py git-svn-id: file:///home/www/usr01/svn/gnuviechadmin/trunk@262 a67ec6bc-e5d5-0310-a910-815c51eb3124 --- gnuviechadmin/backend/BackendEntity.py | 28 ++++----- gnuviechadmin/backend/BackendEntityHandler.py | 17 ++--- gnuviechadmin/backend/client.py | 14 +++-- gnuviechadmin/backend/domain.py | 62 ++++++++++++++++--- gnuviechadmin/backend/settings.py | 7 +-- gnuviechadmin/cli/sysuser.py | 16 ++++- gnuviechadmin/exceptions.py | 5 ++ gnuviechadmin/util/getenttools.py | 6 +- gnuviechadmin/util/passwordutils.py | 35 +++++------ gnuviechadmin/util/stmtcreator.py | 2 +- gnuviechadmin/xmlrpc/users.py | 6 +- setup.cfg | 12 ++++ setup.py | 6 ++ 13 files changed, 147 insertions(+), 69 deletions(-) diff --git a/gnuviechadmin/backend/BackendEntity.py b/gnuviechadmin/backend/BackendEntity.py index 659692a..d985d1c 100644 --- a/gnuviechadmin/backend/BackendEntity.py +++ b/gnuviechadmin/backend/BackendEntity.py @@ -18,16 +18,16 @@ # USA. # # Version: $Id$ +"""This module defines the BackendEntity base class.""" import os import logging import tempfile -from settings import config -from gnuviechadmin.exceptions import * +from gnuviechadmin.exceptions import MissingFieldsError +from gnuviechadmin.backend.settings import config from gnuviechadmin.util import gpgmail -from subprocess import * -import sqlalchemy +from subprocess import Popen, PIPE from sqlalchemy.orm import object_mapper @@ -52,17 +52,17 @@ class BackendEntity(object): suwrapper = config.get('common', 'suwrapper') toexec = "%s %s" % (suwrapper, cmdline) if pipedata: - p = Popen(toexec, shell = True, stdin=PIPE) - pipe = p.stdin - print >>pipe, pipedata + pipeproc = Popen(toexec, shell = True, stdin=PIPE) + pipe = pipeproc.stdin + print >> pipe, pipedata pipe.close() - sts = os.waitpid(p.pid, 0) + sts = os.waitpid(pipeproc.pid, 0) if self.verbose: print "%s|%s: %d" % (pipedata, toexec, sts[1]) self.logger.info("%s|%s: %d", pipedata, toexec, sts[1]) else: - p = Popen(toexec, shell = True) - sts = os.waitpid(p.pid, 0) + pipeproc = Popen(toexec, shell = True) + sts = os.waitpid(pipeproc.pid, 0) if self.verbose: print "%s: %s" % (toexec, sts[1]) self.logger.info("%s: %s", toexec, sts[1]) @@ -77,11 +77,11 @@ class BackendEntity(object): for cmdline in cmdlines: toexec = "%s %s" % (suwrapper, cmdline) if predecessor is None: - p = Popen(toexec, shell = True, stdout = PIPE) + pipeproc = Popen(toexec, shell = True, stdout = PIPE) else: - p = Popen(toexec, shell = True, stdin = predecessor.stdout, - stdout = PIPE) - predecessor = p + pipeproc = Popen(toexec, shell = True, + stdin = predecessor.stdout, stdout = PIPE) + predecessor = pipeproc output = predecessor.communicate()[0] return predecessor.wait() diff --git a/gnuviechadmin/backend/BackendEntityHandler.py b/gnuviechadmin/backend/BackendEntityHandler.py index 9d7ad8c..3fc00d1 100644 --- a/gnuviechadmin/backend/BackendEntityHandler.py +++ b/gnuviechadmin/backend/BackendEntityHandler.py @@ -18,17 +18,18 @@ # USA. # # Version: $Id$ +"""This module defines the BackendEntityHandler class.""" -import sqlalchemy import logging from sqlalchemy.orm import create_session -from gnuviechadmin.exceptions import * -from BackendEntity import * class BackendEntityHandler(object): + """This class is a handler for BackendEntity instances.""" def __init__(self, entityclass, toclass, 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__)) self.entityclass = entityclass @@ -74,17 +75,17 @@ class BackendEntityHandler(object): sess = create_session() transaction = sess.create_transaction() try: - to = sess.query(self.toclass).get(pkvalue) - if to: - entity = self.entityclass(to, self.verbose) + tobj = sess.query(self.toclass).get(pkvalue) + if tobj: + entity = self.entityclass(tobj, self.verbose) self.logger.info("delete %s", str(entity)) if self.verbose: print "delete %s" % (str(entity)) entity.delete_hook(sess) - sess.delete(to) + sess.delete(tobj) sess.flush() transaction.commit() - except Exception, e: + except Exception: transaction.rollback() self.logger.exception("Exception in delete.") raise diff --git a/gnuviechadmin/backend/client.py b/gnuviechadmin/backend/client.py index dffb7f4..98810d5 100644 --- a/gnuviechadmin/backend/client.py +++ b/gnuviechadmin/backend/client.py @@ -18,18 +18,21 @@ # USA. # # Version: $Id$ +"""This module defines the ClientEntity class.""" -from gnuviechadmin.exceptions import * -from settings import config -from BackendTo import * -from BackendEntity import * -from BackendEntityHandler import * +from gnuviechadmin.backend.settings import config, get_template, \ + get_template_string +from gnuviechadmin.exceptions import CannotDeleteError +from gnuviechadmin.backend.BackendTo import Client +from gnuviechadmin.backend.BackendEntity import BackendEntity +from gnuviechadmin.backend.BackendEntityHandler import BackendEntityHandler class ClientEntity(BackendEntity): """Entity class for clients.""" def __init__(self, delegate, verbose = False, **kwargs): + """Initializes the client entity instance.""" BackendEntity.__init__(self, delegate, verbose) for (key, value) in kwargs.items(): self.__setattr__(key, value) @@ -38,6 +41,7 @@ class ClientEntity(BackendEntity): self.validate() 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({ 'firstname': self.delegateto.firstname, diff --git a/gnuviechadmin/backend/domain.py b/gnuviechadmin/backend/domain.py index 5a27441..5aacfc6 100644 --- a/gnuviechadmin/backend/domain.py +++ b/gnuviechadmin/backend/domain.py @@ -18,27 +18,35 @@ # USA. # # Version: $Id$ +"""This module defines the code for handling domains.""" import datetime import os -from gnuviechadmin.exceptions import * -from settings import * -from BackendTo import Record, Domain -from BackendEntity import BackendEntity -from BackendEntityHandler import BackendEntityHandler +from gnuviechadmin.exceptions import ValidationFailedError +from gnuviechadmin.backend.settings import config, get_template, \ + get_template_dir, get_template_string +from gnuviechadmin.backend.BackendTo import Record, Domain +from gnuviechadmin.backend.BackendEntity import BackendEntity +from gnuviechadmin.backend.BackendEntityHandler import BackendEntityHandler class DomainEntity(BackendEntity): """Entity class for DNS domains.""" + # the valid domain types _valid_domain_types = ("MASTER", "SLAVE") def __init__(self, delegate, verbose = False, **kwargs): + """Initializes the DomainEntity instance. + + `delegate` is the corresponding database object. + If `verbose` is `True` verbose logging is turned on. + """ BackendEntity.__init__(self, delegate, verbose) self.ns1 = None self.ns2 = None - self.mx = None + self.mxrr = None self.ipaddr = None for (key, value) in kwargs.items(): self.__setattr__(key, value) @@ -48,17 +56,20 @@ class DomainEntity(BackendEntity): self.ns1 = config.get('domain', 'defaultns1') if not self.ns2: self.ns2 = config.get('domain', 'defaultns2') - if not self.mx: - self.mx = config.get('domain', 'defaultmx') + if not self.mxrr: + self.mxrr = config.get('domain', 'defaultmx') if not self.ipaddr: self.ipaddr = config.get('domain', 'defaultip') self.delegateto.type = self.delegateto.type.upper() self.validate() def getdefaultdomaintype(self): + """Returns the default domain type.""" return self._valid_domain_types[0] def validate(self): + """Validates the consistency if the entity instance and + dependent entities.""" BackendEntity.validate(self) if not self.delegateto.type in self._valid_domain_types: raise ValidationFailedError( @@ -70,11 +81,12 @@ class DomainEntity(BackendEntity): if not self.ns1 or not self.ns2: raise ValidationFailedError( self, "two nameservers must be specified.") - if not self.mx: + if not self.mxrr: raise ValidationFailedError( self, "a primary mx host must be specified.") def _getnewserial(self, oldserial = None): + """Gets a new zone serial number for the DNS domain entity.""" current = datetime.datetime.now() datepart = "%04d%02d%02d" % \ (current.year, current.month, current.day) @@ -87,6 +99,7 @@ class DomainEntity(BackendEntity): return retval def _getnewsoa(self): + """Gets a new SOA record for the DNS domain entity.""" return '%s %s %d %d %d %d %d' % \ (self.ns1, config.get('domain', 'defaulthostmaster'), @@ -97,6 +110,7 @@ class DomainEntity(BackendEntity): config.getint('domain', 'defaultminimumttl')) def update_serial(self, session): + """Updates the serial of the domain.""" query = session.query(Record) soarecord = query.get_by(Record.c.type == 'SOA', Record.c.domainid == self.delegateto.domainid) @@ -107,19 +121,24 @@ class DomainEntity(BackendEntity): session.flush() def _get_vhost_dir(self): + """Gets the directory name for the Apache VirtualHost of the + domain.""" return os.path.join(self.delegateto.sysuser.home, self.delegateto.name, config.get('domain', 'htdir')) def _get_log_dir(self): + """Gets the Apache log file directory for the domain.""" return os.path.join(config.get('domain', 'logpath'), self.delegateto.name) def _get_stats_dir(self): + """Gets the statistics dir for the domain.""" return os.path.join(config.get('domain', 'statspath'), self.delegateto.name) def _create_vhost_dir(self): + """Creates the Apache VirtualHost directory for the domain.""" vhostdir = self._get_vhost_dir() self.logger.debug("creating virtual host dir %s" % (vhostdir)) cmd = 'mkdir -p "%s"' % (vhostdir) @@ -140,10 +159,13 @@ class DomainEntity(BackendEntity): self.sucommand(cmd) def _create_log_dir(self): + """Creates the Apache log file directory for the domain.""" cmd = 'mkdir -p "%s"' % (self._get_log_dir()) self.sucommand(cmd) def _get_auth_userfile(self): + """Gets the file name of the password file for statistic + logins for the domain.""" authdir = config.get('domain', 'authdir') if not os.path.isdir(authdir): cmd = 'mkdir -p "%s"' % (authdir) @@ -171,6 +193,8 @@ class DomainEntity(BackendEntity): '.htaccess'), template) def _create_stats_conf(self): + """Creates the modlogan statistics configuration for the + domain.""" modlogandir = os.path.join(config.get('domain', 'modlogandir'), self.delegateto.sysuser.username) @@ -188,6 +212,7 @@ class DomainEntity(BackendEntity): template) def _create_apache_conf(self): + """Creates the Apache configuration file for the domain.""" template = get_template(config.get('domain', 'conftemplates'), config.get('domain', 'apachetemplate')) template = template.substitute({ @@ -200,6 +225,7 @@ class DomainEntity(BackendEntity): self.delegateto.name), template) def _mail_domain(self): + """Mail a summary of the domain data.""" template = get_template(config.get('common', 'mailtemplates'), config.get('domain', 'create.mail')) text = template.substitute({ @@ -213,6 +239,11 @@ class DomainEntity(BackendEntity): self.send_mail(subject, text) def create_hook(self, session): + """Hook for the creation of the domain. + + This method is called by + `gnuviechadmin.backend.BackendEntityHandler.create()`. + """ self.delegateto.records.append(Record( name = self.delegateto.name, type = 'SOA', content = self._getnewsoa(), @@ -224,7 +255,7 @@ class DomainEntity(BackendEntity): name = self.delegateto.name, type = 'NS', content = self.ns2, ttl = config.getint('domain', 'defaultttl'))) self.delegateto.records.append(Record( - name = self.delegateto.name, type = 'MX', content = self.mx, + name = self.delegateto.name, type = 'MX', content = self.mxrr, ttl = config.getint('domain', 'defaultttl'), prio = config.getint('domain', 'defaultmxprio'))) self.delegateto.records.append(Record( @@ -244,6 +275,7 @@ class DomainEntity(BackendEntity): self._mail_domain() def _delete_apache_conf(self): + """Deletes the Apache configuration file for the domain.""" cmd = 'a2dissite %s' % (self.delegateto.name) self.sucommand(cmd) cmd = 'rm "%s"' % (os.path.join(config.get('domain', 'sitesdir'), @@ -251,12 +283,15 @@ class DomainEntity(BackendEntity): self.sucommand(cmd) def _delete_stats_conf(self): + """Deletes the modlogan stastics configuration for the + domain.""" cmd = 'rm "%s"' % (os.path.join(config.get('domain', 'modlogandir'), self.delegateto.sysuser.username, self.delegateto.name + '.conf')) self.sucommand(cmd) def _archive_stats_dir(self): + """Archives the statistics directory for the domain.""" archive = os.path.join(self.delegateto.sysuser.home, '%(domain)s-stats.tar.gz' % { 'domain': self.delegateto.name}) @@ -276,6 +311,7 @@ class DomainEntity(BackendEntity): self.sucommand(cmd) def _archive_log_dir(self): + """Archives the Apache log file directory for the domain.""" archive = os.path.join(self.delegateto.sysuser.home, '%(domain)s-logs.tar.gz' % { 'domain': self.delegateto.name}) @@ -295,6 +331,7 @@ class DomainEntity(BackendEntity): self.sucommand(cmd) def _archive_vhost_dir(self): + """Archives the Apache VirtualHost directory for the domain.""" archive = os.path.join(self.delegateto.sysuser.home, '%(domain)s-vhost.tar.gz' % { 'domain': self.delegateto.name}) @@ -315,6 +352,10 @@ class DomainEntity(BackendEntity): self.sucommand(cmd) def delete_hook(self, session): + """Deletes domain related files and directories. + + This method is called by `BackendEntityHandler.delete()`. + """ self._delete_apache_conf() self._delete_stats_conf() self._archive_stats_dir() @@ -326,4 +367,5 @@ class DomainHandler(BackendEntityHandler): """BackendEntityHandler for Domain entities.""" def __init__(self, verbose = False): + """Initialize the DomainHandler.""" BackendEntityHandler.__init__(self, DomainEntity, Domain, verbose) diff --git a/gnuviechadmin/backend/settings.py b/gnuviechadmin/backend/settings.py index 2d089f1..623d0d5 100644 --- a/gnuviechadmin/backend/settings.py +++ b/gnuviechadmin/backend/settings.py @@ -27,8 +27,7 @@ templates.""" import ConfigParser import os -import string -import logging.config +from string import Template # global settings which must not be user configurable required_version = 3 @@ -54,9 +53,9 @@ def get_template(dirname, filename): templatefile = file(os.path.join(get_template_dir(dirname), filename)) templatedata = templatefile.read() - return string.Template(templatedata.decode('utf_8')) + return Template(templatedata.decode('utf_8')) def get_template_string(templatestring): """Returns a template object for the given template string.""" - return string.Template(templatestring) + return Template(templatestring) diff --git a/gnuviechadmin/cli/sysuser.py b/gnuviechadmin/cli/sysuser.py index d0ca130..55390e9 100644 --- a/gnuviechadmin/cli/sysuser.py +++ b/gnuviechadmin/cli/sysuser.py @@ -18,12 +18,17 @@ # USA. # # Version: $Id$ -import CliCommand +"""This module provides the command line interface code for system +user management.""" +from gnuviechadmin.cli.CliCommand import CliCommand import sys -class SysuserCli(CliCommand.CliCommand): - """Command line interface command for system user managament.""" +class SysuserCli(CliCommand): + """Command line interface command for system user management. + + This class implements `gnuviechadmin.cli.CliCommand.CliCommand`. + """ name = "sysuser" description = "manage system users" @@ -47,6 +52,10 @@ class SysuserCli(CliCommand.CliCommand): "the system user id", True)])} def _execute(self, subcommand): + """Executes `subcommand`. + + This method implements `CliCommand._execute()`. + """ self.logger.debug("execute %s with data %s", subcommand, str(self._data)) from gnuviechadmin.backend import sysuser @@ -70,4 +79,5 @@ class SysuserCli(CliCommand.CliCommand): self._data["sysuserid"]) def __init__(self, argv): + """Constructor for the sysuser command.""" CliCommand.CliCommand.__init__(self, argv) diff --git a/gnuviechadmin/exceptions.py b/gnuviechadmin/exceptions.py index f982c6c..c65d7fb 100644 --- a/gnuviechadmin/exceptions.py +++ b/gnuviechadmin/exceptions.py @@ -32,6 +32,7 @@ class MissingFieldsError(GnuviechadminError): class is missing.""" def __init__(self, missingfields): + GnuviechadminError.__init__(self) self.missing = missingfields def __str__(self): @@ -43,6 +44,7 @@ class CreationFailedError(GnuviechadminError): be created.""" def __init__(self, classname, cause = None): + GnuviechadminError.__init__(self) self.classname = classname self.cause = cause @@ -58,6 +60,7 @@ class DeleteFailedError(GnuviechadminError): be deleted.""" def __init__(self, classname, cause = None): + GnuviechadminError.__init__(self) self.classname = classname self.cause = cause @@ -73,6 +76,7 @@ class ValidationFailedError(GnuviechadminError): object failed.""" def __init__(self, instance, cause = None): + GnuviechadminError.__init__(self) self.instance = instance self.cause = cause @@ -88,6 +92,7 @@ class CannotDeleteError(GnuviechadminError): because of some unmatched precondition.""" def __init__(self, instance, cause = None): + GnuviechadminError.__init__(self) self.instance = instance self.cause = cause diff --git a/gnuviechadmin/util/getenttools.py b/gnuviechadmin/util/getenttools.py index af20fcf..faaf468 100644 --- a/gnuviechadmin/util/getenttools.py +++ b/gnuviechadmin/util/getenttools.py @@ -28,7 +28,7 @@ import grp class PasswdUser(object): """This class represents users in the user database.""" - def __init__(self, username, pw, uid, gid, gecos, home, shell): + def __init__(self, username, passw, uid, gid, gecos, home, shell): """Create a new PasswdUser.""" self.username = username self.uid = int(uid) @@ -51,7 +51,7 @@ class PasswdUser(object): class PasswdGroup(object): """This class represents lines in the groups database.""" - def __init__(self, groupname, pw, gid, members): + def __init__(self, groupname, passwd, gid, members): """Create a new PasswdGroup.""" self.groupname = groupname self.gid = int(gid) @@ -109,7 +109,7 @@ def get_next_uid(lowerboundary = 10000, upperboundary = 65536): """ for uid in range(lowerboundary, upperboundary): try: - user = pwd.getpwuid(uid) + pwd.getpwuid(uid) except KeyError: return uid raise Exception("no free uid found in range %d to %d", diff --git a/gnuviechadmin/util/passwordutils.py b/gnuviechadmin/util/passwordutils.py index a952de4..f279680 100644 --- a/gnuviechadmin/util/passwordutils.py +++ b/gnuviechadmin/util/passwordutils.py @@ -25,14 +25,14 @@ import crack import random import logging -log = logging.getLogger(__name__) +LOG = logging.getLogger(__name__) -_pwchars = [] +_PWCHARS = [] for _pair in (('0', '9'), ('A', 'Z'), ('a', 'z')): - _pwchars.extend(range(ord(_pair[0]), ord(_pair[1]))) -_saltchars = [_char for _char in _pwchars] + _PWCHARS.extend(range(ord(_pair[0]), ord(_pair[1]))) +_SALTCHARS = [_char for _char in _PWCHARS] for _char in "-+/*_@": - _pwchars.append(ord(_char)) + _PWCHARS.append(ord(_char)) def generatepassword(minlength = 8, maxlength = 12): @@ -41,12 +41,11 @@ def generatepassword(minlength = 8, maxlength = 12): The generated password has a length between minlength and maxlength. Keyword arguments: - minlength -- minimum length of the generated password - maxlength -- the maximum length of the generated password - + `minlength` -- minimum length of the generated password + `maxlength` -- the maximum length of the generated password """ return "".join([chr(letter) for letter in \ - random.sample(_pwchars, + random.sample(_PWCHARS, random.randint(minlength, maxlength))]) @@ -57,12 +56,12 @@ def checkpassword(password): returned. Arguments: - password -- the password to check + `password` -- the password to check """ try: return crack.VeryFascistCheck(password) except ValueError, ve: - log.info("Weak password: %s", ve) + LOG.info("Weak password: %s", ve) return None @@ -72,10 +71,10 @@ def md5_crypt_password(password): A password hashed with MD5 and a random salt value is returned. Arguments: - password -- the password to hash + `password` -- the password to hash """ salt = "".join([chr(letter) for letter in \ - random.sample(_saltchars, 8)]) + random.sample(_SALTCHARS, 8)]) return crypt.crypt(password, '$1$' + salt) @@ -83,7 +82,7 @@ def get_pw_tuple(password = None): """Gets a valid (password, hashvalue) tuple. The tuple consists of a password and a md5 hash of the same - password. If a password is given it is checked and if it is too + password. If a `password` is given it is checked and if it is too weak replaced by a generated one. """ @@ -92,8 +91,8 @@ def get_pw_tuple(password = None): return (password, md5_crypt_password(password)) -def validate_password(hash, password): - """Validates whether the given clear text password matches the - given hash value. +def validate_password(hashvalue, password): + """Validates whether the given clear text `password` matches the + given `hashvalue`. """ - return hash == crypt.crypt(password, hash) + return hashvalue == crypt.crypt(password, hashvalue) diff --git a/gnuviechadmin/util/stmtcreator.py b/gnuviechadmin/util/stmtcreator.py index 345ba18..9f6b05e 100755 --- a/gnuviechadmin/util/stmtcreator.py +++ b/gnuviechadmin/util/stmtcreator.py @@ -24,7 +24,7 @@ creation.""" if __name__ == '__main__': - from passwordutils import get_pw_tuple + from gnuviechadmin.util.passwordutils import get_pw_tuple import sys for line in sys.stdin.readlines(): diff --git a/gnuviechadmin/xmlrpc/users.py b/gnuviechadmin/xmlrpc/users.py index fa53b0f..27cb116 100644 --- a/gnuviechadmin/xmlrpc/users.py +++ b/gnuviechadmin/xmlrpc/users.py @@ -31,11 +31,11 @@ log = logging.getLogger(__name__) class UserProvider(Users): """A base class for user providers.""" - def _get_user(self, username, password, role): + def _get_user(self, username, role): return { 'username': username, 'group': None, - 'password': password, + 'password': None, 'roles': [role]} @@ -45,7 +45,7 @@ class ClientUserProvider(UserProvider): def user(self, username): print 'checking %s' % username if username == 'dummy': - return self._get_user(username, username, 'client') + return self._get_user(username, 'client') return AuthKitNoSuchUserError() def list_roles(self): diff --git a/setup.cfg b/setup.cfg index 5ae9a1d..6859be0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,3 +13,15 @@ cover-package=gnuviechadmin pdb=1 pdb-failures=1 verbosity=3 + +[checksum] +per-file=1 +md5=1 +sha=1 +sign=1 + +[pudge] +dest=apidoc +license=gnu +modules=gnuviechadmin +title=GNUViechAdmin diff --git a/setup.py b/setup.py index 1c2a3b9..8a725ed 100644 --- a/setup.py +++ b/setup.py @@ -21,6 +21,12 @@ from setuptools import setup, find_packages +try: + import pudge + import buildutils +except ImportError: + pass + setup( name = 'gnuviechadmin', version = '0.1',