Merge "Support tacker-db-manage for Multi DB backend"

This commit is contained in:
Zuul 2023-02-27 12:15:34 +00:00 committed by Gerrit Code Review
commit 05a4a17803
25 changed files with 449 additions and 122 deletions

View File

@ -174,6 +174,76 @@ So the first step of installing tacker is to clone Devstack and prepare your
$ ./stack.sh
Use PostgreSQL as Tacker database
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When installing via Devstack, MySQL is used as Tacker database backend
by default.
To use PostgreSQL as Tacker database backend, execute the following command.
#. Install PostgreSQL and login.
.. code-block:: console
$ sudo apt install postgresql postgresql-contrib
$ sudo -i -u postgres
$ psql
#. Create PostgreSQL database and user.
.. code-block::
CREATE DATABASE tacker;
CREATE ROLE tacker WITH CREATEDB LOGIN PASSWORD '<TACKERDB_PASSWORD>';
exit;
#. Modify ``postgresql.conf`` and restart PostgreSQL server.
.. note::
The location of ``postgresql.conf`` is different for each distribution.
For Ubuntu distribution, modify
``/etc/postgresql/{POSTGRESQL_VERSION}/main/postgresql.conf``.
Insert ``escape`` as the value of ``bytea_output`` in ``postgresql.conf``.
.. code-block:: ini
bytea_output = 'escape'
Restart PostgreSQL server.
.. code-block:: console
$ sudo service postgresql restart
#. Modify ``tacker.conf`` for PostgreSQL and restart Tacker server.
Edit the configuration of [database] in ``/etc/tacker/tacker.conf``
as follows.
.. code-block:: ini
[database]
connection = postgresql://tacker:<POSTGRES_PASSWORD>@<POSTGRES_IP>/tacker?client_encoding=utf8
Restart Tacker server.
.. code-block:: console
$ sudo systemctl restart devstack@tacker.service
$ sudo systemctl restart devstack@tacker-conductor.service
#. Populate Tacker database.
.. code-block:: console
$ /usr/local/bin/tacker-db-manage \
--config-file /etc/tacker/tacker.conf \
upgrade head
.. rubric:: Footnotes
.. [#f0] https://docs.openstack.org/devstack/latest/

View File

@ -64,7 +64,13 @@ Installing Tacker Server
.. note::
Make sure to replace the ``<branch_name>`` in command examples with
specific branch name, such as ``stable/ussuri``.
specific branch name, such as ``stable/2023.1``.
.. note::
From Tacker Antelope, PostgreSQL is available as a Tacker DB.
If you would like to use PostgreSQL, please see
`Install via Devstack`_ document.
#. Create MySQL database and user.
@ -328,3 +334,5 @@ required because the console will be locked by a running process.
$ sudo systemctl start tacker-conductor.service
.. _Install via Devstack: https://docs.openstack.org/tacker/latest/install/devstack.html

View File

@ -0,0 +1,6 @@
features:
- |
Support Tacker and tacker-db-manage for Multi DB backend,
especially PostgreSQL.
Use PostgreSQL as Tacker database via Devstack
for Tacker Installation.

View File

@ -187,7 +187,7 @@ class VnfPackage(model_base.BASE, models.SoftDeleteMixin,
VnfPackageVnfd, uselist=False,
primaryjoin='and_(VnfPackage.id == '
'VnfPackageVnfd.package_uuid,'
'VnfPackageVnfd.deleted == 0)')
'VnfPackageVnfd.deleted == "0")')
vnf_artifacts = orm.relationship(
VnfPackageArtifactInfo,

View File

@ -34,6 +34,13 @@ from tacker.db import types
def upgrade(active_plugins=None, options=None):
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
text_type_maxlen = sa.VARCHAR(length=65535)
else:
text_type_maxlen = sa.TEXT(length=65535)
op.create_table('nsd',
sa.Column('tenant_id', sa.String(length=64), nullable=False),
sa.Column('id', types.Uuid(length=36), nullable=False),
@ -56,8 +63,8 @@ def upgrade(active_plugins=None, options=None):
sa.Column('vim_id', sa.String(length=64), nullable=False),
sa.Column('name', sa.String(length=255), nullable=False),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('vnf_ids', sa.TEXT(length=65535), nullable=True),
sa.Column('mgmt_urls', sa.TEXT(length=65535), nullable=True),
sa.Column('vnf_ids', text_type_maxlen, nullable=True),
sa.Column('mgmt_urls', text_type_maxlen, nullable=True),
sa.Column('status', sa.String(length=64), nullable=False),
sa.Column('error_reason', sa.Text(), nullable=True),
sa.ForeignKeyConstraint(['nsd_id'], ['nsd.id'], ),
@ -68,7 +75,7 @@ def upgrade(active_plugins=None, options=None):
sa.Column('id', types.Uuid(length=36), nullable=False),
sa.Column('nsd_id', types.Uuid(length=36), nullable=False),
sa.Column('key', sa.String(length=255), nullable=False),
sa.Column('value', sa.TEXT(length=65535), nullable=True),
sa.Column('value', text_type_maxlen, nullable=True),
sa.ForeignKeyConstraint(['nsd_id'], ['nsd.id'], ),
sa.PrimaryKeyConstraint('id'),
mysql_engine='InnoDB'

View File

@ -32,5 +32,12 @@ import sqlalchemy as sa
def upgrade(active_plugins=None, options=None):
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
text_type_maxlen = sa.VARCHAR(length=65535)
else:
text_type_maxlen = sa.TEXT(length=65535)
op.alter_column('deviceattributes',
'value', type_=sa.TEXT(65535), nullable=True)
'value', type_=text_type_maxlen, nullable=True)

View File

@ -34,6 +34,14 @@ from tacker.db import types
def upgrade(active_plugins=None, options=None):
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
deleted_type = sa.SmallInteger
else:
deleted_type = Boolean
op.create_table(
'placement_constraint',
sa.Column('id', types.Uuid(length=36), nullable=False),
@ -46,7 +54,7 @@ def upgrade(active_plugins=None, options=None):
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.Column('deleted', deleted_type, default=False),
sa.PrimaryKeyConstraint('id'),
mysql_engine='InnoDB'
)

View File

@ -61,7 +61,8 @@ def upgrade(active_plugins=None, options=None):
sa.Enum('INSTANTIATE', 'SCALE', 'SCALE_TO_LEVEL',
'CHANGE_FLAVOUR', 'TERMINATE', 'HEAL', 'OPERATE',
'CHANGE_EXT_CONN', 'CREATE_SNAPSHOT',
'REVERT_TO_SNAPSHOT', 'CHANGE_VNFPKG'),
'REVERT_TO_SNAPSHOT', 'CHANGE_VNFPKG',
name='operation'),
nullable=False),
sa.Column('isAutomaticInvocation', sa.Boolean(), nullable=False),
sa.Column('instantiationLevelId', sa.String(length=255),

View File

@ -34,8 +34,15 @@ from tacker.db import types
def upgrade(active_plugins=None, options=None):
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
text_type_maxlen = sa.VARCHAR(length=65535)
else:
text_type_maxlen = sa.TEXT(length=65535)
op.add_column('ns', sa.Column(
'vnffg_ids', sa.TEXT(length=65535), nullable=True))
'vnffg_ids', text_type_maxlen, nullable=True))
op.add_column('vnffgs', sa.Column(
'ns_id', types.Uuid(length=36), nullable=True))
op.create_foreign_key('vnffg_foreign_key',

View File

@ -35,6 +35,13 @@ from tacker.db.types import Json
def upgrade(active_plugins=None, options=None):
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
deleted_type = sa.SmallInteger
else:
deleted_type = sa.Boolean
op.create_table(
'vnffgtemplates',
sa.Column('id', sa.String(length=36), nullable=False),
@ -68,7 +75,7 @@ def upgrade(active_plugins=None, options=None):
sa.Column('name', sa.String(length=255), nullable=False),
sa.Column('status', sa.String(length=255), nullable=False),
sa.Column('path_id', sa.String(length=255), nullable=False),
sa.Column('symmetrical', sa.Boolean, default=False),
sa.Column('symmetrical', deleted_type, default=False),
sa.ForeignKeyConstraint(['vnffg_id'], ['vnffgs.id'], ),
sa.PrimaryKeyConstraint('id'),
mysql_engine='InnoDB'
@ -82,7 +89,7 @@ def upgrade(active_plugins=None, options=None):
sa.Column('nfp_id', sa.String(length=36), nullable=False),
sa.Column('status', sa.String(length=255), nullable=False),
sa.Column('path_id', sa.String(length=255), nullable=False),
sa.Column('symmetrical', sa.Boolean, default=False),
sa.Column('symmetrical', deleted_type, default=False),
sa.Column('chain', Json),
sa.ForeignKeyConstraint(['nfp_id'], ['vnffgnfps.id'], ),
sa.PrimaryKeyConstraint('id'),

View File

@ -32,5 +32,12 @@ import sqlalchemy as sa
def upgrade(active_plugins=None, options=None):
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
text_type_maxlen = sa.VARCHAR(length=65535)
else:
text_type_maxlen = sa.TEXT(length=65535)
op.alter_column('devicetemplateattributes',
'value', type_=sa.TEXT(65535), nullable=True)
'value', type_=text_type_maxlen, nullable=True)

View File

@ -30,22 +30,57 @@ from alembic import op # noqa: E402
def upgrade(active_plugins=None, options=None):
alter_sql_vnfd_ids = "ALTER TABLE vnf_lcm_filters CHANGE \
vnfd_ids vnfd_ids mediumtext GENERATED ALWAYS AS \
(json_unquote(json_extract(`filter`, \
'$.vnfInstanceSubscriptionFilter.vnfdIds'))) VIRTUAL;"
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
alter_sql_vnfd_ids_drop = "ALTER TABLE vnf_lcm_filters DROP \
COLUMN vnfd_ids;"
alter_sql_vnf_instance_ids = "ALTER TABLE vnf_lcm_filters CHANGE \
vnf_instance_ids vnf_instance_ids mediumtext GENERATED ALWAYS AS \
(json_unquote(json_extract(`filter`, \
'$.vnfInstanceSubscriptionFilter.vnfInstanceIds'))) VIRTUAL;"
alter_sql_vnfd_ids_add = "ALTER TABLE vnf_lcm_filters ADD \
COLUMN vnfd_ids text GENERATED ALWAYS AS (decode(filter->> \
'$.vnfInstanceSubscriptionFilter.vnfdIds','escape')) STORED;"
alter_sql_vnf_instance_names = "ALTER TABLE vnf_lcm_filters CHANGE \
vnf_instance_names vnf_instance_names mediumtext GENERATED \
alter_sql_vnf_instance_ids_drop = "ALTER TABLE vnf_lcm_filters DROP \
COLUMN vnf_instance_ids;"
alter_sql_vnf_instance_ids_add = "ALTER TABLE vnf_lcm_filters ADD \
vnf_instance_ids text GENERATED ALWAYS AS (decode(filter->> \
'$.vnfInstanceSubscriptionFilter.vnfInstanceIds','escape')) \
STORED;"
alter_sql_vnf_instance_names_drop = "ALTER TABLE vnf_lcm_filters \
DROP COLUMN vnf_instance_names;"
alter_sql_vnf_instance_names_add = "ALTER TABLE vnf_lcm_filters ADD \
COLUMN vnf_instance_names text GENERATED \
ALWAYS AS (decode(filter->> \
'$.vnfInstanceSubscriptionFilter.vnfInstanceNames', \
'escape')) STORED;"
op.execute(alter_sql_vnfd_ids_drop)
op.execute(alter_sql_vnfd_ids_add)
op.execute(alter_sql_vnf_instance_ids_drop)
op.execute(alter_sql_vnf_instance_ids_add)
op.execute(alter_sql_vnf_instance_names_drop)
op.execute(alter_sql_vnf_instance_names_add)
else:
alter_sql_vnfd_ids = "ALTER TABLE vnf_lcm_filters CHANGE \
vnfd_ids vnfd_ids mediumtext GENERATED ALWAYS AS \
(json_unquote(json_extract(`filter`, \
'$.vnfInstanceSubscriptionFilter.vnfdIds'))) VIRTUAL;"
alter_sql_vnf_instance_ids = "ALTER TABLE vnf_lcm_filters CHANGE \
vnf_instance_ids vnf_instance_ids mediumtext GENERATED \
ALWAYS AS (json_unquote(json_extract(`filter`, \
'$.vnfInstanceSubscriptionFilter.vnfInstanceNames'))) \
VIRTUAL;"
'$.vnfInstanceSubscriptionFilter.vnfInstanceIds'))) VIRTUAL;"
op.execute(alter_sql_vnfd_ids)
op.execute(alter_sql_vnf_instance_ids)
op.execute(alter_sql_vnf_instance_names)
alter_sql_vnf_instance_names = "ALTER TABLE vnf_lcm_filters CHANGE \
vnf_instance_names vnf_instance_names mediumtext \
GENERATED ALWAYS AS (json_unquote(json_extract(`filter`, \
'$.vnfInstanceSubscriptionFilter.vnfInstanceNames'))) \
VIRTUAL;"
op.execute(alter_sql_vnfd_ids)
op.execute(alter_sql_vnf_instance_ids)
op.execute(alter_sql_vnf_instance_names)

View File

@ -38,4 +38,9 @@ def upgrade(active_plugins=None, options=None):
# unique constraint is taken care by the nfvo_db plugin to support
# soft deletion of vim
op.drop_index('auth_url', table_name='vimauths')
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
op.drop_constraint('vimauths_auth_url_key', table_name='vimauths')
else:
op.drop_index('auth_url', table_name='vimauths')

View File

@ -36,6 +36,14 @@ from tacker.db import types
def upgrade(active_plugins=None, options=None):
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
deleted_type = sa.SmallInteger
else:
deleted_type = Boolean
op.create_table(
'vnf_instances',
sa.Column('id', types.Uuid(length=36), nullable=False),
@ -58,7 +66,7 @@ def upgrade(active_plugins=None, options=None):
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', sa.Boolean, default=False),
sa.Column('deleted', deleted_type, default=False),
sa.PrimaryKeyConstraint('id'),
mysql_engine='InnoDB'
)
@ -82,7 +90,7 @@ def upgrade(active_plugins=None, options=None):
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.Column('deleted', deleted_type, default=False),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(['vnf_instance_id'],
['vnf_instances.id'], ),
@ -101,7 +109,7 @@ def upgrade(active_plugins=None, options=None):
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.Column('deleted', deleted_type, default=False),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(['vnf_instance_id'],
['vnf_instances.id'], ),

