Removed deprecated powerdns 3 driver

This driver was replaced by the pdns 4 driver
many cycles ago and is being permanently removed.

Change-Id: Ic34cee5fde21f838b6dd6b54fcdd767ec8b0bc18
This commit is contained in:
Erik Olof Gunnar Andersson 2019-05-05 13:31:51 -07:00
parent 52ad1c4c13
commit 660eacbce4
41 changed files with 50 additions and 1579 deletions

View File

@ -1,160 +0,0 @@
# Copyright 2014 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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.
import threading
import six
from oslo_config import cfg
from oslo_db.exception import DBDuplicateEntry
from oslo_log import log as logging
from oslo_utils import excutils
from sqlalchemy.sql import select
from designate import exceptions
from designate.backend import base
from designate.backend.impl_powerdns import tables
from designate.sqlalchemy import session
CFG_GROUP_NAME = 'backend:powerdns'
LOG = logging.getLogger(__name__)
def _map_col(keys, col):
return dict([(keys[i], col[i]) for i in range(len(keys))])
class PowerDNSBackend(base.Backend):
__plugin_name__ = 'powerdns'
__backend_status__ = 'deprecated'
def __init__(self, target):
super(PowerDNSBackend, self).__init__(target)
self.host = self.options.get('host', '127.0.0.1')
self.port = int(self.options.get('port', 53))
self.local_store = threading.local()
default_connection = 'sqlite:///%(state_path)s/powerdns.sqlite' % {
'state_path': cfg.CONF.state_path
}
self.connection = self.options.get('connection', default_connection)
def get_session(self):
return session.get_session(self.name, self.connection, self.target.id)
def _create(self, sess, table, values):
query = table.insert()
resultproxy = sess.execute(query, values)
# Refetch the row, for generated columns etc
query = select([table])\
.where(table.c.id == resultproxy.inserted_primary_key[0])
resultproxy = sess.execute(query)
return _map_col(query.columns.keys(), resultproxy.fetchone())
def _get(self, sess, table, id_, exc_notfound, id_col=None):
if id_col is None:
id_col = table.c.id
query = select([table])\
.where(id_col == id_)
resultproxy = sess.execute(query)
results = resultproxy.fetchall()
if len(results) != 1:
raise exc_notfound()
# Map col keys to values in result
return _map_col(query.columns.keys(), results[0])
def _delete(self, sess, table, id_, exc_notfound, id_col=None):
if id_col is None:
id_col = table.c.id
query = table.delete()\
.where(id_col == id_)
resultproxy = sess.execute(query)
if resultproxy.rowcount != 1:
raise exc_notfound()
# Zone Methods
def create_zone(self, context, zone):
# Get a new session
sess = self.get_session()
try:
sess.begin()
def _parse_master(master):
return '%s:%d' % (master.host, master.port)
masters = six.moves.map(_parse_master, self.masters)
domain_values = {
'designate_id': zone['id'],
'name': zone['name'].rstrip('.'),
'master': ','.join(masters),
'type': 'SLAVE',
'account': context.project_id or zone.tenant_id
}
self._create(sess, tables.domains, domain_values)
except DBDuplicateEntry:
LOG.debug('Successful create of %s in pdns, zone already exists'
% zone['name'])
# If create fails because the zone exists, don't reraise
pass
except Exception:
with excutils.save_and_reraise_exception():
sess.rollback()
else:
sess.commit()
self.mdns_api.notify_zone_changed(
context, zone, self.host, self.port, self.timeout,
self.retry_interval, self.max_retries, self.delay)
def delete_zone(self, context, zone):
# Get a new session
sess = self.get_session()
try:
sess.begin()
self._get(sess, tables.domains, zone['id'],
exceptions.ZoneNotFound,
id_col=tables.domains.c.designate_id)
self._delete(sess, tables.domains, zone['id'],
exceptions.ZoneNotFound,
id_col=tables.domains.c.designate_id)
except exceptions.ZoneNotFound:
# If the Zone is already gone, that's ok. We're deleting it
# anyway, so just log and continue.
LOG.critical('Attempted to delete a zone which is not present '
'in the backend. ID: %s', zone['id'])
return
except Exception:
with excutils.save_and_reraise_exception():
sess.rollback()
else:
sess.commit()

