Score:1

Accessing dict subelement value

ph flag
azk

Here's my playbook

- name: Host's luns
  debug:
    msg: "{{ luns }}"
  vars:
    luns: "{{ ansible_facts.lvm.pvs }}"

And the output for this is

TASK [Luns del vg] ************************************************************
ok: [awxworker_rhel6] => {
    "msg": {
        "/dev/sda2": {
            "free_g": "20.72",
            "size_g": "79.72",
            "vg": "vg00"
        },
        "/dev/sdb1": {
            "free_g": "3.99",
            "size_g": "4.99",
            "vg": "vg01"
        },
        "/dev/sdc1": {
            "free_g": "0.99",
            "size_g": "4.99",
            "vg": "vg02"
        },
        "/dev/sdd1": {
            "free_g": "4.99",
            "size_g": "4.99",
            "vg": "vg01"
        }
    }
}

I need to get the luns of a matched vg

Ej: "The vg01 luns are: /dev/sdb1 /dev/sdd1"

I have tried this beetwen other ways

- name: Luns del VG
  set_fact:
    vg_luns: "{{ item }}"
  with_items: "{{ ansible_facts.lvm.pvs }}"
    vars:
      VGname: "{{ VG }}"
  when: ansible_facts.lvm.pvs.vg_luns.vg == VGname
  
- name: Print VG's luns
  debug:
    msg:
      - "The {{ VGname }} luns are: {{ vg_luns }}"

VG is an extravariable where I put the matched VGname

$ ansible-playbook -i proyects/Inventory/awx_hosts -l testhost getvgluns.yml -e VG=vg01

Hope you can help

Thanks in advance!
Score:1
th flag

There's no need for set_fact or Ansible loops. Convert the dictionary to a list and use normal Jinja operations on it.

- debug:
    msg: "The {{ VG }} luns are: {{ ansible_facts.lvm.pvs | dict2items | selectattr('value.vg', 'equalto', VG) | map(attribute='key') | join(' ') }}"
azk avatar
ph flag
azk
Thank you very much! That points directly to what I need.
Score:0
br flag

Create a dictionary of the groups. For example

  - set_fact:
      vgs: "{{ vgs|d({})|
               combine({item.0: item.1|
                                map(attribute='key')|
                                list}) }}"
    loop: "{{ luns|dict2items|groupby('value.vg') }}"

gives

  vgs:
    vg00:
    - /dev/sda2
    vg01:
    - /dev/sdb1
    - /dev/sdd1
    vg02:
    - /dev/sdc1

Then the selection is trivial

    - debug:
        msg: "The {{ VG }} luns are: {{ vgs[VG]|join(' ') }}"

gives the message

shell> ansible-playbook playbook.yml -e VG=vg01

  msg: 'The vg01 luns are: /dev/sdb1 /dev/sdd1'
azk avatar
ph flag
azk
This is an attractive solution too. Perhaps there's a syntax problem because it gives me an error: ``` FAILED! => {"msg": "|combine expects dictionaries, got \"{'vg00': <generator object do_map at 0x7fd9fdd3c888>}\""} ``` I'll try to find out what it is.
br flag
Add the *list* filter. I updated the answer. Actually, both solutions use the same procedure. The *list* is not needed in the solution you accepted because of the filter *join* right after *map*. Here, the *join* filter is used after the group was selected.
azk avatar
ph flag
azk
Perfect. I accept your solution too. It works well. Thank you very much!
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.