networking - 如何重复ansible任务直到结果失败+显示每次重试的时间戳?
问题描述
我正在尝试解决网络自动化问题。问题是我们有一个奇怪的行为网络设备(SNOM 电话)以链的形式连接到某个 Cisco 交换机端口。问题是其中一部手机(每次都是不同的手机)随机消失,之后此类设备无法通过 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 回调插件,但它仅显示成功条件的时间戳(即在我的情况下 - 结果失败)
所以,我正在寻找一个建议,如何实现这两个目标:
- 永远运行任务,直到状态失败
- 写入每次重试的时间戳
提前致谢!
解决方案
好吧,因为最初的问题是关于 Ansible,所以我通过保存时间戳并从路由器获取 dhcp 日志并按时间戳和 MAC 地址过滤日志来解决了这个问题:
---
- 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 调试日志以不同的方式打印它们:
瞻博网络调试日志:
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 地址。
推荐阅读
- java - Java反射从静态类调用嵌套方法
- python - 是否有任何正确的格式可以将上下文名称添加到 snmp 代理?
- c# - Net Core - 集成测试 - TestServer - 真实的http连接
- java - 在java中读取可扩展的arraylist
- sql - 通过 SQL 查询获取百分比
- nginx - 从 $uri NGINX 中获取一部分
- html - 如何使用 col-12 显示前四个记录,重置记录将显示为 col-8(col-6 和 col-6)
- delphi - Delphi泛型类使用编译错误
- c# - 转换类型任务
键入 IEnumerable - ios - 如何在swift中解压缩带有密码的json文件?