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