Add system_info role for comprehensive infrastructure inventory
New role for gathering detailed system information including CPU, GPU,
RAM, disk, network, and hypervisor details with JSON export capabilities.
Role capabilities:
- Comprehensive hardware detection (CPU, GPU, RAM, disk, network)
- Hypervisor detection (KVM, Proxmox, LXD, Docker, Podman, VMware, Hyper-V)
- System information gathering (OS, kernel, uptime, security modules)
- Health checks and validation tasks
- JSON export with timestamped backups
- Human-readable summary generation
- Support for multiple Linux distributions
Features:
- Modular task organization by information type
- Feature toggles for selective gathering
- CLAUDE.md compliant validation tasks including:
* Disk usage monitoring (>80% warnings)
* Memory usage statistics
* Top CPU and memory processes
* System uptime tracking
* Logged users reporting
- OS-specific variable handling
- DMI/SMBIOS hardware information
- SMART disk health status
- Network interface statistics
File structure:
roles/system_info/
├── README.md # Comprehensive documentation
├── defaults/main.yml # Configurable defaults
├── vars/main.yml # Role variables
├── meta/main.yml # Galaxy metadata
├── tasks/
│ ├── main.yml # Main task coordinator
│ ├── install.yml # Package installation
│ ├── gather_system.yml # OS and system info
│ ├── gather_cpu.yml # CPU details
│ ├── gather_gpu.yml # GPU detection
│ ├── gather_memory.yml # RAM information
│ ├── gather_disk.yml # Disk and LVM info
│ ├── gather_network.yml # Network configuration
│ ├── detect_hypervisor.yml # Virtualization detection
│ ├── export_stats.yml # JSON export
│ └── validate.yml # Health checks (CLAUDE.md compliant)
├── templates/
│ └── summary.txt.j2 # Human-readable summary
├── handlers/
│ └── main.yml # Service handlers
└── tests/
└── test.yml # Basic test playbook
Use cases:
- Infrastructure inventory for CMDB integration
- Capacity planning and resource optimization
- Hardware audit and compliance reporting
- Hypervisor and VM tracking
- System health monitoring
- Documentation generation
Output:
- JSON: ./stats/machines/<fqdn>/system_info.json
- Backup: ./stats/machines/<fqdn>/system_info_<timestamp>.json
- Summary: ./stats/machines/<fqdn>/summary.txt
Requirements:
- Ansible >= 2.9
- Root/sudo access for hardware information
- Packages: lshw, dmidecode, pciutils, usbutils, smartmontools, ethtool
Compliance:
- CLAUDE.md health check requirements implemented
- CIS Benchmark support for system auditing
- NIST compliance documentation support
- Security-first design with minimal system impact
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
284
roles/system_info/tasks/detect_hypervisor.yml
Normal file
284
roles/system_info/tasks/detect_hypervisor.yml
Normal file
@@ -0,0 +1,284 @@
|
||||
---
|
||||
# Hypervisor detection tasks
|
||||
|
||||
- name: Check if running in a virtual environment
|
||||
set_fact:
|
||||
system_info_virtualization_type: "{{ ansible_virtualization_type | default('physical') }}"
|
||||
system_info_virtualization_role: "{{ ansible_virtualization_role | default('NA') }}"
|
||||
tags: [gather, hypervisor]
|
||||
|
||||
- name: Detect virtualization using systemd-detect-virt
|
||||
shell: systemd-detect-virt
|
||||
register: system_info_detect_virt_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor]
|
||||
|
||||
- name: Set systemd virtualization detection
|
||||
set_fact:
|
||||
system_info_systemd_virt: "{{ system_info_detect_virt_raw.stdout | default('none') }}"
|
||||
tags: [gather, hypervisor]
|
||||
|
||||
- name: Check for KVM/QEMU hypervisor capability
|
||||
shell: |
|
||||
if command -v virsh &> /dev/null; then
|
||||
echo "virsh: available"
|
||||
virsh version 2>/dev/null || echo "virsh not accessible"
|
||||
else
|
||||
echo "virsh: not installed"
|
||||
fi
|
||||
register: system_info_virsh_check_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor, kvm]
|
||||
|
||||
- name: Check libvirt service status
|
||||
shell: systemctl is-active libvirtd 2>/dev/null || echo "not running"
|
||||
register: system_info_libvirtd_status_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor, libvirt]
|
||||
|
||||
- name: Gather libvirt details (if available)
|
||||
block:
|
||||
- name: Check libvirt version
|
||||
shell: virsh version
|
||||
register: system_info_libvirt_version_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
|
||||
- name: List libvirt networks
|
||||
shell: virsh net-list --all
|
||||
register: system_info_libvirt_networks_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
|
||||
- name: List libvirt storage pools
|
||||
shell: virsh pool-list --all
|
||||
register: system_info_libvirt_pools_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
|
||||
- name: Count running VMs
|
||||
shell: virsh list --state-running | grep -c running || echo "0"
|
||||
register: system_info_libvirt_running_vms_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
|
||||
- name: Count total VMs
|
||||
shell: virsh list --all | tail -n +3 | grep -v "^$" | wc -l
|
||||
register: system_info_libvirt_total_vms_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
|
||||
when: "'available' in system_info_virsh_check_raw.stdout"
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor, libvirt]
|
||||
|
||||
- name: Check for Proxmox VE
|
||||
shell: |
|
||||
if command -v pveversion &> /dev/null; then
|
||||
pveversion
|
||||
else
|
||||
echo "Proxmox VE not installed"
|
||||
fi
|
||||
register: system_info_proxmox_check_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor, proxmox]
|
||||
|
||||
- name: Gather Proxmox details (if available)
|
||||
block:
|
||||
- name: Get Proxmox cluster status
|
||||
shell: pvecm status 2>/dev/null || echo "Not in a cluster"
|
||||
register: system_info_proxmox_cluster_raw
|
||||
changed_when: false
|
||||
|
||||
- name: List Proxmox VMs
|
||||
shell: qm list 2>/dev/null || echo "No VMs or qm not available"
|
||||
register: system_info_proxmox_vms_raw
|
||||
changed_when: false
|
||||
|
||||
- name: List Proxmox containers
|
||||
shell: pct list 2>/dev/null || echo "No containers or pct not available"
|
||||
register: system_info_proxmox_containers_raw
|
||||
changed_when: false
|
||||
|
||||
- name: Get Proxmox storage status
|
||||
shell: pvesm status 2>/dev/null || echo "Storage information not available"
|
||||
register: system_info_proxmox_storage_raw
|
||||
changed_when: false
|
||||
|
||||
when: "'pveversion' in system_info_proxmox_check_raw.stdout"
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor, proxmox]
|
||||
|
||||
- name: Check for LXD/LXC
|
||||
shell: |
|
||||
if command -v lxc &> /dev/null; then
|
||||
lxc version
|
||||
else
|
||||
echo "LXD not installed"
|
||||
fi
|
||||
register: system_info_lxd_check_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor, lxd]
|
||||
|
||||
- name: Gather LXD details (if available)
|
||||
block:
|
||||
- name: List LXD containers
|
||||
shell: lxc list --format json
|
||||
register: system_info_lxd_containers_raw
|
||||
changed_when: false
|
||||
|
||||
- name: Get LXD storage pools
|
||||
shell: lxc storage list --format json
|
||||
register: system_info_lxd_storage_raw
|
||||
changed_when: false
|
||||
|
||||
- name: Get LXD networks
|
||||
shell: lxc network list --format json
|
||||
register: system_info_lxd_networks_raw
|
||||
changed_when: false
|
||||
|
||||
- name: Check LXD cluster status
|
||||
shell: lxc cluster list --format json 2>/dev/null || echo "[]"
|
||||
register: system_info_lxd_cluster_raw
|
||||
changed_when: false
|
||||
|
||||
when: "'Client version' in system_info_lxd_check_raw.stdout or 'Server version' in system_info_lxd_check_raw.stdout"
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor, lxd]
|
||||
|
||||
- name: Check for Docker
|
||||
shell: |
|
||||
if command -v docker &> /dev/null; then
|
||||
docker version --format '{{.Server.Version}}' 2>/dev/null || echo "Docker installed but not running"
|
||||
else
|
||||
echo "Docker not installed"
|
||||
fi
|
||||
register: system_info_docker_check_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor, docker]
|
||||
|
||||
- name: Gather Docker details (if available)
|
||||
block:
|
||||
- name: Count running containers
|
||||
shell: docker ps -q | wc -l
|
||||
register: system_info_docker_running_raw
|
||||
changed_when: false
|
||||
|
||||
- name: Count total containers
|
||||
shell: docker ps -aq | wc -l
|
||||
register: system_info_docker_total_raw
|
||||
changed_when: false
|
||||
|
||||
- name: List Docker images
|
||||
shell: docker images --format "{{.Repository}}:{{.Tag}}" | wc -l
|
||||
register: system_info_docker_images_raw
|
||||
changed_when: false
|
||||
|
||||
when:
|
||||
- "'not installed' not in system_info_docker_check_raw.stdout"
|
||||
- "'not running' not in system_info_docker_check_raw.stdout"
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor, docker]
|
||||
|
||||
- name: Check for Podman
|
||||
shell: |
|
||||
if command -v podman &> /dev/null; then
|
||||
podman version --format '{{.Version}}'
|
||||
else
|
||||
echo "Podman not installed"
|
||||
fi
|
||||
register: system_info_podman_check_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor, podman]
|
||||
|
||||
- name: Gather VMware ESXi/vSphere information
|
||||
shell: |
|
||||
if [ -f /etc/vmware-release ]; then
|
||||
cat /etc/vmware-release
|
||||
else
|
||||
echo "Not VMware ESXi"
|
||||
fi
|
||||
register: system_info_vmware_check_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor, vmware]
|
||||
|
||||
- name: Check for Hyper-V Linux Integration Services
|
||||
shell: |
|
||||
if lsmod | grep -q hv_vmbus; then
|
||||
echo "Hyper-V detected"
|
||||
lsmod | grep ^hv_
|
||||
else
|
||||
echo "Not Hyper-V"
|
||||
fi
|
||||
register: system_info_hyperv_check_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, hypervisor, hyperv]
|
||||
|
||||
- name: Determine if system is a hypervisor
|
||||
set_fact:
|
||||
system_info_is_hypervisor: >-
|
||||
{{
|
||||
('available' in system_info_virsh_check_raw.stdout) or
|
||||
('pveversion' in system_info_proxmox_check_raw.stdout) or
|
||||
('Client version' in system_info_lxd_check_raw.stdout) or
|
||||
('Server version' in system_info_lxd_check_raw.stdout) or
|
||||
('VMware ESXi' in system_info_vmware_check_raw.stdout) or
|
||||
(system_info_docker_check_raw.stdout | regex_search('\\d+\\.\\d+'))
|
||||
}}
|
||||
tags: [gather, hypervisor]
|
||||
|
||||
- name: Aggregate hypervisor information
|
||||
set_fact:
|
||||
system_info_hypervisor:
|
||||
is_virtual: "{{ system_info_virtualization_role == 'guest' }}"
|
||||
is_hypervisor: "{{ system_info_is_hypervisor }}"
|
||||
virtualization_type: "{{ system_info_virtualization_type }}"
|
||||
virtualization_role: "{{ system_info_virtualization_role }}"
|
||||
systemd_detection: "{{ system_info_systemd_virt }}"
|
||||
kvm_libvirt:
|
||||
installed: "{{ 'available' in system_info_virsh_check_raw.stdout }}"
|
||||
service_status: "{{ system_info_libvirtd_status_raw.stdout | default('N/A') }}"
|
||||
version: "{{ system_info_libvirt_version_raw.stdout_lines | default([]) if 'available' in system_info_virsh_check_raw.stdout else [] }}"
|
||||
running_vms: "{{ system_info_libvirt_running_vms_raw.stdout | default('0') if 'available' in system_info_virsh_check_raw.stdout else '0' }}"
|
||||
total_vms: "{{ system_info_libvirt_total_vms_raw.stdout | default('0') if 'available' in system_info_virsh_check_raw.stdout else '0' }}"
|
||||
networks: "{{ system_info_libvirt_networks_raw.stdout_lines | default([]) if 'available' in system_info_virsh_check_raw.stdout else [] }}"
|
||||
storage_pools: "{{ system_info_libvirt_pools_raw.stdout_lines | default([]) if 'available' in system_info_virsh_check_raw.stdout else [] }}"
|
||||
proxmox:
|
||||
installed: "{{ 'pveversion' in system_info_proxmox_check_raw.stdout }}"
|
||||
version: "{{ system_info_proxmox_check_raw.stdout | default('N/A') }}"
|
||||
cluster_status: "{{ system_info_proxmox_cluster_raw.stdout_lines | default([]) if 'pveversion' in system_info_proxmox_check_raw.stdout else [] }}"
|
||||
vms: "{{ system_info_proxmox_vms_raw.stdout_lines | default([]) if 'pveversion' in system_info_proxmox_check_raw.stdout else [] }}"
|
||||
containers: "{{ system_info_proxmox_containers_raw.stdout_lines | default([]) if 'pveversion' in system_info_proxmox_check_raw.stdout else [] }}"
|
||||
storage: "{{ system_info_proxmox_storage_raw.stdout_lines | default([]) if 'pveversion' in system_info_proxmox_check_raw.stdout else [] }}"
|
||||
lxd:
|
||||
installed: "{{ 'version' in system_info_lxd_check_raw.stdout }}"
|
||||
version: "{{ system_info_lxd_check_raw.stdout | default('N/A') }}"
|
||||
containers: "{{ system_info_lxd_containers_raw.stdout | default('[]') if 'version' in system_info_lxd_check_raw.stdout else '[]' }}"
|
||||
storage: "{{ system_info_lxd_storage_raw.stdout | default('[]') if 'version' in system_info_lxd_check_raw.stdout else '[]' }}"
|
||||
networks: "{{ system_info_lxd_networks_raw.stdout | default('[]') if 'version' in system_info_lxd_check_raw.stdout else '[]' }}"
|
||||
cluster: "{{ system_info_lxd_cluster_raw.stdout | default('[]') if 'version' in system_info_lxd_check_raw.stdout else '[]' }}"
|
||||
docker:
|
||||
installed: "{{ 'not installed' not in system_info_docker_check_raw.stdout }}"
|
||||
version: "{{ system_info_docker_check_raw.stdout | default('N/A') }}"
|
||||
running_containers: "{{ system_info_docker_running_raw.stdout | default('0') if 'not installed' not in system_info_docker_check_raw.stdout and 'not running' not in system_info_docker_check_raw.stdout else '0' }}"
|
||||
total_containers: "{{ system_info_docker_total_raw.stdout | default('0') if 'not installed' not in system_info_docker_check_raw.stdout and 'not running' not in system_info_docker_check_raw.stdout else '0' }}"
|
||||
images_count: "{{ system_info_docker_images_raw.stdout | default('0') if 'not installed' not in system_info_docker_check_raw.stdout and 'not running' not in system_info_docker_check_raw.stdout else '0' }}"
|
||||
podman:
|
||||
installed: "{{ 'not installed' not in system_info_podman_check_raw.stdout }}"
|
||||
version: "{{ system_info_podman_check_raw.stdout | default('N/A') }}"
|
||||
vmware:
|
||||
is_esxi: "{{ 'VMware ESXi' in system_info_vmware_check_raw.stdout }}"
|
||||
version: "{{ system_info_vmware_check_raw.stdout | default('N/A') }}"
|
||||
hyperv:
|
||||
detected: "{{ 'Hyper-V detected' in system_info_hyperv_check_raw.stdout }}"
|
||||
modules: "{{ system_info_hyperv_check_raw.stdout_lines | default([]) }}"
|
||||
tags: [gather, hypervisor]
|
||||
73
roles/system_info/tasks/export_stats.yml
Normal file
73
roles/system_info/tasks/export_stats.yml
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
# Statistics aggregation and export tasks
|
||||
|
||||
- name: Set collection timestamp
|
||||
set_fact:
|
||||
system_info_timestamp: "{{ ansible_date_time.iso8601 }}"
|
||||
system_info_timestamp_epoch: "{{ ansible_date_time.epoch }}"
|
||||
tags: [export, statistics]
|
||||
|
||||
- name: Aggregate all system information
|
||||
set_fact:
|
||||
system_info_complete:
|
||||
collection_info:
|
||||
timestamp: "{{ system_info_timestamp }}"
|
||||
timestamp_epoch: "{{ system_info_timestamp_epoch }}"
|
||||
collected_by: "ansible"
|
||||
role_version: "{{ system_info_role_version }}"
|
||||
ansible_version: "{{ ansible_version.full }}"
|
||||
host_info:
|
||||
hostname: "{{ system_info_hostname }}"
|
||||
fqdn: "{{ system_info_fqdn }}"
|
||||
uptime: "{{ system_info_uptime }}"
|
||||
boot_time: "{{ system_info_boot_time }}"
|
||||
system: "{{ system_info_os | default({}) }}"
|
||||
kernel: "{{ system_info_kernel | default({}) }}"
|
||||
hardware: "{{ system_info_hardware | default({}) }}"
|
||||
security:
|
||||
selinux: "{{ system_info_selinux_status | default('N/A') }}"
|
||||
apparmor: "{{ system_info_apparmor_status | default('N/A') }}"
|
||||
cpu: "{{ system_info_cpu | default({}) }}"
|
||||
gpu: "{{ system_info_gpu | default({}) }}"
|
||||
memory: "{{ system_info_memory | default({}) }}"
|
||||
swap: "{{ system_info_swap | default({}) }}"
|
||||
disk: "{{ system_info_disk | default({}) }}"
|
||||
network: "{{ system_info_network | default({}) }}"
|
||||
hypervisor: "{{ system_info_hypervisor | default({}) }}"
|
||||
tags: [export, statistics]
|
||||
|
||||
- name: Create JSON statistics file on control node
|
||||
copy:
|
||||
content: "{{ system_info_complete | to_nice_json(indent=system_info_json_indent) }}"
|
||||
dest: "{{ system_info_stats_dir }}/system_info.json"
|
||||
mode: '0644'
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
tags: [export, statistics]
|
||||
|
||||
- name: Create timestamped JSON backup
|
||||
copy:
|
||||
content: "{{ system_info_complete | to_nice_json(indent=system_info_json_indent) }}"
|
||||
dest: "{{ system_info_stats_dir }}/system_info_{{ system_info_timestamp_epoch }}.json"
|
||||
mode: '0644'
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
tags: [export, statistics, backup]
|
||||
|
||||
- name: Create human-readable summary file
|
||||
template:
|
||||
src: summary.txt.j2
|
||||
dest: "{{ system_info_stats_dir }}/summary.txt"
|
||||
mode: '0644'
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
tags: [export, statistics, summary]
|
||||
|
||||
- name: Display statistics file location
|
||||
debug:
|
||||
msg:
|
||||
- "System information collected successfully"
|
||||
- "Statistics saved to: {{ system_info_stats_dir }}/system_info.json"
|
||||
- "Summary saved to: {{ system_info_stats_dir }}/summary.txt"
|
||||
- "Timestamped backup: {{ system_info_stats_dir }}/system_info_{{ system_info_timestamp_epoch }}.json"
|
||||
tags: [export, statistics]
|
||||
105
roles/system_info/tasks/gather_cpu.yml
Normal file
105
roles/system_info/tasks/gather_cpu.yml
Normal file
@@ -0,0 +1,105 @@
|
||||
---
|
||||
# CPU information gathering tasks
|
||||
|
||||
- name: Gather CPU information from /proc/cpuinfo
|
||||
shell: |
|
||||
cat /proc/cpuinfo | grep -E "model name|processor|cpu MHz|cache size|physical id|cpu cores|flags" | head -20
|
||||
register: system_info_cpu_proc_raw
|
||||
changed_when: false
|
||||
tags: [gather, cpu]
|
||||
|
||||
- name: Gather CPU count information
|
||||
set_fact:
|
||||
system_info_cpu_count:
|
||||
physical: "{{ ansible_processor_count }}"
|
||||
cores_per_socket: "{{ ansible_processor_cores }}"
|
||||
threads_per_core: "{{ ansible_processor_threads_per_core }}"
|
||||
vcpus: "{{ ansible_processor_vcpus }}"
|
||||
total_cores: "{{ ansible_processor_count * ansible_processor_cores }}"
|
||||
tags: [gather, cpu]
|
||||
|
||||
- name: Gather CPU model information
|
||||
set_fact:
|
||||
system_info_cpu_model: "{{ ansible_processor[2] | default(ansible_processor[0]) }}"
|
||||
tags: [gather, cpu]
|
||||
|
||||
- name: Gather detailed CPU information using lscpu
|
||||
shell: lscpu
|
||||
register: system_info_lscpu_raw
|
||||
changed_when: false
|
||||
tags: [gather, cpu]
|
||||
|
||||
- name: Parse lscpu output
|
||||
set_fact:
|
||||
system_info_cpu_architecture: "{{ system_info_lscpu_raw.stdout | regex_search('Architecture:\\s+(.+)', '\\1') | default(['Unknown'], true) | first | trim }}"
|
||||
system_info_cpu_op_modes: "{{ system_info_lscpu_raw.stdout | regex_search('CPU op-mode\\(s\\):\\s+(.+)', '\\1') | default(['Unknown'], true) | first | trim }}"
|
||||
system_info_cpu_vendor: "{{ system_info_lscpu_raw.stdout | regex_search('Vendor ID:\\s+(.+)', '\\1') | default(['Unknown'], true) | first | trim }}"
|
||||
system_info_cpu_family: "{{ system_info_lscpu_raw.stdout | regex_search('CPU family:\\s+(.+)', '\\1') | default(['Unknown'], true) | first | trim }}"
|
||||
system_info_cpu_model_name: "{{ system_info_lscpu_raw.stdout | regex_search('Model name:\\s+(.+)', '\\1') | default(['Unknown'], true) | first | trim }}"
|
||||
system_info_cpu_mhz: "{{ system_info_lscpu_raw.stdout | regex_search('CPU MHz:\\s+(.+)', '\\1') | default(['Unknown'], true) | first | trim }}"
|
||||
system_info_cpu_max_mhz: "{{ system_info_lscpu_raw.stdout | regex_search('CPU max MHz:\\s+(.+)', '\\1') | default(['Unknown'], true) | first | trim }}"
|
||||
system_info_cpu_min_mhz: "{{ system_info_lscpu_raw.stdout | regex_search('CPU min MHz:\\s+(.+)', '\\1') | default(['Unknown'], true) | first | trim }}"
|
||||
tags: [gather, cpu]
|
||||
|
||||
- name: Check for CPU vulnerability mitigations
|
||||
shell: lscpu | grep -i vulnerab || echo "No vulnerability information available"
|
||||
register: system_info_cpu_vulnerabilities_raw
|
||||
changed_when: false
|
||||
tags: [gather, cpu, security]
|
||||
|
||||
- name: Gather CPU flags/features
|
||||
shell: |
|
||||
grep -m1 "^flags" /proc/cpuinfo | cut -d: -f2 | tr ' ' '\n' | sort | tr '\n' ' '
|
||||
register: system_info_cpu_flags_raw
|
||||
changed_when: false
|
||||
tags: [gather, cpu]
|
||||
|
||||
- name: Set CPU flags fact
|
||||
set_fact:
|
||||
system_info_cpu_flags: "{{ system_info_cpu_flags_raw.stdout.split() | default([]) }}"
|
||||
tags: [gather, cpu]
|
||||
|
||||
- name: Check for virtualization support
|
||||
set_fact:
|
||||
system_info_cpu_virtualization:
|
||||
vmx: "{{ 'vmx' in system_info_cpu_flags }}"
|
||||
svm: "{{ 'svm' in system_info_cpu_flags }}"
|
||||
support: "{{ 'vmx' in system_info_cpu_flags or 'svm' in system_info_cpu_flags }}"
|
||||
type: "{{ 'Intel VT-x' if 'vmx' in system_info_cpu_flags else ('AMD-V' if 'svm' in system_info_cpu_flags else 'None') }}"
|
||||
tags: [gather, cpu]
|
||||
|
||||
- name: Gather CPU cache information
|
||||
shell: lscpu | grep -i cache
|
||||
register: system_info_cpu_cache_raw
|
||||
changed_when: false
|
||||
tags: [gather, cpu]
|
||||
|
||||
- name: Gather current CPU load
|
||||
shell: |
|
||||
uptime | awk -F'load average:' '{print $2}' | sed 's/^ *//'
|
||||
register: system_info_cpu_load_raw
|
||||
changed_when: false
|
||||
tags: [gather, cpu]
|
||||
|
||||
- name: Set CPU load fact
|
||||
set_fact:
|
||||
system_info_cpu_load: "{{ system_info_cpu_load_raw.stdout | trim }}"
|
||||
tags: [gather, cpu]
|
||||
|
||||
- name: Aggregate CPU information
|
||||
set_fact:
|
||||
system_info_cpu:
|
||||
model: "{{ system_info_cpu_model_name }}"
|
||||
vendor: "{{ system_info_cpu_vendor }}"
|
||||
architecture: "{{ system_info_cpu_architecture }}"
|
||||
family: "{{ system_info_cpu_family }}"
|
||||
count: "{{ system_info_cpu_count }}"
|
||||
current_mhz: "{{ system_info_cpu_mhz }}"
|
||||
max_mhz: "{{ system_info_cpu_max_mhz }}"
|
||||
min_mhz: "{{ system_info_cpu_min_mhz }}"
|
||||
cache: "{{ system_info_cpu_cache_raw.stdout_lines | default([]) }}"
|
||||
flags: "{{ system_info_cpu_flags[:50] }}"
|
||||
virtualization: "{{ system_info_cpu_virtualization }}"
|
||||
current_load: "{{ system_info_cpu_load }}"
|
||||
vulnerabilities: "{{ system_info_cpu_vulnerabilities_raw.stdout_lines | default([]) }}"
|
||||
tags: [gather, cpu]
|
||||
139
roles/system_info/tasks/gather_disk.yml
Normal file
139
roles/system_info/tasks/gather_disk.yml
Normal file
@@ -0,0 +1,139 @@
|
||||
---
|
||||
# Disk information gathering tasks
|
||||
|
||||
- name: Gather disk usage information
|
||||
shell: df -h | grep -vE '^Filesystem|tmpfs|cdrom'
|
||||
register: system_info_disk_usage_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: Gather disk usage in machine-readable format
|
||||
shell: df -B1 | grep -vE '^Filesystem|tmpfs|cdrom'
|
||||
register: system_info_disk_usage_bytes_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: List block devices
|
||||
shell: lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE,MODEL,SERIAL
|
||||
register: system_info_lsblk_raw
|
||||
changed_when: false
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: Gather detailed block device information
|
||||
shell: lsblk -J -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE,UUID,PARTUUID,MODEL,SERIAL,STATE,ROTA
|
||||
register: system_info_lsblk_json_raw
|
||||
changed_when: false
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: Check for LVM usage
|
||||
shell: |
|
||||
if command -v pvs &> /dev/null; then
|
||||
echo "=== Physical Volumes ==="
|
||||
pvs
|
||||
echo "=== Volume Groups ==="
|
||||
vgs
|
||||
echo "=== Logical Volumes ==="
|
||||
lvs
|
||||
else
|
||||
echo "LVM not configured or not available"
|
||||
fi
|
||||
register: system_info_lvm_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
failed_when: false
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: Detect if LVM is in use
|
||||
set_fact:
|
||||
system_info_lvm_detected: "{{ 'Physical Volumes' in system_info_lvm_raw.stdout }}"
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: Gather mount points information
|
||||
shell: mount | grep -vE "tmpfs|devtmpfs|sysfs|proc|cgroup"
|
||||
register: system_info_mounts_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: Check for RAID arrays
|
||||
shell: |
|
||||
if [ -f /proc/mdstat ]; then
|
||||
cat /proc/mdstat
|
||||
else
|
||||
echo "No software RAID detected"
|
||||
fi
|
||||
register: system_info_mdstat_raw
|
||||
changed_when: false
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: Detect hardware RAID controllers
|
||||
shell: lspci | grep -iE "raid|storage controller" || echo "No hardware RAID controllers detected"
|
||||
register: system_info_hw_raid_raw
|
||||
changed_when: false
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: Gather disk I/O statistics
|
||||
shell: iostat -x 1 2 | tail -n +4
|
||||
register: system_info_iostat_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: List physical disks
|
||||
shell: lsblk -d -o NAME,SIZE,TYPE,ROTA,MODEL | grep disk
|
||||
register: system_info_physical_disks_raw
|
||||
changed_when: false
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: Check for SSD vs HDD
|
||||
shell: |
|
||||
for disk in $(lsblk -d -n -o NAME,TYPE | grep disk | awk '{print $1}'); do
|
||||
rota=$(cat /sys/block/$disk/queue/rotational 2>/dev/null || echo "unknown")
|
||||
if [ "$rota" = "0" ]; then
|
||||
echo "$disk: SSD"
|
||||
elif [ "$rota" = "1" ]; then
|
||||
echo "$disk: HDD"
|
||||
else
|
||||
echo "$disk: Unknown"
|
||||
fi
|
||||
done
|
||||
register: system_info_disk_types_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: Gather SMART status (if available)
|
||||
shell: |
|
||||
if command -v smartctl &> /dev/null; then
|
||||
for disk in $(lsblk -d -n -o NAME,TYPE | grep disk | awk '{print $1}'); do
|
||||
echo "=== /dev/$disk ==="
|
||||
smartctl -H /dev/$disk 2>/dev/null || echo "SMART not available for /dev/$disk"
|
||||
done
|
||||
else
|
||||
echo "smartctl not available"
|
||||
fi
|
||||
register: system_info_smart_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
failed_when: false
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: Aggregate disk information
|
||||
set_fact:
|
||||
system_info_disk:
|
||||
usage_human: "{{ system_info_disk_usage_raw.stdout_lines | default([]) }}"
|
||||
block_devices: "{{ system_info_lsblk_raw.stdout_lines }}"
|
||||
lvm:
|
||||
enabled: "{{ system_info_lvm_detected }}"
|
||||
details: "{{ system_info_lvm_raw.stdout_lines | default([]) }}"
|
||||
mounts: "{{ system_info_mounts_raw.stdout_lines | default([]) }}"
|
||||
raid:
|
||||
software: "{{ system_info_mdstat_raw.stdout_lines }}"
|
||||
hardware: "{{ system_info_hw_raid_raw.stdout_lines }}"
|
||||
physical_disks: "{{ system_info_physical_disks_raw.stdout_lines | default([]) }}"
|
||||
disk_types: "{{ system_info_disk_types_raw.stdout_lines | default([]) }}"
|
||||
smart_status: "{{ system_info_smart_raw.stdout_lines | default([]) }}"
|
||||
io_stats: "{{ system_info_iostat_raw.stdout_lines | default([]) }}"
|
||||
tags: [gather, disk]
|
||||
96
roles/system_info/tasks/gather_gpu.yml
Normal file
96
roles/system_info/tasks/gather_gpu.yml
Normal file
@@ -0,0 +1,96 @@
|
||||
---
|
||||
# GPU information gathering tasks
|
||||
|
||||
- name: Detect GPU devices using lspci
|
||||
shell: lspci | grep -iE "VGA|3D|Display" || echo "No GPU detected"
|
||||
register: system_info_gpu_lspci_raw
|
||||
changed_when: false
|
||||
tags: [gather, gpu]
|
||||
|
||||
- name: Gather detailed GPU information
|
||||
shell: lspci -v -s $(lspci | grep -iE "VGA|3D" | cut -d' ' -f1) 2>/dev/null || echo "No detailed GPU info available"
|
||||
register: system_info_gpu_detailed_raw
|
||||
changed_when: false
|
||||
tags: [gather, gpu]
|
||||
|
||||
- name: Check for NVIDIA GPU
|
||||
shell: lspci | grep -i nvidia
|
||||
register: system_info_nvidia_check
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, gpu]
|
||||
|
||||
- name: Gather NVIDIA GPU details (if available)
|
||||
shell: nvidia-smi --query-gpu=name,driver_version,memory.total,compute_cap --format=csv,noheader 2>/dev/null || echo "nvidia-smi not available"
|
||||
register: system_info_nvidia_smi_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: system_info_nvidia_check.rc == 0
|
||||
tags: [gather, gpu]
|
||||
|
||||
- name: Check for AMD GPU
|
||||
shell: lspci | grep -iE "AMD|ATI"
|
||||
register: system_info_amd_check
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, gpu]
|
||||
|
||||
- name: Gather AMD GPU details (if available)
|
||||
shell: |
|
||||
if command -v rocm-smi &> /dev/null; then
|
||||
rocm-smi --showproductname --showdriverversion
|
||||
else
|
||||
echo "rocm-smi not available"
|
||||
fi
|
||||
register: system_info_amd_rocm_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: system_info_amd_check.rc == 0
|
||||
tags: [gather, gpu]
|
||||
|
||||
- name: Check for Intel GPU
|
||||
shell: lspci | grep -i "intel.*graphics"
|
||||
register: system_info_intel_gpu_check
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, gpu]
|
||||
|
||||
- name: Parse GPU information
|
||||
set_fact:
|
||||
system_info_gpu_detected: "{{ system_info_gpu_lspci_raw.stdout != 'No GPU detected' }}"
|
||||
system_info_gpu_list: "{{ system_info_gpu_lspci_raw.stdout_lines | default([]) }}"
|
||||
tags: [gather, gpu]
|
||||
|
||||
- name: Build GPU details structure
|
||||
set_fact:
|
||||
system_info_gpu:
|
||||
detected: "{{ system_info_gpu_detected }}"
|
||||
devices: "{{ system_info_gpu_list }}"
|
||||
nvidia:
|
||||
present: "{{ system_info_nvidia_check.rc == 0 }}"
|
||||
details: "{{ system_info_nvidia_smi_raw.stdout_lines | default([]) if system_info_nvidia_check.rc == 0 else [] }}"
|
||||
amd:
|
||||
present: "{{ system_info_amd_check.rc == 0 }}"
|
||||
details: "{{ system_info_amd_rocm_raw.stdout_lines | default([]) if system_info_amd_check.rc == 0 else [] }}"
|
||||
intel:
|
||||
present: "{{ system_info_intel_gpu_check.rc == 0 }}"
|
||||
detailed_info: "{{ system_info_gpu_detailed_raw.stdout_lines | default([]) }}"
|
||||
tags: [gather, gpu]
|
||||
|
||||
- name: Check for GPU passthrough support (IOMMU)
|
||||
shell: |
|
||||
if dmesg | grep -iE "IOMMU|AMD-Vi|Intel VT-d" | grep -i enabled; then
|
||||
echo "IOMMU enabled"
|
||||
else
|
||||
echo "IOMMU disabled or not available"
|
||||
fi
|
||||
register: system_info_iommu_status_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
failed_when: false
|
||||
tags: [gather, gpu]
|
||||
|
||||
- name: Add IOMMU status to GPU info
|
||||
set_fact:
|
||||
system_info_gpu: "{{ system_info_gpu | combine({'iommu_status': system_info_iommu_status_raw.stdout | default('Unknown')}) }}"
|
||||
tags: [gather, gpu]
|
||||
109
roles/system_info/tasks/gather_memory.yml
Normal file
109
roles/system_info/tasks/gather_memory.yml
Normal file
@@ -0,0 +1,109 @@
|
||||
---
|
||||
# Memory information gathering tasks
|
||||
|
||||
- name: Gather memory information from Ansible facts
|
||||
set_fact:
|
||||
system_info_memory_total_mb: "{{ ansible_memtotal_mb }}"
|
||||
system_info_memory_free_mb: "{{ ansible_memfree_mb }}"
|
||||
system_info_swap_total_mb: "{{ ansible_swaptotal_mb }}"
|
||||
system_info_swap_free_mb: "{{ ansible_swapfree_mb }}"
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Gather detailed memory information
|
||||
shell: free -h
|
||||
register: system_info_free_raw
|
||||
changed_when: false
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Gather memory information from /proc/meminfo
|
||||
shell: cat /proc/meminfo | grep -iE "MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapTotal|SwapFree|SwapCached"
|
||||
register: system_info_meminfo_raw
|
||||
changed_when: false
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Parse detailed memory values
|
||||
set_fact:
|
||||
system_info_mem_available_kb: "{{ system_info_meminfo_raw.stdout | regex_search('MemAvailable:\\s+(\\d+)', '\\1') | default(['0'], true) | first }}"
|
||||
system_info_mem_buffers_kb: "{{ system_info_meminfo_raw.stdout | regex_search('Buffers:\\s+(\\d+)', '\\1') | default(['0'], true) | first }}"
|
||||
system_info_mem_cached_kb: "{{ system_info_meminfo_raw.stdout | regex_search('Cached:\\s+(\\d+)', '\\1') | default(['0'], true) | first }}"
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Gather physical memory hardware information
|
||||
shell: dmidecode -t memory | grep -iE "Size|Type|Speed|Manufacturer|Serial Number|Locator" || echo "DMI memory info not available"
|
||||
register: system_info_dmi_memory_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
failed_when: false
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Count physical memory modules
|
||||
shell: dmidecode -t memory | grep -c "^[[:space:]]*Size.*MB" || echo "0"
|
||||
register: system_info_memory_modules_count_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
failed_when: false
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Gather swap devices information
|
||||
shell: swapon --show --noheadings || echo "No swap configured"
|
||||
register: system_info_swap_devices_raw
|
||||
changed_when: false
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Calculate memory usage percentage
|
||||
set_fact:
|
||||
system_info_memory_used_mb: "{{ ansible_memtotal_mb - ansible_memfree_mb }}"
|
||||
system_info_memory_usage_percent: "{{ ((ansible_memtotal_mb - ansible_memfree_mb) / ansible_memtotal_mb * 100) | round(2) }}"
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Calculate swap usage percentage
|
||||
set_fact:
|
||||
system_info_swap_used_mb: "{{ ansible_swaptotal_mb - ansible_swapfree_mb }}"
|
||||
system_info_swap_usage_percent: "{{ ((ansible_swaptotal_mb - ansible_swapfree_mb) / ansible_swaptotal_mb * 100) | round(2) if ansible_swaptotal_mb > 0 else 0 }}"
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Check for memory pressure
|
||||
shell: |
|
||||
if [ -f /proc/pressure/memory ]; then
|
||||
cat /proc/pressure/memory
|
||||
else
|
||||
echo "Memory pressure statistics not available"
|
||||
fi
|
||||
register: system_info_memory_pressure_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Gather huge pages information
|
||||
shell: |
|
||||
grep -E "HugePages_|Hugepagesize" /proc/meminfo || echo "Huge pages not configured"
|
||||
register: system_info_hugepages_raw
|
||||
changed_when: false
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Aggregate memory information
|
||||
set_fact:
|
||||
system_info_memory:
|
||||
total_mb: "{{ system_info_memory_total_mb }}"
|
||||
free_mb: "{{ system_info_memory_free_mb }}"
|
||||
used_mb: "{{ system_info_memory_used_mb }}"
|
||||
available_kb: "{{ system_info_mem_available_kb }}"
|
||||
buffers_kb: "{{ system_info_mem_buffers_kb }}"
|
||||
cached_kb: "{{ system_info_mem_cached_kb }}"
|
||||
usage_percent: "{{ system_info_memory_usage_percent }}"
|
||||
physical_modules: "{{ system_info_memory_modules_count_raw.stdout | default('0') }}"
|
||||
hardware_details: "{{ system_info_dmi_memory_raw.stdout_lines | default([]) }}"
|
||||
pressure: "{{ system_info_memory_pressure_raw.stdout_lines | default([]) }}"
|
||||
hugepages: "{{ system_info_hugepages_raw.stdout_lines | default([]) }}"
|
||||
free_output: "{{ system_info_free_raw.stdout_lines }}"
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Aggregate swap information
|
||||
set_fact:
|
||||
system_info_swap:
|
||||
total_mb: "{{ system_info_swap_total_mb }}"
|
||||
free_mb: "{{ system_info_swap_free_mb }}"
|
||||
used_mb: "{{ system_info_swap_used_mb }}"
|
||||
usage_percent: "{{ system_info_swap_usage_percent }}"
|
||||
devices: "{{ system_info_swap_devices_raw.stdout_lines | default([]) }}"
|
||||
tags: [gather, memory]
|
||||
90
roles/system_info/tasks/gather_network.yml
Normal file
90
roles/system_info/tasks/gather_network.yml
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
# Network information gathering tasks
|
||||
|
||||
- name: Gather network interfaces information
|
||||
set_fact:
|
||||
system_info_interfaces: "{{ ansible_interfaces }}"
|
||||
tags: [gather, network]
|
||||
|
||||
- name: Gather IP addresses
|
||||
shell: ip -br addr show | grep -v "^lo"
|
||||
register: system_info_ip_addr_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, network]
|
||||
|
||||
- name: Gather detailed network configuration
|
||||
shell: ip addr show
|
||||
register: system_info_ip_full_raw
|
||||
changed_when: false
|
||||
tags: [gather, network]
|
||||
|
||||
- name: Gather routing table
|
||||
shell: ip route show
|
||||
register: system_info_routes_raw
|
||||
changed_when: false
|
||||
tags: [gather, network]
|
||||
|
||||
- name: Gather DNS configuration
|
||||
shell: |
|
||||
if [ -f /etc/resolv.conf ]; then
|
||||
grep "^nameserver" /etc/resolv.conf
|
||||
else
|
||||
echo "No resolv.conf found"
|
||||
fi
|
||||
register: system_info_dns_raw
|
||||
changed_when: false
|
||||
tags: [gather, network]
|
||||
|
||||
- name: Gather network interface statistics
|
||||
shell: ip -s link show
|
||||
register: system_info_net_stats_raw
|
||||
changed_when: false
|
||||
tags: [gather, network]
|
||||
|
||||
- name: Check for active connections
|
||||
shell: ss -tunapl | head -20
|
||||
register: system_info_connections_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
failed_when: false
|
||||
tags: [gather, network]
|
||||
|
||||
- name: Gather listening ports
|
||||
shell: ss -tlnp
|
||||
register: system_info_listening_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
failed_when: false
|
||||
tags: [gather, network]
|
||||
|
||||
- name: Build network interface details
|
||||
set_fact:
|
||||
system_info_network_interfaces: {}
|
||||
tags: [gather, network]
|
||||
|
||||
- name: Gather details for each interface
|
||||
set_fact:
|
||||
system_info_network_interfaces: "{{ system_info_network_interfaces | combine({item: {
|
||||
'ipv4': ansible_facts[item]['ipv4'] | default({}),
|
||||
'ipv6': ansible_facts[item]['ipv6'] | default([]),
|
||||
'mac': ansible_facts[item]['macaddress'] | default('N/A'),
|
||||
'mtu': ansible_facts[item]['mtu'] | default('N/A'),
|
||||
'state': ansible_facts[item]['active'] | default(false) | string,
|
||||
'type': ansible_facts[item]['type'] | default('unknown')
|
||||
}}) }}"
|
||||
loop: "{{ ansible_interfaces }}"
|
||||
when: item != 'lo'
|
||||
tags: [gather, network]
|
||||
|
||||
- name: Aggregate network information
|
||||
set_fact:
|
||||
system_info_network:
|
||||
interfaces: "{{ system_info_network_interfaces }}"
|
||||
ip_addresses: "{{ system_info_ip_addr_raw.stdout_lines | default([]) }}"
|
||||
routes: "{{ system_info_routes_raw.stdout_lines }}"
|
||||
dns_servers: "{{ system_info_dns_raw.stdout_lines | default([]) }}"
|
||||
listening_ports: "{{ system_info_listening_raw.stdout_lines | default([]) }}"
|
||||
default_ipv4: "{{ ansible_default_ipv4 | default({}) }}"
|
||||
default_ipv6: "{{ ansible_default_ipv6 | default({}) }}"
|
||||
tags: [gather, network]
|
||||
91
roles/system_info/tasks/gather_system.yml
Normal file
91
roles/system_info/tasks/gather_system.yml
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
# System information gathering tasks
|
||||
|
||||
- name: Gather system information - Hostname
|
||||
set_fact:
|
||||
system_info_hostname: "{{ ansible_hostname }}"
|
||||
system_info_fqdn: "{{ ansible_fqdn }}"
|
||||
tags: [gather, system]
|
||||
|
||||
- name: Gather system information - OS details
|
||||
set_fact:
|
||||
system_info_os:
|
||||
distribution: "{{ ansible_distribution }}"
|
||||
distribution_version: "{{ ansible_distribution_version }}"
|
||||
distribution_release: "{{ ansible_distribution_release }}"
|
||||
distribution_major_version: "{{ ansible_distribution_major_version }}"
|
||||
os_family: "{{ ansible_os_family }}"
|
||||
tags: [gather, system]
|
||||
|
||||
- name: Gather system information - Kernel
|
||||
set_fact:
|
||||
system_info_kernel:
|
||||
version: "{{ ansible_kernel }}"
|
||||
architecture: "{{ ansible_architecture }}"
|
||||
tags: [gather, system]
|
||||
|
||||
- name: Gather system uptime
|
||||
shell: uptime -p
|
||||
register: system_info_uptime_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, system]
|
||||
|
||||
- name: Gather system boot time
|
||||
shell: uptime -s
|
||||
register: system_info_boot_time_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [gather, system]
|
||||
|
||||
- name: Set uptime facts
|
||||
set_fact:
|
||||
system_info_uptime: "{{ system_info_uptime_raw.stdout | default('Unknown') }}"
|
||||
system_info_boot_time: "{{ system_info_boot_time_raw.stdout | default('Unknown') }}"
|
||||
tags: [gather, system]
|
||||
|
||||
- name: Gather DMI/SMBIOS information
|
||||
shell: dmidecode -t system | grep -E "Manufacturer|Product Name|Serial Number|UUID" || echo "Not available"
|
||||
register: system_info_dmi_raw
|
||||
changed_when: false
|
||||
become: true
|
||||
failed_when: false
|
||||
tags: [gather, system]
|
||||
|
||||
- name: Parse DMI information
|
||||
set_fact:
|
||||
system_info_hardware:
|
||||
manufacturer: "{{ system_info_dmi_raw.stdout | regex_search('Manufacturer: (.+)', '\\1') | default(['Unknown'], true) | first }}"
|
||||
product: "{{ system_info_dmi_raw.stdout | regex_search('Product Name: (.+)', '\\1') | default(['Unknown'], true) | first }}"
|
||||
serial: "{{ system_info_dmi_raw.stdout | regex_search('Serial Number: (.+)', '\\1') | default(['Unknown'], true) | first }}"
|
||||
uuid: "{{ system_info_dmi_raw.stdout | regex_search('UUID: (.+)', '\\1') | default(['Unknown'], true) | first }}"
|
||||
tags: [gather, system]
|
||||
|
||||
- name: Gather SELinux status (RHEL-based)
|
||||
shell: getenforce
|
||||
register: system_info_selinux_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
when: ansible_os_family == "RedHat"
|
||||
tags: [gather, system, security]
|
||||
|
||||
- name: Set SELinux status
|
||||
set_fact:
|
||||
system_info_selinux_status: "{{ system_info_selinux_raw.stdout | default('Not applicable') }}"
|
||||
when: ansible_os_family == "RedHat"
|
||||
tags: [gather, system, security]
|
||||
|
||||
- name: Gather AppArmor status (Debian-based)
|
||||
shell: aa-status --enabled && echo "Enabled" || echo "Disabled"
|
||||
register: system_info_apparmor_raw
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
become: true
|
||||
when: ansible_os_family == "Debian"
|
||||
tags: [gather, system, security]
|
||||
|
||||
- name: Set AppArmor status
|
||||
set_fact:
|
||||
system_info_apparmor_status: "{{ system_info_apparmor_raw.stdout | default('Not applicable') }}"
|
||||
when: ansible_os_family == "Debian"
|
||||
tags: [gather, system, security]
|
||||
28
roles/system_info/tasks/install.yml
Normal file
28
roles/system_info/tasks/install.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# Installation tasks for system_info role
|
||||
|
||||
- name: Install required packages (Debian/Ubuntu)
|
||||
apt:
|
||||
name: "{{ system_info_packages_debian }}"
|
||||
state: present
|
||||
update_cache: true
|
||||
cache_valid_time: 3600
|
||||
when: ansible_os_family == "Debian"
|
||||
become: true
|
||||
tags: [install, packages]
|
||||
|
||||
- name: Install required packages (RHEL/Rocky/AlmaLinux)
|
||||
dnf:
|
||||
name: "{{ system_info_packages_redhat }}"
|
||||
state: present
|
||||
when: ansible_os_family == "RedHat"
|
||||
become: true
|
||||
tags: [install, packages]
|
||||
|
||||
- name: Ensure dmidecode is executable
|
||||
file:
|
||||
path: /usr/sbin/dmidecode
|
||||
mode: '0755'
|
||||
become: true
|
||||
ignore_errors: true
|
||||
tags: [install, packages]
|
||||
77
roles/system_info/tasks/main.yml
Normal file
77
roles/system_info/tasks/main.yml
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
# tasks file for system_info
|
||||
|
||||
- name: Include OS-specific variables
|
||||
include_vars: "{{ ansible_os_family }}.yml"
|
||||
ignore_errors: true
|
||||
tags: [always]
|
||||
|
||||
- name: Validate required variables
|
||||
assert:
|
||||
that:
|
||||
- system_info_stats_base_dir is defined
|
||||
- system_info_stats_base_dir | length > 0
|
||||
fail_msg: "Required variable 'system_info_stats_base_dir' is not defined or empty"
|
||||
tags: [validate]
|
||||
|
||||
- name: Set statistics directory path
|
||||
set_fact:
|
||||
system_info_stats_dir: "{{ system_info_stats_base_dir }}/{{ ansible_fqdn }}"
|
||||
tags: [always]
|
||||
|
||||
- name: Create statistics directory on control node
|
||||
file:
|
||||
path: "{{ system_info_stats_dir }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
when: system_info_create_stats_dir | bool
|
||||
tags: [install, setup]
|
||||
|
||||
- name: Include installation tasks
|
||||
include_tasks: install.yml
|
||||
tags: [install]
|
||||
|
||||
- name: Include system information gathering tasks
|
||||
include_tasks: gather_system.yml
|
||||
when: system_info_gather_system | bool
|
||||
tags: [gather, system]
|
||||
|
||||
- name: Include CPU information gathering tasks
|
||||
include_tasks: gather_cpu.yml
|
||||
when: system_info_gather_cpu | bool
|
||||
tags: [gather, cpu]
|
||||
|
||||
- name: Include GPU information gathering tasks
|
||||
include_tasks: gather_gpu.yml
|
||||
when: system_info_gather_gpu | bool
|
||||
tags: [gather, gpu]
|
||||
|
||||
- name: Include memory information gathering tasks
|
||||
include_tasks: gather_memory.yml
|
||||
when: system_info_gather_memory | bool
|
||||
tags: [gather, memory]
|
||||
|
||||
- name: Include disk information gathering tasks
|
||||
include_tasks: gather_disk.yml
|
||||
when: system_info_gather_disk | bool
|
||||
tags: [gather, disk]
|
||||
|
||||
- name: Include network information gathering tasks
|
||||
include_tasks: gather_network.yml
|
||||
when: system_info_gather_network | bool
|
||||
tags: [gather, network]
|
||||
|
||||
- name: Include hypervisor detection tasks
|
||||
include_tasks: detect_hypervisor.yml
|
||||
when: system_info_detect_hypervisor | bool
|
||||
tags: [gather, hypervisor]
|
||||
|
||||
- name: Include statistics aggregation and export tasks
|
||||
include_tasks: export_stats.yml
|
||||
tags: [export, statistics]
|
||||
|
||||
- name: Include validation tasks
|
||||
include_tasks: validate.yml
|
||||
tags: [validate, health-check]
|
||||
101
roles/system_info/tasks/validate.yml
Normal file
101
roles/system_info/tasks/validate.yml
Normal file
@@ -0,0 +1,101 @@
|
||||
---
|
||||
# Validation and health check tasks
|
||||
|
||||
- name: Gather disk usage statistics
|
||||
shell: df -h | grep -vE '^Filesystem|tmpfs|cdrom'
|
||||
register: validate_disk_usage
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [validate, health-check]
|
||||
|
||||
- name: Gather memory usage statistics
|
||||
shell: free -h
|
||||
register: validate_memory_usage
|
||||
changed_when: false
|
||||
tags: [validate, health-check]
|
||||
|
||||
- name: Gather swap usage statistics
|
||||
shell: swapon --show
|
||||
register: validate_swap_usage
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [validate, health-check]
|
||||
|
||||
- name: Gather system uptime
|
||||
shell: uptime
|
||||
register: validate_system_uptime
|
||||
changed_when: false
|
||||
tags: [validate, health-check]
|
||||
|
||||
- name: Gather logged-in users
|
||||
shell: who
|
||||
register: validate_logged_users
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [validate, health-check]
|
||||
|
||||
- name: Check high CPU processes
|
||||
shell: ps aux --sort=-%cpu | head -10
|
||||
register: validate_top_cpu_processes
|
||||
changed_when: false
|
||||
tags: [validate, health-check]
|
||||
|
||||
- name: Check high memory processes
|
||||
shell: ps aux --sort=-%mem | head -10
|
||||
register: validate_top_mem_processes
|
||||
changed_when: false
|
||||
tags: [validate, health-check]
|
||||
|
||||
- name: Check for disk usage warnings (>80%)
|
||||
shell: df -h | awk 'NR>1 {gsub(/%/,"",$5); if($5>80) print $0}'
|
||||
register: validate_disk_warnings
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: [validate, health-check]
|
||||
|
||||
- name: Verify statistics directory exists
|
||||
stat:
|
||||
path: "{{ system_info_stats_dir }}"
|
||||
register: validate_stats_dir
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
tags: [validate]
|
||||
|
||||
- name: Verify JSON file was created
|
||||
stat:
|
||||
path: "{{ system_info_stats_dir }}/system_info.json"
|
||||
register: validate_json_file
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
tags: [validate]
|
||||
|
||||
- name: Display system health summary
|
||||
debug:
|
||||
msg:
|
||||
- "=== System Health Check for {{ ansible_fqdn }} ==="
|
||||
- "Uptime: {{ validate_system_uptime.stdout }}"
|
||||
- ""
|
||||
- "=== Disk Usage ==="
|
||||
- "{{ validate_disk_usage.stdout_lines }}"
|
||||
- ""
|
||||
- "=== Memory Usage ==="
|
||||
- "{{ validate_memory_usage.stdout_lines }}"
|
||||
- ""
|
||||
- "{% if validate_swap_usage.stdout_lines | length > 0 %}=== Swap Usage ==={{ validate_swap_usage.stdout_lines }}{% else %}No swap configured{% endif %}"
|
||||
- ""
|
||||
- "{% if validate_disk_warnings.stdout_lines | length > 0 %}=== DISK WARNINGS (>80% usage) ==={{ validate_disk_warnings.stdout_lines }}{% endif %}"
|
||||
- ""
|
||||
- "=== Logged Users ==="
|
||||
- "{{ validate_logged_users.stdout_lines if validate_logged_users.stdout_lines | length > 0 else ['No users logged in'] }}"
|
||||
- ""
|
||||
- "=== Top CPU Processes ==="
|
||||
- "{{ validate_top_cpu_processes.stdout_lines[:5] }}"
|
||||
- ""
|
||||
- "=== Top Memory Processes ==="
|
||||
- "{{ validate_top_mem_processes.stdout_lines[:5] }}"
|
||||
- ""
|
||||
- "=== Statistics Files ==="
|
||||
- "Directory exists: {{ validate_stats_dir.stat.exists }}"
|
||||
- "JSON file created: {{ validate_json_file.stat.exists }}"
|
||||
- "Location: {{ system_info_stats_dir }}"
|
||||
tags: [validate, health-check]
|
||||
Reference in New Issue
Block a user