View File

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

View File

@ -1,23 +0,0 @@
#!/usr/bin/env python
# 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

@ -1,25 +0,0 @@
[db_settings]
# Used to identify which repository this database is versioned under.
# You can use the name of your project.
repository_id=DesignatePowerDNS
# 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

@ -1,103 +0,0 @@
# 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_date', 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

@ -1,55 +0,0 @@
# 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.
from sqlalchemy import MetaData, Table, Column
from designate.sqlalchemy.types import UUID
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
tsigkeys_table = Table('tsigkeys', meta, autoload=True)
domains_table = Table('domains', meta, autoload=True)
records_table = Table('records', meta, autoload=True)
tsigkeys_moniker_id = Column('moniker_id', UUID())
tsigkeys_moniker_id.create(tsigkeys_table)
domains_moniker_id = Column('moniker_id', UUID())
domains_moniker_id.create(domains_table)
records_moniker_id = Column('moniker_id', UUID())
records_moniker_id.create(records_table)
def downgrade(migrate_engine):
meta.bind = migrate_engine
tsigkeys_table = Table('tsigkeys', meta, autoload=True)
domains_table = Table('domains', meta, autoload=True)
records_table = Table('records', meta, autoload=True)
tsigkeys_moniker_id = Column('moniker_id', UUID())
tsigkeys_moniker_id.drop(tsigkeys_table)
domains_moniker_id = Column('moniker_id', UUID())
domains_moniker_id.drop(domains_table)
records_moniker_id = Column('moniker_id', UUID())
records_moniker_id.drop(records_table)

View File

@ -1,32 +0,0 @@
# Copyright 2013 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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 MetaData, Table, String
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
domains_table = Table('domains', meta, autoload=True)
domains_table.c.master.alter(type=String(255))
def downgrade(migrate_engine):
meta.bind = migrate_engine
domains_table = Table('domains', meta, autoload=True)
domains_table.c.master.alter(type=String(20))

View File

@ -1,32 +0,0 @@
# Copyright 2013 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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 MetaData, Table, String, Text
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
records_table = Table('records', meta, autoload=True)
records_table.c.content.alter(type=Text)
def downgrade(migrate_engine):
meta.bind = migrate_engine
records_table = Table('records', meta, autoload=True)
records_table.c.content.alter(type=String(255))

View File

@ -1,42 +0,0 @@
# Copyright 2013 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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 MetaData, Table
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
tsigkeys_table = Table('tsigkeys', meta, autoload=True)
domains_table = Table('domains', meta, autoload=True)
records_table = Table('records', meta, autoload=True)
tsigkeys_table.c.moniker_id.alter(name='designate_id')
domains_table.c.moniker_id.alter(name='designate_id')
records_table.c.moniker_id.alter(name='designate_id')
def downgrade(migrate_engine):
meta.bind = migrate_engine
tsigkeys_table = Table('tsigkeys', meta, autoload=True)
domains_table = Table('domains', meta, autoload=True)
records_table = Table('records', meta, autoload=True)
tsigkeys_table.c.designate_id.alter(name='moniker_id')
domains_table.c.designate_id.alter(name='moniker_id')
records_table.c.designate_id.alter(name='moniker_id')

View File

