Print Data Based On Size In Given Server [need no_of_vols]

i want to print Data Based On Size In Given Server and generate the ‘no_of_vols’.
storage_device:

  • servername: server1
    capacity:
  • no_of_vols: 1
    size: 10
    cap_unit: GB
  • no_of_vols: 2
    size: 11
    cap_unit: GB
  • server: server2
    capacity:
  • no_of_vols: 1
    size: 12
    cap_unit: GB
  • no_of_vols: 1
    size: 13
    cap_unit: GB
  • servername: ‘’
    capacity:
  • no_of_vols: 3
    size: 14
    cap_unit: GB
  • no_of_vols: 1
    size: 15
    cap_unit: GB

below is my code working till creating epecting list of dictionaries , but ‘no_of_vols’ i am facing issue.

It’s not 100% clear to me from your sample data exactly what you’re trying to achieve.

Reading between the lines though, for each server, you want to calculate the number of volumes?

What do you want to count as a ‘volume’? Each block device? Partition? PV? LV? Filesystem? Something else?

And do you need to do this using a statically defined var, or is that just illustrative? It’s highly likely that you can pull the data you need from setup/facts and calculate the values you need based on that.

I have a input
“storage_details_test_capacity”: [
{
“servername”: “server1”,
“cap_unit”: “GB”,
“size”: “10”
},
{
“servername”: “server1”,
“cap_unit”: “GB”,
“size”: “11”
},
{
“servername”: “server1”,
“cap_unit”: “GB”,
“size”: “11”
},
{
“cap_unit”: “GB”,
“servername”: “server2”,
“size”: “12”
},
{
“cap_unit”: “GB”,
“servername”: “server2”,
“size”: “13”
},
{
“cap_unit”: “GB”,
“servername”: “”,
“size”: “14”
},
{
“cap_unit”: “GB”,
“servername”: “”,
“size”: “14”
},
{
“cap_unit”: “GB”,
“servername”: “”,
“size”: “14”
},
{
“cap_unit”: “GB”,
“servername”: “”,
“size”: “15”
}
]

This is the best I’ve been able to come up with.
It isn’t pretty.
Usually when I find myself making something this convoluted, I ask myself if I’m actually solving more problems than I’m creating.
Anyway, here’s some code. Enjoy.

---
# javed01.yml
- name: Data manipulation tests
  hosts: localhost
  gather_facts: false
  vars:
    storage_details_test_capacity:
      - servername: server1
        cap_unit: GB
        size: "10"
      - servername: server1
        cap_unit: GB
        size: "11"
      - servername: server1
        cap_unit: GB
        size: "11"
      - cap_unit: GB
        servername: server2
        size: "12"
      - cap_unit: GB
        servername: server2
        size: "13"
      - cap_unit: GB
        servername: ""
        size: "14"
      - cap_unit: GB
        servername: ""
        size: "14"
      - cap_unit: GB
        servername: ""
        size: "14"
      - cap_unit: GB
        servername: ""
        size: "15"
  tasks:
    - name: Resolve servernames
      ansible.builtin.set_fact:
        server_names: '{{ storage_details_test_capacity | map(attribute="servername") | sort | unique }}'

    - name: Combine size and cap_unit ("10" and "GB" become "scu: 10GB")
      ansible.builtin.set_fact:
        scu: |
          {{ storage_details_test_capacity
             > zip(storage_details_test_capacity
                   > map(attribute="size")
                   > zip( storage_details_test_capacity
                          > map(attribute="cap_unit")
                        )
                   > map("join", "")
                   > map("regex_replace", "^(.*)$", '{"scu": ""}')
                   > map("from_json")
                  )
             > map('combine')
          }}

    - name: Create table storage_device
      ansible.builtin.set_fact:
        storage_device: |
           {% set sd = [] %}
           {% for sn in server_names %}
           {%   set capacity = [] %}
           {%   for sc in           scu | selectattr('servername', 'eq', sn) | map(attribute='scu') | sort | unique %}
           {%      set no_of_vols = scu | selectattr('servername', 'eq', sn) | selectattr('scu', 'eq', sc) | length %}
           {%      set size       =(scu | selectattr('servername', 'eq', sn) | selectattr('scu', 'eq', sc) | first)['size'] %}
           {%      set cap_unit   =(scu | selectattr('servername', 'eq', sn) | selectattr('scu', 'eq', sc) | first)['cap_unit'] %}
           {%      set _ = capacity.append({"no_of_vols": no_of_vols,
                                            "size":       size,
                                            "cap_unit":   cap_unit}) %}
           {%   endfor %}
           {%   set _ = sd.append({"servername": sn, "capacity": capacity}) %}
           {% endfor %}{{ sd }}

I thought there might be a slightly simpler way to achieve this using community.general.counter.

This is rough but:

tasks:

  • name: Append to our count list
    ansible.builtin.set_fact:
    storage_counter: ‘{{ storage_counter|default() + [ “Servername:” + item.servername + “,” + item.size + “GB”] }}’
    loop: ‘{{ storage_details_test_capacity }}’

  • name: Debug data structure
    ansible.builtin.debug:
    msg: ‘{{ storage_counter | community.general.counter }}’

Results in:

TASK [Append to our count list] ******************************************************************************************************************************
ok: [localhost] => (item={‘servername’: ‘server1’, ‘cap_unit’: ‘GB’, ‘size’: ‘10’})
ok: [localhost] => (item={‘servername’: ‘server1’, ‘cap_unit’: ‘GB’, ‘size’: ‘11’})
ok: [localhost] => (item={‘servername’: ‘server1’, ‘cap_unit’: ‘GB’, ‘size’: ‘11’})
ok: [localhost] => (item={‘cap_unit’: ‘GB’, ‘servername’: ‘server2’, ‘size’: ‘12’})
ok: [localhost] => (item={‘cap_unit’: ‘GB’, ‘servername’: ‘server2’, ‘size’: ‘13’})
ok: [localhost] => (item={‘cap_unit’: ‘GB’, ‘servername’: ‘’, ‘size’: ‘14’})
ok: [localhost] => (item={‘cap_unit’: ‘GB’, ‘servername’: ‘’, ‘size’: ‘14’})
ok: [localhost] => (item={‘cap_unit’: ‘GB’, ‘servername’: ‘’, ‘size’: ‘14’})
ok: [localhost] => (item={‘cap_unit’: ‘GB’, ‘servername’: ‘’, ‘size’: ‘15’})

TASK [Debug data structure] **********************************************************************************************************************************
ok: [localhost] => {
“msg”: {
“Servername:,14GB”: 3,
“Servername:,15GB”: 1,
“Servername:server1,10GB”: 1,
“Servername:server1,11GB”: 2,
“Servername:server2,12GB”: 1,
“Servername:server2,13GB”: 1
}
}

Which with some additional refinement, might the same thing as Todd’s method but slightly less mind-bending? :smiley: