Velocity • Durability

13. S3 Gateway

VDURA’s S3 gateway exposes tenant volumes over the S3 protocol. Configuration is split across five areas: per-tenant gateway config, realm-wide S3 administration (Platform Admin only), buckets, credential lookup, and the gateway instances themselves.

13.1 Tenant S3 Configuration

Endpoint Summary

Path Summary Method
/api/v1/tenants/{tenant_id}/s3 Get S3 config GET
/api/v1/tenants/{tenant_id}/s3 Create S3 config PUT
/api/v1/tenants/{tenant_id}/s3 Update S3 config PATCH
/api/v1/tenants/{tenant_id}/s3 Delete S3 config DELETE
/api/v1/tenants/{tenant_id}/s3/tls/renew Renew the realm-generated S3 edge cert POST

GET /api/v1/tenants/{tenant_id}/s3

Get S3 config

Returns the S3 gateway configuration for the specified tenant.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)

Responses

Status Description Schema
200 Successfully retrieved the S3 configuration for the tenant. GetS3ConfigResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 S3 configuration not found for this tenant. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (200, GetS3ConfigResponse)

Field Type Required Default Example Description
s3_config S3ConfigSchema object yes n/a Tenant S3 gateway configuration.

Example

{
   "s3_config" : {
      "default_dir_mode" : "755",
      "default_group" : "gid:65534",
      "default_obj_mode" : "644",
      "default_owner" : "uid:65534",
      "default_prefix" : "/vol1/t1",
      "enabled" : true,
      "tls" : {}
   }
}

PUT /api/v1/tenants/{tenant_id}/s3

Create S3 config

Creates the S3 gateway configuration for the specified tenant. 409 if a config already exists; callers needing replace semantics must DELETE first.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)

Request Body (application/json, required)

Schema: S3ConfigCreateRequest

Request payload for creating a tenant’s S3 configuration.

Every field carries a default, so PUT /s3 {} is a complete request: it creates the disabled config with the empty prefix and the POSIX defaults a tenant starts with. Those defaults live here rather than in a factory beside the service, because this is the only place that can publish them - an operator reading the API document sees what an omitted field will be, and there is no second copy to drift from it.

access_key, secret_key and control_plane have no field here at all; :mod:app.use_cases.create_s3_config mints all three.

Field Type Required Default Example Description
access_log boolean no true Whether the S3 access log is enabled for this tenant (the S3 gateway’s –access-log audit log). Defaults to true.
aggregator S3AggregatorConfigSchema object no n/a Tenant-level S3 aggregator policy (opt-in via enabled=true).
debug_log boolean no false Whether the S3 debug request log is enabled for this tenant. Defaults to false.
default_dir_mode string no 755 755, 0755 Default directory permission mode in octal (e.g. 755).
default_group string no gid:65534 gid:65534, gid:1000 Default POSIX group for objects (e.g. gid:65534). An fs-user created without a gid takes it. gid:65534 (nogroup) is the unset value; an empty string is not accepted.
default_obj_mode string no 644 644, 0644 Default object/file permission mode in octal (e.g. 644).
default_owner string no uid:65534 uid:65534, uid:1000 Default POSIX owner for objects (e.g. uid:65534). An fs-user created without a uid takes it. uid:65534 (nobody) is the unset value; an empty string is not accepted.
default_prefix string no (empty string) /vol1, /vol1/data Tenant-relative path served by S3 (e.g. /vol1 or /vol1/data). Must name an existing volume of the tenant (or a directory inside one); stored resolved into the tenant volume namespace. Optional: omit it to create the config before the tenant has a volume to serve. The empty value skips volume validation and cannot be enabled until a real prefix is set by PATCH.
dns S3DnsConfigSchema object no n/a DNS/named-access policy (default mode=off).
enabled boolean no false Whether S3 access is enabled for this tenant.
metrics_enabled boolean no true Whether S3 metrics are collected for this tenant (the S3 gateway’s StatsD counters to the node-local Telegraf listener). Defaults to true.
tls S3TlsConfigSchema object no n/a TLS configuration for the S3 gateway.

Example

{
   "aggregator" : {
      "enabled" : false
   },
   "default_dir_mode" : "755",
   "default_group" : "gid:65534",
   "default_obj_mode" : "644",
   "default_owner" : "uid:65534",
   "default_prefix" : "/vol1/t1",
   "enabled" : true,
   "tls" : {}
}

Responses

Status Description Schema
201 S3 configuration created successfully. -
400 Bad request: the S3 configuration is invalid for the requested state - enabling without a default_prefix, TLS material that fails validation for the resulting tls.mode, or a tenant short name and realm DNS zone too long to name a realm-generated edge cert. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant not found. -
409 S3 configuration already exists for this tenant. -
422 Validation Error HTTPValidationError
500 Internal server error. -
503 The realm key service could not be reached to sign the S3 edge cert; retry. -

PATCH /api/v1/tenants/{tenant_id}/s3

Update S3 config

Partially updates the S3 gateway configuration for the specified tenant. The response names the fields of this request that already-running gateway instances will not pick up until they are restarted - empty when every change is in effect now, which includes a tenant with no started instance.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)

Request Body (application/json, required)

Schema: S3ConfigPatchRequest

Request payload for partially updating a tenant’s S3 configuration.

At least one field must be provided. Null values are not allowed - omit fields that should not change.

Field Type Required Default Example Description
access_log boolean, nullable no null Whether the S3 access log is enabled for this tenant.
aggregator S3AggregatorConfigSchema object, nullable no null Tenant-level S3 aggregator policy (opt-in via enabled=true).
debug_log boolean, nullable no null Whether the S3 debug request log is enabled for this tenant.
default_dir_mode string, nullable no null Default directory permission mode in octal.
default_group string, nullable no null Default POSIX group for objects. To unset it, send gid:65534 (nogroup), the value a new config starts with; an empty string is not accepted.
default_obj_mode string, nullable no null Default object/file permission mode in octal.
default_owner string, nullable no null Default POSIX owner for objects. To unset it, send uid:65534 (nobody), the value a new config starts with; an empty string is not accepted.
default_prefix string, nullable no null Tenant-relative path served by S3. Must name an existing volume of the tenant (or a directory inside one); immutable while the tenant has S3 enabled.
dns S3DnsConfigSchema object, nullable no null DNS/named-access policy (mode off/panfs/external).
enabled boolean, nullable no null Whether S3 access is enabled for this tenant.
metrics_enabled boolean, nullable no null Whether S3 metrics are collected for this tenant.
tls S3TlsConfigSchema object, nullable no null TLS configuration for the S3 gateway.

Example

{
   "default_prefix" : "/vol1/t1",
   "enabled" : false
}

Responses

Status Description Schema
200 S3 configuration updated successfully. The body names the fields of this request that already-running gateway instances will not pick up until they are restarted; it is empty when every change is in effect now. S3ConfigUpdateResponse
400 Bad request: the S3 configuration is invalid for the requested state - enabling without a default_prefix, TLS material that fails validation for the resulting tls.mode, or a tenant short name and realm DNS zone too long to name a realm-generated edge cert. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 S3 configuration not found for this tenant. -
409 The request conflicts with the tenant S3 state: disabling while an instance is desired started, changing default_prefix while enabled, or deleting the config while any instance record exists. -
422 Validation Error HTTPValidationError
500 Internal server error. -
503 The realm key service could not be reached to sign the S3 edge cert; retry. -

Response Body (200, S3ConfigUpdateResponse)

Field Type Required Default Example Description
restart_required array of string yes n/a Names of S3 config fields this request changed whose new value reaches already-running S3 gateway instances only after those instances are restarted. Empty when every change is in effect now, when the request changed nothing, or when the tenant has no started instance. The set of names can change between releases.

