From 89d63e817ec254beb9aaca75eefda6e194d93f0e Mon Sep 17 00:00:00 2001 From: Jason Lynch Date: Wed, 15 Jan 2025 16:30:25 -0500 Subject: [PATCH] feat: api generation with goa This commit adds an `api` module that uses Goa to generate HTTP client and server code. The API specification so far is incomplete but does have some of the core entities and operations. Some of the generated examples in the OpenAPI spec are wonky, such as repeating the same example for the `ArrayOf` properties. Hopefully I can fix these in a followup commit. --- api/Makefile | 5 + api/design/api.go | 130 + api/design/cluster.go | 33 + api/design/database.go | 375 ++ api/design/host.go | 55 + api/design/instance.go | 118 + api/gen/control_plane/client.go | 130 + api/gen/control_plane/endpoints.go | 134 + api/gen/control_plane/service.go | 352 ++ api/gen/http/cli/control_plane/cli.go | 1084 ++++ api/gen/http/control_plane/client/cli.go | 116 + api/gen/http/control_plane/client/client.go | 273 + .../control_plane/client/encode_decode.go | 2117 ++++++++ api/gen/http/control_plane/client/paths.go | 57 + api/gen/http/control_plane/client/types.go | 2043 ++++++++ .../control_plane/server/encode_decode.go | 1361 +++++ api/gen/http/control_plane/server/paths.go | 57 + api/gen/http/control_plane/server/server.go | 592 +++ api/gen/http/control_plane/server/types.go | 1466 ++++++ api/gen/http/openapi.json | 1 + api/gen/http/openapi.yaml | 2152 ++++++++ api/gen/http/openapi3.json | 1 + api/gen/http/openapi3.yaml | 4613 +++++++++++++++++ api/go.mod | 21 + api/go.sum | 32 + go.work | 1 + go.work.sum | 14 + tools.mk | 3 + 28 files changed, 17336 insertions(+) create mode 100644 api/Makefile create mode 100644 api/design/api.go create mode 100644 api/design/cluster.go create mode 100644 api/design/database.go create mode 100644 api/design/host.go create mode 100644 api/design/instance.go create mode 100644 api/gen/control_plane/client.go create mode 100644 api/gen/control_plane/endpoints.go create mode 100644 api/gen/control_plane/service.go create mode 100644 api/gen/http/cli/control_plane/cli.go create mode 100644 api/gen/http/control_plane/client/cli.go create mode 100644 api/gen/http/control_plane/client/client.go create mode 100644 api/gen/http/control_plane/client/encode_decode.go create mode 100644 api/gen/http/control_plane/client/paths.go create mode 100644 api/gen/http/control_plane/client/types.go create mode 100644 api/gen/http/control_plane/server/encode_decode.go create mode 100644 api/gen/http/control_plane/server/paths.go create mode 100644 api/gen/http/control_plane/server/server.go create mode 100644 api/gen/http/control_plane/server/types.go create mode 100644 api/gen/http/openapi.json create mode 100644 api/gen/http/openapi.yaml create mode 100644 api/gen/http/openapi3.json create mode 100644 api/gen/http/openapi3.yaml create mode 100644 api/go.mod create mode 100644 api/go.sum diff --git a/api/Makefile b/api/Makefile new file mode 100644 index 00000000..04130850 --- /dev/null +++ b/api/Makefile @@ -0,0 +1,5 @@ +include ../tools.mk + +.PHONY: generate +generate: + goa gen github.com/pgEdge/control-plane/api/design diff --git a/api/design/api.go b/api/design/api.go new file mode 100644 index 00000000..9ccd6c32 --- /dev/null +++ b/api/design/api.go @@ -0,0 +1,130 @@ +package design + +import ( + g "goa.design/goa/v3/dsl" +) + +var _ = g.API("control-plane", func() { + g.Title("pgEdge Control Plane API") + g.Description("Service for creating, modifying, and operating pgEdge databases.") + g.Server("control-plane", func() { + g.Host("localhost", func() { + g.URI("http://localhost:3000") + }) + }) +}) + +var _ = g.Service("control-plane", func() { + g.Method("inspect-cluster", func() { + g.Description("Returns information about the cluster.") + g.Result(Cluster) + + g.HTTP(func() { + g.GET("/cluster") + }) + }) + + g.Method("list-hosts", func() { + g.Description("Lists all hosts within the cluster.") + g.Result(g.ArrayOf(Host)) + + g.HTTP(func() { + g.GET("/hosts") + }) + }) + + g.Method("inspect-host", func() { + g.Description("Returns information about a particular host in the cluster.") + g.Payload(func() { + g.Attribute("host_id", g.String, func() { + g.Description("ID of the host to inspect.") + g.Example("de3b1388-1f0c-42f1-a86c-59ab72f255ec") + }) + }) + g.Result(Host) + + g.HTTP(func() { + g.GET("/hosts/{host_id}") + }) + }) + + g.Method("remove-host", func() { + g.Description("Removes a host from the cluster.") + g.Payload(func() { + g.Attribute("host_id", g.String, func() { + g.Description("ID of the host to remove.") + g.Example("de3b1388-1f0c-42f1-a86c-59ab72f255ec") + }) + }) + g.HTTP(func() { + g.DELETE("/hosts/{host_id}") + }) + }) + + g.Method("list-databases", func() { + g.Description("Lists all databases in the cluster.") + g.Result(g.ArrayOf(Database)) + + g.HTTP(func() { + g.GET("/databases") + }) + }) + + g.Method("create-database", func() { + g.Description("Creates a new database in the cluster.") + g.Payload(CreateDatabaseRequest) + g.Result(Database) + + g.HTTP(func() { + g.POST("/databases") + }) + }) + + g.Method("inspect-database", func() { + g.Description("Returns information about a particular database in the cluster.") + g.Payload(func() { + g.Attribute("database_id", g.String, func() { + g.Description("ID of the database to inspect.") + g.Example("02f1a7db-fca8-4521-b57a-2a375c1ced51") + }) + }) + g.Result(Database) + + g.HTTP(func() { + g.GET("/databases/{database_id}") + }) + }) + + g.Method("update-database", func() { + g.Description("Updates a database with the given specification.") + g.Payload(func() { + g.Attribute("database_id", g.String, func() { + g.Description("ID of the database to update.") + g.Example("02f1a7db-fca8-4521-b57a-2a375c1ced51") + }) + g.Attribute("request", UpdateDatabaseRequest) + }) + g.Result(Database) + + g.HTTP(func() { + g.POST("/databases/{database_id}") + g.Body("request") + }) + }) + + g.Method("delete-database", func() { + g.Description("Deletes a database from the cluster.") + g.Payload(func() { + g.Attribute("database_id", g.String, func() { + g.Description("ID of the database to delete.") + g.Example("02f1a7db-fca8-4521-b57a-2a375c1ced51") + }) + }) + g.HTTP(func() { + g.DELETE("/databases/{database_id}") + }) + }) + + // Serves the OpenAPI spec as a static file + g.Files("/openapi.json", "./gen/http/openapi.json") +}) diff --git a/api/design/cluster.go b/api/design/cluster.go new file mode 100644 index 00000000..0cd18273 --- /dev/null +++ b/api/design/cluster.go @@ -0,0 +1,33 @@ +package design + +import ( + g "goa.design/goa/v3/dsl" +) + +var ClusterStatus = g.Type("ClusterStatus", func() { + g.Attribute("state", g.String, func() { + g.Description("The current state of the cluster.") + g.Enum("available", "error") + }) + + g.Required("state") +}) + +var Cluster = g.Type("Cluster", func() { + g.Attribute("id", g.String, func() { + g.Description("Unique identifier for the cluster.") + g.Example("a67cbb36-c3c3-49c9-8aac-f4a0438a883d") + }) + g.Attribute("tenant_id", g.String, func() { + g.Description("Unique identifier for the cluster's owner.") + g.Example("8210ec10-2dca-406c-ac4a-0661d2189954") + }) + g.Attribute("status", ClusterStatus, func() { + g.Description("Current status of the cluster.") + }) + g.Attribute("hosts", g.ArrayOf(Host), func() { + g.Description("All of the hosts in the cluster.") + }) + + g.Required("id", "tenant_id", "status", "hosts") +}) diff --git a/api/design/database.go b/api/design/database.go new file mode 100644 index 00000000..ffd74a16 --- /dev/null +++ b/api/design/database.go @@ -0,0 +1,375 @@ +package design + +import ( + g "goa.design/goa/v3/dsl" +) + +var DatabaseStatus = g.Type("DatabaseStatus", func() { + g.Attribute("state", g.String, func() { + g.Enum( + "creating", + "modifying", + "available", + "error", + ) + }) + g.Attribute("updated_at", g.String, func() { + g.Format(g.FormatDateTime) + g.Description("The time that the database status was last updated.") + g.Example("2025-01-01T10:30:37Z") + }) +}) + +var DatabaseReplicaSpec = g.Type("DatabaseReplicaSpec", func() { + g.Attribute("instance_id", g.String, func() { + g.Description("A unique identifier for the instance that will be created from this replica specification.") + g.Example("5ec51c55-0921-445e-9d5b-32f5fb5dfbae") + }) + g.Attribute("host_id", g.String, func() { + g.Description("The ID of the host that should run this read replica.") + g.Example("de3b1388-1f0c-42f1-a86c-59ab72f255ec") + }) + + g.Required("instance_id", "host_id") +}) + +var DatabaseNodeSpec = g.Type("DatabaseNodeSpec", func() { + g.Attribute("name", g.String, func() { + g.Description("The name of the database node.") + g.Example("n1") + }) + g.Attribute("instance_id", g.String, func() { + g.Description("A unique identifier for the instance that will be created from this node specification.") + g.Example("a67cbb36-c3c3-49c9-8aac-f4a0438a883d") + }) + g.Attribute("host_id", g.String, func() { + g.Description("The ID of the host that should run this node.") + g.Example("de3b1388-1f0c-42f1-a86c-59ab72f255ec") + }) + g.Attribute("postgres_version", g.String, func() { + g.Description("The major version of Postgres for this node. Overrides the Postgres version set in the DatabaseSpec.") + g.Enum("16", "17") + g.Example("17") + }) + g.Attribute("port", g.Int, func() { + g.Description("The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec.") + g.Example(5432) + }) + g.Attribute("read_replicas", DatabaseReplicaSpec, func() { + g.Description("Read replicas for this database node.") + }) + g.Attribute("postgresql_conf", g.MapOf(g.String, g.Any), func() { + g.Description("Additional postgresql.conf settings for this particular node. Will be merged with the settings provided by control-plane.") + g.Example(map[string]any{ + "max_connections": 1000, + }) + }) + + g.Required("name", "instance_id", "host_id") +}) + +var DatabaseUserSpec = g.Type("DatabaseUserSpec", func() { + g.Attribute("username", g.String, func() { + g.Description("The username for this database user.") + g.Example("admin") + }) + g.Attribute("password", g.String, func() { + g.Description("The password for this database user.") + g.Example("secret") + }) + g.Attribute("roles", g.ArrayOf(g.String), func() { + g.Description("The roles to assign to this database user.") + g.Example([]string{"application"}) + g.Example([]string{"application_read_only"}) + }) + g.Attribute("superuser", g.Boolean, func() { + g.Description("Enables SUPERUSER for this database user when true.") + g.Example(true) + }) + + g.Required("username", "password") +}) + +var DatabaseExtensionSpec = g.Type("DatabaseExtensionSpec", func() { + g.Attribute("name", g.String, func() { + g.Description("The name of the extension to install in this database.") + g.Example("postgis") + }) + g.Attribute("version", g.String, func() { + g.Description("The version of the extension to install in this database.") + g.Example("1.2.3") + }) + + g.Required("name") +}) + +var BackupRepositorySpec = g.Type("BackupRepositorySpec", func() { + g.Attribute("id", g.String, func() { + g.Description("The unique identifier of this repository.") + g.Example("f6b84a99-5e91-4203-be1e-131fe82e5984") + }) + g.Attribute("type", g.String, func() { + g.Description("The type of this repository.") + g.Enum("s3", "gcs", "azure") + g.Example("s3") + }) + g.Attribute("s3_bucket", g.String, func() { + g.Description("The S3 bucket name for this repository. Only applies when type = 's3'.") + g.Example("pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1") + }) + g.Attribute("s3_region", g.String, func() { + g.Description("The region of the S3 bucket for this repository. Only applies when type = 's3'.") + g.Example("us-east-1") + }) + g.Attribute("s3_endpoint", g.String, func() { + g.Description("The optional S3 endpoint for this repository. Only applies when type = 's3'.") + g.Example("s3.us-east-1.amazonaws.com") + }) + g.Attribute("gcs_bucket", g.String, func() { + g.Description("The GCS bucket name for this repository. Only applies when type = 'gcs'.") + g.Example("pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1") + }) + g.Attribute("gcs_endpoint", g.String, func() { + g.Description("The optional GCS endpoint for this repository. Only applies when type = 'gcs'.") + g.Example("localhost") + }) + g.Attribute("azure_account", g.String, func() { + g.Description("The Azure account name for this repository. Only applies when type = 'azure'.") + g.Example("pgedge-backups") + }) + g.Attribute("azure_container", g.String, func() { + g.Description("The Azure container name for this repository. Only applies when type = 'azure'.") + g.Example("pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1") + }) + g.Attribute("azure_endpoint", g.String, func() { + g.Description("The optional Azure endpoint for this repository. Only applies when type = 'azure'.") + g.Example("blob.core.usgovcloudapi.net") + }) + g.Attribute("retention_full", g.Int, func() { + g.Description("The count of full backups to retain or the time to retain full backups.") + g.Example(2) + }) + g.Attribute("retention_full_type", g.String, func() { + g.Description("The type of measure used for retention_full.") + g.Enum("time", "count") + g.Example("count") + }) + g.Attribute("base_path", g.String, func() { + g.Description("The base path within the repository to store backups.") + g.Example("/backups") + }) + + g.Required("type") +}) + +var BackupScheduleSpec = g.Type("BackupScheduleSpec", func() { + g.Attribute("id", g.String, func() { + g.Description("The unique identifier for this backup schedule.") + g.Example("daily-full-backup") + }) + g.Attribute("type", g.String, func() { + g.Description("The type of backup to take on this schedule.") + g.Enum("full", "incr") + g.Example("full") + }) + g.Attribute("cron_expression", g.String, func() { + g.Description("The cron expression for this schedule.") + g.Example("0 6 * * ?") + }) + + g.Required("id", "type", "cron_expression") +}) + +var BackupConfigSpec = g.Type("BackupConfigSpec", func() { + g.Attribute("id", g.String, func() { + g.Description("The unique identifier for this backup configuration.") + g.Example("default") + }) + g.Attribute("node_names", g.ArrayOf(g.String), func() { + g.Description("The names of the nodes where this backup configuration should be applied. The configuration will apply to all nodes when this field is empty or unspecified.") + g.Example([]string{"n1", "n3"}) + }) + g.Attribute("provider", g.String, func() { + g.Description("The backup provider for this backup configuration.") + g.Enum("pgbackrest", "pg_dump") + g.Example("pgbackrest") + }) + g.Attribute("repositories", g.ArrayOf(BackupRepositorySpec), func() { + g.Description("The repositories for this backup configuration.") + }) + g.Attribute("schedules", g.ArrayOf(BackupScheduleSpec), func() { + g.Description("The schedules for this backup configuration.") + }) + + g.Required("id", "provider") +}) + +var RestoreRepositorySpec = g.Type("RestoreRepositorySpec", func() { + g.Attribute("id", g.String, func() { + g.Description("The unique identifier of this repository.") + g.Example("f6b84a99-5e91-4203-be1e-131fe82e5984") + }) + g.Attribute("type", g.String, func() { + g.Description("The type of this repository.") + g.Enum("s3", "gcs", "azure") + g.Example("s3") + }) + g.Attribute("s3_bucket", g.String, func() { + g.Description("The S3 bucket name for this repository. Only applies when type = 's3'.") + g.Example("pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1") + }) + g.Attribute("s3_region", g.String, func() { + g.Description("The region of the S3 bucket for this repository. Only applies when type = 's3'.") + g.Example("us-east-1") + }) + g.Attribute("s3_endpoint", g.String, func() { + g.Description("The optional S3 endpoint for this repository. Only applies when type = 's3'.") + g.Example("s3.us-east-1.amazonaws.com") + }) + g.Attribute("gcs_bucket", g.String, func() { + g.Description("The GCS bucket name for this repository. Only applies when type = 'gcs'.") + g.Example("pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1") + }) + g.Attribute("gcs_endpoint", g.String, func() { + g.Description("The optional GCS endpoint for this repository. Only applies when type = 'gcs'.") + g.Example("localhost") + }) + g.Attribute("azure_account", g.String, func() { + g.Description("The Azure account name for this repository. Only applies when type = 'azure'.") + g.Example("pgedge-backups") + }) + g.Attribute("azure_container", g.String, func() { + g.Description("The Azure container name for this repository. Only applies when type = 'azure'.") + g.Example("pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1") + }) + g.Attribute("azure_endpoint", g.String, func() { + g.Description("The optional Azure endpoint for this repository. Only applies when type = 'azure'.") + g.Example("blob.core.usgovcloudapi.net") + }) + g.Attribute("base_path", g.String, func() { + g.Description("The base path within the repository where backups are stored.") + g.Example("/backups") + }) + + g.Required("id", "type") +}) + +var RestoreConfigSpec = g.Type("RestoreConfigSpec", func() { + g.Attribute("provider", g.String, func() { + g.Description("The backup provider for this restore configuration.") + g.Enum("pgbackrest", "pg_dump") + g.Example("pgbackrest") + }) + g.Attribute("node_name", g.String, func() { + g.Description("The name of the node to restore this database from.") + g.Example("n1") + }) + g.Attribute("repository", RestoreRepositorySpec, func() { + g.Description("The repository to restore this database from.") + }) + + g.Required("provider", "node_name", "repository") +}) + +var DatabaseSpec = g.Type("DatabaseSpec", func() { + g.Attribute("database_name", g.String, func() { + g.Description("The name of the Postgres database.") + g.Example("northwind") + }) + g.Attribute("postgres_version", g.String, func() { + g.Description("The major version of the Postgres database.") + g.Enum("16", "17") + g.Example("17") + }) + g.Attribute("spock_version", g.String, func() { + g.Description("The major version of the Spock extension.") + g.Enum("4") + g.Example("4") + }) + g.Attribute("port", g.Int, func() { + g.Description("The port used by the Postgres database.") + g.Example(5432) + }) + g.Attribute("deletion_protection", g.Boolean, func() { + g.Description("Prevents deletion when true.") + g.Example(true) + }) + g.Attribute("nodes", g.ArrayOf(DatabaseNodeSpec), func() { + g.Description("The Spock nodes for this database.") + }) + g.Attribute("database_users", g.ArrayOf(DatabaseUserSpec), func() { + g.Description("The users to create for this database.") + }) + g.Attribute("extensions", g.ArrayOf(DatabaseExtensionSpec), func() { + g.Description("The extensions to install for this database.") + }) + g.Attribute("features", g.MapOf(g.String, g.String), func() { + g.Description("The feature flags for this database.") + g.Example(map[string]string{ + "some_feature": "enabled", + }) + }) + g.Attribute("backup_configs", g.ArrayOf(BackupConfigSpec), func() { + g.Description("The backup configurations for this database.") + }) + g.Attribute("postgresql_conf", g.MapOf(g.String, g.Any), func() { + g.Description("Additional postgresql.conf settings. Will be merged with the settings provided by control-plane.") + g.Example(map[string]any{ + "max_connections": 1000, + }) + }) + + g.Required("database_name", "nodes") +}) + +var Database = g.Type("Database", func() { + g.Attribute("id", g.String, func() { + g.Description("Unique identifier for the database.") + g.Example("02f1a7db-fca8-4521-b57a-2a375c1ced51") + }) + g.Attribute("tenant_id", g.String, func() { + g.Description("Unique identifier for the databases's owner.") + g.Example("8210ec10-2dca-406c-ac4a-0661d2189954") + }) + g.Attribute("created_at", g.String, func() { + g.Format(g.FormatDateTime) + g.Description("The time that the database was created.") + g.Example("2025-01-01T01:30:00Z") + }) + g.Attribute("updated_at", g.String, func() { + g.Format(g.FormatDateTime) + g.Description("The time that the database was last updated.") + g.Example("2025-01-01T02:30:00Z") + }) + g.Attribute("status", DatabaseStatus, func() { + g.Description("Current status of the database.") + }) + g.Attribute("instances", Instance, func() { + g.Description("All of the instances in the database.") + }) + g.Attribute("spec", DatabaseSpec, func() { + g.Description("The user-provided specification for the database.") + }) + + g.Required("id", "status", "instances") +}) + +var CreateDatabaseRequest = g.Type("CreateDatabaseRequest", func() { + g.Attribute("id", g.String, func() { + g.Description("Unique identifier for the database.") + g.Example("02f1a7db-fca8-4521-b57a-2a375c1ced51") + }) + g.Attribute("tenant_id", g.String, func() { + g.Description("Unique identifier for the databases's owner.") + g.Example("8210ec10-2dca-406c-ac4a-0661d2189954") + }) + g.Attribute("spec", DatabaseSpec, func() { + g.Description("The specification for the database.") + }) +}) + +var UpdateDatabaseRequest = g.Type("UpdateDatabaseRequest", func() { + g.Attribute("spec", DatabaseSpec, func() { + g.Description("The specification for the database.") + }) +}) diff --git a/api/design/host.go b/api/design/host.go new file mode 100644 index 00000000..1ce33b1f --- /dev/null +++ b/api/design/host.go @@ -0,0 +1,55 @@ +package design + +import ( + g "goa.design/goa/v3/dsl" +) + +var HostStatus = g.Type("HostStatus", func() { + g.Attribute("state", g.String, func() { + g.Enum("available", "unreachable", "error") + g.Example("available") + }) + + g.Required("state") +}) + +var HostConfiguration = g.Type("HostConfiguration", func() { + g.Attribute("vector_enabled", g.Boolean, func() { + g.Description("Enables the Vector service for metrics and log collection") + }) + g.Attribute("traefik_enabled", g.Boolean, func() { + g.Description("Enables the Treafik load balancer") + }) +}) + +var Host = g.Type("Host", func() { + g.Attribute("id", g.String, func() { + g.Description("Unique identifier for the host") + g.Example("de3b1388-1f0c-42f1-a86c-59ab72f255ec") + }) + g.Attribute("type", g.String, func() { + g.Description("The type of this host") + g.Enum("swarm", "systemd") + }) + g.Attribute("cohort", g.String, func() { + g.Description("The cohort that this host belongs to") + g.Example("pps1n11hqijn9rbee4cjil453") + }) + g.Attribute("hostname", g.String, func() { + g.Description("The hostname of this host.") + g.Example("i-0123456789abcdef.ec2.internal") + }) + g.Attribute("ipv4_address", func() { + g.Description("The IPv4 address of this host.") + g.Format(g.FormatIPv4) + g.Example("10.24.34.0") + }) + g.Attribute("config", HostConfiguration, func() { + g.Description("The configuration for this host") + }) + g.Attribute("status", HostStatus, func() { + g.Description("Current status of the host") + }) + + g.Required("id", "status", "hostname", "ipv4_address") +}) diff --git a/api/design/instance.go b/api/design/instance.go new file mode 100644 index 00000000..93b67a7b --- /dev/null +++ b/api/design/instance.go @@ -0,0 +1,118 @@ +package design + +import ( + g "goa.design/goa/v3/dsl" +) + +var InstanceStatus = g.Type("InstanceStatus", func() { + g.Attribute("state", g.String, func() { + g.Enum( + "creating", + "modifying", + "backing_up", + "available", + "error", + ) + }) + g.Attribute("patroni_state", g.String, func() { + g.Enum( + "stopping", + "stopped", + "stop failed", + "crashed", + "running", + "starting", + "start failed", + "restarting", + "restart failed", + "initializing new cluster", + "initdb failed", + "running custom bootstrap script", + "custom bootstrap failed", + "creating replica", + "unknown", + ) + }) + g.Attribute("role", g.String, func() { + g.Enum("replica", "primary") + }) + g.Attribute("read_only", g.Boolean, func() { + g.Description("True if this instance is in read-only mode.") + }) + g.Attribute("pending_restart", g.Boolean, func() { + g.Description("True if this instance is pending to be restarted from a configuration change.") + }) + g.Attribute("patroni_paused", g.Boolean, func() { + g.Description("True if Patroni has been paused for this instance.") + }) + g.Attribute("postgres_version", g.String, func() { + g.Description("The version of Postgres for this instance.") + g.Example("17.1") + }) + g.Attribute("spock_version", g.String, func() { + g.Description("The version of Spock for this instance.") + g.Example("4.0.9") + }) + g.Attribute("updated_at", g.String, func() { + g.Format(g.FormatDateTime) + g.Description("The time that the instance status was last updated.") + }) + + g.Required("state") +}) + +var InstanceInterface = g.Type("InstanceInterface", func() { + g.Attribute("network_type", g.String, func() { + g.Description("The type of network for this interface.") + g.Enum("docker", "host") + g.Example("docker") + }) + g.Attribute("network_id", g.String, func() { + g.Description("The unique identifier of the network for this interface.") + g.Example("l5imrq28sh6s") + }) + g.Attribute("hostname", g.String, func() { + g.Description("The hostname of the instance on this interface.") + g.Example("postgres-n1") + }) + g.Attribute("ipv4_address", g.String, func() { + g.Format(g.FormatIPv4) + g.Description("The IPv4 address of the instance on this interface.") + g.Example("10.1.0.113") + }) + g.Attribute("port", g.Int, func() { + g.Description("The Postgres port for the instance on this interface.") + g.Example(5432) + }) +}) + +var Instance = g.Type("Instance", func() { + g.Attribute("id", g.String, func() { + g.Description("Unique identifier for the instance.") + g.Example("a67cbb36-c3c3-49c9-8aac-f4a0438a883d") + }) + g.Attribute("host_id", g.String, func() { + g.Description("The ID of the host this instance is running on.") + g.Example("de3b1388-1f0c-42f1-a86c-59ab72f255ec") + }) + g.Attribute("node_name", g.String, func() { + g.Description("The Spock node name for this instance.") + g.Example("n1") + }) + g.Attribute("created_at", g.String, func() { + g.Format(g.FormatDateTime) + g.Description("The time that the instance was created.") + }) + g.Attribute("updated_at", g.String, func() { + g.Format(g.FormatDateTime) + g.Description("The time that the instance was last updated.") + }) + g.Attribute("status", InstanceStatus, func() { + g.Description("Current status of the instance.") + }) + g.Attribute("interfaces", g.ArrayOf(InstanceInterface), func() { + g.Description("All interfaces that this instance serves on.") + }) + + g.Required("id", "status") +}) diff --git a/api/gen/control_plane/client.go b/api/gen/control_plane/client.go new file mode 100644 index 00000000..74682b0d --- /dev/null +++ b/api/gen/control_plane/client.go @@ -0,0 +1,130 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// control-plane client +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package controlplane + +import ( + "context" + + goa "goa.design/goa/v3/pkg" +) + +// Client is the "control-plane" service client. +type Client struct { + InspectClusterEndpoint goa.Endpoint + ListHostsEndpoint goa.Endpoint + InspectHostEndpoint goa.Endpoint + RemoveHostEndpoint goa.Endpoint + ListDatabasesEndpoint goa.Endpoint + CreateDatabaseEndpoint goa.Endpoint + InspectDatabaseEndpoint goa.Endpoint + UpdateDatabaseEndpoint goa.Endpoint + DeleteDatabaseEndpoint goa.Endpoint +} + +// NewClient initializes a "control-plane" service client given the endpoints. +func NewClient(inspectCluster, listHosts, inspectHost, removeHost, listDatabases, createDatabase, inspectDatabase, updateDatabase, deleteDatabase goa.Endpoint) *Client { + return &Client{ + InspectClusterEndpoint: inspectCluster, + ListHostsEndpoint: listHosts, + InspectHostEndpoint: inspectHost, + RemoveHostEndpoint: removeHost, + ListDatabasesEndpoint: listDatabases, + CreateDatabaseEndpoint: createDatabase, + InspectDatabaseEndpoint: inspectDatabase, + UpdateDatabaseEndpoint: updateDatabase, + DeleteDatabaseEndpoint: deleteDatabase, + } +} + +// InspectCluster calls the "inspect-cluster" endpoint of the "control-plane" +// service. +func (c *Client) InspectCluster(ctx context.Context) (res *Cluster, err error) { + var ires any + ires, err = c.InspectClusterEndpoint(ctx, nil) + if err != nil { + return + } + return ires.(*Cluster), nil +} + +// ListHosts calls the "list-hosts" endpoint of the "control-plane" service. +func (c *Client) ListHosts(ctx context.Context) (res []*Host, err error) { + var ires any + ires, err = c.ListHostsEndpoint(ctx, nil) + if err != nil { + return + } + return ires.([]*Host), nil +} + +// InspectHost calls the "inspect-host" endpoint of the "control-plane" service. +func (c *Client) InspectHost(ctx context.Context, p *InspectHostPayload) (res *Host, err error) { + var ires any + ires, err = c.InspectHostEndpoint(ctx, p) + if err != nil { + return + } + return ires.(*Host), nil +} + +// RemoveHost calls the "remove-host" endpoint of the "control-plane" service. +func (c *Client) RemoveHost(ctx context.Context, p *RemoveHostPayload) (err error) { + _, err = c.RemoveHostEndpoint(ctx, p) + return +} + +// ListDatabases calls the "list-databases" endpoint of the "control-plane" +// service. +func (c *Client) ListDatabases(ctx context.Context) (res []*Database, err error) { + var ires any + ires, err = c.ListDatabasesEndpoint(ctx, nil) + if err != nil { + return + } + return ires.([]*Database), nil +} + +// CreateDatabase calls the "create-database" endpoint of the "control-plane" +// service. +func (c *Client) CreateDatabase(ctx context.Context, p *CreateDatabaseRequest) (res *Database, err error) { + var ires any + ires, err = c.CreateDatabaseEndpoint(ctx, p) + if err != nil { + return + } + return ires.(*Database), nil +} + +// InspectDatabase calls the "inspect-database" endpoint of the "control-plane" +// service. +func (c *Client) InspectDatabase(ctx context.Context, p *InspectDatabasePayload) (res *Database, err error) { + var ires any + ires, err = c.InspectDatabaseEndpoint(ctx, p) + if err != nil { + return + } + return ires.(*Database), nil +} + +// UpdateDatabase calls the "update-database" endpoint of the "control-plane" +// service. +func (c *Client) UpdateDatabase(ctx context.Context, p *UpdateDatabasePayload) (res *Database, err error) { + var ires any + ires, err = c.UpdateDatabaseEndpoint(ctx, p) + if err != nil { + return + } + return ires.(*Database), nil +} + +// DeleteDatabase calls the "delete-database" endpoint of the "control-plane" +// service. +func (c *Client) DeleteDatabase(ctx context.Context, p *DeleteDatabasePayload) (err error) { + _, err = c.DeleteDatabaseEndpoint(ctx, p) + return +} diff --git a/api/gen/control_plane/endpoints.go b/api/gen/control_plane/endpoints.go new file mode 100644 index 00000000..aba5c0b4 --- /dev/null +++ b/api/gen/control_plane/endpoints.go @@ -0,0 +1,134 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// control-plane endpoints +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package controlplane + +import ( + "context" + + goa "goa.design/goa/v3/pkg" +) + +// Endpoints wraps the "control-plane" service endpoints. +type Endpoints struct { + InspectCluster goa.Endpoint + ListHosts goa.Endpoint + InspectHost goa.Endpoint + RemoveHost goa.Endpoint + ListDatabases goa.Endpoint + CreateDatabase goa.Endpoint + InspectDatabase goa.Endpoint + UpdateDatabase goa.Endpoint + DeleteDatabase goa.Endpoint +} + +// NewEndpoints wraps the methods of the "control-plane" service with endpoints. +func NewEndpoints(s Service) *Endpoints { + return &Endpoints{ + InspectCluster: NewInspectClusterEndpoint(s), + ListHosts: NewListHostsEndpoint(s), + InspectHost: NewInspectHostEndpoint(s), + RemoveHost: NewRemoveHostEndpoint(s), + ListDatabases: NewListDatabasesEndpoint(s), + CreateDatabase: NewCreateDatabaseEndpoint(s), + InspectDatabase: NewInspectDatabaseEndpoint(s), + UpdateDatabase: NewUpdateDatabaseEndpoint(s), + DeleteDatabase: NewDeleteDatabaseEndpoint(s), + } +} + +// Use applies the given middleware to all the "control-plane" service +// endpoints. +func (e *Endpoints) Use(m func(goa.Endpoint) goa.Endpoint) { + e.InspectCluster = m(e.InspectCluster) + e.ListHosts = m(e.ListHosts) + e.InspectHost = m(e.InspectHost) + e.RemoveHost = m(e.RemoveHost) + e.ListDatabases = m(e.ListDatabases) + e.CreateDatabase = m(e.CreateDatabase) + e.InspectDatabase = m(e.InspectDatabase) + e.UpdateDatabase = m(e.UpdateDatabase) + e.DeleteDatabase = m(e.DeleteDatabase) +} + +// NewInspectClusterEndpoint returns an endpoint function that calls the method +// "inspect-cluster" of service "control-plane". +func NewInspectClusterEndpoint(s Service) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + return s.InspectCluster(ctx) + } +} + +// NewListHostsEndpoint returns an endpoint function that calls the method +// "list-hosts" of service "control-plane". +func NewListHostsEndpoint(s Service) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + return s.ListHosts(ctx) + } +} + +// NewInspectHostEndpoint returns an endpoint function that calls the method +// "inspect-host" of service "control-plane". +func NewInspectHostEndpoint(s Service) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + p := req.(*InspectHostPayload) + return s.InspectHost(ctx, p) + } +} + +// NewRemoveHostEndpoint returns an endpoint function that calls the method +// "remove-host" of service "control-plane". +func NewRemoveHostEndpoint(s Service) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + p := req.(*RemoveHostPayload) + return nil, s.RemoveHost(ctx, p) + } +} + +// NewListDatabasesEndpoint returns an endpoint function that calls the method +// "list-databases" of service "control-plane". +func NewListDatabasesEndpoint(s Service) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + return s.ListDatabases(ctx) + } +} + +// NewCreateDatabaseEndpoint returns an endpoint function that calls the method +// "create-database" of service "control-plane". +func NewCreateDatabaseEndpoint(s Service) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + p := req.(*CreateDatabaseRequest) + return s.CreateDatabase(ctx, p) + } +} + +// NewInspectDatabaseEndpoint returns an endpoint function that calls the +// method "inspect-database" of service "control-plane". +func NewInspectDatabaseEndpoint(s Service) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + p := req.(*InspectDatabasePayload) + return s.InspectDatabase(ctx, p) + } +} + +// NewUpdateDatabaseEndpoint returns an endpoint function that calls the method +// "update-database" of service "control-plane". +func NewUpdateDatabaseEndpoint(s Service) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + p := req.(*UpdateDatabasePayload) + return s.UpdateDatabase(ctx, p) + } +} + +// NewDeleteDatabaseEndpoint returns an endpoint function that calls the method +// "delete-database" of service "control-plane". +func NewDeleteDatabaseEndpoint(s Service) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + p := req.(*DeleteDatabasePayload) + return nil, s.DeleteDatabase(ctx, p) + } +} diff --git a/api/gen/control_plane/service.go b/api/gen/control_plane/service.go new file mode 100644 index 00000000..03d50aa1 --- /dev/null +++ b/api/gen/control_plane/service.go @@ -0,0 +1,352 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// control-plane service +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package controlplane + +import ( + "context" +) + +// Service is the control-plane service interface. +type Service interface { + // Returns information about the cluster. + InspectCluster(context.Context) (res *Cluster, err error) + // Lists all hosts within the cluster. + ListHosts(context.Context) (res []*Host, err error) + // Returns information about a particular host in the cluster. + InspectHost(context.Context, *InspectHostPayload) (res *Host, err error) + // Removes a host from the cluster. + RemoveHost(context.Context, *RemoveHostPayload) (err error) + // Lists all databases in the cluster. + ListDatabases(context.Context) (res []*Database, err error) + // Creates a new database in the cluster. + CreateDatabase(context.Context, *CreateDatabaseRequest) (res *Database, err error) + // Returns information about a particular database in the cluster. + InspectDatabase(context.Context, *InspectDatabasePayload) (res *Database, err error) + // Updates a database with the given specification. + UpdateDatabase(context.Context, *UpdateDatabasePayload) (res *Database, err error) + // Deletes a database from the cluster. + DeleteDatabase(context.Context, *DeleteDatabasePayload) (err error) +} + +// APIName is the name of the API as defined in the design. +const APIName = "control-plane" + +// APIVersion is the version of the API as defined in the design. +const APIVersion = "0.0.1" + +// ServiceName is the name of the service as defined in the design. This is the +// same value that is set in the endpoint request contexts under the ServiceKey +// key. +const ServiceName = "control-plane" + +// MethodNames lists the service method names as defined in the design. These +// are the same values that are set in the endpoint request contexts under the +// MethodKey key. +var MethodNames = [9]string{"inspect-cluster", "list-hosts", "inspect-host", "remove-host", "list-databases", "create-database", "inspect-database", "update-database", "delete-database"} + +type BackupConfigSpec struct { + // The unique identifier for this backup configuration. + ID string + // The names of the nodes where this backup configuration should be applied. + // The configuration will apply to all nodes when this field is empty or + // unspecified. + NodeNames []string + // The backup provider for this backup configuration. + Provider string + // The repositories for this backup configuration. + Repositories []*BackupRepositorySpec + // The schedules for this backup configuration. + Schedules []*BackupScheduleSpec +} + +type BackupRepositorySpec struct { + // The unique identifier of this repository. + ID *string + // The type of this repository. + Type string + // The S3 bucket name for this repository. Only applies when type = 's3'. + S3Bucket *string + // The region of the S3 bucket for this repository. Only applies when type = + // 's3'. + S3Region *string + // The optional S3 endpoint for this repository. Only applies when type = 's3'. + S3Endpoint *string + // The GCS bucket name for this repository. Only applies when type = 'gcs'. + GcsBucket *string + // The optional GCS endpoint for this repository. Only applies when type = + // 'gcs'. + GcsEndpoint *string + // The Azure account name for this repository. Only applies when type = 'azure'. + AzureAccount *string + // The Azure container name for this repository. Only applies when type = + // 'azure'. + AzureContainer *string + // The optional Azure endpoint for this repository. Only applies when type = + // 'azure'. + AzureEndpoint *string + // The count of full backups to retain or the time to retain full backups. + RetentionFull *int + // The type of measure used for retention_full. + RetentionFullType *string + // The base path within the repository to store backups. + BasePath *string +} + +type BackupScheduleSpec struct { + // The unique identifier for this backup schedule. + ID string + // The type of backup to take on this schedule. + Type string + // The cron expression for this schedule. + CronExpression string +} + +// Cluster is the result type of the control-plane service inspect-cluster +// method. +type Cluster struct { + // Unique identifier for the cluster. + ID string + // Unique identifier for the cluster's owner. + TenantID string + // Current status of the cluster. + Status *ClusterStatus + // All of the hosts in the cluster. + Hosts []*Host +} + +type ClusterStatus struct { + // The current state of the cluster. + State string +} + +// CreateDatabaseRequest is the payload type of the control-plane service +// create-database method. +type CreateDatabaseRequest struct { + // Unique identifier for the database. + ID *string + // Unique identifier for the databases's owner. + TenantID *string + // The specification for the database. + Spec *DatabaseSpec +} + +// Database is the result type of the control-plane service create-database +// method. +type Database struct { + // Unique identifier for the database. + ID string + // Unique identifier for the databases's owner. + TenantID *string + // The time that the database was created. + CreatedAt *string + // The time that the database was last updated. + UpdatedAt *string + // Current status of the database. + Status *DatabaseStatus + // All of the instances in the database. + Instances *Instance + // The user-provided specification for the database. + Spec *DatabaseSpec +} + +type DatabaseExtensionSpec struct { + // The name of the extension to install in this database. + Name string + // The version of the extension to install in this database. + Version *string +} + +type DatabaseNodeSpec struct { + // The name of the database node. + Name string + // A unique identifier for the instance that will be created from this node + // specification. + InstanceID string + // The ID of the host that should run this node. + HostID string + // The major version of Postgres for this node. Overrides the Postgres version + // set in the DatabaseSpec. + PostgresVersion *string + // The port used by the Postgres database for this node. Overrides the Postgres + // port set in the DatabaseSpec. + Port *int + // Read replicas for this database node. + ReadReplicas *DatabaseReplicaSpec + // Additional postgresql.conf settings for this particular node. Will be merged + // with the settings provided by control-plane. + PostgresqlConf map[string]any +} + +type DatabaseReplicaSpec struct { + // A unique identifier for the instance that will be created from this replica + // specification. + InstanceID string + // The ID of the host that should run this read replica. + HostID string +} + +type DatabaseSpec struct { + // The name of the Postgres database. + DatabaseName string + // The major version of the Postgres database. + PostgresVersion *string + // The major version of the Spock extension. + SpockVersion *string + // The port used by the Postgres database. + Port *int + // Prevents deletion when true. + DeletionProtection *bool + // The Spock nodes for this database. + Nodes []*DatabaseNodeSpec + // The users to create for this database. + DatabaseUsers []*DatabaseUserSpec + // The extensions to install for this database. + Extensions []*DatabaseExtensionSpec + // The feature flags for this database. + Features map[string]string + // The backup configurations for this database. + BackupConfigs []*BackupConfigSpec + // Additional postgresql.conf settings. Will be merged with the settings + // provided by control-plane. + PostgresqlConf map[string]any +} + +type DatabaseStatus struct { + State *string + // The time that the database status was last updated. + UpdatedAt *string +} + +type DatabaseUserSpec struct { + // The username for this database user. + Username string + // The password for this database user. + Password string + // The roles to assign to this database user. + Roles []string + // Enables SUPERUSER for this database user when true. + Superuser *bool +} + +// DeleteDatabasePayload is the payload type of the control-plane service +// delete-database method. +type DeleteDatabasePayload struct { + // ID of the database to delete. + DatabaseID *string +} + +// Host is the result type of the control-plane service inspect-host method. +type Host struct { + // Unique identifier for the host + ID string + // The type of this host + Type *string + // The cohort that this host belongs to + Cohort *string + // The hostname of this host. + Hostname string + // The IPv4 address of this host. + Ipv4Address string + // The configuration for this host + Config *HostConfiguration + // Current status of the host + Status *HostStatus +} + +type HostConfiguration struct { + // Enables the Vector service for metrics and log collection + VectorEnabled *bool + // Enables the Treafik load balancer + TraefikEnabled *bool +} + +type HostStatus struct { + State string +} + +// InspectDatabasePayload is the payload type of the control-plane service +// inspect-database method. +type InspectDatabasePayload struct { + // ID of the database to inspect. + DatabaseID *string +} + +// InspectHostPayload is the payload type of the control-plane service +// inspect-host method. +type InspectHostPayload struct { + // ID of the host to inspect. + HostID *string +} + +type Instance struct { + // Unique identifier for the instance. + ID string + // The ID of the host this instance is running on. + HostID *string + // The Spock node name for this instance. + NodeName *string + // The time that the instance was created. + CreatedAt *string + // The time that the instance was last updated. + UpdatedAt *string + // Current status of the instance. + Status *InstanceStatus + // All interfaces that this instance serves on. + Interfaces []*InstanceInterface +} + +type InstanceInterface struct { + // The type of network for this interface. + NetworkType *string + // The unique identifier of the network for this interface. + NetworkID *string + // The hostname of the instance on this interface. + Hostname *string + // The IPv4 address of the instance on this interface. + Ipv4Address *string + // The Postgres port for the instance on this interface. + Port *int +} + +type InstanceStatus struct { + State string + PatroniState *string + Role *string + // True if this instance is in read-only mode. + ReadOnly *bool + // True if this instance is pending to be restarted from a configuration change. + PendingRestart *bool + // True if Patroni has been paused for this instance. + PatroniPaused *bool + // The version of Postgres for this instance. + PostgresVersion *string + // The version of Spock for this instance. + SpockVersion *string + // The time that the instance status was last updated. + UpdatedAt *string +} + +// RemoveHostPayload is the payload type of the control-plane service +// remove-host method. +type RemoveHostPayload struct { + // ID of the host to remove. + HostID *string +} + +// UpdateDatabasePayload is the payload type of the control-plane service +// update-database method. +type UpdateDatabasePayload struct { + // ID of the database to update. + DatabaseID *string + Request *UpdateDatabaseRequest +} + +type UpdateDatabaseRequest struct { + // The specification for the database. + Spec *DatabaseSpec +} diff --git a/api/gen/http/cli/control_plane/cli.go b/api/gen/http/cli/control_plane/cli.go new file mode 100644 index 00000000..07fc6ec7 --- /dev/null +++ b/api/gen/http/cli/control_plane/cli.go @@ -0,0 +1,1084 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// control-plane HTTP client CLI support package +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package cli + +import ( + "flag" + "fmt" + "net/http" + "os" + + controlplanec "github.com/pgEdge/control-plane/api/gen/http/control_plane/client" + goahttp "goa.design/goa/v3/http" + goa "goa.design/goa/v3/pkg" +) + +// UsageCommands returns the set of commands and sub-commands using the format +// +// command (subcommand1|subcommand2|...) +func UsageCommands() string { + return `control-plane (inspect-cluster|list-hosts|inspect-host|remove-host|list-databases|create-database|inspect-database|update-database|delete-database) +` +} + +// UsageExamples produces an example of a valid invocation of the CLI tool. +func UsageExamples() string { + return os.Args[0] + ` control-plane inspect-cluster` + "\n" + + "" +} + +// ParseEndpoint returns the endpoint and payload as specified on the command +// line. +func ParseEndpoint( + scheme, host string, + doer goahttp.Doer, + enc func(*http.Request) goahttp.Encoder, + dec func(*http.Response) goahttp.Decoder, + restore bool, +) (goa.Endpoint, any, error) { + var ( + controlPlaneFlags = flag.NewFlagSet("control-plane", flag.ContinueOnError) + + controlPlaneInspectClusterFlags = flag.NewFlagSet("inspect-cluster", flag.ExitOnError) + + controlPlaneListHostsFlags = flag.NewFlagSet("list-hosts", flag.ExitOnError) + + controlPlaneInspectHostFlags = flag.NewFlagSet("inspect-host", flag.ExitOnError) + controlPlaneInspectHostHostIDFlag = controlPlaneInspectHostFlags.String("host-id", "REQUIRED", "ID of the host to inspect.") + + controlPlaneRemoveHostFlags = flag.NewFlagSet("remove-host", flag.ExitOnError) + controlPlaneRemoveHostHostIDFlag = controlPlaneRemoveHostFlags.String("host-id", "REQUIRED", "ID of the host to remove.") + + controlPlaneListDatabasesFlags = flag.NewFlagSet("list-databases", flag.ExitOnError) + + controlPlaneCreateDatabaseFlags = flag.NewFlagSet("create-database", flag.ExitOnError) + controlPlaneCreateDatabaseBodyFlag = controlPlaneCreateDatabaseFlags.String("body", "REQUIRED", "") + + controlPlaneInspectDatabaseFlags = flag.NewFlagSet("inspect-database", flag.ExitOnError) + controlPlaneInspectDatabaseDatabaseIDFlag = controlPlaneInspectDatabaseFlags.String("database-id", "REQUIRED", "ID of the database to inspect.") + + controlPlaneUpdateDatabaseFlags = flag.NewFlagSet("update-database", flag.ExitOnError) + controlPlaneUpdateDatabaseBodyFlag = controlPlaneUpdateDatabaseFlags.String("body", "REQUIRED", "") + controlPlaneUpdateDatabaseDatabaseIDFlag = controlPlaneUpdateDatabaseFlags.String("database-id", "REQUIRED", "ID of the database to update.") + + controlPlaneDeleteDatabaseFlags = flag.NewFlagSet("delete-database", flag.ExitOnError) + controlPlaneDeleteDatabaseDatabaseIDFlag = controlPlaneDeleteDatabaseFlags.String("database-id", "REQUIRED", "ID of the database to delete.") + ) + controlPlaneFlags.Usage = controlPlaneUsage + controlPlaneInspectClusterFlags.Usage = controlPlaneInspectClusterUsage + controlPlaneListHostsFlags.Usage = controlPlaneListHostsUsage + controlPlaneInspectHostFlags.Usage = controlPlaneInspectHostUsage + controlPlaneRemoveHostFlags.Usage = controlPlaneRemoveHostUsage + controlPlaneListDatabasesFlags.Usage = controlPlaneListDatabasesUsage + controlPlaneCreateDatabaseFlags.Usage = controlPlaneCreateDatabaseUsage + controlPlaneInspectDatabaseFlags.Usage = controlPlaneInspectDatabaseUsage + controlPlaneUpdateDatabaseFlags.Usage = controlPlaneUpdateDatabaseUsage + controlPlaneDeleteDatabaseFlags.Usage = controlPlaneDeleteDatabaseUsage + + if err := flag.CommandLine.Parse(os.Args[1:]); err != nil { + return nil, nil, err + } + + if flag.NArg() < 2 { // two non flag args are required: SERVICE and ENDPOINT (aka COMMAND) + return nil, nil, fmt.Errorf("not enough arguments") + } + + var ( + svcn string + svcf *flag.FlagSet + ) + { + svcn = flag.Arg(0) + switch svcn { + case "control-plane": + svcf = controlPlaneFlags + default: + return nil, nil, fmt.Errorf("unknown service %q", svcn) + } + } + if err := svcf.Parse(flag.Args()[1:]); err != nil { + return nil, nil, err + } + + var ( + epn string + epf *flag.FlagSet + ) + { + epn = svcf.Arg(0) + switch svcn { + case "control-plane": + switch epn { + case "inspect-cluster": + epf = controlPlaneInspectClusterFlags + + case "list-hosts": + epf = controlPlaneListHostsFlags + + case "inspect-host": + epf = controlPlaneInspectHostFlags + + case "remove-host": + epf = controlPlaneRemoveHostFlags + + case "list-databases": + epf = controlPlaneListDatabasesFlags + + case "create-database": + epf = controlPlaneCreateDatabaseFlags + + case "inspect-database": + epf = controlPlaneInspectDatabaseFlags + + case "update-database": + epf = controlPlaneUpdateDatabaseFlags + + case "delete-database": + epf = controlPlaneDeleteDatabaseFlags + + } + + } + } + if epf == nil { + return nil, nil, fmt.Errorf("unknown %q endpoint %q", svcn, epn) + } + + // Parse endpoint flags if any + if svcf.NArg() > 1 { + if err := epf.Parse(svcf.Args()[1:]); err != nil { + return nil, nil, err + } + } + + var ( + data any + endpoint goa.Endpoint + err error + ) + { + switch svcn { + case "control-plane": + c := controlplanec.NewClient(scheme, host, doer, enc, dec, restore) + switch epn { + case "inspect-cluster": + endpoint = c.InspectCluster() + case "list-hosts": + endpoint = c.ListHosts() + case "inspect-host": + endpoint = c.InspectHost() + data, err = controlplanec.BuildInspectHostPayload(*controlPlaneInspectHostHostIDFlag) + case "remove-host": + endpoint = c.RemoveHost() + data, err = controlplanec.BuildRemoveHostPayload(*controlPlaneRemoveHostHostIDFlag) + case "list-databases": + endpoint = c.ListDatabases() + case "create-database": + endpoint = c.CreateDatabase() + data, err = controlplanec.BuildCreateDatabasePayload(*controlPlaneCreateDatabaseBodyFlag) + case "inspect-database": + endpoint = c.InspectDatabase() + data, err = controlplanec.BuildInspectDatabasePayload(*controlPlaneInspectDatabaseDatabaseIDFlag) + case "update-database": + endpoint = c.UpdateDatabase() + data, err = controlplanec.BuildUpdateDatabasePayload(*controlPlaneUpdateDatabaseBodyFlag, *controlPlaneUpdateDatabaseDatabaseIDFlag) + case "delete-database": + endpoint = c.DeleteDatabase() + data, err = controlplanec.BuildDeleteDatabasePayload(*controlPlaneDeleteDatabaseDatabaseIDFlag) + } + } + } + if err != nil { + return nil, nil, err + } + + return endpoint, data, nil +} + +// control-planeUsage displays the usage of the control-plane command and its +// subcommands. +func controlPlaneUsage() { + fmt.Fprintf(os.Stderr, `Service is the control-plane service interface. +Usage: + %[1]s [globalflags] control-plane COMMAND [flags] + +COMMAND: + inspect-cluster: Returns information about the cluster. + list-hosts: Lists all hosts within the cluster. + inspect-host: Returns information about a particular host in the cluster. + remove-host: Removes a host from the cluster. + list-databases: Lists all databases in the cluster. + create-database: Creates a new database in the cluster. + inspect-database: Returns information about a particular database in the cluster. + update-database: Updates a database with the given specification. + delete-database: Deletes a database from the cluster. + +Additional help: + %[1]s control-plane COMMAND --help +`, os.Args[0]) +} +func controlPlaneInspectClusterUsage() { + fmt.Fprintf(os.Stderr, `%[1]s [flags] control-plane inspect-cluster + +Returns information about the cluster. + +Example: + %[1]s control-plane inspect-cluster +`, os.Args[0]) +} + +func controlPlaneListHostsUsage() { + fmt.Fprintf(os.Stderr, `%[1]s [flags] control-plane list-hosts + +Lists all hosts within the cluster. + +Example: + %[1]s control-plane list-hosts +`, os.Args[0]) +} + +func controlPlaneInspectHostUsage() { + fmt.Fprintf(os.Stderr, `%[1]s [flags] control-plane inspect-host -host-id STRING + +Returns information about a particular host in the cluster. + -host-id STRING: ID of the host to inspect. + +Example: + %[1]s control-plane inspect-host --host-id "de3b1388-1f0c-42f1-a86c-59ab72f255ec" +`, os.Args[0]) +} + +func controlPlaneRemoveHostUsage() { + fmt.Fprintf(os.Stderr, `%[1]s [flags] control-plane remove-host -host-id STRING + +Removes a host from the cluster. + -host-id STRING: ID of the host to remove. + +Example: + %[1]s control-plane remove-host --host-id "de3b1388-1f0c-42f1-a86c-59ab72f255ec" +`, os.Args[0]) +} + +func controlPlaneListDatabasesUsage() { + fmt.Fprintf(os.Stderr, `%[1]s [flags] control-plane list-databases + +Lists all databases in the cluster. + +Example: + %[1]s control-plane list-databases +`, os.Args[0]) +} + +func controlPlaneCreateDatabaseUsage() { + fmt.Fprintf(os.Stderr, `%[1]s [flags] control-plane create-database -body JSON + +Creates a new database in the cluster. + -body JSON: + +Example: + %[1]s control-plane create-database --body '{ + "id": "02f1a7db-fca8-4521-b57a-2a375c1ced51", + "spec": { + "backup_configs": [ + { + "id": "default", + "node_names": [ + "n1", + "n3" + ], + "provider": "pgbackrest", + "repositories": [ + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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" + } + ] + }, + { + "id": "default", + "node_names": [ + "n1", + "n3" + ], + "provider": "pgbackrest", + "repositories": [ + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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" + } + ] + }, + { + "id": "default", + "node_names": [ + "n1", + "n3" + ], + "provider": "pgbackrest", + "repositories": [ + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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" + } + ] + }, + { + "id": "default", + "node_names": [ + "n1", + "n3" + ], + "provider": "pgbackrest", + "repositories": [ + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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" + } + ] + } + ], + "database_name": "northwind", + "database_users": [ + { + "password": "secret", + "roles": [ + "application_read_only" + ], + "superuser": true, + "username": "admin" + }, + { + "password": "secret", + "roles": [ + "application_read_only" + ], + "superuser": true, + "username": "admin" + }, + { + "password": "secret", + "roles": [ + "application_read_only" + ], + "superuser": true, + "username": "admin" + }, + { + "password": "secret", + "roles": [ + "application_read_only" + ], + "superuser": true, + "username": "admin" + } + ], + "deletion_protection": true, + "extensions": [ + { + "name": "postgis", + "version": "1.2.3" + }, + { + "name": "postgis", + "version": "1.2.3" + }, + { + "name": "postgis", + "version": "1.2.3" + }, + { + "name": "postgis", + "version": "1.2.3" + } + ], + "features": { + "some_feature": "enabled" + }, + "nodes": [ + { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "name": "n1", + "port": 5432, + "postgres_version": "17", + "postgresql_conf": { + "max_connections": 1000 + }, + "read_replicas": { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "5ec51c55-0921-445e-9d5b-32f5fb5dfbae" + } + }, + { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "name": "n1", + "port": 5432, + "postgres_version": "17", + "postgresql_conf": { + "max_connections": 1000 + }, + "read_replicas": { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "5ec51c55-0921-445e-9d5b-32f5fb5dfbae" + } + }, + { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "name": "n1", + "port": 5432, + "postgres_version": "17", + "postgresql_conf": { + "max_connections": 1000 + }, + "read_replicas": { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "5ec51c55-0921-445e-9d5b-32f5fb5dfbae" + } + } + ], + "port": 5432, + "postgres_version": "17", + "postgresql_conf": { + "max_connections": 1000 + }, + "spock_version": "4" + }, + "tenant_id": "8210ec10-2dca-406c-ac4a-0661d2189954" + }' +`, os.Args[0]) +} + +func controlPlaneInspectDatabaseUsage() { + fmt.Fprintf(os.Stderr, `%[1]s [flags] control-plane inspect-database -database-id STRING + +Returns information about a particular database in the cluster. + -database-id STRING: ID of the database to inspect. + +Example: + %[1]s control-plane inspect-database --database-id "02f1a7db-fca8-4521-b57a-2a375c1ced51" +`, os.Args[0]) +} + +func controlPlaneUpdateDatabaseUsage() { + fmt.Fprintf(os.Stderr, `%[1]s [flags] control-plane update-database -body JSON -database-id STRING + +Updates a database with the given specification. + -body JSON: + -database-id STRING: ID of the database to update. + +Example: + %[1]s control-plane update-database --body '{ + "spec": { + "backup_configs": [ + { + "id": "default", + "node_names": [ + "n1", + "n3" + ], + "provider": "pgbackrest", + "repositories": [ + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + } + ] + }, + { + "id": "default", + "node_names": [ + "n1", + "n3" + ], + "provider": "pgbackrest", + "repositories": [ + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + } + ] + }, + { + "id": "default", + "node_names": [ + "n1", + "n3" + ], + "provider": "pgbackrest", + "repositories": [ + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + } + ] + }, + { + "id": "default", + "node_names": [ + "n1", + "n3" + ], + "provider": "pgbackrest", + "repositories": [ + { + "azure_account": "pgedge-backups", + "azure_container": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "azure_endpoint": "blob.core.usgovcloudapi.net", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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", + "base_path": "/backups", + "gcs_bucket": "pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1", + "gcs_endpoint": "localhost", + "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_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" + }, + { + "cron_expression": "0 6 * * ?", + "id": "daily-full-backup", + "type": "full" + } + ] + } + ], + "database_name": "northwind", + "database_users": [ + { + "password": "secret", + "roles": [ + "application_read_only" + ], + "superuser": true, + "username": "admin" + }, + { + "password": "secret", + "roles": [ + "application_read_only" + ], + "superuser": true, + "username": "admin" + }, + { + "password": "secret", + "roles": [ + "application_read_only" + ], + "superuser": true, + "username": "admin" + } + ], + "deletion_protection": true, + "extensions": [ + { + "name": "postgis", + "version": "1.2.3" + }, + { + "name": "postgis", + "version": "1.2.3" + }, + { + "name": "postgis", + "version": "1.2.3" + } + ], + "features": { + "some_feature": "enabled" + }, + "nodes": [ + { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "name": "n1", + "port": 5432, + "postgres_version": "17", + "postgresql_conf": { + "max_connections": 1000 + }, + "read_replicas": { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "5ec51c55-0921-445e-9d5b-32f5fb5dfbae" + } + }, + { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "name": "n1", + "port": 5432, + "postgres_version": "17", + "postgresql_conf": { + "max_connections": 1000 + }, + "read_replicas": { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "5ec51c55-0921-445e-9d5b-32f5fb5dfbae" + } + }, + { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "name": "n1", + "port": 5432, + "postgres_version": "17", + "postgresql_conf": { + "max_connections": 1000 + }, + "read_replicas": { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "5ec51c55-0921-445e-9d5b-32f5fb5dfbae" + } + }, + { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "a67cbb36-c3c3-49c9-8aac-f4a0438a883d", + "name": "n1", + "port": 5432, + "postgres_version": "17", + "postgresql_conf": { + "max_connections": 1000 + }, + "read_replicas": { + "host_id": "de3b1388-1f0c-42f1-a86c-59ab72f255ec", + "instance_id": "5ec51c55-0921-445e-9d5b-32f5fb5dfbae" + } + } + ], + "port": 5432, + "postgres_version": "17", + "postgresql_conf": { + "max_connections": 1000 + }, + "spock_version": "4" + } + }' --database-id "02f1a7db-fca8-4521-b57a-2a375c1ced51" +`, os.Args[0]) +} + +func controlPlaneDeleteDatabaseUsage() { + fmt.Fprintf(os.Stderr, `%[1]s [flags] control-plane delete-database -database-id STRING + +Deletes a database from the cluster. + -database-id STRING: ID of the database to delete. + +Example: + %[1]s control-plane delete-database --database-id "02f1a7db-fca8-4521-b57a-2a375c1ced51" +`, os.Args[0]) +} diff --git a/api/gen/http/control_plane/client/cli.go b/api/gen/http/control_plane/client/cli.go new file mode 100644 index 00000000..de484adb --- /dev/null +++ b/api/gen/http/control_plane/client/cli.go @@ -0,0 +1,116 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// control-plane HTTP client CLI support package +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package client + +import ( + "encoding/json" + "fmt" + + controlplane "github.com/pgEdge/control-plane/api/gen/control_plane" +) + +// BuildInspectHostPayload builds the payload for the control-plane +// inspect-host endpoint from CLI flags. +func BuildInspectHostPayload(controlPlaneInspectHostHostID string) (*controlplane.InspectHostPayload, error) { + var hostID string + { + hostID = controlPlaneInspectHostHostID + } + v := &controlplane.InspectHostPayload{} + v.HostID = &hostID + + return v, nil +} + +// BuildRemoveHostPayload builds the payload for the control-plane remove-host +// endpoint from CLI flags. +func BuildRemoveHostPayload(controlPlaneRemoveHostHostID string) (*controlplane.RemoveHostPayload, error) { + var hostID string + { + hostID = controlPlaneRemoveHostHostID + } + v := &controlplane.RemoveHostPayload{} + v.HostID = &hostID + + return v, nil +} + +// BuildCreateDatabasePayload builds the payload for the control-plane +// create-database endpoint from CLI flags. +func BuildCreateDatabasePayload(controlPlaneCreateDatabaseBody string) (*controlplane.CreateDatabaseRequest, error) { + var err error + var body CreateDatabaseRequestBody + { + err = json.Unmarshal([]byte(controlPlaneCreateDatabaseBody), &body) + if err != nil { + return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "'{\n \"id\": \"02f1a7db-fca8-4521-b57a-2a375c1ced51\",\n \"spec\": {\n \"backup_configs\": [\n {\n \"id\": \"default\",\n \"node_names\": [\n \"n1\",\n \"n3\"\n ],\n \"provider\": \"pgbackrest\",\n \"repositories\": [\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n },\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n }\n ],\n \"schedules\": [\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n }\n ]\n },\n {\n \"id\": \"default\",\n \"node_names\": [\n \"n1\",\n \"n3\"\n ],\n \"provider\": \"pgbackrest\",\n \"repositories\": [\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n },\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n }\n ],\n \"schedules\": [\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n }\n ]\n },\n {\n \"id\": \"default\",\n \"node_names\": [\n \"n1\",\n \"n3\"\n ],\n \"provider\": \"pgbackrest\",\n \"repositories\": [\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n },\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n }\n ],\n \"schedules\": [\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n }\n ]\n },\n {\n \"id\": \"default\",\n \"node_names\": [\n \"n1\",\n \"n3\"\n ],\n \"provider\": \"pgbackrest\",\n \"repositories\": [\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n },\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n }\n ],\n \"schedules\": [\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n }\n ]\n }\n ],\n \"database_name\": \"northwind\",\n \"database_users\": [\n {\n \"password\": \"secret\",\n \"roles\": [\n \"application_read_only\"\n ],\n \"superuser\": true,\n \"username\": \"admin\"\n },\n {\n \"password\": \"secret\",\n \"roles\": [\n \"application_read_only\"\n ],\n \"superuser\": true,\n \"username\": \"admin\"\n },\n {\n \"password\": \"secret\",\n \"roles\": [\n \"application_read_only\"\n ],\n \"superuser\": true,\n \"username\": \"admin\"\n },\n {\n \"password\": \"secret\",\n \"roles\": [\n \"application_read_only\"\n ],\n \"superuser\": true,\n \"username\": \"admin\"\n }\n ],\n \"deletion_protection\": true,\n \"extensions\": [\n {\n \"name\": \"postgis\",\n \"version\": \"1.2.3\"\n },\n {\n \"name\": \"postgis\",\n \"version\": \"1.2.3\"\n },\n {\n \"name\": \"postgis\",\n \"version\": \"1.2.3\"\n },\n {\n \"name\": \"postgis\",\n \"version\": \"1.2.3\"\n }\n ],\n \"features\": {\n \"some_feature\": \"enabled\"\n },\n \"nodes\": [\n {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"a67cbb36-c3c3-49c9-8aac-f4a0438a883d\",\n \"name\": \"n1\",\n \"port\": 5432,\n \"postgres_version\": \"17\",\n \"postgresql_conf\": {\n \"max_connections\": 1000\n },\n \"read_replicas\": {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"5ec51c55-0921-445e-9d5b-32f5fb5dfbae\"\n }\n },\n {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"a67cbb36-c3c3-49c9-8aac-f4a0438a883d\",\n \"name\": \"n1\",\n \"port\": 5432,\n \"postgres_version\": \"17\",\n \"postgresql_conf\": {\n \"max_connections\": 1000\n },\n \"read_replicas\": {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"5ec51c55-0921-445e-9d5b-32f5fb5dfbae\"\n }\n },\n {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"a67cbb36-c3c3-49c9-8aac-f4a0438a883d\",\n \"name\": \"n1\",\n \"port\": 5432,\n \"postgres_version\": \"17\",\n \"postgresql_conf\": {\n \"max_connections\": 1000\n },\n \"read_replicas\": {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"5ec51c55-0921-445e-9d5b-32f5fb5dfbae\"\n }\n }\n ],\n \"port\": 5432,\n \"postgres_version\": \"17\",\n \"postgresql_conf\": {\n \"max_connections\": 1000\n },\n \"spock_version\": \"4\"\n },\n \"tenant_id\": \"8210ec10-2dca-406c-ac4a-0661d2189954\"\n }'") + } + } + v := &controlplane.CreateDatabaseRequest{ + ID: body.ID, + TenantID: body.TenantID, + } + if body.Spec != nil { + v.Spec = marshalDatabaseSpecRequestBodyToControlplaneDatabaseSpec(body.Spec) + } + + return v, nil +} + +// BuildInspectDatabasePayload builds the payload for the control-plane +// inspect-database endpoint from CLI flags. +func BuildInspectDatabasePayload(controlPlaneInspectDatabaseDatabaseID string) (*controlplane.InspectDatabasePayload, error) { + var databaseID string + { + databaseID = controlPlaneInspectDatabaseDatabaseID + } + v := &controlplane.InspectDatabasePayload{} + v.DatabaseID = &databaseID + + return v, nil +} + +// BuildUpdateDatabasePayload builds the payload for the control-plane +// update-database endpoint from CLI flags. +func BuildUpdateDatabasePayload(controlPlaneUpdateDatabaseBody string, controlPlaneUpdateDatabaseDatabaseID string) (*controlplane.UpdateDatabasePayload, error) { + var err error + var body UpdateDatabaseRequestBody + { + err = json.Unmarshal([]byte(controlPlaneUpdateDatabaseBody), &body) + if err != nil { + return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "'{\n \"spec\": {\n \"backup_configs\": [\n {\n \"id\": \"default\",\n \"node_names\": [\n \"n1\",\n \"n3\"\n ],\n \"provider\": \"pgbackrest\",\n \"repositories\": [\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n },\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n },\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n }\n ],\n \"schedules\": [\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n }\n ]\n },\n {\n \"id\": \"default\",\n \"node_names\": [\n \"n1\",\n \"n3\"\n ],\n \"provider\": \"pgbackrest\",\n \"repositories\": [\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n },\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n },\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n }\n ],\n \"schedules\": [\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n }\n ]\n },\n {\n \"id\": \"default\",\n \"node_names\": [\n \"n1\",\n \"n3\"\n ],\n \"provider\": \"pgbackrest\",\n \"repositories\": [\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n },\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n },\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n }\n ],\n \"schedules\": [\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n }\n ]\n },\n {\n \"id\": \"default\",\n \"node_names\": [\n \"n1\",\n \"n3\"\n ],\n \"provider\": \"pgbackrest\",\n \"repositories\": [\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n },\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n },\n {\n \"azure_account\": \"pgedge-backups\",\n \"azure_container\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"azure_endpoint\": \"blob.core.usgovcloudapi.net\",\n \"base_path\": \"/backups\",\n \"gcs_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"gcs_endpoint\": \"localhost\",\n \"id\": \"f6b84a99-5e91-4203-be1e-131fe82e5984\",\n \"retention_full\": 2,\n \"retention_full_type\": \"count\",\n \"s3_bucket\": \"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1\",\n \"s3_endpoint\": \"s3.us-east-1.amazonaws.com\",\n \"s3_region\": \"us-east-1\",\n \"type\": \"s3\"\n }\n ],\n \"schedules\": [\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n },\n {\n \"cron_expression\": \"0 6 * * ?\",\n \"id\": \"daily-full-backup\",\n \"type\": \"full\"\n }\n ]\n }\n ],\n \"database_name\": \"northwind\",\n \"database_users\": [\n {\n \"password\": \"secret\",\n \"roles\": [\n \"application_read_only\"\n ],\n \"superuser\": true,\n \"username\": \"admin\"\n },\n {\n \"password\": \"secret\",\n \"roles\": [\n \"application_read_only\"\n ],\n \"superuser\": true,\n \"username\": \"admin\"\n },\n {\n \"password\": \"secret\",\n \"roles\": [\n \"application_read_only\"\n ],\n \"superuser\": true,\n \"username\": \"admin\"\n }\n ],\n \"deletion_protection\": true,\n \"extensions\": [\n {\n \"name\": \"postgis\",\n \"version\": \"1.2.3\"\n },\n {\n \"name\": \"postgis\",\n \"version\": \"1.2.3\"\n },\n {\n \"name\": \"postgis\",\n \"version\": \"1.2.3\"\n }\n ],\n \"features\": {\n \"some_feature\": \"enabled\"\n },\n \"nodes\": [\n {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"a67cbb36-c3c3-49c9-8aac-f4a0438a883d\",\n \"name\": \"n1\",\n \"port\": 5432,\n \"postgres_version\": \"17\",\n \"postgresql_conf\": {\n \"max_connections\": 1000\n },\n \"read_replicas\": {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"5ec51c55-0921-445e-9d5b-32f5fb5dfbae\"\n }\n },\n {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"a67cbb36-c3c3-49c9-8aac-f4a0438a883d\",\n \"name\": \"n1\",\n \"port\": 5432,\n \"postgres_version\": \"17\",\n \"postgresql_conf\": {\n \"max_connections\": 1000\n },\n \"read_replicas\": {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"5ec51c55-0921-445e-9d5b-32f5fb5dfbae\"\n }\n },\n {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"a67cbb36-c3c3-49c9-8aac-f4a0438a883d\",\n \"name\": \"n1\",\n \"port\": 5432,\n \"postgres_version\": \"17\",\n \"postgresql_conf\": {\n \"max_connections\": 1000\n },\n \"read_replicas\": {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"5ec51c55-0921-445e-9d5b-32f5fb5dfbae\"\n }\n },\n {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"a67cbb36-c3c3-49c9-8aac-f4a0438a883d\",\n \"name\": \"n1\",\n \"port\": 5432,\n \"postgres_version\": \"17\",\n \"postgresql_conf\": {\n \"max_connections\": 1000\n },\n \"read_replicas\": {\n \"host_id\": \"de3b1388-1f0c-42f1-a86c-59ab72f255ec\",\n \"instance_id\": \"5ec51c55-0921-445e-9d5b-32f5fb5dfbae\"\n }\n }\n ],\n \"port\": 5432,\n \"postgres_version\": \"17\",\n \"postgresql_conf\": {\n \"max_connections\": 1000\n },\n \"spock_version\": \"4\"\n }\n }'") + } + } + var databaseID string + { + databaseID = controlPlaneUpdateDatabaseDatabaseID + } + v := &controlplane.UpdateDatabaseRequest{} + if body.Spec != nil { + v.Spec = marshalDatabaseSpecRequestBodyRequestBodyToControlplaneDatabaseSpec(body.Spec) + } + res := &controlplane.UpdateDatabasePayload{ + Request: v, + } + res.DatabaseID = &databaseID + + return res, nil +} + +// BuildDeleteDatabasePayload builds the payload for the control-plane +// delete-database endpoint from CLI flags. +func BuildDeleteDatabasePayload(controlPlaneDeleteDatabaseDatabaseID string) (*controlplane.DeleteDatabasePayload, error) { + var databaseID string + { + databaseID = controlPlaneDeleteDatabaseDatabaseID + } + v := &controlplane.DeleteDatabasePayload{} + v.DatabaseID = &databaseID + + return v, nil +} diff --git a/api/gen/http/control_plane/client/client.go b/api/gen/http/control_plane/client/client.go new file mode 100644 index 00000000..33f58c8a --- /dev/null +++ b/api/gen/http/control_plane/client/client.go @@ -0,0 +1,273 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// control-plane client HTTP transport +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package client + +import ( + "context" + "net/http" + + goahttp "goa.design/goa/v3/http" + goa "goa.design/goa/v3/pkg" +) + +// Client lists the control-plane service endpoint HTTP clients. +type Client struct { + // InspectCluster Doer is the HTTP client used to make requests to the + // inspect-cluster endpoint. + InspectClusterDoer goahttp.Doer + + // ListHosts Doer is the HTTP client used to make requests to the list-hosts + // endpoint. + ListHostsDoer goahttp.Doer + + // InspectHost Doer is the HTTP client used to make requests to the + // inspect-host endpoint. + InspectHostDoer goahttp.Doer + + // RemoveHost Doer is the HTTP client used to make requests to the remove-host + // endpoint. + RemoveHostDoer goahttp.Doer + + // ListDatabases Doer is the HTTP client used to make requests to the + // list-databases endpoint. + ListDatabasesDoer goahttp.Doer + + // CreateDatabase Doer is the HTTP client used to make requests to the + // create-database endpoint. + CreateDatabaseDoer goahttp.Doer + + // InspectDatabase Doer is the HTTP client used to make requests to the + // inspect-database endpoint. + InspectDatabaseDoer goahttp.Doer + + // UpdateDatabase Doer is the HTTP client used to make requests to the + // update-database endpoint. + UpdateDatabaseDoer goahttp.Doer + + // DeleteDatabase Doer is the HTTP client used to make requests to the + // delete-database endpoint. + DeleteDatabaseDoer goahttp.Doer + + // RestoreResponseBody controls whether the response bodies are reset after + // decoding so they can be read again. + RestoreResponseBody bool + + scheme string + host string + encoder func(*http.Request) goahttp.Encoder + decoder func(*http.Response) goahttp.Decoder +} + +// NewClient instantiates HTTP clients for all the control-plane service +// servers. +func NewClient( + scheme string, + host string, + doer goahttp.Doer, + enc func(*http.Request) goahttp.Encoder, + dec func(*http.Response) goahttp.Decoder, + restoreBody bool, +) *Client { + return &Client{ + InspectClusterDoer: doer, + ListHostsDoer: doer, + InspectHostDoer: doer, + RemoveHostDoer: doer, + ListDatabasesDoer: doer, + CreateDatabaseDoer: doer, + InspectDatabaseDoer: doer, + UpdateDatabaseDoer: doer, + DeleteDatabaseDoer: doer, + RestoreResponseBody: restoreBody, + scheme: scheme, + host: host, + decoder: dec, + encoder: enc, + } +} + +// InspectCluster returns an endpoint that makes HTTP requests to the +// control-plane service inspect-cluster server. +func (c *Client) InspectCluster() goa.Endpoint { + var ( + decodeResponse = DecodeInspectClusterResponse(c.decoder, c.RestoreResponseBody) + ) + return func(ctx context.Context, v any) (any, error) { + req, err := c.BuildInspectClusterRequest(ctx, v) + if err != nil { + return nil, err + } + resp, err := c.InspectClusterDoer.Do(req) + if err != nil { + return nil, goahttp.ErrRequestError("control-plane", "inspect-cluster", err) + } + return decodeResponse(resp) + } +} + +// ListHosts returns an endpoint that makes HTTP requests to the control-plane +// service list-hosts server. +func (c *Client) ListHosts() goa.Endpoint { + var ( + decodeResponse = DecodeListHostsResponse(c.decoder, c.RestoreResponseBody) + ) + return func(ctx context.Context, v any) (any, error) { + req, err := c.BuildListHostsRequest(ctx, v) + if err != nil { + return nil, err + } + resp, err := c.ListHostsDoer.Do(req) + if err != nil { + return nil, goahttp.ErrRequestError("control-plane", "list-hosts", err) + } + return decodeResponse(resp) + } +} + +// InspectHost returns an endpoint that makes HTTP requests to the +// control-plane service inspect-host server. +func (c *Client) InspectHost() goa.Endpoint { + var ( + decodeResponse = DecodeInspectHostResponse(c.decoder, c.RestoreResponseBody) + ) + return func(ctx context.Context, v any) (any, error) { + req, err := c.BuildInspectHostRequest(ctx, v) + if err != nil { + return nil, err + } + resp, err := c.InspectHostDoer.Do(req) + if err != nil { + return nil, goahttp.ErrRequestError("control-plane", "inspect-host", err) + } + return decodeResponse(resp) + } +} + +// RemoveHost returns an endpoint that makes HTTP requests to the control-plane +// service remove-host server. +func (c *Client) RemoveHost() goa.Endpoint { + var ( + decodeResponse = DecodeRemoveHostResponse(c.decoder, c.RestoreResponseBody) + ) + return func(ctx context.Context, v any) (any, error) { + req, err := c.BuildRemoveHostRequest(ctx, v) + if err != nil { + return nil, err + } + resp, err := c.RemoveHostDoer.Do(req) + if err != nil { + return nil, goahttp.ErrRequestError("control-plane", "remove-host", err) + } + return decodeResponse(resp) + } +} + +// ListDatabases returns an endpoint that makes HTTP requests to the +// control-plane service list-databases server. +func (c *Client) ListDatabases() goa.Endpoint { + var ( + decodeResponse = DecodeListDatabasesResponse(c.decoder, c.RestoreResponseBody) + ) + return func(ctx context.Context, v any) (any, error) { + req, err := c.BuildListDatabasesRequest(ctx, v) + if err != nil { + return nil, err + } + resp, err := c.ListDatabasesDoer.Do(req) + if err != nil { + return nil, goahttp.ErrRequestError("control-plane", "list-databases", err) + } + return decodeResponse(resp) + } +} + +// CreateDatabase returns an endpoint that makes HTTP requests to the +// control-plane service create-database server. +func (c *Client) CreateDatabase() goa.Endpoint { + var ( + encodeRequest = EncodeCreateDatabaseRequest(c.encoder) + decodeResponse = DecodeCreateDatabaseResponse(c.decoder, c.RestoreResponseBody) + ) + return func(ctx context.Context, v any) (any, error) { + req, err := c.BuildCreateDatabaseRequest(ctx, v) + if err != nil { + return nil, err + } + err = encodeRequest(req, v) + if err != nil { + return nil, err + } + resp, err := c.CreateDatabaseDoer.Do(req) + if err != nil { + return nil, goahttp.ErrRequestError("control-plane", "create-database", err) + } + return decodeResponse(resp) + } +} + +// InspectDatabase returns an endpoint that makes HTTP requests to the +// control-plane service inspect-database server. +func (c *Client) InspectDatabase() goa.Endpoint { + var ( + decodeResponse = DecodeInspectDatabaseResponse(c.decoder, c.RestoreResponseBody) + ) + return func(ctx context.Context, v any) (any, error) { + req, err := c.BuildInspectDatabaseRequest(ctx, v) + if err != nil { + return nil, err + } + resp, err := c.InspectDatabaseDoer.Do(req) + if err != nil { + return nil, goahttp.ErrRequestError("control-plane", "inspect-database", err) + } + return decodeResponse(resp) + } +} + +// UpdateDatabase returns an endpoint that makes HTTP requests to the +// control-plane service update-database server. +func (c *Client) UpdateDatabase() goa.Endpoint { + var ( + encodeRequest = EncodeUpdateDatabaseRequest(c.encoder) + decodeResponse = DecodeUpdateDatabaseResponse(c.decoder, c.RestoreResponseBody) + ) + return func(ctx context.Context, v any) (any, error) { + req, err := c.BuildUpdateDatabaseRequest(ctx, v) + if err != nil { + return nil, err + } + err = encodeRequest(req, v) + if err != nil { + return nil, err + } + resp, err := c.UpdateDatabaseDoer.Do(req) + if err != nil { + return nil, goahttp.ErrRequestError("control-plane", "update-database", err) + } + return decodeResponse(resp) + } +} + +// DeleteDatabase returns an endpoint that makes HTTP requests to the +// control-plane service delete-database server. +func (c *Client) DeleteDatabase() goa.Endpoint { + var ( + decodeResponse = DecodeDeleteDatabaseResponse(c.decoder, c.RestoreResponseBody) + ) + return func(ctx context.Context, v any) (any, error) { + req, err := c.BuildDeleteDatabaseRequest(ctx, v) + if err != nil { + return nil, err + } + resp, err := c.DeleteDatabaseDoer.Do(req) + if err != nil { + return nil, goahttp.ErrRequestError("control-plane", "delete-database", err) + } + return decodeResponse(resp) + } +} diff --git a/api/gen/http/control_plane/client/encode_decode.go b/api/gen/http/control_plane/client/encode_decode.go new file mode 100644 index 00000000..10e9c8a6 --- /dev/null +++ b/api/gen/http/control_plane/client/encode_decode.go @@ -0,0 +1,2117 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// control-plane HTTP client encoders and decoders +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package client + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + + controlplane "github.com/pgEdge/control-plane/api/gen/control_plane" + goahttp "goa.design/goa/v3/http" + goa "goa.design/goa/v3/pkg" +) + +// BuildInspectClusterRequest instantiates a HTTP request object with method +// and path set to call the "control-plane" service "inspect-cluster" endpoint +func (c *Client) BuildInspectClusterRequest(ctx context.Context, v any) (*http.Request, error) { + u := &url.URL{Scheme: c.scheme, Host: c.host, Path: InspectClusterControlPlanePath()} + req, err := http.NewRequest("GET", u.String(), nil) + if err != nil { + return nil, goahttp.ErrInvalidURL("control-plane", "inspect-cluster", u.String(), err) + } + if ctx != nil { + req = req.WithContext(ctx) + } + + return req, nil +} + +// DecodeInspectClusterResponse returns a decoder for responses returned by the +// control-plane inspect-cluster endpoint. restoreBody controls whether the +// response body should be restored after having been read. +func DecodeInspectClusterResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (any, error) { + return func(resp *http.Response) (any, error) { + if restoreBody { + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + defer func() { + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + }() + } else { + defer resp.Body.Close() + } + switch resp.StatusCode { + case http.StatusOK: + var ( + body InspectClusterResponseBody + err error + ) + err = decoder(resp).Decode(&body) + if err != nil { + return nil, goahttp.ErrDecodingError("control-plane", "inspect-cluster", err) + } + err = ValidateInspectClusterResponseBody(&body) + if err != nil { + return nil, goahttp.ErrValidationError("control-plane", "inspect-cluster", err) + } + res := NewInspectClusterClusterOK(&body) + return res, nil + default: + body, _ := io.ReadAll(resp.Body) + return nil, goahttp.ErrInvalidResponse("control-plane", "inspect-cluster", resp.StatusCode, string(body)) + } + } +} + +// BuildListHostsRequest instantiates a HTTP request object with method and +// path set to call the "control-plane" service "list-hosts" endpoint +func (c *Client) BuildListHostsRequest(ctx context.Context, v any) (*http.Request, error) { + u := &url.URL{Scheme: c.scheme, Host: c.host, Path: ListHostsControlPlanePath()} + req, err := http.NewRequest("GET", u.String(), nil) + if err != nil { + return nil, goahttp.ErrInvalidURL("control-plane", "list-hosts", u.String(), err) + } + if ctx != nil { + req = req.WithContext(ctx) + } + + return req, nil +} + +// DecodeListHostsResponse returns a decoder for responses returned by the +// control-plane list-hosts endpoint. restoreBody controls whether the response +// body should be restored after having been read. +func DecodeListHostsResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (any, error) { + return func(resp *http.Response) (any, error) { + if restoreBody { + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + defer func() { + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + }() + } else { + defer resp.Body.Close() + } + switch resp.StatusCode { + case http.StatusOK: + var ( + body ListHostsResponseBody + err error + ) + err = decoder(resp).Decode(&body) + if err != nil { + return nil, goahttp.ErrDecodingError("control-plane", "list-hosts", err) + } + for _, e := range body { + if e != nil { + if err2 := ValidateHostResponse(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + if err != nil { + return nil, goahttp.ErrValidationError("control-plane", "list-hosts", err) + } + res := NewListHostsHostOK(body) + return res, nil + default: + body, _ := io.ReadAll(resp.Body) + return nil, goahttp.ErrInvalidResponse("control-plane", "list-hosts", resp.StatusCode, string(body)) + } + } +} + +// BuildInspectHostRequest instantiates a HTTP request object with method and +// path set to call the "control-plane" service "inspect-host" endpoint +func (c *Client) BuildInspectHostRequest(ctx context.Context, v any) (*http.Request, error) { + var ( + hostID string + ) + { + p, ok := v.(*controlplane.InspectHostPayload) + if !ok { + return nil, goahttp.ErrInvalidType("control-plane", "inspect-host", "*controlplane.InspectHostPayload", v) + } + if p.HostID != nil { + hostID = *p.HostID + } + } + u := &url.URL{Scheme: c.scheme, Host: c.host, Path: InspectHostControlPlanePath(hostID)} + req, err := http.NewRequest("GET", u.String(), nil) + if err != nil { + return nil, goahttp.ErrInvalidURL("control-plane", "inspect-host", u.String(), err) + } + if ctx != nil { + req = req.WithContext(ctx) + } + + return req, nil +} + +// DecodeInspectHostResponse returns a decoder for responses returned by the +// control-plane inspect-host endpoint. restoreBody controls whether the +// response body should be restored after having been read. +func DecodeInspectHostResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (any, error) { + return func(resp *http.Response) (any, error) { + if restoreBody { + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + defer func() { + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + }() + } else { + defer resp.Body.Close() + } + switch resp.StatusCode { + case http.StatusOK: + var ( + body InspectHostResponseBody + err error + ) + err = decoder(resp).Decode(&body) + if err != nil { + return nil, goahttp.ErrDecodingError("control-plane", "inspect-host", err) + } + err = ValidateInspectHostResponseBody(&body) + if err != nil { + return nil, goahttp.ErrValidationError("control-plane", "inspect-host", err) + } + res := NewInspectHostHostOK(&body) + return res, nil + default: + body, _ := io.ReadAll(resp.Body) + return nil, goahttp.ErrInvalidResponse("control-plane", "inspect-host", resp.StatusCode, string(body)) + } + } +} + +// BuildRemoveHostRequest instantiates a HTTP request object with method and +// path set to call the "control-plane" service "remove-host" endpoint +func (c *Client) BuildRemoveHostRequest(ctx context.Context, v any) (*http.Request, error) { + var ( + hostID string + ) + { + p, ok := v.(*controlplane.RemoveHostPayload) + if !ok { + return nil, goahttp.ErrInvalidType("control-plane", "remove-host", "*controlplane.RemoveHostPayload", v) + } + if p.HostID != nil { + hostID = *p.HostID + } + } + u := &url.URL{Scheme: c.scheme, Host: c.host, Path: RemoveHostControlPlanePath(hostID)} + req, err := http.NewRequest("DELETE", u.String(), nil) + if err != nil { + return nil, goahttp.ErrInvalidURL("control-plane", "remove-host", u.String(), err) + } + if ctx != nil { + req = req.WithContext(ctx) + } + + return req, nil +} + +// DecodeRemoveHostResponse returns a decoder for responses returned by the +// control-plane remove-host endpoint. restoreBody controls whether the +// response body should be restored after having been read. +func DecodeRemoveHostResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (any, error) { + return func(resp *http.Response) (any, error) { + if restoreBody { + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + defer func() { + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + }() + } else { + defer resp.Body.Close() + } + switch resp.StatusCode { + case http.StatusNoContent: + return nil, nil + default: + body, _ := io.ReadAll(resp.Body) + return nil, goahttp.ErrInvalidResponse("control-plane", "remove-host", resp.StatusCode, string(body)) + } + } +} + +// BuildListDatabasesRequest instantiates a HTTP request object with method and +// path set to call the "control-plane" service "list-databases" endpoint +func (c *Client) BuildListDatabasesRequest(ctx context.Context, v any) (*http.Request, error) { + u := &url.URL{Scheme: c.scheme, Host: c.host, Path: ListDatabasesControlPlanePath()} + req, err := http.NewRequest("GET", u.String(), nil) + if err != nil { + return nil, goahttp.ErrInvalidURL("control-plane", "list-databases", u.String(), err) + } + if ctx != nil { + req = req.WithContext(ctx) + } + + return req, nil +} + +// DecodeListDatabasesResponse returns a decoder for responses returned by the +// control-plane list-databases endpoint. restoreBody controls whether the +// response body should be restored after having been read. +func DecodeListDatabasesResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (any, error) { + return func(resp *http.Response) (any, error) { + if restoreBody { + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + defer func() { + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + }() + } else { + defer resp.Body.Close() + } + switch resp.StatusCode { + case http.StatusOK: + var ( + body ListDatabasesResponseBody + err error + ) + err = decoder(resp).Decode(&body) + if err != nil { + return nil, goahttp.ErrDecodingError("control-plane", "list-databases", err) + } + for _, e := range body { + if e != nil { + if err2 := ValidateDatabaseResponse(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + if err != nil { + return nil, goahttp.ErrValidationError("control-plane", "list-databases", err) + } + res := NewListDatabasesDatabaseOK(body) + return res, nil + default: + body, _ := io.ReadAll(resp.Body) + return nil, goahttp.ErrInvalidResponse("control-plane", "list-databases", resp.StatusCode, string(body)) + } + } +} + +// BuildCreateDatabaseRequest instantiates a HTTP request object with method +// and path set to call the "control-plane" service "create-database" endpoint +func (c *Client) BuildCreateDatabaseRequest(ctx context.Context, v any) (*http.Request, error) { + u := &url.URL{Scheme: c.scheme, Host: c.host, Path: CreateDatabaseControlPlanePath()} + req, err := http.NewRequest("POST", u.String(), nil) + if err != nil { + return nil, goahttp.ErrInvalidURL("control-plane", "create-database", u.String(), err) + } + if ctx != nil { + req = req.WithContext(ctx) + } + + return req, nil +} + +// EncodeCreateDatabaseRequest returns an encoder for requests sent to the +// control-plane create-database server. +func EncodeCreateDatabaseRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, any) error { + return func(req *http.Request, v any) error { + p, ok := v.(*controlplane.CreateDatabaseRequest) + if !ok { + return goahttp.ErrInvalidType("control-plane", "create-database", "*controlplane.CreateDatabaseRequest", v) + } + body := NewCreateDatabaseRequestBody(p) + if err := encoder(req).Encode(&body); err != nil { + return goahttp.ErrEncodingError("control-plane", "create-database", err) + } + return nil + } +} + +// DecodeCreateDatabaseResponse returns a decoder for responses returned by the +// control-plane create-database endpoint. restoreBody controls whether the +// response body should be restored after having been read. +func DecodeCreateDatabaseResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (any, error) { + return func(resp *http.Response) (any, error) { + if restoreBody { + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + defer func() { + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + }() + } else { + defer resp.Body.Close() + } + switch resp.StatusCode { + case http.StatusOK: + var ( + body CreateDatabaseResponseBody + err error + ) + err = decoder(resp).Decode(&body) + if err != nil { + return nil, goahttp.ErrDecodingError("control-plane", "create-database", err) + } + err = ValidateCreateDatabaseResponseBody(&body) + if err != nil { + return nil, goahttp.ErrValidationError("control-plane", "create-database", err) + } + res := NewCreateDatabaseDatabaseOK(&body) + return res, nil + default: + body, _ := io.ReadAll(resp.Body) + return nil, goahttp.ErrInvalidResponse("control-plane", "create-database", resp.StatusCode, string(body)) + } + } +} + +// BuildInspectDatabaseRequest instantiates a HTTP request object with method +// and path set to call the "control-plane" service "inspect-database" endpoint +func (c *Client) BuildInspectDatabaseRequest(ctx context.Context, v any) (*http.Request, error) { + var ( + databaseID string + ) + { + p, ok := v.(*controlplane.InspectDatabasePayload) + if !ok { + return nil, goahttp.ErrInvalidType("control-plane", "inspect-database", "*controlplane.InspectDatabasePayload", v) + } + if p.DatabaseID != nil { + databaseID = *p.DatabaseID + } + } + u := &url.URL{Scheme: c.scheme, Host: c.host, Path: InspectDatabaseControlPlanePath(databaseID)} + req, err := http.NewRequest("GET", u.String(), nil) + if err != nil { + return nil, goahttp.ErrInvalidURL("control-plane", "inspect-database", u.String(), err) + } + if ctx != nil { + req = req.WithContext(ctx) + } + + return req, nil +} + +// DecodeInspectDatabaseResponse returns a decoder for responses returned by +// the control-plane inspect-database endpoint. restoreBody controls whether +// the response body should be restored after having been read. +func DecodeInspectDatabaseResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (any, error) { + return func(resp *http.Response) (any, error) { + if restoreBody { + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + defer func() { + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + }() + } else { + defer resp.Body.Close() + } + switch resp.StatusCode { + case http.StatusOK: + var ( + body InspectDatabaseResponseBody + err error + ) + err = decoder(resp).Decode(&body) + if err != nil { + return nil, goahttp.ErrDecodingError("control-plane", "inspect-database", err) + } + err = ValidateInspectDatabaseResponseBody(&body) + if err != nil { + return nil, goahttp.ErrValidationError("control-plane", "inspect-database", err) + } + res := NewInspectDatabaseDatabaseOK(&body) + return res, nil + default: + body, _ := io.ReadAll(resp.Body) + return nil, goahttp.ErrInvalidResponse("control-plane", "inspect-database", resp.StatusCode, string(body)) + } + } +} + +// BuildUpdateDatabaseRequest instantiates a HTTP request object with method +// and path set to call the "control-plane" service "update-database" endpoint +func (c *Client) BuildUpdateDatabaseRequest(ctx context.Context, v any) (*http.Request, error) { + var ( + databaseID string + ) + { + p, ok := v.(*controlplane.UpdateDatabasePayload) + if !ok { + return nil, goahttp.ErrInvalidType("control-plane", "update-database", "*controlplane.UpdateDatabasePayload", v) + } + if p.DatabaseID != nil { + databaseID = *p.DatabaseID + } + } + u := &url.URL{Scheme: c.scheme, Host: c.host, Path: UpdateDatabaseControlPlanePath(databaseID)} + req, err := http.NewRequest("POST", u.String(), nil) + if err != nil { + return nil, goahttp.ErrInvalidURL("control-plane", "update-database", u.String(), err) + } + if ctx != nil { + req = req.WithContext(ctx) + } + + return req, nil +} + +// EncodeUpdateDatabaseRequest returns an encoder for requests sent to the +// control-plane update-database server. +func EncodeUpdateDatabaseRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, any) error { + return func(req *http.Request, v any) error { + p, ok := v.(*controlplane.UpdateDatabasePayload) + if !ok { + return goahttp.ErrInvalidType("control-plane", "update-database", "*controlplane.UpdateDatabasePayload", v) + } + body := NewUpdateDatabaseRequestBody(p) + if err := encoder(req).Encode(&body); err != nil { + return goahttp.ErrEncodingError("control-plane", "update-database", err) + } + return nil + } +} + +// DecodeUpdateDatabaseResponse returns a decoder for responses returned by the +// control-plane update-database endpoint. restoreBody controls whether the +// response body should be restored after having been read. +func DecodeUpdateDatabaseResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (any, error) { + return func(resp *http.Response) (any, error) { + if restoreBody { + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + defer func() { + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + }() + } else { + defer resp.Body.Close() + } + switch resp.StatusCode { + case http.StatusOK: + var ( + body UpdateDatabaseResponseBody + err error + ) + err = decoder(resp).Decode(&body) + if err != nil { + return nil, goahttp.ErrDecodingError("control-plane", "update-database", err) + } + err = ValidateUpdateDatabaseResponseBody(&body) + if err != nil { + return nil, goahttp.ErrValidationError("control-plane", "update-database", err) + } + res := NewUpdateDatabaseDatabaseOK(&body) + return res, nil + default: + body, _ := io.ReadAll(resp.Body) + return nil, goahttp.ErrInvalidResponse("control-plane", "update-database", resp.StatusCode, string(body)) + } + } +} + +// BuildDeleteDatabaseRequest instantiates a HTTP request object with method +// and path set to call the "control-plane" service "delete-database" endpoint +func (c *Client) BuildDeleteDatabaseRequest(ctx context.Context, v any) (*http.Request, error) { + var ( + databaseID string + ) + { + p, ok := v.(*controlplane.DeleteDatabasePayload) + if !ok { + return nil, goahttp.ErrInvalidType("control-plane", "delete-database", "*controlplane.DeleteDatabasePayload", v) + } + if p.DatabaseID != nil { + databaseID = *p.DatabaseID + } + } + u := &url.URL{Scheme: c.scheme, Host: c.host, Path: DeleteDatabaseControlPlanePath(databaseID)} + req, err := http.NewRequest("DELETE", u.String(), nil) + if err != nil { + return nil, goahttp.ErrInvalidURL("control-plane", "delete-database", u.String(), err) + } + if ctx != nil { + req = req.WithContext(ctx) + } + + return req, nil +} + +// DecodeDeleteDatabaseResponse returns a decoder for responses returned by the +// control-plane delete-database endpoint. restoreBody controls whether the +// response body should be restored after having been read. +func DecodeDeleteDatabaseResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (any, error) { + return func(resp *http.Response) (any, error) { + if restoreBody { + b, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + defer func() { + resp.Body = io.NopCloser(bytes.NewBuffer(b)) + }() + } else { + defer resp.Body.Close() + } + switch resp.StatusCode { + case http.StatusNoContent: + return nil, nil + default: + body, _ := io.ReadAll(resp.Body) + return nil, goahttp.ErrInvalidResponse("control-plane", "delete-database", resp.StatusCode, string(body)) + } + } +} + +// unmarshalClusterStatusResponseBodyToControlplaneClusterStatus builds a value +// of type *controlplane.ClusterStatus from a value of type +// *ClusterStatusResponseBody. +func unmarshalClusterStatusResponseBodyToControlplaneClusterStatus(v *ClusterStatusResponseBody) *controlplane.ClusterStatus { + res := &controlplane.ClusterStatus{ + State: *v.State, + } + + return res +} + +// unmarshalHostResponseBodyToControlplaneHost builds a value of type +// *controlplane.Host from a value of type *HostResponseBody. +func unmarshalHostResponseBodyToControlplaneHost(v *HostResponseBody) *controlplane.Host { + res := &controlplane.Host{ + ID: *v.ID, + Type: v.Type, + Cohort: v.Cohort, + Hostname: *v.Hostname, + Ipv4Address: *v.Ipv4Address, + } + if v.Config != nil { + res.Config = unmarshalHostConfigurationResponseBodyToControlplaneHostConfiguration(v.Config) + } + res.Status = unmarshalHostStatusResponseBodyToControlplaneHostStatus(v.Status) + + return res +} + +// unmarshalHostConfigurationResponseBodyToControlplaneHostConfiguration builds +// a value of type *controlplane.HostConfiguration from a value of type +// *HostConfigurationResponseBody. +func unmarshalHostConfigurationResponseBodyToControlplaneHostConfiguration(v *HostConfigurationResponseBody) *controlplane.HostConfiguration { + if v == nil { + return nil + } + res := &controlplane.HostConfiguration{ + VectorEnabled: v.VectorEnabled, + TraefikEnabled: v.TraefikEnabled, + } + + return res +} + +// unmarshalHostStatusResponseBodyToControlplaneHostStatus builds a value of +// type *controlplane.HostStatus from a value of type *HostStatusResponseBody. +func unmarshalHostStatusResponseBodyToControlplaneHostStatus(v *HostStatusResponseBody) *controlplane.HostStatus { + res := &controlplane.HostStatus{ + State: *v.State, + } + + return res +} + +// unmarshalHostResponseToControlplaneHost builds a value of type +// *controlplane.Host from a value of type *HostResponse. +func unmarshalHostResponseToControlplaneHost(v *HostResponse) *controlplane.Host { + res := &controlplane.Host{ + ID: *v.ID, + Type: v.Type, + Cohort: v.Cohort, + Hostname: *v.Hostname, + Ipv4Address: *v.Ipv4Address, + } + if v.Config != nil { + res.Config = unmarshalHostConfigurationResponseToControlplaneHostConfiguration(v.Config) + } + res.Status = unmarshalHostStatusResponseToControlplaneHostStatus(v.Status) + + return res +} + +// unmarshalHostConfigurationResponseToControlplaneHostConfiguration builds a +// value of type *controlplane.HostConfiguration from a value of type +// *HostConfigurationResponse. +func unmarshalHostConfigurationResponseToControlplaneHostConfiguration(v *HostConfigurationResponse) *controlplane.HostConfiguration { + if v == nil { + return nil + } + res := &controlplane.HostConfiguration{ + VectorEnabled: v.VectorEnabled, + TraefikEnabled: v.TraefikEnabled, + } + + return res +} + +// unmarshalHostStatusResponseToControlplaneHostStatus builds a value of type +// *controlplane.HostStatus from a value of type *HostStatusResponse. +func unmarshalHostStatusResponseToControlplaneHostStatus(v *HostStatusResponse) *controlplane.HostStatus { + res := &controlplane.HostStatus{ + State: *v.State, + } + + return res +} + +// unmarshalDatabaseResponseToControlplaneDatabase builds a value of type +// *controlplane.Database from a value of type *DatabaseResponse. +func unmarshalDatabaseResponseToControlplaneDatabase(v *DatabaseResponse) *controlplane.Database { + res := &controlplane.Database{ + ID: *v.ID, + TenantID: v.TenantID, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + } + res.Status = unmarshalDatabaseStatusResponseToControlplaneDatabaseStatus(v.Status) + res.Instances = unmarshalInstanceResponseToControlplaneInstance(v.Instances) + if v.Spec != nil { + res.Spec = unmarshalDatabaseSpecResponseToControlplaneDatabaseSpec(v.Spec) + } + + return res +} + +// unmarshalDatabaseStatusResponseToControlplaneDatabaseStatus builds a value +// of type *controlplane.DatabaseStatus from a value of type +// *DatabaseStatusResponse. +func unmarshalDatabaseStatusResponseToControlplaneDatabaseStatus(v *DatabaseStatusResponse) *controlplane.DatabaseStatus { + res := &controlplane.DatabaseStatus{ + State: v.State, + UpdatedAt: v.UpdatedAt, + } + + return res +} + +// unmarshalInstanceResponseToControlplaneInstance builds a value of type +// *controlplane.Instance from a value of type *InstanceResponse. +func unmarshalInstanceResponseToControlplaneInstance(v *InstanceResponse) *controlplane.Instance { + res := &controlplane.Instance{ + ID: *v.ID, + HostID: v.HostID, + NodeName: v.NodeName, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + } + res.Status = unmarshalInstanceStatusResponseToControlplaneInstanceStatus(v.Status) + if v.Interfaces != nil { + res.Interfaces = make([]*controlplane.InstanceInterface, len(v.Interfaces)) + for i, val := range v.Interfaces { + res.Interfaces[i] = unmarshalInstanceInterfaceResponseToControlplaneInstanceInterface(val) + } + } + + return res +} + +// unmarshalInstanceStatusResponseToControlplaneInstanceStatus builds a value +// of type *controlplane.InstanceStatus from a value of type +// *InstanceStatusResponse. +func unmarshalInstanceStatusResponseToControlplaneInstanceStatus(v *InstanceStatusResponse) *controlplane.InstanceStatus { + res := &controlplane.InstanceStatus{ + State: *v.State, + PatroniState: v.PatroniState, + Role: v.Role, + ReadOnly: v.ReadOnly, + PendingRestart: v.PendingRestart, + PatroniPaused: v.PatroniPaused, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + UpdatedAt: v.UpdatedAt, + } + + return res +} + +// unmarshalInstanceInterfaceResponseToControlplaneInstanceInterface builds a +// value of type *controlplane.InstanceInterface from a value of type +// *InstanceInterfaceResponse. +func unmarshalInstanceInterfaceResponseToControlplaneInstanceInterface(v *InstanceInterfaceResponse) *controlplane.InstanceInterface { + if v == nil { + return nil + } + res := &controlplane.InstanceInterface{ + NetworkType: v.NetworkType, + NetworkID: v.NetworkID, + Hostname: v.Hostname, + Ipv4Address: v.Ipv4Address, + Port: v.Port, + } + + return res +} + +// unmarshalDatabaseSpecResponseToControlplaneDatabaseSpec builds a value of +// type *controlplane.DatabaseSpec from a value of type *DatabaseSpecResponse. +func unmarshalDatabaseSpecResponseToControlplaneDatabaseSpec(v *DatabaseSpecResponse) *controlplane.DatabaseSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseSpec{ + DatabaseName: *v.DatabaseName, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + Port: v.Port, + DeletionProtection: v.DeletionProtection, + } + res.Nodes = make([]*controlplane.DatabaseNodeSpec, len(v.Nodes)) + for i, val := range v.Nodes { + res.Nodes[i] = unmarshalDatabaseNodeSpecResponseToControlplaneDatabaseNodeSpec(val) + } + if v.DatabaseUsers != nil { + res.DatabaseUsers = make([]*controlplane.DatabaseUserSpec, len(v.DatabaseUsers)) + for i, val := range v.DatabaseUsers { + res.DatabaseUsers[i] = unmarshalDatabaseUserSpecResponseToControlplaneDatabaseUserSpec(val) + } + } + if v.Extensions != nil { + res.Extensions = make([]*controlplane.DatabaseExtensionSpec, len(v.Extensions)) + for i, val := range v.Extensions { + res.Extensions[i] = unmarshalDatabaseExtensionSpecResponseToControlplaneDatabaseExtensionSpec(val) + } + } + if v.Features != nil { + res.Features = make(map[string]string, len(v.Features)) + for key, val := range v.Features { + tk := key + tv := val + res.Features[tk] = tv + } + } + if v.BackupConfigs != nil { + res.BackupConfigs = make([]*controlplane.BackupConfigSpec, len(v.BackupConfigs)) + for i, val := range v.BackupConfigs { + res.BackupConfigs[i] = unmarshalBackupConfigSpecResponseToControlplaneBackupConfigSpec(val) + } + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// unmarshalDatabaseNodeSpecResponseToControlplaneDatabaseNodeSpec builds a +// value of type *controlplane.DatabaseNodeSpec from a value of type +// *DatabaseNodeSpecResponse. +func unmarshalDatabaseNodeSpecResponseToControlplaneDatabaseNodeSpec(v *DatabaseNodeSpecResponse) *controlplane.DatabaseNodeSpec { + res := &controlplane.DatabaseNodeSpec{ + Name: *v.Name, + InstanceID: *v.InstanceID, + HostID: *v.HostID, + PostgresVersion: v.PostgresVersion, + Port: v.Port, + } + if v.ReadReplicas != nil { + res.ReadReplicas = unmarshalDatabaseReplicaSpecResponseToControlplaneDatabaseReplicaSpec(v.ReadReplicas) + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// unmarshalDatabaseReplicaSpecResponseToControlplaneDatabaseReplicaSpec builds +// a value of type *controlplane.DatabaseReplicaSpec from a value of type +// *DatabaseReplicaSpecResponse. +func unmarshalDatabaseReplicaSpecResponseToControlplaneDatabaseReplicaSpec(v *DatabaseReplicaSpecResponse) *controlplane.DatabaseReplicaSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseReplicaSpec{ + InstanceID: *v.InstanceID, + HostID: *v.HostID, + } + + return res +} + +// unmarshalDatabaseUserSpecResponseToControlplaneDatabaseUserSpec builds a +// value of type *controlplane.DatabaseUserSpec from a value of type +// *DatabaseUserSpecResponse. +func unmarshalDatabaseUserSpecResponseToControlplaneDatabaseUserSpec(v *DatabaseUserSpecResponse) *controlplane.DatabaseUserSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseUserSpec{ + Username: *v.Username, + Password: *v.Password, + Superuser: v.Superuser, + } + if v.Roles != nil { + res.Roles = make([]string, len(v.Roles)) + for i, val := range v.Roles { + res.Roles[i] = val + } + } + + return res +} + +// unmarshalDatabaseExtensionSpecResponseToControlplaneDatabaseExtensionSpec +// builds a value of type *controlplane.DatabaseExtensionSpec from a value of +// type *DatabaseExtensionSpecResponse. +func unmarshalDatabaseExtensionSpecResponseToControlplaneDatabaseExtensionSpec(v *DatabaseExtensionSpecResponse) *controlplane.DatabaseExtensionSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseExtensionSpec{ + Name: *v.Name, + Version: v.Version, + } + + return res +} + +// unmarshalBackupConfigSpecResponseToControlplaneBackupConfigSpec builds a +// value of type *controlplane.BackupConfigSpec from a value of type +// *BackupConfigSpecResponse. +func unmarshalBackupConfigSpecResponseToControlplaneBackupConfigSpec(v *BackupConfigSpecResponse) *controlplane.BackupConfigSpec { + if v == nil { + return nil + } + res := &controlplane.BackupConfigSpec{ + ID: *v.ID, + Provider: *v.Provider, + } + if v.NodeNames != nil { + res.NodeNames = make([]string, len(v.NodeNames)) + for i, val := range v.NodeNames { + res.NodeNames[i] = val + } + } + if v.Repositories != nil { + res.Repositories = make([]*controlplane.BackupRepositorySpec, len(v.Repositories)) + for i, val := range v.Repositories { + res.Repositories[i] = unmarshalBackupRepositorySpecResponseToControlplaneBackupRepositorySpec(val) + } + } + if v.Schedules != nil { + res.Schedules = make([]*controlplane.BackupScheduleSpec, len(v.Schedules)) + for i, val := range v.Schedules { + res.Schedules[i] = unmarshalBackupScheduleSpecResponseToControlplaneBackupScheduleSpec(val) + } + } + + return res +} + +// unmarshalBackupRepositorySpecResponseToControlplaneBackupRepositorySpec +// builds a value of type *controlplane.BackupRepositorySpec from a value of +// type *BackupRepositorySpecResponse. +func unmarshalBackupRepositorySpecResponseToControlplaneBackupRepositorySpec(v *BackupRepositorySpecResponse) *controlplane.BackupRepositorySpec { + if v == nil { + return nil + } + res := &controlplane.BackupRepositorySpec{ + ID: v.ID, + Type: *v.Type, + S3Bucket: v.S3Bucket, + S3Region: v.S3Region, + S3Endpoint: v.S3Endpoint, + GcsBucket: v.GcsBucket, + GcsEndpoint: v.GcsEndpoint, + AzureAccount: v.AzureAccount, + AzureContainer: v.AzureContainer, + AzureEndpoint: v.AzureEndpoint, + RetentionFull: v.RetentionFull, + RetentionFullType: v.RetentionFullType, + BasePath: v.BasePath, + } + + return res +} + +// unmarshalBackupScheduleSpecResponseToControlplaneBackupScheduleSpec builds a +// value of type *controlplane.BackupScheduleSpec from a value of type +// *BackupScheduleSpecResponse. +func unmarshalBackupScheduleSpecResponseToControlplaneBackupScheduleSpec(v *BackupScheduleSpecResponse) *controlplane.BackupScheduleSpec { + if v == nil { + return nil + } + res := &controlplane.BackupScheduleSpec{ + ID: *v.ID, + Type: *v.Type, + CronExpression: *v.CronExpression, + } + + return res +} + +// marshalControlplaneDatabaseSpecToDatabaseSpecRequestBody builds a value of +// type *DatabaseSpecRequestBody from a value of type +// *controlplane.DatabaseSpec. +func marshalControlplaneDatabaseSpecToDatabaseSpecRequestBody(v *controlplane.DatabaseSpec) *DatabaseSpecRequestBody { + if v == nil { + return nil + } + res := &DatabaseSpecRequestBody{ + DatabaseName: v.DatabaseName, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + Port: v.Port, + DeletionProtection: v.DeletionProtection, + } + if v.Nodes != nil { + res.Nodes = make([]*DatabaseNodeSpecRequestBody, len(v.Nodes)) + for i, val := range v.Nodes { + res.Nodes[i] = marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecRequestBody(val) + } + } else { + res.Nodes = []*DatabaseNodeSpecRequestBody{} + } + if v.DatabaseUsers != nil { + res.DatabaseUsers = make([]*DatabaseUserSpecRequestBody, len(v.DatabaseUsers)) + for i, val := range v.DatabaseUsers { + res.DatabaseUsers[i] = marshalControlplaneDatabaseUserSpecToDatabaseUserSpecRequestBody(val) + } + } + if v.Extensions != nil { + res.Extensions = make([]*DatabaseExtensionSpecRequestBody, len(v.Extensions)) + for i, val := range v.Extensions { + res.Extensions[i] = marshalControlplaneDatabaseExtensionSpecToDatabaseExtensionSpecRequestBody(val) + } + } + if v.Features != nil { + res.Features = make(map[string]string, len(v.Features)) + for key, val := range v.Features { + tk := key + tv := val + res.Features[tk] = tv + } + } + if v.BackupConfigs != nil { + res.BackupConfigs = make([]*BackupConfigSpecRequestBody, len(v.BackupConfigs)) + for i, val := range v.BackupConfigs { + res.BackupConfigs[i] = marshalControlplaneBackupConfigSpecToBackupConfigSpecRequestBody(val) + } + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecRequestBody builds a +// value of type *DatabaseNodeSpecRequestBody from a value of type +// *controlplane.DatabaseNodeSpec. +func marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecRequestBody(v *controlplane.DatabaseNodeSpec) *DatabaseNodeSpecRequestBody { + res := &DatabaseNodeSpecRequestBody{ + Name: v.Name, + InstanceID: v.InstanceID, + HostID: v.HostID, + PostgresVersion: v.PostgresVersion, + Port: v.Port, + } + if v.ReadReplicas != nil { + res.ReadReplicas = marshalControlplaneDatabaseReplicaSpecToDatabaseReplicaSpecRequestBody(v.ReadReplicas) + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// marshalControlplaneDatabaseReplicaSpecToDatabaseReplicaSpecRequestBody +// builds a value of type *DatabaseReplicaSpecRequestBody from a value of type +// *controlplane.DatabaseReplicaSpec. +func marshalControlplaneDatabaseReplicaSpecToDatabaseReplicaSpecRequestBody(v *controlplane.DatabaseReplicaSpec) *DatabaseReplicaSpecRequestBody { + if v == nil { + return nil + } + res := &DatabaseReplicaSpecRequestBody{ + InstanceID: v.InstanceID, + HostID: v.HostID, + } + + return res +} + +// marshalControlplaneDatabaseUserSpecToDatabaseUserSpecRequestBody builds a +// value of type *DatabaseUserSpecRequestBody from a value of type +// *controlplane.DatabaseUserSpec. +func marshalControlplaneDatabaseUserSpecToDatabaseUserSpecRequestBody(v *controlplane.DatabaseUserSpec) *DatabaseUserSpecRequestBody { + if v == nil { + return nil + } + res := &DatabaseUserSpecRequestBody{ + Username: v.Username, + Password: v.Password, + Superuser: v.Superuser, + } + if v.Roles != nil { + res.Roles = make([]string, len(v.Roles)) + for i, val := range v.Roles { + res.Roles[i] = val + } + } + + return res +} + +// marshalControlplaneDatabaseExtensionSpecToDatabaseExtensionSpecRequestBody +// builds a value of type *DatabaseExtensionSpecRequestBody from a value of +// type *controlplane.DatabaseExtensionSpec. +func marshalControlplaneDatabaseExtensionSpecToDatabaseExtensionSpecRequestBody(v *controlplane.DatabaseExtensionSpec) *DatabaseExtensionSpecRequestBody { + if v == nil { + return nil + } + res := &DatabaseExtensionSpecRequestBody{ + Name: v.Name, + Version: v.Version, + } + + return res +} + +// marshalControlplaneBackupConfigSpecToBackupConfigSpecRequestBody builds a +// value of type *BackupConfigSpecRequestBody from a value of type +// *controlplane.BackupConfigSpec. +func marshalControlplaneBackupConfigSpecToBackupConfigSpecRequestBody(v *controlplane.BackupConfigSpec) *BackupConfigSpecRequestBody { + if v == nil { + return nil + } + res := &BackupConfigSpecRequestBody{ + ID: v.ID, + Provider: v.Provider, + } + if v.NodeNames != nil { + res.NodeNames = make([]string, len(v.NodeNames)) + for i, val := range v.NodeNames { + res.NodeNames[i] = val + } + } + if v.Repositories != nil { + res.Repositories = make([]*BackupRepositorySpecRequestBody, len(v.Repositories)) + for i, val := range v.Repositories { + res.Repositories[i] = marshalControlplaneBackupRepositorySpecToBackupRepositorySpecRequestBody(val) + } + } + if v.Schedules != nil { + res.Schedules = make([]*BackupScheduleSpecRequestBody, len(v.Schedules)) + for i, val := range v.Schedules { + res.Schedules[i] = marshalControlplaneBackupScheduleSpecToBackupScheduleSpecRequestBody(val) + } + } + + return res +} + +// marshalControlplaneBackupRepositorySpecToBackupRepositorySpecRequestBody +// builds a value of type *BackupRepositorySpecRequestBody from a value of type +// *controlplane.BackupRepositorySpec. +func marshalControlplaneBackupRepositorySpecToBackupRepositorySpecRequestBody(v *controlplane.BackupRepositorySpec) *BackupRepositorySpecRequestBody { + if v == nil { + return nil + } + res := &BackupRepositorySpecRequestBody{ + ID: v.ID, + Type: v.Type, + S3Bucket: v.S3Bucket, + S3Region: v.S3Region, + S3Endpoint: v.S3Endpoint, + GcsBucket: v.GcsBucket, + GcsEndpoint: v.GcsEndpoint, + AzureAccount: v.AzureAccount, + AzureContainer: v.AzureContainer, + AzureEndpoint: v.AzureEndpoint, + RetentionFull: v.RetentionFull, + RetentionFullType: v.RetentionFullType, + BasePath: v.BasePath, + } + + return res +} + +// marshalControlplaneBackupScheduleSpecToBackupScheduleSpecRequestBody builds +// a value of type *BackupScheduleSpecRequestBody from a value of type +// *controlplane.BackupScheduleSpec. +func marshalControlplaneBackupScheduleSpecToBackupScheduleSpecRequestBody(v *controlplane.BackupScheduleSpec) *BackupScheduleSpecRequestBody { + if v == nil { + return nil + } + res := &BackupScheduleSpecRequestBody{ + ID: v.ID, + Type: v.Type, + CronExpression: v.CronExpression, + } + + return res +} + +// marshalDatabaseSpecRequestBodyToControlplaneDatabaseSpec builds a value of +// type *controlplane.DatabaseSpec from a value of type +// *DatabaseSpecRequestBody. +func marshalDatabaseSpecRequestBodyToControlplaneDatabaseSpec(v *DatabaseSpecRequestBody) *controlplane.DatabaseSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseSpec{ + DatabaseName: v.DatabaseName, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + Port: v.Port, + DeletionProtection: v.DeletionProtection, + } + if v.Nodes != nil { + res.Nodes = make([]*controlplane.DatabaseNodeSpec, len(v.Nodes)) + for i, val := range v.Nodes { + res.Nodes[i] = marshalDatabaseNodeSpecRequestBodyToControlplaneDatabaseNodeSpec(val) + } + } else { + res.Nodes = []*controlplane.DatabaseNodeSpec{} + } + if v.DatabaseUsers != nil { + res.DatabaseUsers = make([]*controlplane.DatabaseUserSpec, len(v.DatabaseUsers)) + for i, val := range v.DatabaseUsers { + res.DatabaseUsers[i] = marshalDatabaseUserSpecRequestBodyToControlplaneDatabaseUserSpec(val) + } + } + if v.Extensions != nil { + res.Extensions = make([]*controlplane.DatabaseExtensionSpec, len(v.Extensions)) + for i, val := range v.Extensions { + res.Extensions[i] = marshalDatabaseExtensionSpecRequestBodyToControlplaneDatabaseExtensionSpec(val) + } + } + if v.Features != nil { + res.Features = make(map[string]string, len(v.Features)) + for key, val := range v.Features { + tk := key + tv := val + res.Features[tk] = tv + } + } + if v.BackupConfigs != nil { + res.BackupConfigs = make([]*controlplane.BackupConfigSpec, len(v.BackupConfigs)) + for i, val := range v.BackupConfigs { + res.BackupConfigs[i] = marshalBackupConfigSpecRequestBodyToControlplaneBackupConfigSpec(val) + } + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// marshalDatabaseNodeSpecRequestBodyToControlplaneDatabaseNodeSpec builds a +// value of type *controlplane.DatabaseNodeSpec from a value of type +// *DatabaseNodeSpecRequestBody. +func marshalDatabaseNodeSpecRequestBodyToControlplaneDatabaseNodeSpec(v *DatabaseNodeSpecRequestBody) *controlplane.DatabaseNodeSpec { + res := &controlplane.DatabaseNodeSpec{ + Name: v.Name, + InstanceID: v.InstanceID, + HostID: v.HostID, + PostgresVersion: v.PostgresVersion, + Port: v.Port, + } + if v.ReadReplicas != nil { + res.ReadReplicas = marshalDatabaseReplicaSpecRequestBodyToControlplaneDatabaseReplicaSpec(v.ReadReplicas) + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// marshalDatabaseReplicaSpecRequestBodyToControlplaneDatabaseReplicaSpec +// builds a value of type *controlplane.DatabaseReplicaSpec from a value of +// type *DatabaseReplicaSpecRequestBody. +func marshalDatabaseReplicaSpecRequestBodyToControlplaneDatabaseReplicaSpec(v *DatabaseReplicaSpecRequestBody) *controlplane.DatabaseReplicaSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseReplicaSpec{ + InstanceID: v.InstanceID, + HostID: v.HostID, + } + + return res +} + +// marshalDatabaseUserSpecRequestBodyToControlplaneDatabaseUserSpec builds a +// value of type *controlplane.DatabaseUserSpec from a value of type +// *DatabaseUserSpecRequestBody. +func marshalDatabaseUserSpecRequestBodyToControlplaneDatabaseUserSpec(v *DatabaseUserSpecRequestBody) *controlplane.DatabaseUserSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseUserSpec{ + Username: v.Username, + Password: v.Password, + Superuser: v.Superuser, + } + if v.Roles != nil { + res.Roles = make([]string, len(v.Roles)) + for i, val := range v.Roles { + res.Roles[i] = val + } + } + + return res +} + +// marshalDatabaseExtensionSpecRequestBodyToControlplaneDatabaseExtensionSpec +// builds a value of type *controlplane.DatabaseExtensionSpec from a value of +// type *DatabaseExtensionSpecRequestBody. +func marshalDatabaseExtensionSpecRequestBodyToControlplaneDatabaseExtensionSpec(v *DatabaseExtensionSpecRequestBody) *controlplane.DatabaseExtensionSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseExtensionSpec{ + Name: v.Name, + Version: v.Version, + } + + return res +} + +// marshalBackupConfigSpecRequestBodyToControlplaneBackupConfigSpec builds a +// value of type *controlplane.BackupConfigSpec from a value of type +// *BackupConfigSpecRequestBody. +func marshalBackupConfigSpecRequestBodyToControlplaneBackupConfigSpec(v *BackupConfigSpecRequestBody) *controlplane.BackupConfigSpec { + if v == nil { + return nil + } + res := &controlplane.BackupConfigSpec{ + ID: v.ID, + Provider: v.Provider, + } + if v.NodeNames != nil { + res.NodeNames = make([]string, len(v.NodeNames)) + for i, val := range v.NodeNames { + res.NodeNames[i] = val + } + } + if v.Repositories != nil { + res.Repositories = make([]*controlplane.BackupRepositorySpec, len(v.Repositories)) + for i, val := range v.Repositories { + res.Repositories[i] = marshalBackupRepositorySpecRequestBodyToControlplaneBackupRepositorySpec(val) + } + } + if v.Schedules != nil { + res.Schedules = make([]*controlplane.BackupScheduleSpec, len(v.Schedules)) + for i, val := range v.Schedules { + res.Schedules[i] = marshalBackupScheduleSpecRequestBodyToControlplaneBackupScheduleSpec(val) + } + } + + return res +} + +// marshalBackupRepositorySpecRequestBodyToControlplaneBackupRepositorySpec +// builds a value of type *controlplane.BackupRepositorySpec from a value of +// type *BackupRepositorySpecRequestBody. +func marshalBackupRepositorySpecRequestBodyToControlplaneBackupRepositorySpec(v *BackupRepositorySpecRequestBody) *controlplane.BackupRepositorySpec { + if v == nil { + return nil + } + res := &controlplane.BackupRepositorySpec{ + ID: v.ID, + Type: v.Type, + S3Bucket: v.S3Bucket, + S3Region: v.S3Region, + S3Endpoint: v.S3Endpoint, + GcsBucket: v.GcsBucket, + GcsEndpoint: v.GcsEndpoint, + AzureAccount: v.AzureAccount, + AzureContainer: v.AzureContainer, + AzureEndpoint: v.AzureEndpoint, + RetentionFull: v.RetentionFull, + RetentionFullType: v.RetentionFullType, + BasePath: v.BasePath, + } + + return res +} + +// marshalBackupScheduleSpecRequestBodyToControlplaneBackupScheduleSpec builds +// a value of type *controlplane.BackupScheduleSpec from a value of type +// *BackupScheduleSpecRequestBody. +func marshalBackupScheduleSpecRequestBodyToControlplaneBackupScheduleSpec(v *BackupScheduleSpecRequestBody) *controlplane.BackupScheduleSpec { + if v == nil { + return nil + } + res := &controlplane.BackupScheduleSpec{ + ID: v.ID, + Type: v.Type, + CronExpression: v.CronExpression, + } + + return res +} + +// unmarshalDatabaseStatusResponseBodyToControlplaneDatabaseStatus builds a +// value of type *controlplane.DatabaseStatus from a value of type +// *DatabaseStatusResponseBody. +func unmarshalDatabaseStatusResponseBodyToControlplaneDatabaseStatus(v *DatabaseStatusResponseBody) *controlplane.DatabaseStatus { + res := &controlplane.DatabaseStatus{ + State: v.State, + UpdatedAt: v.UpdatedAt, + } + + return res +} + +// unmarshalInstanceResponseBodyToControlplaneInstance builds a value of type +// *controlplane.Instance from a value of type *InstanceResponseBody. +func unmarshalInstanceResponseBodyToControlplaneInstance(v *InstanceResponseBody) *controlplane.Instance { + res := &controlplane.Instance{ + ID: *v.ID, + HostID: v.HostID, + NodeName: v.NodeName, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + } + res.Status = unmarshalInstanceStatusResponseBodyToControlplaneInstanceStatus(v.Status) + if v.Interfaces != nil { + res.Interfaces = make([]*controlplane.InstanceInterface, len(v.Interfaces)) + for i, val := range v.Interfaces { + res.Interfaces[i] = unmarshalInstanceInterfaceResponseBodyToControlplaneInstanceInterface(val) + } + } + + return res +} + +// unmarshalInstanceStatusResponseBodyToControlplaneInstanceStatus builds a +// value of type *controlplane.InstanceStatus from a value of type +// *InstanceStatusResponseBody. +func unmarshalInstanceStatusResponseBodyToControlplaneInstanceStatus(v *InstanceStatusResponseBody) *controlplane.InstanceStatus { + res := &controlplane.InstanceStatus{ + State: *v.State, + PatroniState: v.PatroniState, + Role: v.Role, + ReadOnly: v.ReadOnly, + PendingRestart: v.PendingRestart, + PatroniPaused: v.PatroniPaused, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + UpdatedAt: v.UpdatedAt, + } + + return res +} + +// unmarshalInstanceInterfaceResponseBodyToControlplaneInstanceInterface builds +// a value of type *controlplane.InstanceInterface from a value of type +// *InstanceInterfaceResponseBody. +func unmarshalInstanceInterfaceResponseBodyToControlplaneInstanceInterface(v *InstanceInterfaceResponseBody) *controlplane.InstanceInterface { + if v == nil { + return nil + } + res := &controlplane.InstanceInterface{ + NetworkType: v.NetworkType, + NetworkID: v.NetworkID, + Hostname: v.Hostname, + Ipv4Address: v.Ipv4Address, + Port: v.Port, + } + + return res +} + +// unmarshalDatabaseSpecResponseBodyToControlplaneDatabaseSpec builds a value +// of type *controlplane.DatabaseSpec from a value of type +// *DatabaseSpecResponseBody. +func unmarshalDatabaseSpecResponseBodyToControlplaneDatabaseSpec(v *DatabaseSpecResponseBody) *controlplane.DatabaseSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseSpec{ + DatabaseName: *v.DatabaseName, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + Port: v.Port, + DeletionProtection: v.DeletionProtection, + } + res.Nodes = make([]*controlplane.DatabaseNodeSpec, len(v.Nodes)) + for i, val := range v.Nodes { + res.Nodes[i] = unmarshalDatabaseNodeSpecResponseBodyToControlplaneDatabaseNodeSpec(val) + } + if v.DatabaseUsers != nil { + res.DatabaseUsers = make([]*controlplane.DatabaseUserSpec, len(v.DatabaseUsers)) + for i, val := range v.DatabaseUsers { + res.DatabaseUsers[i] = unmarshalDatabaseUserSpecResponseBodyToControlplaneDatabaseUserSpec(val) + } + } + if v.Extensions != nil { + res.Extensions = make([]*controlplane.DatabaseExtensionSpec, len(v.Extensions)) + for i, val := range v.Extensions { + res.Extensions[i] = unmarshalDatabaseExtensionSpecResponseBodyToControlplaneDatabaseExtensionSpec(val) + } + } + if v.Features != nil { + res.Features = make(map[string]string, len(v.Features)) + for key, val := range v.Features { + tk := key + tv := val + res.Features[tk] = tv + } + } + if v.BackupConfigs != nil { + res.BackupConfigs = make([]*controlplane.BackupConfigSpec, len(v.BackupConfigs)) + for i, val := range v.BackupConfigs { + res.BackupConfigs[i] = unmarshalBackupConfigSpecResponseBodyToControlplaneBackupConfigSpec(val) + } + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// unmarshalDatabaseNodeSpecResponseBodyToControlplaneDatabaseNodeSpec builds a +// value of type *controlplane.DatabaseNodeSpec from a value of type +// *DatabaseNodeSpecResponseBody. +func unmarshalDatabaseNodeSpecResponseBodyToControlplaneDatabaseNodeSpec(v *DatabaseNodeSpecResponseBody) *controlplane.DatabaseNodeSpec { + res := &controlplane.DatabaseNodeSpec{ + Name: *v.Name, + InstanceID: *v.InstanceID, + HostID: *v.HostID, + PostgresVersion: v.PostgresVersion, + Port: v.Port, + } + if v.ReadReplicas != nil { + res.ReadReplicas = unmarshalDatabaseReplicaSpecResponseBodyToControlplaneDatabaseReplicaSpec(v.ReadReplicas) + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// unmarshalDatabaseReplicaSpecResponseBodyToControlplaneDatabaseReplicaSpec +// builds a value of type *controlplane.DatabaseReplicaSpec from a value of +// type *DatabaseReplicaSpecResponseBody. +func unmarshalDatabaseReplicaSpecResponseBodyToControlplaneDatabaseReplicaSpec(v *DatabaseReplicaSpecResponseBody) *controlplane.DatabaseReplicaSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseReplicaSpec{ + InstanceID: *v.InstanceID, + HostID: *v.HostID, + } + + return res +} + +// unmarshalDatabaseUserSpecResponseBodyToControlplaneDatabaseUserSpec builds a +// value of type *controlplane.DatabaseUserSpec from a value of type +// *DatabaseUserSpecResponseBody. +func unmarshalDatabaseUserSpecResponseBodyToControlplaneDatabaseUserSpec(v *DatabaseUserSpecResponseBody) *controlplane.DatabaseUserSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseUserSpec{ + Username: *v.Username, + Password: *v.Password, + Superuser: v.Superuser, + } + if v.Roles != nil { + res.Roles = make([]string, len(v.Roles)) + for i, val := range v.Roles { + res.Roles[i] = val + } + } + + return res +} + +// unmarshalDatabaseExtensionSpecResponseBodyToControlplaneDatabaseExtensionSpec +// builds a value of type *controlplane.DatabaseExtensionSpec from a value of +// type *DatabaseExtensionSpecResponseBody. +func unmarshalDatabaseExtensionSpecResponseBodyToControlplaneDatabaseExtensionSpec(v *DatabaseExtensionSpecResponseBody) *controlplane.DatabaseExtensionSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseExtensionSpec{ + Name: *v.Name, + Version: v.Version, + } + + return res +} + +// unmarshalBackupConfigSpecResponseBodyToControlplaneBackupConfigSpec builds a +// value of type *controlplane.BackupConfigSpec from a value of type +// *BackupConfigSpecResponseBody. +func unmarshalBackupConfigSpecResponseBodyToControlplaneBackupConfigSpec(v *BackupConfigSpecResponseBody) *controlplane.BackupConfigSpec { + if v == nil { + return nil + } + res := &controlplane.BackupConfigSpec{ + ID: *v.ID, + Provider: *v.Provider, + } + if v.NodeNames != nil { + res.NodeNames = make([]string, len(v.NodeNames)) + for i, val := range v.NodeNames { + res.NodeNames[i] = val + } + } + if v.Repositories != nil { + res.Repositories = make([]*controlplane.BackupRepositorySpec, len(v.Repositories)) + for i, val := range v.Repositories { + res.Repositories[i] = unmarshalBackupRepositorySpecResponseBodyToControlplaneBackupRepositorySpec(val) + } + } + if v.Schedules != nil { + res.Schedules = make([]*controlplane.BackupScheduleSpec, len(v.Schedules)) + for i, val := range v.Schedules { + res.Schedules[i] = unmarshalBackupScheduleSpecResponseBodyToControlplaneBackupScheduleSpec(val) + } + } + + return res +} + +// unmarshalBackupRepositorySpecResponseBodyToControlplaneBackupRepositorySpec +// builds a value of type *controlplane.BackupRepositorySpec from a value of +// type *BackupRepositorySpecResponseBody. +func unmarshalBackupRepositorySpecResponseBodyToControlplaneBackupRepositorySpec(v *BackupRepositorySpecResponseBody) *controlplane.BackupRepositorySpec { + if v == nil { + return nil + } + res := &controlplane.BackupRepositorySpec{ + ID: v.ID, + Type: *v.Type, + S3Bucket: v.S3Bucket, + S3Region: v.S3Region, + S3Endpoint: v.S3Endpoint, + GcsBucket: v.GcsBucket, + GcsEndpoint: v.GcsEndpoint, + AzureAccount: v.AzureAccount, + AzureContainer: v.AzureContainer, + AzureEndpoint: v.AzureEndpoint, + RetentionFull: v.RetentionFull, + RetentionFullType: v.RetentionFullType, + BasePath: v.BasePath, + } + + return res +} + +// unmarshalBackupScheduleSpecResponseBodyToControlplaneBackupScheduleSpec +// builds a value of type *controlplane.BackupScheduleSpec from a value of type +// *BackupScheduleSpecResponseBody. +func unmarshalBackupScheduleSpecResponseBodyToControlplaneBackupScheduleSpec(v *BackupScheduleSpecResponseBody) *controlplane.BackupScheduleSpec { + if v == nil { + return nil + } + res := &controlplane.BackupScheduleSpec{ + ID: *v.ID, + Type: *v.Type, + CronExpression: *v.CronExpression, + } + + return res +} + +// marshalControlplaneDatabaseSpecToDatabaseSpecRequestBodyRequestBody builds a +// value of type *DatabaseSpecRequestBodyRequestBody from a value of type +// *controlplane.DatabaseSpec. +func marshalControlplaneDatabaseSpecToDatabaseSpecRequestBodyRequestBody(v *controlplane.DatabaseSpec) *DatabaseSpecRequestBodyRequestBody { + if v == nil { + return nil + } + res := &DatabaseSpecRequestBodyRequestBody{ + DatabaseName: v.DatabaseName, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + Port: v.Port, + DeletionProtection: v.DeletionProtection, + } + if v.Nodes != nil { + res.Nodes = make([]*DatabaseNodeSpecRequestBodyRequestBody, len(v.Nodes)) + for i, val := range v.Nodes { + res.Nodes[i] = marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecRequestBodyRequestBody(val) + } + } else { + res.Nodes = []*DatabaseNodeSpecRequestBodyRequestBody{} + } + if v.DatabaseUsers != nil { + res.DatabaseUsers = make([]*DatabaseUserSpecRequestBodyRequestBody, len(v.DatabaseUsers)) + for i, val := range v.DatabaseUsers { + res.DatabaseUsers[i] = marshalControlplaneDatabaseUserSpecToDatabaseUserSpecRequestBodyRequestBody(val) + } + } + if v.Extensions != nil { + res.Extensions = make([]*DatabaseExtensionSpecRequestBodyRequestBody, len(v.Extensions)) + for i, val := range v.Extensions { + res.Extensions[i] = marshalControlplaneDatabaseExtensionSpecToDatabaseExtensionSpecRequestBodyRequestBody(val) + } + } + if v.Features != nil { + res.Features = make(map[string]string, len(v.Features)) + for key, val := range v.Features { + tk := key + tv := val + res.Features[tk] = tv + } + } + if v.BackupConfigs != nil { + res.BackupConfigs = make([]*BackupConfigSpecRequestBodyRequestBody, len(v.BackupConfigs)) + for i, val := range v.BackupConfigs { + res.BackupConfigs[i] = marshalControlplaneBackupConfigSpecToBackupConfigSpecRequestBodyRequestBody(val) + } + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecRequestBodyRequestBody +// builds a value of type *DatabaseNodeSpecRequestBodyRequestBody from a value +// of type *controlplane.DatabaseNodeSpec. +func marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecRequestBodyRequestBody(v *controlplane.DatabaseNodeSpec) *DatabaseNodeSpecRequestBodyRequestBody { + res := &DatabaseNodeSpecRequestBodyRequestBody{ + Name: v.Name, + InstanceID: v.InstanceID, + HostID: v.HostID, + PostgresVersion: v.PostgresVersion, + Port: v.Port, + } + if v.ReadReplicas != nil { + res.ReadReplicas = marshalControlplaneDatabaseReplicaSpecToDatabaseReplicaSpecRequestBodyRequestBody(v.ReadReplicas) + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// marshalControlplaneDatabaseReplicaSpecToDatabaseReplicaSpecRequestBodyRequestBody +// builds a value of type *DatabaseReplicaSpecRequestBodyRequestBody from a +// value of type *controlplane.DatabaseReplicaSpec. +func marshalControlplaneDatabaseReplicaSpecToDatabaseReplicaSpecRequestBodyRequestBody(v *controlplane.DatabaseReplicaSpec) *DatabaseReplicaSpecRequestBodyRequestBody { + if v == nil { + return nil + } + res := &DatabaseReplicaSpecRequestBodyRequestBody{ + InstanceID: v.InstanceID, + HostID: v.HostID, + } + + return res +} + +// marshalControlplaneDatabaseUserSpecToDatabaseUserSpecRequestBodyRequestBody +// builds a value of type *DatabaseUserSpecRequestBodyRequestBody from a value +// of type *controlplane.DatabaseUserSpec. +func marshalControlplaneDatabaseUserSpecToDatabaseUserSpecRequestBodyRequestBody(v *controlplane.DatabaseUserSpec) *DatabaseUserSpecRequestBodyRequestBody { + if v == nil { + return nil + } + res := &DatabaseUserSpecRequestBodyRequestBody{ + Username: v.Username, + Password: v.Password, + Superuser: v.Superuser, + } + if v.Roles != nil { + res.Roles = make([]string, len(v.Roles)) + for i, val := range v.Roles { + res.Roles[i] = val + } + } + + return res +} + +// marshalControlplaneDatabaseExtensionSpecToDatabaseExtensionSpecRequestBodyRequestBody +// builds a value of type *DatabaseExtensionSpecRequestBodyRequestBody from a +// value of type *controlplane.DatabaseExtensionSpec. +func marshalControlplaneDatabaseExtensionSpecToDatabaseExtensionSpecRequestBodyRequestBody(v *controlplane.DatabaseExtensionSpec) *DatabaseExtensionSpecRequestBodyRequestBody { + if v == nil { + return nil + } + res := &DatabaseExtensionSpecRequestBodyRequestBody{ + Name: v.Name, + Version: v.Version, + } + + return res +} + +// marshalControlplaneBackupConfigSpecToBackupConfigSpecRequestBodyRequestBody +// builds a value of type *BackupConfigSpecRequestBodyRequestBody from a value +// of type *controlplane.BackupConfigSpec. +func marshalControlplaneBackupConfigSpecToBackupConfigSpecRequestBodyRequestBody(v *controlplane.BackupConfigSpec) *BackupConfigSpecRequestBodyRequestBody { + if v == nil { + return nil + } + res := &BackupConfigSpecRequestBodyRequestBody{ + ID: v.ID, + Provider: v.Provider, + } + if v.NodeNames != nil { + res.NodeNames = make([]string, len(v.NodeNames)) + for i, val := range v.NodeNames { + res.NodeNames[i] = val + } + } + if v.Repositories != nil { + res.Repositories = make([]*BackupRepositorySpecRequestBodyRequestBody, len(v.Repositories)) + for i, val := range v.Repositories { + res.Repositories[i] = marshalControlplaneBackupRepositorySpecToBackupRepositorySpecRequestBodyRequestBody(val) + } + } + if v.Schedules != nil { + res.Schedules = make([]*BackupScheduleSpecRequestBodyRequestBody, len(v.Schedules)) + for i, val := range v.Schedules { + res.Schedules[i] = marshalControlplaneBackupScheduleSpecToBackupScheduleSpecRequestBodyRequestBody(val) + } + } + + return res +} + +// marshalControlplaneBackupRepositorySpecToBackupRepositorySpecRequestBodyRequestBody +// builds a value of type *BackupRepositorySpecRequestBodyRequestBody from a +// value of type *controlplane.BackupRepositorySpec. +func marshalControlplaneBackupRepositorySpecToBackupRepositorySpecRequestBodyRequestBody(v *controlplane.BackupRepositorySpec) *BackupRepositorySpecRequestBodyRequestBody { + if v == nil { + return nil + } + res := &BackupRepositorySpecRequestBodyRequestBody{ + ID: v.ID, + Type: v.Type, + S3Bucket: v.S3Bucket, + S3Region: v.S3Region, + S3Endpoint: v.S3Endpoint, + GcsBucket: v.GcsBucket, + GcsEndpoint: v.GcsEndpoint, + AzureAccount: v.AzureAccount, + AzureContainer: v.AzureContainer, + AzureEndpoint: v.AzureEndpoint, + RetentionFull: v.RetentionFull, + RetentionFullType: v.RetentionFullType, + BasePath: v.BasePath, + } + + return res +} + +// marshalControlplaneBackupScheduleSpecToBackupScheduleSpecRequestBodyRequestBody +// builds a value of type *BackupScheduleSpecRequestBodyRequestBody from a +// value of type *controlplane.BackupScheduleSpec. +func marshalControlplaneBackupScheduleSpecToBackupScheduleSpecRequestBodyRequestBody(v *controlplane.BackupScheduleSpec) *BackupScheduleSpecRequestBodyRequestBody { + if v == nil { + return nil + } + res := &BackupScheduleSpecRequestBodyRequestBody{ + ID: v.ID, + Type: v.Type, + CronExpression: v.CronExpression, + } + + return res +} + +// marshalDatabaseSpecRequestBodyRequestBodyToControlplaneDatabaseSpec builds a +// value of type *controlplane.DatabaseSpec from a value of type +// *DatabaseSpecRequestBodyRequestBody. +func marshalDatabaseSpecRequestBodyRequestBodyToControlplaneDatabaseSpec(v *DatabaseSpecRequestBodyRequestBody) *controlplane.DatabaseSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseSpec{ + DatabaseName: v.DatabaseName, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + Port: v.Port, + DeletionProtection: v.DeletionProtection, + } + if v.Nodes != nil { + res.Nodes = make([]*controlplane.DatabaseNodeSpec, len(v.Nodes)) + for i, val := range v.Nodes { + res.Nodes[i] = marshalDatabaseNodeSpecRequestBodyRequestBodyToControlplaneDatabaseNodeSpec(val) + } + } else { + res.Nodes = []*controlplane.DatabaseNodeSpec{} + } + if v.DatabaseUsers != nil { + res.DatabaseUsers = make([]*controlplane.DatabaseUserSpec, len(v.DatabaseUsers)) + for i, val := range v.DatabaseUsers { + res.DatabaseUsers[i] = marshalDatabaseUserSpecRequestBodyRequestBodyToControlplaneDatabaseUserSpec(val) + } + } + if v.Extensions != nil { + res.Extensions = make([]*controlplane.DatabaseExtensionSpec, len(v.Extensions)) + for i, val := range v.Extensions { + res.Extensions[i] = marshalDatabaseExtensionSpecRequestBodyRequestBodyToControlplaneDatabaseExtensionSpec(val) + } + } + if v.Features != nil { + res.Features = make(map[string]string, len(v.Features)) + for key, val := range v.Features { + tk := key + tv := val + res.Features[tk] = tv + } + } + if v.BackupConfigs != nil { + res.BackupConfigs = make([]*controlplane.BackupConfigSpec, len(v.BackupConfigs)) + for i, val := range v.BackupConfigs { + res.BackupConfigs[i] = marshalBackupConfigSpecRequestBodyRequestBodyToControlplaneBackupConfigSpec(val) + } + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// marshalDatabaseNodeSpecRequestBodyRequestBodyToControlplaneDatabaseNodeSpec +// builds a value of type *controlplane.DatabaseNodeSpec from a value of type +// *DatabaseNodeSpecRequestBodyRequestBody. +func marshalDatabaseNodeSpecRequestBodyRequestBodyToControlplaneDatabaseNodeSpec(v *DatabaseNodeSpecRequestBodyRequestBody) *controlplane.DatabaseNodeSpec { + res := &controlplane.DatabaseNodeSpec{ + Name: v.Name, + InstanceID: v.InstanceID, + HostID: v.HostID, + PostgresVersion: v.PostgresVersion, + Port: v.Port, + } + if v.ReadReplicas != nil { + res.ReadReplicas = marshalDatabaseReplicaSpecRequestBodyRequestBodyToControlplaneDatabaseReplicaSpec(v.ReadReplicas) + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// marshalDatabaseReplicaSpecRequestBodyRequestBodyToControlplaneDatabaseReplicaSpec +// builds a value of type *controlplane.DatabaseReplicaSpec from a value of +// type *DatabaseReplicaSpecRequestBodyRequestBody. +func marshalDatabaseReplicaSpecRequestBodyRequestBodyToControlplaneDatabaseReplicaSpec(v *DatabaseReplicaSpecRequestBodyRequestBody) *controlplane.DatabaseReplicaSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseReplicaSpec{ + InstanceID: v.InstanceID, + HostID: v.HostID, + } + + return res +} + +// marshalDatabaseUserSpecRequestBodyRequestBodyToControlplaneDatabaseUserSpec +// builds a value of type *controlplane.DatabaseUserSpec from a value of type +// *DatabaseUserSpecRequestBodyRequestBody. +func marshalDatabaseUserSpecRequestBodyRequestBodyToControlplaneDatabaseUserSpec(v *DatabaseUserSpecRequestBodyRequestBody) *controlplane.DatabaseUserSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseUserSpec{ + Username: v.Username, + Password: v.Password, + Superuser: v.Superuser, + } + if v.Roles != nil { + res.Roles = make([]string, len(v.Roles)) + for i, val := range v.Roles { + res.Roles[i] = val + } + } + + return res +} + +// marshalDatabaseExtensionSpecRequestBodyRequestBodyToControlplaneDatabaseExtensionSpec +// builds a value of type *controlplane.DatabaseExtensionSpec from a value of +// type *DatabaseExtensionSpecRequestBodyRequestBody. +func marshalDatabaseExtensionSpecRequestBodyRequestBodyToControlplaneDatabaseExtensionSpec(v *DatabaseExtensionSpecRequestBodyRequestBody) *controlplane.DatabaseExtensionSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseExtensionSpec{ + Name: v.Name, + Version: v.Version, + } + + return res +} + +// marshalBackupConfigSpecRequestBodyRequestBodyToControlplaneBackupConfigSpec +// builds a value of type *controlplane.BackupConfigSpec from a value of type +// *BackupConfigSpecRequestBodyRequestBody. +func marshalBackupConfigSpecRequestBodyRequestBodyToControlplaneBackupConfigSpec(v *BackupConfigSpecRequestBodyRequestBody) *controlplane.BackupConfigSpec { + if v == nil { + return nil + } + res := &controlplane.BackupConfigSpec{ + ID: v.ID, + Provider: v.Provider, + } + if v.NodeNames != nil { + res.NodeNames = make([]string, len(v.NodeNames)) + for i, val := range v.NodeNames { + res.NodeNames[i] = val + } + } + if v.Repositories != nil { + res.Repositories = make([]*controlplane.BackupRepositorySpec, len(v.Repositories)) + for i, val := range v.Repositories { + res.Repositories[i] = marshalBackupRepositorySpecRequestBodyRequestBodyToControlplaneBackupRepositorySpec(val) + } + } + if v.Schedules != nil { + res.Schedules = make([]*controlplane.BackupScheduleSpec, len(v.Schedules)) + for i, val := range v.Schedules { + res.Schedules[i] = marshalBackupScheduleSpecRequestBodyRequestBodyToControlplaneBackupScheduleSpec(val) + } + } + + return res +} + +// marshalBackupRepositorySpecRequestBodyRequestBodyToControlplaneBackupRepositorySpec +// builds a value of type *controlplane.BackupRepositorySpec from a value of +// type *BackupRepositorySpecRequestBodyRequestBody. +func marshalBackupRepositorySpecRequestBodyRequestBodyToControlplaneBackupRepositorySpec(v *BackupRepositorySpecRequestBodyRequestBody) *controlplane.BackupRepositorySpec { + if v == nil { + return nil + } + res := &controlplane.BackupRepositorySpec{ + ID: v.ID, + Type: v.Type, + S3Bucket: v.S3Bucket, + S3Region: v.S3Region, + S3Endpoint: v.S3Endpoint, + GcsBucket: v.GcsBucket, + GcsEndpoint: v.GcsEndpoint, + AzureAccount: v.AzureAccount, + AzureContainer: v.AzureContainer, + AzureEndpoint: v.AzureEndpoint, + RetentionFull: v.RetentionFull, + RetentionFullType: v.RetentionFullType, + BasePath: v.BasePath, + } + + return res +} + +// marshalBackupScheduleSpecRequestBodyRequestBodyToControlplaneBackupScheduleSpec +// builds a value of type *controlplane.BackupScheduleSpec from a value of type +// *BackupScheduleSpecRequestBodyRequestBody. +func marshalBackupScheduleSpecRequestBodyRequestBodyToControlplaneBackupScheduleSpec(v *BackupScheduleSpecRequestBodyRequestBody) *controlplane.BackupScheduleSpec { + if v == nil { + return nil + } + res := &controlplane.BackupScheduleSpec{ + ID: v.ID, + Type: v.Type, + CronExpression: v.CronExpression, + } + + return res +} diff --git a/api/gen/http/control_plane/client/paths.go b/api/gen/http/control_plane/client/paths.go new file mode 100644 index 00000000..0a6c7107 --- /dev/null +++ b/api/gen/http/control_plane/client/paths.go @@ -0,0 +1,57 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// HTTP request path constructors for the control-plane service. +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package client + +import ( + "fmt" +) + +// InspectClusterControlPlanePath returns the URL path to the control-plane service inspect-cluster HTTP endpoint. +func InspectClusterControlPlanePath() string { + return "/cluster" +} + +// ListHostsControlPlanePath returns the URL path to the control-plane service list-hosts HTTP endpoint. +func ListHostsControlPlanePath() string { + return "/hosts" +} + +// InspectHostControlPlanePath returns the URL path to the control-plane service inspect-host HTTP endpoint. +func InspectHostControlPlanePath(hostID string) string { + return fmt.Sprintf("/hosts/%v", hostID) +} + +// RemoveHostControlPlanePath returns the URL path to the control-plane service remove-host HTTP endpoint. +func RemoveHostControlPlanePath(hostID string) string { + return fmt.Sprintf("/hosts/%v", hostID) +} + +// ListDatabasesControlPlanePath returns the URL path to the control-plane service list-databases HTTP endpoint. +func ListDatabasesControlPlanePath() string { + return "/databases" +} + +// CreateDatabaseControlPlanePath returns the URL path to the control-plane service create-database HTTP endpoint. +func CreateDatabaseControlPlanePath() string { + return "/databases" +} + +// InspectDatabaseControlPlanePath returns the URL path to the control-plane service inspect-database HTTP endpoint. +func InspectDatabaseControlPlanePath(databaseID string) string { + return fmt.Sprintf("/databases/%v", databaseID) +} + +// UpdateDatabaseControlPlanePath returns the URL path to the control-plane service update-database HTTP endpoint. +func UpdateDatabaseControlPlanePath(databaseID string) string { + return fmt.Sprintf("/databases/%v", databaseID) +} + +// DeleteDatabaseControlPlanePath returns the URL path to the control-plane service delete-database HTTP endpoint. +func DeleteDatabaseControlPlanePath(databaseID string) string { + return fmt.Sprintf("/databases/%v", databaseID) +} diff --git a/api/gen/http/control_plane/client/types.go b/api/gen/http/control_plane/client/types.go new file mode 100644 index 00000000..b2fd4d56 --- /dev/null +++ b/api/gen/http/control_plane/client/types.go @@ -0,0 +1,2043 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// control-plane HTTP client types +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package client + +import ( + controlplane "github.com/pgEdge/control-plane/api/gen/control_plane" + goa "goa.design/goa/v3/pkg" +) + +// CreateDatabaseRequestBody is the type of the "control-plane" service +// "create-database" endpoint HTTP request body. +type CreateDatabaseRequestBody struct { + // Unique identifier for the database. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // Unique identifier for the databases's owner. + TenantID *string `form:"tenant_id,omitempty" json:"tenant_id,omitempty" xml:"tenant_id,omitempty"` + // The specification for the database. + Spec *DatabaseSpecRequestBody `form:"spec,omitempty" json:"spec,omitempty" xml:"spec,omitempty"` +} + +// UpdateDatabaseRequestBody is the type of the "control-plane" service +// "update-database" endpoint HTTP request body. +type UpdateDatabaseRequestBody struct { + // The specification for the database. + Spec *DatabaseSpecRequestBodyRequestBody `form:"spec,omitempty" json:"spec,omitempty" xml:"spec,omitempty"` +} + +// InspectClusterResponseBody is the type of the "control-plane" service +// "inspect-cluster" endpoint HTTP response body. +type InspectClusterResponseBody struct { + // Unique identifier for the cluster. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // Unique identifier for the cluster's owner. + TenantID *string `form:"tenant_id,omitempty" json:"tenant_id,omitempty" xml:"tenant_id,omitempty"` + // Current status of the cluster. + Status *ClusterStatusResponseBody `form:"status,omitempty" json:"status,omitempty" xml:"status,omitempty"` + // All of the hosts in the cluster. + Hosts []*HostResponseBody `form:"hosts,omitempty" json:"hosts,omitempty" xml:"hosts,omitempty"` +} + +// ListHostsResponseBody is the type of the "control-plane" service +// "list-hosts" endpoint HTTP response body. +type ListHostsResponseBody []*HostResponse + +// InspectHostResponseBody is the type of the "control-plane" service +// "inspect-host" endpoint HTTP response body. +type InspectHostResponseBody struct { + // Unique identifier for the host + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of this host + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The cohort that this host belongs to + Cohort *string `form:"cohort,omitempty" json:"cohort,omitempty" xml:"cohort,omitempty"` + // The hostname of this host. + Hostname *string `form:"hostname,omitempty" json:"hostname,omitempty" xml:"hostname,omitempty"` + // The IPv4 address of this host. + Ipv4Address *string `form:"ipv4_address,omitempty" json:"ipv4_address,omitempty" xml:"ipv4_address,omitempty"` + // The configuration for this host + Config *HostConfigurationResponseBody `form:"config,omitempty" json:"config,omitempty" xml:"config,omitempty"` + // Current status of the host + Status *HostStatusResponseBody `form:"status,omitempty" json:"status,omitempty" xml:"status,omitempty"` +} + +// ListDatabasesResponseBody is the type of the "control-plane" service +// "list-databases" endpoint HTTP response body. +type ListDatabasesResponseBody []*DatabaseResponse + +// CreateDatabaseResponseBody is the type of the "control-plane" service +// "create-database" endpoint HTTP response body. +type CreateDatabaseResponseBody struct { + // Unique identifier for the database. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // Unique identifier for the databases's owner. + TenantID *string `form:"tenant_id,omitempty" json:"tenant_id,omitempty" xml:"tenant_id,omitempty"` + // The time that the database was created. + CreatedAt *string `form:"created_at,omitempty" json:"created_at,omitempty" xml:"created_at,omitempty"` + // The time that the database was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` + // Current status of the database. + Status *DatabaseStatusResponseBody `form:"status,omitempty" json:"status,omitempty" xml:"status,omitempty"` + // All of the instances in the database. + Instances *InstanceResponseBody `form:"instances,omitempty" json:"instances,omitempty" xml:"instances,omitempty"` + // The user-provided specification for the database. + Spec *DatabaseSpecResponseBody `form:"spec,omitempty" json:"spec,omitempty" xml:"spec,omitempty"` +} + +// InspectDatabaseResponseBody is the type of the "control-plane" service +// "inspect-database" endpoint HTTP response body. +type InspectDatabaseResponseBody struct { + // Unique identifier for the database. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // Unique identifier for the databases's owner. + TenantID *string `form:"tenant_id,omitempty" json:"tenant_id,omitempty" xml:"tenant_id,omitempty"` + // The time that the database was created. + CreatedAt *string `form:"created_at,omitempty" json:"created_at,omitempty" xml:"created_at,omitempty"` + // The time that the database was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` + // Current status of the database. + Status *DatabaseStatusResponseBody `form:"status,omitempty" json:"status,omitempty" xml:"status,omitempty"` + // All of the instances in the database. + Instances *InstanceResponseBody `form:"instances,omitempty" json:"instances,omitempty" xml:"instances,omitempty"` + // The user-provided specification for the database. + Spec *DatabaseSpecResponseBody `form:"spec,omitempty" json:"spec,omitempty" xml:"spec,omitempty"` +} + +// UpdateDatabaseResponseBody is the type of the "control-plane" service +// "update-database" endpoint HTTP response body. +type UpdateDatabaseResponseBody struct { + // Unique identifier for the database. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // Unique identifier for the databases's owner. + TenantID *string `form:"tenant_id,omitempty" json:"tenant_id,omitempty" xml:"tenant_id,omitempty"` + // The time that the database was created. + CreatedAt *string `form:"created_at,omitempty" json:"created_at,omitempty" xml:"created_at,omitempty"` + // The time that the database was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` + // Current status of the database. + Status *DatabaseStatusResponseBody `form:"status,omitempty" json:"status,omitempty" xml:"status,omitempty"` + // All of the instances in the database. + Instances *InstanceResponseBody `form:"instances,omitempty" json:"instances,omitempty" xml:"instances,omitempty"` + // The user-provided specification for the database. + Spec *DatabaseSpecResponseBody `form:"spec,omitempty" json:"spec,omitempty" xml:"spec,omitempty"` +} + +// ClusterStatusResponseBody is used to define fields on response body types. +type ClusterStatusResponseBody struct { + // The current state of the cluster. + State *string `form:"state,omitempty" json:"state,omitempty" xml:"state,omitempty"` +} + +// HostResponseBody is used to define fields on response body types. +type HostResponseBody struct { + // Unique identifier for the host + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of this host + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The cohort that this host belongs to + Cohort *string `form:"cohort,omitempty" json:"cohort,omitempty" xml:"cohort,omitempty"` + // The hostname of this host. + Hostname *string `form:"hostname,omitempty" json:"hostname,omitempty" xml:"hostname,omitempty"` + // The IPv4 address of this host. + Ipv4Address *string `form:"ipv4_address,omitempty" json:"ipv4_address,omitempty" xml:"ipv4_address,omitempty"` + // The configuration for this host + Config *HostConfigurationResponseBody `form:"config,omitempty" json:"config,omitempty" xml:"config,omitempty"` + // Current status of the host + Status *HostStatusResponseBody `form:"status,omitempty" json:"status,omitempty" xml:"status,omitempty"` +} + +// HostConfigurationResponseBody is used to define fields on response body +// types. +type HostConfigurationResponseBody struct { + // Enables the Vector service for metrics and log collection + VectorEnabled *bool `form:"vector_enabled,omitempty" json:"vector_enabled,omitempty" xml:"vector_enabled,omitempty"` + // Enables the Treafik load balancer + TraefikEnabled *bool `form:"traefik_enabled,omitempty" json:"traefik_enabled,omitempty" xml:"traefik_enabled,omitempty"` +} + +// HostStatusResponseBody is used to define fields on response body types. +type HostStatusResponseBody struct { + State *string `form:"state,omitempty" json:"state,omitempty" xml:"state,omitempty"` +} + +// HostResponse is used to define fields on response body types. +type HostResponse struct { + // Unique identifier for the host + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of this host + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The cohort that this host belongs to + Cohort *string `form:"cohort,omitempty" json:"cohort,omitempty" xml:"cohort,omitempty"` + // The hostname of this host. + Hostname *string `form:"hostname,omitempty" json:"hostname,omitempty" xml:"hostname,omitempty"` + // The IPv4 address of this host. + Ipv4Address *string `form:"ipv4_address,omitempty" json:"ipv4_address,omitempty" xml:"ipv4_address,omitempty"` + // The configuration for this host + Config *HostConfigurationResponse `form:"config,omitempty" json:"config,omitempty" xml:"config,omitempty"` + // Current status of the host + Status *HostStatusResponse `form:"status,omitempty" json:"status,omitempty" xml:"status,omitempty"` +} + +// HostConfigurationResponse is used to define fields on response body types. +type HostConfigurationResponse struct { + // Enables the Vector service for metrics and log collection + VectorEnabled *bool `form:"vector_enabled,omitempty" json:"vector_enabled,omitempty" xml:"vector_enabled,omitempty"` + // Enables the Treafik load balancer + TraefikEnabled *bool `form:"traefik_enabled,omitempty" json:"traefik_enabled,omitempty" xml:"traefik_enabled,omitempty"` +} + +// HostStatusResponse is used to define fields on response body types. +type HostStatusResponse struct { + State *string `form:"state,omitempty" json:"state,omitempty" xml:"state,omitempty"` +} + +// DatabaseResponse is used to define fields on response body types. +type DatabaseResponse struct { + // Unique identifier for the database. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // Unique identifier for the databases's owner. + TenantID *string `form:"tenant_id,omitempty" json:"tenant_id,omitempty" xml:"tenant_id,omitempty"` + // The time that the database was created. + CreatedAt *string `form:"created_at,omitempty" json:"created_at,omitempty" xml:"created_at,omitempty"` + // The time that the database was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` + // Current status of the database. + Status *DatabaseStatusResponse `form:"status,omitempty" json:"status,omitempty" xml:"status,omitempty"` + // All of the instances in the database. + Instances *InstanceResponse `form:"instances,omitempty" json:"instances,omitempty" xml:"instances,omitempty"` + // The user-provided specification for the database. + Spec *DatabaseSpecResponse `form:"spec,omitempty" json:"spec,omitempty" xml:"spec,omitempty"` +} + +// DatabaseStatusResponse is used to define fields on response body types. +type DatabaseStatusResponse struct { + State *string `form:"state,omitempty" json:"state,omitempty" xml:"state,omitempty"` + // The time that the database status was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` +} + +// InstanceResponse is used to define fields on response body types. +type InstanceResponse struct { + // Unique identifier for the instance. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The ID of the host this instance is running on. + HostID *string `form:"host_id,omitempty" json:"host_id,omitempty" xml:"host_id,omitempty"` + // The Spock node name for this instance. + NodeName *string `form:"node_name,omitempty" json:"node_name,omitempty" xml:"node_name,omitempty"` + // The time that the instance was created. + CreatedAt *string `form:"created_at,omitempty" json:"created_at,omitempty" xml:"created_at,omitempty"` + // The time that the instance was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` + // Current status of the instance. + Status *InstanceStatusResponse `form:"status,omitempty" json:"status,omitempty" xml:"status,omitempty"` + // All interfaces that this instance serves on. + Interfaces []*InstanceInterfaceResponse `form:"interfaces,omitempty" json:"interfaces,omitempty" xml:"interfaces,omitempty"` +} + +// InstanceStatusResponse is used to define fields on response body types. +type InstanceStatusResponse struct { + State *string `form:"state,omitempty" json:"state,omitempty" xml:"state,omitempty"` + PatroniState *string `form:"patroni_state,omitempty" json:"patroni_state,omitempty" xml:"patroni_state,omitempty"` + Role *string `form:"role,omitempty" json:"role,omitempty" xml:"role,omitempty"` + // True if this instance is in read-only mode. + ReadOnly *bool `form:"read_only,omitempty" json:"read_only,omitempty" xml:"read_only,omitempty"` + // True if this instance is pending to be restarted from a configuration change. + PendingRestart *bool `form:"pending_restart,omitempty" json:"pending_restart,omitempty" xml:"pending_restart,omitempty"` + // True if Patroni has been paused for this instance. + PatroniPaused *bool `form:"patroni_paused,omitempty" json:"patroni_paused,omitempty" xml:"patroni_paused,omitempty"` + // The version of Postgres for this instance. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The version of Spock for this instance. + SpockVersion *string `form:"spock_version,omitempty" json:"spock_version,omitempty" xml:"spock_version,omitempty"` + // The time that the instance status was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` +} + +// InstanceInterfaceResponse is used to define fields on response body types. +type InstanceInterfaceResponse struct { + // The type of network for this interface. + NetworkType *string `form:"network_type,omitempty" json:"network_type,omitempty" xml:"network_type,omitempty"` + // The unique identifier of the network for this interface. + NetworkID *string `form:"network_id,omitempty" json:"network_id,omitempty" xml:"network_id,omitempty"` + // The hostname of the instance on this interface. + Hostname *string `form:"hostname,omitempty" json:"hostname,omitempty" xml:"hostname,omitempty"` + // The IPv4 address of the instance on this interface. + Ipv4Address *string `form:"ipv4_address,omitempty" json:"ipv4_address,omitempty" xml:"ipv4_address,omitempty"` + // The Postgres port for the instance on this interface. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` +} + +// DatabaseSpecResponse is used to define fields on response body types. +type DatabaseSpecResponse struct { + // The name of the Postgres database. + DatabaseName *string `form:"database_name,omitempty" json:"database_name,omitempty" xml:"database_name,omitempty"` + // The major version of the Postgres database. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The major version of the Spock extension. + SpockVersion *string `form:"spock_version,omitempty" json:"spock_version,omitempty" xml:"spock_version,omitempty"` + // The port used by the Postgres database. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Prevents deletion when true. + DeletionProtection *bool `form:"deletion_protection,omitempty" json:"deletion_protection,omitempty" xml:"deletion_protection,omitempty"` + // The Spock nodes for this database. + Nodes []*DatabaseNodeSpecResponse `form:"nodes,omitempty" json:"nodes,omitempty" xml:"nodes,omitempty"` + // The users to create for this database. + DatabaseUsers []*DatabaseUserSpecResponse `form:"database_users,omitempty" json:"database_users,omitempty" xml:"database_users,omitempty"` + // The extensions to install for this database. + Extensions []*DatabaseExtensionSpecResponse `form:"extensions,omitempty" json:"extensions,omitempty" xml:"extensions,omitempty"` + // The feature flags for this database. + Features map[string]string `form:"features,omitempty" json:"features,omitempty" xml:"features,omitempty"` + // The backup configurations for this database. + BackupConfigs []*BackupConfigSpecResponse `form:"backup_configs,omitempty" json:"backup_configs,omitempty" xml:"backup_configs,omitempty"` + // Additional postgresql.conf settings. Will be merged with the settings + // provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseNodeSpecResponse is used to define fields on response body types. +type DatabaseNodeSpecResponse struct { + // The name of the database node. + Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + // A unique identifier for the instance that will be created from this node + // specification. + InstanceID *string `form:"instance_id,omitempty" json:"instance_id,omitempty" xml:"instance_id,omitempty"` + // The ID of the host that should run this node. + HostID *string `form:"host_id,omitempty" json:"host_id,omitempty" xml:"host_id,omitempty"` + // The major version of Postgres for this node. Overrides the Postgres version + // set in the DatabaseSpec. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The port used by the Postgres database for this node. Overrides the Postgres + // port set in the DatabaseSpec. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Read replicas for this database node. + ReadReplicas *DatabaseReplicaSpecResponse `form:"read_replicas,omitempty" json:"read_replicas,omitempty" xml:"read_replicas,omitempty"` + // Additional postgresql.conf settings for this particular node. Will be merged + // with the settings provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseReplicaSpecResponse is used to define fields on response body types. +type DatabaseReplicaSpecResponse struct { + // A unique identifier for the instance that will be created from this replica + // specification. + InstanceID *string `form:"instance_id,omitempty" json:"instance_id,omitempty" xml:"instance_id,omitempty"` + // The ID of the host that should run this read replica. + HostID *string `form:"host_id,omitempty" json:"host_id,omitempty" xml:"host_id,omitempty"` +} + +// DatabaseUserSpecResponse is used to define fields on response body types. +type DatabaseUserSpecResponse struct { + // The username for this database user. + Username *string `form:"username,omitempty" json:"username,omitempty" xml:"username,omitempty"` + // The password for this database user. + Password *string `form:"password,omitempty" json:"password,omitempty" xml:"password,omitempty"` + // The roles to assign to this database user. + Roles []string `form:"roles,omitempty" json:"roles,omitempty" xml:"roles,omitempty"` + // Enables SUPERUSER for this database user when true. + Superuser *bool `form:"superuser,omitempty" json:"superuser,omitempty" xml:"superuser,omitempty"` +} + +// DatabaseExtensionSpecResponse is used to define fields on response body +// types. +type DatabaseExtensionSpecResponse struct { + // The name of the extension to install in this database. + Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + // The version of the extension to install in this database. + Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` +} + +// BackupConfigSpecResponse is used to define fields on response body types. +type BackupConfigSpecResponse struct { + // The unique identifier for this backup configuration. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The names of the nodes where this backup configuration should be applied. + // The configuration will apply to all nodes when this field is empty or + // unspecified. + NodeNames []string `form:"node_names,omitempty" json:"node_names,omitempty" xml:"node_names,omitempty"` + // The backup provider for this backup configuration. + Provider *string `form:"provider,omitempty" json:"provider,omitempty" xml:"provider,omitempty"` + // The repositories for this backup configuration. + Repositories []*BackupRepositorySpecResponse `form:"repositories,omitempty" json:"repositories,omitempty" xml:"repositories,omitempty"` + // The schedules for this backup configuration. + Schedules []*BackupScheduleSpecResponse `form:"schedules,omitempty" json:"schedules,omitempty" xml:"schedules,omitempty"` +} + +// BackupRepositorySpecResponse is used to define fields on response body types. +type BackupRepositorySpecResponse struct { + // The unique identifier of this repository. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of this repository. + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The S3 bucket name for this repository. Only applies when type = 's3'. + S3Bucket *string `form:"s3_bucket,omitempty" json:"s3_bucket,omitempty" xml:"s3_bucket,omitempty"` + // The region of the S3 bucket for this repository. Only applies when type = + // 's3'. + S3Region *string `form:"s3_region,omitempty" json:"s3_region,omitempty" xml:"s3_region,omitempty"` + // The optional S3 endpoint for this repository. Only applies when type = 's3'. + S3Endpoint *string `form:"s3_endpoint,omitempty" json:"s3_endpoint,omitempty" xml:"s3_endpoint,omitempty"` + // The GCS bucket name for this repository. Only applies when type = 'gcs'. + GcsBucket *string `form:"gcs_bucket,omitempty" json:"gcs_bucket,omitempty" xml:"gcs_bucket,omitempty"` + // The optional GCS endpoint for this repository. Only applies when type = + // 'gcs'. + GcsEndpoint *string `form:"gcs_endpoint,omitempty" json:"gcs_endpoint,omitempty" xml:"gcs_endpoint,omitempty"` + // The Azure account name for this repository. Only applies when type = 'azure'. + AzureAccount *string `form:"azure_account,omitempty" json:"azure_account,omitempty" xml:"azure_account,omitempty"` + // The Azure container name for this repository. Only applies when type = + // 'azure'. + AzureContainer *string `form:"azure_container,omitempty" json:"azure_container,omitempty" xml:"azure_container,omitempty"` + // The optional Azure endpoint for this repository. Only applies when type = + // 'azure'. + AzureEndpoint *string `form:"azure_endpoint,omitempty" json:"azure_endpoint,omitempty" xml:"azure_endpoint,omitempty"` + // The count of full backups to retain or the time to retain full backups. + RetentionFull *int `form:"retention_full,omitempty" json:"retention_full,omitempty" xml:"retention_full,omitempty"` + // The type of measure used for retention_full. + RetentionFullType *string `form:"retention_full_type,omitempty" json:"retention_full_type,omitempty" xml:"retention_full_type,omitempty"` + // The base path within the repository to store backups. + BasePath *string `form:"base_path,omitempty" json:"base_path,omitempty" xml:"base_path,omitempty"` +} + +// BackupScheduleSpecResponse is used to define fields on response body types. +type BackupScheduleSpecResponse struct { + // The unique identifier for this backup schedule. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of backup to take on this schedule. + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The cron expression for this schedule. + CronExpression *string `form:"cron_expression,omitempty" json:"cron_expression,omitempty" xml:"cron_expression,omitempty"` +} + +// DatabaseSpecRequestBody is used to define fields on request body types. +type DatabaseSpecRequestBody struct { + // The name of the Postgres database. + DatabaseName string `form:"database_name" json:"database_name" xml:"database_name"` + // The major version of the Postgres database. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The major version of the Spock extension. + SpockVersion *string `form:"spock_version,omitempty" json:"spock_version,omitempty" xml:"spock_version,omitempty"` + // The port used by the Postgres database. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Prevents deletion when true. + DeletionProtection *bool `form:"deletion_protection,omitempty" json:"deletion_protection,omitempty" xml:"deletion_protection,omitempty"` + // The Spock nodes for this database. + Nodes []*DatabaseNodeSpecRequestBody `form:"nodes" json:"nodes" xml:"nodes"` + // The users to create for this database. + DatabaseUsers []*DatabaseUserSpecRequestBody `form:"database_users,omitempty" json:"database_users,omitempty" xml:"database_users,omitempty"` + // The extensions to install for this database. + Extensions []*DatabaseExtensionSpecRequestBody `form:"extensions,omitempty" json:"extensions,omitempty" xml:"extensions,omitempty"` + // The feature flags for this database. + Features map[string]string `form:"features,omitempty" json:"features,omitempty" xml:"features,omitempty"` + // The backup configurations for this database. + BackupConfigs []*BackupConfigSpecRequestBody `form:"backup_configs,omitempty" json:"backup_configs,omitempty" xml:"backup_configs,omitempty"` + // Additional postgresql.conf settings. Will be merged with the settings + // provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseNodeSpecRequestBody is used to define fields on request body types. +type DatabaseNodeSpecRequestBody struct { + // The name of the database node. + Name string `form:"name" json:"name" xml:"name"` + // A unique identifier for the instance that will be created from this node + // specification. + InstanceID string `form:"instance_id" json:"instance_id" xml:"instance_id"` + // The ID of the host that should run this node. + HostID string `form:"host_id" json:"host_id" xml:"host_id"` + // The major version of Postgres for this node. Overrides the Postgres version + // set in the DatabaseSpec. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The port used by the Postgres database for this node. Overrides the Postgres + // port set in the DatabaseSpec. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Read replicas for this database node. + ReadReplicas *DatabaseReplicaSpecRequestBody `form:"read_replicas,omitempty" json:"read_replicas,omitempty" xml:"read_replicas,omitempty"` + // Additional postgresql.conf settings for this particular node. Will be merged + // with the settings provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseReplicaSpecRequestBody is used to define fields on request body +// types. +type DatabaseReplicaSpecRequestBody struct { + // A unique identifier for the instance that will be created from this replica + // specification. + InstanceID string `form:"instance_id" json:"instance_id" xml:"instance_id"` + // The ID of the host that should run this read replica. + HostID string `form:"host_id" json:"host_id" xml:"host_id"` +} + +// DatabaseUserSpecRequestBody is used to define fields on request body types. +type DatabaseUserSpecRequestBody struct { + // The username for this database user. + Username string `form:"username" json:"username" xml:"username"` + // The password for this database user. + Password string `form:"password" json:"password" xml:"password"` + // The roles to assign to this database user. + Roles []string `form:"roles,omitempty" json:"roles,omitempty" xml:"roles,omitempty"` + // Enables SUPERUSER for this database user when true. + Superuser *bool `form:"superuser,omitempty" json:"superuser,omitempty" xml:"superuser,omitempty"` +} + +// DatabaseExtensionSpecRequestBody is used to define fields on request body +// types. +type DatabaseExtensionSpecRequestBody struct { + // The name of the extension to install in this database. + Name string `form:"name" json:"name" xml:"name"` + // The version of the extension to install in this database. + Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` +} + +// BackupConfigSpecRequestBody is used to define fields on request body types. +type BackupConfigSpecRequestBody struct { + // The unique identifier for this backup configuration. + ID string `form:"id" json:"id" xml:"id"` + // The names of the nodes where this backup configuration should be applied. + // The configuration will apply to all nodes when this field is empty or + // unspecified. + NodeNames []string `form:"node_names,omitempty" json:"node_names,omitempty" xml:"node_names,omitempty"` + // The backup provider for this backup configuration. + Provider string `form:"provider" json:"provider" xml:"provider"` + // The repositories for this backup configuration. + Repositories []*BackupRepositorySpecRequestBody `form:"repositories,omitempty" json:"repositories,omitempty" xml:"repositories,omitempty"` + // The schedules for this backup configuration. + Schedules []*BackupScheduleSpecRequestBody `form:"schedules,omitempty" json:"schedules,omitempty" xml:"schedules,omitempty"` +} + +// BackupRepositorySpecRequestBody is used to define fields on request body +// types. +type BackupRepositorySpecRequestBody struct { + // The unique identifier of this repository. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of this repository. + Type string `form:"type" json:"type" xml:"type"` + // The S3 bucket name for this repository. Only applies when type = 's3'. + S3Bucket *string `form:"s3_bucket,omitempty" json:"s3_bucket,omitempty" xml:"s3_bucket,omitempty"` + // The region of the S3 bucket for this repository. Only applies when type = + // 's3'. + S3Region *string `form:"s3_region,omitempty" json:"s3_region,omitempty" xml:"s3_region,omitempty"` + // The optional S3 endpoint for this repository. Only applies when type = 's3'. + S3Endpoint *string `form:"s3_endpoint,omitempty" json:"s3_endpoint,omitempty" xml:"s3_endpoint,omitempty"` + // The GCS bucket name for this repository. Only applies when type = 'gcs'. + GcsBucket *string `form:"gcs_bucket,omitempty" json:"gcs_bucket,omitempty" xml:"gcs_bucket,omitempty"` + // The optional GCS endpoint for this repository. Only applies when type = + // 'gcs'. + GcsEndpoint *string `form:"gcs_endpoint,omitempty" json:"gcs_endpoint,omitempty" xml:"gcs_endpoint,omitempty"` + // The Azure account name for this repository. Only applies when type = 'azure'. + AzureAccount *string `form:"azure_account,omitempty" json:"azure_account,omitempty" xml:"azure_account,omitempty"` + // The Azure container name for this repository. Only applies when type = + // 'azure'. + AzureContainer *string `form:"azure_container,omitempty" json:"azure_container,omitempty" xml:"azure_container,omitempty"` + // The optional Azure endpoint for this repository. Only applies when type = + // 'azure'. + AzureEndpoint *string `form:"azure_endpoint,omitempty" json:"azure_endpoint,omitempty" xml:"azure_endpoint,omitempty"` + // The count of full backups to retain or the time to retain full backups. + RetentionFull *int `form:"retention_full,omitempty" json:"retention_full,omitempty" xml:"retention_full,omitempty"` + // The type of measure used for retention_full. + RetentionFullType *string `form:"retention_full_type,omitempty" json:"retention_full_type,omitempty" xml:"retention_full_type,omitempty"` + // The base path within the repository to store backups. + BasePath *string `form:"base_path,omitempty" json:"base_path,omitempty" xml:"base_path,omitempty"` +} + +// BackupScheduleSpecRequestBody is used to define fields on request body types. +type BackupScheduleSpecRequestBody struct { + // The unique identifier for this backup schedule. + ID string `form:"id" json:"id" xml:"id"` + // The type of backup to take on this schedule. + Type string `form:"type" json:"type" xml:"type"` + // The cron expression for this schedule. + CronExpression string `form:"cron_expression" json:"cron_expression" xml:"cron_expression"` +} + +// DatabaseStatusResponseBody is used to define fields on response body types. +type DatabaseStatusResponseBody struct { + State *string `form:"state,omitempty" json:"state,omitempty" xml:"state,omitempty"` + // The time that the database status was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` +} + +// InstanceResponseBody is used to define fields on response body types. +type InstanceResponseBody struct { + // Unique identifier for the instance. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The ID of the host this instance is running on. + HostID *string `form:"host_id,omitempty" json:"host_id,omitempty" xml:"host_id,omitempty"` + // The Spock node name for this instance. + NodeName *string `form:"node_name,omitempty" json:"node_name,omitempty" xml:"node_name,omitempty"` + // The time that the instance was created. + CreatedAt *string `form:"created_at,omitempty" json:"created_at,omitempty" xml:"created_at,omitempty"` + // The time that the instance was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` + // Current status of the instance. + Status *InstanceStatusResponseBody `form:"status,omitempty" json:"status,omitempty" xml:"status,omitempty"` + // All interfaces that this instance serves on. + Interfaces []*InstanceInterfaceResponseBody `form:"interfaces,omitempty" json:"interfaces,omitempty" xml:"interfaces,omitempty"` +} + +// InstanceStatusResponseBody is used to define fields on response body types. +type InstanceStatusResponseBody struct { + State *string `form:"state,omitempty" json:"state,omitempty" xml:"state,omitempty"` + PatroniState *string `form:"patroni_state,omitempty" json:"patroni_state,omitempty" xml:"patroni_state,omitempty"` + Role *string `form:"role,omitempty" json:"role,omitempty" xml:"role,omitempty"` + // True if this instance is in read-only mode. + ReadOnly *bool `form:"read_only,omitempty" json:"read_only,omitempty" xml:"read_only,omitempty"` + // True if this instance is pending to be restarted from a configuration change. + PendingRestart *bool `form:"pending_restart,omitempty" json:"pending_restart,omitempty" xml:"pending_restart,omitempty"` + // True if Patroni has been paused for this instance. + PatroniPaused *bool `form:"patroni_paused,omitempty" json:"patroni_paused,omitempty" xml:"patroni_paused,omitempty"` + // The version of Postgres for this instance. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The version of Spock for this instance. + SpockVersion *string `form:"spock_version,omitempty" json:"spock_version,omitempty" xml:"spock_version,omitempty"` + // The time that the instance status was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` +} + +// InstanceInterfaceResponseBody is used to define fields on response body +// types. +type InstanceInterfaceResponseBody struct { + // The type of network for this interface. + NetworkType *string `form:"network_type,omitempty" json:"network_type,omitempty" xml:"network_type,omitempty"` + // The unique identifier of the network for this interface. + NetworkID *string `form:"network_id,omitempty" json:"network_id,omitempty" xml:"network_id,omitempty"` + // The hostname of the instance on this interface. + Hostname *string `form:"hostname,omitempty" json:"hostname,omitempty" xml:"hostname,omitempty"` + // The IPv4 address of the instance on this interface. + Ipv4Address *string `form:"ipv4_address,omitempty" json:"ipv4_address,omitempty" xml:"ipv4_address,omitempty"` + // The Postgres port for the instance on this interface. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` +} + +// DatabaseSpecResponseBody is used to define fields on response body types. +type DatabaseSpecResponseBody struct { + // The name of the Postgres database. + DatabaseName *string `form:"database_name,omitempty" json:"database_name,omitempty" xml:"database_name,omitempty"` + // The major version of the Postgres database. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The major version of the Spock extension. + SpockVersion *string `form:"spock_version,omitempty" json:"spock_version,omitempty" xml:"spock_version,omitempty"` + // The port used by the Postgres database. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Prevents deletion when true. + DeletionProtection *bool `form:"deletion_protection,omitempty" json:"deletion_protection,omitempty" xml:"deletion_protection,omitempty"` + // The Spock nodes for this database. + Nodes []*DatabaseNodeSpecResponseBody `form:"nodes,omitempty" json:"nodes,omitempty" xml:"nodes,omitempty"` + // The users to create for this database. + DatabaseUsers []*DatabaseUserSpecResponseBody `form:"database_users,omitempty" json:"database_users,omitempty" xml:"database_users,omitempty"` + // The extensions to install for this database. + Extensions []*DatabaseExtensionSpecResponseBody `form:"extensions,omitempty" json:"extensions,omitempty" xml:"extensions,omitempty"` + // The feature flags for this database. + Features map[string]string `form:"features,omitempty" json:"features,omitempty" xml:"features,omitempty"` + // The backup configurations for this database. + BackupConfigs []*BackupConfigSpecResponseBody `form:"backup_configs,omitempty" json:"backup_configs,omitempty" xml:"backup_configs,omitempty"` + // Additional postgresql.conf settings. Will be merged with the settings + // provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseNodeSpecResponseBody is used to define fields on response body types. +type DatabaseNodeSpecResponseBody struct { + // The name of the database node. + Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + // A unique identifier for the instance that will be created from this node + // specification. + InstanceID *string `form:"instance_id,omitempty" json:"instance_id,omitempty" xml:"instance_id,omitempty"` + // The ID of the host that should run this node. + HostID *string `form:"host_id,omitempty" json:"host_id,omitempty" xml:"host_id,omitempty"` + // The major version of Postgres for this node. Overrides the Postgres version + // set in the DatabaseSpec. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The port used by the Postgres database for this node. Overrides the Postgres + // port set in the DatabaseSpec. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Read replicas for this database node. + ReadReplicas *DatabaseReplicaSpecResponseBody `form:"read_replicas,omitempty" json:"read_replicas,omitempty" xml:"read_replicas,omitempty"` + // Additional postgresql.conf settings for this particular node. Will be merged + // with the settings provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseReplicaSpecResponseBody is used to define fields on response body +// types. +type DatabaseReplicaSpecResponseBody struct { + // A unique identifier for the instance that will be created from this replica + // specification. + InstanceID *string `form:"instance_id,omitempty" json:"instance_id,omitempty" xml:"instance_id,omitempty"` + // The ID of the host that should run this read replica. + HostID *string `form:"host_id,omitempty" json:"host_id,omitempty" xml:"host_id,omitempty"` +} + +// DatabaseUserSpecResponseBody is used to define fields on response body types. +type DatabaseUserSpecResponseBody struct { + // The username for this database user. + Username *string `form:"username,omitempty" json:"username,omitempty" xml:"username,omitempty"` + // The password for this database user. + Password *string `form:"password,omitempty" json:"password,omitempty" xml:"password,omitempty"` + // The roles to assign to this database user. + Roles []string `form:"roles,omitempty" json:"roles,omitempty" xml:"roles,omitempty"` + // Enables SUPERUSER for this database user when true. + Superuser *bool `form:"superuser,omitempty" json:"superuser,omitempty" xml:"superuser,omitempty"` +} + +// DatabaseExtensionSpecResponseBody is used to define fields on response body +// types. +type DatabaseExtensionSpecResponseBody struct { + // The name of the extension to install in this database. + Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + // The version of the extension to install in this database. + Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` +} + +// BackupConfigSpecResponseBody is used to define fields on response body types. +type BackupConfigSpecResponseBody struct { + // The unique identifier for this backup configuration. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The names of the nodes where this backup configuration should be applied. + // The configuration will apply to all nodes when this field is empty or + // unspecified. + NodeNames []string `form:"node_names,omitempty" json:"node_names,omitempty" xml:"node_names,omitempty"` + // The backup provider for this backup configuration. + Provider *string `form:"provider,omitempty" json:"provider,omitempty" xml:"provider,omitempty"` + // The repositories for this backup configuration. + Repositories []*BackupRepositorySpecResponseBody `form:"repositories,omitempty" json:"repositories,omitempty" xml:"repositories,omitempty"` + // The schedules for this backup configuration. + Schedules []*BackupScheduleSpecResponseBody `form:"schedules,omitempty" json:"schedules,omitempty" xml:"schedules,omitempty"` +} + +// BackupRepositorySpecResponseBody is used to define fields on response body +// types. +type BackupRepositorySpecResponseBody struct { + // The unique identifier of this repository. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of this repository. + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The S3 bucket name for this repository. Only applies when type = 's3'. + S3Bucket *string `form:"s3_bucket,omitempty" json:"s3_bucket,omitempty" xml:"s3_bucket,omitempty"` + // The region of the S3 bucket for this repository. Only applies when type = + // 's3'. + S3Region *string `form:"s3_region,omitempty" json:"s3_region,omitempty" xml:"s3_region,omitempty"` + // The optional S3 endpoint for this repository. Only applies when type = 's3'. + S3Endpoint *string `form:"s3_endpoint,omitempty" json:"s3_endpoint,omitempty" xml:"s3_endpoint,omitempty"` + // The GCS bucket name for this repository. Only applies when type = 'gcs'. + GcsBucket *string `form:"gcs_bucket,omitempty" json:"gcs_bucket,omitempty" xml:"gcs_bucket,omitempty"` + // The optional GCS endpoint for this repository. Only applies when type = + // 'gcs'. + GcsEndpoint *string `form:"gcs_endpoint,omitempty" json:"gcs_endpoint,omitempty" xml:"gcs_endpoint,omitempty"` + // The Azure account name for this repository. Only applies when type = 'azure'. + AzureAccount *string `form:"azure_account,omitempty" json:"azure_account,omitempty" xml:"azure_account,omitempty"` + // The Azure container name for this repository. Only applies when type = + // 'azure'. + AzureContainer *string `form:"azure_container,omitempty" json:"azure_container,omitempty" xml:"azure_container,omitempty"` + // The optional Azure endpoint for this repository. Only applies when type = + // 'azure'. + AzureEndpoint *string `form:"azure_endpoint,omitempty" json:"azure_endpoint,omitempty" xml:"azure_endpoint,omitempty"` + // The count of full backups to retain or the time to retain full backups. + RetentionFull *int `form:"retention_full,omitempty" json:"retention_full,omitempty" xml:"retention_full,omitempty"` + // The type of measure used for retention_full. + RetentionFullType *string `form:"retention_full_type,omitempty" json:"retention_full_type,omitempty" xml:"retention_full_type,omitempty"` + // The base path within the repository to store backups. + BasePath *string `form:"base_path,omitempty" json:"base_path,omitempty" xml:"base_path,omitempty"` +} + +// BackupScheduleSpecResponseBody is used to define fields on response body +// types. +type BackupScheduleSpecResponseBody struct { + // The unique identifier for this backup schedule. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of backup to take on this schedule. + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The cron expression for this schedule. + CronExpression *string `form:"cron_expression,omitempty" json:"cron_expression,omitempty" xml:"cron_expression,omitempty"` +} + +// DatabaseSpecRequestBodyRequestBody is used to define fields on request body +// types. +type DatabaseSpecRequestBodyRequestBody struct { + // The name of the Postgres database. + DatabaseName string `form:"database_name" json:"database_name" xml:"database_name"` + // The major version of the Postgres database. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The major version of the Spock extension. + SpockVersion *string `form:"spock_version,omitempty" json:"spock_version,omitempty" xml:"spock_version,omitempty"` + // The port used by the Postgres database. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Prevents deletion when true. + DeletionProtection *bool `form:"deletion_protection,omitempty" json:"deletion_protection,omitempty" xml:"deletion_protection,omitempty"` + // The Spock nodes for this database. + Nodes []*DatabaseNodeSpecRequestBodyRequestBody `form:"nodes" json:"nodes" xml:"nodes"` + // The users to create for this database. + DatabaseUsers []*DatabaseUserSpecRequestBodyRequestBody `form:"database_users,omitempty" json:"database_users,omitempty" xml:"database_users,omitempty"` + // The extensions to install for this database. + Extensions []*DatabaseExtensionSpecRequestBodyRequestBody `form:"extensions,omitempty" json:"extensions,omitempty" xml:"extensions,omitempty"` + // The feature flags for this database. + Features map[string]string `form:"features,omitempty" json:"features,omitempty" xml:"features,omitempty"` + // The backup configurations for this database. + BackupConfigs []*BackupConfigSpecRequestBodyRequestBody `form:"backup_configs,omitempty" json:"backup_configs,omitempty" xml:"backup_configs,omitempty"` + // Additional postgresql.conf settings. Will be merged with the settings + // provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseNodeSpecRequestBodyRequestBody is used to define fields on request +// body types. +type DatabaseNodeSpecRequestBodyRequestBody struct { + // The name of the database node. + Name string `form:"name" json:"name" xml:"name"` + // A unique identifier for the instance that will be created from this node + // specification. + InstanceID string `form:"instance_id" json:"instance_id" xml:"instance_id"` + // The ID of the host that should run this node. + HostID string `form:"host_id" json:"host_id" xml:"host_id"` + // The major version of Postgres for this node. Overrides the Postgres version + // set in the DatabaseSpec. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The port used by the Postgres database for this node. Overrides the Postgres + // port set in the DatabaseSpec. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Read replicas for this database node. + ReadReplicas *DatabaseReplicaSpecRequestBodyRequestBody `form:"read_replicas,omitempty" json:"read_replicas,omitempty" xml:"read_replicas,omitempty"` + // Additional postgresql.conf settings for this particular node. Will be merged + // with the settings provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseReplicaSpecRequestBodyRequestBody is used to define fields on +// request body types. +type DatabaseReplicaSpecRequestBodyRequestBody struct { + // A unique identifier for the instance that will be created from this replica + // specification. + InstanceID string `form:"instance_id" json:"instance_id" xml:"instance_id"` + // The ID of the host that should run this read replica. + HostID string `form:"host_id" json:"host_id" xml:"host_id"` +} + +// DatabaseUserSpecRequestBodyRequestBody is used to define fields on request +// body types. +type DatabaseUserSpecRequestBodyRequestBody struct { + // The username for this database user. + Username string `form:"username" json:"username" xml:"username"` + // The password for this database user. + Password string `form:"password" json:"password" xml:"password"` + // The roles to assign to this database user. + Roles []string `form:"roles,omitempty" json:"roles,omitempty" xml:"roles,omitempty"` + // Enables SUPERUSER for this database user when true. + Superuser *bool `form:"superuser,omitempty" json:"superuser,omitempty" xml:"superuser,omitempty"` +} + +// DatabaseExtensionSpecRequestBodyRequestBody is used to define fields on +// request body types. +type DatabaseExtensionSpecRequestBodyRequestBody struct { + // The name of the extension to install in this database. + Name string `form:"name" json:"name" xml:"name"` + // The version of the extension to install in this database. + Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` +} + +// BackupConfigSpecRequestBodyRequestBody is used to define fields on request +// body types. +type BackupConfigSpecRequestBodyRequestBody struct { + // The unique identifier for this backup configuration. + ID string `form:"id" json:"id" xml:"id"` + // The names of the nodes where this backup configuration should be applied. + // The configuration will apply to all nodes when this field is empty or + // unspecified. + NodeNames []string `form:"node_names,omitempty" json:"node_names,omitempty" xml:"node_names,omitempty"` + // The backup provider for this backup configuration. + Provider string `form:"provider" json:"provider" xml:"provider"` + // The repositories for this backup configuration. + Repositories []*BackupRepositorySpecRequestBodyRequestBody `form:"repositories,omitempty" json:"repositories,omitempty" xml:"repositories,omitempty"` + // The schedules for this backup configuration. + Schedules []*BackupScheduleSpecRequestBodyRequestBody `form:"schedules,omitempty" json:"schedules,omitempty" xml:"schedules,omitempty"` +} + +// BackupRepositorySpecRequestBodyRequestBody is used to define fields on +// request body types. +type BackupRepositorySpecRequestBodyRequestBody struct { + // The unique identifier of this repository. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of this repository. + Type string `form:"type" json:"type" xml:"type"` + // The S3 bucket name for this repository. Only applies when type = 's3'. + S3Bucket *string `form:"s3_bucket,omitempty" json:"s3_bucket,omitempty" xml:"s3_bucket,omitempty"` + // The region of the S3 bucket for this repository. Only applies when type = + // 's3'. + S3Region *string `form:"s3_region,omitempty" json:"s3_region,omitempty" xml:"s3_region,omitempty"` + // The optional S3 endpoint for this repository. Only applies when type = 's3'. + S3Endpoint *string `form:"s3_endpoint,omitempty" json:"s3_endpoint,omitempty" xml:"s3_endpoint,omitempty"` + // The GCS bucket name for this repository. Only applies when type = 'gcs'. + GcsBucket *string `form:"gcs_bucket,omitempty" json:"gcs_bucket,omitempty" xml:"gcs_bucket,omitempty"` + // The optional GCS endpoint for this repository. Only applies when type = + // 'gcs'. + GcsEndpoint *string `form:"gcs_endpoint,omitempty" json:"gcs_endpoint,omitempty" xml:"gcs_endpoint,omitempty"` + // The Azure account name for this repository. Only applies when type = 'azure'. + AzureAccount *string `form:"azure_account,omitempty" json:"azure_account,omitempty" xml:"azure_account,omitempty"` + // The Azure container name for this repository. Only applies when type = + // 'azure'. + AzureContainer *string `form:"azure_container,omitempty" json:"azure_container,omitempty" xml:"azure_container,omitempty"` + // The optional Azure endpoint for this repository. Only applies when type = + // 'azure'. + AzureEndpoint *string `form:"azure_endpoint,omitempty" json:"azure_endpoint,omitempty" xml:"azure_endpoint,omitempty"` + // The count of full backups to retain or the time to retain full backups. + RetentionFull *int `form:"retention_full,omitempty" json:"retention_full,omitempty" xml:"retention_full,omitempty"` + // The type of measure used for retention_full. + RetentionFullType *string `form:"retention_full_type,omitempty" json:"retention_full_type,omitempty" xml:"retention_full_type,omitempty"` + // The base path within the repository to store backups. + BasePath *string `form:"base_path,omitempty" json:"base_path,omitempty" xml:"base_path,omitempty"` +} + +// BackupScheduleSpecRequestBodyRequestBody is used to define fields on request +// body types. +type BackupScheduleSpecRequestBodyRequestBody struct { + // The unique identifier for this backup schedule. + ID string `form:"id" json:"id" xml:"id"` + // The type of backup to take on this schedule. + Type string `form:"type" json:"type" xml:"type"` + // The cron expression for this schedule. + CronExpression string `form:"cron_expression" json:"cron_expression" xml:"cron_expression"` +} + +// NewCreateDatabaseRequestBody builds the HTTP request body from the payload +// of the "create-database" endpoint of the "control-plane" service. +func NewCreateDatabaseRequestBody(p *controlplane.CreateDatabaseRequest) *CreateDatabaseRequestBody { + body := &CreateDatabaseRequestBody{ + ID: p.ID, + TenantID: p.TenantID, + } + if p.Spec != nil { + body.Spec = marshalControlplaneDatabaseSpecToDatabaseSpecRequestBody(p.Spec) + } + return body +} + +// NewUpdateDatabaseRequestBody builds the HTTP request body from the payload +// of the "update-database" endpoint of the "control-plane" service. +func NewUpdateDatabaseRequestBody(p *controlplane.UpdateDatabasePayload) *UpdateDatabaseRequestBody { + body := &UpdateDatabaseRequestBody{} + if p.Request.Spec != nil { + body.Spec = marshalControlplaneDatabaseSpecToDatabaseSpecRequestBodyRequestBody(p.Request.Spec) + } + return body +} + +// NewInspectClusterClusterOK builds a "control-plane" service +// "inspect-cluster" endpoint result from a HTTP "OK" response. +func NewInspectClusterClusterOK(body *InspectClusterResponseBody) *controlplane.Cluster { + v := &controlplane.Cluster{ + ID: *body.ID, + TenantID: *body.TenantID, + } + v.Status = unmarshalClusterStatusResponseBodyToControlplaneClusterStatus(body.Status) + v.Hosts = make([]*controlplane.Host, len(body.Hosts)) + for i, val := range body.Hosts { + v.Hosts[i] = unmarshalHostResponseBodyToControlplaneHost(val) + } + + return v +} + +// NewListHostsHostOK builds a "control-plane" service "list-hosts" endpoint +// result from a HTTP "OK" response. +func NewListHostsHostOK(body []*HostResponse) []*controlplane.Host { + v := make([]*controlplane.Host, len(body)) + for i, val := range body { + v[i] = unmarshalHostResponseToControlplaneHost(val) + } + + return v +} + +// NewInspectHostHostOK builds a "control-plane" service "inspect-host" +// endpoint result from a HTTP "OK" response. +func NewInspectHostHostOK(body *InspectHostResponseBody) *controlplane.Host { + v := &controlplane.Host{ + ID: *body.ID, + Type: body.Type, + Cohort: body.Cohort, + Hostname: *body.Hostname, + Ipv4Address: *body.Ipv4Address, + } + if body.Config != nil { + v.Config = unmarshalHostConfigurationResponseBodyToControlplaneHostConfiguration(body.Config) + } + v.Status = unmarshalHostStatusResponseBodyToControlplaneHostStatus(body.Status) + + return v +} + +// NewListDatabasesDatabaseOK builds a "control-plane" service "list-databases" +// endpoint result from a HTTP "OK" response. +func NewListDatabasesDatabaseOK(body []*DatabaseResponse) []*controlplane.Database { + v := make([]*controlplane.Database, len(body)) + for i, val := range body { + v[i] = unmarshalDatabaseResponseToControlplaneDatabase(val) + } + + return v +} + +// NewCreateDatabaseDatabaseOK builds a "control-plane" service +// "create-database" endpoint result from a HTTP "OK" response. +func NewCreateDatabaseDatabaseOK(body *CreateDatabaseResponseBody) *controlplane.Database { + v := &controlplane.Database{ + ID: *body.ID, + TenantID: body.TenantID, + CreatedAt: body.CreatedAt, + UpdatedAt: body.UpdatedAt, + } + v.Status = unmarshalDatabaseStatusResponseBodyToControlplaneDatabaseStatus(body.Status) + v.Instances = unmarshalInstanceResponseBodyToControlplaneInstance(body.Instances) + if body.Spec != nil { + v.Spec = unmarshalDatabaseSpecResponseBodyToControlplaneDatabaseSpec(body.Spec) + } + + return v +} + +// NewInspectDatabaseDatabaseOK builds a "control-plane" service +// "inspect-database" endpoint result from a HTTP "OK" response. +func NewInspectDatabaseDatabaseOK(body *InspectDatabaseResponseBody) *controlplane.Database { + v := &controlplane.Database{ + ID: *body.ID, + TenantID: body.TenantID, + CreatedAt: body.CreatedAt, + UpdatedAt: body.UpdatedAt, + } + v.Status = unmarshalDatabaseStatusResponseBodyToControlplaneDatabaseStatus(body.Status) + v.Instances = unmarshalInstanceResponseBodyToControlplaneInstance(body.Instances) + if body.Spec != nil { + v.Spec = unmarshalDatabaseSpecResponseBodyToControlplaneDatabaseSpec(body.Spec) + } + + return v +} + +// NewUpdateDatabaseDatabaseOK builds a "control-plane" service +// "update-database" endpoint result from a HTTP "OK" response. +func NewUpdateDatabaseDatabaseOK(body *UpdateDatabaseResponseBody) *controlplane.Database { + v := &controlplane.Database{ + ID: *body.ID, + TenantID: body.TenantID, + CreatedAt: body.CreatedAt, + UpdatedAt: body.UpdatedAt, + } + v.Status = unmarshalDatabaseStatusResponseBodyToControlplaneDatabaseStatus(body.Status) + v.Instances = unmarshalInstanceResponseBodyToControlplaneInstance(body.Instances) + if body.Spec != nil { + v.Spec = unmarshalDatabaseSpecResponseBodyToControlplaneDatabaseSpec(body.Spec) + } + + return v +} + +// ValidateInspectClusterResponseBody runs the validations defined on +// Inspect-ClusterResponseBody +func ValidateInspectClusterResponseBody(body *InspectClusterResponseBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.TenantID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("tenant_id", "body")) + } + if body.Status == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("status", "body")) + } + if body.Hosts == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("hosts", "body")) + } + if body.Status != nil { + if err2 := ValidateClusterStatusResponseBody(body.Status); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + for _, e := range body.Hosts { + if e != nil { + if err2 := ValidateHostResponseBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateInspectHostResponseBody runs the validations defined on +// Inspect-HostResponseBody +func ValidateInspectHostResponseBody(body *InspectHostResponseBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Status == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("status", "body")) + } + if body.Hostname == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("hostname", "body")) + } + if body.Ipv4Address == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("ipv4_address", "body")) + } + if body.Type != nil { + if !(*body.Type == "swarm" || *body.Type == "systemd") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", *body.Type, []any{"swarm", "systemd"})) + } + } + if body.Ipv4Address != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.ipv4_address", *body.Ipv4Address, goa.FormatIPv4)) + } + if body.Status != nil { + if err2 := ValidateHostStatusResponseBody(body.Status); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateCreateDatabaseResponseBody runs the validations defined on +// Create-DatabaseResponseBody +func ValidateCreateDatabaseResponseBody(body *CreateDatabaseResponseBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Status == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("status", "body")) + } + if body.Instances == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("instances", "body")) + } + if body.CreatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.created_at", *body.CreatedAt, goa.FormatDateTime)) + } + if body.UpdatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.updated_at", *body.UpdatedAt, goa.FormatDateTime)) + } + if body.Status != nil { + if err2 := ValidateDatabaseStatusResponseBody(body.Status); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + if body.Instances != nil { + if err2 := ValidateInstanceResponseBody(body.Instances); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + if body.Spec != nil { + if err2 := ValidateDatabaseSpecResponseBody(body.Spec); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateInspectDatabaseResponseBody runs the validations defined on +// Inspect-DatabaseResponseBody +func ValidateInspectDatabaseResponseBody(body *InspectDatabaseResponseBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Status == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("status", "body")) + } + if body.Instances == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("instances", "body")) + } + if body.CreatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.created_at", *body.CreatedAt, goa.FormatDateTime)) + } + if body.UpdatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.updated_at", *body.UpdatedAt, goa.FormatDateTime)) + } + if body.Status != nil { + if err2 := ValidateDatabaseStatusResponseBody(body.Status); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + if body.Instances != nil { + if err2 := ValidateInstanceResponseBody(body.Instances); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + if body.Spec != nil { + if err2 := ValidateDatabaseSpecResponseBody(body.Spec); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateUpdateDatabaseResponseBody runs the validations defined on +// Update-DatabaseResponseBody +func ValidateUpdateDatabaseResponseBody(body *UpdateDatabaseResponseBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Status == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("status", "body")) + } + if body.Instances == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("instances", "body")) + } + if body.CreatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.created_at", *body.CreatedAt, goa.FormatDateTime)) + } + if body.UpdatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.updated_at", *body.UpdatedAt, goa.FormatDateTime)) + } + if body.Status != nil { + if err2 := ValidateDatabaseStatusResponseBody(body.Status); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + if body.Instances != nil { + if err2 := ValidateInstanceResponseBody(body.Instances); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + if body.Spec != nil { + if err2 := ValidateDatabaseSpecResponseBody(body.Spec); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateClusterStatusResponseBody runs the validations defined on +// ClusterStatusResponseBody +func ValidateClusterStatusResponseBody(body *ClusterStatusResponseBody) (err error) { + if body.State == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("state", "body")) + } + if body.State != nil { + if !(*body.State == "available" || *body.State == "error") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.state", *body.State, []any{"available", "error"})) + } + } + return +} + +// ValidateHostResponseBody runs the validations defined on HostResponseBody +func ValidateHostResponseBody(body *HostResponseBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Status == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("status", "body")) + } + if body.Hostname == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("hostname", "body")) + } + if body.Ipv4Address == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("ipv4_address", "body")) + } + if body.Type != nil { + if !(*body.Type == "swarm" || *body.Type == "systemd") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", *body.Type, []any{"swarm", "systemd"})) + } + } + if body.Ipv4Address != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.ipv4_address", *body.Ipv4Address, goa.FormatIPv4)) + } + if body.Status != nil { + if err2 := ValidateHostStatusResponseBody(body.Status); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateHostStatusResponseBody runs the validations defined on +// HostStatusResponseBody +func ValidateHostStatusResponseBody(body *HostStatusResponseBody) (err error) { + if body.State == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("state", "body")) + } + if body.State != nil { + if !(*body.State == "available" || *body.State == "unreachable" || *body.State == "error") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.state", *body.State, []any{"available", "unreachable", "error"})) + } + } + return +} + +// ValidateHostResponse runs the validations defined on HostResponse +func ValidateHostResponse(body *HostResponse) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Status == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("status", "body")) + } + if body.Hostname == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("hostname", "body")) + } + if body.Ipv4Address == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("ipv4_address", "body")) + } + if body.Type != nil { + if !(*body.Type == "swarm" || *body.Type == "systemd") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", *body.Type, []any{"swarm", "systemd"})) + } + } + if body.Ipv4Address != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.ipv4_address", *body.Ipv4Address, goa.FormatIPv4)) + } + if body.Status != nil { + if err2 := ValidateHostStatusResponse(body.Status); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateHostStatusResponse runs the validations defined on HostStatusResponse +func ValidateHostStatusResponse(body *HostStatusResponse) (err error) { + if body.State == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("state", "body")) + } + if body.State != nil { + if !(*body.State == "available" || *body.State == "unreachable" || *body.State == "error") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.state", *body.State, []any{"available", "unreachable", "error"})) + } + } + return +} + +// ValidateDatabaseResponse runs the validations defined on DatabaseResponse +func ValidateDatabaseResponse(body *DatabaseResponse) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Status == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("status", "body")) + } + if body.Instances == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("instances", "body")) + } + if body.CreatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.created_at", *body.CreatedAt, goa.FormatDateTime)) + } + if body.UpdatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.updated_at", *body.UpdatedAt, goa.FormatDateTime)) + } + if body.Status != nil { + if err2 := ValidateDatabaseStatusResponse(body.Status); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + if body.Instances != nil { + if err2 := ValidateInstanceResponse(body.Instances); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + if body.Spec != nil { + if err2 := ValidateDatabaseSpecResponse(body.Spec); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateDatabaseStatusResponse runs the validations defined on +// DatabaseStatusResponse +func ValidateDatabaseStatusResponse(body *DatabaseStatusResponse) (err error) { + if body.State != nil { + if !(*body.State == "creating" || *body.State == "modifying" || *body.State == "available" || *body.State == "error") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.state", *body.State, []any{"creating", "modifying", "available", "error"})) + } + } + if body.UpdatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.updated_at", *body.UpdatedAt, goa.FormatDateTime)) + } + return +} + +// ValidateInstanceResponse runs the validations defined on InstanceResponse +func ValidateInstanceResponse(body *InstanceResponse) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Status == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("status", "body")) + } + if body.CreatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.created_at", *body.CreatedAt, goa.FormatDateTime)) + } + if body.UpdatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.updated_at", *body.UpdatedAt, goa.FormatDateTime)) + } + if body.Status != nil { + if err2 := ValidateInstanceStatusResponse(body.Status); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + for _, e := range body.Interfaces { + if e != nil { + if err2 := ValidateInstanceInterfaceResponse(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateInstanceStatusResponse runs the validations defined on +// InstanceStatusResponse +func ValidateInstanceStatusResponse(body *InstanceStatusResponse) (err error) { + if body.State == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("state", "body")) + } + if body.State != nil { + if !(*body.State == "creating" || *body.State == "modifying" || *body.State == "backing_up" || *body.State == "available" || *body.State == "error") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.state", *body.State, []any{"creating", "modifying", "backing_up", "available", "error"})) + } + } + if body.PatroniState != nil { + if !(*body.PatroniState == "stopping" || *body.PatroniState == "stopped" || *body.PatroniState == "stop failed" || *body.PatroniState == "crashed" || *body.PatroniState == "running" || *body.PatroniState == "starting" || *body.PatroniState == "start failed" || *body.PatroniState == "restarting" || *body.PatroniState == "restart failed" || *body.PatroniState == "initializing new cluster" || *body.PatroniState == "initdb failed" || *body.PatroniState == "running custom bootstrap script" || *body.PatroniState == "custom bootstrap failed" || *body.PatroniState == "creating replica" || *body.PatroniState == "unknown") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.patroni_state", *body.PatroniState, []any{"stopping", "stopped", "stop failed", "crashed", "running", "starting", "start failed", "restarting", "restart failed", "initializing new cluster", "initdb failed", "running custom bootstrap script", "custom bootstrap failed", "creating replica", "unknown"})) + } + } + if body.Role != nil { + if !(*body.Role == "replica" || *body.Role == "primary") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.role", *body.Role, []any{"replica", "primary"})) + } + } + if body.UpdatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.updated_at", *body.UpdatedAt, goa.FormatDateTime)) + } + return +} + +// ValidateInstanceInterfaceResponse runs the validations defined on +// InstanceInterfaceResponse +func ValidateInstanceInterfaceResponse(body *InstanceInterfaceResponse) (err error) { + if body.NetworkType != nil { + if !(*body.NetworkType == "docker" || *body.NetworkType == "host") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.network_type", *body.NetworkType, []any{"docker", "host"})) + } + } + if body.Ipv4Address != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.ipv4_address", *body.Ipv4Address, goa.FormatIPv4)) + } + return +} + +// ValidateDatabaseSpecResponse runs the validations defined on +// DatabaseSpecResponse +func ValidateDatabaseSpecResponse(body *DatabaseSpecResponse) (err error) { + if body.DatabaseName == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("database_name", "body")) + } + if body.Nodes == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("nodes", "body")) + } + if body.PostgresVersion != nil { + if !(*body.PostgresVersion == "16" || *body.PostgresVersion == "17") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.postgres_version", *body.PostgresVersion, []any{"16", "17"})) + } + } + if body.SpockVersion != nil { + if !(*body.SpockVersion == "4") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.spock_version", *body.SpockVersion, []any{"4"})) + } + } + for _, e := range body.Nodes { + if e != nil { + if err2 := ValidateDatabaseNodeSpecResponse(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.DatabaseUsers { + if e != nil { + if err2 := ValidateDatabaseUserSpecResponse(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.Extensions { + if e != nil { + if err2 := ValidateDatabaseExtensionSpecResponse(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.BackupConfigs { + if e != nil { + if err2 := ValidateBackupConfigSpecResponse(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateDatabaseNodeSpecResponse runs the validations defined on +// DatabaseNodeSpecResponse +func ValidateDatabaseNodeSpecResponse(body *DatabaseNodeSpecResponse) (err error) { + if body.Name == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("name", "body")) + } + if body.InstanceID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("instance_id", "body")) + } + if body.HostID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("host_id", "body")) + } + if body.PostgresVersion != nil { + if !(*body.PostgresVersion == "16" || *body.PostgresVersion == "17") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.postgres_version", *body.PostgresVersion, []any{"16", "17"})) + } + } + if body.ReadReplicas != nil { + if err2 := ValidateDatabaseReplicaSpecResponse(body.ReadReplicas); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateDatabaseReplicaSpecResponse runs the validations defined on +// DatabaseReplicaSpecResponse +func ValidateDatabaseReplicaSpecResponse(body *DatabaseReplicaSpecResponse) (err error) { + if body.InstanceID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("instance_id", "body")) + } + if body.HostID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("host_id", "body")) + } + return +} + +// ValidateDatabaseUserSpecResponse runs the validations defined on +// DatabaseUserSpecResponse +func ValidateDatabaseUserSpecResponse(body *DatabaseUserSpecResponse) (err error) { + if body.Username == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("username", "body")) + } + if body.Password == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("password", "body")) + } + return +} + +// ValidateDatabaseExtensionSpecResponse runs the validations defined on +// DatabaseExtensionSpecResponse +func ValidateDatabaseExtensionSpecResponse(body *DatabaseExtensionSpecResponse) (err error) { + if body.Name == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("name", "body")) + } + return +} + +// ValidateBackupConfigSpecResponse runs the validations defined on +// BackupConfigSpecResponse +func ValidateBackupConfigSpecResponse(body *BackupConfigSpecResponse) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Provider == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("provider", "body")) + } + if body.Provider != nil { + if !(*body.Provider == "pgbackrest" || *body.Provider == "pg_dump") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.provider", *body.Provider, []any{"pgbackrest", "pg_dump"})) + } + } + for _, e := range body.Repositories { + if e != nil { + if err2 := ValidateBackupRepositorySpecResponse(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.Schedules { + if e != nil { + if err2 := ValidateBackupScheduleSpecResponse(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateBackupRepositorySpecResponse runs the validations defined on +// BackupRepositorySpecResponse +func ValidateBackupRepositorySpecResponse(body *BackupRepositorySpecResponse) (err error) { + if body.Type == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("type", "body")) + } + if body.Type != nil { + if !(*body.Type == "s3" || *body.Type == "gcs" || *body.Type == "azure") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", *body.Type, []any{"s3", "gcs", "azure"})) + } + } + if body.RetentionFullType != nil { + if !(*body.RetentionFullType == "time" || *body.RetentionFullType == "count") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.retention_full_type", *body.RetentionFullType, []any{"time", "count"})) + } + } + return +} + +// ValidateBackupScheduleSpecResponse runs the validations defined on +// BackupScheduleSpecResponse +func ValidateBackupScheduleSpecResponse(body *BackupScheduleSpecResponse) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Type == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("type", "body")) + } + if body.CronExpression == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("cron_expression", "body")) + } + if body.Type != nil { + if !(*body.Type == "full" || *body.Type == "incr") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", *body.Type, []any{"full", "incr"})) + } + } + return +} + +// ValidateDatabaseSpecRequestBody runs the validations defined on +// DatabaseSpecRequestBody +func ValidateDatabaseSpecRequestBody(body *DatabaseSpecRequestBody) (err error) { + if body.Nodes == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("nodes", "body")) + } + if body.PostgresVersion != nil { + if !(*body.PostgresVersion == "16" || *body.PostgresVersion == "17") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.postgres_version", *body.PostgresVersion, []any{"16", "17"})) + } + } + if body.SpockVersion != nil { + if !(*body.SpockVersion == "4") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.spock_version", *body.SpockVersion, []any{"4"})) + } + } + for _, e := range body.Nodes { + if e != nil { + if err2 := ValidateDatabaseNodeSpecRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.BackupConfigs { + if e != nil { + if err2 := ValidateBackupConfigSpecRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateDatabaseNodeSpecRequestBody runs the validations defined on +// DatabaseNodeSpecRequestBody +func ValidateDatabaseNodeSpecRequestBody(body *DatabaseNodeSpecRequestBody) (err error) { + if body.PostgresVersion != nil { + if !(*body.PostgresVersion == "16" || *body.PostgresVersion == "17") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.postgres_version", *body.PostgresVersion, []any{"16", "17"})) + } + } + return +} + +// ValidateBackupConfigSpecRequestBody runs the validations defined on +// BackupConfigSpecRequestBody +func ValidateBackupConfigSpecRequestBody(body *BackupConfigSpecRequestBody) (err error) { + if !(body.Provider == "pgbackrest" || body.Provider == "pg_dump") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.provider", body.Provider, []any{"pgbackrest", "pg_dump"})) + } + for _, e := range body.Repositories { + if e != nil { + if err2 := ValidateBackupRepositorySpecRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.Schedules { + if e != nil { + if err2 := ValidateBackupScheduleSpecRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateBackupRepositorySpecRequestBody runs the validations defined on +// BackupRepositorySpecRequestBody +func ValidateBackupRepositorySpecRequestBody(body *BackupRepositorySpecRequestBody) (err error) { + if !(body.Type == "s3" || body.Type == "gcs" || body.Type == "azure") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", body.Type, []any{"s3", "gcs", "azure"})) + } + if body.RetentionFullType != nil { + if !(*body.RetentionFullType == "time" || *body.RetentionFullType == "count") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.retention_full_type", *body.RetentionFullType, []any{"time", "count"})) + } + } + return +} + +// ValidateBackupScheduleSpecRequestBody runs the validations defined on +// BackupScheduleSpecRequestBody +func ValidateBackupScheduleSpecRequestBody(body *BackupScheduleSpecRequestBody) (err error) { + if !(body.Type == "full" || body.Type == "incr") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", body.Type, []any{"full", "incr"})) + } + return +} + +// ValidateDatabaseStatusResponseBody runs the validations defined on +// DatabaseStatusResponseBody +func ValidateDatabaseStatusResponseBody(body *DatabaseStatusResponseBody) (err error) { + if body.State != nil { + if !(*body.State == "creating" || *body.State == "modifying" || *body.State == "available" || *body.State == "error") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.state", *body.State, []any{"creating", "modifying", "available", "error"})) + } + } + if body.UpdatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.updated_at", *body.UpdatedAt, goa.FormatDateTime)) + } + return +} + +// ValidateInstanceResponseBody runs the validations defined on +// InstanceResponseBody +func ValidateInstanceResponseBody(body *InstanceResponseBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Status == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("status", "body")) + } + if body.CreatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.created_at", *body.CreatedAt, goa.FormatDateTime)) + } + if body.UpdatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.updated_at", *body.UpdatedAt, goa.FormatDateTime)) + } + if body.Status != nil { + if err2 := ValidateInstanceStatusResponseBody(body.Status); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + for _, e := range body.Interfaces { + if e != nil { + if err2 := ValidateInstanceInterfaceResponseBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateInstanceStatusResponseBody runs the validations defined on +// InstanceStatusResponseBody +func ValidateInstanceStatusResponseBody(body *InstanceStatusResponseBody) (err error) { + if body.State == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("state", "body")) + } + if body.State != nil { + if !(*body.State == "creating" || *body.State == "modifying" || *body.State == "backing_up" || *body.State == "available" || *body.State == "error") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.state", *body.State, []any{"creating", "modifying", "backing_up", "available", "error"})) + } + } + if body.PatroniState != nil { + if !(*body.PatroniState == "stopping" || *body.PatroniState == "stopped" || *body.PatroniState == "stop failed" || *body.PatroniState == "crashed" || *body.PatroniState == "running" || *body.PatroniState == "starting" || *body.PatroniState == "start failed" || *body.PatroniState == "restarting" || *body.PatroniState == "restart failed" || *body.PatroniState == "initializing new cluster" || *body.PatroniState == "initdb failed" || *body.PatroniState == "running custom bootstrap script" || *body.PatroniState == "custom bootstrap failed" || *body.PatroniState == "creating replica" || *body.PatroniState == "unknown") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.patroni_state", *body.PatroniState, []any{"stopping", "stopped", "stop failed", "crashed", "running", "starting", "start failed", "restarting", "restart failed", "initializing new cluster", "initdb failed", "running custom bootstrap script", "custom bootstrap failed", "creating replica", "unknown"})) + } + } + if body.Role != nil { + if !(*body.Role == "replica" || *body.Role == "primary") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.role", *body.Role, []any{"replica", "primary"})) + } + } + if body.UpdatedAt != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.updated_at", *body.UpdatedAt, goa.FormatDateTime)) + } + return +} + +// ValidateInstanceInterfaceResponseBody runs the validations defined on +// InstanceInterfaceResponseBody +func ValidateInstanceInterfaceResponseBody(body *InstanceInterfaceResponseBody) (err error) { + if body.NetworkType != nil { + if !(*body.NetworkType == "docker" || *body.NetworkType == "host") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.network_type", *body.NetworkType, []any{"docker", "host"})) + } + } + if body.Ipv4Address != nil { + err = goa.MergeErrors(err, goa.ValidateFormat("body.ipv4_address", *body.Ipv4Address, goa.FormatIPv4)) + } + return +} + +// ValidateDatabaseSpecResponseBody runs the validations defined on +// DatabaseSpecResponseBody +func ValidateDatabaseSpecResponseBody(body *DatabaseSpecResponseBody) (err error) { + if body.DatabaseName == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("database_name", "body")) + } + if body.Nodes == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("nodes", "body")) + } + if body.PostgresVersion != nil { + if !(*body.PostgresVersion == "16" || *body.PostgresVersion == "17") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.postgres_version", *body.PostgresVersion, []any{"16", "17"})) + } + } + if body.SpockVersion != nil { + if !(*body.SpockVersion == "4") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.spock_version", *body.SpockVersion, []any{"4"})) + } + } + for _, e := range body.Nodes { + if e != nil { + if err2 := ValidateDatabaseNodeSpecResponseBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.DatabaseUsers { + if e != nil { + if err2 := ValidateDatabaseUserSpecResponseBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.Extensions { + if e != nil { + if err2 := ValidateDatabaseExtensionSpecResponseBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.BackupConfigs { + if e != nil { + if err2 := ValidateBackupConfigSpecResponseBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateDatabaseNodeSpecResponseBody runs the validations defined on +// DatabaseNodeSpecResponseBody +func ValidateDatabaseNodeSpecResponseBody(body *DatabaseNodeSpecResponseBody) (err error) { + if body.Name == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("name", "body")) + } + if body.InstanceID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("instance_id", "body")) + } + if body.HostID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("host_id", "body")) + } + if body.PostgresVersion != nil { + if !(*body.PostgresVersion == "16" || *body.PostgresVersion == "17") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.postgres_version", *body.PostgresVersion, []any{"16", "17"})) + } + } + if body.ReadReplicas != nil { + if err2 := ValidateDatabaseReplicaSpecResponseBody(body.ReadReplicas); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateDatabaseReplicaSpecResponseBody runs the validations defined on +// DatabaseReplicaSpecResponseBody +func ValidateDatabaseReplicaSpecResponseBody(body *DatabaseReplicaSpecResponseBody) (err error) { + if body.InstanceID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("instance_id", "body")) + } + if body.HostID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("host_id", "body")) + } + return +} + +// ValidateDatabaseUserSpecResponseBody runs the validations defined on +// DatabaseUserSpecResponseBody +func ValidateDatabaseUserSpecResponseBody(body *DatabaseUserSpecResponseBody) (err error) { + if body.Username == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("username", "body")) + } + if body.Password == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("password", "body")) + } + return +} + +// ValidateDatabaseExtensionSpecResponseBody runs the validations defined on +// DatabaseExtensionSpecResponseBody +func ValidateDatabaseExtensionSpecResponseBody(body *DatabaseExtensionSpecResponseBody) (err error) { + if body.Name == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("name", "body")) + } + return +} + +// ValidateBackupConfigSpecResponseBody runs the validations defined on +// BackupConfigSpecResponseBody +func ValidateBackupConfigSpecResponseBody(body *BackupConfigSpecResponseBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Provider == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("provider", "body")) + } + if body.Provider != nil { + if !(*body.Provider == "pgbackrest" || *body.Provider == "pg_dump") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.provider", *body.Provider, []any{"pgbackrest", "pg_dump"})) + } + } + for _, e := range body.Repositories { + if e != nil { + if err2 := ValidateBackupRepositorySpecResponseBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.Schedules { + if e != nil { + if err2 := ValidateBackupScheduleSpecResponseBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateBackupRepositorySpecResponseBody runs the validations defined on +// BackupRepositorySpecResponseBody +func ValidateBackupRepositorySpecResponseBody(body *BackupRepositorySpecResponseBody) (err error) { + if body.Type == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("type", "body")) + } + if body.Type != nil { + if !(*body.Type == "s3" || *body.Type == "gcs" || *body.Type == "azure") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", *body.Type, []any{"s3", "gcs", "azure"})) + } + } + if body.RetentionFullType != nil { + if !(*body.RetentionFullType == "time" || *body.RetentionFullType == "count") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.retention_full_type", *body.RetentionFullType, []any{"time", "count"})) + } + } + return +} + +// ValidateBackupScheduleSpecResponseBody runs the validations defined on +// BackupScheduleSpecResponseBody +func ValidateBackupScheduleSpecResponseBody(body *BackupScheduleSpecResponseBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Type == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("type", "body")) + } + if body.CronExpression == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("cron_expression", "body")) + } + if body.Type != nil { + if !(*body.Type == "full" || *body.Type == "incr") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", *body.Type, []any{"full", "incr"})) + } + } + return +} + +// ValidateDatabaseSpecRequestBodyRequestBody runs the validations defined on +// DatabaseSpecRequestBodyRequestBody +func ValidateDatabaseSpecRequestBodyRequestBody(body *DatabaseSpecRequestBodyRequestBody) (err error) { + if body.Nodes == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("nodes", "body")) + } + if body.PostgresVersion != nil { + if !(*body.PostgresVersion == "16" || *body.PostgresVersion == "17") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.postgres_version", *body.PostgresVersion, []any{"16", "17"})) + } + } + if body.SpockVersion != nil { + if !(*body.SpockVersion == "4") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.spock_version", *body.SpockVersion, []any{"4"})) + } + } + for _, e := range body.Nodes { + if e != nil { + if err2 := ValidateDatabaseNodeSpecRequestBodyRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.BackupConfigs { + if e != nil { + if err2 := ValidateBackupConfigSpecRequestBodyRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateDatabaseNodeSpecRequestBodyRequestBody runs the validations defined +// on DatabaseNodeSpecRequestBodyRequestBody +func ValidateDatabaseNodeSpecRequestBodyRequestBody(body *DatabaseNodeSpecRequestBodyRequestBody) (err error) { + if body.PostgresVersion != nil { + if !(*body.PostgresVersion == "16" || *body.PostgresVersion == "17") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.postgres_version", *body.PostgresVersion, []any{"16", "17"})) + } + } + return +} + +// ValidateBackupConfigSpecRequestBodyRequestBody runs the validations defined +// on BackupConfigSpecRequestBodyRequestBody +func ValidateBackupConfigSpecRequestBodyRequestBody(body *BackupConfigSpecRequestBodyRequestBody) (err error) { + if !(body.Provider == "pgbackrest" || body.Provider == "pg_dump") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.provider", body.Provider, []any{"pgbackrest", "pg_dump"})) + } + for _, e := range body.Repositories { + if e != nil { + if err2 := ValidateBackupRepositorySpecRequestBodyRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.Schedules { + if e != nil { + if err2 := ValidateBackupScheduleSpecRequestBodyRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateBackupRepositorySpecRequestBodyRequestBody runs the validations +// defined on BackupRepositorySpecRequestBodyRequestBody +func ValidateBackupRepositorySpecRequestBodyRequestBody(body *BackupRepositorySpecRequestBodyRequestBody) (err error) { + if !(body.Type == "s3" || body.Type == "gcs" || body.Type == "azure") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", body.Type, []any{"s3", "gcs", "azure"})) + } + if body.RetentionFullType != nil { + if !(*body.RetentionFullType == "time" || *body.RetentionFullType == "count") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.retention_full_type", *body.RetentionFullType, []any{"time", "count"})) + } + } + return +} + +// ValidateBackupScheduleSpecRequestBodyRequestBody runs the validations +// defined on BackupScheduleSpecRequestBodyRequestBody +func ValidateBackupScheduleSpecRequestBodyRequestBody(body *BackupScheduleSpecRequestBodyRequestBody) (err error) { + if !(body.Type == "full" || body.Type == "incr") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", body.Type, []any{"full", "incr"})) + } + return +} diff --git a/api/gen/http/control_plane/server/encode_decode.go b/api/gen/http/control_plane/server/encode_decode.go new file mode 100644 index 00000000..f95a53d4 --- /dev/null +++ b/api/gen/http/control_plane/server/encode_decode.go @@ -0,0 +1,1361 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// control-plane HTTP server encoders and decoders +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package server + +import ( + "context" + "errors" + "io" + "net/http" + + controlplane "github.com/pgEdge/control-plane/api/gen/control_plane" + goahttp "goa.design/goa/v3/http" + goa "goa.design/goa/v3/pkg" +) + +// EncodeInspectClusterResponse returns an encoder for responses returned by +// the control-plane inspect-cluster endpoint. +func EncodeInspectClusterResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, any) error { + return func(ctx context.Context, w http.ResponseWriter, v any) error { + res, _ := v.(*controlplane.Cluster) + enc := encoder(ctx, w) + body := NewInspectClusterResponseBody(res) + w.WriteHeader(http.StatusOK) + return enc.Encode(body) + } +} + +// EncodeListHostsResponse returns an encoder for responses returned by the +// control-plane list-hosts endpoint. +func EncodeListHostsResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, any) error { + return func(ctx context.Context, w http.ResponseWriter, v any) error { + res, _ := v.([]*controlplane.Host) + enc := encoder(ctx, w) + body := NewListHostsResponseBody(res) + w.WriteHeader(http.StatusOK) + return enc.Encode(body) + } +} + +// EncodeInspectHostResponse returns an encoder for responses returned by the +// control-plane inspect-host endpoint. +func EncodeInspectHostResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, any) error { + return func(ctx context.Context, w http.ResponseWriter, v any) error { + res, _ := v.(*controlplane.Host) + enc := encoder(ctx, w) + body := NewInspectHostResponseBody(res) + w.WriteHeader(http.StatusOK) + return enc.Encode(body) + } +} + +// DecodeInspectHostRequest returns a decoder for requests sent to the +// control-plane inspect-host endpoint. +func DecodeInspectHostRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) { + return func(r *http.Request) (any, error) { + var ( + hostID string + + params = mux.Vars(r) + ) + hostID = params["host_id"] + payload := NewInspectHostPayload(hostID) + + return payload, nil + } +} + +// EncodeRemoveHostResponse returns an encoder for responses returned by the +// control-plane remove-host endpoint. +func EncodeRemoveHostResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, any) error { + return func(ctx context.Context, w http.ResponseWriter, v any) error { + w.WriteHeader(http.StatusNoContent) + return nil + } +} + +// DecodeRemoveHostRequest returns a decoder for requests sent to the +// control-plane remove-host endpoint. +func DecodeRemoveHostRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) { + return func(r *http.Request) (any, error) { + var ( + hostID string + + params = mux.Vars(r) + ) + hostID = params["host_id"] + payload := NewRemoveHostPayload(hostID) + + return payload, nil + } +} + +// EncodeListDatabasesResponse returns an encoder for responses returned by the +// control-plane list-databases endpoint. +func EncodeListDatabasesResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, any) error { + return func(ctx context.Context, w http.ResponseWriter, v any) error { + res, _ := v.([]*controlplane.Database) + enc := encoder(ctx, w) + body := NewListDatabasesResponseBody(res) + w.WriteHeader(http.StatusOK) + return enc.Encode(body) + } +} + +// EncodeCreateDatabaseResponse returns an encoder for responses returned by +// the control-plane create-database endpoint. +func EncodeCreateDatabaseResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, any) error { + return func(ctx context.Context, w http.ResponseWriter, v any) error { + res, _ := v.(*controlplane.Database) + enc := encoder(ctx, w) + body := NewCreateDatabaseResponseBody(res) + w.WriteHeader(http.StatusOK) + return enc.Encode(body) + } +} + +// DecodeCreateDatabaseRequest returns a decoder for requests sent to the +// control-plane create-database endpoint. +func DecodeCreateDatabaseRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) { + return func(r *http.Request) (any, error) { + var ( + body CreateDatabaseRequestBody + err error + ) + err = decoder(r).Decode(&body) + if err != nil { + if err == io.EOF { + return nil, goa.MissingPayloadError() + } + var gerr *goa.ServiceError + if errors.As(err, &gerr) { + return nil, gerr + } + return nil, goa.DecodePayloadError(err.Error()) + } + err = ValidateCreateDatabaseRequestBody(&body) + if err != nil { + return nil, err + } + payload := NewCreateDatabaseRequest(&body) + + return payload, nil + } +} + +// EncodeInspectDatabaseResponse returns an encoder for responses returned by +// the control-plane inspect-database endpoint. +func EncodeInspectDatabaseResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, any) error { + return func(ctx context.Context, w http.ResponseWriter, v any) error { + res, _ := v.(*controlplane.Database) + enc := encoder(ctx, w) + body := NewInspectDatabaseResponseBody(res) + w.WriteHeader(http.StatusOK) + return enc.Encode(body) + } +} + +// DecodeInspectDatabaseRequest returns a decoder for requests sent to the +// control-plane inspect-database endpoint. +func DecodeInspectDatabaseRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) { + return func(r *http.Request) (any, error) { + var ( + databaseID string + + params = mux.Vars(r) + ) + databaseID = params["database_id"] + payload := NewInspectDatabasePayload(databaseID) + + return payload, nil + } +} + +// EncodeUpdateDatabaseResponse returns an encoder for responses returned by +// the control-plane update-database endpoint. +func EncodeUpdateDatabaseResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, any) error { + return func(ctx context.Context, w http.ResponseWriter, v any) error { + res, _ := v.(*controlplane.Database) + enc := encoder(ctx, w) + body := NewUpdateDatabaseResponseBody(res) + w.WriteHeader(http.StatusOK) + return enc.Encode(body) + } +} + +// DecodeUpdateDatabaseRequest returns a decoder for requests sent to the +// control-plane update-database endpoint. +func DecodeUpdateDatabaseRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) { + return func(r *http.Request) (any, error) { + var ( + body UpdateDatabaseRequestBody + err error + ) + err = decoder(r).Decode(&body) + if err != nil { + if err == io.EOF { + err = nil + } else { + var gerr *goa.ServiceError + if errors.As(err, &gerr) { + return nil, gerr + } + return nil, goa.DecodePayloadError(err.Error()) + } + } + err = ValidateUpdateDatabaseRequestBody(&body) + if err != nil { + return nil, err + } + + var ( + databaseID string + + params = mux.Vars(r) + ) + databaseID = params["database_id"] + payload := NewUpdateDatabasePayload(&body, databaseID) + + return payload, nil + } +} + +// EncodeDeleteDatabaseResponse returns an encoder for responses returned by +// the control-plane delete-database endpoint. +func EncodeDeleteDatabaseResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, any) error { + return func(ctx context.Context, w http.ResponseWriter, v any) error { + w.WriteHeader(http.StatusNoContent) + return nil + } +} + +// DecodeDeleteDatabaseRequest returns a decoder for requests sent to the +// control-plane delete-database endpoint. +func DecodeDeleteDatabaseRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (any, error) { + return func(r *http.Request) (any, error) { + var ( + databaseID string + + params = mux.Vars(r) + ) + databaseID = params["database_id"] + payload := NewDeleteDatabasePayload(databaseID) + + return payload, nil + } +} + +// marshalControlplaneClusterStatusToClusterStatusResponseBody builds a value +// of type *ClusterStatusResponseBody from a value of type +// *controlplane.ClusterStatus. +func marshalControlplaneClusterStatusToClusterStatusResponseBody(v *controlplane.ClusterStatus) *ClusterStatusResponseBody { + res := &ClusterStatusResponseBody{ + State: v.State, + } + + return res +} + +// marshalControlplaneHostToHostResponseBody builds a value of type +// *HostResponseBody from a value of type *controlplane.Host. +func marshalControlplaneHostToHostResponseBody(v *controlplane.Host) *HostResponseBody { + res := &HostResponseBody{ + ID: v.ID, + Type: v.Type, + Cohort: v.Cohort, + Hostname: v.Hostname, + Ipv4Address: v.Ipv4Address, + } + if v.Config != nil { + res.Config = marshalControlplaneHostConfigurationToHostConfigurationResponseBody(v.Config) + } + if v.Status != nil { + res.Status = marshalControlplaneHostStatusToHostStatusResponseBody(v.Status) + } + + return res +} + +// marshalControlplaneHostConfigurationToHostConfigurationResponseBody builds a +// value of type *HostConfigurationResponseBody from a value of type +// *controlplane.HostConfiguration. +func marshalControlplaneHostConfigurationToHostConfigurationResponseBody(v *controlplane.HostConfiguration) *HostConfigurationResponseBody { + if v == nil { + return nil + } + res := &HostConfigurationResponseBody{ + VectorEnabled: v.VectorEnabled, + TraefikEnabled: v.TraefikEnabled, + } + + return res +} + +// marshalControlplaneHostStatusToHostStatusResponseBody builds a value of type +// *HostStatusResponseBody from a value of type *controlplane.HostStatus. +func marshalControlplaneHostStatusToHostStatusResponseBody(v *controlplane.HostStatus) *HostStatusResponseBody { + res := &HostStatusResponseBody{ + State: v.State, + } + + return res +} + +// marshalControlplaneHostToHostResponse builds a value of type *HostResponse +// from a value of type *controlplane.Host. +func marshalControlplaneHostToHostResponse(v *controlplane.Host) *HostResponse { + res := &HostResponse{ + ID: v.ID, + Type: v.Type, + Cohort: v.Cohort, + Hostname: v.Hostname, + Ipv4Address: v.Ipv4Address, + } + if v.Config != nil { + res.Config = marshalControlplaneHostConfigurationToHostConfigurationResponse(v.Config) + } + if v.Status != nil { + res.Status = marshalControlplaneHostStatusToHostStatusResponse(v.Status) + } + + return res +} + +// marshalControlplaneHostConfigurationToHostConfigurationResponse builds a +// value of type *HostConfigurationResponse from a value of type +// *controlplane.HostConfiguration. +func marshalControlplaneHostConfigurationToHostConfigurationResponse(v *controlplane.HostConfiguration) *HostConfigurationResponse { + if v == nil { + return nil + } + res := &HostConfigurationResponse{ + VectorEnabled: v.VectorEnabled, + TraefikEnabled: v.TraefikEnabled, + } + + return res +} + +// marshalControlplaneHostStatusToHostStatusResponse builds a value of type +// *HostStatusResponse from a value of type *controlplane.HostStatus. +func marshalControlplaneHostStatusToHostStatusResponse(v *controlplane.HostStatus) *HostStatusResponse { + res := &HostStatusResponse{ + State: v.State, + } + + return res +} + +// marshalControlplaneDatabaseToDatabaseResponse builds a value of type +// *DatabaseResponse from a value of type *controlplane.Database. +func marshalControlplaneDatabaseToDatabaseResponse(v *controlplane.Database) *DatabaseResponse { + res := &DatabaseResponse{ + ID: v.ID, + TenantID: v.TenantID, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + } + if v.Status != nil { + res.Status = marshalControlplaneDatabaseStatusToDatabaseStatusResponse(v.Status) + } + if v.Instances != nil { + res.Instances = marshalControlplaneInstanceToInstanceResponse(v.Instances) + } + if v.Spec != nil { + res.Spec = marshalControlplaneDatabaseSpecToDatabaseSpecResponse(v.Spec) + } + + return res +} + +// marshalControlplaneDatabaseStatusToDatabaseStatusResponse builds a value of +// type *DatabaseStatusResponse from a value of type +// *controlplane.DatabaseStatus. +func marshalControlplaneDatabaseStatusToDatabaseStatusResponse(v *controlplane.DatabaseStatus) *DatabaseStatusResponse { + res := &DatabaseStatusResponse{ + State: v.State, + UpdatedAt: v.UpdatedAt, + } + + return res +} + +// marshalControlplaneInstanceToInstanceResponse builds a value of type +// *InstanceResponse from a value of type *controlplane.Instance. +func marshalControlplaneInstanceToInstanceResponse(v *controlplane.Instance) *InstanceResponse { + res := &InstanceResponse{ + ID: v.ID, + HostID: v.HostID, + NodeName: v.NodeName, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + } + if v.Status != nil { + res.Status = marshalControlplaneInstanceStatusToInstanceStatusResponse(v.Status) + } + if v.Interfaces != nil { + res.Interfaces = make([]*InstanceInterfaceResponse, len(v.Interfaces)) + for i, val := range v.Interfaces { + res.Interfaces[i] = marshalControlplaneInstanceInterfaceToInstanceInterfaceResponse(val) + } + } + + return res +} + +// marshalControlplaneInstanceStatusToInstanceStatusResponse builds a value of +// type *InstanceStatusResponse from a value of type +// *controlplane.InstanceStatus. +func marshalControlplaneInstanceStatusToInstanceStatusResponse(v *controlplane.InstanceStatus) *InstanceStatusResponse { + res := &InstanceStatusResponse{ + State: v.State, + PatroniState: v.PatroniState, + Role: v.Role, + ReadOnly: v.ReadOnly, + PendingRestart: v.PendingRestart, + PatroniPaused: v.PatroniPaused, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + UpdatedAt: v.UpdatedAt, + } + + return res +} + +// marshalControlplaneInstanceInterfaceToInstanceInterfaceResponse builds a +// value of type *InstanceInterfaceResponse from a value of type +// *controlplane.InstanceInterface. +func marshalControlplaneInstanceInterfaceToInstanceInterfaceResponse(v *controlplane.InstanceInterface) *InstanceInterfaceResponse { + if v == nil { + return nil + } + res := &InstanceInterfaceResponse{ + NetworkType: v.NetworkType, + NetworkID: v.NetworkID, + Hostname: v.Hostname, + Ipv4Address: v.Ipv4Address, + Port: v.Port, + } + + return res +} + +// marshalControlplaneDatabaseSpecToDatabaseSpecResponse builds a value of type +// *DatabaseSpecResponse from a value of type *controlplane.DatabaseSpec. +func marshalControlplaneDatabaseSpecToDatabaseSpecResponse(v *controlplane.DatabaseSpec) *DatabaseSpecResponse { + if v == nil { + return nil + } + res := &DatabaseSpecResponse{ + DatabaseName: v.DatabaseName, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + Port: v.Port, + DeletionProtection: v.DeletionProtection, + } + if v.Nodes != nil { + res.Nodes = make([]*DatabaseNodeSpecResponse, len(v.Nodes)) + for i, val := range v.Nodes { + res.Nodes[i] = marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecResponse(val) + } + } else { + res.Nodes = []*DatabaseNodeSpecResponse{} + } + if v.DatabaseUsers != nil { + res.DatabaseUsers = make([]*DatabaseUserSpecResponse, len(v.DatabaseUsers)) + for i, val := range v.DatabaseUsers { + res.DatabaseUsers[i] = marshalControlplaneDatabaseUserSpecToDatabaseUserSpecResponse(val) + } + } + if v.Extensions != nil { + res.Extensions = make([]*DatabaseExtensionSpecResponse, len(v.Extensions)) + for i, val := range v.Extensions { + res.Extensions[i] = marshalControlplaneDatabaseExtensionSpecToDatabaseExtensionSpecResponse(val) + } + } + if v.Features != nil { + res.Features = make(map[string]string, len(v.Features)) + for key, val := range v.Features { + tk := key + tv := val + res.Features[tk] = tv + } + } + if v.BackupConfigs != nil { + res.BackupConfigs = make([]*BackupConfigSpecResponse, len(v.BackupConfigs)) + for i, val := range v.BackupConfigs { + res.BackupConfigs[i] = marshalControlplaneBackupConfigSpecToBackupConfigSpecResponse(val) + } + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecResponse builds a value +// of type *DatabaseNodeSpecResponse from a value of type +// *controlplane.DatabaseNodeSpec. +func marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecResponse(v *controlplane.DatabaseNodeSpec) *DatabaseNodeSpecResponse { + res := &DatabaseNodeSpecResponse{ + Name: v.Name, + InstanceID: v.InstanceID, + HostID: v.HostID, + PostgresVersion: v.PostgresVersion, + Port: v.Port, + } + if v.ReadReplicas != nil { + res.ReadReplicas = marshalControlplaneDatabaseReplicaSpecToDatabaseReplicaSpecResponse(v.ReadReplicas) + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// marshalControlplaneDatabaseReplicaSpecToDatabaseReplicaSpecResponse builds a +// value of type *DatabaseReplicaSpecResponse from a value of type +// *controlplane.DatabaseReplicaSpec. +func marshalControlplaneDatabaseReplicaSpecToDatabaseReplicaSpecResponse(v *controlplane.DatabaseReplicaSpec) *DatabaseReplicaSpecResponse { + if v == nil { + return nil + } + res := &DatabaseReplicaSpecResponse{ + InstanceID: v.InstanceID, + HostID: v.HostID, + } + + return res +} + +// marshalControlplaneDatabaseUserSpecToDatabaseUserSpecResponse builds a value +// of type *DatabaseUserSpecResponse from a value of type +// *controlplane.DatabaseUserSpec. +func marshalControlplaneDatabaseUserSpecToDatabaseUserSpecResponse(v *controlplane.DatabaseUserSpec) *DatabaseUserSpecResponse { + if v == nil { + return nil + } + res := &DatabaseUserSpecResponse{ + Username: v.Username, + Password: v.Password, + Superuser: v.Superuser, + } + if v.Roles != nil { + res.Roles = make([]string, len(v.Roles)) + for i, val := range v.Roles { + res.Roles[i] = val + } + } + + return res +} + +// marshalControlplaneDatabaseExtensionSpecToDatabaseExtensionSpecResponse +// builds a value of type *DatabaseExtensionSpecResponse from a value of type +// *controlplane.DatabaseExtensionSpec. +func marshalControlplaneDatabaseExtensionSpecToDatabaseExtensionSpecResponse(v *controlplane.DatabaseExtensionSpec) *DatabaseExtensionSpecResponse { + if v == nil { + return nil + } + res := &DatabaseExtensionSpecResponse{ + Name: v.Name, + Version: v.Version, + } + + return res +} + +// marshalControlplaneBackupConfigSpecToBackupConfigSpecResponse builds a value +// of type *BackupConfigSpecResponse from a value of type +// *controlplane.BackupConfigSpec. +func marshalControlplaneBackupConfigSpecToBackupConfigSpecResponse(v *controlplane.BackupConfigSpec) *BackupConfigSpecResponse { + if v == nil { + return nil + } + res := &BackupConfigSpecResponse{ + ID: v.ID, + Provider: v.Provider, + } + if v.NodeNames != nil { + res.NodeNames = make([]string, len(v.NodeNames)) + for i, val := range v.NodeNames { + res.NodeNames[i] = val + } + } + if v.Repositories != nil { + res.Repositories = make([]*BackupRepositorySpecResponse, len(v.Repositories)) + for i, val := range v.Repositories { + res.Repositories[i] = marshalControlplaneBackupRepositorySpecToBackupRepositorySpecResponse(val) + } + } + if v.Schedules != nil { + res.Schedules = make([]*BackupScheduleSpecResponse, len(v.Schedules)) + for i, val := range v.Schedules { + res.Schedules[i] = marshalControlplaneBackupScheduleSpecToBackupScheduleSpecResponse(val) + } + } + + return res +} + +// marshalControlplaneBackupRepositorySpecToBackupRepositorySpecResponse builds +// a value of type *BackupRepositorySpecResponse from a value of type +// *controlplane.BackupRepositorySpec. +func marshalControlplaneBackupRepositorySpecToBackupRepositorySpecResponse(v *controlplane.BackupRepositorySpec) *BackupRepositorySpecResponse { + if v == nil { + return nil + } + res := &BackupRepositorySpecResponse{ + ID: v.ID, + Type: v.Type, + S3Bucket: v.S3Bucket, + S3Region: v.S3Region, + S3Endpoint: v.S3Endpoint, + GcsBucket: v.GcsBucket, + GcsEndpoint: v.GcsEndpoint, + AzureAccount: v.AzureAccount, + AzureContainer: v.AzureContainer, + AzureEndpoint: v.AzureEndpoint, + RetentionFull: v.RetentionFull, + RetentionFullType: v.RetentionFullType, + BasePath: v.BasePath, + } + + return res +} + +// marshalControlplaneBackupScheduleSpecToBackupScheduleSpecResponse builds a +// value of type *BackupScheduleSpecResponse from a value of type +// *controlplane.BackupScheduleSpec. +func marshalControlplaneBackupScheduleSpecToBackupScheduleSpecResponse(v *controlplane.BackupScheduleSpec) *BackupScheduleSpecResponse { + if v == nil { + return nil + } + res := &BackupScheduleSpecResponse{ + ID: v.ID, + Type: v.Type, + CronExpression: v.CronExpression, + } + + return res +} + +// unmarshalDatabaseSpecRequestBodyToControlplaneDatabaseSpec builds a value of +// type *controlplane.DatabaseSpec from a value of type +// *DatabaseSpecRequestBody. +func unmarshalDatabaseSpecRequestBodyToControlplaneDatabaseSpec(v *DatabaseSpecRequestBody) *controlplane.DatabaseSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseSpec{ + DatabaseName: *v.DatabaseName, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + Port: v.Port, + DeletionProtection: v.DeletionProtection, + } + res.Nodes = make([]*controlplane.DatabaseNodeSpec, len(v.Nodes)) + for i, val := range v.Nodes { + res.Nodes[i] = unmarshalDatabaseNodeSpecRequestBodyToControlplaneDatabaseNodeSpec(val) + } + if v.DatabaseUsers != nil { + res.DatabaseUsers = make([]*controlplane.DatabaseUserSpec, len(v.DatabaseUsers)) + for i, val := range v.DatabaseUsers { + res.DatabaseUsers[i] = unmarshalDatabaseUserSpecRequestBodyToControlplaneDatabaseUserSpec(val) + } + } + if v.Extensions != nil { + res.Extensions = make([]*controlplane.DatabaseExtensionSpec, len(v.Extensions)) + for i, val := range v.Extensions { + res.Extensions[i] = unmarshalDatabaseExtensionSpecRequestBodyToControlplaneDatabaseExtensionSpec(val) + } + } + if v.Features != nil { + res.Features = make(map[string]string, len(v.Features)) + for key, val := range v.Features { + tk := key + tv := val + res.Features[tk] = tv + } + } + if v.BackupConfigs != nil { + res.BackupConfigs = make([]*controlplane.BackupConfigSpec, len(v.BackupConfigs)) + for i, val := range v.BackupConfigs { + res.BackupConfigs[i] = unmarshalBackupConfigSpecRequestBodyToControlplaneBackupConfigSpec(val) + } + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// unmarshalDatabaseNodeSpecRequestBodyToControlplaneDatabaseNodeSpec builds a +// value of type *controlplane.DatabaseNodeSpec from a value of type +// *DatabaseNodeSpecRequestBody. +func unmarshalDatabaseNodeSpecRequestBodyToControlplaneDatabaseNodeSpec(v *DatabaseNodeSpecRequestBody) *controlplane.DatabaseNodeSpec { + res := &controlplane.DatabaseNodeSpec{ + Name: *v.Name, + InstanceID: *v.InstanceID, + HostID: *v.HostID, + PostgresVersion: v.PostgresVersion, + Port: v.Port, + } + if v.ReadReplicas != nil { + res.ReadReplicas = unmarshalDatabaseReplicaSpecRequestBodyToControlplaneDatabaseReplicaSpec(v.ReadReplicas) + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// unmarshalDatabaseReplicaSpecRequestBodyToControlplaneDatabaseReplicaSpec +// builds a value of type *controlplane.DatabaseReplicaSpec from a value of +// type *DatabaseReplicaSpecRequestBody. +func unmarshalDatabaseReplicaSpecRequestBodyToControlplaneDatabaseReplicaSpec(v *DatabaseReplicaSpecRequestBody) *controlplane.DatabaseReplicaSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseReplicaSpec{ + InstanceID: *v.InstanceID, + HostID: *v.HostID, + } + + return res +} + +// unmarshalDatabaseUserSpecRequestBodyToControlplaneDatabaseUserSpec builds a +// value of type *controlplane.DatabaseUserSpec from a value of type +// *DatabaseUserSpecRequestBody. +func unmarshalDatabaseUserSpecRequestBodyToControlplaneDatabaseUserSpec(v *DatabaseUserSpecRequestBody) *controlplane.DatabaseUserSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseUserSpec{ + Username: *v.Username, + Password: *v.Password, + Superuser: v.Superuser, + } + if v.Roles != nil { + res.Roles = make([]string, len(v.Roles)) + for i, val := range v.Roles { + res.Roles[i] = val + } + } + + return res +} + +// unmarshalDatabaseExtensionSpecRequestBodyToControlplaneDatabaseExtensionSpec +// builds a value of type *controlplane.DatabaseExtensionSpec from a value of +// type *DatabaseExtensionSpecRequestBody. +func unmarshalDatabaseExtensionSpecRequestBodyToControlplaneDatabaseExtensionSpec(v *DatabaseExtensionSpecRequestBody) *controlplane.DatabaseExtensionSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseExtensionSpec{ + Name: *v.Name, + Version: v.Version, + } + + return res +} + +// unmarshalBackupConfigSpecRequestBodyToControlplaneBackupConfigSpec builds a +// value of type *controlplane.BackupConfigSpec from a value of type +// *BackupConfigSpecRequestBody. +func unmarshalBackupConfigSpecRequestBodyToControlplaneBackupConfigSpec(v *BackupConfigSpecRequestBody) *controlplane.BackupConfigSpec { + if v == nil { + return nil + } + res := &controlplane.BackupConfigSpec{ + ID: *v.ID, + Provider: *v.Provider, + } + if v.NodeNames != nil { + res.NodeNames = make([]string, len(v.NodeNames)) + for i, val := range v.NodeNames { + res.NodeNames[i] = val + } + } + if v.Repositories != nil { + res.Repositories = make([]*controlplane.BackupRepositorySpec, len(v.Repositories)) + for i, val := range v.Repositories { + res.Repositories[i] = unmarshalBackupRepositorySpecRequestBodyToControlplaneBackupRepositorySpec(val) + } + } + if v.Schedules != nil { + res.Schedules = make([]*controlplane.BackupScheduleSpec, len(v.Schedules)) + for i, val := range v.Schedules { + res.Schedules[i] = unmarshalBackupScheduleSpecRequestBodyToControlplaneBackupScheduleSpec(val) + } + } + + return res +} + +// unmarshalBackupRepositorySpecRequestBodyToControlplaneBackupRepositorySpec +// builds a value of type *controlplane.BackupRepositorySpec from a value of +// type *BackupRepositorySpecRequestBody. +func unmarshalBackupRepositorySpecRequestBodyToControlplaneBackupRepositorySpec(v *BackupRepositorySpecRequestBody) *controlplane.BackupRepositorySpec { + if v == nil { + return nil + } + res := &controlplane.BackupRepositorySpec{ + ID: v.ID, + Type: *v.Type, + S3Bucket: v.S3Bucket, + S3Region: v.S3Region, + S3Endpoint: v.S3Endpoint, + GcsBucket: v.GcsBucket, + GcsEndpoint: v.GcsEndpoint, + AzureAccount: v.AzureAccount, + AzureContainer: v.AzureContainer, + AzureEndpoint: v.AzureEndpoint, + RetentionFull: v.RetentionFull, + RetentionFullType: v.RetentionFullType, + BasePath: v.BasePath, + } + + return res +} + +// unmarshalBackupScheduleSpecRequestBodyToControlplaneBackupScheduleSpec +// builds a value of type *controlplane.BackupScheduleSpec from a value of type +// *BackupScheduleSpecRequestBody. +func unmarshalBackupScheduleSpecRequestBodyToControlplaneBackupScheduleSpec(v *BackupScheduleSpecRequestBody) *controlplane.BackupScheduleSpec { + if v == nil { + return nil + } + res := &controlplane.BackupScheduleSpec{ + ID: *v.ID, + Type: *v.Type, + CronExpression: *v.CronExpression, + } + + return res +} + +// marshalControlplaneDatabaseStatusToDatabaseStatusResponseBody builds a value +// of type *DatabaseStatusResponseBody from a value of type +// *controlplane.DatabaseStatus. +func marshalControlplaneDatabaseStatusToDatabaseStatusResponseBody(v *controlplane.DatabaseStatus) *DatabaseStatusResponseBody { + res := &DatabaseStatusResponseBody{ + State: v.State, + UpdatedAt: v.UpdatedAt, + } + + return res +} + +// marshalControlplaneInstanceToInstanceResponseBody builds a value of type +// *InstanceResponseBody from a value of type *controlplane.Instance. +func marshalControlplaneInstanceToInstanceResponseBody(v *controlplane.Instance) *InstanceResponseBody { + res := &InstanceResponseBody{ + ID: v.ID, + HostID: v.HostID, + NodeName: v.NodeName, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + } + if v.Status != nil { + res.Status = marshalControlplaneInstanceStatusToInstanceStatusResponseBody(v.Status) + } + if v.Interfaces != nil { + res.Interfaces = make([]*InstanceInterfaceResponseBody, len(v.Interfaces)) + for i, val := range v.Interfaces { + res.Interfaces[i] = marshalControlplaneInstanceInterfaceToInstanceInterfaceResponseBody(val) + } + } + + return res +} + +// marshalControlplaneInstanceStatusToInstanceStatusResponseBody builds a value +// of type *InstanceStatusResponseBody from a value of type +// *controlplane.InstanceStatus. +func marshalControlplaneInstanceStatusToInstanceStatusResponseBody(v *controlplane.InstanceStatus) *InstanceStatusResponseBody { + res := &InstanceStatusResponseBody{ + State: v.State, + PatroniState: v.PatroniState, + Role: v.Role, + ReadOnly: v.ReadOnly, + PendingRestart: v.PendingRestart, + PatroniPaused: v.PatroniPaused, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + UpdatedAt: v.UpdatedAt, + } + + return res +} + +// marshalControlplaneInstanceInterfaceToInstanceInterfaceResponseBody builds a +// value of type *InstanceInterfaceResponseBody from a value of type +// *controlplane.InstanceInterface. +func marshalControlplaneInstanceInterfaceToInstanceInterfaceResponseBody(v *controlplane.InstanceInterface) *InstanceInterfaceResponseBody { + if v == nil { + return nil + } + res := &InstanceInterfaceResponseBody{ + NetworkType: v.NetworkType, + NetworkID: v.NetworkID, + Hostname: v.Hostname, + Ipv4Address: v.Ipv4Address, + Port: v.Port, + } + + return res +} + +// marshalControlplaneDatabaseSpecToDatabaseSpecResponseBody builds a value of +// type *DatabaseSpecResponseBody from a value of type +// *controlplane.DatabaseSpec. +func marshalControlplaneDatabaseSpecToDatabaseSpecResponseBody(v *controlplane.DatabaseSpec) *DatabaseSpecResponseBody { + if v == nil { + return nil + } + res := &DatabaseSpecResponseBody{ + DatabaseName: v.DatabaseName, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + Port: v.Port, + DeletionProtection: v.DeletionProtection, + } + if v.Nodes != nil { + res.Nodes = make([]*DatabaseNodeSpecResponseBody, len(v.Nodes)) + for i, val := range v.Nodes { + res.Nodes[i] = marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecResponseBody(val) + } + } else { + res.Nodes = []*DatabaseNodeSpecResponseBody{} + } + if v.DatabaseUsers != nil { + res.DatabaseUsers = make([]*DatabaseUserSpecResponseBody, len(v.DatabaseUsers)) + for i, val := range v.DatabaseUsers { + res.DatabaseUsers[i] = marshalControlplaneDatabaseUserSpecToDatabaseUserSpecResponseBody(val) + } + } + if v.Extensions != nil { + res.Extensions = make([]*DatabaseExtensionSpecResponseBody, len(v.Extensions)) + for i, val := range v.Extensions { + res.Extensions[i] = marshalControlplaneDatabaseExtensionSpecToDatabaseExtensionSpecResponseBody(val) + } + } + if v.Features != nil { + res.Features = make(map[string]string, len(v.Features)) + for key, val := range v.Features { + tk := key + tv := val + res.Features[tk] = tv + } + } + if v.BackupConfigs != nil { + res.BackupConfigs = make([]*BackupConfigSpecResponseBody, len(v.BackupConfigs)) + for i, val := range v.BackupConfigs { + res.BackupConfigs[i] = marshalControlplaneBackupConfigSpecToBackupConfigSpecResponseBody(val) + } + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecResponseBody builds a +// value of type *DatabaseNodeSpecResponseBody from a value of type +// *controlplane.DatabaseNodeSpec. +func marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecResponseBody(v *controlplane.DatabaseNodeSpec) *DatabaseNodeSpecResponseBody { + res := &DatabaseNodeSpecResponseBody{ + Name: v.Name, + InstanceID: v.InstanceID, + HostID: v.HostID, + PostgresVersion: v.PostgresVersion, + Port: v.Port, + } + if v.ReadReplicas != nil { + res.ReadReplicas = marshalControlplaneDatabaseReplicaSpecToDatabaseReplicaSpecResponseBody(v.ReadReplicas) + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// marshalControlplaneDatabaseReplicaSpecToDatabaseReplicaSpecResponseBody +// builds a value of type *DatabaseReplicaSpecResponseBody from a value of type +// *controlplane.DatabaseReplicaSpec. +func marshalControlplaneDatabaseReplicaSpecToDatabaseReplicaSpecResponseBody(v *controlplane.DatabaseReplicaSpec) *DatabaseReplicaSpecResponseBody { + if v == nil { + return nil + } + res := &DatabaseReplicaSpecResponseBody{ + InstanceID: v.InstanceID, + HostID: v.HostID, + } + + return res +} + +// marshalControlplaneDatabaseUserSpecToDatabaseUserSpecResponseBody builds a +// value of type *DatabaseUserSpecResponseBody from a value of type +// *controlplane.DatabaseUserSpec. +func marshalControlplaneDatabaseUserSpecToDatabaseUserSpecResponseBody(v *controlplane.DatabaseUserSpec) *DatabaseUserSpecResponseBody { + if v == nil { + return nil + } + res := &DatabaseUserSpecResponseBody{ + Username: v.Username, + Password: v.Password, + Superuser: v.Superuser, + } + if v.Roles != nil { + res.Roles = make([]string, len(v.Roles)) + for i, val := range v.Roles { + res.Roles[i] = val + } + } + + return res +} + +// marshalControlplaneDatabaseExtensionSpecToDatabaseExtensionSpecResponseBody +// builds a value of type *DatabaseExtensionSpecResponseBody from a value of +// type *controlplane.DatabaseExtensionSpec. +func marshalControlplaneDatabaseExtensionSpecToDatabaseExtensionSpecResponseBody(v *controlplane.DatabaseExtensionSpec) *DatabaseExtensionSpecResponseBody { + if v == nil { + return nil + } + res := &DatabaseExtensionSpecResponseBody{ + Name: v.Name, + Version: v.Version, + } + + return res +} + +// marshalControlplaneBackupConfigSpecToBackupConfigSpecResponseBody builds a +// value of type *BackupConfigSpecResponseBody from a value of type +// *controlplane.BackupConfigSpec. +func marshalControlplaneBackupConfigSpecToBackupConfigSpecResponseBody(v *controlplane.BackupConfigSpec) *BackupConfigSpecResponseBody { + if v == nil { + return nil + } + res := &BackupConfigSpecResponseBody{ + ID: v.ID, + Provider: v.Provider, + } + if v.NodeNames != nil { + res.NodeNames = make([]string, len(v.NodeNames)) + for i, val := range v.NodeNames { + res.NodeNames[i] = val + } + } + if v.Repositories != nil { + res.Repositories = make([]*BackupRepositorySpecResponseBody, len(v.Repositories)) + for i, val := range v.Repositories { + res.Repositories[i] = marshalControlplaneBackupRepositorySpecToBackupRepositorySpecResponseBody(val) + } + } + if v.Schedules != nil { + res.Schedules = make([]*BackupScheduleSpecResponseBody, len(v.Schedules)) + for i, val := range v.Schedules { + res.Schedules[i] = marshalControlplaneBackupScheduleSpecToBackupScheduleSpecResponseBody(val) + } + } + + return res +} + +// marshalControlplaneBackupRepositorySpecToBackupRepositorySpecResponseBody +// builds a value of type *BackupRepositorySpecResponseBody from a value of +// type *controlplane.BackupRepositorySpec. +func marshalControlplaneBackupRepositorySpecToBackupRepositorySpecResponseBody(v *controlplane.BackupRepositorySpec) *BackupRepositorySpecResponseBody { + if v == nil { + return nil + } + res := &BackupRepositorySpecResponseBody{ + ID: v.ID, + Type: v.Type, + S3Bucket: v.S3Bucket, + S3Region: v.S3Region, + S3Endpoint: v.S3Endpoint, + GcsBucket: v.GcsBucket, + GcsEndpoint: v.GcsEndpoint, + AzureAccount: v.AzureAccount, + AzureContainer: v.AzureContainer, + AzureEndpoint: v.AzureEndpoint, + RetentionFull: v.RetentionFull, + RetentionFullType: v.RetentionFullType, + BasePath: v.BasePath, + } + + return res +} + +// marshalControlplaneBackupScheduleSpecToBackupScheduleSpecResponseBody builds +// a value of type *BackupScheduleSpecResponseBody from a value of type +// *controlplane.BackupScheduleSpec. +func marshalControlplaneBackupScheduleSpecToBackupScheduleSpecResponseBody(v *controlplane.BackupScheduleSpec) *BackupScheduleSpecResponseBody { + if v == nil { + return nil + } + res := &BackupScheduleSpecResponseBody{ + ID: v.ID, + Type: v.Type, + CronExpression: v.CronExpression, + } + + return res +} + +// unmarshalDatabaseSpecRequestBodyRequestBodyToControlplaneDatabaseSpec builds +// a value of type *controlplane.DatabaseSpec from a value of type +// *DatabaseSpecRequestBodyRequestBody. +func unmarshalDatabaseSpecRequestBodyRequestBodyToControlplaneDatabaseSpec(v *DatabaseSpecRequestBodyRequestBody) *controlplane.DatabaseSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseSpec{ + DatabaseName: *v.DatabaseName, + PostgresVersion: v.PostgresVersion, + SpockVersion: v.SpockVersion, + Port: v.Port, + DeletionProtection: v.DeletionProtection, + } + res.Nodes = make([]*controlplane.DatabaseNodeSpec, len(v.Nodes)) + for i, val := range v.Nodes { + res.Nodes[i] = unmarshalDatabaseNodeSpecRequestBodyRequestBodyToControlplaneDatabaseNodeSpec(val) + } + if v.DatabaseUsers != nil { + res.DatabaseUsers = make([]*controlplane.DatabaseUserSpec, len(v.DatabaseUsers)) + for i, val := range v.DatabaseUsers { + res.DatabaseUsers[i] = unmarshalDatabaseUserSpecRequestBodyRequestBodyToControlplaneDatabaseUserSpec(val) + } + } + if v.Extensions != nil { + res.Extensions = make([]*controlplane.DatabaseExtensionSpec, len(v.Extensions)) + for i, val := range v.Extensions { + res.Extensions[i] = unmarshalDatabaseExtensionSpecRequestBodyRequestBodyToControlplaneDatabaseExtensionSpec(val) + } + } + if v.Features != nil { + res.Features = make(map[string]string, len(v.Features)) + for key, val := range v.Features { + tk := key + tv := val + res.Features[tk] = tv + } + } + if v.BackupConfigs != nil { + res.BackupConfigs = make([]*controlplane.BackupConfigSpec, len(v.BackupConfigs)) + for i, val := range v.BackupConfigs { + res.BackupConfigs[i] = unmarshalBackupConfigSpecRequestBodyRequestBodyToControlplaneBackupConfigSpec(val) + } + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// unmarshalDatabaseNodeSpecRequestBodyRequestBodyToControlplaneDatabaseNodeSpec +// builds a value of type *controlplane.DatabaseNodeSpec from a value of type +// *DatabaseNodeSpecRequestBodyRequestBody. +func unmarshalDatabaseNodeSpecRequestBodyRequestBodyToControlplaneDatabaseNodeSpec(v *DatabaseNodeSpecRequestBodyRequestBody) *controlplane.DatabaseNodeSpec { + res := &controlplane.DatabaseNodeSpec{ + Name: *v.Name, + InstanceID: *v.InstanceID, + HostID: *v.HostID, + PostgresVersion: v.PostgresVersion, + Port: v.Port, + } + if v.ReadReplicas != nil { + res.ReadReplicas = unmarshalDatabaseReplicaSpecRequestBodyRequestBodyToControlplaneDatabaseReplicaSpec(v.ReadReplicas) + } + if v.PostgresqlConf != nil { + res.PostgresqlConf = make(map[string]any, len(v.PostgresqlConf)) + for key, val := range v.PostgresqlConf { + tk := key + tv := val + res.PostgresqlConf[tk] = tv + } + } + + return res +} + +// unmarshalDatabaseReplicaSpecRequestBodyRequestBodyToControlplaneDatabaseReplicaSpec +// builds a value of type *controlplane.DatabaseReplicaSpec from a value of +// type *DatabaseReplicaSpecRequestBodyRequestBody. +func unmarshalDatabaseReplicaSpecRequestBodyRequestBodyToControlplaneDatabaseReplicaSpec(v *DatabaseReplicaSpecRequestBodyRequestBody) *controlplane.DatabaseReplicaSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseReplicaSpec{ + InstanceID: *v.InstanceID, + HostID: *v.HostID, + } + + return res +} + +// unmarshalDatabaseUserSpecRequestBodyRequestBodyToControlplaneDatabaseUserSpec +// builds a value of type *controlplane.DatabaseUserSpec from a value of type +// *DatabaseUserSpecRequestBodyRequestBody. +func unmarshalDatabaseUserSpecRequestBodyRequestBodyToControlplaneDatabaseUserSpec(v *DatabaseUserSpecRequestBodyRequestBody) *controlplane.DatabaseUserSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseUserSpec{ + Username: *v.Username, + Password: *v.Password, + Superuser: v.Superuser, + } + if v.Roles != nil { + res.Roles = make([]string, len(v.Roles)) + for i, val := range v.Roles { + res.Roles[i] = val + } + } + + return res +} + +// unmarshalDatabaseExtensionSpecRequestBodyRequestBodyToControlplaneDatabaseExtensionSpec +// builds a value of type *controlplane.DatabaseExtensionSpec from a value of +// type *DatabaseExtensionSpecRequestBodyRequestBody. +func unmarshalDatabaseExtensionSpecRequestBodyRequestBodyToControlplaneDatabaseExtensionSpec(v *DatabaseExtensionSpecRequestBodyRequestBody) *controlplane.DatabaseExtensionSpec { + if v == nil { + return nil + } + res := &controlplane.DatabaseExtensionSpec{ + Name: *v.Name, + Version: v.Version, + } + + return res +} + +// unmarshalBackupConfigSpecRequestBodyRequestBodyToControlplaneBackupConfigSpec +// builds a value of type *controlplane.BackupConfigSpec from a value of type +// *BackupConfigSpecRequestBodyRequestBody. +func unmarshalBackupConfigSpecRequestBodyRequestBodyToControlplaneBackupConfigSpec(v *BackupConfigSpecRequestBodyRequestBody) *controlplane.BackupConfigSpec { + if v == nil { + return nil + } + res := &controlplane.BackupConfigSpec{ + ID: *v.ID, + Provider: *v.Provider, + } + if v.NodeNames != nil { + res.NodeNames = make([]string, len(v.NodeNames)) + for i, val := range v.NodeNames { + res.NodeNames[i] = val + } + } + if v.Repositories != nil { + res.Repositories = make([]*controlplane.BackupRepositorySpec, len(v.Repositories)) + for i, val := range v.Repositories { + res.Repositories[i] = unmarshalBackupRepositorySpecRequestBodyRequestBodyToControlplaneBackupRepositorySpec(val) + } + } + if v.Schedules != nil { + res.Schedules = make([]*controlplane.BackupScheduleSpec, len(v.Schedules)) + for i, val := range v.Schedules { + res.Schedules[i] = unmarshalBackupScheduleSpecRequestBodyRequestBodyToControlplaneBackupScheduleSpec(val) + } + } + + return res +} + +// unmarshalBackupRepositorySpecRequestBodyRequestBodyToControlplaneBackupRepositorySpec +// builds a value of type *controlplane.BackupRepositorySpec from a value of +// type *BackupRepositorySpecRequestBodyRequestBody. +func unmarshalBackupRepositorySpecRequestBodyRequestBodyToControlplaneBackupRepositorySpec(v *BackupRepositorySpecRequestBodyRequestBody) *controlplane.BackupRepositorySpec { + if v == nil { + return nil + } + res := &controlplane.BackupRepositorySpec{ + ID: v.ID, + Type: *v.Type, + S3Bucket: v.S3Bucket, + S3Region: v.S3Region, + S3Endpoint: v.S3Endpoint, + GcsBucket: v.GcsBucket, + GcsEndpoint: v.GcsEndpoint, + AzureAccount: v.AzureAccount, + AzureContainer: v.AzureContainer, + AzureEndpoint: v.AzureEndpoint, + RetentionFull: v.RetentionFull, + RetentionFullType: v.RetentionFullType, + BasePath: v.BasePath, + } + + return res +} + +// unmarshalBackupScheduleSpecRequestBodyRequestBodyToControlplaneBackupScheduleSpec +// builds a value of type *controlplane.BackupScheduleSpec from a value of type +// *BackupScheduleSpecRequestBodyRequestBody. +func unmarshalBackupScheduleSpecRequestBodyRequestBodyToControlplaneBackupScheduleSpec(v *BackupScheduleSpecRequestBodyRequestBody) *controlplane.BackupScheduleSpec { + if v == nil { + return nil + } + res := &controlplane.BackupScheduleSpec{ + ID: *v.ID, + Type: *v.Type, + CronExpression: *v.CronExpression, + } + + return res +} diff --git a/api/gen/http/control_plane/server/paths.go b/api/gen/http/control_plane/server/paths.go new file mode 100644 index 00000000..afe35d85 --- /dev/null +++ b/api/gen/http/control_plane/server/paths.go @@ -0,0 +1,57 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// HTTP request path constructors for the control-plane service. +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package server + +import ( + "fmt" +) + +// InspectClusterControlPlanePath returns the URL path to the control-plane service inspect-cluster HTTP endpoint. +func InspectClusterControlPlanePath() string { + return "/cluster" +} + +// ListHostsControlPlanePath returns the URL path to the control-plane service list-hosts HTTP endpoint. +func ListHostsControlPlanePath() string { + return "/hosts" +} + +// InspectHostControlPlanePath returns the URL path to the control-plane service inspect-host HTTP endpoint. +func InspectHostControlPlanePath(hostID string) string { + return fmt.Sprintf("/hosts/%v", hostID) +} + +// RemoveHostControlPlanePath returns the URL path to the control-plane service remove-host HTTP endpoint. +func RemoveHostControlPlanePath(hostID string) string { + return fmt.Sprintf("/hosts/%v", hostID) +} + +// ListDatabasesControlPlanePath returns the URL path to the control-plane service list-databases HTTP endpoint. +func ListDatabasesControlPlanePath() string { + return "/databases" +} + +// CreateDatabaseControlPlanePath returns the URL path to the control-plane service create-database HTTP endpoint. +func CreateDatabaseControlPlanePath() string { + return "/databases" +} + +// InspectDatabaseControlPlanePath returns the URL path to the control-plane service inspect-database HTTP endpoint. +func InspectDatabaseControlPlanePath(databaseID string) string { + return fmt.Sprintf("/databases/%v", databaseID) +} + +// UpdateDatabaseControlPlanePath returns the URL path to the control-plane service update-database HTTP endpoint. +func UpdateDatabaseControlPlanePath(databaseID string) string { + return fmt.Sprintf("/databases/%v", databaseID) +} + +// DeleteDatabaseControlPlanePath returns the URL path to the control-plane service delete-database HTTP endpoint. +func DeleteDatabaseControlPlanePath(databaseID string) string { + return fmt.Sprintf("/databases/%v", databaseID) +} diff --git a/api/gen/http/control_plane/server/server.go b/api/gen/http/control_plane/server/server.go new file mode 100644 index 00000000..f0a4992c --- /dev/null +++ b/api/gen/http/control_plane/server/server.go @@ -0,0 +1,592 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// control-plane HTTP server +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package server + +import ( + "context" + "net/http" + "path" + + controlplane "github.com/pgEdge/control-plane/api/gen/control_plane" + goahttp "goa.design/goa/v3/http" + goa "goa.design/goa/v3/pkg" +) + +// Server lists the control-plane service endpoint HTTP handlers. +type Server struct { + Mounts []*MountPoint + InspectCluster http.Handler + ListHosts http.Handler + InspectHost http.Handler + RemoveHost http.Handler + ListDatabases http.Handler + CreateDatabase http.Handler + InspectDatabase http.Handler + UpdateDatabase http.Handler + DeleteDatabase http.Handler + GenHTTPOpenapiJSON http.Handler +} + +// MountPoint holds information about the mounted endpoints. +type MountPoint struct { + // Method is the name of the service method served by the mounted HTTP handler. + Method string + // Verb is the HTTP method used to match requests to the mounted handler. + Verb string + // Pattern is the HTTP request path pattern used to match requests to the + // mounted handler. + Pattern string +} + +// New instantiates HTTP handlers for all the control-plane service endpoints +// using the provided encoder and decoder. The handlers are mounted on the +// given mux using the HTTP verb and path defined in the design. errhandler is +// called whenever a response fails to be encoded. formatter is used to format +// errors returned by the service methods prior to encoding. Both errhandler +// and formatter are optional and can be nil. +func New( + e *controlplane.Endpoints, + mux goahttp.Muxer, + decoder func(*http.Request) goahttp.Decoder, + encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, + errhandler func(context.Context, http.ResponseWriter, error), + formatter func(ctx context.Context, err error) goahttp.Statuser, + fileSystemGenHTTPOpenapiJSON http.FileSystem, +) *Server { + if fileSystemGenHTTPOpenapiJSON == nil { + fileSystemGenHTTPOpenapiJSON = http.Dir(".") + } + fileSystemGenHTTPOpenapiJSON = appendPrefix(fileSystemGenHTTPOpenapiJSON, "/gen/http") + return &Server{ + Mounts: []*MountPoint{ + {"InspectCluster", "GET", "/cluster"}, + {"ListHosts", "GET", "/hosts"}, + {"InspectHost", "GET", "/hosts/{host_id}"}, + {"RemoveHost", "DELETE", "/hosts/{host_id}"}, + {"ListDatabases", "GET", "/databases"}, + {"CreateDatabase", "POST", "/databases"}, + {"InspectDatabase", "GET", "/databases/{database_id}"}, + {"UpdateDatabase", "POST", "/databases/{database_id}"}, + {"DeleteDatabase", "DELETE", "/databases/{database_id}"}, + {"Serve ./gen/http/openapi.json", "GET", "/openapi.json"}, + }, + InspectCluster: NewInspectClusterHandler(e.InspectCluster, mux, decoder, encoder, errhandler, formatter), + ListHosts: NewListHostsHandler(e.ListHosts, mux, decoder, encoder, errhandler, formatter), + InspectHost: NewInspectHostHandler(e.InspectHost, mux, decoder, encoder, errhandler, formatter), + RemoveHost: NewRemoveHostHandler(e.RemoveHost, mux, decoder, encoder, errhandler, formatter), + ListDatabases: NewListDatabasesHandler(e.ListDatabases, mux, decoder, encoder, errhandler, formatter), + CreateDatabase: NewCreateDatabaseHandler(e.CreateDatabase, mux, decoder, encoder, errhandler, formatter), + InspectDatabase: NewInspectDatabaseHandler(e.InspectDatabase, mux, decoder, encoder, errhandler, formatter), + UpdateDatabase: NewUpdateDatabaseHandler(e.UpdateDatabase, mux, decoder, encoder, errhandler, formatter), + DeleteDatabase: NewDeleteDatabaseHandler(e.DeleteDatabase, mux, decoder, encoder, errhandler, formatter), + GenHTTPOpenapiJSON: http.FileServer(fileSystemGenHTTPOpenapiJSON), + } +} + +// Service returns the name of the service served. +func (s *Server) Service() string { return "control-plane" } + +// Use wraps the server handlers with the given middleware. +func (s *Server) Use(m func(http.Handler) http.Handler) { + s.InspectCluster = m(s.InspectCluster) + s.ListHosts = m(s.ListHosts) + s.InspectHost = m(s.InspectHost) + s.RemoveHost = m(s.RemoveHost) + s.ListDatabases = m(s.ListDatabases) + s.CreateDatabase = m(s.CreateDatabase) + s.InspectDatabase = m(s.InspectDatabase) + s.UpdateDatabase = m(s.UpdateDatabase) + s.DeleteDatabase = m(s.DeleteDatabase) +} + +// MethodNames returns the methods served. +func (s *Server) MethodNames() []string { return controlplane.MethodNames[:] } + +// Mount configures the mux to serve the control-plane endpoints. +func Mount(mux goahttp.Muxer, h *Server) { + MountInspectClusterHandler(mux, h.InspectCluster) + MountListHostsHandler(mux, h.ListHosts) + MountInspectHostHandler(mux, h.InspectHost) + MountRemoveHostHandler(mux, h.RemoveHost) + MountListDatabasesHandler(mux, h.ListDatabases) + MountCreateDatabaseHandler(mux, h.CreateDatabase) + MountInspectDatabaseHandler(mux, h.InspectDatabase) + MountUpdateDatabaseHandler(mux, h.UpdateDatabase) + MountDeleteDatabaseHandler(mux, h.DeleteDatabase) + MountGenHTTPOpenapiJSON(mux, h.GenHTTPOpenapiJSON) +} + +// Mount configures the mux to serve the control-plane endpoints. +func (s *Server) Mount(mux goahttp.Muxer) { + Mount(mux, s) +} + +// MountInspectClusterHandler configures the mux to serve the "control-plane" +// service "inspect-cluster" endpoint. +func MountInspectClusterHandler(mux goahttp.Muxer, h http.Handler) { + f, ok := h.(http.HandlerFunc) + if !ok { + f = func(w http.ResponseWriter, r *http.Request) { + h.ServeHTTP(w, r) + } + } + mux.Handle("GET", "/cluster", f) +} + +// NewInspectClusterHandler creates a HTTP handler which loads the HTTP request +// and calls the "control-plane" service "inspect-cluster" endpoint. +func NewInspectClusterHandler( + endpoint goa.Endpoint, + mux goahttp.Muxer, + decoder func(*http.Request) goahttp.Decoder, + encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, + errhandler func(context.Context, http.ResponseWriter, error), + formatter func(ctx context.Context, err error) goahttp.Statuser, +) http.Handler { + var ( + encodeResponse = EncodeInspectClusterResponse(encoder) + encodeError = goahttp.ErrorEncoder(encoder, formatter) + ) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept")) + ctx = context.WithValue(ctx, goa.MethodKey, "inspect-cluster") + ctx = context.WithValue(ctx, goa.ServiceKey, "control-plane") + var err error + res, err := endpoint(ctx, nil) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + if err := encodeResponse(ctx, w, res); err != nil { + errhandler(ctx, w, err) + } + }) +} + +// MountListHostsHandler configures the mux to serve the "control-plane" +// service "list-hosts" endpoint. +func MountListHostsHandler(mux goahttp.Muxer, h http.Handler) { + f, ok := h.(http.HandlerFunc) + if !ok { + f = func(w http.ResponseWriter, r *http.Request) { + h.ServeHTTP(w, r) + } + } + mux.Handle("GET", "/hosts", f) +} + +// NewListHostsHandler creates a HTTP handler which loads the HTTP request and +// calls the "control-plane" service "list-hosts" endpoint. +func NewListHostsHandler( + endpoint goa.Endpoint, + mux goahttp.Muxer, + decoder func(*http.Request) goahttp.Decoder, + encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, + errhandler func(context.Context, http.ResponseWriter, error), + formatter func(ctx context.Context, err error) goahttp.Statuser, +) http.Handler { + var ( + encodeResponse = EncodeListHostsResponse(encoder) + encodeError = goahttp.ErrorEncoder(encoder, formatter) + ) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept")) + ctx = context.WithValue(ctx, goa.MethodKey, "list-hosts") + ctx = context.WithValue(ctx, goa.ServiceKey, "control-plane") + var err error + res, err := endpoint(ctx, nil) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + if err := encodeResponse(ctx, w, res); err != nil { + errhandler(ctx, w, err) + } + }) +} + +// MountInspectHostHandler configures the mux to serve the "control-plane" +// service "inspect-host" endpoint. +func MountInspectHostHandler(mux goahttp.Muxer, h http.Handler) { + f, ok := h.(http.HandlerFunc) + if !ok { + f = func(w http.ResponseWriter, r *http.Request) { + h.ServeHTTP(w, r) + } + } + mux.Handle("GET", "/hosts/{host_id}", f) +} + +// NewInspectHostHandler creates a HTTP handler which loads the HTTP request +// and calls the "control-plane" service "inspect-host" endpoint. +func NewInspectHostHandler( + endpoint goa.Endpoint, + mux goahttp.Muxer, + decoder func(*http.Request) goahttp.Decoder, + encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, + errhandler func(context.Context, http.ResponseWriter, error), + formatter func(ctx context.Context, err error) goahttp.Statuser, +) http.Handler { + var ( + decodeRequest = DecodeInspectHostRequest(mux, decoder) + encodeResponse = EncodeInspectHostResponse(encoder) + encodeError = goahttp.ErrorEncoder(encoder, formatter) + ) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept")) + ctx = context.WithValue(ctx, goa.MethodKey, "inspect-host") + ctx = context.WithValue(ctx, goa.ServiceKey, "control-plane") + payload, err := decodeRequest(r) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + res, err := endpoint(ctx, payload) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + if err := encodeResponse(ctx, w, res); err != nil { + errhandler(ctx, w, err) + } + }) +} + +// MountRemoveHostHandler configures the mux to serve the "control-plane" +// service "remove-host" endpoint. +func MountRemoveHostHandler(mux goahttp.Muxer, h http.Handler) { + f, ok := h.(http.HandlerFunc) + if !ok { + f = func(w http.ResponseWriter, r *http.Request) { + h.ServeHTTP(w, r) + } + } + mux.Handle("DELETE", "/hosts/{host_id}", f) +} + +// NewRemoveHostHandler creates a HTTP handler which loads the HTTP request and +// calls the "control-plane" service "remove-host" endpoint. +func NewRemoveHostHandler( + endpoint goa.Endpoint, + mux goahttp.Muxer, + decoder func(*http.Request) goahttp.Decoder, + encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, + errhandler func(context.Context, http.ResponseWriter, error), + formatter func(ctx context.Context, err error) goahttp.Statuser, +) http.Handler { + var ( + decodeRequest = DecodeRemoveHostRequest(mux, decoder) + encodeResponse = EncodeRemoveHostResponse(encoder) + encodeError = goahttp.ErrorEncoder(encoder, formatter) + ) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept")) + ctx = context.WithValue(ctx, goa.MethodKey, "remove-host") + ctx = context.WithValue(ctx, goa.ServiceKey, "control-plane") + payload, err := decodeRequest(r) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + res, err := endpoint(ctx, payload) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + if err := encodeResponse(ctx, w, res); err != nil { + errhandler(ctx, w, err) + } + }) +} + +// MountListDatabasesHandler configures the mux to serve the "control-plane" +// service "list-databases" endpoint. +func MountListDatabasesHandler(mux goahttp.Muxer, h http.Handler) { + f, ok := h.(http.HandlerFunc) + if !ok { + f = func(w http.ResponseWriter, r *http.Request) { + h.ServeHTTP(w, r) + } + } + mux.Handle("GET", "/databases", f) +} + +// NewListDatabasesHandler creates a HTTP handler which loads the HTTP request +// and calls the "control-plane" service "list-databases" endpoint. +func NewListDatabasesHandler( + endpoint goa.Endpoint, + mux goahttp.Muxer, + decoder func(*http.Request) goahttp.Decoder, + encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, + errhandler func(context.Context, http.ResponseWriter, error), + formatter func(ctx context.Context, err error) goahttp.Statuser, +) http.Handler { + var ( + encodeResponse = EncodeListDatabasesResponse(encoder) + encodeError = goahttp.ErrorEncoder(encoder, formatter) + ) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept")) + ctx = context.WithValue(ctx, goa.MethodKey, "list-databases") + ctx = context.WithValue(ctx, goa.ServiceKey, "control-plane") + var err error + res, err := endpoint(ctx, nil) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + if err := encodeResponse(ctx, w, res); err != nil { + errhandler(ctx, w, err) + } + }) +} + +// MountCreateDatabaseHandler configures the mux to serve the "control-plane" +// service "create-database" endpoint. +func MountCreateDatabaseHandler(mux goahttp.Muxer, h http.Handler) { + f, ok := h.(http.HandlerFunc) + if !ok { + f = func(w http.ResponseWriter, r *http.Request) { + h.ServeHTTP(w, r) + } + } + mux.Handle("POST", "/databases", f) +} + +// NewCreateDatabaseHandler creates a HTTP handler which loads the HTTP request +// and calls the "control-plane" service "create-database" endpoint. +func NewCreateDatabaseHandler( + endpoint goa.Endpoint, + mux goahttp.Muxer, + decoder func(*http.Request) goahttp.Decoder, + encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, + errhandler func(context.Context, http.ResponseWriter, error), + formatter func(ctx context.Context, err error) goahttp.Statuser, +) http.Handler { + var ( + decodeRequest = DecodeCreateDatabaseRequest(mux, decoder) + encodeResponse = EncodeCreateDatabaseResponse(encoder) + encodeError = goahttp.ErrorEncoder(encoder, formatter) + ) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept")) + ctx = context.WithValue(ctx, goa.MethodKey, "create-database") + ctx = context.WithValue(ctx, goa.ServiceKey, "control-plane") + payload, err := decodeRequest(r) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + res, err := endpoint(ctx, payload) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + if err := encodeResponse(ctx, w, res); err != nil { + errhandler(ctx, w, err) + } + }) +} + +// MountInspectDatabaseHandler configures the mux to serve the "control-plane" +// service "inspect-database" endpoint. +func MountInspectDatabaseHandler(mux goahttp.Muxer, h http.Handler) { + f, ok := h.(http.HandlerFunc) + if !ok { + f = func(w http.ResponseWriter, r *http.Request) { + h.ServeHTTP(w, r) + } + } + mux.Handle("GET", "/databases/{database_id}", f) +} + +// NewInspectDatabaseHandler creates a HTTP handler which loads the HTTP +// request and calls the "control-plane" service "inspect-database" endpoint. +func NewInspectDatabaseHandler( + endpoint goa.Endpoint, + mux goahttp.Muxer, + decoder func(*http.Request) goahttp.Decoder, + encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, + errhandler func(context.Context, http.ResponseWriter, error), + formatter func(ctx context.Context, err error) goahttp.Statuser, +) http.Handler { + var ( + decodeRequest = DecodeInspectDatabaseRequest(mux, decoder) + encodeResponse = EncodeInspectDatabaseResponse(encoder) + encodeError = goahttp.ErrorEncoder(encoder, formatter) + ) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept")) + ctx = context.WithValue(ctx, goa.MethodKey, "inspect-database") + ctx = context.WithValue(ctx, goa.ServiceKey, "control-plane") + payload, err := decodeRequest(r) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + res, err := endpoint(ctx, payload) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + if err := encodeResponse(ctx, w, res); err != nil { + errhandler(ctx, w, err) + } + }) +} + +// MountUpdateDatabaseHandler configures the mux to serve the "control-plane" +// service "update-database" endpoint. +func MountUpdateDatabaseHandler(mux goahttp.Muxer, h http.Handler) { + f, ok := h.(http.HandlerFunc) + if !ok { + f = func(w http.ResponseWriter, r *http.Request) { + h.ServeHTTP(w, r) + } + } + mux.Handle("POST", "/databases/{database_id}", f) +} + +// NewUpdateDatabaseHandler creates a HTTP handler which loads the HTTP request +// and calls the "control-plane" service "update-database" endpoint. +func NewUpdateDatabaseHandler( + endpoint goa.Endpoint, + mux goahttp.Muxer, + decoder func(*http.Request) goahttp.Decoder, + encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, + errhandler func(context.Context, http.ResponseWriter, error), + formatter func(ctx context.Context, err error) goahttp.Statuser, +) http.Handler { + var ( + decodeRequest = DecodeUpdateDatabaseRequest(mux, decoder) + encodeResponse = EncodeUpdateDatabaseResponse(encoder) + encodeError = goahttp.ErrorEncoder(encoder, formatter) + ) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept")) + ctx = context.WithValue(ctx, goa.MethodKey, "update-database") + ctx = context.WithValue(ctx, goa.ServiceKey, "control-plane") + payload, err := decodeRequest(r) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + res, err := endpoint(ctx, payload) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + if err := encodeResponse(ctx, w, res); err != nil { + errhandler(ctx, w, err) + } + }) +} + +// MountDeleteDatabaseHandler configures the mux to serve the "control-plane" +// service "delete-database" endpoint. +func MountDeleteDatabaseHandler(mux goahttp.Muxer, h http.Handler) { + f, ok := h.(http.HandlerFunc) + if !ok { + f = func(w http.ResponseWriter, r *http.Request) { + h.ServeHTTP(w, r) + } + } + mux.Handle("DELETE", "/databases/{database_id}", f) +} + +// NewDeleteDatabaseHandler creates a HTTP handler which loads the HTTP request +// and calls the "control-plane" service "delete-database" endpoint. +func NewDeleteDatabaseHandler( + endpoint goa.Endpoint, + mux goahttp.Muxer, + decoder func(*http.Request) goahttp.Decoder, + encoder func(context.Context, http.ResponseWriter) goahttp.Encoder, + errhandler func(context.Context, http.ResponseWriter, error), + formatter func(ctx context.Context, err error) goahttp.Statuser, +) http.Handler { + var ( + decodeRequest = DecodeDeleteDatabaseRequest(mux, decoder) + encodeResponse = EncodeDeleteDatabaseResponse(encoder) + encodeError = goahttp.ErrorEncoder(encoder, formatter) + ) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept")) + ctx = context.WithValue(ctx, goa.MethodKey, "delete-database") + ctx = context.WithValue(ctx, goa.ServiceKey, "control-plane") + payload, err := decodeRequest(r) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + res, err := endpoint(ctx, payload) + if err != nil { + if err := encodeError(ctx, w, err); err != nil { + errhandler(ctx, w, err) + } + return + } + if err := encodeResponse(ctx, w, res); err != nil { + errhandler(ctx, w, err) + } + }) +} + +// appendFS is a custom implementation of fs.FS that appends a specified prefix +// to the file paths before delegating the Open call to the underlying fs.FS. +type appendFS struct { + prefix string + fs http.FileSystem +} + +// Open opens the named file, appending the prefix to the file path before +// passing it to the underlying fs.FS. +func (s appendFS) Open(name string) (http.File, error) { + switch name { + } + return s.fs.Open(path.Join(s.prefix, name)) +} + +// appendPrefix returns a new fs.FS that appends the specified prefix to file paths +// before delegating to the provided embed.FS. +func appendPrefix(fsys http.FileSystem, prefix string) http.FileSystem { + return appendFS{prefix: prefix, fs: fsys} +} + +// MountGenHTTPOpenapiJSON configures the mux to serve GET request made to +// "/openapi.json". +func MountGenHTTPOpenapiJSON(mux goahttp.Muxer, h http.Handler) { + mux.Handle("GET", "/openapi.json", h.ServeHTTP) +} diff --git a/api/gen/http/control_plane/server/types.go b/api/gen/http/control_plane/server/types.go new file mode 100644 index 00000000..950858b7 --- /dev/null +++ b/api/gen/http/control_plane/server/types.go @@ -0,0 +1,1466 @@ +// Code generated by goa v3.19.1, DO NOT EDIT. +// +// control-plane HTTP server types +// +// Command: +// $ goa gen github.com/pgEdge/control-plane/api/design + +package server + +import ( + controlplane "github.com/pgEdge/control-plane/api/gen/control_plane" + goa "goa.design/goa/v3/pkg" +) + +// CreateDatabaseRequestBody is the type of the "control-plane" service +// "create-database" endpoint HTTP request body. +type CreateDatabaseRequestBody struct { + // Unique identifier for the database. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // Unique identifier for the databases's owner. + TenantID *string `form:"tenant_id,omitempty" json:"tenant_id,omitempty" xml:"tenant_id,omitempty"` + // The specification for the database. + Spec *DatabaseSpecRequestBody `form:"spec,omitempty" json:"spec,omitempty" xml:"spec,omitempty"` +} + +// UpdateDatabaseRequestBody is the type of the "control-plane" service +// "update-database" endpoint HTTP request body. +type UpdateDatabaseRequestBody struct { + // The specification for the database. + Spec *DatabaseSpecRequestBodyRequestBody `form:"spec,omitempty" json:"spec,omitempty" xml:"spec,omitempty"` +} + +// InspectClusterResponseBody is the type of the "control-plane" service +// "inspect-cluster" endpoint HTTP response body. +type InspectClusterResponseBody struct { + // Unique identifier for the cluster. + ID string `form:"id" json:"id" xml:"id"` + // Unique identifier for the cluster's owner. + TenantID string `form:"tenant_id" json:"tenant_id" xml:"tenant_id"` + // Current status of the cluster. + Status *ClusterStatusResponseBody `form:"status" json:"status" xml:"status"` + // All of the hosts in the cluster. + Hosts []*HostResponseBody `form:"hosts" json:"hosts" xml:"hosts"` +} + +// ListHostsResponseBody is the type of the "control-plane" service +// "list-hosts" endpoint HTTP response body. +type ListHostsResponseBody []*HostResponse + +// InspectHostResponseBody is the type of the "control-plane" service +// "inspect-host" endpoint HTTP response body. +type InspectHostResponseBody struct { + // Unique identifier for the host + ID string `form:"id" json:"id" xml:"id"` + // The type of this host + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The cohort that this host belongs to + Cohort *string `form:"cohort,omitempty" json:"cohort,omitempty" xml:"cohort,omitempty"` + // The hostname of this host. + Hostname string `form:"hostname" json:"hostname" xml:"hostname"` + // The IPv4 address of this host. + Ipv4Address string `form:"ipv4_address" json:"ipv4_address" xml:"ipv4_address"` + // The configuration for this host + Config *HostConfigurationResponseBody `form:"config,omitempty" json:"config,omitempty" xml:"config,omitempty"` + // Current status of the host + Status *HostStatusResponseBody `form:"status" json:"status" xml:"status"` +} + +// ListDatabasesResponseBody is the type of the "control-plane" service +// "list-databases" endpoint HTTP response body. +type ListDatabasesResponseBody []*DatabaseResponse + +// CreateDatabaseResponseBody is the type of the "control-plane" service +// "create-database" endpoint HTTP response body. +type CreateDatabaseResponseBody struct { + // Unique identifier for the database. + ID string `form:"id" json:"id" xml:"id"` + // Unique identifier for the databases's owner. + TenantID *string `form:"tenant_id,omitempty" json:"tenant_id,omitempty" xml:"tenant_id,omitempty"` + // The time that the database was created. + CreatedAt *string `form:"created_at,omitempty" json:"created_at,omitempty" xml:"created_at,omitempty"` + // The time that the database was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` + // Current status of the database. + Status *DatabaseStatusResponseBody `form:"status" json:"status" xml:"status"` + // All of the instances in the database. + Instances *InstanceResponseBody `form:"instances" json:"instances" xml:"instances"` + // The user-provided specification for the database. + Spec *DatabaseSpecResponseBody `form:"spec,omitempty" json:"spec,omitempty" xml:"spec,omitempty"` +} + +// InspectDatabaseResponseBody is the type of the "control-plane" service +// "inspect-database" endpoint HTTP response body. +type InspectDatabaseResponseBody struct { + // Unique identifier for the database. + ID string `form:"id" json:"id" xml:"id"` + // Unique identifier for the databases's owner. + TenantID *string `form:"tenant_id,omitempty" json:"tenant_id,omitempty" xml:"tenant_id,omitempty"` + // The time that the database was created. + CreatedAt *string `form:"created_at,omitempty" json:"created_at,omitempty" xml:"created_at,omitempty"` + // The time that the database was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` + // Current status of the database. + Status *DatabaseStatusResponseBody `form:"status" json:"status" xml:"status"` + // All of the instances in the database. + Instances *InstanceResponseBody `form:"instances" json:"instances" xml:"instances"` + // The user-provided specification for the database. + Spec *DatabaseSpecResponseBody `form:"spec,omitempty" json:"spec,omitempty" xml:"spec,omitempty"` +} + +// UpdateDatabaseResponseBody is the type of the "control-plane" service +// "update-database" endpoint HTTP response body. +type UpdateDatabaseResponseBody struct { + // Unique identifier for the database. + ID string `form:"id" json:"id" xml:"id"` + // Unique identifier for the databases's owner. + TenantID *string `form:"tenant_id,omitempty" json:"tenant_id,omitempty" xml:"tenant_id,omitempty"` + // The time that the database was created. + CreatedAt *string `form:"created_at,omitempty" json:"created_at,omitempty" xml:"created_at,omitempty"` + // The time that the database was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` + // Current status of the database. + Status *DatabaseStatusResponseBody `form:"status" json:"status" xml:"status"` + // All of the instances in the database. + Instances *InstanceResponseBody `form:"instances" json:"instances" xml:"instances"` + // The user-provided specification for the database. + Spec *DatabaseSpecResponseBody `form:"spec,omitempty" json:"spec,omitempty" xml:"spec,omitempty"` +} + +// ClusterStatusResponseBody is used to define fields on response body types. +type ClusterStatusResponseBody struct { + // The current state of the cluster. + State string `form:"state" json:"state" xml:"state"` +} + +// HostResponseBody is used to define fields on response body types. +type HostResponseBody struct { + // Unique identifier for the host + ID string `form:"id" json:"id" xml:"id"` + // The type of this host + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The cohort that this host belongs to + Cohort *string `form:"cohort,omitempty" json:"cohort,omitempty" xml:"cohort,omitempty"` + // The hostname of this host. + Hostname string `form:"hostname" json:"hostname" xml:"hostname"` + // The IPv4 address of this host. + Ipv4Address string `form:"ipv4_address" json:"ipv4_address" xml:"ipv4_address"` + // The configuration for this host + Config *HostConfigurationResponseBody `form:"config,omitempty" json:"config,omitempty" xml:"config,omitempty"` + // Current status of the host + Status *HostStatusResponseBody `form:"status" json:"status" xml:"status"` +} + +// HostConfigurationResponseBody is used to define fields on response body +// types. +type HostConfigurationResponseBody struct { + // Enables the Vector service for metrics and log collection + VectorEnabled *bool `form:"vector_enabled,omitempty" json:"vector_enabled,omitempty" xml:"vector_enabled,omitempty"` + // Enables the Treafik load balancer + TraefikEnabled *bool `form:"traefik_enabled,omitempty" json:"traefik_enabled,omitempty" xml:"traefik_enabled,omitempty"` +} + +// HostStatusResponseBody is used to define fields on response body types. +type HostStatusResponseBody struct { + State string `form:"state" json:"state" xml:"state"` +} + +// HostResponse is used to define fields on response body types. +type HostResponse struct { + // Unique identifier for the host + ID string `form:"id" json:"id" xml:"id"` + // The type of this host + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The cohort that this host belongs to + Cohort *string `form:"cohort,omitempty" json:"cohort,omitempty" xml:"cohort,omitempty"` + // The hostname of this host. + Hostname string `form:"hostname" json:"hostname" xml:"hostname"` + // The IPv4 address of this host. + Ipv4Address string `form:"ipv4_address" json:"ipv4_address" xml:"ipv4_address"` + // The configuration for this host + Config *HostConfigurationResponse `form:"config,omitempty" json:"config,omitempty" xml:"config,omitempty"` + // Current status of the host + Status *HostStatusResponse `form:"status" json:"status" xml:"status"` +} + +// HostConfigurationResponse is used to define fields on response body types. +type HostConfigurationResponse struct { + // Enables the Vector service for metrics and log collection + VectorEnabled *bool `form:"vector_enabled,omitempty" json:"vector_enabled,omitempty" xml:"vector_enabled,omitempty"` + // Enables the Treafik load balancer + TraefikEnabled *bool `form:"traefik_enabled,omitempty" json:"traefik_enabled,omitempty" xml:"traefik_enabled,omitempty"` +} + +// HostStatusResponse is used to define fields on response body types. +type HostStatusResponse struct { + State string `form:"state" json:"state" xml:"state"` +} + +// DatabaseResponse is used to define fields on response body types. +type DatabaseResponse struct { + // Unique identifier for the database. + ID string `form:"id" json:"id" xml:"id"` + // Unique identifier for the databases's owner. + TenantID *string `form:"tenant_id,omitempty" json:"tenant_id,omitempty" xml:"tenant_id,omitempty"` + // The time that the database was created. + CreatedAt *string `form:"created_at,omitempty" json:"created_at,omitempty" xml:"created_at,omitempty"` + // The time that the database was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` + // Current status of the database. + Status *DatabaseStatusResponse `form:"status" json:"status" xml:"status"` + // All of the instances in the database. + Instances *InstanceResponse `form:"instances" json:"instances" xml:"instances"` + // The user-provided specification for the database. + Spec *DatabaseSpecResponse `form:"spec,omitempty" json:"spec,omitempty" xml:"spec,omitempty"` +} + +// DatabaseStatusResponse is used to define fields on response body types. +type DatabaseStatusResponse struct { + State *string `form:"state,omitempty" json:"state,omitempty" xml:"state,omitempty"` + // The time that the database status was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` +} + +// InstanceResponse is used to define fields on response body types. +type InstanceResponse struct { + // Unique identifier for the instance. + ID string `form:"id" json:"id" xml:"id"` + // The ID of the host this instance is running on. + HostID *string `form:"host_id,omitempty" json:"host_id,omitempty" xml:"host_id,omitempty"` + // The Spock node name for this instance. + NodeName *string `form:"node_name,omitempty" json:"node_name,omitempty" xml:"node_name,omitempty"` + // The time that the instance was created. + CreatedAt *string `form:"created_at,omitempty" json:"created_at,omitempty" xml:"created_at,omitempty"` + // The time that the instance was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` + // Current status of the instance. + Status *InstanceStatusResponse `form:"status" json:"status" xml:"status"` + // All interfaces that this instance serves on. + Interfaces []*InstanceInterfaceResponse `form:"interfaces,omitempty" json:"interfaces,omitempty" xml:"interfaces,omitempty"` +} + +// InstanceStatusResponse is used to define fields on response body types. +type InstanceStatusResponse struct { + State string `form:"state" json:"state" xml:"state"` + PatroniState *string `form:"patroni_state,omitempty" json:"patroni_state,omitempty" xml:"patroni_state,omitempty"` + Role *string `form:"role,omitempty" json:"role,omitempty" xml:"role,omitempty"` + // True if this instance is in read-only mode. + ReadOnly *bool `form:"read_only,omitempty" json:"read_only,omitempty" xml:"read_only,omitempty"` + // True if this instance is pending to be restarted from a configuration change. + PendingRestart *bool `form:"pending_restart,omitempty" json:"pending_restart,omitempty" xml:"pending_restart,omitempty"` + // True if Patroni has been paused for this instance. + PatroniPaused *bool `form:"patroni_paused,omitempty" json:"patroni_paused,omitempty" xml:"patroni_paused,omitempty"` + // The version of Postgres for this instance. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The version of Spock for this instance. + SpockVersion *string `form:"spock_version,omitempty" json:"spock_version,omitempty" xml:"spock_version,omitempty"` + // The time that the instance status was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` +} + +// InstanceInterfaceResponse is used to define fields on response body types. +type InstanceInterfaceResponse struct { + // The type of network for this interface. + NetworkType *string `form:"network_type,omitempty" json:"network_type,omitempty" xml:"network_type,omitempty"` + // The unique identifier of the network for this interface. + NetworkID *string `form:"network_id,omitempty" json:"network_id,omitempty" xml:"network_id,omitempty"` + // The hostname of the instance on this interface. + Hostname *string `form:"hostname,omitempty" json:"hostname,omitempty" xml:"hostname,omitempty"` + // The IPv4 address of the instance on this interface. + Ipv4Address *string `form:"ipv4_address,omitempty" json:"ipv4_address,omitempty" xml:"ipv4_address,omitempty"` + // The Postgres port for the instance on this interface. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` +} + +// DatabaseSpecResponse is used to define fields on response body types. +type DatabaseSpecResponse struct { + // The name of the Postgres database. + DatabaseName string `form:"database_name" json:"database_name" xml:"database_name"` + // The major version of the Postgres database. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The major version of the Spock extension. + SpockVersion *string `form:"spock_version,omitempty" json:"spock_version,omitempty" xml:"spock_version,omitempty"` + // The port used by the Postgres database. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Prevents deletion when true. + DeletionProtection *bool `form:"deletion_protection,omitempty" json:"deletion_protection,omitempty" xml:"deletion_protection,omitempty"` + // The Spock nodes for this database. + Nodes []*DatabaseNodeSpecResponse `form:"nodes" json:"nodes" xml:"nodes"` + // The users to create for this database. + DatabaseUsers []*DatabaseUserSpecResponse `form:"database_users,omitempty" json:"database_users,omitempty" xml:"database_users,omitempty"` + // The extensions to install for this database. + Extensions []*DatabaseExtensionSpecResponse `form:"extensions,omitempty" json:"extensions,omitempty" xml:"extensions,omitempty"` + // The feature flags for this database. + Features map[string]string `form:"features,omitempty" json:"features,omitempty" xml:"features,omitempty"` + // The backup configurations for this database. + BackupConfigs []*BackupConfigSpecResponse `form:"backup_configs,omitempty" json:"backup_configs,omitempty" xml:"backup_configs,omitempty"` + // Additional postgresql.conf settings. Will be merged with the settings + // provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseNodeSpecResponse is used to define fields on response body types. +type DatabaseNodeSpecResponse struct { + // The name of the database node. + Name string `form:"name" json:"name" xml:"name"` + // A unique identifier for the instance that will be created from this node + // specification. + InstanceID string `form:"instance_id" json:"instance_id" xml:"instance_id"` + // The ID of the host that should run this node. + HostID string `form:"host_id" json:"host_id" xml:"host_id"` + // The major version of Postgres for this node. Overrides the Postgres version + // set in the DatabaseSpec. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The port used by the Postgres database for this node. Overrides the Postgres + // port set in the DatabaseSpec. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Read replicas for this database node. + ReadReplicas *DatabaseReplicaSpecResponse `form:"read_replicas,omitempty" json:"read_replicas,omitempty" xml:"read_replicas,omitempty"` + // Additional postgresql.conf settings for this particular node. Will be merged + // with the settings provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseReplicaSpecResponse is used to define fields on response body types. +type DatabaseReplicaSpecResponse struct { + // A unique identifier for the instance that will be created from this replica + // specification. + InstanceID string `form:"instance_id" json:"instance_id" xml:"instance_id"` + // The ID of the host that should run this read replica. + HostID string `form:"host_id" json:"host_id" xml:"host_id"` +} + +// DatabaseUserSpecResponse is used to define fields on response body types. +type DatabaseUserSpecResponse struct { + // The username for this database user. + Username string `form:"username" json:"username" xml:"username"` + // The password for this database user. + Password string `form:"password" json:"password" xml:"password"` + // The roles to assign to this database user. + Roles []string `form:"roles,omitempty" json:"roles,omitempty" xml:"roles,omitempty"` + // Enables SUPERUSER for this database user when true. + Superuser *bool `form:"superuser,omitempty" json:"superuser,omitempty" xml:"superuser,omitempty"` +} + +// DatabaseExtensionSpecResponse is used to define fields on response body +// types. +type DatabaseExtensionSpecResponse struct { + // The name of the extension to install in this database. + Name string `form:"name" json:"name" xml:"name"` + // The version of the extension to install in this database. + Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` +} + +// BackupConfigSpecResponse is used to define fields on response body types. +type BackupConfigSpecResponse struct { + // The unique identifier for this backup configuration. + ID string `form:"id" json:"id" xml:"id"` + // The names of the nodes where this backup configuration should be applied. + // The configuration will apply to all nodes when this field is empty or + // unspecified. + NodeNames []string `form:"node_names,omitempty" json:"node_names,omitempty" xml:"node_names,omitempty"` + // The backup provider for this backup configuration. + Provider string `form:"provider" json:"provider" xml:"provider"` + // The repositories for this backup configuration. + Repositories []*BackupRepositorySpecResponse `form:"repositories,omitempty" json:"repositories,omitempty" xml:"repositories,omitempty"` + // The schedules for this backup configuration. + Schedules []*BackupScheduleSpecResponse `form:"schedules,omitempty" json:"schedules,omitempty" xml:"schedules,omitempty"` +} + +// BackupRepositorySpecResponse is used to define fields on response body types. +type BackupRepositorySpecResponse struct { + // The unique identifier of this repository. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of this repository. + Type string `form:"type" json:"type" xml:"type"` + // The S3 bucket name for this repository. Only applies when type = 's3'. + S3Bucket *string `form:"s3_bucket,omitempty" json:"s3_bucket,omitempty" xml:"s3_bucket,omitempty"` + // The region of the S3 bucket for this repository. Only applies when type = + // 's3'. + S3Region *string `form:"s3_region,omitempty" json:"s3_region,omitempty" xml:"s3_region,omitempty"` + // The optional S3 endpoint for this repository. Only applies when type = 's3'. + S3Endpoint *string `form:"s3_endpoint,omitempty" json:"s3_endpoint,omitempty" xml:"s3_endpoint,omitempty"` + // The GCS bucket name for this repository. Only applies when type = 'gcs'. + GcsBucket *string `form:"gcs_bucket,omitempty" json:"gcs_bucket,omitempty" xml:"gcs_bucket,omitempty"` + // The optional GCS endpoint for this repository. Only applies when type = + // 'gcs'. + GcsEndpoint *string `form:"gcs_endpoint,omitempty" json:"gcs_endpoint,omitempty" xml:"gcs_endpoint,omitempty"` + // The Azure account name for this repository. Only applies when type = 'azure'. + AzureAccount *string `form:"azure_account,omitempty" json:"azure_account,omitempty" xml:"azure_account,omitempty"` + // The Azure container name for this repository. Only applies when type = + // 'azure'. + AzureContainer *string `form:"azure_container,omitempty" json:"azure_container,omitempty" xml:"azure_container,omitempty"` + // The optional Azure endpoint for this repository. Only applies when type = + // 'azure'. + AzureEndpoint *string `form:"azure_endpoint,omitempty" json:"azure_endpoint,omitempty" xml:"azure_endpoint,omitempty"` + // The count of full backups to retain or the time to retain full backups. + RetentionFull *int `form:"retention_full,omitempty" json:"retention_full,omitempty" xml:"retention_full,omitempty"` + // The type of measure used for retention_full. + RetentionFullType *string `form:"retention_full_type,omitempty" json:"retention_full_type,omitempty" xml:"retention_full_type,omitempty"` + // The base path within the repository to store backups. + BasePath *string `form:"base_path,omitempty" json:"base_path,omitempty" xml:"base_path,omitempty"` +} + +// BackupScheduleSpecResponse is used to define fields on response body types. +type BackupScheduleSpecResponse struct { + // The unique identifier for this backup schedule. + ID string `form:"id" json:"id" xml:"id"` + // The type of backup to take on this schedule. + Type string `form:"type" json:"type" xml:"type"` + // The cron expression for this schedule. + CronExpression string `form:"cron_expression" json:"cron_expression" xml:"cron_expression"` +} + +// DatabaseStatusResponseBody is used to define fields on response body types. +type DatabaseStatusResponseBody struct { + State *string `form:"state,omitempty" json:"state,omitempty" xml:"state,omitempty"` + // The time that the database status was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` +} + +// InstanceResponseBody is used to define fields on response body types. +type InstanceResponseBody struct { + // Unique identifier for the instance. + ID string `form:"id" json:"id" xml:"id"` + // The ID of the host this instance is running on. + HostID *string `form:"host_id,omitempty" json:"host_id,omitempty" xml:"host_id,omitempty"` + // The Spock node name for this instance. + NodeName *string `form:"node_name,omitempty" json:"node_name,omitempty" xml:"node_name,omitempty"` + // The time that the instance was created. + CreatedAt *string `form:"created_at,omitempty" json:"created_at,omitempty" xml:"created_at,omitempty"` + // The time that the instance was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` + // Current status of the instance. + Status *InstanceStatusResponseBody `form:"status" json:"status" xml:"status"` + // All interfaces that this instance serves on. + Interfaces []*InstanceInterfaceResponseBody `form:"interfaces,omitempty" json:"interfaces,omitempty" xml:"interfaces,omitempty"` +} + +// InstanceStatusResponseBody is used to define fields on response body types. +type InstanceStatusResponseBody struct { + State string `form:"state" json:"state" xml:"state"` + PatroniState *string `form:"patroni_state,omitempty" json:"patroni_state,omitempty" xml:"patroni_state,omitempty"` + Role *string `form:"role,omitempty" json:"role,omitempty" xml:"role,omitempty"` + // True if this instance is in read-only mode. + ReadOnly *bool `form:"read_only,omitempty" json:"read_only,omitempty" xml:"read_only,omitempty"` + // True if this instance is pending to be restarted from a configuration change. + PendingRestart *bool `form:"pending_restart,omitempty" json:"pending_restart,omitempty" xml:"pending_restart,omitempty"` + // True if Patroni has been paused for this instance. + PatroniPaused *bool `form:"patroni_paused,omitempty" json:"patroni_paused,omitempty" xml:"patroni_paused,omitempty"` + // The version of Postgres for this instance. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The version of Spock for this instance. + SpockVersion *string `form:"spock_version,omitempty" json:"spock_version,omitempty" xml:"spock_version,omitempty"` + // The time that the instance status was last updated. + UpdatedAt *string `form:"updated_at,omitempty" json:"updated_at,omitempty" xml:"updated_at,omitempty"` +} + +// InstanceInterfaceResponseBody is used to define fields on response body +// types. +type InstanceInterfaceResponseBody struct { + // The type of network for this interface. + NetworkType *string `form:"network_type,omitempty" json:"network_type,omitempty" xml:"network_type,omitempty"` + // The unique identifier of the network for this interface. + NetworkID *string `form:"network_id,omitempty" json:"network_id,omitempty" xml:"network_id,omitempty"` + // The hostname of the instance on this interface. + Hostname *string `form:"hostname,omitempty" json:"hostname,omitempty" xml:"hostname,omitempty"` + // The IPv4 address of the instance on this interface. + Ipv4Address *string `form:"ipv4_address,omitempty" json:"ipv4_address,omitempty" xml:"ipv4_address,omitempty"` + // The Postgres port for the instance on this interface. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` +} + +// DatabaseSpecResponseBody is used to define fields on response body types. +type DatabaseSpecResponseBody struct { + // The name of the Postgres database. + DatabaseName string `form:"database_name" json:"database_name" xml:"database_name"` + // The major version of the Postgres database. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The major version of the Spock extension. + SpockVersion *string `form:"spock_version,omitempty" json:"spock_version,omitempty" xml:"spock_version,omitempty"` + // The port used by the Postgres database. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Prevents deletion when true. + DeletionProtection *bool `form:"deletion_protection,omitempty" json:"deletion_protection,omitempty" xml:"deletion_protection,omitempty"` + // The Spock nodes for this database. + Nodes []*DatabaseNodeSpecResponseBody `form:"nodes" json:"nodes" xml:"nodes"` + // The users to create for this database. + DatabaseUsers []*DatabaseUserSpecResponseBody `form:"database_users,omitempty" json:"database_users,omitempty" xml:"database_users,omitempty"` + // The extensions to install for this database. + Extensions []*DatabaseExtensionSpecResponseBody `form:"extensions,omitempty" json:"extensions,omitempty" xml:"extensions,omitempty"` + // The feature flags for this database. + Features map[string]string `form:"features,omitempty" json:"features,omitempty" xml:"features,omitempty"` + // The backup configurations for this database. + BackupConfigs []*BackupConfigSpecResponseBody `form:"backup_configs,omitempty" json:"backup_configs,omitempty" xml:"backup_configs,omitempty"` + // Additional postgresql.conf settings. Will be merged with the settings + // provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseNodeSpecResponseBody is used to define fields on response body types. +type DatabaseNodeSpecResponseBody struct { + // The name of the database node. + Name string `form:"name" json:"name" xml:"name"` + // A unique identifier for the instance that will be created from this node + // specification. + InstanceID string `form:"instance_id" json:"instance_id" xml:"instance_id"` + // The ID of the host that should run this node. + HostID string `form:"host_id" json:"host_id" xml:"host_id"` + // The major version of Postgres for this node. Overrides the Postgres version + // set in the DatabaseSpec. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The port used by the Postgres database for this node. Overrides the Postgres + // port set in the DatabaseSpec. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Read replicas for this database node. + ReadReplicas *DatabaseReplicaSpecResponseBody `form:"read_replicas,omitempty" json:"read_replicas,omitempty" xml:"read_replicas,omitempty"` + // Additional postgresql.conf settings for this particular node. Will be merged + // with the settings provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseReplicaSpecResponseBody is used to define fields on response body +// types. +type DatabaseReplicaSpecResponseBody struct { + // A unique identifier for the instance that will be created from this replica + // specification. + InstanceID string `form:"instance_id" json:"instance_id" xml:"instance_id"` + // The ID of the host that should run this read replica. + HostID string `form:"host_id" json:"host_id" xml:"host_id"` +} + +// DatabaseUserSpecResponseBody is used to define fields on response body types. +type DatabaseUserSpecResponseBody struct { + // The username for this database user. + Username string `form:"username" json:"username" xml:"username"` + // The password for this database user. + Password string `form:"password" json:"password" xml:"password"` + // The roles to assign to this database user. + Roles []string `form:"roles,omitempty" json:"roles,omitempty" xml:"roles,omitempty"` + // Enables SUPERUSER for this database user when true. + Superuser *bool `form:"superuser,omitempty" json:"superuser,omitempty" xml:"superuser,omitempty"` +} + +// DatabaseExtensionSpecResponseBody is used to define fields on response body +// types. +type DatabaseExtensionSpecResponseBody struct { + // The name of the extension to install in this database. + Name string `form:"name" json:"name" xml:"name"` + // The version of the extension to install in this database. + Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` +} + +// BackupConfigSpecResponseBody is used to define fields on response body types. +type BackupConfigSpecResponseBody struct { + // The unique identifier for this backup configuration. + ID string `form:"id" json:"id" xml:"id"` + // The names of the nodes where this backup configuration should be applied. + // The configuration will apply to all nodes when this field is empty or + // unspecified. + NodeNames []string `form:"node_names,omitempty" json:"node_names,omitempty" xml:"node_names,omitempty"` + // The backup provider for this backup configuration. + Provider string `form:"provider" json:"provider" xml:"provider"` + // The repositories for this backup configuration. + Repositories []*BackupRepositorySpecResponseBody `form:"repositories,omitempty" json:"repositories,omitempty" xml:"repositories,omitempty"` + // The schedules for this backup configuration. + Schedules []*BackupScheduleSpecResponseBody `form:"schedules,omitempty" json:"schedules,omitempty" xml:"schedules,omitempty"` +} + +// BackupRepositorySpecResponseBody is used to define fields on response body +// types. +type BackupRepositorySpecResponseBody struct { + // The unique identifier of this repository. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of this repository. + Type string `form:"type" json:"type" xml:"type"` + // The S3 bucket name for this repository. Only applies when type = 's3'. + S3Bucket *string `form:"s3_bucket,omitempty" json:"s3_bucket,omitempty" xml:"s3_bucket,omitempty"` + // The region of the S3 bucket for this repository. Only applies when type = + // 's3'. + S3Region *string `form:"s3_region,omitempty" json:"s3_region,omitempty" xml:"s3_region,omitempty"` + // The optional S3 endpoint for this repository. Only applies when type = 's3'. + S3Endpoint *string `form:"s3_endpoint,omitempty" json:"s3_endpoint,omitempty" xml:"s3_endpoint,omitempty"` + // The GCS bucket name for this repository. Only applies when type = 'gcs'. + GcsBucket *string `form:"gcs_bucket,omitempty" json:"gcs_bucket,omitempty" xml:"gcs_bucket,omitempty"` + // The optional GCS endpoint for this repository. Only applies when type = + // 'gcs'. + GcsEndpoint *string `form:"gcs_endpoint,omitempty" json:"gcs_endpoint,omitempty" xml:"gcs_endpoint,omitempty"` + // The Azure account name for this repository. Only applies when type = 'azure'. + AzureAccount *string `form:"azure_account,omitempty" json:"azure_account,omitempty" xml:"azure_account,omitempty"` + // The Azure container name for this repository. Only applies when type = + // 'azure'. + AzureContainer *string `form:"azure_container,omitempty" json:"azure_container,omitempty" xml:"azure_container,omitempty"` + // The optional Azure endpoint for this repository. Only applies when type = + // 'azure'. + AzureEndpoint *string `form:"azure_endpoint,omitempty" json:"azure_endpoint,omitempty" xml:"azure_endpoint,omitempty"` + // The count of full backups to retain or the time to retain full backups. + RetentionFull *int `form:"retention_full,omitempty" json:"retention_full,omitempty" xml:"retention_full,omitempty"` + // The type of measure used for retention_full. + RetentionFullType *string `form:"retention_full_type,omitempty" json:"retention_full_type,omitempty" xml:"retention_full_type,omitempty"` + // The base path within the repository to store backups. + BasePath *string `form:"base_path,omitempty" json:"base_path,omitempty" xml:"base_path,omitempty"` +} + +// BackupScheduleSpecResponseBody is used to define fields on response body +// types. +type BackupScheduleSpecResponseBody struct { + // The unique identifier for this backup schedule. + ID string `form:"id" json:"id" xml:"id"` + // The type of backup to take on this schedule. + Type string `form:"type" json:"type" xml:"type"` + // The cron expression for this schedule. + CronExpression string `form:"cron_expression" json:"cron_expression" xml:"cron_expression"` +} + +// DatabaseSpecRequestBody is used to define fields on request body types. +type DatabaseSpecRequestBody struct { + // The name of the Postgres database. + DatabaseName *string `form:"database_name,omitempty" json:"database_name,omitempty" xml:"database_name,omitempty"` + // The major version of the Postgres database. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The major version of the Spock extension. + SpockVersion *string `form:"spock_version,omitempty" json:"spock_version,omitempty" xml:"spock_version,omitempty"` + // The port used by the Postgres database. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Prevents deletion when true. + DeletionProtection *bool `form:"deletion_protection,omitempty" json:"deletion_protection,omitempty" xml:"deletion_protection,omitempty"` + // The Spock nodes for this database. + Nodes []*DatabaseNodeSpecRequestBody `form:"nodes,omitempty" json:"nodes,omitempty" xml:"nodes,omitempty"` + // The users to create for this database. + DatabaseUsers []*DatabaseUserSpecRequestBody `form:"database_users,omitempty" json:"database_users,omitempty" xml:"database_users,omitempty"` + // The extensions to install for this database. + Extensions []*DatabaseExtensionSpecRequestBody `form:"extensions,omitempty" json:"extensions,omitempty" xml:"extensions,omitempty"` + // The feature flags for this database. + Features map[string]string `form:"features,omitempty" json:"features,omitempty" xml:"features,omitempty"` + // The backup configurations for this database. + BackupConfigs []*BackupConfigSpecRequestBody `form:"backup_configs,omitempty" json:"backup_configs,omitempty" xml:"backup_configs,omitempty"` + // Additional postgresql.conf settings. Will be merged with the settings + // provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseNodeSpecRequestBody is used to define fields on request body types. +type DatabaseNodeSpecRequestBody struct { + // The name of the database node. + Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + // A unique identifier for the instance that will be created from this node + // specification. + InstanceID *string `form:"instance_id,omitempty" json:"instance_id,omitempty" xml:"instance_id,omitempty"` + // The ID of the host that should run this node. + HostID *string `form:"host_id,omitempty" json:"host_id,omitempty" xml:"host_id,omitempty"` + // The major version of Postgres for this node. Overrides the Postgres version + // set in the DatabaseSpec. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The port used by the Postgres database for this node. Overrides the Postgres + // port set in the DatabaseSpec. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Read replicas for this database node. + ReadReplicas *DatabaseReplicaSpecRequestBody `form:"read_replicas,omitempty" json:"read_replicas,omitempty" xml:"read_replicas,omitempty"` + // Additional postgresql.conf settings for this particular node. Will be merged + // with the settings provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseReplicaSpecRequestBody is used to define fields on request body +// types. +type DatabaseReplicaSpecRequestBody struct { + // A unique identifier for the instance that will be created from this replica + // specification. + InstanceID *string `form:"instance_id,omitempty" json:"instance_id,omitempty" xml:"instance_id,omitempty"` + // The ID of the host that should run this read replica. + HostID *string `form:"host_id,omitempty" json:"host_id,omitempty" xml:"host_id,omitempty"` +} + +// DatabaseUserSpecRequestBody is used to define fields on request body types. +type DatabaseUserSpecRequestBody struct { + // The username for this database user. + Username *string `form:"username,omitempty" json:"username,omitempty" xml:"username,omitempty"` + // The password for this database user. + Password *string `form:"password,omitempty" json:"password,omitempty" xml:"password,omitempty"` + // The roles to assign to this database user. + Roles []string `form:"roles,omitempty" json:"roles,omitempty" xml:"roles,omitempty"` + // Enables SUPERUSER for this database user when true. + Superuser *bool `form:"superuser,omitempty" json:"superuser,omitempty" xml:"superuser,omitempty"` +} + +// DatabaseExtensionSpecRequestBody is used to define fields on request body +// types. +type DatabaseExtensionSpecRequestBody struct { + // The name of the extension to install in this database. + Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + // The version of the extension to install in this database. + Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` +} + +// BackupConfigSpecRequestBody is used to define fields on request body types. +type BackupConfigSpecRequestBody struct { + // The unique identifier for this backup configuration. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The names of the nodes where this backup configuration should be applied. + // The configuration will apply to all nodes when this field is empty or + // unspecified. + NodeNames []string `form:"node_names,omitempty" json:"node_names,omitempty" xml:"node_names,omitempty"` + // The backup provider for this backup configuration. + Provider *string `form:"provider,omitempty" json:"provider,omitempty" xml:"provider,omitempty"` + // The repositories for this backup configuration. + Repositories []*BackupRepositorySpecRequestBody `form:"repositories,omitempty" json:"repositories,omitempty" xml:"repositories,omitempty"` + // The schedules for this backup configuration. + Schedules []*BackupScheduleSpecRequestBody `form:"schedules,omitempty" json:"schedules,omitempty" xml:"schedules,omitempty"` +} + +// BackupRepositorySpecRequestBody is used to define fields on request body +// types. +type BackupRepositorySpecRequestBody struct { + // The unique identifier of this repository. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of this repository. + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The S3 bucket name for this repository. Only applies when type = 's3'. + S3Bucket *string `form:"s3_bucket,omitempty" json:"s3_bucket,omitempty" xml:"s3_bucket,omitempty"` + // The region of the S3 bucket for this repository. Only applies when type = + // 's3'. + S3Region *string `form:"s3_region,omitempty" json:"s3_region,omitempty" xml:"s3_region,omitempty"` + // The optional S3 endpoint for this repository. Only applies when type = 's3'. + S3Endpoint *string `form:"s3_endpoint,omitempty" json:"s3_endpoint,omitempty" xml:"s3_endpoint,omitempty"` + // The GCS bucket name for this repository. Only applies when type = 'gcs'. + GcsBucket *string `form:"gcs_bucket,omitempty" json:"gcs_bucket,omitempty" xml:"gcs_bucket,omitempty"` + // The optional GCS endpoint for this repository. Only applies when type = + // 'gcs'. + GcsEndpoint *string `form:"gcs_endpoint,omitempty" json:"gcs_endpoint,omitempty" xml:"gcs_endpoint,omitempty"` + // The Azure account name for this repository. Only applies when type = 'azure'. + AzureAccount *string `form:"azure_account,omitempty" json:"azure_account,omitempty" xml:"azure_account,omitempty"` + // The Azure container name for this repository. Only applies when type = + // 'azure'. + AzureContainer *string `form:"azure_container,omitempty" json:"azure_container,omitempty" xml:"azure_container,omitempty"` + // The optional Azure endpoint for this repository. Only applies when type = + // 'azure'. + AzureEndpoint *string `form:"azure_endpoint,omitempty" json:"azure_endpoint,omitempty" xml:"azure_endpoint,omitempty"` + // The count of full backups to retain or the time to retain full backups. + RetentionFull *int `form:"retention_full,omitempty" json:"retention_full,omitempty" xml:"retention_full,omitempty"` + // The type of measure used for retention_full. + RetentionFullType *string `form:"retention_full_type,omitempty" json:"retention_full_type,omitempty" xml:"retention_full_type,omitempty"` + // The base path within the repository to store backups. + BasePath *string `form:"base_path,omitempty" json:"base_path,omitempty" xml:"base_path,omitempty"` +} + +// BackupScheduleSpecRequestBody is used to define fields on request body types. +type BackupScheduleSpecRequestBody struct { + // The unique identifier for this backup schedule. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of backup to take on this schedule. + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The cron expression for this schedule. + CronExpression *string `form:"cron_expression,omitempty" json:"cron_expression,omitempty" xml:"cron_expression,omitempty"` +} + +// DatabaseSpecRequestBodyRequestBody is used to define fields on request body +// types. +type DatabaseSpecRequestBodyRequestBody struct { + // The name of the Postgres database. + DatabaseName *string `form:"database_name,omitempty" json:"database_name,omitempty" xml:"database_name,omitempty"` + // The major version of the Postgres database. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The major version of the Spock extension. + SpockVersion *string `form:"spock_version,omitempty" json:"spock_version,omitempty" xml:"spock_version,omitempty"` + // The port used by the Postgres database. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Prevents deletion when true. + DeletionProtection *bool `form:"deletion_protection,omitempty" json:"deletion_protection,omitempty" xml:"deletion_protection,omitempty"` + // The Spock nodes for this database. + Nodes []*DatabaseNodeSpecRequestBodyRequestBody `form:"nodes,omitempty" json:"nodes,omitempty" xml:"nodes,omitempty"` + // The users to create for this database. + DatabaseUsers []*DatabaseUserSpecRequestBodyRequestBody `form:"database_users,omitempty" json:"database_users,omitempty" xml:"database_users,omitempty"` + // The extensions to install for this database. + Extensions []*DatabaseExtensionSpecRequestBodyRequestBody `form:"extensions,omitempty" json:"extensions,omitempty" xml:"extensions,omitempty"` + // The feature flags for this database. + Features map[string]string `form:"features,omitempty" json:"features,omitempty" xml:"features,omitempty"` + // The backup configurations for this database. + BackupConfigs []*BackupConfigSpecRequestBodyRequestBody `form:"backup_configs,omitempty" json:"backup_configs,omitempty" xml:"backup_configs,omitempty"` + // Additional postgresql.conf settings. Will be merged with the settings + // provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseNodeSpecRequestBodyRequestBody is used to define fields on request +// body types. +type DatabaseNodeSpecRequestBodyRequestBody struct { + // The name of the database node. + Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + // A unique identifier for the instance that will be created from this node + // specification. + InstanceID *string `form:"instance_id,omitempty" json:"instance_id,omitempty" xml:"instance_id,omitempty"` + // The ID of the host that should run this node. + HostID *string `form:"host_id,omitempty" json:"host_id,omitempty" xml:"host_id,omitempty"` + // The major version of Postgres for this node. Overrides the Postgres version + // set in the DatabaseSpec. + PostgresVersion *string `form:"postgres_version,omitempty" json:"postgres_version,omitempty" xml:"postgres_version,omitempty"` + // The port used by the Postgres database for this node. Overrides the Postgres + // port set in the DatabaseSpec. + Port *int `form:"port,omitempty" json:"port,omitempty" xml:"port,omitempty"` + // Read replicas for this database node. + ReadReplicas *DatabaseReplicaSpecRequestBodyRequestBody `form:"read_replicas,omitempty" json:"read_replicas,omitempty" xml:"read_replicas,omitempty"` + // Additional postgresql.conf settings for this particular node. Will be merged + // with the settings provided by control-plane. + PostgresqlConf map[string]any `form:"postgresql_conf,omitempty" json:"postgresql_conf,omitempty" xml:"postgresql_conf,omitempty"` +} + +// DatabaseReplicaSpecRequestBodyRequestBody is used to define fields on +// request body types. +type DatabaseReplicaSpecRequestBodyRequestBody struct { + // A unique identifier for the instance that will be created from this replica + // specification. + InstanceID *string `form:"instance_id,omitempty" json:"instance_id,omitempty" xml:"instance_id,omitempty"` + // The ID of the host that should run this read replica. + HostID *string `form:"host_id,omitempty" json:"host_id,omitempty" xml:"host_id,omitempty"` +} + +// DatabaseUserSpecRequestBodyRequestBody is used to define fields on request +// body types. +type DatabaseUserSpecRequestBodyRequestBody struct { + // The username for this database user. + Username *string `form:"username,omitempty" json:"username,omitempty" xml:"username,omitempty"` + // The password for this database user. + Password *string `form:"password,omitempty" json:"password,omitempty" xml:"password,omitempty"` + // The roles to assign to this database user. + Roles []string `form:"roles,omitempty" json:"roles,omitempty" xml:"roles,omitempty"` + // Enables SUPERUSER for this database user when true. + Superuser *bool `form:"superuser,omitempty" json:"superuser,omitempty" xml:"superuser,omitempty"` +} + +// DatabaseExtensionSpecRequestBodyRequestBody is used to define fields on +// request body types. +type DatabaseExtensionSpecRequestBodyRequestBody struct { + // The name of the extension to install in this database. + Name *string `form:"name,omitempty" json:"name,omitempty" xml:"name,omitempty"` + // The version of the extension to install in this database. + Version *string `form:"version,omitempty" json:"version,omitempty" xml:"version,omitempty"` +} + +// BackupConfigSpecRequestBodyRequestBody is used to define fields on request +// body types. +type BackupConfigSpecRequestBodyRequestBody struct { + // The unique identifier for this backup configuration. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The names of the nodes where this backup configuration should be applied. + // The configuration will apply to all nodes when this field is empty or + // unspecified. + NodeNames []string `form:"node_names,omitempty" json:"node_names,omitempty" xml:"node_names,omitempty"` + // The backup provider for this backup configuration. + Provider *string `form:"provider,omitempty" json:"provider,omitempty" xml:"provider,omitempty"` + // The repositories for this backup configuration. + Repositories []*BackupRepositorySpecRequestBodyRequestBody `form:"repositories,omitempty" json:"repositories,omitempty" xml:"repositories,omitempty"` + // The schedules for this backup configuration. + Schedules []*BackupScheduleSpecRequestBodyRequestBody `form:"schedules,omitempty" json:"schedules,omitempty" xml:"schedules,omitempty"` +} + +// BackupRepositorySpecRequestBodyRequestBody is used to define fields on +// request body types. +type BackupRepositorySpecRequestBodyRequestBody struct { + // The unique identifier of this repository. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of this repository. + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The S3 bucket name for this repository. Only applies when type = 's3'. + S3Bucket *string `form:"s3_bucket,omitempty" json:"s3_bucket,omitempty" xml:"s3_bucket,omitempty"` + // The region of the S3 bucket for this repository. Only applies when type = + // 's3'. + S3Region *string `form:"s3_region,omitempty" json:"s3_region,omitempty" xml:"s3_region,omitempty"` + // The optional S3 endpoint for this repository. Only applies when type = 's3'. + S3Endpoint *string `form:"s3_endpoint,omitempty" json:"s3_endpoint,omitempty" xml:"s3_endpoint,omitempty"` + // The GCS bucket name for this repository. Only applies when type = 'gcs'. + GcsBucket *string `form:"gcs_bucket,omitempty" json:"gcs_bucket,omitempty" xml:"gcs_bucket,omitempty"` + // The optional GCS endpoint for this repository. Only applies when type = + // 'gcs'. + GcsEndpoint *string `form:"gcs_endpoint,omitempty" json:"gcs_endpoint,omitempty" xml:"gcs_endpoint,omitempty"` + // The Azure account name for this repository. Only applies when type = 'azure'. + AzureAccount *string `form:"azure_account,omitempty" json:"azure_account,omitempty" xml:"azure_account,omitempty"` + // The Azure container name for this repository. Only applies when type = + // 'azure'. + AzureContainer *string `form:"azure_container,omitempty" json:"azure_container,omitempty" xml:"azure_container,omitempty"` + // The optional Azure endpoint for this repository. Only applies when type = + // 'azure'. + AzureEndpoint *string `form:"azure_endpoint,omitempty" json:"azure_endpoint,omitempty" xml:"azure_endpoint,omitempty"` + // The count of full backups to retain or the time to retain full backups. + RetentionFull *int `form:"retention_full,omitempty" json:"retention_full,omitempty" xml:"retention_full,omitempty"` + // The type of measure used for retention_full. + RetentionFullType *string `form:"retention_full_type,omitempty" json:"retention_full_type,omitempty" xml:"retention_full_type,omitempty"` + // The base path within the repository to store backups. + BasePath *string `form:"base_path,omitempty" json:"base_path,omitempty" xml:"base_path,omitempty"` +} + +// BackupScheduleSpecRequestBodyRequestBody is used to define fields on request +// body types. +type BackupScheduleSpecRequestBodyRequestBody struct { + // The unique identifier for this backup schedule. + ID *string `form:"id,omitempty" json:"id,omitempty" xml:"id,omitempty"` + // The type of backup to take on this schedule. + Type *string `form:"type,omitempty" json:"type,omitempty" xml:"type,omitempty"` + // The cron expression for this schedule. + CronExpression *string `form:"cron_expression,omitempty" json:"cron_expression,omitempty" xml:"cron_expression,omitempty"` +} + +// NewInspectClusterResponseBody builds the HTTP response body from the result +// of the "inspect-cluster" endpoint of the "control-plane" service. +func NewInspectClusterResponseBody(res *controlplane.Cluster) *InspectClusterResponseBody { + body := &InspectClusterResponseBody{ + ID: res.ID, + TenantID: res.TenantID, + } + if res.Status != nil { + body.Status = marshalControlplaneClusterStatusToClusterStatusResponseBody(res.Status) + } + if res.Hosts != nil { + body.Hosts = make([]*HostResponseBody, len(res.Hosts)) + for i, val := range res.Hosts { + body.Hosts[i] = marshalControlplaneHostToHostResponseBody(val) + } + } else { + body.Hosts = []*HostResponseBody{} + } + return body +} + +// NewListHostsResponseBody builds the HTTP response body from the result of +// the "list-hosts" endpoint of the "control-plane" service. +func NewListHostsResponseBody(res []*controlplane.Host) ListHostsResponseBody { + body := make([]*HostResponse, len(res)) + for i, val := range res { + body[i] = marshalControlplaneHostToHostResponse(val) + } + return body +} + +// NewInspectHostResponseBody builds the HTTP response body from the result of +// the "inspect-host" endpoint of the "control-plane" service. +func NewInspectHostResponseBody(res *controlplane.Host) *InspectHostResponseBody { + body := &InspectHostResponseBody{ + ID: res.ID, + Type: res.Type, + Cohort: res.Cohort, + Hostname: res.Hostname, + Ipv4Address: res.Ipv4Address, + } + if res.Config != nil { + body.Config = marshalControlplaneHostConfigurationToHostConfigurationResponseBody(res.Config) + } + if res.Status != nil { + body.Status = marshalControlplaneHostStatusToHostStatusResponseBody(res.Status) + } + return body +} + +// NewListDatabasesResponseBody builds the HTTP response body from the result +// of the "list-databases" endpoint of the "control-plane" service. +func NewListDatabasesResponseBody(res []*controlplane.Database) ListDatabasesResponseBody { + body := make([]*DatabaseResponse, len(res)) + for i, val := range res { + body[i] = marshalControlplaneDatabaseToDatabaseResponse(val) + } + return body +} + +// NewCreateDatabaseResponseBody builds the HTTP response body from the result +// of the "create-database" endpoint of the "control-plane" service. +func NewCreateDatabaseResponseBody(res *controlplane.Database) *CreateDatabaseResponseBody { + body := &CreateDatabaseResponseBody{ + ID: res.ID, + TenantID: res.TenantID, + CreatedAt: res.CreatedAt, + UpdatedAt: res.UpdatedAt, + } + if res.Status != nil { + body.Status = marshalControlplaneDatabaseStatusToDatabaseStatusResponseBody(res.Status) + } + if res.Instances != nil { + body.Instances = marshalControlplaneInstanceToInstanceResponseBody(res.Instances) + } + if res.Spec != nil { + body.Spec = marshalControlplaneDatabaseSpecToDatabaseSpecResponseBody(res.Spec) + } + return body +} + +// NewInspectDatabaseResponseBody builds the HTTP response body from the result +// of the "inspect-database" endpoint of the "control-plane" service. +func NewInspectDatabaseResponseBody(res *controlplane.Database) *InspectDatabaseResponseBody { + body := &InspectDatabaseResponseBody{ + ID: res.ID, + TenantID: res.TenantID, + CreatedAt: res.CreatedAt, + UpdatedAt: res.UpdatedAt, + } + if res.Status != nil { + body.Status = marshalControlplaneDatabaseStatusToDatabaseStatusResponseBody(res.Status) + } + if res.Instances != nil { + body.Instances = marshalControlplaneInstanceToInstanceResponseBody(res.Instances) + } + if res.Spec != nil { + body.Spec = marshalControlplaneDatabaseSpecToDatabaseSpecResponseBody(res.Spec) + } + return body +} + +// NewUpdateDatabaseResponseBody builds the HTTP response body from the result +// of the "update-database" endpoint of the "control-plane" service. +func NewUpdateDatabaseResponseBody(res *controlplane.Database) *UpdateDatabaseResponseBody { + body := &UpdateDatabaseResponseBody{ + ID: res.ID, + TenantID: res.TenantID, + CreatedAt: res.CreatedAt, + UpdatedAt: res.UpdatedAt, + } + if res.Status != nil { + body.Status = marshalControlplaneDatabaseStatusToDatabaseStatusResponseBody(res.Status) + } + if res.Instances != nil { + body.Instances = marshalControlplaneInstanceToInstanceResponseBody(res.Instances) + } + if res.Spec != nil { + body.Spec = marshalControlplaneDatabaseSpecToDatabaseSpecResponseBody(res.Spec) + } + return body +} + +// NewInspectHostPayload builds a control-plane service inspect-host endpoint +// payload. +func NewInspectHostPayload(hostID string) *controlplane.InspectHostPayload { + v := &controlplane.InspectHostPayload{} + v.HostID = &hostID + + return v +} + +// NewRemoveHostPayload builds a control-plane service remove-host endpoint +// payload. +func NewRemoveHostPayload(hostID string) *controlplane.RemoveHostPayload { + v := &controlplane.RemoveHostPayload{} + v.HostID = &hostID + + return v +} + +// NewCreateDatabaseRequest builds a control-plane service create-database +// endpoint payload. +func NewCreateDatabaseRequest(body *CreateDatabaseRequestBody) *controlplane.CreateDatabaseRequest { + v := &controlplane.CreateDatabaseRequest{ + ID: body.ID, + TenantID: body.TenantID, + } + if body.Spec != nil { + v.Spec = unmarshalDatabaseSpecRequestBodyToControlplaneDatabaseSpec(body.Spec) + } + + return v +} + +// NewInspectDatabasePayload builds a control-plane service inspect-database +// endpoint payload. +func NewInspectDatabasePayload(databaseID string) *controlplane.InspectDatabasePayload { + v := &controlplane.InspectDatabasePayload{} + v.DatabaseID = &databaseID + + return v +} + +// NewUpdateDatabasePayload builds a control-plane service update-database +// endpoint payload. +func NewUpdateDatabasePayload(body *UpdateDatabaseRequestBody, databaseID string) *controlplane.UpdateDatabasePayload { + v := &controlplane.UpdateDatabaseRequest{} + if body.Spec != nil { + v.Spec = unmarshalDatabaseSpecRequestBodyRequestBodyToControlplaneDatabaseSpec(body.Spec) + } + res := &controlplane.UpdateDatabasePayload{ + Request: v, + } + res.DatabaseID = &databaseID + + return res +} + +// NewDeleteDatabasePayload builds a control-plane service delete-database +// endpoint payload. +func NewDeleteDatabasePayload(databaseID string) *controlplane.DeleteDatabasePayload { + v := &controlplane.DeleteDatabasePayload{} + v.DatabaseID = &databaseID + + return v +} + +// ValidateCreateDatabaseRequestBody runs the validations defined on +// Create-DatabaseRequestBody +func ValidateCreateDatabaseRequestBody(body *CreateDatabaseRequestBody) (err error) { + if body.Spec != nil { + if err2 := ValidateDatabaseSpecRequestBody(body.Spec); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateUpdateDatabaseRequestBody runs the validations defined on +// Update-DatabaseRequestBody +func ValidateUpdateDatabaseRequestBody(body *UpdateDatabaseRequestBody) (err error) { + if body.Spec != nil { + if err2 := ValidateDatabaseSpecRequestBodyRequestBody(body.Spec); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateDatabaseSpecRequestBody runs the validations defined on +// DatabaseSpecRequestBody +func ValidateDatabaseSpecRequestBody(body *DatabaseSpecRequestBody) (err error) { + if body.DatabaseName == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("database_name", "body")) + } + if body.Nodes == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("nodes", "body")) + } + if body.PostgresVersion != nil { + if !(*body.PostgresVersion == "16" || *body.PostgresVersion == "17") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.postgres_version", *body.PostgresVersion, []any{"16", "17"})) + } + } + if body.SpockVersion != nil { + if !(*body.SpockVersion == "4") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.spock_version", *body.SpockVersion, []any{"4"})) + } + } + for _, e := range body.Nodes { + if e != nil { + if err2 := ValidateDatabaseNodeSpecRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.DatabaseUsers { + if e != nil { + if err2 := ValidateDatabaseUserSpecRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.Extensions { + if e != nil { + if err2 := ValidateDatabaseExtensionSpecRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.BackupConfigs { + if e != nil { + if err2 := ValidateBackupConfigSpecRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateDatabaseNodeSpecRequestBody runs the validations defined on +// DatabaseNodeSpecRequestBody +func ValidateDatabaseNodeSpecRequestBody(body *DatabaseNodeSpecRequestBody) (err error) { + if body.Name == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("name", "body")) + } + if body.InstanceID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("instance_id", "body")) + } + if body.HostID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("host_id", "body")) + } + if body.PostgresVersion != nil { + if !(*body.PostgresVersion == "16" || *body.PostgresVersion == "17") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.postgres_version", *body.PostgresVersion, []any{"16", "17"})) + } + } + if body.ReadReplicas != nil { + if err2 := ValidateDatabaseReplicaSpecRequestBody(body.ReadReplicas); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateDatabaseReplicaSpecRequestBody runs the validations defined on +// DatabaseReplicaSpecRequestBody +func ValidateDatabaseReplicaSpecRequestBody(body *DatabaseReplicaSpecRequestBody) (err error) { + if body.InstanceID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("instance_id", "body")) + } + if body.HostID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("host_id", "body")) + } + return +} + +// ValidateDatabaseUserSpecRequestBody runs the validations defined on +// DatabaseUserSpecRequestBody +func ValidateDatabaseUserSpecRequestBody(body *DatabaseUserSpecRequestBody) (err error) { + if body.Username == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("username", "body")) + } + if body.Password == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("password", "body")) + } + return +} + +// ValidateDatabaseExtensionSpecRequestBody runs the validations defined on +// DatabaseExtensionSpecRequestBody +func ValidateDatabaseExtensionSpecRequestBody(body *DatabaseExtensionSpecRequestBody) (err error) { + if body.Name == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("name", "body")) + } + return +} + +// ValidateBackupConfigSpecRequestBody runs the validations defined on +// BackupConfigSpecRequestBody +func ValidateBackupConfigSpecRequestBody(body *BackupConfigSpecRequestBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Provider == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("provider", "body")) + } + if body.Provider != nil { + if !(*body.Provider == "pgbackrest" || *body.Provider == "pg_dump") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.provider", *body.Provider, []any{"pgbackrest", "pg_dump"})) + } + } + for _, e := range body.Repositories { + if e != nil { + if err2 := ValidateBackupRepositorySpecRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.Schedules { + if e != nil { + if err2 := ValidateBackupScheduleSpecRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateBackupRepositorySpecRequestBody runs the validations defined on +// BackupRepositorySpecRequestBody +func ValidateBackupRepositorySpecRequestBody(body *BackupRepositorySpecRequestBody) (err error) { + if body.Type == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("type", "body")) + } + if body.Type != nil { + if !(*body.Type == "s3" || *body.Type == "gcs" || *body.Type == "azure") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", *body.Type, []any{"s3", "gcs", "azure"})) + } + } + if body.RetentionFullType != nil { + if !(*body.RetentionFullType == "time" || *body.RetentionFullType == "count") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.retention_full_type", *body.RetentionFullType, []any{"time", "count"})) + } + } + return +} + +// ValidateBackupScheduleSpecRequestBody runs the validations defined on +// BackupScheduleSpecRequestBody +func ValidateBackupScheduleSpecRequestBody(body *BackupScheduleSpecRequestBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Type == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("type", "body")) + } + if body.CronExpression == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("cron_expression", "body")) + } + if body.Type != nil { + if !(*body.Type == "full" || *body.Type == "incr") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", *body.Type, []any{"full", "incr"})) + } + } + return +} + +// ValidateDatabaseSpecRequestBodyRequestBody runs the validations defined on +// DatabaseSpecRequestBodyRequestBody +func ValidateDatabaseSpecRequestBodyRequestBody(body *DatabaseSpecRequestBodyRequestBody) (err error) { + if body.DatabaseName == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("database_name", "body")) + } + if body.Nodes == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("nodes", "body")) + } + if body.PostgresVersion != nil { + if !(*body.PostgresVersion == "16" || *body.PostgresVersion == "17") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.postgres_version", *body.PostgresVersion, []any{"16", "17"})) + } + } + if body.SpockVersion != nil { + if !(*body.SpockVersion == "4") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.spock_version", *body.SpockVersion, []any{"4"})) + } + } + for _, e := range body.Nodes { + if e != nil { + if err2 := ValidateDatabaseNodeSpecRequestBodyRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.DatabaseUsers { + if e != nil { + if err2 := ValidateDatabaseUserSpecRequestBodyRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.Extensions { + if e != nil { + if err2 := ValidateDatabaseExtensionSpecRequestBodyRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.BackupConfigs { + if e != nil { + if err2 := ValidateBackupConfigSpecRequestBodyRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateDatabaseNodeSpecRequestBodyRequestBody runs the validations defined +// on DatabaseNodeSpecRequestBodyRequestBody +func ValidateDatabaseNodeSpecRequestBodyRequestBody(body *DatabaseNodeSpecRequestBodyRequestBody) (err error) { + if body.Name == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("name", "body")) + } + if body.InstanceID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("instance_id", "body")) + } + if body.HostID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("host_id", "body")) + } + if body.PostgresVersion != nil { + if !(*body.PostgresVersion == "16" || *body.PostgresVersion == "17") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.postgres_version", *body.PostgresVersion, []any{"16", "17"})) + } + } + if body.ReadReplicas != nil { + if err2 := ValidateDatabaseReplicaSpecRequestBodyRequestBody(body.ReadReplicas); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + return +} + +// ValidateDatabaseReplicaSpecRequestBodyRequestBody runs the validations +// defined on DatabaseReplicaSpecRequestBodyRequestBody +func ValidateDatabaseReplicaSpecRequestBodyRequestBody(body *DatabaseReplicaSpecRequestBodyRequestBody) (err error) { + if body.InstanceID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("instance_id", "body")) + } + if body.HostID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("host_id", "body")) + } + return +} + +// ValidateDatabaseUserSpecRequestBodyRequestBody runs the validations defined +// on DatabaseUserSpecRequestBodyRequestBody +func ValidateDatabaseUserSpecRequestBodyRequestBody(body *DatabaseUserSpecRequestBodyRequestBody) (err error) { + if body.Username == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("username", "body")) + } + if body.Password == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("password", "body")) + } + return +} + +// ValidateDatabaseExtensionSpecRequestBodyRequestBody runs the validations +// defined on DatabaseExtensionSpecRequestBodyRequestBody +func ValidateDatabaseExtensionSpecRequestBodyRequestBody(body *DatabaseExtensionSpecRequestBodyRequestBody) (err error) { + if body.Name == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("name", "body")) + } + return +} + +// ValidateBackupConfigSpecRequestBodyRequestBody runs the validations defined +// on BackupConfigSpecRequestBodyRequestBody +func ValidateBackupConfigSpecRequestBodyRequestBody(body *BackupConfigSpecRequestBodyRequestBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Provider == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("provider", "body")) + } + if body.Provider != nil { + if !(*body.Provider == "pgbackrest" || *body.Provider == "pg_dump") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.provider", *body.Provider, []any{"pgbackrest", "pg_dump"})) + } + } + for _, e := range body.Repositories { + if e != nil { + if err2 := ValidateBackupRepositorySpecRequestBodyRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + for _, e := range body.Schedules { + if e != nil { + if err2 := ValidateBackupScheduleSpecRequestBodyRequestBody(e); err2 != nil { + err = goa.MergeErrors(err, err2) + } + } + } + return +} + +// ValidateBackupRepositorySpecRequestBodyRequestBody runs the validations +// defined on BackupRepositorySpecRequestBodyRequestBody +func ValidateBackupRepositorySpecRequestBodyRequestBody(body *BackupRepositorySpecRequestBodyRequestBody) (err error) { + if body.Type == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("type", "body")) + } + if body.Type != nil { + if !(*body.Type == "s3" || *body.Type == "gcs" || *body.Type == "azure") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", *body.Type, []any{"s3", "gcs", "azure"})) + } + } + if body.RetentionFullType != nil { + if !(*body.RetentionFullType == "time" || *body.RetentionFullType == "count") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.retention_full_type", *body.RetentionFullType, []any{"time", "count"})) + } + } + return +} + +// ValidateBackupScheduleSpecRequestBodyRequestBody runs the validations +// defined on BackupScheduleSpecRequestBodyRequestBody +func ValidateBackupScheduleSpecRequestBodyRequestBody(body *BackupScheduleSpecRequestBodyRequestBody) (err error) { + if body.ID == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("id", "body")) + } + if body.Type == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("type", "body")) + } + if body.CronExpression == nil { + err = goa.MergeErrors(err, goa.MissingFieldError("cron_expression", "body")) + } + if body.Type != nil { + if !(*body.Type == "full" || *body.Type == "incr") { + err = goa.MergeErrors(err, goa.InvalidEnumValueError("body.type", *body.Type, []any{"full", "incr"})) + } + } + return +} diff --git a/api/gen/http/openapi.json b/api/gen/http/openapi.json new file mode 100644 index 00000000..31fd449a --- /dev/null +++ b/api/gen/http/openapi.json @@ -0,0 +1 @@ +{"swagger":"2.0","info":{"title":"pgEdge Control Plane API","description":"Service for creating, modifying, and operating pgEdge databases.","version":"0.0.1"},"host":"localhost:3000","consumes":["application/json","application/xml","application/gob"],"produces":["application/json","application/xml","application/gob"],"paths":{"/cluster":{"get":{"tags":["control-plane"],"summary":"inspect-cluster control-plane","description":"Returns information about the cluster.","operationId":"control-plane#inspect-cluster","responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/Cluster","required":["id","tenant_id","status","hosts"]}}},"schemes":["http"]}},"/databases":{"get":{"tags":["control-plane"],"summary":"list-databases control-plane","description":"Lists all databases in the cluster.","operationId":"control-plane#list-databases","responses":{"200":{"description":"OK response.","schema":{"type":"array","items":{"$ref":"#/definitions/Database"}}}},"schemes":["http"]},"post":{"tags":["control-plane"],"summary":"create-database control-plane","description":"Creates a new database in the cluster.","operationId":"control-plane#create-database","parameters":[{"name":"Create-DatabaseRequestBody","in":"body","required":true,"schema":{"$ref":"#/definitions/CreateDatabaseRequest"}}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/Database","required":["id","status","instances"]}}},"schemes":["http"]}},"/databases/{database_id}":{"get":{"tags":["control-plane"],"summary":"inspect-database control-plane","description":"Returns information about a particular database in the cluster.","operationId":"control-plane#inspect-database","parameters":[{"name":"database_id","in":"path","description":"ID of the database to inspect.","required":true,"type":"string"}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/Database","required":["id","status","instances"]}}},"schemes":["http"]},"post":{"tags":["control-plane"],"summary":"update-database control-plane","description":"Updates a database with the given specification.","operationId":"control-plane#update-database","parameters":[{"name":"database_id","in":"path","description":"ID of the database to update.","required":true,"type":"string"},{"name":"Update-DatabaseRequestBody","in":"body","required":true,"schema":{"$ref":"#/definitions/UpdateDatabaseRequest"}}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/Database","required":["id","status","instances"]}}},"schemes":["http"]},"delete":{"tags":["control-plane"],"summary":"delete-database control-plane","description":"Deletes a database from the cluster.","operationId":"control-plane#delete-database","parameters":[{"name":"database_id","in":"path","description":"ID of the database to delete.","required":true,"type":"string"}],"responses":{"204":{"description":"No Content response."}},"schemes":["http"]}},"/hosts":{"get":{"tags":["control-plane"],"summary":"list-hosts control-plane","description":"Lists all hosts within the cluster.","operationId":"control-plane#list-hosts","responses":{"200":{"description":"OK response.","schema":{"type":"array","items":{"$ref":"#/definitions/Host"}}}},"schemes":["http"]}},"/hosts/{host_id}":{"get":{"tags":["control-plane"],"summary":"inspect-host control-plane","description":"Returns information about a particular host in the cluster.","operationId":"control-plane#inspect-host","parameters":[{"name":"host_id","in":"path","description":"ID of the host to inspect.","required":true,"type":"string"}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/Host","required":["id","status","hostname","ipv4_address"]}}},"schemes":["http"]},"delete":{"tags":["control-plane"],"summary":"remove-host control-plane","description":"Removes a host from the cluster.","operationId":"control-plane#remove-host","parameters":[{"name":"host_id","in":"path","description":"ID of the host to remove.","required":true,"type":"string"}],"responses":{"204":{"description":"No Content response."}},"schemes":["http"]}},"/openapi.json":{"get":{"tags":["control-plane"],"summary":"Download ./gen/http/openapi.json","operationId":"control-plane#/openapi.json","responses":{"200":{"description":"File downloaded","schema":{"type":"file"}}},"schemes":["http"]}}},"definitions":{"BackupConfigSpec":{"title":"BackupConfigSpec","type":"object","properties":{"id":{"type":"string","description":"The unique identifier for this backup configuration.","example":"default"},"node_names":{"type":"array","items":{"type":"string","example":"Labore in."},"description":"The names of the nodes where this backup configuration should be applied. The configuration will apply to all nodes when this field is empty or unspecified.","example":["n1","n3"]},"provider":{"type":"string","description":"The backup provider for this backup configuration.","example":"pgbackrest","enum":["pgbackrest","pg_dump"]},"repositories":{"type":"array","items":{"$ref":"#/definitions/BackupRepositorySpec"},"description":"The repositories for this backup configuration.","example":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_region":"us-east-1","type":"s3"}]},"schedules":{"type":"array","items":{"$ref":"#/definitions/BackupScheduleSpec"},"description":"The schedules for this backup configuration.","example":[{"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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]}},"example":{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},"required":["id","provider"]},"BackupRepositorySpec":{"title":"BackupRepositorySpec","type":"object","properties":{"azure_account":{"type":"string","description":"The Azure account name for this repository. Only applies when type = 'azure'.","example":"pgedge-backups"},"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"},"azure_endpoint":{"type":"string","description":"The optional Azure endpoint for this repository. Only applies when type = 'azure'.","example":"blob.core.usgovcloudapi.net"},"base_path":{"type":"string","description":"The base path within the repository to store backups.","example":"/backups"},"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"},"gcs_endpoint":{"type":"string","description":"The optional GCS endpoint for this repository. Only applies when type = 'gcs'.","example":"localhost"},"id":{"type":"string","description":"The unique identifier of this repository.","example":"f6b84a99-5e91-4203-be1e-131fe82e5984"},"retention_full":{"type":"integer","description":"The count of full backups to retain or the time to retain full backups.","example":2,"format":"int64"},"retention_full_type":{"type":"string","description":"The type of measure used for retention_full.","example":"count","enum":["time","count"]},"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"},"s3_endpoint":{"type":"string","description":"The optional S3 endpoint for this repository. Only applies when type = 's3'.","example":"s3.us-east-1.amazonaws.com"},"s3_region":{"type":"string","description":"The region of the S3 bucket for this repository. Only applies when type = 's3'.","example":"us-east-1"},"type":{"type":"string","description":"The type of this repository.","example":"s3","enum":["s3","gcs","azure"]}},"example":{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_region":"us-east-1","type":"s3"},"required":["type"]},"BackupScheduleSpec":{"title":"BackupScheduleSpec","type":"object","properties":{"cron_expression":{"type":"string","description":"The cron expression for this schedule.","example":"0 6 * * ?"},"id":{"type":"string","description":"The unique identifier for this backup schedule.","example":"daily-full-backup"},"type":{"type":"string","description":"The type of backup to take on this schedule.","example":"full","enum":["full","incr"]}},"example":{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"},"required":["id","type","cron_expression"]},"Cluster":{"title":"Cluster","type":"object","properties":{"hosts":{"type":"array","items":{"$ref":"#/definitions/Host"},"description":"All of the hosts in the cluster.","example":[{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":true},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"systemd"},{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":true},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"systemd"}]},"id":{"type":"string","description":"Unique identifier for the cluster.","example":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d"},"status":{"$ref":"#/definitions/ClusterStatus"},"tenant_id":{"type":"string","description":"Unique identifier for the cluster's owner.","example":"8210ec10-2dca-406c-ac4a-0661d2189954"}},"example":{"hosts":[{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":true},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"systemd"},{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":true},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"systemd"}],"id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","status":{"state":"available"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954"},"required":["id","tenant_id","status","hosts"]},"ClusterStatus":{"title":"ClusterStatus","type":"object","properties":{"state":{"type":"string","description":"The current state of the cluster.","example":"error","enum":["available","error"]}},"example":{"state":"error"},"required":["state"]},"CreateDatabaseRequest":{"title":"CreateDatabaseRequest","type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the database.","example":"02f1a7db-fca8-4521-b57a-2a375c1ced51"},"spec":{"$ref":"#/definitions/DatabaseSpec"},"tenant_id":{"type":"string","description":"Unique identifier for the databases's owner.","example":"8210ec10-2dca-406c-ac4a-0661d2189954"}},"example":{"id":"02f1a7db-fca8-4521-b57a-2a375c1ced51","spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954"}},"Database":{"title":"Database","type":"object","properties":{"created_at":{"type":"string","description":"The time that the database was created.","example":"2025-01-01T01:30:00Z","format":"date-time"},"id":{"type":"string","description":"Unique identifier for the database.","example":"02f1a7db-fca8-4521-b57a-2a375c1ced51"},"instances":{"$ref":"#/definitions/Instance"},"spec":{"$ref":"#/definitions/DatabaseSpec"},"status":{"$ref":"#/definitions/DatabaseStatus"},"tenant_id":{"type":"string","description":"Unique identifier for the databases's owner.","example":"8210ec10-2dca-406c-ac4a-0661d2189954"},"updated_at":{"type":"string","description":"The time that the database was last updated.","example":"2025-01-01T02:30:00Z","format":"date-time"}},"example":{"created_at":"2025-01-01T01:30:00Z","id":"02f1a7db-fca8-4521-b57a-2a375c1ced51","instances":{"created_at":"1979-11-26T06:52:11Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":true,"patroni_state":"initializing new cluster","pending_restart":false,"postgres_version":"17.1","read_only":true,"role":"primary","spock_version":"4.0.9","state":"modifying","updated_at":"2014-10-05T16:37:36Z"},"updated_at":"1981-04-07T04:09:52Z"},"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"status":{"state":"error","updated_at":"2025-01-01T10:30:37Z"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954","updated_at":"2025-01-01T02:30:00Z"},"required":["id","status","instances"]},"DatabaseExtensionSpec":{"title":"DatabaseExtensionSpec","type":"object","properties":{"name":{"type":"string","description":"The name of the extension to install in this database.","example":"postgis"},"version":{"type":"string","description":"The version of the extension to install in this database.","example":"1.2.3"}},"example":{"name":"postgis","version":"1.2.3"},"required":["name"]},"DatabaseNodeSpec":{"title":"DatabaseNodeSpec","type":"object","properties":{"host_id":{"type":"string","description":"The ID of the host that should run this node.","example":"de3b1388-1f0c-42f1-a86c-59ab72f255ec"},"instance_id":{"type":"string","description":"A unique identifier for the instance that will be created from this node specification.","example":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d"},"name":{"type":"string","description":"The name of the database node.","example":"n1"},"port":{"type":"integer","description":"The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec.","example":5432,"format":"int64"},"postgres_version":{"type":"string","description":"The major version of Postgres for this node. Overrides the Postgres version set in the DatabaseSpec.","example":"17","enum":["16","17"]},"postgresql_conf":{"type":"object","description":"Additional postgresql.conf settings for this particular node. Will be merged with the settings provided by control-plane.","example":{"max_connections":1000},"additionalProperties":true},"read_replicas":{"$ref":"#/definitions/DatabaseReplicaSpec"}},"example":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},"required":["name","instance_id","host_id"]},"DatabaseReplicaSpec":{"title":"DatabaseReplicaSpec","type":"object","properties":{"host_id":{"type":"string","description":"The ID of the host that should run this read replica.","example":"de3b1388-1f0c-42f1-a86c-59ab72f255ec"},"instance_id":{"type":"string","description":"A unique identifier for the instance that will be created from this replica specification.","example":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},"example":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"},"required":["instance_id","host_id"]},"DatabaseSpec":{"title":"DatabaseSpec","type":"object","properties":{"backup_configs":{"type":"array","items":{"$ref":"#/definitions/BackupConfigSpec"},"description":"The backup configurations for this database.","example":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}]},"database_name":{"type":"string","description":"The name of the Postgres database.","example":"northwind"},"database_users":{"type":"array","items":{"$ref":"#/definitions/DatabaseUserSpec"},"description":"The users to create for this database.","example":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}]},"deletion_protection":{"type":"boolean","description":"Prevents deletion when true.","example":true},"extensions":{"type":"array","items":{"$ref":"#/definitions/DatabaseExtensionSpec"},"description":"The extensions to install for this database.","example":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}]},"features":{"type":"object","description":"The feature flags for this database.","example":{"some_feature":"enabled"},"additionalProperties":{"type":"string","example":"Magni quaerat qui quam id aut velit."}},"nodes":{"type":"array","items":{"$ref":"#/definitions/DatabaseNodeSpec"},"description":"The Spock nodes for this database.","example":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}]},"port":{"type":"integer","description":"The port used by the Postgres database.","example":5432,"format":"int64"},"postgres_version":{"type":"string","description":"The major version of the Postgres database.","example":"17","enum":["16","17"]},"postgresql_conf":{"type":"object","description":"Additional postgresql.conf settings. Will be merged with the settings provided by control-plane.","example":{"max_connections":1000},"additionalProperties":true},"spock_version":{"type":"string","description":"The major version of the Spock extension.","example":"4","enum":["4"]}},"example":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"required":["database_name","nodes"]},"DatabaseStatus":{"title":"DatabaseStatus","type":"object","properties":{"state":{"type":"string","example":"available","enum":["creating","modifying","available","error"]},"updated_at":{"type":"string","description":"The time that the database status was last updated.","example":"2025-01-01T10:30:37Z","format":"date-time"}},"example":{"state":"modifying","updated_at":"2025-01-01T10:30:37Z"}},"DatabaseUserSpec":{"title":"DatabaseUserSpec","type":"object","properties":{"password":{"type":"string","description":"The password for this database user.","example":"secret"},"roles":{"type":"array","items":{"type":"string","example":"Laudantium et quia commodi."},"description":"The roles to assign to this database user.","example":["application_read_only"]},"superuser":{"type":"boolean","description":"Enables SUPERUSER for this database user when true.","example":true},"username":{"type":"string","description":"The username for this database user.","example":"admin"}},"example":{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},"required":["username","password"]},"Host":{"title":"Host","type":"object","properties":{"cohort":{"type":"string","description":"The cohort that this host belongs to","example":"pps1n11hqijn9rbee4cjil453"},"config":{"$ref":"#/definitions/HostConfiguration"},"hostname":{"type":"string","description":"The hostname of this host.","example":"i-0123456789abcdef.ec2.internal"},"id":{"type":"string","description":"Unique identifier for the host","example":"de3b1388-1f0c-42f1-a86c-59ab72f255ec"},"ipv4_address":{"type":"string","description":"The IPv4 address of this host.","example":"10.24.34.0","format":"ipv4"},"status":{"$ref":"#/definitions/HostStatus"},"type":{"type":"string","description":"The type of this host","example":"swarm","enum":["swarm","systemd"]}},"example":{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":true},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"systemd"},"required":["id","status","hostname","ipv4_address"]},"HostConfiguration":{"title":"HostConfiguration","type":"object","properties":{"traefik_enabled":{"type":"boolean","description":"Enables the Treafik load balancer","example":false},"vector_enabled":{"type":"boolean","description":"Enables the Vector service for metrics and log collection","example":true}},"example":{"traefik_enabled":false,"vector_enabled":true}},"HostStatus":{"title":"HostStatus","type":"object","properties":{"state":{"type":"string","example":"available","enum":["available","unreachable","error"]}},"example":{"state":"available"},"required":["state"]},"Instance":{"title":"Instance","type":"object","properties":{"created_at":{"type":"string","description":"The time that the instance was created.","example":"1981-08-03T21:17:54Z","format":"date-time"},"host_id":{"type":"string","description":"The ID of the host this instance is running on.","example":"de3b1388-1f0c-42f1-a86c-59ab72f255ec"},"id":{"type":"string","description":"Unique identifier for the instance.","example":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d"},"interfaces":{"type":"array","items":{"$ref":"#/definitions/InstanceInterface"},"description":"All interfaces that this instance serves on.","example":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}]},"node_name":{"type":"string","description":"The Spock node name for this instance.","example":"n1"},"status":{"$ref":"#/definitions/InstanceStatus"},"updated_at":{"type":"string","description":"The time that the instance was last updated.","example":"2009-09-01T05:13:11Z","format":"date-time"}},"example":{"created_at":"2004-11-09T18:36:56Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":true,"patroni_state":"initializing new cluster","pending_restart":false,"postgres_version":"17.1","read_only":true,"role":"primary","spock_version":"4.0.9","state":"modifying","updated_at":"2014-10-05T16:37:36Z"},"updated_at":"1978-08-17T11:52:12Z"},"required":["id","status"]},"InstanceInterface":{"title":"InstanceInterface","type":"object","properties":{"hostname":{"type":"string","description":"The hostname of the instance on this interface.","example":"postgres-n1"},"ipv4_address":{"type":"string","description":"The IPv4 address of the instance on this interface.","example":"10.1.0.113","format":"ipv4"},"network_id":{"type":"string","description":"The unique identifier of the network for this interface.","example":"l5imrq28sh6s"},"network_type":{"type":"string","description":"The type of network for this interface.","example":"docker","enum":["docker","host"]},"port":{"type":"integer","description":"The Postgres port for the instance on this interface.","example":5432,"format":"int64"}},"example":{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}},"InstanceStatus":{"title":"InstanceStatus","type":"object","properties":{"patroni_paused":{"type":"boolean","description":"True if Patroni has been paused for this instance.","example":true},"patroni_state":{"type":"string","example":"custom bootstrap failed","enum":["stopping","stopped","stop failed","crashed","running","starting","start failed","restarting","restart failed","initializing new cluster","initdb failed","running custom bootstrap script","custom bootstrap failed","creating replica","unknown"]},"pending_restart":{"type":"boolean","description":"True if this instance is pending to be restarted from a configuration change.","example":true},"postgres_version":{"type":"string","description":"The version of Postgres for this instance.","example":"17.1"},"read_only":{"type":"boolean","description":"True if this instance is in read-only mode.","example":false},"role":{"type":"string","example":"replica","enum":["replica","primary"]},"spock_version":{"type":"string","description":"The version of Spock for this instance.","example":"4.0.9"},"state":{"type":"string","example":"creating","enum":["creating","modifying","backing_up","available","error"]},"updated_at":{"type":"string","description":"The time that the instance status was last updated.","example":"1998-03-09T10:30:37Z","format":"date-time"}},"example":{"patroni_paused":true,"patroni_state":"stopped","pending_restart":false,"postgres_version":"17.1","read_only":true,"role":"primary","spock_version":"4.0.9","state":"modifying","updated_at":"1986-12-19T00:29:43Z"},"required":["state"]},"UpdateDatabaseRequest":{"title":"UpdateDatabaseRequest","type":"object","properties":{"spec":{"$ref":"#/definitions/DatabaseSpec"}},"example":{"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"}}}}} \ No newline at end of file diff --git a/api/gen/http/openapi.yaml b/api/gen/http/openapi.yaml new file mode 100644 index 00000000..edc05cb3 --- /dev/null +++ b/api/gen/http/openapi.yaml @@ -0,0 +1,2152 @@ +swagger: "2.0" +info: + title: pgEdge Control Plane API + description: Service for creating, modifying, and operating pgEdge databases. + version: 0.0.1 +host: localhost:3000 +consumes: + - application/json + - application/xml + - application/gob +produces: + - application/json + - application/xml + - application/gob +paths: + /cluster: + get: + tags: + - control-plane + summary: inspect-cluster control-plane + description: Returns information about the cluster. + operationId: control-plane#inspect-cluster + responses: + "200": + description: OK response. + schema: + $ref: '#/definitions/Cluster' + required: + - id + - tenant_id + - status + - hosts + schemes: + - http + /databases: + get: + tags: + - control-plane + summary: list-databases control-plane + description: Lists all databases in the cluster. + operationId: control-plane#list-databases + responses: + "200": + description: OK response. + schema: + type: array + items: + $ref: '#/definitions/Database' + schemes: + - http + post: + tags: + - control-plane + summary: create-database control-plane + description: Creates a new database in the cluster. + operationId: control-plane#create-database + parameters: + - name: Create-DatabaseRequestBody + in: body + required: true + schema: + $ref: '#/definitions/CreateDatabaseRequest' + responses: + "200": + description: OK response. + schema: + $ref: '#/definitions/Database' + required: + - id + - status + - instances + schemes: + - http + /databases/{database_id}: + get: + tags: + - control-plane + summary: inspect-database control-plane + description: Returns information about a particular database in the cluster. + operationId: control-plane#inspect-database + parameters: + - name: database_id + in: path + description: ID of the database to inspect. + required: true + type: string + responses: + "200": + description: OK response. + schema: + $ref: '#/definitions/Database' + required: + - id + - status + - instances + schemes: + - http + post: + tags: + - control-plane + summary: update-database control-plane + description: Updates a database with the given specification. + operationId: control-plane#update-database + parameters: + - name: database_id + in: path + description: ID of the database to update. + required: true + type: string + - name: Update-DatabaseRequestBody + in: body + required: true + schema: + $ref: '#/definitions/UpdateDatabaseRequest' + responses: + "200": + description: OK response. + schema: + $ref: '#/definitions/Database' + required: + - id + - status + - instances + schemes: + - http + delete: + tags: + - control-plane + summary: delete-database control-plane + description: Deletes a database from the cluster. + operationId: control-plane#delete-database + parameters: + - name: database_id + in: path + description: ID of the database to delete. + required: true + type: string + responses: + "204": + description: No Content response. + schemes: + - http + /hosts: + get: + tags: + - control-plane + summary: list-hosts control-plane + description: Lists all hosts within the cluster. + operationId: control-plane#list-hosts + responses: + "200": + description: OK response. + schema: + type: array + items: + $ref: '#/definitions/Host' + schemes: + - http + /hosts/{host_id}: + get: + tags: + - control-plane + summary: inspect-host control-plane + description: Returns information about a particular host in the cluster. + operationId: control-plane#inspect-host + parameters: + - name: host_id + in: path + description: ID of the host to inspect. + required: true + type: string + responses: + "200": + description: OK response. + schema: + $ref: '#/definitions/Host' + required: + - id + - status + - hostname + - ipv4_address + schemes: + - http + delete: + tags: + - control-plane + summary: remove-host control-plane + description: Removes a host from the cluster. + operationId: control-plane#remove-host + parameters: + - name: host_id + in: path + description: ID of the host to remove. + required: true + type: string + responses: + "204": + description: No Content response. + schemes: + - http + /openapi.json: + get: + tags: + - control-plane + summary: Download ./gen/http/openapi.json + operationId: control-plane#/openapi.json + responses: + "200": + description: File downloaded + schema: + type: file + schemes: + - http +definitions: + BackupConfigSpec: + title: BackupConfigSpec + type: object + properties: + id: + type: string + description: The unique identifier for this backup configuration. + example: default + node_names: + type: array + items: + type: string + example: Labore in. + description: The names of the nodes where this backup configuration should be applied. The configuration will apply to all nodes when this field is empty or unspecified. + example: + - n1 + - n3 + provider: + type: string + description: The backup provider for this backup configuration. + example: pgbackrest + enum: + - pgbackrest + - pg_dump + repositories: + type: array + items: + $ref: '#/definitions/BackupRepositorySpec' + description: The repositories for this backup configuration. + example: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_region: us-east-1 + type: s3 + schedules: + type: array + items: + $ref: '#/definitions/BackupScheduleSpec' + description: The schedules for this backup configuration. + example: + - 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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + example: + id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + required: + - id + - provider + BackupRepositorySpec: + title: BackupRepositorySpec + type: object + properties: + azure_account: + type: string + description: The Azure account name for this repository. Only applies when type = 'azure'. + example: pgedge-backups + 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 + azure_endpoint: + type: string + description: The optional Azure endpoint for this repository. Only applies when type = 'azure'. + example: blob.core.usgovcloudapi.net + base_path: + type: string + description: The base path within the repository to store backups. + example: /backups + 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 + gcs_endpoint: + type: string + description: The optional GCS endpoint for this repository. Only applies when type = 'gcs'. + example: localhost + id: + type: string + description: The unique identifier of this repository. + example: f6b84a99-5e91-4203-be1e-131fe82e5984 + retention_full: + type: integer + description: The count of full backups to retain or the time to retain full backups. + example: 2 + format: int64 + retention_full_type: + type: string + description: The type of measure used for retention_full. + example: count + enum: + - time + - count + 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 + s3_endpoint: + type: string + description: The optional S3 endpoint for this repository. Only applies when type = 's3'. + example: s3.us-east-1.amazonaws.com + s3_region: + type: string + description: The region of the S3 bucket for this repository. Only applies when type = 's3'. + example: us-east-1 + type: + type: string + description: The type of this repository. + example: s3 + enum: + - s3 + - gcs + - azure + example: + azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_region: us-east-1 + type: s3 + required: + - type + BackupScheduleSpec: + title: BackupScheduleSpec + type: object + properties: + cron_expression: + type: string + description: The cron expression for this schedule. + example: 0 6 * * ? + id: + type: string + description: The unique identifier for this backup schedule. + example: daily-full-backup + type: + type: string + description: The type of backup to take on this schedule. + example: full + enum: + - full + - incr + example: + cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + required: + - id + - type + - cron_expression + Cluster: + title: Cluster + type: object + properties: + hosts: + type: array + items: + $ref: '#/definitions/Host' + description: All of the hosts in the cluster. + example: + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: true + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: systemd + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: true + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: systemd + id: + type: string + description: Unique identifier for the cluster. + example: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + status: + $ref: '#/definitions/ClusterStatus' + tenant_id: + type: string + description: Unique identifier for the cluster's owner. + example: 8210ec10-2dca-406c-ac4a-0661d2189954 + example: + hosts: + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: true + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: systemd + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: true + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: systemd + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + status: + state: available + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + required: + - id + - tenant_id + - status + - hosts + ClusterStatus: + title: ClusterStatus + type: object + properties: + state: + type: string + description: The current state of the cluster. + example: error + enum: + - available + - error + example: + state: error + required: + - state + CreateDatabaseRequest: + title: CreateDatabaseRequest + type: object + properties: + id: + type: string + description: Unique identifier for the database. + example: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + spec: + $ref: '#/definitions/DatabaseSpec' + tenant_id: + type: string + description: Unique identifier for the databases's owner. + example: 8210ec10-2dca-406c-ac4a-0661d2189954 + example: + id: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + Database: + title: Database + type: object + properties: + created_at: + type: string + description: The time that the database was created. + example: "2025-01-01T01:30:00Z" + format: date-time + id: + type: string + description: Unique identifier for the database. + example: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + instances: + $ref: '#/definitions/Instance' + spec: + $ref: '#/definitions/DatabaseSpec' + status: + $ref: '#/definitions/DatabaseStatus' + tenant_id: + type: string + description: Unique identifier for the databases's owner. + example: 8210ec10-2dca-406c-ac4a-0661d2189954 + updated_at: + type: string + description: The time that the database was last updated. + example: "2025-01-01T02:30:00Z" + format: date-time + example: + created_at: "2025-01-01T01:30:00Z" + id: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + instances: + created_at: "1979-11-26T06:52:11Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: true + patroni_state: initializing new cluster + pending_restart: false + postgres_version: "17.1" + read_only: true + role: primary + spock_version: 4.0.9 + state: modifying + updated_at: "2014-10-05T16:37:36Z" + updated_at: "1981-04-07T04:09:52Z" + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + status: + state: error + updated_at: "2025-01-01T10:30:37Z" + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + updated_at: "2025-01-01T02:30:00Z" + required: + - id + - status + - instances + DatabaseExtensionSpec: + title: DatabaseExtensionSpec + type: object + properties: + name: + type: string + description: The name of the extension to install in this database. + example: postgis + version: + type: string + description: The version of the extension to install in this database. + example: 1.2.3 + example: + name: postgis + version: 1.2.3 + required: + - name + DatabaseNodeSpec: + title: DatabaseNodeSpec + type: object + properties: + host_id: + type: string + description: The ID of the host that should run this node. + example: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: + type: string + description: A unique identifier for the instance that will be created from this node specification. + example: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: + type: string + description: The name of the database node. + example: n1 + port: + type: integer + description: The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec. + example: 5432 + format: int64 + postgres_version: + type: string + description: The major version of Postgres for this node. Overrides the Postgres version set in the DatabaseSpec. + example: "17" + enum: + - "16" + - "17" + postgresql_conf: + type: object + description: Additional postgresql.conf settings for this particular node. Will be merged with the settings provided by control-plane. + example: + max_connections: 1000 + additionalProperties: true + read_replicas: + $ref: '#/definitions/DatabaseReplicaSpec' + example: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + required: + - name + - instance_id + - host_id + DatabaseReplicaSpec: + title: DatabaseReplicaSpec + type: object + properties: + host_id: + type: string + description: The ID of the host that should run this read replica. + example: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: + type: string + description: A unique identifier for the instance that will be created from this replica specification. + example: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + example: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + required: + - instance_id + - host_id + DatabaseSpec: + title: DatabaseSpec + type: object + properties: + backup_configs: + type: array + items: + $ref: '#/definitions/BackupConfigSpec' + description: The backup configurations for this database. + example: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: + type: string + description: The name of the Postgres database. + example: northwind + database_users: + type: array + items: + $ref: '#/definitions/DatabaseUserSpec' + description: The users to create for this database. + example: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: + type: boolean + description: Prevents deletion when true. + example: true + extensions: + type: array + items: + $ref: '#/definitions/DatabaseExtensionSpec' + description: The extensions to install for this database. + example: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + type: object + description: The feature flags for this database. + example: + some_feature: enabled + additionalProperties: + type: string + example: Magni quaerat qui quam id aut velit. + nodes: + type: array + items: + $ref: '#/definitions/DatabaseNodeSpec' + description: The Spock nodes for this database. + example: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: + type: integer + description: The port used by the Postgres database. + example: 5432 + format: int64 + postgres_version: + type: string + description: The major version of the Postgres database. + example: "17" + enum: + - "16" + - "17" + postgresql_conf: + type: object + description: Additional postgresql.conf settings. Will be merged with the settings provided by control-plane. + example: + max_connections: 1000 + additionalProperties: true + spock_version: + type: string + description: The major version of the Spock extension. + example: "4" + enum: + - "4" + example: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + required: + - database_name + - nodes + DatabaseStatus: + title: DatabaseStatus + type: object + properties: + state: + type: string + example: available + enum: + - creating + - modifying + - available + - error + updated_at: + type: string + description: The time that the database status was last updated. + example: "2025-01-01T10:30:37Z" + format: date-time + example: + state: modifying + updated_at: "2025-01-01T10:30:37Z" + DatabaseUserSpec: + title: DatabaseUserSpec + type: object + properties: + password: + type: string + description: The password for this database user. + example: secret + roles: + type: array + items: + type: string + example: Laudantium et quia commodi. + description: The roles to assign to this database user. + example: + - application_read_only + superuser: + type: boolean + description: Enables SUPERUSER for this database user when true. + example: true + username: + type: string + description: The username for this database user. + example: admin + example: + password: secret + roles: + - application_read_only + superuser: true + username: admin + required: + - username + - password + Host: + title: Host + type: object + properties: + cohort: + type: string + description: The cohort that this host belongs to + example: pps1n11hqijn9rbee4cjil453 + config: + $ref: '#/definitions/HostConfiguration' + hostname: + type: string + description: The hostname of this host. + example: i-0123456789abcdef.ec2.internal + id: + type: string + description: Unique identifier for the host + example: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: + type: string + description: The IPv4 address of this host. + example: 10.24.34.0 + format: ipv4 + status: + $ref: '#/definitions/HostStatus' + type: + type: string + description: The type of this host + example: swarm + enum: + - swarm + - systemd + example: + cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: true + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: systemd + required: + - id + - status + - hostname + - ipv4_address + HostConfiguration: + title: HostConfiguration + type: object + properties: + traefik_enabled: + type: boolean + description: Enables the Treafik load balancer + example: false + vector_enabled: + type: boolean + description: Enables the Vector service for metrics and log collection + example: true + example: + traefik_enabled: false + vector_enabled: true + HostStatus: + title: HostStatus + type: object + properties: + state: + type: string + example: available + enum: + - available + - unreachable + - error + example: + state: available + required: + - state + Instance: + title: Instance + type: object + properties: + created_at: + type: string + description: The time that the instance was created. + example: "1981-08-03T21:17:54Z" + format: date-time + host_id: + type: string + description: The ID of the host this instance is running on. + example: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: + type: string + description: Unique identifier for the instance. + example: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + type: array + items: + $ref: '#/definitions/InstanceInterface' + description: All interfaces that this instance serves on. + example: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: + type: string + description: The Spock node name for this instance. + example: n1 + status: + $ref: '#/definitions/InstanceStatus' + updated_at: + type: string + description: The time that the instance was last updated. + example: "2009-09-01T05:13:11Z" + format: date-time + example: + created_at: "2004-11-09T18:36:56Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: true + patroni_state: initializing new cluster + pending_restart: false + postgres_version: "17.1" + read_only: true + role: primary + spock_version: 4.0.9 + state: modifying + updated_at: "2014-10-05T16:37:36Z" + updated_at: "1978-08-17T11:52:12Z" + required: + - id + - status + InstanceInterface: + title: InstanceInterface + type: object + properties: + hostname: + type: string + description: The hostname of the instance on this interface. + example: postgres-n1 + ipv4_address: + type: string + description: The IPv4 address of the instance on this interface. + example: 10.1.0.113 + format: ipv4 + network_id: + type: string + description: The unique identifier of the network for this interface. + example: l5imrq28sh6s + network_type: + type: string + description: The type of network for this interface. + example: docker + enum: + - docker + - host + port: + type: integer + description: The Postgres port for the instance on this interface. + example: 5432 + format: int64 + example: + hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + InstanceStatus: + title: InstanceStatus + type: object + properties: + patroni_paused: + type: boolean + description: True if Patroni has been paused for this instance. + example: true + patroni_state: + type: string + example: custom bootstrap failed + enum: + - stopping + - stopped + - stop failed + - crashed + - running + - starting + - start failed + - restarting + - restart failed + - initializing new cluster + - initdb failed + - running custom bootstrap script + - custom bootstrap failed + - creating replica + - unknown + pending_restart: + type: boolean + description: True if this instance is pending to be restarted from a configuration change. + example: true + postgres_version: + type: string + description: The version of Postgres for this instance. + example: "17.1" + read_only: + type: boolean + description: True if this instance is in read-only mode. + example: false + role: + type: string + example: replica + enum: + - replica + - primary + spock_version: + type: string + description: The version of Spock for this instance. + example: 4.0.9 + state: + type: string + example: creating + enum: + - creating + - modifying + - backing_up + - available + - error + updated_at: + type: string + description: The time that the instance status was last updated. + example: "1998-03-09T10:30:37Z" + format: date-time + example: + patroni_paused: true + patroni_state: stopped + pending_restart: false + postgres_version: "17.1" + read_only: true + role: primary + spock_version: 4.0.9 + state: modifying + updated_at: "1986-12-19T00:29:43Z" + required: + - state + UpdateDatabaseRequest: + title: UpdateDatabaseRequest + type: object + properties: + spec: + $ref: '#/definitions/DatabaseSpec' + example: + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" diff --git a/api/gen/http/openapi3.json b/api/gen/http/openapi3.json new file mode 100644 index 00000000..de9bc330 --- /dev/null +++ b/api/gen/http/openapi3.json @@ -0,0 +1 @@ +{"openapi":"3.0.3","info":{"title":"pgEdge Control Plane API","description":"Service for creating, modifying, and operating pgEdge databases.","version":"0.0.1"},"servers":[{"url":"http://localhost:3000"}],"paths":{"/cluster":{"get":{"tags":["control-plane"],"summary":"inspect-cluster control-plane","description":"Returns information about the cluster.","operationId":"control-plane#inspect-cluster","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Cluster"},"example":{"hosts":[{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":true},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"systemd"},{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":true},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"systemd"}],"id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","status":{"state":"available"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954"}}}}}}},"/databases":{"get":{"tags":["control-plane"],"summary":"list-databases control-plane","description":"Lists all databases in the cluster.","operationId":"control-plane#list-databases","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Database"},"example":[{"created_at":"2025-01-01T01:30:00Z","id":"02f1a7db-fca8-4521-b57a-2a375c1ced51","instances":{"created_at":"1979-11-26T06:52:11Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":true,"patroni_state":"initializing new cluster","pending_restart":false,"postgres_version":"17.1","read_only":true,"role":"primary","spock_version":"4.0.9","state":"modifying","updated_at":"2014-10-05T16:37:36Z"},"updated_at":"1981-04-07T04:09:52Z"},"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"status":{"state":"error","updated_at":"2025-01-01T10:30:37Z"},"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":{"created_at":"1979-11-26T06:52:11Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":true,"patroni_state":"initializing new cluster","pending_restart":false,"postgres_version":"17.1","read_only":true,"role":"primary","spock_version":"4.0.9","state":"modifying","updated_at":"2014-10-05T16:37:36Z"},"updated_at":"1981-04-07T04:09:52Z"},"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"status":{"state":"error","updated_at":"2025-01-01T10:30:37Z"},"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":{"created_at":"1979-11-26T06:52:11Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":true,"patroni_state":"initializing new cluster","pending_restart":false,"postgres_version":"17.1","read_only":true,"role":"primary","spock_version":"4.0.9","state":"modifying","updated_at":"2014-10-05T16:37:36Z"},"updated_at":"1981-04-07T04:09:52Z"},"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"status":{"state":"error","updated_at":"2025-01-01T10:30:37Z"},"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":{"created_at":"1979-11-26T06:52:11Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":true,"patroni_state":"initializing new cluster","pending_restart":false,"postgres_version":"17.1","read_only":true,"role":"primary","spock_version":"4.0.9","state":"modifying","updated_at":"2014-10-05T16:37:36Z"},"updated_at":"1981-04-07T04:09:52Z"},"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"status":{"state":"error","updated_at":"2025-01-01T10:30:37Z"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954","updated_at":"2025-01-01T02:30:00Z"}]},"example":[{"created_at":"2025-01-01T01:30:00Z","id":"02f1a7db-fca8-4521-b57a-2a375c1ced51","instances":{"created_at":"1979-11-26T06:52:11Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":true,"patroni_state":"initializing new cluster","pending_restart":false,"postgres_version":"17.1","read_only":true,"role":"primary","spock_version":"4.0.9","state":"modifying","updated_at":"2014-10-05T16:37:36Z"},"updated_at":"1981-04-07T04:09:52Z"},"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"status":{"state":"error","updated_at":"2025-01-01T10:30:37Z"},"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":{"created_at":"1979-11-26T06:52:11Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":true,"patroni_state":"initializing new cluster","pending_restart":false,"postgres_version":"17.1","read_only":true,"role":"primary","spock_version":"4.0.9","state":"modifying","updated_at":"2014-10-05T16:37:36Z"},"updated_at":"1981-04-07T04:09:52Z"},"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"status":{"state":"error","updated_at":"2025-01-01T10:30:37Z"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954","updated_at":"2025-01-01T02:30:00Z"}]}}}}},"post":{"tags":["control-plane"],"summary":"create-database control-plane","description":"Creates a new database in the cluster.","operationId":"control-plane#create-database","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDatabaseRequest"},"example":{"id":"02f1a7db-fca8-4521-b57a-2a375c1ced51","spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954"}}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Database"},"example":{"created_at":"2025-01-01T01:30:00Z","id":"02f1a7db-fca8-4521-b57a-2a375c1ced51","instances":{"created_at":"1983-06-23T19:00:09Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":false,"patroni_state":"running","pending_restart":false,"postgres_version":"17.1","read_only":false,"role":"replica","spock_version":"4.0.9","state":"available","updated_at":"1987-12-08T09:28:21Z"},"updated_at":"1985-05-18T17:19:50Z"},"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"status":{"state":"available","updated_at":"2025-01-01T10:30:37Z"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954","updated_at":"2025-01-01T02:30:00Z"}}}}}}},"/databases/{database_id}":{"delete":{"tags":["control-plane"],"summary":"delete-database control-plane","description":"Deletes a database from the cluster.","operationId":"control-plane#delete-database","parameters":[{"name":"database_id","in":"path","description":"ID of the database to delete.","required":true,"schema":{"type":"string","description":"ID of the database to delete.","example":"02f1a7db-fca8-4521-b57a-2a375c1ced51"},"example":"02f1a7db-fca8-4521-b57a-2a375c1ced51"}],"responses":{"204":{"description":"No Content response."}}},"get":{"tags":["control-plane"],"summary":"inspect-database control-plane","description":"Returns information about a particular database in the cluster.","operationId":"control-plane#inspect-database","parameters":[{"name":"database_id","in":"path","description":"ID of the database to inspect.","required":true,"schema":{"type":"string","description":"ID of the database to inspect.","example":"02f1a7db-fca8-4521-b57a-2a375c1ced51"},"example":"02f1a7db-fca8-4521-b57a-2a375c1ced51"}],"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Database"},"example":{"created_at":"2025-01-01T01:30:00Z","id":"02f1a7db-fca8-4521-b57a-2a375c1ced51","instances":{"created_at":"1983-06-23T19:00:09Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":false,"patroni_state":"running","pending_restart":false,"postgres_version":"17.1","read_only":false,"role":"replica","spock_version":"4.0.9","state":"available","updated_at":"1987-12-08T09:28:21Z"},"updated_at":"1985-05-18T17:19:50Z"},"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"status":{"state":"available","updated_at":"2025-01-01T10:30:37Z"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954","updated_at":"2025-01-01T02:30:00Z"}}}}}},"post":{"tags":["control-plane"],"summary":"update-database control-plane","description":"Updates a database with the given specification.","operationId":"control-plane#update-database","parameters":[{"name":"database_id","in":"path","description":"ID of the database to update.","required":true,"schema":{"type":"string","description":"ID of the database to update.","example":"02f1a7db-fca8-4521-b57a-2a375c1ced51"},"example":"02f1a7db-fca8-4521-b57a-2a375c1ced51"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDatabaseRequest"},"example":{"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"}}}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Database"},"example":{"created_at":"2025-01-01T01:30:00Z","id":"02f1a7db-fca8-4521-b57a-2a375c1ced51","instances":{"created_at":"1983-06-23T19:00:09Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":false,"patroni_state":"running","pending_restart":false,"postgres_version":"17.1","read_only":false,"role":"replica","spock_version":"4.0.9","state":"available","updated_at":"1987-12-08T09:28:21Z"},"updated_at":"1985-05-18T17:19:50Z"},"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"status":{"state":"available","updated_at":"2025-01-01T10:30:37Z"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954","updated_at":"2025-01-01T02:30:00Z"}}}}}}},"/hosts":{"get":{"tags":["control-plane"],"summary":"list-hosts control-plane","description":"Lists all hosts within the cluster.","operationId":"control-plane#list-hosts","responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Host"},"example":[{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":false,"vector_enabled":false},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"swarm"},{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":false,"vector_enabled":false},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"swarm"}]},"example":[{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":false,"vector_enabled":false},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"swarm"},{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":false,"vector_enabled":false},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"swarm"}]}}}}}},"/hosts/{host_id}":{"delete":{"tags":["control-plane"],"summary":"remove-host control-plane","description":"Removes a host from the cluster.","operationId":"control-plane#remove-host","parameters":[{"name":"host_id","in":"path","description":"ID of the host to remove.","required":true,"schema":{"type":"string","description":"ID of the host to remove.","example":"de3b1388-1f0c-42f1-a86c-59ab72f255ec"},"example":"de3b1388-1f0c-42f1-a86c-59ab72f255ec"}],"responses":{"204":{"description":"No Content response."}}},"get":{"tags":["control-plane"],"summary":"inspect-host control-plane","description":"Returns information about a particular host in the cluster.","operationId":"control-plane#inspect-host","parameters":[{"name":"host_id","in":"path","description":"ID of the host to inspect.","required":true,"schema":{"type":"string","description":"ID of the host to inspect.","example":"de3b1388-1f0c-42f1-a86c-59ab72f255ec"},"example":"de3b1388-1f0c-42f1-a86c-59ab72f255ec"}],"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Host"},"example":{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":true},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"swarm"}}}}}}},"/openapi.json":{"get":{"tags":["control-plane"],"summary":"Download ./gen/http/openapi.json","operationId":"control-plane#/openapi.json","responses":{"200":{"description":"File downloaded"}}}}},"components":{"schemas":{"BackupConfigSpec":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for this backup configuration.","example":"default"},"node_names":{"type":"array","items":{"type":"string","example":"Totam dolorem."},"description":"The names of the nodes where this backup configuration should be applied. The configuration will apply to all nodes when this field is empty or unspecified.","example":["n1","n3"]},"provider":{"type":"string","description":"The backup provider for this backup configuration.","example":"pgbackrest","enum":["pgbackrest","pg_dump"]},"repositories":{"type":"array","items":{"$ref":"#/components/schemas/BackupRepositorySpec"},"description":"The repositories for this backup configuration.","example":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_region":"us-east-1","type":"s3"}]},"schedules":{"type":"array","items":{"$ref":"#/components/schemas/BackupScheduleSpec"},"description":"The schedules for this backup configuration.","example":[{"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"}]}},"example":{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"},{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"}]},"required":["id","provider"]},"BackupRepositorySpec":{"type":"object","properties":{"azure_account":{"type":"string","description":"The Azure account name for this repository. Only applies when type = 'azure'.","example":"pgedge-backups"},"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"},"azure_endpoint":{"type":"string","description":"The optional Azure endpoint for this repository. Only applies when type = 'azure'.","example":"blob.core.usgovcloudapi.net"},"base_path":{"type":"string","description":"The base path within the repository to store backups.","example":"/backups"},"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"},"gcs_endpoint":{"type":"string","description":"The optional GCS endpoint for this repository. Only applies when type = 'gcs'.","example":"localhost"},"id":{"type":"string","description":"The unique identifier of this repository.","example":"f6b84a99-5e91-4203-be1e-131fe82e5984"},"retention_full":{"type":"integer","description":"The count of full backups to retain or the time to retain full backups.","example":2,"format":"int64"},"retention_full_type":{"type":"string","description":"The type of measure used for retention_full.","example":"count","enum":["time","count"]},"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"},"s3_endpoint":{"type":"string","description":"The optional S3 endpoint for this repository. Only applies when type = 's3'.","example":"s3.us-east-1.amazonaws.com"},"s3_region":{"type":"string","description":"The region of the S3 bucket for this repository. Only applies when type = 's3'.","example":"us-east-1"},"type":{"type":"string","description":"The type of this repository.","example":"s3","enum":["s3","gcs","azure"]}},"example":{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_region":"us-east-1","type":"s3"},"required":["type"]},"BackupScheduleSpec":{"type":"object","properties":{"cron_expression":{"type":"string","description":"The cron expression for this schedule.","example":"0 6 * * ?"},"id":{"type":"string","description":"The unique identifier for this backup schedule.","example":"daily-full-backup"},"type":{"type":"string","description":"The type of backup to take on this schedule.","example":"full","enum":["full","incr"]}},"example":{"cron_expression":"0 6 * * ?","id":"daily-full-backup","type":"full"},"required":["id","type","cron_expression"]},"Cluster":{"type":"object","properties":{"hosts":{"type":"array","items":{"$ref":"#/components/schemas/Host"},"description":"All of the hosts in the cluster.","example":[{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":false},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"swarm"},{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":false},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"swarm"},{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":false},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"swarm"}]},"id":{"type":"string","description":"Unique identifier for the cluster.","example":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d"},"status":{"$ref":"#/components/schemas/ClusterStatus"},"tenant_id":{"type":"string","description":"Unique identifier for the cluster's owner.","example":"8210ec10-2dca-406c-ac4a-0661d2189954"}},"example":{"hosts":[{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":false},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"swarm"},{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":false},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"swarm"},{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":false},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"swarm"},{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":false},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"swarm"}],"id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","status":{"state":"available"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954"},"required":["id","tenant_id","status","hosts"]},"ClusterStatus":{"type":"object","properties":{"state":{"type":"string","description":"The current state of the cluster.","example":"error","enum":["available","error"]}},"example":{"state":"available"},"required":["state"]},"CreateDatabaseRequest":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for the database.","example":"02f1a7db-fca8-4521-b57a-2a375c1ced51"},"spec":{"$ref":"#/components/schemas/DatabaseSpec"},"tenant_id":{"type":"string","description":"Unique identifier for the databases's owner.","example":"8210ec10-2dca-406c-ac4a-0661d2189954"}},"example":{"id":"02f1a7db-fca8-4521-b57a-2a375c1ced51","spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954"}},"Database":{"type":"object","properties":{"created_at":{"type":"string","description":"The time that the database was created.","example":"2025-01-01T01:30:00Z","format":"date-time"},"id":{"type":"string","description":"Unique identifier for the database.","example":"02f1a7db-fca8-4521-b57a-2a375c1ced51"},"instances":{"$ref":"#/components/schemas/Instance"},"spec":{"$ref":"#/components/schemas/DatabaseSpec"},"status":{"$ref":"#/components/schemas/DatabaseStatus"},"tenant_id":{"type":"string","description":"Unique identifier for the databases's owner.","example":"8210ec10-2dca-406c-ac4a-0661d2189954"},"updated_at":{"type":"string","description":"The time that the database was last updated.","example":"2025-01-01T02:30:00Z","format":"date-time"}},"example":{"created_at":"2025-01-01T01:30:00Z","id":"02f1a7db-fca8-4521-b57a-2a375c1ced51","instances":{"created_at":"1975-03-20T03:08:32Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":true,"patroni_state":"unknown","pending_restart":false,"postgres_version":"17.1","read_only":true,"role":"primary","spock_version":"4.0.9","state":"backing_up","updated_at":"2000-08-17T12:59:00Z"},"updated_at":"1972-05-07T22:20:35Z"},"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"status":{"state":"error","updated_at":"2025-01-01T10:30:37Z"},"tenant_id":"8210ec10-2dca-406c-ac4a-0661d2189954","updated_at":"2025-01-01T02:30:00Z"},"required":["id","status","instances"]},"DatabaseExtensionSpec":{"type":"object","properties":{"name":{"type":"string","description":"The name of the extension to install in this database.","example":"postgis"},"version":{"type":"string","description":"The version of the extension to install in this database.","example":"1.2.3"}},"example":{"name":"postgis","version":"1.2.3"},"required":["name"]},"DatabaseNodeSpec":{"type":"object","properties":{"host_id":{"type":"string","description":"The ID of the host that should run this node.","example":"de3b1388-1f0c-42f1-a86c-59ab72f255ec"},"instance_id":{"type":"string","description":"A unique identifier for the instance that will be created from this node specification.","example":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d"},"name":{"type":"string","description":"The name of the database node.","example":"n1"},"port":{"type":"integer","description":"The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec.","example":5432,"format":"int64"},"postgres_version":{"type":"string","description":"The major version of Postgres for this node. Overrides the Postgres version set in the DatabaseSpec.","example":"17","enum":["16","17"]},"postgresql_conf":{"type":"object","description":"Additional postgresql.conf settings for this particular node. Will be merged with the settings provided by control-plane.","example":{"max_connections":1000},"additionalProperties":true},"read_replicas":{"$ref":"#/components/schemas/DatabaseReplicaSpec"}},"example":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},"required":["name","instance_id","host_id"]},"DatabaseReplicaSpec":{"type":"object","properties":{"host_id":{"type":"string","description":"The ID of the host that should run this read replica.","example":"de3b1388-1f0c-42f1-a86c-59ab72f255ec"},"instance_id":{"type":"string","description":"A unique identifier for the instance that will be created from this replica specification.","example":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},"example":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"},"required":["instance_id","host_id"]},"DatabaseSpec":{"type":"object","properties":{"backup_configs":{"type":"array","items":{"$ref":"#/components/schemas/BackupConfigSpec"},"description":"The backup configurations for this database.","example":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}]},"database_name":{"type":"string","description":"The name of the Postgres database.","example":"northwind"},"database_users":{"type":"array","items":{"$ref":"#/components/schemas/DatabaseUserSpec"},"description":"The users to create for this database.","example":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}]},"deletion_protection":{"type":"boolean","description":"Prevents deletion when true.","example":true},"extensions":{"type":"array","items":{"$ref":"#/components/schemas/DatabaseExtensionSpec"},"description":"The extensions to install for this database.","example":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}]},"features":{"type":"object","description":"The feature flags for this database.","example":{"some_feature":"enabled"},"additionalProperties":{"type":"string","example":"Nihil facere ad tenetur iure quisquam."}},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/DatabaseNodeSpec"},"description":"The Spock nodes for this database.","example":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}]},"port":{"type":"integer","description":"The port used by the Postgres database.","example":5432,"format":"int64"},"postgres_version":{"type":"string","description":"The major version of the Postgres database.","example":"17","enum":["16","17"]},"postgresql_conf":{"type":"object","description":"Additional postgresql.conf settings. Will be merged with the settings provided by control-plane.","example":{"max_connections":1000},"additionalProperties":true},"spock_version":{"type":"string","description":"The major version of the Spock extension.","example":"4","enum":["4"]}},"example":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"},"required":["database_name","nodes"]},"DatabaseStatus":{"type":"object","properties":{"state":{"type":"string","example":"available","enum":["creating","modifying","available","error"]},"updated_at":{"type":"string","description":"The time that the database status was last updated.","example":"2025-01-01T10:30:37Z","format":"date-time"}},"example":{"state":"modifying","updated_at":"2025-01-01T10:30:37Z"}},"DatabaseUserSpec":{"type":"object","properties":{"password":{"type":"string","description":"The password for this database user.","example":"secret"},"roles":{"type":"array","items":{"type":"string","example":"Voluptatum nulla commodi quo aut facere."},"description":"The roles to assign to this database user.","example":["application_read_only"]},"superuser":{"type":"boolean","description":"Enables SUPERUSER for this database user when true.","example":true},"username":{"type":"string","description":"The username for this database user.","example":"admin"}},"example":{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},"required":["username","password"]},"Host":{"type":"object","properties":{"cohort":{"type":"string","description":"The cohort that this host belongs to","example":"pps1n11hqijn9rbee4cjil453"},"config":{"$ref":"#/components/schemas/HostConfiguration"},"hostname":{"type":"string","description":"The hostname of this host.","example":"i-0123456789abcdef.ec2.internal"},"id":{"type":"string","description":"Unique identifier for the host","example":"de3b1388-1f0c-42f1-a86c-59ab72f255ec"},"ipv4_address":{"type":"string","description":"The IPv4 address of this host.","example":"10.24.34.0","format":"ipv4"},"status":{"$ref":"#/components/schemas/HostStatus"},"type":{"type":"string","description":"The type of this host","example":"swarm","enum":["swarm","systemd"]}},"example":{"cohort":"pps1n11hqijn9rbee4cjil453","config":{"traefik_enabled":true,"vector_enabled":false},"hostname":"i-0123456789abcdef.ec2.internal","id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","ipv4_address":"10.24.34.0","status":{"state":"available"},"type":"systemd"},"required":["id","status","hostname","ipv4_address"]},"HostConfiguration":{"type":"object","properties":{"traefik_enabled":{"type":"boolean","description":"Enables the Treafik load balancer","example":false},"vector_enabled":{"type":"boolean","description":"Enables the Vector service for metrics and log collection","example":false}},"example":{"traefik_enabled":true,"vector_enabled":false}},"HostStatus":{"type":"object","properties":{"state":{"type":"string","example":"available","enum":["available","unreachable","error"]}},"example":{"state":"available"},"required":["state"]},"Instance":{"type":"object","properties":{"created_at":{"type":"string","description":"The time that the instance was created.","example":"1975-11-29T11:29:36Z","format":"date-time"},"host_id":{"type":"string","description":"The ID of the host this instance is running on.","example":"de3b1388-1f0c-42f1-a86c-59ab72f255ec"},"id":{"type":"string","description":"Unique identifier for the instance.","example":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d"},"interfaces":{"type":"array","items":{"$ref":"#/components/schemas/InstanceInterface"},"description":"All interfaces that this instance serves on.","example":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}]},"node_name":{"type":"string","description":"The Spock node name for this instance.","example":"n1"},"status":{"$ref":"#/components/schemas/InstanceStatus"},"updated_at":{"type":"string","description":"The time that the instance was last updated.","example":"1975-10-27T03:55:24Z","format":"date-time"}},"example":{"created_at":"1972-05-03T15:38:49Z","host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","interfaces":[{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432},{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}],"node_name":"n1","status":{"patroni_paused":true,"patroni_state":"unknown","pending_restart":false,"postgres_version":"17.1","read_only":true,"role":"primary","spock_version":"4.0.9","state":"backing_up","updated_at":"2000-08-17T12:59:00Z"},"updated_at":"1982-12-11T10:43:34Z"},"required":["id","status"]},"InstanceInterface":{"type":"object","properties":{"hostname":{"type":"string","description":"The hostname of the instance on this interface.","example":"postgres-n1"},"ipv4_address":{"type":"string","description":"The IPv4 address of the instance on this interface.","example":"10.1.0.113","format":"ipv4"},"network_id":{"type":"string","description":"The unique identifier of the network for this interface.","example":"l5imrq28sh6s"},"network_type":{"type":"string","description":"The type of network for this interface.","example":"docker","enum":["docker","host"]},"port":{"type":"integer","description":"The Postgres port for the instance on this interface.","example":5432,"format":"int64"}},"example":{"hostname":"postgres-n1","ipv4_address":"10.1.0.113","network_id":"l5imrq28sh6s","network_type":"docker","port":5432}},"InstanceStatus":{"type":"object","properties":{"patroni_paused":{"type":"boolean","description":"True if Patroni has been paused for this instance.","example":true},"patroni_state":{"type":"string","example":"crashed","enum":["stopping","stopped","stop failed","crashed","running","starting","start failed","restarting","restart failed","initializing new cluster","initdb failed","running custom bootstrap script","custom bootstrap failed","creating replica","unknown"]},"pending_restart":{"type":"boolean","description":"True if this instance is pending to be restarted from a configuration change.","example":false},"postgres_version":{"type":"string","description":"The version of Postgres for this instance.","example":"17.1"},"read_only":{"type":"boolean","description":"True if this instance is in read-only mode.","example":false},"role":{"type":"string","example":"replica","enum":["replica","primary"]},"spock_version":{"type":"string","description":"The version of Spock for this instance.","example":"4.0.9"},"state":{"type":"string","example":"error","enum":["creating","modifying","backing_up","available","error"]},"updated_at":{"type":"string","description":"The time that the instance status was last updated.","example":"2000-09-09T15:06:57Z","format":"date-time"}},"example":{"patroni_paused":false,"patroni_state":"stopping","pending_restart":false,"postgres_version":"17.1","read_only":false,"role":"replica","spock_version":"4.0.9","state":"creating","updated_at":"1997-12-31T00:50:06Z"},"required":["state"]},"RestoreConfigSpec":{"type":"object","properties":{"node_name":{"type":"string","description":"The name of the node to restore this database from.","example":"n1"},"provider":{"type":"string","description":"The backup provider for this restore configuration.","example":"pgbackrest","enum":["pgbackrest","pg_dump"]},"repository":{"$ref":"#/components/schemas/RestoreRepositorySpec"}},"example":{"node_name":"n1","provider":"pgbackrest","repository":{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","id":"f6b84a99-5e91-4203-be1e-131fe82e5984","s3_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","s3_endpoint":"s3.us-east-1.amazonaws.com","s3_region":"us-east-1","type":"s3"}},"required":["provider","node_name","repository"]},"RestoreRepositorySpec":{"type":"object","properties":{"azure_account":{"type":"string","description":"The Azure account name for this repository. Only applies when type = 'azure'.","example":"pgedge-backups"},"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"},"azure_endpoint":{"type":"string","description":"The optional Azure endpoint for this repository. Only applies when type = 'azure'.","example":"blob.core.usgovcloudapi.net"},"base_path":{"type":"string","description":"The base path within the repository where backups are stored.","example":"/backups"},"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"},"gcs_endpoint":{"type":"string","description":"The optional GCS endpoint for this repository. Only applies when type = 'gcs'.","example":"localhost"},"id":{"type":"string","description":"The unique identifier of this repository.","example":"f6b84a99-5e91-4203-be1e-131fe82e5984"},"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"},"s3_endpoint":{"type":"string","description":"The optional S3 endpoint for this repository. Only applies when type = 's3'.","example":"s3.us-east-1.amazonaws.com"},"s3_region":{"type":"string","description":"The region of the S3 bucket for this repository. Only applies when type = 's3'.","example":"us-east-1"},"type":{"type":"string","description":"The type of this repository.","example":"s3","enum":["s3","gcs","azure"]}},"example":{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","id":"f6b84a99-5e91-4203-be1e-131fe82e5984","s3_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","s3_endpoint":"s3.us-east-1.amazonaws.com","s3_region":"us-east-1","type":"s3"},"required":["id","type"]},"UpdateDatabaseRequest":{"type":"object","properties":{"spec":{"$ref":"#/components/schemas/DatabaseSpec"}},"example":{"spec":{"backup_configs":[{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]},{"id":"default","node_names":["n1","n3"],"provider":"pgbackrest","repositories":[{"azure_account":"pgedge-backups","azure_container":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","azure_endpoint":"blob.core.usgovcloudapi.net","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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","base_path":"/backups","gcs_bucket":"pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1","gcs_endpoint":"localhost","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_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"}]}],"database_name":"northwind","database_users":[{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"},{"password":"secret","roles":["application_read_only"],"superuser":true,"username":"admin"}],"deletion_protection":true,"extensions":[{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"},{"name":"postgis","version":"1.2.3"}],"features":{"some_feature":"enabled"},"nodes":[{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}},{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"a67cbb36-c3c3-49c9-8aac-f4a0438a883d","name":"n1","port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"read_replicas":{"host_id":"de3b1388-1f0c-42f1-a86c-59ab72f255ec","instance_id":"5ec51c55-0921-445e-9d5b-32f5fb5dfbae"}}],"port":5432,"postgres_version":"17","postgresql_conf":{"max_connections":1000},"spock_version":"4"}}}}},"tags":[{"name":"control-plane"}]} \ No newline at end of file diff --git a/api/gen/http/openapi3.yaml b/api/gen/http/openapi3.yaml new file mode 100644 index 00000000..64f1d9d4 --- /dev/null +++ b/api/gen/http/openapi3.yaml @@ -0,0 +1,4613 @@ +openapi: 3.0.3 +info: + title: pgEdge Control Plane API + description: Service for creating, modifying, and operating pgEdge databases. + version: 0.0.1 +servers: + - url: http://localhost:3000 +paths: + /cluster: + get: + tags: + - control-plane + summary: inspect-cluster control-plane + description: Returns information about the cluster. + operationId: control-plane#inspect-cluster + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/Cluster' + example: + hosts: + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: true + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: systemd + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: true + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: systemd + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + status: + state: available + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + /databases: + get: + tags: + - control-plane + summary: list-databases control-plane + description: Lists all databases in the cluster. + operationId: control-plane#list-databases + responses: + "200": + description: OK response. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Database' + example: + - created_at: "2025-01-01T01:30:00Z" + id: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + instances: + created_at: "1979-11-26T06:52:11Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: true + patroni_state: initializing new cluster + pending_restart: false + postgres_version: "17.1" + read_only: true + role: primary + spock_version: 4.0.9 + state: modifying + updated_at: "2014-10-05T16:37:36Z" + updated_at: "1981-04-07T04:09:52Z" + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + status: + state: error + updated_at: "2025-01-01T10:30:37Z" + 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: + created_at: "1979-11-26T06:52:11Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: true + patroni_state: initializing new cluster + pending_restart: false + postgres_version: "17.1" + read_only: true + role: primary + spock_version: 4.0.9 + state: modifying + updated_at: "2014-10-05T16:37:36Z" + updated_at: "1981-04-07T04:09:52Z" + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + status: + state: error + updated_at: "2025-01-01T10:30:37Z" + 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: + created_at: "1979-11-26T06:52:11Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: true + patroni_state: initializing new cluster + pending_restart: false + postgres_version: "17.1" + read_only: true + role: primary + spock_version: 4.0.9 + state: modifying + updated_at: "2014-10-05T16:37:36Z" + updated_at: "1981-04-07T04:09:52Z" + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + status: + state: error + updated_at: "2025-01-01T10:30:37Z" + 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: + created_at: "1979-11-26T06:52:11Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: true + patroni_state: initializing new cluster + pending_restart: false + postgres_version: "17.1" + read_only: true + role: primary + spock_version: 4.0.9 + state: modifying + updated_at: "2014-10-05T16:37:36Z" + updated_at: "1981-04-07T04:09:52Z" + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + status: + state: error + updated_at: "2025-01-01T10:30:37Z" + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + updated_at: "2025-01-01T02:30:00Z" + example: + - created_at: "2025-01-01T01:30:00Z" + id: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + instances: + created_at: "1979-11-26T06:52:11Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: true + patroni_state: initializing new cluster + pending_restart: false + postgres_version: "17.1" + read_only: true + role: primary + spock_version: 4.0.9 + state: modifying + updated_at: "2014-10-05T16:37:36Z" + updated_at: "1981-04-07T04:09:52Z" + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + status: + state: error + updated_at: "2025-01-01T10:30:37Z" + 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: + created_at: "1979-11-26T06:52:11Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: true + patroni_state: initializing new cluster + pending_restart: false + postgres_version: "17.1" + read_only: true + role: primary + spock_version: 4.0.9 + state: modifying + updated_at: "2014-10-05T16:37:36Z" + updated_at: "1981-04-07T04:09:52Z" + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + status: + state: error + updated_at: "2025-01-01T10:30:37Z" + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + updated_at: "2025-01-01T02:30:00Z" + post: + tags: + - control-plane + summary: create-database control-plane + description: Creates a new database in the cluster. + operationId: control-plane#create-database + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateDatabaseRequest' + example: + id: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/Database' + example: + created_at: "2025-01-01T01:30:00Z" + id: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + instances: + created_at: "1983-06-23T19:00:09Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: false + patroni_state: running + pending_restart: false + postgres_version: "17.1" + read_only: false + role: replica + spock_version: 4.0.9 + state: available + updated_at: "1987-12-08T09:28:21Z" + updated_at: "1985-05-18T17:19:50Z" + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + status: + state: available + updated_at: "2025-01-01T10:30:37Z" + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + updated_at: "2025-01-01T02:30:00Z" + /databases/{database_id}: + delete: + tags: + - control-plane + summary: delete-database control-plane + description: Deletes a database from the cluster. + operationId: control-plane#delete-database + parameters: + - name: database_id + in: path + description: ID of the database to delete. + required: true + schema: + type: string + description: ID of the database to delete. + example: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + example: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + responses: + "204": + description: No Content response. + get: + tags: + - control-plane + summary: inspect-database control-plane + description: Returns information about a particular database in the cluster. + operationId: control-plane#inspect-database + parameters: + - name: database_id + in: path + description: ID of the database to inspect. + required: true + schema: + type: string + description: ID of the database to inspect. + example: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + example: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/Database' + example: + created_at: "2025-01-01T01:30:00Z" + id: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + instances: + created_at: "1983-06-23T19:00:09Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: false + patroni_state: running + pending_restart: false + postgres_version: "17.1" + read_only: false + role: replica + spock_version: 4.0.9 + state: available + updated_at: "1987-12-08T09:28:21Z" + updated_at: "1985-05-18T17:19:50Z" + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + status: + state: available + updated_at: "2025-01-01T10:30:37Z" + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + updated_at: "2025-01-01T02:30:00Z" + post: + tags: + - control-plane + summary: update-database control-plane + description: Updates a database with the given specification. + operationId: control-plane#update-database + parameters: + - name: database_id + in: path + description: ID of the database to update. + required: true + schema: + type: string + description: ID of the database to update. + example: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + example: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateDatabaseRequest' + example: + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/Database' + example: + created_at: "2025-01-01T01:30:00Z" + id: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + instances: + created_at: "1983-06-23T19:00:09Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: false + patroni_state: running + pending_restart: false + postgres_version: "17.1" + read_only: false + role: replica + spock_version: 4.0.9 + state: available + updated_at: "1987-12-08T09:28:21Z" + updated_at: "1985-05-18T17:19:50Z" + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + status: + state: available + updated_at: "2025-01-01T10:30:37Z" + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + updated_at: "2025-01-01T02:30:00Z" + /hosts: + get: + tags: + - control-plane + summary: list-hosts control-plane + description: Lists all hosts within the cluster. + operationId: control-plane#list-hosts + responses: + "200": + description: OK response. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Host' + example: + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: false + vector_enabled: false + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: swarm + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: false + vector_enabled: false + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: swarm + example: + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: false + vector_enabled: false + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: swarm + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: false + vector_enabled: false + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: swarm + /hosts/{host_id}: + delete: + tags: + - control-plane + summary: remove-host control-plane + description: Removes a host from the cluster. + operationId: control-plane#remove-host + parameters: + - name: host_id + in: path + description: ID of the host to remove. + required: true + schema: + type: string + description: ID of the host to remove. + example: de3b1388-1f0c-42f1-a86c-59ab72f255ec + example: de3b1388-1f0c-42f1-a86c-59ab72f255ec + responses: + "204": + description: No Content response. + get: + tags: + - control-plane + summary: inspect-host control-plane + description: Returns information about a particular host in the cluster. + operationId: control-plane#inspect-host + parameters: + - name: host_id + in: path + description: ID of the host to inspect. + required: true + schema: + type: string + description: ID of the host to inspect. + example: de3b1388-1f0c-42f1-a86c-59ab72f255ec + example: de3b1388-1f0c-42f1-a86c-59ab72f255ec + responses: + "200": + description: OK response. + content: + application/json: + schema: + $ref: '#/components/schemas/Host' + example: + cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: true + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: swarm + /openapi.json: + get: + tags: + - control-plane + summary: Download ./gen/http/openapi.json + operationId: control-plane#/openapi.json + responses: + "200": + description: File downloaded +components: + schemas: + BackupConfigSpec: + type: object + properties: + id: + type: string + description: The unique identifier for this backup configuration. + example: default + node_names: + type: array + items: + type: string + example: Totam dolorem. + description: The names of the nodes where this backup configuration should be applied. The configuration will apply to all nodes when this field is empty or unspecified. + example: + - n1 + - n3 + provider: + type: string + description: The backup provider for this backup configuration. + example: pgbackrest + enum: + - pgbackrest + - pg_dump + repositories: + type: array + items: + $ref: '#/components/schemas/BackupRepositorySpec' + description: The repositories for this backup configuration. + example: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_region: us-east-1 + type: s3 + schedules: + type: array + items: + $ref: '#/components/schemas/BackupScheduleSpec' + description: The schedules for this backup configuration. + example: + - 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 + example: + id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + required: + - id + - provider + BackupRepositorySpec: + type: object + properties: + azure_account: + type: string + description: The Azure account name for this repository. Only applies when type = 'azure'. + example: pgedge-backups + 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 + azure_endpoint: + type: string + description: The optional Azure endpoint for this repository. Only applies when type = 'azure'. + example: blob.core.usgovcloudapi.net + base_path: + type: string + description: The base path within the repository to store backups. + example: /backups + 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 + gcs_endpoint: + type: string + description: The optional GCS endpoint for this repository. Only applies when type = 'gcs'. + example: localhost + id: + type: string + description: The unique identifier of this repository. + example: f6b84a99-5e91-4203-be1e-131fe82e5984 + retention_full: + type: integer + description: The count of full backups to retain or the time to retain full backups. + example: 2 + format: int64 + retention_full_type: + type: string + description: The type of measure used for retention_full. + example: count + enum: + - time + - count + 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 + s3_endpoint: + type: string + description: The optional S3 endpoint for this repository. Only applies when type = 's3'. + example: s3.us-east-1.amazonaws.com + s3_region: + type: string + description: The region of the S3 bucket for this repository. Only applies when type = 's3'. + example: us-east-1 + type: + type: string + description: The type of this repository. + example: s3 + enum: + - s3 + - gcs + - azure + example: + azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_region: us-east-1 + type: s3 + required: + - type + BackupScheduleSpec: + type: object + properties: + cron_expression: + type: string + description: The cron expression for this schedule. + example: 0 6 * * ? + id: + type: string + description: The unique identifier for this backup schedule. + example: daily-full-backup + type: + type: string + description: The type of backup to take on this schedule. + example: full + enum: + - full + - incr + example: + cron_expression: 0 6 * * ? + id: daily-full-backup + type: full + required: + - id + - type + - cron_expression + Cluster: + type: object + properties: + hosts: + type: array + items: + $ref: '#/components/schemas/Host' + description: All of the hosts in the cluster. + example: + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: false + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: swarm + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: false + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: swarm + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: false + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: swarm + id: + type: string + description: Unique identifier for the cluster. + example: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + status: + $ref: '#/components/schemas/ClusterStatus' + tenant_id: + type: string + description: Unique identifier for the cluster's owner. + example: 8210ec10-2dca-406c-ac4a-0661d2189954 + example: + hosts: + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: false + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: swarm + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: false + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: swarm + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: false + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: swarm + - cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: false + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: swarm + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + status: + state: available + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + required: + - id + - tenant_id + - status + - hosts + ClusterStatus: + type: object + properties: + state: + type: string + description: The current state of the cluster. + example: error + enum: + - available + - error + example: + state: available + required: + - state + CreateDatabaseRequest: + type: object + properties: + id: + type: string + description: Unique identifier for the database. + example: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + spec: + $ref: '#/components/schemas/DatabaseSpec' + tenant_id: + type: string + description: Unique identifier for the databases's owner. + example: 8210ec10-2dca-406c-ac4a-0661d2189954 + example: + id: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + Database: + type: object + properties: + created_at: + type: string + description: The time that the database was created. + example: "2025-01-01T01:30:00Z" + format: date-time + id: + type: string + description: Unique identifier for the database. + example: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + instances: + $ref: '#/components/schemas/Instance' + spec: + $ref: '#/components/schemas/DatabaseSpec' + status: + $ref: '#/components/schemas/DatabaseStatus' + tenant_id: + type: string + description: Unique identifier for the databases's owner. + example: 8210ec10-2dca-406c-ac4a-0661d2189954 + updated_at: + type: string + description: The time that the database was last updated. + example: "2025-01-01T02:30:00Z" + format: date-time + example: + created_at: "2025-01-01T01:30:00Z" + id: 02f1a7db-fca8-4521-b57a-2a375c1ced51 + instances: + created_at: "1975-03-20T03:08:32Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: true + patroni_state: unknown + pending_restart: false + postgres_version: "17.1" + read_only: true + role: primary + spock_version: 4.0.9 + state: backing_up + updated_at: "2000-08-17T12:59:00Z" + updated_at: "1972-05-07T22:20:35Z" + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + status: + state: error + updated_at: "2025-01-01T10:30:37Z" + tenant_id: 8210ec10-2dca-406c-ac4a-0661d2189954 + updated_at: "2025-01-01T02:30:00Z" + required: + - id + - status + - instances + DatabaseExtensionSpec: + type: object + properties: + name: + type: string + description: The name of the extension to install in this database. + example: postgis + version: + type: string + description: The version of the extension to install in this database. + example: 1.2.3 + example: + name: postgis + version: 1.2.3 + required: + - name + DatabaseNodeSpec: + type: object + properties: + host_id: + type: string + description: The ID of the host that should run this node. + example: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: + type: string + description: A unique identifier for the instance that will be created from this node specification. + example: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: + type: string + description: The name of the database node. + example: n1 + port: + type: integer + description: The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec. + example: 5432 + format: int64 + postgres_version: + type: string + description: The major version of Postgres for this node. Overrides the Postgres version set in the DatabaseSpec. + example: "17" + enum: + - "16" + - "17" + postgresql_conf: + type: object + description: Additional postgresql.conf settings for this particular node. Will be merged with the settings provided by control-plane. + example: + max_connections: 1000 + additionalProperties: true + read_replicas: + $ref: '#/components/schemas/DatabaseReplicaSpec' + example: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + required: + - name + - instance_id + - host_id + DatabaseReplicaSpec: + type: object + properties: + host_id: + type: string + description: The ID of the host that should run this read replica. + example: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: + type: string + description: A unique identifier for the instance that will be created from this replica specification. + example: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + example: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + required: + - instance_id + - host_id + DatabaseSpec: + type: object + properties: + backup_configs: + type: array + items: + $ref: '#/components/schemas/BackupConfigSpec' + description: The backup configurations for this database. + example: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: + type: string + description: The name of the Postgres database. + example: northwind + database_users: + type: array + items: + $ref: '#/components/schemas/DatabaseUserSpec' + description: The users to create for this database. + example: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: + type: boolean + description: Prevents deletion when true. + example: true + extensions: + type: array + items: + $ref: '#/components/schemas/DatabaseExtensionSpec' + description: The extensions to install for this database. + example: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + type: object + description: The feature flags for this database. + example: + some_feature: enabled + additionalProperties: + type: string + example: Nihil facere ad tenetur iure quisquam. + nodes: + type: array + items: + $ref: '#/components/schemas/DatabaseNodeSpec' + description: The Spock nodes for this database. + example: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: + type: integer + description: The port used by the Postgres database. + example: 5432 + format: int64 + postgres_version: + type: string + description: The major version of the Postgres database. + example: "17" + enum: + - "16" + - "17" + postgresql_conf: + type: object + description: Additional postgresql.conf settings. Will be merged with the settings provided by control-plane. + example: + max_connections: 1000 + additionalProperties: true + spock_version: + type: string + description: The major version of the Spock extension. + example: "4" + enum: + - "4" + example: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" + required: + - database_name + - nodes + DatabaseStatus: + type: object + properties: + state: + type: string + example: available + enum: + - creating + - modifying + - available + - error + updated_at: + type: string + description: The time that the database status was last updated. + example: "2025-01-01T10:30:37Z" + format: date-time + example: + state: modifying + updated_at: "2025-01-01T10:30:37Z" + DatabaseUserSpec: + type: object + properties: + password: + type: string + description: The password for this database user. + example: secret + roles: + type: array + items: + type: string + example: Voluptatum nulla commodi quo aut facere. + description: The roles to assign to this database user. + example: + - application_read_only + superuser: + type: boolean + description: Enables SUPERUSER for this database user when true. + example: true + username: + type: string + description: The username for this database user. + example: admin + example: + password: secret + roles: + - application_read_only + superuser: true + username: admin + required: + - username + - password + Host: + type: object + properties: + cohort: + type: string + description: The cohort that this host belongs to + example: pps1n11hqijn9rbee4cjil453 + config: + $ref: '#/components/schemas/HostConfiguration' + hostname: + type: string + description: The hostname of this host. + example: i-0123456789abcdef.ec2.internal + id: + type: string + description: Unique identifier for the host + example: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: + type: string + description: The IPv4 address of this host. + example: 10.24.34.0 + format: ipv4 + status: + $ref: '#/components/schemas/HostStatus' + type: + type: string + description: The type of this host + example: swarm + enum: + - swarm + - systemd + example: + cohort: pps1n11hqijn9rbee4cjil453 + config: + traefik_enabled: true + vector_enabled: false + hostname: i-0123456789abcdef.ec2.internal + id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + ipv4_address: 10.24.34.0 + status: + state: available + type: systemd + required: + - id + - status + - hostname + - ipv4_address + HostConfiguration: + type: object + properties: + traefik_enabled: + type: boolean + description: Enables the Treafik load balancer + example: false + vector_enabled: + type: boolean + description: Enables the Vector service for metrics and log collection + example: false + example: + traefik_enabled: true + vector_enabled: false + HostStatus: + type: object + properties: + state: + type: string + example: available + enum: + - available + - unreachable + - error + example: + state: available + required: + - state + Instance: + type: object + properties: + created_at: + type: string + description: The time that the instance was created. + example: "1975-11-29T11:29:36Z" + format: date-time + host_id: + type: string + description: The ID of the host this instance is running on. + example: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: + type: string + description: Unique identifier for the instance. + example: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + type: array + items: + $ref: '#/components/schemas/InstanceInterface' + description: All interfaces that this instance serves on. + example: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: + type: string + description: The Spock node name for this instance. + example: n1 + status: + $ref: '#/components/schemas/InstanceStatus' + updated_at: + type: string + description: The time that the instance was last updated. + example: "1975-10-27T03:55:24Z" + format: date-time + example: + created_at: "1972-05-03T15:38:49Z" + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + interfaces: + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + - hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + node_name: n1 + status: + patroni_paused: true + patroni_state: unknown + pending_restart: false + postgres_version: "17.1" + read_only: true + role: primary + spock_version: 4.0.9 + state: backing_up + updated_at: "2000-08-17T12:59:00Z" + updated_at: "1982-12-11T10:43:34Z" + required: + - id + - status + InstanceInterface: + type: object + properties: + hostname: + type: string + description: The hostname of the instance on this interface. + example: postgres-n1 + ipv4_address: + type: string + description: The IPv4 address of the instance on this interface. + example: 10.1.0.113 + format: ipv4 + network_id: + type: string + description: The unique identifier of the network for this interface. + example: l5imrq28sh6s + network_type: + type: string + description: The type of network for this interface. + example: docker + enum: + - docker + - host + port: + type: integer + description: The Postgres port for the instance on this interface. + example: 5432 + format: int64 + example: + hostname: postgres-n1 + ipv4_address: 10.1.0.113 + network_id: l5imrq28sh6s + network_type: docker + port: 5432 + InstanceStatus: + type: object + properties: + patroni_paused: + type: boolean + description: True if Patroni has been paused for this instance. + example: true + patroni_state: + type: string + example: crashed + enum: + - stopping + - stopped + - stop failed + - crashed + - running + - starting + - start failed + - restarting + - restart failed + - initializing new cluster + - initdb failed + - running custom bootstrap script + - custom bootstrap failed + - creating replica + - unknown + pending_restart: + type: boolean + description: True if this instance is pending to be restarted from a configuration change. + example: false + postgres_version: + type: string + description: The version of Postgres for this instance. + example: "17.1" + read_only: + type: boolean + description: True if this instance is in read-only mode. + example: false + role: + type: string + example: replica + enum: + - replica + - primary + spock_version: + type: string + description: The version of Spock for this instance. + example: 4.0.9 + state: + type: string + example: error + enum: + - creating + - modifying + - backing_up + - available + - error + updated_at: + type: string + description: The time that the instance status was last updated. + example: "2000-09-09T15:06:57Z" + format: date-time + example: + patroni_paused: false + patroni_state: stopping + pending_restart: false + postgres_version: "17.1" + read_only: false + role: replica + spock_version: 4.0.9 + state: creating + updated_at: "1997-12-31T00:50:06Z" + required: + - state + RestoreConfigSpec: + type: object + properties: + node_name: + type: string + description: The name of the node to restore this database from. + example: n1 + provider: + type: string + description: The backup provider for this restore configuration. + example: pgbackrest + enum: + - pgbackrest + - pg_dump + repository: + $ref: '#/components/schemas/RestoreRepositorySpec' + example: + node_name: n1 + provider: pgbackrest + repository: + azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + id: f6b84a99-5e91-4203-be1e-131fe82e5984 + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_region: us-east-1 + type: s3 + required: + - provider + - node_name + - repository + RestoreRepositorySpec: + type: object + properties: + azure_account: + type: string + description: The Azure account name for this repository. Only applies when type = 'azure'. + example: pgedge-backups + 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 + azure_endpoint: + type: string + description: The optional Azure endpoint for this repository. Only applies when type = 'azure'. + example: blob.core.usgovcloudapi.net + base_path: + type: string + description: The base path within the repository where backups are stored. + example: /backups + 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 + gcs_endpoint: + type: string + description: The optional GCS endpoint for this repository. Only applies when type = 'gcs'. + example: localhost + id: + type: string + description: The unique identifier of this repository. + example: f6b84a99-5e91-4203-be1e-131fe82e5984 + 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 + s3_endpoint: + type: string + description: The optional S3 endpoint for this repository. Only applies when type = 's3'. + example: s3.us-east-1.amazonaws.com + s3_region: + type: string + description: The region of the S3 bucket for this repository. Only applies when type = 's3'. + example: us-east-1 + type: + type: string + description: The type of this repository. + example: s3 + enum: + - s3 + - gcs + - azure + example: + azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + id: f6b84a99-5e91-4203-be1e-131fe82e5984 + s3_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + s3_endpoint: s3.us-east-1.amazonaws.com + s3_region: us-east-1 + type: s3 + required: + - id + - type + UpdateDatabaseRequest: + type: object + properties: + spec: + $ref: '#/components/schemas/DatabaseSpec' + example: + spec: + backup_configs: + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + - id: default + node_names: + - n1 + - n3 + provider: pgbackrest + repositories: + - azure_account: pgedge-backups + azure_container: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + azure_endpoint: blob.core.usgovcloudapi.net + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + base_path: /backups + gcs_bucket: pgedge-backups-9f81786f-373b-4ff2-afee-e054a06a96f1 + gcs_endpoint: localhost + 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_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 + database_name: northwind + database_users: + - password: secret + roles: + - application_read_only + superuser: true + username: admin + - password: secret + roles: + - application_read_only + superuser: true + username: admin + deletion_protection: true + extensions: + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + - name: postgis + version: 1.2.3 + features: + some_feature: enabled + nodes: + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + - host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: a67cbb36-c3c3-49c9-8aac-f4a0438a883d + name: n1 + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + read_replicas: + host_id: de3b1388-1f0c-42f1-a86c-59ab72f255ec + instance_id: 5ec51c55-0921-445e-9d5b-32f5fb5dfbae + port: 5432 + postgres_version: "17" + postgresql_conf: + max_connections: 1000 + spock_version: "4" +tags: + - name: control-plane diff --git a/api/go.mod b/api/go.mod new file mode 100644 index 00000000..ffd03497 --- /dev/null +++ b/api/go.mod @@ -0,0 +1,21 @@ +module github.com/pgEdge/control-plane/api + +go 1.23.1 + +require goa.design/goa/v3 v3.19.1 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 // indirect + github.com/go-chi/chi/v5 v5.1.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.9.0 // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/text v0.18.0 // indirect + golang.org/x/tools v0.25.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/api/go.sum b/api/go.sum new file mode 100644 index 00000000..50bc10de --- /dev/null +++ b/api/go.sum @@ -0,0 +1,32 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 h1:MGKhKyiYrvMDZsmLR/+RGffQSXwEkXgfLSA08qDn9AI= +github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598/go.mod h1:0FpDmbrt36utu8jEmeU05dPC9AB5tsLYVVi+ZHfyuwI= +github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= +github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d h1:Zj+PHjnhRYWBK6RqCDBcAhLXoi3TzC27Zad/Vn+gnVQ= +github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d/go.mod h1:WZy8Q5coAB1zhY9AOBJP0O6J4BuDfbupUDavKY+I3+s= +github.com/manveru/gobdd v0.0.0-20131210092515-f1a17fdd710b h1:3E44bLeN8uKYdfQqVQycPnaVviZdBLbizFhU49mtbe4= +github.com/manveru/gobdd v0.0.0-20131210092515-f1a17fdd710b/go.mod h1:Bj8LjjP0ReT1eKt5QlKjwgi5AFm5mI6O1A2G4ChI0Ag= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +goa.design/goa/v3 v3.19.1 h1:jpV3LEy7YANzPMwm++Lu17RoThRJgXrPxdEM0A1nlOE= +goa.design/goa/v3 v3.19.1/go.mod h1:astNE9ube0YCxqq7DQkt1MtLxB/b3kRPEFkEZovcO2I= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go.work b/go.work index 9ea7356a..daa333e6 100644 --- a/go.work +++ b/go.work @@ -1,6 +1,7 @@ go 1.23.1 use ( + ./api ./mqtt ./server ) diff --git a/go.work.sum b/go.work.sum index 4d9dfd41..a14c67de 100644 --- a/go.work.sum +++ b/go.work.sum @@ -513,6 +513,7 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= +github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/go-critic/go-critic v0.9.0 h1:Pmys9qvU3pSML/3GEQ2Xd9RZ/ip+aXHKILuxczKGV/U= github.com/go-critic/go-critic v0.9.0/go.mod h1:5P8tdXL7m/6qnyG6oRAlYLORvoXH0WDypYgAEmagT40= @@ -524,6 +525,8 @@ github.com/go-kit/log v0.1.0 h1:DGJh0Sm43HbOeYDNnVZFl8BvcYVvjD5bqYJvp0REbwQ= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= @@ -622,12 +625,14 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68U github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/intel/goresctrl v0.3.0/go.mod h1:fdz3mD85cmP9sHD8JUlrNWAxvwM86CrbmVXltEKd7zk= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report/v2 v2.0.0-beta1 h1:UyfToJkXjdv0R6jr+8qL8R6O/xVoyTN9WiPqVGEjVs0= @@ -664,6 +669,7 @@ github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xq github.com/lyft/protoc-gen-star/v2 v2.0.4-0.20230330145011-496ad1ac90a4/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= @@ -694,6 +700,7 @@ github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0Gq github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/moricho/tparallel v0.3.1 h1:fQKD4U1wRMAYNngDonW5XupoB/ZGJHdpzrWqgyg9krA= github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= @@ -715,6 +722,7 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= @@ -872,6 +880,7 @@ golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -885,7 +894,9 @@ golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= @@ -898,6 +909,7 @@ golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= @@ -925,6 +937,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240205150955-31a09d347014/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240304161311-37d4d3c04a78/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs= google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= diff --git a/tools.mk b/tools.mk index 43f2f238..0d5bec89 100644 --- a/tools.mk +++ b/tools.mk @@ -3,8 +3,11 @@ gobin=$(or $(shell go env GOBIN),$(shell go env GOPATH)/bin) gotestsum=$(gobin)/gotestsum golangcilint=$(gobin)/golangci-lint +goa=$(gobin)/goa .PHONY: install-tools install-tools: go install gotest.tools/gotestsum@v1.12.0 go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.2 + go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.35.2 + go install goa.design/goa/v3/cmd/goa@v3.19.1