Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to download diagnostics #151

Merged
merged 1 commit into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion custom_components/proxmoxve/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def __init__(
self.config_entry: ConfigEntry = self.config_entry
self.proxmox = proxmox
self.node_name = node_name
self.resource_id = node_name

async def _async_update_data(self) -> ProxmoxNodeData:
"""Update data for Proxmox Node."""
Expand Down Expand Up @@ -112,6 +113,7 @@ def poll_api() -> dict[str, Any] | None:
)

return ProxmoxNodeData(
type="NODE",
model=api_status["cpuinfo"]["model"],
status=api_status["status"],
version=api_status["version"]["version"],
Expand Down Expand Up @@ -152,6 +154,7 @@ def __init__(
self.proxmox = proxmox
self.node_name: str
self.vm_id = qemu_id
self.resource_id = qemu_id

async def _async_update_data(self) -> ProxmoxVMData:
"""Update data for Proxmox QEMU."""
Expand Down Expand Up @@ -218,6 +221,7 @@ def poll_api() -> dict[str, Any] | None:

update_device_via(self, ProxmoxType.QEMU)
return ProxmoxVMData(
type="QEMU",
status=api_status["status"],
name=api_status["name"],
node=self.node_name,
Expand Down Expand Up @@ -256,8 +260,9 @@ def __init__(
self.hass = hass
self.config_entry: ConfigEntry = self.config_entry
self.proxmox = proxmox
self.vm_id = container_id
self.node_name: str
self.vm_id = container_id
self.resource_id = container_id

async def _async_update_data(self) -> ProxmoxLXCData:
"""Update data for Proxmox LXC."""
Expand Down Expand Up @@ -324,6 +329,7 @@ def poll_api() -> dict[str, Any] | None:

update_device_via(self, ProxmoxType.LXC)
return ProxmoxLXCData(
type="LXC",
status=api_status["status"],
name=api_status["name"],
node=self.node_name,
Expand Down
111 changes: 111 additions & 0 deletions custom_components/proxmoxve/diagnostics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
"""Support for the Airzone diagnostics."""
from __future__ import annotations
import datetime

from typing import Any
from attr import asdict

from proxmoxer import ProxmoxAPI

from homeassistant.components.diagnostics.util import async_redact_data
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_UNIQUE_ID
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.device_registry import DeviceEntry
from homeassistant.helpers import device_registry as dr, entity_registry as er

from .const import COORDINATORS, DOMAIN, LOGGER, PROXMOX_CLIENT
from .coordinator import ProxmoxNodeCoordinator, ProxmoxQEMUCoordinator, ProxmoxLXCCoordinator

TO_REDACT_CONFIG = ["host", "username", "password"]

TO_REDACT_COORD = []

TO_REDACT_API = []

TO_REDACT_DATA = []


async def async_get_config_entry_diagnostics(
hass: HomeAssistant, config_entry: ConfigEntry
) -> dict[str, Any]:
"""Return diagnostics for a config entry."""

coordinators: dict[str, ProxmoxNodeCoordinator | ProxmoxQEMUCoordinator | ProxmoxLXCCoordinator] = hass.data[DOMAIN][config_entry.entry_id][COORDINATORS]

proxmox_client = hass.data[DOMAIN][config_entry.entry_id][PROXMOX_CLIENT]

proxmox = proxmox_client.get_api_client()

resources = await hass.async_add_executor_job(proxmox.cluster.resources.get)

nodes = {}
nodes_api= await hass.async_add_executor_job(proxmox.nodes().get)

for node in nodes_api:
nodes[node["node"]] = node
nodes[node["node"]]["qemu"] = await hass.async_add_executor_job(proxmox.nodes(node["node"]).qemu.get)
nodes[node["node"]]["lxc"] = await hass.async_add_executor_job(proxmox.nodes(node["node"]).lxc.get)

api_data = {
"resources": resources,
"nodes":nodes,
}

device_registry = dr.async_get(hass)
entity_registry = er.async_get(hass)

devices = []

registry_devices = dr.async_entries_for_config_entry(
device_registry, config_entry.entry_id
)

for device in registry_devices:
entities = []

registry_entities = er.async_entries_for_device(
entity_registry,
device_id=device.id,
include_disabled_entities=True,
)

for entity_entry in registry_entities:
state_dict = None
if state := hass.states.get(entity_entry.entity_id):
state_dict = dict(state.as_dict())
state_dict.pop("context", None)

entities.append({"entry": asdict(entity_entry), "state": state_dict})

devices.append({"device": asdict(device), "entities": entities})

return {
"source": "config_entry",
"timestamp": datetime.datetime.now,
"config_entry": async_redact_data(config_entry.data, TO_REDACT_CONFIG),
"options": async_redact_data(config_entry.options, TO_REDACT_CONFIG),
"devices": async_redact_data(devices, TO_REDACT_DATA),
"proxmox_coordinators": {
coordinator.name: {
"data": async_redact_data(
coordinator.data.__dict__, TO_REDACT_COORD
),
}
for i, coordinator in enumerate(coordinators.values())
},
"api_response": async_redact_data(api_data, TO_REDACT_API),
}

async def async_get_device_diagnostics(
hass: HomeAssistant, config_entry: ConfigEntry, device: DeviceEntry
) -> dict:
"""Return diagnostics for a device entry."""

config_entry_diagnostics = await async_get_config_entry_diagnostics(hass, config_entry)

return {
"source": f"device - {device.id}",
**config_entry_diagnostics,
}
2 changes: 1 addition & 1 deletion custom_components/proxmoxve/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"issue_tracker": "https://github.com/dougiteixeira/proxmoxve/issues",
"loggers": ["proxmoxer"],
"requirements": ["proxmoxer==2.0.1"],
"version": "2.0.6"
"version": "2.1.0"
}
29 changes: 16 additions & 13 deletions custom_components/proxmoxve/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,56 +48,59 @@ class ProxmoxSwitchDescription(SwitchEntityDescription):
class ProxmoxNodeData:
"""Data parsed from the Proxmox API for Node."""

model: str
status: str
version: str
uptime: int
type: str
cpu: float
disk_total: float
disk_used: float
model: str
memory_total: float
memory_used: float
memory_free: float
status: str
swap_total: float
swap_free: float
swap_used: float
uptime: int
version: str


@dataclasses.dataclass
class ProxmoxVMData:
"""Data parsed from the Proxmox API for QEMU."""

type: str
name: str
status: str
node: str
health: str
uptime: int
cpu: float
disk_total: float
disk_used: float
health: str
memory_total: float
memory_used: float
memory_free: float
network_in: float
network_out: float
disk_total: float
disk_used: float
status: str
uptime: int


@dataclasses.dataclass
class ProxmoxLXCData:
"""Data parsed from the Proxmox API for LXC."""

type: str
name: str
status: str
node: str
uptime: int
cpu: float
disk_total: float
disk_used: float
memory_total: float
memory_used: float
memory_free: float
network_in: float
network_out: float
disk_total: float
disk_used: float
status: str
swap_total: float
swap_free: float
swap_used: float
uptime: int
Loading