如何使用Ansible订阅NETCONF通知并等待通知?
实现Ansible订阅NETCONF通知并等待的方案
可以实现,Ansible本身没有原生支持NETCONF通知订阅的模块,但可以通过自定义Python脚本结合ncclient库(Ansible的NETCONF模块底层依赖该库)来完成订阅和等待逻辑,以下是具体实现步骤:
核心思路
软件更新的每一步(下载/安装/激活)分为两个阶段:
- 用Ansible原生的
netconf_rpc模块触发启动操作的RPC - 调用自定义脚本建立NETCONF订阅会话,阻塞等待对应操作完成的通知,收到通知后再进入下一步
步骤1:编写自定义等待通知的Python脚本
利用ncclient库建立NETCONF连接,订阅目标通知并阻塞等待,直到收到指定的操作完成通知后退出。
示例脚本wait_netconf_notification.py:
from ncclient import manager import xml.etree.ElementTree as ET import sys import os def main(): # 从环境变量或命令行参数获取连接信息(Ansible可通过extra_vars传递) host = os.getenv('NETCONF_HOST') or sys.argv[1] port = int(os.getenv('NETCONF_PORT') or sys.argv[2]) username = os.getenv('NETCONF_USER') or sys.argv[3] password = os.getenv('NETCONF_PASS') or sys.argv[4] target_event = sys.argv[5] # 传入要等待的事件:download-complete/install-complete/activate-complete # 定义通知过滤条件,只关注软件更新相关事件 filter_xml = f""" <filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"> <event> <software-update xmlns="your-device-namespace"> <{target_event}/> </software-update> </event> </notification> </filter> """ try: with manager.connect( host=host, port=port, username=username, password=password, hostkey_verify=False, device_params={'name': 'default'} ) as m: # 创建NETCONF通知订阅 m.create_subscription(filter=filter_xml) print(f"Waiting for {target_event} notification...") while True: msg = m.take_notification() if msg is None: continue # 解析通知XML,检查是否匹配目标事件 root = ET.fromstring(msg.xml) event_path = f".//{{your-device-namespace}}{target_event}" if root.find(event_path) is not None: print(f"Successfully received {target_event} notification") sys.exit(0) except Exception as e: print(f"Error waiting for notification: {str(e)}") sys.exit(1) if __name__ == "__main__": main()
步骤2:在Ansible Playbook中集成脚本
先触发启动RPC,再调用脚本等待对应通知,通过until重试机制处理超时和重试。
示例Playbook:
--- - name: Embedded Device Software Update via NETCONF hosts: embedded_devices gather_facts: no vars: netconf_port: 830 device_namespace: "your-device-namespace" # 替换为设备实际的命名空间 tasks: # 1. 触发下载启动RPC - name: Initiate software download netconf_rpc: rpc: | <initiate-download xmlns="{{ device_namespace }}"> <package-url>http://your-repo/software-package.bin</package-url> </initiate-download> display: xml # 2. 等待下载完成通知 - name: Wait for download completion notification script: wait_netconf_notification.py "{{ ansible_host }}" "{{ netconf_port }}" "{{ ansible_user }}" "{{ ansible_password }}" download-complete args: executable: python3 chdir: "{{ playbook_dir }}" register: download_result until: download_result.stdout.find("download-complete") != -1 retries: 20 # 根据操作耗时调整重试次数 delay: 15 # 每次重试间隔15秒 # 3. 触发安装启动RPC - name: Initiate software installation netconf_rpc: rpc: | <initiate-install xmlns="{{ device_namespace }}"> <package-name>software-package.bin</package-name> </initiate-install> display: xml # 4. 等待安装完成通知 - name: Wait for installation completion notification script: wait_netconf_notification.py "{{ ansible_host }}" "{{ netconf_port }}" "{{ ansible_user }}" "{{ ansible_password }}" install-complete args: executable: python3 chdir: "{{ playbook_dir }}" register: install_result until: install_result.stdout.find("install-complete") != -1 retries: 20 delay: 15 # 5. 触发激活启动RPC - name: Initiate software activation netconf_rpc: rpc: | <initiate-activate xmlns="{{ device_namespace }}"> <package-name>software-package.bin</package-name> </initiate-activate> display: xml # 6. 等待激活完成通知 - name: Wait for activation completion notification script: wait_netconf_notification.py "{{ ansible_host }}" "{{ netconf_port }}" "{{ ansible_user }}" "{{ ansible_password }}" activate-complete args: executable: python3 chdir: "{{ playbook_dir }}" register: activate_result until: activate_result.stdout.find("activate-complete") != -1 retries: 10 delay: 10
关键注意事项
- 确保嵌入式设备的NETCONF服务器支持NETCONF Notification(RFC 5277),且软件更新流程会发送对应操作完成的通知
- 脚本中的命名空间、通知元素路径必须与设备实际返回的XML结构完全匹配,可通过
netconf_get模块先获取通知示例来调整 - 可在脚本中添加超时逻辑,避免无限等待(比如设置最大等待时长,超时后退出并返回错误)
- 若嵌入式设备无法安装ncclient,可将脚本打包为独立可执行文件(比如用PyInstaller)后上传到设备执行
内容的提问来源于stack exchange,提问作者c.censier
相关产品推荐
相关产品推荐

