- database versioning with migrate
- backend for domains - settings for immutable things and config encapsulation git-svn-id: file:///home/www/usr01/svn/gnuviechadmin/gnuviech.info/gnuviechadmin/trunk@229 a67ec6bc-e5d5-0310-a910-815c51eb3124
This commit is contained in:
parent
0d12afc71e
commit
3f4457bdca
22 changed files with 432 additions and 50 deletions
|
@ -29,19 +29,19 @@ class BackendEntityHandler(object):
|
|||
self.verbose = verbose
|
||||
|
||||
def create(self, **kwargs):
|
||||
try:
|
||||
entity = self.entityclass(self.verbose, **kwargs)
|
||||
# try:
|
||||
sess = create_session()
|
||||
sess.save(entity)
|
||||
sess.flush()
|
||||
entity = self.entityclass(self.verbose, **kwargs)
|
||||
try:
|
||||
entity.create_hook()
|
||||
sess.save(entity)
|
||||
sess.flush()
|
||||
except:
|
||||
sess.delete(entity)
|
||||
sess.flush()
|
||||
raise
|
||||
except Exception, e:
|
||||
raise CreationFailedError(self.entityclass.__name__, e)
|
||||
# except Exception, e:
|
||||
# raise CreationFailedError(self.entityclass.__name__, e)
|
||||
|
||||
def fetchall(self):
|
||||
"""Fetches all entities of the managed entity type."""
|
||||
|
|
|
@ -40,8 +40,8 @@ class Client(BackendEntity):
|
|||
self.address2 = None
|
||||
self.mobile = None
|
||||
self.fax = None
|
||||
for item in kwargs.items():
|
||||
self.__setattr__(item)
|
||||
for (key, value) in kwargs.items():
|
||||
self.__setattr__(key, value)
|
||||
self.validate()
|
||||
|
||||
def create_hook(self):
|
||||
|
|
|
@ -23,14 +23,17 @@ from sqlalchemy import *
|
|||
from tables import domain_table
|
||||
from gnuviechadmin.exceptions import *
|
||||
|
||||
import record
|
||||
from record import Record
|
||||
import datetime
|
||||
from BackendEntity import *
|
||||
from BackendEntityHandler import *
|
||||
from settings import config
|
||||
|
||||
class Domain(BackendEntity):
|
||||
"""Entity class for DNS domains."""
|
||||
|
||||
_shortkeys = ("domainid", "sysuserid", "name", "type")
|
||||
_valid_domain_types = ("MASTER", "SLAVE")
|
||||
|
||||
def __init__(self, verbose = False, **kwargs):
|
||||
BackendEntity.__init__(self, verbose)
|
||||
|
@ -38,10 +41,87 @@ class Domain(BackendEntity):
|
|||
self.sysuserid = None
|
||||
self.name = None
|
||||
self.type = None
|
||||
self.master = None
|
||||
self.ns1 = None
|
||||
self.ns2 = None
|
||||
self.mx = None
|
||||
self.ipaddr = None
|
||||
for (key, value) in kwargs.items():
|
||||
self.__setattr__(key, value)
|
||||
if not self.type:
|
||||
self.type = self.getdefaultdomaintype()
|
||||
if not self.ns1:
|
||||
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.ipaddr:
|
||||
self.ipaddr = config.get('domain', 'defaultip')
|
||||
self.type = self.type.upper()
|
||||
self.validate()
|
||||
|
||||
def getdefaultdomaintype(self):
|
||||
return self._valid_domain_types[0]
|
||||
|
||||
def validate(self):
|
||||
BackendEntity.validate(self)
|
||||
if not self.type in self._valid_domain_types:
|
||||
raise ValidationFailedError(
|
||||
self, "invalid domain type %s" % (self.type))
|
||||
if self.type == 'SLAVE' and not self.master:
|
||||
raise ValidationFailedError(
|
||||
self, "you have to specify a master for slave domains.")
|
||||
if self.type == 'MASTER':
|
||||
if not self.ns1 or not self.ns2:
|
||||
raise ValidationFailedError(
|
||||
self, "two nameservers must be specified.")
|
||||
if not self.mx:
|
||||
raise ValidationFailedError(
|
||||
self, "a primary mx host must be specified.")
|
||||
|
||||
def _getnewserial(self):
|
||||
current = datetime.datetime.now()
|
||||
return int("%04d%02d%02d01" % \
|
||||
(current.year, current.month, current.day))
|
||||
|
||||
def _getnewsoa(self):
|
||||
return '%s %s %d %d %d %d %d' % \
|
||||
(self.ns1,
|
||||
config.get('domain', 'defaulthostmaster'),
|
||||
self._getnewserial(),
|
||||
config.getint('domain', 'defaultrefresh'),
|
||||
config.getint('domain', 'defaultretry'),
|
||||
config.getint('domain', 'defaultexpire'),
|
||||
config.getint('domain', 'defaultminimumttl'))
|
||||
|
||||
def create_hook(self):
|
||||
self.records.append(Record(
|
||||
name = self.name, type = 'SOA',
|
||||
content = self._getnewsoa(),
|
||||
ttl = config.getint('domain', 'defaultttl')))
|
||||
self.records.append(Record(
|
||||
name = self.name, type = 'NS', content = self.ns1,
|
||||
ttl = config.getint('domain', 'defaultttl')))
|
||||
self.records.append(Record(
|
||||
name = self.name, type = 'NS', content = self.ns2,
|
||||
ttl = config.getint('domain', 'defaultttl')))
|
||||
self.records.append(Record(
|
||||
name = self.name, type = 'MX', content = self.mx,
|
||||
ttl = config.getint('domain', 'defaultttl'),
|
||||
prio = config.getint('domain', 'defaultmxprio')))
|
||||
self.records.append(Record(
|
||||
name = self.name, type = 'A', content = self.ipaddr,
|
||||
ttl = config.getint('domain', 'defaultttl')))
|
||||
self.records.append(Record(
|
||||
name = "www.%s" % (self.name), type = 'A', content = self.ipaddr,
|
||||
ttl = config.getint('domain', 'defaultttl')))
|
||||
|
||||
def delete_hook(self):
|
||||
pass
|
||||
|
||||
domain_mapper = mapper(Domain, domain_table)
|
||||
domain_mapper.add_property("records", relation(record.Record))
|
||||
domain_mapper.add_property("records", relation(Record))
|
||||
|
||||
class DomainHandler(BackendEntityHandler):
|
||||
"""BackendEntityHandler for Domain entities."""
|
||||
|
|
|
@ -26,22 +26,25 @@ from gnuviechadmin.exceptions import *
|
|||
from BackendEntity import *
|
||||
from BackendEntityHandler import *
|
||||
|
||||
class Record(BackendEntity):
|
||||
class Record(object):
|
||||
"""Entity class for DNS domain records."""
|
||||
def __init__(self, **kwargs):
|
||||
for (key, value) in kwargs.items():
|
||||
self.__setattr__(key, value)
|
||||
|
||||
_shortkeys = ("recordid", "domainid", "name", "type", "content")
|
||||
#_shortkeys = ("recordid", "domainid", "name", "type", "content")
|
||||
|
||||
def __init__(self, verbose = False, **kwargs):
|
||||
BackendEntity.__init__(self, verbose)
|
||||
self.recordid = None
|
||||
self.domainid = None
|
||||
self.name = None
|
||||
self.type = None
|
||||
self.content = None
|
||||
self.ttl = None
|
||||
self.prio = None
|
||||
self.change_date = None
|
||||
self.validate()
|
||||
#def __init__(self, verbose = False, **kwargs):
|
||||
# BackendEntity.__init__(self, verbose)
|
||||
# self.recordid = None
|
||||
# self.domainid = None
|
||||
# self.name = None
|
||||
# self.type = None
|
||||
# self.content = None
|
||||
# self.ttl = None
|
||||
# self.prio = None
|
||||
# self.change_date = None
|
||||
# self.validate()
|
||||
|
||||
record_mapper = mapper(Record, record_table)
|
||||
|
||||
|
|
31
gnuviechadmin/backend/settings.py
Normal file
31
gnuviechadmin/backend/settings.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
# -*- coding: UTF-8 -*-
|
||||
#
|
||||
# Copyright (C) 2007 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
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
# USA.
|
||||
#
|
||||
# Version: $Id$
|
||||
|
||||
import ConfigParser, os
|
||||
|
||||
# global settings which must not be user configurable
|
||||
required_version = 2
|
||||
dbschema = 'gva'
|
||||
|
||||
# load user configuration
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.readfp(open('gnuviechadmin/defaults.cfg'))
|
||||
config.read(['gnuviechadmin/gva.cfg', os.path.expanduser('~/.gva.cfg')])
|
|
@ -43,8 +43,8 @@ class Sysuser(BackendEntity):
|
|||
self.md5pass = None
|
||||
self.clientid = None
|
||||
self.sysuid = None
|
||||
for key in kwargs.keys():
|
||||
self.__setattr__(key, kwargs[key])
|
||||
for (key, value) in kwargs.items():
|
||||
self.__setattr__(key, value)
|
||||
if not self.username:
|
||||
self.username = self.getnextsysusername()
|
||||
if not self.usertype:
|
||||
|
|
|
@ -20,11 +20,22 @@
|
|||
# Version: $Id$
|
||||
|
||||
from sqlalchemy import *
|
||||
import ConfigParser, os
|
||||
import sys
|
||||
import migrate.versioning.api
|
||||
from settings import *
|
||||
|
||||
config = ConfigParser.ConfigParser()
|
||||
config.readfp(open('gnuviechadmin/defaults.cfg'))
|
||||
config.read(['gnuviechadmin/gva.cfg', os.path.expanduser('~/.gva.cfg')])
|
||||
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, run
|
||||
|
||||
migrate upgrade %s %s
|
||||
|
||||
to fix this.""" %
|
||||
(dbversion, required_version, config.get('database', 'uri'),
|
||||
config.get('database', 'repository')))
|
||||
sys.exit(1)
|
||||
|
||||
meta = BoundMetaData(config.get('database', 'uri'))
|
||||
client_table = Table(
|
||||
|
@ -42,10 +53,8 @@ client_table = Table(
|
|||
Column('mobile', String(32)),
|
||||
Column('fax', String(32)),
|
||||
Column('email', String(64), unique=True, nullable=False),
|
||||
schema = config.get('database', 'schema')
|
||||
schema = dbschema
|
||||
)
|
||||
client_table.create(checkfirst=True)
|
||||
|
||||
sysuser_table = Table(
|
||||
'sysuser', meta,
|
||||
Column('sysuserid', Integer, primary_key=True),
|
||||
|
@ -55,13 +64,12 @@ sysuser_table = Table(
|
|||
Column('shell', Boolean, nullable=False, default=False),
|
||||
Column('clearpass', String(64)),
|
||||
Column('md5pass', String(34)),
|
||||
Column('clientid', Integer, ForeignKey("client.clientid"), nullable=False),
|
||||
Column('clientid', Integer, ForeignKey("client.clientid"),
|
||||
nullable=False),
|
||||
Column('sysuid', Integer, nullable=False, unique=True),
|
||||
Column('lastchange', DateTime, default=func.now()),
|
||||
schema = config.get('database', 'schema')
|
||||
schema = dbschema
|
||||
)
|
||||
sysuser_table.create(checkfirst=True)
|
||||
|
||||
domain_table = Table(
|
||||
'domain', meta,
|
||||
Column('domainid', Integer, primary_key=True),
|
||||
|
@ -72,10 +80,8 @@ domain_table = Table(
|
|||
Column('notified_serial', Integer),
|
||||
Column('sysuserid', Integer, ForeignKey("sysuser.sysuserid"),
|
||||
nullable=False),
|
||||
schema = config.get('database', 'schema')
|
||||
schema = dbschema
|
||||
)
|
||||
domain_table.create(checkfirst=True)
|
||||
|
||||
record_table = Table(
|
||||
'record', meta,
|
||||
Column('recordid', Integer, primary_key=True),
|
||||
|
@ -87,16 +93,13 @@ record_table = Table(
|
|||
Column('ttl', Integer),
|
||||
Column('prio', Integer),
|
||||
Column('change_date', Integer),
|
||||
schema = config.get('database', 'schema')
|
||||
schema = dbschema
|
||||
)
|
||||
record_table.create(checkfirst=True)
|
||||
|
||||
supermaster_table = Table(
|
||||
'supermaster', meta,
|
||||
Column('ip', String(25), nullable=False),
|
||||
Column('nameserver', String(255), nullable=False),
|
||||
Column('account', Integer, ForeignKey("sysuser.sysuserid"),
|
||||
nullable=False),
|
||||
schema = config.get('database', 'schema')
|
||||
schema = dbschema
|
||||
)
|
||||
supermaster_table.create(checkfirst=True)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue