fuel-web/nailgun/nailgun/db/migration/alembic_migrations/versions/fuel_9_0.py

755 lines
19 KiB
Python

# Copyright 2015 Mirantis, Inc.
#
# 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.
"""Fuel 9.0
Revision ID: 11a9adc6d36a
Revises: 2f879fa32f00
Create Date: 2015-12-15 17:20:49.519542
"""
from alembic import op
import six
import sqlalchemy as sa
from oslo_serialization import jsonutils
from nailgun import consts
from nailgun.db.sqlalchemy.models import fields
from nailgun.utils.migration import upgrade_enum
revision = '11a9adc6d36a'
down_revision = '43b2cb64dae6'
cluster_statuses_old = (
'new',
'deployment',
'stopped',
'operational',
'error',
'remove',
'update',
'update_error'
)
cluster_statuses_new = (
'new',
'deployment',
'stopped',
'operational',
'error',
'remove',
'partially_deployed'
)
def upgrade():
add_foreign_key_ondelete()
upgrade_ip_address()
update_vips_from_network_roles()
upgrade_node_roles_metadata()
merge_node_attributes_with_nodes()
upgrade_node_attributes()
upgrade_remove_wizard_metadata_from_releases()
drop_legacy_patching()
def downgrade():
restore_legacy_patching()
downgrade_remove_wizard_metadata_from_releases()
downgrade_node_attributes()
downgrade_merge_node_attributes_with_nodes()
downgrade_node_roles_metadata()
remove_foreign_key_ondelete()
downgrade_ip_address()
def remove_foreign_key_ondelete():
op.drop_constraint(
'attributes_cluster_id_fkey',
'attributes',
type_='foreignkey'
)
op.create_foreign_key(
'attributes_cluster_id_fkey',
'attributes', 'clusters',
['cluster_id'], ['id'],
)
op.drop_constraint(
'cluster_changes_cluster_id_fkey',
'cluster_changes',
type_='foreignkey'
)
op.create_foreign_key(
'cluster_changes_cluster_id_fkey',
'cluster_changes', 'clusters',
['cluster_id'], ['id'],
)
op.drop_constraint(
'nodegroups_cluster_id_fkey',
'nodegroups',
type_='foreignkey'
)
op.create_foreign_key(
'nodegroups_cluster_id_fkey',
'nodegroups', 'clusters',
['cluster_id'], ['id'],
)
op.drop_constraint(
'vmware_attributes_cluster_id_fkey',
'vmware_attributes',
type_='foreignkey'
)
op.create_foreign_key(
'vmware_attributes_cluster_id_fkey',
'vmware_attributes', 'clusters',
['cluster_id'], ['id'],
)
op.drop_constraint(
'networking_configs_cluster_id_fkey',
'networking_configs',
type_='foreignkey'
)
op.create_foreign_key(
'networking_configs_cluster_id_fkey',
'networking_configs', 'clusters',
['cluster_id'], ['id'],
)
op.drop_constraint(
'network_groups_nodegroups_fk',
'network_groups',
type_='foreignkey'
)
op.create_foreign_key(
'network_groups_nodegroups_fk',
'network_groups', 'nodegroups',
['group_id'], ['id'],
)
op.drop_constraint(
'neutron_config_id_fkey',
'neutron_config',
type_='foreignkey'
)
op.create_foreign_key(
'neutron_config_id_fkey',
'neutron_config', 'networking_configs',
['id'], ['id'],
)
op.drop_constraint(
'nodes_nodegroups_fk',
'nodes',
type_='foreignkey'
)
op.create_foreign_key(
'nodes_nodegroups_fk',
'nodes', 'nodegroups',
['group_id'], ['id'],
)
op.drop_constraint(
'nodes_cluster_id_fkey',
'nodes',
type_='foreignkey'
)
op.create_foreign_key(
'nodes_cluster_id_fkey',
'nodes', 'clusters',
['cluster_id'], ['id'],
)
op.drop_constraint(
'cluster_plugin_links_cluster_id_fkey',
'cluster_plugin_links',
type_='foreignkey'
)
op.create_foreign_key(
'cluster_plugin_links_cluster_id_fkey',
'cluster_plugin_links', 'clusters',
['cluster_id'], ['id'],
)
op.drop_constraint(
'node_nic_interfaces_parent_id_fkey',
'node_nic_interfaces',
type_='foreignkey'
)
op.create_foreign_key(
'node_nic_interfaces_parent_id_fkey',
'node_nic_interfaces', 'node_bond_interfaces',
['parent_id'], ['id'],
)
op.drop_constraint(
'openstack_configs_cluster_id_fkey',
'openstack_configs',
type_='foreignkey'
)
op.create_foreign_key(
'openstack_configs_cluster_id_fkey',
'openstack_configs', 'clusters',
['cluster_id'], ['id'],
)
op.drop_constraint(
'openstack_configs_node_id_fkey',
'openstack_configs',
type_='foreignkey'
)
op.create_foreign_key(
'openstack_configs_node_id_fkey',
'openstack_configs', 'nodes',
['node_id'], ['id'],
)
op.drop_constraint(
'plugin_links_plugin_id_fkey',
'plugin_links',
type_='foreignkey'
)
op.create_foreign_key(
'plugin_links_plugin_id_fkey',
'plugin_links', 'plugins',
['plugin_id'], ['id'],
)
op.drop_constraint(
'tasks_cluster_id_fkey',
'tasks',
type_='foreignkey'
)
op.create_foreign_key(
'tasks_cluster_id_fkey',
'tasks', 'clusters',
['cluster_id'], ['id'],
)
op.drop_constraint(
'tasks_parent_id_fkey',
'tasks',
type_='foreignkey'
)
op.create_foreign_key(
'tasks_parent_id_fkey',
'tasks', 'tasks',
['parent_id'], ['id'],
)
def add_foreign_key_ondelete():
op.drop_constraint(
'attributes_cluster_id_fkey',
'attributes',
type_='foreignkey'
)
op.create_foreign_key(
'attributes_cluster_id_fkey',
'attributes', 'clusters',
['cluster_id'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'cluster_changes_cluster_id_fkey',
'cluster_changes',
type_='foreignkey'
)
op.create_foreign_key(
'cluster_changes_cluster_id_fkey',
'cluster_changes', 'clusters',
['cluster_id'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'nodegroups_cluster_id_fkey',
'nodegroups',
type_='foreignkey'
)
op.create_foreign_key(
'nodegroups_cluster_id_fkey',
'nodegroups', 'clusters',
['cluster_id'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'vmware_attributes_cluster_id_fkey',
'vmware_attributes',
type_='foreignkey'
)
op.create_foreign_key(
'vmware_attributes_cluster_id_fkey',
'vmware_attributes', 'clusters',
['cluster_id'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'networking_configs_cluster_id_fkey',
'networking_configs',
type_='foreignkey'
)
op.create_foreign_key(
'networking_configs_cluster_id_fkey',
'networking_configs', 'clusters',
['cluster_id'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'network_groups_nodegroups_fk',
'network_groups',
type_='foreignkey'
)
op.create_foreign_key(
'network_groups_nodegroups_fk',
'network_groups', 'nodegroups',
['group_id'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'network_groups_release_fkey',
'network_groups',
type_='foreignkey'
)
op.create_foreign_key(
'network_groups_release_fk',
'network_groups', 'releases',
['release'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'neutron_config_id_fkey',
'neutron_config',
type_='foreignkey'
)
op.create_foreign_key(
'neutron_config_id_fkey',
'neutron_config', 'networking_configs',
['id'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'nodes_nodegroups_fk',
'nodes',
type_='foreignkey'
)
op.create_foreign_key(
'nodes_nodegroups_fk',
'nodes', 'nodegroups',
['group_id'], ['id'],
ondelete='SET NULL'
)
op.drop_constraint(
'nodes_cluster_id_fkey',
'nodes',
type_='foreignkey'
)
op.create_foreign_key(
'nodes_cluster_id_fkey',
'nodes', 'clusters',
['cluster_id'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'cluster_plugin_links_cluster_id_fkey',
'cluster_plugin_links',
type_='foreignkey'
)
op.create_foreign_key(
'cluster_plugin_links_cluster_id_fkey',
'cluster_plugin_links', 'clusters',
['cluster_id'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'node_nic_interfaces_parent_id_fkey',
'node_nic_interfaces',
type_='foreignkey'
)
op.create_foreign_key(
'node_nic_interfaces_parent_id_fkey',
'node_nic_interfaces', 'node_bond_interfaces',
['parent_id'], ['id'],
ondelete='SET NULL'
)
op.drop_constraint(
'openstack_configs_cluster_id_fkey',
'openstack_configs',
type_='foreignkey'
)
op.create_foreign_key(
'openstack_configs_cluster_id_fkey',
'openstack_configs', 'clusters',
['cluster_id'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'openstack_configs_node_id_fkey',
'openstack_configs',
type_='foreignkey'
)
op.create_foreign_key(
'openstack_configs_node_id_fkey',
'openstack_configs', 'nodes',
['node_id'], ['id'],
ondelete='SET NULL'
)
op.drop_constraint(
'plugin_links_plugin_id_fkey',
'plugin_links',
type_='foreignkey'
)
op.create_foreign_key(
'plugin_links_plugin_id_fkey',
'plugin_links', 'plugins',
['plugin_id'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'tasks_cluster_id_fkey',
'tasks',
type_='foreignkey'
)
op.create_foreign_key(
'tasks_cluster_id_fkey',
'tasks', 'clusters',
['cluster_id'], ['id'],
ondelete='CASCADE'
)
op.drop_constraint(
'tasks_parent_id_fkey',
'tasks',
type_='foreignkey'
)
op.create_foreign_key(
'tasks_parent_id_fkey',
'tasks', 'tasks',
['parent_id'], ['id'],
ondelete='CASCADE'
)
def upgrade_ip_address():
op.add_column(
'ip_addrs',
sa.Column(
'is_user_defined',
sa.Boolean,
nullable=False,
default=False,
server_default="false"
)
)
op.add_column(
'ip_addrs',
sa.Column(
'vip_namespace',
sa.String(length=25),
nullable=True,
default=None,
server_default=None
)
)
op.alter_column(
'ip_addrs',
'vip_type',
new_column_name='vip_name',
type_=sa.String(length=25)
)
def update_vips_from_network_roles():
def _update_network_roles_from_db_metadata(query):
connection = op.get_bind()
_vip_name_to_vip_data = {}
select = sa.text(query)
network_roles_metadata = connection.execute(select)
for network_roles_json in network_roles_metadata:
if not network_roles_json or not network_roles_json[0]:
continue
network_roles = jsonutils.loads(network_roles_json[0])
# warning: in current schema it is possible that network
# role is declared as dict
if isinstance(network_roles, dict):
network_roles = [network_roles]
for network_role in network_roles:
vips = network_role.get('properties', {}).get('vip', [])
for vip in vips:
_vip_name_to_vip_data[vip['name']] = vip
return _vip_name_to_vip_data
roles_vip_name_to_vip_data = {}
# get namespaces from plugins
roles_vip_name_to_vip_data.update(
_update_network_roles_from_db_metadata(
"SELECT network_roles_metadata from plugins"
)
)
# get namespaces from releases
roles_vip_name_to_vip_data.update(
_update_network_roles_from_db_metadata(
"SELECT network_roles_metadata from releases"
)
)
# perform update
connection = op.get_bind()
ip_addrs_select = sa.text(
"SELECT id, vip_name from ip_addrs"
)
ip_addrs = connection.execute(ip_addrs_select)
ip_addrs_update = sa.sql.text(
"UPDATE ip_addrs "
"SET vip_namespace = :vip_namespace WHERE id = :id"
)
existing_names_to_id = dict(
(vip_name, vip_id) for (vip_id, vip_name) in ip_addrs
)
for vip_name in existing_names_to_id:
namespace = roles_vip_name_to_vip_data\
.get(vip_name, {}).get('namespace')
# update only if namespace arrived
if namespace:
connection.execute(
ip_addrs_update,
id=existing_names_to_id[vip_name],
vip_namespace=namespace
)
def downgrade_ip_address():
op.alter_column(
'ip_addrs',
'vip_name',
new_column_name='vip_type',
type_=sa.String(length=25)
)
op.drop_column('ip_addrs', 'is_user_defined')
op.drop_column('ip_addrs', 'vip_namespace')
def upgrade_node_roles_metadata():
connection = op.get_bind()
select_query = sa.sql.text(
"SELECT id, roles_metadata FROM releases "
"WHERE roles_metadata IS NOT NULL")
update_query = sa.sql.text(
"UPDATE releases SET roles_metadata = :roles_metadata WHERE id = :id")
for id, roles_metadata in connection.execute(select_query):
roles_metadata = jsonutils.loads(roles_metadata)
role_groups = {
'controller': 'base',
'compute': 'compute',
'virt': 'compute',
'compute-vmware': 'compute',
'ironic': 'compute',
'cinder': 'storage',
'cinder-block-device': 'storage',
'cinder-vmware': 'storage',
'ceph-osd': 'storage'
}
for role_name, role_metadata in six.iteritems(roles_metadata):
role_metadata['group'] = role_groups\
.get(role_name, consts.NODE_ROLE_GROUPS.other)
connection.execute(
update_query,
id=id,
roles_metadata=jsonutils.dumps(roles_metadata),
)
def downgrade_node_roles_metadata():
connection = op.get_bind()
select_query = sa.sql.text(
"SELECT id, roles_metadata FROM releases "
"WHERE roles_metadata IS NOT NULL")
update_query = sa.sql.text(
"UPDATE releases SET roles_metadata = :roles_metadata WHERE id = :id")
for id, roles_metadata in connection.execute(select_query):
roles_metadata = jsonutils.loads(roles_metadata)
for role_name, role_metadata in six.iteritems(roles_metadata):
del role_metadata['group']
connection.execute(
update_query,
id=id,
roles_metadata=jsonutils.dumps(roles_metadata),
)
def merge_node_attributes_with_nodes():
connection = op.get_bind()
op.add_column(
'nodes',
sa.Column(
'vms_conf',
fields.JSON(),
nullable=False,
server_default='[]'
)
)
select_query = sa.sql.text('SELECT node_id, vms_conf FROM node_attributes')
update_query = sa.sql.text(
'UPDATE nodes SET vms_conf = :vms_conf WHERE id = :node_id')
for node_id, vms_conf in connection.execute(select_query):
connection.execute(update_query, node_id=node_id, vms_conf=vms_conf)
op.drop_table('node_attributes')
def downgrade_merge_node_attributes_with_nodes():
op.create_table(
'node_attributes',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('node_id', sa.Integer(), nullable=True),
sa.Column('interfaces', fields.JSON(), nullable=True),
sa.Column('vms_conf', fields.JSON(),
nullable=False, server_default='[]'),
sa.ForeignKeyConstraint(['node_id'], ['nodes.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.drop_column('nodes', 'vms_conf')
def upgrade_node_attributes():
op.add_column(
'nodes',
sa.Column(
'attributes',
fields.JSON(),
nullable=False,
server_default='{}'
)
)
op.add_column(
'releases',
sa.Column(
'node_attributes',
fields.JSON(),
nullable=False,
server_default='{}'
)
)
def downgrade_node_attributes():
op.drop_column('releases', 'node_attributes')
op.drop_column('nodes', 'attributes')
def upgrade_remove_wizard_metadata_from_releases():
op.drop_column('releases', 'wizard_metadata')
def downgrade_remove_wizard_metadata_from_releases():
op.add_column(
'releases',
sa.Column(
'wizard_metadata',
fields.JSON(),
nullable=True
)
)
def drop_legacy_patching():
upgrade_enum(
"clusters", # table
"status", # column
"cluster_status", # ENUM name
cluster_statuses_old, # old options
cluster_statuses_new, # new options
)
op.drop_constraint(
'fk_pending_release_id',
'clusters',
type_='foreignkey'
)
op.drop_column('clusters', 'pending_release_id')
op.drop_column('releases', 'can_update_from_versions')
def restore_legacy_patching():
op.add_column(
'releases',
sa.Column(
'can_update_from_versions',
fields.JSON(),
nullable=False,
server_default='[]'
))
op.add_column(
'clusters',
sa.Column(
'pending_release_id',
sa.Integer(),
nullable=True
))
op.create_foreign_key(
'fk_pending_release_id',
'clusters',
'releases',
['pending_release_id'],
['id'])
upgrade_enum(
"clusters", # table
"status", # column
"cluster_status", # ENUM name
cluster_statuses_new, # new options
cluster_statuses_old, # old options
)