行动计划的版本化通知¶
https://blueprints.launchpad.net/watcher/+spec/action-plan-versioned-notifications-api
在实施 watcher-notifications-ovo 蓝图 之后,Watcher 现在具备在其代码库中提供版本化通知所需的所有先决条件。此蓝图将重点描述在 Watcher 中有关 行动计划 对象实现的通知。
问题描述¶
目前,任何服务(包括 Watcher)都无法得知行动计划何时被创建、修改或删除。这阻止了任何形式的基于事件的反应,这对于第三方服务或插件可能很有用。
用例¶
作为 OpenStack 开发者,我希望能够监听来自 Watcher 关于行动计划的通知。
作为 OpenStack 开发者,我想知道行动计划通知的格式是什么。
作为 OpenStack 开发者,我希望在以下情况下收到通知:
行动计划已被创建、更新或删除
行动计划已完成
作为 OpenStack 开发者,我还希望在以下情况下收到通知:
行动计划开始执行其动作(行动计划由 Applier 触发)
行动计划完成执行
行动计划因错误而失败
提议的变更¶
为了实现上述用例,需要许多不同的通知
actionplan.create每当创建行动计划时。actionplan.update每当更新行动计划时。这包括所有状态更新,包括行动计划的删除。actionplan.delete每当删除行动计划(软删除)时。actionplan.execution.start每当行动计划开始时。actionplan.execution.end每当行动计划结束时。actionplan.execution.error每当行动计划失败时。
此外,我们将依赖 oslo.versionedobjects 来对行动计划相关的通知的有效负载进行版本化。
以下是针对上述每个事件的通知结构建议
actionplan.create
{
"priority": "INFO",
"payload": {
"watcher_object.data": {
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6",
"state": "RECOMMENDED",
"global_efficacy": {
"description": "Global efficacy",
"name": "test_global_efficacy",
"unit": "%",
"value": 95
},
"audit_uuid": "55bc1fe8-8030-4bd0-b0d0-2e62937f02a0",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:29:20Z",
"audit": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "SUCCEEDED",
"updated_at": null,
"deleted_at": null,
"fault": null,
"interval": null,
"scope": [],
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
},
"watcher_object.name": "AuditPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
}
},
"watcher_object.name": "ActionPlanCreatePayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673",
"event_type": "actionplan.create",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}
actionplan.update
{
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:51:38.722986",
"payload": {
"watcher_object.name": "ActionPlanUpdatePayload",
"watcher_object.data": {
"global_efficacy": {
"description": "Global efficacy",
"name": "test_global_efficacy",
"unit": "%",
"value": 95
},
"strategy": {
"watcher_object.name": "StrategyPayload",
"watcher_object.data": {
"name": "dummy",
"parameters_spec": {
"properties": {
"para2": {
"default": "hello",
"type": "string",
"description": "string parameter example"
},
"para1": {
"maximum": 10.2,
"default": 3.2,
"minimum": 1.0,
"description": "number parameter example",
"type": "number"
}
}
},
"updated_at": null,
"display_name": "Dummy strategy",
"deleted_at": null,
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"audit_uuid": "55bc1fe8-8030-4bd0-b0d0-2e62937f02a0",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"created_at": "2016-11-04T16:25:35Z"
},
"watcher_object.namespace": "watcher",
"watcher_object.version": "1.0"
},
"audit": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "SUCCEEDED",
"updated_at": null,
"deleted_at": null,
"fault": null,
"interval": null,
"scope": [],
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
},
"watcher_object.name": "AuditPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"created_at": "2016-11-04T16:51:21Z",
"uuid": "f1e0d912-afd9-4bf2-91ef-c99cd08cc1ef",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"deleted_at": null,
"state_update": {
"watcher_object.name": "ActionPlanStateUpdatePayload",
"watcher_object.data": {
"state": "ONGOING",
"old_state": "PENDING"
},
"watcher_object.namespace": "watcher",
"watcher_object.version": "1.0"
},
"state": "ONGOING",
"priority": "INFO",
"event_type": "actionplan.update",
"message_id": "697fdf55-7252-4b6c-a2c2-5b9e85f6342c"
}
}
}
actionplan.delete
{
"priority": "INFO",
"payload": {
"watcher_object.data": {
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6",
"state": "DELETED",
"global_efficacy": {
"description": "Global efficacy",
"name": "test_global_efficacy",
"unit": "%",
"value": 95
},
"audit_uuid": "55bc1fe8-8030-4bd0-b0d0-2e62937f02a0",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:29:20Z",
"audit": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "SUCCEEDED",
"updated_at": null,
"deleted_at": null,
"fault": null,
"interval": null,
"scope": [],
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
},
"watcher_object.name": "AuditPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
}
},
"watcher_object.name": "ActionPlanDeletePayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673",
"event_type": "actionplan.delete",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}
actionplan.execution.start
{
"priority": "INFO",
"payload": {
"watcher_object.data": {
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6",
"state": "PENDING",
"global_efficacy": {
"description": "Global efficacy",
"name": "test_global_efficacy",
"unit": "%",
"value": 95
},
"audit_uuid": "55bc1fe8-8030-4bd0-b0d0-2e62937f02a0",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:29:20Z",
"audit": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "SUCCEEDED",
"updated_at": null,
"deleted_at": null,
"fault": null,
"interval": null,
"scope": [],
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
},
"watcher_object.name": "AuditPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
}
},
"watcher_object.name": "ActionPlanActionPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673",
"event_type": "actionplan.execution.start",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}
actionplan.execution.end
{
"priority": "INFO",
"payload": {
"watcher_object.data": {
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6",
"state": "SUCCEEDED",
"global_efficacy": {
"description": "Global efficacy",
"name": "test_global_efficacy",
"unit": "%",
"value": 95
},
"audit_uuid": "55bc1fe8-8030-4bd0-b0d0-2e62937f02a0",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:29:20Z",
"audit": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "SUCCEEDED",
"updated_at": null,
"deleted_at": null,
"fault": null,
"interval": null,
"scope": [],
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6",
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39"
},
"watcher_object.name": "AuditPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
}
},
"watcher_object.name": "ActionPlanActionPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673",
"event_type": "actionplan.execution.end",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}
actionplan.execution.error
{
"priority": "ERROR",
"payload": {
"watcher_object.data": {
"state": "ONGOING",
"updated_at": null,
"deleted_at": null,
"audit_uuid": "55bc1fe8-8030-4bd0-b0d0-2e62937f02a0",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a3",
"global_efficacy": {
"description": "Global efficacy",
"name": "test_global_efficacy",
"unit": "%",
"value": 95
},
"fault": {
"watcher_object.data": {
"exception": "WatcherException",
"exception_message": "TEST",
"function_name": "test_send_action_plan_action_with_error",
"module_name": "watcher.tests.notifications.test_action_plan_notification"
},
"watcher_object.name": "ExceptionPayload",
"watcher_object.namespace": "watcher",
"watcher_object.version": "1.0"
},
"audit": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "SUCCEEDED",
"updated_at": null,
"deleted_at": null,
"fault": null,
"interval": null,
"scope": [],
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6",
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39"
},
"watcher_object.name": "AuditPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
},
"watcher_object.name": "ActionPlanActionPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673",
"event_type": "actionplan.execution.error",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}
备选方案¶
与其使用版本化对象,我们可以定义行动计划通知的有效负载,而无需任何版本化支持。
数据模型影响¶
将创建新的版本化对象,但它们都不会被持久化,因为它们将用于构建通知的内容。
以下是一些需要声明的有效负载
@base.WatcherObjectRegistry.register_notification
class ActionPlanPayload(base.NotificationPayloadBase):
VERSION = '1.0'
fields = {
'uuid': fields.UUIDField(),
'state': fields.StringField(),
'global_efficacy': fields.FlexibleDictField(nullable=True),
'audit_uuid': fields.UUIDField(),
'audit': fields.ObjectField('Audit'),
'strategy_uuid': fields.UUIDField(nullable=True),
'strategy': fields.ObjectField('Strategy', nullable=True),
'created_at': fields.DateTimeField(nullable=True),
'updated_at': fields.DateTimeField(nullable=True),
'deleted_at': fields.DateTimeField(nullable=True),
}
@base.WatcherObjectRegistry.register_notification
class ActionPlanStateUpdatePayload(base.NotificationPayloadBase):
VERSION = '1.0'
fields = {
'old_state': fields.StringField(nullable=True),
'state': fields.StringField(nullable=True),
}
@base.WatcherObjectRegistry.register_notification
class ActionPlanUpdatePayload(ActionPlanPayload):
VERSION = '1.0'
fields = {
'state_update': fields.ObjectField('ActionPlanStateUpdatePayload'),
}
REST API 影响¶
无。
安全影响¶
无。
通知影响¶
此蓝图将实现以下通知
actionplan.createactionplan.updateactionplan.deleteactionplan.execution.startactionplan.execution.endactionplan.execution.error
其他最终用户影响¶
无。
性能影响¶
启用后,每次发生触发通知的事件时,都会调用发送通知的代码。这对于 Watcher 本身来说问题不大,但应考虑所使用的消息总线上的负载。
其他部署者影响¶
为了发出通知,部署者将不得不使用 oslo.messaging 配置通知主题。通过 oslo.messaging 暴露的其他配置选项也可以进行调整。
开发人员影响¶
开发者应遵守适当的版本化指南,并在创建/更新通知时使用通知基类。
实现¶
负责人¶
- 主要负责人
vincent-francoise
工作项¶
实现
actionplan.create实现
actionplan.update实现
actionplan.delete实现
actionplan.execution.start实现
actionplan.execution.end实现
actionplan.execution.error
依赖项¶
测试¶
这些通知主要需要通过单元测试进行测试。
文档影响¶
应提供一个通知示例,并使其在在线文档中动态可用。
在 Watcher 架构 中,序列图。
参考资料¶
无。