262 lines
9.0 KiB
Python
262 lines
9.0 KiB
Python
from __future__ import annotations
|
|
from typing import Optional
|
|
from . import base_api
|
|
import json
|
|
|
|
|
|
class Snapshot(base_api.BaseApi):
|
|
"""Class for interacting with Snapshot APIs.
|
|
|
|
This class implements APIs to manage snapshots.
|
|
There is no documentation for these APIs, so the implementation is based on network inspection.
|
|
|
|
Examples
|
|
--------
|
|
List snapshots for a share:
|
|
>>> from synology_api import snapshot
|
|
>>> ss = snapshot.Snapshot('IP', 'PORT', 'USER', 'PASSWORD')
|
|
>>> resp = ss.list_snapshots('share_name')
|
|
>>> print(resp)
|
|
|
|
Create a snapshot for a share:
|
|
>>> resp = ss.create_snapshot('share_name')
|
|
>>> print(resp)
|
|
|
|
Delete snapshots for a share:
|
|
>>> resp = ss.delete_snapshots('share_name', ['snapshot_name'])
|
|
>>> print(resp)
|
|
|
|
Set attributes for a snapshot:
|
|
>>> resp = ss.set_snapshot_attr('share_name', 'snapshot_name', description='new description', lock=True)
|
|
>>> print(resp)
|
|
"""
|
|
|
|
def list_snapshots(self,
|
|
share_name: str,
|
|
attribute_filter: list[str] = [],
|
|
additional_attribute: list[str] = [],
|
|
offset: int = 0,
|
|
limit: int = -1) -> dict[str, object] | str:
|
|
"""List snapshots for a share.
|
|
|
|
Parameters
|
|
----------
|
|
share_name : str
|
|
Name of the share to list snapshots for
|
|
attribute_filter : list[str], optional
|
|
List of attributes filter to apply. Defaults to [] (no filter).
|
|
|
|
Each attribute filter is a string in the format of "attr==value" or "attr=value" and
|
|
optionally prefixed with "!" to negate the filter.
|
|
The following are examples of valid attribute filters:
|
|
|
|
- ["!hide==true", "desc==abc"] # hide is not true and desc is exactly abc
|
|
- ["desc=abc"] # desc has abc in it
|
|
additional_attribute : list[str], optional
|
|
List of snapshot attributes whose values are included in the response.
|
|
Defaults to [] (only time is returned).
|
|
|
|
Note that not all attributes are available via API. The following are confirmed to work:
|
|
|
|
- desc
|
|
- lock
|
|
- worm_lock
|
|
- schedule_snapshot
|
|
offset : int, optional
|
|
Offset to start listing from. Defaults to 0.
|
|
limit : int, optional
|
|
Number of snapshots to return. Defaults to -1 (all).
|
|
|
|
Returns
|
|
-------
|
|
dict[str, object] | str
|
|
API response if successful, error message if not
|
|
|
|
Example:
|
|
{
|
|
"data": {
|
|
"snapshots": [
|
|
{
|
|
"desc": "",
|
|
"lock": true,
|
|
"schedule_snapshot": false,
|
|
"time": "GMT+09-2023.09.11-23.23.40",
|
|
"worm_lock": true,
|
|
"worm_lock_begin": "1694442321",
|
|
"worm_lock_day": "1",
|
|
"worm_lock_end": "1694528721"
|
|
}
|
|
],
|
|
"total": 1
|
|
},
|
|
"success": true
|
|
}
|
|
"""
|
|
|
|
api_name = 'SYNO.Core.Share.Snapshot'
|
|
info = self.gen_list[api_name]
|
|
api_path = info['path']
|
|
|
|
req_param = {'version': '2',
|
|
'method': 'list',
|
|
'name': share_name,
|
|
'filter': json.dumps({"attr": attribute_filter}),
|
|
'additional': json.dumps(additional_attribute),
|
|
'offset': offset,
|
|
'limit': limit}
|
|
|
|
return self.request_data(api_name, api_path, req_param)
|
|
|
|
def create_snapshot(self,
|
|
share_name: str,
|
|
description: str = "",
|
|
lock: bool = False,
|
|
immutable: bool = False,
|
|
immutable_days: int = 7,
|
|
) -> dict[str, object] | str:
|
|
"""Create a snapshot for a share.
|
|
|
|
Parameters
|
|
----------
|
|
share_name : str
|
|
Name of the share to create a snapshot for
|
|
description : str, optional
|
|
Description of the snapshot. Defaults to "".
|
|
lock : bool, optional
|
|
Whether to lock the snapshot. Defaults to False.
|
|
immutable : bool, optional
|
|
Whether to make the snapshot immutable. Defaults to False.
|
|
immutable_days : int, optional
|
|
Number of days to make the snapshot immutable for. Defaults to 7.
|
|
Must be greater than 0. Mandatory if immutable is True.
|
|
|
|
Returns
|
|
-------
|
|
dict[str, object] | str
|
|
API response if successful, error message if not
|
|
|
|
Example:
|
|
{
|
|
"data": "GMT+09-2023.09.12-00.33.20",
|
|
"success": true
|
|
}
|
|
"""
|
|
|
|
api_name = 'SYNO.Core.Share.Snapshot'
|
|
info = self.gen_list[api_name]
|
|
api_path = info['path']
|
|
|
|
snapinfo = {
|
|
"desc": description,
|
|
"lock": lock,
|
|
}
|
|
if immutable == True:
|
|
snapinfo['worm_lock'] = True
|
|
if immutable_days < 1:
|
|
return "immutable_days must be greater than 0"
|
|
snapinfo['worm_lock_day'] = immutable_days
|
|
req_param = {'version': '1',
|
|
'method': 'create',
|
|
'snapinfo': json.dumps(snapinfo),
|
|
'name': share_name}
|
|
|
|
return self.request_data(api_name, api_path, req_param)
|
|
|
|
def delete_snapshots(self,
|
|
share_name: str,
|
|
snapshots: list[str]
|
|
) -> dict[str, object] | str:
|
|
"""Delete snapshots for a share.
|
|
|
|
Parameters
|
|
----------
|
|
share_name : str
|
|
Name of the share to delete snapshots for
|
|
snapshots : list[str]
|
|
List of snapshots to delete
|
|
|
|
Returns
|
|
-------
|
|
dict[str, object] | str
|
|
API response if successful, error message if not
|
|
|
|
Example:
|
|
{
|
|
"success": true
|
|
}
|
|
"""
|
|
|
|
api_name = 'SYNO.Core.Share.Snapshot'
|
|
info = self.gen_list[api_name]
|
|
api_path = info['path']
|
|
|
|
req_param = {'version': '1',
|
|
'method': 'delete',
|
|
'name': share_name,
|
|
'snapshots': json.dumps(snapshots)}
|
|
|
|
return self.request_data(api_name, api_path, req_param)
|
|
|
|
def set_snapshot_attr(self,
|
|
share_name: str,
|
|
snapshot: str,
|
|
description: Optional[str] = None,
|
|
lock: Optional[bool] = None,
|
|
immutable: Optional[bool] = None,
|
|
immutable_days: Optional[int] = None
|
|
) -> dict[str, object] | str:
|
|
"""Set attributes for a snapshot.
|
|
|
|
Parameters
|
|
----------
|
|
share_name : str
|
|
Name of the share to set attributes for
|
|
snapshot : str
|
|
Name of the snapshot to set attributes for
|
|
description : str, optional
|
|
Description of the snapshot. Defaults to None (no change).
|
|
lock : bool, optional
|
|
Whether to lock the snapshot. Defaults to None (no change).
|
|
immutable : bool, optional
|
|
Whether to make the snapshot immutable. Defaults to None (no change).
|
|
immutable_days : int, optional
|
|
Number of days to make the snapshot immutable for. Defaults to None (no change).
|
|
Must be greater than 0. Mandatory if immutable is True.
|
|
|
|
Returns
|
|
-------
|
|
dict[str, object] | str
|
|
API response if successful, error message if not
|
|
|
|
Example:
|
|
{
|
|
"success": true
|
|
}
|
|
"""
|
|
|
|
api_name = 'SYNO.Core.Share.Snapshot'
|
|
info = self.gen_list[api_name]
|
|
api_path = info['path']
|
|
|
|
snapinfo = {}
|
|
if description is not None:
|
|
snapinfo['desc'] = description
|
|
if lock is not None:
|
|
snapinfo['lock'] = lock
|
|
if immutable is not None:
|
|
if immutable == False:
|
|
return "immutable cannot be set to False"
|
|
if immutable_days is None:
|
|
return "immutable_days must be specified if immutable is True"
|
|
if immutable_days < 1:
|
|
return "immutable_days must be greater than 0"
|
|
snapinfo['worm_lock'] = True
|
|
snapinfo['worm_lock_day'] = immutable_days
|
|
req_param = {'version': '1',
|
|
'method': 'set',
|
|
'snapinfo': json.dumps(snapinfo),
|
|
'name': share_name,
|
|
'snapshot': snapshot}
|
|
|
|
return self.request_data(api_name, api_path, req_param)
|