Snapshot review script

This commit is contained in:
Théophile Bastian 2024-08-01 12:29:13 +02:00
parent 72a5ae31f0
commit aed349520a
6 changed files with 132 additions and 0 deletions

1
.gitignore vendored
View file

@ -59,3 +59,4 @@ target/
# Project-specific
venv
proxmox_scripts/settings.py

19
proxmox_scripts/auth.py Normal file
View file

@ -0,0 +1,19 @@
from proxmoxer import ProxmoxAPI
from . import settings
import typing as t
_api: t.Optional[ProxmoxAPI] = None
def get_api() -> ProxmoxAPI:
global _api
if _api is None:
_api = ProxmoxAPI(
settings.PROXMOX_HOST,
user=settings.PROXMOX_USER,
password=settings.PROXMOX_PASS(),
verify_ssl=True,
)
return _api

View file

@ -0,0 +1,5 @@
import typing as t
PROXMOX_HOST: str = "hv1.example.com:8006" # FIXME
PROXMOX_USER: str = "username@pam" # FIXME
PROXMOX_PASS: t.Callable[[], str] = lambda: "changeme" # FIXME

View file

@ -0,0 +1,53 @@
from . import auth
from . import util
import datetime
import typing as t
from proxmoxer.core import ProxmoxResource
from argparse import ArgumentParser
def list_snapshots() -> list:
snapshots = []
for vmid, vm in util.qemu_vms().items():
for snapshot in vm['api'].snapshot().get():
if snapshot['name'] != 'current':
snapshot['node'] = vm['node']
snapshot['vmid'] = vmid
snapshot['vmname'] = vm['name']
snapshot['api'] = vm['api'].snapshot(snapshot['name'])
snapshots.append(snapshot)
return snapshots
def review_snapshots():
parser = ArgumentParser()
parser.add_argument('--older-than', help='More than N days ago only', type=int,
default=0)
parser.add_argument('--delete', '-d', help='Offer to delete snapshots',
action='store_true')
args = parser.parse_args()
filter_date = datetime.datetime.now() - datetime.timedelta(days=args.older_than)
for snap in list_snapshots():
snap_date = datetime.datetime.fromtimestamp(snap['snaptime'])
snap_age = datetime.datetime.now() - snap_date
if snap_date > filter_date:
continue
print(
f"{snap['node']} -- [{snap['vmid']}] {snap['vmname']} -- "
f"at {snap_date} ({snap_age.days}d ago)")
for attr, val in snap.items():
if attr in ('node', 'vmid', 'vmname', 'snap_date', 'snaptime', 'api'):
continue
print(f" {attr}: {val}")
if args.delete:
print(" Delete? [vmid to delete] ", end='')
res = input().strip()
if res == str(snap['vmid']):
snap['api'].delete()
print(" Deleted.")
print("")

20
proxmox_scripts/util.py Normal file
View file

@ -0,0 +1,20 @@
from . import auth
def nodes() -> dict[str, dict]:
""" List of hypervisors """
nodes = auth.get_api().nodes.get()
return {node['node']: node for node in nodes}
def qemu_vms() -> dict:
""" Flat dict of QEMU VMs on all hypervisors """
out = {}
api = auth.get_api()
for node in nodes():
for vm in api.nodes(node).qemu.get():
vm['node'] = node
vm['api'] = api.nodes(node).qemu(vm['vmid'])
out[vm['vmid']] = vm
return out

34
setup.py Normal file
View file

@ -0,0 +1,34 @@
#!/usr/bin/env python3
from setuptools import setup, find_packages
def parse_requirements():
reqs = []
with open("requirements.txt", "r") as handle:
for line in handle:
reqs.append(line)
return reqs
setup(
name="proxmox_scripts",
version="0.1.0",
description="Collection of misc scripts to manage proxmox",
author="tobast",
author_email="contact@tobast.fr",
license="LICENSE",
url="https://git.tobast.fr/tobast/proxmox_scripts/",
packages=find_packages(),
include_package_data=True,
long_description=open("README.md").read(),
install_requires=parse_requirements(),
entry_points={
"console_scripts": [
(
"proxmox-snapshot-review = proxmox_scripts.snapshots:review_snapshots",
),
]
},
)