Example

{
   "restart_required" : [
      "access_log",
      "debug_log"
   ]
}

DELETE /api/v1/tenants/{tenant_id}/s3

Delete S3 config

Deletes the S3 gateway configuration for the specified tenant.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)

Responses

Status Description Schema
204 S3 configuration deleted successfully. No content in response body. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 S3 configuration not found for this tenant. -
409 The request conflicts with the tenant S3 state: disabling while an instance is desired started, changing default_prefix while enabled, or deleting the config while any instance record exists. -
422 Validation Error HTTPValidationError
500 Internal server error. -

POST /api/v1/tenants/{tenant_id}/s3/tls/renew

Renew the realm-generated S3 edge cert

Forces a fresh mint of the tenant S3 edge certificate and stores it with the tenant’s S3 configuration. Manual operator action: renewal is not automated, so an operator runs this before the stored cert lapses. Valid only when tls.mode = realm-generated (the realm owns that cert); a tenant-provided cert is renewed by uploading a new one via PATCH /s3 and this returns 409. The minted SANs follow the tenant’s current aggregator.enabled state. Renewal disrupts nothing: a running gateway re-reads the cert and key without restarting. Authorization: gated on s3-config:update, like every other write to the tenant S3 config; the tenant admin and platform-admin both hold it.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)

Responses

Status Description Schema
204 S3 edge cert renewed and stored. No content in response body. -
400 The tenant short name and realm DNS zone are too long to name the edge cert. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 S3 configuration not found for this tenant. -
409 Tenant uses tls.mode=tenant-provided; upload a new cert instead. -
422 Validation Error HTTPValidationError
500 Internal server error. -
503 The realm key service could not be reached to sign the S3 edge cert; retry. -

13.2 Realm-Wide S3 Administration

Endpoint Summary

Path Summary Method
/api/v1/s3/enabled Get realm-wide S3 enable flag GET
/api/v1/s3/enabled Set realm-wide S3 enable flag PUT
/api/v1/s3/prefix Get realm-wide S3 prefix path GET
/api/v1/s3/prefix Set realm-wide S3 prefix path PUT

GET /api/v1/s3/enabled

Get realm-wide S3 enable flag

Returns the realm-wide S3 enable flag. Distinct from the per-tenant s3 enabled toggle on /api/v1/tenants/{id}/s3/; this flag gates provisioning of any new tenant-level S3 state. A fresh realm reports enabled=false until the operator opts in via PUT.

Authentication: required (PasswordLogin or BearerJWT).

Responses

Status Description Schema
200 Current realm-wide enable flag. S3EnabledResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
500 Internal server error. -

Response Body (200, S3EnabledResponse)

Field Type Required Default Example Description
enabled boolean yes n/a Realm-wide S3 enable flag.
tenants_with_s3_enabled array of string, nullable no null Tenant short names that still have tenant-level S3 enabled after the realm-wide disable. Absent on get and on enable.
warning string, nullable no null Warning surfaced when realm-disable leaves tenants with S3 enabled.

Example

{
   "enabled" : false,
   "tenants_with_s3_enabled" : [
      "tn1"
   ],
   "warning" : "1 tenant(s) still have S3 enabled at the tenant level"
}

PUT /api/v1/s3/enabled

Set realm-wide S3 enable flag

Sets the realm-wide S3 enable flag. A successful write takes effect on every node: turning S3 off stops every running S3 gateway instance; turning it back on re-applies per-tenant intent and brings the gateways back up. Per-tenant enabled records are preserved across both transitions. Disabling while at least one tenant has tenant-level S3 enabled is permitted but surfaces a warning listing the still-enabled tenants in the response.

Authentication: required (PasswordLogin or BearerJWT).

Request Body (application/json, required)

Schema: S3EnabledRequest

Request body for PUT /s3/enabled.

Field Type Required Default Example Description
enabled boolean yes n/a Realm-wide S3 enable flag.

Example

