Merge "sql: Squash train migrations"

This commit is contained in:
Zuul 2022-02-08 14:18:29 +00:00 committed by Gerrit Code Review
commit ee53aed658
35 changed files with 75 additions and 804 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 Stein backports. Do not use this number for new
# Train work. New Train 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 Stein backports. Do not use this number for new
# Train work. New Train 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 Stein backports. Do not use this number for new
# Train work. New Train 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 Stein backports. Do not use this number for new
# Train work. New Train 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 Stein backports. Do not use this number for new
# Train work. New Train 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,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
limit_table = sql.Table('limit', meta, autoload=True)
limit_table.c.service_id.drop()
limit_table.c.region_id.drop()
limit_table.c.resource_name.drop()

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,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.
# NOTE(morgan): there is nothing to do here, no contract action to take
# at this time
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 Stein backports. Do not use this number for new
# Train work. New Train 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 Stein backports. Do not use this number for new
# Train work. New Train 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 Stein backports. Do not use this number for new
# Train work. New Train 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 Stein backports. Do not use this number for new
# Train work. New Train 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 Stein backports. Do not use this number for new
# Train work. New Train work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,43 +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.
from oslo_serialization import jsonutils
import sqlalchemy as sql
def upgrade(migrate_engine):
meta = sql.MetaData()
meta.bind = migrate_engine
trust_table = sql.Table('trust', meta, autoload=True)
trust_list = list(trust_table.select().execute())
# Loop through all the trusts and move the redelegeated trust id out of
# extras.
for trust in trust_list:
if trust.extra is not None:
extra_dict = jsonutils.loads(trust.extra)
else:
extra_dict = {}
new_values = {}
new_values['redelegated_trust_id'] = extra_dict.pop(
'redelegated_trust_id', None)
new_values['redelegation_count'] = extra_dict.pop(
'redelegation_count', None)
new_values['extra'] = jsonutils.dumps(extra_dict)
clause = trust_table.c.id == trust.id
update = trust_table.update().where(clause).values(new_values)
migrate_engine.execute(update)

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,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.
# NOTE(morgan): there is nothing to do here, data migration for user
# resource options will occur in a future change.
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 Stein backports. Do not use this number for new
# Train work. New Train 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 Stein backports. Do not use this number for new
# Train work. New Train 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 Stein backports. Do not use this number for new
# Train work. New Train 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 Stein backports. Do not use this number for new
# Train work. New Train 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 Stein backports. Do not use this number for new
# Train work. New Train work starts after all the placeholders.
def upgrade(migrate_engine):
pass

View File

@ -1,31 +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
trust_table = sql.Table('trust', meta, autoload=True)
trust_id_column = sql.Column(
'redelegated_trust_id',
sql.String(64),
nullable=True)
count_column = sql.Column(
'redelegation_count',
sql.Integer,
nullable=True)
trust_table.create_column(trust_id_column)
trust_table.create_column(count_column)

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,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
federation_protocol_table = sql.Table(
'federation_protocol', meta, autoload=True)
remote_id_attribute = sql.Column('remote_id_attribute', sql.String(64))
federation_protocol_table.create_column(remote_id_attribute)

View File

@ -1,39 +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 migrate
import sqlalchemy as sql
def upgrade(migrate_engine):
meta = sql.MetaData()
meta.bind = migrate_engine
access_rule = sql.Table('access_rule', meta, autoload=True)
external_id = sql.Column('external_id', sql.String(64))
access_rule.create_column(external_id)
sql.Index('external_id', access_rule.c.external_id).create()
unique_constraint_id = migrate.UniqueConstraint('external_id',
table=access_rule)
unique_constraint_id.create()
user_id = sql.Column('user_id', sql.String(64))
access_rule.create_column(user_id)
sql.Index('user_id', access_rule.c.user_id).create()
unique_constraint_rule_for_user = migrate.UniqueConstraint(
'user_id', 'service', 'path', 'method',
name='duplicate_access_rule_for_user_constraint',
table=access_rule)
unique_constraint_rule_for_user.create()

View File

