diff --git a/linstor-common b/linstor-common index efff112..cc22bcc 160000 --- a/linstor-common +++ b/linstor-common @@ -1 +1 @@ -Subproject commit efff11250a53489f6d9841d6a03fd87420c80ef6 +Subproject commit cc22bcce2bb3bdd84922151ab588e6bf542d0ca2 diff --git a/linstor/linstorapi.py b/linstor/linstorapi.py index cb65b04..a3043da 100644 --- a/linstor/linstorapi.py +++ b/linstor/linstorapi.py @@ -30,7 +30,7 @@ from linstor.responses import SpaceReport, ExosListResponse, ExosExecResponse, \ ExosEnclosureEventListResponse, ExosMapListResponse, ExosDefaults from linstor.responses import CloneStarted, CloneStatus -from linstor.responses import RemoteListResponse, BackupListResponse +from linstor.responses import RemoteListResponse, BackupListResponse, BackupInfoResponse from linstor.size_calc import SizeCalc try: @@ -174,6 +174,7 @@ class Linstor(object): apiconsts.API_CLONE_RSCDFN_STATUS: CloneStatus, apiconsts.API_LST_REMOTE: RemoteListResponse, apiconsts.API_LST_BACKUPS: BackupListResponse, + apiconsts.API_BACKUP_INFO: BackupInfoResponse, } REST_PORT = 3370 @@ -3567,6 +3568,32 @@ def backup_ship( body ) + def backup_info( + self, + remote_name, + resource_name=None, + bak_id=None, + target_node=None, + stor_pool_map=None): + self._require_version("1.10.2", msg="Backup info is not supported by server") + + path = "/v1/remotes/{rn}/backups/info".format(rn=remote_name) + body = {} + + if resource_name: + body["src_rsc_name"] = resource_name + if bak_id: + body["last_backup"] = bak_id + if target_node: + body["node_name"] = target_node + if stor_pool_map: + body["stor_pool_map"] = stor_pool_map + return self._rest_request( + apiconsts.API_BACKUP_INFO, + "POST", + path , + body) + def remote_list(self): """ diff --git a/linstor/responses.py b/linstor/responses.py index 8551ec9..fed87bd 100644 --- a/linstor/responses.py +++ b/linstor/responses.py @@ -2450,3 +2450,97 @@ def other(self): :rtype: list[BackupOther] """ return BackupOther(self._rest_data.get("other", {})) + + +class BackupInfoResponse(RESTMessageResponse): + + def __init__(self, rest_data): + super(BackupInfoResponse, self).__init__(rest_data) + + @property + def rsc(self): + return self._rest_data.get("rsc") + + @property + def full(self): + return self._rest_data.get("full") + + @property + def latest(self): + return self._rest_data.get("latest") + + @property + def count(self): + return self._rest_data.get("count") + + @property + def dl_size(self): + return self._rest_data.get("dl_size_kib") + + @property + def alloc_size(self): + return self._rest_data.get("alloc_size_kib") + + @property + def storpools(self): + """ + :return: + :rtype: list[BackupInfoStorPool] + """ + return [BackupInfoStorPool(v) for v in self._rest_data.get("storpools", [])] + + +class BackupInfoStorPool(RESTMessageResponse): + + def __init__(self, rest_data): + super(BackupInfoStorPool, self).__init__(rest_data) + + @property + def name(self): + return self._rest_data.get("name") + + @property + def provider_kind(self): + return self._rest_data.get("provider_kind") + + @property + def target_name(self): + return self._rest_data.get("target_name") + + @property + def remaining_space(self): + return self._rest_data.get("remaining_space_kib") + + @property + def volumes(self): + """ + :return: + :rtype: list[BackupInfoStorPoolVolume] + """ + return [BackupInfoStorPoolVolume(v) for v in self._rest_data.get("vlms", [])] + + +class BackupInfoStorPoolVolume(RESTMessageResponse): + + def __init__(self, rest_data): + super(BackupInfoStorPoolVolume, self).__init__(rest_data) + + @property + def name(self): + return self._rest_data.get("name") + + @property + def layer_type(self): + return self._rest_data.get("layer_type") + + @property + def dl_size(self): + return self._rest_data.get("dl_size_kib") + + @property + def alloc_size(self): + return self._rest_data.get("alloc_size_kib") + + @property + def usable_size(self): + return self._rest_data.get("usable_size_kib")