{
   "enabled" : true
}

Responses

Status Description Schema
200 Realm-wide enable flag updated. S3EnabledResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (200, S3EnabledResponse)

Field Type Required Default Example Description
enabled boolean yes n/a Realm-wide S3 enable flag.
tenants_with_s3_enabled array of string, nullable no null Tenant short names that still have tenant-level S3 enabled after the realm-wide disable. Absent on get and on enable.
warning string, nullable no null Warning surfaced when realm-disable leaves tenants with S3 enabled.

Example

{
   "enabled" : false,
   "tenants_with_s3_enabled" : [
      "tn1"
   ],
   "warning" : "1 tenant(s) still have S3 enabled at the tenant level"
}

GET /api/v1/s3/prefix

Get realm-wide S3 prefix path

Returns the realm-wide S3 prefix path that anchors per-tenant prefixes under a common root. Distinct from the per-tenant default_prefix carried on /api/v1/tenants/{id}/s3/. A fresh realm reports the empty string until the operator sets a value.

Authentication: required (PasswordLogin or BearerJWT).

Responses

Status Description Schema
200 Current realm-wide prefix. S3PrefixResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
500 Internal server error. -

Response Body (200, S3PrefixResponse)

Field Type Required Default Example Description
prefix string yes n/a Current realm-wide path prefix.

Example

{
   "prefix" : "/realm-root"
}

PUT /api/v1/s3/prefix

Set realm-wide S3 prefix path

Sets the realm-wide S3 prefix path. Non-empty values MUST begin with “/” and MUST NOT carry trailing whitespace. An empty string clears the prefix.

Authentication: required (PasswordLogin or BearerJWT).

Request Body (application/json, required)

Schema: S3PrefixRequest

Request body for PUT /s3/prefix.

Field Type Required Default Example Description
prefix string yes n/a Realm-wide POSIX-style path prefix. Empty string means “no realm-wide prefix”; otherwise the value MUST begin with “/” and MUST NOT contain trailing whitespace.

Example

{
   "prefix" : "/realm-root"
}

Responses

Status Description Schema
200 Realm-wide prefix updated. S3PrefixResponse
400 Invalid prefix (missing leading “/” or trailing whitespace). -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (200, S3PrefixResponse)

Field Type Required Default Example Description
prefix string yes n/a Current realm-wide path prefix.

Example

{
   "prefix" : "/realm-root"
}

13.3 S3 Buckets

Endpoint Summary

Path Summary Method
/api/v1/tenants/{tenant_id}/s3/buckets List S3 buckets GET
/api/v1/tenants/{tenant_id}/s3/buckets Create S3 bucket POST
/api/v1/tenants/{tenant_id}/s3/buckets/{name} Delete S3 bucket DELETE

GET /api/v1/tenants/{tenant_id}/s3/buckets

List S3 buckets

List the tenant’s S3 buckets, as a running gateway reports them.

The gateway is the only bucket catalogue, so a tenant with no running instance cannot be listed: that is a 503, never an empty list.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)

Responses

Status Description Schema
200 The buckets a running S3 gateway holds for the tenant. ListS3BucketsResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant not found. -
422 Validation Error HTTPValidationError
500 Internal server error. -
503 No running S3 instance could answer, and nothing was performed. The response detail names which case applies and the panctl command that resolves it. -

Response Body (200, ListS3BucketsResponse)

Field Type Required Default Example Description
s3_buckets array of S3BucketSchema object yes n/a List of S3 buckets.

POST /api/v1/tenants/{tenant_id}/s3/buckets

Create S3 bucket

Create an S3 bucket on a running gateway, owned by the PanFS user the request names.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)

Request Body (application/json, required)

Schema: S3BucketCreateRequest

Request payload for creating an S3 bucket.

Field Type Required Default Example Description
name string yes n/a Bucket name.
owner string yes n/a S3 access_key of the PanFS user the bucket belongs to. Required, and must name a PanFS user in this tenant: the gateway resolves the owner through its IAM backend, so a value that is not a PanFS user cannot be resolved there at all.

