HEX
Server: Apache/2.4.63 (Unix)
System: Linux TOMS-220NAS 4.4.302+ #86009 SMP Wed Nov 26 18:19:17 CST 2025 x86_64
User: flavio87 (1026)
PHP: 8.3.27
Disabled: NONE
Upload Files
File: //usr/local/packages/@appstore/ActiveInsight/collectors/snapshot_replication.py
#!/usr/bin/python
import subprocess
import json
from typing import Dict, Tuple, List


def _format_info_dict(name: str, label: Dict[str, str], data: Dict[str, str]) -> Dict:
    return {
        "application": "SnapshotReplication",
        "name": name,
        "type": "info",
        "label": label,
        "attribute": data,
    }


def _synowebapi(api: str, method: str, version: int, params: Dict, check: bool = False) -> Tuple[int, Dict]:
    cmd = ["/usr/syno/bin/synowebapi", "--exec", f"api={api}", f"method={method}", f"version={version}"]
    for key, value in params.items():
        cmd.append(f"{key}={json.dumps(value)}")
    ret = subprocess.run(cmd, check=check, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
    return ret.returncode, json.loads(ret.stdout.decode('utf-8').strip())


def _synowebapi_check(api: str, method: str, version: int, params: Dict) -> Dict:
    _, ret = _synowebapi(api, method, version, params, True)
    return ret


def _get_active_insight_snapshot_count(share_name: str) -> int:
    returncode, webapi_response = _synowebapi("SYNO.Core.Share.Snapshot", "list", 2, {"name": share_name, "additional": ["desc"]})
    if returncode != 0:
        return 0
    if webapi_response.get("success", False) is False:
        return 0
    count = 0
    for snapshot in webapi_response.get("data", {}).get("snapshots", []):
        if snapshot.get("desc", "") == "This snapshot was taken by Active Insight.":
            count += 1
    return count


def collect_snapshot_replication() -> List:
    snapshot_info_dict = {}
    webapi_response = _synowebapi_check("SYNO.Core.Share", "list", 1, {"shareType": "all", "additional": ["snapshot_info", "include_cold_storage_share", "include_worm_share"]})
    if webapi_response.get("success", False) is False:
        raise Exception("SYNO.Core.Share.list failed")
    shares = webapi_response.get("data", {}).get("shares", [])
    for share in shares:
        uuid = share.get("uuid", "")
        if uuid == "":
            continue
        snapshot_info = share.get("snapshot_info", {})
        snapshot_info_retention = snapshot_info.get("retention", {})
        enable_retention = snapshot_info_retention != {} and snapshot_info_retention.get("policyType", 0) != 0
        name = share.get("name", "")
        if name == "":
            count = 0
        else:
            count = _get_active_insight_snapshot_count(name)

        snapshot_info_dict[uuid] = (enable_retention, count)

    ret = []
    for share_uuid, (enable_retention, count) in snapshot_info_dict.items():
        ret.append(_format_info_dict(
            "share_retention_enable",
            {"share_id": share_uuid},
            {"enable": str(enable_retention)}
        ))
        ret.append(_format_info_dict(
            "active_insight_snapshot_count",
            {"share_id": share_uuid},
            {"count": str(count)}
        ))
    return ret