Add initial PowerDNS migration repo

Change-Id: I24823d391cb642ebc5c47a1e4de1602a6d088879
This commit is contained in:
Kiall Mac Innes 2013-02-11 11:47:33 +00:00
parent f1fd51eb90
commit 0edf9a5de4
9 changed files with 221 additions and 2 deletions

View File

@ -0,0 +1,4 @@
This is a database migration repository for the project Moniker.
More information at
http://code.google.com/p/sqlalchemy-migrate/

View File

@ -0,0 +1,24 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 Hewlett-Packard Development Company, L.P.
# All Rights Reserved.
#
# Author: Patrick Galbraith <patg@hp.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from migrate.versioning.shell import main
if __name__ == '__main__':
main(debug='False')

View File

@ -0,0 +1,25 @@
[db_settings]
# Used to identify which repository this database is versioned under.
# You can use the name of your project.
repository_id=MonikerPowerDNS
# The name of the database table used to track the schema version.
# This name shouldn't already be used by your project.
# If this is changed once a database is under version control, you'll need to
# change the table name in each database too.
version_table=migrate_version
# When committing a change script, Migrate will attempt to generate the
# sql for all supported databases; normally, if one of them fails - probably
# because you don't have that database installed - it is ignored and the
# commit continues, perhaps ending successfully.
# Databases in this list MUST compile successfully during a commit, or the
# entire commit will fail. List the databases your application will actually
# be using to ensure your updates to that database work properly.
# This must be a list; example: ['postgres','sqlite']
required_dbs=[]
# When creating new change scripts, Migrate will stamp the new script with
# a version number. By default this is latest_version + 1. You can set this
# to 'true' to tell Migrate to use the UTC timestamp instead.
use_timestamp_numbering=False

View File

@ -0,0 +1,105 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2012 Hewlett-Packard Development Company, L.P.
# All Rights Reserved.
#
# Author: Patrick Galbraith <patg@hp.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from sqlalchemy import Integer, String, Text, Boolean
from sqlalchemy.schema import Table, Column, MetaData, Index
meta = MetaData()
domains = Table('domains', meta,
Column('id', Integer(), autoincrement=True,
primary_key=True, nullable=False),
Column('name', String(255), nullable=False, unique=True),
Column('master', String(20), default=None, nullable=True),
Column('last_check', Integer(), default=None,
nullable=True),
Column('type', String(6), nullable=False),
Column('notified_serial', Integer(), default=None,
nullable=True),
Column('account', String(40), default=None, nullable=True))
records = Table('records', meta,
Column('id', Integer(), autoincrement=True,
primary_key=True, nullable=False),
Column('domain_id', Integer(), default=None, nullable=True),
Column('name', String(255), default=None, nullable=True),
Column('type', String(10), default=None, nullable=True),
Column('content', String(255), default=None, nullable=True),
Column('ttl', Integer(), default=None, nullable=True),
Column('prio', Integer(), default=None, nullable=True),
Column('change_data', Integer(), default=None,
nullable=True),
Column('ordername', String(255), default=None, nullable=True),
Column('auth', Boolean(), default=None, nullable=True))
Index('rec_name_index', records.c.name)
Index('nametype_index', records.c.name, records.c.type)
Index('domain_id', records.c.domain_id)
Index('orderindex', records.c.ordername)
cryptokeys = Table('cryptokeys', meta,
Column('id', Integer(), autoincrement=True,
primary_key=True, nullable=False),
Column('domain_id', Integer(), nullable=False),
Column('flags', Integer(), nullable=False),
Column('active', Boolean(), default=None, nullable=True),
Column('content', Text()))
domainmetadata = Table('domainmetadata', meta,
Column('id', Integer(), autoincrement=True,
primary_key=True, nullable=False),
Column('domain_id', Integer(), nullable=False),
Column('kind', String(16), default=None, nullable=True),
Column('content', Text()))
supermasters = Table('supermasters', meta,
Column('ip', String(25), nullable=False),
Column('nameserver', String(255), nullable=False),
Column('account', String(40), default=None,
nullable=True))
tsigkeys = Table('tsigkeys', meta,
Column('id', Integer(), autoincrement=True,
primary_key=True, nullable=False),
Column('name', String(255), default=None, nullable=True),
Column('algorithm', String(255), default=None, nullable=True),
Column('secret', String(255), default=None, nullable=True))
Index('namealgoindex', tsigkeys.c.name, tsigkeys.c.algorithm, unique=True)
def upgrade(migrate_engine):
meta.bind = migrate_engine
domains.create()
records.create()
cryptokeys.create()
domainmetadata.create()
supermasters.create()
tsigkeys.create()
def downgrade(migrate_engine):
meta.bind = migrate_engine
tsigkeys.drop()
supermasters.drop()
domainmetadata.drop()
cryptokeys.drop()
records.drop()
domains.drop()

View File

@ -0,0 +1,61 @@
# Copyright 2012 Managed I.T.
#
# Author: Kiall Mac Innes <kiall@managedit.ie>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
from migrate.exceptions import DatabaseAlreadyControlledError
from migrate.versioning import api as versioning_api
from cliff.command import Command
from moniker.openstack.common import log as logging
from moniker.openstack.common import cfg
LOG = logging.getLogger(__name__)
REPOSITORY = os.path.abspath(os.path.join(os.path.dirname(__file__), '..',
'backend', 'impl_powerdns',
'migrate_repo'))
cfg.CONF.import_opt('database_connection', 'moniker.backend.impl_powerdns',
group='backend:powerdns')
class DatabaseInitCommand(Command):
""" Init PowerDNS database """
def take_action(self, parsed_args):
url = cfg.CONF['backend:powerdns'].database_connection
if not os.path.exists(REPOSITORY):
raise Exception('Migration Respository Not Found')
try:
LOG.info('Attempting to initialize database')
versioning_api.version_control(url=url, repository=REPOSITORY)
LOG.info('Database initialized sucessfully')
except DatabaseAlreadyControlledError:
raise Exception('Database already initialized')
class DatabaseSyncCommand(Command):
""" Sync PowerDNS database """
def take_action(self, parsed_args):
# TODO: Support specifying version
url = cfg.CONF['backend:powerdns'].database_connection
if not os.path.exists(REPOSITORY):
raise Exception('Migration Respository Not Found')
LOG.info('Attempting to synchronize database')
versioning_api.upgrade(url=url, repository=REPOSITORY,
version=None)
LOG.info('Database synchronized sucessfully')

View File

@ -16,8 +16,6 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# should this be in schema.py?
from sqlalchemy import ForeignKey, Enum, Integer, String, DateTime, Text from sqlalchemy import ForeignKey, Enum, Integer, String, DateTime, Text
from sqlalchemy.schema import Column, MetaData from sqlalchemy.schema import Column, MetaData
from moniker.openstack.common import timeutils from moniker.openstack.common import timeutils

View File

@ -74,6 +74,8 @@ setup(
[moniker.manage] [moniker.manage]
database init = moniker.manage.database:InitCommand database init = moniker.manage.database:InitCommand
database sync = moniker.manage.database:SyncCommand database sync = moniker.manage.database:SyncCommand
powerdns database init = moniker.manage.powerdns:DatabaseInitCommand
powerdns database sync = moniker.manage.powerdns:DatabaseSyncCommand
"""), """),
classifiers=[ classifiers=[
'Development Status :: 3 - Alpha', 'Development Status :: 3 - Alpha',