Example

{
   "name" : "my-bucket",
   "owner" : "alice"
}

Responses

Status Description Schema
201 S3 bucket created on a running gateway. -
400 The S3 gateway refused the operation - most often a bucket name outside the gateway-enforced AWS rules (3-63 characters, lowercase, DNS-shaped, not an IP address). -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant not found. -
409 S3 bucket already exists. -
422 Validation Error HTTPValidationError
500 Internal server error. -
503 No running S3 instance could answer, and nothing was performed. The response detail names which case applies and the panctl command that resolves it. -
504 No running S3 instance confirmed the create, and the bucket may exist. List the buckets to check. -

DELETE /api/v1/tenants/{tenant_id}/s3/buckets/{name}

Delete S3 bucket

Delete an S3 bucket from a running gateway.

A non-empty bucket returns 409 and stays listed. A bucket the gateway does not hold is a 404, unless an earlier attempt of this same request may have deleted it.

Authorization is the s3-buckets:delete verb plus caller-tenant scoping, like every other operation on this surface. Deletion is NOT conditioned on the caller having created the bucket.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)
name path string yes S3 bucket name

Responses

Status Description Schema
204 S3 bucket deleted from a running gateway. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant not found, or S3 bucket not found on the gateway. -
409 S3 bucket still holds objects; empty it over the S3 API before deleting. -
422 Validation Error HTTPValidationError
500 Internal server error. -
503 No running S3 instance could answer, and nothing was performed. The response detail names which case applies and the panctl command that resolves it. -
504 No running S3 instance confirmed the delete, and the bucket may have been deleted. List the buckets to check. -

13.4 S3 Credentials

Endpoint Summary

Path Summary Method
/api/v1/tenants/{tenant_id}/s3-credentials/{access_key}/reveal Resolve an S3 access key to the identity behind it POST

POST /api/v1/tenants/{tenant_id}/s3-credentials/{access_key}/reveal

Resolve an S3 access key to the identity behind it

Return the credential behind an access key, with the profile and POSIX ids that go with it - everything an auth.Account needs, because the access key is the only handle the data plane holds and a second lookup would cost a round trip per IAM cache miss. Called by the S3 gateway on that miss, through POST /s3/gateway/s3-credentials/{access_key}/reveal, and gated on fs-users:read-s3-secret. A disabled user answers 404, which the gateway maps to its no-such-user error.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID).
access_key path string yes S3 access key

Responses

Status Description Schema
200 Credential and identity returned. S3CredentialsRevealResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 No PanFS user owns this access key in this tenant, or that user is disabled. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (200, S3CredentialsRevealResponse)

Field Type Required Default Example Description
access_key string yes n/a The access key that was resolved.
gid integer yes n/a POSIX group id objects written by this user are owned by.
profile S3Profile (disabled, user, privileged) yes n/a S3 access profile. The gateway maps it to a role: privileged carries bucket-creation rights, anything else is an ordinary user.
secret_key string yes n/a Plaintext S3 secret key.
uid integer yes n/a POSIX user id objects written by this user are owned by.

Example

{
   "access_key" : "alice",
   "gid" : 65534,
   "profile" : "user",
   "secret_key" : "7f9a3d2e8c1b4a6f0d5e2c8b9f1a3d7e",
   "uid" : 65534
}

13.5 S3 Gateway Instances

Endpoint Summary

