temp0825a

Young-Kyoo Kim·2025년 8월 25일
# roles/hardware_inventory/tasks/main.yml
---
# Collection phase - runs on all hosts
- name: Get CPU information
  shell: nproc
  register: cpu_count
  
- name: Get memory information (GB)
  shell: free -g | grep '^Mem:' | awk '{print $2}'
  register: memory_gb
  
- name: Get disk information with mount status
  shell: |
    lsblk -b -o NAME,SIZE,TYPE,MOUNTPOINT --json | jq -r '
      .blockdevices[] | 
      select(.type=="disk") | 
      {
        name: .name,
        size_gb: (.size|tonumber/1024/1024/1024|floor),
        mounted: (if (.children // []) | map(.mountpoint) | any then true else false end)
      } | 
      "\(.name):\(.size_gb)GB:\(.mounted)"
    '
  register: disk_info
  
- name: Get partition information with mount status
  shell: |
    lsblk -b -o NAME,SIZE,TYPE,MOUNTPOINT --json | jq -r '
      .blockdevices[] | 
      .. | 
      select(.type?=="part") | 
      {
        name: .name,
        size_gb: (.size|tonumber/1024/1024/1024|floor),
        mounted: (.mountpoint != null)
      } | 
      "\(.name):\(.size_gb)GB:\(.mounted)"
    '
  register: partition_info
  failed_when: false
  
- name: Get PVS information
  shell: |
    if command -v pvs >/dev/null 2>&1; then
      pvs --noheadings --options pv_name | awk '{gsub("/dev/", "", $1); print $1}' | sort
    else
      echo ""
    fi
  register: pvs_info
  failed_when: false

- name: Process disk information
  set_fact:
    raw_disks: "{{ disk_info.stdout_lines | default([]) }}"
    raw_partitions: "{{ partition_info.stdout_lines | default([]) }}"
    pvs_list: "{{ pvs_info.stdout_lines | default([]) }}"

- name: Initialize disk summary variables
  set_fact:
    disk_sizes: {}
    mounted_sizes: {}
    unmounted_sizes: {}

- name: Process disk sizes
  set_fact:
    disk_sizes: "{{ disk_sizes | combine({item.split(':')[1]: (disk_sizes[item.split(':')[1]] | default(0)) + 1}) }}"
  loop: "{{ raw_disks }}"
  when: raw_disks | length > 0

- name: Process mounted disks
  set_fact:
    mounted_sizes: "{{ mounted_sizes | combine({item.split(':')[1]: (mounted_sizes[item.split(':')[1]] | default(0)) + 1}) }}"
  loop: "{{ raw_disks }}"
  when: 
    - raw_disks | length > 0
    - item.split(':')[2] == 'true'

- name: Process unmounted disks  
  set_fact:
    unmounted_sizes: "{{ unmounted_sizes | combine({item.split(':')[1]: (unmounted_sizes[item.split(':')[1]] | default(0)) + 1}) }}"
  loop: "{{ raw_disks }}"
  when: 
    - raw_disks | length > 0
    - item.split(':')[2] == 'false'

- name: Process mounted partitions
  set_fact:
    size_key: "{{ item.split(':')[1] }}{{ '(PVS)' if item.split(':')[0] in pvs_list else '' }}"
    mounted_sizes: "{{ mounted_sizes | combine({size_key: (mounted_sizes[size_key] | default(0)) + 1}) }}"
  loop: "{{ raw_partitions }}"
  when: 
    - raw_partitions | length > 0
    - item.split(':')[2] == 'true'

- name: Process unmounted partitions
  set_fact:
    size_key: "{{ item.split(':')[1] }}{{ '(PVS)' if item.split(':')[0] in pvs_list else '' }}"
    unmounted_sizes: "{{ unmounted_sizes | combine({size_key: (unmounted_sizes[size_key] | default(0)) + 1}) }}"
  loop: "{{ raw_partitions }}"
  when: 
    - raw_partitions | length > 0
    - item.split(':')[2] == 'false'

- name: Store hardware specs in host facts
  set_fact:
    hw_spec:
      hostname: "{{ inventory_hostname }}"
      cpu_count: "{{ cpu_count.stdout | int }}"
      memory_gb: "{{ memory_gb.stdout | int }}"
      disk_sizes: "{{ disk_sizes }}"
      mounted_sizes: "{{ mounted_sizes }}"
      unmounted_sizes: "{{ unmounted_sizes }}"

# Analysis phase - runs only once after all hosts have collected data
- name: Wait for all hosts to complete collection
  meta: end_host
  when: inventory_hostname != groups['all'][0]

- name: Collect all hardware specifications
  set_fact:
    hw_specs: "{{ groups['all'] | map('extract', hostvars, 'hw_spec') | select('defined') | list }}"
  when: inventory_hostname == groups['all'][0]

- name: Initialize grouping variables
  set_fact:
    cpu_groups: {}
    memory_groups: {}
  when: inventory_hostname == groups['all'][0]

- name: Group by CPU count
  set_fact:
    cpu_groups: "{{ cpu_groups | combine({item.cpu_count | string: (cpu_groups[item.cpu_count | string] | default([])) + [item.hostname]}) }}"
  loop: "{{ hw_specs }}"
  when: inventory_hostname == groups['all'][0]
  
- name: Group by Memory size
  set_fact:
    memory_groups: "{{ memory_groups | combine({item.memory_gb | string: (memory_groups[item.memory_gb | string] | default([])) + [item.hostname]}) }}"
  loop: "{{ hw_specs }}"
  when: inventory_hostname == groups['all'][0]
  
- name: Display Hardware Specification Summary
  debug:
    msg: |
      
      ================================================
      HARDWARE SPECIFICATION COLLECTION SUMMARY
      ================================================
      
      Total Nodes Checked: {{ hw_specs | length }}
      
      CPU COUNT DISTRIBUTION:
      {% for cpu_count, hosts in cpu_groups.items() %}
      - {{ cpu_count }} CPUs: {{ hosts | length }} nodes
        Hosts: {{ hosts | join(', ') }}
      {% endfor %}
      
      MEMORY SIZE DISTRIBUTION:
      {% for memory_size, hosts in memory_groups.items() %}
      - {{ memory_size }}GB RAM: {{ hosts | length }} nodes
        Hosts: {{ hosts | join(', ') }}
      {% endfor %}
  when: inventory_hostname == groups['all'][0]
      
- name: Display Detailed Hardware Information
  debug:
    msg: |
      
      ================================================
      DETAILED HARDWARE INFORMATION
      ================================================
      
      HOST: {{ item.hostname }}
      - CPU Count: {{ item.cpu_count }}
      - Memory: {{ item.memory_gb }}GB
      
      DISK SUMMARY:
      {% for size, count in item.disk_sizes.items() %}
      - {{ size }} disks: {{ count }}개
      {% endfor %}
      
      MOUNTED STORAGE:
      {% if item.mounted_sizes %}
      {% for size, count in item.mounted_sizes.items() %}
      - {{ size }}: {{ count }}개{% if '(PVS)' in size %} ← LVM Physical Volume{% endif %}
      {% endfor %}
      {% else %}
      - None
      {% endif %}
      
      UNMOUNTED STORAGE:
      {% if item.unmounted_sizes %}
      {% for size, count in item.unmounted_sizes.items() %}
      - {{ size }}: {{ count }}개{% if '(PVS)' in size %} ← LVM Physical Volume{% endif %}
      {% endfor %}
      {% else %}
      - None
      {% endif %}
      
  loop: "{{ hw_specs }}"
  when: inventory_hostname == groups['all'][0]
  
- name: Generate CSV Report
  copy:
    content: |
      Hostname,CPU_Count,Memory_GB,Disk_Summary,Mounted_Storage,Unmounted_Storage
      {% for spec in hw_specs -%}
      {{ spec.hostname }},{{ spec.cpu_count }},{{ spec.memory_gb }},"{{ spec.disk_sizes | dict2items | map('join', ':') | join(';') }}","{{ spec.mounted_sizes | dict2items | map('join', ':') | join(';') }}","{{ spec.unmounted_sizes | dict2items | map('join', ':') | join(';') }}"
      {% endfor %}
    dest: "{{ hw_report_path | default('./hardware_specs_report.csv') }}"
  when: inventory_hostname == groups['all'][0]
  delegate_to: localhost
      
- name: Display report location
  debug:
    msg: "Hardware specification report saved to: {{ hw_report_path | default('./hardware_specs_report.csv') }}"
  when: inventory_hostname == groups['all'][0]

0개의 댓글