Merge "Add 'deployed_before' flag to cluster that forbids stop deployment"

This commit is contained in:
Jenkins 2016-02-01 14:04:44 +00:00 committed by Gerrit Code Review
commit a9281e8d79
14 changed files with 176 additions and 5 deletions

View File

@ -562,6 +562,7 @@ class DeferredTaskHandler(BaseHandler):
errors.NoDeploymentTasks,
errors.WrongNodeStatus,
errors.UnavailableRelease,
errors.CannotBeStopped,
) as exc:
raise self.http(400, exc.message)
except Exception as exc:

View File

@ -29,6 +29,7 @@ from nailgun.api.v1.handlers.base import SingleHandler
from nailgun.api.v1.validators.cluster import AttributesValidator
from nailgun.api.v1.validators.cluster import ClusterChangesValidator
from nailgun.api.v1.validators.cluster import ClusterStopDeploymentValidator
from nailgun.api.v1.validators.cluster import ClusterValidator
from nailgun.api.v1.validators.cluster import VmwareAttributesValidator
@ -92,6 +93,7 @@ class ClusterStopDeploymentHandler(DeferredTaskHandler):
log_error = u"Error during execution of deployment " \
u"stopping task on environment '{env_id}': {error}"
task_manager = StopDeploymentTaskManager
validator = ClusterStopDeploymentValidator
class ClusterResetHandler(DeferredTaskHandler):

View File

@ -433,6 +433,19 @@ class ClusterChangesValidator(BaseDefferedTaskValidator):
ProvisionSelectedNodesValidator.validate_provision(None, cluster)
class ClusterStopDeploymentValidator(BaseDefferedTaskValidator):
@classmethod
def validate(cls, cluster):
super(ClusterStopDeploymentValidator, cls).validate(cluster)
# FIXME(aroma): remove when stop action will be reworked for ha
# cluster. To get more details, please, refer to [1]
# [1]: https://bugs.launchpad.net/fuel/+bug/1529691
if cluster.attributes.generated['deployed_before']['value']:
raise errors.CannotBeStopped()
class VmwareAttributesValidator(BasicValidator):
single_schema = cluster_schema.vmware_attributes_schema

View File