@ -1,61 +0,0 @@
# 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.
from oslo_log import log as logging
from sqlalchemy import MetaData, Table, Column, Boolean
LOG = logging.getLogger(__name__)
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
records_table = Table('records', meta, autoload=True)
# Create the new inherit_ttl column
inherit_ttl = Column('inherit_ttl', Boolean(), default=True)
inherit_ttl.create(records_table)
# Semi-Populate the new inherit_ttl column. We'll need to do a cross-db
# join from powerdns.records -> powerdns.domains -> designate.domains, so
# we can't perform the second half here.
query = records_table.update().values(inherit_ttl=False)
query = query.where(records_table.c.ttl is not None)
query.execute()
# If there are records without an explicity configured TTL, we'll need
# a manual post-migration step.
query = records_table.select()
query = query.where(records_table.c.ttl is None)
c = query.count()
if c > 0:
pmq = ('UPDATE powerdns.records JOIN powerdns.domains ON powerdns.reco'
'rds.domain_id = powerdns.domains.id JOIN designate.domains ON '
'powerdns.domains.designate_id = designate.domains.id SET power'
'dns.records.ttl = designate.domains.ttl WHERE powerdns.records'
'.inherit_ttl = 1;')
LOG.warning('**** A manual post-migration step is required ****')
LOG.warning('Please issue this query: %s', pmq)
def downgrade(migrate_engine):
meta.bind = migrate_engine
records_table = Table('records', meta, autoload=True)
records_table.c.inherit_ttl.drop()

View File

@ -1,38 +0,0 @@
# 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.
from sqlalchemy import MetaData, Table, Column
from designate.sqlalchemy.types import UUID
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
records_table = Table('records', meta, autoload=True)
recordset_id = Column('designate_recordset_id', UUID())
recordset_id.create(records_table)
def downgrade(migrate_engine):
meta.bind = migrate_engine
records_table = Table('records', meta, autoload=True)
records_table.c.designate_recordset_id.drop()

View File

@ -1,37 +0,0 @@
# Copyright 2013 Hewlett-Packard Development Company, L.P.
#
# Author: Endre Karlson <endre.karlson@hpe.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 MetaData, Index, Table
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
records_table = Table('records', meta, autoload=True)
index = Index('designate_recordset_id',
records_table.c.designate_recordset_id)
index.create()
def downgrade(migrate_engine):
meta.bind = migrate_engine
records_table = Table('records', meta, autoload=True)
index = Index('designate_recordset_id',
records_table.c.designate_recordset_id)
index.drop()

View File

@ -1,63 +0,0 @@
# Copyright 2014 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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 MetaData, Table
from migrate.changeset.constraint import ForeignKeyConstraint
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
domains_table = Table('domains', meta, autoload=True)
domainmetadata_table = Table('domainmetadata', meta, autoload=True)
records_table = Table('records', meta, autoload=True)
records_fk = ForeignKeyConstraint(
[records_table.c.domain_id],
[domains_table.c.id],
ondelete="CASCADE")
records_fk.create()
domainmetadata_fk = ForeignKeyConstraint(
[domainmetadata_table.c.domain_id],
[domains_table.c.id],
ondelete="CASCADE")
domainmetadata_fk.create()
def downgrade(migrate_engine):
meta.bind = migrate_engine
domains_table = Table('domains', meta, autoload=True)
domainmetadata_table = Table('domainmetadata', meta, autoload=True)
records_table = Table('records', meta, autoload=True)
records_fk = ForeignKeyConstraint(
[records_table.c.domain_id],
[domains_table.c.id],
ondelete="CASCADE")
records_fk.drop()
domainmetadata_fk = ForeignKeyConstraint(
[domainmetadata_table.c.domain_id],
[domains_table.c.id],
ondelete="CASCADE")
domainmetadata_fk.drop()

View File

@ -1,36 +0,0 @@
# Copyright 2015 NetEase, Inc.
#
# Author: Zhang Gengyuan <stanzgy@gmail.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 MetaData, Table, Column, Boolean
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
records_table = Table('records', meta, autoload=True)
disabled = Column('disabled', Boolean(), server_default='0')
disabled.create(records_table)
def downgrade(migrate_engine):
meta.bind = migrate_engine
records_table = Table('records', meta, autoload=True)
records_table.c.disabled.drop()

View File

