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

38 views
Skip to first unread message

javed khan Siddque

unread,
Dec 18, 2023, 7:56:25 AM12/18/23
to Ansible Project
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.

---
- name: "This Play To Print Data Based On Size In Given Server"
  hosts: localhost
  gather_facts: false
  vars:
    storage_device:
      - servername: server1
      - servername: server2
    "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: Populate storage_device list
      ansible.builtin.set_fact:
        storage_device: "{{ storage_device | default([]) + [{'servername': item.servername | default(''), 'capacity': [{'size': item.size | int, 'cap_unit': item.cap_unit}]}] }}"
      loop: "{{ storage_details_test_capacity }}"


    - name: Debug storage_device list
      ansible.builtin.debug:
        var: storage_device

Will McDonald

unread,
Dec 18, 2023, 8:26:29 AM12/18/23
to ansible...@googlegroups.com
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.


--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/fc1c5e4d-eb2e-4712-b2c1-9ac6f8d2c7aen%40googlegroups.com.

javed khan Siddque

unread,
Dec 18, 2023, 8:37:19 AM12/18/23
to Ansible Project
I have a input
--------------------------------------------------------





=> I want generate ' storage_device' variable which give me below data [capacity of server with no_of_vols].
---------------------------------------------------------

storage_device:
  - servername: server1
    capacity:
      - no_of_vols: 1   # how many 10 GB for  server1

        size: 10
        cap_unit: GB
      - no_of_vols: 2
        size: 11
        cap_unit: GB
  - server: server2
    capacity:
      - no_of_vols: 1  # how many 12 GB for  server2

        size: 12
        cap_unit: GB
      - no_of_vols: 1
        size: 13
        cap_unit: GB
  - servername: ''   # how many 10 GB for  '<blank>'

    capacity:
      - no_of_vols: 3
        size: 14
        cap_unit: GB
      - no_of_vols: 1
        size: 15
        cap_unit: GB

Todd Lewis

unread,
Dec 18, 2023, 1:00:37 PM12/18/23
to ansible...@googlegroups.com, uto...@gmail.com
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": "\1"}')
                   | 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 }}

Will McDonald

unread,
Dec 18, 2023, 2:39:21 PM12/18/23
to ansible...@googlegroups.com, uto...@gmail.com
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? :D


Reply all
Reply to author
Forward
0 new messages