在 Vitrage 模板中支持外部动作¶
launchpad 蓝图: https://blueprints.launchpad.net/vitrage/+spec/support-external-actions
目前,Vitrage 模板支持以下动作:触发告警、设置状态、标记因果关系和降级。降级功能的实现比较零散(更新顶点上的属性并调用通知器)。
我们需要一种在模板中定义应该采取的外部动作的方式。一个例子是降级。另一个例子是执行 Mistral 工作流或 Congress 策略。
问题描述¶
应支持以下用例
降级。这是一个现有的用例。如果存在降级动作,Vitrage 将调用 Nova 降级 API。更改后行为应保持不变。
执行 Mistral 工作流。用户应该能够基于 Vitrage insights 执行 Mistral 工作流。
执行其他外部动作,例如 Congress 策略。
提议的变更¶
为每个我们想要支持的外部引擎添加一个新的动作。该动作将具有要发送到引擎的参数的元数据。
示例¶
action:
action_type: execute_nova
metadata:
api_call: mark-down
host: host1
action:
action_type: execute_mistral
metadata:
workflow: evacuate_host
failed_host: host1
为每个引擎添加一个新的 external_* 动作背后的想法是强调 Vitrage 支持预定义的外部动作集合,并且明确不支持运行脚本。
内部实现对于 Nova、Mistral、Congress 等将是相同的。在模板加载阶段,execute_* 动作将被转换为通用的 Execute 动作,并带有 notifier 参数。模板验证器将验证所需的 notifier 是否在 vitrage.conf 中启用,否则模板加载将失败。
当执行 Execute 动作时,评估器将向所需 notifier 的消息总线发送一个事件。这样,只有 Mistral notifier 会处理 execute_mistral 动作。
请注意,目前只有 Vitrage 图发送通知到 notifier。这种行为将被改变,因此通知将同时从图(用于推导出的告警和设置状态)和从评估器发送。
备选方案¶
有两种替代方案
发送消息总线通知¶
Vitrage 可以有一个消息总线 notifier,它将发送关于触发/删除告警、设置状态和标记因果关系的通知。Mistral 将被配置为基于从 Vitrage 接收到的通知执行某些工作流。
优点
无需在 Vitrage 中进行额外的配置
可以与当前的 notifiers 机制一起工作
缺点
消息总线通知可能会丢失
功能较弱。在 Vitrage 模板中,用户可以决定基于告警的组合或特定的拓扑来执行工作流。一旦 Mistral 收到通知,拓扑上下文就不再存在。
此解决方案不支持降级用例
在特定 notifier 上完成配置¶
将编写一个 Mistral notifier 并接收来自图的通知。它将通过一个 yaml 文件进行配置,该文件将确定针对特定告警执行哪个工作流。
优点
无需在 Vitrage 中进行额外的配置
可以与当前的 notifiers 机制一起工作
不会丢失消息
缺点
功能较弱。在 Vitrage 模板中,用户可以决定基于告警的组合或特定的拓扑来执行工作流。在 Mistral notifier 中,我们不再拥有这种上下文。
此解决方案不支持降级用例
计算 action_target¶
每个“常规”动作(raise_alarm、set_state、add_causal_relationship)都有一个 action_target 块。对于外部动作,action_target 没有意义,因为它们由一个没有“目标”术语的外部引擎管理。
问题是 action_target 对于子图匹配计算至关重要,以便计算连通分量。
提出的解决方案¶
对于外部动作,我们将自动计算一个 action target。目标将从可能的目标的集合中任意选择。在涉及 {and, or, not} 的复杂条件下,找到目标可能并不容易。由于这个原因,对于外部动作,一些更复杂的条件将不受支持。
计算方法
And 条件 - 条件的任何顶点都可以是目标
Not 条件 - 条件的任何顶点都不能是目标
Or 条件 - 目标应该是出现在 Or 条件的任何“正向”部分(即,前面没有 ‘not’)中的顶点
示例:¶
注意: 在某些情况下,找到有效的目标是不可能的。它们用 ‘/’ 标记。
在这些情况下,模板验证应该失败,对于所有类型的动作。
条件 |
可能的 targets |
a_in_error_status |
a |
a_contains_b |
a, b |
a_contains_b or a_contains_c |
a |
a_contains_b or a_contains_c or a_contains_d |
a |
a_in_error_status or a_contains_c or a_contains_d |
a |
a_contains_b or a_contains_c or b_contains_d |
不支持 |
a_contains_b and a_contains_c |
a, b, c |
a_contains_b and a_contains_c and a_contains_d |
a, b, c, d |
a_contains_b or (a_contains_c and a_contains_d) |
a |
a_contains_b or (a_contains_c and b_contains_d) |
a,b |
not a_contains_b |
不支持 |
not a_in_error_status |
不支持 |
a_contains_b or not a_contains_c |
不支持 |
a_contains_b or (a_contains_c and not a_contains_d) |
a |
a_contains_b or (not a_contains_c and not a_contains_d) |
不支持 |
计算 action_target 的替代方案¶
我们可以决定外部动作需要像所有其他动作一样的 action_target。这将简化实现,但在逻辑上是错误的。action_target 将作为子图匹配的“辅助实体”,不应该由最终用户来帮助修复实现问题。就外部引擎而言,action_target 没有意义。
数据模型影响¶
将向评估器添加一个新的 Execute 动作。
REST API 影响¶
无
版本影响¶
我们应该为模板引入一个版本控制机制。这将在一修改降级功能的实现时完成。
其他最终用户影响¶
无
部署者影响¶
无
开发者影响¶
无
Horizon 影响¶
无
实现¶
负责人¶
- 主要负责人
ifat-afek
工作项¶
增强模板语言(模板加载和验证)
更新文档
从评估器执行外部动作
依赖项¶
无
测试¶
实现将由单元测试和 tempest 测试覆盖。
文档影响¶
应该记录新的动作
参考资料¶
无