Ansible处理Cisco NXOS时钟时间计算与格式化问题咨询
场景说明
- 示例设备时钟输出格式如下:
12:02:43.569 UTC Wed Jul 06 2022
- 需求:编写Ansible脚本,基于上述格式的时间值,计算往前偏移15分钟的时间结果。
- 初始编写的Playbook内容如下:
--- - name: Cisco NXOS hosts: all connection: network_cli gather_facts: false vars: - cmdlist1: sh clock - ansible_python_interpreter: /usr/bin/python3 - ansible_network_os: nxos - cmdlist2: sh logging | include 2/3 tasks: - name: Execute command nxos_command: commands: "{{ cmdlist1 }}" register: output - set_fact: arr: "{{ output.stdout_lines[0][1].split() }}" - debug: msg: "{{ arr[0] }}"
- 参考@vladimir提供的可行方案修改后的Playbook代码如下(已修正原代码中t3变量未闭合引号的笔误):
--- - name: Cisco NXOS hosts: all connection: network_cli gather_facts: false vars: - cmdlist1: sh clock - ansible_python_interpreter: /usr/bin/python3 - ansible_network_os: nxos - cmdlist2: sh logging | include 2/3 tasks: - name: Execute command nxos_command: commands: "{{ cmdlist1 }}" register: output - set_fact: arr: "{{ output.stdout_lines[0][1] }}" - debug: msg: | {{ arr }} {{ t1 }} {{ t2 }} {{ t3 }} vars: t1: "{{ (arr|to_datetime('%H:%M:%S.%f %Z %a %b %d %Y')).strftime('%s') }}" t2: "{{ t1|int - 15 * 60 }}" t3: "{{ '%H:%M:%S %Z %a %b %d %Y'|strftime(t2) }}"
- 执行Playbook的命令如下:
[LABPC@lab-jump-host dow]$ ansible-playbook interfaceflappingdup.yml -i inventory1.txt --limit nxos -verbose
- 执行时默认加载配置文件路径为
/etc/ansible/ansible.cfg,执行输出结果如下:
PLAY [Cisco NXOS] ****************************************************************************************************************************************************************************************** TASK [Execute command] ************************************************************************************************************************************************************************************* ok: [nxos] => {"changed": false, "stdout": ["Time source is NTP\n19:53:30.797 UTC Wed Jul 06 2022"], "stdout_lines": [["Time source is NTP", "19:53:30.797 UTC Wed Jul 06 2022"]]} TASK [set_fact] ******************************************************************************************************************************************************************************************** ok: [nxos] => {"ansible_facts": {"arr": "19:53:30.797 UTC Wed Jul 06 2022"}, "changed": false} TASK [debug] *********************************************************************************************************************************************************************************************** ok: [nxos] => { "msg": "19:53:30.797 UTC Wed Jul 06 2022\n1657151610 \n1657150710 \n19:38:30 EDT Wed Jul 06 2022\n" } PLAY RECAP ************************************************************************************************************************************************************************************************* nxos : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
问题解答
- 是。
strftime('%s')的作用就是将解析完成的datetime对象,转换为从Unix纪元(1970-01-01 00:00:00 UTC)起算的秒级时间戳,后续做时间偏移的加减算术运算会非常方便。 - 是。这部分逻辑是把偏移计算后得到的秒级epoch时间戳,按照预先定义的
%H:%M:%S %Z %a %b %d %Y格式模板,转换为可直接阅读的时间字符串。 - 不需要编辑全局ansible.cfg,两种方案都可以解决:
- 临时指定输出回调:执行playbook命令前加环境变量
ANSIBLE_STDOUT_CALLBACK=yaml,临时把输出格式改成yaml渲染模式,换行符会被正常解析,不会显示成字面量\n,示例命令:
ANSIBLE_STDOUT_CALLBACK=yaml ansible-playbook interfaceflappingdup.yml -i inventory1.txt --limit nxos -v- 调整debug输出写法:把原来用
|定义的多行块msg,改成列表格式输出,或者拆成多个独立debug任务分别打印变量,Ansible输出列表/多任务结果时会自动换行,不会把换行符转义成普通字符。
- 临时指定输出回调:执行playbook命令前加环境变量
- 输出EDT时区是因为strftime处理epoch时间戳时,默认取Ansible执行节点的本地时区做转换,要输出UTC时间直接修改时间计算逻辑即可,推荐直接在datetime对象层面做偏移,避免时区干扰:
把t1、t2、t3的变量定义替换成下面的内容即可:
如果不想改偏移计算逻辑,也可以在把时间戳转回datetime对象时指定按UTC解析,修改t3定义为:vars: t1: "{{ arr | to_datetime('%H:%M:%S.%f %Z %a %b %d %Y') }}" t2: "{{ t1 - timedelta(minutes=15) }}" t3: "{{ t2.strftime('%H:%M:%S UTC %a %b %d %Y') }}"
两种方式最终输出的都是UTC时区的偏移后时间。t3: "{{ ((t2 | int) | to_datetime(fmt='%s', utc=True)).strftime('%H:%M:%S UTC %a %b %d %Y') }}"
内容的提问来源于stack exchange,提问作者Inlovewithansible
相关产品推荐
相关产品推荐

