1867 lines
45 KiB
YAML
1867 lines
45 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: AtlasOS Storage Controller API
|
|
description: |
|
|
REST API for managing ZFS storage, storage services (SMB/NFS/iSCSI), snapshots, and system configuration.
|
|
|
|
## Authentication
|
|
Most endpoints require authentication via JWT token. Include the token in the Authorization header:
|
|
```
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
## Roles
|
|
- **Administrator**: Full system access
|
|
- **Operator**: Storage and service operations
|
|
- **Viewer**: Read-only access
|
|
|
|
version: 1.0.0
|
|
contact:
|
|
name: AtlasOS Support
|
|
url: https://github.com/atlasos
|
|
|
|
servers:
|
|
- url: http://localhost:8080
|
|
description: Local development server
|
|
- url: https://atlas.example.com
|
|
description: Production server
|
|
|
|
tags:
|
|
- name: Authentication
|
|
description: User authentication and authorization
|
|
- name: Users
|
|
description: User management (Administrator only)
|
|
- name: ZFS
|
|
description: ZFS pool, dataset, and ZVOL management
|
|
- name: Snapshots
|
|
description: Snapshot management and policies
|
|
- name: Storage Services
|
|
description: SMB, NFS, and iSCSI service management
|
|
- name: Jobs
|
|
description: Background job management
|
|
- name: Audit
|
|
description: Audit log access
|
|
- name: System
|
|
description: System health and metrics
|
|
|
|
paths:
|
|
/api/v1/auth/login:
|
|
post:
|
|
tags:
|
|
- Authentication
|
|
summary: Authenticate user
|
|
description: Login with username and password to receive JWT token
|
|
operationId: login
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- username
|
|
- password
|
|
properties:
|
|
username:
|
|
type: string
|
|
example: admin
|
|
password:
|
|
type: string
|
|
format: password
|
|
example: admin
|
|
responses:
|
|
'200':
|
|
description: Login successful
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
token:
|
|
type: string
|
|
description: JWT token for authentication
|
|
user:
|
|
$ref: '#/components/schemas/User'
|
|
expires_in:
|
|
type: integer
|
|
description: Token expiration in seconds
|
|
example: 86400
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
|
|
/api/v1/auth/logout:
|
|
post:
|
|
tags:
|
|
- Authentication
|
|
summary: Logout user
|
|
description: Logout (client-side token removal for stateless JWT)
|
|
operationId: logout
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: Logout successful
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
example: logged out
|
|
|
|
/api/v1/users:
|
|
get:
|
|
tags:
|
|
- Users
|
|
summary: List users
|
|
description: List all users (requires authentication)
|
|
operationId: listUsers
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: List of users
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/User'
|
|
post:
|
|
tags:
|
|
- Users
|
|
summary: Create user
|
|
description: Create a new user (Administrator only)
|
|
operationId: createUser
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- username
|
|
- password
|
|
properties:
|
|
username:
|
|
type: string
|
|
email:
|
|
type: string
|
|
format: email
|
|
password:
|
|
type: string
|
|
format: password
|
|
role:
|
|
$ref: '#/components/schemas/Role'
|
|
responses:
|
|
'201':
|
|
description: User created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/User'
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'409':
|
|
$ref: '#/components/responses/Conflict'
|
|
|
|
/api/v1/users/{id}:
|
|
get:
|
|
tags:
|
|
- Users
|
|
summary: Get user
|
|
operationId: getUser
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/UserId'
|
|
responses:
|
|
'200':
|
|
description: User details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/User'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
put:
|
|
tags:
|
|
- Users
|
|
summary: Update user
|
|
description: Update user (Administrator only)
|
|
operationId: updateUser
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/UserId'
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
role:
|
|
$ref: '#/components/schemas/Role'
|
|
active:
|
|
type: boolean
|
|
responses:
|
|
'200':
|
|
description: User updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/User'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
delete:
|
|
tags:
|
|
- Users
|
|
summary: Delete user
|
|
description: Delete user (Administrator only, cannot delete yourself)
|
|
operationId: deleteUser
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- $ref: '#/components/parameters/UserId'
|
|
responses:
|
|
'200':
|
|
description: User deleted
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/api/v1/pools:
|
|
get:
|
|
tags:
|
|
- ZFS
|
|
summary: List ZFS pools
|
|
operationId: listPools
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: List of ZFS pools
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Pool'
|
|
post:
|
|
tags:
|
|
- ZFS
|
|
summary: Create ZFS pool
|
|
operationId: createPool
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- name
|
|
- vdevs
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: tank
|
|
vdevs:
|
|
type: array
|
|
items:
|
|
type: string
|
|
example: ["/dev/sdb", "/dev/sdc"]
|
|
options:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
responses:
|
|
'201':
|
|
description: Pool created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Pool'
|
|
|
|
/api/v1/pools/{name}:
|
|
get:
|
|
tags:
|
|
- ZFS
|
|
summary: Get pool details
|
|
operationId: getPool
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: name
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Pool details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Pool'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
delete:
|
|
tags:
|
|
- ZFS
|
|
summary: Delete pool
|
|
operationId: deletePool
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: name
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Pool deleted
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/api/v1/pools/{name}/scrub:
|
|
post:
|
|
tags:
|
|
- ZFS
|
|
summary: Scrub pool
|
|
operationId: scrubPool
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: name
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Scrub started
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
example: scrub started
|
|
|
|
/api/v1/datasets:
|
|
get:
|
|
tags:
|
|
- ZFS
|
|
summary: List datasets
|
|
operationId: listDatasets
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: pool
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Filter by pool name
|
|
responses:
|
|
'200':
|
|
description: List of datasets
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Dataset'
|
|
post:
|
|
tags:
|
|
- ZFS
|
|
summary: Create dataset
|
|
operationId: createDataset
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- name
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: tank/data
|
|
options:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
responses:
|
|
'201':
|
|
description: Dataset created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Dataset'
|
|
|
|
/api/v1/datasets/{name}:
|
|
get:
|
|
tags:
|
|
- ZFS
|
|
summary: Get dataset
|
|
operationId: getDataset
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: name
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Dataset details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Dataset'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
put:
|
|
tags:
|
|
- ZFS
|
|
summary: Update dataset
|
|
operationId: updateDataset
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: name
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
options:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Dataset updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Dataset'
|
|
delete:
|
|
tags:
|
|
- ZFS
|
|
summary: Delete dataset
|
|
operationId: deleteDataset
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: name
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Dataset deleted
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/api/v1/zvols:
|
|
get:
|
|
tags:
|
|
- ZFS
|
|
summary: List ZVOLs
|
|
operationId: listZVOLs
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: pool
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Filter by pool name
|
|
responses:
|
|
'200':
|
|
description: List of ZVOLs
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ZVOL'
|
|
post:
|
|
tags:
|
|
- ZFS
|
|
summary: Create ZVOL
|
|
operationId: createZVOL
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- name
|
|
- size
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: tank/block/vol1
|
|
size:
|
|
type: string
|
|
description: Size in human-readable format (e.g., "10G", "1T")
|
|
example: 10G
|
|
options:
|
|
type: object
|
|
additionalProperties:
|
|
type: string
|
|
responses:
|
|
'201':
|
|
description: ZVOL created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ZVOL'
|
|
|
|
/api/v1/zvols/{name}:
|
|
get:
|
|
tags:
|
|
- ZFS
|
|
summary: Get ZVOL
|
|
operationId: getZVOL
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: name
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: ZVOL details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ZVOL'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
delete:
|
|
tags:
|
|
- ZFS
|
|
summary: Delete ZVOL
|
|
operationId: deleteZVOL
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: name
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: ZVOL deleted
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/api/v1/snapshots:
|
|
get:
|
|
tags:
|
|
- Snapshots
|
|
summary: List snapshots
|
|
operationId: listSnapshots
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: dataset
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Filter by dataset name
|
|
responses:
|
|
'200':
|
|
description: List of snapshots
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Snapshot'
|
|
post:
|
|
tags:
|
|
- Snapshots
|
|
summary: Create snapshot
|
|
operationId: createSnapshot
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- dataset
|
|
- name
|
|
properties:
|
|
dataset:
|
|
type: string
|
|
example: tank/data
|
|
name:
|
|
type: string
|
|
example: manual-20241215
|
|
responses:
|
|
'201':
|
|
description: Snapshot created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Snapshot'
|
|
|
|
/api/v1/snapshots/{name}:
|
|
get:
|
|
tags:
|
|
- Snapshots
|
|
summary: Get snapshot
|
|
operationId: getSnapshot
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: name
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: Full snapshot name (dataset@snapshot)
|
|
responses:
|
|
'200':
|
|
description: Snapshot details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Snapshot'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
delete:
|
|
tags:
|
|
- Snapshots
|
|
summary: Delete snapshot
|
|
operationId: deleteSnapshot
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: name
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Snapshot deleted
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/api/v1/snapshot-policies:
|
|
get:
|
|
tags:
|
|
- Snapshots
|
|
summary: List snapshot policies
|
|
operationId: listSnapshotPolicies
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: List of snapshot policies
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/SnapshotPolicy'
|
|
post:
|
|
tags:
|
|
- Snapshots
|
|
summary: Create snapshot policy
|
|
operationId: createSnapshotPolicy
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SnapshotPolicy'
|
|
responses:
|
|
'201':
|
|
description: Policy created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SnapshotPolicy'
|
|
|
|
/api/v1/snapshot-policies/{dataset}:
|
|
get:
|
|
tags:
|
|
- Snapshots
|
|
summary: Get snapshot policy
|
|
operationId: getSnapshotPolicy
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: dataset
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Policy details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SnapshotPolicy'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
put:
|
|
tags:
|
|
- Snapshots
|
|
summary: Update snapshot policy
|
|
operationId: updateSnapshotPolicy
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: dataset
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SnapshotPolicy'
|
|
responses:
|
|
'200':
|
|
description: Policy updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SnapshotPolicy'
|
|
delete:
|
|
tags:
|
|
- Snapshots
|
|
summary: Delete snapshot policy
|
|
operationId: deleteSnapshotPolicy
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: dataset
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Policy deleted
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/api/v1/shares/smb:
|
|
get:
|
|
tags:
|
|
- Storage Services
|
|
summary: List SMB shares
|
|
operationId: listSMBShares
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: List of SMB shares
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/SMBShare'
|
|
post:
|
|
tags:
|
|
- Storage Services
|
|
summary: Create SMB share
|
|
operationId: createSMBShare
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- name
|
|
- dataset
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: data
|
|
path:
|
|
type: string
|
|
description: Mount point path (auto-filled from dataset if not provided)
|
|
dataset:
|
|
type: string
|
|
example: tank/data
|
|
description:
|
|
type: string
|
|
read_only:
|
|
type: boolean
|
|
default: false
|
|
guest_ok:
|
|
type: boolean
|
|
default: false
|
|
valid_users:
|
|
type: array
|
|
items:
|
|
type: string
|
|
responses:
|
|
'201':
|
|
description: Share created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SMBShare'
|
|
|
|
/api/v1/shares/smb/{id}:
|
|
get:
|
|
tags:
|
|
- Storage Services
|
|
summary: Get SMB share
|
|
operationId: getSMBShare
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Share details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SMBShare'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
put:
|
|
tags:
|
|
- Storage Services
|
|
summary: Update SMB share
|
|
operationId: updateSMBShare
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
description:
|
|
type: string
|
|
read_only:
|
|
type: boolean
|
|
guest_ok:
|
|
type: boolean
|
|
enabled:
|
|
type: boolean
|
|
valid_users:
|
|
type: array
|
|
items:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Share updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/SMBShare'
|
|
delete:
|
|
tags:
|
|
- Storage Services
|
|
summary: Delete SMB share
|
|
operationId: deleteSMBShare
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Share deleted
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/api/v1/exports/nfs:
|
|
get:
|
|
tags:
|
|
- Storage Services
|
|
summary: List NFS exports
|
|
operationId: listNFSExports
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: List of NFS exports
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/NFSExport'
|
|
post:
|
|
tags:
|
|
- Storage Services
|
|
summary: Create NFS export
|
|
operationId: createNFSExport
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- dataset
|
|
properties:
|
|
path:
|
|
type: string
|
|
description: Mount point path (auto-filled from dataset if not provided)
|
|
dataset:
|
|
type: string
|
|
example: tank/data
|
|
clients:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Allowed clients (CIDR or hostnames), default ["*"]
|
|
example: ["192.168.1.0/24"]
|
|
read_only:
|
|
type: boolean
|
|
default: false
|
|
root_squash:
|
|
type: boolean
|
|
default: true
|
|
responses:
|
|
'201':
|
|
description: Export created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/NFSExport'
|
|
|
|
/api/v1/exports/nfs/{id}:
|
|
get:
|
|
tags:
|
|
- Storage Services
|
|
summary: Get NFS export
|
|
operationId: getNFSExport
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Export details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/NFSExport'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
put:
|
|
tags:
|
|
- Storage Services
|
|
summary: Update NFS export
|
|
operationId: updateNFSExport
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
clients:
|
|
type: array
|
|
items:
|
|
type: string
|
|
read_only:
|
|
type: boolean
|
|
root_squash:
|
|
type: boolean
|
|
enabled:
|
|
type: boolean
|
|
responses:
|
|
'200':
|
|
description: Export updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/NFSExport'
|
|
delete:
|
|
tags:
|
|
- Storage Services
|
|
summary: Delete NFS export
|
|
operationId: deleteNFSExport
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Export deleted
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/api/v1/iscsi/targets:
|
|
get:
|
|
tags:
|
|
- Storage Services
|
|
summary: List iSCSI targets
|
|
operationId: listISCSITargets
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: List of iSCSI targets
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ISCSITarget'
|
|
post:
|
|
tags:
|
|
- Storage Services
|
|
summary: Create iSCSI target
|
|
operationId: createISCSITarget
|
|
security:
|
|
- bearerAuth: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- iqn
|
|
properties:
|
|
iqn:
|
|
type: string
|
|
description: iSCSI Qualified Name
|
|
example: iqn.2024-12.com.atlas:storage.target1
|
|
initiators:
|
|
type: array
|
|
items:
|
|
type: string
|
|
description: Allowed initiator IQNs
|
|
responses:
|
|
'201':
|
|
description: Target created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ISCSITarget'
|
|
|
|
/api/v1/iscsi/targets/{id}:
|
|
get:
|
|
tags:
|
|
- Storage Services
|
|
summary: Get iSCSI target
|
|
operationId: getISCSITarget
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Target details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ISCSITarget'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
put:
|
|
tags:
|
|
- Storage Services
|
|
summary: Update iSCSI target
|
|
operationId: updateISCSITarget
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
initiators:
|
|
type: array
|
|
items:
|
|
type: string
|
|
enabled:
|
|
type: boolean
|
|
responses:
|
|
'200':
|
|
description: Target updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ISCSITarget'
|
|
delete:
|
|
tags:
|
|
- Storage Services
|
|
summary: Delete iSCSI target
|
|
operationId: deleteISCSITarget
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Target deleted
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/api/v1/iscsi/targets/{id}/luns:
|
|
post:
|
|
tags:
|
|
- Storage Services
|
|
summary: Add LUN to target
|
|
operationId: addLUN
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- zvol
|
|
properties:
|
|
zvol:
|
|
type: string
|
|
example: tank/block/vol1
|
|
responses:
|
|
'201':
|
|
description: LUN added
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/LUN'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
$ref: '#/components/responses/Conflict'
|
|
|
|
/api/v1/iscsi/targets/{id}/luns/remove:
|
|
post:
|
|
tags:
|
|
- Storage Services
|
|
summary: Remove LUN from target
|
|
operationId: removeLUN
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- lun_id
|
|
properties:
|
|
lun_id:
|
|
type: integer
|
|
example: 0
|
|
responses:
|
|
'200':
|
|
description: LUN removed
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/api/v1/jobs:
|
|
get:
|
|
tags:
|
|
- Jobs
|
|
summary: List jobs
|
|
operationId: listJobs
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: status
|
|
in: query
|
|
schema:
|
|
$ref: '#/components/schemas/JobStatus'
|
|
description: Filter by job status
|
|
responses:
|
|
'200':
|
|
description: List of jobs
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Job'
|
|
|
|
/api/v1/jobs/{id}:
|
|
get:
|
|
tags:
|
|
- Jobs
|
|
summary: Get job
|
|
operationId: getJob
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Job details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Job'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/api/v1/jobs/{id}/cancel:
|
|
post:
|
|
tags:
|
|
- Jobs
|
|
summary: Cancel job
|
|
operationId: cancelJob
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
'200':
|
|
description: Job cancelled
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
|
|
/api/v1/audit:
|
|
get:
|
|
tags:
|
|
- Audit
|
|
summary: List audit logs
|
|
operationId: listAuditLogs
|
|
security:
|
|
- bearerAuth: []
|
|
parameters:
|
|
- name: actor
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Filter by actor (user ID)
|
|
- name: action
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Filter by action (e.g., "pools.create")
|
|
- name: resource
|
|
in: query
|
|
schema:
|
|
type: string
|
|
description: Filter by resource
|
|
- name: limit
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
default: 100
|
|
description: Limit number of results
|
|
responses:
|
|
'200':
|
|
description: List of audit logs
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/AuditLog'
|
|
|
|
/api/v1/dashboard:
|
|
get:
|
|
tags:
|
|
- System
|
|
summary: Get dashboard data
|
|
operationId: getDashboard
|
|
security:
|
|
- bearerAuth: []
|
|
responses:
|
|
'200':
|
|
description: Dashboard statistics
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
storage:
|
|
type: object
|
|
properties:
|
|
total_capacity:
|
|
type: integer
|
|
format: int64
|
|
pool_count:
|
|
type: integer
|
|
dataset_count:
|
|
type: integer
|
|
zvol_count:
|
|
type: integer
|
|
snapshot_count:
|
|
type: integer
|
|
services:
|
|
type: object
|
|
properties:
|
|
smb_shares:
|
|
type: integer
|
|
nfs_exports:
|
|
type: integer
|
|
iscsi_targets:
|
|
type: integer
|
|
smb_status:
|
|
type: boolean
|
|
nfs_status:
|
|
type: boolean
|
|
iscsi_status:
|
|
type: boolean
|
|
jobs:
|
|
type: object
|
|
properties:
|
|
total:
|
|
type: integer
|
|
running:
|
|
type: integer
|
|
completed:
|
|
type: integer
|
|
failed:
|
|
type: integer
|
|
|
|
/healthz:
|
|
get:
|
|
tags:
|
|
- System
|
|
summary: Health check
|
|
operationId: healthz
|
|
responses:
|
|
'200':
|
|
description: Service is healthy
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: string
|
|
example: ok
|
|
ts:
|
|
type: string
|
|
description: Request ID for correlation
|
|
|
|
/metrics:
|
|
get:
|
|
tags:
|
|
- System
|
|
summary: Prometheus metrics
|
|
operationId: metrics
|
|
description: Returns metrics in Prometheus format
|
|
responses:
|
|
'200':
|
|
description: Prometheus metrics
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
|
|
components:
|
|
securitySchemes:
|
|
bearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
description: JWT token obtained from /api/v1/auth/login
|
|
|
|
parameters:
|
|
UserId:
|
|
name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: User ID
|
|
|
|
schemas:
|
|
User:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: user-1
|
|
username:
|
|
type: string
|
|
example: admin
|
|
email:
|
|
type: string
|
|
format: email
|
|
example: admin@example.com
|
|
role:
|
|
$ref: '#/components/schemas/Role'
|
|
active:
|
|
type: boolean
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
updated_at:
|
|
type: string
|
|
format: date-time
|
|
|
|
Role:
|
|
type: string
|
|
enum:
|
|
- administrator
|
|
- operator
|
|
- viewer
|
|
example: administrator
|
|
|
|
Pool:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: tank
|
|
status:
|
|
type: string
|
|
enum: [ONLINE, DEGRADED, FAULTED, OFFLINE]
|
|
example: ONLINE
|
|
size:
|
|
type: integer
|
|
format: int64
|
|
description: Total size in bytes
|
|
allocated:
|
|
type: integer
|
|
format: int64
|
|
description: Allocated space in bytes
|
|
free:
|
|
type: integer
|
|
format: int64
|
|
description: Free space in bytes
|
|
health:
|
|
type: string
|
|
example: ONLINE
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
|
|
Dataset:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: tank/data
|
|
pool:
|
|
type: string
|
|
example: tank
|
|
type:
|
|
type: string
|
|
enum: [filesystem, volume]
|
|
size:
|
|
type: integer
|
|
format: int64
|
|
used:
|
|
type: integer
|
|
format: int64
|
|
available:
|
|
type: integer
|
|
format: int64
|
|
mountpoint:
|
|
type: string
|
|
example: /tank/data
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
|
|
ZVOL:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: tank/block/vol1
|
|
pool:
|
|
type: string
|
|
example: tank
|
|
size:
|
|
type: integer
|
|
format: int64
|
|
description: Size in bytes
|
|
used:
|
|
type: integer
|
|
format: int64
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
|
|
Snapshot:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: tank/data@hourly-20241215-143000
|
|
dataset:
|
|
type: string
|
|
example: tank/data
|
|
size:
|
|
type: integer
|
|
format: int64
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
|
|
SnapshotPolicy:
|
|
type: object
|
|
properties:
|
|
dataset:
|
|
type: string
|
|
example: tank/data
|
|
frequent:
|
|
type: integer
|
|
description: Keep N frequent snapshots
|
|
example: 4
|
|
hourly:
|
|
type: integer
|
|
description: Keep N hourly snapshots
|
|
example: 24
|
|
daily:
|
|
type: integer
|
|
description: Keep N daily snapshots
|
|
example: 7
|
|
weekly:
|
|
type: integer
|
|
description: Keep N weekly snapshots
|
|
example: 4
|
|
monthly:
|
|
type: integer
|
|
description: Keep N monthly snapshots
|
|
example: 12
|
|
yearly:
|
|
type: integer
|
|
description: Keep N yearly snapshots
|
|
example: 2
|
|
autosnap:
|
|
type: boolean
|
|
description: Enable automatic snapshots
|
|
autoprune:
|
|
type: boolean
|
|
description: Enable automatic pruning
|
|
|
|
SMBShare:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: smb-1
|
|
name:
|
|
type: string
|
|
example: data
|
|
path:
|
|
type: string
|
|
example: /tank/data
|
|
dataset:
|
|
type: string
|
|
example: tank/data
|
|
description:
|
|
type: string
|
|
read_only:
|
|
type: boolean
|
|
guest_ok:
|
|
type: boolean
|
|
valid_users:
|
|
type: array
|
|
items:
|
|
type: string
|
|
enabled:
|
|
type: boolean
|
|
|
|
NFSExport:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: nfs-1
|
|
path:
|
|
type: string
|
|
example: /tank/data
|
|
dataset:
|
|
type: string
|
|
example: tank/data
|
|
clients:
|
|
type: array
|
|
items:
|
|
type: string
|
|
example: ["192.168.1.0/24", "10.0.0.0/8"]
|
|
read_only:
|
|
type: boolean
|
|
root_squash:
|
|
type: boolean
|
|
enabled:
|
|
type: boolean
|
|
|
|
ISCSITarget:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: iscsi-1
|
|
iqn:
|
|
type: string
|
|
example: iqn.2024-12.com.atlas:storage.target1
|
|
luns:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/LUN'
|
|
initiators:
|
|
type: array
|
|
items:
|
|
type: string
|
|
example: ["iqn.2024-12.com.client:initiator1"]
|
|
enabled:
|
|
type: boolean
|
|
|
|
LUN:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: integer
|
|
description: LUN number
|
|
example: 0
|
|
zvol:
|
|
type: string
|
|
example: tank/block/vol1
|
|
size:
|
|
type: integer
|
|
format: int64
|
|
description: Size in bytes
|
|
backend:
|
|
type: string
|
|
example: zvol
|
|
|
|
Job:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: job-1
|
|
type:
|
|
type: string
|
|
example: snapshot.create
|
|
status:
|
|
$ref: '#/components/schemas/JobStatus'
|
|
progress:
|
|
type: integer
|
|
description: Progress percentage (0-100)
|
|
message:
|
|
type: string
|
|
error:
|
|
type: string
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
started_at:
|
|
type: string
|
|
format: date-time
|
|
completed_at:
|
|
type: string
|
|
format: date-time
|
|
|
|
JobStatus:
|
|
type: string
|
|
enum:
|
|
- pending
|
|
- running
|
|
- completed
|
|
- failed
|
|
- cancelled
|
|
|
|
AuditLog:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: audit-1
|
|
actor:
|
|
type: string
|
|
description: User ID or "system"
|
|
example: user-1
|
|
action:
|
|
type: string
|
|
example: pools.create
|
|
resource:
|
|
type: string
|
|
example: pools/tank
|
|
result:
|
|
type: string
|
|
enum: [success, failure]
|
|
message:
|
|
type: string
|
|
ip:
|
|
type: string
|
|
example: 192.168.1.100
|
|
user_agent:
|
|
type: string
|
|
example: curl/7.68.0
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
|
|
Error:
|
|
type: object
|
|
properties:
|
|
code:
|
|
type: string
|
|
example: NOT_FOUND
|
|
message:
|
|
type: string
|
|
example: dataset not found
|
|
details:
|
|
type: string
|
|
example: tank/missing
|
|
|
|
responses:
|
|
BadRequest:
|
|
description: Bad request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
Unauthorized:
|
|
description: Unauthorized
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
Forbidden:
|
|
description: Forbidden
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
NotFound:
|
|
description: Resource not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
Conflict:
|
|
description: Resource conflict
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
InternalServerError:
|
|
description: Internal server error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|