Sanitized mirror from private repository - 2026-03-11 06:48:12 UTC
This commit is contained in:
195
ansible/automation/playbooks/proxmox_management.yml
Normal file
195
ansible/automation/playbooks/proxmox_management.yml
Normal file
@@ -0,0 +1,195 @@
|
||||
---
|
||||
# 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
|
||||
Reference in New Issue
Block a user