@ -42,6 +42,7 @@ default_messages = {
"NoDeploymentTasks": "Deployment tasks not found for specific release in the database",
"DeletionAlreadyStarted": "Environment removal already started",
"StopAlreadyRunning": "Stopping deployment already initiated",
"CannotBeStopped": "Stop action is forbidden for the cluster",
"FailedProvisioning": "Failed to start provisioning",
"WrongNodeStatus": "Wrong node status",
"NodeOffline": "Node is offline",

View File

@ -1351,6 +1351,8 @@
puppet:
manifests: "rsync://{settings.MASTER_IP}:/puppet/{cluster.release.version}/manifests/"
modules: "rsync://{settings.MASTER_IP}:/puppet/{cluster.release.version}/modules/"
deployed_before:
value: false
wizard_metadata:
Mode:
metadata:

View File

@ -1339,6 +1339,29 @@ class Cluster(NailgunObject):
attrs = cls.get_editable_attributes(instance, False)
return attrs['common'].get('task_deploy', {}).get('value')
# FIXME(aroma): remove updating of 'deployed_before'
# when stop action is reworked. 'deployed_before'
# flag identifies whether stop action is allowed for the
# cluster. Please, refer to [1] for more details.
# [1]: https://bugs.launchpad.net/fuel/+bug/1529691
@classmethod
def set_deployed_before_flag(cls, instance, value):
"""Change value for before_deployed if needed
:param instance: nailgun.db.sqlalchemy.models.Cluster instance
:param value: new value for flag
:type value: bool
"""
if instance.attributes.generated['deployed_before']['value'] != value:
# TODO(aroma): remove unnecessary copying when enhancement
# of Mutable types will be introduced for corresponding
# fields of ORM models
generated_attrs = copy.deepcopy(instance.attributes.generated)
generated_attrs['deployed_before']['value'] = value
instance.attributes.generated = generated_attrs
db.flush()
class ClusterCollection(NailgunCollection):
"""Cluster collection."""

View File

@ -167,7 +167,18 @@ class Task(NailgunObject):
logger.debug(
"Updating cluster (%s) status: from %s to %s",
cluster.full_name, cluster.status, status)
Cluster.update(cluster, data={'status': status})
data = {'status': status}
# FIXME(aroma): remove updating of 'deployed_before'
# when stop action is reworked. 'deployed_before'
# flag identifies whether stop action is allowed for the
# cluster. Please, refer to [1] for more details.
# [1]: https://bugs.launchpad.net/fuel/+bug/1529691
if status == consts.CLUSTER_STATUSES.operational:
Cluster.set_deployed_before_flag(cluster, value=True)
Cluster.update(cluster, data)
@classmethod
def _update_cluster_data(cls, instance):
@ -175,7 +186,7 @@ class Task(NailgunObject):
if instance.name == 'deploy':
if instance.status == 'ready':
# If for some reasosns orchestrator
# If for some reasons orchestrator
# didn't send ready status for node
# we should set it explicitly
for n in cluster.nodes:

View File

@ -747,6 +747,14 @@ class StopDeploymentTaskManager(TaskManager):
class ResetEnvironmentTaskManager(TaskManager):
def execute(self):
# FIXME(aroma): remove updating of 'deployed_before'
# when stop action is reworked. 'deployed_before'
# flag identifies whether stop action is allowed for the
# cluster. Please, refer to [1] for more details.
# [1]: https://bugs.launchpad.net/fuel/+bug/1529691
objects.Cluster.set_deployed_before_flag(self.cluster, value=False)
deploy_running = db().query(Task).filter_by(
cluster=self.cluster,
name=consts.TASK_NAMES.deploy,

View File

@ -59,6 +59,12 @@ class TestResetEnvironment(BaseIntegrationTest):
self.assertEqual(cluster_db.status, "new")
# FIXME(aroma): remove when stop action will be reworked for ha
# cluster. To get more details, please, refer to [1]
# [1]: https://bugs.launchpad.net/fuel/+bug/1529691
self.assertFalse(
cluster_db.attributes.generated['deployed_before']['value'])
for n in cluster_db.nodes:
self.assertEqual(n.online, False)
self.assertEqual(n.status, "discover")

View File

@ -23,6 +23,7 @@ from nailgun.db.sqlalchemy.models.task import Task
from nailgun import objects
from nailgun.test.base import BaseIntegrationTest
from nailgun.test.base import fake_tasks
from nailgun.test.base import reverse
class TestStopDeployment(BaseIntegrationTest):
@ -78,6 +79,42 @@ class TestStopDeployment(BaseIntegrationTest):
'Please make changes and reset the environment '
'if you want to redeploy it.')
# FIXME(aroma): remove when stop action will be reworked for ha
# cluster. To get more details, please, refer to [1]
# [1]: https://bugs.launchpad.net/fuel/+bug/1529691
@fake_tasks(tick_interval=1)
def test_stop_deployment_fail_if_deployed_before(self):
deploy_task = self.env.launch_deployment()
self.env.wait_ready(deploy_task)
# changes to deploy
self.env.create_node(
cluster_id=self.cluster.id,
roles=["controller"],
pending_addition=True
)
redeploy_task = self.env.launch_deployment()
self.env.wait_until_task_pending(redeploy_task)
# stop task will not be created as in this situation
# the error will be raised by validator thus we cannot use
# self.env.stop_deployment to check the result
resp = self.app.put(
reverse(
'ClusterStopDeploymentHandler',
kwargs={'cluster_id': self.cluster.id}),
expect_errors=True,
headers=self.default_headers
)
self.assertEqual(resp.status_code, 400)
self.assertEqual(resp.json_body['message'],
'Stop action is forbidden for the cluster')
# wait that redeployment end successfully
self.env.wait_ready(redeploy_task)
@fake_tasks(fake_rpc=False, mock_rpc=False)
@patch('nailgun.rpc.cast')
def test_admin_ip_in_args(self, mocked_rpc):

View File

@ -14,7 +14,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from mock import patch
from nailgun.test.base import BaseIntegrationTest
@ -162,6 +161,13 @@ class TestTasksLogging(BaseIntegrationTest):
self.env.wait_ready(deploy)
self.simulate_running_deployment(deploy)
# FIXME(aroma): remove when stop action will be reworked for ha
# cluster. To get more details, please, refer to [1]
# [1]: https://bugs.launchpad.net/fuel/+bug/1529691
cluster = self.env.clusters[0]
objects.Cluster.set_deployed_before_flag(cluster, value=False)
self.env.stop_deployment()
self.assertGreaterEqual(len(logger.call_args_list), 1)
@ -283,6 +289,12 @@ class TestTasksLogging(BaseIntegrationTest):
deploy_uuid = deploy.uuid
self.simulate_running_deployment(deploy)
# FIXME(aroma): remove when stop action will be reworked for ha
# cluster. To get more details, please, refer to [1]
# [1]: https://bugs.launchpad.net/fuel/+bug/1529691
cluster = self.env.clusters[0]
objects.Cluster.set_deployed_before_flag(cluster, value=False)
# Stopping deployment
self.env.stop_deployment()

View File

@ -22,6 +22,7 @@ from six.moves import range
import unittest2
from nailgun import consts
from nailgun import objects
from nailgun.test.base import BaseIntegrationTest
from nailgun.test.base import fake_tasks
from nailgun.utils import reverse
@ -691,6 +692,12 @@ class TestVerifyNeutronVlan(BaseIntegrationTest):
cluster = self.env.clusters[0]
deploy_task = self.env.launch_deployment()
self.env.wait_until_task_pending(deploy_task)
# FIXME(aroma): remove when stop action will be reworked for ha
# cluster. To get more details, please, refer to [1]
# [1]: https://bugs.launchpad.net/fuel/+bug/1529691
objects.Cluster.set_deployed_before_flag(cluster, value=False)
stop_task = self.env.stop_deployment()
self.env.wait_ready(stop_task, 60)
self.db.refresh(cluster)

View File

@ -18,9 +18,11 @@ from mock import patch
from mock import PropertyMock
from oslo_serialization import jsonutils
from nailgun.api.v1.validators.cluster import ClusterStopDeploymentValidator
from nailgun.api.v1.validators.cluster import ClusterValidator
from nailgun import consts
from nailgun.errors import errors
from nailgun import objects
from nailgun.test.base import BaseTestCase
@ -214,3 +216,20 @@ class TestClusterValidator(BaseTestCase):
ClusterValidator.validate_update,
self.cluster_data,
cluster_mock)
class TestClusterStopDeploymentValidator(BaseTestCase):
# FIXME(aroma): remove this test when stop action will be reworked for ha
# cluster. To get more details, please, refer to [1]
# [1]: https://bugs.launchpad.net/fuel/+bug/1529691
def test_stop_deployment_failed_for_once_deployed_cluster(self):
cluster = self.env.create_cluster(api=False)
objects.Cluster.set_deployed_before_flag(cluster, value=True)
self.assertRaises(
errors.CannotBeStopped,
ClusterStopDeploymentValidator.validate,
cluster
)

