{ "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" } ] }