summaryrefslogtreecommitdiff
path: root/designate/storage/impl_sqlalchemy/alembic
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2022-08-30 05:11:25 +0000
committerGerrit Code Review <review@openstack.org>2022-08-30 05:11:25 +0000
commit218e11ea204ee948a7aa3dcda0febff379ef0ec2 (patch)
tree611370a1c00ceb9f539fbf06df6545daeb3dd552 /designate/storage/impl_sqlalchemy/alembic
parent71c7542a892d76a6631e919fdd7ecf636f834eaa (diff)
parent60c378763aa37246762ff210f024e2af019f6397 (diff)
downloaddesignate-218e11ea204ee948a7aa3dcda0febff379ef0ec2.tar.gz
Merge "Switch Designate to Alembic database migrations"
Diffstat (limited to 'designate/storage/impl_sqlalchemy/alembic')
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/README5
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/env.py83
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/legacy_utils.py43
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/script.py.mako32
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/0bcf910ea823_add_zone_attributes.py95
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/15b34ff3ecb8_fix_service_charset.py48
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/304d41c3847a_add_services.py59
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/7977deaa5167_add_rrset_indexes_for_filtering_perf.py46
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/867a331ce1fc_domain_to_zone_rename.py149
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/91eb1eb7c882_support_caa_records.py48
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/93a00a815f07_unique_service_status.py60
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/a69b45715cc1_add_delayed_notify_column.py45
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/b8999fd10721_support_naptr_records.py48
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/bfcfc4a07487_unique_ns_record.py65
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/c9f427f7180a_liberty.py340
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/d04819112169_new_pools_tables.py121
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/d9a1883e93e9_add_fks.py64
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/e5e2199ed76e_support_cert_records.py48
-rw-r--r--designate/storage/impl_sqlalchemy/alembic/versions/f9f969f9d85e_change_managed_column_types.py61
19 files changed, 1460 insertions, 0 deletions
diff --git a/designate/storage/impl_sqlalchemy/alembic/README b/designate/storage/impl_sqlalchemy/alembic/README
new file mode 100644
index 00000000..81b6a350
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/README
@@ -0,0 +1,5 @@
+Please use the "designate-manage database" command for database management.
+
+Developers adding new migrations can run 'alembic -m "<migration title>"' from
+the designate/storage/impl_sqlalchemy directory where the alembic.ini file is
+located.
diff --git a/designate/storage/impl_sqlalchemy/alembic/env.py b/designate/storage/impl_sqlalchemy/alembic/env.py
new file mode 100644
index 00000000..0d23c33e
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/env.py
@@ -0,0 +1,83 @@
+# 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.mport threading
+from sqlalchemy import engine_from_config
+from sqlalchemy import pool
+
+from alembic import context
+
+# this is the Alembic Config object, which provides
+# access to the values within the .ini file in use.
+config = context.config
+
+# add your model's MetaData object here
+# for 'autogenerate' support
+# from myapp import mymodel
+# target_metadata = mymodel.Base.metadata
+target_metadata = None
+
+# other values from the config, defined by the needs of env.py,
+# can be acquired:
+# my_important_option = config.get_main_option("my_important_option")
+# ... etc.
+
+
+def run_migrations_offline() -> None:
+ """Run migrations in 'offline' mode.
+
+ This configures the context with just a URL
+ and not an Engine, though an Engine is acceptable
+ here as well. By skipping the Engine creation
+ we don't even need a DBAPI to be available.
+
+ Calls to context.execute() here emit the given string to the
+ script output.
+
+ """
+ url = config.get_main_option("sqlalchemy.url")
+ context.configure(
+ url=url,
+ target_metadata=target_metadata,
+ literal_binds=True,
+ dialect_opts={"paramstyle": "named"},
+ )
+
+ with context.begin_transaction():
+ context.run_migrations()
+
+
+def run_migrations_online() -> None:
+ """Run migrations in 'online' mode.
+
+ In this scenario we need to create an Engine
+ and associate a connection with the context.
+
+ """
+ connectable = engine_from_config(
+ config.get_section(config.config_ini_section),
+ prefix="sqlalchemy.",
+ poolclass=pool.NullPool,
+ )
+
+ with connectable.connect() as connection:
+ context.configure(
+ connection=connection, target_metadata=target_metadata,
+ transactional_ddl=True, transaction_per_migration=True
+ )
+
+ with context.begin_transaction():
+ context.run_migrations()
+
+
+if context.is_offline_mode():
+ run_migrations_offline()
+else:
+ run_migrations_online()
diff --git a/designate/storage/impl_sqlalchemy/alembic/legacy_utils.py b/designate/storage/impl_sqlalchemy/alembic/legacy_utils.py
new file mode 100644
index 00000000..b0f7179e
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/legacy_utils.py
@@ -0,0 +1,43 @@
+# Copyright 2022 Red Hat
+#
+# 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 alembic import op
+from oslo_log import log as logging
+import sqlalchemy as sa
+
+LOG = logging.getLogger(__name__)
+
+
+def is_migration_needed(equivalent_revision):
+ metadata = sa.MetaData(bind=op.get_bind())
+ sa.MetaData.reflect(metadata)
+
+ if 'migrate_version' not in metadata.tables.keys():
+ return True
+
+ version_sql = sa.text("SELECT version FROM migrate_version;")
+ legacy_db_rev = None
+ try:
+ legacy_db_rev = op.get_bind().execute(version_sql).scalar_one_or_none()
+ except Exception as e:
+ LOG.debug("Unable to query the database for the legacy revision "
+ "number. Assuming there is no legacy migration revision "
+ "or the migration is running in offline mode. Error: %s",
+ str(e))
+
+ # Check if this migration was already run by the legacy sqlalchemy-migrate
+ # migrations.
+ if legacy_db_rev and int(legacy_db_rev) >= equivalent_revision:
+ return False
+ return True
diff --git a/designate/storage/impl_sqlalchemy/alembic/script.py.mako b/designate/storage/impl_sqlalchemy/alembic/script.py.mako
new file mode 100644
index 00000000..8fd7d546
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/script.py.mako
@@ -0,0 +1,32 @@
+# 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.
+
+"""${message}
+
+Revision ID: ${up_revision}
+Revises: ${down_revision | comma,n}
+Create Date: ${create_date}
+
+"""
+from alembic import op
+import sqlalchemy as sa
+${imports if imports else ""}
+
+# revision identifiers, used by Alembic.
+revision = ${repr(up_revision)}
+down_revision = ${repr(down_revision)}
+branch_labels = ${repr(branch_labels)}
+depends_on = ${repr(depends_on)}
+
+
+def upgrade() -> None:
+ ${upgrades if upgrades else "pass"}
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/0bcf910ea823_add_zone_attributes.py b/designate/storage/impl_sqlalchemy/alembic/versions/0bcf910ea823_add_zone_attributes.py
new file mode 100644
index 00000000..531d11b1
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/0bcf910ea823_add_zone_attributes.py
@@ -0,0 +1,95 @@
+# Copyright 2015 Hewlett-Packard Development Company, L.P.
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""add_zone_attributes
+
+Revision ID: 0bcf910ea823
+Revises: a69b45715cc1
+Create Date: 2022-07-29 21:36:15.117658
+
+"""
+from alembic import op
+from oslo_utils import timeutils
+import sqlalchemy as sa
+
+from designate.sqlalchemy.types import UUID
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+from designate import utils
+
+# revision identifiers, used by Alembic.
+revision = '0bcf910ea823'
+down_revision = 'a69b45715cc1'
+branch_labels = None
+depends_on = None
+
+# Equivalent to legacy sqlalchemy-migrate revision 085_add_zone_attributes
+
+# Note from original migration file:
+# Move zone masters to their own table, and allow for abstract keys in the
+# attributes table
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(85):
+ return
+
+ metadata = sa.MetaData()
+
+ zone_masters_table = op.create_table(
+ 'zone_masters', metadata,
+ sa.Column('id', UUID, default=utils.generate_uuid, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime,
+ default=lambda: timeutils.utcnow()),
+ sa.Column('updated_at', sa.DateTime,
+ onupdate=lambda: timeutils.utcnow()),
+ sa.Column('host', sa.String(32), nullable=False),
+ sa.Column('port', sa.Integer, nullable=False),
+ sa.Column('zone_id', UUID, nullable=False),
+ sa.UniqueConstraint('host', 'port', 'zone_id', name='unique_masters'),
+ sa.ForeignKeyConstraint(['zone_id'], ['zones.id'], ondelete='CASCADE'))
+
+ zone_attr_sql = sa.text(
+ 'SELECT id, version, created_at, updated_at, value, zone_id FROM '
+ 'zone_attributes WHERE \'key\' = \'master\';')
+
+ masters = op.get_bind().execute(zone_attr_sql).fetchall()
+
+ masters_input = []
+
+ for master in masters:
+ host, port = utils.split_host_port(
+ master['value'])
+ masters_input.append({
+ 'id': master['id'],
+ 'version': master['version'],
+ 'created_at': master['created_at'],
+ 'updated_at': master['updated_at'],
+ 'zone_id': master['zone_id'],
+ 'host': host,
+ 'port': port
+ })
+
+ op.bulk_insert(zone_masters_table, masters_input)
+
+ master_delete_sql = sa.text(
+ 'DELETE FROM zone_attributes WHERE \'key\' = \'master\';')
+
+ op.get_bind().execute(master_delete_sql)
+
+ with op.batch_alter_table('zone_attributes') as batch_op:
+ batch_op.alter_column('key', type_=sa.String(50),
+ existing_type=sa.Enum)
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/15b34ff3ecb8_fix_service_charset.py b/designate/storage/impl_sqlalchemy/alembic/versions/15b34ff3ecb8_fix_service_charset.py
new file mode 100644
index 00000000..a385ef72
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/15b34ff3ecb8_fix_service_charset.py
@@ -0,0 +1,48 @@
+# Copyright 2016 Hewlett Packard Enterprise Development Company LP
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""fix_service_charset
+
+Revision ID: 15b34ff3ecb8
+Revises: 304d41c3847a
+Create Date: 2022-08-01 16:53:34.612019
+
+"""
+from alembic import op
+
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+
+# revision identifiers, used by Alembic.
+revision = '15b34ff3ecb8'
+down_revision = '304d41c3847a'
+branch_labels = None
+depends_on = None
+
+# Equivalent to legacy sqlalchemy-migrate revision 098_fix_service_charset
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(98):
+ return
+
+ current_bind = op.get_bind()
+ if current_bind.dialect.name != 'mysql':
+ return
+
+ op.execute('SET foreign_key_checks = 0;')
+ op.execute('ALTER TABLE service_statuses CONVERT TO CHARACTER SET utf8;')
+ op.execute('SET foreign_key_checks = 1;')
+ op.execute('ALTER DATABASE DEFAULT CHARACTER SET utf8;')
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/304d41c3847a_add_services.py b/designate/storage/impl_sqlalchemy/alembic/versions/304d41c3847a_add_services.py
new file mode 100644
index 00000000..02e6a09a
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/304d41c3847a_add_services.py
@@ -0,0 +1,59 @@
+# Copyright 2016 Hewlett Packard Enterprise Development Company LP
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""add_services
+
+Revision ID: 304d41c3847a
+Revises: d04819112169
+Create Date: 2022-08-01 16:41:55.139558
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+from designate.sqlalchemy.types import UUID
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+from designate import utils
+
+# revision identifiers, used by Alembic.
+revision = '304d41c3847a'
+down_revision = 'd04819112169'
+branch_labels = None
+depends_on = None
+
+SERVICE_STATES = ["UP", "DOWN", "WARNING"]
+
+# Equivalent to legacy sqlalchemy-migrate revision 097_add_services
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(97):
+ return
+
+ metadata = sa.MetaData()
+
+ op.create_table(
+ 'service_statuses', metadata,
+ sa.Column('id', UUID, default=utils.generate_uuid, primary_key=True),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('service_name', sa.String(40), nullable=False),
+ sa.Column('hostname', sa.String(255), nullable=False),
+ sa.Column('heartbeated_at', sa.DateTime, nullable=True),
+ sa.Column('status', sa.Enum(name='service_statuses_enum',
+ *SERVICE_STATES), nullable=False),
+ sa.Column('stats', sa.Text, nullable=False),
+ sa.Column('capabilities', sa.Text, nullable=False))
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/7977deaa5167_add_rrset_indexes_for_filtering_perf.py b/designate/storage/impl_sqlalchemy/alembic/versions/7977deaa5167_add_rrset_indexes_for_filtering_perf.py
new file mode 100644
index 00000000..12abecbd
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/7977deaa5167_add_rrset_indexes_for_filtering_perf.py
@@ -0,0 +1,46 @@
+# Copyright 2016 Rackspace
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""add_rrset_indexes_for_filtering_perf
+
+Revision ID: 7977deaa5167
+Revises: 15b34ff3ecb8
+Create Date: 2022-08-01 17:13:01.429689
+
+"""
+from alembic import op
+
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+
+# revision identifiers, used by Alembic.
+revision = '7977deaa5167'
+down_revision = '15b34ff3ecb8'
+branch_labels = None
+depends_on = None
+
+# Equivalent to legacy sqlalchemy-migrate revision
+# 099_add_rrset_indexes_for_filtering_perf
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(99):
+ return
+
+ op.create_index('rrset_updated_at', 'recordsets', ['updated_at'])
+ op.create_index('rrset_zoneid', 'recordsets', ['zone_id'])
+ op.create_index('rrset_type', 'recordsets', ['type'])
+ op.create_index('rrset_ttl', 'recordsets', ['ttl'])
+ op.create_index('rrset_tenant_id', 'recordsets', ['tenant_id'])
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/867a331ce1fc_domain_to_zone_rename.py b/designate/storage/impl_sqlalchemy/alembic/versions/867a331ce1fc_domain_to_zone_rename.py
new file mode 100644
index 00000000..65b6df70
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/867a331ce1fc_domain_to_zone_rename.py
@@ -0,0 +1,149 @@
+# Copyright 2015 Hewlett-Packard Development Company, L.P.
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""domain_to_zone_rename
+
+Revision ID: 867a331ce1fc
+Revises: c9f427f7180a
+Create Date: 2022-07-29 18:41:19.427853
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+from designate.sqlalchemy.types import UUID
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+
+# revision identifiers, used by Alembic.
+revision = '867a331ce1fc'
+down_revision = 'c9f427f7180a'
+branch_labels = None
+depends_on = None
+
+# Equivalent to legacy sqlalchemy-migrate revision 080_domain_to_zone_rename
+
+# Notes from the original migration file:
+# This migration removes all references to domain from our Database.
+# We rename the domains and domain_attribute tables, and rename any columns
+# that had "domain" in the name.as
+# There is a follow on patch to recreate the FKs for the newly renamed
+# tables as the lib we use doesn't seem to like creating FKs on renamed
+# tables until after the migration is complete.
+
+
+def _drop_foreign_key(fk_def):
+
+ table = fk_def[0].table
+
+ col = fk_def[0]
+ ref_col = fk_def[1]
+
+ # We need a naming convention to find unnamed foreign keys on sqlite
+ naming_convention = {
+ "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s"}
+
+ # Use .copy() to avoid the set changing during the for operation
+ # We need to search for the foreign keys as they may be named differently
+ # between different dialects (mysql, sqlite, etc.)
+ for fk in table.foreign_keys.copy():
+ # We must use batch mode because the unit tests use sqlite
+ with op.batch_alter_table(
+ table.name, naming_convention=naming_convention) as batch_op:
+
+ # Check if the fk is the one we want
+ if fk.column == col and fk.parent == ref_col:
+ batch_op.drop_constraint(fk.constraint.name,
+ type_='foreignkey')
+
+ # Check if the fk is the one we want (sometimes it seems the parent
+ # / col is switched
+ if fk.parent == col and fk.column == ref_col:
+ batch_op.drop_constraint(fk.constraint.name,
+ type_='foreignkey')
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(80):
+ return
+
+ convention = {
+ "ix": 'ix_%(column_0_label)s',
+ "uq": "uq_%(table_name)s_%(column_0_name)s",
+ "ck": "ck_%(table_name)s_%(constraint_name)s",
+ "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
+ "pk": "pk_%(table_name)s"}
+
+ metadata = sa.MetaData(naming_convention=convention)
+ metadata.bind = op.get_bind()
+
+ # Get all the tables
+ domains_table = sa.Table('domains', metadata, autoload=True)
+ domain_attrib_table = sa.Table('domain_attributes', metadata,
+ autoload=True)
+ recordsets_table = sa.Table('recordsets', metadata, autoload=True)
+ records_table = sa.Table('records', metadata, autoload=True)
+ ztr_table = sa.Table('zone_transfer_requests', metadata, autoload=True)
+ zta_table = sa.Table('zone_transfer_accepts', metadata, autoload=True)
+
+ # Remove the affected FKs
+ # Define FKs
+ fks = [
+ [domains_table.c.id, domains_table.c.parent_domain_id],
+ [domain_attrib_table.c.domain_id, domains_table.c.id],
+ [recordsets_table.c.domain_id, domains_table.c.id],
+ [records_table.c.domain_id, domains_table.c.id],
+ [ztr_table.c.domain_id, domains_table.c.id],
+ [zta_table.c.domain_id, domains_table.c.id]
+ ]
+
+ # Drop FKs
+ for fk in fks:
+ _drop_foreign_key(fk)
+
+ with op.batch_alter_table('domains') as batch_op:
+ batch_op.alter_column('parent_domain_id',
+ new_column_name='parent_zone_id',
+ existing_type=UUID)
+ op.rename_table('domains', 'zones')
+
+ with op.batch_alter_table('domain_attributes') as batch_op:
+ batch_op.alter_column('domain_id', new_column_name='zone_id',
+ existing_type=UUID)
+ op.rename_table('domain_attributes', 'zone_attributes')
+
+ with op.batch_alter_table('recordsets') as batch_op:
+ batch_op.alter_column('domain_id', new_column_name='zone_id',
+ existing_type=UUID)
+ batch_op.alter_column('domain_shard', new_column_name='zone_shard',
+ existing_type=sa.SmallInteger)
+
+ with op.batch_alter_table('records') as batch_op:
+ batch_op.alter_column('domain_id', new_column_name='zone_id',
+ existing_type=UUID)
+ batch_op.alter_column('domain_shard', new_column_name='zone_shard',
+ existing_type=sa.SmallInteger)
+
+ with op.batch_alter_table('zone_transfer_requests') as batch_op:
+ batch_op.alter_column('domain_id', new_column_name='zone_id',
+ existing_type=UUID)
+
+ with op.batch_alter_table('zone_transfer_accepts') as batch_op:
+ batch_op.alter_column('domain_id', new_column_name='zone_id',
+ existing_type=UUID)
+
+ with op.batch_alter_table('zone_tasks') as batch_op:
+ batch_op.alter_column('domain_id', new_column_name='zone_id',
+ existing_type=UUID)
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/91eb1eb7c882_support_caa_records.py b/designate/storage/impl_sqlalchemy/alembic/versions/91eb1eb7c882_support_caa_records.py
new file mode 100644
index 00000000..668569ad
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/91eb1eb7c882_support_caa_records.py
@@ -0,0 +1,48 @@
+# Copyright 2018 Canonical Ltd.
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""support_caa_records
+
+Revision ID: 91eb1eb7c882
+Revises: b8999fd10721
+Create Date: 2022-08-01 17:32:21.386556
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+
+# revision identifiers, used by Alembic.
+revision = '91eb1eb7c882'
+down_revision = 'b8999fd10721'
+branch_labels = None
+depends_on = None
+
+# Equivalent to legacy sqlalchemy-migrate revision 102_support_caa_records
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(102):
+ return
+
+ RECORD_TYPES = ['A', 'AAAA', 'CNAME', 'MX', 'SRV', 'TXT', 'SPF', 'NS',
+ 'PTR', 'SSHFP', 'SOA', 'NAPTR', 'CAA']
+
+ with op.batch_alter_table('recordsets') as batch_op:
+ batch_op.alter_column('type', type_=sa.Enum(name='record_types',
+ *RECORD_TYPES),
+ existing_type=sa.Enum, existing_nullable=False)
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/93a00a815f07_unique_service_status.py b/designate/storage/impl_sqlalchemy/alembic/versions/93a00a815f07_unique_service_status.py
new file mode 100644
index 00000000..6071a7ba
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/93a00a815f07_unique_service_status.py
@@ -0,0 +1,60 @@
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""unique_service_status
+
+Revision ID: 93a00a815f07
+Revises: 7977deaa5167
+Create Date: 2022-08-01 17:17:44.572964
+
+"""
+import sys
+
+from alembic import op
+from oslo_log import log as logging
+import sqlalchemy as sa
+
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+
+# revision identifiers, used by Alembic.
+revision = '93a00a815f07'
+down_revision = '7977deaa5167'
+branch_labels = None
+depends_on = None
+
+LOG = logging.getLogger()
+
+# Equivalent to legacy sqlalchemy-migrate revision 100_unique_service_status
+
+EXPLANATION = """
+You need to manually remove duplicate entries from the database.
+
+The error message was:
+%s
+"""
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(100):
+ return
+
+ try:
+ with op.batch_alter_table('service_statuses') as batch_op:
+ batch_op.create_unique_constraint('unique_service_status',
+ ['service_name', 'hostname'])
+ except sa.exc.IntegrityError as e:
+ LOG.error(EXPLANATION, e)
+ # Use sys.exit so we don't blow up with a huge trace
+ sys.exit(1)
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/a69b45715cc1_add_delayed_notify_column.py b/designate/storage/impl_sqlalchemy/alembic/versions/a69b45715cc1_add_delayed_notify_column.py
new file mode 100644
index 00000000..93bd6c5f
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/a69b45715cc1_add_delayed_notify_column.py
@@ -0,0 +1,45 @@
+# Copyright 2015 Hewlett-Packard Development Company, L.P.
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""add_delayed_notify_column
+
+Revision ID: a69b45715cc1
+Revises: f9f969f9d85e
+Create Date: 2022-07-29 21:30:12.127816
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+
+# revision identifiers, used by Alembic.
+revision = 'a69b45715cc1'
+down_revision = 'f9f969f9d85e'
+branch_labels = None
+depends_on = None
+
+# Equivalent to legacy sqlalchemy-migrate revision
+# 084_add_delayed_notify_column
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(84):
+ return
+
+ op.add_column('zones',
+ sa.Column('delayed_notify', sa.Boolean, default=False))
+ op.create_index('delayed_notify', 'zones', ['delayed_notify'])
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/b8999fd10721_support_naptr_records.py b/designate/storage/impl_sqlalchemy/alembic/versions/b8999fd10721_support_naptr_records.py
new file mode 100644
index 00000000..ec456d4c
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/b8999fd10721_support_naptr_records.py
@@ -0,0 +1,48 @@
+# Copyright 2018 Canonical Ltd.
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""support_naptr_records
+
+Revision ID: b8999fd10721
+Revises: 93a00a815f07
+Create Date: 2022-08-01 17:25:33.058845
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+
+# revision identifiers, used by Alembic.
+revision = 'b8999fd10721'
+down_revision = '93a00a815f07'
+branch_labels = None
+depends_on = None
+
+# Equivalent to legacy sqlalchemy-migrate revision 101_support_naptr_records
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(101):
+ return
+
+ RECORD_TYPES = ['A', 'AAAA', 'CNAME', 'MX', 'SRV', 'TXT', 'SPF', 'NS',
+ 'PTR', 'SSHFP', 'SOA', 'NAPTR']
+
+ with op.batch_alter_table('recordsets') as batch_op:
+ batch_op.alter_column('type', type_=sa.Enum(name='record_types',
+ *RECORD_TYPES),
+ existing_type=sa.Enum, existing_nullable=False)
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/bfcfc4a07487_unique_ns_record.py b/designate/storage/impl_sqlalchemy/alembic/versions/bfcfc4a07487_unique_ns_record.py
new file mode 100644
index 00000000..6f355a60
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/bfcfc4a07487_unique_ns_record.py
@@ -0,0 +1,65 @@
+# Copyright 2015 Hewlett-Packard Development Company, L.P.
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""unique_ns_record
+
+Revision ID: bfcfc4a07487
+Revises: d9a1883e93e9
+Create Date: 2022-07-29 21:05:19.276173
+
+"""
+import sys
+
+from alembic import op
+from oslo_log import log as logging
+import sqlalchemy as sa
+
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+
+# revision identifiers, used by Alembic.
+revision = 'bfcfc4a07487'
+down_revision = 'd9a1883e93e9'
+branch_labels = None
+depends_on = None
+
+LOG = logging.getLogger()
+
+# Equivalent to legacy sqlalchemy-migrate revision 082_unique_ns_record
+
+# Note from the original migration script:
+# Add Unique constraint on ('pool_id', 'hostname') in the pool_ns_records
+# table Bug #1517389
+
+EXPLANATION = """
+You need to manually remove duplicate entries from the database.
+
+The error message was:
+%s
+"""
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(82):
+ return
+
+ try:
+ with op.batch_alter_table('pool_ns_records') as batch_op:
+ batch_op.create_unique_constraint('unique_ns_name',
+ ['pool_id', 'hostname'])
+ except sa.exc.IntegrityError as e:
+ LOG.error(EXPLANATION, e)
+ # Use sys.exit so we don't blow up with a huge trace
+ sys.exit(1)
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/c9f427f7180a_liberty.py b/designate/storage/impl_sqlalchemy/alembic/versions/c9f427f7180a_liberty.py
new file mode 100644
index 00000000..62b7135f
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/c9f427f7180a_liberty.py
@@ -0,0 +1,340 @@
+# Copyright 2015 Hewlett-Packard Development Company, L.P.
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""liberty
+
+Revision ID: c9f427f7180a
+Revises:
+Create Date: 2022-07-28 23:06:40.731452
+
+"""
+from alembic import op
+from oslo_config import cfg
+from oslo_utils import timeutils
+import sqlalchemy as sa
+
+from designate.conf import central
+from designate.sqlalchemy.types import UUID
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+
+# revision identifiers, used by Alembic.
+revision = 'c9f427f7180a'
+down_revision = None
+branch_labels = None
+depends_on = None
+
+# Equivalent to legacy sqlalchemy-migrate revision 070_liberty
+
+CONF = cfg.CONF
+central.register_opts(CONF)
+
+ACTIONS = ('CREATE', 'DELETE', 'UPDATE', 'NONE')
+POOL_PROVISIONERS = ('UNMANAGED',)
+RECORD_TYPES = ('A', 'AAAA', 'CNAME', 'MX', 'SRV', 'TXT', 'SPF', 'NS', 'PTR',
+ 'SSHFP', 'SOA')
+RESOURCE_STATUSES = ('ACTIVE', 'PENDING', 'DELETED', 'ERROR')
+TASK_STATUSES = ('ACTIVE', 'PENDING', 'DELETED', 'ERROR', 'COMPLETE')
+TSIG_ALGORITHMS = ('hmac-md5', 'hmac-sha1', 'hmac-sha224', 'hmac-sha256',
+ 'hmac-sha384', 'hmac-sha512')
+TSIG_SCOPES = ('POOL', 'ZONE')
+ZONE_ATTRIBUTE_KEYS = ('master',)
+ZONE_TASK_TYPES = ('IMPORT', 'EXPORT')
+ZONE_TYPES = ('PRIMARY', 'SECONDARY')
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(70):
+ return
+
+ metadata = sa.MetaData()
+
+ pools_table = op.create_table(
+ 'pools', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('name', sa.String(50), nullable=False),
+ sa.Column('description', sa.Unicode(160), nullable=True),
+ sa.Column('tenant_id', sa.String(36), nullable=True),
+ sa.Column('provisioner', sa.Enum(name='pool_provisioner',
+ *POOL_PROVISIONERS),
+ nullable=False, server_default='UNMANAGED'),
+ sa.UniqueConstraint('name', name='unique_pool_name'))
+
+ op.bulk_insert(
+ pools_table,
+ [{'id': CONF['service:central'].default_pool_id,
+ 'name': 'default',
+ 'version': 1}])
+
+ op.create_table(
+ 'pool_ns_records', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('pool_id', UUID, nullable=False),
+ sa.Column('priority', sa.Integer, nullable=False),
+ sa.Column('hostname', sa.String(255), nullable=False),
+ sa.ForeignKeyConstraint(['pool_id'], ['pools.id'], ondelete='CASCADE'))
+
+ op.create_table(
+ 'pool_attributes', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('key', sa.String(255), nullable=False),
+ sa.Column('value', sa.String(255), nullable=False),
+ sa.Column('pool_id', UUID, nullable=False),
+ sa.UniqueConstraint('pool_id', 'key', 'value',
+ name='unique_pool_attribute'),
+ sa.ForeignKeyConstraint(['pool_id'], ['pools.id'], ondelete='CASCADE'))
+
+ op.create_table(
+ 'domains', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('version', sa.Integer, nullable=False),
+ sa.Column('tenant_id', sa.String(36), default=None, nullable=True),
+ sa.Column('name', sa.String(255), nullable=False),
+ sa.Column('email', sa.String(255), nullable=False),
+ sa.Column('ttl', sa.Integer, default=CONF.default_ttl, nullable=False),
+ sa.Column('refresh', sa.Integer, nullable=False),
+ sa.Column('retry', sa.Integer, nullable=False),
+ sa.Column('expire', sa.Integer, nullable=False),
+ sa.Column('minimum', sa.Integer, nullable=False),
+ sa.Column('parent_domain_id', UUID, default=None, nullable=True),
+ sa.Column('serial', sa.Integer, nullable=False, server_default='1'),
+ sa.Column('deleted', sa.CHAR(32), nullable=False, default='0',
+ server_default='0'),
+ sa.Column('deleted_at', sa.DateTime, nullable=True, default=None),
+ sa.Column('description', sa.Unicode(160), nullable=True),
+ sa.Column('status', sa.Enum(name='domains_resource_statuses',
+ *RESOURCE_STATUSES),
+ nullable=False, server_default='PENDING', default='PENDING'),
+ sa.Column('action', sa.Enum(name='domain_actions', *ACTIONS),
+ default='CREATE', server_default='CREATE', nullable=False),
+ sa.Column('pool_id', UUID, default=None, nullable=True),
+ sa.Column('reverse_name', sa.String(255), nullable=False,
+ server_default=''),
+ sa.Column("type", sa.Enum(name='type', *ZONE_TYPES),
+ server_default='PRIMARY', default='PRIMARY'),
+ sa.Column('transferred_at', sa.DateTime, default=None),
+ sa.Column('shard', sa.SmallInteger, nullable=False),
+ sa.UniqueConstraint('name', 'deleted', 'pool_id',
+ name='unique_domain_name'),
+ sa.ForeignKeyConstraint(['parent_domain_id'],
+ ['domains.id'],
+ ondelete='SET NULL'),
+ sa.Index('zone_deleted', 'deleted'),
+ sa.Index('zone_tenant_deleted', 'tenant_id', 'deleted'),
+ sa.Index('reverse_name_deleted', 'reverse_name', 'deleted'),
+ sa.Index('zone_created_at', 'created_at'))
+
+ op.create_table(
+ 'domain_attributes', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('key', sa.Enum(name='key', *ZONE_ATTRIBUTE_KEYS)),
+ sa.Column('value', sa.String(255), nullable=False),
+ sa.Column('domain_id', UUID, nullable=False),
+ sa.UniqueConstraint('key', 'value', 'domain_id',
+ name='unique_attributes'),
+ sa.ForeignKeyConstraint(['domain_id'], ['domains.id'],
+ ondelete='CASCADE'))
+ op.create_table(
+ 'recordsets', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('domain_shard', sa.SmallInteger, nullable=False),
+ sa.Column('tenant_id', sa.String(36), default=None, nullable=True),
+ sa.Column('domain_id', UUID, nullable=False),
+ sa.Column('name', sa.String(255), nullable=False),
+ sa.Column('type', sa.Enum(name='record_types', *RECORD_TYPES),
+ nullable=False),
+ sa.Column('ttl', sa.Integer, default=None, nullable=True),
+ sa.Column('description', sa.Unicode(160), nullable=True),
+ sa.Column('reverse_name', sa.String(255), nullable=False,
+ server_default=''),
+ sa.UniqueConstraint('domain_id', 'name', 'type',
+ name='unique_recordset'),
+ sa.ForeignKeyConstraint(['domain_id'], ['domains.id'],
+ ondelete='CASCADE'),
+ sa.Index('rrset_type_domainid', 'type', 'domain_id'),
+ sa.Index('recordset_type_name', 'type', 'name'),
+ sa.Index('reverse_name_dom_id', 'reverse_name', 'domain_id'),
+ sa.Index('recordset_created_at', 'created_at'))
+
+ op.create_table(
+ 'records', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('data', sa.Text, nullable=False),
+ sa.Column('domain_id', UUID, nullable=False),
+ sa.Column('managed', sa.Boolean, default=False),
+ sa.Column('managed_resource_type', sa.Unicode(50), default=None,
+ nullable=True),
+ sa.Column('managed_resource_id', UUID, default=None, nullable=True),
+ sa.Column('managed_plugin_type', sa.Unicode(50), default=None,
+ nullable=True),
+ sa.Column('managed_plugin_name', sa.Unicode(50), default=None,
+ nullable=True),
+ sa.Column('hash', sa.String(32), nullable=False),
+ sa.Column('description', sa.Unicode(160), nullable=True),
+ sa.Column('status', sa.Enum(name='record_resource_statuses',
+ *RESOURCE_STATUSES),
+ server_default='PENDING', default='PENDING', nullable=False),
+ sa.Column('tenant_id', sa.String(36), default=None, nullable=True),
+ sa.Column('recordset_id', UUID, nullable=False),
+ sa.Column('managed_tenant_id', sa.Unicode(36), default=None,
+ nullable=True),
+ sa.Column('managed_resource_region', sa.Unicode(100), default=None,
+ nullable=True),
+ sa.Column('managed_extra', sa.Unicode(100), default=None,
+ nullable=True),
+ sa.Column('action', sa.Enum(name='record_actions', *ACTIONS),
+ default='CREATE', server_default='CREATE', nullable=False),
+ sa.Column('serial', sa.Integer, server_default='1', nullable=False),
+ sa.Column('domain_shard', sa.SmallInteger, nullable=False),
+ sa.UniqueConstraint('hash', name='unique_record'),
+ sa.ForeignKeyConstraint(['domain_id'], ['domains.id'],
+ ondelete='CASCADE'),
+ sa.ForeignKeyConstraint(['recordset_id'], ['recordsets.id'],
+ ondelete='CASCADE'),
+ sa.ForeignKeyConstraint(['domain_id'], ['domains.id'],
+ ondelete='CASCADE',
+ name='fkey_records_domain_id'),
+ sa.ForeignKeyConstraint(['recordset_id'], ['recordsets.id'],
+ ondelete='CASCADE',
+ name='fkey_records_recordset_id'),
+ sa.Index('records_tenant', 'tenant_id'),
+ sa.Index('record_created_at', 'created_at'),
+ sa.Index('update_status_index', 'status', 'domain_id', 'tenant_id',
+ 'created_at', 'serial'))
+
+ op.create_table(
+ 'quotas', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime,
+ default=lambda: timeutils.utcnow()),
+ sa.Column('updated_at', sa.DateTime,
+ onupdate=lambda: timeutils.utcnow()),
+ sa.Column('tenant_id', sa.String(36), nullable=False),
+ sa.Column('resource', sa.String(32), nullable=False),
+ sa.Column('hard_limit', sa.Integer, nullable=False),
+ sa.UniqueConstraint('tenant_id', 'resource', name='unique_quota'))
+
+ op.create_table(
+ 'tsigkeys', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('name', sa.String(255), nullable=False),
+ sa.Column('algorithm',
+ sa.Enum(name='tsig_algorithms', *TSIG_ALGORITHMS),
+ nullable=False),
+ sa.Column('secret', sa.String(255), nullable=False),
+ sa.Column('scope', sa.Enum(name='tsig_scopes', *TSIG_SCOPES),
+ nullable=False, server_default='POOL'),
+ sa.Column('resource_id', UUID, nullable=False),
+ sa.UniqueConstraint('name', name='unique_tsigkey_name'))
+
+ op.create_table(
+ 'tlds', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime,
+ default=lambda: timeutils.utcnow()),
+ sa.Column('updated_at', sa.DateTime,
+ onupdate=lambda: timeutils.utcnow()),
+ sa.Column('name', sa.String(255), nullable=False),
+ sa.Column('description', sa.Unicode(160), nullable=True),
+ sa.UniqueConstraint('name', name='unique_tld_name'))
+
+ op.create_table(
+ 'zone_transfer_requests', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('domain_id', UUID, nullable=False),
+ sa.Column("key", sa.String(255), nullable=False),
+ sa.Column("description", sa.String(255)),
+ sa.Column("tenant_id", sa.String(36), default=None, nullable=False),
+ sa.Column("target_tenant_id", sa.String(36), default=None,
+ nullable=True),
+ sa.Column("status",
+ sa.Enum(name='zone_transfer_requests_resource_statuses',
+ *TASK_STATUSES),
+ nullable=False, server_default='ACTIVE', default='ACTIVE'),
+ sa.ForeignKeyConstraint(['domain_id'], ['domains.id'],
+ ondelete='CASCADE'))
+
+ op.create_table(
+ 'zone_transfer_accepts', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('domain_id', UUID, nullable=False),
+ sa.Column('zone_transfer_request_id', UUID, nullable=False),
+ sa.Column("tenant_id", sa.String(36), default=None, nullable=False),
+ sa.Column("status",
+ sa.Enum(name='zone_transfer_accepts_resource_statuses',
+ *TASK_STATUSES),
+ nullable=False, server_default='ACTIVE', default='ACTIVE'),
+ sa.ForeignKeyConstraint(['domain_id'], ['domains.id'],
+ ondelete='CASCADE'),
+ sa.ForeignKeyConstraint(['zone_transfer_request_id'],
+ ['zone_transfer_requests.id'],
+ ondelete='CASCADE'))
+
+ op.create_table(
+ 'zone_tasks', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('tenant_id', sa.String(36), default=None, nullable=True),
+ sa.Column('domain_id', UUID, nullable=True),
+ sa.Column('task_type', sa.Enum(name='task_types', *ZONE_TASK_TYPES),
+ nullable=True),
+ sa.Column('message', sa.String(160), nullable=True),
+ sa.Column('status', sa.Enum(name='zone_tasks_resource_statuses',
+ *TASK_STATUSES),
+ nullable=False, server_default='ACTIVE', default='ACTIVE'),
+ sa.Column('location', sa.String(160), nullable=True))
+
+ op.create_table(
+ 'blacklists', metadata,
+ sa.Column('id', UUID, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('updated_at', sa.DateTime),
+ sa.Column('created_at', sa.DateTime),
+ sa.Column('pattern', sa.String(255), nullable=False),
+ sa.Column('description', sa.Unicode(160), nullable=True),
+ sa.UniqueConstraint('pattern', name='pattern'))
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/d04819112169_new_pools_tables.py b/designate/storage/impl_sqlalchemy/alembic/versions/d04819112169_new_pools_tables.py
new file mode 100644
index 00000000..d321fb51
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/d04819112169_new_pools_tables.py
@@ -0,0 +1,121 @@
+# Copyright 2015 Hewlett-Packard Development Company, L.P.
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""new_pools_tables
+
+Revision ID: d04819112169
+Revises: 0bcf910ea823
+Create Date: 2022-08-01 16:20:17.440784
+
+"""
+from alembic import op
+from oslo_utils import timeutils
+import sqlalchemy as sa
+
+from designate.sqlalchemy.types import UUID
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+from designate import utils
+
+# revision identifiers, used by Alembic.
+revision = 'd04819112169'
+down_revision = '0bcf910ea823'
+branch_labels = None
+depends_on = None
+
+# Equivalent to legacy sqlalchemy-migrate revision 086_new_pools_tables
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(86):
+ return
+
+ metadata = sa.MetaData()
+
+ op.create_table(
+ 'pool_nameservers', metadata,
+ sa.Column('id', UUID, default=utils.generate_uuid, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime,
+ default=lambda: timeutils.utcnow()),
+ sa.Column('updated_at', sa.DateTime,
+ onupdate=lambda: timeutils.utcnow()),
+ sa.Column('pool_id', UUID, nullable=False),
+ sa.Column('host', sa.String(255), nullable=False),
+ sa.Column('port', sa.Integer, nullable=False),
+ sa.ForeignKeyConstraint(['pool_id'], ['pools.id'], ondelete='CASCADE'),
+ sa.UniqueConstraint('pool_id', 'host', 'port',
+ name='unique_pool_host_port'))
+
+ op.create_table(
+ 'pool_targets', metadata,
+ sa.Column('id', UUID, default=utils.generate_uuid, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime,
+ default=lambda: timeutils.utcnow()),
+ sa.Column('updated_at', sa.DateTime,
+ onupdate=lambda: timeutils.utcnow()),
+ sa.Column('pool_id', UUID, nullable=False),
+ sa.Column('type', sa.String(50), nullable=False),
+ sa.Column('tsigkey_id', UUID, nullable=True),
+ sa.Column('description', sa.Unicode(160), nullable=True),
+ sa.ForeignKeyConstraint(['pool_id'], ['pools.id'], ondelete='CASCADE'))
+
+ op.create_table(
+ 'pool_target_masters', metadata,
+ sa.Column('id', UUID, default=utils.generate_uuid, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime,
+ default=lambda: timeutils.utcnow()),
+ sa.Column('updated_at', sa.DateTime,
+ onupdate=lambda: timeutils.utcnow()),
+ sa.Column('pool_target_id', UUID, nullable=False),
+ sa.Column('host', sa.String(255), nullable=False),
+ sa.Column('port', sa.Integer, nullable=False),
+ sa.ForeignKeyConstraint(['pool_target_id'], ['pool_targets.id'],
+ ondelete='CASCADE'),
+ sa.UniqueConstraint('pool_target_id', 'host', 'port',
+ name='unique_pool_target_host_port'))
+
+ op.create_table(
+ 'pool_target_options', metadata,
+ sa.Column('id', UUID, default=utils.generate_uuid, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime,
+ default=lambda: timeutils.utcnow()),
+ sa.Column('updated_at', sa.DateTime,
+ onupdate=lambda: timeutils.utcnow()),
+ sa.Column('pool_target_id', UUID, nullable=False),
+ sa.Column('key', sa.String(255), nullable=False),
+ sa.Column('value', sa.String(255), nullable=False),
+ sa.ForeignKeyConstraint(['pool_target_id'], ['pool_targets.id'],
+ ondelete='CASCADE'),
+ sa.UniqueConstraint('pool_target_id', 'key',
+ name='unique_pool_target_key'))
+
+ op.create_table(
+ 'pool_also_notifies', metadata,
+ sa.Column('id', UUID, default=utils.generate_uuid, primary_key=True),
+ sa.Column('version', sa.Integer, default=1, nullable=False),
+ sa.Column('created_at', sa.DateTime,
+ default=lambda: timeutils.utcnow()),
+ sa.Column('updated_at', sa.DateTime,
+ onupdate=lambda: timeutils.utcnow()),
+ sa.Column('pool_id', UUID, nullable=False),
+ sa.Column('host', sa.String(255), nullable=False),
+ sa.Column('port', sa.Integer, nullable=False),
+ sa.ForeignKeyConstraint(['pool_id'], ['pools.id'], ondelete='CASCADE'),
+ sa.UniqueConstraint('pool_id', 'host', 'port',
+ name='unique_pool_also_notifies_pool0host0port'))
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/d9a1883e93e9_add_fks.py b/designate/storage/impl_sqlalchemy/alembic/versions/d9a1883e93e9_add_fks.py
new file mode 100644
index 00000000..81d4a557
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/d9a1883e93e9_add_fks.py
@@ -0,0 +1,64 @@
+# Copyright 2015 Hewlett-Packard Development Company, L.P.
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""add_FKs
+
+Revision ID: d9a1883e93e9
+Revises: 867a331ce1fc
+Create Date: 2022-07-29 20:41:51.855014
+
+"""
+from alembic import op
+
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+
+# revision identifiers, used by Alembic.
+revision = 'd9a1883e93e9'
+down_revision = '867a331ce1fc'
+branch_labels = None
+depends_on = None
+
+# Equivalent to legacy sqlalchemy-migrate revision 081_add_FKs
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(81):
+ return
+
+ # We must use batch mode because the unit tests use sqlite
+ with op.batch_alter_table('zones') as batch_op:
+ batch_op.create_foreign_key('fk_zones_id_parent_zone_id', 'zones',
+ ['parent_zone_id'], ['id'],
+ ondelete='SET NULL')
+ with op.batch_alter_table('zone_attributes') as batch_op:
+ batch_op.create_foreign_key('fk_zone_attributes_zones_id_zone_id',
+ 'zones', ['zone_id'], ['id'],
+ ondelete='CASCADE')
+ with op.batch_alter_table('recordsets') as batch_op:
+ batch_op.create_foreign_key('fk_recordsets_zones_id_zone_id', 'zones',
+ ['zone_id'], ['id'], ondelete='CASCADE')
+ with op.batch_alter_table('records') as batch_op:
+ batch_op.create_foreign_key('fk_records_zones_id_zone_id', 'zones',
+ ['zone_id'], ['id'], ondelete='CASCADE')
+ with op.batch_alter_table('zone_transfer_requests') as batch_op:
+ batch_op.create_foreign_key('fk_ztr_zones_id_zone_id', 'zones',
+ ['zone_id'], ['id'], ondelete='CASCADE')
+ with op.batch_alter_table('zone_transfer_accepts') as batch_op:
+ batch_op.create_foreign_key('fk_zta_zones_id_zone_id', 'zones',
+ ['zone_id'], ['id'], ondelete='CASCADE')
+ with op.batch_alter_table('zone_tasks') as batch_op:
+ batch_op.create_foreign_key('fk_zone_tasks_zones_id_zone_id', 'zones',
+ ['zone_id'], ['id'], ondelete='CASCADE')
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/e5e2199ed76e_support_cert_records.py b/designate/storage/impl_sqlalchemy/alembic/versions/e5e2199ed76e_support_cert_records.py
new file mode 100644
index 00000000..f759ef6c
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/e5e2199ed76e_support_cert_records.py
@@ -0,0 +1,48 @@
+# Copyright 2021 Cloudification GmbH
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""support_cert_records
+
+Revision ID: e5e2199ed76e
+Revises: 91eb1eb7c882
+Create Date: 2022-08-01 17:34:45.569101
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+
+# revision identifiers, used by Alembic.
+revision = 'e5e2199ed76e'
+down_revision = '91eb1eb7c882'
+branch_labels = None
+depends_on = None
+
+# Equivalent to legacy sqlalchemy-migrate revision 103_support_cert_records
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(103):
+ return
+
+ RECORD_TYPES = ['A', 'AAAA', 'CNAME', 'MX', 'SRV', 'TXT', 'SPF', 'NS',
+ 'PTR', 'SSHFP', 'SOA', 'NAPTR', 'CAA', 'CERT']
+
+ with op.batch_alter_table('recordsets') as batch_op:
+ batch_op.alter_column('type', type_=sa.Enum(name='record_types',
+ *RECORD_TYPES),
+ existing_type=sa.Enum, existing_nullable=False)
diff --git a/designate/storage/impl_sqlalchemy/alembic/versions/f9f969f9d85e_change_managed_column_types.py b/designate/storage/impl_sqlalchemy/alembic/versions/f9f969f9d85e_change_managed_column_types.py
new file mode 100644
index 00000000..3cec4940
--- /dev/null
+++ b/designate/storage/impl_sqlalchemy/alembic/versions/f9f969f9d85e_change_managed_column_types.py
@@ -0,0 +1,61 @@
+# Copyright 2016 Hewlett Packard Enterprise Development Company LP
+# Copyright 2022 Red Hat
+#
+# 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.
+
+"""change_managed_column_types
+
+Revision ID: f9f969f9d85e
+Revises: bfcfc4a07487
+Create Date: 2022-07-29 21:18:35.403634
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+from designate.storage.impl_sqlalchemy.alembic import legacy_utils
+
+# revision identifiers, used by Alembic.
+revision = 'f9f969f9d85e'
+down_revision = 'bfcfc4a07487'
+branch_labels = None
+depends_on = None
+
+# Equivalent to legacy sqlalchemy-migrate revision
+# 083_change_managed_column_types
+
+
+def upgrade() -> None:
+ # Check if the equivalent legacy migration has already run
+ if not legacy_utils.is_migration_needed(83):
+ return
+
+ with op.batch_alter_table('records') as batch_op:
+ batch_op.alter_column('managed_extra', type_=sa.String(100),
+ existing_type=sa.Unicode(100),
+ existing_nullable=True)
+ batch_op.alter_column('managed_plugin_type', type_=sa.String(50),
+ existing_type=sa.Unicode(50),
+ existing_nullable=True)
+ batch_op.alter_column('managed_plugin_name', type_=sa.String(50),
+ existing_type=sa.Unicode(50),
+ existing_nullable=True)
+ batch_op.alter_column('managed_resource_type', type_=sa.String(50),
+ existing_type=sa.Unicode(50),
+ existing_nullable=True)
+ batch_op.alter_column('managed_resource_region', type_=sa.String(100),
+ existing_type=sa.Unicode(100),
+ existing_nullable=True)
+ batch_op.alter_column('managed_tenant_id', type_=sa.String(36),
+ existing_type=sa.Unicode(36),
+ existing_nullable=True)