【问题标题】:Extract multiple fields from file with Ansible使用 Ansible 从文件中提取多个字段
【发布时间】:2024-01-19 07:26:01
【问题描述】:

为了从这个 json 文件中收集数据,我制作了一个 ansible playbook

{
    "validacion_user": {
        "stdout_lines": [
            "",
            "Account name: root",
            "Description: root",
            "Enabled: No",
            "Password Last Change Date: Thu Feb 14 2019 (UTC)",
            "Password Expiration Date: Not Applicable (UTC)",
            "Locked: No",
            "Role: root",
            "AD membership: 0-255",
            "Home AD: 0",
            "Day Time Access: N/A",
            "",
            "Account name: admin",
            "Description: Administrator",
            "Enabled: Yes",
            "Password Last Change Date: Thu Feb 14 2019 (UTC)",
            "Password Expiration Date: Not Applicable (UTC)",
            "Locked: No",
            "Role: admin",
            "AD membership: 0-255",
            "Home AD: 0",
            "Day Time Access: N/A",
            "",
            "Account name: user",
            "Description: User",
            "Enabled: Yes",
            "Password Last Change Date: Thu Feb 14 2019 (UTC)",
            "Password Expiration Date: Not Applicable (UTC)",
            "Locked: No",
            "Role: user",
            "AD membership: 0",
            "Home AD: 0",
            "Day Time Access: N/A",
            ""
        ]
    }
}

这是我写的剧本

---
 - name: User, Role and Status Playbook
   hosts: localhost
   gather_facts: false
   tasks: 
     - name: Obtener Usuario, rol y estado
       uri:
         url: http://192.168.1.20:80/data_broadcade.json
         validate_certs: no
         return_content: yes
       register: userbroadcade
     - debug: 
         var: userbroadcade  

     - name: Query broadcad
       set_fact:
         userdata_broadcade: "{{ userbroadcade.json.validacion_user.stdout_lines | json_query(query1) }}"
         
       vars:
         query1: "[*].{User: 'Account Name' ,Rol: Role, Estado: Enabled }"
     
         # - copy: content={{userdata_broadcade | replace('Yes','Activado') | replace('No','Desactivado')}} dest=/root/ansible/broadcade.txt

     - name: Debug
       debug:
         var: userdata_broadcade

但是当我执行 playbook 时,它会发送一个 null 和一个 Account Name 字符串:

我认为问题在于该文件的结构不如 Json,我一直在搜索,但我找不到如何获取帐户名称、启用和角色(注释行是它们工作时的数据导出) 有人知道如何导出这些字段吗?
('userdata_broadcade' 的路由没问题,因为如果我只在 query1 上放“[*]”,它就会显示所有数据)

【问题讨论】:

  • 您想获得哪个“帐户名称”?其中有 root、admin 和 user 三个。

标签: json ansible yaml


【解决方案1】:

让我们按原样保存文件并将密钥放入变量my_keys。例如

  vars_files:
    data_broadcade.json
  vars:
    my_keys: ['Account name', 'Role', 'Enabled']

然后下面的任务选择需要的数据

    - set_fact:
        my_dict: "{{ my_dict|default({})|
                     combine({item: my_values}) }}"
      loop: "{{ my_keys }}"
      vars:
        my_regex: '^{{ item }}:(.*)$'
        my_replace: '\1'
        my_values: "{{ validacion_user.stdout_lines|
                       select('match', my_regex)|
                       map('regex_replace', my_regex, my_replace)|
                       map('trim')|
                       list }}"
    - debug:
        var: my_dict

给予

  my_dict:
    Account name:
    - root
    - admin
    - user
    Enabled:
    - 'No'
    - 'Yes'
    - 'Yes'
    Role:
    - root
    - admin
    - user

下一个任务连接所需的字典列表

    - set_fact:
        my_list_length: "{{ my_dict[my_keys.0]|length }}"
    - set_fact:
        my_list: "{{ my_list|default([]) +
                     [dict(my_keys|zip(my_values))] }}"
      loop: "{{ range(0, my_list_length|int)|list }}"
      vars:
        my_values: "{{ my_keys|
                       map('extract', my_dict, [item])|
                       list }}"
    - debug:
        var: my_list

给予

  my_list:
  - Account name: root
    Enabled: 'No'
    Role: root
  - Account name: admin
    Enabled: 'Yes'
    Role: admin
  - Account name: user
    Enabled: 'Yes'
    Role: user

【讨论】:

    【解决方案2】:

    我认为问题在于文件没有像 Json 那样结构良好

    绝对正确,然而,几乎 yaml:

    -
      Account name: root
      Description: root
      Enabled: No
      Password Last Change Date: Thu Feb 14 2019 (UTC)
      Password Expiration Date: Not Applicable (UTC)
      Locked: No
      Role: root
      AD membership: 0-255
      Home AD: 0
      Day Time Access: N/A
    -
      Account name: admin
      Description: Administrator
      Enabled: Yes
    

    所以你可以做一些按摩来将这些行转换为 yaml,然后你有很多方法可以进入这些字典列表,或者使用 jinja2 过滤器或使用你最初尝试的 JMESpath,如果语法更简单的话给你

      - debug:
          var: userdata_broadcade
        vars:
          userdata_broadcade: >-
            {{ userbroadcade.json.validacion_user.stdout_lines
            | map("regex_replace", "^", "  ") 
            | map("regex_replace", "^ *$", "- ") 
            | join("\n") 
            | from_yaml
            }}
    

    【讨论】: