db schema improvements: uuid consistency

Validate the id format is always uuid4 format.

Foreign key length does not matches with reference table
column lenght and this ptach fixes this issue.

Closes-bug: #1587579
Change-Id: I95377e8ada45f90b4cc78f738ba1b2147afa8268
This commit is contained in:
Kanagaraj Manickam 2016-05-27 17:50:04 +05:30
parent e6d787ba2a
commit 7fe9e48f0d
6 changed files with 104 additions and 20 deletions

View File

@ -1 +1 @@
acf941e54075
f958f58e5daa

View File

@ -0,0 +1,55 @@
# Copyright 2016 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.
#
"""uuid consistency
Revision ID: f958f58e5daa
Revises: acf941e54075
Create Date: 2016-05-28 07:13:07.125562
"""
# revision identifiers, used by Alembic.
revision = 'f958f58e5daa'
down_revision = 'acf941e54075'
from alembic import op
from tacker.db import types
def upgrade(active_plugins=None, options=None):
for table in ['vims', 'vimauths', 'devices', 'deviceattributes',
'servicetypes', 'devicetemplates',
'devicetemplateattributes']:
op.alter_column(table,
'id',
type_=types.Uuid)
for table in ['devices', 'servicetypes', 'devicetemplateattributes']:
op.alter_column(table,
'template_id',
type_=types.Uuid)
for table in ['devices', 'vimauths']:
op.alter_column(table,
'vim_id',
type_=types.Uuid)
for table in ['deviceattributes', 'proxymgmtports']:
op.alter_column(table,
'device_id',
type_=types.Uuid)

View File

@ -15,6 +15,7 @@
import sqlalchemy as sa
from tacker.db import types
from tacker.openstack.common import uuidutils
@ -28,6 +29,6 @@ class HasTenant(object):
class HasId(object):
"""id mixin, add to subclasses that have an id."""
id = sa.Column(sa.String(36),
id = sa.Column(types.Uuid,
primary_key=True,
default=uuidutils.generate_uuid)

View File

@ -25,10 +25,10 @@ from sqlalchemy import sql
from tacker.db import db_base
from tacker.db import model_base
from tacker.db import models_v1
from tacker.db import types
from tacker.db.vm import vm_db
from tacker.extensions import nfvo
from tacker import manager
from tacker.openstack.common import uuidutils
VIM_ATTRIBUTES = ('id', 'type', 'tenant_id', 'name', 'description',
@ -36,12 +36,8 @@ VIM_ATTRIBUTES = ('id', 'type', 'tenant_id', 'name', 'description',
VIM_AUTH_ATTRIBUTES = ('auth_url', 'vim_project', 'password', 'auth_cred')
class Vim(model_base.BASE, models_v1.HasTenant):
id = sa.Column(sa.String(255),
primary_key=True,
default=uuidutils.generate_uuid)
class Vim(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
type = sa.Column(sa.String(255), nullable=False)
tenant_id = sa.Column(sa.String(255), nullable=True)
name = sa.Column(sa.String(255), nullable=True)
description = sa.Column(sa.String(255), nullable=True)
placement_attr = sa.Column(sa.PickleType, nullable=True)
@ -51,7 +47,7 @@ class Vim(model_base.BASE, models_v1.HasTenant):
class VimAuth(model_base.BASE, models_v1.HasId):
vim_id = sa.Column(sa.String(255), sa.ForeignKey('vims.id'),
vim_id = sa.Column(types.Uuid, sa.ForeignKey('vims.id'),
nullable=False)
password = sa.Column(sa.String(128), nullable=False)
auth_url = sa.Column(sa.String(255), nullable=False)

36
tacker/db/types.py Normal file
View File

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# 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 uuid
from sqlalchemy.types import String
from sqlalchemy.types import TypeDecorator
class Uuid(TypeDecorator):
impl = String(36)
def process_bind_param(self, value, dialect):
if value is not None:
try:
uuid.UUID(value, version=4)
except ValueError:
raise ValueError(
"Invalid format. It should be in UUID v4 format")
return value
def process_result_value(self, value, dialect):
return value

View File

@ -26,9 +26,9 @@ from tacker import context as t_context
from tacker.db import db_base
from tacker.db import model_base
from tacker.db import models_v1
from tacker.db import types
from tacker.extensions import vnfm
from tacker import manager
from tacker.openstack.common import uuidutils
from tacker.plugins.common import constants
LOG = logging.getLogger(__name__)
@ -71,7 +71,7 @@ class ServiceType(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
Since a device may provide many services, This is one-to-many
relationship.
"""
template_id = sa.Column(sa.String(36), sa.ForeignKey('devicetemplates.id'),
template_id = sa.Column(types.Uuid, sa.ForeignKey('devicetemplates.id'),
nullable=False)
service_type = sa.Column(sa.String(255), nullable=False)
@ -83,23 +83,19 @@ class DeviceTemplateAttribute(model_base.BASE, models_v1.HasId):
like nova, heat or others. e.g. image-id, flavor-id for Nova.
The interpretation is up to actual driver of hosting device.
"""
template_id = sa.Column(sa.String(36), sa.ForeignKey('devicetemplates.id'),
template_id = sa.Column(types.Uuid, sa.ForeignKey('devicetemplates.id'),
nullable=False)
key = sa.Column(sa.String(255), nullable=False)
value = sa.Column(sa.TEXT(65535), nullable=True)
class Device(model_base.BASE, models_v1.HasTenant):
class Device(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
"""Represents devices that hosts services.
Here the term, 'VM', is intentionally avoided because it can be
VM or other container.
"""
id = sa.Column(sa.String(255),
primary_key=True,
default=uuidutils.generate_uuid)
template_id = sa.Column(sa.String(36), sa.ForeignKey('devicetemplates.id'))
template_id = sa.Column(types.Uuid, sa.ForeignKey('devicetemplates.id'))
template = orm.relationship('DeviceTemplate')
name = sa.Column(sa.String(255), nullable=True)
@ -116,7 +112,7 @@ class Device(model_base.BASE, models_v1.HasTenant):
attributes = orm.relationship("DeviceAttribute", backref="device")
status = sa.Column(sa.String(255), nullable=False)
vim_id = sa.Column(sa.String(36), sa.ForeignKey('vims.id'), nullable=False)
vim_id = sa.Column(types.Uuid, sa.ForeignKey('vims.id'), nullable=False)
placement_attr = sa.Column(sa.PickleType, nullable=True)
vim = orm.relationship('Vim')
error_reason = sa.Column(sa.Text, nullable=True)
@ -129,7 +125,7 @@ class DeviceAttribute(model_base.BASE, models_v1.HasId):
like nova, heat or others. e.g. image-id, flavor-id for Nova.
The interpretation is up to actual driver of hosting device.
"""
device_id = sa.Column(sa.String(255), sa.ForeignKey('devices.id'),
device_id = sa.Column(types.Uuid, sa.ForeignKey('devices.id'),
nullable=False)
key = sa.Column(sa.String(255), nullable=False)
# json encoded value. example