From 156d9bfe47d822db05a380f15b9054268ce8d4e2 Mon Sep 17 00:00:00 2001 From: Niraj Singh Date: Mon, 3 Jun 2019 09:25:23 +0000 Subject: [PATCH] Add DB script and models for vnf packages * Added a new db script to add new db tables needed for vnf packages. * Added new db models for vnf packages. Partial-Implements: blueprint tosca-csar-mgmt-driver Co-Author: Neha Alhat Change-Id: Ib754c6cab2de5ffb8932ef66e7c17bd20e34c16b --- tacker/context.py | 11 ++ tacker/db/db_sqlalchemy/__init__.py | 0 tacker/db/db_sqlalchemy/api.py | 56 +++++++ tacker/db/db_sqlalchemy/models.py | 146 +++++++++++++++++ .../versions/9d425296f2c3_add_vnfpkgm_db.py | 150 ++++++++++++++++++ .../alembic_migrations/versions/HEAD | 2 +- 6 files changed, 364 insertions(+), 1 deletion(-) create mode 100644 tacker/db/db_sqlalchemy/__init__.py create mode 100644 tacker/db/db_sqlalchemy/api.py create mode 100644 tacker/db/db_sqlalchemy/models.py create mode 100644 tacker/db/migration/alembic_migrations/versions/9d425296f2c3_add_vnfpkgm_db.py diff --git a/tacker/context.py b/tacker/context.py index 177368f58..9d99d1695 100644 --- a/tacker/context.py +++ b/tacker/context.py @@ -177,6 +177,17 @@ def get_admin_context_without_session(): is_admin=True) +def is_user_context(context): + """Indicates if the request context is a normal user.""" + if not context: + return False + if context.is_admin: + return False + if not context.user_id or not context.project_id: + return False + return True + + def generate_tacker_service_context(): return keystone_password.KeystonePassword( password=CONF.keystone_authtoken.password, diff --git a/tacker/db/db_sqlalchemy/__init__.py b/tacker/db/db_sqlalchemy/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tacker/db/db_sqlalchemy/api.py b/tacker/db/db_sqlalchemy/api.py new file mode 100644 index 000000000..2febbdc44 --- /dev/null +++ b/tacker/db/db_sqlalchemy/api.py @@ -0,0 +1,56 @@ +# Copyright (C) 2019 NTT DATA +# All Rights Reserved. +# +# 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_db.sqlalchemy import utils as sqlalchemyutils + +import tacker.context + + +def model_query(context, model, args=None, read_deleted=None, + project_only=False): + """Query helper that accounts for context's `read_deleted` field. + + :param context: TackerContext of the query. + :param model: Model to query. Must be a subclass of ModelBase. + :param args: Arguments to query. If None - model is used. + :param read_deleted: If not None, overrides context's read_deleted field. + Permitted values are 'no', which does not return + deleted values; 'only', which only returns deleted + values; and 'yes', which does not filter deleted + values. + :param project_only: If set and context is user-type, then restrict + query to match the context's project_id. If set to + 'allow_none', restriction includes project_id = None. + """ + + query_kwargs = {} + if read_deleted: + if 'no' == read_deleted: + query_kwargs['deleted'] = False + elif 'only' == read_deleted: + query_kwargs['deleted'] = True + elif 'yes' == read_deleted: + pass + else: + raise ValueError(_("Unrecognized read_deleted value '%s'") + % read_deleted) + + query = sqlalchemyutils.model_query( + model, context.session, args, **query_kwargs) + + if tacker.context.is_user_context(context) and project_only: + query = query.filter_by(tenant_id=context.project_id) + + return query diff --git a/tacker/db/db_sqlalchemy/models.py b/tacker/db/db_sqlalchemy/models.py new file mode 100644 index 000000000..23c97a50d --- /dev/null +++ b/tacker/db/db_sqlalchemy/models.py @@ -0,0 +1,146 @@ +# Copyright (C) 2019 NTT DATA +# All Rights Reserved. +# +# 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_db.sqlalchemy import models +import sqlalchemy as sa +from sqlalchemy import orm + +from tacker.db import model_base +from tacker.db import models_v1 +from tacker.db import types + + +class VnfPackageUserData(model_base.BASE, models.SoftDeleteMixin, + models.TimestampMixin): + """Contains all info about vnf packages UserDefinedData.""" + + __tablename__ = 'vnf_packages_user_data' + id = sa.Column(sa.Integer, nullable=False, primary_key=True) + package_uuid = sa.Column(sa.String(36), + sa.ForeignKey('vnf_packages.id'), + nullable=False) + key = sa.Column(sa.String(255), nullable=False) + value = sa.Column(sa.String(255), nullable=False) + + +class VnfSoftwareImageMetadata(model_base.BASE, models.SoftDeleteMixin, + models.TimestampMixin): + """Contains all info about vnf packages software image metadata.""" + + __tablename__ = 'vnf_software_image_metadata' + id = sa.Column(sa.Integer, nullable=False, primary_key=True) + image_uuid = sa.Column(sa.String(36), + sa.ForeignKey('vnf_software_images.id'), + nullable=False) + key = sa.Column(sa.String(255), nullable=False) + value = sa.Column(sa.String(255), nullable=False) + + +class VnfSoftwareImage(model_base.BASE, models.SoftDeleteMixin, + models.TimestampMixin, models_v1.HasId): + """Contains all info about vnf packages software images.""" + + __tablename__ = 'vnf_software_images' + software_image_id = sa.Column(sa.Integer, nullable=False) + flavour_uuid = sa.Column(sa.String(36), sa.ForeignKey( + 'vnf_deployment_flavours.id'), nullable=False) + name = sa.Column(sa.String(255), nullable=True) + provider = sa.Column(sa.String(255), nullable=True) + version = sa.Column(sa.String(255), nullable=True) + algorithm = sa.Column(sa.String(64), nullable=True) + hash = sa.Column(sa.String(128), nullable=True) + container_format = sa.Column(sa.String(20), nullable=True) + disk_format = sa.Column(sa.String(20), nullable=True) + min_disk = sa.Column(sa.Integer, nullable=False) + min_ram = sa.Column(sa.Integer, nullable=False) + size = sa.Column(sa.BigInteger, nullable=False) + image_path = sa.Column(sa.Text, nullable=False) + + _metadata = orm.relationship( + VnfSoftwareImageMetadata, + primaryjoin='and_(VnfSoftwareImage.id == ' + 'VnfSoftwareImageMetadata.image_uuid)') + + @property + def metadetails(self): + return {m.key: m.value for m in self._metadata} + + +class VnfDeploymentFlavour(model_base.BASE, models.SoftDeleteMixin, + models.TimestampMixin, models_v1.HasId): + """Contains all info about vnf packages Deployment Flavours.""" + + __tablename__ = 'vnf_deployment_flavours' + package_uuid = sa.Column(sa.String(36), + sa.ForeignKey('vnf_packages.id'), + nullable=False) + flavour_id = sa.Column(sa.String(255), nullable=False) + flavour_description = sa.Column(sa.Text(), nullable=False) + instantiation_levels = sa.Column(sa.Text(), nullable=True) + + software_images = orm.relationship( + VnfSoftwareImage, primaryjoin='and_(VnfDeploymentFlavour.id == ' + 'VnfSoftwareImage.flavour_uuid,' + 'VnfSoftwareImage.deleted == 0)') + + +class VnfPackageVnfd(model_base.BASE, models.SoftDeleteMixin, + models.TimestampMixin, models_v1.HasId): + """Contains all info about vnf packages VNFD.""" + + __tablename__ = 'vnf_package_vnfd' + package_uuid = sa.Column(sa.String(36), + sa.ForeignKey('vnf_packages.id'), + nullable=False) + vnfd_id = sa.Column(types.Uuid, nullable=False) + vnf_provider = sa.Column(sa.String(255), nullable=False) + vnf_product_name = sa.Column(sa.String(255), nullable=False) + vnf_software_version = sa.Column(sa.String(255), nullable=False) + vnfd_version = sa.Column(sa.String(255), nullable=False) + + +class VnfPackage(model_base.BASE, models.SoftDeleteMixin, + models.TimestampMixin, models_v1.HasTenant, + models_v1.HasId): + """Contains all info about vnf packages.""" + + __tablename__ = 'vnf_packages' + onboarding_state = sa.Column(sa.String(255), nullable=False) + operational_state = sa.Column(sa.String(255), nullable=False) + usage_state = sa.Column(sa.String(255), nullable=False) + algorithm = sa.Column(sa.String(64), nullable=True) + hash = sa.Column(sa.String(128), nullable=True) + location_glance_store = sa.Column(sa.Text(), nullable=True) + + _metadata = orm.relationship( + VnfPackageUserData, + primaryjoin='and_(VnfPackage.id == ' + 'VnfPackageUserData.package_uuid)') + + vnf_deployment_flavours = orm.relationship( + VnfDeploymentFlavour, + primaryjoin='and_(VnfPackage.id == ' + 'VnfDeploymentFlavour.package_uuid,' + 'VnfDeploymentFlavour.deleted == 0)') + + vnfd = orm.relationship( + VnfPackageVnfd, uselist=False, + primaryjoin='and_(VnfPackage.id == ' + 'VnfPackageVnfd.package_uuid,' + 'VnfPackageVnfd.deleted == 0)') + + @property + def metadetails(self): + return {m.key: m.value for m in self._metadata} diff --git a/tacker/db/migration/alembic_migrations/versions/9d425296f2c3_add_vnfpkgm_db.py b/tacker/db/migration/alembic_migrations/versions/9d425296f2c3_add_vnfpkgm_db.py new file mode 100644 index 000000000..cac517e59 --- /dev/null +++ b/tacker/db/migration/alembic_migrations/versions/9d425296f2c3_add_vnfpkgm_db.py @@ -0,0 +1,150 @@ +# Copyright (C) 2019 NTT DATA +# All Rights Reserved. +# +# 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. + +"""empty message + +Revision ID: 9d425296f2c3 +Revises: cd04a8335c18 +Create Date: 2019-06-03 08:37:05.095587 + +""" + +# revision identifiers, used by Alembic. +revision = '9d425296f2c3' +down_revision = 'cd04a8335c18' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy import Boolean + +from tacker.db import types + + +def upgrade(active_plugins=None, options=None): + op.create_table( + 'vnf_packages', + sa.Column('id', types.Uuid(length=36), nullable=False), + sa.Column('onboarding_state', sa.String(length=255), nullable=False), + sa.Column('operational_state', sa.String(length=255), nullable=False), + sa.Column('usage_state', sa.String(length=255), nullable=False), + sa.Column('tenant_id', sa.String(length=64), nullable=False), + sa.Column('algorithm', sa.String(length=64), nullable=True), + sa.Column('hash', sa.String(length=128), nullable=True), + sa.Column('location_glance_store', sa.Text(), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=True), + sa.Column('deleted_at', sa.DateTime(), nullable=True), + sa.Column('deleted', Boolean, default=False), + sa.PrimaryKeyConstraint('id'), + mysql_engine='InnoDB' + ) + op.create_table( + 'vnf_packages_user_data', + sa.Column('id', sa.Integer, nullable=False, autoincrement=True), + sa.Column('package_uuid', types.Uuid(length=36), nullable=False), + sa.Column('key', sa.String(length=255), nullable=False), + sa.Column('value', sa.String(length=255), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=True), + sa.Column('deleted_at', sa.DateTime(), nullable=True), + sa.Column('deleted', Boolean, default=False), + sa.PrimaryKeyConstraint('id'), + sa.ForeignKeyConstraint(['package_uuid'], + ['vnf_packages.id'], ), + sa.Index('vnf_packages_user_data_key_idx', 'key'), + sa.Index('vnf_packages_user_data_value_idx', 'value'), + sa.UniqueConstraint('id', 'key', 'deleted', + name='uniq_vnf_packages_user_data0idid0key0deleted'), + mysql_engine='InnoDB' + ) + op.create_table( + 'vnf_package_vnfd', + sa.Column('id', types.Uuid(length=36), nullable=False), + sa.Column('package_uuid', types.Uuid(length=36), nullable=False), + sa.Column('vnfd_id', types.Uuid(length=36), nullable=False), + sa.Column('vnf_provider', sa.String(length=255), nullable=False), + sa.Column('vnf_product_name', sa.String(length=255), nullable=False), + sa.Column('vnf_software_version', sa.String(length=255), + nullable=False), + sa.Column('vnfd_version', sa.String(length=255), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=True), + sa.Column('deleted_at', sa.DateTime(), nullable=True), + sa.Column('deleted', Boolean, default=False), + sa.PrimaryKeyConstraint('id'), + sa.ForeignKeyConstraint(['package_uuid'], + ['vnf_packages.id'], ), + mysql_engine='InnoDB' + ) + op.create_table( + 'vnf_deployment_flavours', + sa.Column('id', types.Uuid(length=36), nullable=False), + sa.Column('package_uuid', types.Uuid(length=36), nullable=False), + sa.Column('flavour_id', sa.String(length=255), nullable=False), + sa.Column('flavour_description', sa.Text(), nullable=False), + sa.Column('instantiation_levels', sa.Text(), nullable=True), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=True), + sa.Column('deleted_at', sa.DateTime(), nullable=True), + sa.Column('deleted', Boolean, default=False), + sa.PrimaryKeyConstraint('id'), + sa.ForeignKeyConstraint(['package_uuid'], + ['vnf_packages.id'], ), + mysql_engine='InnoDB' + ) + op.create_table( + 'vnf_software_images', + sa.Column('id', types.Uuid(length=36), nullable=False), + sa.Column('software_image_id', sa.String(length=255), nullable=False), + sa.Column('flavour_uuid', types.Uuid(length=36), nullable=False), + sa.Column('name', sa.String(length=255), nullable=False), + sa.Column('provider', sa.String(length=255), nullable=False), + sa.Column('version', sa.String(length=255), nullable=False), + sa.Column('algorithm', sa.String(length=64), nullable=False), + sa.Column('hash', sa.String(length=128), nullable=False), + sa.Column('container_format', sa.String(length=20), nullable=False), + sa.Column('disk_format', sa.String(length=20), nullable=False), + sa.Column('min_disk', sa.Integer, nullable=False), + sa.Column('min_ram', sa.Integer, nullable=False), + sa.Column('size', sa.BigInteger, nullable=False), + sa.Column('image_path', sa.Text(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=True), + sa.Column('deleted_at', sa.DateTime(), nullable=True), + sa.Column('deleted', Boolean, default=False), + sa.PrimaryKeyConstraint('id'), + sa.ForeignKeyConstraint(['flavour_uuid'], + ['vnf_deployment_flavours.id'], ), + mysql_engine='InnoDB' + ) + op.create_table( + 'vnf_software_image_metadata', + sa.Column('id', sa.Integer, nullable=False, autoincrement=True), + sa.Column('image_uuid', types.Uuid(length=36), nullable=False), + sa.Column('key', sa.String(length=255), nullable=False), + sa.Column('value', sa.String(length=255), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=True), + sa.Column('deleted_at', sa.DateTime(), nullable=True), + sa.Column('deleted', Boolean, default=False), + sa.PrimaryKeyConstraint('id'), + sa.ForeignKeyConstraint(['image_uuid'], + ['vnf_software_images.id'], ), + sa.Index('vnf_software_image_metadata_key_idx', 'key'), + sa.Index('vnf_software_image_metadata_value_idx', 'value'), + sa.UniqueConstraint('id', 'key', 'deleted', + name='uniq_vnf_software_image_metadata0idid0key0deleted'), + mysql_engine='InnoDB' + ) diff --git a/tacker/db/migration/alembic_migrations/versions/HEAD b/tacker/db/migration/alembic_migrations/versions/HEAD index a110ead88..84b7b9c00 100644 --- a/tacker/db/migration/alembic_migrations/versions/HEAD +++ b/tacker/db/migration/alembic_migrations/versions/HEAD @@ -1 +1 @@ -cd04a8335c18 \ No newline at end of file +9d425296f2c3 \ No newline at end of file