196 lines
7.1 KiB
YAML
196 lines
7.1 KiB
YAML
---
|
|
# Proxmox VE Management Playbook
|
|
# Inventory and health check for VMs, LXC containers, storage, and recent tasks
|
|
# Usage: ansible-playbook playbooks/proxmox_management.yml -i hosts.ini
|
|
# Usage: ansible-playbook playbooks/proxmox_management.yml -i hosts.ini -e action=snapshot -e vm_id=100
|
|
|
|
- name: Proxmox VE Management
|
|
hosts: pve
|
|
gather_facts: yes
|
|
become: false
|
|
|
|
vars:
|
|
action: "{{ action | default('status') }}"
|
|
vm_id: "{{ vm_id | default('') }}"
|
|
report_dir: "/tmp/health_reports"
|
|
|
|
tasks:
|
|
|
|
# ---------- Report directory ----------
|
|
- name: Ensure health report directory exists
|
|
ansible.builtin.file:
|
|
path: "{{ report_dir }}"
|
|
state: directory
|
|
mode: '0755'
|
|
delegate_to: localhost
|
|
run_once: true
|
|
|
|
# ---------- Status mode ----------
|
|
- name: Get PVE version
|
|
ansible.builtin.command: pveversion
|
|
register: pve_version
|
|
changed_when: false
|
|
failed_when: false
|
|
when: action == 'status'
|
|
|
|
- name: Get node resource summary
|
|
ansible.builtin.shell: |
|
|
pvesh get /nodes/$(hostname)/status --output-format json 2>/dev/null || \
|
|
echo '{"error": "pvesh not available"}'
|
|
register: node_status_raw
|
|
changed_when: false
|
|
failed_when: false
|
|
when: action == 'status'
|
|
|
|
- name: List all VMs
|
|
ansible.builtin.command: qm list
|
|
register: vm_list
|
|
changed_when: false
|
|
failed_when: false
|
|
when: action == 'status'
|
|
|
|
- name: List all LXC containers
|
|
ansible.builtin.command: pct list
|
|
register: lxc_list
|
|
changed_when: false
|
|
failed_when: false
|
|
when: action == 'status'
|
|
|
|
- name: Count running VMs
|
|
ansible.builtin.shell: qm list 2>/dev/null | grep -c running || echo "0"
|
|
register: running_vm_count
|
|
changed_when: false
|
|
failed_when: false
|
|
when: action == 'status'
|
|
|
|
- name: Count running LXC containers
|
|
ansible.builtin.shell: pct list 2>/dev/null | grep -c running || echo "0"
|
|
register: running_lxc_count
|
|
changed_when: false
|
|
failed_when: false
|
|
when: action == 'status'
|
|
|
|
- name: Get storage pool status
|
|
ansible.builtin.shell: |
|
|
pvesh get /nodes/$(hostname)/storage --output-format json 2>/dev/null | python3 << 'PYEOF' || pvesm status 2>/dev/null || echo "Storage info unavailable"
|
|
import sys, json
|
|
try:
|
|
pools = json.load(sys.stdin)
|
|
except Exception:
|
|
sys.exit(1)
|
|
print('{:<20} {:<15} {:>8} {:>14}'.format('Storage', 'Type', 'Used%', 'Avail (GiB)'))
|
|
print('-' * 62)
|
|
for p in pools:
|
|
name = p.get('storage', 'n/a')
|
|
stype = p.get('type', 'n/a')
|
|
total = p.get('total', 0)
|
|
used = p.get('used', 0)
|
|
avail = p.get('avail', 0)
|
|
pct = round(used / total * 100, 1) if total and total > 0 else 0.0
|
|
avail_gib = round(avail / 1024**3, 2)
|
|
print('{:<20} {:<15} {:>7}% {:>13} GiB'.format(name, stype, pct, avail_gib))
|
|
PYEOF
|
|
register: storage_status
|
|
changed_when: false
|
|
failed_when: false
|
|
when: action == 'status'
|
|
|
|
- name: Get last 10 task log entries
|
|
ansible.builtin.shell: |
|
|
pvesh get /nodes/$(hostname)/tasks --limit 10 --output-format json 2>/dev/null | python3 << 'PYEOF' || echo "Task log unavailable"
|
|
import sys, json, datetime
|
|
try:
|
|
tasks = json.load(sys.stdin)
|
|
except Exception:
|
|
sys.exit(1)
|
|
print('{:<22} {:<12} {}'.format('Timestamp', 'Status', 'UPID'))
|
|
print('-' * 80)
|
|
for t in tasks:
|
|
upid = t.get('upid', 'n/a')
|
|
status = t.get('status', 'n/a')
|
|
starttime = t.get('starttime', 0)
|
|
try:
|
|
ts = datetime.datetime.fromtimestamp(starttime).strftime('%Y-%m-%d %H:%M:%S')
|
|
except Exception:
|
|
ts = str(starttime)
|
|
print('{:<22} {:<12} {}'.format(ts, status, upid[:60]))
|
|
PYEOF
|
|
register: task_log
|
|
changed_when: false
|
|
failed_when: false
|
|
when: action == 'status'
|
|
|
|
# ---------- Status summary ----------
|
|
- name: Display Proxmox status summary
|
|
ansible.builtin.debug:
|
|
msg: |
|
|
============================================================
|
|
Proxmox VE Status — {{ inventory_hostname }}
|
|
============================================================
|
|
PVE Version : {{ pve_version.stdout | default('n/a') }}
|
|
Running VMs : {{ running_vm_count.stdout | default('0') | trim }}
|
|
Running LXCs : {{ running_lxc_count.stdout | default('0') | trim }}
|
|
|
|
--- Node Resource Summary (JSON) ---
|
|
{{ node_status_raw.stdout | default('{}') | from_json | to_nice_json if (node_status_raw.stdout | default('') | length > 0 and node_status_raw.stdout | default('') is search('{')) else node_status_raw.stdout | default('unavailable') }}
|
|
|
|
--- VMs (qm list) ---
|
|
{{ vm_list.stdout | default('none') }}
|
|
|
|
--- LXC Containers (pct list) ---
|
|
{{ lxc_list.stdout | default('none') }}
|
|
|
|
--- Storage Pools ---
|
|
{{ storage_status.stdout | default('unavailable') }}
|
|
|
|
--- Recent Tasks (last 10) ---
|
|
{{ task_log.stdout | default('unavailable') }}
|
|
============================================================
|
|
when: action == 'status'
|
|
|
|
# ---------- Write JSON report ----------
|
|
- name: Write Proxmox health JSON report
|
|
ansible.builtin.copy:
|
|
content: "{{ report_data | to_nice_json }}"
|
|
dest: "{{ report_dir }}/proxmox_{{ ansible_date_time.date }}.json"
|
|
vars:
|
|
report_data:
|
|
timestamp: "{{ ansible_date_time.iso8601 }}"
|
|
host: "{{ inventory_hostname }}"
|
|
pve_version: "{{ pve_version.stdout | default('n/a') | trim }}"
|
|
running_vms: "{{ running_vm_count.stdout | default('0') | trim }}"
|
|
running_lxcs: "{{ running_lxc_count.stdout | default('0') | trim }}"
|
|
vm_list: "{{ vm_list.stdout | default('') }}"
|
|
lxc_list: "{{ lxc_list.stdout | default('') }}"
|
|
storage_status: "{{ storage_status.stdout | default('') }}"
|
|
task_log: "{{ task_log.stdout | default('') }}"
|
|
node_status_raw: "{{ node_status_raw.stdout | default('') }}"
|
|
delegate_to: localhost
|
|
run_once: true
|
|
changed_when: false
|
|
when: action == 'status'
|
|
|
|
# ---------- Snapshot mode ----------
|
|
- name: Create VM snapshot
|
|
ansible.builtin.shell: >
|
|
qm snapshot {{ vm_id }} "ansible-snap-{{ ansible_date_time.epoch }}"
|
|
--description "Ansible automated snapshot"
|
|
register: snapshot_result
|
|
changed_when: true
|
|
failed_when: false
|
|
when:
|
|
- action == 'snapshot'
|
|
- vm_id | string | length > 0
|
|
|
|
- name: Display snapshot result
|
|
ansible.builtin.debug:
|
|
msg: |
|
|
Snapshot created on {{ inventory_hostname }}
|
|
VM ID : {{ vm_id }}
|
|
Result:
|
|
{{ (snapshot_result | default({})).stdout | default('') }}
|
|
{{ (snapshot_result | default({})).stderr | default('') }}
|
|
when:
|
|
- action == 'snapshot'
|
|
- vm_id | string | length > 0
|