You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Ansible订阅NETCONF通知并等待通知?

实现Ansible订阅NETCONF通知并等待的方案

可以实现,Ansible本身没有原生支持NETCONF通知订阅的模块,但可以通过自定义Python脚本结合ncclient库(Ansible的NETCONF模块底层依赖该库)来完成订阅和等待逻辑,以下是具体实现步骤:

核心思路

软件更新的每一步(下载/安装/激活)分为两个阶段:

  1. 用Ansible原生的netconf_rpc模块触发启动操作的RPC
  2. 调用自定义脚本建立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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 10:04:57