如何重复ansible任务直到结果失败+显示每次重试的时间戳?

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

我正在尝试解决网络自动化问题。问题是我们有一个奇怪的行为,网络设备(SNOM电话)链接到某个思科交换机端口。事情是这样的电话之一(每次不同的电话)随机消失,之后这种设备无法通过DHCP获得IP地址。我们仍然没有找到重现问题的方法,因此我在DHCP服务器上启用了调试日志,现在等待,其中一个mac地址将从交换机接口mac地址表中消失。

由于cisco不支持linux'watch'命令,我为此目的编写了一个简单的ansible playbook:

---
- name: show mac address-table 
  hosts: ios
  gather_facts: no


  tasks:

  - name: show mac address-table interface Fa0/31
    ios_command:
      commands: show mac address-table interface Fa0/31
      wait_for:
        - result[0] contains 0004.1341.799e
        - result[0] contains 0004.134a.f67d
        - result[0] contains 0004.138e.1a53
    register: result
    until: result is failed
    retries: 1000
  - debug: var=result

但在那种配置中我只看到了

FAILED - RETRYING: show mac address-table interface Fa0/31 (660 retries left).
FAILED - RETRYING: show mac address-table interface Fa0/31 (659 retries left).
FAILED - RETRYING: show mac address-table interface Fa0/31 (658 retries left).
FAILED - RETRYING: show mac address-table interface Fa0/31 (657 retries left).

在输出。我试图使用anstomlog回调插件,但它只显示成功条件的时间戳(即在我的情况下 - 然后结果失败)

所以,我正在寻求建议,如何实现这两个目标:

  • 永远运行任务,直到状态失败
  • 写每个重试的时间戳

提前致谢!

networking ansible cisco snom
2个回答
0
投票

最好将其重写为普通循环(使用include_tasks)并报告该任务中所需的所有信息。

依靠'重审'作为监督者并不是一个好主意。

而且,我认为将其重写为独立程序会更好。如果你担心转换ssh,netmiko是所有网络设备的一个很好的即用型怪癖集合。它有'.command'方法在交换机上执行。


0
投票

好吧,因为最初的问题是关于Ansible我只是通过时间戳和mac地址保存时间戳并从路由器和过滤日志中获取dhcp日志来解决问题:

---
- name: Find switch port by host ip address
  hosts: all
  gather_facts: no
  connection: local
  roles:
    - Juniper.junos  
  vars:
    systime: "{{ ansible_date_time.time }}"
    timestamp: "{{ ansible_date_time.date }}_{{ systime }}"
    connection_settings:
      host: "{{ ansible_host }}"
      timeout: 120
    snom_mac_addresses:
      - '00_04:13_41:79_9e'
      - '00_04:13_4a:f6_7d'
      - '00_04:13_8e:1a_53'

  tasks:

  - name: show mac address-table interface Fa0/31
    ios_command:
      commands: show mac address-table interface Fa0/31
      wait_for:
        - result[0] contains {{ snom_mac_addresses[0] | replace(':', '.')| replace('_', '') }}
        - result[0] contains {{ snom_mac_addresses[1] | replace(':', '.')| replace('_', '') }}
        - result[0] contains {{ snom_mac_addresses[2] | replace(':', '.')| replace('_', '') }}
        - result[0] contains {{ snom_mac_addresses[3] | replace(':', '.')| replace('_', '') }}
    register: result
    until: result is failed
    retries: 1000
    ignore_errors: True
    when: inventory_hostname == 'access-switch'


  - name: save timestamp in Junos format
    set_fact: 
      junos_timestamp: "{{ lookup('pipe','date +%b_%_d_%H:%M') | replace('_', ' ') }}"
    run_once: yes
    delegate_to: localhost

  - debug: 
      var: junos_timestamp
    run_once: yes
    delegate_to: localhost

  - name: get dhcp log from router
    junos_scp:
      provider: "{{ connection_settings }}"
      src: /var/log/dhcp-service.log
      remote_src: true
    when: inventory_hostname == 'router'

  - name: filter log for time
    run_once: yes
    shell: "egrep -i '{{ junos_timestamp }}' dhcp-service.log"
    register: grep_time_output
    delegate_to: localhost

  - debug: var=grep_time_output.stdout_lines    

  - name: filter log for time and mac
    run_once: yes
    shell: "egrep -i '{{ snom_mac_addresses | join('|') | replace(':', ' ')| replace('_', ' ') }}' dhcp-service.log"
    register: grep_mac_output
    delegate_to: localhost

  - debug: var=grep_mac_output.stdout_lines

很确定它看起来不是一个优雅的解决方案,但至少我在一个Ansible环境中完成所有工作,任何人都可以重复使用我的部分代码而无需重大的重构。

只有一个疑问 - 我将自己的格式用于mac地址,因为Cisco和Juniper调试日志以不同的方式打印它们:

Juniper调试日志:

Mar  6 13:14:19.582886 [MSTR][DEBUG] client_key_compose: Composing key (0x1c6aa00) for cid_l 7, cid d4 a3 3d a1 e2 38, mac d4 a3 3d a1 e2 38, htype 1, subnet 10.111.111.1, ifindx 0, opt82_l 0, opt82 NULL

思科:

 30    0004.133d.39fb    DYNAMIC     Po1

但也许有一种聪明的方法来处理Ansible中mac地址的所有不同格式。

© www.soinside.com 2019 - 2024. All rights reserved.