diff --git a/Makefile b/Makefile index 1aeb5187..61f3dd6a 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,7 @@ gotestsum=$(gobin)/gotestsum \ $(if $(filter true,$(CI)),--junitfile $@-results.xml) golangci-lint=$(gobin)/golangci-lint \ - $(if $(filter true,$(CI)),--output.junit-xml.path $@-results.xml) + $(if $(filter true,$(CI)),--output.text.path stdout --output.junit-xml.path $@-results.xml) .DEFAULT_GOAL := build diff --git a/api/apiv1/design/database.go b/api/apiv1/design/database.go index ec7a73f6..61fe8bad 100644 --- a/api/apiv1/design/database.go +++ b/api/apiv1/design/database.go @@ -186,6 +186,10 @@ var ServiceSpec = g.Type("ServiceSpec", func() { g.Example("512M") g.Meta("struct:tag:json", "memory,omitempty") }) + g.Attribute("orchestrator_opts", OrchestratorOpts, func() { + g.Description("Orchestrator-specific options for this service.") + g.Meta("struct:tag:json", "orchestrator_opts,omitempty") + }) g.Required("service_id", "service_type", "version", "host_ids", "config") }) diff --git a/api/apiv1/gen/control_plane/service.go b/api/apiv1/gen/control_plane/service.go index 2115bb8f..8b578c11 100644 --- a/api/apiv1/gen/control_plane/service.go +++ b/api/apiv1/gen/control_plane/service.go @@ -975,6 +975,8 @@ type ServiceSpec struct { // The amount of memory in SI or IEC notation to allocate for this service. // Defaults to container defaults if unspecified. Memory *string `json:"memory,omitempty"` + // Orchestrator-specific options for this service. + OrchestratorOpts *OrchestratorOpts `json:"orchestrator_opts,omitempty"` } // StartInstancePayload is the payload type of the control-plane service diff --git a/api/apiv1/gen/http/control_plane/client/encode_decode.go b/api/apiv1/gen/http/control_plane/client/encode_decode.go index 7c9bee56..1cbeba72 100644 --- a/api/apiv1/gen/http/control_plane/client/encode_decode.go +++ b/api/apiv1/gen/http/control_plane/client/encode_decode.go @@ -4716,6 +4716,9 @@ func marshalControlplaneServiceSpecToServiceSpecRequestBody(v *controlplane.Serv res.Config[tk] = tv } } + if v.OrchestratorOpts != nil { + res.OrchestratorOpts = marshalControlplaneOrchestratorOptsToOrchestratorOptsRequestBody(v.OrchestratorOpts) + } return res } @@ -5132,6 +5135,9 @@ func marshalServiceSpecRequestBodyToControlplaneServiceSpec(v *ServiceSpecReques res.Config[tk] = tv } } + if v.OrchestratorOpts != nil { + res.OrchestratorOpts = marshalOrchestratorOptsRequestBodyToControlplaneOrchestratorOpts(v.OrchestratorOpts) + } return res } @@ -5658,6 +5664,9 @@ func unmarshalServiceSpecResponseBodyToControlplaneServiceSpec(v *ServiceSpecRes tv := val res.Config[tk] = tv } + if v.OrchestratorOpts != nil { + res.OrchestratorOpts = unmarshalOrchestratorOptsResponseBodyToControlplaneOrchestratorOpts(v.OrchestratorOpts) + } return res } @@ -6076,6 +6085,9 @@ func marshalControlplaneServiceSpecToServiceSpecRequestBodyRequestBody(v *contro res.Config[tk] = tv } } + if v.OrchestratorOpts != nil { + res.OrchestratorOpts = marshalControlplaneOrchestratorOptsToOrchestratorOptsRequestBodyRequestBody(v.OrchestratorOpts) + } return res } @@ -6494,6 +6506,9 @@ func marshalServiceSpecRequestBodyRequestBodyToControlplaneServiceSpec(v *Servic res.Config[tk] = tv } } + if v.OrchestratorOpts != nil { + res.OrchestratorOpts = marshalOrchestratorOptsRequestBodyRequestBodyToControlplaneOrchestratorOpts(v.OrchestratorOpts) + } return res } diff --git a/api/apiv1/gen/http/control_plane/client/types.go b/api/apiv1/gen/http/control_plane/client/types.go index cf1cdeaa..1c8d745c 100644 --- a/api/apiv1/gen/http/control_plane/client/types.go +++ b/api/apiv1/gen/http/control_plane/client/types.go @@ -2099,6 +2099,8 @@ type ServiceSpecRequestBody struct { // The amount of memory in SI or IEC notation to allocate for this service. // Defaults to container defaults if unspecified. Memory *string `json:"memory,omitempty"` + // Orchestrator-specific options for this service. + OrchestratorOpts *OrchestratorOptsRequestBody `json:"orchestrator_opts,omitempty"` } // DatabaseResponseBody is used to define fields on response body types. @@ -2480,6 +2482,8 @@ type ServiceSpecResponseBody struct { // The amount of memory in SI or IEC notation to allocate for this service. // Defaults to container defaults if unspecified. Memory *string `json:"memory,omitempty"` + // Orchestrator-specific options for this service. + OrchestratorOpts *OrchestratorOptsResponseBody `json:"orchestrator_opts,omitempty"` } // DatabaseSpecRequestBodyRequestBody is used to define fields on request body @@ -2786,6 +2790,8 @@ type ServiceSpecRequestBodyRequestBody struct { // The amount of memory in SI or IEC notation to allocate for this service. // Defaults to container defaults if unspecified. Memory *string `json:"memory,omitempty"` + // Orchestrator-specific options for this service. + OrchestratorOpts *OrchestratorOptsRequestBodyRequestBody `json:"orchestrator_opts,omitempty"` } // TaskLogEntryResponseBody is used to define fields on response body types. @@ -6185,6 +6191,11 @@ func ValidateServiceSpecRequestBody(body *ServiceSpecRequestBody) (err error) { err = goa.MergeErrors(err, goa.InvalidLengthError("body.memory", *body.Memory, utf8.RuneCountInString(*body.Memory), 16, false)) } } + if body.OrchestratorOpts != nil { + if err2 := ValidateOrchestratorOptsRequestBody(body.OrchestratorOpts); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } return } @@ -6902,6 +6913,11 @@ func ValidateServiceSpecRequestBodyRequestBody(body *ServiceSpecRequestBodyReque err = goa.MergeErrors(err, goa.InvalidLengthError("body.memory", *body.Memory, utf8.RuneCountInString(*body.Memory), 16, false)) } } + if body.OrchestratorOpts != nil { + if err2 := ValidateOrchestratorOptsRequestBodyRequestBody(body.OrchestratorOpts); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } return } diff --git a/api/apiv1/gen/http/control_plane/server/encode_decode.go b/api/apiv1/gen/http/control_plane/server/encode_decode.go index 7a201789..dc50c0d8 100644 --- a/api/apiv1/gen/http/control_plane/server/encode_decode.go +++ b/api/apiv1/gen/http/control_plane/server/encode_decode.go @@ -4069,6 +4069,9 @@ func unmarshalServiceSpecRequestBodyToControlplaneServiceSpec(v *ServiceSpecRequ tv := val res.Config[tk] = tv } + if v.OrchestratorOpts != nil { + res.OrchestratorOpts = unmarshalOrchestratorOptsRequestBodyToControlplaneOrchestratorOpts(v.OrchestratorOpts) + } return res } @@ -4615,6 +4618,9 @@ func marshalControlplaneServiceSpecToServiceSpecResponseBody(v *controlplane.Ser res.Config[tk] = tv } } + if v.OrchestratorOpts != nil { + res.OrchestratorOpts = marshalControlplaneOrchestratorOptsToOrchestratorOptsResponseBody(v.OrchestratorOpts) + } return res } @@ -5013,6 +5019,9 @@ func unmarshalServiceSpecRequestBodyRequestBodyToControlplaneServiceSpec(v *Serv tv := val res.Config[tk] = tv } + if v.OrchestratorOpts != nil { + res.OrchestratorOpts = unmarshalOrchestratorOptsRequestBodyRequestBodyToControlplaneOrchestratorOpts(v.OrchestratorOpts) + } return res } diff --git a/api/apiv1/gen/http/control_plane/server/types.go b/api/apiv1/gen/http/control_plane/server/types.go index 8998fe9c..9b97c0db 100644 --- a/api/apiv1/gen/http/control_plane/server/types.go +++ b/api/apiv1/gen/http/control_plane/server/types.go @@ -2185,6 +2185,8 @@ type ServiceSpecResponseBody struct { // The amount of memory in SI or IEC notation to allocate for this service. // Defaults to container defaults if unspecified. Memory *string `json:"memory,omitempty"` + // Orchestrator-specific options for this service. + OrchestratorOpts *OrchestratorOptsResponseBody `json:"orchestrator_opts,omitempty"` } // TaskLogEntryResponseBody is used to define fields on response body types. @@ -2490,6 +2492,8 @@ type ServiceSpecRequestBody struct { // The amount of memory in SI or IEC notation to allocate for this service. // Defaults to container defaults if unspecified. Memory *string `json:"memory,omitempty"` + // Orchestrator-specific options for this service. + OrchestratorOpts *OrchestratorOptsRequestBody `json:"orchestrator_opts,omitempty"` } // DatabaseSpecRequestBodyRequestBody is used to define fields on request body @@ -2796,6 +2800,8 @@ type ServiceSpecRequestBodyRequestBody struct { // The amount of memory in SI or IEC notation to allocate for this service. // Defaults to container defaults if unspecified. Memory *string `json:"memory,omitempty"` + // Orchestrator-specific options for this service. + OrchestratorOpts *OrchestratorOptsRequestBodyRequestBody `json:"orchestrator_opts,omitempty"` } // NewInitClusterResponseBody builds the HTTP response body from the result of @@ -5693,6 +5699,11 @@ func ValidateServiceSpecRequestBody(body *ServiceSpecRequestBody) (err error) { err = goa.MergeErrors(err, goa.InvalidLengthError("body.memory", *body.Memory, utf8.RuneCountInString(*body.Memory), 16, false)) } } + if body.OrchestratorOpts != nil { + if err2 := ValidateOrchestratorOptsRequestBody(body.OrchestratorOpts); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } return } @@ -6394,5 +6405,10 @@ func ValidateServiceSpecRequestBodyRequestBody(body *ServiceSpecRequestBodyReque err = goa.MergeErrors(err, goa.InvalidLengthError("body.memory", *body.Memory, utf8.RuneCountInString(*body.Memory), 16, false)) } } + if body.OrchestratorOpts != nil { + if err2 := ValidateOrchestratorOptsRequestBodyRequestBody(body.OrchestratorOpts); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } return } diff --git a/api/apiv1/gen/http/openapi.json b/api/apiv1/gen/http/openapi.json index dca6daaa..5e1f9c79 100644 --- a/api/apiv1/gen/http/openapi.json +++ b/api/apiv1/gen/http/openapi.json @@ -4789,6 +4789,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -4806,6 +4860,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -4823,6 +4931,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -5454,6 +5616,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -5471,6 +5687,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -8715,6 +8985,9 @@ "example": "512M", "maxLength": 16 }, + "orchestrator_opts": { + "$ref": "#/definitions/OrchestratorOpts" + }, "port": { "type": "integer", "description": "The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network.", @@ -8757,6 +9030,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", diff --git a/api/apiv1/gen/http/openapi.yaml b/api/apiv1/gen/http/openapi.yaml index 11d26a5b..84450975 100644 --- a/api/apiv1/gen/http/openapi.yaml +++ b/api/apiv1/gen/http/openapi.yaml @@ -3432,6 +3432,37 @@ definitions: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -3445,6 +3476,37 @@ definitions: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -3458,6 +3520,37 @@ definitions: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -3923,6 +4016,37 @@ definitions: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -3936,6 +4060,37 @@ definitions: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -6313,6 +6468,8 @@ definitions: description: The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified. example: 512M maxLength: 16 + orchestrator_opts: + $ref: '#/definitions/OrchestratorOpts' port: type: integer description: The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network. @@ -6347,6 +6504,37 @@ definitions: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp diff --git a/api/apiv1/gen/http/openapi3.json b/api/apiv1/gen/http/openapi3.json index fe364db0..ba27dad3 100644 --- a/api/apiv1/gen/http/openapi3.json +++ b/api/apiv1/gen/http/openapi3.json @@ -1704,21 +1704,20 @@ "type": "array", "items": { "type": "string", - "example": "Deserunt earum doloribus eos et error vel." + "example": "Earum doloribus eos et error." }, "description": "Host IDs to treat as removed during this update. Events targeting these hosts will be skipped.", "example": [ - "Recusandae aspernatur non sit aliquam dolor quam.", - "Tempore veniam et.", - "Dignissimos voluptatem soluta veritatis repellat est rerum.", - "Inventore modi explicabo dicta sint." + "Et recusandae aspernatur non sit aliquam.", + "Quam ea tempore veniam et deleniti dignissimos.", + "Soluta veritatis repellat est rerum est." ] }, "example": [ - "Et animi magnam velit vitae praesentium ad.", - "Eos pariatur nobis hic.", - "Et consectetur eius temporibus.", - "Porro ut placeat non ut." + "Explicabo dicta sint.", + "Quis et animi.", + "Velit vitae praesentium ad.", + "Eos pariatur nobis hic." ] }, { @@ -5731,7 +5730,7 @@ }, "additionalProperties": { "type": "string", - "example": "Ipsum officiis et est et dolorem labore." + "example": "Beatae quasi ipsum." } }, "gcs_bucket": { @@ -6702,7 +6701,7 @@ "ipv4_address": "10.24.34.2", "port": 5432 }, - "created_at": "1970-10-16T01:30:13Z", + "created_at": "1996-08-08T19:06:06Z", "error": "failed to get patroni status: connection refused", "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", @@ -6717,107 +6716,6 @@ "spock": { "read_only": "off", "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" - }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" - }, - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "1970-10-16T01:30:13Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": true, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" - }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" - }, - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "1970-10-16T01:30:13Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": true, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, { "name": "sub_n1n2", "provider_node": "n2", @@ -6836,9 +6734,9 @@ ], "version": "4.10.0" }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" }, { "connection_info": { @@ -6846,7 +6744,7 @@ "ipv4_address": "10.24.34.2", "port": 5432 }, - "created_at": "1970-10-16T01:30:13Z", + "created_at": "1996-08-08T19:06:06Z", "error": "failed to get patroni status: connection refused", "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", @@ -6871,11 +6769,6 @@ "provider_node": "n2", "status": "down" }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, { "name": "sub_n1n2", "provider_node": "n2", @@ -6884,9 +6777,9 @@ ], "version": "4.10.0" }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" } ] }, @@ -7065,7 +6958,7 @@ "state": { "type": "string", "description": "Current state of the database.", - "example": "backing_up", + "example": "degraded", "enum": [ "creating", "modifying", @@ -7271,92 +7164,6 @@ }, "description": "All of the instances in the database.", "example": [ - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "2011-03-15T17:48:48Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": false, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" - }, - "state": "unknown", - "status_updated_at": "1993-04-25T23:06:28Z", - "updated_at": "1981-08-22T23:20:01Z" - }, - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "2011-03-15T17:48:48Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": false, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" - }, - "state": "unknown", - "status_updated_at": "1993-04-25T23:06:28Z", - "updated_at": "1981-08-22T23:20:01Z" - }, { "connection_info": { "hostname": "i-0123456789abcdef.ec2.internal", @@ -7497,51 +7304,6 @@ }, "updated_at": "2025-01-28T10:05:00Z" }, - { - "created_at": "2025-01-28T10:00:00Z", - "database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "error": "failed to start container: image not found", - "host_id": "host-1", - "service_id": "mcp-server", - "service_instance_id": "mcp-server-host-1", - "state": "running", - "status": { - "container_id": "a1b2c3d4e5f6", - "health_check": { - "checked_at": "2025-01-28T10:00:00Z", - "message": "Connection refused", - "status": "healthy" - }, - "hostname": "mcp-server-host-1.internal", - "image_version": "1.0.0", - "ipv4_address": "10.0.1.5", - "last_health_at": "2025-01-28T10:00:00Z", - "ports": [ - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - }, - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - }, - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - }, - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - } - ], - "service_ready": true - }, - "updated_at": "2025-01-28T10:05:00Z" - }, { "created_at": "2025-01-28T10:00:00Z", "database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", @@ -7595,7 +7357,7 @@ "state": { "type": "string", "description": "Current state of the database.", - "example": "backing_up", + "example": "restoring", "enum": [ "creating", "modifying", @@ -7929,61 +7691,59 @@ "state": "unknown", "status_updated_at": "1993-04-25T23:06:28Z", "updated_at": "1981-08-22T23:20:01Z" - } - ] - }, - "service_instances": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ServiceInstance" - }, - "description": "Service instances running alongside this database.", - "example": [ + }, { - "created_at": "2025-01-28T10:00:00Z", - "database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "error": "failed to start container: image not found", - "host_id": "host-1", - "service_id": "mcp-server", - "service_instance_id": "mcp-server-host-1", - "state": "running", - "status": { - "container_id": "a1b2c3d4e5f6", - "health_check": { - "checked_at": "2025-01-28T10:00:00Z", - "message": "Connection refused", - "status": "healthy" - }, - "hostname": "mcp-server-host-1.internal", - "image_version": "1.0.0", - "ipv4_address": "10.0.1.5", - "last_health_at": "2025-01-28T10:00:00Z", - "ports": [ - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - }, + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 5432 + }, + "created_at": "2011-03-15T17:48:48Z", + "error": "failed to get patroni status: connection refused", + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "node_name": "n1", + "postgres": { + "patroni_paused": false, + "patroni_state": "unknown", + "pending_restart": true, + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" }, { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" }, { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" } ], - "service_ready": true + "version": "4.10.0" }, - "updated_at": "2025-01-28T10:05:00Z" - }, + "state": "unknown", + "status_updated_at": "1993-04-25T23:06:28Z", + "updated_at": "1981-08-22T23:20:01Z" + } + ] + }, + "service_instances": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceInstance" + }, + "description": "Service instances running alongside this database.", + "example": [ { "created_at": "2025-01-28T10:00:00Z", "database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", @@ -8127,7 +7887,7 @@ "state": { "type": "string", "description": "Current state of the database.", - "example": "available", + "example": "degraded", "enum": [ "creating", "modifying", @@ -8419,49 +8179,6 @@ "status_updated_at": "1993-04-25T23:06:28Z", "updated_at": "1981-08-22T23:20:01Z" }, - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "2011-03-15T17:48:48Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": false, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" - }, - "state": "unknown", - "status_updated_at": "1993-04-25T23:06:28Z", - "updated_at": "1981-08-22T23:20:01Z" - }, { "connection_info": { "hostname": "i-0123456789abcdef.ec2.internal", @@ -8559,51 +8276,6 @@ }, "updated_at": "2025-01-28T10:05:00Z" }, - { - "created_at": "2025-01-28T10:00:00Z", - "database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "error": "failed to start container: image not found", - "host_id": "host-1", - "service_id": "mcp-server", - "service_instance_id": "mcp-server-host-1", - "state": "running", - "status": { - "container_id": "a1b2c3d4e5f6", - "health_check": { - "checked_at": "2025-01-28T10:00:00Z", - "message": "Connection refused", - "status": "healthy" - }, - "hostname": "mcp-server-host-1.internal", - "image_version": "1.0.0", - "ipv4_address": "10.0.1.5", - "last_health_at": "2025-01-28T10:00:00Z", - "ports": [ - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - }, - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - }, - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - }, - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - } - ], - "service_ready": true - }, - "updated_at": "2025-01-28T10:05:00Z" - }, { "created_at": "2025-01-28T10:00:00Z", "database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", @@ -8657,7 +8329,7 @@ "state": { "type": "string", "description": "Current state of the database.", - "example": "deleting", + "example": "degraded", "enum": [ "creating", "modifying", @@ -8863,92 +8535,6 @@ }, "description": "All of the instances in the database.", "example": [ - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "2011-03-15T17:48:48Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": false, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" - }, - "state": "unknown", - "status_updated_at": "1993-04-25T23:06:28Z", - "updated_at": "1981-08-22T23:20:01Z" - }, - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "2011-03-15T17:48:48Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": false, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" - }, - "state": "unknown", - "status_updated_at": "1993-04-25T23:06:28Z", - "updated_at": "1981-08-22T23:20:01Z" - }, { "connection_info": { "hostname": "i-0123456789abcdef.ec2.internal", @@ -9232,7 +8818,7 @@ "state": { "type": "string", "description": "Current state of the database.", - "example": "creating", + "example": "unknown", "enum": [ "creating", "modifying", @@ -9660,6 +9246,7 @@ }, "description": "The IDs of the hosts that should run this node. When multiple hosts are specified, one host will chosen as a primary, and the others will be read replicas.", "example": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "minItems": 1 @@ -9925,6 +9512,8 @@ }, "description": "The IDs of the hosts that should run this node. When multiple hosts are specified, one host will chosen as a primary, and the others will be read replicas.", "example": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696", "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "minItems": 1 @@ -10458,7 +10047,6 @@ }, "description": "The IDs of the hosts that should run this node. When multiple hosts are specified, one host will chosen as a primary, and the others will be read replicas.", "example": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "minItems": 1 @@ -10602,8 +10190,6 @@ }, "cpus": "500m", "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696", "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "500M", @@ -10869,6 +10455,7 @@ }, "cpus": "500m", "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", "76f9b8c0-4958-11f0-a489-3bb29577c696", "76f9b8c0-4958-11f0-a489-3bb29577c696" ], @@ -10992,6 +10579,8 @@ }, "description": "The IDs of the hosts that should run this node. When multiple hosts are specified, one host will chosen as a primary, and the others will be read replicas.", "example": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696", "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "minItems": 1 @@ -11267,7 +10856,7 @@ "CREATEDB", "CREATEROLE" ], - "db_owner": true, + "db_owner": false, "password": "secret", "roles": [ "pgedge_superuser" @@ -11280,7 +10869,7 @@ "CREATEDB", "CREATEROLE" ], - "db_owner": true, + "db_owner": false, "password": "secret", "roles": [ "pgedge_superuser" @@ -11293,7 +10882,7 @@ "CREATEDB", "CREATEROLE" ], - "db_owner": true, + "db_owner": false, "password": "secret", "roles": [ "pgedge_superuser" @@ -11507,10 +11096,137 @@ }, "cpus": "500m", "host_ids": [ + "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "de3b1388-1f0c-42f1-a86c-59ab72f255ec" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, + "port": 0, + "service_id": "analytics-service", + "service_type": "mcp", + "version": "latest" + }, + { + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "de3b1388-1f0c-42f1-a86c-59ab72f255ec" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "analytics-service", "service_type": "mcp", @@ -11524,10 +11240,65 @@ }, "cpus": "500m", "host_ids": [ + "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "de3b1388-1f0c-42f1-a86c-59ab72f255ec" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "analytics-service", "service_type": "mcp", @@ -11541,10 +11312,65 @@ }, "cpus": "500m", "host_ids": [ + "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "de3b1388-1f0c-42f1-a86c-59ab72f255ec" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "analytics-service", "service_type": "mcp", @@ -11613,7 +11439,7 @@ "CREATEDB", "CREATEROLE" ], - "db_owner": true, + "db_owner": false, "password": "secret", "roles": [ "pgedge_superuser" @@ -11626,7 +11452,7 @@ "CREATEDB", "CREATEROLE" ], - "db_owner": true, + "db_owner": false, "password": "secret", "roles": [ "pgedge_superuser" @@ -11639,7 +11465,7 @@ "CREATEDB", "CREATEROLE" ], - "db_owner": true, + "db_owner": false, "password": "secret", "roles": [ "pgedge_superuser" @@ -12177,27 +12003,65 @@ }, "cpus": "500m", "host_ids": [ + "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "de3b1388-1f0c-42f1-a86c-59ab72f255ec" ], "memory": "512M", - "port": 0, - "service_id": "analytics-service", - "service_type": "mcp", - "version": "latest" - }, - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } }, - "cpus": "500m", - "host_ids": [ - "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "de3b1388-1f0c-42f1-a86c-59ab72f255ec" - ], - "memory": "512M", "port": 0, "service_id": "analytics-service", "service_type": "mcp", @@ -12212,26 +12076,64 @@ "cpus": "500m", "host_ids": [ "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "de3b1388-1f0c-42f1-a86c-59ab72f255ec" - ], - "memory": "512M", - "port": 0, - "service_id": "analytics-service", - "service_type": "mcp", - "version": "latest" - }, - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." - }, - "cpus": "500m", - "host_ids": [ "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "de3b1388-1f0c-42f1-a86c-59ab72f255ec" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "analytics-service", "service_type": "mcp", @@ -12932,7 +12834,7 @@ "services": { "type": "array", "items": { - "$ref": "#/components/schemas/ServiceSpec" + "$ref": "#/components/schemas/ServiceSpec2" }, "description": "Service instances to run alongside the database (e.g., MCP servers).", "example": [ @@ -12948,40 +12850,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - }, - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - }, - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." - }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -12999,6 +12921,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -13632,6 +13608,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -13649,6 +13679,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -14346,7 +14430,7 @@ "services": { "type": "array", "items": { - "$ref": "#/components/schemas/ServiceSpec" + "$ref": "#/components/schemas/ServiceSpec3" }, "description": "Service instances to run alongside the database (e.g., MCP servers).", "example": [ @@ -14362,6 +14446,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -14379,6 +14517,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -15199,29 +15391,66 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - }, - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." - }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - }, - { + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" + }, + { "config": { "llm_model": "gpt-4", "llm_provider": "openai", @@ -15233,6 +15462,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -15704,245 +15987,178 @@ "source_node_name": "n1" }, "source_node": "n1" - } - ], - "minItems": 1, - "maxItems": 9 - }, - "orchestrator_opts": { - "$ref": "#/components/schemas/OrchestratorOpts" - }, - "port": { - "type": "integer", - "description": "The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature.", - "example": 5432, - "format": "int64", - "minimum": 0, - "maximum": 65535 - }, - "postgres_version": { - "type": "string", - "description": "The Postgres version in 'major.minor' format.", - "example": "17.6", - "pattern": "^\\d{2}\\.\\d{1,2}$" - }, - "postgresql_conf": { - "type": "object", - "description": "Additional postgresql.conf settings. Will be merged with the settings provided by control-plane.", - "example": { - "max_connections": 1000 - }, - "maxLength": 64, - "additionalProperties": true - }, - "restore_config": { - "$ref": "#/components/schemas/RestoreConfigSpec" - }, - "services": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ServiceSpec" - }, - "description": "Service instances to run alongside the database (e.g., MCP servers).", - "example": [ + }, { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." + "backup_config": { + "repositories": [ + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + }, + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + }, + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + } + ], + "schedules": [ + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + } + ] }, "cpus": "500m", "host_ids": [ "76f9b8c0-4958-11f0-a489-3bb29577c696", "76f9b8c0-4958-11f0-a489-3bb29577c696" ], - "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - }, - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." - }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - } - ] - }, - "spock_version": { - "type": "string", - "description": "The major version of the Spock extension.", - "example": "5", - "pattern": "^\\d{1}$" - } - }, - "example": { - "backup_config": { - "repositories": [ - { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" - }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" - }, - { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" + "memory": "500M", + "name": "n1", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" - }, - { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" + "port": 5432, + "postgres_version": "17.6", + "postgresql_conf": { + "max_connections": 1000 }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" - } - ], - "schedules": [ - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - }, - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - }, - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - } - ] - }, - "cpus": "500m", - "database_name": "northwind", - "database_users": [ - { - "attributes": [ - "LOGIN", - "CREATEDB", - "CREATEROLE" - ], - "db_owner": false, - "password": "secret", - "roles": [ - "pgedge_superuser" - ], - "username": "admin" - }, - { - "attributes": [ - "LOGIN", - "CREATEDB", - "CREATEROLE" - ], - "db_owner": false, - "password": "secret", - "roles": [ - "pgedge_superuser" - ], - "username": "admin" - }, - { - "attributes": [ - "LOGIN", - "CREATEDB", - "CREATEROLE" - ], - "db_owner": false, - "password": "secret", - "roles": [ - "pgedge_superuser" - ], - "username": "admin" - } - ], - "memory": "500M", - "nodes": [ - { - "backup_config": { - "repositories": [ - { + "restore_config": { + "repository": { "azure_account": "pgedge-backups", "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", "azure_endpoint": "blob.core.usgovcloudapi.net", "azure_key": "YXpLZXk=", "base_path": "/backups", "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" }, "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", "gcs_endpoint": "localhost", "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", "s3_endpoint": "s3.us-east-1.amazonaws.com", "s3_key": "AKIAIOSFODNN7EXAMPLE", @@ -15950,169 +16166,486 @@ "s3_region": "us-east-1", "type": "s3" }, - { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" - }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" + "restore_options": { + "set": "20250505-153628F", + "target": "123456", + "type": "xid" }, - { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" + "source_database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "source_database_name": "northwind", + "source_node_name": "n1" + }, + "source_node": "n1" + } + ], + "minItems": 1, + "maxItems": 9 + }, + "orchestrator_opts": { + "$ref": "#/components/schemas/OrchestratorOpts" + }, + "port": { + "type": "integer", + "description": "The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature.", + "example": 5432, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, + "postgres_version": { + "type": "string", + "description": "The Postgres version in 'major.minor' format.", + "example": "17.6", + "pattern": "^\\d{2}\\.\\d{1,2}$" + }, + "postgresql_conf": { + "type": "object", + "description": "Additional postgresql.conf settings. Will be merged with the settings provided by control-plane.", + "example": { + "max_connections": 1000 + }, + "maxLength": 64, + "additionalProperties": true + }, + "restore_config": { + "$ref": "#/components/schemas/RestoreConfigSpec" + }, + "services": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceSpec4" + }, + "description": "Service instances to run alongside the database (e.g., MCP servers).", + "example": [ + { + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] } + }, + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" + }, + { + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" ], - "schedules": [ - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - }, - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - }, - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] } - ] + }, + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "500M", - "name": "n1", - "orchestrator_opts": { - "swarm": { - "extra_labels": { - "traefik.enable": "true", - "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" - }, - "extra_networks": [ - { - "aliases": [ - "pg-db", - "db-alias" - ], - "driver_opts": { - "com.docker.network.endpoint.expose": "true" - }, - "id": "traefik-public" + { + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" }, - { - "aliases": [ - "pg-db", - "db-alias" - ], - "driver_opts": { - "com.docker.network.endpoint.expose": "true" + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" }, - "id": "traefik-public" - }, - { - "aliases": [ - "pg-db", - "db-alias" - ], - "driver_opts": { - "com.docker.network.endpoint.expose": "true" + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" }, - "id": "traefik-public" - } - ], - "extra_volumes": [ - { - "destination_path": "/backups/container", - "host_path": "/Users/user/backups/host" - }, - { - "destination_path": "/backups/container", - "host_path": "/Users/user/backups/host" - }, - { - "destination_path": "/backups/container", - "host_path": "/Users/user/backups/host" - } - ] - } - }, - "port": 5432, - "postgres_version": "17.6", - "postgresql_conf": { - "max_connections": 1000 + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" }, - "restore_config": { - "repository": { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" - }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" + { + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" + } + ] + }, + "spock_version": { + "type": "string", + "description": "The major version of the Spock extension.", + "example": "5", + "pattern": "^\\d{1}$" + } + }, + "example": { + "backup_config": { + "repositories": [ + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" }, - "restore_options": { - "set": "20250505-153628F", - "target": "123456", - "type": "xid" + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + }, + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" }, - "source_database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "source_database_name": "northwind", - "source_node_name": "n1" + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" }, - "source_node": "n1" + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + } + ], + "schedules": [ + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + } + ] + }, + "cpus": "500m", + "database_name": "northwind", + "database_users": [ + { + "attributes": [ + "LOGIN", + "CREATEDB", + "CREATEROLE" + ], + "db_owner": false, + "password": "secret", + "roles": [ + "pgedge_superuser" + ], + "username": "admin" + }, + { + "attributes": [ + "LOGIN", + "CREATEDB", + "CREATEROLE" + ], + "db_owner": false, + "password": "secret", + "roles": [ + "pgedge_superuser" + ], + "username": "admin" }, + { + "attributes": [ + "LOGIN", + "CREATEDB", + "CREATEROLE" + ], + "db_owner": false, + "password": "secret", + "roles": [ + "pgedge_superuser" + ], + "username": "admin" + } + ], + "memory": "500M", + "nodes": [ { "backup_config": { "repositories": [ @@ -16405,6 +16938,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -16422,6 +17009,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -16433,12 +17074,66 @@ "llm_provider": "openai", "openai_api_key": "sk-..." }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -16504,35 +17199,224 @@ ], "username": "admin" }, - { - "attributes": [ - "LOGIN", - "CREATEDB", - "CREATEROLE" - ], - "db_owner": false, - "password": "secret", - "roles": [ - "pgedge_superuser" - ], - "username": "admin" - } - ], - "maxItems": 16 - }, - "memory": { - "type": "string", - "description": "The amount of memory in SI or IEC notation to allocate for the database and to use for tuning Postgres. Defaults to the total available memory on the host. Whether this limit is enforced depends on the orchestrator.", - "example": "500M", - "maxLength": 16 - }, - "nodes": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DatabaseNodeSpec5" - }, - "description": "The Spock nodes for this database.", - "example": [ + { + "attributes": [ + "LOGIN", + "CREATEDB", + "CREATEROLE" + ], + "db_owner": false, + "password": "secret", + "roles": [ + "pgedge_superuser" + ], + "username": "admin" + } + ], + "maxItems": 16 + }, + "memory": { + "type": "string", + "description": "The amount of memory in SI or IEC notation to allocate for the database and to use for tuning Postgres. Defaults to the total available memory on the host. Whether this limit is enforced depends on the orchestrator.", + "example": "500M", + "maxLength": 16 + }, + "nodes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DatabaseNodeSpec5" + }, + "description": "The Spock nodes for this database.", + "example": [ + { + "backup_config": { + "repositories": [ + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + }, + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + }, + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + } + ], + "schedules": [ + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + } + ] + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "500M", + "name": "n1", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, + "port": 5432, + "postgres_version": "17.6", + "postgresql_conf": { + "max_connections": 1000 + }, + "restore_config": { + "repository": { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + }, + "restore_options": { + "set": "20250505-153628F", + "target": "123456", + "type": "xid" + }, + "source_database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "source_database_name": "northwind", + "source_node_name": "n1" + }, + "source_node": "n1" + }, { "backup_config": { "repositories": [ @@ -16592,45 +17476,257 @@ "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", "storage-upload-chunk-size": "5MiB" }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" - } - ], - "schedules": [ - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - }, - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - }, - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - } - ] + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + } + ], + "schedules": [ + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + } + ] + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "500M", + "name": "n1", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, + "port": 5432, + "postgres_version": "17.6", + "postgresql_conf": { + "max_connections": 1000 + }, + "restore_config": { + "repository": { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + }, + "restore_options": { + "set": "20250505-153628F", + "target": "123456", + "type": "xid" + }, + "source_database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "source_database_name": "northwind", + "source_node_name": "n1" + }, + "source_node": "n1" + } + ], + "minItems": 1, + "maxItems": 9 + }, + "orchestrator_opts": { + "$ref": "#/components/schemas/OrchestratorOpts" + }, + "port": { + "type": "integer", + "description": "The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature.", + "example": 5432, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, + "postgres_version": { + "type": "string", + "description": "The Postgres version in 'major.minor' format.", + "example": "17.6", + "pattern": "^\\d{2}\\.\\d{1,2}$" + }, + "postgresql_conf": { + "type": "object", + "description": "Additional postgresql.conf settings. Will be merged with the settings provided by control-plane.", + "example": { + "max_connections": 1000 + }, + "maxLength": 64, + "additionalProperties": true + }, + "restore_config": { + "$ref": "#/components/schemas/RestoreConfigSpec" + }, + "services": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ServiceSpec5" + }, + "description": "Service instances to run alongside the database (e.g., MCP servers).", + "example": [ + { + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" + }, + { + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." }, "cpus": "500m", "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", "76f9b8c0-4958-11f0-a489-3bb29577c696" ], - "memory": "500M", - "name": "n1", + "memory": "512M", "orchestrator_opts": { "swarm": { "extra_labels": { @@ -16685,141 +17781,92 @@ ] } }, - "port": 5432, - "postgres_version": "17.6", - "postgresql_conf": { - "max_connections": 1000 - }, - "restore_config": { - "repository": { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" - }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" - }, - "restore_options": { - "set": "20250505-153628F", - "target": "123456", - "type": "xid" - }, - "source_database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "source_database_name": "northwind", - "source_node_name": "n1" - }, - "source_node": "n1" + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" }, { - "backup_config": { - "repositories": [ - { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" - }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" }, - { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" - }, - { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" - } - ], - "schedules": [ - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - }, - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - }, - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - } - ] + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" + }, + { + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." }, "cpus": "500m", "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", "76f9b8c0-4958-11f0-a489-3bb29577c696" ], - "memory": "500M", - "name": "n1", + "memory": "512M", "orchestrator_opts": { "swarm": { "extra_labels": { @@ -16874,110 +17921,6 @@ ] } }, - "port": 5432, - "postgres_version": "17.6", - "postgresql_conf": { - "max_connections": 1000 - }, - "restore_config": { - "repository": { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" - }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" - }, - "restore_options": { - "set": "20250505-153628F", - "target": "123456", - "type": "xid" - }, - "source_database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "source_database_name": "northwind", - "source_node_name": "n1" - }, - "source_node": "n1" - } - ], - "minItems": 1, - "maxItems": 9 - }, - "orchestrator_opts": { - "$ref": "#/components/schemas/OrchestratorOpts" - }, - "port": { - "type": "integer", - "description": "The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature.", - "example": 5432, - "format": "int64", - "minimum": 0, - "maximum": 65535 - }, - "postgres_version": { - "type": "string", - "description": "The Postgres version in 'major.minor' format.", - "example": "17.6", - "pattern": "^\\d{2}\\.\\d{1,2}$" - }, - "postgresql_conf": { - "type": "object", - "description": "Additional postgresql.conf settings. Will be merged with the settings provided by control-plane.", - "example": { - "max_connections": 1000 - }, - "maxLength": 64, - "additionalProperties": true - }, - "restore_config": { - "$ref": "#/components/schemas/RestoreConfigSpec" - }, - "services": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ServiceSpec" - }, - "description": "Service instances to run alongside the database (e.g., MCP servers).", - "example": [ - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." - }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - }, - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." - }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -17566,347 +18509,266 @@ "postgresql_conf": { "max_connections": 1000 }, - "restore_config": { - "repository": { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" - }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" - }, - "restore_options": { - "set": "20250505-153628F", - "target": "123456", - "type": "xid" - }, - "source_database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "source_database_name": "northwind", - "source_node_name": "n1" - }, - "services": [ - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." - }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - }, - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." - }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - } - ], - "spock_version": "5" - }, - "required": [ - "database_name", - "nodes" - ] - }, - "DatabaseSpec6": { - "type": "object", - "properties": { - "backup_config": { - "$ref": "#/components/schemas/BackupConfigSpec" - }, - "cpus": { - "type": "string", - "description": "The number of CPUs to allocate for the database and to use for tuning Postgres. Defaults to the number of available CPUs on the host. Can include an SI suffix, e.g. '500m' for 500 millicpus. Whether this limit is enforced depends on the orchestrator.", - "example": "500m", - "pattern": "^[0-9]+(\\.[0-9]{1,3}|m)?$" - }, - "database_name": { - "type": "string", - "description": "The name of the Postgres database.", - "example": "northwind", - "minLength": 1, - "maxLength": 31 - }, - "database_users": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DatabaseUserSpec" - }, - "description": "The users to create for this database.", - "example": [ - { - "attributes": [ - "LOGIN", - "CREATEDB", - "CREATEROLE" - ], - "db_owner": false, - "password": "secret", - "roles": [ - "pgedge_superuser" - ], - "username": "admin" - }, - { - "attributes": [ - "LOGIN", - "CREATEDB", - "CREATEROLE" - ], - "db_owner": false, - "password": "secret", - "roles": [ - "pgedge_superuser" - ], - "username": "admin" - }, - { - "attributes": [ - "LOGIN", - "CREATEDB", - "CREATEROLE" - ], - "db_owner": false, - "password": "secret", - "roles": [ - "pgedge_superuser" - ], - "username": "admin" - } - ], - "maxItems": 16 - }, - "memory": { - "type": "string", - "description": "The amount of memory in SI or IEC notation to allocate for the database and to use for tuning Postgres. Defaults to the total available memory on the host. Whether this limit is enforced depends on the orchestrator.", - "example": "500M", - "maxLength": 16 - }, - "nodes": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DatabaseNodeSpec6" + "restore_config": { + "repository": { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" }, - "description": "The Spock nodes for this database.", - "example": [ - { - "backup_config": { - "repositories": [ + "restore_options": { + "set": "20250505-153628F", + "target": "123456", + "type": "xid" + }, + "source_database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "source_database_name": "northwind", + "source_node_name": "n1" + }, + "services": [ + { + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" + "id": "traefik-public" }, { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" + "id": "traefik-public" }, { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" + "id": "traefik-public" } ], - "schedules": [ + "extra_volumes": [ { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" }, { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" }, { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" } ] - }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "500M", - "name": "n1", - "orchestrator_opts": { - "swarm": { - "extra_labels": { - "traefik.enable": "true", - "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" - }, - "extra_networks": [ - { - "aliases": [ - "pg-db", - "db-alias" - ], - "driver_opts": { - "com.docker.network.endpoint.expose": "true" - }, - "id": "traefik-public" - }, - { - "aliases": [ - "pg-db", - "db-alias" - ], - "driver_opts": { - "com.docker.network.endpoint.expose": "true" - }, - "id": "traefik-public" + } + }, + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" + }, + { + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" }, - { - "aliases": [ - "pg-db", - "db-alias" - ], - "driver_opts": { - "com.docker.network.endpoint.expose": "true" - }, - "id": "traefik-public" - } - ], - "extra_volumes": [ - { - "destination_path": "/backups/container", - "host_path": "/Users/user/backups/host" + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" }, - { - "destination_path": "/backups/container", - "host_path": "/Users/user/backups/host" + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" }, - { - "destination_path": "/backups/container", - "host_path": "/Users/user/backups/host" - } - ] - } - }, - "port": 5432, - "postgres_version": "17.6", - "postgresql_conf": { - "max_connections": 1000 - }, - "restore_config": { - "repository": { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" - }, - "restore_options": { - "set": "20250505-153628F", - "target": "123456", - "type": "xid" - }, - "source_database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "source_database_name": "northwind", - "source_node_name": "n1" - }, - "source_node": "n1" + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" + } + ], + "spock_version": "5" + }, + "required": [ + "database_name", + "nodes" + ] + }, + "DatabaseSpec6": { + "type": "object", + "properties": { + "backup_config": { + "$ref": "#/components/schemas/BackupConfigSpec" + }, + "cpus": { + "type": "string", + "description": "The number of CPUs to allocate for the database and to use for tuning Postgres. Defaults to the number of available CPUs on the host. Can include an SI suffix, e.g. '500m' for 500 millicpus. Whether this limit is enforced depends on the orchestrator.", + "example": "500m", + "pattern": "^[0-9]+(\\.[0-9]{1,3}|m)?$" + }, + "database_name": { + "type": "string", + "description": "The name of the Postgres database.", + "example": "northwind", + "minLength": 1, + "maxLength": 31 + }, + "database_users": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DatabaseUserSpec" + }, + "description": "The users to create for this database.", + "example": [ + { + "attributes": [ + "LOGIN", + "CREATEDB", + "CREATEROLE" + ], + "db_owner": false, + "password": "secret", + "roles": [ + "pgedge_superuser" + ], + "username": "admin" }, + { + "attributes": [ + "LOGIN", + "CREATEDB", + "CREATEROLE" + ], + "db_owner": false, + "password": "secret", + "roles": [ + "pgedge_superuser" + ], + "username": "admin" + }, + { + "attributes": [ + "LOGIN", + "CREATEDB", + "CREATEROLE" + ], + "db_owner": false, + "password": "secret", + "roles": [ + "pgedge_superuser" + ], + "username": "admin" + } + ], + "maxItems": 16 + }, + "memory": { + "type": "string", + "description": "The amount of memory in SI or IEC notation to allocate for the database and to use for tuning Postgres. Defaults to the total available memory on the host. Whether this limit is enforced depends on the orchestrator.", + "example": "500M", + "maxLength": 16 + }, + "nodes": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DatabaseNodeSpec6" + }, + "description": "The Spock nodes for this database.", + "example": [ { "backup_config": { "repositories": [ @@ -18321,7 +19183,7 @@ "services": { "type": "array", "items": { - "$ref": "#/components/schemas/ServiceSpec" + "$ref": "#/components/schemas/ServiceSpec6" }, "description": "Service instances to run alongside the database (e.g., MCP servers).", "example": [ @@ -18337,6 +19199,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -18354,23 +19270,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - }, - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -18411,116 +19364,305 @@ "s3_region": "us-east-1", "type": "s3" }, - { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" - }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + }, + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + } + ], + "schedules": [ + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + } + ] + }, + "cpus": "500m", + "database_name": "northwind", + "database_users": [ + { + "attributes": [ + "LOGIN", + "CREATEDB", + "CREATEROLE" + ], + "db_owner": false, + "password": "secret", + "roles": [ + "pgedge_superuser" + ], + "username": "admin" + }, + { + "attributes": [ + "LOGIN", + "CREATEDB", + "CREATEROLE" + ], + "db_owner": false, + "password": "secret", + "roles": [ + "pgedge_superuser" + ], + "username": "admin" + }, + { + "attributes": [ + "LOGIN", + "CREATEDB", + "CREATEROLE" + ], + "db_owner": false, + "password": "secret", + "roles": [ + "pgedge_superuser" + ], + "username": "admin" + } + ], + "memory": "500M", + "nodes": [ + { + "backup_config": { + "repositories": [ + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + }, + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + }, + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", + "storage-upload-chunk-size": "5MiB" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "retention_full": 2, + "retention_full_type": "count", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + } + ], + "schedules": [ + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + } + ] + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "500M", + "name": "n1", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, + "port": 5432, + "postgres_version": "17.6", + "postgresql_conf": { + "max_connections": 1000 }, - { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab", - "storage-upload-chunk-size": "5MiB" + "restore_config": { + "repository": { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "retention_full": 2, - "retention_full_type": "count", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" - } - ], - "schedules": [ - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - }, - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" + "restore_options": { + "set": "20250505-153628F", + "target": "123456", + "type": "xid" + }, + "source_database_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "source_database_name": "northwind", + "source_node_name": "n1" }, - { - "cron_expression": "0 6 * * ?", - "id": "daily-full-backup", - "type": "full" - } - ] - }, - "cpus": "500m", - "database_name": "northwind", - "database_users": [ - { - "attributes": [ - "LOGIN", - "CREATEDB", - "CREATEROLE" - ], - "db_owner": false, - "password": "secret", - "roles": [ - "pgedge_superuser" - ], - "username": "admin" - }, - { - "attributes": [ - "LOGIN", - "CREATEDB", - "CREATEROLE" - ], - "db_owner": false, - "password": "secret", - "roles": [ - "pgedge_superuser" - ], - "username": "admin" + "source_node": "n1" }, - { - "attributes": [ - "LOGIN", - "CREATEDB", - "CREATEROLE" - ], - "db_owner": false, - "password": "secret", - "roles": [ - "pgedge_superuser" - ], - "username": "admin" - } - ], - "memory": "500M", - "nodes": [ { "backup_config": { "repositories": [ @@ -18813,23 +19955,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - }, - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -18847,23 +20026,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - }, - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -19183,7 +20399,7 @@ "services": { "type": "array", "items": { - "$ref": "#/components/schemas/ServiceSpec" + "$ref": "#/components/schemas/ServiceSpec7" }, "description": "Service instances to run alongside the database (e.g., MCP servers).", "example": [ @@ -19199,6 +20415,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -19216,6 +20486,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -19233,6 +20557,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -19244,12 +20622,66 @@ "llm_provider": "openai", "openai_api_key": "sk-..." }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -20070,23 +21502,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", - "port": 0, - "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "service_type": "mcp", - "version": "latest" - }, - { - "config": { - "llm_model": "gpt-4", - "llm_provider": "openai", - "openai_api_key": "sk-..." + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } }, - "cpus": "500m", - "host_ids": [ - "76f9b8c0-4958-11f0-a489-3bb29577c696", - "76f9b8c0-4958-11f0-a489-3bb29577c696" - ], - "memory": "512M", "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -20104,6 +21573,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -20121,6 +21644,60 @@ "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", @@ -20163,55 +21740,7 @@ "ipv4_address": "10.24.34.2", "port": 5432 }, - "created_at": "1970-10-16T01:30:13Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": true, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" - }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" - }, - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "1970-10-16T01:30:13Z", + "created_at": "1996-08-08T19:06:06Z", "error": "failed to get patroni status: connection refused", "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", @@ -20236,11 +21765,6 @@ "provider_node": "n2", "status": "down" }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, { "name": "sub_n1n2", "provider_node": "n2", @@ -20249,9 +21773,9 @@ ], "version": "4.10.0" }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" }, { "connection_info": { @@ -20259,7 +21783,7 @@ "ipv4_address": "10.24.34.2", "port": 5432 }, - "created_at": "1970-10-16T01:30:13Z", + "created_at": "1996-08-08T19:06:06Z", "error": "failed to get patroni status: connection refused", "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", @@ -20284,11 +21808,6 @@ "provider_node": "n2", "status": "down" }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, { "name": "sub_n1n2", "provider_node": "n2", @@ -20297,9 +21816,9 @@ ], "version": "4.10.0" }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" }, { "connection_info": { @@ -20307,7 +21826,7 @@ "ipv4_address": "10.24.34.2", "port": 5432 }, - "created_at": "1970-10-16T01:30:13Z", + "created_at": "1996-08-08T19:06:06Z", "error": "failed to get patroni status: connection refused", "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", @@ -20332,11 +21851,6 @@ "provider_node": "n2", "status": "down" }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, { "name": "sub_n1n2", "provider_node": "n2", @@ -20345,16 +21859,16 @@ ], "version": "4.10.0" }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" } ] }, "state": { "type": "string", "description": "Current state of the database.", - "example": "failed", + "example": "backing_up", "enum": [ "creating", "modifying", @@ -20391,7 +21905,7 @@ "ipv4_address": "10.24.34.2", "port": 5432 }, - "created_at": "1970-10-16T01:30:13Z", + "created_at": "1996-08-08T19:06:06Z", "error": "failed to get patroni status: connection refused", "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", @@ -20416,11 +21930,6 @@ "provider_node": "n2", "status": "down" }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, { "name": "sub_n1n2", "provider_node": "n2", @@ -20429,9 +21938,9 @@ ], "version": "4.10.0" }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" }, { "connection_info": { @@ -20439,7 +21948,7 @@ "ipv4_address": "10.24.34.2", "port": 5432 }, - "created_at": "1970-10-16T01:30:13Z", + "created_at": "1996-08-08T19:06:06Z", "error": "failed to get patroni status: connection refused", "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", @@ -20464,11 +21973,6 @@ "provider_node": "n2", "status": "down" }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, { "name": "sub_n1n2", "provider_node": "n2", @@ -20477,9 +21981,9 @@ ], "version": "4.10.0" }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" }, { "connection_info": { @@ -20487,7 +21991,7 @@ "ipv4_address": "10.24.34.2", "port": 5432 }, - "created_at": "1970-10-16T01:30:13Z", + "created_at": "1996-08-08T19:06:06Z", "error": "failed to get patroni status: connection refused", "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", @@ -20512,11 +22016,6 @@ "provider_node": "n2", "status": "down" }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, { "name": "sub_n1n2", "provider_node": "n2", @@ -20525,12 +22024,12 @@ ], "version": "4.10.0" }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" } ], - "state": "creating", + "state": "deleting", "tenant_id": "8210ec10-2dca-406c-ac4a-0661d2189954", "updated_at": "2025-01-01T02:30:00Z" }, @@ -20796,12 +22295,12 @@ "type": "boolean", "description": "If true, skip the health validations that prevent running failover on a healthy cluster.", "default": false, - "example": false + "example": true } }, "example": { "candidate_instance_id": "68f50878-44d2-4524-a823-e31bd478706d-n1-689qacsi", - "skip_validation": true + "skip_validation": false } }, "FailoverDatabaseNodeResponse": { @@ -20935,6 +22434,10 @@ "postgres_version": "17.6", "spock_version": "5" }, + { + "postgres_version": "17.6", + "spock_version": "5" + }, { "postgres_version": "17.6", "spock_version": "5" @@ -20985,6 +22488,14 @@ "updated_at": "2021-07-01T12:34:56Z" }, "supported_pgedge_versions": [ + { + "postgres_version": "17.6", + "spock_version": "5" + }, + { + "postgres_version": "17.6", + "spock_version": "5" + }, { "postgres_version": "17.6", "spock_version": "5" @@ -21041,25 +22552,7 @@ "type": "object", "description": "The status of each component of the host.", "example": { - "Eius at.": { - "details": { - "alarms": [ - "3: NOSPACE" - ] - }, - "error": "failed to connect to etcd", - "healthy": false - }, - "Placeat illo dolore totam accusamus alias ipsa.": { - "details": { - "alarms": [ - "3: NOSPACE" - ] - }, - "error": "failed to connect to etcd", - "healthy": false - }, - "Ut dolorem.": { + "Praesentium ut dolorem sapiente.": { "details": { "alarms": [ "3: NOSPACE" @@ -21092,25 +22585,7 @@ }, "example": { "components": { - "Et aut aut.": { - "details": { - "alarms": [ - "3: NOSPACE" - ] - }, - "error": "failed to connect to etcd", - "healthy": false - }, - "Minus dolore eos et sunt culpa animi.": { - "details": { - "alarms": [ - "3: NOSPACE" - ] - }, - "error": "failed to connect to etcd", - "healthy": false - }, - "Rem culpa.": { + "Dolore totam accusamus.": { "details": { "alarms": [ "3: NOSPACE" @@ -21154,7 +22629,7 @@ "created_at": { "type": "string", "description": "The time that the instance was created.", - "example": "1972-03-21T12:41:47Z", + "example": "1987-01-18T23:06:23Z", "format": "date-time" }, "error": { @@ -21185,7 +22660,7 @@ }, "state": { "type": "string", - "example": "stopped", + "example": "creating", "enum": [ "creating", "modifying", @@ -21200,13 +22675,13 @@ "status_updated_at": { "type": "string", "description": "The time that the instance status information was last updated.", - "example": "1995-02-03T18:46:08Z", + "example": "2015-08-25T11:23:33Z", "format": "date-time" }, "updated_at": { "type": "string", "description": "The time that the instance was last modified.", - "example": "1984-04-26T06:38:50Z", + "example": "1986-06-02T18:22:13Z", "format": "date-time" } }, @@ -21217,7 +22692,7 @@ "ipv4_address": "10.24.34.2", "port": 5432 }, - "created_at": "2003-06-04T21:30:35Z", + "created_at": "1983-08-30T09:21:42Z", "error": "failed to get patroni status: connection refused", "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", @@ -21242,11 +22717,6 @@ "provider_node": "n2", "status": "down" }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, { "name": "sub_n1n2", "provider_node": "n2", @@ -21255,9 +22725,9 @@ ], "version": "4.10.0" }, - "state": "degraded", - "status_updated_at": "1982-02-16T16:16:42Z", - "updated_at": "1993-11-23T04:43:18Z" + "state": "available", + "status_updated_at": "1983-06-11T05:45:56Z", + "updated_at": "1971-05-19T18:59:31Z" }, "required": [ "id", @@ -21302,7 +22772,7 @@ "patroni_paused": { "type": "boolean", "description": "True if Patroni is paused for this instance.", - "example": false + "example": true }, "patroni_state": { "type": "string", @@ -21323,99 +22793,810 @@ "example": "18.1" } }, - "description": "Postgres status information for a pgEdge instance.", - "example": { - "patroni_paused": false, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - } + "description": "Postgres status information for a pgEdge instance.", + "example": { + "patroni_paused": true, + "patroni_state": "unknown", + "pending_restart": true, + "role": "primary", + "version": "18.1" + } + }, + "InstanceSpockStatus": { + "type": "object", + "properties": { + "read_only": { + "type": "string", + "description": "The current spock.readonly setting.", + "example": "off" + }, + "subscriptions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/InstanceSubscription" + }, + "description": "Status information for this instance's Spock subscriptions.", + "example": [ + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + } + ] + }, + "version": { + "type": "string", + "description": "The version of Spock for this instance.", + "example": "4.10.0" + } + }, + "description": "Spock status information for a pgEdge instance.", + "example": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + } + ], + "version": "4.10.0" + } + }, + "InstanceSubscription": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the subscription.", + "example": "sub_n1n2" + }, + "provider_node": { + "type": "string", + "description": "The Spock node name of the provider for this subscription.", + "example": "n2", + "pattern": "n[0-9]+" + }, + "status": { + "type": "string", + "description": "The current status of the subscription.", + "example": "down" + } + }, + "description": "Status information for a Spock subscription.", + "example": { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + "required": [ + "provider_node", + "name", + "status" + ] + }, + "ListDatabaseTasksResponse": { + "type": "object", + "properties": { + "tasks": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Task" + }, + "description": "The tasks for the given database.", + "example": [ + { + "completed_at": "2025-06-18T16:52:35Z", + "created_at": "2025-06-18T16:52:05Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", + "type": "create" + }, + { + "completed_at": "2025-06-18T16:52:35Z", + "created_at": "2025-06-18T16:52:05Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", + "type": "create" + }, + { + "completed_at": "2025-06-18T16:52:35Z", + "created_at": "2025-06-18T16:52:05Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", + "type": "create" + } + ] + } + }, + "example": { + "tasks": [ + { + "completed_at": "2025-06-18T17:54:36Z", + "created_at": "2025-06-18T17:54:28Z", + "database_id": "storefront", + "entity_id": "storefront", + "instance_id": "storefront-n1-689qacsi", + "scope": "database", + "status": "completed", + "task_id": "0197842d-9082-7496-b787-77bd2e11809f", + "type": "node_backup" + }, + { + "completed_at": "2025-06-18T17:54:04Z", + "created_at": "2025-06-18T17:53:17Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "0197842c-7c4f-7a8c-829e-7405c2a41c8c", + "type": "update" + }, + { + "completed_at": "2025-06-18T17:23:28Z", + "created_at": "2025-06-18T17:23:14Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "01978410-fb5d-7cd2-bbd2-66c0bf929dc0", + "type": "update" + }, + { + "completed_at": "2025-06-18T16:52:35Z", + "created_at": "2025-06-18T16:52:05Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", + "type": "create" + } + ] + }, + "required": [ + "tasks" + ] }, - "InstanceSpockStatus": { + "ListDatabasesResponse": { "type": "object", "properties": { - "read_only": { - "type": "string", - "description": "The current spock.readonly setting.", - "example": "off" - }, - "subscriptions": { + "databases": { "type": "array", "items": { - "$ref": "#/components/schemas/InstanceSubscription" + "$ref": "#/components/schemas/DatabaseSummary" }, - "description": "Status information for this instance's Spock subscriptions.", + "description": "The databases managed by this cluster.", "example": [ { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" + "created_at": "2025-01-01T01:30:00Z", + "id": "02f1a7db-fca8-4521-b57a-2a375c1ced51", + "instances": [ + { + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 5432 + }, + "created_at": "1996-08-08T19:06:06Z", + "error": "failed to get patroni status: connection refused", + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "node_name": "n1", + "postgres": { + "patroni_paused": true, + "patroni_state": "unknown", + "pending_restart": true, + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + } + ], + "version": "4.10.0" + }, + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" + }, + { + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 5432 + }, + "created_at": "1996-08-08T19:06:06Z", + "error": "failed to get patroni status: connection refused", + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "node_name": "n1", + "postgres": { + "patroni_paused": true, + "patroni_state": "unknown", + "pending_restart": true, + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + } + ], + "version": "4.10.0" + }, + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" + }, + { + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 5432 + }, + "created_at": "1996-08-08T19:06:06Z", + "error": "failed to get patroni status: connection refused", + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "node_name": "n1", + "postgres": { + "patroni_paused": true, + "patroni_state": "unknown", + "pending_restart": true, + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + } + ], + "version": "4.10.0" + }, + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" + }, + { + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 5432 + }, + "created_at": "1996-08-08T19:06:06Z", + "error": "failed to get patroni status: connection refused", + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "node_name": "n1", + "postgres": { + "patroni_paused": true, + "patroni_state": "unknown", + "pending_restart": true, + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + } + ], + "version": "4.10.0" + }, + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" + } + ], + "state": "available", + "tenant_id": "8210ec10-2dca-406c-ac4a-0661d2189954", + "updated_at": "2025-01-01T02:30:00Z" }, { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" + "created_at": "2025-01-01T01:30:00Z", + "id": "02f1a7db-fca8-4521-b57a-2a375c1ced51", + "instances": [ + { + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 5432 + }, + "created_at": "1996-08-08T19:06:06Z", + "error": "failed to get patroni status: connection refused", + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "node_name": "n1", + "postgres": { + "patroni_paused": true, + "patroni_state": "unknown", + "pending_restart": true, + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + } + ], + "version": "4.10.0" + }, + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" + }, + { + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 5432 + }, + "created_at": "1996-08-08T19:06:06Z", + "error": "failed to get patroni status: connection refused", + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "node_name": "n1", + "postgres": { + "patroni_paused": true, + "patroni_state": "unknown", + "pending_restart": true, + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + } + ], + "version": "4.10.0" + }, + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" + }, + { + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 5432 + }, + "created_at": "1996-08-08T19:06:06Z", + "error": "failed to get patroni status: connection refused", + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "node_name": "n1", + "postgres": { + "patroni_paused": true, + "patroni_state": "unknown", + "pending_restart": true, + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + } + ], + "version": "4.10.0" + }, + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" + }, + { + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 5432 + }, + "created_at": "1996-08-08T19:06:06Z", + "error": "failed to get patroni status: connection refused", + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "node_name": "n1", + "postgres": { + "patroni_paused": true, + "patroni_state": "unknown", + "pending_restart": true, + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "down" + } + ], + "version": "4.10.0" + }, + "state": "creating", + "status_updated_at": "1971-06-17T15:27:08Z", + "updated_at": "2009-02-16T03:06:12Z" + } + ], + "state": "available", + "tenant_id": "8210ec10-2dca-406c-ac4a-0661d2189954", + "updated_at": "2025-01-01T02:30:00Z" } ] - }, - "version": { - "type": "string", - "description": "The version of Spock for this instance.", - "example": "4.10.0" } }, - "description": "Spock status information for a pgEdge instance.", "example": { - "read_only": "off", - "subscriptions": [ + "databases": [ { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" + "created_at": "2025-06-17T20:05:10Z", + "id": "inventory", + "instances": [ + { + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 5432 + }, + "created_at": "2025-06-17T20:05:10Z", + "host_id": "us-east-1", + "id": "inventory-n1-689qacsi", + "node_name": "n1", + "postgres": { + "patroni_state": "running", + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n3", + "provider_node": "n3", + "status": "replicating" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "replicating" + } + ], + "version": "4.0.10" + }, + "state": "available", + "status_updated_at": "2025-06-17T20:05:10Z", + "updated_at": "2025-06-17T20:05:10Z" + }, + { + "connection_info": { + "hostname": "i-058731542fee493f.ec2.internal", + "ipv4_address": "10.24.35.2", + "port": 5432 + }, + "created_at": "2025-06-17T20:05:10Z", + "host_id": "ap-south-1", + "id": "inventory-n2-9ptayhma", + "node_name": "n2", + "postgres": { + "patroni_state": "running", + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n2n1", + "provider_node": "n1", + "status": "replicating" + }, + { + "name": "sub_n2n3", + "provider_node": "n3", + "status": "replicating" + } + ], + "version": "4.0.10" + }, + "state": "available", + "status_updated_at": "2025-06-17T20:05:10Z", + "updated_at": "2025-06-17T20:05:10Z" + }, + { + "connection_info": { + "hostname": "i-494027b7b53f6a23.ec2.internal", + "ipv4_address": "10.24.36.2", + "port": 5432 + }, + "created_at": "2025-06-17T20:05:10Z", + "host_id": "eu-central-1", + "id": "inventory-n3-ant97dj4", + "node_name": "n3", + "postgres": { + "patroni_state": "running", + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n3n1", + "provider_node": "n1", + "status": "replicating" + }, + { + "name": "sub_n3n2", + "provider_node": "n2", + "status": "replicating" + } + ], + "version": "4.0.10" + }, + "state": "available", + "status_updated_at": "2025-06-17T20:05:10Z", + "updated_at": "2025-06-17T20:05:10Z" + } + ], + "state": "available", + "updated_at": "2025-06-17T20:05:10Z" }, { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" + "created_at": "2025-06-12T15:10:05Z", + "id": "storefront", + "instances": [ + { + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 6432 + }, + "created_at": "2025-06-12T15:10:05Z", + "host_id": "us-east-1", + "id": "storefront-n1-689qacsi", + "node_name": "n1", + "postgres": { + "patroni_state": "running", + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n3", + "provider_node": "n3", + "status": "replicating" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "replicating" + } + ], + "version": "4.0.10" + }, + "state": "available", + "status_updated_at": "2025-06-17T20:05:10Z", + "updated_at": "2025-06-12T15:10:05Z" + }, + { + "connection_info": { + "hostname": "i-058731542fee493f.ec2.internal", + "ipv4_address": "10.24.35.2", + "port": 6432 + }, + "created_at": "2025-06-12T15:10:05Z", + "host_id": "ap-south-1", + "id": "storefront-n2-9ptayhma", + "node_name": "n2", + "postgres": { + "patroni_state": "running", + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n2n1", + "provider_node": "n1", + "status": "replicating" + }, + { + "name": "sub_n2n3", + "provider_node": "n3", + "status": "replicating" + } + ], + "version": "4.0.10" + }, + "state": "available", + "status_updated_at": "2025-06-17T20:05:10Z", + "updated_at": "2025-06-12T15:10:05Z" + }, + { + "connection_info": { + "hostname": "i-494027b7b53f6a23.ec2.internal", + "ipv4_address": "10.24.36.2", + "port": 6432 + }, + "created_at": "2025-06-12T15:10:05Z", + "host_id": "eu-central-1", + "id": "storefront-n3-ant97dj4", + "node_name": "n3", + "postgres": { + "patroni_state": "running", + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n3n1", + "provider_node": "n1", + "status": "replicating" + }, + { + "name": "sub_n3n2", + "provider_node": "n2", + "status": "replicating" + } + ], + "version": "4.0.10" + }, + "state": "available", + "status_updated_at": "2025-06-17T20:05:10Z", + "updated_at": "2025-06-12T15:10:05Z" + } + ], + "state": "available", + "updated_at": "2025-06-12T15:10:05Z" } - ], - "version": "4.10.0" - } - }, - "InstanceSubscription": { - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "The name of the subscription.", - "example": "sub_n1n2" - }, - "provider_node": { - "type": "string", - "description": "The Spock node name of the provider for this subscription.", - "example": "n2", - "pattern": "n[0-9]+" - }, - "status": { - "type": "string", - "description": "The current status of the subscription.", - "example": "down" - } - }, - "description": "Status information for a Spock subscription.", - "example": { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" + ] }, "required": [ - "provider_node", - "name", - "status" + "databases" ] }, - "ListDatabaseTasksResponse": { + "ListHostTasksResponse": { "type": "object", "properties": { "tasks": { @@ -21423,7 +23604,7 @@ "items": { "$ref": "#/components/schemas/Task" }, - "description": "The tasks for the given database.", + "description": "The tasks for the given host.", "example": [ { "completed_at": "2025-06-18T16:52:35Z", @@ -21435,16 +23616,6 @@ "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", "type": "create" }, - { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" - }, { "completed_at": "2025-06-18T16:52:35Z", "created_at": "2025-06-18T16:52:05Z", @@ -21463,43 +23634,12 @@ { "completed_at": "2025-06-18T17:54:36Z", "created_at": "2025-06-18T17:54:28Z", - "database_id": "storefront", - "entity_id": "storefront", - "instance_id": "storefront-n1-689qacsi", - "scope": "database", + "entity_id": "host-1", + "host_id": "host-1", + "scope": "host", "status": "completed", "task_id": "0197842d-9082-7496-b787-77bd2e11809f", - "type": "node_backup" - }, - { - "completed_at": "2025-06-18T17:54:04Z", - "created_at": "2025-06-18T17:53:17Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "0197842c-7c4f-7a8c-829e-7405c2a41c8c", - "type": "update" - }, - { - "completed_at": "2025-06-18T17:23:28Z", - "created_at": "2025-06-18T17:23:14Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "01978410-fb5d-7cd2-bbd2-66c0bf929dc0", - "type": "update" - }, - { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" + "type": "remove_host" } ] }, @@ -21507,560 +23647,428 @@ "tasks" ] }, - "ListDatabasesResponse": { + "ListHostsResponse": { "type": "object", "properties": { - "databases": { + "hosts": { "type": "array", "items": { - "$ref": "#/components/schemas/DatabaseSummary" + "$ref": "#/components/schemas/Host" }, - "description": "The databases managed by this cluster.", + "description": "List of hosts in the cluster", "example": [ { - "created_at": "2025-01-01T01:30:00Z", - "id": "02f1a7db-fca8-4521-b57a-2a375c1ced51", - "instances": [ - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "1970-10-16T01:30:13Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": true, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" + "cohort": { + "control_available": true, + "member_id": "lah4bsznw6kc0hp7biylmmmll", + "type": "swarm" + }, + "cpus": 4, + "data_dir": "/data", + "default_pgedge_version": { + "postgres_version": "17.6", + "spock_version": "5" + }, + "etcd_mode": "server", + "hostname": "i-0123456789abcdef.ec2.internal", + "id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "ipv4_address": "10.24.34.2", + "memory": "16GiB", + "orchestrator": "swarm", + "status": { + "components": { + "Enim et voluptatum ex ea dolore.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "Tenetur nostrum repellendus sint qui.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false + } }, + "state": "available", + "updated_at": "2021-07-01T12:34:56Z" + }, + "supported_pgedge_versions": [ { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "1970-10-16T01:30:13Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": true, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" - }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "postgres_version": "17.6", + "spock_version": "5" }, { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "1970-10-16T01:30:13Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": true, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" - }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "postgres_version": "17.6", + "spock_version": "5" + }, + { + "postgres_version": "17.6", + "spock_version": "5" } - ], - "state": "modifying", - "tenant_id": "8210ec10-2dca-406c-ac4a-0661d2189954", - "updated_at": "2025-01-01T02:30:00Z" + ] }, { - "created_at": "2025-01-01T01:30:00Z", - "id": "02f1a7db-fca8-4521-b57a-2a375c1ced51", - "instances": [ - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "1970-10-16T01:30:13Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": true, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" + "cohort": { + "control_available": true, + "member_id": "lah4bsznw6kc0hp7biylmmmll", + "type": "swarm" + }, + "cpus": 4, + "data_dir": "/data", + "default_pgedge_version": { + "postgres_version": "17.6", + "spock_version": "5" + }, + "etcd_mode": "server", + "hostname": "i-0123456789abcdef.ec2.internal", + "id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "ipv4_address": "10.24.34.2", + "memory": "16GiB", + "orchestrator": "swarm", + "status": { + "components": { + "Enim et voluptatum ex ea dolore.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" + "Tenetur nostrum repellendus sint qui.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false + } + }, + "state": "available", + "updated_at": "2021-07-01T12:34:56Z" + }, + "supported_pgedge_versions": [ + { + "postgres_version": "17.6", + "spock_version": "5" + }, + { + "postgres_version": "17.6", + "spock_version": "5" + }, + { + "postgres_version": "17.6", + "spock_version": "5" + } + ] + }, + { + "cohort": { + "control_available": true, + "member_id": "lah4bsznw6kc0hp7biylmmmll", + "type": "swarm" + }, + "cpus": 4, + "data_dir": "/data", + "default_pgedge_version": { + "postgres_version": "17.6", + "spock_version": "5" + }, + "etcd_mode": "server", + "hostname": "i-0123456789abcdef.ec2.internal", + "id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "ipv4_address": "10.24.34.2", + "memory": "16GiB", + "orchestrator": "swarm", + "status": { + "components": { + "Enim et voluptatum ex ea dolore.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "Tenetur nostrum repellendus sint qui.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false + } + }, + "state": "available", + "updated_at": "2021-07-01T12:34:56Z" + }, + "supported_pgedge_versions": [ + { + "postgres_version": "17.6", + "spock_version": "5" }, { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "1970-10-16T01:30:13Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": true, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" - }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "postgres_version": "17.6", + "spock_version": "5" }, { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "1970-10-16T01:30:13Z", - "error": "failed to get patroni status: connection refused", - "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", - "node_name": "n1", - "postgres": { - "patroni_paused": true, - "patroni_state": "unknown", - "pending_restart": true, - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "down" - } - ], - "version": "4.10.0" + "postgres_version": "17.6", + "spock_version": "5" + } + ] + }, + { + "cohort": { + "control_available": true, + "member_id": "lah4bsznw6kc0hp7biylmmmll", + "type": "swarm" + }, + "cpus": 4, + "data_dir": "/data", + "default_pgedge_version": { + "postgres_version": "17.6", + "spock_version": "5" + }, + "etcd_mode": "server", + "hostname": "i-0123456789abcdef.ec2.internal", + "id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "ipv4_address": "10.24.34.2", + "memory": "16GiB", + "orchestrator": "swarm", + "status": { + "components": { + "Enim et voluptatum ex ea dolore.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false }, - "state": "unknown", - "status_updated_at": "2013-04-06T16:38:09Z", - "updated_at": "1971-07-18T16:52:12Z" + "Tenetur nostrum repellendus sint qui.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false + } + }, + "state": "available", + "updated_at": "2021-07-01T12:34:56Z" + }, + "supported_pgedge_versions": [ + { + "postgres_version": "17.6", + "spock_version": "5" + }, + { + "postgres_version": "17.6", + "spock_version": "5" + }, + { + "postgres_version": "17.6", + "spock_version": "5" } - ], - "state": "modifying", - "tenant_id": "8210ec10-2dca-406c-ac4a-0661d2189954", - "updated_at": "2025-01-01T02:30:00Z" + ] } ] } }, + "description": "Response containing the list of hosts", "example": { - "databases": [ + "hosts": [ { - "created_at": "2025-06-17T20:05:10Z", - "id": "inventory", - "instances": [ - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "2025-06-17T20:05:10Z", - "host_id": "us-east-1", - "id": "inventory-n1-689qacsi", - "node_name": "n1", - "postgres": { - "patroni_state": "running", - "role": "primary", - "version": "18.1" + "cohort": { + "control_available": true, + "member_id": "lah4bsznw6kc0hp7biylmmmll", + "type": "swarm" + }, + "cpus": 4, + "data_dir": "/data", + "default_pgedge_version": { + "postgres_version": "17.6", + "spock_version": "5" + }, + "etcd_mode": "server", + "hostname": "i-0123456789abcdef.ec2.internal", + "id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "ipv4_address": "10.24.34.2", + "memory": "16GiB", + "orchestrator": "swarm", + "status": { + "components": { + "Enim et voluptatum ex ea dolore.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n3", - "provider_node": "n3", - "status": "replicating" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "replicating" - } - ], - "version": "4.0.10" + "Tenetur nostrum repellendus sint qui.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false + } + }, + "state": "available", + "updated_at": "2021-07-01T12:34:56Z" + }, + "supported_pgedge_versions": [ + { + "postgres_version": "17.6", + "spock_version": "5" + }, + { + "postgres_version": "17.6", + "spock_version": "5" + }, + { + "postgres_version": "17.6", + "spock_version": "5" + } + ] + }, + { + "cohort": { + "control_available": true, + "member_id": "lah4bsznw6kc0hp7biylmmmll", + "type": "swarm" + }, + "cpus": 4, + "data_dir": "/data", + "default_pgedge_version": { + "postgres_version": "17.6", + "spock_version": "5" + }, + "etcd_mode": "server", + "hostname": "i-0123456789abcdef.ec2.internal", + "id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "ipv4_address": "10.24.34.2", + "memory": "16GiB", + "orchestrator": "swarm", + "status": { + "components": { + "Enim et voluptatum ex ea dolore.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false }, - "state": "available", - "status_updated_at": "2025-06-17T20:05:10Z", - "updated_at": "2025-06-17T20:05:10Z" + "Tenetur nostrum repellendus sint qui.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false + } }, + "state": "available", + "updated_at": "2021-07-01T12:34:56Z" + }, + "supported_pgedge_versions": [ { - "connection_info": { - "hostname": "i-058731542fee493f.ec2.internal", - "ipv4_address": "10.24.35.2", - "port": 5432 - }, - "created_at": "2025-06-17T20:05:10Z", - "host_id": "ap-south-1", - "id": "inventory-n2-9ptayhma", - "node_name": "n2", - "postgres": { - "patroni_state": "running", - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n2n1", - "provider_node": "n1", - "status": "replicating" - }, - { - "name": "sub_n2n3", - "provider_node": "n3", - "status": "replicating" - } - ], - "version": "4.0.10" - }, - "state": "available", - "status_updated_at": "2025-06-17T20:05:10Z", - "updated_at": "2025-06-17T20:05:10Z" + "postgres_version": "17.6", + "spock_version": "5" }, { - "connection_info": { - "hostname": "i-494027b7b53f6a23.ec2.internal", - "ipv4_address": "10.24.36.2", - "port": 5432 - }, - "created_at": "2025-06-17T20:05:10Z", - "host_id": "eu-central-1", - "id": "inventory-n3-ant97dj4", - "node_name": "n3", - "postgres": { - "patroni_state": "running", - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n3n1", - "provider_node": "n1", - "status": "replicating" - }, - { - "name": "sub_n3n2", - "provider_node": "n2", - "status": "replicating" - } - ], - "version": "4.0.10" - }, - "state": "available", - "status_updated_at": "2025-06-17T20:05:10Z", - "updated_at": "2025-06-17T20:05:10Z" + "postgres_version": "17.6", + "spock_version": "5" + }, + { + "postgres_version": "17.6", + "spock_version": "5" } - ], - "state": "available", - "updated_at": "2025-06-17T20:05:10Z" + ] }, { - "created_at": "2025-06-12T15:10:05Z", - "id": "storefront", - "instances": [ - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 6432 - }, - "created_at": "2025-06-12T15:10:05Z", - "host_id": "us-east-1", - "id": "storefront-n1-689qacsi", - "node_name": "n1", - "postgres": { - "patroni_state": "running", - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n3", - "provider_node": "n3", - "status": "replicating" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "replicating" - } - ], - "version": "4.0.10" + "cohort": { + "control_available": true, + "member_id": "lah4bsznw6kc0hp7biylmmmll", + "type": "swarm" + }, + "cpus": 4, + "data_dir": "/data", + "default_pgedge_version": { + "postgres_version": "17.6", + "spock_version": "5" + }, + "etcd_mode": "server", + "hostname": "i-0123456789abcdef.ec2.internal", + "id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "ipv4_address": "10.24.34.2", + "memory": "16GiB", + "orchestrator": "swarm", + "status": { + "components": { + "Enim et voluptatum ex ea dolore.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false }, - "state": "available", - "status_updated_at": "2025-06-17T20:05:10Z", - "updated_at": "2025-06-12T15:10:05Z" + "Tenetur nostrum repellendus sint qui.": { + "details": { + "alarms": [ + "3: NOSPACE" + ] + }, + "error": "failed to connect to etcd", + "healthy": false + } }, + "state": "available", + "updated_at": "2021-07-01T12:34:56Z" + }, + "supported_pgedge_versions": [ { - "connection_info": { - "hostname": "i-058731542fee493f.ec2.internal", - "ipv4_address": "10.24.35.2", - "port": 6432 - }, - "created_at": "2025-06-12T15:10:05Z", - "host_id": "ap-south-1", - "id": "storefront-n2-9ptayhma", - "node_name": "n2", - "postgres": { - "patroni_state": "running", - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n2n1", - "provider_node": "n1", - "status": "replicating" - }, - { - "name": "sub_n2n3", - "provider_node": "n3", - "status": "replicating" - } - ], - "version": "4.0.10" - }, - "state": "available", - "status_updated_at": "2025-06-17T20:05:10Z", - "updated_at": "2025-06-12T15:10:05Z" + "postgres_version": "17.6", + "spock_version": "5" }, { - "connection_info": { - "hostname": "i-494027b7b53f6a23.ec2.internal", - "ipv4_address": "10.24.36.2", - "port": 6432 - }, - "created_at": "2025-06-12T15:10:05Z", - "host_id": "eu-central-1", - "id": "storefront-n3-ant97dj4", - "node_name": "n3", - "postgres": { - "patroni_state": "running", - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n3n1", - "provider_node": "n1", - "status": "replicating" - }, - { - "name": "sub_n3n2", - "provider_node": "n2", - "status": "replicating" - } - ], - "version": "4.0.10" - }, - "state": "available", - "status_updated_at": "2025-06-17T20:05:10Z", - "updated_at": "2025-06-12T15:10:05Z" + "postgres_version": "17.6", + "spock_version": "5" + }, + { + "postgres_version": "17.6", + "spock_version": "5" } - ], - "state": "available", - "updated_at": "2025-06-12T15:10:05Z" + ] } ] }, "required": [ - "databases" + "hosts" ] }, - "ListHostTasksResponse": { + "ListTasksResponse": { "type": "object", "properties": { "tasks": { @@ -22068,7 +24076,7 @@ "items": { "$ref": "#/components/schemas/Task" }, - "description": "The tasks for the given host.", + "description": "The tasks for the given entity.", "example": [ { "completed_at": "2025-06-18T16:52:35Z", @@ -22095,6 +24103,17 @@ }, "example": { "tasks": [ + { + "completed_at": "2025-06-18T17:54:36Z", + "created_at": "2025-06-18T17:54:28Z", + "database_id": "storefront", + "entity_id": "storefront", + "instance_id": "storefront-n1-689qacsi", + "scope": "database", + "status": "completed", + "task_id": "0197842d-9082-7496-b787-77bd2e11809f", + "type": "node_backup" + }, { "completed_at": "2025-06-18T17:54:36Z", "created_at": "2025-06-18T17:54:28Z", @@ -22111,265 +24130,363 @@ "tasks" ] }, - "ListHostsResponse": { + "OrchestratorOpts": { "type": "object", "properties": { - "hosts": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Host" + "swarm": { + "$ref": "#/components/schemas/SwarmOpts" + } + }, + "description": "Options specific to the selected orchestrator.", + "example": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" }, - "description": "List of hosts in the cluster", - "example": [ + "extra_networks": [ { - "cohort": { - "control_available": true, - "member_id": "lah4bsznw6kc0hp7biylmmmll", - "type": "swarm" - }, - "cpus": 4, - "data_dir": "/data", - "default_pgedge_version": { - "postgres_version": "17.6", - "spock_version": "5" - }, - "etcd_mode": "server", - "hostname": "i-0123456789abcdef.ec2.internal", - "id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "ipv4_address": "10.24.34.2", - "memory": "16GiB", - "orchestrator": "swarm", - "status": { - "components": { - "Enim et voluptatum ex ea dolore.": { - "details": { - "alarms": [ - "3: NOSPACE" - ] - }, - "error": "failed to connect to etcd", - "healthy": false - }, - "Tenetur nostrum repellendus sint qui.": { - "details": { - "alarms": [ - "3: NOSPACE" - ] - }, - "error": "failed to connect to etcd", - "healthy": false - } - }, - "state": "available", - "updated_at": "2021-07-01T12:34:56Z" + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" }, - "supported_pgedge_versions": [ - { - "postgres_version": "17.6", - "spock_version": "5" - }, - { - "postgres_version": "17.6", - "spock_version": "5" - }, - { - "postgres_version": "17.6", - "spock_version": "5" - } - ] + "id": "traefik-public" }, { - "cohort": { - "control_available": true, - "member_id": "lah4bsznw6kc0hp7biylmmmll", - "type": "swarm" - }, - "cpus": 4, - "data_dir": "/data", - "default_pgedge_version": { - "postgres_version": "17.6", - "spock_version": "5" + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" }, - "etcd_mode": "server", - "hostname": "i-0123456789abcdef.ec2.internal", - "id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "ipv4_address": "10.24.34.2", - "memory": "16GiB", - "orchestrator": "swarm", - "status": { - "components": { - "Enim et voluptatum ex ea dolore.": { - "details": { - "alarms": [ - "3: NOSPACE" - ] - }, - "error": "failed to connect to etcd", - "healthy": false - }, - "Tenetur nostrum repellendus sint qui.": { - "details": { - "alarms": [ - "3: NOSPACE" - ] - }, - "error": "failed to connect to etcd", - "healthy": false - } - }, - "state": "available", - "updated_at": "2021-07-01T12:34:56Z" + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" }, - "supported_pgedge_versions": [ - { - "postgres_version": "17.6", - "spock_version": "5" - }, - { - "postgres_version": "17.6", - "spock_version": "5" - }, - { - "postgres_version": "17.6", - "spock_version": "5" - } - ] + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + } + }, + "PgEdgeVersion": { + "type": "object", + "properties": { + "postgres_version": { + "type": "string", + "description": "The Postgres major and minor version.", + "example": "17.6" + }, + "spock_version": { + "type": "string", + "description": "The Spock major version.", + "example": "5" + } + }, + "example": { + "postgres_version": "17.6", + "spock_version": "5" + }, + "required": [ + "postgres_version", + "spock_version" + ] + }, + "PortMapping": { + "type": "object", + "properties": { + "container_port": { + "type": "integer", + "description": "The port number inside the container.", + "example": 8080, + "format": "int64", + "minimum": 1, + "maximum": 65535 + }, + "host_port": { + "type": "integer", + "description": "The port number on the host (if port-forwarded).", + "example": 8080, + "format": "int64", + "minimum": 1, + "maximum": 65535 + }, + "name": { + "type": "string", + "description": "The name of the port (e.g., 'http', 'web-client').", + "example": "web-client" + } + }, + "description": "Port mapping information for a service instance.", + "example": { + "container_port": 8080, + "host_port": 8080, + "name": "web-client" + }, + "required": [ + "name" + ] + }, + "RemoveHostResponse": { + "type": "object", + "properties": { + "task": { + "$ref": "#/components/schemas/Task" + }, + "update_database_tasks": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Task" + }, + "description": "The tasks that will update databases affected by the host removal.", + "example": [ + { + "completed_at": "2025-06-18T16:52:35Z", + "created_at": "2025-06-18T16:52:05Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", + "type": "create" + }, + { + "completed_at": "2025-06-18T16:52:35Z", + "created_at": "2025-06-18T16:52:05Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", + "type": "create" + }, + { + "completed_at": "2025-06-18T16:52:35Z", + "created_at": "2025-06-18T16:52:05Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", + "type": "create" } ] } }, - "description": "Response containing the list of hosts", "example": { - "hosts": [ + "task": { + "completed_at": "2025-06-18T16:52:35Z", + "created_at": "2025-06-18T16:52:05Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", + "type": "create" + }, + "update_database_tasks": [ { - "cohort": { - "control_available": true, - "member_id": "lah4bsznw6kc0hp7biylmmmll", - "type": "swarm" - }, - "cpus": 4, - "data_dir": "/data", - "default_pgedge_version": { - "postgres_version": "17.6", - "spock_version": "5" - }, - "etcd_mode": "server", - "hostname": "i-0123456789abcdef.ec2.internal", - "id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "ipv4_address": "10.24.34.2", - "memory": "16GiB", - "orchestrator": "swarm", - "status": { - "components": { - "Enim et voluptatum ex ea dolore.": { - "details": { - "alarms": [ - "3: NOSPACE" - ] - }, - "error": "failed to connect to etcd", - "healthy": false - }, - "Tenetur nostrum repellendus sint qui.": { - "details": { - "alarms": [ - "3: NOSPACE" - ] - }, - "error": "failed to connect to etcd", - "healthy": false - } - }, - "state": "available", - "updated_at": "2021-07-01T12:34:56Z" - }, - "supported_pgedge_versions": [ - { - "postgres_version": "17.6", - "spock_version": "5" - }, - { - "postgres_version": "17.6", - "spock_version": "5" - }, - { - "postgres_version": "17.6", - "spock_version": "5" - } - ] + "completed_at": "2025-06-18T16:52:35Z", + "created_at": "2025-06-18T16:52:05Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", + "type": "create" }, { - "cohort": { - "control_available": true, - "member_id": "lah4bsznw6kc0hp7biylmmmll", - "type": "swarm" - }, - "cpus": 4, - "data_dir": "/data", - "default_pgedge_version": { - "postgres_version": "17.6", - "spock_version": "5" - }, - "etcd_mode": "server", - "hostname": "i-0123456789abcdef.ec2.internal", - "id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "ipv4_address": "10.24.34.2", - "memory": "16GiB", - "orchestrator": "swarm", - "status": { - "components": { - "Enim et voluptatum ex ea dolore.": { - "details": { - "alarms": [ - "3: NOSPACE" - ] - }, - "error": "failed to connect to etcd", - "healthy": false - }, - "Tenetur nostrum repellendus sint qui.": { - "details": { - "alarms": [ - "3: NOSPACE" - ] - }, - "error": "failed to connect to etcd", - "healthy": false - } - }, - "state": "available", - "updated_at": "2021-07-01T12:34:56Z" - }, - "supported_pgedge_versions": [ - { - "postgres_version": "17.6", - "spock_version": "5" - }, - { - "postgres_version": "17.6", - "spock_version": "5" - }, - { - "postgres_version": "17.6", - "spock_version": "5" - } - ] + "completed_at": "2025-06-18T16:52:35Z", + "created_at": "2025-06-18T16:52:05Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", + "type": "create" + } + ] + }, + "required": [ + "task", + "update_database_tasks" + ] + }, + "RestartInstanceResponse": { + "type": "object", + "properties": { + "task": { + "$ref": "#/components/schemas/Task" + } + }, + "description": "Response containing the restart task", + "example": { + "task": { + "completed_at": "2025-06-18T16:52:35Z", + "created_at": "2025-06-18T16:52:05Z", + "database_id": "storefront", + "entity_id": "storefront", + "scope": "database", + "status": "completed", + "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", + "type": "create" + } + }, + "required": [ + "task" + ] + }, + "RestoreConfigSpec": { + "type": "object", + "properties": { + "repository": { + "$ref": "#/components/schemas/RestoreRepositorySpec" + }, + "restore_options": { + "type": "object", + "description": "Additional options to use when restoring this database. If omitted, the database will be restored to the latest point in the given repository.", + "example": { + "set": "20250505-153628F", + "target": "123456", + "type": "xid" + }, + "maxLength": 32, + "additionalProperties": { + "type": "string", + "example": "Accusantium ut aperiam qui sed quis architecto." } + }, + "source_database_id": { + "type": "string", + "description": "A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens.", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 + }, + "source_database_name": { + "type": "string", + "description": "The name of the database in this repository. The database will be renamed to the database_name in the DatabaseSpec after it's restored.", + "example": "northwind", + "minLength": 1, + "maxLength": 31 + }, + "source_node_name": { + "type": "string", + "description": "The name of the node to restore this database from.", + "example": "n1", + "pattern": "n[0-9]+" + } + }, + "example": { + "repository": { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "f6b84a99-5e91-4203-be1e-131fe82e5984", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" + }, + "restore_options": { + "set": "20250505-153628F", + "target": "123456", + "type": "xid" + }, + "source_database_id": "02f1a7db-fca8-4521-b57a-2a375c1ced51", + "source_database_name": "northwind", + "source_node_name": "n1" + }, + "required": [ + "source_database_id", + "source_node_name", + "source_database_name", + "repository" + ] + }, + "RestoreDatabaseRequest": { + "type": "object", + "properties": { + "restore_config": { + "$ref": "#/components/schemas/RestoreConfigSpec" + }, + "target_nodes": { + "type": "array", + "items": { + "type": "string", + "example": "Et et reprehenderit et nam quo." + }, + "description": "The nodes to restore. Defaults to all nodes if empty or unspecified.", + "example": [ + "n1" + ], + "maxItems": 9 + } + }, + "example": { + "restore_config": { + "repository": { + "base_path": "/backups", + "type": "posix" + }, + "source_database_id": "storefront", + "source_database_name": "storefront", + "source_node_name": "n1" + }, + "target_nodes": [ + "n1" ] }, "required": [ - "hosts" + "restore_config" ] }, - "ListTasksResponse": { + "RestoreDatabaseResponse": { "type": "object", "properties": { - "tasks": { + "database": { + "$ref": "#/components/schemas/Database" + }, + "node_tasks": { "type": "array", "items": { "$ref": "#/components/schemas/Task" }, - "description": "The tasks for the given entity.", + "description": "The tasks that will restore each database node.", "example": [ { "completed_at": "2025-06-18T16:52:35Z", @@ -22381,16 +24498,6 @@ "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", "type": "create" }, - { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" - }, { "completed_at": "2025-06-18T16:52:35Z", "created_at": "2025-06-18T16:52:05Z", @@ -22402,170 +24509,216 @@ "type": "create" } ] + }, + "task": { + "$ref": "#/components/schemas/Task" } }, "example": { - "tasks": [ - { - "completed_at": "2025-06-18T17:54:36Z", - "created_at": "2025-06-18T17:54:28Z", - "database_id": "storefront", - "entity_id": "storefront", - "instance_id": "storefront-n1-689qacsi", - "scope": "database", - "status": "completed", - "task_id": "0197842d-9082-7496-b787-77bd2e11809f", - "type": "node_backup" - }, - { - "completed_at": "2025-06-18T17:54:36Z", - "created_at": "2025-06-18T17:54:28Z", - "entity_id": "host-1", - "host_id": "host-1", - "scope": "host", - "status": "completed", - "task_id": "0197842d-9082-7496-b787-77bd2e11809f", - "type": "remove_host" - } - ] - }, - "required": [ - "tasks" - ] - }, - "OrchestratorOpts": { - "type": "object", - "properties": { - "swarm": { - "$ref": "#/components/schemas/SwarmOpts" - } - }, - "description": "Options specific to the selected orchestrator.", - "example": { - "swarm": { - "extra_labels": { - "traefik.enable": "true", - "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" - }, - "extra_networks": [ + "database": { + "created_at": "2025-06-18T16:52:05Z", + "id": "storefront", + "instances": [ { - "aliases": [ - "pg-db", - "db-alias" - ], - "driver_opts": { - "com.docker.network.endpoint.expose": "true" + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 5432 }, - "id": "traefik-public" + "created_at": "2025-06-18T16:52:22Z", + "host_id": "us-east-1", + "id": "storefront-n1-689qacsi", + "node_name": "n1", + "postgres": { + "patroni_state": "running", + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n3", + "provider_node": "n3", + "status": "replicating" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "replicating" + } + ], + "version": "4.0.10" + }, + "state": "available", + "status_updated_at": "2025-06-18T17:58:56Z", + "updated_at": "2025-06-18T17:54:36Z" }, { - "aliases": [ - "pg-db", - "db-alias" - ], - "driver_opts": { - "com.docker.network.endpoint.expose": "true" + "connection_info": { + "hostname": "i-058731542fee493f.ec2.internal", + "ipv4_address": "10.24.35.2", + "port": 5432 + }, + "created_at": "2025-06-18T16:52:22Z", + "host_id": "ap-south-1", + "id": "storefront-n2-9ptayhma", + "node_name": "n2", + "postgres": { + "patroni_state": "running", + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n2n1", + "provider_node": "n1", + "status": "replicating" + }, + { + "name": "sub_n2n3", + "provider_node": "n3", + "status": "replicating" + } + ], + "version": "4.0.10" + }, + "state": "available", + "status_updated_at": "2025-06-18T17:58:56Z", + "updated_at": "2025-06-18T17:54:01Z" + }, + { + "connection_info": { + "hostname": "i-494027b7b53f6a23.ec2.internal", + "ipv4_address": "10.24.36.2", + "port": 5432 + }, + "created_at": "2025-06-18T16:52:22Z", + "host_id": "eu-central-1", + "id": "storefront-n3-ant97dj4", + "node_name": "n3", + "postgres": { + "patroni_state": "running", + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n3n1", + "provider_node": "n1", + "status": "replicating" + }, + { + "name": "sub_n3n2", + "provider_node": "n2", + "status": "replicating" + } + ], + "version": "4.0.10" + }, + "state": "available", + "status_updated_at": "2025-06-18T17:58:56Z", + "updated_at": "2025-06-18T17:54:01Z" + } + ], + "spec": { + "database_name": "storefront", + "database_users": [ + { + "attributes": [ + "SUPERUSER", + "LOGIN" + ], + "db_owner": true, + "username": "admin" + } + ], + "nodes": [ + { + "host_ids": [ + "us-east-1" + ], + "name": "n1" }, - "id": "traefik-public" - }, - { - "aliases": [ - "pg-db", - "db-alias" - ], - "driver_opts": { - "com.docker.network.endpoint.expose": "true" + { + "host_ids": [ + "ap-south-1" + ], + "name": "n2" }, - "id": "traefik-public" - } - ], - "extra_volumes": [ - { - "destination_path": "/backups/container", - "host_path": "/Users/user/backups/host" - }, - { - "destination_path": "/backups/container", - "host_path": "/Users/user/backups/host" - }, - { - "destination_path": "/backups/container", - "host_path": "/Users/user/backups/host" - } - ] - } - } - }, - "PgEdgeVersion": { - "type": "object", - "properties": { - "postgres_version": { - "type": "string", - "description": "The Postgres major and minor version.", - "example": "17.6" - }, - "spock_version": { - "type": "string", - "description": "The Spock major version.", - "example": "5" - } - }, - "example": { - "postgres_version": "17.6", - "spock_version": "5" - }, - "required": [ - "postgres_version", - "spock_version" - ] - }, - "PortMapping": { - "type": "object", - "properties": { - "container_port": { - "type": "integer", - "description": "The port number inside the container.", - "example": 8080, - "format": "int64", - "minimum": 1, - "maximum": 65535 - }, - "host_port": { - "type": "integer", - "description": "The port number on the host (if port-forwarded).", - "example": 8080, - "format": "int64", - "minimum": 1, - "maximum": 65535 + { + "host_ids": [ + "eu-central-1" + ], + "name": "n3" + } + ], + "port": 5432, + "postgres_version": "17.6", + "spock_version": "5" + }, + "state": "restoring", + "updated_at": "2025-06-18T17:58:59Z" }, - "name": { - "type": "string", - "description": "The name of the port (e.g., 'http', 'web-client').", - "example": "web-client" + "node_tasks": [ + { + "created_at": "2025-06-18T17:58:59Z", + "database_id": "storefront", + "node_name": "n1", + "parent_id": "01978431-b628-758a-aec6-03b331fa1a17", + "status": "pending", + "task_id": "01978431-b62b-723b-a09c-e4072cd64bdb", + "type": "node_restore" + }, + { + "created_at": "2025-06-18T17:58:59Z", + "database_id": "storefront", + "node_name": "n2", + "parent_id": "01978431-b628-758a-aec6-03b331fa1a17", + "status": "pending", + "task_id": "01978431-b62c-7593-aad8-43b03df2031b", + "type": "node_restore" + }, + { + "created_at": "2025-06-18T17:58:59Z", + "database_id": "storefront", + "node_name": "n3", + "parent_id": "01978431-b628-758a-aec6-03b331fa1a17", + "status": "pending", + "task_id": "01978431-b62d-7b65-ab09-272d0b2fea91", + "type": "node_restore" + } + ], + "task": { + "created_at": "2025-06-18T17:58:59Z", + "database_id": "storefront", + "status": "pending", + "task_id": "01978431-b628-758a-aec6-03b331fa1a17", + "type": "restore" } }, - "description": "Port mapping information for a service instance.", - "example": { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - }, "required": [ - "name" + "task", + "node_tasks", + "database" ] }, - "RemoveHostResponse": { + "RestoreDatabaseResponse2": { "type": "object", "properties": { - "task": { - "$ref": "#/components/schemas/Task" + "database": { + "$ref": "#/components/schemas/Database5" }, - "update_database_tasks": { + "node_tasks": { "type": "array", "items": { "$ref": "#/components/schemas/Task" }, - "description": "The tasks that will update databases affected by the host removal.", + "description": "The tasks that will restore each database node.", "example": [ { "completed_at": "2025-06-18T16:52:35Z", @@ -22597,1019 +24750,1466 @@ "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", "type": "create" } - ] - } - }, - "example": { - "task": { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" + ] + }, + "task": { + "$ref": "#/components/schemas/Task" + } + }, + "example": { + "database": { + "created_at": "2025-06-18T16:52:05Z", + "id": "storefront", + "instances": [ + { + "connection_info": { + "hostname": "i-0123456789abcdef.ec2.internal", + "ipv4_address": "10.24.34.2", + "port": 5432 + }, + "created_at": "2025-06-18T16:52:22Z", + "host_id": "us-east-1", + "id": "storefront-n1-689qacsi", + "node_name": "n1", + "postgres": { + "patroni_state": "running", + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n1n3", + "provider_node": "n3", + "status": "replicating" + }, + { + "name": "sub_n1n2", + "provider_node": "n2", + "status": "replicating" + } + ], + "version": "4.0.10" + }, + "state": "available", + "status_updated_at": "2025-06-18T17:58:56Z", + "updated_at": "2025-06-18T17:54:36Z" + }, + { + "connection_info": { + "hostname": "i-058731542fee493f.ec2.internal", + "ipv4_address": "10.24.35.2", + "port": 5432 + }, + "created_at": "2025-06-18T16:52:22Z", + "host_id": "ap-south-1", + "id": "storefront-n2-9ptayhma", + "node_name": "n2", + "postgres": { + "patroni_state": "running", + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n2n1", + "provider_node": "n1", + "status": "replicating" + }, + { + "name": "sub_n2n3", + "provider_node": "n3", + "status": "replicating" + } + ], + "version": "4.0.10" + }, + "state": "available", + "status_updated_at": "2025-06-18T17:58:56Z", + "updated_at": "2025-06-18T17:54:01Z" + }, + { + "connection_info": { + "hostname": "i-494027b7b53f6a23.ec2.internal", + "ipv4_address": "10.24.36.2", + "port": 5432 + }, + "created_at": "2025-06-18T16:52:22Z", + "host_id": "eu-central-1", + "id": "storefront-n3-ant97dj4", + "node_name": "n3", + "postgres": { + "patroni_state": "running", + "role": "primary", + "version": "18.1" + }, + "spock": { + "read_only": "off", + "subscriptions": [ + { + "name": "sub_n3n1", + "provider_node": "n1", + "status": "replicating" + }, + { + "name": "sub_n3n2", + "provider_node": "n2", + "status": "replicating" + } + ], + "version": "4.0.10" + }, + "state": "available", + "status_updated_at": "2025-06-18T17:58:56Z", + "updated_at": "2025-06-18T17:54:01Z" + } + ], + "spec": { + "database_name": "storefront", + "database_users": [ + { + "attributes": [ + "SUPERUSER", + "LOGIN" + ], + "db_owner": true, + "username": "admin" + } + ], + "nodes": [ + { + "host_ids": [ + "us-east-1" + ], + "name": "n1" + }, + { + "host_ids": [ + "ap-south-1" + ], + "name": "n2" + }, + { + "host_ids": [ + "eu-central-1" + ], + "name": "n3" + } + ], + "port": 5432, + "postgres_version": "17.6", + "spock_version": "5" + }, + "state": "restoring", + "updated_at": "2025-06-18T17:58:59Z" }, - "update_database_tasks": [ + "node_tasks": [ { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", + "created_at": "2025-06-18T17:58:59Z", "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" + "node_name": "n1", + "parent_id": "01978431-b628-758a-aec6-03b331fa1a17", + "status": "pending", + "task_id": "01978431-b62b-723b-a09c-e4072cd64bdb", + "type": "node_restore" }, { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", + "created_at": "2025-06-18T17:58:59Z", "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" + "node_name": "n2", + "parent_id": "01978431-b628-758a-aec6-03b331fa1a17", + "status": "pending", + "task_id": "01978431-b62c-7593-aad8-43b03df2031b", + "type": "node_restore" + }, + { + "created_at": "2025-06-18T17:58:59Z", + "database_id": "storefront", + "node_name": "n3", + "parent_id": "01978431-b628-758a-aec6-03b331fa1a17", + "status": "pending", + "task_id": "01978431-b62d-7b65-ab09-272d0b2fea91", + "type": "node_restore" } - ] + ], + "task": { + "created_at": "2025-06-18T17:58:59Z", + "database_id": "storefront", + "status": "pending", + "task_id": "01978431-b628-758a-aec6-03b331fa1a17", + "type": "restore" + } }, "required": [ "task", - "update_database_tasks" + "node_tasks", + "database" ] }, - "RestartInstanceResponse": { + "RestoreRepositorySpec": { "type": "object", "properties": { - "task": { - "$ref": "#/components/schemas/Task" + "azure_account": { + "type": "string", + "description": "The Azure account name for this repository. Only applies when type = 'azure'.", + "example": "pgedge-backups", + "minLength": 3, + "maxLength": 24 + }, + "azure_container": { + "type": "string", + "description": "The Azure container name for this repository. Only applies when type = 'azure'.", + "example": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "minLength": 3, + "maxLength": 63 + }, + "azure_endpoint": { + "type": "string", + "description": "The optional Azure endpoint for this repository. Only applies when type = 'azure'.", + "example": "blob.core.usgovcloudapi.net", + "minLength": 3, + "maxLength": 128 + }, + "azure_key": { + "type": "string", + "description": "An optional Azure storage account access key to use for this repository. If not provided, pgbackrest will use the VM's managed identity.", + "example": "YXpLZXk=", + "maxLength": 128 + }, + "base_path": { + "type": "string", + "description": "The base path within the repository to store backups. Required for type = 'posix' and 'cifs'.", + "example": "/backups", + "maxLength": 256 + }, + "custom_options": { + "type": "object", + "description": "Additional options to apply to this repository.", + "example": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" + }, + "additionalProperties": { + "type": "string", + "example": "Labore explicabo culpa eos natus aperiam excepturi." + } + }, + "gcs_bucket": { + "type": "string", + "description": "The GCS bucket name for this repository. Only applies when type = 'gcs'.", + "example": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "minLength": 3, + "maxLength": 63 + }, + "gcs_endpoint": { + "type": "string", + "description": "The optional GCS endpoint for this repository. Only applies when type = 'gcs'.", + "example": "localhost", + "minLength": 3, + "maxLength": 128 + }, + "gcs_key": { + "type": "string", + "description": "Optional base64-encoded private key data. If omitted, pgbackrest will use the service account attached to the instance profile.", + "example": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "maxLength": 1024 + }, + "id": { + "type": "string", + "description": "A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens.", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 + }, + "s3_bucket": { + "type": "string", + "description": "The S3 bucket name for this repository. Only applies when type = 's3'.", + "example": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "minLength": 3, + "maxLength": 63 + }, + "s3_endpoint": { + "type": "string", + "description": "The optional S3 endpoint for this repository. Only applies when type = 's3'.", + "example": "s3.us-east-1.amazonaws.com", + "minLength": 3, + "maxLength": 128 + }, + "s3_key": { + "type": "string", + "description": "An optional AWS access key ID to use for this repository. If not provided, pgbackrest will use the default credential provider chain.", + "example": "AKIAIOSFODNN7EXAMPLE", + "maxLength": 128 + }, + "s3_key_secret": { + "type": "string", + "description": "The corresponding secret for the AWS access key ID in s3_key.", + "example": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "maxLength": 128 + }, + "s3_region": { + "type": "string", + "description": "The region of the S3 bucket for this repository. Only applies when type = 's3'.", + "example": "us-east-1", + "minLength": 1, + "maxLength": 32 + }, + "type": { + "type": "string", + "description": "The type of this repository.", + "example": "s3", + "enum": [ + "s3", + "gcs", + "azure", + "posix", + "cifs" + ] } }, - "description": "Response containing the restart task", "example": { - "task": { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" - } + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "azure_key": "YXpLZXk=", + "base_path": "/backups", + "custom_options": { + "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" + }, + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", + "id": "f6b84a99-5e91-4203-be1e-131fe82e5984", + "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "s3_endpoint": "s3.us-east-1.amazonaws.com", + "s3_key": "AKIAIOSFODNN7EXAMPLE", + "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "s3_region": "us-east-1", + "type": "s3" }, "required": [ - "task" + "type" ] }, - "RestoreConfigSpec": { + "ServiceInstance": { "type": "object", "properties": { - "repository": { - "$ref": "#/components/schemas/RestoreRepositorySpec" - }, - "restore_options": { - "type": "object", - "description": "Additional options to use when restoring this database. If omitted, the database will be restored to the latest point in the given repository.", - "example": { - "set": "20250505-153628F", - "target": "123456", - "type": "xid" - }, - "maxLength": 32, - "additionalProperties": { - "type": "string", - "example": "Qui sed quis architecto." - } + "created_at": { + "type": "string", + "description": "The time that the service instance was created.", + "example": "2025-01-28T10:00:00Z", + "format": "date-time" }, - "source_database_id": { + "database_id": { "type": "string", "description": "A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens.", "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", "minLength": 1, "maxLength": 63 }, - "source_database_name": { + "error": { "type": "string", - "description": "The name of the database in this repository. The database will be renamed to the database_name in the DatabaseSpec after it's restored.", - "example": "northwind", - "minLength": 1, - "maxLength": 31 + "description": "An error message if the service instance is in an error state.", + "example": "failed to start container: image not found" }, - "source_node_name": { + "host_id": { "type": "string", - "description": "The name of the node to restore this database from.", - "example": "n1", - "pattern": "n[0-9]+" + "description": "The ID of the host this service instance is running on.", + "example": "host-1" + }, + "service_id": { + "type": "string", + "description": "The service ID from the DatabaseSpec.", + "example": "mcp-server" + }, + "service_instance_id": { + "type": "string", + "description": "Unique identifier for the service instance.", + "example": "mcp-server-host-1" + }, + "state": { + "type": "string", + "description": "Current state of the service instance.", + "example": "running", + "enum": [ + "creating", + "running", + "failed", + "deleting" + ] + }, + "status": { + "$ref": "#/components/schemas/ServiceInstanceStatus" + }, + "updated_at": { + "type": "string", + "description": "The time that the service instance was last updated.", + "example": "2025-01-28T10:05:00Z", + "format": "date-time" } }, + "description": "A service instance running on a host alongside the database.", "example": { - "repository": { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" + "created_at": "2025-01-28T10:00:00Z", + "database_id": "production", + "error": "failed to start container: image not found", + "host_id": "host-1", + "service_id": "mcp-server", + "service_instance_id": "mcp-server-host-1", + "state": "running", + "status": { + "container_id": "a1b2c3d4e5f6", + "health_check": { + "checked_at": "2025-01-28T10:00:00Z", + "message": "Connection refused", + "status": "healthy" }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "f6b84a99-5e91-4203-be1e-131fe82e5984", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" - }, - "restore_options": { - "set": "20250505-153628F", - "target": "123456", - "type": "xid" + "hostname": "mcp-server-host-1.internal", + "image_version": "1.0.0", + "ipv4_address": "10.0.1.5", + "last_health_at": "2025-01-28T10:00:00Z", + "ports": [ + { + "container_port": 8080, + "host_port": 8080, + "name": "web-client" + }, + { + "container_port": 8080, + "host_port": 8080, + "name": "web-client" + }, + { + "container_port": 8080, + "host_port": 8080, + "name": "web-client" + } + ], + "service_ready": true }, - "source_database_id": "02f1a7db-fca8-4521-b57a-2a375c1ced51", - "source_database_name": "northwind", - "source_node_name": "n1" + "updated_at": "2025-01-28T10:05:00Z" }, "required": [ - "source_database_id", - "source_node_name", - "source_database_name", - "repository" + "service_instance_id", + "service_id", + "database_id", + "host_id", + "state", + "created_at", + "updated_at" ] }, - "RestoreDatabaseRequest": { + "ServiceInstanceStatus": { "type": "object", "properties": { - "restore_config": { - "$ref": "#/components/schemas/RestoreConfigSpec" + "container_id": { + "type": "string", + "description": "The Docker container ID.", + "example": "a1b2c3d4e5f6" }, - "target_nodes": { + "health_check": { + "$ref": "#/components/schemas/HealthCheckResult" + }, + "hostname": { + "type": "string", + "description": "The hostname of the service instance.", + "example": "mcp-server-host-1.internal" + }, + "image_version": { + "type": "string", + "description": "The container image version currently running.", + "example": "1.0.0" + }, + "ipv4_address": { + "type": "string", + "description": "The IPv4 address of the service instance.", + "example": "10.0.1.5", + "format": "ipv4" + }, + "last_health_at": { + "type": "string", + "description": "The time of the last health check attempt.", + "example": "2025-01-28T10:00:00Z", + "format": "date-time" + }, + "ports": { "type": "array", "items": { - "type": "string", - "example": "Et et reprehenderit et nam quo." + "$ref": "#/components/schemas/PortMapping" }, - "description": "The nodes to restore. Defaults to all nodes if empty or unspecified.", + "description": "Port mappings for this service instance.", "example": [ - "n1" - ], - "maxItems": 9 + { + "container_port": 8080, + "host_port": 8080, + "name": "web-client" + }, + { + "container_port": 8080, + "host_port": 8080, + "name": "web-client" + }, + { + "container_port": 8080, + "host_port": 8080, + "name": "web-client" + }, + { + "container_port": 8080, + "host_port": 8080, + "name": "web-client" + } + ] + }, + "service_ready": { + "type": "boolean", + "description": "Whether the service is ready to accept requests.", + "example": true } }, + "description": "Runtime status information for a service instance.", "example": { - "restore_config": { - "repository": { - "base_path": "/backups", - "type": "posix" - }, - "source_database_id": "storefront", - "source_database_name": "storefront", - "source_node_name": "n1" + "container_id": "a1b2c3d4e5f6", + "health_check": { + "checked_at": "2025-01-28T10:00:00Z", + "message": "Connection refused", + "status": "healthy" }, - "target_nodes": [ - "n1" - ] - }, - "required": [ - "restore_config" - ] + "hostname": "mcp-server-host-1.internal", + "image_version": "1.0.0", + "ipv4_address": "10.0.1.5", + "last_health_at": "2025-01-28T10:00:00Z", + "ports": [ + { + "container_port": 8080, + "host_port": 8080, + "name": "web-client" + }, + { + "container_port": 8080, + "host_port": 8080, + "name": "web-client" + } + ], + "service_ready": true + } }, - "RestoreDatabaseResponse": { + "ServiceSpec": { "type": "object", "properties": { - "database": { - "$ref": "#/components/schemas/Database" + "config": { + "type": "object", + "description": "Service-specific configuration. For MCP services, this includes llm_provider, llm_model, and provider-specific API keys.", + "example": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "additionalProperties": true }, - "node_tasks": { + "cpus": { + "type": "string", + "description": "The number of CPUs to allocate for this service. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Defaults to container defaults if unspecified.", + "example": "500m", + "pattern": "^[0-9]+(\\.[0-9]{1,3}|m)?$" + }, + "host_ids": { "type": "array", "items": { - "$ref": "#/components/schemas/Task" + "type": "string", + "description": "A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens.", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 }, - "description": "The tasks that will restore each database node.", + "description": "The IDs of the hosts that should run this service. One service instance will be created per host.", "example": [ - { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" - }, - { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" - }, - { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" - } + "de3b1388-1f0c-42f1-a86c-59ab72f255ec" + ], + "minItems": 1 + }, + "memory": { + "type": "string", + "description": "The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified.", + "example": "512M", + "maxLength": 16 + }, + "orchestrator_opts": { + "$ref": "#/components/schemas/OrchestratorOpts" + }, + "port": { + "type": "integer", + "description": "The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network.", + "example": 0, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, + "service_id": { + "type": "string", + "description": "A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens.", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 + }, + "service_type": { + "type": "string", + "description": "The type of service to run.", + "example": "mcp", + "enum": [ + "mcp" ] }, - "task": { - "$ref": "#/components/schemas/Task" + "version": { + "type": "string", + "description": "The version of the service in semver format (e.g., '1.0.0') or the literal 'latest'.", + "example": "latest", + "pattern": "^(\\d+\\.\\d+\\.\\d+|latest)$" } }, "example": { - "database": { - "created_at": "2025-06-18T16:52:05Z", - "id": "storefront", - "instances": [ - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "2025-06-18T16:52:22Z", - "host_id": "us-east-1", - "id": "storefront-n1-689qacsi", - "node_name": "n1", - "postgres": { - "patroni_state": "running", - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n3", - "provider_node": "n3", - "status": "replicating" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "replicating" - } - ], - "version": "4.0.10" - }, - "state": "available", - "status_updated_at": "2025-06-18T17:58:56Z", - "updated_at": "2025-06-18T17:54:36Z" + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "de3b1388-1f0c-42f1-a86c-59ab72f255ec" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" }, - { - "connection_info": { - "hostname": "i-058731542fee493f.ec2.internal", - "ipv4_address": "10.24.35.2", - "port": 5432 - }, - "created_at": "2025-06-18T16:52:22Z", - "host_id": "ap-south-1", - "id": "storefront-n2-9ptayhma", - "node_name": "n2", - "postgres": { - "patroni_state": "running", - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n2n1", - "provider_node": "n1", - "status": "replicating" - }, - { - "name": "sub_n2n3", - "provider_node": "n3", - "status": "replicating" - } + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" ], - "version": "4.0.10" - }, - "state": "available", - "status_updated_at": "2025-06-18T17:58:56Z", - "updated_at": "2025-06-18T17:54:01Z" - }, - { - "connection_info": { - "hostname": "i-494027b7b53f6a23.ec2.internal", - "ipv4_address": "10.24.36.2", - "port": 5432 - }, - "created_at": "2025-06-18T16:52:22Z", - "host_id": "eu-central-1", - "id": "storefront-n3-ant97dj4", - "node_name": "n3", - "postgres": { - "patroni_state": "running", - "role": "primary", - "version": "18.1" + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n3n1", - "provider_node": "n1", - "status": "replicating" - }, - { - "name": "sub_n3n2", - "provider_node": "n2", - "status": "replicating" - } + { + "aliases": [ + "pg-db", + "db-alias" ], - "version": "4.0.10" + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" }, - "state": "available", - "status_updated_at": "2025-06-18T17:58:56Z", - "updated_at": "2025-06-18T17:54:01Z" - } - ], - "spec": { - "database_name": "storefront", - "database_users": [ { - "attributes": [ - "SUPERUSER", - "LOGIN" + "aliases": [ + "pg-db", + "db-alias" ], - "db_owner": true, - "username": "admin" + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" } ], - "nodes": [ + "extra_volumes": [ { - "host_ids": [ - "us-east-1" - ], - "name": "n1" + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" }, { - "host_ids": [ - "ap-south-1" - ], - "name": "n2" + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" }, { - "host_ids": [ - "eu-central-1" - ], - "name": "n3" + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" } - ], - "port": 5432, - "postgres_version": "17.6", - "spock_version": "5" - }, - "state": "restoring", - "updated_at": "2025-06-18T17:58:59Z" - }, - "node_tasks": [ - { - "created_at": "2025-06-18T17:58:59Z", - "database_id": "storefront", - "node_name": "n1", - "parent_id": "01978431-b628-758a-aec6-03b331fa1a17", - "status": "pending", - "task_id": "01978431-b62b-723b-a09c-e4072cd64bdb", - "type": "node_restore" - }, - { - "created_at": "2025-06-18T17:58:59Z", - "database_id": "storefront", - "node_name": "n2", - "parent_id": "01978431-b628-758a-aec6-03b331fa1a17", - "status": "pending", - "task_id": "01978431-b62c-7593-aad8-43b03df2031b", - "type": "node_restore" - }, - { - "created_at": "2025-06-18T17:58:59Z", - "database_id": "storefront", - "node_name": "n3", - "parent_id": "01978431-b628-758a-aec6-03b331fa1a17", - "status": "pending", - "task_id": "01978431-b62d-7b65-ab09-272d0b2fea91", - "type": "node_restore" + ] } - ], - "task": { - "created_at": "2025-06-18T17:58:59Z", - "database_id": "storefront", - "status": "pending", - "task_id": "01978431-b628-758a-aec6-03b331fa1a17", - "type": "restore" - } + }, + "port": 0, + "service_id": "analytics-service", + "service_type": "mcp", + "version": "latest" }, "required": [ - "task", - "node_tasks", - "database" + "service_id", + "service_type", + "version", + "host_ids", + "config" ] }, - "RestoreDatabaseResponse2": { + "ServiceSpec2": { "type": "object", "properties": { - "database": { - "$ref": "#/components/schemas/Database5" + "config": { + "type": "object", + "description": "Service-specific configuration. For MCP services, this includes llm_provider, llm_model, and provider-specific API keys.", + "example": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "additionalProperties": true }, - "node_tasks": { + "cpus": { + "type": "string", + "description": "The number of CPUs to allocate for this service. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Defaults to container defaults if unspecified.", + "example": "500m", + "pattern": "^[0-9]+(\\.[0-9]{1,3}|m)?$" + }, + "host_ids": { "type": "array", "items": { - "$ref": "#/components/schemas/Task" + "type": "string", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 }, - "description": "The tasks that will restore each database node.", + "description": "The IDs of the hosts that should run this service. One service instance will be created per host.", "example": [ - { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" - }, - { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" - }, - { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" - }, - { - "completed_at": "2025-06-18T16:52:35Z", - "created_at": "2025-06-18T16:52:05Z", - "database_id": "storefront", - "entity_id": "storefront", - "scope": "database", - "status": "completed", - "task_id": "019783f4-75f4-71e7-85a3-c9b96b345d77", - "type": "create" - } + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "minItems": 1 + }, + "memory": { + "type": "string", + "description": "The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified.", + "example": "512M", + "maxLength": 16 + }, + "orchestrator_opts": { + "$ref": "#/components/schemas/OrchestratorOpts" + }, + "port": { + "type": "integer", + "description": "The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network.", + "example": 0, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, + "service_id": { + "type": "string", + "description": "The unique identifier for this service.", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 + }, + "service_type": { + "type": "string", + "description": "The type of service to run.", + "example": "mcp", + "enum": [ + "mcp" ] }, - "task": { - "$ref": "#/components/schemas/Task" - } - }, - "example": { - "database": { - "created_at": "2025-06-18T16:52:05Z", - "id": "storefront", - "instances": [ - { - "connection_info": { - "hostname": "i-0123456789abcdef.ec2.internal", - "ipv4_address": "10.24.34.2", - "port": 5432 - }, - "created_at": "2025-06-18T16:52:22Z", - "host_id": "us-east-1", - "id": "storefront-n1-689qacsi", - "node_name": "n1", - "postgres": { - "patroni_state": "running", - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n1n3", - "provider_node": "n3", - "status": "replicating" - }, - { - "name": "sub_n1n2", - "provider_node": "n2", - "status": "replicating" - } - ], - "version": "4.0.10" - }, - "state": "available", - "status_updated_at": "2025-06-18T17:58:56Z", - "updated_at": "2025-06-18T17:54:36Z" - }, - { - "connection_info": { - "hostname": "i-058731542fee493f.ec2.internal", - "ipv4_address": "10.24.35.2", - "port": 5432 - }, - "created_at": "2025-06-18T16:52:22Z", - "host_id": "ap-south-1", - "id": "storefront-n2-9ptayhma", - "node_name": "n2", - "postgres": { - "patroni_state": "running", - "role": "primary", - "version": "18.1" - }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n2n1", - "provider_node": "n1", - "status": "replicating" - }, - { - "name": "sub_n2n3", - "provider_node": "n3", - "status": "replicating" - } - ], - "version": "4.0.10" - }, - "state": "available", - "status_updated_at": "2025-06-18T17:58:56Z", - "updated_at": "2025-06-18T17:54:01Z" + "version": { + "type": "string", + "description": "The version of the service in semver format (e.g., '1.0.0') or the literal 'latest'.", + "example": "latest", + "pattern": "^(\\d+\\.\\d+\\.\\d+|latest)$" + } + }, + "example": { + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" }, - { - "connection_info": { - "hostname": "i-494027b7b53f6a23.ec2.internal", - "ipv4_address": "10.24.36.2", - "port": 5432 - }, - "created_at": "2025-06-18T16:52:22Z", - "host_id": "eu-central-1", - "id": "storefront-n3-ant97dj4", - "node_name": "n3", - "postgres": { - "patroni_state": "running", - "role": "primary", - "version": "18.1" + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" }, - "spock": { - "read_only": "off", - "subscriptions": [ - { - "name": "sub_n3n1", - "provider_node": "n1", - "status": "replicating" - }, - { - "name": "sub_n3n2", - "provider_node": "n2", - "status": "replicating" - } + { + "aliases": [ + "pg-db", + "db-alias" ], - "version": "4.0.10" + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" }, - "state": "available", - "status_updated_at": "2025-06-18T17:58:56Z", - "updated_at": "2025-06-18T17:54:01Z" - } - ], - "spec": { - "database_name": "storefront", - "database_users": [ { - "attributes": [ - "SUPERUSER", - "LOGIN" + "aliases": [ + "pg-db", + "db-alias" ], - "db_owner": true, - "username": "admin" + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" } ], - "nodes": [ + "extra_volumes": [ { - "host_ids": [ - "us-east-1" - ], - "name": "n1" + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" }, { - "host_ids": [ - "ap-south-1" - ], - "name": "n2" + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" }, { - "host_ids": [ - "eu-central-1" - ], - "name": "n3" + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" } - ], - "port": 5432, - "postgres_version": "17.6", - "spock_version": "5" - }, - "state": "restoring", - "updated_at": "2025-06-18T17:58:59Z" + ] + } }, - "node_tasks": [ - { - "created_at": "2025-06-18T17:58:59Z", - "database_id": "storefront", - "node_name": "n1", - "parent_id": "01978431-b628-758a-aec6-03b331fa1a17", - "status": "pending", - "task_id": "01978431-b62b-723b-a09c-e4072cd64bdb", - "type": "node_restore" + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" + }, + "required": [ + "service_id", + "service_type", + "version", + "host_ids", + "config" + ] + }, + "ServiceSpec3": { + "type": "object", + "properties": { + "config": { + "type": "object", + "description": "Service-specific configuration. For MCP services, this includes llm_provider, llm_model, and provider-specific API keys.", + "example": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." }, - { - "created_at": "2025-06-18T17:58:59Z", - "database_id": "storefront", - "node_name": "n2", - "parent_id": "01978431-b628-758a-aec6-03b331fa1a17", - "status": "pending", - "task_id": "01978431-b62c-7593-aad8-43b03df2031b", - "type": "node_restore" + "additionalProperties": true + }, + "cpus": { + "type": "string", + "description": "The number of CPUs to allocate for this service. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Defaults to container defaults if unspecified.", + "example": "500m", + "pattern": "^[0-9]+(\\.[0-9]{1,3}|m)?$" + }, + "host_ids": { + "type": "array", + "items": { + "type": "string", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 }, - { - "created_at": "2025-06-18T17:58:59Z", - "database_id": "storefront", - "node_name": "n3", - "parent_id": "01978431-b628-758a-aec6-03b331fa1a17", - "status": "pending", - "task_id": "01978431-b62d-7b65-ab09-272d0b2fea91", - "type": "node_restore" + "description": "The IDs of the hosts that should run this service. One service instance will be created per host.", + "example": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "minItems": 1 + }, + "memory": { + "type": "string", + "description": "The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified.", + "example": "512M", + "maxLength": 16 + }, + "orchestrator_opts": { + "$ref": "#/components/schemas/OrchestratorOpts" + }, + "port": { + "type": "integer", + "description": "The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network.", + "example": 0, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, + "service_id": { + "type": "string", + "description": "The unique identifier for this service.", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 + }, + "service_type": { + "type": "string", + "description": "The type of service to run.", + "example": "mcp", + "enum": [ + "mcp" + ] + }, + "version": { + "type": "string", + "description": "The version of the service in semver format (e.g., '1.0.0') or the literal 'latest'.", + "example": "latest", + "pattern": "^(\\d+\\.\\d+\\.\\d+|latest)$" + } + }, + "example": { + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] } - ], - "task": { - "created_at": "2025-06-18T17:58:59Z", - "database_id": "storefront", - "status": "pending", - "task_id": "01978431-b628-758a-aec6-03b331fa1a17", - "type": "restore" - } + }, + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" }, "required": [ - "task", - "node_tasks", - "database" + "service_id", + "service_type", + "version", + "host_ids", + "config" ] }, - "RestoreRepositorySpec": { + "ServiceSpec4": { "type": "object", "properties": { - "azure_account": { - "type": "string", - "description": "The Azure account name for this repository. Only applies when type = 'azure'.", - "example": "pgedge-backups", - "minLength": 3, - "maxLength": 24 - }, - "azure_container": { - "type": "string", - "description": "The Azure container name for this repository. Only applies when type = 'azure'.", - "example": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "minLength": 3, - "maxLength": 63 - }, - "azure_endpoint": { - "type": "string", - "description": "The optional Azure endpoint for this repository. Only applies when type = 'azure'.", - "example": "blob.core.usgovcloudapi.net", - "minLength": 3, - "maxLength": 128 - }, - "azure_key": { - "type": "string", - "description": "An optional Azure storage account access key to use for this repository. If not provided, pgbackrest will use the VM's managed identity.", - "example": "YXpLZXk=", - "maxLength": 128 - }, - "base_path": { - "type": "string", - "description": "The base path within the repository to store backups. Required for type = 'posix' and 'cifs'.", - "example": "/backups", - "maxLength": 256 - }, - "custom_options": { + "config": { "type": "object", - "description": "Additional options to apply to this repository.", + "description": "Service-specific configuration. For MCP services, this includes llm_provider, llm_model, and provider-specific API keys.", "example": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." }, - "additionalProperties": { - "type": "string", - "example": "Excepturi consectetur accusantium ut." - } - }, - "gcs_bucket": { - "type": "string", - "description": "The GCS bucket name for this repository. Only applies when type = 'gcs'.", - "example": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "minLength": 3, - "maxLength": 63 - }, - "gcs_endpoint": { - "type": "string", - "description": "The optional GCS endpoint for this repository. Only applies when type = 'gcs'.", - "example": "localhost", - "minLength": 3, - "maxLength": 128 - }, - "gcs_key": { - "type": "string", - "description": "Optional base64-encoded private key data. If omitted, pgbackrest will use the service account attached to the instance profile.", - "example": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "maxLength": 1024 + "additionalProperties": true }, - "id": { + "cpus": { "type": "string", - "description": "A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens.", - "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "minLength": 1, - "maxLength": 63 + "description": "The number of CPUs to allocate for this service. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Defaults to container defaults if unspecified.", + "example": "500m", + "pattern": "^[0-9]+(\\.[0-9]{1,3}|m)?$" }, - "s3_bucket": { - "type": "string", - "description": "The S3 bucket name for this repository. Only applies when type = 's3'.", - "example": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "minLength": 3, - "maxLength": 63 + "host_ids": { + "type": "array", + "items": { + "type": "string", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 + }, + "description": "The IDs of the hosts that should run this service. One service instance will be created per host.", + "example": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "minItems": 1 }, - "s3_endpoint": { + "memory": { "type": "string", - "description": "The optional S3 endpoint for this repository. Only applies when type = 's3'.", - "example": "s3.us-east-1.amazonaws.com", - "minLength": 3, - "maxLength": 128 + "description": "The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified.", + "example": "512M", + "maxLength": 16 }, - "s3_key": { - "type": "string", - "description": "An optional AWS access key ID to use for this repository. If not provided, pgbackrest will use the default credential provider chain.", - "example": "AKIAIOSFODNN7EXAMPLE", - "maxLength": 128 + "orchestrator_opts": { + "$ref": "#/components/schemas/OrchestratorOpts" }, - "s3_key_secret": { - "type": "string", - "description": "The corresponding secret for the AWS access key ID in s3_key.", - "example": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "maxLength": 128 + "port": { + "type": "integer", + "description": "The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network.", + "example": 0, + "format": "int64", + "minimum": 0, + "maximum": 65535 }, - "s3_region": { + "service_id": { "type": "string", - "description": "The region of the S3 bucket for this repository. Only applies when type = 's3'.", - "example": "us-east-1", + "description": "The unique identifier for this service.", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", "minLength": 1, - "maxLength": 32 + "maxLength": 63 }, - "type": { + "service_type": { "type": "string", - "description": "The type of this repository.", - "example": "s3", + "description": "The type of service to run.", + "example": "mcp", "enum": [ - "s3", - "gcs", - "azure", - "posix", - "cifs" + "mcp" ] + }, + "version": { + "type": "string", + "description": "The version of the service in semver format (e.g., '1.0.0') or the literal 'latest'.", + "example": "latest", + "pattern": "^(\\d+\\.\\d+\\.\\d+|latest)$" } }, "example": { - "azure_account": "pgedge-backups", - "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "azure_endpoint": "blob.core.usgovcloudapi.net", - "azure_key": "YXpLZXk=", - "base_path": "/backups", - "custom_options": { - "s3-kms-key-id": "1234abcd-12ab-34cd-56ef-1234567890ab" + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } }, - "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "gcs_endpoint": "localhost", - "gcs_key": "ZXhhbXBsZSBnY3Mga2V5Cg==", - "id": "f6b84a99-5e91-4203-be1e-131fe82e5984", - "s3_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", - "s3_endpoint": "s3.us-east-1.amazonaws.com", - "s3_key": "AKIAIOSFODNN7EXAMPLE", - "s3_key_secret": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "s3_region": "us-east-1", - "type": "s3" + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" }, "required": [ - "type" + "service_id", + "service_type", + "version", + "host_ids", + "config" ] }, - "ServiceInstance": { + "ServiceSpec5": { "type": "object", "properties": { - "created_at": { - "type": "string", - "description": "The time that the service instance was created.", - "example": "2025-01-28T10:00:00Z", - "format": "date-time" + "config": { + "type": "object", + "description": "Service-specific configuration. For MCP services, this includes llm_provider, llm_model, and provider-specific API keys.", + "example": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "additionalProperties": true }, - "database_id": { + "cpus": { "type": "string", - "description": "A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens.", - "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", - "minLength": 1, - "maxLength": 63 + "description": "The number of CPUs to allocate for this service. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Defaults to container defaults if unspecified.", + "example": "500m", + "pattern": "^[0-9]+(\\.[0-9]{1,3}|m)?$" }, - "error": { - "type": "string", - "description": "An error message if the service instance is in an error state.", - "example": "failed to start container: image not found" + "host_ids": { + "type": "array", + "items": { + "type": "string", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 + }, + "description": "The IDs of the hosts that should run this service. One service instance will be created per host.", + "example": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "minItems": 1 }, - "host_id": { + "memory": { "type": "string", - "description": "The ID of the host this service instance is running on.", - "example": "host-1" + "description": "The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified.", + "example": "512M", + "maxLength": 16 }, - "service_id": { - "type": "string", - "description": "The service ID from the DatabaseSpec.", - "example": "mcp-server" + "orchestrator_opts": { + "$ref": "#/components/schemas/OrchestratorOpts" }, - "service_instance_id": { + "port": { + "type": "integer", + "description": "The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network.", + "example": 0, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, + "service_id": { "type": "string", - "description": "Unique identifier for the service instance.", - "example": "mcp-server-host-1" + "description": "The unique identifier for this service.", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 }, - "state": { + "service_type": { "type": "string", - "description": "Current state of the service instance.", - "example": "running", + "description": "The type of service to run.", + "example": "mcp", "enum": [ - "creating", - "running", - "failed", - "deleting" + "mcp" ] }, - "status": { - "$ref": "#/components/schemas/ServiceInstanceStatus" - }, - "updated_at": { + "version": { "type": "string", - "description": "The time that the service instance was last updated.", - "example": "2025-01-28T10:05:00Z", - "format": "date-time" + "description": "The version of the service in semver format (e.g., '1.0.0') or the literal 'latest'.", + "example": "latest", + "pattern": "^(\\d+\\.\\d+\\.\\d+|latest)$" } }, - "description": "A service instance running on a host alongside the database.", "example": { - "created_at": "2025-01-28T10:00:00Z", - "database_id": "production", - "error": "failed to start container: image not found", - "host_id": "host-1", - "service_id": "mcp-server", - "service_instance_id": "mcp-server-host-1", - "state": "running", - "status": { - "container_id": "a1b2c3d4e5f6", - "health_check": { - "checked_at": "2025-01-28T10:00:00Z", - "message": "Connection refused", - "status": "healthy" - }, - "hostname": "mcp-server-host-1.internal", - "image_version": "1.0.0", - "ipv4_address": "10.0.1.5", - "last_health_at": "2025-01-28T10:00:00Z", - "ports": [ - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - }, - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" }, - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - } - ], - "service_ready": true + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } }, - "updated_at": "2025-01-28T10:05:00Z" + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" }, "required": [ - "service_instance_id", "service_id", - "database_id", - "host_id", - "state", - "created_at", - "updated_at" + "service_type", + "version", + "host_ids", + "config" ] }, - "ServiceInstanceStatus": { + "ServiceSpec6": { "type": "object", "properties": { - "container_id": { - "type": "string", - "description": "The Docker container ID.", - "example": "a1b2c3d4e5f6" - }, - "health_check": { - "$ref": "#/components/schemas/HealthCheckResult" + "config": { + "type": "object", + "description": "Service-specific configuration. For MCP services, this includes llm_provider, llm_model, and provider-specific API keys.", + "example": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." + }, + "additionalProperties": true }, - "hostname": { + "cpus": { "type": "string", - "description": "The hostname of the service instance.", - "example": "mcp-server-host-1.internal" + "description": "The number of CPUs to allocate for this service. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Defaults to container defaults if unspecified.", + "example": "500m", + "pattern": "^[0-9]+(\\.[0-9]{1,3}|m)?$" }, - "image_version": { - "type": "string", - "description": "The container image version currently running.", - "example": "1.0.0" + "host_ids": { + "type": "array", + "items": { + "type": "string", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 + }, + "description": "The IDs of the hosts that should run this service. One service instance will be created per host.", + "example": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" + ], + "minItems": 1 }, - "ipv4_address": { + "memory": { "type": "string", - "description": "The IPv4 address of the service instance.", - "example": "10.0.1.5", - "format": "ipv4" + "description": "The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified.", + "example": "512M", + "maxLength": 16 }, - "last_health_at": { + "orchestrator_opts": { + "$ref": "#/components/schemas/OrchestratorOpts" + }, + "port": { + "type": "integer", + "description": "The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network.", + "example": 0, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, + "service_id": { "type": "string", - "description": "The time of the last health check attempt.", - "example": "2025-01-28T10:00:00Z", - "format": "date-time" + "description": "The unique identifier for this service.", + "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "minLength": 1, + "maxLength": 63 }, - "ports": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PortMapping" - }, - "description": "Port mappings for this service instance.", - "example": [ - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - }, - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - } + "service_type": { + "type": "string", + "description": "The type of service to run.", + "example": "mcp", + "enum": [ + "mcp" ] }, - "service_ready": { - "type": "boolean", - "description": "Whether the service is ready to accept requests.", - "example": true + "version": { + "type": "string", + "description": "The version of the service in semver format (e.g., '1.0.0') or the literal 'latest'.", + "example": "latest", + "pattern": "^(\\d+\\.\\d+\\.\\d+|latest)$" } }, - "description": "Runtime status information for a service instance.", "example": { - "container_id": "a1b2c3d4e5f6", - "health_check": { - "checked_at": "2025-01-28T10:00:00Z", - "message": "Connection refused", - "status": "healthy" + "config": { + "llm_model": "gpt-4", + "llm_provider": "openai", + "openai_api_key": "sk-..." }, - "hostname": "mcp-server-host-1.internal", - "image_version": "1.0.0", - "ipv4_address": "10.0.1.5", - "last_health_at": "2025-01-28T10:00:00Z", - "ports": [ - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - }, - { - "container_port": 8080, - "host_port": 8080, - "name": "web-client" - } + "cpus": "500m", + "host_ids": [ + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" ], - "service_ready": true - } + "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, + "port": 0, + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", + "service_type": "mcp", + "version": "latest" + }, + "required": [ + "service_id", + "service_type", + "version", + "host_ids", + "config" + ] }, - "ServiceSpec": { + "ServiceSpec7": { "type": "object", "properties": { "config": { @@ -23632,16 +26232,15 @@ "type": "array", "items": { "type": "string", - "description": "A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens.", "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", "minLength": 1, "maxLength": 63 }, "description": "The IDs of the hosts that should run this service. One service instance will be created per host.", "example": [ - "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "de3b1388-1f0c-42f1-a86c-59ab72f255ec" + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "minItems": 1 }, @@ -23651,6 +26250,9 @@ "example": "512M", "maxLength": 16 }, + "orchestrator_opts": { + "$ref": "#/components/schemas/OrchestratorOpts" + }, "port": { "type": "integer", "description": "The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network.", @@ -23661,7 +26263,7 @@ }, "service_id": { "type": "string", - "description": "A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens.", + "description": "The unique identifier for this service.", "example": "76f9b8c0-4958-11f0-a489-3bb29577c696", "minLength": 1, "maxLength": 63 @@ -23689,13 +26291,67 @@ }, "cpus": "500m", "host_ids": [ - "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "de3b1388-1f0c-42f1-a86c-59ab72f255ec", - "de3b1388-1f0c-42f1-a86c-59ab72f255ec" + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696", + "76f9b8c0-4958-11f0-a489-3bb29577c696" ], "memory": "512M", + "orchestrator_opts": { + "swarm": { + "extra_labels": { + "traefik.enable": "true", + "traefik.tcp.routers.mydb.rule": "HostSNI(`mydb.example.com`)" + }, + "extra_networks": [ + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + }, + { + "aliases": [ + "pg-db", + "db-alias" + ], + "driver_opts": { + "com.docker.network.endpoint.expose": "true" + }, + "id": "traefik-public" + } + ], + "extra_volumes": [ + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + }, + { + "destination_path": "/backups/container", + "host_path": "/Users/user/backups/host" + } + ] + } + }, "port": 0, - "service_id": "analytics-service", + "service_id": "76f9b8c0-4958-11f0-a489-3bb29577c696", "service_type": "mcp", "version": "latest" }, diff --git a/api/apiv1/gen/http/openapi3.yaml b/api/apiv1/gen/http/openapi3.yaml index 8e1375ed..ac461a8e 100644 --- a/api/apiv1/gen/http/openapi3.yaml +++ b/api/apiv1/gen/http/openapi3.yaml @@ -1115,18 +1115,17 @@ paths: type: array items: type: string - example: Deserunt earum doloribus eos et error vel. + example: Earum doloribus eos et error. description: Host IDs to treat as removed during this update. Events targeting these hosts will be skipped. example: - - Recusandae aspernatur non sit aliquam dolor quam. - - Tempore veniam et. - - Dignissimos voluptatem soluta veritatis repellat est rerum. - - Inventore modi explicabo dicta sint. + - Et recusandae aspernatur non sit aliquam. + - Quam ea tempore veniam et deleniti dignissimos. + - Soluta veritatis repellat est rerum est. example: - - Et animi magnam velit vitae praesentium ad. + - Explicabo dicta sint. + - Quis et animi. + - Velit vitae praesentium ad. - Eos pariatur nobis hic. - - Et consectetur eius temporibus. - - Porro ut placeat non ut. - name: database_id in: path description: ID of the database to update. @@ -3872,7 +3871,7 @@ components: storage-upload-chunk-size: 5MiB additionalProperties: type: string - example: Ipsum officiis et est et dolorem labore. + example: Beatae quasi ipsum. gcs_bucket: type: string description: The GCS bucket name for this repository. Only applies when type = 'gcs'. @@ -4575,7 +4574,7 @@ components: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -4598,86 +4597,15 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down - version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" - - connection_info: - hostname: i-0123456789abcdef.ec2.internal - ipv4_address: 10.24.34.2 - port: 5432 - created_at: "1970-10-16T01:30:13Z" - error: 'failed to get patroni status: connection refused' - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec - id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d - node_name: n1 - postgres: - patroni_paused: true - patroni_state: unknown - pending_restart: true - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" - - connection_info: - hostname: i-0123456789abcdef.ec2.internal - ipv4_address: 10.24.34.2 - port: 5432 - created_at: "1970-10-16T01:30:13Z" - error: 'failed to get patroni status: connection refused' - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec - id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d - node_name: n1 - postgres: - patroni_paused: true - patroni_state: unknown - pending_restart: true - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" - connection_info: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -4700,13 +4628,10 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" service_instances: type: array items: @@ -4834,7 +4759,7 @@ components: state: type: string description: Current state of the database. - example: backing_up + example: degraded enum: - creating - modifying @@ -5045,68 +4970,6 @@ components: state: unknown status_updated_at: "1993-04-25T23:06:28Z" updated_at: "1981-08-22T23:20:01Z" - - connection_info: - hostname: i-0123456789abcdef.ec2.internal - ipv4_address: 10.24.34.2 - port: 5432 - created_at: "2011-03-15T17:48:48Z" - error: 'failed to get patroni status: connection refused' - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec - id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d - node_name: n1 - postgres: - patroni_paused: false - patroni_state: unknown - pending_restart: true - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - version: 4.10.0 - state: unknown - status_updated_at: "1993-04-25T23:06:28Z" - updated_at: "1981-08-22T23:20:01Z" - - connection_info: - hostname: i-0123456789abcdef.ec2.internal - ipv4_address: 10.24.34.2 - port: 5432 - created_at: "2011-03-15T17:48:48Z" - error: 'failed to get patroni status: connection refused' - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec - id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d - node_name: n1 - postgres: - patroni_paused: false - patroni_state: unknown - pending_restart: true - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - version: 4.10.0 - state: unknown - status_updated_at: "1993-04-25T23:06:28Z" - updated_at: "1981-08-22T23:20:01Z" service_instances: type: array items: @@ -5177,44 +5040,12 @@ components: name: web-client service_ready: true updated_at: "2025-01-28T10:05:00Z" - - created_at: "2025-01-28T10:00:00Z" - database_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - error: 'failed to start container: image not found' - host_id: host-1 - service_id: mcp-server - service_instance_id: mcp-server-host-1 - state: running - status: - container_id: a1b2c3d4e5f6 - health_check: - checked_at: "2025-01-28T10:00:00Z" - message: Connection refused - status: healthy - hostname: mcp-server-host-1.internal - image_version: 1.0.0 - ipv4_address: 10.0.1.5 - last_health_at: "2025-01-28T10:00:00Z" - ports: - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - service_ready: true - updated_at: "2025-01-28T10:05:00Z" spec: $ref: '#/components/schemas/DatabaseSpec3' state: type: string description: Current state of the database. - example: backing_up + example: restoring enum: - creating - modifying @@ -5456,6 +5287,37 @@ components: state: unknown status_updated_at: "1993-04-25T23:06:28Z" updated_at: "1981-08-22T23:20:01Z" + - connection_info: + hostname: i-0123456789abcdef.ec2.internal + ipv4_address: 10.24.34.2 + port: 5432 + created_at: "2011-03-15T17:48:48Z" + error: 'failed to get patroni status: connection refused' + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + node_name: n1 + postgres: + patroni_paused: false + patroni_state: unknown + pending_restart: true + role: primary + version: "18.1" + spock: + read_only: "off" + subscriptions: + - name: sub_n1n2 + provider_node: n2 + status: down + - name: sub_n1n2 + provider_node: n2 + status: down + - name: sub_n1n2 + provider_node: n2 + status: down + version: 4.10.0 + state: unknown + status_updated_at: "1993-04-25T23:06:28Z" + updated_at: "1981-08-22T23:20:01Z" service_instances: type: array items: @@ -5558,44 +5420,12 @@ components: name: web-client service_ready: true updated_at: "2025-01-28T10:05:00Z" - - created_at: "2025-01-28T10:00:00Z" - database_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - error: 'failed to start container: image not found' - host_id: host-1 - service_id: mcp-server - service_instance_id: mcp-server-host-1 - state: running - status: - container_id: a1b2c3d4e5f6 - health_check: - checked_at: "2025-01-28T10:00:00Z" - message: Connection refused - status: healthy - hostname: mcp-server-host-1.internal - image_version: 1.0.0 - ipv4_address: 10.0.1.5 - last_health_at: "2025-01-28T10:00:00Z" - ports: - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - service_ready: true - updated_at: "2025-01-28T10:05:00Z" spec: $ref: '#/components/schemas/DatabaseSpec4' state: type: string description: Current state of the database. - example: available + example: degraded enum: - creating - modifying @@ -5837,37 +5667,6 @@ components: state: unknown status_updated_at: "1993-04-25T23:06:28Z" updated_at: "1981-08-22T23:20:01Z" - - connection_info: - hostname: i-0123456789abcdef.ec2.internal - ipv4_address: 10.24.34.2 - port: 5432 - created_at: "2011-03-15T17:48:48Z" - error: 'failed to get patroni status: connection refused' - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec - id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d - node_name: n1 - postgres: - patroni_paused: false - patroni_state: unknown - pending_restart: true - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - version: 4.10.0 - state: unknown - status_updated_at: "1993-04-25T23:06:28Z" - updated_at: "1981-08-22T23:20:01Z" service_instances: type: array items: @@ -5938,44 +5737,12 @@ components: name: web-client service_ready: true updated_at: "2025-01-28T10:05:00Z" - - created_at: "2025-01-28T10:00:00Z" - database_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - error: 'failed to start container: image not found' - host_id: host-1 - service_id: mcp-server - service_instance_id: mcp-server-host-1 - state: running - status: - container_id: a1b2c3d4e5f6 - health_check: - checked_at: "2025-01-28T10:00:00Z" - message: Connection refused - status: healthy - hostname: mcp-server-host-1.internal - image_version: 1.0.0 - ipv4_address: 10.0.1.5 - last_health_at: "2025-01-28T10:00:00Z" - ports: - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - service_ready: true - updated_at: "2025-01-28T10:05:00Z" spec: $ref: '#/components/schemas/DatabaseSpec6' state: type: string description: Current state of the database. - example: deleting + example: degraded enum: - creating - modifying @@ -6186,68 +5953,6 @@ components: state: unknown status_updated_at: "1993-04-25T23:06:28Z" updated_at: "1981-08-22T23:20:01Z" - - connection_info: - hostname: i-0123456789abcdef.ec2.internal - ipv4_address: 10.24.34.2 - port: 5432 - created_at: "2011-03-15T17:48:48Z" - error: 'failed to get patroni status: connection refused' - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec - id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d - node_name: n1 - postgres: - patroni_paused: false - patroni_state: unknown - pending_restart: true - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - version: 4.10.0 - state: unknown - status_updated_at: "1993-04-25T23:06:28Z" - updated_at: "1981-08-22T23:20:01Z" - - connection_info: - hostname: i-0123456789abcdef.ec2.internal - ipv4_address: 10.24.34.2 - port: 5432 - created_at: "2011-03-15T17:48:48Z" - error: 'failed to get patroni status: connection refused' - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec - id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d - node_name: n1 - postgres: - patroni_paused: false - patroni_state: unknown - pending_restart: true - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - version: 4.10.0 - state: unknown - status_updated_at: "1993-04-25T23:06:28Z" - updated_at: "1981-08-22T23:20:01Z" service_instances: type: array items: @@ -6387,7 +6092,7 @@ components: state: type: string description: Current state of the database. - example: creating + example: unknown enum: - creating - modifying @@ -6700,6 +6405,7 @@ components: description: The IDs of the hosts that should run this node. When multiple hosts are specified, one host will chosen as a primary, and the others will be read replicas. example: - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 minItems: 1 memory: type: string @@ -6900,6 +6606,8 @@ components: description: The IDs of the hosts that should run this node. When multiple hosts are specified, one host will chosen as a primary, and the others will be read replicas. example: - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 minItems: 1 memory: type: string @@ -7303,7 +7011,6 @@ components: description: The IDs of the hosts that should run this node. When multiple hosts are specified, one host will chosen as a primary, and the others will be read replicas. example: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 minItems: 1 memory: type: string @@ -7417,8 +7124,6 @@ components: cpus: 500m host_ids: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 500M name: n1 orchestrator_opts: @@ -7620,6 +7325,7 @@ components: host_ids: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 500M name: n1 orchestrator_opts: @@ -7707,6 +7413,8 @@ components: description: The IDs of the hosts that should run this node. When multiple hosts are specified, one host will chosen as a primary, and the others will be read replicas. example: - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 minItems: 1 memory: type: string @@ -7913,7 +7621,7 @@ components: - LOGIN - CREATEDB - CREATEROLE - db_owner: true + db_owner: false password: secret roles: - pgedge_superuser @@ -7922,7 +7630,7 @@ components: - LOGIN - CREATEDB - CREATEROLE - db_owner: true + db_owner: false password: secret roles: - pgedge_superuser @@ -7931,7 +7639,7 @@ components: - LOGIN - CREATEDB - CREATEROLE - db_owner: true + db_owner: false password: secret roles: - pgedge_superuser @@ -8087,7 +7795,39 @@ components: host_ids: - de3b1388-1f0c-42f1-a86c-59ab72f255ec - de3b1388-1f0c-42f1-a86c-59ab72f255ec + - de3b1388-1f0c-42f1-a86c-59ab72f255ec memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: analytics-service service_type: mcp @@ -8100,7 +7840,39 @@ components: host_ids: - de3b1388-1f0c-42f1-a86c-59ab72f255ec - de3b1388-1f0c-42f1-a86c-59ab72f255ec + - de3b1388-1f0c-42f1-a86c-59ab72f255ec memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: analytics-service service_type: mcp @@ -8113,57 +7885,134 @@ components: host_ids: - de3b1388-1f0c-42f1-a86c-59ab72f255ec - de3b1388-1f0c-42f1-a86c-59ab72f255ec + - de3b1388-1f0c-42f1-a86c-59ab72f255ec memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: analytics-service service_type: mcp version: latest - spock_version: - type: string - description: The major version of the Spock extension. - example: "5" - pattern: ^\d{1}$ - example: - backup_config: - repositories: - - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - storage-upload-chunk-size: 5MiB - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: f6b84a99-5e91-4203-be1e-131fe82e5984 - retention_full: 2 - retention_full_type: count - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 - schedules: - - cron_expression: 0 6 * * ? - id: daily-full-backup - type: full - - cron_expression: 0 6 * * ? - id: daily-full-backup - type: full - - cron_expression: 0 6 * * ? - id: daily-full-backup - type: full - cpus: 500m - database_name: northwind - database_users: - - attributes: - - LOGIN - - CREATEDB + - config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - de3b1388-1f0c-42f1-a86c-59ab72f255ec + - de3b1388-1f0c-42f1-a86c-59ab72f255ec + - de3b1388-1f0c-42f1-a86c-59ab72f255ec + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: analytics-service + service_type: mcp + version: latest + spock_version: + type: string + description: The major version of the Spock extension. + example: "5" + pattern: ^\d{1}$ + example: + backup_config: + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + storage-upload-chunk-size: 5MiB + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: f6b84a99-5e91-4203-be1e-131fe82e5984 + retention_full: 2 + retention_full_type: count + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 + schedules: + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + cpus: 500m + database_name: northwind + database_users: + - attributes: + - LOGIN + - CREATEDB - CREATEROLE - db_owner: true + db_owner: false password: secret roles: - pgedge_superuser @@ -8172,7 +8021,7 @@ components: - LOGIN - CREATEDB - CREATEROLE - db_owner: true + db_owner: false password: secret roles: - pgedge_superuser @@ -8181,7 +8030,7 @@ components: - LOGIN - CREATEDB - CREATEROLE - db_owner: true + db_owner: false password: secret roles: - pgedge_superuser @@ -8558,20 +8407,39 @@ components: host_ids: - de3b1388-1f0c-42f1-a86c-59ab72f255ec - de3b1388-1f0c-42f1-a86c-59ab72f255ec - memory: 512M - port: 0 - service_id: analytics-service - service_type: mcp - version: latest - - config: - llm_model: gpt-4 - llm_provider: openai - openai_api_key: sk-... - cpus: 500m - host_ids: - - de3b1388-1f0c-42f1-a86c-59ab72f255ec - de3b1388-1f0c-42f1-a86c-59ab72f255ec memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: analytics-service service_type: mcp @@ -8584,20 +8452,39 @@ components: host_ids: - de3b1388-1f0c-42f1-a86c-59ab72f255ec - de3b1388-1f0c-42f1-a86c-59ab72f255ec - memory: 512M - port: 0 - service_id: analytics-service - service_type: mcp - version: latest - - config: - llm_model: gpt-4 - llm_provider: openai - openai_api_key: sk-... - cpus: 500m - host_ids: - - de3b1388-1f0c-42f1-a86c-59ab72f255ec - de3b1388-1f0c-42f1-a86c-59ab72f255ec memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: analytics-service service_type: mcp @@ -9118,7 +9005,7 @@ components: services: type: array items: - $ref: '#/components/schemas/ServiceSpec' + $ref: '#/components/schemas/ServiceSpec2' description: Service instances to run alongside the database (e.g., MCP servers). example: - config: @@ -9130,6 +9017,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -9143,32 +9061,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M - port: 0 - service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - service_type: mcp - version: latest - - config: - llm_model: gpt-4 - llm_provider: openai - openai_api_key: sk-... - cpus: 500m - host_ids: - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - memory: 512M - port: 0 - service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - service_type: mcp - version: latest - - config: - llm_model: gpt-4 - llm_provider: openai - openai_api_key: sk-... - cpus: 500m - host_ids: - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -9636,6 +9559,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -9649,6 +9603,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -10166,7 +10151,7 @@ components: services: type: array items: - $ref: '#/components/schemas/ServiceSpec' + $ref: '#/components/schemas/ServiceSpec3' description: Service instances to run alongside the database (e.g., MCP servers). example: - config: @@ -10178,6 +10163,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -10191,6 +10207,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -10796,6 +10843,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -10809,19 +10887,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M - port: 0 - service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - service_type: mcp - version: latest - - config: - llm_model: gpt-4 - llm_provider: openai - openai_api_key: sk-... - cpus: 500m - host_ids: - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -11171,313 +11267,463 @@ components: source_database_name: northwind source_node_name: n1 source_node: n1 - minItems: 1 - maxItems: 9 - orchestrator_opts: - $ref: '#/components/schemas/OrchestratorOpts' - port: - type: integer - description: The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature. - example: 5432 - format: int64 - minimum: 0 - maximum: 65535 - postgres_version: - type: string - description: The Postgres version in 'major.minor' format. - example: "17.6" - pattern: ^\d{2}\.\d{1,2}$ - postgresql_conf: - type: object - description: Additional postgresql.conf settings. Will be merged with the settings provided by control-plane. - example: - max_connections: 1000 - maxLength: 64 - additionalProperties: true - restore_config: - $ref: '#/components/schemas/RestoreConfigSpec' - services: - type: array - items: - $ref: '#/components/schemas/ServiceSpec' - description: Service instances to run alongside the database (e.g., MCP servers). - example: - - config: - llm_model: gpt-4 - llm_provider: openai - openai_api_key: sk-... - cpus: 500m - host_ids: - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - memory: 512M - port: 0 - service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - service_type: mcp - version: latest - - config: - llm_model: gpt-4 - llm_provider: openai - openai_api_key: sk-... + - backup_config: + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + storage-upload-chunk-size: 5MiB + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + retention_full: 2 + retention_full_type: count + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + storage-upload-chunk-size: 5MiB + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + retention_full: 2 + retention_full_type: count + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + storage-upload-chunk-size: 5MiB + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + retention_full: 2 + retention_full_type: count + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 + schedules: + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full cpus: 500m host_ids: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 - memory: 512M - port: 0 - service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - service_type: mcp - version: latest - spock_version: - type: string - description: The major version of the Spock extension. - example: "5" - pattern: ^\d{1}$ - example: - backup_config: - repositories: - - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - storage-upload-chunk-size: 5MiB - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - retention_full: 2 - retention_full_type: count - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 - - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - storage-upload-chunk-size: 5MiB - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - retention_full: 2 - retention_full_type: count - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 - - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - storage-upload-chunk-size: 5MiB - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - retention_full: 2 - retention_full_type: count - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 - schedules: - - cron_expression: 0 6 * * ? - id: daily-full-backup - type: full - - cron_expression: 0 6 * * ? - id: daily-full-backup - type: full - - cron_expression: 0 6 * * ? - id: daily-full-backup - type: full - cpus: 500m - database_name: northwind - database_users: - - attributes: - - LOGIN - - CREATEDB - - CREATEROLE - db_owner: false - password: secret - roles: - - pgedge_superuser - username: admin - - attributes: - - LOGIN - - CREATEDB - - CREATEROLE - db_owner: false - password: secret - roles: - - pgedge_superuser - username: admin - - attributes: - - LOGIN - - CREATEDB - - CREATEROLE - db_owner: false - password: secret - roles: - - pgedge_superuser - username: admin - memory: 500M - nodes: - - backup_config: - repositories: - - azure_account: pgedge-backups + memory: 500M + name: n1 + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 5432 + postgres_version: "17.6" + postgresql_conf: + max_connections: 1000 + restore_config: + repository: + azure_account: pgedge-backups azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 azure_endpoint: blob.core.usgovcloudapi.net azure_key: YXpLZXk= base_path: /backups custom_options: s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - storage-upload-chunk-size: 5MiB gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 gcs_endpoint: localhost gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - retention_full: 2 - retention_full_type: count s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 s3_endpoint: s3.us-east-1.amazonaws.com s3_key: AKIAIOSFODNN7EXAMPLE s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY s3_region: us-east-1 type: s3 - - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - storage-upload-chunk-size: 5MiB - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - retention_full: 2 - retention_full_type: count - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 - - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - storage-upload-chunk-size: 5MiB - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - retention_full: 2 - retention_full_type: count - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 - schedules: - - cron_expression: 0 6 * * ? - id: daily-full-backup - type: full - - cron_expression: 0 6 * * ? - id: daily-full-backup - type: full - - cron_expression: 0 6 * * ? - id: daily-full-backup - type: full - cpus: 500m - host_ids: - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - memory: 500M - name: n1 - orchestrator_opts: - swarm: - extra_labels: - traefik.enable: "true" - traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) - extra_networks: - - aliases: - - pg-db - - db-alias - driver_opts: - com.docker.network.endpoint.expose: "true" - id: traefik-public - - aliases: - - pg-db - - db-alias - driver_opts: - com.docker.network.endpoint.expose: "true" - id: traefik-public - - aliases: - - pg-db - - db-alias - driver_opts: - com.docker.network.endpoint.expose: "true" - id: traefik-public - extra_volumes: - - destination_path: /backups/container - host_path: /Users/user/backups/host - - destination_path: /backups/container - host_path: /Users/user/backups/host - - destination_path: /backups/container - host_path: /Users/user/backups/host - port: 5432 - postgres_version: "17.6" - postgresql_conf: - max_connections: 1000 - restore_config: - repository: - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 - restore_options: - set: 20250505-153628F - target: "123456" - type: xid - source_database_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - source_database_name: northwind - source_node_name: n1 - source_node: n1 + restore_options: + set: 20250505-153628F + target: "123456" + type: xid + source_database_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + source_database_name: northwind + source_node_name: n1 + source_node: n1 + minItems: 1 + maxItems: 9 + orchestrator_opts: + $ref: '#/components/schemas/OrchestratorOpts' + port: + type: integer + description: The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature. + example: 5432 + format: int64 + minimum: 0 + maximum: 65535 + postgres_version: + type: string + description: The Postgres version in 'major.minor' format. + example: "17.6" + pattern: ^\d{2}\.\d{1,2}$ + postgresql_conf: + type: object + description: Additional postgresql.conf settings. Will be merged with the settings provided by control-plane. + example: + max_connections: 1000 + maxLength: 64 + additionalProperties: true + restore_config: + $ref: '#/components/schemas/RestoreConfigSpec' + services: + type: array + items: + $ref: '#/components/schemas/ServiceSpec4' + description: Service instances to run alongside the database (e.g., MCP servers). + example: + - config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + service_type: mcp + version: latest + - config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + service_type: mcp + version: latest + - config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + service_type: mcp + version: latest + - config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + service_type: mcp + version: latest + spock_version: + type: string + description: The major version of the Spock extension. + example: "5" + pattern: ^\d{1}$ + example: + backup_config: + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + storage-upload-chunk-size: 5MiB + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + retention_full: 2 + retention_full_type: count + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + storage-upload-chunk-size: 5MiB + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + retention_full: 2 + retention_full_type: count + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + storage-upload-chunk-size: 5MiB + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + retention_full: 2 + retention_full_type: count + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 + schedules: + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + cpus: 500m + database_name: northwind + database_users: + - attributes: + - LOGIN + - CREATEDB + - CREATEROLE + db_owner: false + password: secret + roles: + - pgedge_superuser + username: admin + - attributes: + - LOGIN + - CREATEDB + - CREATEROLE + db_owner: false + password: secret + roles: + - pgedge_superuser + username: admin + - attributes: + - LOGIN + - CREATEDB + - CREATEROLE + db_owner: false + password: secret + roles: + - pgedge_superuser + username: admin + memory: 500M + nodes: - backup_config: repositories: - azure_account: pgedge-backups @@ -11689,6 +11935,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -11702,6 +11979,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -11715,6 +12023,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -12092,7 +12431,7 @@ components: services: type: array items: - $ref: '#/components/schemas/ServiceSpec' + $ref: '#/components/schemas/ServiceSpec5' description: Service instances to run alongside the database (e.g., MCP servers). example: - config: @@ -12103,6 +12442,123 @@ components: host_ids: - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + service_type: mcp + version: latest + - config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + service_type: mcp + version: latest + - config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -12115,6 +12571,37 @@ components: host_ids: - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -12579,6 +13066,37 @@ components: host_ids: - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -12591,6 +13109,37 @@ components: host_ids: - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -12940,146 +13489,6 @@ components: source_database_name: northwind source_node_name: n1 source_node: n1 - - backup_config: - repositories: - - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - storage-upload-chunk-size: 5MiB - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - retention_full: 2 - retention_full_type: count - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 - - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - storage-upload-chunk-size: 5MiB - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - retention_full: 2 - retention_full_type: count - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 - - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - storage-upload-chunk-size: 5MiB - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - retention_full: 2 - retention_full_type: count - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 - schedules: - - cron_expression: 0 6 * * ? - id: daily-full-backup - type: full - - cron_expression: 0 6 * * ? - id: daily-full-backup - type: full - - cron_expression: 0 6 * * ? - id: daily-full-backup - type: full - cpus: 500m - host_ids: - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - memory: 500M - name: n1 - orchestrator_opts: - swarm: - extra_labels: - traefik.enable: "true" - traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) - extra_networks: - - aliases: - - pg-db - - db-alias - driver_opts: - com.docker.network.endpoint.expose: "true" - id: traefik-public - - aliases: - - pg-db - - db-alias - driver_opts: - com.docker.network.endpoint.expose: "true" - id: traefik-public - - aliases: - - pg-db - - db-alias - driver_opts: - com.docker.network.endpoint.expose: "true" - id: traefik-public - extra_volumes: - - destination_path: /backups/container - host_path: /Users/user/backups/host - - destination_path: /backups/container - host_path: /Users/user/backups/host - - destination_path: /backups/container - host_path: /Users/user/backups/host - port: 5432 - postgres_version: "17.6" - postgresql_conf: - max_connections: 1000 - restore_config: - repository: - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 - restore_options: - set: 20250505-153628F - target: "123456" - type: xid - source_database_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - source_database_name: northwind - source_node_name: n1 - source_node: n1 minItems: 1 maxItems: 9 orchestrator_opts: @@ -13103,27 +13512,14 @@ components: max_connections: 1000 maxLength: 64 additionalProperties: true - restore_config: - $ref: '#/components/schemas/RestoreConfigSpec' - services: - type: array - items: - $ref: '#/components/schemas/ServiceSpec' - description: Service instances to run alongside the database (e.g., MCP servers). - example: - - config: - llm_model: gpt-4 - llm_provider: openai - openai_api_key: sk-... - cpus: 500m - host_ids: - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - memory: 512M - port: 0 - service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - service_type: mcp - version: latest + restore_config: + $ref: '#/components/schemas/RestoreConfigSpec' + services: + type: array + items: + $ref: '#/components/schemas/ServiceSpec6' + description: Service instances to run alongside the database (e.g., MCP servers). + example: - config: llm_model: gpt-4 llm_provider: openai @@ -13133,6 +13529,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -13146,6 +13573,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -13400,6 +13858,146 @@ components: source_database_name: northwind source_node_name: n1 source_node: n1 + - backup_config: + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + storage-upload-chunk-size: 5MiB + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + retention_full: 2 + retention_full_type: count + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + storage-upload-chunk-size: 5MiB + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + retention_full: 2 + retention_full_type: count + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + storage-upload-chunk-size: 5MiB + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + retention_full: 2 + retention_full_type: count + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 + schedules: + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + cpus: 500m + host_ids: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + memory: 500M + name: n1 + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 5432 + postgres_version: "17.6" + postgresql_conf: + max_connections: 1000 + restore_config: + repository: + azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 + restore_options: + set: 20250505-153628F + target: "123456" + type: xid + source_database_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + source_database_name: northwind + source_node_name: n1 + source_node: n1 orchestrator_opts: swarm: extra_labels: @@ -13471,6 +14069,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -13484,32 +14113,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M - port: 0 - service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - service_type: mcp - version: latest - - config: - llm_model: gpt-4 - llm_provider: openai - openai_api_key: sk-... - cpus: 500m - host_ids: - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - memory: 512M - port: 0 - service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - service_type: mcp - version: latest - - config: - llm_model: gpt-4 - llm_provider: openai - openai_api_key: sk-... - cpus: 500m - host_ids: - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -13747,7 +14381,7 @@ components: services: type: array items: - $ref: '#/components/schemas/ServiceSpec' + $ref: '#/components/schemas/ServiceSpec7' description: Service instances to run alongside the database (e.g., MCP servers). example: - config: @@ -13759,6 +14393,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -13772,6 +14437,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -13785,6 +14481,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -13798,6 +14525,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -14403,6 +15161,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -14416,6 +15205,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -14429,19 +15249,37 @@ components: - 76f9b8c0-4958-11f0-a489-3bb29577c696 - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M - port: 0 - service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 - service_type: mcp - version: latest - - config: - llm_model: gpt-4 - llm_provider: openai - openai_api_key: sk-... - cpus: 500m - host_ids: - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - - 76f9b8c0-4958-11f0-a489-3bb29577c696 - memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp @@ -14474,41 +15312,7 @@ components: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" - error: 'failed to get patroni status: connection refused' - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec - id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d - node_name: n1 - postgres: - patroni_paused: true - patroni_state: unknown - pending_restart: true - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - - name: sub_n1n2 - provider_node: n2 - status: down - version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" - - connection_info: - hostname: i-0123456789abcdef.ec2.internal - ipv4_address: 10.24.34.2 - port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -14531,18 +15335,15 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" - connection_info: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -14565,18 +15366,15 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" - connection_info: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -14599,17 +15397,14 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" state: type: string description: Current state of the database. - example: failed + example: backing_up enum: - creating - modifying @@ -14639,7 +15434,7 @@ components: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -14662,18 +15457,15 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" - connection_info: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -14696,18 +15488,15 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" - connection_info: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -14730,14 +15519,11 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" - state: creating + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" + state: deleting tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 updated_at: "2025-01-01T02:30:00Z" required: @@ -14938,10 +15724,10 @@ components: type: boolean description: If true, skip the health validations that prevent running failover on a healthy cluster. default: false - example: false + example: true example: candidate_instance_id: 68f50878-44d2-4524-a823-e31bd478706d-n1-689qacsi - skip_validation: true + skip_validation: false FailoverDatabaseNodeResponse: type: object properties: @@ -15044,6 +15830,8 @@ components: spock_version: "5" - postgres_version: "17.6" spock_version: "5" + - postgres_version: "17.6" + spock_version: "5" example: cohort: control_available: true @@ -15081,6 +15869,10 @@ components: spock_version: "5" - postgres_version: "17.6" spock_version: "5" + - postgres_version: "17.6" + spock_version: "5" + - postgres_version: "17.6" + spock_version: "5" required: - id - orchestrator @@ -15118,19 +15910,7 @@ components: type: object description: The status of each component of the host. example: - Eius at.: - details: - alarms: - - '3: NOSPACE' - error: failed to connect to etcd - healthy: false - Placeat illo dolore totam accusamus alias ipsa.: - details: - alarms: - - '3: NOSPACE' - error: failed to connect to etcd - healthy: false - Ut dolorem.: + Praesentium ut dolorem sapiente.: details: alarms: - '3: NOSPACE' @@ -15153,19 +15933,7 @@ components: format: date-time example: components: - Et aut aut.: - details: - alarms: - - '3: NOSPACE' - error: failed to connect to etcd - healthy: false - Minus dolore eos et sunt culpa animi.: - details: - alarms: - - '3: NOSPACE' - error: failed to connect to etcd - healthy: false - Rem culpa.: + Dolore totam accusamus.: details: alarms: - '3: NOSPACE' @@ -15197,7 +15965,7 @@ components: created_at: type: string description: The time that the instance was created. - example: "1972-03-21T12:41:47Z" + example: "1987-01-18T23:06:23Z" format: date-time error: type: string @@ -15221,7 +15989,7 @@ components: $ref: '#/components/schemas/InstanceSpockStatus' state: type: string - example: stopped + example: creating enum: - creating - modifying @@ -15234,12 +16002,12 @@ components: status_updated_at: type: string description: The time that the instance status information was last updated. - example: "1995-02-03T18:46:08Z" + example: "2015-08-25T11:23:33Z" format: date-time updated_at: type: string description: The time that the instance was last modified. - example: "1984-04-26T06:38:50Z" + example: "1986-06-02T18:22:13Z" format: date-time description: An instance of pgEdge Postgres running on a host. example: @@ -15247,7 +16015,7 @@ components: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "2003-06-04T21:30:35Z" + created_at: "1983-08-30T09:21:42Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -15270,13 +16038,10 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: degraded - status_updated_at: "1982-02-16T16:16:42Z" - updated_at: "1993-11-23T04:43:18Z" + state: available + status_updated_at: "1983-06-11T05:45:56Z" + updated_at: "1971-05-19T18:59:31Z" required: - id - host_id @@ -15312,7 +16077,7 @@ components: patroni_paused: type: boolean description: True if Patroni is paused for this instance. - example: false + example: true patroni_state: type: string example: unknown @@ -15329,7 +16094,7 @@ components: example: "18.1" description: Postgres status information for a pgEdge instance. example: - patroni_paused: false + patroni_paused: true patroni_state: unknown pending_restart: true role: primary @@ -15367,6 +16132,12 @@ components: - name: sub_n1n2 provider_node: n2 status: down + - name: sub_n1n2 + provider_node: n2 + status: down + - name: sub_n1n2 + provider_node: n2 + status: down version: 4.10.0 InstanceSubscription: type: object @@ -15479,7 +16250,7 @@ components: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -15502,18 +16273,15 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" - connection_info: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -15536,18 +16304,15 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" - connection_info: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -15570,14 +16335,42 @@ components: - name: sub_n1n2 provider_node: n2 status: down + version: 4.10.0 + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" + - connection_info: + hostname: i-0123456789abcdef.ec2.internal + ipv4_address: 10.24.34.2 + port: 5432 + created_at: "1996-08-08T19:06:06Z" + error: 'failed to get patroni status: connection refused' + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + node_name: n1 + postgres: + patroni_paused: true + patroni_state: unknown + pending_restart: true + role: primary + version: "18.1" + spock: + read_only: "off" + subscriptions: + - name: sub_n1n2 + provider_node: n2 + status: down + - name: sub_n1n2 + provider_node: n2 + status: down - name: sub_n1n2 provider_node: n2 status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" - state: modifying + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" + state: available tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 updated_at: "2025-01-01T02:30:00Z" - created_at: "2025-01-01T01:30:00Z" @@ -15587,7 +16380,7 @@ components: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -15610,18 +16403,15 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" - connection_info: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -15644,18 +16434,15 @@ components: - name: sub_n1n2 provider_node: n2 status: down - - name: sub_n1n2 - provider_node: n2 - status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" - connection_info: hostname: i-0123456789abcdef.ec2.internal ipv4_address: 10.24.34.2 port: 5432 - created_at: "1970-10-16T01:30:13Z" + created_at: "1996-08-08T19:06:06Z" error: 'failed to get patroni status: connection refused' host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d @@ -15678,14 +16465,42 @@ components: - name: sub_n1n2 provider_node: n2 status: down + version: 4.10.0 + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" + - connection_info: + hostname: i-0123456789abcdef.ec2.internal + ipv4_address: 10.24.34.2 + port: 5432 + created_at: "1996-08-08T19:06:06Z" + error: 'failed to get patroni status: connection refused' + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + node_name: n1 + postgres: + patroni_paused: true + patroni_state: unknown + pending_restart: true + role: primary + version: "18.1" + spock: + read_only: "off" + subscriptions: + - name: sub_n1n2 + provider_node: n2 + status: down + - name: sub_n1n2 + provider_node: n2 + status: down - name: sub_n1n2 provider_node: n2 status: down version: 4.10.0 - state: unknown - status_updated_at: "2013-04-06T16:38:09Z" - updated_at: "1971-07-18T16:52:12Z" - state: modifying + state: creating + status_updated_at: "1971-06-17T15:27:08Z" + updated_at: "2009-02-16T03:06:12Z" + state: available tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 updated_at: "2025-01-01T02:30:00Z" example: @@ -15974,6 +16789,82 @@ components: spock_version: "5" - postgres_version: "17.6" spock_version: "5" + - cohort: + control_available: true + member_id: lah4bsznw6kc0hp7biylmmmll + type: swarm + cpus: 4 + data_dir: /data + default_pgedge_version: + postgres_version: "17.6" + spock_version: "5" + etcd_mode: server + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.2 + memory: 16GiB + orchestrator: swarm + status: + components: + Enim et voluptatum ex ea dolore.: + details: + alarms: + - '3: NOSPACE' + error: failed to connect to etcd + healthy: false + Tenetur nostrum repellendus sint qui.: + details: + alarms: + - '3: NOSPACE' + error: failed to connect to etcd + healthy: false + state: available + updated_at: "2021-07-01T12:34:56Z" + supported_pgedge_versions: + - postgres_version: "17.6" + spock_version: "5" + - postgres_version: "17.6" + spock_version: "5" + - postgres_version: "17.6" + spock_version: "5" + - cohort: + control_available: true + member_id: lah4bsznw6kc0hp7biylmmmll + type: swarm + cpus: 4 + data_dir: /data + default_pgedge_version: + postgres_version: "17.6" + spock_version: "5" + etcd_mode: server + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.2 + memory: 16GiB + orchestrator: swarm + status: + components: + Enim et voluptatum ex ea dolore.: + details: + alarms: + - '3: NOSPACE' + error: failed to connect to etcd + healthy: false + Tenetur nostrum repellendus sint qui.: + details: + alarms: + - '3: NOSPACE' + error: failed to connect to etcd + healthy: false + state: available + updated_at: "2021-07-01T12:34:56Z" + supported_pgedge_versions: + - postgres_version: "17.6" + spock_version: "5" + - postgres_version: "17.6" + spock_version: "5" + - postgres_version: "17.6" + spock_version: "5" description: Response containing the list of hosts example: hosts: @@ -16053,16 +16944,357 @@ components: spock_version: "5" - postgres_version: "17.6" spock_version: "5" + - cohort: + control_available: true + member_id: lah4bsznw6kc0hp7biylmmmll + type: swarm + cpus: 4 + data_dir: /data + default_pgedge_version: + postgres_version: "17.6" + spock_version: "5" + etcd_mode: server + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.2 + memory: 16GiB + orchestrator: swarm + status: + components: + Enim et voluptatum ex ea dolore.: + details: + alarms: + - '3: NOSPACE' + error: failed to connect to etcd + healthy: false + Tenetur nostrum repellendus sint qui.: + details: + alarms: + - '3: NOSPACE' + error: failed to connect to etcd + healthy: false + state: available + updated_at: "2021-07-01T12:34:56Z" + supported_pgedge_versions: + - postgres_version: "17.6" + spock_version: "5" + - postgres_version: "17.6" + spock_version: "5" + - postgres_version: "17.6" + spock_version: "5" + required: + - hosts + ListTasksResponse: + type: object + properties: + tasks: + type: array + items: + $ref: '#/components/schemas/Task' + description: The tasks for the given entity. + example: + - completed_at: "2025-06-18T16:52:35Z" + created_at: "2025-06-18T16:52:05Z" + database_id: storefront + entity_id: storefront + scope: database + status: completed + task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 + type: create + - completed_at: "2025-06-18T16:52:35Z" + created_at: "2025-06-18T16:52:05Z" + database_id: storefront + entity_id: storefront + scope: database + status: completed + task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 + type: create + example: + tasks: + - completed_at: "2025-06-18T17:54:36Z" + created_at: "2025-06-18T17:54:28Z" + database_id: storefront + entity_id: storefront + instance_id: storefront-n1-689qacsi + scope: database + status: completed + task_id: 0197842d-9082-7496-b787-77bd2e11809f + type: node_backup + - completed_at: "2025-06-18T17:54:36Z" + created_at: "2025-06-18T17:54:28Z" + entity_id: host-1 + host_id: host-1 + scope: host + status: completed + task_id: 0197842d-9082-7496-b787-77bd2e11809f + type: remove_host + required: + - tasks + OrchestratorOpts: + type: object + properties: + swarm: + $ref: '#/components/schemas/SwarmOpts' + description: Options specific to the selected orchestrator. + example: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + PgEdgeVersion: + type: object + properties: + postgres_version: + type: string + description: The Postgres major and minor version. + example: "17.6" + spock_version: + type: string + description: The Spock major version. + example: "5" + example: + postgres_version: "17.6" + spock_version: "5" + required: + - postgres_version + - spock_version + PortMapping: + type: object + properties: + container_port: + type: integer + description: The port number inside the container. + example: 8080 + format: int64 + minimum: 1 + maximum: 65535 + host_port: + type: integer + description: The port number on the host (if port-forwarded). + example: 8080 + format: int64 + minimum: 1 + maximum: 65535 + name: + type: string + description: The name of the port (e.g., 'http', 'web-client'). + example: web-client + description: Port mapping information for a service instance. + example: + container_port: 8080 + host_port: 8080 + name: web-client + required: + - name + RemoveHostResponse: + type: object + properties: + task: + $ref: '#/components/schemas/Task' + update_database_tasks: + type: array + items: + $ref: '#/components/schemas/Task' + description: The tasks that will update databases affected by the host removal. + example: + - completed_at: "2025-06-18T16:52:35Z" + created_at: "2025-06-18T16:52:05Z" + database_id: storefront + entity_id: storefront + scope: database + status: completed + task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 + type: create + - completed_at: "2025-06-18T16:52:35Z" + created_at: "2025-06-18T16:52:05Z" + database_id: storefront + entity_id: storefront + scope: database + status: completed + task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 + type: create + - completed_at: "2025-06-18T16:52:35Z" + created_at: "2025-06-18T16:52:05Z" + database_id: storefront + entity_id: storefront + scope: database + status: completed + task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 + type: create + example: + task: + completed_at: "2025-06-18T16:52:35Z" + created_at: "2025-06-18T16:52:05Z" + database_id: storefront + entity_id: storefront + scope: database + status: completed + task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 + type: create + update_database_tasks: + - completed_at: "2025-06-18T16:52:35Z" + created_at: "2025-06-18T16:52:05Z" + database_id: storefront + entity_id: storefront + scope: database + status: completed + task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 + type: create + - completed_at: "2025-06-18T16:52:35Z" + created_at: "2025-06-18T16:52:05Z" + database_id: storefront + entity_id: storefront + scope: database + status: completed + task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 + type: create + required: + - task + - update_database_tasks + RestartInstanceResponse: + type: object + properties: + task: + $ref: '#/components/schemas/Task' + description: Response containing the restart task + example: + task: + completed_at: "2025-06-18T16:52:35Z" + created_at: "2025-06-18T16:52:05Z" + database_id: storefront + entity_id: storefront + scope: database + status: completed + task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 + type: create + required: + - task + RestoreConfigSpec: + type: object + properties: + repository: + $ref: '#/components/schemas/RestoreRepositorySpec' + restore_options: + type: object + description: Additional options to use when restoring this database. If omitted, the database will be restored to the latest point in the given repository. + example: + set: 20250505-153628F + target: "123456" + type: xid + maxLength: 32 + additionalProperties: + type: string + example: Accusantium ut aperiam qui sed quis architecto. + source_database_id: + type: string + description: A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens. + example: 76f9b8c0-4958-11f0-a489-3bb29577c696 + minLength: 1 + maxLength: 63 + source_database_name: + type: string + description: The name of the database in this repository. The database will be renamed to the database_name in the DatabaseSpec after it's restored. + example: northwind + minLength: 1 + maxLength: 31 + source_node_name: + type: string + description: The name of the node to restore this database from. + example: n1 + pattern: n[0-9]+ + example: + repository: + azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: f6b84a99-5e91-4203-be1e-131fe82e5984 + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 + restore_options: + set: 20250505-153628F + target: "123456" + type: xid + source_database_id: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + source_database_name: northwind + source_node_name: n1 required: - - hosts - ListTasksResponse: + - source_database_id + - source_node_name + - source_database_name + - repository + RestoreDatabaseRequest: type: object properties: - tasks: + restore_config: + $ref: '#/components/schemas/RestoreConfigSpec' + target_nodes: + type: array + items: + type: string + example: Et et reprehenderit et nam quo. + description: The nodes to restore. Defaults to all nodes if empty or unspecified. + example: + - n1 + maxItems: 9 + example: + restore_config: + repository: + base_path: /backups + type: posix + source_database_id: storefront + source_database_name: storefront + source_node_name: n1 + target_nodes: + - n1 + required: + - restore_config + RestoreDatabaseResponse: + type: object + properties: + database: + $ref: '#/components/schemas/Database' + node_tasks: type: array items: $ref: '#/components/schemas/Task' - description: The tasks for the given entity. + description: The tasks that will restore each database node. example: - completed_at: "2025-06-18T16:52:35Z" created_at: "2025-06-18T16:52:05Z" @@ -16080,127 +17312,153 @@ components: status: completed task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 type: create - - completed_at: "2025-06-18T16:52:35Z" - created_at: "2025-06-18T16:52:05Z" - database_id: storefront - entity_id: storefront - scope: database - status: completed - task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 - type: create - example: - tasks: - - completed_at: "2025-06-18T17:54:36Z" - created_at: "2025-06-18T17:54:28Z" - database_id: storefront - entity_id: storefront - instance_id: storefront-n1-689qacsi - scope: database - status: completed - task_id: 0197842d-9082-7496-b787-77bd2e11809f - type: node_backup - - completed_at: "2025-06-18T17:54:36Z" - created_at: "2025-06-18T17:54:28Z" - entity_id: host-1 - host_id: host-1 - scope: host - status: completed - task_id: 0197842d-9082-7496-b787-77bd2e11809f - type: remove_host - required: - - tasks - OrchestratorOpts: - type: object - properties: - swarm: - $ref: '#/components/schemas/SwarmOpts' - description: Options specific to the selected orchestrator. - example: - swarm: - extra_labels: - traefik.enable: "true" - traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) - extra_networks: - - aliases: - - pg-db - - db-alias - driver_opts: - com.docker.network.endpoint.expose: "true" - id: traefik-public - - aliases: - - pg-db - - db-alias - driver_opts: - com.docker.network.endpoint.expose: "true" - id: traefik-public - - aliases: - - pg-db - - db-alias - driver_opts: - com.docker.network.endpoint.expose: "true" - id: traefik-public - extra_volumes: - - destination_path: /backups/container - host_path: /Users/user/backups/host - - destination_path: /backups/container - host_path: /Users/user/backups/host - - destination_path: /backups/container - host_path: /Users/user/backups/host - PgEdgeVersion: - type: object - properties: - postgres_version: - type: string - description: The Postgres major and minor version. - example: "17.6" - spock_version: - type: string - description: The Spock major version. - example: "5" - example: - postgres_version: "17.6" - spock_version: "5" - required: - - postgres_version - - spock_version - PortMapping: - type: object - properties: - container_port: - type: integer - description: The port number inside the container. - example: 8080 - format: int64 - minimum: 1 - maximum: 65535 - host_port: - type: integer - description: The port number on the host (if port-forwarded). - example: 8080 - format: int64 - minimum: 1 - maximum: 65535 - name: - type: string - description: The name of the port (e.g., 'http', 'web-client'). - example: web-client - description: Port mapping information for a service instance. + task: + $ref: '#/components/schemas/Task' example: - container_port: 8080 - host_port: 8080 - name: web-client + database: + created_at: "2025-06-18T16:52:05Z" + id: storefront + instances: + - connection_info: + hostname: i-0123456789abcdef.ec2.internal + ipv4_address: 10.24.34.2 + port: 5432 + created_at: "2025-06-18T16:52:22Z" + host_id: us-east-1 + id: storefront-n1-689qacsi + node_name: n1 + postgres: + patroni_state: running + role: primary + version: "18.1" + spock: + read_only: "off" + subscriptions: + - name: sub_n1n3 + provider_node: n3 + status: replicating + - name: sub_n1n2 + provider_node: n2 + status: replicating + version: 4.0.10 + state: available + status_updated_at: "2025-06-18T17:58:56Z" + updated_at: "2025-06-18T17:54:36Z" + - connection_info: + hostname: i-058731542fee493f.ec2.internal + ipv4_address: 10.24.35.2 + port: 5432 + created_at: "2025-06-18T16:52:22Z" + host_id: ap-south-1 + id: storefront-n2-9ptayhma + node_name: n2 + postgres: + patroni_state: running + role: primary + version: "18.1" + spock: + read_only: "off" + subscriptions: + - name: sub_n2n1 + provider_node: n1 + status: replicating + - name: sub_n2n3 + provider_node: n3 + status: replicating + version: 4.0.10 + state: available + status_updated_at: "2025-06-18T17:58:56Z" + updated_at: "2025-06-18T17:54:01Z" + - connection_info: + hostname: i-494027b7b53f6a23.ec2.internal + ipv4_address: 10.24.36.2 + port: 5432 + created_at: "2025-06-18T16:52:22Z" + host_id: eu-central-1 + id: storefront-n3-ant97dj4 + node_name: n3 + postgres: + patroni_state: running + role: primary + version: "18.1" + spock: + read_only: "off" + subscriptions: + - name: sub_n3n1 + provider_node: n1 + status: replicating + - name: sub_n3n2 + provider_node: n2 + status: replicating + version: 4.0.10 + state: available + status_updated_at: "2025-06-18T17:58:56Z" + updated_at: "2025-06-18T17:54:01Z" + spec: + database_name: storefront + database_users: + - attributes: + - SUPERUSER + - LOGIN + db_owner: true + username: admin + nodes: + - host_ids: + - us-east-1 + name: n1 + - host_ids: + - ap-south-1 + name: n2 + - host_ids: + - eu-central-1 + name: n3 + port: 5432 + postgres_version: "17.6" + spock_version: "5" + state: restoring + updated_at: "2025-06-18T17:58:59Z" + node_tasks: + - created_at: "2025-06-18T17:58:59Z" + database_id: storefront + node_name: n1 + parent_id: 01978431-b628-758a-aec6-03b331fa1a17 + status: pending + task_id: 01978431-b62b-723b-a09c-e4072cd64bdb + type: node_restore + - created_at: "2025-06-18T17:58:59Z" + database_id: storefront + node_name: n2 + parent_id: 01978431-b628-758a-aec6-03b331fa1a17 + status: pending + task_id: 01978431-b62c-7593-aad8-43b03df2031b + type: node_restore + - created_at: "2025-06-18T17:58:59Z" + database_id: storefront + node_name: n3 + parent_id: 01978431-b628-758a-aec6-03b331fa1a17 + status: pending + task_id: 01978431-b62d-7b65-ab09-272d0b2fea91 + type: node_restore + task: + created_at: "2025-06-18T17:58:59Z" + database_id: storefront + status: pending + task_id: 01978431-b628-758a-aec6-03b331fa1a17 + type: restore required: - - name - RemoveHostResponse: + - task + - node_tasks + - database + RestoreDatabaseResponse2: type: object properties: - task: - $ref: '#/components/schemas/Task' - update_database_tasks: + database: + $ref: '#/components/schemas/Database5' + node_tasks: type: array items: $ref: '#/components/schemas/Task' - description: The tasks that will update databases affected by the host removal. + description: The tasks that will restore each database node. example: - completed_at: "2025-06-18T16:52:35Z" created_at: "2025-06-18T16:52:05Z" @@ -16226,764 +17484,1078 @@ components: status: completed task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 type: create - example: - task: - completed_at: "2025-06-18T16:52:35Z" - created_at: "2025-06-18T16:52:05Z" - database_id: storefront - entity_id: storefront - scope: database - status: completed - task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 - type: create - update_database_tasks: - - completed_at: "2025-06-18T16:52:35Z" - created_at: "2025-06-18T16:52:05Z" - database_id: storefront - entity_id: storefront - scope: database - status: completed - task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 - type: create - - completed_at: "2025-06-18T16:52:35Z" - created_at: "2025-06-18T16:52:05Z" - database_id: storefront - entity_id: storefront - scope: database - status: completed - task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 - type: create - required: - - task - - update_database_tasks - RestartInstanceResponse: - type: object - properties: task: $ref: '#/components/schemas/Task' - description: Response containing the restart task example: - task: - completed_at: "2025-06-18T16:52:35Z" + database: created_at: "2025-06-18T16:52:05Z" - database_id: storefront - entity_id: storefront - scope: database - status: completed - task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 - type: create + id: storefront + instances: + - connection_info: + hostname: i-0123456789abcdef.ec2.internal + ipv4_address: 10.24.34.2 + port: 5432 + created_at: "2025-06-18T16:52:22Z" + host_id: us-east-1 + id: storefront-n1-689qacsi + node_name: n1 + postgres: + patroni_state: running + role: primary + version: "18.1" + spock: + read_only: "off" + subscriptions: + - name: sub_n1n3 + provider_node: n3 + status: replicating + - name: sub_n1n2 + provider_node: n2 + status: replicating + version: 4.0.10 + state: available + status_updated_at: "2025-06-18T17:58:56Z" + updated_at: "2025-06-18T17:54:36Z" + - connection_info: + hostname: i-058731542fee493f.ec2.internal + ipv4_address: 10.24.35.2 + port: 5432 + created_at: "2025-06-18T16:52:22Z" + host_id: ap-south-1 + id: storefront-n2-9ptayhma + node_name: n2 + postgres: + patroni_state: running + role: primary + version: "18.1" + spock: + read_only: "off" + subscriptions: + - name: sub_n2n1 + provider_node: n1 + status: replicating + - name: sub_n2n3 + provider_node: n3 + status: replicating + version: 4.0.10 + state: available + status_updated_at: "2025-06-18T17:58:56Z" + updated_at: "2025-06-18T17:54:01Z" + - connection_info: + hostname: i-494027b7b53f6a23.ec2.internal + ipv4_address: 10.24.36.2 + port: 5432 + created_at: "2025-06-18T16:52:22Z" + host_id: eu-central-1 + id: storefront-n3-ant97dj4 + node_name: n3 + postgres: + patroni_state: running + role: primary + version: "18.1" + spock: + read_only: "off" + subscriptions: + - name: sub_n3n1 + provider_node: n1 + status: replicating + - name: sub_n3n2 + provider_node: n2 + status: replicating + version: 4.0.10 + state: available + status_updated_at: "2025-06-18T17:58:56Z" + updated_at: "2025-06-18T17:54:01Z" + spec: + database_name: storefront + database_users: + - attributes: + - SUPERUSER + - LOGIN + db_owner: true + username: admin + nodes: + - host_ids: + - us-east-1 + name: n1 + - host_ids: + - ap-south-1 + name: n2 + - host_ids: + - eu-central-1 + name: n3 + port: 5432 + postgres_version: "17.6" + spock_version: "5" + state: restoring + updated_at: "2025-06-18T17:58:59Z" + node_tasks: + - created_at: "2025-06-18T17:58:59Z" + database_id: storefront + node_name: n1 + parent_id: 01978431-b628-758a-aec6-03b331fa1a17 + status: pending + task_id: 01978431-b62b-723b-a09c-e4072cd64bdb + type: node_restore + - created_at: "2025-06-18T17:58:59Z" + database_id: storefront + node_name: n2 + parent_id: 01978431-b628-758a-aec6-03b331fa1a17 + status: pending + task_id: 01978431-b62c-7593-aad8-43b03df2031b + type: node_restore + - created_at: "2025-06-18T17:58:59Z" + database_id: storefront + node_name: n3 + parent_id: 01978431-b628-758a-aec6-03b331fa1a17 + status: pending + task_id: 01978431-b62d-7b65-ab09-272d0b2fea91 + type: node_restore + task: + created_at: "2025-06-18T17:58:59Z" + database_id: storefront + status: pending + task_id: 01978431-b628-758a-aec6-03b331fa1a17 + type: restore required: - task - RestoreConfigSpec: + - node_tasks + - database + RestoreRepositorySpec: type: object properties: - repository: - $ref: '#/components/schemas/RestoreRepositorySpec' - restore_options: + azure_account: + type: string + description: The Azure account name for this repository. Only applies when type = 'azure'. + example: pgedge-backups + minLength: 3 + maxLength: 24 + azure_container: + type: string + description: The Azure container name for this repository. Only applies when type = 'azure'. + example: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + minLength: 3 + maxLength: 63 + azure_endpoint: + type: string + description: The optional Azure endpoint for this repository. Only applies when type = 'azure'. + example: blob.core.usgovcloudapi.net + minLength: 3 + maxLength: 128 + azure_key: + type: string + description: An optional Azure storage account access key to use for this repository. If not provided, pgbackrest will use the VM's managed identity. + example: YXpLZXk= + maxLength: 128 + base_path: + type: string + description: The base path within the repository to store backups. Required for type = 'posix' and 'cifs'. + example: /backups + maxLength: 256 + custom_options: type: object - description: Additional options to use when restoring this database. If omitted, the database will be restored to the latest point in the given repository. + description: Additional options to apply to this repository. example: - set: 20250505-153628F - target: "123456" - type: xid - maxLength: 32 + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab additionalProperties: type: string - example: Qui sed quis architecto. - source_database_id: + example: Labore explicabo culpa eos natus aperiam excepturi. + gcs_bucket: + type: string + description: The GCS bucket name for this repository. Only applies when type = 'gcs'. + example: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + minLength: 3 + maxLength: 63 + gcs_endpoint: + type: string + description: The optional GCS endpoint for this repository. Only applies when type = 'gcs'. + example: localhost + minLength: 3 + maxLength: 128 + gcs_key: + type: string + description: Optional base64-encoded private key data. If omitted, pgbackrest will use the service account attached to the instance profile. + example: ZXhhbXBsZSBnY3Mga2V5Cg== + maxLength: 1024 + id: type: string description: A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens. example: 76f9b8c0-4958-11f0-a489-3bb29577c696 minLength: 1 maxLength: 63 - source_database_name: + s3_bucket: type: string - description: The name of the database in this repository. The database will be renamed to the database_name in the DatabaseSpec after it's restored. - example: northwind + description: The S3 bucket name for this repository. Only applies when type = 's3'. + example: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + minLength: 3 + maxLength: 63 + s3_endpoint: + type: string + description: The optional S3 endpoint for this repository. Only applies when type = 's3'. + example: s3.us-east-1.amazonaws.com + minLength: 3 + maxLength: 128 + s3_key: + type: string + description: An optional AWS access key ID to use for this repository. If not provided, pgbackrest will use the default credential provider chain. + example: AKIAIOSFODNN7EXAMPLE + maxLength: 128 + s3_key_secret: + type: string + description: The corresponding secret for the AWS access key ID in s3_key. + example: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + maxLength: 128 + s3_region: + type: string + description: The region of the S3 bucket for this repository. Only applies when type = 's3'. + example: us-east-1 minLength: 1 - maxLength: 31 - source_node_name: + maxLength: 32 + type: type: string - description: The name of the node to restore this database from. - example: n1 - pattern: n[0-9]+ + description: The type of this repository. + example: s3 + enum: + - s3 + - gcs + - azure + - posix + - cifs example: - repository: - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: f6b84a99-5e91-4203-be1e-131fe82e5984 - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 - restore_options: - set: 20250505-153628F - target: "123456" - type: xid - source_database_id: 02f1a7db-fca8-4521-b57a-2a375c1ced51 - source_database_name: northwind - source_node_name: n1 + azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + azure_key: YXpLZXk= + base_path: /backups + custom_options: + s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== + id: f6b84a99-5e91-4203-be1e-131fe82e5984 + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_key: AKIAIOSFODNN7EXAMPLE + s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + s3_region: us-east-1 + type: s3 required: - - source_database_id - - source_node_name - - source_database_name - - repository - RestoreDatabaseRequest: + - type + ServiceInstance: type: object properties: - restore_config: - $ref: '#/components/schemas/RestoreConfigSpec' - target_nodes: - type: array - items: - type: string - example: Et et reprehenderit et nam quo. - description: The nodes to restore. Defaults to all nodes if empty or unspecified. - example: - - n1 - maxItems: 9 + created_at: + type: string + description: The time that the service instance was created. + example: "2025-01-28T10:00:00Z" + format: date-time + database_id: + type: string + description: A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens. + example: 76f9b8c0-4958-11f0-a489-3bb29577c696 + minLength: 1 + maxLength: 63 + error: + type: string + description: An error message if the service instance is in an error state. + example: 'failed to start container: image not found' + host_id: + type: string + description: The ID of the host this service instance is running on. + example: host-1 + service_id: + type: string + description: The service ID from the DatabaseSpec. + example: mcp-server + service_instance_id: + type: string + description: Unique identifier for the service instance. + example: mcp-server-host-1 + state: + type: string + description: Current state of the service instance. + example: running + enum: + - creating + - running + - failed + - deleting + status: + $ref: '#/components/schemas/ServiceInstanceStatus' + updated_at: + type: string + description: The time that the service instance was last updated. + example: "2025-01-28T10:05:00Z" + format: date-time + description: A service instance running on a host alongside the database. example: - restore_config: - repository: - base_path: /backups - type: posix - source_database_id: storefront - source_database_name: storefront - source_node_name: n1 - target_nodes: - - n1 - required: - - restore_config - RestoreDatabaseResponse: + created_at: "2025-01-28T10:00:00Z" + database_id: production + error: 'failed to start container: image not found' + host_id: host-1 + service_id: mcp-server + service_instance_id: mcp-server-host-1 + state: running + status: + container_id: a1b2c3d4e5f6 + health_check: + checked_at: "2025-01-28T10:00:00Z" + message: Connection refused + status: healthy + hostname: mcp-server-host-1.internal + image_version: 1.0.0 + ipv4_address: 10.0.1.5 + last_health_at: "2025-01-28T10:00:00Z" + ports: + - container_port: 8080 + host_port: 8080 + name: web-client + - container_port: 8080 + host_port: 8080 + name: web-client + - container_port: 8080 + host_port: 8080 + name: web-client + service_ready: true + updated_at: "2025-01-28T10:05:00Z" + required: + - service_instance_id + - service_id + - database_id + - host_id + - state + - created_at + - updated_at + ServiceInstanceStatus: type: object properties: - database: - $ref: '#/components/schemas/Database' - node_tasks: + container_id: + type: string + description: The Docker container ID. + example: a1b2c3d4e5f6 + health_check: + $ref: '#/components/schemas/HealthCheckResult' + hostname: + type: string + description: The hostname of the service instance. + example: mcp-server-host-1.internal + image_version: + type: string + description: The container image version currently running. + example: 1.0.0 + ipv4_address: + type: string + description: The IPv4 address of the service instance. + example: 10.0.1.5 + format: ipv4 + last_health_at: + type: string + description: The time of the last health check attempt. + example: "2025-01-28T10:00:00Z" + format: date-time + ports: type: array items: - $ref: '#/components/schemas/Task' - description: The tasks that will restore each database node. + $ref: '#/components/schemas/PortMapping' + description: Port mappings for this service instance. example: - - completed_at: "2025-06-18T16:52:35Z" - created_at: "2025-06-18T16:52:05Z" - database_id: storefront - entity_id: storefront - scope: database - status: completed - task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 - type: create - - completed_at: "2025-06-18T16:52:35Z" - created_at: "2025-06-18T16:52:05Z" - database_id: storefront - entity_id: storefront - scope: database - status: completed - task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 - type: create - - completed_at: "2025-06-18T16:52:35Z" - created_at: "2025-06-18T16:52:05Z" - database_id: storefront - entity_id: storefront - scope: database - status: completed - task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 - type: create - task: - $ref: '#/components/schemas/Task' + - container_port: 8080 + host_port: 8080 + name: web-client + - container_port: 8080 + host_port: 8080 + name: web-client + - container_port: 8080 + host_port: 8080 + name: web-client + - container_port: 8080 + host_port: 8080 + name: web-client + service_ready: + type: boolean + description: Whether the service is ready to accept requests. + example: true + description: Runtime status information for a service instance. example: - database: - created_at: "2025-06-18T16:52:05Z" - id: storefront - instances: - - connection_info: - hostname: i-0123456789abcdef.ec2.internal - ipv4_address: 10.24.34.2 - port: 5432 - created_at: "2025-06-18T16:52:22Z" - host_id: us-east-1 - id: storefront-n1-689qacsi - node_name: n1 - postgres: - patroni_state: running - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n1n3 - provider_node: n3 - status: replicating - - name: sub_n1n2 - provider_node: n2 - status: replicating - version: 4.0.10 - state: available - status_updated_at: "2025-06-18T17:58:56Z" - updated_at: "2025-06-18T17:54:36Z" - - connection_info: - hostname: i-058731542fee493f.ec2.internal - ipv4_address: 10.24.35.2 - port: 5432 - created_at: "2025-06-18T16:52:22Z" - host_id: ap-south-1 - id: storefront-n2-9ptayhma - node_name: n2 - postgres: - patroni_state: running - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n2n1 - provider_node: n1 - status: replicating - - name: sub_n2n3 - provider_node: n3 - status: replicating - version: 4.0.10 - state: available - status_updated_at: "2025-06-18T17:58:56Z" - updated_at: "2025-06-18T17:54:01Z" - - connection_info: - hostname: i-494027b7b53f6a23.ec2.internal - ipv4_address: 10.24.36.2 - port: 5432 - created_at: "2025-06-18T16:52:22Z" - host_id: eu-central-1 - id: storefront-n3-ant97dj4 - node_name: n3 - postgres: - patroni_state: running - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n3n1 - provider_node: n1 - status: replicating - - name: sub_n3n2 - provider_node: n2 - status: replicating - version: 4.0.10 - state: available - status_updated_at: "2025-06-18T17:58:56Z" - updated_at: "2025-06-18T17:54:01Z" - spec: - database_name: storefront - database_users: - - attributes: - - SUPERUSER - - LOGIN - db_owner: true - username: admin - nodes: - - host_ids: - - us-east-1 - name: n1 - - host_ids: - - ap-south-1 - name: n2 - - host_ids: - - eu-central-1 - name: n3 - port: 5432 - postgres_version: "17.6" - spock_version: "5" - state: restoring - updated_at: "2025-06-18T17:58:59Z" - node_tasks: - - created_at: "2025-06-18T17:58:59Z" - database_id: storefront - node_name: n1 - parent_id: 01978431-b628-758a-aec6-03b331fa1a17 - status: pending - task_id: 01978431-b62b-723b-a09c-e4072cd64bdb - type: node_restore - - created_at: "2025-06-18T17:58:59Z" - database_id: storefront - node_name: n2 - parent_id: 01978431-b628-758a-aec6-03b331fa1a17 - status: pending - task_id: 01978431-b62c-7593-aad8-43b03df2031b - type: node_restore - - created_at: "2025-06-18T17:58:59Z" - database_id: storefront - node_name: n3 - parent_id: 01978431-b628-758a-aec6-03b331fa1a17 - status: pending - task_id: 01978431-b62d-7b65-ab09-272d0b2fea91 - type: node_restore - task: - created_at: "2025-06-18T17:58:59Z" - database_id: storefront - status: pending - task_id: 01978431-b628-758a-aec6-03b331fa1a17 - type: restore - required: - - task - - node_tasks - - database - RestoreDatabaseResponse2: + container_id: a1b2c3d4e5f6 + health_check: + checked_at: "2025-01-28T10:00:00Z" + message: Connection refused + status: healthy + hostname: mcp-server-host-1.internal + image_version: 1.0.0 + ipv4_address: 10.0.1.5 + last_health_at: "2025-01-28T10:00:00Z" + ports: + - container_port: 8080 + host_port: 8080 + name: web-client + - container_port: 8080 + host_port: 8080 + name: web-client + service_ready: true + ServiceSpec: type: object properties: - database: - $ref: '#/components/schemas/Database5' - node_tasks: + config: + type: object + description: Service-specific configuration. For MCP services, this includes llm_provider, llm_model, and provider-specific API keys. + example: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + additionalProperties: true + cpus: + type: string + description: The number of CPUs to allocate for this service. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Defaults to container defaults if unspecified. + example: 500m + pattern: ^[0-9]+(\.[0-9]{1,3}|m)?$ + host_ids: type: array items: - $ref: '#/components/schemas/Task' - description: The tasks that will restore each database node. + type: string + description: A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens. + example: 76f9b8c0-4958-11f0-a489-3bb29577c696 + minLength: 1 + maxLength: 63 + description: The IDs of the hosts that should run this service. One service instance will be created per host. example: - - completed_at: "2025-06-18T16:52:35Z" - created_at: "2025-06-18T16:52:05Z" - database_id: storefront - entity_id: storefront - scope: database - status: completed - task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 - type: create - - completed_at: "2025-06-18T16:52:35Z" - created_at: "2025-06-18T16:52:05Z" - database_id: storefront - entity_id: storefront - scope: database - status: completed - task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 - type: create - - completed_at: "2025-06-18T16:52:35Z" - created_at: "2025-06-18T16:52:05Z" - database_id: storefront - entity_id: storefront - scope: database - status: completed - task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 - type: create - - completed_at: "2025-06-18T16:52:35Z" - created_at: "2025-06-18T16:52:05Z" - database_id: storefront - entity_id: storefront - scope: database - status: completed - task_id: 019783f4-75f4-71e7-85a3-c9b96b345d77 - type: create - task: - $ref: '#/components/schemas/Task' + - de3b1388-1f0c-42f1-a86c-59ab72f255ec + minItems: 1 + memory: + type: string + description: The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified. + example: 512M + maxLength: 16 + orchestrator_opts: + $ref: '#/components/schemas/OrchestratorOpts' + port: + type: integer + description: The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network. + example: 0 + format: int64 + minimum: 0 + maximum: 65535 + service_id: + type: string + description: A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens. + example: 76f9b8c0-4958-11f0-a489-3bb29577c696 + minLength: 1 + maxLength: 63 + service_type: + type: string + description: The type of service to run. + example: mcp + enum: + - mcp + version: + type: string + description: The version of the service in semver format (e.g., '1.0.0') or the literal 'latest'. + example: latest + pattern: ^(\d+\.\d+\.\d+|latest)$ example: - database: - created_at: "2025-06-18T16:52:05Z" - id: storefront - instances: - - connection_info: - hostname: i-0123456789abcdef.ec2.internal - ipv4_address: 10.24.34.2 - port: 5432 - created_at: "2025-06-18T16:52:22Z" - host_id: us-east-1 - id: storefront-n1-689qacsi - node_name: n1 - postgres: - patroni_state: running - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n1n3 - provider_node: n3 - status: replicating - - name: sub_n1n2 - provider_node: n2 - status: replicating - version: 4.0.10 - state: available - status_updated_at: "2025-06-18T17:58:56Z" - updated_at: "2025-06-18T17:54:36Z" - - connection_info: - hostname: i-058731542fee493f.ec2.internal - ipv4_address: 10.24.35.2 - port: 5432 - created_at: "2025-06-18T16:52:22Z" - host_id: ap-south-1 - id: storefront-n2-9ptayhma - node_name: n2 - postgres: - patroni_state: running - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n2n1 - provider_node: n1 - status: replicating - - name: sub_n2n3 - provider_node: n3 - status: replicating - version: 4.0.10 - state: available - status_updated_at: "2025-06-18T17:58:56Z" - updated_at: "2025-06-18T17:54:01Z" - - connection_info: - hostname: i-494027b7b53f6a23.ec2.internal - ipv4_address: 10.24.36.2 - port: 5432 - created_at: "2025-06-18T16:52:22Z" - host_id: eu-central-1 - id: storefront-n3-ant97dj4 - node_name: n3 - postgres: - patroni_state: running - role: primary - version: "18.1" - spock: - read_only: "off" - subscriptions: - - name: sub_n3n1 - provider_node: n1 - status: replicating - - name: sub_n3n2 - provider_node: n2 - status: replicating - version: 4.0.10 - state: available - status_updated_at: "2025-06-18T17:58:56Z" - updated_at: "2025-06-18T17:54:01Z" - spec: - database_name: storefront - database_users: - - attributes: - - SUPERUSER - - LOGIN - db_owner: true - username: admin - nodes: - - host_ids: - - us-east-1 - name: n1 - - host_ids: - - ap-south-1 - name: n2 - - host_ids: - - eu-central-1 - name: n3 - port: 5432 - postgres_version: "17.6" - spock_version: "5" - state: restoring - updated_at: "2025-06-18T17:58:59Z" - node_tasks: - - created_at: "2025-06-18T17:58:59Z" - database_id: storefront - node_name: n1 - parent_id: 01978431-b628-758a-aec6-03b331fa1a17 - status: pending - task_id: 01978431-b62b-723b-a09c-e4072cd64bdb - type: node_restore - - created_at: "2025-06-18T17:58:59Z" - database_id: storefront - node_name: n2 - parent_id: 01978431-b628-758a-aec6-03b331fa1a17 - status: pending - task_id: 01978431-b62c-7593-aad8-43b03df2031b - type: node_restore - - created_at: "2025-06-18T17:58:59Z" - database_id: storefront - node_name: n3 - parent_id: 01978431-b628-758a-aec6-03b331fa1a17 - status: pending - task_id: 01978431-b62d-7b65-ab09-272d0b2fea91 - type: node_restore - task: - created_at: "2025-06-18T17:58:59Z" - database_id: storefront - status: pending - task_id: 01978431-b628-758a-aec6-03b331fa1a17 - type: restore + config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - de3b1388-1f0c-42f1-a86c-59ab72f255ec + - de3b1388-1f0c-42f1-a86c-59ab72f255ec + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: analytics-service + service_type: mcp + version: latest required: - - task - - node_tasks - - database - RestoreRepositorySpec: + - service_id + - service_type + - version + - host_ids + - config + ServiceSpec2: type: object properties: - azure_account: + config: + type: object + description: Service-specific configuration. For MCP services, this includes llm_provider, llm_model, and provider-specific API keys. + example: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + additionalProperties: true + cpus: type: string - description: The Azure account name for this repository. Only applies when type = 'azure'. - example: pgedge-backups - minLength: 3 - maxLength: 24 - azure_container: + description: The number of CPUs to allocate for this service. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Defaults to container defaults if unspecified. + example: 500m + pattern: ^[0-9]+(\.[0-9]{1,3}|m)?$ + host_ids: + type: array + items: + type: string + example: 76f9b8c0-4958-11f0-a489-3bb29577c696 + minLength: 1 + maxLength: 63 + description: The IDs of the hosts that should run this service. One service instance will be created per host. + example: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + minItems: 1 + memory: type: string - description: The Azure container name for this repository. Only applies when type = 'azure'. - example: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - minLength: 3 - maxLength: 63 - azure_endpoint: + description: The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified. + example: 512M + maxLength: 16 + orchestrator_opts: + $ref: '#/components/schemas/OrchestratorOpts' + port: + type: integer + description: The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network. + example: 0 + format: int64 + minimum: 0 + maximum: 65535 + service_id: type: string - description: The optional Azure endpoint for this repository. Only applies when type = 'azure'. - example: blob.core.usgovcloudapi.net - minLength: 3 - maxLength: 128 - azure_key: + description: The unique identifier for this service. + example: 76f9b8c0-4958-11f0-a489-3bb29577c696 + minLength: 1 + maxLength: 63 + service_type: type: string - description: An optional Azure storage account access key to use for this repository. If not provided, pgbackrest will use the VM's managed identity. - example: YXpLZXk= - maxLength: 128 - base_path: + description: The type of service to run. + example: mcp + enum: + - mcp + version: type: string - description: The base path within the repository to store backups. Required for type = 'posix' and 'cifs'. - example: /backups - maxLength: 256 - custom_options: + description: The version of the service in semver format (e.g., '1.0.0') or the literal 'latest'. + example: latest + pattern: ^(\d+\.\d+\.\d+|latest)$ + example: + config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + service_type: mcp + version: latest + required: + - service_id + - service_type + - version + - host_ids + - config + ServiceSpec3: + type: object + properties: + config: type: object - description: Additional options to apply to this repository. + description: Service-specific configuration. For MCP services, this includes llm_provider, llm_model, and provider-specific API keys. example: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - additionalProperties: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + additionalProperties: true + cpus: + type: string + description: The number of CPUs to allocate for this service. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Defaults to container defaults if unspecified. + example: 500m + pattern: ^[0-9]+(\.[0-9]{1,3}|m)?$ + host_ids: + type: array + items: type: string - example: Excepturi consectetur accusantium ut. - gcs_bucket: + example: 76f9b8c0-4958-11f0-a489-3bb29577c696 + minLength: 1 + maxLength: 63 + description: The IDs of the hosts that should run this service. One service instance will be created per host. + example: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + minItems: 1 + memory: type: string - description: The GCS bucket name for this repository. Only applies when type = 'gcs'. - example: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - minLength: 3 + description: The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified. + example: 512M + maxLength: 16 + orchestrator_opts: + $ref: '#/components/schemas/OrchestratorOpts' + port: + type: integer + description: The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network. + example: 0 + format: int64 + minimum: 0 + maximum: 65535 + service_id: + type: string + description: The unique identifier for this service. + example: 76f9b8c0-4958-11f0-a489-3bb29577c696 + minLength: 1 maxLength: 63 - gcs_endpoint: + service_type: type: string - description: The optional GCS endpoint for this repository. Only applies when type = 'gcs'. - example: localhost - minLength: 3 - maxLength: 128 - gcs_key: + description: The type of service to run. + example: mcp + enum: + - mcp + version: + type: string + description: The version of the service in semver format (e.g., '1.0.0') or the literal 'latest'. + example: latest + pattern: ^(\d+\.\d+\.\d+|latest)$ + example: + config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + service_type: mcp + version: latest + required: + - service_id + - service_type + - version + - host_ids + - config + ServiceSpec4: + type: object + properties: + config: + type: object + description: Service-specific configuration. For MCP services, this includes llm_provider, llm_model, and provider-specific API keys. + example: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + additionalProperties: true + cpus: + type: string + description: The number of CPUs to allocate for this service. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Defaults to container defaults if unspecified. + example: 500m + pattern: ^[0-9]+(\.[0-9]{1,3}|m)?$ + host_ids: + type: array + items: + type: string + example: 76f9b8c0-4958-11f0-a489-3bb29577c696 + minLength: 1 + maxLength: 63 + description: The IDs of the hosts that should run this service. One service instance will be created per host. + example: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + minItems: 1 + memory: type: string - description: Optional base64-encoded private key data. If omitted, pgbackrest will use the service account attached to the instance profile. - example: ZXhhbXBsZSBnY3Mga2V5Cg== - maxLength: 1024 - id: + description: The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified. + example: 512M + maxLength: 16 + orchestrator_opts: + $ref: '#/components/schemas/OrchestratorOpts' + port: + type: integer + description: The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network. + example: 0 + format: int64 + minimum: 0 + maximum: 65535 + service_id: type: string - description: A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens. + description: The unique identifier for this service. example: 76f9b8c0-4958-11f0-a489-3bb29577c696 minLength: 1 maxLength: 63 - s3_bucket: + service_type: type: string - description: The S3 bucket name for this repository. Only applies when type = 's3'. - example: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - minLength: 3 - maxLength: 63 - s3_endpoint: + description: The type of service to run. + example: mcp + enum: + - mcp + version: type: string - description: The optional S3 endpoint for this repository. Only applies when type = 's3'. - example: s3.us-east-1.amazonaws.com - minLength: 3 - maxLength: 128 - s3_key: + description: The version of the service in semver format (e.g., '1.0.0') or the literal 'latest'. + example: latest + pattern: ^(\d+\.\d+\.\d+|latest)$ + example: + config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + service_type: mcp + version: latest + required: + - service_id + - service_type + - version + - host_ids + - config + ServiceSpec5: + type: object + properties: + config: + type: object + description: Service-specific configuration. For MCP services, this includes llm_provider, llm_model, and provider-specific API keys. + example: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + additionalProperties: true + cpus: type: string - description: An optional AWS access key ID to use for this repository. If not provided, pgbackrest will use the default credential provider chain. - example: AKIAIOSFODNN7EXAMPLE - maxLength: 128 - s3_key_secret: + description: The number of CPUs to allocate for this service. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Defaults to container defaults if unspecified. + example: 500m + pattern: ^[0-9]+(\.[0-9]{1,3}|m)?$ + host_ids: + type: array + items: + type: string + example: 76f9b8c0-4958-11f0-a489-3bb29577c696 + minLength: 1 + maxLength: 63 + description: The IDs of the hosts that should run this service. One service instance will be created per host. + example: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + minItems: 1 + memory: type: string - description: The corresponding secret for the AWS access key ID in s3_key. - example: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - maxLength: 128 - s3_region: + description: The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified. + example: 512M + maxLength: 16 + orchestrator_opts: + $ref: '#/components/schemas/OrchestratorOpts' + port: + type: integer + description: The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network. + example: 0 + format: int64 + minimum: 0 + maximum: 65535 + service_id: type: string - description: The region of the S3 bucket for this repository. Only applies when type = 's3'. - example: us-east-1 + description: The unique identifier for this service. + example: 76f9b8c0-4958-11f0-a489-3bb29577c696 minLength: 1 - maxLength: 32 - type: + maxLength: 63 + service_type: type: string - description: The type of this repository. - example: s3 + description: The type of service to run. + example: mcp enum: - - s3 - - gcs - - azure - - posix - - cifs + - mcp + version: + type: string + description: The version of the service in semver format (e.g., '1.0.0') or the literal 'latest'. + example: latest + pattern: ^(\d+\.\d+\.\d+|latest)$ example: - azure_account: pgedge-backups - azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - azure_endpoint: blob.core.usgovcloudapi.net - azure_key: YXpLZXk= - base_path: /backups - custom_options: - s3-kms-key-id: 1234abcd-12ab-34cd-56ef-1234567890ab - gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - gcs_endpoint: localhost - gcs_key: ZXhhbXBsZSBnY3Mga2V5Cg== - id: f6b84a99-5e91-4203-be1e-131fe82e5984 - s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 - s3_endpoint: s3.us-east-1.amazonaws.com - s3_key: AKIAIOSFODNN7EXAMPLE - s3_key_secret: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - s3_region: us-east-1 - type: s3 + config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + service_type: mcp + version: latest required: - - type - ServiceInstance: + - service_id + - service_type + - version + - host_ids + - config + ServiceSpec6: type: object properties: - created_at: + config: + type: object + description: Service-specific configuration. For MCP services, this includes llm_provider, llm_model, and provider-specific API keys. + example: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + additionalProperties: true + cpus: + type: string + description: The number of CPUs to allocate for this service. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Defaults to container defaults if unspecified. + example: 500m + pattern: ^[0-9]+(\.[0-9]{1,3}|m)?$ + host_ids: + type: array + items: + type: string + example: 76f9b8c0-4958-11f0-a489-3bb29577c696 + minLength: 1 + maxLength: 63 + description: The IDs of the hosts that should run this service. One service instance will be created per host. + example: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + minItems: 1 + memory: type: string - description: The time that the service instance was created. - example: "2025-01-28T10:00:00Z" - format: date-time - database_id: + description: The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified. + example: 512M + maxLength: 16 + orchestrator_opts: + $ref: '#/components/schemas/OrchestratorOpts' + port: + type: integer + description: The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network. + example: 0 + format: int64 + minimum: 0 + maximum: 65535 + service_id: type: string - description: A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens. + description: The unique identifier for this service. example: 76f9b8c0-4958-11f0-a489-3bb29577c696 minLength: 1 maxLength: 63 - error: - type: string - description: An error message if the service instance is in an error state. - example: 'failed to start container: image not found' - host_id: - type: string - description: The ID of the host this service instance is running on. - example: host-1 - service_id: - type: string - description: The service ID from the DatabaseSpec. - example: mcp-server - service_instance_id: - type: string - description: Unique identifier for the service instance. - example: mcp-server-host-1 - state: + service_type: type: string - description: Current state of the service instance. - example: running + description: The type of service to run. + example: mcp enum: - - creating - - running - - failed - - deleting - status: - $ref: '#/components/schemas/ServiceInstanceStatus' - updated_at: + - mcp + version: type: string - description: The time that the service instance was last updated. - example: "2025-01-28T10:05:00Z" - format: date-time - description: A service instance running on a host alongside the database. + description: The version of the service in semver format (e.g., '1.0.0') or the literal 'latest'. + example: latest + pattern: ^(\d+\.\d+\.\d+|latest)$ example: - created_at: "2025-01-28T10:00:00Z" - database_id: production - error: 'failed to start container: image not found' - host_id: host-1 - service_id: mcp-server - service_instance_id: mcp-server-host-1 - state: running - status: - container_id: a1b2c3d4e5f6 - health_check: - checked_at: "2025-01-28T10:00:00Z" - message: Connection refused - status: healthy - hostname: mcp-server-host-1.internal - image_version: 1.0.0 - ipv4_address: 10.0.1.5 - last_health_at: "2025-01-28T10:00:00Z" - ports: - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - service_ready: true - updated_at: "2025-01-28T10:05:00Z" + config: + llm_model: gpt-4 + llm_provider: openai + openai_api_key: sk-... + cpus: 500m + host_ids: + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + port: 0 + service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 + service_type: mcp + version: latest required: - - service_instance_id - service_id - - database_id - - host_id - - state - - created_at - - updated_at - ServiceInstanceStatus: - type: object - properties: - container_id: - type: string - description: The Docker container ID. - example: a1b2c3d4e5f6 - health_check: - $ref: '#/components/schemas/HealthCheckResult' - hostname: - type: string - description: The hostname of the service instance. - example: mcp-server-host-1.internal - image_version: - type: string - description: The container image version currently running. - example: 1.0.0 - ipv4_address: - type: string - description: The IPv4 address of the service instance. - example: 10.0.1.5 - format: ipv4 - last_health_at: - type: string - description: The time of the last health check attempt. - example: "2025-01-28T10:00:00Z" - format: date-time - ports: - type: array - items: - $ref: '#/components/schemas/PortMapping' - description: Port mappings for this service instance. - example: - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - service_ready: - type: boolean - description: Whether the service is ready to accept requests. - example: true - description: Runtime status information for a service instance. - example: - container_id: a1b2c3d4e5f6 - health_check: - checked_at: "2025-01-28T10:00:00Z" - message: Connection refused - status: healthy - hostname: mcp-server-host-1.internal - image_version: 1.0.0 - ipv4_address: 10.0.1.5 - last_health_at: "2025-01-28T10:00:00Z" - ports: - - container_port: 8080 - host_port: 8080 - name: web-client - - container_port: 8080 - host_port: 8080 - name: web-client - service_ready: true - ServiceSpec: + - service_type + - version + - host_ids + - config + ServiceSpec7: type: object properties: config: @@ -17003,21 +18575,22 @@ components: type: array items: type: string - description: A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens. example: 76f9b8c0-4958-11f0-a489-3bb29577c696 minLength: 1 maxLength: 63 description: The IDs of the hosts that should run this service. One service instance will be created per host. example: - - de3b1388-1f0c-42f1-a86c-59ab72f255ec - - de3b1388-1f0c-42f1-a86c-59ab72f255ec - - de3b1388-1f0c-42f1-a86c-59ab72f255ec + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 minItems: 1 memory: type: string description: The amount of memory in SI or IEC notation to allocate for this service. Defaults to container defaults if unspecified. example: 512M maxLength: 16 + orchestrator_opts: + $ref: '#/components/schemas/OrchestratorOpts' port: type: integer description: The port to publish the service on the host. If 0, Docker assigns a random port. If unspecified, no port is published and the service is not accessible from outside the Docker network. @@ -17027,7 +18600,7 @@ components: maximum: 65535 service_id: type: string - description: A user-specified identifier. Must be 1-63 characters, contain only lower-cased letters and hyphens, start and end with a letter or number, and not contain consecutive hyphens. + description: The unique identifier for this service. example: 76f9b8c0-4958-11f0-a489-3bb29577c696 minLength: 1 maxLength: 63 @@ -17049,12 +18622,43 @@ components: openai_api_key: sk-... cpus: 500m host_ids: - - de3b1388-1f0c-42f1-a86c-59ab72f255ec - - de3b1388-1f0c-42f1-a86c-59ab72f255ec - - de3b1388-1f0c-42f1-a86c-59ab72f255ec + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 + - 76f9b8c0-4958-11f0-a489-3bb29577c696 memory: 512M + orchestrator_opts: + swarm: + extra_labels: + traefik.enable: "true" + traefik.tcp.routers.mydb.rule: HostSNI(`mydb.example.com`) + extra_networks: + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + - aliases: + - pg-db + - db-alias + driver_opts: + com.docker.network.endpoint.expose: "true" + id: traefik-public + extra_volumes: + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host + - destination_path: /backups/container + host_path: /Users/user/backups/host port: 0 - service_id: analytics-service + service_id: 76f9b8c0-4958-11f0-a489-3bb29577c696 service_type: mcp version: latest required: diff --git a/server/internal/api/apiv1/convert.go b/server/internal/api/apiv1/convert.go index 1f3f32c8..142cb0a9 100644 --- a/server/internal/api/apiv1/convert.go +++ b/server/internal/api/apiv1/convert.go @@ -222,14 +222,15 @@ func serviceSpecToAPI(svc *database.ServiceSpec) *api.ServiceSpec { } return &api.ServiceSpec{ - ServiceID: api.Identifier(svc.ServiceID), - ServiceType: svc.ServiceType, - Version: svc.Version, - HostIds: hostIDs, - Port: svc.Port, - Config: filteredConfig, - Cpus: utils.NillablePointerTo(humanizeCPUs(utils.FromPointer(svc.CPUs))), - Memory: utils.NillablePointerTo(humanizeBytes(utils.FromPointer(svc.MemoryBytes))), + ServiceID: api.Identifier(svc.ServiceID), + ServiceType: svc.ServiceType, + Version: svc.Version, + HostIds: hostIDs, + Port: svc.Port, + Config: filteredConfig, + Cpus: utils.NillablePointerTo(humanizeCPUs(utils.FromPointer(svc.CPUs))), + Memory: utils.NillablePointerTo(humanizeBytes(utils.FromPointer(svc.MemoryBytes))), + OrchestratorOpts: orchestratorOptsToAPI(svc.OrchestratorOpts), } } @@ -647,14 +648,15 @@ func apiToServiceSpec(apiSvc *api.ServiceSpec) (*database.ServiceSpec, error) { } return &database.ServiceSpec{ - ServiceID: string(apiSvc.ServiceID), - ServiceType: apiSvc.ServiceType, - Version: apiSvc.Version, - HostIDs: hostIDs, - Port: apiSvc.Port, - Config: apiSvc.Config, - CPUs: cpus, - MemoryBytes: memory, + ServiceID: string(apiSvc.ServiceID), + ServiceType: apiSvc.ServiceType, + Version: apiSvc.Version, + HostIDs: hostIDs, + Port: apiSvc.Port, + Config: apiSvc.Config, + CPUs: cpus, + MemoryBytes: memory, + OrchestratorOpts: orchestratorOptsToDatabase(apiSvc.OrchestratorOpts), }, nil } diff --git a/server/internal/api/apiv1/validate.go b/server/internal/api/apiv1/validate.go index 2d75430b..766599dd 100644 --- a/server/internal/api/apiv1/validate.go +++ b/server/internal/api/apiv1/validate.go @@ -124,6 +124,9 @@ func validateDatabaseSpec(spec *api.DatabaseSpec) error { errs = append(errs, validateRestoreConfig(spec.RestoreConfig, []string{"restore_config"})...) } + // Validate orchestrator_opts (spec-level) + errs = append(errs, validateOrchestratorOpts(spec.OrchestratorOpts, []string{"orchestrator_opts"})...) + // Validate services seenServiceIDs := make(ds.Set[string], len(spec.Services)) for i, svc := range spec.Services { @@ -223,6 +226,9 @@ func validateNode(node *api.DatabaseNodeSpec, path []string) []error { errs = append(errs, validateRestoreConfig(node.RestoreConfig, restoreConfigPath)...) } + // Validate orchestrator_opts (per-node) + errs = append(errs, validateOrchestratorOpts(node.OrchestratorOpts, appendPath(path, "orchestrator_opts"))...) + return errs } @@ -276,6 +282,9 @@ func validateServiceSpec(svc *api.ServiceSpec, path []string) []error { errs = append(errs, validateMemory(svc.Memory, appendPath(path, "memory"))...) } + // Validate orchestrator_opts + errs = append(errs, validateOrchestratorOpts(svc.OrchestratorOpts, appendPath(path, "orchestrator_opts"))...) + return errs } @@ -520,6 +529,25 @@ func validateS3RepoProperties(props repoProperties, path []string) []error { var pgBackRestOptionPattern = regexp.MustCompile(`^[a-z0-9-]+$`) var semverPattern = regexp.MustCompile(`^\d+\.\d+\.\d+$`) +// reservedLabelPrefix is the label key prefix reserved for system use. +const reservedLabelPrefix = "pgedge." + +func validateOrchestratorOpts(opts *api.OrchestratorOpts, path []string) []error { + if opts == nil || opts.Swarm == nil { + return nil + } + + var errs []error + for key := range opts.Swarm.ExtraLabels { + if strings.HasPrefix(key, reservedLabelPrefix) { + labelPath := appendPath(path, "swarm", "extra_labels", mapKeyPath(key)) + err := fmt.Errorf("labels starting with %q are reserved for system use", reservedLabelPrefix) + errs = append(errs, newValidationError(err, labelPath)) + } + } + return errs +} + func validatePgBackRestOptions(opts map[string]string, path []string) []error { var errs []error diff --git a/server/internal/api/apiv1/validate_test.go b/server/internal/api/apiv1/validate_test.go index 771aab90..18b5d7b4 100644 --- a/server/internal/api/apiv1/validate_test.go +++ b/server/internal/api/apiv1/validate_test.go @@ -978,6 +978,53 @@ func TestValidateServiceSpec(t *testing.T) { "memory: failed to parse bytes", }, }, + { + name: "valid service with extra labels", + svc: &api.ServiceSpec{ + ServiceID: "mcp-server", + ServiceType: "mcp", + Version: "1.0.0", + HostIds: []api.Identifier{"host-1"}, + Config: map[string]any{ + "llm_provider": "anthropic", + "llm_model": "claude-sonnet-4-5", + "anthropic_api_key": "sk-ant-...", + }, + OrchestratorOpts: &api.OrchestratorOpts{ + Swarm: &api.SwarmOpts{ + ExtraLabels: map[string]string{ + "traefik.enable": "true", + "custom.label": "value", + }, + }, + }, + }, + }, + { + name: "reserved pgedge label in extra_labels", + svc: &api.ServiceSpec{ + ServiceID: "mcp-server", + ServiceType: "mcp", + Version: "1.0.0", + HostIds: []api.Identifier{"host-1"}, + Config: map[string]any{ + "llm_provider": "anthropic", + "llm_model": "claude-sonnet-4-5", + "anthropic_api_key": "sk-ant-...", + }, + OrchestratorOpts: &api.OrchestratorOpts{ + Swarm: &api.SwarmOpts{ + ExtraLabels: map[string]string{ + "traefik.enable": "true", + "pgedge.component": "hacked", + }, + }, + }, + }, + expected: []string{ + `orchestrator_opts.swarm.extra_labels[pgedge.component]: labels starting with "pgedge." are reserved`, + }, + }, { name: "multiple validation errors", svc: &api.ServiceSpec{ @@ -1009,3 +1056,80 @@ func TestValidateServiceSpec(t *testing.T) { }) } } + +func TestValidateOrchestratorOpts(t *testing.T) { + for _, tc := range []struct { + name string + opts *api.OrchestratorOpts + expected []string + }{ + { + name: "nil opts", + opts: nil, + }, + { + name: "nil swarm", + opts: &api.OrchestratorOpts{Swarm: nil}, + }, + { + name: "empty extra_labels", + opts: &api.OrchestratorOpts{ + Swarm: &api.SwarmOpts{ + ExtraLabels: map[string]string{}, + }, + }, + }, + { + name: "valid labels", + opts: &api.OrchestratorOpts{ + Swarm: &api.SwarmOpts{ + ExtraLabels: map[string]string{ + "traefik.enable": "true", + "traefik.http.routers.mcp.rule": "Host(`mcp.example.com`)", + "custom.label": "value", + }, + }, + }, + }, + { + name: "single reserved label", + opts: &api.OrchestratorOpts{ + Swarm: &api.SwarmOpts{ + ExtraLabels: map[string]string{ + "pgedge.component": "hacked", + }, + }, + }, + expected: []string{ + `extra_labels[pgedge.component]: labels starting with "pgedge." are reserved`, + }, + }, + { + name: "multiple reserved labels", + opts: &api.OrchestratorOpts{ + Swarm: &api.SwarmOpts{ + ExtraLabels: map[string]string{ + "traefik.enable": "true", + "pgedge.component": "hacked", + "pgedge.database.id": "wrong", + }, + }, + }, + expected: []string{ + `extra_labels[pgedge.component]: labels starting with "pgedge." are reserved`, + `extra_labels[pgedge.database.id]: labels starting with "pgedge." are reserved`, + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + err := errors.Join(validateOrchestratorOpts(tc.opts, []string{"orchestrator_opts"})...) + if len(tc.expected) < 1 { + assert.NoError(t, err) + } else { + for _, expected := range tc.expected { + assert.ErrorContains(t, err, expected) + } + } + }) + } +} diff --git a/server/internal/database/spec.go b/server/internal/database/spec.go index 2fd2123b..9e26928c 100644 --- a/server/internal/database/spec.go +++ b/server/internal/database/spec.go @@ -114,14 +114,15 @@ func (u *User) DefaultOptionalFieldsFrom(other *User) { } type ServiceSpec struct { - ServiceID string `json:"service_id"` - ServiceType string `json:"service_type"` - Version string `json:"version"` - HostIDs []string `json:"host_ids"` - Config map[string]any `json:"config"` - Port *int `json:"port,omitempty"` - CPUs *float64 `json:"cpus,omitempty"` - MemoryBytes *uint64 `json:"memory,omitempty"` + ServiceID string `json:"service_id"` + ServiceType string `json:"service_type"` + Version string `json:"version"` + HostIDs []string `json:"host_ids"` + Config map[string]any `json:"config"` + Port *int `json:"port,omitempty"` + CPUs *float64 `json:"cpus,omitempty"` + MemoryBytes *uint64 `json:"memory,omitempty"` + OrchestratorOpts *OrchestratorOpts `json:"orchestrator_opts,omitempty"` } func (s *ServiceSpec) Clone() *ServiceSpec { @@ -129,14 +130,15 @@ func (s *ServiceSpec) Clone() *ServiceSpec { return nil } return &ServiceSpec{ - ServiceID: s.ServiceID, - ServiceType: s.ServiceType, - Version: s.Version, - HostIDs: slices.Clone(s.HostIDs), - Config: maps.Clone(s.Config), - Port: utils.ClonePointer(s.Port), - CPUs: utils.ClonePointer(s.CPUs), - MemoryBytes: utils.ClonePointer(s.MemoryBytes), + ServiceID: s.ServiceID, + ServiceType: s.ServiceType, + Version: s.Version, + HostIDs: slices.Clone(s.HostIDs), + Config: maps.Clone(s.Config), + Port: utils.ClonePointer(s.Port), + CPUs: utils.ClonePointer(s.CPUs), + MemoryBytes: utils.ClonePointer(s.MemoryBytes), + OrchestratorOpts: s.OrchestratorOpts.Clone(), } } diff --git a/server/internal/orchestrator/swarm/service_spec.go b/server/internal/orchestrator/swarm/service_spec.go index c32f6ee6..b5b1ba35 100644 --- a/server/internal/orchestrator/swarm/service_spec.go +++ b/server/internal/orchestrator/swarm/service_spec.go @@ -42,6 +42,13 @@ func ServiceContainerSpec(opts *ServiceContainerSpecOptions) (swarm.ServiceSpec, "pgedge.host.id": opts.HostID, } + // Merge user-provided extra labels (matches Postgres ExtraLabels behavior) + if opts.ServiceSpec.OrchestratorOpts != nil && opts.ServiceSpec.OrchestratorOpts.Swarm != nil { + for k, v := range opts.ServiceSpec.OrchestratorOpts.Swarm.ExtraLabels { + labels[k] = v + } + } + // Build networks - attach to both bridge and database overlay networks // Bridge network provides: // - Control Plane access to service health/API endpoints (port 8080) diff --git a/server/internal/orchestrator/swarm/service_spec_test.go b/server/internal/orchestrator/swarm/service_spec_test.go index 95260bd6..b324d5c0 100644 --- a/server/internal/orchestrator/swarm/service_spec_test.go +++ b/server/internal/orchestrator/swarm/service_spec_test.go @@ -333,6 +333,109 @@ func TestServiceContainerSpec(t *testing.T) { } }, }, + { + name: "service with extra labels for Traefik", + opts: &ServiceContainerSpecOptions{ + ServiceSpec: &database.ServiceSpec{ + ServiceID: "mcp-server", + ServiceType: "mcp", + Version: "latest", + Config: map[string]interface{}{ + "llm_provider": "anthropic", + "llm_model": "claude-sonnet-4-5", + "anthropic_api_key": "sk-ant-test", + }, + OrchestratorOpts: &database.OrchestratorOpts{ + Swarm: &database.SwarmOpts{ + ExtraLabels: map[string]string{ + "traefik.enable": "true", + "traefik.http.routers.mcp.rule": "Host(`mcp.example.com`)", + "traefik.http.services.mcp.loadbalancer.server.port": "8080", + }, + }, + }, + }, + ServiceInstanceID: "db1-mcp-server-host1", + DatabaseID: "db1", + DatabaseName: "testdb", + HostID: "host1", + ServiceName: "db1-mcp-server-host1", + Hostname: "mcp-server-host1", + CohortMemberID: "swarm-node-123", + ServiceImage: &ServiceImage{ + Tag: "ghcr.io/pgedge/postgres-mcp:latest", + }, + DatabaseNetworkID: "db1-database", + DatabaseHost: "postgres-instance-1", + DatabasePort: 5432, + }, + wantErr: false, + checkLabels: func(t *testing.T, labels map[string]string) { + // System labels must still be present + expectedSystem := map[string]string{ + "pgedge.component": "service", + "pgedge.service.instance.id": "db1-mcp-server-host1", + "pgedge.service.id": "mcp-server", + "pgedge.database.id": "db1", + "pgedge.host.id": "host1", + } + for k, v := range expectedSystem { + if labels[k] != v { + t.Errorf("system label %s = %q, want %q", k, labels[k], v) + } + } + // Extra labels must be merged in + expectedExtra := map[string]string{ + "traefik.enable": "true", + "traefik.http.routers.mcp.rule": "Host(`mcp.example.com`)", + "traefik.http.services.mcp.loadbalancer.server.port": "8080", + } + for k, v := range expectedExtra { + if labels[k] != v { + t.Errorf("extra label %s = %q, want %q", k, labels[k], v) + } + } + // Total should be system + extra + if len(labels) != len(expectedSystem)+len(expectedExtra) { + t.Errorf("got %d labels, want %d", len(labels), len(expectedSystem)+len(expectedExtra)) + } + }, + }, + { + name: "service with nil orchestrator opts (backward compat)", + opts: &ServiceContainerSpecOptions{ + ServiceSpec: &database.ServiceSpec{ + ServiceID: "mcp-server", + ServiceType: "mcp", + Version: "latest", + Config: map[string]interface{}{"llm_provider": "anthropic", "llm_model": "claude-sonnet-4-5", "anthropic_api_key": "sk-ant-test"}, + OrchestratorOpts: nil, + }, + ServiceInstanceID: "db1-mcp-server-host1", + DatabaseID: "db1", + DatabaseName: "testdb", + HostID: "host1", + ServiceName: "db1-mcp-server-host1", + Hostname: "mcp-server-host1", + CohortMemberID: "swarm-node-123", + ServiceImage: &ServiceImage{ + Tag: "ghcr.io/pgedge/postgres-mcp:latest", + }, + DatabaseNetworkID: "db1-database", + DatabaseHost: "postgres-instance-1", + DatabasePort: 5432, + }, + wantErr: false, + checkLabels: func(t *testing.T, labels map[string]string) { + // Only system labels, no extras + if len(labels) != 5 { + t.Errorf("got %d labels, want 5 (system only)", len(labels)) + } + if labels["pgedge.component"] != "service" { + t.Errorf("pgedge.component = %q, want %q", labels["pgedge.component"], "service") + } + }, + }, } for _, tt := range tests { @@ -347,9 +450,10 @@ func TestServiceContainerSpec(t *testing.T) { return } - // Run validation checks + // Verify labels are applied to both ContainerSpec and Annotations if tt.checkLabels != nil { tt.checkLabels(t, got.TaskTemplate.ContainerSpec.Labels) + tt.checkLabels(t, got.Labels) } if tt.checkNetworks != nil { tt.checkNetworks(t, got.TaskTemplate.Networks)