View File

@ -35,6 +35,14 @@ from tacker.db import types
def upgrade(active_plugins=None, options=None):
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
deleted_type = sa.SmallInteger
else:
deleted_type = Boolean
op.create_table(
'vnf_packages',
sa.Column('id', types.Uuid(length=36), nullable=False),
@ -48,7 +56,7 @@ def upgrade(active_plugins=None, options=None):
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.Column('deleted', deleted_type, default=False),
sa.PrimaryKeyConstraint('id'),
mysql_engine='InnoDB'
)
@ -61,7 +69,7 @@ def upgrade(active_plugins=None, options=None):
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.Column('deleted', deleted_type, default=False),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(['package_uuid'],
['vnf_packages.id'], ),
@ -100,7 +108,7 @@ def upgrade(active_plugins=None, options=None):
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.Column('deleted', deleted_type, default=False),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(['package_uuid'],
['vnf_packages.id'], ),
@ -125,7 +133,7 @@ def upgrade(active_plugins=None, options=None):
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.Column('deleted', deleted_type, default=False),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(['flavour_uuid'],
['vnf_deployment_flavours.id'], ),
@ -140,7 +148,7 @@ def upgrade(active_plugins=None, options=None):
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.Column('deleted', deleted_type, default=False),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(['image_uuid'],
['vnf_software_images.id'], ),

