sql: Squash stein migrations

Make the following changes to the new "initial" migrations.

- Add 'description' column to 'role' table (053)
- Drop 'password' column from 'password' table (054)
- Add 'domain_id' column to 'limit' table (055)
- Alter 'project_id' column of 'limit' table to be nullable (055)
- Add 'access_rule' and 'application_credential_access_rule' tables
  (056)

Change-Id: I58e4b6833036a25ea8a1202c87ceebdbe932b447
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane 2022-01-10 16:25:35 +00:00
parent 30ec0df2a3
commit 1639282e49
29 changed files with 49 additions and 619 deletions

View File

@ -1,18 +0,0 @@
# 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 Rocky backports. Do not use this number for new
# Stein work. New Stein work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,18 +0,0 @@
# 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 Rocky backports. Do not use this number for new
# Stein work. New Stein work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,18 +0,0 @@
# 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 Rocky backports. Do not use this number for new
# Stein work. New Stein work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,18 +0,0 @@
# 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 Rocky backports. Do not use this number for new
# Stein work. New Stein work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,15 +0,0 @@
# 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.
def upgrade(migrate_engine):
pass

View File

@ -1,21 +0,0 @@
# 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 sqlalchemy as sql
def upgrade(migrate_engine):
meta = sql.MetaData()
meta.bind = migrate_engine
password_table = sql.Table('password', meta, autoload=True)
password_table.c.password.drop()

View File

@ -1,21 +0,0 @@
# 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 sqlalchemy as sql
def upgrade(migrate_engine):
meta = sql.MetaData()
meta.bind = migrate_engine
limit_table = sql.Table('limit', meta, autoload=True)
limit_table.c.project_id.alter(nullable=True)

View File

@ -1,17 +0,0 @@
# Copyright 2019 SUSE Linux GmbH
#
# 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.
def upgrade(migrate_engine):
pass

View File

@ -1,18 +0,0 @@
# 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 Rocky backports. Do not use this number for new
# Stein work. New Stein work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,18 +0,0 @@
# 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 Rocky backports. Do not use this number for new
# Stein work. New Stein work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,18 +0,0 @@
# 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 Rocky backports. Do not use this number for new
# Stein work. New Stein work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,18 +0,0 @@
# 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 Rocky backports. Do not use this number for new
# Stein work. New Stein work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,15 +0,0 @@
# 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.
def upgrade(migrate_engine):
pass

View File

@ -1,15 +0,0 @@
# 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.
def upgrade(migrate_engine):
pass

View File

@ -1,15 +0,0 @@
# 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.
def upgrade(migrate_engine):
pass

View File

@ -1,17 +0,0 @@
# Copyright 2019 SUSE Linux GmbH
#
# 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.
def upgrade(migrate_engine):
pass

View File

@ -1,18 +0,0 @@
# 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 Rocky backports. Do not use this number for new
# Stein work. New Stein work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,18 +0,0 @@
# 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 Rocky backports. Do not use this number for new
# Stein work. New Stein work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,18 +0,0 @@
# 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 Rocky backports. Do not use this number for new
# Stein work. New Stein work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,18 +0,0 @@
# 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 Rocky backports. Do not use this number for new
# Stein work. New Stein work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,23 +0,0 @@
# 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 sqlalchemy as sql
def upgrade(migrate_engine):
meta = sql.MetaData()
meta.bind = migrate_engine
role_table = sql.Table('role', meta, autoload=True)
description = sql.Column('description', sql.String(255),
nullable=True)
role_table.create_column(description)

View File

@ -1,15 +0,0 @@
# 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.
def upgrade(migrate_engine):
pass

View File

@ -1,34 +0,0 @@
# 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 sqlalchemy as sql
def upgrade(migrate_engine):
meta = sql.MetaData()
meta.bind = migrate_engine
limit_table = sql.Table('limit', meta, autoload=True)
domain_id = sql.Column('domain_id', sql.String(64), nullable=True)
limit_table.create_column(domain_id)
if migrate_engine.name == 'sqlite':
meta = sql.MetaData()
meta.bind = migrate_engine
# "limit_new" is the table created in 047 expand script for SQLite
# case.
try:
limit_table_new = sql.Table('limit_new', meta, autoload=True)
domain_id = sql.Column('domain_id', sql.String(64), nullable=True)
limit_table_new.create_column(domain_id)
except sql.exc.NoSuchTableError:
pass

View File

