行动计划的版本化通知

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.create

  • actionplan.update

  • actionplan.delete

  • actionplan.execution.start

  • actionplan.execution.end

  • actionplan.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 架构 中,序列图。

参考资料

无。