@ -1,38 +0,0 @@
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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.
import sys
from oslo_log import log as logging
from sqlalchemy import MetaData, Table
LOG = logging.getLogger(__name__)
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
LOG.warning('It will not be possible to downgrade from schema #11')
records_table = Table('records', meta, autoload=True)
records_table.c.designate_id.drop()
records_table.c.designate_recordset_id.drop()
def downgrade(migrate_engine):
LOG.error('It is not possible to downgrade from schema #11')
sys.exit(1)

View File

@ -1,30 +0,0 @@
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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.
#
# This is a placeholder for Kilo backports.
# Do not use this number for new Liberty work. New Liberty work starts after
# all the placeholders.
#
# See https://blueprints.launchpad.net/nova/+spec/backportable-db-migrations
# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
def upgrade(migrate_engine):
pass
def downgrade(migration_engine):
pass

View File

@ -1,30 +0,0 @@
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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.
#
# This is a placeholder for Kilo backports.
# Do not use this number for new Liberty work. New Liberty work starts after
# all the placeholders.
#
# See https://blueprints.launchpad.net/nova/+spec/backportable-db-migrations
# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
def upgrade(migrate_engine):
pass
def downgrade(migration_engine):
pass

View File

@ -1,30 +0,0 @@
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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.
#
# This is a placeholder for Kilo backports.
# Do not use this number for new Liberty work. New Liberty work starts after
# all the placeholders.
#
# See https://blueprints.launchpad.net/nova/+spec/backportable-db-migrations
# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
def upgrade(migrate_engine):
pass
def downgrade(migration_engine):
pass

View File

@ -1,30 +0,0 @@
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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.
#
# This is a placeholder for Kilo backports.
# Do not use this number for new Liberty work. New Liberty work starts after
# all the placeholders.
#
# See https://blueprints.launchpad.net/nova/+spec/backportable-db-migrations
# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
def upgrade(migrate_engine):
pass
def downgrade(migration_engine):
pass

View File

@ -1,30 +0,0 @@
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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.
#
# This is a placeholder for Kilo backports.
# Do not use this number for new Liberty work. New Liberty work starts after
# all the placeholders.
#
# See https://blueprints.launchpad.net/nova/+spec/backportable-db-migrations
# http://lists.openstack.org/pipermail/openstack-dev/2013-March/006827.html
def upgrade(migrate_engine):
pass
def downgrade(migration_engine):
pass

View File

@ -1,38 +0,0 @@
# Copyright 2015 NetEase, Inc.
#
# Author: Zhang Gengyuan <stanzgy@gmail.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 MetaData, Index, Table
meta = MetaData()
def upgrade(migrate_engine):
meta.bind = migrate_engine
records_table = Table('records', meta, autoload=True)
name_idx = Index('rec_name_index',
records_table.c.name)
name_idx.drop()
def downgrade(migrate_engine):
meta.bind = migrate_engine
records_table = Table('records', meta, autoload=True)
name_idx = Index('rec_name_index',
records_table.c.name)
name_idx.create()

View File

@ -1,39 +0,0 @@
# Copyright 2012-2014 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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 MetaData, Table, Column, String, Integer
from oslo_config import cfg
from designate.sqlalchemy.types import UUID
CONF = cfg.CONF
metadata = MetaData()
domains = Table(
'domains', metadata,
Column('id', Integer, primary_key=True, autoincrement=True),
Column('designate_id', UUID, nullable=False),
Column('name', String(255), nullable=False, unique=True),
Column('master', String(255), 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),
mysql_engine='InnoDB',
mysql_charset='utf8')

View File

@ -1,71 +0,0 @@
# 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.versioning import api as versioning_api
from oslo_config import cfg
from oslo_db.sqlalchemy.migration_cli import manager as migration_manager
from designate.manage import base
from designate import rpc
from designate.central import rpcapi as central_rpcapi
REPOSITORY = os.path.abspath(os.path.join(os.path.dirname(__file__), '..',
'backend', 'impl_powerdns',
'migrate_repo'))
CONF = cfg.CONF
def get_manager(pool_target):
connection = pool_target.options.get('connection', None)
migration_config = {
'migration_repo_path': REPOSITORY,
'db_url': connection}
return migration_manager.MigrationManager(migration_config)
class DatabaseCommands(base.Commands):
def __init__(self):
super(DatabaseCommands, self).__init__()
rpc.init(cfg.CONF)
self.central_api = central_rpcapi.CentralAPI()
@base.args('pool-id', help="Pool to Migrate", type=str)
def version(self, pool_id):
pool = self.central_api.find_pool(self.context, {"id": pool_id})
for pool_target in pool.targets:
current = get_manager(pool_target).version()
latest = versioning_api.version(repository=REPOSITORY).value
print("Current: %s Latest: %s" % (current, latest))
@base.args('pool-id', help="Pool to Migrate", type=str)
def sync(self, pool_id):
pool = self.central_api.find_pool(self.context, {"id": pool_id})
for pool_target in pool.targets:
get_manager(pool_target).upgrade(None)
@base.args('pool-id', help="Pool to Migrate", type=str)
@base.args('revision', nargs='?')
def upgrade(self, pool_id, revision):
pool = self.central_api.find_pool(self.context, {"id": pool_id})
for pool_target in pool.targets:
get_manager(pool_target).upgrade(revision)

View File

@ -1,6 +1,6 @@
---
- name: pool-1
description: Default PowerDNS Pool
description: Default PowerDNS 4 Pool
attributes:
internal: true
ns_records:
@ -14,13 +14,14 @@
- host: 192.0.2.3
port: 53
targets:
- type: powerdns
description: PowerDNS Database Cluster
- type: pdns4
description: PowerDNS 4 Server
masters:
- host: 192.0.2.1
port: 5354
options:
connection: 'mysql+pymysql://designate:password@127.0.0.1/designate_pdns?charset=utf8'
api_endpoint: http://192.0.2.1:8081
api_token: api_key
also_notifies:
- host: 192.0.2.4
port: 53

View File

@ -1,7 +1,7 @@
---
- name: default
description: Default PowerDNS Pool
description: Default PowerDNS 4 Pool
attributes:
type: internal
@ -19,13 +19,14 @@
port: 53
targets:
- type: powerdns
description: PowerDNS Database Cluster
- type: pdns4
description: PowerDNS 4 Server
masters:
- host: 192.0.2.1
port: 5354
options:
connection: 'mysql+pymysql://designate:password@127.0.0.1/designate_pdns?charset=utf8'
api_endpoint: http://192.0.2.1:8081
api_token: api_key
also_notifies:
- host: 192.0.2.4
port: 53

View File

@ -2,7 +2,7 @@
- host: 192.0.2.4
port: 53
attributes: {}
description: Default PowerDNS Pool
description: Default PowerDNS 4 Pool
id: cf2e8eab-76cd-4162-bf76-8aeee3556de0
name: default
nameservers:
@ -16,10 +16,11 @@
- hostname: ns1-2.example.org.
priority: 2
targets:
- description: PowerDNS Database Cluster
- description: PowerDNS 4 Server
masters:
- host: 192.0.2.1
port: 5354
options:
connection: mysql+pymysql://designate:password@127.0.0.1/designate_pdns?charset=utf8
type: powerdns
api_endpoint: http://192.0.2.1:8081
api_token: api_key
type: pdns4

View File

