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

Ansible动态生成CSV表头适配SNMP主机数量需求

解决Ansible采集SNMP主机数据动态生成CSV表头的方案

方案一:动态生成CSV表头(推荐)

通过先汇总所有设备的SNMP主机字段,再基于唯一字段生成表头,完美匹配实际采集数据:

  1. 采集并处理单设备SNMP主机数据
    将每个设备的SNMP主机列表转换为带序号的键值对(如snmp_host_1: 192.168.1.1),方便后续字段汇总:

    - name: 采集设备SNMP主机数据
      snmp_facts:
        host: "{{ inventory_hostname }}"
        version: v2c
        community: public
      register: snmp_raw_data
    
    - name: 格式化SNMP主机为带序号的键值对
      set_fact:
        formatted_snmp_hosts: >
          {% set host_list = snmp_raw_data.snmp_hosts | default([]) %}
          {% set result = {} %}
          {% for idx, host in enumerate(host_list, start=1) %}
            {% set _ = result.update({'snmp_host_' ~ idx: host}) %}
          {% endfor %}
          {{ result }}
    
  2. 汇总所有设备的SNMP字段
    在本地节点汇总所有设备的字段名,去重后作为最终表头:

    - name: 收集所有设备的SNMP字段
      set_fact:
        all_snmp_fields: "{{ all_snmp_fields | default([]) + formatted_snmp_hosts.keys() | list }}"
      delegate_to: localhost
      run_once: true
    
    - name: 生成唯一有序的表头字段
      set_fact:
        final_csv_headers: "{{ all_snmp_fields | unique | sort }}"
      delegate_to: localhost
      run_once: true
    
  3. 生成CSV文件
    使用Jinja2模板,基于动态表头写入所有设备数据,缺失字段自动留空:

    - name: 生成最终CSV报告
      template:
        src: snmp_report.csv.j2
        dest: ./network_snmp_hosts.csv
      delegate_to: localhost
      run_once: true
    

    模板文件snmp_report.csv.j2内容:

    {{ final_csv_headers | join(',') }}
    {% for device in groups['network_devices'] %}
      {% set device_data = hostvars[device]['formatted_snmp_hosts'] | default({}) %}
      {{ final_csv_headers | map('extract', device_data, '') | join(',') }}
    {% endfor %}
    

方案二:填充默认值后移除空列

如果无法提前汇总字段,可先按预估最大数量定义表头,填充缺失值后再清理空列:

  1. 预定义表头并填充数据
    假设最多可能有10个SNMP主机,预定义表头后,对每个设备的缺失字段填充空值:

    - name: 预定义初始CSV表头
      set_fact:
        temp_headers: "{{ ['snmp_host_' ~ idx for idx in range(1, 11)] }}"
      delegate_to: localhost
      run_once: true
    
    - name: 填充设备SNMP数据(不足10个则补空)
      set_fact:
        filled_snmp_data: >
          {% set data = formatted_snmp_hosts | default({}) %}
          {% set result = {} %}
          {% for header in temp_headers %}
            {% set _ = result.update({header: data.get(header, '')}) %}
          {% endfor %}
          {{ result }}
    
  2. 移除全空列
    使用Python脚本过滤掉所有行都为空的列,生成最终CSV:

    - name: 清理CSV空列
      shell: |
        python3 - << 'EOF'
        import csv
        import sys
    
        input_path = sys.argv[1]
        output_path = sys.argv[2]
    
        with open(input_path, 'r') as f:
            rows = list(csv.reader(f))
    
        # 筛选非空列索引
        valid_cols = []
        for col_idx in range(len(rows[0])):
            if any(row[col_idx].strip() for row in rows[1:]):
                valid_cols.append(col_idx)
    
        # 生成过滤后的数据
        filtered_rows = [[row[idx] for idx in valid_cols] for row in rows]
    
        with open(output_path, 'w', newline='') as f:
            csv.writer(f).writerows(filtered_rows)
        EOF
        ./temp_snmp_report.csv ./final_snmp_report.csv
      delegate_to: localhost
      run_once: true
    

注意事项

  • 方案一无需事后处理,效率更高,适合字段波动大的场景;方案二适合采集任务分散、无法提前汇总字段的情况。
  • 不同厂商设备的SNMP返回结构可能有差异,需根据实际返回调整formatted_snmp_hosts的处理逻辑。

内容的提问来源于stack exchange,提问作者Yashas K.M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:30:56