From c3294d60efa71e25ab825cb19a523a89908e0c42 Mon Sep 17 00:00:00 2001 From: Nikita Zubkov Date: Wed, 13 Jul 2016 15:29:16 +0300 Subject: [PATCH] Extract cluster upgrade to a separate repository cluster_upgrade extension will be developed by octane team in a separate repository Change-Id: Id0bc78478cf3f40767fed760cd54e487a934fa10 --- .../extensions/cluster_upgrade/__init__.py | 0 .../alembic_migrations/__init__.py | 0 .../alembic_migrations/alembic.ini | 54 ---- .../alembic_migrations/migrations/__init__.py | 0 .../alembic_migrations/migrations/env.py | 90 ------- .../migrations/script.py.mako | 24 -- .../001_add_upgrade_relations_table.py | 51 ---- .../extensions/cluster_upgrade/extension.py | 47 ---- .../extensions/cluster_upgrade/handlers.py | 141 ---------- .../extensions/cluster_upgrade/models.py | 31 --- .../cluster_upgrade/objects/__init__.py | 0 .../cluster_upgrade/objects/adapters.py | 211 --------------- .../cluster_upgrade/objects/relations.py | 48 ---- .../cluster_upgrade/tests/__init__.py | 17 -- .../extensions/cluster_upgrade/tests/base.py | 55 ---- .../tests/test_db_migrations.py | 47 ---- .../cluster_upgrade/tests/test_extension.py | 29 -- .../cluster_upgrade/tests/test_handlers.py | 249 ------------------ .../cluster_upgrade/tests/test_objects.py | 48 ---- .../cluster_upgrade/tests/test_upgrade.py | 212 --------------- .../cluster_upgrade/tests/test_validators.py | 230 ---------------- .../extensions/cluster_upgrade/upgrade.py | 238 ----------------- .../extensions/cluster_upgrade/validators.py | 164 ------------ nailgun/setup.py | 2 - 24 files changed, 1988 deletions(-) delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/__init__.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/__init__.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/alembic.ini delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/__init__.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/env.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/script.py.mako delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/versions/001_add_upgrade_relations_table.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/extension.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/handlers.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/models.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/objects/__init__.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/objects/adapters.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/objects/relations.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/tests/__init__.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/tests/base.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/tests/test_db_migrations.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/tests/test_extension.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/tests/test_handlers.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/tests/test_objects.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/tests/test_upgrade.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/tests/test_validators.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/upgrade.py delete mode 100644 nailgun/nailgun/extensions/cluster_upgrade/validators.py diff --git a/nailgun/nailgun/extensions/cluster_upgrade/__init__.py b/nailgun/nailgun/extensions/cluster_upgrade/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/__init__.py b/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/alembic.ini b/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/alembic.ini deleted file mode 100644 index c0990fea2b..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/alembic.ini +++ /dev/null @@ -1,54 +0,0 @@ -# A generic, single database configuration. - -[alembic] -# path to migration scripts -script_location = migrations - -# template used to generate migration files -# file_template = %%(rev)s_%%(slug)s - -# max length of characters to apply to the -# "slug" field -#truncate_slug_length = 40 - -# set to 'true' to run the environment during -# the 'revision' command, regardless of autogenerate -# revision_environment = false - -sqlalchemy.url = driver://user:pass@localhost/dbname - - -# Logging configuration -[loggers] -keys = root,sqlalchemy,alembic - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = WARN -handlers = console -qualname = - -[logger_sqlalchemy] -level = WARN -handlers = -qualname = sqlalchemy.engine - -[logger_alembic] -level = INFO -handlers = -qualname = alembic - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(levelname)-5.5s [%(name)s] %(message)s -datefmt = %H:%M:%S diff --git a/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/__init__.py b/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/env.py b/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/env.py deleted file mode 100644 index 14343dba0c..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/env.py +++ /dev/null @@ -1,90 +0,0 @@ -# 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. - -from __future__ import with_statement - -from alembic import context -from logging.config import fileConfig -from sqlalchemy import engine_from_config -from sqlalchemy import pool - -# this is the Alembic Config object, which provides -# access to the values within the .ini file in use. -config = context.config - -# Interpret the config file for Python logging. -# This line sets up loggers basically. -fileConfig(config.config_file_name) - -# add your model's MetaData object here -# for 'autogenerate' support -# from myapp import mymodel -# target_metadata = mymodel.Base.metadata -target_metadata = None - -# other values from the config, defined by the needs of env.py, -# can be acquired: -# my_important_option = config.get_main_option("my_important_option") -# ... etc. - - -def run_migrations_offline(): - """Run migrations in 'offline' mode. - - This configures the context with just a URL - and not an Engine, though an Engine is acceptable - here as well. By skipping the Engine creation - we don't even need a DBAPI to be available. - - Calls to context.execute() here emit the given string to the - script output. - - """ - context.configure( - url=config.get_main_option('sqlalchemy.url'), - version_table=config.get_main_option('version_table')) - - with context.begin_transaction(): - context.run_migrations() - - -def run_migrations_online(): - """Run migrations in 'online' mode. - - In this scenario we need to create an Engine - and associate a connection with the context. - - """ - engine = engine_from_config( - config.get_section(config.config_ini_section), - prefix='sqlalchemy.', - poolclass=pool.NullPool) - connection = engine.connect() - - context.configure( - connection=connection, - target_metadata=target_metadata, - version_table=config.get_main_option('version_table')) - - try: - with context.begin_transaction(): - context.run_migrations() - finally: - connection.close() - - -if context.is_offline_mode(): - run_migrations_offline() -else: - run_migrations_online() diff --git a/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/script.py.mako b/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/script.py.mako deleted file mode 100644 index 43c09401bc..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/script.py.mako +++ /dev/null @@ -1,24 +0,0 @@ -"""${message} - -Revision ID: ${up_revision} -Revises: ${down_revision | comma,n} -Create Date: ${create_date} - -""" - -# revision identifiers, used by Alembic. -revision = ${repr(up_revision)} -down_revision = ${repr(down_revision)} -branch_labels = ${repr(branch_labels)} -depends_on = ${repr(depends_on)} - -from alembic import op -import sqlalchemy as sa -${imports if imports else ""} - -def upgrade(): - ${upgrades if upgrades else "pass"} - - -def downgrade(): - ${downgrades if downgrades else "pass"} diff --git a/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/versions/001_add_upgrade_relations_table.py b/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/versions/001_add_upgrade_relations_table.py deleted file mode 100644 index c55cadde74..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/alembic_migrations/migrations/versions/001_add_upgrade_relations_table.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -"""cluster_upgrade - -Revision ID: 3b5d115d7e49 -Revises: None -Create Date: 2015-07-17 19:46:59.579553 - -""" - -# revision identifiers, used by Alembic. -revision = '3b5d115d7e49' -down_revision = None - - -from alembic import context -from alembic import op - -import sqlalchemy as sa - -table_prefix = context.config.get_main_option('table_prefix') -table_upgrade_relation_name = '{0}relations'.format(table_prefix) - - -def upgrade(): - op.create_table( - table_upgrade_relation_name, - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('orig_cluster_id', sa.Integer(), nullable=False), - sa.Column('seed_cluster_id', sa.Integer(), nullable=False), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('orig_cluster_id'), - sa.UniqueConstraint('seed_cluster_id')) - - -def downgrade(): - op.drop_table(table_upgrade_relation_name) diff --git a/nailgun/nailgun/extensions/cluster_upgrade/extension.py b/nailgun/nailgun/extensions/cluster_upgrade/extension.py deleted file mode 100644 index 66df1062d0..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/extension.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -import os - -from nailgun import extensions - -from . import handlers - - -class ClusterUpgradeExtension(extensions.BaseExtension): - name = 'cluster_upgrade' - version = '0.0.1' - description = "Cluster Upgrade Extension" - - urls = [ - {'uri': r'/clusters/(?P\d+)/upgrade/clone/?$', - 'handler': handlers.ClusterUpgradeCloneHandler}, - {'uri': r'/clusters/(?P\d+)/upgrade/assign/?$', - 'handler': handlers.NodeReassignHandler}, - {'uri': r'/clusters/(?P\d+)/upgrade/vips/?$', - 'handler': handlers.CopyVIPsHandler}, - ] - - @classmethod - def alembic_migrations_path(cls): - return os.path.join(os.path.dirname(__file__), - 'alembic_migrations', 'migrations') - - @classmethod - def on_cluster_delete(cls, cluster): - from .objects import relations - - relations.UpgradeRelationObject.delete_relation(cluster.id) diff --git a/nailgun/nailgun/extensions/cluster_upgrade/handlers.py b/nailgun/nailgun/extensions/cluster_upgrade/handlers.py deleted file mode 100644 index 4f61f2e4d4..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/handlers.py +++ /dev/null @@ -1,141 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -import six - -from nailgun.api.v1.handlers import base -from nailgun import objects -from nailgun.task import manager - -from . import upgrade -from . import validators -from .objects import adapters - - -class ClusterUpgradeCloneHandler(base.BaseHandler): - single = objects.Cluster - validator = validators.ClusterUpgradeValidator - - @base.content - def POST(self, cluster_id): - """Initialize the upgrade of the cluster. - - Creates a new cluster with specified name and release_id. The - new cluster is created with parameters that are copied from the - cluster with the given cluster_id. The values of the generated - and editable attributes are just copied from one to the other. - - :param cluster_id: ID of the cluster from which parameters would - be copied - :returns: JSON representation of the created cluster - :http: * 200 (OK) - * 400 (upgrade parameters are invalid) - * 404 (node or release not found in db) - """ - orig_cluster = adapters.NailgunClusterAdapter( - self.get_object_or_404(self.single, cluster_id)) - request_data = self.checked_data(cluster=orig_cluster) - new_cluster = upgrade.UpgradeHelper.clone_cluster(orig_cluster, - request_data) - return new_cluster.to_json() - - -class NodeReassignHandler(base.BaseHandler): - single = objects.Cluster - validator = validators.NodeReassignValidator - task_manager = manager.ProvisioningTaskManager - - def handle_task(self, cluster_id, nodes): - try: - task_manager = self.task_manager(cluster_id=cluster_id) - task = task_manager.execute(nodes) - except Exception as exc: - raise self.http(400, msg=six.text_type(exc)) - - self.raise_task(task) - - @base.content - def POST(self, cluster_id): - """Reassign node to the given cluster. - - The given node will be assigned from the current cluster to the - given cluster, by default it involves the reprovisioning of this - node. If the 'reprovision' flag is set to False, then the node - will be just reassigned. If the 'roles' list is specified, then - the given roles will be used as 'pending_roles' in case of - the reprovisioning or otherwise as 'roles'. - - :param cluster_id: ID of the cluster node should be assigned to. - :returns: None - :http: * 202 (OK) - * 400 (Incorrect node state, problem with task execution, - conflicting or incorrect roles) - * 404 (Cluster or node not found) - """ - cluster = adapters.NailgunClusterAdapter( - self.get_object_or_404(self.single, cluster_id)) - - data = self.checked_data(cluster=cluster) - node = adapters.NailgunNodeAdapter( - self.get_object_or_404(objects.Node, data['node_id'])) - reprovision = data.get('reprovision', True) - given_roles = data.get('roles', []) - - roles, pending_roles = upgrade.UpgradeHelper.get_node_roles( - reprovision, node.roles, given_roles) - upgrade.UpgradeHelper.assign_node_to_cluster( - node, cluster, roles, pending_roles) - - if reprovision: - self.handle_task(cluster_id, [node.node]) - - -class CopyVIPsHandler(base.BaseHandler): - single = objects.Cluster - validator = validators.CopyVIPsValidator - - @base.content - def POST(self, cluster_id): - """Copy VIPs from original cluster to new one - - Original cluster object is obtained from existing relation between - clusters that is created on cluster clone operation - - :param cluster_id: id of cluster that VIPs must be copied to - - :http: * 200 (OK) - * 400 (validation failed) - * 404 (seed cluster is not found) - """ - from .objects import relations - - cluster = self.get_object_or_404(self.single, cluster_id) - relation = relations.UpgradeRelationObject.get_cluster_relation( - cluster.id) - - self.checked_data(cluster=cluster, relation=relation) - - # get original cluster object and create adapter with it - orig_cluster_adapter = \ - adapters.NailgunClusterAdapter( - adapters.NailgunClusterAdapter.get_by_uid( - relation.orig_cluster_id) - ) - - seed_cluster_adapter = adapters.NailgunClusterAdapter(cluster) - - upgrade.UpgradeHelper.copy_vips(orig_cluster_adapter, - seed_cluster_adapter) diff --git a/nailgun/nailgun/extensions/cluster_upgrade/models.py b/nailgun/nailgun/extensions/cluster_upgrade/models.py deleted file mode 100644 index c6f740fbbb..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/models.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -from sqlalchemy import Column -from sqlalchemy import Integer - -from nailgun.db.sqlalchemy.models.base import Base - -from . import extension - - -class UpgradeRelation(Base): - __tablename__ = '{0}relations'.format( - extension.ClusterUpgradeExtension.table_prefix()) - - id = Column(Integer, primary_key=True) - orig_cluster_id = Column(Integer, unique=True, nullable=False) - seed_cluster_id = Column(Integer, unique=True, nullable=False) diff --git a/nailgun/nailgun/extensions/cluster_upgrade/objects/__init__.py b/nailgun/nailgun/extensions/cluster_upgrade/objects/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/nailgun/nailgun/extensions/cluster_upgrade/objects/adapters.py b/nailgun/nailgun/extensions/cluster_upgrade/objects/adapters.py deleted file mode 100644 index 3348229517..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/objects/adapters.py +++ /dev/null @@ -1,211 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -from nailgun import objects - - -class NailgunClusterAdapter(object): - def __init__(self, cluster): - self.cluster = cluster - - @classmethod - def create(cls, data): - cluster = objects.Cluster.create(data) - return cls(cluster) - - @property - def id(self): - return self.cluster.id - - @property - def name(self): - return self.cluster.name - - @property - def net_provider(self): - return self.cluster.net_provider - - @property - def release(self): - return NailgunReleaseAdapter(self.cluster.release) - - @property - def attributes(self): - return self.cluster.attributes - - @property - def generated_attrs(self): - return self.cluster.attributes.generated - - @generated_attrs.setter - def generated_attrs(self, attrs): - self.cluster.attributes.generated = attrs - - @property - def editable_attrs(self): - return self.cluster.attributes.editable - - @property - def network_template(self): - return self.cluster.network_config.configuration_template - - @editable_attrs.setter - def editable_attrs(self, attrs): - self.cluster.attributes.editable = attrs - - def get_create_data(self): - return objects.Cluster.get_create_data(self.cluster) - - def get_network_manager(self): - net_manager = objects.Cluster.get_network_manager( - instance=self.cluster) - return NailgunNetworkManager(self.cluster, net_manager) - - def to_json(self): - return objects.Cluster.to_json(self.cluster) - - @classmethod - def get_by_uid(cls, cluster_id): - cluster = objects.Cluster.get_by_uid(cluster_id) - return cls(cluster) - - def get_network_groups(self): - return (NailgunNetworkGroupAdapter(ng) - for ng in self.cluster.network_groups) - - def get_admin_network_group(self): - return objects.NetworkGroup.get_admin_network_group() - - -class NailgunReleaseAdapter(object): - def __init__(self, release): - self.release = release - - @classmethod - def get_by_uid(cls, uid, fail_if_not_found=False): - release = objects.Release.get_by_uid( - uid, fail_if_not_found=fail_if_not_found) - return release - - @property - def is_deployable(self): - return objects.Release.is_deployable(self.release) - - @property - def environment_version(self): - return self.release.environment_version - - @property - def roles_metadata(self): - return self.release.roles_metadata - - def __cmp__(self, other): - if isinstance(other, NailgunReleaseAdapter): - other = other.release - return self.release.__cmp__(other) - - -class NailgunNetworkManager(object): - def __init__(self, cluster, net_manager): - self.cluster = cluster - self.net_manager = net_manager - - def update(self, network_configuration): - self.net_manager.update(self.cluster, network_configuration) - - def get_assigned_vips(self): - return self.net_manager.get_assigned_vips(self.cluster) - - def assign_vips_for_net_groups(self): - return self.net_manager.assign_vips_for_net_groups(self.cluster) - - def assign_given_vips_for_net_groups(self, vips): - self.net_manager.assign_given_vips_for_net_groups(self.cluster, vips) - - def set_node_netgroups_ids(self, node, mapping): - return objects.Node.set_netgroups_ids(node.node, mapping) - - def set_nic_assignment_netgroups_ids(self, node, mapping): - return objects.Node.set_nic_assignment_netgroups_ids( - node.node, mapping) - - def set_bond_assignment_netgroups_ids(self, node, mapping): - return objects.Node.set_bond_assignment_netgroups_ids( - node.node, mapping) - - -class NailgunNodeAdapter(object): - - def __new__(cls, node=None): - if not node: - return None - return super(NailgunNodeAdapter, cls).__new__(cls, node) - - def __init__(self, node): - self.node = node - - @property - def id(self): - return self.node.id - - @property - def cluster_id(self): - return self.node.cluster_id - - @property - def hostname(self): - return self.node.hostname - - @hostname.setter - def hostname(self, hostname): - self.node.hostname = hostname - - @property - def status(self): - return self.node.status - - @property - def error_type(self): - return self.node.error_type - - @classmethod - def get_by_uid(cls, node_id): - return cls(objects.Node.get_by_uid(node_id)) - - @property - def roles(self): - return self.node.roles - - def update_cluster_assignment(self, cluster, roles, pending_roles): - objects.Node.update_cluster_assignment(self.node, cluster, roles, - pending_roles) - - def add_pending_change(self, change): - objects.Node.add_pending_change(self.node, change) - - -class NailgunNetworkGroupAdapter(object): - - def __init__(self, network_group): - self.network_group = network_group - - @property - def id(self): - return self.network_group.id - - @property - def name(self): - return self.network_group.name diff --git a/nailgun/nailgun/extensions/cluster_upgrade/objects/relations.py b/nailgun/nailgun/extensions/cluster_upgrade/objects/relations.py deleted file mode 100644 index 5e2acc8cf5..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/objects/relations.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -from nailgun.db import db - -from .. import models - - -class UpgradeRelationObject(object): - @staticmethod - def _query_cluster_relations(cluster_id): - return db.query(models.UpgradeRelation).filter( - (models.UpgradeRelation.orig_cluster_id == cluster_id) | - (models.UpgradeRelation.seed_cluster_id == cluster_id)) - - @classmethod - def get_cluster_relation(cls, cluster_id): - return cls._query_cluster_relations(cluster_id).first() - - @classmethod - def delete_relation(cls, cluster_id): - cls._query_cluster_relations(cluster_id).delete() - - @classmethod - def is_cluster_in_upgrade(cls, cluster_id): - query = cls._query_cluster_relations(cluster_id).exists() - return db.query(query).scalar() - - @classmethod - def create_relation(cls, orig_cluster_id, seed_cluster_id): - relation = models.UpgradeRelation( - orig_cluster_id=orig_cluster_id, - seed_cluster_id=seed_cluster_id) - db.add(relation) - db.flush() diff --git a/nailgun/nailgun/extensions/cluster_upgrade/tests/__init__.py b/nailgun/nailgun/extensions/cluster_upgrade/tests/__init__.py deleted file mode 100644 index 86c153e448..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/tests/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2013 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. - -EXTENSION = "nailgun.extensions.cluster_upgrade." diff --git a/nailgun/nailgun/extensions/cluster_upgrade/tests/base.py b/nailgun/nailgun/extensions/cluster_upgrade/tests/base.py deleted file mode 100644 index 497656fda8..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/tests/base.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -from nailgun import consts -from nailgun.test import base as nailgun_test_base - -from .. import upgrade -from ..objects import adapters - - -class BaseCloneClusterTest(nailgun_test_base.BaseIntegrationTest): - helper = upgrade.UpgradeHelper - - def setUp(self): - super(BaseCloneClusterTest, self).setUp() - self.src_release = self.env.create_release( - operating_system=consts.RELEASE_OS.ubuntu, - version="2014.2.2-6.1", - state=consts.RELEASE_STATES.manageonly - ) - - self.dst_release = self.env.create_release( - operating_system=consts.RELEASE_OS.ubuntu, - version="liberty-9.0", - ) - - self.src_cluster_db = self.env.create( - cluster_kwargs={ - 'api': False, - 'release_id': self.src_release.id, - 'net_provider': consts.CLUSTER_NET_PROVIDERS.neutron, - 'net_l23_provider': consts.NEUTRON_L23_PROVIDERS.ovs, - }, - nodes_kwargs=[{'roles': ['controller']}] - ) - self.src_cluster = adapters.NailgunClusterAdapter( - self.src_cluster_db) - - self.data = { - "name": "cluster-clone-{0}".format(self.src_cluster.id), - "release_id": self.dst_release.id, - } diff --git a/nailgun/nailgun/extensions/cluster_upgrade/tests/test_db_migrations.py b/nailgun/nailgun/extensions/cluster_upgrade/tests/test_db_migrations.py deleted file mode 100644 index 16ce49c55e..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/tests/test_db_migrations.py +++ /dev/null @@ -1,47 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -import alembic - -from nailgun import db -from nailgun.db.migration import make_alembic_config_from_extension -from nailgun.test import base - -from .. import extension - - -_test_revision = '3b5d115d7e49' - - -def setup_module(module): - alembic_config = make_alembic_config_from_extension( - extension.ClusterUpgradeExtension) - db.dropdb() - alembic.command.upgrade(alembic_config, _test_revision) - - -class TestAddRelations(base.BaseAlembicMigrationTest): - - def test_works_without_core_migrations(self): - columns = [ - t.name for t in - self.meta.tables['cluster_upgrade_relations'].columns] - - self.assertItemsEqual(columns, [ - 'id', - 'orig_cluster_id', - 'seed_cluster_id', - ]) diff --git a/nailgun/nailgun/extensions/cluster_upgrade/tests/test_extension.py b/nailgun/nailgun/extensions/cluster_upgrade/tests/test_extension.py deleted file mode 100644 index 92bff1da70..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/tests/test_extension.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -import mock -from nailgun.test.base import BaseTestCase - -from .. import extension -from ..objects import relations - - -class TestExtension(BaseTestCase): - @mock.patch.object(relations.UpgradeRelationObject, "delete_relation") - def test_on_cluster_delete(self, mock_on_cluster_delete): - cluster = mock.Mock(id=42) - extension.ClusterUpgradeExtension.on_cluster_delete(cluster) - mock_on_cluster_delete.assert_called_once_with(42) diff --git a/nailgun/nailgun/extensions/cluster_upgrade/tests/test_handlers.py b/nailgun/nailgun/extensions/cluster_upgrade/tests/test_handlers.py deleted file mode 100644 index cc82acb865..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/tests/test_handlers.py +++ /dev/null @@ -1,249 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -import mock - -from oslo_serialization import jsonutils - -from nailgun import consts -from nailgun.test import base -from nailgun.utils import reverse - -from . import base as tests_base - - -class TestClusterUpgradeCloneHandler(tests_base.BaseCloneClusterTest): - def test_clone(self): - resp = self.app.post( - reverse("ClusterUpgradeCloneHandler", - kwargs={"cluster_id": self.src_cluster.id}), - jsonutils.dumps(self.data), - headers=self.default_headers) - body = resp.json_body - self.assertEqual(resp.status_code, 200) - self.assertEqual(body["name"], - "cluster-clone-{0}".format(self.src_cluster.id)) - self.assertEqual(body["release_id"], self.dst_release.id) - - def test_clone_cluster_not_found_error(self): - resp = self.app.post( - reverse("ClusterUpgradeCloneHandler", - kwargs={"cluster_id": 42}), - jsonutils.dumps(self.data), - headers=self.default_headers, - expect_errors=True) - self.assertEqual(resp.status_code, 404) - self.assertEqual(resp.json_body["message"], "Cluster not found") - - def test_clone_cluster_already_in_upgrade_error(self): - self.app.post( - reverse("ClusterUpgradeCloneHandler", - kwargs={"cluster_id": self.src_cluster.id}), - jsonutils.dumps(self.data), - headers=self.default_headers) - resp = self.app.post( - reverse("ClusterUpgradeCloneHandler", - kwargs={"cluster_id": self.src_cluster.id}), - jsonutils.dumps(self.data), - headers=self.default_headers, - expect_errors=True) - self.assertEqual(resp.status_code, 400) - - def test_clone_cluster_name_already_exists_error(self): - data = dict(self.data, name=self.src_cluster.name) - resp = self.app.post( - reverse("ClusterUpgradeCloneHandler", - kwargs={"cluster_id": self.src_cluster.id}), - jsonutils.dumps(data), - headers=self.default_headers, - expect_errors=True) - self.assertEqual(resp.status_code, 409) - - -class TestNodeReassignHandler(base.BaseIntegrationTest): - - @mock.patch('nailgun.task.task.rpc.cast') - def test_node_reassign_handler(self, mcast): - cluster = self.env.create( - cluster_kwargs={'api': False}, - nodes_kwargs=[{'status': consts.NODE_STATUSES.ready}]) - seed_cluster = self.env.create_cluster() - node_id = cluster.nodes[0]['id'] - - resp = self.app.post( - reverse('NodeReassignHandler', - kwargs={'cluster_id': seed_cluster['id']}), - jsonutils.dumps({'node_id': node_id}), - headers=self.default_headers) - self.assertEqual(202, resp.status_code) - - args, kwargs = mcast.call_args - nodes = args[1]['args']['provisioning_info']['nodes'] - provisioned_uids = [int(n['uid']) for n in nodes] - self.assertEqual([node_id, ], provisioned_uids) - - @mock.patch('nailgun.task.task.rpc.cast') - def test_node_reassign_handler_with_roles(self, mcast): - cluster = self.env.create( - cluster_kwargs={'api': False}, - nodes_kwargs=[{'status': consts.NODE_STATUSES.ready, - 'roles': ['controller']}]) - node = cluster.nodes[0] - seed_cluster = self.env.create_cluster(api=False) - - # NOTE(akscram): reprovision=True means that the node will be - # re-provisioned during the reassigning. This is - # a default behavior. - data = {'node_id': node.id, - 'reprovision': True, - 'roles': ['compute']} - resp = self.app.post( - reverse('NodeReassignHandler', - kwargs={'cluster_id': seed_cluster.id}), - jsonutils.dumps(data), - headers=self.default_headers) - self.assertEqual(202, resp.status_code) - self.assertEqual(node.roles, []) - self.assertEqual(node.pending_roles, ['compute']) - self.assertTrue(mcast.called) - - @mock.patch('nailgun.task.task.rpc.cast') - def test_node_reassign_handler_without_reprovisioning(self, mcast): - cluster = self.env.create( - cluster_kwargs={'api': False}, - nodes_kwargs=[{'status': consts.NODE_STATUSES.ready, - 'roles': ['controller']}]) - node = cluster.nodes[0] - seed_cluster = self.env.create_cluster(api=False) - - data = {'node_id': node.id, - 'reprovision': False, - 'roles': ['compute']} - resp = self.app.post( - reverse('NodeReassignHandler', - kwargs={'cluster_id': seed_cluster.id}), - jsonutils.dumps(data), - headers=self.default_headers) - self.assertEqual(200, resp.status_code) - self.assertFalse(mcast.called) - self.assertEqual(node.roles, ['compute']) - - def test_node_reassign_handler_no_node(self): - cluster = self.env.create_cluster() - - resp = self.app.post( - reverse('NodeReassignHandler', - kwargs={'cluster_id': cluster['id']}), - jsonutils.dumps({'node_id': 42}), - headers=self.default_headers, - expect_errors=True) - self.assertEqual(404, resp.status_code) - self.assertEqual("Node with id 42 was not found.", - resp.json_body['message']) - - def test_node_reassing_handler_wrong_status(self): - cluster = self.env.create( - cluster_kwargs={'api': False}, - nodes_kwargs=[{'status': 'discover'}]) - - resp = self.app.post( - reverse('NodeReassignHandler', - kwargs={'cluster_id': cluster['id']}), - jsonutils.dumps({'node_id': cluster.nodes[0]['id']}), - headers=self.default_headers, - expect_errors=True) - self.assertEqual(400, resp.status_code) - self.assertRegexpMatches(resp.json_body['message'], - "^Node should be in one of statuses:") - - def test_node_reassing_handler_wrong_error_type(self): - cluster = self.env.create( - cluster_kwargs={'api': False}, - nodes_kwargs=[{'status': 'error', - 'error_type': 'provision'}]) - - resp = self.app.post( - reverse('NodeReassignHandler', - kwargs={'cluster_id': cluster['id']}), - jsonutils.dumps({'node_id': cluster.nodes[0]['id']}), - headers=self.default_headers, - expect_errors=True) - self.assertEqual(400, resp.status_code) - self.assertRegexpMatches(resp.json_body['message'], - "^Node should be in error state") - - def test_node_reassign_handler_to_the_same_cluster(self): - cluster = self.env.create( - cluster_kwargs={'api': False}, - nodes_kwargs=[{'status': 'ready'}]) - - cluster_id = cluster['id'] - node_id = cluster.nodes[0]['id'] - resp = self.app.post( - reverse('NodeReassignHandler', - kwargs={'cluster_id': cluster_id}), - jsonutils.dumps({'node_id': node_id}), - headers=self.default_headers, - expect_errors=True) - self.assertEqual(400, resp.status_code) - self.assertEqual("Node {0} is already assigned to cluster {1}". - format(node_id, cluster_id), - resp.json_body['message']) - - def test_node_reassign_handler_with_empty_data(self): - cluster = self.env.create_cluster(api=False) - resp = self.app.post( - reverse('NodeReassignHandler', - kwargs={'cluster_id': cluster.id}), - "{}", - headers=self.default_headers, - expect_errors=True) - self.assertEqual(400, resp.status_code) - - def test_node_reassign_handler_with_empty_body(self): - cluster = self.env.create_cluster(api=False) - resp = self.app.post( - reverse('NodeReassignHandler', - kwargs={'cluster_id': cluster.id}), - "", - headers=self.default_headers, - expect_errors=True) - self.assertEqual(400, resp.status_code) - - -class TestCopyVipsHandler(base.BaseIntegrationTest): - - def test_copy_vips_called(self): - from ..objects import relations - - orig_cluster = self.env.create_cluster(api=False) - new_cluster = self.env.create_cluster(api=False) - - relations.UpgradeRelationObject.create_relation( - orig_cluster.id, new_cluster.id) - - with mock.patch('nailgun.extensions.cluster_upgrade.handlers' - '.upgrade.UpgradeHelper.copy_vips') as copy_vips_mc: - resp = self.app.post( - reverse( - 'CopyVIPsHandler', - kwargs={'cluster_id': new_cluster.id} - ), - headers=self.default_headers, - ) - - self.assertEqual(resp.status_code, 200) - self.assertTrue(copy_vips_mc.called) diff --git a/nailgun/nailgun/extensions/cluster_upgrade/tests/test_objects.py b/nailgun/nailgun/extensions/cluster_upgrade/tests/test_objects.py deleted file mode 100644 index 746b9ec2cf..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/tests/test_objects.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -from nailgun.test.base import BaseIntegrationTest - -from .. import models -from ..objects import relations as objects - - -class TestUpgradeRelationObject(BaseIntegrationTest): - def test_get_and_create_relation(self): - objects.UpgradeRelationObject.create_relation(1, 2) - rel0 = objects.UpgradeRelationObject.get_cluster_relation(1) - self.assertEqual(rel0.orig_cluster_id, 1) - self.assertEqual(rel0.seed_cluster_id, 2) - rel1 = objects.UpgradeRelationObject.get_cluster_relation(2) - self.assertEqual(rel1.orig_cluster_id, 1) - self.assertEqual(rel1.seed_cluster_id, 2) - - def test_is_cluster_in_upgrade(self): - objects.UpgradeRelationObject.create_relation(1, 2) - in_upgrade = objects.UpgradeRelationObject.is_cluster_in_upgrade - self.assertTrue(in_upgrade(1)) - self.assertTrue(in_upgrade(2)) - - def test_is_cluster_not_in_upgrade(self): - self.assertEqual(self.db.query(models.UpgradeRelation).count(), 0) - in_upgrade = objects.UpgradeRelationObject.is_cluster_in_upgrade - self.assertFalse(in_upgrade(1)) - self.assertFalse(in_upgrade(2)) - - def test_delete_relation(self): - objects.UpgradeRelationObject.create_relation(1, 2) - objects.UpgradeRelationObject.delete_relation(1) - self.assertEqual(self.db.query(models.UpgradeRelation).count(), 0) diff --git a/nailgun/nailgun/extensions/cluster_upgrade/tests/test_upgrade.py b/nailgun/nailgun/extensions/cluster_upgrade/tests/test_upgrade.py deleted file mode 100644 index e762696490..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/tests/test_upgrade.py +++ /dev/null @@ -1,212 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -import copy -import six - -from nailgun import consts -from nailgun.extensions.cluster_upgrade.upgrade import merge_attributes -from nailgun.extensions.network_manager.objects.serializers import \ - network_configuration - -from . import base as base_tests -from ..objects import adapters -from ..objects import relations - - -class TestUpgradeHelperCloneCluster(base_tests.BaseCloneClusterTest): - - def setUp(self): - super(TestUpgradeHelperCloneCluster, self).setUp() - - self.orig_net_manager = self.src_cluster.get_network_manager() - - self.serialize_nets = network_configuration.\ - NeutronNetworkConfigurationSerializer.\ - serialize_for_cluster - - self.public_net_data = { - "cidr": "192.168.42.0/24", - "gateway": "192.168.42.1", - "ip_ranges": [["192.168.42.5", "192.168.42.11"]], - } - - def test_merge_attributes(self): - src_editable_attrs = { - "test": - {"metadata": "src_fake", - "key": - {"type": "text", - "value": "fake1, fake2,fake3 , fake4"}, - "src_key": "src_data" - }, - "repo_setup": "src_data" - } - - new_editable_attrs = { - "test": - {"metadata": "new_fake", - "key": - {"type": "text_list", - "value": "fake"}, - "new_key": "new_data" - }, - "repo_setup": "new_data" - } - result = merge_attributes(src_editable_attrs, new_editable_attrs) - new_editable_attrs["test"]["key"]["value"] = \ - [value.strip() for value in - src_editable_attrs["test"]["key"]["value"].split(',')] - self.assertEqual(result, new_editable_attrs) - - def test_create_cluster_clone(self): - new_cluster = self.helper.create_cluster_clone(self.src_cluster, - self.data) - src_cluster_data = self.src_cluster.get_create_data() - new_cluster_data = new_cluster.get_create_data() - for key, value in src_cluster_data.items(): - if key in ("name", "release_id"): - continue - self.assertEqual(value, new_cluster_data[key]) - - def test_copy_attributes(self): - new_cluster = self.helper.create_cluster_clone(self.src_cluster, - self.data) - self.assertNotEqual(self.src_cluster.generated_attrs, - new_cluster.generated_attrs) - - # Do some unordinary changes - attrs = copy.deepcopy(self.src_cluster.editable_attrs) - attrs["access"]["user"]["value"] = "operator" - attrs["access"]["password"]["value"] = "secrete" - self.src_cluster.editable_attrs = attrs - - self.helper.copy_attributes(self.src_cluster, new_cluster) - - self.assertEqual(self.src_cluster.generated_attrs, - new_cluster.generated_attrs) - editable_attrs = self.src_cluster.editable_attrs - for section, params in six.iteritems(new_cluster.editable_attrs): - if section == "repo_setup": - continue - for key, value in six.iteritems(params): - if key == "metadata": - continue - self.assertEqual(editable_attrs[section][key]["value"], - value["value"]) - - def update_public_net_params(self, networks): - pub_net = self._get_pub_net(networks) - pub_net.update(self.public_net_data) - self.orig_net_manager.update(networks) - - def _get_pub_net(self, networks): - return next(net for net in networks['networks'] if - net['name'] == consts.NETWORKS.public) - - def test_copy_network_config(self): - new_cluster = self.helper.create_cluster_clone(self.src_cluster, - self.data) - # Do some unordinary changes to public network - nets = self.serialize_nets(self.src_cluster.cluster) - self.update_public_net_params(nets) - - self.helper.copy_network_config(self.src_cluster, new_cluster) - - new_nets = self.serialize_nets(new_cluster.cluster) - - public_net = self._get_pub_net(new_nets) - - self.assertEqual(public_net['cidr'], self.public_net_data['cidr']) - self.assertEqual(public_net['gateway'], - self.public_net_data['gateway']) - self.assertEqual(public_net['ip_ranges'], - self.public_net_data['ip_ranges']) - - def test_copy_vips(self): - # save network information before node reassignment to seed cluster - # as after that no VIP will be allocated/serialized due to - # absence of assigned nodes for the source cluster - orig_nets = self.serialize_nets(self.src_cluster.cluster) - - new_cluster = self.helper.clone_cluster(self.src_cluster, self.data) - - # we have to move node to new cluster before VIP assignment - # because there is no point in the operation for a cluster - # w/o nodes - node = adapters.NailgunNodeAdapter(self.src_cluster.cluster.nodes[0]) - self.helper.assign_node_to_cluster(node, new_cluster, node.roles, []) - - self.helper.copy_vips(self.src_cluster, new_cluster) - - new_nets = self.serialize_nets(new_cluster.cluster) - - self.assertEqual(orig_nets["management_vip"], - new_nets["management_vip"]) - self.assertEqual(orig_nets["management_vrouter_vip"], - new_nets["management_vrouter_vip"]) - self.assertEqual(orig_nets["public_vip"], - new_nets["public_vip"]) - self.assertEqual(orig_nets["public_vrouter_vip"], - new_nets["public_vrouter_vip"]) - - def test_clone_cluster(self): - self.orig_net_manager.assign_vips_for_net_groups() - new_cluster = self.helper.clone_cluster(self.src_cluster, self.data) - relation = relations.UpgradeRelationObject.get_cluster_relation( - self.src_cluster.id) - self.assertEqual(relation.orig_cluster_id, self.src_cluster.id) - self.assertEqual(relation.seed_cluster_id, new_cluster.id) - - def _check_dns_and_ntp_list_values(self, new_cluster, dns_list, ntp_list): - self.assertEqual( - new_cluster.editable_attrs["external_ntp"]["ntp_list"]["value"], - ntp_list) - self.assertEqual( - new_cluster.editable_attrs["external_dns"]["dns_list"]["value"], - dns_list) - self.assertEqual( - new_cluster.editable_attrs["external_ntp"]["ntp_list"]["type"], - "text_list") - self.assertEqual( - new_cluster.editable_attrs["external_dns"]["dns_list"]["type"], - "text_list") - - def test_cluster_copy_attrs_with_different_types_dns_and_ntp_lists(self): - attrs = copy.deepcopy(self.src_cluster.editable_attrs) - attrs["external_ntp"]["ntp_list"]["type"] = "text" - attrs["external_ntp"]["ntp_list"]["value"] = "1,2,3" - attrs["external_dns"]["dns_list"]["type"] = "text" - attrs["external_dns"]["dns_list"]["value"] = "4,5,6" - self.src_cluster.editable_attrs = attrs - new_cluster = self.helper.create_cluster_clone( - self.src_cluster, self.data) - self.helper.copy_attributes(self.src_cluster, new_cluster) - self._check_dns_and_ntp_list_values( - new_cluster, ["4", "5", "6"], ["1", "2", "3"]) - - def test_cluster_copy_attrs_with_same_types_dns_and_ntp_lists(self): - attrs = copy.deepcopy(self.src_cluster.editable_attrs) - attrs["external_ntp"]["ntp_list"]["type"] = "text_list" - attrs["external_ntp"]["ntp_list"]["value"] = ["1", "2", "3"] - attrs["external_dns"]["dns_list"]["type"] = "text_list" - attrs["external_dns"]["dns_list"]["value"] = ["4", "5", "6"] - self.src_cluster.editable_attrs = attrs - new_cluster = self.helper.create_cluster_clone( - self.src_cluster, self.data) - self.helper.copy_attributes(self.src_cluster, new_cluster) - self._check_dns_and_ntp_list_values( - new_cluster, ["4", "5", "6"], ["1", "2", "3"]) diff --git a/nailgun/nailgun/extensions/cluster_upgrade/tests/test_validators.py b/nailgun/nailgun/extensions/cluster_upgrade/tests/test_validators.py deleted file mode 100644 index 056c1cb308..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/tests/test_validators.py +++ /dev/null @@ -1,230 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -import mock - -from oslo_serialization import jsonutils - -from nailgun import consts -from nailgun import errors -from nailgun.settings import settings -from nailgun.test import base - -from .. import validators -from . import base as tests_base -from . import EXTENSION -from ..objects import relations - - -class TestClusterUpgradeValidator(tests_base.BaseCloneClusterTest): - validator = validators.ClusterUpgradeValidator - - def test_validate_release_upgrade(self): - self.validator.validate_release_upgrade(self.src_release, - self.dst_release) - - @mock.patch.dict(settings.VERSION, {'feature_groups': []}) - def test_validate_release_upgrade_deprecated_release(self): - release_511 = self.env.create_release( - operating_system=consts.RELEASE_OS.ubuntu, - version="2014.1.3-5.1.1", - state=consts.RELEASE_STATES.manageonly - ) - msg = "^Upgrade to the given release \({0}\).*is deprecated and " \ - "cannot be installed\.$".format(self.src_release.id) - with self.assertRaisesRegexp(errors.InvalidData, msg): - self.validator.validate_release_upgrade(release_511, - self.src_release) - - def test_validate_release_upgrade_to_older_release(self): - self.src_release.state = consts.RELEASE_STATES.available - msg = "^Upgrade to the given release \({0}\).*release is equal or " \ - "lower than the release of the original cluster\.$" \ - .format(self.src_release.id) - with self.assertRaisesRegexp(errors.InvalidData, msg): - self.validator.validate_release_upgrade(self.dst_release, - self.src_release) - - def test_validate_cluster_name(self): - self.validator.validate_cluster_name("cluster-42") - - def test_validate_cluster_name_already_exists(self): - msg = "^Environment with this name '{0}' already exists\.$"\ - .format(self.src_cluster.name) - with self.assertRaisesRegexp(errors.AlreadyExists, msg): - self.validator.validate_cluster_name(self.src_cluster.name) - - def test_validate_cluster_status(self): - self.validator.validate_cluster_status(self.src_cluster) - - def test_validate_cluster_status_invalid(self): - dst_cluster = self.env.create_cluster( - api=False, - release_id=self.dst_release.id, - ) - relations.UpgradeRelationObject.create_relation(self.src_cluster.id, - dst_cluster.id) - msg = "^Upgrade is not possible because of the original cluster " \ - "\({0}\) is already involved in the upgrade routine\.$" \ - .format(self.src_cluster.id) - with self.assertRaisesRegexp(errors.InvalidData, msg): - self.validator.validate_cluster_status(self.src_cluster) - - def test_validate(self): - data = jsonutils.dumps(self.data) - self.validator.validate(data, self.src_cluster) - - def test_validate_invalid_data(self): - data = "{}" - with self.assertRaises(errors.InvalidData): - self.validator.validate(data, self.src_cluster) - - -class TestNodeReassignValidator(base.BaseTestCase): - validator = validators.NodeReassignValidator - - @mock.patch(EXTENSION + "validators.adapters.NailgunNodeAdapter." - "get_by_uid") - def test_validate_node_not_found(self, mock_gbu): - mock_gbu.return_value = None - with self.assertRaises(errors.ObjectNotFound): - self.validator.validate_node(42) - - @mock.patch(EXTENSION + "validators.adapters.NailgunNodeAdapter." - "get_by_uid") - def test_validate_node_wrong_status(self, mock_gbu): - mock_gbu.return_value = mock.Mock(status='wrong_state') - with self.assertRaises(errors.InvalidData): - self.validator.validate_node(42) - - @mock.patch(EXTENSION + "validators.adapters.NailgunNodeAdapter." - "get_by_uid") - def test_validate_node_wrong_error_type(self, mock_gbu): - mock_gbu.return_value = mock.Mock(status='error', - error_type='wrong') - with self.assertRaises(errors.InvalidData): - self.validator.validate_node(42) - - def test_validate_node_cluster(self): - node = mock.Mock(id=42, cluster_id=42) - cluster = mock.Mock(id=42) - with self.assertRaises(errors.InvalidData): - self.validator.validate_node_cluster(node, cluster) - - def test_validate_empty_data(self): - cluster = self.env.create_cluster(api=False) - node = self.env.create_node(cluster_id=cluster.id, - roles=["compute"], - status="ready") - msg = "^'node_id' is a required property" - with self.assertRaisesRegexp(errors.InvalidData, msg): - self.validator.validate("{}", node) - - def test_validate_empty_body(self): - cluster = self.env.create_cluster(api=False) - node = self.env.create_node(cluster_id=cluster.id, - roles=["compute"], - status="ready") - msg = "^Empty request received$" - with self.assertRaisesRegexp(errors.InvalidData, msg): - self.validator.validate("", node) - - -class TestNodeReassignNoReinstallValidator(tests_base.BaseCloneClusterTest): - validator = validators.NodeReassignValidator - - def setUp(self): - super(TestNodeReassignNoReinstallValidator, self).setUp() - self.dst_cluster = self.env.create_cluster( - api=False, - release_id=self.dst_release.id, - ) - self.node = self.env.create_node(cluster_id=self.src_cluster.id, - roles=["compute"], status="ready") - - def test_validate_defaults(self): - request = {"node_id": self.node.id} - data = jsonutils.dumps(request) - parsed = self.validator.validate(data, self.dst_cluster) - self.assertEqual(parsed, request) - self.assertEqual(self.node.roles, ['compute']) - - def test_validate_with_roles(self): - request = { - "node_id": self.node.id, - "reprovision": True, - "roles": ['controller'], - } - data = jsonutils.dumps(request) - parsed = self.validator.validate(data, self.dst_cluster) - self.assertEqual(parsed, request) - - def test_validate_not_unique_roles(self): - data = jsonutils.dumps({ - "node_id": self.node.id, - "roles": ['compute', 'compute'], - }) - msg = "has non-unique elements" - with self.assertRaisesRegexp(errors.InvalidData, msg): - self.validator.validate(data, self.dst_cluster) - - def test_validate_no_reprovision_with_conflicts(self): - data = jsonutils.dumps({ - "node_id": self.node.id, - "reprovision": False, - "roles": ['controller', 'compute'], - }) - with self.assertRaises(errors.InvalidData) as exc: - self.validator.validate(data, self.dst_cluster) - - self.assertEqual( - exc.exception.message, - "Role 'controller' in conflict with role 'compute'." - ) - - -class TestCopyVIPsValidator(base.BaseTestCase): - validator = validators.CopyVIPsValidator - - def test_non_existing_relation_fail(self): - with self.assertRaises(errors.InvalidData) as cm: - self.validator.validate(data=None, cluster=None, relation=None) - - self.assertEqual( - cm.exception.message, - "Relation for given cluster does not exist" - ) - - def test_cluster_is_not_seed(self): - cluster = self.env.create_cluster(api=False) - seed_cluster = self.env.create_cluster(api=False) - - relations.UpgradeRelationObject.create_relation( - orig_cluster_id=cluster.id, - seed_cluster_id=cluster.id, - ) - - relation = relations.UpgradeRelationObject.get_cluster_relation( - cluster.id) - - with self.assertRaises(errors.InvalidData) as cm: - self.validator.validate(data=None, cluster=seed_cluster, - relation=relation) - - self.assertEqual( - cm.exception.message, - "Given cluster is not seed cluster" - ) diff --git a/nailgun/nailgun/extensions/cluster_upgrade/upgrade.py b/nailgun/nailgun/extensions/cluster_upgrade/upgrade.py deleted file mode 100644 index b700da5055..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/upgrade.py +++ /dev/null @@ -1,238 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -import collections -import copy -from distutils import version -import six - -from nailgun import consts -from nailgun.extensions.network_manager.objects.serializers import \ - network_configuration -from nailgun import objects -from nailgun import utils - -from .objects import adapters - - -def merge_attributes(a, b): - """Merge values of editable attributes. - - The values of the b attributes have precedence over the values - of the a attributes. - """ - attrs = copy.deepcopy(b) - for section, pairs in six.iteritems(attrs): - if section == "repo_setup" or section not in a: - continue - a_values = a[section] - for key, values in six.iteritems(pairs): - if key != "metadata" and key in a_values: - values["value"] = a_values[key]["value"] - # NOTE: In the mitaka-9.0 release types of values dns_list and - # ntp_list were changed from 'text' - # (a string of comma-separated IP-addresses) - # to 'text_list' (a list of strings of IP-addresses). - if a_values[key]['type'] == 'text' and \ - values['type'] == 'text_list': - values["value"] =\ - [value.strip() for value in values['value'].split(',')] - return attrs - - -def merge_nets(a, b): - new_settings = copy.deepcopy(b) - source_networks = dict((n["name"], n) for n in a["networks"]) - for net in new_settings["networks"]: - if net["name"] not in source_networks: - continue - source_net = source_networks[net["name"]] - for key, value in six.iteritems(net): - if (key not in ("cluster_id", "id", "meta", "group_id") and - key in source_net): - net[key] = source_net[key] - networking_params = new_settings["networking_parameters"] - source_params = a["networking_parameters"] - for key, value in six.iteritems(networking_params): - if key not in source_params: - continue - networking_params[key] = source_params[key] - return new_settings - - -class UpgradeHelper(object): - network_serializers = { - consts.CLUSTER_NET_PROVIDERS.neutron: - network_configuration.NeutronNetworkConfigurationSerializer, - consts.CLUSTER_NET_PROVIDERS.nova_network: - network_configuration.NovaNetworkConfigurationSerializer, - } - - @classmethod - def clone_cluster(cls, orig_cluster, data): - from .objects import relations - - new_cluster = cls.create_cluster_clone(orig_cluster, data) - cls.copy_attributes(orig_cluster, new_cluster) - cls.copy_network_config(orig_cluster, new_cluster) - relations.UpgradeRelationObject.create_relation(orig_cluster.id, - new_cluster.id) - return new_cluster - - @classmethod - def create_cluster_clone(cls, orig_cluster, data): - create_data = orig_cluster.get_create_data() - create_data["name"] = data["name"] - create_data["release_id"] = data["release_id"] - new_cluster = adapters.NailgunClusterAdapter.create(create_data) - return new_cluster - - @classmethod - def copy_attributes(cls, orig_cluster, new_cluster): - # TODO(akscram): Attributes should be copied including - # borderline cases when some parameters are - # renamed or moved into plugins. Also, we should - # to keep special steps in copying of parameters - # that know how to translate parameters from one - # version to another. A set of this kind of steps - # should define an upgrade path of a particular - # cluster. - new_cluster.generated_attrs = utils.dict_merge( - new_cluster.generated_attrs, - orig_cluster.generated_attrs) - new_cluster.editable_attrs = merge_attributes( - orig_cluster.editable_attrs, - new_cluster.editable_attrs) - - @classmethod - def transform_vips_for_net_groups_70(cls, vips): - """Rename or remove types of VIPs for 7.0 network groups. - - This method renames types of VIPs from older releases (<7.0) to - be compatible with network groups of the 7.0 release according - to the rules: - - management: haproxy -> management - public: haproxy -> public - public: vrouter -> vrouter_pub - - Note, that in the result VIPs are present only those IPs that - correspond to the given rules. - """ - rename_vip_rules = { - "management": { - "haproxy": "management", - "vrouter": "vrouter", - }, - "public": { - "haproxy": "public", - "vrouter": "vrouter_pub", - }, - } - renamed_vips = collections.defaultdict(dict) - for ng_name, vips in six.iteritems(vips): - ng_vip_rules = rename_vip_rules[ng_name] - for vip_name, vip_addr in six.iteritems(vips): - if vip_name not in ng_vip_rules: - continue - new_vip_name = ng_vip_rules[vip_name] - renamed_vips[ng_name][new_vip_name] = vip_addr - return renamed_vips - - @classmethod - def copy_network_config(cls, orig_cluster, new_cluster): - nets_serializer = cls.network_serializers[orig_cluster.net_provider] - nets = merge_nets( - nets_serializer.serialize_for_cluster(orig_cluster.cluster), - nets_serializer.serialize_for_cluster(new_cluster.cluster)) - - new_net_manager = new_cluster.get_network_manager() - - new_net_manager.update(nets) - - @classmethod - def copy_vips(cls, orig_cluster, new_cluster): - orig_net_manager = orig_cluster.get_network_manager() - new_net_manager = new_cluster.get_network_manager() - - vips = {} - assigned_vips = orig_net_manager.get_assigned_vips() - for ng_name in (consts.NETWORKS.public, consts.NETWORKS.management): - vips[ng_name] = assigned_vips[ng_name] - # NOTE(akscram): In the 7.0 release was introduced networking - # templates that use the vip_name column as - # unique names of VIPs. - if version.LooseVersion(orig_cluster.release.environment_version) < \ - version.LooseVersion("7.0"): - vips = cls.transform_vips_for_net_groups_70(vips) - new_net_manager.assign_given_vips_for_net_groups(vips) - new_net_manager.assign_vips_for_net_groups() - - @classmethod - def get_node_roles(cls, reprovision, current_roles, given_roles): - """Return roles depending on the reprovisioning status. - - In case the node should be re-provisioned, only pending roles - should be set, otherwise for an already provisioned and deployed - node only actual roles should be set. In the both case the - given roles will have precedence over the existing. - - :param reprovision: boolean, if set to True then the node should - be re-provisioned - :param current_roles: a list of current roles of the node - :param given_roles: a list of roles that should be assigned to - the node - :returns: a tuple of a list of roles and a list of pending roles - that will be assigned to the node - """ - roles_to_assign = given_roles if given_roles else current_roles - if reprovision: - roles, pending_roles = [], roles_to_assign - else: - roles, pending_roles = roles_to_assign, [] - return roles, pending_roles - - @classmethod - def assign_node_to_cluster(cls, node, seed_cluster, roles, pending_roles): - orig_cluster = adapters.NailgunClusterAdapter.get_by_uid( - node.cluster_id) - - orig_manager = orig_cluster.get_network_manager() - - netgroups_id_mapping = cls.get_netgroups_id_mapping( - orig_cluster, seed_cluster) - - node.update_cluster_assignment(seed_cluster, roles, pending_roles) - objects.Node.set_netgroups_ids(node, netgroups_id_mapping) - - if not seed_cluster.network_template: - orig_manager.set_nic_assignment_netgroups_ids( - node, netgroups_id_mapping) - orig_manager.set_bond_assignment_netgroups_ids( - node, netgroups_id_mapping) - - node.add_pending_change(consts.CLUSTER_CHANGES.interfaces) - - @classmethod - def get_netgroups_id_mapping(self, orig_cluster, seed_cluster): - orig_ng = orig_cluster.get_network_groups() - seed_ng = seed_cluster.get_network_groups() - - seed_ng_dict = dict((ng.name, ng.id) for ng in seed_ng) - mapping = dict((ng.id, seed_ng_dict[ng.name]) for ng in orig_ng) - mapping[orig_cluster.get_admin_network_group().id] = \ - seed_cluster.get_admin_network_group().id - return mapping diff --git a/nailgun/nailgun/extensions/cluster_upgrade/validators.py b/nailgun/nailgun/extensions/cluster_upgrade/validators.py deleted file mode 100644 index 0dcd286bc3..0000000000 --- a/nailgun/nailgun/extensions/cluster_upgrade/validators.py +++ /dev/null @@ -1,164 +0,0 @@ -# -*- coding: utf-8 -*- - -# 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. - -from nailgun.api.v1.validators import assignment -from nailgun.api.v1.validators import base -from nailgun import consts -from nailgun import errors -from nailgun import objects - -from .objects import adapters - - -class ClusterUpgradeValidator(base.BasicValidator): - schema = { - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Start upgrade procedure for a cluster", - "description": "Serialized parameters to upgrade a cluster.", - "type": "object", - "properties": { - "name": {"type": "string"}, - "release_id": {"type": "number"}, - }, - "required": ["name", "release_id"], - } - - @classmethod - def validate(cls, data, cluster): - cluster = adapters.NailgunClusterAdapter(cluster) - data = super(ClusterUpgradeValidator, cls).validate(data) - cls.validate_schema(data, cls.schema) - cls.validate_cluster_status(cluster) - cls.validate_cluster_name(data["name"]) - release = adapters.NailgunReleaseAdapter.get_by_uid( - data["release_id"], fail_if_not_found=True) - cls.validate_release_upgrade(cluster.release, release) - return data - - @classmethod - def validate_release_upgrade(cls, orig_release, new_release): - if not objects.Release.is_deployable(new_release): - raise errors.InvalidData( - "Upgrade to the given release ({0}) is not possible because " - "this release is deprecated and cannot be installed." - .format(new_release.id), - log_message=True) - if orig_release >= new_release: - raise errors.InvalidData( - "Upgrade to the given release ({0}) is not possible because " - "this release is equal or lower than the release of the " - "original cluster.".format(new_release.id), - log_message=True) - - @classmethod - def validate_cluster_name(cls, cluster_name): - clusters = objects.ClusterCollection.filter_by(None, - name=cluster_name) - if clusters.first(): - raise errors.AlreadyExists( - "Environment with this name '{0}' already exists." - .format(cluster_name), - log_message=True) - - @classmethod - def validate_cluster_status(cls, cluster): - from .objects.relations import UpgradeRelationObject - - if UpgradeRelationObject.is_cluster_in_upgrade(cluster.id): - raise errors.InvalidData( - "Upgrade is not possible because of the original cluster ({0})" - " is already involved in the upgrade routine." - .format(cluster.id), - log_message=True) - - -class NodeReassignValidator(assignment.NodeAssignmentValidator): - schema = { - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "Assign Node Parameters", - "description": "Serialized parameters to assign node", - "type": "object", - "properties": { - "node_id": {"type": "number"}, - "reprovision": {"type": "boolean", "default": True}, - "roles": {"type": "array", - "items": {"type": "string"}, - "uniqueItems": True}, - }, - "required": ["node_id"], - } - - @classmethod - def validate(cls, data, cluster): - parsed = super(NodeReassignValidator, cls).validate(data) - cls.validate_schema(parsed, cls.schema) - - node = cls.validate_node(parsed['node_id']) - cls.validate_node_cluster(node, cluster) - - roles = parsed.get('roles', []) - if roles: - cls.validate_roles(cluster, roles) - else: - cls.validate_roles(cluster, node.roles) - return parsed - - @classmethod - def validate_node(cls, node_id): - node = adapters.NailgunNodeAdapter.get_by_uid(node_id) - - if not node: - raise errors.ObjectNotFound("Node with id {0} was not found.". - format(node_id), log_message=True) - - # node can go to error state while upgrade process - allowed_statuses = (consts.NODE_STATUSES.ready, - consts.NODE_STATUSES.provisioned, - consts.NODE_STATUSES.error) - if node.status not in allowed_statuses: - raise errors.InvalidData("Node should be in one of statuses: {0}." - " Currently node has {1} status.". - format(allowed_statuses, node.status), - log_message=True) - if node.status == consts.NODE_STATUSES.error and\ - node.error_type != consts.NODE_ERRORS.deploy: - raise errors.InvalidData("Node should be in error state only with" - "deploy error type. Currently error type" - " of node is {0}".format(node.error_type), - log_message=True) - return node - - @classmethod - def validate_node_cluster(cls, node, cluster): - if node.cluster_id == cluster.id: - raise errors.InvalidData("Node {0} is already assigned to cluster" - " {1}".format(node.id, cluster.id), - log_message=True) - - -class CopyVIPsValidator(base.BasicValidator): - - @classmethod - def validate(cls, data, cluster, relation): - if relation is None: - raise errors.InvalidData( - "Relation for given cluster does not exist" - ) - - if cluster.id != relation.seed_cluster_id: - raise errors.InvalidData("Given cluster is not seed cluster") - - return data diff --git a/nailgun/setup.py b/nailgun/setup.py index ff4aaeef22..f024abcd2b 100644 --- a/nailgun/setup.py +++ b/nailgun/setup.py @@ -88,8 +88,6 @@ if __name__ == "__main__": 'delete_expired_oswl_entries'), ], 'nailgun.extensions': [ - ('cluster_upgrade = nailgun.extensions.cluster_upgrade' - '.extension:ClusterUpgradeExtension'), ('volume_manager = nailgun.extensions.volume_manager' '.extension:VolumeManagerExtension'), ('network_manager = nailgun.extensions.network_manager'