Trilio Share Protectionfor OpenStack File Shares
API reference

API Reference

REST API and Python client bindings


Description

The Abacá REST API is a Keystone-authenticated HTTP service versioned at /v1 that lets tenants and operators manage every aspect of Manila share protection: registering S3 backup targets, defining protection policies, triggering on-demand backups, requesting restores, and inspecting job progress. Operators additionally have access to admin-scoped endpoints that expose cross-tenant job administration, worker fleet lifecycle management, scheduler control, reconciliation triggers, and protection-coverage reporting. All asynchronous operations return a 202 Accepted with a Job resource that you poll to track progress through the job state machine.


Parameters

Most collection endpoints accept the following common query parameters.

ParameterTypeRequiredDescription
limitinteger (1–1000)NoMaximum number of items to return. Server default is 100; hard maximum is 1000. Controlled by the api.default_limit and api.max_limit config options.
markerstring (UUID)NoPagination cursor. Pass the next_marker value from a previous response to retrieve the next page. When next_marker is null there are no more pages.

Path parameters vary by resource and are described in each resource section below. All write operations accept a JSON body (Content-Type: application/json).


Returns

Every successful response carries one of the following shapes.

Single resource — a JSON object whose fields match the schema for that resource (see Resource schemas).

Paginated collection — a JSON object with two top-level keys:

{
  "items": [ … ],
  "pagination": {
    "count": 42,
    "limit": 100,
    "next_marker": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
  }
}

next_marker is null when you have reached the last page.

Accepted action202 Accepted with no body (or, for backup creation, with a Backup object). Poll the returned Job resource for completion.

Deleted204 No Content with no body.

Error responses always use the Error schema (see Error responses).


Errors

Every error response body conforms to the Error schema:

{
  "code": "policy_not_found",
  "title": "Policy not found",
  "detail": "No policy with id 'abc…' exists in this project.",
  "category": "tenant_action_required"
}
FieldTypeDescription
codestringMachine-readable error identifier.
titlestringShort human-readable summary.
detailstringFull explanation, including remediation hints where possible.
categoryenumtenant_action_required — the tenant must act (e.g., invalid credentials, missing resource). operator_action_required — the operator must act (e.g., no worker fleet available).

Common HTTP status codes and when they occur:

StatusMeaning
400 Bad RequestMalformed JSON, missing required field, or a field value that violates a schema constraint.
401 UnauthorizedNo X-Auth-Token header, or the token has expired. Obtain a fresh Keystone token.
403 ForbiddenThe authenticated user lacks the required oslo.policy role for this operation.
404 Not FoundThe addressed resource does not exist or is not visible to this project.
409 ConflictThe operation is not valid for the resource's current state (e.g., cancelling an already-terminal job, or enrolling a bucket that is already enrolling).

Examples

Authentication

All requests require a Keystone token in the X-Auth-Token header. Obtain one with the OpenStack CLI or directly from Keystone:

# Using the OpenStack CLI (recommended)
export OS_CLOUD=mycloud
TOKEN=$(openstack token issue -f value -c id)

curl -s -H "X-Auth-Token: $TOKEN" \
     https://abaca.example.com/v1/policies

The API base URL is registered in the Keystone service catalog under the share-protection catalog type (configurable via DEFAULT.catalog_type). Discover it with:

openstack catalog show share-protection

List protection policies

Retrieve all policies visible to the current project, with pagination:

curl -s -H "X-Auth-Token: $TOKEN" \
     "https://abaca.example.com/v1/policies?limit=2"
{
  "items": [
    {
      "id": "1a2b3c4d-0000-0000-0000-000000000001",
      "name": "daily-gold",
      "share_id": "share-uuid-aaa",
      "target_template_id": "tmpl-uuid-bbb",
      "schedule": "0 2 * * *",
      "retention": { "keep_last": 7 },
      "enabled": true,
      "max_retries": 0
    }
  ],
  "pagination": {
    "count": 1,
    "limit": 2,
    "next_marker": null
  }
}