View File

@ -38,7 +38,8 @@ def upgrade(active_plugins=None, options=None):
sa.Column('filter', sa.JSON(), nullable=True),
sa.Column('callbackUri', sa.String(length=255), nullable=False),
sa.Column('authentication', sa.JSON(), nullable=True),
sa.Column('verbosity', sa.Enum('FULL', 'SHORT'), nullable=False),
sa.Column('verbosity',
sa.Enum('FULL', 'SHORT', name='verbosity'), nullable=False),
sa.PrimaryKeyConstraint('id'),
mysql_engine='InnoDB'
)
@ -55,7 +56,8 @@ def upgrade(active_plugins=None, options=None):
sa.Column('vnfConfigurableProperties', sa.JSON(), nullable=True),
sa.Column('vimConnectionInfo', sa.JSON(), nullable=True),
sa.Column('instantiationState',
sa.Enum('NOT_INSTANTIATED', 'INSTANTIATED'),
sa.Enum('NOT_INSTANTIATED', 'INSTANTIATED',
name='instantiationState'),
nullable=False),
sa.Column('instantiatedVnfInfo', sa.JSON(), nullable=True),
sa.Column('metadata', sa.JSON(), nullable=True),
@ -68,7 +70,8 @@ def upgrade(active_plugins=None, options=None):
sa.Column('id', sa.String(length=255), nullable=False),
sa.Column('operationState',
sa.Enum('STARTING', 'PROCESSING', 'COMPLETED', 'FAILED_TEMP',
'FAILED', 'ROLLING_BACK', 'ROLLED_BACK'),
'FAILED', 'ROLLING_BACK', 'ROLLED_BACK',
name='operationState'),
nullable=False),
sa.Column('stateEnteredTime', sa.DateTime(), nullable=False),
sa.Column('startTime', sa.DateTime(), nullable=False),
@ -78,12 +81,15 @@ def upgrade(active_plugins=None, options=None):
sa.Enum('INSTANTIATE', 'SCALE', 'SCALE_TO_LEVEL',
'CHANGE_FLAVOUR', 'TERMINATE', 'HEAL', 'OPERATE',
'CHANGE_EXT_CONN', 'MODIFY_INFO', 'CREATE_SNAPSHOT',
'REVERT_TO_SNAPSHOT', 'CHANGE_VNFPKG'),
'REVERT_TO_SNAPSHOT', 'CHANGE_VNFPKG',
name='operation'),
nullable=False),
sa.Column('isAutomaticInvocation', sa.Boolean(), nullable=False),
sa.Column('operationParams', sa.JSON(), nullable=True),
sa.Column('isCancelPending', sa.Boolean(), nullable=False),
sa.Column('cancelMode', sa.Enum('GRACEFUL', 'FORCEFUL'), nullable=True),
sa.Column('cancelMode',
sa.Enum('GRACEFUL', 'FORCEFUL', name='cancelMode'),
nullable=True),
sa.Column('error', sa.JSON(), nullable=True),
sa.Column('resourceChanges', sa.JSON(), nullable=True),
sa.Column('changedInfo', sa.JSON(), nullable=True),

View File

