Need To Create List Of Dictionary With New Field 'device_id' Added

I have my code written like below .
But i am not able to get proper List of dictionary.

---
- name: Create final list by adding device_id to san_mount_list without exceeding size_gb
  hosts: localhost
  gather_facts: false
  vars:
    my_remain_space: 0
    my_hard_disk_converted_to_GB:
      - device_id: 2
        size: 32212254725
        size_gb: 30
      - device_id: 3
        size: 32212254724
        size_gb: 30

    san_mount_list_converted_to_GB:
      - no_of_vols: 1
        cap_unit: 'BYTES'
        size_gb: 9.74
        size: 10475277143
        mount_point: G

      - no_of_vols: 1
        cap_unit: 'BYTES'
        size_gb: 29.85
        size: 32212254723
        mount_point: H

      - no_of_vols: 1
        cap_unit: 'BYTES'
        size_gb: 9.75
        size: 10475277144
        mount_point: F

      - no_of_vols: 1
        cap_unit: 'BYTES'
        size_gb: 9.78
        size: 10475277145
        mount_point: H


  tasks:
    - name: "Convert 'san_mount_list_converted_to_GB' With Sorted To 'size_gb'"
      ansible.builtin.set_fact:
        my_hard_disk_converted_to_GB_sorted_decending: "{{ my_hard_disk_converted_to_GB | sort(attribute='size') }}"
        san_mount_list_converted_to_GB_sorted_ascending: "{{ san_mount_list_converted_to_GB | sort(attribute='size_gb') }}"




    - name: "Set Fact 'my_final_list'"
      ansible.builtin.set_fact:
        final_full_lun_details: "{{ final_full_lun_details | default([]) + [{ 'no_of_vols': item.1.no_of_vols, 'cap_unit': item.1.cap_unit, 'size': item.1.size, 'size_gb': item.1.size_gb, 'mount_point': item.1.mount_point, 'device_id': item.0.device_id }] }}"
        my_device_id: "{{ my_device_id | default([]) + [item.0.device_id] }}"
        my_remain_space: "{{ my_remain_space | int - item.1.size_gb | int | round(2) }}"
      when:
        - item.0.size_gb | int | round(2) >= item.1.size_gb | int | round(2)
        # - item.0.device_id not in my_device_id | default([])
        - my_remain_space | int > item.1.size_gb | int | round(2)
      with_nested:
        - "{{ my_hard_disk_converted_to_GB_sorted_decending }}"
        - "{{ san_mount_list_converted_to_GB_sorted_ascending }}"
      vars:
        my_disk_size: "{{ item.0.size_gb | int | round(2) }}"
        my_remain_space: "{{ my_disk_size }}"


    - name: "Print my_final_list"
      ansible.builtin.debug:
        var: final_full_lun_details

I have 2 list

my_hard_disk_converted_to_GB:
  - device_id: 2
    size: 32212254725
    size_gb: 30
  - device_id: 3
    size: 32212254724
    size_gb: 30


san_mount_list_converted_to_GB:
  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 29.85
    size: 32212254723
    mount_point: H

  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 9.75
    size: 10475277144
    mount_point: F

  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 9.78
    size: 10475277145
    mount_point: H

  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 9.74
    size: 10475277143
    mount_point: G

I want to create a final_list
which will add device_id on san_mount_list_converted_to_GB and doesn’t cross size_gb of my_hard_disk_converted_to_GB.

san_mount_list_converted_to_GB:
  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 29.85
    size: 32212254723
    mount_point: H
    device_id: 2

  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 9.75
    size: 10475277144
    mount_point: F
    device_id: 3

  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 9.78
    size: 10475277145
    mount_point: H
    device_id: 3

  - no_of_vols: 1
    cap_unit: 'BYTES'
    size_gb: 9.74
    size: 10475277143
    mount_point: G
    device_id: 3

What is the relationship between items in the two lists? Put another way, how are you supposed to know what device_id each item in san_mount_list_converted_to_GB gets?

my_hard_disk_converted_to_GB:
- device_id: 2
size: 32212254725
size_gb: 50
- device_id: 3
size: 32212254724
size_gb: 50
- device_id: 4
size: 32212254723
size_gb: 50

san_mount_list_converted_to_GB:
- no_of_vols: 1
cap_unit: ‘BYTES’
size_gb: 49.84
size: 50475274245
mount_point: G
device_id: 12
- no_of_vols: 1
cap_unit: ‘BYTES’
size_gb: 9.84
size: 10475274245
mount_point: G
device_id: 13
- no_of_vols: 1
cap_unit: ‘BYTES’
size_gb: 39.85
size: 404752742465
mount_point: F
device_id: 13
- no_of_vols: 1
cap_unit: ‘BYTES’
size_gb: 9.87
size: 10475274240
mount_point: F
device_id: 14
- no_of_vols: 1
cap_unit: ‘BYTES’
size_gb: 19.89
size: 11932554240
mount_point: H
device_id: 14
- no_of_vols: 1
cap_unit: ‘BYTES’
size_gb: 19.92
size: 11932554240
mount_point: I
device_id: 14

