Merge "Add information about the cluster in magnum event notifications"

This commit is contained in:
Zuul 2019-08-01 10:26:30 +00:00 committed by Gerrit Code Review
commit fdb971459e
6 changed files with 100 additions and 24 deletions

View File

@ -69,7 +69,8 @@ class Handler(object):
cert_manager.generate_certificates_to_cluster(cluster,
context=context)
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_CREATE, taxonomy.OUTCOME_PENDING)
context, taxonomy.ACTION_CREATE, taxonomy.OUTCOME_PENDING,
cluster)
# Get driver
cluster_driver = driver.Driver.get_driver_for_cluster(context,
cluster)
@ -82,7 +83,8 @@ class Handler(object):
cluster.status_reason = six.text_type(e)
cluster.save()
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_CREATE, taxonomy.OUTCOME_FAILURE)
context, taxonomy.ACTION_CREATE, taxonomy.OUTCOME_FAILURE,
cluster)
if isinstance(e, exc.HTTPBadRequest):
e = exception.InvalidParameterValue(message=six.text_type(e))
@ -108,7 +110,8 @@ class Handler(object):
)
if cluster.status not in allow_update_status:
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE)
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE,
cluster)
operation = _('Updating a cluster when status is '
'"%s"') % cluster.status
raise exception.NotSupported(operation=operation)
@ -132,7 +135,8 @@ class Handler(object):
# Update cluster
try:
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_PENDING)
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_PENDING,
cluster)
worker_ng.node_count = node_count
worker_ng.save()
cluster_driver.update_cluster(context, cluster, manager, rollback)
@ -146,7 +150,8 @@ class Handler(object):
worker_ng.node_count = old_node_count
worker_ng.save()
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE)
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE,
cluster)
if isinstance(e, exc.HTTPBadRequest):
e = exception.InvalidParameterValue(message=six.text_type(e))
raise e
@ -165,7 +170,8 @@ class Handler(object):
ct.coe)
try:
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_PENDING)
context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_PENDING,
cluster)
cluster_driver.delete_cluster(context, cluster)
cluster.status = fields.ClusterStatus.DELETE_IN_PROGRESS
cluster.status_reason = None
@ -184,15 +190,18 @@ class Handler(object):
LOG.info('The cluster %s has been deleted by others.',
uuid)
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_SUCCESS)
context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_SUCCESS,
cluster)
return None
except exc.HTTPConflict:
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_FAILURE)
context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_FAILURE,
cluster)
raise exception.OperationInProgress(cluster_name=cluster.name)
except Exception as unexp:
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_FAILURE)
context, taxonomy.ACTION_DELETE, taxonomy.OUTCOME_FAILURE,
cluster)
cluster.status = fields.ClusterStatus.DELETE_FAILED
cluster.status_reason = six.text_type(unexp)
cluster.save()
@ -227,7 +236,8 @@ class Handler(object):
)
if cluster.status not in allow_update_status:
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE)
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE,
cluster)
operation = _('Resizing a cluster when status is '
'"%s"') % cluster.status
raise exception.NotSupported(operation=operation)
@ -248,7 +258,8 @@ class Handler(object):
nodegroup.node_count = node_count
nodegroup.save()
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_PENDING)
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_PENDING,
cluster)
cluster_driver.resize_cluster(context, cluster, resize_manager,
node_count, nodes_to_remove,
nodegroup)
@ -261,7 +272,8 @@ class Handler(object):
nodegroup.node_count = old_node_count
nodegroup.save()
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE)
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE,
cluster)
if isinstance(e, exc.HTTPBadRequest):
e = exception.InvalidParameterValue(message=six.text_type(e))
raise e
@ -287,7 +299,8 @@ class Handler(object):
)
if cluster.status not in allow_update_status:
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE)
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE,
cluster)
operation = _('Upgrading a cluster when status is '
'"%s"') % cluster.status
raise exception.NotSupported(operation=operation)
@ -300,7 +313,8 @@ class Handler(object):
# Upgrade cluster
try:
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_PENDING)
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_PENDING,
cluster)
cluster_driver.upgrade_cluster(context, cluster, cluster_template,
max_batch_size, nodegroup, rollback)
cluster.status = fields.ClusterStatus.UPDATE_IN_PROGRESS
@ -310,7 +324,8 @@ class Handler(object):
cluster.status_reason = six.text_type(e)
cluster.save()
conductor_utils.notify_about_cluster_operation(
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE)
context, taxonomy.ACTION_UPDATE, taxonomy.OUTCOME_FAILURE,
cluster)
if isinstance(e, exc.HTTPBadRequest):
e = exception.InvalidParameterValue(message=six.text_type(e))
raise e

View File

