Ansible with_subelements 在 FortiGates 上出错

问题描述 投票:0回答:1

我有一个 Ansible 剧本,我正在使用 with_subelements 模块在 FortiGates 上执行 SNMP 用户操作。我尝试使用循环,但这表现出了一些非常奇怪的行为(在另一个问题here中概述)。由于某种原因,我似乎无法让它正确解析和执行。您可以在控制台错误输出中看到 JSON 信息,其中“meta”是顶级元素。我需要将 JSON 数据转换为其他格式吗?我使用了错误的语法吗?难道我想做的事不会以这种方式进行吗?

它在 RHEL 9.4、Ansible 9.7 和 Python 3.11.7 上运行。

host_pinned
就是策略。

代码非常简单。它首先执行 API 调用来获取所有 SNMP 用户信息。然后,它应该使用 with_subelements 来遍历输出并删除任何不符合条件的 SNMP 用户,即标准用户。

剧本#1:

- name: Gather SNMP info
  fortinet.fortios.fortios_json_generic:
    vdom: "root"
    json_generic:
        method: "GET"
        path: "/api/v2/cmdb/system.snmp/user"
  register: snmp_output 

- name: Remove non-standard usernames from FortiGate devices
  fortinet.fortios.fortios_system_snmp_user:
    vdom: "root"
    state: "absent"
    system_snmp_user:
      name: "{{ item.1 }}"
  with_subelements: 
    - "{{ snmp_output | default([]) }}"
    - "{{ meta.results.name }}"
  when: 
    - item.1 != "test1"
    - item.1 != "test2"

此代码产生以下输出和相应的错误。请注意错误消息如何开始流入之前的任务,这可能是也可能不是控制台奇怪,尽管这种行为是一致的。

***编辑:添加到 snmp_output 的调试中以添加参考

WITH_SUBELEMENTS 错误#1:

TASK [Gather SNMP info] ********************************************************
changed: [firewall1] => changed=true 
  meta:
    build: 1577
    http_method: GET
    http_status: 200
    matched_count: 2
    name: user
    next_idx: 1
    path: system.snmp
    results:
    - auth-proto: sha
      auth-pwd: ENC XXXX
      events: cpu-high mem-low log-full intf-ip vpn-tun-up vpn-tun-down ha-switch ha-hb-failure ips-signature ips-anomaly av-virus av-oversize av-pattern av-fragmented fm-if-change bgp-established bgp-backward-transition ha-member-up ha-member-down ent-conf-change av-conserve av-bypass av-oversize-passed av-oversize-blocked ips-pkg-update ips-fail-open temperature-high voltage-alert power-supply-failure faz-disconnect wc-ap-up wc-ap-down fswctl-session-up fswctl-session-down load-balance-real-server-down per-cpu-high dhcp pool-usage ospf-nbr-state-change ospf-virtnbr-state-change
      ha-direct: enable
      mib-view: ''
      name: test1
      notify-hosts: XXXX
      notify-hosts6: ''
      priv-proto: aes
      priv-pwd: ENC XXXX
      q_origin_key: test1
      queries: enable
      query-port: 161
      security-level: auth-priv
      source-ip: 0.0.0.0
      source-ipv6: '::'
      status: enable
      trap-lport: 162
      trap-rport: 162
      trap-status: disable
      vdoms: []
    - auth-proto: sha
      auth-pwd: ENC XXXX
      events: cpu-high mem-low log-full intf-ip vpn-tun-up vpn-tun-down ha-switch ha-hb-failure ips-signature ips-anomaly av-virus av-oversize av-pattern av-fragmented fm-if-change bgp-established bgp-backward-transition ha-member-up ha-member-down ent-conf-change av-conserve av-bypass av-oversize-passed av-oversize-blocked ips-pkg-update ips-fail-open temperature-high voltage-alert power-supply-failure faz-disconnect wc-ap-up wc-ap-down fswctl-session-up fswctl-session-down load-balance-real-server-down per-cpu-high dhcp pool-usage ospf-nbr-state-change ospf-virtnbr-state-change
      ha-direct: enable
      mib-view: ''
      name: test2
      notify-hosts: XXXX
      notify-hosts6: ''
      priv-proto: aes
      priv-pwd: ENC XXXX
      q_origin_key: test2
      queries: enable
      query-port: 161
      security-level: auth-priv
      source-ip: 0.0.0.0
      source-ipv6: '::'
      status: enable
      trap-lport: 162
      trap-rport: 162
      trap-status: disable
      vdoms: []
    revision: XXXX
    serial: XXXX
    size: 2
    status: success
    vdom: root
    version: v7.2.7