This is new 2 list I have now … It is having only size sum match … where device_id is different.
So 2 supposed to be replaced 12
So 3 supposed to be replaced 13
So 4 supposed to be replaced 14

Im afraid I still dont understand the relationship between the two lists. I dont see any matching sizes or size_gbs in the two lists

So 2 supposed to be replaced 12
So 3 supposed to be replaced 13
So 4 supposed to be replaced 14

I dont understand this either. Are you saying device_id 2 should be replaced with device_id: 12? Or the second item in the first list should be replaced by the 12th item in the second list?

server 'A" was having 3 LUN DIsk [with ID 12 and 13 and 14] and was having drives created over there. [List : san_mount_list_converted_to_GB].

I got server ‘B’ which is having same count of disk [with ID 2 and 3 and 4]
I want to create same drive over server ‘B’. [List :my_hard_disk_converted_to_GB].

Since Server ‘B’ don’t have 12,13,14 I want them to be replaced by 2,3,4 respectively.

Hope this helps. If you wanted to specify your own device ID mapping, the playbook could be simpler

- hosts: localhost
  gather_facts: false
  vars_files:
    - my_hard_disk_converted_to_GB.yml
    - san_mount_list_converted_to_GB.yml
  tasks:
    - name: Get Unique Device IDs Lists
      ansible.builtin.set_fact:
        my_hard_disk_converted_to_GB_device_ids: >-
          {{ my_hard_disk_converted_to_GB | map(attribute='device_id') | unique }}
        san_mount_list_converted_to_GB_device_ids: >-
          {{ san_mount_list_converted_to_GB | map(attribute='device_id') | unique }}
    - name: Create New san_mount_list_converted_to_GB
      ansible.builtin.set_fact:
        new_san_mount_list_converted_to_GB: >-
          {{ new_san_mount_list_converted_to_GB | default([]) +
          [item | combine({'device_id': _device_id_map[item['device_id']]})] }}
      loop: "{{ san_mount_list_converted_to_GB }}"
      vars:
        _device_id_map: >-
          {{ my_hard_disk_converted_to_GB_device_ids | zip(san_mount_list_converted_to_GB_device_ids) |
          map('reverse') | community.general.dict }}
    - name: Print New List
      ansible.builtin.debug:
        var: new_san_mount_list_converted_to_GB

