Merge "Add 'deployed_before' flag to cluster that forbids stop deployment"
This commit is contained in:
commit
a9281e8d79
|
@ -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:
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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."""
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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'])
|
||||
|
||||
|
|
Loading…
Reference in New Issue