1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 19:26:48 +00:00
webvirtcloud/instances/report.py
catborise a80d093c94 feat(instances): a report of every VM with its addresses and OS, as an Excel file
The Administration menu gets "VM report (.xlsx)", a workbook for
superusers. The VMs sheet has one row per VM on every compute, shut-off
ones and those the panel has not registered too: name,
state, host, OS and OS family, vCPUs, memory, IP addresses and where they
came from, MAC addresses, owners, and whether the panel has registered
it. A Coverage sheet says when it was made and what could not be read.

The addresses come from the same live reading as the address search,
now shared by both. The OS is the guest agent's (libvirt's guest info)
or, without one, the libosinfo id a tool such as virt-install wrote into
the definition. Link-local IPv6 addresses are left out of the report.
Text cells stay text: a VM name starting with "=" is not a formula.

openpyxl 3.1.5 writes the workbook.
2026-10-24 22:30:07 +03:00

38 lines
1.3 KiB
Python

"""An Excel workbook: rows under a bold, filterable header, and a sheet of notes."""
from io import BytesIO
from openpyxl import Workbook
from openpyxl.styles import Font
from openpyxl.utils import get_column_letter
MAX_WIDTH = 60
def workbook(title, header, rows, notes_title, notes):
"""The .xlsx file's bytes. Every text cell stays text: openpyxl would
write one starting with "=" as a formula, and the text comes from VM
names and guests."""
book = Workbook()
sheet = book.active
sheet.title = title
for values in [header, *rows]:
sheet.append(values)
for row in sheet.iter_rows():
for cell in row:
if isinstance(cell.value, str):
cell.data_type = "s"
for cell in sheet[1]:
cell.font = Font(bold=True)
sheet.freeze_panes = "A2"
sheet.auto_filter.ref = sheet.dimensions
for index, column in enumerate(sheet.columns, start=1):
width = max(len(str(cell.value or "")) for cell in column) + 2
sheet.column_dimensions[get_column_letter(index)].width = min(width, MAX_WIDTH)
notes_sheet = book.create_sheet(notes_title)
for line in notes:
notes_sheet.append([line])
notes_sheet.column_dimensions["A"].width = MAX_WIDTH * 2
out = BytesIO()
book.save(out)
return out.getvalue()