@ -1,45 +0,0 @@
# Copyright 2019 SUSE Linux GmbH
#
# 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 sqlalchemy as sql
def upgrade(migrate_engine):
meta = sql.MetaData()
meta.bind = migrate_engine
application_credential = sql.Table(
'application_credential', meta, autoload=True)
access_rule = sql.Table(
'access_rule', meta,
sql.Column('id', sql.Integer, primary_key=True, nullable=False),
sql.Column('service', sql.String(64)),
sql.Column('path', sql.String(128)),
sql.Column('method', sql.String(16)),
mysql_engine='InnoDB', mysql_charset='utf8'
)
app_cred_access_rule = sql.Table(
'application_credential_access_rule', meta,
sql.Column('application_credential_id', sql.Integer,
sql.ForeignKey(application_credential.c.internal_id,
ondelete='CASCADE'),
primary_key=True, nullable=False),
sql.Column('access_rule_id', sql.Integer,
sql.ForeignKey(access_rule.c.id,
ondelete='CASCADE'),
primary_key=True, nullable=False),
mysql_engine='InnoDB', mysql_charset='utf8'
)
access_rule.create(migrate_engine, checkfirst=True)
app_cred_access_rule.create(migrate_engine, checkfirst=True)

View File

@ -255,7 +255,6 @@ def upgrade(migrate_engine):
sql.ForeignKey(local_user.c.id, ondelete='CASCADE'),
nullable=False,
),
sql.Column('password', sql.String(128), nullable=True),
sql.Column('expires_at', sql.DateTime(), nullable=True),
sql.Column(
'self_service',
@ -463,6 +462,7 @@ def upgrade(migrate_engine):
nullable=False,
server_default='<<null>>',
),
sql.Column('description', sql.String(255), nullable=True),
migrate.UniqueConstraint(
'name',
'domain_id',
@ -753,7 +753,7 @@ def upgrade(migrate_engine):
'limit',
meta,
sql.Column('id', sql.String(length=64), nullable=False),
sql.Column('project_id', sql.String(64)),
sql.Column('project_id', sql.String(64), nullable=True),
sql.Column('service_id', sql.String(255)),
sql.Column('region_id', sql.String(64), nullable=True),
sql.Column('resource_name', sql.String(255)),
@ -767,6 +767,7 @@ def upgrade(migrate_engine):
'registered_limit_id',
sql.String(64),
),
sql.Column('domain_id', sql.String(64), nullable=True),
# NOTE(stephenfin): Name chosen to preserve backwards compatibility
# with names used for primary key unique constraints
sql.UniqueConstraint('id', name='limit_id_key'),
@ -815,6 +816,40 @@ def upgrade(migrate_engine):
mysql_charset='utf8',
)
access_rule = sql.Table(
'access_rule',
meta,
sql.Column('id', sql.Integer, primary_key=True, nullable=False),
sql.Column('service', sql.String(64)),
sql.Column('path', sql.String(128)),
sql.Column('method', sql.String(16)),
mysql_engine='InnoDB',
mysql_charset='utf8',
)
app_cred_access_rule = sql.Table(
'application_credential_access_rule',
meta,
sql.Column(
'application_credential_id',
sql.Integer,
sql.ForeignKey(
application_credential.c.internal_id, ondelete='CASCADE'
),
primary_key=True,
nullable=False,
),
sql.Column(
'access_rule_id',
sql.Integer,
sql.ForeignKey(access_rule.c.id, ondelete='CASCADE'),
primary_key=True,
nullable=False,
),
mysql_engine='InnoDB',
mysql_charset='utf8',
)
# create all tables
tables = [
credential,
@ -860,6 +895,8 @@ def upgrade(migrate_engine):
limit,
application_credential,
application_credential_role,
access_rule,
app_cred_access_rule,
]
for table in tables:

View File

@ -29,7 +29,7 @@ from keystone.i18n import _
USE_TRIGGERS = True
INITIAL_VERSION = 47
INITIAL_VERSION = 55
EXPAND_REPO = 'expand_repo'
DATA_MIGRATION_REPO = 'data_migration_repo'
CONTRACT_REPO = 'contract_repo'

View File

