How to solve missing SLA policies in SynetoOS 6

Written By Christian Castagna (Administrator)

Updated at September 9th, 2025

→ Applies to: SynetoOS 6.x

After upgrading from SynetoOS 5 to SynetoOS 6, some or all previously configured SLA policies may no longer be visible. For example, in the screenshot below the Platinum SLA policy is missing after upgrading to SynetoOS 6. Follow the steps below to resolve this issue.
 

 

Step 1. Connect to SynetoOS appliance via SSH as admin

ssh admin@<your_ip_address_or_hostname>

 

Step 2. Get root privileges

sudo su -

 

Step 3. Create “/tmp/slapolicy_assignments_os6.py” file

vi /tmp/slapolicy_assignments_os6.py

IMPORTANT
Make sure to copy and paste the exact lines below.

#!/usr/share/syneto-giove/.venv/bin/python

from typing import Optional

import signal
import sys
import getpass

from syneto_api import Authentication, V1Protection, V1Jobs, Storage


def signal_handler(signum, frame):
    """Handle Ctrl-C gracefully with exit code 130"""
    print("\nInterrupted by user (Ctrl-C)")
    sys.exit(130)


def get_policy_by_id(id: str, policies: list[dict]) -> Optional[dict]:
    if not id:
        raise ValueError("Policy id cannot be empty")
    for policy in policies:
        if policy.get("id") == id:
            return policy
    return None


def get_storage_volume_by_id(id: str, volumes: list[dict]) -> Optional[dict]:
    if not id:
        raise ValueError("Volume id cannot be empty")
    for volume in volumes:
        if volume.get("id") == id:
            return volume
    return None


def delete_policy_assignments(assignments: list[dict], protection_api: V1Protection, jobs_api: V1Jobs):
    delete_job_ids = {}
    for assignment in assignments:
        assignment_id = assignment.get("id")
        if not assignment_id:
            print(f"Error: Failed to delete policy assignment with invalid id={assignment_id}")
            continue
        delete_response = protection_api.delete_policy_assignment(assignment_id)
        delete_job_id = delete_response.get("jobId")
        if not delete_job_id:
            print(f"Error: Failed to delete policy assignment id={assignment_id}, could not retrieve deletion job id")
            continue
        delete_job_ids[delete_job_id] = assignment_id

    failed_delete_job_ids = {}
    for job_id in delete_job_ids:
        try:
            job_response = jobs_api.wait_for_job_completion(job_id, timeout=10)
            if job_response.get("status") != "SUCCEEDED":
                failed_delete_job_ids[job_id] = delete_job_ids[job_id]
        except Exception as e:
            print(f"Error: failed to wait for completion of job id={job_id}: {repr(e)}")
            failed_delete_job_ids[job_id] = delete_job_ids[job_id]

    if failed_delete_job_ids:
        print("Error: Failed to delete the following policy assignments:")
        for job_id in failed_delete_job_ids:
            print(f"  - policyAssignmentId={failed_delete_job_ids[job_id]} (jobId={job_id})")

    print(f"Deleted {len(delete_job_ids) - len(failed_delete_job_ids)} of {len(delete_job_ids)} policy assignments")


def main():
    password = getpass.getpass("Enter support password: ")
    print()

    auth = Authentication(url_base="https://localhost/api/auth", insecure_ssl=True)
    auth_response = auth.login(username="support", password=password)
    jwt = auth_response["jwt"]

    protection_api = V1Protection(url_base="https://localhost/api/protection", insecure_ssl=True)
    protection_api.set_auth_jwt(jwt)

    storage_api = Storage(url_base="https://localhost/api/storage", insecure_ssl=True)
    storage_api.set_auth_jwt(jwt)

    jobs_api = V1Jobs(url_base="https://localhost/api/protection", insecure_ssl=True)
    jobs_api.set_auth_jwt(jwt)

    assignments = protection_api.get_policy_assignments()
    policies = protection_api.get_policies()
    volumes = storage_api.get_volumes()

    assignments_to_delete = []
    for assignment in assignments:
        assignment_id = assignment.get("id")
        storage_volume_id = assignment.get("storageVolumeId")
        if not storage_volume_id:
            print(
                f"Warning: Policy assignment id={assignment_id} has invalid storageVolumeId={storage_volume_id}, skipping"
            )
            continue
        policy_id = assignment.get("policyId")
        if not policy_id:
            print(f"Warning: Policy assignment id={assignment_id} has invalid policyId={policy_id}, skipping")
            continue
        policy = get_policy_by_id(policy_id, policies)
        if not policy:
            print(f"Warning: Policy id={policy_id} for assignment id={assignment_id} not found, skipping")
            continue
        if not policy.get("origin"):
            continue  # Not a replicated policy, skip
        # We now have a replicated policy
        storage_volume = get_storage_volume_by_id(storage_volume_id, volumes)
        if not storage_volume:
            print(
                f"Warning: Storage volume id={storage_volume_id} for assignment id={assignment_id} not found, skipping"
            )
            continue
        if storage_volume.get("replicaInfo"):
            continue  # Correct case: replicated policy + replicated volume, skip
        assignments_to_delete.append(assignment)

    if not assignments_to_delete:
        print("\nFound no policy assignments to delete. Exiting.")
        sys.exit(0)

    print(f"\nFound {len(assignments_to_delete)} policy assignments to delete:\n")
    for assignment in assignments_to_delete:
        print(
            f"  - policyAssignmentId={assignment.get('id')} policyId={assignment.get('policyId')} storageVolumeId={assignment.get('storageVolumeId')}"
        )

    proceed = input("\nDo you want to proceed with deleting these policy assignments? (y/n): ").strip().lower()
    print()
    if proceed != "y":
        print("Aborted by user.")
        sys.exit(0)

    delete_policy_assignments(assignments_to_delete, protection_api=protection_api, jobs_api=jobs_api)


if __name__ == "__main__":
    # Set up signal handler for Ctrl-C
    signal.signal(signal.SIGINT, signal_handler)

    try:
        main()
    except KeyboardInterrupt:
        # This should not be reached due to signal handler, but just in case
        print("\nInterrupted by user (Ctrl-C)")
        sys.exit(130)

 

Step 4. Make the script executable

chmod +x /tmp/slapolicy_assignments_os6.py

 

Step 5. Run the "slapolicy_assignments_os6.py" script

./tmp/slapolicy_assignments_os6.py