Path Summary Method
/api/v1/tenants/{tenant_id}/s3/instances List a tenant’s S3 gateway instances GET
/api/v1/tenants/{tenant_id}/s3/instances Create an S3 gateway instance POST
/api/v1/tenants/{tenant_id}/s3/instances/delete-all Delete every instance of the tenant and wait for teardown POST
/api/v1/tenants/{tenant_id}/s3/instances/start-all Start every instance of the tenant POST
/api/v1/tenants/{tenant_id}/s3/instances/stop-all Stop every instance of the tenant POST
/api/v1/tenants/{tenant_id}/s3/instances/{iid} Show an S3 gateway instance (bare-iid fan-out or specific node) GET
/api/v1/tenants/{tenant_id}/s3/instances/{iid} Delete an S3 gateway instance (fan-out if node omitted; requires confirm) DELETE
/api/v1/tenants/{tenant_id}/s3/instances/{iid}/start Start an S3 gateway instance (fan-out if node omitted) POST
/api/v1/tenants/{tenant_id}/s3/instances/{iid}/stop Stop an S3 gateway instance (fan-out if node omitted) POST

GET /api/v1/tenants/{tenant_id}/s3/instances

List a tenant’s S3 gateway instances

Return every instance of the tenant with its observed/health merged in.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)

Responses

Status Description Schema
200 List of merged desired + observed instance views. S3InstanceListResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant not found. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (200, S3InstanceListResponse)

Field Type Required Default Example Description
instances array of S3InstanceViewSchema object yes n/a

POST /api/v1/tenants/{tenant_id}/s3/instances

Create an S3 gateway instance

Writes the desired-state record for a new S3 gateway instance placed on the specified node. The instance starts in desired=created; use the start endpoint to bring it online. At most one instance per tenant per node, and the tenant must have a subnet: the gateway binds inside the tenant network namespace, which a tenant with no subnet does not have.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)

Request Body (application/json, required)

Schema: S3InstanceCreateRequest

Create a new S3 gateway instance for a tenant on a specific node.

Field Type Required Default Example Description
dataserial string yes n/a Target node’s dataserial (14 hex chars) as returned by GET /nodes and consumed by every /nodes/{dataserial} endpoint (e.g. 08823f71a1eecc). The stable placement identity - unaffected by node renames.
instance_id string yes n/a Instance identifier: exactly 5 alphanumeric characters (D10).

Example

{
   "dataserial" : "08823f71a1eecc",
   "instance_id" : "abc12"
}

Responses

Status Description Schema
201 Instance created. S3InstanceCreateResponse
400 Invalid iid format or unknown dataserial. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant not found. -
409 Instance already exists at (iid, dataserial), the tenant already has an instance on that node, or the tenant has no subnet. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (201, S3InstanceCreateResponse)

Field Type Required Default Example Description
instance S3InstanceSchema object yes n/a Desired-state view of an S3 gateway instance.

POST /api/v1/tenants/{tenant_id}/s3/instances/delete-all

Delete every instance of the tenant and wait for teardown

Fan out desired=deleting to every (iid, data_serial) owned by the tenant and block until the owning node has removed each instance record, which is the terminal state, or until timeout seconds elapse. Intended as the companion to the DELETE /api/v1/tenants/{id} guard: an operator runs delete-all first, waits for it to succeed, then deletes the tenant.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)
timeout query integer no Upper bound in seconds on the blocking wait for instance teardown.

Responses

Status Description Schema
200 Every instance torn down; no rows remain. results lists what each pass recorded on each node (202 once recorded), so a node retried by a later pass appears more than once. S3InstanceFanoutResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant not found. -
409 Timed out waiting for teardown; see error body. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (200, S3InstanceFanoutResponse)

Field Type Required Default Example Description
aggregate_status integer yes n/a Aggregate HTTP status: the rows’ shared success code (202 for a recorded state change, 200 for a read) if every node succeeded, the shared error code if every node failed with the same code, otherwise 207. delete-all answers 200 once every instance is gone, and start-all/stop-all answer 200 with no results for a tenant with no instances.
confirmed boolean no true For delete fan-out, true once the caller has confirmed the destructive operation. When false, the request body enumerates matches without deleting anything.
results array of S3InstancePerNodeResult object yes n/a

POST /api/v1/tenants/{tenant_id}/s3/instances/start-all

