设置一个Ansible变量为true,如果CSV表格的某一列至少有一行具有特定值。

huangapple go评论60阅读模式
英文:

set an ansible variable to true if at least one row in a csv sheet column has a certain value

问题

我需要设置一个Ansible变量为true,如果csv表格的某一列中至少有一行具有特定值(假设为"ERROR"),列名为特定值(假设为"lv2"),否则为false。

我已将csv表格的内容保存(注册)到一个变量中,使用以下任务:

- name: 读取 my_data CSV
  community.general.read_csv:
    path: "{{ log_base_path }}/my_data.csv"
    delimiter: ;
  register: my_data

该变量的内容由以下任务显示:

- name: 显示包含 my_data CSV 内容的变量
  debug:
    var: my_data

其输出是:

localhost ok: {
    "changed": false,
    "my_data": {
        "changed": false,
        "dict": {},
        "failed": false,
        "list": [
            {
                "lv1": "ERROR",
                "attr1": "OK",
                "attr2": "OK",
                "lv2": "ERROR",
                "st_id": "75",
                "attr3": "OK"
            },
            {
                "lv1": "OK",
                "attr1": "OK",
                "attr2": "OK",
                "lv2": "OK",
                "st_id": "20",
                "attr3": "OK"
            }
        ]
    }
}

我尝试过以下方式:

- name: 检查 lv2 是否有任何错误
  set_fact:
    lv2_check_all: true
  when: "'ERROR' in my_data | map(attribute=lv2) | list"

但会抛出以下错误:

localhost failed | msg: 条件检查 "'ERROR' in my_data | map(attribute=lv2) | list" 失败。错误是:在评估条件时发生错误('ERROR' in my_data | map(attribute=lv2) | list):ansible.utils.unsafe_proxy.AnsibleUnsafeText 对象没有元素 AnsibleUndefined

问题是什么?

英文:

I need to set an ansible variable to true if at least one row in a csv sheet column has a certain value (let's say "ERROR") under a certain column (let's say "lv2"), to false otherwise.

I have saved (registered) the content of the csv sheet into a variable with this task

- name: read my_data CSV
  community.general.read_csv:
    path: "{{ log_base_path }}/my_data.csv"
    delimiter: ;
  register: my_data

the content of thei variable is showed by this task

- name: show the variable in which is the my_data CSV content
  debug:
    var: my_data

whose output is

  localhost ok: {
    "changed": false,
    "my_data": {
        "changed": false,
        "dict": {},
        "failed": false,
        "list": [
            {
                "lv1": "ERROR",
                "attr1": "OK",
                "attr2": "OK",
                "lv2": "ERROR",
                "st_id": "75",
                "attr3": "OK"
            },
            {
                "lv1": "OK",
                "attr1": "OK",
                "attr2": "OK",
                "lv2": "OK",
                "st_id": "20",
                "attr3": "OK"
            }
        ]
    }
}

I have tryed with

- name: Check if any error in lv2
  set_fact:
    lv2_check_all: true
  when: "'ERROR' in my_data | map(attribute=lv2) | list"

but it throws this error:

localhost failed | msg: The conditional check ''ERROR' in my_data | map(attribute=lv2) | list' failed. The error was: error while evaluating conditional ('ERROR' in my_data | map(attribute=lv2) | list): ansible.utils.unsafe_proxy.AnsibleUnsafeText object has no element AnsibleUndefined

What is the problem?

答案1

得分: 2

你可以设置无条件的事实。这样,变量将始终被定义

  lv2_check_all: "{{ 'ERROR' in my_data.list|map(attribute='lv2') }}"

下一个选项是计算与条件匹配的项目数

  lv2_check_all: "{{ my_data.list|
                     selectattr('lv2', 'eq', 'ERROR')|
                     length > 0 }}"

两个选项都会得到

  lv2_check_all: true

给定文件

shell> cat /tmp/my_data.csv
lv1;attr1;attr2;lv2;st_id;attr3
ERROR;OK;OK;ERROR;75;OK
OK;OK;OK;OK;20;OK

用于测试的完整playbook示例

shell> cat pb.yml
- hosts: localhost

  vars:

    lv2_check_all: "{{ my_data.list|
                       selectattr('lv2', 'eq', 'ERROR')|
                       length > 0 }}"

  tasks:

    - read_csv:
        path: /tmp/my_data.csv
        delimiter: ;
      register: my_data

    - debug:
        msg: ERROR in lv2
      when: lv2_check_all

得到

shell> ansible-playbook pb.yml 

PLAY [localhost] ******************************************************************************

TASK [read_csv] *******************************************************************************
ok: [localhost]

TASK [debug] **********************************************************************************
ok: [localhost] => 
  msg: ERROR in lv2

PLAY RECAP ************************************************************************************
localhost: ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

英文:

You can set the fact without condition. This way the variable will always be defined

  lv2_check_all: "{{ 'ERROR' in my_data.list|map(attribute='lv2') }}"

The next option is to count items that match the condition

  lv2_check_all: "{{ my_data.list|
                     selectattr('lv2', 'eq', 'ERROR')|
                     length > 0 }}"

both options give

  lv2_check_all: true

<hr>

<sup>

Given the file

shell&gt; cat /tmp/my_data.csv
lv1;attr1;attr2;lv2;st_id;attr3
ERROR;OK;OK;ERROR;75;OK
OK;OK;OK;OK;20;OK

Example of a complete playbook for testing

shell&gt; cat pb.yml
- hosts: localhost

  vars:

    lv2_check_all: &quot;{{ my_data.list|
                       selectattr(&#39;lv2&#39;, &#39;eq&#39;, &#39;ERROR&#39;)|
                       length &gt; 0 }}&quot;

  tasks:

    - read_csv:
        path: /tmp/my_data.csv
        delimiter: ;
      register: my_data

    - debug:
        msg: ERROR in lv2
      when: lv2_check_all

gives

shell&gt; ansible-playbook pb.yml 

PLAY [localhost] ******************************************************************************

TASK [read_csv] *******************************************************************************
ok: [localhost]

TASK [debug] **********************************************************************************
ok: [localhost] =&gt; 
  msg: ERROR in lv2

PLAY RECAP ************************************************************************************
localhost: ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

</sup>

huangapple
  • 本文由 发表于 2023年6月8日 18:15:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76430830.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定