条件
在事件驱动自动化中,条件决定了规则是否触发(运行其动作)。
示例
condition: event.status == "enabled"
- 每个条件可以使用来自以下方面的信息
接收到的事件
规则内先前保存的事件
关于系统的长期事实
用户在启动时提供的并保存为 vars 的变量
- 编写条件时
访问当前事件的数据时,使用 event 前缀
访问 rulebook 中 set_facts 动作的数据时,使用 fact 前缀
在规则内分配变量并访问数据时,使用 events 前缀
在规则内分配变量并访问数据时,使用 facts 前缀
访问通过 –vars 和 –env-vars 传入的变量时,使用 vars 前缀
注意
在访问从命令行传入的变量时,条件 不能 包含 Jinja 风格的替换,否则我们会丢失数据类型信息,且规则引擎将无法处理该条件。相反,请使用 vars 前缀来访问从命令行传入的数据
- 条件可以包含
一个条件
所有条件都必须满足的多条件情况
满足任一条件即可的多条件情况
并非所有条件都必须满足的多条件情况
支持的数据类型
数据类型对规则引擎非常重要。支持以下类型
整数
strings
布尔值
浮点数(点号表示法和科学计数法)
null
支持的运算符
条件支持以下运算符
Name |
描述 |
|---|---|
== |
用于字符串和数字的相等运算符 |
!= |
用于字符串和数字的不相等运算符 |
> |
用于数字的大于运算符 |
< |
用于数字的小于运算符 |
>= |
用于数字的大于等于运算符 |
<= |
用于数字的小于等于运算符 |
+ |
用于数字的加法运算符 |
- |
用于数字的减法运算符 |
* |
用于数字的乘法运算符 |
and (与) |
合取与,用于构建复合表达式 |
或 |
析取或 |
in |
检查左侧的值是否存在于右侧的列表中 |
not in |
检查左侧的值是否不存在于右侧的列表中 |
contains |
检查左侧的列表是否包含右侧的值 |
not contains |
检查左侧的列表是否不包含右侧的值 |
is defined |
检查变量是否已定义 |
is not defined |
检查变量是否未定义,请参阅下面列出的注意事项 |
is match(pattern,ignorecase=true) |
检查模式是否存在于字符串的开头。支持正则表达式 |
is not match(pattern,ignorecase=true) |
检查模式是否不存在于字符串的开头。支持正则表达式 |
is search(pattern,ignorecase=true) |
检查模式是否存在于字符串中的任何位置。支持正则表达式 |
is not search(pattern,ignorecase=true) |
检查模式是否不存在于字符串中的任何位置。支持正则表达式 |
is regex(pattern,ignorecase=true) |
检查正则表达式模式是否存在于字符串中 |
is not regex(pattern,ignorecase=true) |
检查正则表达式模式是否不存在于字符串中 |
is select(operator, value) |
检查列表中是否存在满足由运算符和值定义的测试的项目 |
is not select(operator, value) |
检查列表中是否没有项目满足由运算符 and 值定义的测试 |
is selectattr(key, operator, value) |
检查列表中是否存在满足由键、运算符和值定义的测试的对象 |
is not selectattr(key, operator, value) |
检查列表中是否没有对象满足由键、运算符和值定义的测试 |
<< |
赋值运算符,用于保存带有 events 或 facts 前缀的匹配事件或事实 |
not |
否定运算符,用于否定布尔表达式 |
示例
单一条件
name: An automatic remediation rule condition: event.outage == true action: run_playbook: name: remediate_outage.yml
当事件带有的 outage 属性为 true 时,将执行指定的 playbook。
单一布尔值
name: An automatic remediation rule condition: event.outage action: run_playbook: name: remediate_outage.yml
如果 outage 属性是布尔值,您可以在条件中单独使用它。这是前一个示例的简化版本。如果值为 true,则条件通过并触发动作。
所有条件都必须满足的多条件情况
name: All conditions must match condition: all: - event.target_os == "linux" - event.tracking_id == 345 action: debug:
当我们从源插件接收事件时,我们会将它们发送到规则引擎中运行的相应规则集会话。在多条件情况下,规则引擎将跟踪已匹配的条件,并等待下一个可能匹配其他条件的事件到来。一旦所有条件都满足,它将向您返回所有匹配的事件,这些事件可在动作中使用。
警告
请注意,在此情况下,引擎将考虑 所有不同的事件,直到满足条件,无论这些事件是来自单个源还是多个源。具有
all的多条件不等于具有and运算符的单一条件。如果您想使用多个属性仅匹配一个事件,规则必须使用具有
and运算符的单一条件name: One condition combining attributes condition: event.target_os == "linux" and event.tracking_id == 345 action: debug:
具有内部引用且所有条件都必须满足的多条件情况
--- - name: Delayed comparison hosts: all sources: - eda.builtin.generic: payload: - friend_list: names: - fred - barney - request: type: Delete friend_name: fred rules: - name: r1 condition: all: - event.request.type == "Delete" - event.friend_list.names is select("search", events.m_0.request.friend_name) action: print_event: pretty: true
--- - name: multiple conditions caching hosts: all sources: - eda.builtin.generic: payload: - request: type: Delete friend_name: fred - request: type: Delete friend_name: wilma - friend_list: names: - fred - barney - friend_list: names: - betty - wilma rules: - name: r1 condition: all: - event.request.type == "Delete" - event.friend_list.names contains events.m_0.request.friend_name action: print_event:
满足任一条件即可的多条件情况
name: Any condition can match condition: any: - event.target_os == "linux" - event.target_os == "windows" action: debug:注意
请注意,在此情况下,引擎将考虑 所有不同的事件,直到其中一个事件满足其中一个条件,无论这些事件是来自单个源还是多个源。具有
any的多条件不等于具有or运算符的单一条件。如果您想使用多个属性仅匹配一个事件,规则必须使用具有
or运算符的单一条件name: One condition combining attributes condition: event.target_os == "linux" or event.target_os == "windows" action: debug:
包含事实和事件的多条件情况,且其中之一的所有条件都必须满足
name: Condition using both a fact and an event condition: all: - fact.meta.hosts == "localhost" - event.target_os == "windows" action: debug:
包含事实和事件的条件
name: Condition using a set_fact fact and an event condition: all: - facts.first << fact.custom.expected_index is defined - event.i == facts.first.custom.expected_index action: debug:
包含变量和事件的条件
name: Condition using a passed in variable and an event condition: all: - event.year == vars.person.year - event.age == vars.person.age action: debug:
--vars 传入 ansible-rulebook 的变量文件中传递的。使用 vars 允许我们name: Single condition comparing vars and event condition: event.name == vars.name action: debug:
逻辑与 (and)
name: Multiple Attribute match from a single event condition: event.target_os == "linux" and event.version == "1.1" action: debug:
逻辑或 (or)
name: Match any one attribute from a single event condition: event.version == "2.0" or event.version == "1.1" action: debug:
组合逻辑运算符
您可以组合多个 and 运算符
name: Combining and operators condition: event.version == "2.0" and event.name == "example" and event.alert_count > 10 action: debug:
如果您组合使用 and 和 or 运算符,它们必须用圆括号括起来
name: Combining and -and- or operators condition: ((event.i > 100 and event.i < 200) or (event.i > 500 and event.i < 600)) action: debug:name: Combining and -and- or operators condition: (event.i > 100 and event.i < 200) or event.i > 1000 action: debug:
带赋值的多条件情况
当条件被评估时,如果条件通过,匹配的事件将存储在名为 m_0、m_1、m_2 等常用属性中。第一个条件将存储在 m_0 中,第二个条件存储在 m_1 中……这是基于条件在列表中的位置,因此您可以预见地在其他条件中使用它。您还可以选择使用 << 运算符为这些属性设置别名。例如
name: multiple conditions condition: all: - events.first << event.i == 0 - events.second << event.i == 1 - events.third << event.i == events.first.i + 2 action: debug: msg: - "first: {{ events.first }}" - "second: {{ events.second }}" - "third: {{ events.third }}"
name: multiple conditions using default assignments condition: all: - event.i == 0 - event.i == 1 - event.i == events.m_0.i + 2 action: debug: msg: - "first: {{ events.m_0 }}" - "second: {{ events.m_1 }}" - "third: {{ events.m_2 }}"
带默认赋值的多条件情况
name: multiple conditions condition: all: - event.i == 1 - event.i == 2 - event.i == events.m_0.i + 3 action: debug: msg: - "first: {{ events.m_0 }}" - "second: {{ events.m_1 }}" - "third: {{ events.m_2 }}"
第一个匹配项存储为 m_0,后续匹配项存储为 m_1、m_2 等……
单一条件赋值(不支持)
name: assignment ignored condition: event.first << event.i == 0 action: debug: msg: - "event: {{event}}"
否定示例
name: negation condition: not (event.i > 50 or event.i < 10) action: print_event:
注意
当值为单个逻辑语句时,not 运算符可以在没有圆括号的情况下工作
如果存在多个带有 or 或 and 的逻辑语句,请像上面所示那样使用圆括号。
为多条件规则添加时间限制
name: Condition with timeout condition: all: - event.x == 5 - event.y == 99 timeout: 10 seconds action: debug:
当“并非所有”条件都满足时为规则添加时间限制
name: Not all conditions met with timeout condition: not_all: - event.msg == "Applying Maintenance" - event.msg == "Server Rebooted" - event.msg == "Application Restarted" timeout: 5 minutes action: run_playbook: name: notify_delays.yml
限制动作以应对事件风暴:反应式
name: Throttle example reactive condition: event.code == "error" throttle: once_within: 5 minutes group_by_attributes: - event.meta.hosts - event.code action: run_playbook: name: notify_outage.yml
限制动作以应对事件风暴:被动式
name: Throttle example passive condition: event.code == "warning" throttle: once_after: 5 minutes group_by_attributes: - event.meta.hosts - event.code action: run_playbook: name: notify_outage.yml
限制动作,直到接收到特定数量的事件
name: Throttle with threshold condition: event.code == "warning" throttle: accumulate_within: 5 minutes threshold: 10 group_by_attributes: - event.meta.hosts - event.code action: run_playbook: name: notify_outage.yml
字符串搜索
name: string search example condition: event.url is search("example.com", ignorecase=true) action: print_event:
name: string not search example condition: event.url is not search("example.com", ignorecase=true) action: print_event:
字符串匹配
name: string match example condition: event.url is match("http://www.example.com", ignorecase=true) action: print_event:
name: string not search example condition: event.url is not match("http://www.example.com", ignorecase=true) action: print_event:
字符串正则表达式
name: string regex example condition: event.url is regex("example\.com", ignorecase=true) action: print_event:
name: string not regex example condition: event.url is not regex("example\.com", ignorecase=true) action: print_event:
检查列表是否存在某个项目
# variables file expected_levels: - "WARNING" - "ERROR"name: check if an item exist in a list condition: event.level in vars.expected_levels action: debug: msg: matched!name: check if an item does no exist in a list condition: event.level not in ["INFO", "DEBUG"] action: debug: msg: matched!name: check if a list contains an item condition: event.affected_hosts contains "host1" action: debug: msg: matched!name: check if a list does not contain an item condition: vars.expected_levels not contains "INFO" action: debug: msg: This will match always for every event because INFO is not in the list!
基于测试检查列表是否存在某个项目
name: check if an item exist in list condition: event.levels is select('>=', 10) action: debug: msg: The list has an item with the value greater than or equal to 10
基于测试检查列表是否不存在某个项目
name: check if an item does not exist in list condition: event.levels is not select('>=', 10) action: debug: msg: The list does not have item with the value greater than or equal to 10
您还可以在关于循环和列表推导式的 Ansible playbook 文档中找到有关 select 条件的更多信息。
基于测试检查列表是否存在某个对象
name: check if an object exist in list condition: event.objects is selectattr('age', '>=', 20) action: debug: msg: An object with age greater than 20 found
基于测试检查列表是否不存在某个对象
name: check if an object does not exist in list condition: event.objects is not selectattr('age', '>=', 20) action: debug: msg: No object with age greater than 20 found
您还可以在关于循环和列表推导式的 Ansible playbook 文档中找到有关 selectattr 条件的更多信息。
常见问题解答 (FAQ)
- 示例
name: send to debug condition: event.payload.eventType != 'GET' action: debug:
在上述情况下,如果 event.payload.eventType 未定义,则该条件将被忽略,不匹配任何内容。
- 示例
name: rule1 condition: event.msg is defined action: retract_fact: fact: msg: "{{event.msg}}"
- 示例
name: rule2 condition: fact.msg is not defined action: set_fact: fact: msg: Hello World
- 示例
name: rule1 condition: 'event.abc == "test: 1"'
name: rule1 condition: > event.abc == "test: 1"
name: rule1 condition: | event.abc == "test: 1"