Apology For late response
This is probably the best solution.


  • name: “Mapping SAN Mount Drive With Source/Old Device ID And Target/new Device ID”
    hosts: localhost
    gather_facts: false
    vars:

    my_hard_disk_converted_to_GB:

    - { device_id: 1, size: 32212254720, size_gb: 300.0 } # 11

    - { cap_unit: “BYTES”, device_id: 11, mount_point: “H”, no_of_vols: “1”, size: 10479468544, size_gb: 250.00 }

    - { cap_unit: “BYTES”, device_id: 11, mount_point: “J”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]

    - { device_id: 3, size: 32212254720, size_gb: 100.0 } # 14

    - { cap_unit: “BYTES”, device_id: 14, mount_point: “E”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]

    - { cap_unit: “BYTES”, device_id: 14, mount_point: “J”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]

    - { device_id: 2, size: 32212254720, size_gb: 400.0 } # 12

    - { cap_unit: “BYTES”, device_id: 12, mount_point: “G”, no_of_vols: “1”, size: 10479468544, size_gb: 400.00 }

    - { device_id: 4, size: 32212254720, size_gb: 100.0 } # 13

    - { cap_unit: “BYTES”, device_id: 13, mount_point: “F”, no_of_vols: “1”, size: 10479468544, size_gb: 100.00 }

    - { device_id: 5, size: 32212254720, size_gb: 500.0 } # 15

    - { cap_unit: “BYTES”, device_id: 15, mount_point: “I”, no_of_vols: “1”, size: 31460425728, size_gb: 500.00 }

    my_hard_disk_converted_to_GB:
    - { device_id: 1, size: 32212254720, size_gb: 300.0 } # 11
    - { device_id: 3, size: 32212254720, size_gb: 100.0 } # 14
    - { device_id: 2, size: 32212254720, size_gb: 400.0 } # 12
    - { device_id: 4, size: 32212254720, size_gb: 100.0 } # 13
    - { device_id: 5, size: 32212254720, size_gb: 500.0 } # 15
    san_mount_drive_details_converted_to_GB:
    - { cap_unit: “BYTES”, device_id: 13, mount_point: “F”, no_of_vols: “1”, size: 10479468544, size_gb: 100.00 }
    - { cap_unit: “BYTES”, device_id: 11, mount_point: “H”, no_of_vols: “1”, size: 10479468544, size_gb: 250.00 }
    - { cap_unit: “BYTES”, device_id: 15, mount_point: “I”, no_of_vols: “1”, size: 31460425728, size_gb: 500.00 }
    - { cap_unit: “BYTES”, device_id: 14, mount_point: “E”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]
    - { cap_unit: “BYTES”, device_id: 11, mount_point: “J”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]
    - { cap_unit: “BYTES”, device_id: 12, mount_point: “G”, no_of_vols: “1”, size: 10479468544, size_gb: 400.00 }
    - { cap_unit: “BYTES”, device_id: 14, mount_point: “J”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]

    san_mount_drive_details_converted_to_GB:

    - { cap_unit: “BYTES”, device_id: 13, mount_point: “F”, no_of_vols: “1”, size: 10479468544, size_gb: 90.00 } # noqa yaml[colons]

    - { cap_unit: “BYTES”, device_id: 11, mount_point: “H”, no_of_vols: “1”, size: 10479468544, size_gb: 245.00 }

    - { cap_unit: “BYTES”, device_id: 15, mount_point: “I”, no_of_vols: “1”, size: 31460425728, size_gb: 480.00 }

    - { cap_unit: “BYTES”, device_id: 14, mount_point: “E”, no_of_vols: “1”, size: 31460425728, size_gb: 45.00 } # noqa yaml[colons]

    - { cap_unit: “BYTES”, device_id: 11, mount_point: “J”, no_of_vols: “1”, size: 31460425728, size_gb: 50.00 } # noqa yaml[colons]

    - { cap_unit: “BYTES”, device_id: 12, mount_point: “G”, no_of_vols: “1”, size: 10479468544, size_gb: 390.00 }

    - { cap_unit: “BYTES”, device_id: 14, mount_point: “J”, no_of_vols: “1”, size: 31460425728, size_gb: 40.00 } # noqa yaml[colons]

    tasks:

    • name: “Fetch Total Size Used Per Device-IDs By Looping Over ‘san_mount_drive_details_converted_to_GB’”
      ansible.builtin.set_fact:
      total_size_per_device: “{{total_size_per_device | default({}) | combine({item.device_id: (total_size_per_device[item.device_id] | default(0)) + item.size_gb}) }}”
      loop: “{{ san_mount_drive_details_converted_to_GB }}”
      loop_control:
      label: “{{ item.device_id }}”

    • name: “Format ‘total_size_per_device’ Total Size Used Per Device-IDs”
      ansible.builtin.set_fact:
      final_total_size_per_device: “{{ final_total_size_per_device | default() + [{‘device_id’:item.key, ‘size_gb’: item.value}] }}”
      loop: “{{ total_size_per_device | dict2items }}”

    • name: “Print Total Size Used Per Device-IDs”
      ansible.builtin.debug:
      var: final_total_size_per_device

    • name: “Initialize Empty Lists For Device Mappings And Processed Device-IDs”
      ansible.builtin.set_fact:
      device_mapping_list:
      processed_source_device_ids:
      processed_target_device_ids:

    • name: “Map ‘source_device_id’ With ‘target_device_id’ Pairs Without Duplicates”
      ansible.builtin.set_fact:
      device_mapping_list: “{{ device_mapping_list + [{‘source_device_id’: item.0.device_id, ‘target_device_id’: item.1.device_id}] }}”
      processed_source_device_ids: “{{ processed_source_device_ids + [item.0.device_id] }}”
      processed_target_device_ids: “{{ processed_target_device_ids + [item.1.device_id] }}”
      when:

      • item.0.device_id not in processed_source_device_ids
      • item.1.device_id not in processed_target_device_ids
      • item.1.size_gb | float >= item.0.size_gb | float

      - item.1.size_gb | float == item.0.size_gb | float

      with_nested:

      • “{{ final_total_size_per_device | sort(attribute=‘size_gb’) | reverse }}”
      • “{{ my_hard_disk_converted_to_GB }}”
    • name: “Display ‘device_mapping_list’”
      ansible.builtin.debug:
      var: device_mapping_list

    • name: “Map And Replace ‘source_device_id’ With ‘target_device_id’ On Var ‘san_mount_drive_details_converted_to_GB’”
      ansible.builtin.set_fact:
      final_mapped_san_mount_drive_details: “{{ final_mapped_san_mount_drive_details | default() + [
      {
      ‘device_id’: item.0.target_device_id,
      ‘size_gb’: item.1.size_gb,
      ‘mount_point’: item.1.mount_point,
      ‘no_of_vols’: item.1.no_of_vols,
      ‘size’: item.1.size,
      ‘cap_unit’: item.1.cap_unit
      }] }}”
      when: item.0.source_device_id | int == item.1.device_id | int
      with_nested:

      • “{{ device_mapping_list }}”
      • “{{ san_mount_drive_details_converted_to_GB }}”
    • name: “Show Final ‘final_mapped_san_mount_drive_details’”
      ansible.builtin.debug:
      var: final_mapped_san_mount_drive_details

Could you enclose the YAML in three backticks to improve the formatting? See for example the GitHub guide.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.