@ -34,6 +34,78 @@ down_revision = '3adac34764da'
def upgrade(active_plugins=None, options=None):
sql_text_length = 65535
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
type = sa.VARCHAR(length=sql_text_length)
operation_states = sa.Computed(
"decode(filter->>'$.operationStates','escape')")
operation_states_len = sa.Computed(
"coalesce(json_array_length(filter->'$.operationStates'),0)")
vnfd_ids = sa.Computed(
"decode(filter->>'$.vnfdIds','escape')")
vnfd_ids_len = sa.Computed(
"coalesce(json_array_length(filter->'$.vnfdIds'),0)")
vnf_provider = sa.Computed(
"(coalesce(decode("
"vnf_products_from_providers->>'$.vnfProvider','escape')),0)")
vnf_product_name = sa.Computed(
"(coalesce(decode("
"vnf_products_from_providers->>"
"'$.vnfProducts[0].vnfProductName','escape')),0)")
vnf_software_version = sa.Computed(
"(coalesce(decode("
"vnf_products_from_providers->>'$.vnfProducts[0]"
".versions[0].vnfSoftwareVersion','escape')),0)")
vnfd_versions = sa.Computed(
"decode(vnf_products_from_providers->>"
"'$.vnfProducts[0].versions[0].vnfdVersions','escape')")
vnfd_versions_len = sa.Computed(
"coalesce(json_array_length(filter->"
"'$.vnfProducts[0].versions[0].vnfdVersions'),0)")
vnf_instance_ids = sa.Computed(
"decode(filter->>'$.vnfInstanceIds','escape')")
vnf_instance_ids_len = sa.Computed(
"coalesce(json_array_length(filter->'$.vnfInstanceIds'),0)")
vnf_instance_names = sa.Computed(
"decode(filter->>'$.vnfInstanceNames','escape')")
vnf_instance_names_len = sa.Computed(
"coalesce(json_array_length(filter->'$.vnfInstanceNames'),0)")
else:
type = sa.TEXT(length=sql_text_length)
operation_states = sa.Computed(
"json_unquote(json_extract(`filter`,'$.operationStates'))")
operation_states_len = sa.Computed(
"ifnull(json_length(`operation_states`),0)")
vnfd_ids = sa.Computed(
"json_unquote(json_extract(`filter`,'$.vnfdIds'))")
vnfd_ids_len = sa.Computed(
"ifnull(json_length(`vnfd_ids`),0)")
vnf_provider = sa.Computed(
"(ifnull(json_unquote(json_extract("
"`vnf_products_from_providers`,'$.vnfProvider')),''))")
vnf_product_name = sa.Computed(
"(ifnull(json_unquote(json_extract("
"`vnf_products_from_providers`,"
"'$.vnfProducts[0].vnfProductName')),''))")
vnf_software_version = sa.Computed(
"(ifnull(json_unquote(json_extract("
"`vnf_products_from_providers`,'$.vnfProducts[0]"
".versions[0].vnfSoftwareVersion')),''))")
vnfd_versions = sa.Computed(
"json_unquote(json_extract(`vnf_products_from_providers`,"
"'$.vnfProducts[0].versions[0].vnfdVersions'))")
vnfd_versions_len = sa.Computed(
"ifnull(json_length(`vnfd_versions`),0)")
vnf_instance_ids = sa.Computed(
"json_unquote(json_extract(`filter`,'$.vnfInstanceIds'))")
vnf_instance_ids_len = sa.Computed(
"ifnull(json_length(`vnf_instance_ids`),0)")
vnf_instance_names = sa.Computed(
"json_unquote(json_extract(`filter`,'$.vnfInstanceNames'))")
vnf_instance_names_len = sa.Computed(
"ifnull(json_length(`vnf_instance_names`),0)")
op.add_column(
'vnf_lcm_filters',
sa.Column(
@ -42,96 +114,64 @@ def upgrade(active_plugins=None, options=None):
op.add_column(
'vnf_lcm_filters',
sa.Column(
'operation_states', sa.TEXT(length=sql_text_length),
sa.Computed(
"json_unquote(json_extract(`filter`,'$.operationStates'))")))
'operation_states', type, operation_states))
op.add_column(
'vnf_lcm_filters',
sa.Column(
'operation_states_len', sa.Integer,
sa.Computed(
"ifnull(json_length(`operation_states`),0)")))
'operation_states_len', sa.Integer, operation_states_len))
op.add_column(
'vnf_lcm_filters',
sa.Column(
'vnfd_ids', sa.TEXT(length=sql_text_length),
sa.Computed(
"json_unquote(json_extract(`filter`,'$.vnfdIds'))")))
'vnfd_ids', type, vnfd_ids))
op.add_column(
'vnf_lcm_filters',
sa.Column(
'vnfd_ids_len', sa.Integer,
sa.Computed(
"ifnull(json_length(`vnfd_ids`),0)")))
'vnfd_ids_len', sa.Integer, vnfd_ids_len))
op.add_column(
'vnf_lcm_filters',
sa.Column(
'vnf_provider', sa.TEXT(length=sql_text_length),
sa.Computed(
"(ifnull(json_unquote(json_extract("
"`vnf_products_from_providers`,'$.vnfProvider')),''))")))
'vnf_provider', type, vnf_provider))
op.add_column(
'vnf_lcm_filters',
sa.Column(
'vnf_product_name', sa.TEXT(length=sql_text_length),
sa.Computed(
"(ifnull(json_unquote(json_extract("
"`vnf_products_from_providers`,"
"'$.vnfProducts[0].vnfProductName')),''))")))
'vnf_product_name', type, vnf_product_name))
op.add_column(
'vnf_lcm_filters',
sa.Column(
'vnf_software_version', sa.TEXT(length=sql_text_length),
sa.Computed(
"(ifnull(json_unquote(json_extract("
"`vnf_products_from_providers`,'$.vnfProducts[0]"
".versions[0].vnfSoftwareVersion')),''))")))
'vnf_software_version', type, vnf_software_version))
op.add_column(
'vnf_lcm_filters',
sa.Column(
'vnfd_versions', sa.TEXT(length=sql_text_length),
sa.Computed(
"json_unquote(json_extract(`vnf_products_from_providers`,"
"'$.vnfProducts[0].versions[0].vnfdVersions'))")))
'vnfd_versions', type, vnfd_versions))
op.add_column(
'vnf_lcm_filters',
sa.Column(
'vnfd_versions_len', sa.Integer,
sa.Computed(
"ifnull(json_length(`vnfd_versions`),0)")))
'vnfd_versions_len', sa.Integer, vnfd_versions_len))
op.add_column(
'vnf_lcm_filters',
sa.Column(
'vnf_instance_ids', sa.TEXT(length=sql_text_length),
sa.Computed(
"json_unquote(json_extract(`filter`,'$.vnfInstanceIds'))")))
'vnf_instance_ids', type, vnf_instance_ids))
op.add_column(
'vnf_lcm_filters',
sa.Column(
'vnf_instance_ids_len', sa.Integer,
sa.Computed(
"ifnull(json_length(`vnf_instance_ids`),0)")))
'vnf_instance_ids_len', sa.Integer, vnf_instance_ids_len))
op.add_column(
'vnf_lcm_filters',
sa.Column(
'vnf_instance_names', sa.TEXT(length=sql_text_length),
sa.Computed(
"json_unquote(json_extract(`filter`,'$.vnfInstanceNames'))")))
'vnf_instance_names', type, vnf_instance_names))
op.add_column(
'vnf_lcm_filters',
sa.Column(
'vnf_instance_names_len', sa.Integer,
sa.Computed(
"ifnull(json_length(`vnf_instance_names`),0)")))
'vnf_instance_names_len', sa.Integer, vnf_instance_names_len))

View File

@ -35,6 +35,26 @@ from tacker.db import types
def upgrade(active_plugins=None, options=None):
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
deleted_type = sa.SmallInteger
notif_type = "decode(filter->>'$.notificationTypes','escape')"
notif_type_len = "coalesce \
(json_array_length(filter->'$.notificationTypes'),0)"
op_state = "decode(filter->>'$.operationStates','escape')"
op_state_len = "coalesce \
(json_array_length(filter->'$.operationStates'),0)"
else:
deleted_type = Boolean
notif_type = "json_unquote \
(json_extract('filter','$.notificationTypes'))"
notif_type_len = "ifnull(json_length('notification_types'),0)"
op_state = "json_unquote(json_extract('filter','$.operationStates'))"
op_state_len = "ifnull(json_length('operation_states'),0)"
op.create_table(
'vnf_lcm_subscriptions',
sa.Column('id', types.Uuid(length=36), nullable=False),
@ -43,13 +63,11 @@ def upgrade(active_plugins=None, options=None):
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.Column('deleted', deleted_type, default=False),
sa.PrimaryKeyConstraint('id'),
mysql_engine='InnoDB'
)
noti_str = "json_unquote(json_extract('filter','$.notificationTypes'))"
sta_str = "json_unquote(json_extract('filter','$.operationStates'))"
op.create_table(
'vnf_lcm_filters',
sa.Column('id', sa.Integer, autoincrement=True, nullable=False),
@ -57,16 +75,16 @@ def upgrade(active_plugins=None, options=None):
sa.Column('filter', sa.JSON(), nullable=False),
sa.Column('notification_types',
sa.LargeBinary(length=65536),
sa.Computed(noti_str)),
sa.Computed(notif_type)),
sa.Column('notification_types_len',
sa.Integer,
sa.Computed("ifnull(json_length('notification_types'),0)")),
sa.Computed(notif_type_len)),
sa.Column('operation_states',
sa.LargeBinary(length=65536),
sa.Computed(sta_str)),
sa.Computed(op_state)),
sa.Column('operation_states_len',
sa.Integer,
sa.Computed("ifnull(json_length('operation_states'),0)")),
sa.Computed(op_state_len)),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(['subscription_uuid'],
['vnf_lcm_subscriptions.id'], ),
@ -81,10 +99,10 @@ def upgrade(active_plugins=None, options=None):
sa.Column('start_time', sa.DateTime(), nullable=False),
sa.Column('vnf_instance_id', types.Uuid(length=36), nullable=False),
sa.Column('operation', sa.String(length=255), nullable=False),
sa.Column('is_automatic_invocation', sa.Boolean, nullable=False),
sa.Column('is_automatic_invocation', deleted_type, nullable=False),
sa.Column('operation_params', sa.JSON(), nullable=True),
sa.Column('error', sa.JSON(), nullable=True),
sa.Column('deleted', Boolean, default=False),
sa.Column('deleted', deleted_type, default=False),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(['vnf_instance_id'],
['vnf_instances.id'], ),

View File

@ -32,9 +32,16 @@ import sqlalchemy as sa
def upgrade(active_plugins=None, options=None):
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
text_type_maxlen = sa.VARCHAR(length=65535)
else:
text_type_maxlen = sa.TEXT(length=65535)
op.alter_column('ns',
'mgmt_urls', new_column_name='mgmt_ip_addresses',
existing_type=sa.TEXT(65535), nullable=True)
existing_type=text_type_maxlen, nullable=True)
op.alter_column('vnf',
'mgmt_url', new_column_name='mgmt_ip_address',
existing_type=sa.String(255), nullable=True)

View File

@ -35,11 +35,21 @@ from tacker.db import migration
def upgrade(active_plugins=None, options=None):
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
deleted_type = sa.SmallInteger
sta_str = "decode(filter->>'$.operationTypes','escape')"
sta_len = "coalesce(json_array_length(filter->'$.operationTypes'),0)"
else:
deleted_type = sa.Boolean
sta_str = "json_unquote(json_extract('filter','$.operationTypes'))"
sta_len = "ifnull(json_length('operation_types'),0)"
op.alter_column('vnf_lcm_filters', 'subscription_uuid',
type_=types.Uuid(length=36), existing_type=sa.String(length=255),
nullable=False)
sta_str = "json_unquote(json_extract('filter','$.operationTypes'))"
op.add_column(
'vnf_lcm_filters',
sa.Column('operation_types',
@ -50,7 +60,7 @@ def upgrade(active_plugins=None, options=None):
'vnf_lcm_filters',
sa.Column('operation_types_len',
sa.Integer,
sa.Computed("ifnull(json_length('operation_types'),0)")))
sa.Computed(sta_len)))
op.drop_column('vnf_lcm_filters', 'operation_states')
op.drop_column('vnf_lcm_filters', 'operation_states_len')
@ -62,7 +72,7 @@ def upgrade(active_plugins=None, options=None):
type_=sa.String(length=16),existing_type=sa.String(length=255))
op.add_column('vnf_lcm_op_occs',
sa.Column('is_cancel_pending', sa.Boolean, nullable=False)),
sa.Column('is_cancel_pending', deleted_type, nullable=False)),
op.add_column('vnf_lcm_op_occs',
sa.Column('resource_changes', sa.JSON(), nullable=True))

View File

@ -42,15 +42,17 @@ def upgrade(active_plugins=None, options=None):
sa.Column('alarmClearedTime', sa.DateTime(), nullable=True),
sa.Column('alarmAcknowledgedTime', sa.DateTime(), nullable=True),
sa.Column('ackState', sa.Enum(
'UNACKNOWLEDGED', 'ACKNOWLEDGED'), nullable=False),
'UNACKNOWLEDGED', 'ACKNOWLEDGED',
name='ackState'), nullable=False),
sa.Column('perceivedSeverity', sa.Enum(
'CRITICAL', 'MAJOR', 'MINOR', 'WARNING',
'INDETERMINATE', 'CLEARED'), nullable=False),
'INDETERMINATE', 'CLEARED',
name='perceivedSeverity'), nullable=False),
sa.Column('eventTime', sa.DateTime(), nullable=False),
sa.Column('eventType', sa.Enum(
'COMMUNICATIONS_ALARM', 'PROCESSING_ERROR_ALARM',
'ENVIRONMENTAL_ALARM', 'QOS_ALARM',
'EQUIPMENT_ALARM'), nullable=False),
'EQUIPMENT_ALARM', name='eventType'), nullable=False),
sa.Column('faultType', sa.String(length=255), nullable=True),
sa.Column('probableCause', sa.String(length=255), nullable=False),
sa.Column('isRootCause', sa.Boolean(), nullable=False),

View File