@ -1,51 +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
from keystone.common import sql as ks_sql
def upgrade(migrate_engine):
meta = sql.MetaData()
meta.bind = migrate_engine
role_table = sql.Table('role', meta, autoload=True)
project_table = sql.Table('project', meta, autoload=True)
role_resource_options_table = sql.Table(
'role_option',
meta,
sql.Column('role_id', sql.String(64), sql.ForeignKey(role_table.c.id,
ondelete='CASCADE'), nullable=False, primary_key=True),
sql.Column('option_id', sql.String(4), nullable=False,
primary_key=True),
sql.Column('option_value', ks_sql.JsonBlob, nullable=True),
mysql_engine='InnoDB',
mysql_charset='utf8'
)
project_resource_options_table = sql.Table(
'project_option',
meta,
sql.Column('project_id', sql.String(64),
sql.ForeignKey(project_table.c.id, ondelete='CASCADE'),
nullable=False, primary_key=True),
sql.Column('option_id', sql.String(4), nullable=False,
primary_key=True),
sql.Column('option_value', ks_sql.JsonBlob, nullable=True),
mysql_engine='InnoDB',
mysql_charset='utf8'
)
project_resource_options_table.create()
role_resource_options_table.create()

View File

@ -165,6 +165,7 @@ def upgrade(migrate_engine):
primary_key=True,
),
sql.Column('mapping_id', sql.String(64), nullable=False),
sql.Column('remote_id_attribute', sql.String(64)),
mysql_engine='InnoDB',
mysql_charset='utf8',
)
@ -333,6 +334,24 @@ def upgrade(migrate_engine):
mysql_charset='utf8',
)
project_option = sql.Table(
'project_option',
meta,
sql.Column(
'project_id',
sql.String(64),
sql.ForeignKey(project.c.id, ondelete='CASCADE'),
nullable=False,
primary_key=True,
),
sql.Column(
'option_id', sql.String(4), nullable=False, primary_key=True
),
sql.Column('option_value', ks_sql.JsonBlob, nullable=True),
mysql_engine='InnoDB',
mysql_charset='utf8',
)
# NOTE(lamt) To allow tag name to be case sensitive for MySQL, the 'name'
# column needs to use collation, which is incompatible with Postgresql.
# Using unicode to mirror nova's server tag:
@ -472,6 +491,24 @@ def upgrade(migrate_engine):
mysql_charset='utf8',
)
role_option = sql.Table(
'role_option',
meta,
sql.Column(
'role_id',
sql.String(64),
sql.ForeignKey(role.c.id, ondelete='CASCADE'),
nullable=False,
primary_key=True,
),
sql.Column(
'option_id', sql.String(4), nullable=False, primary_key=True
),
sql.Column('option_value', ks_sql.JsonBlob, nullable=True),
mysql_engine='InnoDB',
mysql_charset='utf8',
)
service = sql.Table(
'service',
meta,
@ -546,6 +583,16 @@ def upgrade(migrate_engine):
'expires_at_int',
name='duplicate_trust_constraint_expanded',
),
sql.Column(
'redelegated_trust_id',
sql.String(64),
nullable=True,
),
sql.Column(
'redelegation_count',
sql.Integer,
nullable=True,
),
mysql_engine='InnoDB',
mysql_charset='utf8',
)
@ -754,9 +801,6 @@ def upgrade(migrate_engine):
meta,
sql.Column('id', sql.String(length=64), nullable=False),
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)),
sql.Column('resource_limit', sql.Integer, nullable=False),
sql.Column('description', sql.Text),
sql.Column('internal_id', sql.Integer, primary_key=True),
@ -823,6 +867,21 @@ def upgrade(migrate_engine):
sql.Column('service', sql.String(64)),
sql.Column('path', sql.String(128)),
sql.Column('method', sql.String(16)),
sql.Column('external_id', sql.String(64)),
sql.Column('user_id', sql.String(64)),
sql.UniqueConstraint(
'external_id',
name='access_rule_external_id_key',
),
sql.UniqueConstraint(
'user_id',
'service',
'path',
'method',
name='duplicate_access_rule_for_user_constraint',
),
sql.Index('user_id', 'user_id'),
sql.Index('external_id', 'external_id'),
mysql_engine='InnoDB',
mysql_charset='utf8',
)
@ -857,8 +916,10 @@ def upgrade(migrate_engine):
group,
policy,
project,
project_option,
project_tag,
role,
role_option,
service,
token,
trust,