OpenStack CLI equivalent:

openstack share protection policy list

Create an on-demand backup

POST /v1/backups accepts a JSON body identifying the share and (optionally) whether to force a crash-consistent backup:

curl -s -X POST \
     -H "X-Auth-Token: $TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"share_id": "share-uuid-aaa", "crash_consistent": false}' \
     https://abaca.example.com/v1/backups
{
  "id": "bkp-uuid-ccc",
  "share_id": "share-uuid-aaa",
  "target_bucket_id": "bucket-uuid-ddd",
  "kopia_snapshot_id": null,
  "crash_consistent": false,
  "status": "queued"
}

The status field reflects the Job state machine. Poll GET /v1/jobs/{job_id} (returned in the Location response header) until state is available or error.

OpenStack CLI equivalent:

openstack share protection backup create --share share-uuid-aaa

Poll a job

curl -s -H "X-Auth-Token: $TOKEN" \
     https://abaca.example.com/v1/jobs/job-uuid-eee
{
  "id": "job-uuid-eee",
  "job_type": "backup",
  "state": "transferring",
  "progress": 42
}

The state field walks through: queuedprovisioning_networkprovisioning_sourceconnecting_repositorytransferringfinalizingreleasingavailable (or error).


Restore a share from backup

POST /v1/restores creates a restore job. Choose mode: new_share to restore into a fresh Manila share, or in_place to overwrite the existing share's contents. Optionally specify sub_path to restore only a directory subtree or single file:

curl -s -X POST \
     -H "X-Auth-Token: $TOKEN" \
     -H "Content-Type: application/json" \
     -d '{
           "backup_id": "bkp-uuid-ccc",
           "mode": "new_share",
           "sub_path": null,
           "force": false
         }' \
     https://abaca.example.com/v1/restores
{
  "id": "rst-uuid-fff",
  "backup_id": "bkp-uuid-ccc",
  "mode": "new_share",
  "sub_path": null,
  "force": false,
  "status": "queued"
}

OpenStack CLI equivalent:

openstack share protection restore create \
    --backup bkp-uuid-ccc \
    --mode new_share

Admin: list all workers in the fleet

Admin endpoints require a token scoped to a user with the operator-level policy role:

curl -s -H "X-Auth-Token: $ADMIN_TOKEN" \
     https://abaca.example.com/v1/admin/workers
{
  "items": [
    { "id": "wkr-uuid-ggg", "hostname": "abaca-worker-ggg", "state": "ready" },
    { "id": "wkr-uuid-hhh", "hostname": "abaca-worker-hhh", "state": "draining" }
  ],
  "pagination": { "count": 2, "limit": 100, "next_marker": null }
}

Admin: drain and retire a worker

Draining marks a worker so it receives no new jobs; retiring removes it from the fleet after it finishes current work:

# Drain first
curl -s -X POST \
     -H "X-Auth-Token: $ADMIN_TOKEN" \
     https://abaca.example.com/v1/admin/workers/wkr-uuid-hhh/drain

# Then retire once drained
curl -s -X POST \
     -H "X-Auth-Token: $ADMIN_TOKEN" \
     https://abaca.example.com/v1/admin/workers/wkr-uuid-hhh/retire

Both return 202 Accepted. A 409 Conflict is returned if the transition is invalid for the worker's current state (e.g., retiring a worker that still has running jobs and has not been drained).


Admin: pause and resume the scheduler

Use pause before maintenance windows to prevent new policy-driven backups from being queued:

curl -s -X POST \
     -H "X-Auth-Token: $ADMIN_TOKEN" \
     https://abaca.example.com/v1/admin/scheduling/pause

# … perform maintenance …

curl -s -X POST \
     -H "X-Auth-Token: $ADMIN_TOKEN" \
     https://abaca.example.com/v1/admin/scheduling/resume

