226 lines
7.2 KiB
YAML
226 lines
7.2 KiB
YAML
# yaml-language-server: $schema=https://json-schema.org/draft/2020-12/schema
|
|
openapi: 3.1.0
|
|
info:
|
|
title: agent-call Cell Agent API
|
|
version: 1.0.0
|
|
description: >-
|
|
Restricted mTLS API used by the SIP management backend to deliver a
|
|
versioned Trunk snapshot to one voice Cell. The Cell validates the SHA-256
|
|
snapshot, applies it with an atomic file replacement, reloads Asterisk,
|
|
restores the previous file on reload failure, and returns applied only
|
|
after the reload succeeds. A disabled snapshot removes the Cell-local
|
|
Trunk fragment and reloads Asterisk.
|
|
servers:
|
|
- url: https://cell.internal:9443
|
|
description: Cell management network only
|
|
tags:
|
|
- name: health
|
|
- name: trunk-apply
|
|
paths:
|
|
/healthz/live:
|
|
get:
|
|
tags: [health]
|
|
operationId: live
|
|
responses:
|
|
'200':
|
|
description: Cell Agent is alive
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/Health'}
|
|
/v1/sip/trunks/{trunk_id}/apply:
|
|
parameters:
|
|
- {$ref: '#/components/parameters/TrunkId'}
|
|
post:
|
|
tags: [trunk-apply]
|
|
operationId: applyTrunk
|
|
security: [{CellManagementMtls: []}]
|
|
parameters:
|
|
- {$ref: '#/components/parameters/RequestId'}
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/Publication'}
|
|
responses:
|
|
'200':
|
|
description: Asterisk has loaded the exact snapshot
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/Acknowledgement'}
|
|
'400': {$ref: '#/components/responses/BadRequest'}
|
|
'403': {$ref: '#/components/responses/Forbidden'}
|
|
'409':
|
|
description: Revision is stale or has a gap
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/ErrorResponse'}
|
|
'502':
|
|
description: Asterisk rejected the apply or reload
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/ErrorResponse'}
|
|
/v1/sip/trunks/{trunk_id}/state:
|
|
parameters:
|
|
- {$ref: '#/components/parameters/TrunkId'}
|
|
get:
|
|
tags: [trunk-apply]
|
|
operationId: getTrunkState
|
|
security: [{CellManagementMtls: []}]
|
|
responses:
|
|
'200':
|
|
description: Durable Cell apply state
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/State'}
|
|
'404': {$ref: '#/components/responses/NotFound'}
|
|
components:
|
|
securitySchemes:
|
|
CellManagementMtls:
|
|
type: mutualTLS
|
|
description: Management backend client certificate signed by the Cell CA.
|
|
parameters:
|
|
TrunkId:
|
|
name: trunk_id
|
|
in: path
|
|
required: true
|
|
schema: {type: string, pattern: '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$'}
|
|
RequestId:
|
|
name: X-Request-ID
|
|
in: header
|
|
required: true
|
|
schema: {type: string, minLength: 1, maxLength: 128}
|
|
schemas:
|
|
Health:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [status, mode, cell_id]
|
|
properties:
|
|
status: {type: string, const: ok}
|
|
mode: {type: string, const: real}
|
|
cell_id: {type: string}
|
|
CodecProfile:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [allowed, preferred]
|
|
properties:
|
|
allowed:
|
|
type: array
|
|
minItems: 1
|
|
uniqueItems: true
|
|
items: {type: string, enum: [PCMA, PCMU]}
|
|
preferred: {type: string, enum: [PCMA, PCMU]}
|
|
SipConfig:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [host, port, transport, auth_mode, register, credential_ref]
|
|
properties:
|
|
host: {type: string, minLength: 1, maxLength: 253}
|
|
port: {type: integer, minimum: 1, maximum: 65535}
|
|
transport: {type: string, enum: [udp, tcp, tls]}
|
|
auth_mode: {type: string, enum: [ip, digest]}
|
|
register: {type: boolean}
|
|
credential_ref:
|
|
type: [string, 'null']
|
|
description: Secret-store reference only; plaintext is forbidden.
|
|
TrunkConfig:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
- display_name
|
|
- enabled
|
|
- sip
|
|
- codec_profile
|
|
- caller_ids
|
|
- dial_prefix
|
|
- egress_pool_id
|
|
- max_concurrency
|
|
- max_cps
|
|
properties:
|
|
display_name: {type: string, minLength: 1, maxLength: 256}
|
|
enabled: {type: boolean}
|
|
sip: {$ref: '#/components/schemas/SipConfig'}
|
|
codec_profile: {$ref: '#/components/schemas/CodecProfile'}
|
|
caller_ids:
|
|
type: array
|
|
minItems: 1
|
|
uniqueItems: true
|
|
items: {type: string, minLength: 1, maxLength: 128}
|
|
dial_prefix: {type: string, maxLength: 32}
|
|
egress_pool_id: {type: string}
|
|
max_concurrency: {type: integer, minimum: 1}
|
|
max_cps: {type: integer, minimum: 1}
|
|
Publication:
|
|
type: object
|
|
additionalProperties: false
|
|
required: [mode, cell_id, trunk_id, revision, config, config_sha256]
|
|
properties:
|
|
mode: {type: string, const: real}
|
|
cell_id: {type: string}
|
|
trunk_id: {type: string}
|
|
revision: {type: integer, minimum: 1}
|
|
config: {$ref: '#/components/schemas/TrunkConfig'}
|
|
config_sha256:
|
|
type: string
|
|
pattern: '^[0-9a-f]{64}$'
|
|
Acknowledgement:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
[mode, cell_id, trunk_id, revision, config_sha256, status, idempotent]
|
|
properties:
|
|
mode: {type: string, const: real}
|
|
cell_id: {type: string}
|
|
trunk_id: {type: string}
|
|
revision: {type: integer, minimum: 1}
|
|
config_sha256: {type: string, pattern: '^[0-9a-f]{64}$'}
|
|
status: {type: string, const: applied}
|
|
idempotent: {type: boolean}
|
|
State:
|
|
type: object
|
|
additionalProperties: false
|
|
required:
|
|
[
|
|
mode,
|
|
cell_id,
|
|
trunk_id,
|
|
desired_revision,
|
|
applied_revision,
|
|
status,
|
|
updated_at,
|
|
]
|
|
properties:
|
|
mode: {type: string, const: real}
|
|
cell_id: {type: string}
|
|
trunk_id: {type: string}
|
|
desired_revision: {type: integer, minimum: 1}
|
|
applied_revision: {type: integer, minimum: 0}
|
|
status: {type: string, enum: [applying, applied, failed]}
|
|
last_error: {type: [string, 'null']}
|
|
updated_at: {type: string, format: date-time}
|
|
ErrorResponse:
|
|
type: object
|
|
required: [error]
|
|
properties:
|
|
error:
|
|
type: object
|
|
required: [code, message]
|
|
properties:
|
|
code: {type: string}
|
|
message: {type: string}
|
|
responses:
|
|
BadRequest:
|
|
description: Invalid publication or hash
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/ErrorResponse'}
|
|
Forbidden:
|
|
description: Certificate or Cell identity is not authorized
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/ErrorResponse'}
|
|
NotFound:
|
|
description: State does not exist
|
|
content:
|
|
application/json:
|
|
schema: {$ref: '#/components/schemas/ErrorResponse'}
|