The conditional check 'item.1 != "test1"' failed. The error was: error while evaluating conditional (item.1 != "test1"): 'item' is undefined. 'item' is undefined

The error appears to be in '/home/svc-acct/_work/7/s/ansible/import_tasks/FortiOS_snmp_update-task.yml': line 61, column 3, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:


- name: Remove non-standard usernames from FortiGate devices
  ^ here

TASK [Debug snmp_output register] **************************************************
ok: [firewall1] => 
  msg: 'Contents of snmp_output: {''changed'': True, ''meta'': {''http_method'': ''GET'', ''size'': 2, ''matched_count'': 2, ''next_idx'': 1, ''revision'': ''XXXX'', ''results'': [{''name'': ''test1'', ''q_origin_key'': ''test1'', ''status'': ''enable'', ''trap-status'': ''disable'', ''trap-lport'': 162, ''trap-rport'': 162, ''queries'': ''enable'', ''query-port'': 161, ''notify-hosts'': ''XXXX'', ''notify-hosts6'': '''', ''source-ip'': ''0.0.0.0'', ''source-ipv6'': ''::'', ''ha-direct'': ''enable'', ''events'': ''cpu-high mem-low log-full intf-ip vpn-tun-up vpn-tun-down ha-switch ha-hb-failure ips-signature ips-anomaly av-virus av-oversize av-pattern av-fragmented fm-if-change bgp-established bgp-backward-transition ha-member-up ha-member-down ent-conf-change av-conserve av-bypass av-oversize-passed av-oversize-blocked ips-pkg-update ips-fail-open temperature-high voltage-alert power-supply-failure faz-disconnect wc-ap-up wc-ap-down fswctl-session-up
    fswctl-session-down load-balance-real-server-down per-cpu-high dhcp pool-usage ospf-nbr-state-change ospf-virtnbr-state-change'', ''mib-view'': '''', ''vdoms'': [], ''security-level'': ''auth-priv'', ''auth-proto'': ''sha'', ''auth-pwd'': ''ENC XXXX'', ''priv-proto'': ''aes'', ''priv-pwd'': ''ENC XXXX''}, {''name'': ''test2'', ''q_origin_key'': ''test2'', ''status'': ''enable'', ''trap-status'': ''disable'', ''trap-lport'': 162, ''trap-rport'': 162, ''queries'': ''enable'', ''query-port'': 161, ''notify-hosts'': ''XXXX'', ''notify-hosts6'': '''', ''source-ip'': ''0.0.0.0'', ''source-ipv6'': ''::'', ''ha-direct'': ''enable'', ''events'': ''cpu-high mem-low log-full intf-ip vpn-tun-up vpn-tun-down ha-switch ha-hb-failure ips-signature ips-anomaly av-virus av-oversize av-pattern av-fragmented fm-if-change bgp-established bgp-backward-transition ha-member-up ha-member-down ent-conf-change av-conserve
    av-bypass av-oversize-passed av-oversize-blocked ips-pkg-update ips-fail-open temperature-high voltage-alert power-supply-failure faz-disconnect wc-ap-up wc-ap-down fswctl-session-up fswctl-session-down load-balance-real-server-down per-cpu-high dhcp pool-usage ospf-nbr-state-change ospf-virtnbr-state-change'', ''mib-view'': '''', ''vdoms'': [], ''security-level'': ''auth-priv'', ''auth-proto'': ''sha'', ''auth-pwd'': ''ENC XXXX'', ''priv-proto'': ''aes'', ''priv-pwd'': ''ENC XXXX''}], ''vdom'': ''root'', ''path'': ''system.snmp'', ''name'': ''user'', ''status'': ''success'', ''http_status'': 200, ''serial'': ''XXXX'', ''version'': ''v7.2.7'', ''build'': 1577}, ''failed'': False}'