Start every instance of the tenant

Records the new desired state of every instance of the tenant and returns without waiting for them to reach it. Poll GET /tenants/{tenant_id}/s3/instances for the observed state.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)

Responses

Status Description Schema
200 The tenant has no instances; nothing was recorded. -
202 Recorded on every instance. S3InstanceFanoutResponse
207 Partial success; see per-node results. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant not found. -
409 Every target refused: S3 is disabled for the tenant, the target’s node has its S3 service stopped, or the instance is being deleted (desired=deleting). -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (202, S3InstanceFanoutResponse)

Field Type Required Default Example Description
aggregate_status integer yes n/a Aggregate HTTP status: the rows’ shared success code (202 for a recorded state change, 200 for a read) if every node succeeded, the shared error code if every node failed with the same code, otherwise 207. delete-all answers 200 once every instance is gone, and start-all/stop-all answer 200 with no results for a tenant with no instances.
confirmed boolean no true For delete fan-out, true once the caller has confirmed the destructive operation. When false, the request body enumerates matches without deleting anything.
results array of S3InstancePerNodeResult object yes n/a

POST /api/v1/tenants/{tenant_id}/s3/instances/stop-all

Stop every instance of the tenant

Records the new desired state of every instance of the tenant and returns without waiting for them to reach it. Poll GET /tenants/{tenant_id}/s3/instances for the observed state.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)

Responses

Status Description Schema
200 The tenant has no instances; nothing was recorded. -
202 Recorded on every instance. S3InstanceFanoutResponse
207 Partial success; see per-node results. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 Tenant not found. -
409 Every instance is being deleted (desired=deleting) and cannot be stopped. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (202, S3InstanceFanoutResponse)

Field Type Required Default Example Description
aggregate_status integer yes n/a Aggregate HTTP status: the rows’ shared success code (202 for a recorded state change, 200 for a read) if every node succeeded, the shared error code if every node failed with the same code, otherwise 207. delete-all answers 200 once every instance is gone, and start-all/stop-all answer 200 with no results for a tenant with no instances.
confirmed boolean no true For delete fan-out, true once the caller has confirmed the destructive operation. When false, the request body enumerates matches without deleting anything.
results array of S3InstancePerNodeResult object yes n/a

GET /api/v1/tenants/{tenant_id}/s3/instances/{iid}

Show an S3 gateway instance (bare-iid fan-out or specific node)

Return one or many matching rows as a per-node result set.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)
iid path string yes Instance identifier: exactly 5 alphanumeric characters.
dataserial query string, nullable no Optional target node dataserial; without it, fan out over every matching (iid, data_serial).

Responses

Status Description Schema
200 One entry in results per matching node. S3InstanceFanoutResponse
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 No matching instance for this iid under the tenant. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (200, S3InstanceFanoutResponse)

Field Type Required Default Example Description
aggregate_status integer yes n/a Aggregate HTTP status: the rows’ shared success code (202 for a recorded state change, 200 for a read) if every node succeeded, the shared error code if every node failed with the same code, otherwise 207. delete-all answers 200 once every instance is gone, and start-all/stop-all answer 200 with no results for a tenant with no instances.
confirmed boolean no true For delete fan-out, true once the caller has confirmed the destructive operation. When false, the request body enumerates matches without deleting anything.
results array of S3InstancePerNodeResult object yes n/a

DELETE /api/v1/tenants/{tenant_id}/s3/instances/{iid}

Delete an S3 gateway instance (fan-out if node omitted; requires confirm)

If dataserial is omitted and more than one node hosts a matching iid, confirm=true is required; otherwise the API returns 409 and a preview body listing the matches, so the caller can decide whether to proceed.

