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

如何在Ansible Playbook中展开VLAN范围列表为完整数字列表?

问题:在Ansible中展开VLAN范围列表

我有一个格式为 allowed_vlans: "1,20-22,37,39-40,600,1011-1013,1025" 的VLAN列表,需要将其转换为展开后的完整数字列表:allowed_vlans_range: "1, 20, 21, 22, 37, 39, 40, 600, 1011, 1012, 1013, 1025"

限制条件

  • 仅允许使用单个Playbook文件
  • 不能使用外部Jinja2模板(可嵌入Playbook内)
  • 禁止使用外部Python插件

已完成的前置步骤

1. 获取端口通道允许VLAN列表

已通过以下任务获取每个端口通道的允许VLAN配置:

tasks:
  - name: 获取端口通道接口信息
    cisco.nxos.nxos_facts:
      gather_subset: interfaces
      gather_network_resources: interfaces
    register: pc_info

  - name: 获取端口通道接口允许的VLAN列表
    vars:
      port_channels_list: "{{ pc_info.ansible_facts.ansible_network_resources.interfaces | map(attribute='name') | flatten | to_json | from_json | regex_findall('port-channel[0-9]+') }}"
    cisco.nxos.nxos_command:
      commands:
        - show run interface {{ item }} | grep "allowed vlan"
    loop: "{{ port_channels_list }}"
    register: pc_allowed_vlans

2. 提取范围格式的VLAN项

已从结果中提取出类似20-22、39-40的范围项:

- name: 解析允许的VLAN
    vars:
      allowed_vlans: "{{ item.stdout | regex_findall('[0-9]+(?:-[0-9]+)?') }}"
      allowed_vlans_ranges: "{{ allowed_vlans | regex_findall('[0-9]+-[0-9]+') }}"
    debug:
      msg: "{{ allowed_vlans_ranges }}"
    loop: "{{ pc_allowed_vlans.results }}"
    register: allowed_vlans_range

解决方案:嵌入Jinja2逻辑实现范围展开

可以在Playbook中直接嵌入Jinja2逻辑,逐个处理每个VLAN项(单个数字或范围),最终生成展开后的完整列表。以下是完整任务实现:

- name: 展开VLAN范围并生成完整列表
    vars:
      # 提取纯VLAN字符串(去掉命令输出前缀)并分割为单个项
      vlan_items: "{{ item.stdout | regex_replace('.*allowed vlan ', '') | split(',') }}"
      # Jinja2逻辑:展开所有VLAN项
      expand_vlan_logic: |
        {% set expanded_list = [] %}
        {% for vlan in vlan_items %}
          {% if '-' in vlan %}
            {% set start = vlan.split('-')[0] | int %}
            {% set end = vlan.split('-')[1] | int %}
            {% for num in range(start, end + 1) %}
              {% do expanded_list.append(num | string) %}
            {% endfor %}
          {% else %}
            {% do expanded_list.append(vlan) %}
          {% endif %}
        {% endfor %}
        {{ expanded_list | join(', ') }}
    debug:
      msg: "端口通道 {{ item.item }} 展开后的VLAN列表: {{ expand_vlan_logic }}"
    loop: "{{ pc_allowed_vlans.results }}"
    register: expanded_vlans

逻辑说明

  1. 提取并分割VLAN项:用regex_replace移除命令输出中的allowed vlan 前缀,再用split(',')将字符串拆分为独立的VLAN项列表
  2. 展开范围项:
    • 遍历每个VLAN项,若包含-则分割为起始和结束数字,通过range生成中间所有数字
    • 单个VLAN数字直接加入结果列表
  3. 拼接结果:用join(', ')将展开后的数字列表转换为带空格分隔的字符串

如果需要将结果存储为变量供后续任务使用,可将debug模块替换为set_fact,或者直接引用expanded_vlans.results中的对应字段。


内容的提问来源于stack exchange,提问作者Karl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 08:56:02