Admin: trigger reconciliation

Force the conductor's reconciliation sweep immediately rather than waiting for the next conductor.reconciliation_interval:

curl -s -X POST \
     -H "X-Auth-Token: $ADMIN_TOKEN" \
     https://abaca.example.com/v1/admin/reconciliation/trigger

Python client library example

The python-abacaclient package exposes a thin SDK. Use it in scripts and automation that need programmatic access:

import openstack
from abacaclient import AbacaClient

conn = openstack.connect(cloud="mycloud")
client = AbacaClient(session=conn.session)

# List policies
policies = client.policies.list()
for p in policies:
    print(p.id, p.name, p.schedule)

# Trigger an on-demand backup
backup = client.backups.create(share_id="share-uuid-aaa")
print("Backup queued:", backup.id)

# Poll until terminal
import time
while True:
    job = client.jobs.get(backup.job_id)
    print(job.state, job.progress)
    if job.state in ("available", "error"):
        break
    time.sleep(5)

Notes

Base path and versioning

All endpoints documented here are served under the /v1 prefix. The full base URL is {catalog_endpoint}/v1. The service currently does not use microversion negotiation; version 0.1.0 is encoded in the OpenAPI specification (info.version).


Authentication and token scope

Acquire a Keystone token scoped to your project (openstack token issue) and pass it as X-Auth-Token. Requests without a valid token receive 401 Unauthorized. The api.noauth config option (false by default) is a development-only override — it is not available on production deployments.


Tenant vs. admin endpoints

Paths under /v1/admin/… require the operator-level oslo.policy role (see the policy reference). Tenant-facing paths (everything else) require only a project-scoped token with the appropriate tenant role. The precise default policy rules and how to override them with policy.yaml are documented in the Access control reference.


Asynchronous operations and the job state machine

Backup creation (POST /v1/backups), restore creation (POST /v1/restores), and target enrollment all return 202 Accepted immediately and proceed asynchronously. The returned resource's status field (and the linked Job object's state field) reflects the current position in the state machine:

queuedprovisioning_networkprovisioning_sourceconnecting_repositorytransferringfinalizingreleasingavailable | error

When state is error, inspect the Job's error fields — the category field tells you whether action is required from the tenant (tenant_action_required) or the operator (operator_action_required).


Pagination

All collection endpoints are paginated. The default page size is 100 items (controlled by api.default_limit); the maximum is 1000 (controlled by api.max_limit). Always check pagination.next_marker — a non-null value means more pages exist. Pass it as the marker query parameter on the next request.


Immutability of bucket_scheme

The bucket_scheme field on a TargetTemplate (per_project or shared) is immutable after creation. Changing it would re-point existing policies at a different Kopia repository and orphan all prior backups. If you need a different scheme, create a new template and migrate policies to it.


max_retries semantics on Policy

The max_retries field (0–10, default 0) controls how many times the conductor automatically retries a failed backup. A value of 0 means a single attempt; the conductor does not retry. Only failures that provably did not write a Kopia snapshot are retried — partial transfers are not retried automatically, because retrying after a partial transfer would write a second snapshot and could displace a restore point under the keep_* retention rules.


Secrets are never returned in API responses

Fields such as s3_access_key_ref, s3_secret_key_ref, kopia_key_ref, and kopia_key_trust_id on TargetBucket are Barbican secret hrefs — opaque references to secrets held in Barbican — not the secret values themselves. Abacá never stores or returns raw credentials in API responses.


project_id on TargetBucket

For templates with bucket_scheme: shared, the project_id field on a TargetBucket is null because the bucket is shared across all projects in the Domain. For per_project templates, project_id identifies the owning project.


Service catalog discovery

The catalog type registered for Abacá is share-protection (the value of DEFAULT.catalog_type). The endpoint type used for internal lookups defaults to publicURL (DEFAULT.endpoint_type). Discover the endpoint with:

openstack catalog show share-protection