@ -43,24 +43,71 @@ def upgrade(active_plugins=None, options=None):
# (2) Need to fix SQL statement to utilize sqlalchemy. Currently, we
# use raw SQL with op.exec as a workaround since op.alter_column does
# not work correctly.
alter_sql_notification_types = "ALTER TABLE vnf_lcm_filters CHANGE \
notification_types notification_types text GENERATED \
ALWAYS AS (json_unquote(json_extract(`filter`,\
'$.notificationTypes'))) VIRTUAL;"
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
alter_sql_notification_types_drop = "ALTER TABLE vnf_lcm_filters \
DROP COLUMN notification_types;"
alter_sql_notification_types_len = "ALTER TABLE vnf_lcm_filters CHANGE \
notification_types_len notification_types_len int(11) GENERATED \
ALWAYS AS (ifnull(json_length(`notification_types`),0)) VIRTUAL;"
alter_sql_notification_types_add = "ALTER TABLE vnf_lcm_filters ADD \
COLUMN notification_types text GENERATED \
ALWAYS AS (decode(filter->>\
'$.notificationTypes','escape')) STORED;"
alter_sql_operation_types = "ALTER TABLE vnf_lcm_filters CHANGE \
operation_types operation_types text GENERATED ALWAYS AS \
(json_unquote(json_extract(`filter`,'$.operationTypes'))) VIRTUAL;"
alter_sql_notification_types_len_drop = "ALTER TABLE vnf_lcm_filters \
DROP COLUMN notification_types_len;"
alter_sql_operation_types_len = "ALTER TABLE vnf_lcm_filters CHANGE \
operation_types_len operation_types_len int(11) GENERATED ALWAYS \
AS (ifnull(json_length(`operation_types`),0)) VIRTUAL;"
alter_sql_notification_types_len_add = "ALTER TABLE vnf_lcm_filters \
ADD COLUMN notification_types_len numeric(11) GENERATED \
ALWAYS AS (coalesce(json_array_length(filter->\
'$.notificationTypes'),0)) STORED;"
op.execute(alter_sql_notification_types)
op.execute(alter_sql_notification_types_len)
op.execute(alter_sql_operation_types)
op.execute(alter_sql_operation_types_len)
alter_sql_operation_types_drop = "ALTER TABLE vnf_lcm_filters DROP \
COLUMN operation_types;"
alter_sql_operation_types_add = "ALTER TABLE vnf_lcm_filters ADD \
COLUMN operation_types text GENERATED \
ALWAYS AS (decode(filter->>\
'$.operationTypes','escape')) STORED;"
alter_sql_operation_types_len_drop = "ALTER TABLE vnf_lcm_filters \
DROP COLUMN operation_types_len;"
alter_sql_operation_types_len_add = "ALTER TABLE vnf_lcm_filters ADD \
COLUMN operation_types_len numeric(11) GENERATED \
ALWAYS AS (coalesce(json_array_length(filter->\
'$.operationTypes'),0)) STORED;"
op.execute(alter_sql_notification_types_drop)
op.execute(alter_sql_notification_types_add)
op.execute(alter_sql_notification_types_len_drop)
op.execute(alter_sql_notification_types_len_add)
op.execute(alter_sql_operation_types_drop)
op.execute(alter_sql_operation_types_add)
op.execute(alter_sql_operation_types_len_drop)
op.execute(alter_sql_operation_types_len_add)
else:
alter_sql_notification_types = "ALTER TABLE vnf_lcm_filters CHANGE \
notification_types notification_types text GENERATED \
ALWAYS AS (json_unquote(json_extract(`filter`,\
'$.notificationTypes'))) VIRTUAL;"
alter_sql_notification_types_len = "ALTER TABLE vnf_lcm_filters \
CHANGE notification_types_len notification_types_len int(11) \
GENERATED ALWAYS AS \
(ifnull(json_length(`notification_types`),0)) VIRTUAL;"
alter_sql_operation_types = "ALTER TABLE vnf_lcm_filters CHANGE \
operation_types operation_types text GENERATED ALWAYS AS \
(json_unquote(json_extract(`filter`,'$.operationTypes'))) \
VIRTUAL;"
alter_sql_operation_types_len = "ALTER TABLE vnf_lcm_filters CHANGE \
operation_types_len operation_types_len int(11) GENERATED ALWAYS \
AS (ifnull(json_length(`operation_types`),0)) VIRTUAL;"
op.execute(alter_sql_notification_types)
op.execute(alter_sql_notification_types_len)
op.execute(alter_sql_operation_types)
op.execute(alter_sql_operation_types_len)

View File

@ -36,6 +36,14 @@ from tacker.db import types
def upgrade(active_plugins=None, options=None):
bind = op.get_bind()
engine = bind.engine
if engine.name == 'postgresql':
deleted_type = sa.SmallInteger
else:
deleted_type = Boolean
op.create_table(
'vnf_artifacts',
sa.Column('id', types.Uuid(length=36), nullable=False),
@ -47,7 +55,7 @@ def upgrade(active_plugins=None, options=None):
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.Column('deleted', deleted_type, default=False),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(['package_uuid'],
['vnf_packages.id'], ),

View File

@ -47,9 +47,14 @@ class Json(TypeDecorator):
cache_ok = False
def process_bind_param(self, value, dialect):
return jsonutils.dump_as_bytes(value)
if dialect.name == 'postgresql':
return jsonutils.dumps(value)
else:
return jsonutils.dump_as_bytes(value)
def process_result_value(self, value, dialect):
if value is None:
return None
if isinstance(value, dict):
return value
return jsonutils.loads(value)

View File

@ -200,7 +200,7 @@ class TackerPersistentObject(object):
'created_at': obj_fields.DateTimeField(nullable=False),
'updated_at': obj_fields.DateTimeField(nullable=True),
'deleted_at': obj_fields.DateTimeField(nullable=True),
'deleted': obj_fields.BooleanField(default=False)
'deleted': obj_fields.IntegerField(nullable=True, default=0)
}