Create dictionary / list from registered variable in Ansible

Viewed 258

Hej *,

I'm writing a playbook which should set some disk attributes in the Windows registry. All disk attributes are stored under a specific vendor folder. There is a value under each disk folder that I want to change in the end.

- Disk&Ven_QEMU&Prod_QEMU_HARDDISK
  |- 00000
  |- 00001
- Disk&Ven_VMware&Prod_Virtual_disk
  |- 00000

I'm able to determine the vendor folder as well as the disk folders under the root of HKLM:\SYSTEM\CurrentControlSet\Enum\SCSI:

- hosts: some_host
  tasks:
    - name: Get vendor folders
      win_reg_stat:
        path: HKLM:\SYSTEM\CurrentControlSet\Enum\SCSI
      register: vendors
    
    - name: Get disk folders
      win_reg_stat:
        path: "HKLM:\\SYSTEM\\CurrentControlSet\\Enum\\SCSI\\{{ item }}"
      with_items:
      - "{{ vendors.sub_keys }}"
      register: disks
    
    - debug:
        var: disks.results

The output looks like this:

ok: [some_host] => {
    "disks.results": [
        {
            "ansible_loop_var": "item",
            "changed": false,
            "exists": true,
            "failed": false,
            "item": "CdRom&Ven_QEMU&Prod_QEMU_DVD-ROM",
            "properties": {},
            "sub_keys": [
                "000001"
            ]
        },
        {
            "ansible_loop_var": "item",
            "changed": false,
            "exists": true,
            "failed": false,
            "item": "Disk&Ven_QEMU&Prod_QEMU_HARDDISK",
            "properties": {},
            "sub_keys": [
                "000000",
                "000001"
            ]
        },
        {
            "ansible_loop_var": "item",
            "changed": false,
            "exists": true,
            "failed": false,
            "item": "Disk&Ven_VMware&Prod_Virtual_disk",
            "properties": {},
            "sub_keys": [
                "000000"
            ]
        }
    ]
}

I'm a bit stuck right now. I'm trying to get a dictionary or list for iterating through all those disk folders. Something like that:

Disk&Ven_QEMU&Prod_QEMU_HARDDISK: 000000
Disk&Ven_QEMU&Prod_QEMU_HARDDISK: 000001
Disk&Ven_VMware&Prod_Virtual_disk: 000000

Is there a way to accomplish that?

Thanks and regards Erik

2 Answers

For example

    - set_fact:
        my_list: "{{ my_list|default([]) + [{item.0.item:item.1}] }}"
      with_subelements:
        - "{{ disks.results }}"
        - sub_keys

gives

  my_list:
  - CdRom&Ven_QEMU&Prod_QEMU_DVD-ROM: '000001'
  - Disk&Ven_QEMU&Prod_QEMU_HARDDISK: '000000'
  - Disk&Ven_QEMU&Prod_QEMU_HARDDISK: '000001'
  - Disk&Ven_VMware&Prod_Virtual_disk: '000000'

It's not possible to create a dictionary because, in a dictionary, the keys must be unique.

I want to share my final solution with you. Thanks to Vladimir for the help.

- name: Get vendors
  win_reg_stat:
    path: HKLM:\SYSTEM\CurrentControlSet\Enum\SCSI
  register: os_vendors
    
- name: Get vendors subfolders
  win_reg_stat:
    path: "HKLM:\\SYSTEM\\CurrentControlSet\\Enum\\SCSI\\{{ item }}"
  loop: "{{ os_vendors.sub_keys }}"
  register: os_subfolders

- name: Build registry pathes with vendors and disks
  set_fact:
    os_regpath_dict: "{{ os_regpath_dict | default({}) | combine ({item.item : item.sub_keys })}}"
  loop: "{{ os_subfolders.results }}"

- name: Get disk folders
  win_reg_stat:
    path: "HKLM:\\SYSTEM\\CurrentControlSet\\Enum\\SCSI\\{{ item.0.key }}\\{{ item.1 }}\\Device Parameters\\Partmgr"
    name: "Attributes"
  loop: "{{ os_regpath_dict | dict2items | subelements('value') }}"
  when: "'Disk' in item.0.key"
  register: os_disks

- name: Set value of entry Attributes to 0
  win_regedit:
    path: "HKLM:\\SYSTEM\\CurrentControlSet\\Enum\\SCSI\\{{ item.item.0.key }}\\{{ item.item.1 }}\\Device Parameters\\Partmgr"
    name: Attributes
    data: 0
    type: dword
  loop: "{{ os_disks.results }}"
  when: item.value is defined
Related