View File

@ -723,8 +723,10 @@ class TestTaskObject(BaseIntegrationTest):
objects.Task._update_cluster_data(task)
self.db.flush()
self.assertEquals(self.cluster.status,
consts.CLUSTER_STATUSES.operational)
self.assertEqual(self.cluster.status,
consts.CLUSTER_STATUSES.operational)
self.assertTrue(
self.cluster.attributes.generated['deployed_before']['value'])
def test_update_vms_conf(self):
kvm_node = self.cluster.nodes[0]
@ -984,6 +986,33 @@ class TestClusterObject(BaseTestCase):
return dict_merge(network_role, kwargs)
# FIXME(aroma): remove this test when stop action will be reworked for ha
# cluster. To get more details, please, refer to [1]
# [1]: https://bugs.launchpad.net/fuel/+bug/1529691
def test_set_deployed_before_flag(self):
self.assertFalse(
self.cluster.attributes.generated['deployed_before']['value'])
# check that the flags is set to true if was false
objects.Cluster.set_deployed_before_flag(self.cluster, value=True)
self.assertTrue(
self.cluster.attributes.generated['deployed_before']['value'])
# check that flag is set to false if was true
objects.Cluster.set_deployed_before_flag(self.cluster, value=False)
self.assertFalse(
self.cluster.attributes.generated['deployed_before']['value'])
# check that flag is not changed when same value is given
# and interaction w/ db is not performed
with mock.patch.object(self.db, 'flush') as m_flush:
objects.Cluster.set_deployed_before_flag(self.cluster,
value=False)
self.assertFalse(
self.cluster.attributes.generated['deployed_before']['value'])
m_flush.assert_not_called()
def test_network_defaults(self):
cluster = objects.Cluster.get_by_uid(self.env.create(api=True)['id'])