@ -13,6 +13,7 @@
# limitations under the License.
from oslo_utils import uuidutils
from pycadf import attachment
from pycadf import cadftaxonomy as taxonomy
from pycadf import cadftype
from pycadf import eventfactory
@ -98,19 +99,58 @@ def _get_request_audit_info(context):
return initiator
def notify_about_cluster_operation(context, action, outcome):
def _get_event_target(cluster_obj=None):
if cluster_obj:
target = resource.Resource(
id=cluster_obj.uuid,
name=cluster_obj.name,
typeURI='service/magnum/cluster'
)
target.add_attachment(attach_val=attachment.Attachment(
typeURI='service/magnum/cluster',
content={
'status': cluster_obj.status,
'status_reason': cluster_obj.status_reason,
'project_id': cluster_obj.project_id,
'created_at': cluster_obj.created_at,
'updated_at': cluster_obj.updated_at,
'cluster_template_id': cluster_obj.cluster_template_id,
'keypair': cluster_obj.keypair,
'docker_volume_size:': cluster_obj.docker_volume_size,
'labels': cluster_obj.labels,
'master_flavor_id': cluster_obj.master_flavor_id,
'flavor_id': cluster_obj.flavor_id,
'stack_id': cluster_obj.stack_id,
'health_status': cluster_obj.health_status,
'create_timeout': cluster_obj.create_timeout,
'api_address': cluster_obj.api_address,
'discovery_url': cluster_obj.discovery_url,
'node_addresses': cluster_obj.node_addresses,
'master_addresses': cluster_obj.master_addresses,
'node_count': cluster_obj.node_count,
'master_count': cluster_obj.master_count,
},
name='cluster_data'
))
return target
return resource.Resource(typeURI='service/magnum/cluster')
def notify_about_cluster_operation(context, action, outcome, cluster_obj=None):
"""Send a notification about cluster operation.
:param action: CADF action being audited
:param outcome: CADF outcome
:param cluster_obj: the cluster the notification is related to
"""
notifier = rpc.get_notifier()
event = eventfactory.EventFactory().new_event(
eventType=cadftype.EVENTTYPE_ACTIVITY,
outcome=outcome,
action=action,
initiator=_get_request_audit_info(context),
target=resource.Resource(typeURI='service/magnum/cluster'),
target=_get_event_target(cluster_obj=cluster_obj),
observer=resource.Resource(typeURI='service/magnum/cluster'))
service = 'magnum'
event_type = '%(service)s.cluster.%(action)s' % {

View File

@ -76,11 +76,11 @@ class ClusterUpdateJob(object):
if self.cluster.status.endswith("_COMPLETE"):
conductor_utils.notify_about_cluster_operation(
self.ctx, self.status_to_event[self.cluster.status],
taxonomy.OUTCOME_SUCCESS)
taxonomy.OUTCOME_SUCCESS, self.cluster)
if self.cluster.status.endswith("_FAILED"):
conductor_utils.notify_about_cluster_operation(
self.ctx, self.status_to_event[self.cluster.status],
taxonomy.OUTCOME_FAILURE)
taxonomy.OUTCOME_FAILURE, self.cluster)
# if we're done with it, delete it
if self.cluster.status == objects.fields.ClusterStatus.DELETE_COMPLETE:
# delete all the nodegroups that belong to this cluster

View File

@ -115,6 +115,10 @@ def get_test_cluster(**kw):
for attr in ['trustee_username', 'trustee_password', 'trust_id']:
if attr in kw:
attrs[attr] = kw[attr]
# Required only in PeriodicTestCase, may break other tests
for attr in ['keypair', 'health_status']:
if attr in kw:
attrs[attr] = kw[attr]
return attrs

View File

@ -65,31 +65,36 @@ class PeriodicTestCase(base.TestCase):
uuid = uuidutils.generate_uuid()
trust_attrs.update({'id': 1, 'stack_id': '11', 'uuid': uuid,
'status': cluster_status.CREATE_IN_PROGRESS,
'status_reason': 'no change'})
'status_reason': 'no change',
'keypair': 'keipair1', 'health_status': None})
cluster1 = utils.get_test_cluster(**trust_attrs)
ngs1 = utils.get_nodegroups_for_cluster()
uuid = uuidutils.generate_uuid()
trust_attrs.update({'id': 2, 'stack_id': '22', 'uuid': uuid,
'status': cluster_status.DELETE_IN_PROGRESS,
'status_reason': 'no change'})
'status_reason': 'no change',
'keypair': 'keipair1', 'health_status': None})
cluster2 = utils.get_test_cluster(**trust_attrs)
ngs2 = utils.get_nodegroups_for_cluster()
uuid = uuidutils.generate_uuid()
trust_attrs.update({'id': 3, 'stack_id': '33', 'uuid': uuid,
'status': cluster_status.UPDATE_IN_PROGRESS,
'status_reason': 'no change'})
'status_reason': 'no change',
'keypair': 'keipair1', 'health_status': None})
cluster3 = utils.get_test_cluster(**trust_attrs)
ngs3 = utils.get_nodegroups_for_cluster()
uuid = uuidutils.generate_uuid()
trust_attrs.update({'id': 4, 'stack_id': '44', 'uuid': uuid,
'status': cluster_status.DELETE_IN_PROGRESS,
'status_reason': 'no change'})
'status_reason': 'no change',
'keypair': 'keipair1', 'health_status': None})
cluster4 = utils.get_test_cluster(**trust_attrs)
ngs4 = utils.get_nodegroups_for_cluster()
uuid = uuidutils.generate_uuid()
trust_attrs.update({'id': 5, 'stack_id': '55', 'uuid': uuid,
'status': cluster_status.ROLLBACK_IN_PROGRESS,
'status_reason': 'no change'})
'status_reason': 'no change',
'keypair': 'keipair1', 'health_status': None})
cluster5 = utils.get_test_cluster(**trust_attrs)
ngs5 = utils.get_nodegroups_for_cluster()

View File

@ -0,0 +1,12 @@
---
features:
- |
Add information about the cluster in magnum event notifications.
Previously the CADF notification's target ID was randomly generated and
no other relevant info about the cluster was sent. Cluster details are
now included in the notifications. This is useful for other OpenStack
projects like Searchlight or third party projects that cache information
regarding OpenStack objects or have custom actions running on
notification. Caching systems can now efficiently update one single
object (e.g. cluster), while without notifications they need to
periodically retrieve object list, which is inefficient.