首页 > 解决方案 > Ansible parse_cli 以任意顺序从配置行构建对象

问题描述

我正在尝试使用 Ansible 从一系列 Cisco IOS 路由器中解析 DHCP 范围。

<TL;博士; >我目前正在使用带有正则表达式的 parse_cli,其中包括在不同位置(例如domain_name_1domain_name_2)中相同事物的多个命名匹配项,然后通过将它们分配为将它们组合到输出对象中domain_name: "{{ item.domain_name_1 }}{{ item.domain_name_2 }}"- 因为一次只会填充其中一个,输出对象仍然包含正确的数据。我想找到一种方法来做到这一点,它不需要像那种丑陋的不灵活的黑客。< /TL;博士; >

我喜欢parse_cliJinja 过滤器,因为它提供了一个很好的对象作为仅包含我需要的信息的输出,但我无法找到一种方法让它处理配置中任意顺序的命令。

以下是三个不同顺序的相同配置示例。配置行的顺序可能因路由器运行的固件版本、输入命令的顺序或路由器的型号而异。命令本身(在这种情况下)总是相同的,所以我只需要一种方法来提取每一行并适当地解析它。

思科 867

ip dhcp pool Data
  import all
  network 192.168.1.0 255.255.255.0
  update dns
  default-router 192.168.1.1
  dns-server 192.168.1.1 8.8.8.8
  option 42 ip 192.168.1.1
  domain-name test.local
  lease 8

思科 881

ip dhcp pool Data
  import all
  network 192.168.1.0 255.255.255.0
  option 42 ip 192.168.1.1
  default-router 192.168.1.1
  dns-server 192.168.1.1 8.8.8.8
  domain-name test.local
  lease 8

思科 1111

ip dhcp pool Data
  import all
  network 192.168.1.0 255.255.255.0
  default-router 192.168.1.1
  dns-server 192.168.1.1 8.8.8.8
  domain-name test.local
  option 42 ip 192.168.1.1
  lease 8

在所有这些情况下或将来出现的任何其他新顺序中,我想在 ansible 中创建一个对象,作为具有以下格式的事实:

{
  "network": "192.168.1.0",
  "dns-servers": ["192.168.1.1", "8.8.8.8"],
  "domain-name": "test.local",
  "options": {
    "42": {
      "type": "ip",
      "value": "192.168.1.1"
    }
  }
}

目前我正在做这样的事情:

任务/main.yml

- name: Get Cisco IOS DHCP pools
  ios_command:
    commands:
      - 'show running-config | s ip dhcp pool'
    retries: 1
  register: ciscoios_dhcp_pool_output

- name: Convert Cisco IOS DHCP pools to list
  delegate_to: 127.0.0.1
  set_fact:
    info_dhcp_pools: "{{ ciscoios_dhcp_pool_output.stdout[0] | parse_cli('roles/get-router-dhcp-pools/parsers/ios-pools.yml') }}"

解析器/ios-pools.yml

---
vars:
  dhcp_pool:
    name: "{{ item.name }}"
    network: "{{ item.network_ip }}"
    subnet: "{{ item.network_subnet }}"
    dns_servers: "{{ item.dns_servers_1 }}{{ item.dns_servers_2 }}"
    domain_name: "{{ item.domain_name_0 }}{{ item.domain_name_1 }}{{ item.domain_name_2 }}{{ item.domain_name_3 }}"
    options: "{{ item.options_1 }}{{ item.options_2 }}"
    lease_days: "{{ item.lease_days }}"
    lease_hours: "{{ item.lease_hours }}"
    lease_minutes: "{{ item.lease_minutes }}"

keys:
  dhcp_pools:
    value: "{{ dhcp_pool }}"
    items: "^ip dhcp pool (?P<name>[^\\n]+)\\s+(?:import (?P<import_all>all)\\s*)?(?:network (?P<network_ip>[\\d.]+) (?P<network_subnet>[\\d.]+)?\\s*)?(?:update dns\\s*)?(?:host (?P<host_ip>[\\d.]+) (?P<host_subnet>[\\d.]+)\\s*)?(?:domain-name (?P<domain_name_0>[\\w._-]+)\\s+)?(?:default-router (?P<default_router>[\\d.]+)\\s*)?(?:dns-server (?P<dns_servers_1>(?:[\\d.]+ ?)+ ?)+\\s*)?(?:domain-name (?P<domain_name_1>[\\w._-]+)\\s+)?(?P<options_1>(?:option [^\\n]+\\n*\\s*)*)?(?:domain-name (?P<domain_name_2>[\\w._-]+)\\s+)?(?P<options_2>(?:option [^\\n]+\\n*\\s*)*)?(?:dns-server (?P<dns_servers_2>(?:[\\d.]+ ?)+ ?)+\\s*)?(?:domain-name (?P<domain_name_3>[\\w._-]+)\\s*)?(lease (?P<lease_days>\\d+)(?: (?P<lease_hours>\\d+))?(?: (?P<lease_minutes>\\d+))?\\s*)?(?:update arp)?"

然而,这感觉非常混乱,每次我发现配置行可以出现的新顺序时都需要更新。感觉应该有更好的方法来实现,但我不确定它是什么。

标签: ansible

解决方案


推荐阅读