Added provision notifications
Added notification of provisioning results. Success and errors. Change-Id: Ia500a9c2c36d146d0ba9dba008502801fccd9ca3 Partial-Bug: 1515891
This commit is contained in:
parent
54b0a43628
commit
83225f87f3
|
@ -314,8 +314,9 @@ class NailgunReceiver(object):
|
|||
node_db.error_msg = u"Node is offline"
|
||||
# Notification on particular node failure
|
||||
notifier.notify(
|
||||
"error",
|
||||
u"Failed to deploy node '{0}': {1}".format(
|
||||
consts.NOTIFICATION_TOPICS.error,
|
||||
u"Failed to {0} node '{1}': {2}".format(
|
||||
consts.TASK_NAMES.deploy,
|
||||
node_db.name,
|
||||
node_db.error_msg or "Unknown error"
|
||||
),
|
||||
|
@ -331,15 +332,7 @@ class NailgunReceiver(object):
|
|||
if master.get('status') == consts.TASK_STATUSES.error:
|
||||
status = consts.TASK_STATUSES.error
|
||||
|
||||
# Let's check the whole task status
|
||||
if status == consts.TASK_STATUSES.error:
|
||||
cls._error_action(task, status, progress, message)
|
||||
elif status == consts.TASK_STATUSES.ready:
|
||||
cls._success_action(task, status, progress)
|
||||
else:
|
||||
data = {'status': status, 'progress': progress, 'message': message}
|
||||
objects.Task.update(task, data)
|
||||
|
||||
cls._update_task_status(task, status, progress, message)
|
||||
cls._update_action_log_entry(status, task.name, task_uuid, nodes)
|
||||
|
||||
@classmethod
|
||||
|
@ -392,7 +385,7 @@ class NailgunReceiver(object):
|
|||
if node.get('status') == consts.TASK_STATUSES.error:
|
||||
node_db.status = consts.TASK_STATUSES.error
|
||||
node_db.progress = 100
|
||||
node_db.error_type = 'provision'
|
||||
node_db.error_type = consts.TASK_NAMES.provision
|
||||
node_db.error_msg = node.get('error_msg', 'Unknown error')
|
||||
else:
|
||||
node_db.status = node.get('status')
|
||||
|
@ -402,9 +395,7 @@ class NailgunReceiver(object):
|
|||
if nodes and not progress:
|
||||
progress = TaskHelper.recalculate_provisioning_task_progress(task)
|
||||
|
||||
data = {'status': status, 'progress': progress, 'message': message}
|
||||
objects.Task.update(task, data)
|
||||
|
||||
cls._update_task_status(task, status, progress, message)
|
||||
cls._update_action_log_entry(status, task.name, task_uuid, nodes)
|
||||
|
||||
@classmethod
|
||||
|
@ -448,6 +439,48 @@ class NailgunReceiver(object):
|
|||
|
||||
cls._update_action_log_entry(status, task.name, task_uuid, nodes)
|
||||
|
||||
@classmethod
|
||||
def _notify(cls, task, topic, message, node_id=None, task_uuid=None):
|
||||
"""Send notification.
|
||||
|
||||
:param task: objects.Task object
|
||||
:param topic: consts.NOTIFICATION_TOPICS value
|
||||
:param message: message text
|
||||
:param node_id: node identifier
|
||||
:param task_uuid: task uuid. specify task_uuid if necessary to pass it
|
||||
"""
|
||||
# Due to design of UI, that shows all notifications,
|
||||
# we should notify provision task only then the task is top-level task
|
||||
if task.name == consts.TASK_NAMES.provision \
|
||||
and task.parent_id is not None:
|
||||
return
|
||||
|
||||
notifier.notify(
|
||||
topic,
|
||||
message,
|
||||
task.cluster_id,
|
||||
node_id=node_id,
|
||||
task_uuid=task_uuid
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _update_task_status(cls, task, status, progress, message):
|
||||
"""Do update task status actions.
|
||||
|
||||
:param task: objects.Task object
|
||||
:param status: consts.TASK_STATUSES value
|
||||
:param progress: progress number value
|
||||
:param message: message text
|
||||
"""
|
||||
# Let's check the whole task status
|
||||
if status == consts.TASK_STATUSES.error:
|
||||
cls._error_action(task, status, progress, message)
|
||||
elif status == consts.TASK_STATUSES.ready:
|
||||
cls._success_action(task, status, progress)
|
||||
else:
|
||||
data = {'status': status, 'progress': progress, 'message': message}
|
||||
objects.Task.update(task, data)
|
||||
|
||||
@classmethod
|
||||
def _update_action_log_entry(cls, task_status, task_name, task_uuid,
|
||||
nodes_from_resp):
|
||||
|
@ -527,11 +560,7 @@ class NailgunReceiver(object):
|
|||
)
|
||||
notify_message = message
|
||||
|
||||
notifier.notify(
|
||||
"error",
|
||||
notify_message,
|
||||
task.cluster_id
|
||||
)
|
||||
cls._notify(task, consts.NOTIFICATION_TOPICS.error, notify_message)
|
||||
data = {'status': status, 'progress': progress, 'message': message}
|
||||
objects.Task.update(task, data)
|
||||
|
||||
|
@ -574,7 +603,7 @@ class NailgunReceiver(object):
|
|||
if plugins_msg:
|
||||
message = '{0}\n\n{1}'.format(message, plugins_msg)
|
||||
|
||||
notifier.notify("done", message, task.cluster_id)
|
||||
cls._notify(task, consts.NOTIFICATION_TOPICS.done, message)
|
||||
data = {'status': status, 'progress': progress, 'message': message}
|
||||
objects.Task.update(task, data)
|
||||
|
||||
|
|
|
@ -1176,35 +1176,153 @@ class TestConsumer(BaseReciverTestCase):
|
|||
|
||||
self.assertEqual(supertask.progress, calculated_progress)
|
||||
|
||||
def test_error_node_progress(self):
|
||||
def _prepare_task(self, name):
|
||||
self.env.create(
|
||||
cluster_kwargs={},
|
||||
nodes_kwargs=[
|
||||
{"api": False},
|
||||
{"api": False}
|
||||
]
|
||||
)
|
||||
task = Task(
|
||||
uuid=str(uuid.uuid4()),
|
||||
name="super",
|
||||
status="running",
|
||||
name=name,
|
||||
status=consts.TASK_STATUSES.running,
|
||||
cluster_id=self.env.clusters[0].id
|
||||
)
|
||||
self.db.add(task)
|
||||
self.db.commit()
|
||||
kwargs = {
|
||||
'task_uuid': task.uuid,
|
||||
'progress': 20,
|
||||
self.db.flush()
|
||||
return task
|
||||
|
||||
def _prepare_sub_task(self, name):
|
||||
task = self._prepare_task(consts.TASK_NAMES.super)
|
||||
sub_task = Task(
|
||||
uuid=str(uuid.uuid4()),
|
||||
name=name,
|
||||
status=consts.TASK_STATUSES.running,
|
||||
cluster_id=self.env.clusters[0].id,
|
||||
parent_id=task.id
|
||||
)
|
||||
self.db.add(sub_task)
|
||||
self.db.flush()
|
||||
return sub_task
|
||||
|
||||
def _create_resp_kwargs(
|
||||
self,
|
||||
task_uuid,
|
||||
status,
|
||||
progress,
|
||||
node_status,
|
||||
node_progress
|
||||
):
|
||||
return {
|
||||
'task_uuid': task_uuid,
|
||||
'progress': progress,
|
||||
'status': status,
|
||||
'nodes': [
|
||||
{
|
||||
'uid': self.env.nodes[0].id,
|
||||
'status': 'error',
|
||||
'status': node_status,
|
||||
'progress': node_progress
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
def test_deploy_resp_error_node_progress(self):
|
||||
task = self._prepare_task(consts.TASK_NAMES.deployment)
|
||||
kwargs = self._create_resp_kwargs(
|
||||
task.uuid, consts.TASK_STATUSES.running, 20,
|
||||
consts.TASK_STATUSES.error, 50
|
||||
)
|
||||
self.receiver.deploy_resp(**kwargs)
|
||||
self.db.refresh(self.env.nodes[0])
|
||||
self.assertEqual(self.env.nodes[0].progress, 100)
|
||||
|
||||
def test_provision_resp_error_node_progress(self):
|
||||
task = self._prepare_task(consts.TASK_NAMES.provision)
|
||||
kwargs = self._create_resp_kwargs(
|
||||
task.uuid, consts.TASK_STATUSES.running, 20,
|
||||
consts.TASK_STATUSES.error, 50
|
||||
)
|
||||
self.receiver.provision_resp(**kwargs)
|
||||
self.db.refresh(self.env.nodes[0])
|
||||
self.assertEqual(self.env.nodes[0].progress, 100)
|
||||
|
||||
def test_provision_resp_error_notification(self):
|
||||
task = self._prepare_task(consts.TASK_NAMES.provision)
|
||||
kwargs = self._create_resp_kwargs(
|
||||
task.uuid, consts.TASK_STATUSES.error, 20,
|
||||
consts.TASK_STATUSES.error, 50
|
||||
)
|
||||
self.receiver.provision_resp(**kwargs)
|
||||
notifications_number = self.db.query(Notification).filter_by(
|
||||
cluster_id=task.cluster_id
|
||||
).count()
|
||||
self.assertEqual(1, notifications_number)
|
||||
|
||||
def test_provision_resp_sub_task_no_error_notification(self):
|
||||
sub_task = self._prepare_sub_task(consts.TASK_NAMES.provision)
|
||||
kwargs = self._create_resp_kwargs(
|
||||
sub_task.uuid, consts.TASK_STATUSES.error, 20,
|
||||
consts.TASK_STATUSES.error, 50
|
||||
)
|
||||
self.receiver.provision_resp(**kwargs)
|
||||
notifications_number = self.db.query(Notification).filter_by(
|
||||
cluster_id=sub_task.cluster_id
|
||||
).count()
|
||||
self.assertEqual(0, notifications_number)
|
||||
|
||||
def test_provision_resp_success_notification(self):
|
||||
task = self._prepare_task(consts.TASK_NAMES.provision)
|
||||
kwargs = self._create_resp_kwargs(
|
||||
task.uuid, consts.TASK_STATUSES.ready, 100,
|
||||
consts.TASK_STATUSES.ready, 100
|
||||
)
|
||||
|
||||
self.receiver.provision_resp(**kwargs)
|
||||
notifications_number = self.db.query(Notification).filter_by(
|
||||
cluster_id=task.cluster_id
|
||||
).count()
|
||||
self.assertEqual(1, notifications_number)
|
||||
|
||||
def test_provision_resp_sub_task_no_success_notification(self):
|
||||
sub_task = self._prepare_sub_task(consts.TASK_NAMES.provision)
|
||||
kwargs = self._create_resp_kwargs(
|
||||
sub_task.uuid, consts.TASK_STATUSES.ready, 100,
|
||||
consts.TASK_STATUSES.ready, 100
|
||||
)
|
||||
self.receiver.provision_resp(**kwargs)
|
||||
notifications_number = self.db.query(Notification).filter_by(
|
||||
cluster_id=sub_task.cluster_id
|
||||
).count()
|
||||
self.assertEqual(0, notifications_number)
|
||||
|
||||
def test_provision_resp_nodes_failed(self):
|
||||
task = self._prepare_task(consts.TASK_NAMES.provision)
|
||||
kwargs = {
|
||||
'task_uuid': task.uuid,
|
||||
'progress': 20,
|
||||
'status': consts.TASK_STATUSES.ready,
|
||||
'nodes': [
|
||||
{
|
||||
'uid': self.env.nodes[0].id,
|
||||
'status': consts.TASK_STATUSES.error,
|
||||
'progress': 50
|
||||
},
|
||||
{
|
||||
'uid': self.env.nodes[1].id,
|
||||
'status': consts.TASK_STATUSES.error,
|
||||
'progress': 50
|
||||
}
|
||||
]
|
||||
}
|
||||
self.receiver.deploy_resp(**kwargs)
|
||||
self.db.refresh(self.env.nodes[0])
|
||||
self.assertEqual(self.env.nodes[0].progress, 100)
|
||||
self.receiver.provision_resp(**kwargs)
|
||||
notifications_number = self.db.query(Notification).filter_by(
|
||||
cluster_id=task.cluster_id).count()
|
||||
self.assertEqual(1, notifications_number)
|
||||
self.assertRegexpMatches(
|
||||
task.message,
|
||||
u"Provision has failed\. Check these nodes:\n'(.*)', '(.*)'")
|
||||
|
||||
def test_remove_nodes_resp(self):
|
||||
self.env.create(
|
||||
|
|
|
@ -90,7 +90,10 @@ class TestNailgunReceiver(base.BaseTestCase):
|
|||
mnotify.assert_called_with(
|
||||
task_resp['status'],
|
||||
u'Deployment has failed. Method granular_deploy.',
|
||||
self.cluster.id)
|
||||
self.cluster.id,
|
||||
task_uuid=None,
|
||||
node_id=None
|
||||
)
|
||||
|
||||
@patch('nailgun.objects.Task.update_verify_networks')
|
||||
def test_check_repositories_resp_success(self, update_verify_networks):
|
||||
|
@ -158,3 +161,77 @@ class TestNailgunReceiver(base.BaseTestCase):
|
|||
self.db.flush()
|
||||
NailgunReceiver.task_in_orchestrator(**resp)
|
||||
self.assertEqual(status, self.task.status)
|
||||
|
||||
@patch('nailgun.rpc.receiver.notifier.notify')
|
||||
def test_notify_provision(self, notify_checker):
|
||||
NailgunReceiver._notify(
|
||||
self.task,
|
||||
"done",
|
||||
"Test error.",
|
||||
"123",
|
||||
self.task.uuid
|
||||
)
|
||||
notify_checker.assert_called_with(
|
||||
"done",
|
||||
u'Test error.',
|
||||
self.task.cluster_id,
|
||||
node_id="123",
|
||||
task_uuid=self.task.uuid
|
||||
)
|
||||
|
||||
@patch('nailgun.rpc.receiver.notifier.notify')
|
||||
def test_notify_provision_sub_task(self, notify_checker):
|
||||
sub_task = self.env.create_task(
|
||||
name=consts.TASK_NAMES.provision,
|
||||
status=consts.TASK_STATUSES.ready,
|
||||
cluster_id=self.cluster.id,
|
||||
parent_id=self.task.id
|
||||
)
|
||||
NailgunReceiver._notify(
|
||||
sub_task,
|
||||
"done",
|
||||
"Test error.",
|
||||
"123",
|
||||
sub_task.uuid
|
||||
)
|
||||
self.assertEqual(0, notify_checker.call_count)
|
||||
|
||||
@patch('nailgun.rpc.receiver.notifier.notify')
|
||||
def test_notify_deployment(self, notify_checker):
|
||||
NailgunReceiver._notify(
|
||||
self.task,
|
||||
"done",
|
||||
"Test error.",
|
||||
"123",
|
||||
self.task.uuid
|
||||
)
|
||||
notify_checker.assert_called_with(
|
||||
"done",
|
||||
u'Test error.',
|
||||
self.task.cluster_id,
|
||||
node_id="123",
|
||||
task_uuid=self.task.uuid
|
||||
)
|
||||
|
||||
@patch('nailgun.rpc.receiver.notifier.notify')
|
||||
def test_notify_deployment_sub_task(self, notify_checker):
|
||||
sub_task = self.env.create_task(
|
||||
name=consts.TASK_NAMES.deployment,
|
||||
status=consts.TASK_STATUSES.ready,
|
||||
cluster_id=self.cluster.id,
|
||||
parent_id=self.task.id
|
||||
)
|
||||
NailgunReceiver._notify(
|
||||
sub_task,
|
||||
"done",
|
||||
"Test error.",
|
||||
"123",
|
||||
sub_task.uuid
|
||||
)
|
||||
notify_checker.assert_called_with(
|
||||
"done",
|
||||
u'Test error.',
|
||||
sub_task.cluster_id,
|
||||
node_id="123",
|
||||
task_uuid=sub_task.uuid
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue