可靠的。解析 yaml

Ansible. Parse yaml

我正在尝试从变量 interf 获取地址 192.168.176.129:

"interf": {
    "1": {
        "adminstatus": "up",
        "description": "",
        "ifindex": "1",
        "ipv4": [
            {
                "address": "192.168.176.129",
                "netmask": "255.255.255.0"
            }
        ],
        "mac": "000c29788c7f",
        "mtu": "1500",
        "name": "ether1",
        "operstatus": "up",
        "speed": "1000000000"
    }
}

我尝试这样做,但没有结果

- set_fact:
    test_name: "{{ interf|
                   select('regex', my_regex)|
                   first|
                   regex_replace(my_regex, my_replace) }}"
  vars:
    my_regex: '^address (.*)$'
    my_replace: ''
- debug:
    var: test_name

如何获取地址值:192.168.176.129 和操作状态值:up?我做错了什么?

为什么要使用正则表达式? Ansible 能够访问字典的 JSON 和 YAML 属性以及访问列表。

如果你只关心一个IP地址,你可以这样做:

- debug:
   var: interf['1'].ipv4.0.address

如果您关心拥有多个地址的可能性,那么您将获得一个地址列表:

- debug:
   var: interf['1'].ipv4 | map(attribute='address')

鉴于剧本:

- hosts: localhost
  gather_facts: no
  vars:
        interf:
          '1':
            adminstatus: up
            description: ''
            ifindex: '1'
            ipv4:
            - address: 192.168.176.129
              netmask: 255.255.255.0
            mac: 000c29788c7f
            mtu: '1500'
            name: ether1
            operstatus: up
            speed: '1000000000'

  tasks:
    - name: Get the first IP address only
      debug:
       var: interf['1'].ipv4.0.address

    - name: Get a list of (possibly) all the IPs address
      debug:
       var: interf['1'].ipv4 | map(attribute='address')

这产生:

TASK [Get the first IP address only] **************************************************
ok: [localhost] => 
  interf['1'].ipv4.0.address: 192.168.176.129

TASK [Get a list of (possibly) all the IPs address] ***********************************
ok: [localhost] => 
  interf['1'].ipv4 | map(attribute='address'):
  - 192.168.176.129

我采取了稍微不同的方法,假设 var 被解析为 JSON 对象而不是直接转换为 YAML。

在这个例子中,我们首先解析JSON,然后使用JMESPATH 来提取地址。调试语句循环遍历列表并输出每个地址。​​

如果您知道您只需要第一项,那么您可以将 json 查询更改为 interf.*.ipv4[*].address | [0][0],并且只返回一个地址。

- name: Test
  hosts: localhost
  vars:
    json: | 
      {
        "interf": {
          "1": {
              "adminstatus": "up",
              "description": "",
              "ifindex": "1",
              "ipv4": [
                  {
                      "address": "192.168.176.129",
                      "netmask": "255.255.255.0"
                  }
              ],
              "mac": "000c29788c7f",
              "mtu": "1500",
              "name": "ether1",
              "operstatus": "up",
              "speed": "1000000000"
          }
        }
      }
  tasks:
    - name: Extract IPs
      set_fact: 
        addresses: "{{ json | from_json | json_query(\"interf.*.ipv4[*].address | [0]\") | list }}"
    - name: Loop through addresses
      debug:
        msg: "{{ item }}"
      with_items: "{{ addresses }}"