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