Ansible 更新 Vyos 上的多个防火墙规则

Ansible Update multiple firewall rules on Vyos

我一直在尝试创建一个剧本,我可以 运行 定期检查我所有的 Vyos 防火墙规则并确保存在“启用日志”命令,以防有人忘记添加日志记录到防火墙规则。我找到了 vyos.vyos.vyos_firewall_rules 模块,我认为它非常适合我需要做的事情。

唯一的问题是,此模块要求您输入要更新的每个防火墙规则的规则集名称和规则编号。但是在我的例子中,我希望自动完成此操作,并且 Ansible 遍历每个防火墙规则集和存在的相关规则,并确保在每个规则上启用日志记录。我需要这样的东西:

- name: Enable logging for each firewall rule
  vyos.vyos.vyos_firewall_rules:
    config:
    - afi: ipv4
      rule_sets:
      - name: *all rules sets*
        rules:
        - number: *all numbers*
          log: enabled

我使用 vyos.vyos.vyos_firewall_rules 收集了所有规则集和关联规则的转储,并将其过滤以列出每个规则集名称以及每个关联规则规则编号:

    - name: Get rulesets
      vyos.vyos.vyos_firewall_rules:
        config:
        state: gathered
      register: output

    - name: Filter output and populate the list of rule set names
      debug:
        msg: "Rule set name: {{ item.0.name }}, rule number: {{ item.1.number }}"
      loop: "{{ output.gathered[0]['rule_sets'] | subelements('rules') }}"

这会产生如下输出:

"Rule set name: ruleset-1, rule number: 1"
"Rule set name: ruleset-1, rule number: 2"
"Rule set name: ruleset-1, rule number: 15"
"Rule set name: ruleset-1, rule number: 20"
"Rule set name: ruleset-2, rule number: 1"
"Rule set name: ruleset-2, rule number: 2"

我有点不知从何而来。我觉得我需要像下面那样将信息过滤到嵌套列表中,然后以某种方式循环 vyos.vyos.vyos_firewall_rules 模块以更新每个规则集名称和规则编号。

firewall_rules:
   ruleset-1:
     1
     2
     15
     20
   ruleset-2
     1
     2

我一直无法弄清楚如何创建嵌套列表,或者我什至一开始就需要一个。

我对 Ansible 比较陌生,所以如果有人能指出正确的方向,我将不胜感激。

您可以先创建字典

    - set_fact:
        firewall_rules: "{{ dict(rsets|zip(rules)) }}"
      vars:
        rsets: "{{ output.gathered.0.rule_sets|
                   map(attribute='name')|list }}"
        rules: "{{ output.gathered.0.rule_sets|
                   map(attribute='rules')|
                   map('map', attribute='number')|list }}"

给予

  firewall_rules:
    ruleset-1:
    - 1
    - 2
    - 15
    - 20
    ruleset-2:
    - 1
    - 2

然后使用 Jinja 创建结构,例如

    - debug:
        var: _config|from_yaml
      vars:
        _config: |-
          - afi: ipv4
            rule_sets:
          {% for set, rules in firewall_rules.items() %}
              - name: {{ set }}
                rules:
          {% for rule in rules %}
                  - number: {{ rule }}
          {% endfor %}
          {% endfor %}

给予

  _config|from_yaml:
  - afi: ipv4
    rule_sets:
    - name: ruleset-1
      rules:
      - number: 1
      - number: 2
      - number: 15
      - number: 20
    - name: ruleset-2
      rules:
      - number: 1
      - number: 2

根据您的需要调整结构并在模块中使用它,例如

- vyos.vyos.vyos_firewall_rules:
    config: "{{ _config|from_yaml }}"
  vars:
    _config: |-
    ...

问:“{{ _config|from_yaml }} 的输出没有保留连字符。”

A:你看到的格式取决于callback plugin. If you want to see YAML set DEFAULT_STDOUT_CALLBACKyaml

shell> ANSIBLE_STDOUT_CALLBACK=yaml ansible-playbook test-753.yml

或将内容复制到文件

    - copy:
        dest: test-753-out.yml
        content: |
          {{ _config }}
      vars:
        _config: |-
          - afi: ipv4
            rule_sets:
          {% for set, rules in firewall_rules.items() %}
              - name: {{ set }}
                rules:
          {% for rule in rules %}
                  - number: {{ rule }}
          {% endfor %}
          {% endfor %}

给予

shell> cat test-753-out.yml
- afi: ipv4
  rule_sets:
    - name: ruleset-1
      rules:
        - number: 1
        - number: 2
        - number: 15
        - number: 20
    - name: ruleset-2
      rules:
        - number: 1
        - number: 2