diff --git a/src/synology_dsm/api/virtual_machine_manager/__init__.py b/src/synology_dsm/api/virtual_machine_manager/__init__.py new file mode 100644 index 00000000..97a86e57 --- /dev/null +++ b/src/synology_dsm/api/virtual_machine_manager/__init__.py @@ -0,0 +1 @@ +"""Synology Virtual Machine Manager API models.""" \ No newline at end of file diff --git a/src/synology_dsm/api/virtual_machine_manager/guest.py b/src/synology_dsm/api/virtual_machine_manager/guest.py new file mode 100644 index 00000000..65ae03f0 --- /dev/null +++ b/src/synology_dsm/api/virtual_machine_manager/guest.py @@ -0,0 +1,90 @@ +"""DSM Virtual Machine data.""" +from synology_dsm.helpers import SynoFormatHelper + + +class SynoVirtualMachineManager: + """Class containing Virtual Machine Guests""" + + API_KEY = "SYNO.Virtualization.API.Guest" + ACTION_API_KEY = "SYNO.Virtualization.API.Guest.Action" + + def __init__(self, dsm): + """Constructor method.""" + self._dsm = dsm + self._data = {} + + def update(self): + """Updates Virtual Machine Guest data.""" + raw_data = self._dsm.get(self.API_KEY, "list") + if raw_data: + self._data = raw_data["data"] + + # Root + @property + def guests(self): + """Gets all Virtual Machines.""" + return self._data.get("guests", []) + + @property + def guest_ids(self): + """Gets a Virtual Machines name.""" + guests = [] + for guest in self.guests: + guests.append(guest["guest_id"]) + return guests + + def get_guest(self, guest_id): + """Returns a specific guest.""" + for guest in self.guests: + if guest["guest_id"] == guest_id: + return guest + return {} + + def guest_name(self, guest_id): + """Return the name of this guest.""" + return self.get_guest(guest_id).get("guest_name") + + def guest_status(self, guest_id): + """Gets Status of Guest (Shutdown, Running etc)""" + return self.get_guest(guest_id).get("status") + + def guest_network_name(self, guest_id): + """Gets Network Name of Guest.""" + return self.get_guest(guest_id).get("network_name") + + def poweron(self, guest_id, guest_name): + """Power on a virtual machine""" + res = self._dsm.post( + self.ACTION_API_KEY, + "poweron", + { + "guest_id": guest_id, + "guest_name": guest_name, + }, + ) + self.update() + + def shutdown(self, guest_id, guest_name): + """Gracefully Shutdown a virtual machine""" + res = self._dsm.post( + self.ACTION_API_KEY, + "shutdown", + { + "guest_id": guest_id, + "guest_name": guest_name, + }, + ) + self.update() + + def poweroff(self, guest_id, guest_name): + """Force Shutdown a virtual machine""" + res = self._dsm.post( + self.ACTION_API_KEY, + "poweroff", + { + "guest_id": guest_id, + "guest_name": guest_name, + }, + ) + self.update() + return res diff --git a/src/synology_dsm/synology_dsm.py b/src/synology_dsm/synology_dsm.py index 7c90d4df..7bcef425 100644 --- a/src/synology_dsm/synology_dsm.py +++ b/src/synology_dsm/synology_dsm.py @@ -18,6 +18,7 @@ from .api.dsm.network import SynoDSMNetwork from .api.storage.storage import SynoStorage from .api.surveillance_station import SynoSurveillanceStation +from .api.virtual_machine_manager.guest import SynoVirtualMachineManager from .const import API_AUTH from .const import API_INFO from .const import SENSITIV_PARAMS @@ -84,6 +85,8 @@ def __init__( self._system = None self._utilisation = None self._upgrade = None + self._guests = None + # Build variables if use_https: @@ -362,6 +365,9 @@ def update(self, with_information: bool = False, with_network: bool = False): if self._surveillance: self._surveillance.update() + if self._guests: + self._guests.update() + if self._system: self._system.update() @@ -400,6 +406,9 @@ def reset(self, api: any) -> bool: if api == SynoSurveillanceStation.API_KEY: self._surveillance = None return True + if api == SynoVirtualMachineManager.API_KEY: + self._guests = None + return True if isinstance(api, SynoCoreSecurity): self._security = None return True @@ -424,6 +433,9 @@ def reset(self, api: any) -> bool: if isinstance(api, SynoSurveillanceStation): self._surveillance = None return True + if isinstance(api, SynoVirtualMachineManager): + self._guests = None + return True return False @property @@ -495,3 +507,10 @@ def utilisation(self) -> SynoCoreUtilization: if not self._utilisation: self._utilisation = SynoCoreUtilization(self) return self._utilisation + + @property + def virtual_machine_manager(self) -> SynoVirtualMachineManager: + """Gets NAS utilisation informations.""" + if not self._guests: + self._guests = SynoVirtualMachineManager(self) + return self._guests \ No newline at end of file