From d28469e6fde030fc3f405f0e198227f3b7bbcdaf Mon Sep 17 00:00:00 2001 From: Luka Peschke Date: Tue, 30 Oct 2018 10:36:58 +0100 Subject: [PATCH] Make tenant_id a string in hashmap models Since scopes are now configurable, the scope_id (tenant_id in hashmap models) is not necessarily a uuid anymore. This updates the "mapping" and "threshold" models of the hashmap module in order to remove uuid validation for the "tenant_id" field. Work items: * Changed the WSME type of tenant_id from Uuid to String * Added an alembic migration in order to increase the length of tenant_id from 36 to 255. Change-Id: If7dfb82e523ca045c1f266396bc6e01406823f11 Story: 2004200 Task: 27703 --- cloudkitty/rating/hash/datamodels/mapping.py | 6 +- .../rating/hash/datamodels/threshold.py | 6 +- ...update_tenant_id_type_from_uuid_to_text.py | 97 +++++++++++++++++++ .../rating/hash/db/sqlalchemy/models.py | 4 +- 4 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 cloudkitty/rating/hash/db/sqlalchemy/alembic/versions/644faa4491fd_update_tenant_id_type_from_uuid_to_text.py diff --git a/cloudkitty/rating/hash/datamodels/mapping.py b/cloudkitty/rating/hash/datamodels/mapping.py index 0a1c56fa..10925b7a 100644 --- a/cloudkitty/rating/hash/datamodels/mapping.py +++ b/cloudkitty/rating/hash/datamodels/mapping.py @@ -56,10 +56,8 @@ class Mapping(wtypes.Base): mandatory=False) """UUID of the hashmap group.""" - tenant_id = wtypes.wsattr(ck_types.UuidType(), - mandatory=False, - default=None) - """UUID of the hashmap tenant.""" + tenant_id = wtypes.wsattr(wtypes.text, mandatory=False, default=None) + """ID of the hashmap tenant.""" @classmethod def sample(cls): diff --git a/cloudkitty/rating/hash/datamodels/threshold.py b/cloudkitty/rating/hash/datamodels/threshold.py index 182668d8..e8ec1dee 100644 --- a/cloudkitty/rating/hash/datamodels/threshold.py +++ b/cloudkitty/rating/hash/datamodels/threshold.py @@ -59,10 +59,8 @@ class Threshold(wtypes.Base): mandatory=False) """UUID of the hashmap group.""" - tenant_id = wtypes.wsattr(ck_types.UuidType(), - mandatory=False, - default=None) - """UUID of the hashmap tenant.""" + tenant_id = wtypes.wsattr(wtypes.text, mandatory=False, default=None) + """ID of the hashmap tenant.""" @classmethod def sample(cls): diff --git a/cloudkitty/rating/hash/db/sqlalchemy/alembic/versions/644faa4491fd_update_tenant_id_type_from_uuid_to_text.py b/cloudkitty/rating/hash/db/sqlalchemy/alembic/versions/644faa4491fd_update_tenant_id_type_from_uuid_to_text.py new file mode 100644 index 00000000..1dfdfd1e --- /dev/null +++ b/cloudkitty/rating/hash/db/sqlalchemy/alembic/versions/644faa4491fd_update_tenant_id_type_from_uuid_to_text.py @@ -0,0 +1,97 @@ +# Copyright 2018 OpenStack Foundation +# +# 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. +# + +"""Update tenant_id type from uuid to text + +Revision ID: 644faa4491fd +Revises: 4da82e1c11c8 +Create Date: 2018-10-29 17:25:37.901136 + +""" + +# revision identifiers, used by Alembic. +revision = '644faa4491fd' +down_revision = '4da82e1c11c8' + +from alembic import op +import sqlalchemy as sa + + +CONSTRAINT_MAP = { + 'hashmap_mappings': { + u'uniq_field_mapping': ( + ['value', 'field_id', 'tenant_id'], + ['value', 'field_id']), + u'uniq_service_mapping': ( + ['value', 'service_id', 'tenant_id'], + ['value', 'service_id'])}, + 'hashmap_thresholds': { + u'uniq_field_threshold': ( + ['level', 'field_id', 'tenant_id'], + ['level', 'field_id']), + u'uniq_service_threshold': ( + ['level', 'service_id', 'tenant_id'], + ['level', 'service_id'])}} + + +def get_reflect(table): + reflect_args = [ + sa.Column( + 'service_id', + sa.Integer, + sa.ForeignKey( + 'hashmap_services.id', + ondelete='CASCADE', + name='fk_{}_service_id_hashmap_services'.format(table)), + nullable=True), + sa.Column( + 'field_id', + sa.Integer, + sa.ForeignKey( + 'hashmap_fields.id', + ondelete='CASCADE', + name='fk_{}_field_id_hashmap_fields'.format(table)), + nullable=True), + sa.Column( + 'group_id', + sa.Integer, + sa.ForeignKey( + 'hashmap_groups.id', + ondelete='SET NULL', + name='fk_{}_group_id_hashmap_groups'.format(table)), + nullable=True), + sa.Column( + 'map_type', + sa.Enum( + 'flat', + 'rate', + name='enum_{}map_type'.format( + 'hash' if table == 'hashmap_thresholds' else '')), + nullable=False)] + return reflect_args + + +def upgrade(): + for table in ('hashmap_mappings', 'hashmap_thresholds'): + with op.batch_alter_table( + table, + reflect_args=get_reflect(table) + ) as batch_op: + batch_op.alter_column('tenant_id', + type_=sa.String(length=255), + existing_nullable=True) + for name, columns in CONSTRAINT_MAP[table].items(): + batch_op.drop_constraint(name, type_='unique') + batch_op.create_unique_constraint(name, columns[0]) diff --git a/cloudkitty/rating/hash/db/sqlalchemy/models.py b/cloudkitty/rating/hash/db/sqlalchemy/models.py index bd009a7c..c4b1d0c1 100644 --- a/cloudkitty/rating/hash/db/sqlalchemy/models.py +++ b/cloudkitty/rating/hash/db/sqlalchemy/models.py @@ -259,7 +259,7 @@ class HashMapMapping(Base, HashMapBase): ondelete='SET NULL'), nullable=True) tenant_id = sqlalchemy.Column( - sqlalchemy.String(36), + sqlalchemy.String(255), nullable=True) def __repr__(self): @@ -338,7 +338,7 @@ class HashMapThreshold(Base, HashMapBase): ondelete='SET NULL'), nullable=True) tenant_id = sqlalchemy.Column( - sqlalchemy.String(36), + sqlalchemy.String(255), nullable=True) def __repr__(self):