@ -1,176 +0,0 @@
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# Author: Kiall Mac Innes <kiall@hpe.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.
import mock
import testtools
import sqlalchemy
from designate.tests.test_backend import BackendTestCase
from designate import objects
from designate import exceptions
from designate.backend import impl_powerdns
from designate.backend.impl_powerdns import tables
class PowerDNSBackendTestCase(BackendTestCase):
def setUp(self):
super(PowerDNSBackendTestCase, self).setUp()
self.zone = objects.Zone(id='e2bed4dc-9d01-11e4-89d3-123b93f75cba',
name='example.com.',
email='example@example.com')
self.target = objects.PoolTarget.from_dict({
'id': '4588652b-50e7-46b9-b688-a9bad40a873e',
'type': 'powerdns',
'masters': [
{'host': '192.0.2.1', 'port': 53},
{'host': '192.0.2.2', 'port': 35},
],
'options': [
{'key': 'connection', 'value': 'memory://'},
{'key': 'host', 'value': '192.0.2.3'},
{'key': 'port', 'value': '53'},
],
})
self.backend = impl_powerdns.PowerDNSBackend(self.target)
# Helper Methpds
def assertSessionTransactionCalls(self, session_mock, begin=0, commit=0,
rollback=0):
# Ensure the Sessions Transactions functions are called correctly
self.assertEqual(begin, session_mock.begin.call_count)
self.assertEqual(commit, session_mock.commit.call_count)
self.assertEqual(rollback, session_mock.rollback.call_count)
# Tests for Public Methods
@mock.patch.object(impl_powerdns.PowerDNSBackend, 'get_session')
def test_create_zone(self, get_session_mock):
session_mock = mock.MagicMock()
get_session_mock.return_value = session_mock
context = self.get_context()
self.backend.create_zone(context, self.zone)
self.assertSessionTransactionCalls(
session_mock, begin=1, commit=1, rollback=0)
# Ensure we have two queries, one INSERT, one SELECT
self.assertEqual(2, session_mock.execute.call_count)
self.assertIsInstance(
session_mock.execute.call_args_list[0][0][0],
sqlalchemy.sql.dml.Insert)
self.assertDictContainsSubset(
{'type': 'SLAVE',
'designate_id': self.zone.id,
'master': '192.0.2.1:53,192.0.2.2:35',
'name': self.zone.name.rstrip('.')},
session_mock.execute.call_args_list[0][0][1])
self.assertIsInstance(
session_mock.execute.call_args_list[1][0][0],
sqlalchemy.sql.selectable.Select)
@mock.patch.object(impl_powerdns.PowerDNSBackend, 'get_session')
@mock.patch.object(impl_powerdns.PowerDNSBackend, '_create',
side_effect=Exception)
def test_create_zone_failure_on_create(self, create_mock,
get_session_mock):
session_mock = mock.MagicMock()
get_session_mock.return_value = session_mock
with testtools.ExpectedException(Exception):
self.backend.create_zone(self.get_context(), self.zone)
self.assertSessionTransactionCalls(
session_mock, begin=1, commit=0, rollback=1)
# Ensure we called out into the _create method exactly once
self.assertEqual(1, create_mock.call_count)
@mock.patch.object(impl_powerdns.PowerDNSBackend, 'get_session')
@mock.patch.object(impl_powerdns.PowerDNSBackend, '_create',
return_value=None)
def test_create_zone_failure_on_commit(self, create_mock,
get_session_mock):
session_mock = mock.MagicMock()
get_session_mock.return_value = session_mock
# Configure the Session mocks's commit method to raise an exception
session_mock.commit.side_effect = Exception
with testtools.ExpectedException(Exception):
self.backend.create_zone(self.get_context(), self.zone)
self.assertSessionTransactionCalls(
session_mock, begin=1, commit=1, rollback=0)
# Ensure we called out into the _create method exactly once
self.assertEqual(1, create_mock.call_count)
@mock.patch.object(impl_powerdns.PowerDNSBackend, 'get_session')
@mock.patch.object(impl_powerdns.PowerDNSBackend, '_get',
return_value=None)
def test_delete_zone(self, get_mock, get_session_mock):
session_mock = mock.MagicMock()
get_session_mock.return_value = session_mock
# Configure the Session mocks's execute method to return a fudged
# resultproxy.
rp_mock = mock.Mock()
rp_mock.rowcount = 1
session_mock.execute.return_value = rp_mock
context = self.get_context()
self.backend.delete_zone(context, self.zone)
# Ensure the _get method was called with the correct arguments
get_mock.assert_called_once_with(
session_mock, tables.domains, self.zone.id,
exceptions.ZoneNotFound, id_col=tables.domains.c.designate_id)
# Ensure we have one query, a DELETE
self.assertEqual(1, session_mock.execute.call_count)
self.assertIsInstance(
session_mock.execute.call_args_list[0][0][0],
sqlalchemy.sql.dml.Delete)
# TODO(kiall): Validate the ID being deleted
@mock.patch.object(impl_powerdns.PowerDNSBackend, 'get_session')
@mock.patch.object(impl_powerdns.PowerDNSBackend, '_get',
side_effect=exceptions.ZoneNotFound)
@mock.patch.object(impl_powerdns.PowerDNSBackend, '_delete',
return_value=None)
def test_delete_zone_zone_not_found(self, delete_mock, get_mock,
get_session_mock):
session_mock = mock.MagicMock()
get_session_mock.return_value = session_mock
context = self.get_context()
self.backend.delete_zone(context, self.zone)
# Ensure the _get method was called with the correct arguments
get_mock.assert_called_once_with(
session_mock, tables.domains, self.zone.id,
exceptions.ZoneNotFound, id_col=tables.domains.c.designate_id)
# Ensure the _delete method was not called
self.assertFalse(delete_mock.called)