View File

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

View File

@ -39,10 +39,8 @@ For further information, see `oslo.db documentation
all data will be lost.
"""
import datetime
import glob
import os
import uuid
import fixtures
from migrate.versioning import script
@ -51,7 +49,6 @@ from oslo_db.sqlalchemy import enginefacade
from oslo_db.sqlalchemy import test_fixtures as db_fixtures
from oslo_log import fixture as log_fixture
from oslo_log import log
from oslo_serialization import jsonutils
from oslotest import base as test_base
import sqlalchemy.exc
from sqlalchemy import inspect
@ -90,12 +87,18 @@ INITIAL_TABLE_STRUCTURE = {
'id', 'name', 'extra', 'description', 'enabled', 'domain_id',
'parent_id', 'is_domain',
],
'project_option': [
'project_id', 'option_id', 'option_value',
],
'project_tag': [
'project_id', 'name',
],
'role': [
'id', 'name', 'extra', 'domain_id', 'description',
],
'role_option': [
'role_id', 'option_id', 'option_value',
],
'service': [
'id', 'type', 'extra', 'enabled',
],
@ -105,7 +108,7 @@ INITIAL_TABLE_STRUCTURE = {
'trust': [
'id', 'trustor_user_id', 'trustee_user_id', 'project_id',
'impersonation', 'deleted_at', 'expires_at', 'remaining_uses', 'extra',
'expires_at_int',
'expires_at_int', 'redelegated_trust_id', 'redelegation_count',
],
'trust_role': [
'trust_id', 'role_id',
@ -142,7 +145,7 @@ INITIAL_TABLE_STRUCTURE = {
'id', 'enabled', 'description', 'domain_id',
],
'federation_protocol': [
'id', 'idp_id', 'mapping_id',
'id', 'idp_id', 'mapping_id', 'remote_id_attribute',
],
'mapping': [
'id', 'rules',
@ -204,8 +207,7 @@ INITIAL_TABLE_STRUCTURE = {
'default_limit', 'description',
],
'limit': [
'internal_id', 'id', 'project_id', 'service_id', 'region_id',
'resource_name', 'resource_limit', 'description',
'internal_id', 'id', 'project_id', 'resource_limit', 'description',
'registered_limit_id', 'domain_id',
],
'application_credential': [
@ -216,7 +218,7 @@ INITIAL_TABLE_STRUCTURE = {
'application_credential_id', 'role_id',
],
'access_rule': [
'id', 'service', 'path', 'method',
'id', 'service', 'path', 'method', 'external_id', 'user_id',
],
'application_credential_access_rule': [
'application_credential_id', 'access_rule_id',
@ -631,177 +633,6 @@ class FullMigration(MigrateBase, unit.TestCase):
upgrades.INITIAL_VERSION + 2,
)
def test_migration_062_add_trust_redelegation(self):
# ensure initial schema
self.expand(61)
self.migrate(61)
self.contract(61)
self.assertTableColumns('trust', ['id',
'trustor_user_id',
'trustee_user_id',
'project_id',
'impersonation',
'expires_at',
'expires_at_int',
'remaining_uses',
'deleted_at',
'extra'])
# fixture
trust = {
'id': uuid.uuid4().hex,
'trustor_user_id': uuid.uuid4().hex,
'trustee_user_id': uuid.uuid4().hex,
'project_id': uuid.uuid4().hex,
'impersonation': True,
'expires_at': datetime.datetime.now(),
'remaining_uses': 10,
'deleted_at': datetime.datetime.now(),
'redelegated_trust_id': uuid.uuid4().hex,
'redelegation_count': 3,
'other': uuid.uuid4().hex
}
old_trust = trust.copy()
old_extra = {
'redelegated_trust_id': old_trust.pop('redelegated_trust_id'),
'redelegation_count': old_trust.pop('redelegation_count'),
'other': old_trust.pop('other')
}
old_trust['extra'] = jsonutils.dumps(old_extra)
# load fixture
session = self.sessionmaker()
self.insert_dict(session, 'trust', old_trust)
# ensure redelegation data is in extra
stored_trust = list(
session.execute(self.load_table('trust').select())
)[0]
self.assertDictEqual({
'redelegated_trust_id': trust['redelegated_trust_id'],
'redelegation_count': trust['redelegation_count'],
'other': trust['other']},
jsonutils.loads(stored_trust.extra))
# upgrade and ensure expected schema
self.expand(62)
self.migrate(62)
self.contract(62)
self.assertTableColumns('trust', ['id',
'trustor_user_id',
'trustee_user_id',
'project_id',
'impersonation',
'expires_at',
'expires_at_int',
'remaining_uses',
'deleted_at',
'redelegated_trust_id',
'redelegation_count',
'extra'])
trust_table = sqlalchemy.Table('trust', self.metadata, autoload=True)
self.assertTrue(trust_table.c.redelegated_trust_id.nullable)
self.assertTrue(trust_table.c.redelegation_count.nullable)
# test target data layout
upgraded_trust = list(
session.execute(self.load_table('trust').select())
)[0]
self.assertDictEqual({'other': trust['other']},
jsonutils.loads(upgraded_trust.extra))
self.assertEqual(trust['redelegated_trust_id'],
upgraded_trust.redelegated_trust_id)
self.assertEqual(trust['redelegation_count'],
upgraded_trust.redelegation_count)
def test_migration_063_drop_limit_columns(self):
self.expand(62)
self.migrate(62)
self.contract(62)
limit_table = 'limit'
self.assertTableColumns(
limit_table,
['id', 'project_id', 'service_id', 'region_id', 'resource_name',
'resource_limit', 'description', 'internal_id',
'registered_limit_id', 'domain_id'])
self.expand(63)
self.migrate(63)
self.contract(63)
self.assertTableColumns(
limit_table,
['id', 'project_id', 'resource_limit', 'description',
'internal_id', 'registered_limit_id', 'domain_id'])
def test_migration_064_add_remote_id_attribute_federation_protocol(self):
self.expand(63)
self.migrate(63)
self.contract(63)
federation_protocol_table_name = 'federation_protocol'
self.assertTableColumns(
federation_protocol_table_name,
['id', 'idp_id', 'mapping_id']
)
self.expand(64)
self.migrate(64)
self.contract(64)
self.assertTableColumns(
federation_protocol_table_name,
['id', 'idp_id', 'mapping_id', 'remote_id_attribute']
)
def test_migration_065_add_user_external_id_to_access_rule(self):
self.expand(64)
self.migrate(64)
self.contract(64)
self.assertTableColumns(
'access_rule',
['id', 'service', 'path', 'method']
)
self.expand(65)
self.migrate(65)
self.contract(65)
self.assertTableColumns(
'access_rule',
['id', 'external_id', 'user_id', 'service', 'path', 'method']
)
self.assertTrue(self.does_index_exist('access_rule', 'external_id'))
self.assertTrue(self.does_index_exist('access_rule', 'user_id'))
self.assertTrue(self.does_unique_constraint_exist(
'access_rule', 'external_id'))
self.assertTrue(self.does_unique_constraint_exist(
'access_rule', ['user_id', 'service', 'path', 'method']))
def test_migration_066_add_role_and_project_options_tables(self):
self.expand(65)
self.migrate(65)
self.contract(65)
role_option = 'role_option'
project_option = 'project_option'
self.assertTableDoesNotExist(role_option)
self.assertTableDoesNotExist(project_option)
self.expand(66)
self.migrate(66)
self.contract(66)
self.assertTableColumns(
project_option,
['project_id', 'option_id', 'option_value'])
self.assertTableColumns(
role_option,
['role_id', 'option_id', 'option_value'])
def test_migration_072_drop_domain_id_fk(self):
self.expand(71)
self.migrate(71)