Files

1462 lines
49 KiB
JSON
Raw Permalink Normal View History

2026-07-27 14:41:04 +02:00
{
"swagger": "2.0",
"info": {
"title": "NodeMaster API",
"description": "API for managing a node, its services, and a cluster of remote nodes.\n",
"version": "1.0.0",
"contact": {
"email": "yves.cerezal@irt-saintexupery.com"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"basePath": "/v1",
"paths": {
"/node/": {
"get": {
"tags": [
"node"
],
"description": "get current node info including runtime config_file path\n\u003cbr\u003e",
"operationId": "NodeController.GetNode",
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.NodeInfo"
}
}
}
},
"put": {
"tags": [
"node"
],
"description": "update current node hostname, description, or restic_password (the repository password used to encrypt/decrypt all restic backup targets on this node)\n\u003cbr\u003e",
"operationId": "NodeController.UpdateNode",
"parameters": [
{
"in": "body",
"name": "body",
"description": "fields to update",
"required": true,
"schema": {
"$ref": "#/definitions/models.NodeInfo"
}
}
],
"responses": {
"200": {
"description": "{string} update success"
},
"400": {
"description": "invalid body"
}
}
}
},
"/node/backup": {
"get": {
"tags": [
"node"
],
"description": "get node backup configuration\n\u003cbr\u003e",
"operationId": "NodeController.GetBackup",
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.BackupConfig"
}
}
}
},
"put": {
"tags": [
"node"
],
"description": "update node backup configuration\n\u003cbr\u003e",
"operationId": "NodeController.UpdateBackup",
"parameters": [
{
"in": "body",
"name": "body",
"description": "backup config",
"required": true,
"schema": {
"$ref": "#/definitions/models.BackupConfig"
}
}
],
"responses": {
"200": {
"description": "{string} update success"
},
"400": {
"description": "invalid body"
}
}
}
},
"/node/backup/progress": {
"get": {
"tags": [
"node"
],
"description": "get the current/last run state for every node backup target\n\u003cbr\u003e",
"operationId": "NodeController.GetBackupProgress",
"responses": {
"200": {
"description": "",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/models.RunState"
}
}
}
}
}
},
"/node/backup/run": {
"post": {
"tags": [
"node"
],
"description": "trigger an immediate node backup across all targets (asynchronous)\n\u003cbr\u003e",
"operationId": "NodeController.RunBackup",
"responses": {
"202": {
"description": "{string} backup started"
},
"400": {
"description": "no targets configured"
}
}
}
},
"/node/backup/targets": {
"get": {
"tags": [
"node"
],
"description": "list node backup target definitions\n\u003cbr\u003e",
"operationId": "NodeController.GetBackupTargets",
"responses": {
"200": {
"description": "",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/models.BackupTarget"
}
}
}
}
},
"post": {
"tags": [
"node"
],
"description": "define a new node backup target\n\u003cbr\u003e",
"operationId": "NodeController.AddBackupTarget",
"parameters": [
{
"in": "body",
"name": "body",
"description": "backup target definition",
"required": true,
"schema": {
"$ref": "#/definitions/models.BackupTarget"
}
}
],
"responses": {
"201": {
"description": "",
"schema": {
"$ref": "#/definitions/models.BackupTarget"
}
},
"400": {
"description": "invalid body"
}
}
}
},
"/node/backup/targets/{tid}": {
"get": {
"tags": [
"node"
],
"description": "get a node backup target by id\n\u003cbr\u003e",
"operationId": "NodeController.GetBackupTarget",
"parameters": [
{
"in": "path",
"name": "tid",
"description": "backup target id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.BackupTarget"
}
},
"404": {
"description": "not found"
}
}
},
"put": {
"tags": [
"node"
],
"description": "update a node backup target definition\n\u003cbr\u003e",
"operationId": "NodeController.PutBackupTarget",
"parameters": [
{
"in": "path",
"name": "tid",
"description": "backup target id",
"required": true,
"type": "string"
},
{
"in": "body",
"name": "body",
"description": "updated backup target",
"required": true,
"schema": {
"$ref": "#/definitions/models.BackupTarget"
}
}
],
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.BackupTarget"
}
},
"400": {
"description": "invalid body"
},
"404": {
"description": "not found"
}
}
},
"delete": {
"tags": [
"node"
],
"description": "delete a node backup target definition\n\u003cbr\u003e",
"operationId": "NodeController.DeleteBackupTarget",
"parameters": [
{
"in": "path",
"name": "tid",
"description": "backup target id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "{string} delete success"
},
"404": {
"description": "not found"
}
}
}
},
"/node/backup/targets/{tid}/progress": {
"get": {
"tags": [
"node"
],
"description": "get the current/last run state for a node backup target\n\u003cbr\u003e",
"operationId": "NodeController.GetBackupTargetProgress",
"parameters": [
{
"in": "path",
"name": "tid",
"description": "backup target id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.RunState"
}
},
"404": {
"description": "not found"
}
}
}
},
"/node/backup/targets/{tid}/run": {
"post": {
"tags": [
"node"
],
"description": "trigger an immediate backup for a single node target (asynchronous)\n\u003cbr\u003e",
"operationId": "NodeController.RunBackupTarget",
"parameters": [
{
"in": "path",
"name": "tid",
"description": "backup target id",
"required": true,
"type": "string"
}
],
"responses": {
"202": {
"description": "{string} backup started"
},
"404": {
"description": "not found"
}
}
}
},
"/node/scan": {
"post": {
"tags": [
"node"
],
"description": "scan compose folders and index discovered services; accepts optional {\"folder\":\"/path\"} body\n\u003cbr\u003e",
"operationId": "NodeController.Scan",
"parameters": [
{
"in": "body",
"name": "body",
"description": "optional folder override",
"schema": {
"$ref": "#/definitions/object"
}
}
],
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.ScanResult"
}
}
}
}
},
"/node/updates": {
"get": {
"tags": [
"node"
],
"description": "list update history\n\u003cbr\u003e",
"operationId": "NodeController.GetUpdates",
"responses": {
"200": {
"description": "",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/models.UpdateRecord"
}
}
}
}
},
"post": {
"tags": [
"node"
],
"description": "record a new update entry\n\u003cbr\u003e",
"operationId": "NodeController.AddUpdate",
"parameters": [
{
"in": "body",
"name": "body",
"description": "update record",
"required": true,
"schema": {
"$ref": "#/definitions/models.UpdateRecord"
}
}
],
"responses": {
"201": {
"description": "",
"schema": {
"$ref": "#/definitions/models.UpdateRecord"
}
},
"400": {
"description": "invalid body"
}
}
}
},
"/node/updates/{id}": {
"get": {
"tags": [
"node"
],
"description": "get a single update record\n\u003cbr\u003e",
"operationId": "NodeController.GetUpdate",
"parameters": [
{
"in": "path",
"name": "id",
"description": "update record id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.UpdateRecord"
}
},
"404": {
"description": "not found"
}
}
},
"delete": {
"tags": [
"node"
],
"description": "delete an update record\n\u003cbr\u003e",
"operationId": "NodeController.DeleteUpdate",
"parameters": [
{
"in": "path",
"name": "id",
"description": "update record id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "{string} delete success"
},
"404": {
"description": "not found"
}
}
}
},
"/nodes/": {
"get": {
"tags": [
"nodes"
],
"description": "list all registered remote nodes\n\u003cbr\u003e",
"operationId": "NodesController.GetAllNodes",
"responses": {
"200": {
"description": "",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/models.RemoteNode"
}
}
}
}
},
"post": {
"tags": [
"nodes"
],
"description": "register a remote node\n\u003cbr\u003e",
"operationId": "NodesController.AddNode",
"parameters": [
{
"in": "body",
"name": "body",
"description": "node to register",
"required": true,
"schema": {
"$ref": "#/definitions/models.RemoteNode"
}
}
],
"responses": {
"201": {
"description": "",
"schema": {
"$ref": "#/definitions/models.RemoteNode"
}
},
"400": {
"description": "invalid body"
}
}
}
},
"/nodes/aggregated": {
"get": {
"tags": [
"nodes"
],
"description": "query all registered nodes for their services and return an aggregated view\n\u003cbr\u003e",
"operationId": "NodesController.GetAggregated",
"responses": {
"200": {
"description": "",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/nodeServices"
}
}
}
}
}
},
"/nodes/{id}": {
"get": {
"tags": [
"nodes"
],
"description": "get a remote node by id\n\u003cbr\u003e",
"operationId": "NodesController.GetNode",
"parameters": [
{
"in": "path",
"name": "id",
"description": "node id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.RemoteNode"
}
},
"404": {
"description": "not found"
}
}
},
"put": {
"tags": [
"nodes"
],
"description": "update a remote node\n\u003cbr\u003e",
"operationId": "NodesController.UpdateNode",
"parameters": [
{
"in": "path",
"name": "id",
"description": "node id",
"required": true,
"type": "string"
},
{
"in": "body",
"name": "body",
"description": "updated node data",
"required": true,
"schema": {
"$ref": "#/definitions/models.RemoteNode"
}
}
],
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.RemoteNode"
}
},
"400": {
"description": "invalid body"
},
"404": {
"description": "not found"
}
}
},
"delete": {
"tags": [
"nodes"
],
"description": "delete a remote node\n\u003cbr\u003e",
"operationId": "NodesController.DeleteNode",
"parameters": [
{
"in": "path",
"name": "id",
"description": "node id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "{string} delete success"
},
"404": {
"description": "not found"
}
}
}
},
"/services/": {
"get": {
"tags": [
"services"
],
"description": "list all services\n\u003cbr\u003e",
"operationId": "ServicesController.GetAllServices",
"responses": {
"200": {
"description": "",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/models.Service"
}
}
}
}
},
"post": {
"tags": [
"services"
],
"description": "register a new service\n\u003cbr\u003e",
"operationId": "ServicesController.AddService",
"parameters": [
{
"in": "body",
"name": "body",
"description": "service definition",
"required": true,
"schema": {
"$ref": "#/definitions/models.Service"
}
}
],
"responses": {
"201": {
"description": "",
"schema": {
"$ref": "#/definitions/models.Service"
}
},
"400": {
"description": "invalid body"
}
}
}
},
"/services/{id}": {
"get": {
"tags": [
"services"
],
"description": "get a service by id\n\u003cbr\u003e",
"operationId": "ServicesController.GetService",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.Service"
}
},
"404": {
"description": "not found"
}
}
},
"put": {
"tags": [
"services"
],
"description": "update a service definition\n\u003cbr\u003e",
"operationId": "ServicesController.UpdateService",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
},
{
"in": "body",
"name": "body",
"description": "updated service data",
"required": true,
"schema": {
"$ref": "#/definitions/models.Service"
}
}
],
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.Service"
}
},
"400": {
"description": "invalid body"
},
"404": {
"description": "not found"
}
}
},
"delete": {
"tags": [
"services"
],
"description": "delete a service\n\u003cbr\u003e",
"operationId": "ServicesController.DeleteService",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "{string} delete success"
},
"404": {
"description": "not found"
}
}
}
},
"/services/{id}/backup": {
"post": {
"tags": [
"services"
],
"description": "trigger an immediate backup for a service across all targets (asynchronous)\n\u003cbr\u003e",
"operationId": "ServicesController.BackupService",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
}
],
"responses": {
"202": {
"description": "{string} backup started"
},
"400": {
"description": "no backup configured"
},
"404": {
"description": "not found"
}
}
}
},
"/services/{id}/backup/progress": {
"get": {
"tags": [
"services"
],
"description": "get the current/last run state for every backup target of a service\n\u003cbr\u003e",
"operationId": "ServicesController.GetServiceBackupProgress",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/models.RunState"
}
}
},
"404": {
"description": "not found"
}
}
}
},
"/services/{id}/backup/targets": {
"get": {
"tags": [
"services"
],
"description": "list a service's backup target definitions\n\u003cbr\u003e",
"operationId": "ServicesController.GetServiceBackupTargets",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/models.BackupTarget"
}
}
},
"404": {
"description": "not found"
}
}
},
"post": {
"tags": [
"services"
],
"description": "define a new backup target for a service\n\u003cbr\u003e",
"operationId": "ServicesController.AddServiceBackupTarget",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
},
{
"in": "body",
"name": "body",
"description": "backup target definition",
"required": true,
"schema": {
"$ref": "#/definitions/models.BackupTarget"
}
}
],
"responses": {
"201": {
"description": "",
"schema": {
"$ref": "#/definitions/models.BackupTarget"
}
},
"400": {
"description": "invalid body"
},
"404": {
"description": "not found"
}
}
}
},
"/services/{id}/backup/targets/{tid}": {
"get": {
"tags": [
"services"
],
"description": "get a service backup target by id\n\u003cbr\u003e",
"operationId": "ServicesController.GetServiceBackupTarget",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
},
{
"in": "path",
"name": "tid",
"description": "backup target id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.BackupTarget"
}
},
"404": {
"description": "not found"
}
}
},
"put": {
"tags": [
"services"
],
"description": "update a service backup target definition\n\u003cbr\u003e",
"operationId": "ServicesController.PutServiceBackupTarget",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
},
{
"in": "path",
"name": "tid",
"description": "backup target id",
"required": true,
"type": "string"
},
{
"in": "body",
"name": "body",
"description": "updated backup target",
"required": true,
"schema": {
"$ref": "#/definitions/models.BackupTarget"
}
}
],
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.BackupTarget"
}
},
"400": {
"description": "invalid body"
},
"404": {
"description": "not found"
}
}
},
"delete": {
"tags": [
"services"
],
"description": "delete a service backup target definition\n\u003cbr\u003e",
"operationId": "ServicesController.DeleteServiceBackupTarget",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
},
{
"in": "path",
"name": "tid",
"description": "backup target id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "{string} delete success"
},
"404": {
"description": "not found"
}
}
}
},
"/services/{id}/backup/targets/{tid}/progress": {
"get": {
"tags": [
"services"
],
"description": "get the current/last run state for a service backup target\n\u003cbr\u003e",
"operationId": "ServicesController.GetServiceBackupTargetProgress",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
},
{
"in": "path",
"name": "tid",
"description": "backup target id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/models.RunState"
}
},
"404": {
"description": "not found"
}
}
}
},
"/services/{id}/backup/targets/{tid}/run": {
"post": {
"tags": [
"services"
],
"description": "trigger an immediate backup for a single service target (asynchronous)\n\u003cbr\u003e",
"operationId": "ServicesController.RunServiceBackupTarget",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
},
{
"in": "path",
"name": "tid",
"description": "backup target id",
"required": true,
"type": "string"
}
],
"responses": {
"202": {
"description": "{string} backup started"
},
"404": {
"description": "not found"
}
}
}
},
"/services/{id}/start": {
"post": {
"tags": [
"services"
],
"description": "start a service via its compose file\n\u003cbr\u003e",
"operationId": "ServicesController.StartService",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "{string} started"
},
"404": {
"description": "not found"
}
}
}
},
"/services/{id}/stop": {
"post": {
"tags": [
"services"
],
"description": "stop a service via its compose file\n\u003cbr\u003e",
"operationId": "ServicesController.StopService",
"parameters": [
{
"in": "path",
"name": "id",
"description": "service id",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "{string} stopped"
},
"404": {
"description": "not found"
}
}
}
}
},
"definitions": {
"models.BackupConfig": {
"title": "BackupConfig",
"type": "object",
"properties": {
"history": {
"type": "array",
"items": {
"$ref": "#/definitions/models.BackupExecution"
}
},
"last_run": {
"description": "aggregate: latest LastRun across Targets",
"type": "string",
"format": "datetime"
},
"next_run": {
"description": "aggregate: earliest NextRun across Targets",
"type": "string",
"format": "datetime"
},
"source_path": {
"type": "string"
},
"targets": {
"type": "array",
"items": {
"$ref": "#/definitions/models.BackupTarget"
}
}
}
},
"models.BackupExecution": {
"title": "BackupExecution",
"type": "object",
"properties": {
"duration_seconds": {
"type": "integer",
"format": "int64"
},
"id": {
"type": "string"
},
"message": {
"type": "string"
},
"success": {
"type": "boolean"
},
"target_id": {
"type": "string"
},
"timestamp": {
"type": "string",
"format": "datetime"
}
}
},
"models.BackupMethod": {
"title": "BackupMethod",
"type": "string",
"enum": [
"MethodRsync = \"rsync\"",
"MethodRestic = \"restic\"",
"MethodExternal = \"external\""
],
"example": "rsync"
},
"models.BackupTarget": {
"title": "BackupTarget",
"type": "object",
"properties": {
"id": {
"type": "string"
},
"last_run": {
"type": "string",
"format": "datetime"
},
"method": {
"$ref": "#/definitions/models.BackupMethod"
},
"name": {
"type": "string"
},
"next_run": {
"type": "string",
"format": "datetime"
},
"params": {
"additionalProperties": {
"type": "string"
}
},
"remote": {
"description": "destination: rsync target path (e.g. \"user@host:/path\") or restic repository string (e.g. \"/mnt/backup/repo\", \"s3:s3.amazonaws.com/bucket/path\", \"sftp:user@host:/path\")",
"type": "string"
},
"schedule": {
"description": "cron expression (5-field, standard). Empty = manual-only.",
"type": "string"
}
}
},
"models.NodeInfo": {
"title": "NodeInfo",
"type": "object",
"properties": {
"backup": {
"$ref": "#/definitions/models.BackupConfig"
},
"description": {
"type": "string"
},
"hostname": {
"type": "string"
},
"restic_password": {
"description": "repository password used to encrypt/decrypt all restic backup targets on this node",
"type": "string"
},
"update_history": {
"type": "array",
"items": {
"$ref": "#/definitions/models.UpdateRecord"
}
}
}
},
"models.RemoteNode": {
"title": "RemoteNode",
"type": "object",
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"last_seen": {
"type": "string",
"format": "datetime"
},
"name": {
"type": "string"
},
"status": {
"type": "string"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"url": {
"type": "string"
}
}
},
"models.RunState": {
"title": "RunState",
"type": "object",
"properties": {
"eta": {
"type": "string"
},
"message": {
"type": "string"
},
"method": {
"$ref": "#/definitions/models.BackupMethod"
},
"percent": {
"type": "number",
"format": "double"
},
"running": {
"type": "boolean"
},
"started_at": {
"type": "string",
"format": "datetime"
},
"target_id": {
"type": "string"
}
}
},
"models.ScanResult": {
"title": "ScanResult",
"type": "object",
"properties": {
"created": {
"type": "array",
"items": {
"$ref": "#/definitions/models.ServiceScanInfo"
}
},
"errors": {
"type": "array",
"items": {
"type": "string"
}
},
"found": {
"type": "integer",
"format": "int64"
},
"scanned_paths": {
"type": "array",
"items": {
"type": "string"
}
},
"updated": {
"type": "array",
"items": {
"$ref": "#/definitions/models.ServiceScanInfo"
}
}
}
},
"models.Service": {
"title": "Service",
"type": "object",
"properties": {
"backup": {
"$ref": "#/definitions/models.BackupConfig"
},
"backup_folder": {
"type": "string"
},
"compose_file": {
"type": "string"
},
"compose_type": {
"type": "string"
},
"external_backup_start_minutes": {
"type": "integer",
"format": "int64"
},
"external_backup_stop_minutes": {
"type": "integer",
"format": "int64"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"status": {
"description": "\"up\", \"down\", \"unknown\"",
"type": "string"
},
"stop_on_backup": {
"type": "boolean"
}
}
},
"models.ServiceScanInfo": {
"title": "ServiceScanInfo",
"type": "object",
"properties": {
"backup_folder": {
"type": "string"
},
"compose_file": {
"type": "string"
},
"name": {
"type": "string"
},
"status": {
"type": "string"
}
}
},
"models.UpdateRecord": {
"title": "UpdateRecord",
"type": "object",
"properties": {
"id": {
"type": "string"
},
"message": {
"type": "string"
},
"packages": {
"type": "array",
"items": {
"type": "string"
}
},
"success": {
"type": "boolean"
},
"timestamp": {
"type": "string",
"format": "datetime"
}
}
},
"nodeServices": {
"title": "nodeServices",
"type": "object"
},
"object": {
"title": "object",
"type": "object"
}
},
"tags": [
{
"name": "node",
"description": "NodeController manages the current host node.\n"
},
{
"name": "nodes",
"description": "NodesController manages the registry of remote nodes.\n"
},
{
"name": "services",
"description": "ServicesController manages services on this host.\n"
}
]
}