View File

@ -37,7 +37,7 @@ class DesignateYAMLAdapterTest(oslotest.base.BaseTestCase):
r_pool = adapters.DesignateAdapter.parse(
'YAML', xpool, objects.Pool())
self.assertEqual('default', r_pool.name)
self.assertEqual('Default PowerDNS Pool', r_pool.description)
self.assertEqual('Default PowerDNS 4 Pool', r_pool.description)
self.assertEqual(2, len(r_pool.ns_records))
self.assertEqual(1, r_pool.ns_records[0].priority)
self.assertEqual(2, r_pool.ns_records[1].priority)
@ -46,18 +46,22 @@ class DesignateYAMLAdapterTest(oslotest.base.BaseTestCase):
self.assertEqual(
'ns1-2.example.org.', r_pool.ns_records[1].hostname)
self.assertEqual(1, len(r_pool.targets))
self.assertEqual('powerdns', r_pool.targets[0].type)
self.assertEqual('pdns4', r_pool.targets[0].type)
self.assertEqual(
'PowerDNS Database Cluster', r_pool.targets[0].description)
'PowerDNS 4 Server', r_pool.targets[0].description)
self.assertEqual(1, len(r_pool.targets[0].masters))
self.assertEqual('192.0.2.1', r_pool.targets[0].masters[0].host)
self.assertEqual(DEFAULT_MDNS_PORT,
r_pool.targets[0].masters[0].port)
self.assertEqual(1, len(r_pool.targets[0].options))
self.assertEqual('connection', r_pool.targets[0].options[0].key)
self.assertEqual(
'mysql+pymysql://designate:password@127.0.0.1/designate_pdns?charset=utf8', # noqa
r_pool.targets[0].options[0].value)
self.assertEqual(2, len(r_pool.targets[0].options))
options = {}
for option in r_pool.targets[0].options:
options[option.key] = option.value
self.assertEqual(options['api_endpoint'], 'http://192.0.2.1:8081')
self.assertEqual(options['api_token'], 'api_key')
self.assertEqual(1, len(r_pool.also_notifies))
self.assertEqual('192.0.2.4', r_pool.also_notifies[0].host)
self.assertEqual(53, r_pool.also_notifies[0].port)
@ -75,7 +79,7 @@ class DesignateYAMLAdapterTest(oslotest.base.BaseTestCase):
}
],
'attributes': [],
'description': u'Default PowerDNS Pool',
'description': u'Default PowerDNS 4 Pool',