Records the delete and returns without waiting for the instance to be removed. Poll GET /tenants/{tenant_id}/s3/instances/{iid} until it answers 404: the instance is gone. If the delete named a dataserial, poll with the same dataserial: without it the GET still answers for the placements on other nodes.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)
iid path string yes Instance identifier: exactly 5 alphanumeric characters.
dataserial query string, nullable no Optional target node dataserial.
confirm query boolean no Required (true) when dataserial is omitted and multiple instances match - prevents destructive fan-out without explicit opt-in.

Responses

Status Description Schema
202 Recorded on every target. S3InstanceFanoutResponse
207 Partial success; see per-node results. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 No matching instance. -
409 Destructive fan-out without confirm=true; body lists matches. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (202, S3InstanceFanoutResponse)

Field Type Required Default Example Description
aggregate_status integer yes n/a Aggregate HTTP status: the rows’ shared success code (202 for a recorded state change, 200 for a read) if every node succeeded, the shared error code if every node failed with the same code, otherwise 207. delete-all answers 200 once every instance is gone, and start-all/stop-all answer 200 with no results for a tenant with no instances.
confirmed boolean no true For delete fan-out, true once the caller has confirmed the destructive operation. When false, the request body enumerates matches without deleting anything.
results array of S3InstancePerNodeResult object yes n/a

POST /api/v1/tenants/{tenant_id}/s3/instances/{iid}/start

Start an S3 gateway instance (fan-out if node omitted)

Records the new desired state and returns without waiting for the instance to reach it. Poll GET /tenants/{tenant_id}/s3/instances/{iid} for the observed state.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)
iid path string yes Instance identifier: exactly 5 alphanumeric characters.
dataserial query string, nullable no Optional target node dataserial.

Responses

Status Description Schema
202 Recorded on every target. S3InstanceFanoutResponse
207 Mixed success; see per-node results. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 No matching instance. -
409 Every target refused: S3 is disabled for the tenant, the target’s node has its S3 service stopped, or the instance is being deleted (desired=deleting). -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (202, S3InstanceFanoutResponse)

Field Type Required Default Example Description
aggregate_status integer yes n/a Aggregate HTTP status: the rows’ shared success code (202 for a recorded state change, 200 for a read) if every node succeeded, the shared error code if every node failed with the same code, otherwise 207. delete-all answers 200 once every instance is gone, and start-all/stop-all answer 200 with no results for a tenant with no instances.
confirmed boolean no true For delete fan-out, true once the caller has confirmed the destructive operation. When false, the request body enumerates matches without deleting anything.
results array of S3InstancePerNodeResult object yes n/a

POST /api/v1/tenants/{tenant_id}/s3/instances/{iid}/stop

Stop an S3 gateway instance (fan-out if node omitted)

Records the new desired state and returns without waiting for the instance to reach it. Poll GET /tenants/{tenant_id}/s3/instances/{iid} for the observed state.

Authentication: required (PasswordLogin or BearerJWT).

Parameters

Name In Type Required Description
tenant_id path string (uuid) yes Tenant identifier (UUID)
iid path string yes Instance identifier: exactly 5 alphanumeric characters.
dataserial query string, nullable no Optional target node dataserial.

Responses

Status Description Schema
202 Recorded on every target. S3InstanceFanoutResponse
207 Mixed success; see per-node results. -
401 Unauthorized. Authentication required. -
403 Forbidden. Insufficient permissions. -
404 No matching instance. -
409 Every target is being deleted (desired=deleting) and cannot be stopped. -
422 Validation Error HTTPValidationError
500 Internal server error. -

Response Body (202, S3InstanceFanoutResponse)

Field Type Required Default Example Description
aggregate_status integer yes n/a Aggregate HTTP status: the rows’ shared success code (202 for a recorded state change, 200 for a read) if every node succeeded, the shared error code if every node failed with the same code, otherwise 207. delete-all answers 200 once every instance is gone, and start-all/stop-all answer 200 with no results for a tenant with no instances.
confirmed boolean no true For delete fan-out, true once the caller has confirmed the destructive operation. When false, the request body enumerates matches without deleting anything.
results array of S3InstancePerNodeResult object yes n/a