TASK [Remove non-standard usernames from FortiGate devices] ********************
fatal: [firewall1]: FAILED! => 
  msg: '''meta'' is undefined. ''meta'' is undefined'

TASK [Log failure and rescue] **************************************************
ok: [firewall1] => 
  msg: firewall1 has experienced a failure

TASK [ansible.builtin.lineinfile] **********************************************
changed: [firewall1] => changed=true 
  backup: ''
  msg: line added

PLAY RECAP *********************************************************************
firewall1           : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=1    ignored=0

如果我稍微调整 with_subelements 参数,我将得到以下结果(后续示例中省略的收集 SNMP 信息任务输出):

剧本#2:

- name: Gather SNMP info
  fortinet.fortios.fortios_json_generic:
    vdom: "root"
    json_generic:
        method: "GET"
        path: "/api/v2/cmdb/system.snmp/user"
  register: snmp_output 

- name: Remove non-standard usernames from FortiGate devices
  fortinet.fortios.fortios_system_snmp_user:
    vdom: "root"
    state: "absent"
    system_snmp_user:
      name: "{{ item.1 }}"
  with_subelements: 
    - "{{ snmp_output.meta.results | default([]) }}"
    - name
  when: 
    - item.1 != "test1"
    - item.1 != "test2"

WITH_SUBELEMENTS 错误#2:

TASK [Remove non-standard usernames from FortiGate devices] ********************
fatal: [uslb1m01fwl01-01]: FAILED! => 
  msg: the key name should point to a list, got 'CPR-CTL-RO'

如果我尝试一点不同,我会得到:

剧本#3:

- name: Gather SNMP info
  fortinet.fortios.fortios_json_generic:
    vdom: "root"
    json_generic:
        method: "GET"
        path: "/api/v2/cmdb/system.snmp/user"
  register: snmp_output 

- name: Remove non-standard usernames from FortiGate devices
  fortinet.fortios.fortios_system_snmp_user:
    vdom: "root"
    state: "absent"
    system_snmp_user:
      name: "{{ item.1 }}"
  with_subelements: 
    - "{{ snmp_output.meta | default([]) }}"
    - name
  when: 
    - item.1 != "test1"
    - item.1 != "test2"

WITH_SUBELEMENTS 错误#3:

TASK [Remove non-standard usernames from FortiGate devices] ********************
fatal: [firewall1]: FAILED! => 
  msg: subelements lookup expects a dictionary, got 'test1'

最后一次尝试...

剧本#4:

- name: Gather SNMP info
  fortinet.fortios.fortios_json_generic:
    vdom: "root"
    json_generic:
        method: "GET"
        path: "/api/v2/cmdb/system.snmp/user"
  register: snmp_output 

- name: Remove non-standard usernames from FortiGate devices
  fortinet.fortios.fortios_system_snmp_user:
    vdom: "root"
    state: "absent"
    system_snmp_user:
      name: "{{ item.1 }}"
  with_subelements: 
    - "{{ snmp_output.meta | default([]) }}"
    - results.name
  when: 
    - item.1 != "test1"
    - item.1 != "test2"

WITH_SUBELEMENTS 错误#4:

TASK [Remove non-standard usernames from FortiGate devices] ********************
fatal: [firewall1]: FAILED! => 
  msg: subelements lookup expects a dictionary, got 'GET'

库存文件样本:

inventory:
  children:
    lab:
#
lab:
  hosts:
    switch1:
      ansible_host: 10.1.2.2
      ansible_network_os: cisco.ios.ios
      ansible_connection: ansible.netcommon.network_cli
#
    firewall1:
      ansible_host: 10.1.2.3
      ansible_network_os: fortinet.fortios.fortios
      ansible_connection: ansible.netcommon.httpapi
      ansible_httpapi_use_ssl: yes
      ansible_httpapi_validate_certs: no
      ansible_httpapi_port: 4443

如果需要任何其他信息或有帮助,请告诉我。预先感谢!

ansible module element fortigate
1个回答
0
投票

除非我完全错过了你的剧本的目标,否则根据你的第一个任务输出和收集到的信息,绝对没有必要在这里使用

subelements
查找:

- name: Remove non-standard usernames from FortiGate devices
  fortinet.fortios.fortios_system_snmp_user:
    vdom: "root"
    state: "absent"
    system_snmp_user:
      name: "{{ item.name }}"
  loop: "{{ snmp_output.meta.results | default([]) }}"
  when: item.name not in ["test1", "test2"]
© www.soinside.com 2019 - 2024. All rights reserved.