@ -60,7 +60,6 @@ from keystone.cmd import cli
from keystone.common import sql
from keystone.common.sql import upgrades
from keystone.credential.providers import fernet as credential_fernet
from keystone.resource.backends import base as resource_base
from keystone.tests import unit
from keystone.tests.unit import ksfixtures
from keystone.tests.unit.ksfixtures import database
@ -95,7 +94,7 @@ INITIAL_TABLE_STRUCTURE = {
'project_id', 'name',
],
'role': [
'id', 'name', 'extra', 'domain_id',
'id', 'name', 'extra', 'domain_id', 'description',
],
'service': [
'id', 'type', 'extra', 'enabled',
@ -188,7 +187,7 @@ INITIAL_TABLE_STRUCTURE = {
'failed_auth_at',
],
'password': [
'id', 'local_user_id', 'password', 'created_at', 'expires_at',
'id', 'local_user_id', 'created_at', 'expires_at',
'self_service', 'password_hash', 'created_at_int', 'expires_at_int',
],
'federated_user': [
@ -207,7 +206,7 @@ INITIAL_TABLE_STRUCTURE = {
'limit': [
'internal_id', 'id', 'project_id', 'service_id', 'region_id',
'resource_name', 'resource_limit', 'description',
'registered_limit_id',
'registered_limit_id', 'domain_id',
],
'application_credential': [
'internal_id', 'id', 'name', 'secret_hash', 'description', 'user_id',
@ -216,6 +215,12 @@ INITIAL_TABLE_STRUCTURE = {
'application_credential_role': [
'application_credential_id', 'role_id',
],
'access_rule': [
'id', 'service', 'path', 'method',
],
'application_credential_access_rule': [
'application_credential_id', 'access_rule_id',
],
}
@ -626,149 +631,6 @@ class FullMigration(MigrateBase, unit.TestCase):
upgrades.INITIAL_VERSION + 2,
)
def test_migration_053_adds_description_to_role(self):
self.expand(52)
self.migrate(52)
self.contract(52)
role_table_name = 'role'
self.assertTableColumns(
role_table_name,
['id', 'name', 'domain_id', 'extra']
)
self.expand(53)
self.migrate(53)
self.contract(53)
self.assertTableColumns(
role_table_name,
['id', 'name', 'domain_id', 'extra', 'description']
)
role_table = sqlalchemy.Table(
role_table_name, self.metadata, autoload=True
)
role = {
'id': uuid.uuid4().hex,
'name': "test",
'domain_id': resource_base.NULL_DOMAIN_ID,
'description': "This is a string"
}
role_table.insert().values(role).execute()
role_without_description = {
'id': uuid.uuid4().hex,
'name': "test1",
'domain_id': resource_base.NULL_DOMAIN_ID
}
role_table.insert().values(role_without_description).execute()
def test_migration_054_drop_old_password_column(self):
self.expand(53)
self.migrate(53)
self.contract(53)
password_table = 'password'
self.assertTableColumns(
password_table,
['id', 'local_user_id', 'password', 'password_hash',
'self_service', 'created_at_int', 'created_at', 'expires_at_int',
'expires_at']
)
self.expand(54)
self.migrate(54)
self.contract(54)
self.assertTableColumns(
password_table,
['id', 'local_user_id', 'password_hash', 'self_service',
'created_at_int', 'created_at', 'expires_at_int', 'expires_at']
)
def test_migration_055_add_domain_to_limit(self):
self.expand(54)
self.migrate(54)
self.contract(54)
limit_table_name = 'limit'
limit_table = sqlalchemy.Table(limit_table_name, self.metadata,
autoload=True)
self.assertFalse(hasattr(limit_table.c, 'domain_id'))
self.expand(55)
self.migrate(55)
self.contract(55)
self.assertTableColumns(
limit_table_name,
['id', 'project_id', 'service_id', 'region_id', 'resource_name',
'resource_limit', 'description', 'internal_id',
'registered_limit_id', 'domain_id'])
self.assertTrue(limit_table.c.project_id.nullable)
def test_migration_056_add_application_credential_access_rules(self):
self.expand(55)
self.migrate(55)
self.contract(55)
self.assertTableDoesNotExist('access_rule')
self.assertTableDoesNotExist('application_credential_access_rule')
self.expand(56)
self.migrate(56)
self.contract(56)
self.assertTableExists('access_rule')
self.assertTableExists('application_credential_access_rule')
self.assertTableColumns(
'access_rule',
['id', 'service', 'path', 'method']
)
self.assertTableColumns(
'application_credential_access_rule',
['application_credential_id', 'access_rule_id']
)
self.assertTrue(self.does_fk_exist(
'application_credential_access_rule', 'application_credential_id'))
self.assertTrue(self.does_fk_exist(
'application_credential_access_rule', 'access_rule_id'))
app_cred_table = sqlalchemy.Table(
'application_credential', self.metadata, autoload=True
)
access_rule_table = sqlalchemy.Table(
'access_rule', self.metadata, autoload=True
)
app_cred_access_rule_table = sqlalchemy.Table(
'application_credential_access_rule',
self.metadata, autoload=True
)
app_cred = {
'internal_id': 1,
'id': uuid.uuid4().hex,
'name': uuid.uuid4().hex,
'secret_hash': uuid.uuid4().hex,
'user_id': uuid.uuid4().hex,
'project_id': uuid.uuid4().hex
}
app_cred_table.insert().values(app_cred).execute()
access_rule = {
'id': 1,
'service': uuid.uuid4().hex,
'path': '/v2.1/servers',
'method': 'GET'
}
access_rule_table.insert().values(access_rule).execute()
app_cred_access_rule_rel = {
'application_credential_id': app_cred['internal_id'],
'access_rule_id': access_rule['id']
}
app_cred_access_rule_table.insert().values(
app_cred_access_rule_rel).execute()
def test_migration_062_add_trust_redelegation(self):
# ensure initial schema
self.expand(61)