483 lines
13 KiB
YAML
483 lines
13 KiB
YAML
openapi: "3.1.0"
|
|
info:
|
|
title: Two API
|
|
version: "0.1.0"
|
|
description: REST API for managing VPCs and Subnets in the Two orchestrator.
|
|
|
|
servers:
|
|
- url: http://localhost:8080
|
|
description: Local development server
|
|
|
|
paths:
|
|
|
|
# ── VPC ────────────────────────────────────────────────────────────────────
|
|
|
|
/vpcs:
|
|
get:
|
|
summary: List all VPCs
|
|
operationId: listVPCs
|
|
responses:
|
|
"200":
|
|
description: List of VPCs
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/VPC"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
post:
|
|
summary: Create a VPC
|
|
operationId: createVPC
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/VPCCreateRequest"
|
|
responses:
|
|
"202":
|
|
description: VPC creation accepted
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/VPC"
|
|
"400":
|
|
description: Missing required field or invalid request body
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
"409":
|
|
description: VPC already exists
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/vpcs/{name}:
|
|
parameters:
|
|
- $ref: "#/components/parameters/ResourceName"
|
|
|
|
get:
|
|
summary: Get VPC status and info
|
|
operationId: getVPC
|
|
responses:
|
|
"200":
|
|
description: VPC found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/VPC"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
delete:
|
|
summary: Delete a VPC
|
|
operationId: deleteVPC
|
|
responses:
|
|
"202":
|
|
description: VPC deletion accepted
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/VPC"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
description: VPC not in a deletable state
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
# ── VM ─────────────────────────────────────────────────────────────────────
|
|
|
|
/vms:
|
|
get:
|
|
summary: List all VMs
|
|
operationId: listVMs
|
|
responses:
|
|
"200":
|
|
description: List of VMs
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/VM"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
post:
|
|
summary: Start a VM
|
|
operationId: startVM
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/VMCreateRequest"
|
|
responses:
|
|
"202":
|
|
description: VM start accepted
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/VM"
|
|
"400":
|
|
description: Missing required field or invalid request body
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
"409":
|
|
description: VM already exists
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
"422":
|
|
description: Subnet not found or not in created state
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/vms/{name}:
|
|
parameters:
|
|
- $ref: "#/components/parameters/ResourceName"
|
|
|
|
get:
|
|
summary: Get VM status and info
|
|
operationId: getVM
|
|
responses:
|
|
"200":
|
|
description: VM found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/VM"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
delete:
|
|
summary: Stop a VM
|
|
operationId: stopVM
|
|
responses:
|
|
"202":
|
|
description: VM stop accepted
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/VM"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
# ── Subnet ─────────────────────────────────────────────────────────────────
|
|
|
|
/subnets:
|
|
get:
|
|
summary: List all subnets
|
|
operationId: listSubnets
|
|
responses:
|
|
"200":
|
|
description: List of subnets
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Subnet"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
post:
|
|
summary: Create a subnet
|
|
operationId: createSubnet
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SubnetCreateRequest"
|
|
responses:
|
|
"202":
|
|
description: Subnet creation accepted
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Subnet"
|
|
"400":
|
|
description: Missing required field or unknown iface_type
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
"409":
|
|
description: Subnet already exists
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
"422":
|
|
description: Parent VPC does not exist or is not ready
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/subnets/{name}:
|
|
parameters:
|
|
- $ref: "#/components/parameters/ResourceName"
|
|
|
|
get:
|
|
summary: Get subnet status and info
|
|
operationId: getSubnet
|
|
responses:
|
|
"200":
|
|
description: Subnet found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Subnet"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
delete:
|
|
summary: Delete a subnet
|
|
operationId: deleteSubnet
|
|
responses:
|
|
"202":
|
|
description: Subnet deletion accepted
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Subnet"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
# ── Components ──────────────────────────────────────────────────────────────
|
|
|
|
components:
|
|
|
|
parameters:
|
|
ResourceName:
|
|
name: name
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
description: Resource name
|
|
|
|
schemas:
|
|
|
|
VPCCreateRequest:
|
|
type: object
|
|
required: [name]
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: Unique name for the VPC, must follow the format vp-[id]
|
|
pattern: '^vp-.+'
|
|
example: vp-00001
|
|
|
|
VPC:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: vp-00001
|
|
state:
|
|
type: string
|
|
enum: [creating, created, deleting, deleted]
|
|
example: created
|
|
|
|
SubnetCreateRequest:
|
|
type: object
|
|
required: [name, vpc, vxlan_id, gateway_ip, cidr]
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: Unique name for the subnet
|
|
example: sn-00001
|
|
vpc:
|
|
type: string
|
|
description: Parent VPC name
|
|
example: vpc1
|
|
vxlan_id:
|
|
type: integer
|
|
description: VXLAN VNI identifier
|
|
example: 100
|
|
iface_type:
|
|
type: string
|
|
description: Interface type key defined in the agent config (e.g. vms, internet, admin). Falls back to default_interface if omitted or unknown.
|
|
example: vms
|
|
gateway_ip:
|
|
type: string
|
|
format: ipv4
|
|
description: Gateway IP for the subnet
|
|
example: "10.10.10.1"
|
|
cidr:
|
|
type: string
|
|
description: Subnet CIDR block
|
|
example: "10.10.10.0/24"
|
|
|
|
Subnet:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: sn-00001
|
|
state:
|
|
type: string
|
|
enum: [creating, created, deleting, deleted]
|
|
example: created
|
|
vpc:
|
|
type: string
|
|
example: vpc1
|
|
vxlan_id:
|
|
type: integer
|
|
example: 100
|
|
local_iface:
|
|
type: string
|
|
description: Resolved interface name
|
|
example: br-000000
|
|
gateway_ip:
|
|
type: string
|
|
example: "10.10.10.1"
|
|
cidr:
|
|
type: string
|
|
example: "10.10.10.0/24"
|
|
|
|
VMCreateRequest:
|
|
type: object
|
|
required: [name, metadata_port, interfaces, storage]
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: vm-00001
|
|
metadata_port:
|
|
type: string
|
|
example: "80"
|
|
memory:
|
|
type: integer
|
|
description: Memory in MB (default 512)
|
|
example: 1024
|
|
cpus:
|
|
type: integer
|
|
description: Number of vCPUs (default 1)
|
|
example: 2
|
|
password:
|
|
type: string
|
|
sshkey:
|
|
type: string
|
|
example: "ssh-ed25519 AAAA..."
|
|
interfaces:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
$ref: "#/components/schemas/VMInterface"
|
|
storage:
|
|
type: array
|
|
minItems: 1
|
|
items:
|
|
$ref: "#/components/schemas/VMStorage"
|
|
|
|
VMInterface:
|
|
type: object
|
|
required: [subnet, ip, primary]
|
|
properties:
|
|
subnet:
|
|
type: string
|
|
example: sn-00001
|
|
ip:
|
|
type: string
|
|
format: ipv4
|
|
example: "10.0.0.5"
|
|
primary:
|
|
type: boolean
|
|
example: true
|
|
|
|
VMStorage:
|
|
type: object
|
|
required: [path, dev]
|
|
properties:
|
|
path:
|
|
type: string
|
|
description: Path to the disk image on the host
|
|
example: /var/lib/two/volumes/abc.qcow2
|
|
dev:
|
|
type: string
|
|
description: Device name inside the VM
|
|
pattern: '^[sv]d[a-z]$'
|
|
example: vda
|
|
|
|
VM:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: vm-00001
|
|
state:
|
|
type: string
|
|
enum: [starting, started, stopping, stopped]
|
|
example: started
|
|
metadata_port:
|
|
type: string
|
|
example: "80"
|
|
memory:
|
|
type: integer
|
|
example: 1024
|
|
cpus:
|
|
type: integer
|
|
example: 2
|
|
interfaces:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/VMInterface"
|
|
storage:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/VMStorage"
|
|
|
|
Error:
|
|
type: object
|
|
properties:
|
|
error:
|
|
type: string
|
|
example: "resource not found"
|
|
|
|
responses:
|
|
NotFound:
|
|
description: Resource not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
InternalError:
|
|
description: Internal server error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|