From 522c4731899430b5daa1c786d1953ff07f634f65 Mon Sep 17 00:00:00 2001 From: Jason Lynch Date: Wed, 25 Feb 2026 09:42:23 -0500 Subject: [PATCH] feat: add patroni_port field to database api Adds the ability to set the Patroni port via the database spec. It will be necessary to explicitly set the Patroni port for SystemD instances until we add a port allocation mechanism PLAT-417 --- api/apiv1/design/database.go | 14 ++ api/apiv1/gen/control_plane/service.go | 7 + .../control_plane/client/encode_decode.go | 10 ++ .../gen/http/control_plane/client/types.go | 61 +++++++ .../control_plane/server/encode_decode.go | 6 + .../gen/http/control_plane/server/types.go | 61 +++++++ api/apiv1/gen/http/openapi.json | 23 +++ api/apiv1/gen/http/openapi.yaml | 21 +++ api/apiv1/gen/http/openapi3.json | 157 ++++++++++++++++++ api/apiv1/gen/http/openapi3.yaml | 143 ++++++++++++++++ changes/unreleased/Added-20260225-091421.yaml | 3 + server/internal/api/apiv1/convert.go | 4 + server/internal/api/apiv1/validate.go | 15 ++ server/internal/api/apiv1/validate_test.go | 72 +++++++- server/internal/database/spec.go | 7 + 15 files changed, 601 insertions(+), 3 deletions(-) create mode 100644 changes/unreleased/Added-20260225-091421.yaml diff --git a/api/apiv1/design/database.go b/api/apiv1/design/database.go index 61fe8bad..c0248dae 100644 --- a/api/apiv1/design/database.go +++ b/api/apiv1/design/database.go @@ -43,6 +43,13 @@ var DatabaseNodeSpec = g.Type("DatabaseNodeSpec", func() { g.Example(5432) g.Meta("struct:tag:json", "port,omitempty") }) + g.Attribute("patroni_port", g.Int, func() { + g.Description("The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.") + g.Minimum(0) + g.Maximum(65535) + g.Example(8888) + g.Meta("struct:tag:json", "patroni_port,omitempty") + }) g.Attribute("cpus", g.String, func() { g.Description("The number of CPUs to allocate for the database on this node and to use for tuning Postgres. It can include the SI suffix 'm', e.g. '500m' for 500 millicpus. Cannot allocate units smaller than 1m. Defaults to the number of available CPUs on the host if 0 or unspecified. Cannot allocate more CPUs than are available on the host. Whether this limit is enforced depends on the orchestrator.") g.Pattern(cpuPattern) @@ -540,6 +547,13 @@ var DatabaseSpec = g.Type("DatabaseSpec", func() { g.Example(5432) g.Meta("struct:tag:json", "port,omitempty") }) + g.Attribute("patroni_port", g.Int, func() { + g.Description("The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.") + g.Minimum(0) + g.Maximum(65535) + g.Example(8888) + g.Meta("struct:tag:json", "patroni_port,omitempty") + }) g.Attribute("cpus", g.String, func() { g.Description("The number of CPUs to allocate for the database and to use for tuning Postgres. Defaults to the number of available CPUs on the host. Can include an SI suffix, e.g. '500m' for 500 millicpus. Whether this limit is enforced depends on the orchestrator.") g.Pattern(cpuPattern) diff --git a/api/apiv1/gen/control_plane/service.go b/api/apiv1/gen/control_plane/service.go index 8b578c11..52a0bff7 100644 --- a/api/apiv1/gen/control_plane/service.go +++ b/api/apiv1/gen/control_plane/service.go @@ -335,6 +335,10 @@ type DatabaseNodeSpec struct { // The port used by the Postgres database for this node. Overrides the Postgres // port set in the DatabaseSpec. Port *int `json:"port,omitempty"` + // The port used by Patroni for this node. Overrides the Patroni port set in + // the DatabaseSpec. NOTE: This field is not currently supported for Docker + // Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database on this node and to use for // tuning Postgres. It can include the SI suffix 'm', e.g. '500m' for 500 // millicpus. Cannot allocate units smaller than 1m. Defaults to the number of @@ -374,6 +378,9 @@ type DatabaseSpec struct { // be assigned a random port. If the port is unspecified, the database will not // be exposed on any port, dependent on orchestrator support for that feature. Port *int `json:"port,omitempty"` + // The port used by Patroni for this database. NOTE: This field is not + // currently supported for Docker Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database and to use for tuning // Postgres. Defaults to the number of available CPUs on the host. Can include // an SI suffix, e.g. '500m' for 500 millicpus. Whether this limit is enforced diff --git a/api/apiv1/gen/http/control_plane/client/encode_decode.go b/api/apiv1/gen/http/control_plane/client/encode_decode.go index 1cbeba72..a2bb8e7e 100644 --- a/api/apiv1/gen/http/control_plane/client/encode_decode.go +++ b/api/apiv1/gen/http/control_plane/client/encode_decode.go @@ -4313,6 +4313,7 @@ func marshalControlplaneDatabaseSpecToDatabaseSpecRequestBody(v *controlplane.Da PostgresVersion: v.PostgresVersion, SpockVersion: v.SpockVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, } @@ -4377,6 +4378,7 @@ func marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecRequestBody(v *control Name: v.Name, PostgresVersion: v.PostgresVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, SourceNode: v.SourceNode, @@ -4732,6 +4734,7 @@ func marshalDatabaseSpecRequestBodyToControlplaneDatabaseSpec(v *DatabaseSpecReq PostgresVersion: v.PostgresVersion, SpockVersion: v.SpockVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, } @@ -4796,6 +4799,7 @@ func marshalDatabaseNodeSpecRequestBodyToControlplaneDatabaseNodeSpec(v *Databas Name: v.Name, PostgresVersion: v.PostgresVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, SourceNode: v.SourceNode, @@ -5281,6 +5285,7 @@ func unmarshalDatabaseSpecResponseBodyToControlplaneDatabaseSpec(v *DatabaseSpec PostgresVersion: v.PostgresVersion, SpockVersion: v.SpockVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, } @@ -5341,6 +5346,7 @@ func unmarshalDatabaseNodeSpecResponseBodyToControlplaneDatabaseNodeSpec(v *Data Name: *v.Name, PostgresVersion: v.PostgresVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, SourceNode: v.SourceNode, @@ -5680,6 +5686,7 @@ func marshalControlplaneDatabaseSpecToDatabaseSpecRequestBodyRequestBody(v *cont PostgresVersion: v.PostgresVersion, SpockVersion: v.SpockVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, } @@ -5744,6 +5751,7 @@ func marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecRequestBodyRequestBody Name: v.Name, PostgresVersion: v.PostgresVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, SourceNode: v.SourceNode, @@ -6101,6 +6109,7 @@ func marshalDatabaseSpecRequestBodyRequestBodyToControlplaneDatabaseSpec(v *Data PostgresVersion: v.PostgresVersion, SpockVersion: v.SpockVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, } @@ -6165,6 +6174,7 @@ func marshalDatabaseNodeSpecRequestBodyRequestBodyToControlplaneDatabaseNodeSpec Name: v.Name, PostgresVersion: v.PostgresVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, SourceNode: v.SourceNode, diff --git a/api/apiv1/gen/http/control_plane/client/types.go b/api/apiv1/gen/http/control_plane/client/types.go index 1c8d745c..71a2252d 100644 --- a/api/apiv1/gen/http/control_plane/client/types.go +++ b/api/apiv1/gen/http/control_plane/client/types.go @@ -1818,6 +1818,9 @@ type DatabaseSpecRequestBody struct { // be assigned a random port. If the port is unspecified, the database will not // be exposed on any port, dependent on orchestrator support for that feature. Port *int `json:"port,omitempty"` + // The port used by Patroni for this database. NOTE: This field is not + // currently supported for Docker Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database and to use for tuning // Postgres. Defaults to the number of available CPUs on the host. Can include // an SI suffix, e.g. '500m' for 500 millicpus. Whether this limit is enforced @@ -1858,6 +1861,10 @@ type DatabaseNodeSpecRequestBody struct { // The port used by the Postgres database for this node. Overrides the Postgres // port set in the DatabaseSpec. Port *int `json:"port,omitempty"` + // The port used by Patroni for this node. Overrides the Patroni port set in + // the DatabaseSpec. NOTE: This field is not currently supported for Docker + // Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database on this node and to use for // tuning Postgres. It can include the SI suffix 'm', e.g. '500m' for 500 // millicpus. Cannot allocate units smaller than 1m. Defaults to the number of @@ -2199,6 +2206,9 @@ type DatabaseSpecResponseBody struct { // be assigned a random port. If the port is unspecified, the database will not // be exposed on any port, dependent on orchestrator support for that feature. Port *int `json:"port,omitempty"` + // The port used by Patroni for this database. NOTE: This field is not + // currently supported for Docker Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database and to use for tuning // Postgres. Defaults to the number of available CPUs on the host. Can include // an SI suffix, e.g. '500m' for 500 millicpus. Whether this limit is enforced @@ -2239,6 +2249,10 @@ type DatabaseNodeSpecResponseBody struct { // The port used by the Postgres database for this node. Overrides the Postgres // port set in the DatabaseSpec. Port *int `json:"port,omitempty"` + // The port used by Patroni for this node. Overrides the Patroni port set in + // the DatabaseSpec. NOTE: This field is not currently supported for Docker + // Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database on this node and to use for // tuning Postgres. It can include the SI suffix 'm', e.g. '500m' for 500 // millicpus. Cannot allocate units smaller than 1m. Defaults to the number of @@ -2499,6 +2513,9 @@ type DatabaseSpecRequestBodyRequestBody struct { // be assigned a random port. If the port is unspecified, the database will not // be exposed on any port, dependent on orchestrator support for that feature. Port *int `json:"port,omitempty"` + // The port used by Patroni for this database. NOTE: This field is not + // currently supported for Docker Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database and to use for tuning // Postgres. Defaults to the number of available CPUs on the host. Can include // an SI suffix, e.g. '500m' for 500 millicpus. Whether this limit is enforced @@ -2540,6 +2557,10 @@ type DatabaseNodeSpecRequestBodyRequestBody struct { // The port used by the Postgres database for this node. Overrides the Postgres // port set in the DatabaseSpec. Port *int `json:"port,omitempty"` + // The port used by Patroni for this node. Overrides the Patroni port set in + // the DatabaseSpec. NOTE: This field is not currently supported for Docker + // Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database on this node and to use for // tuning Postgres. It can include the SI suffix 'm', e.g. '500m' for 500 // millicpus. Cannot allocate units smaller than 1m. Defaults to the number of @@ -5612,6 +5633,16 @@ func ValidateDatabaseSpecRequestBody(body *DatabaseSpecRequestBody) (err error) err = goa.MergeErrors(err, goa.InvalidRangeError("body.port", *body.Port, 65535, false)) } } + if body.PatroniPort != nil { + if *body.PatroniPort < 0 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 0, true)) + } + } + if body.PatroniPort != nil { + if *body.PatroniPort > 65535 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 65535, false)) + } + } if body.Cpus != nil { err = goa.MergeErrors(err, goa.ValidatePattern("body.cpus", *body.Cpus, "^[0-9]+(\\.[0-9]{1,3}|m)?$")) } @@ -5702,6 +5733,16 @@ func ValidateDatabaseNodeSpecRequestBody(body *DatabaseNodeSpecRequestBody) (err err = goa.MergeErrors(err, goa.InvalidRangeError("body.port", *body.Port, 65535, false)) } } + if body.PatroniPort != nil { + if *body.PatroniPort < 0 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 0, true)) + } + } + if body.PatroniPort != nil { + if *body.PatroniPort > 65535 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 65535, false)) + } + } if body.Cpus != nil { err = goa.MergeErrors(err, goa.ValidatePattern("body.cpus", *body.Cpus, "^[0-9]+(\\.[0-9]{1,3}|m)?$")) } @@ -6334,6 +6375,16 @@ func ValidateDatabaseSpecRequestBodyRequestBody(body *DatabaseSpecRequestBodyReq err = goa.MergeErrors(err, goa.InvalidRangeError("body.port", *body.Port, 65535, false)) } } + if body.PatroniPort != nil { + if *body.PatroniPort < 0 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 0, true)) + } + } + if body.PatroniPort != nil { + if *body.PatroniPort > 65535 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 65535, false)) + } + } if body.Cpus != nil { err = goa.MergeErrors(err, goa.ValidatePattern("body.cpus", *body.Cpus, "^[0-9]+(\\.[0-9]{1,3}|m)?$")) } @@ -6424,6 +6475,16 @@ func ValidateDatabaseNodeSpecRequestBodyRequestBody(body *DatabaseNodeSpecReques err = goa.MergeErrors(err, goa.InvalidRangeError("body.port", *body.Port, 65535, false)) } } + if body.PatroniPort != nil { + if *body.PatroniPort < 0 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 0, true)) + } + } + if body.PatroniPort != nil { + if *body.PatroniPort > 65535 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 65535, false)) + } + } if body.Cpus != nil { err = goa.MergeErrors(err, goa.ValidatePattern("body.cpus", *body.Cpus, "^[0-9]+(\\.[0-9]{1,3}|m)?$")) } diff --git a/api/apiv1/gen/http/control_plane/server/encode_decode.go b/api/apiv1/gen/http/control_plane/server/encode_decode.go index dc50c0d8..8271d0d4 100644 --- a/api/apiv1/gen/http/control_plane/server/encode_decode.go +++ b/api/apiv1/gen/http/control_plane/server/encode_decode.go @@ -3686,6 +3686,7 @@ func unmarshalDatabaseSpecRequestBodyToControlplaneDatabaseSpec(v *DatabaseSpecR PostgresVersion: v.PostgresVersion, SpockVersion: v.SpockVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, } @@ -3746,6 +3747,7 @@ func unmarshalDatabaseNodeSpecRequestBodyToControlplaneDatabaseNodeSpec(v *Datab Name: *v.Name, PostgresVersion: v.PostgresVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, SourceNode: v.SourceNode, @@ -4215,6 +4217,7 @@ func marshalControlplaneDatabaseSpecToDatabaseSpecResponseBody(v *controlplane.D PostgresVersion: v.PostgresVersion, SpockVersion: v.SpockVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, } @@ -4279,6 +4282,7 @@ func marshalControlplaneDatabaseNodeSpecToDatabaseNodeSpecResponseBody(v *contro Name: v.Name, PostgresVersion: v.PostgresVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, SourceNode: v.SourceNode, @@ -4634,6 +4638,7 @@ func unmarshalDatabaseSpecRequestBodyRequestBodyToControlplaneDatabaseSpec(v *Da PostgresVersion: v.PostgresVersion, SpockVersion: v.SpockVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, } @@ -4694,6 +4699,7 @@ func unmarshalDatabaseNodeSpecRequestBodyRequestBodyToControlplaneDatabaseNodeSp Name: *v.Name, PostgresVersion: v.PostgresVersion, Port: v.Port, + PatroniPort: v.PatroniPort, Cpus: v.Cpus, Memory: v.Memory, SourceNode: v.SourceNode, diff --git a/api/apiv1/gen/http/control_plane/server/types.go b/api/apiv1/gen/http/control_plane/server/types.go index 9b97c0db..ed567c09 100644 --- a/api/apiv1/gen/http/control_plane/server/types.go +++ b/api/apiv1/gen/http/control_plane/server/types.go @@ -1902,6 +1902,9 @@ type DatabaseSpecResponseBody struct { // be assigned a random port. If the port is unspecified, the database will not // be exposed on any port, dependent on orchestrator support for that feature. Port *int `json:"port,omitempty"` + // The port used by Patroni for this database. NOTE: This field is not + // currently supported for Docker Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database and to use for tuning // Postgres. Defaults to the number of available CPUs on the host. Can include // an SI suffix, e.g. '500m' for 500 millicpus. Whether this limit is enforced @@ -1942,6 +1945,10 @@ type DatabaseNodeSpecResponseBody struct { // The port used by the Postgres database for this node. Overrides the Postgres // port set in the DatabaseSpec. Port *int `json:"port,omitempty"` + // The port used by Patroni for this node. Overrides the Patroni port set in + // the DatabaseSpec. NOTE: This field is not currently supported for Docker + // Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database on this node and to use for // tuning Postgres. It can include the SI suffix 'm', e.g. '500m' for 500 // millicpus. Cannot allocate units smaller than 1m. Defaults to the number of @@ -2211,6 +2218,9 @@ type DatabaseSpecRequestBody struct { // be assigned a random port. If the port is unspecified, the database will not // be exposed on any port, dependent on orchestrator support for that feature. Port *int `json:"port,omitempty"` + // The port used by Patroni for this database. NOTE: This field is not + // currently supported for Docker Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database and to use for tuning // Postgres. Defaults to the number of available CPUs on the host. Can include // an SI suffix, e.g. '500m' for 500 millicpus. Whether this limit is enforced @@ -2251,6 +2261,10 @@ type DatabaseNodeSpecRequestBody struct { // The port used by the Postgres database for this node. Overrides the Postgres // port set in the DatabaseSpec. Port *int `json:"port,omitempty"` + // The port used by Patroni for this node. Overrides the Patroni port set in + // the DatabaseSpec. NOTE: This field is not currently supported for Docker + // Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database on this node and to use for // tuning Postgres. It can include the SI suffix 'm', e.g. '500m' for 500 // millicpus. Cannot allocate units smaller than 1m. Defaults to the number of @@ -2509,6 +2523,9 @@ type DatabaseSpecRequestBodyRequestBody struct { // be assigned a random port. If the port is unspecified, the database will not // be exposed on any port, dependent on orchestrator support for that feature. Port *int `json:"port,omitempty"` + // The port used by Patroni for this database. NOTE: This field is not + // currently supported for Docker Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database and to use for tuning // Postgres. Defaults to the number of available CPUs on the host. Can include // an SI suffix, e.g. '500m' for 500 millicpus. Whether this limit is enforced @@ -2550,6 +2567,10 @@ type DatabaseNodeSpecRequestBodyRequestBody struct { // The port used by the Postgres database for this node. Overrides the Postgres // port set in the DatabaseSpec. Port *int `json:"port,omitempty"` + // The port used by Patroni for this node. Overrides the Patroni port set in + // the DatabaseSpec. NOTE: This field is not currently supported for Docker + // Swarm. + PatroniPort *int `json:"patroni_port,omitempty"` // The number of CPUs to allocate for the database on this node and to use for // tuning Postgres. It can include the SI suffix 'm', e.g. '500m' for 500 // millicpus. Cannot allocate units smaller than 1m. Defaults to the number of @@ -5036,6 +5057,16 @@ func ValidateDatabaseSpecRequestBody(body *DatabaseSpecRequestBody) (err error) err = goa.MergeErrors(err, goa.InvalidRangeError("body.port", *body.Port, 65535, false)) } } + if body.PatroniPort != nil { + if *body.PatroniPort < 0 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 0, true)) + } + } + if body.PatroniPort != nil { + if *body.PatroniPort > 65535 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 65535, false)) + } + } if body.Cpus != nil { err = goa.MergeErrors(err, goa.ValidatePattern("body.cpus", *body.Cpus, "^[0-9]+(\\.[0-9]{1,3}|m)?$")) } @@ -5131,6 +5162,16 @@ func ValidateDatabaseNodeSpecRequestBody(body *DatabaseNodeSpecRequestBody) (err err = goa.MergeErrors(err, goa.InvalidRangeError("body.port", *body.Port, 65535, false)) } } + if body.PatroniPort != nil { + if *body.PatroniPort < 0 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 0, true)) + } + } + if body.PatroniPort != nil { + if *body.PatroniPort > 65535 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 65535, false)) + } + } if body.Cpus != nil { err = goa.MergeErrors(err, goa.ValidatePattern("body.cpus", *body.Cpus, "^[0-9]+(\\.[0-9]{1,3}|m)?$")) } @@ -5742,6 +5783,16 @@ func ValidateDatabaseSpecRequestBodyRequestBody(body *DatabaseSpecRequestBodyReq err = goa.MergeErrors(err, goa.InvalidRangeError("body.port", *body.Port, 65535, false)) } } + if body.PatroniPort != nil { + if *body.PatroniPort < 0 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 0, true)) + } + } + if body.PatroniPort != nil { + if *body.PatroniPort > 65535 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 65535, false)) + } + } if body.Cpus != nil { err = goa.MergeErrors(err, goa.ValidatePattern("body.cpus", *body.Cpus, "^[0-9]+(\\.[0-9]{1,3}|m)?$")) } @@ -5837,6 +5888,16 @@ func ValidateDatabaseNodeSpecRequestBodyRequestBody(body *DatabaseNodeSpecReques err = goa.MergeErrors(err, goa.InvalidRangeError("body.port", *body.Port, 65535, false)) } } + if body.PatroniPort != nil { + if *body.PatroniPort < 0 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 0, true)) + } + } + if body.PatroniPort != nil { + if *body.PatroniPort > 65535 { + err = goa.MergeErrors(err, goa.InvalidRangeError("body.patroni_port", *body.PatroniPort, 65535, false)) + } + } if body.Cpus != nil { err = goa.MergeErrors(err, goa.ValidatePattern("body.cpus", *body.Cpus, "^[0-9]+(\\.[0-9]{1,3}|m)?$")) } diff --git a/api/apiv1/gen/http/openapi.json b/api/apiv1/gen/http/openapi.json index 5e1f9c79..f72c29a6 100644 --- a/api/apiv1/gen/http/openapi.json +++ b/api/apiv1/gen/http/openapi.json @@ -3863,6 +3863,14 @@ "orchestrator_opts": { "$ref": "#/definitions/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec.", @@ -4046,6 +4054,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -4322,6 +4331,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -4511,6 +4521,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -4700,6 +4711,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -4744,6 +4756,14 @@ "orchestrator_opts": { "$ref": "#/definitions/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature.", @@ -5287,6 +5307,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -5476,6 +5497,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -5568,6 +5590,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { diff --git a/api/apiv1/gen/http/openapi.yaml b/api/apiv1/gen/http/openapi.yaml index 84450975..1260f870 100644 --- a/api/apiv1/gen/http/openapi.yaml +++ b/api/apiv1/gen/http/openapi.yaml @@ -2742,6 +2742,13 @@ definitions: pattern: n[0-9]+ orchestrator_opts: $ref: '#/definitions/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec. @@ -2876,6 +2883,7 @@ definitions: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -3081,6 +3089,7 @@ definitions: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -3221,6 +3230,7 @@ definitions: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -3361,6 +3371,7 @@ definitions: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -3396,6 +3407,13 @@ definitions: maxItems: 9 orchestrator_opts: $ref: '#/definitions/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature. @@ -3774,6 +3792,7 @@ definitions: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -3914,6 +3933,7 @@ definitions: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -3976,6 +3996,7 @@ definitions: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: diff --git a/api/apiv1/gen/http/openapi3.json b/api/apiv1/gen/http/openapi3.json index ba27dad3..b720b2dc 100644 --- a/api/apiv1/gen/http/openapi3.json +++ b/api/apiv1/gen/http/openapi3.json @@ -9045,6 +9045,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec.", @@ -9182,6 +9190,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -9266,6 +9275,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec.", @@ -9448,6 +9465,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -9533,6 +9551,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec.", @@ -9716,6 +9742,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -9799,6 +9826,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec.", @@ -9983,6 +10018,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -10066,6 +10102,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec.", @@ -10248,6 +10292,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -10331,6 +10376,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec.", @@ -10515,6 +10568,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -10600,6 +10654,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec.", @@ -10782,6 +10844,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -11011,6 +11074,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -11055,6 +11119,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature.", @@ -11581,6 +11653,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -11724,6 +11797,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -11867,6 +11941,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -11959,6 +12034,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -12381,6 +12457,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -12571,6 +12648,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -12761,6 +12839,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -12805,6 +12884,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature.", @@ -13278,6 +13365,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -13468,6 +13556,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -13560,6 +13649,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -13979,6 +14069,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -14168,6 +14259,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -14357,6 +14449,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -14401,6 +14494,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature.", @@ -14873,6 +14974,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -15062,6 +15164,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -15251,6 +15354,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -15343,6 +15447,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -15762,6 +15867,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -15951,6 +16057,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -16140,6 +16247,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -16184,6 +16292,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature.", @@ -16798,6 +16914,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -16890,6 +17007,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -17380,6 +17498,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -17569,6 +17688,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -17613,6 +17733,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature.", @@ -18223,6 +18351,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -18412,6 +18541,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -18504,6 +18634,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -18921,6 +19052,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -19110,6 +19242,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -19154,6 +19287,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature.", @@ -19626,6 +19767,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -19815,6 +19957,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -19907,6 +20050,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -20326,6 +20470,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -20370,6 +20515,14 @@ "orchestrator_opts": { "$ref": "#/components/schemas/OrchestratorOpts" }, + "patroni_port": { + "type": "integer", + "description": "The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.", + "example": 8888, + "format": "int64", + "minimum": 0, + "maximum": 65535 + }, "port": { "type": "integer", "description": "The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature.", @@ -20984,6 +21137,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -21173,6 +21327,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -21362,6 +21517,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { @@ -21454,6 +21610,7 @@ ] } }, + "patroni_port": 8888, "port": 5432, "postgres_version": "17.6", "postgresql_conf": { diff --git a/api/apiv1/gen/http/openapi3.yaml b/api/apiv1/gen/http/openapi3.yaml index ac461a8e..29b44310 100644 --- a/api/apiv1/gen/http/openapi3.yaml +++ b/api/apiv1/gen/http/openapi3.yaml @@ -6257,6 +6257,13 @@ components: pattern: n[0-9]+ orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec. @@ -6351,6 +6358,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -6419,6 +6427,13 @@ components: pattern: n[0-9]+ orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec. @@ -6552,6 +6567,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -6621,6 +6637,13 @@ components: pattern: n[0-9]+ orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec. @@ -6755,6 +6778,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -6822,6 +6846,13 @@ components: pattern: n[0-9]+ orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec. @@ -6957,6 +6988,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -7024,6 +7056,13 @@ components: pattern: n[0-9]+ orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec. @@ -7157,6 +7196,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -7224,6 +7264,13 @@ components: pattern: n[0-9]+ orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec. @@ -7359,6 +7406,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -7428,6 +7476,13 @@ components: pattern: n[0-9]+ orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this node. Overrides the Patroni port set in the DatabaseSpec. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database for this node. Overrides the Postgres port set in the DatabaseSpec. @@ -7561,6 +7616,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -7725,6 +7781,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -7760,6 +7817,13 @@ components: maxItems: 9 orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature. @@ -8106,6 +8170,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -8206,6 +8271,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -8306,6 +8372,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -8368,6 +8435,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -8664,6 +8732,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -8805,6 +8874,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -8946,6 +9016,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -8981,6 +9052,13 @@ components: maxItems: 9 orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature. @@ -9316,6 +9394,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -9457,6 +9536,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -9519,6 +9599,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -9812,6 +9893,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -9952,6 +10034,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -10092,6 +10175,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -10127,6 +10211,13 @@ components: maxItems: 9 orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature. @@ -10461,6 +10552,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -10601,6 +10693,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -10741,6 +10834,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -10803,6 +10897,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -11096,6 +11191,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -11236,6 +11332,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -11376,6 +11473,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -11411,6 +11509,13 @@ components: maxItems: 9 orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature. @@ -11833,6 +11938,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -11895,6 +12001,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -12232,6 +12339,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -12372,6 +12480,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -12407,6 +12516,13 @@ components: maxItems: 9 orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature. @@ -12825,6 +12941,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -12965,6 +13082,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -13027,6 +13145,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -13318,6 +13437,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -13458,6 +13578,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -13493,6 +13614,13 @@ components: maxItems: 9 orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature. @@ -13827,6 +13955,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -13967,6 +14096,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -14029,6 +14159,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -14322,6 +14453,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -14357,6 +14489,13 @@ components: maxItems: 9 orchestrator_opts: $ref: '#/components/schemas/OrchestratorOpts' + patroni_port: + type: integer + description: 'The port used by Patroni for this database. NOTE: This field is not currently supported for Docker Swarm.' + example: 8888 + format: int64 + minimum: 0 + maximum: 65535 port: type: integer description: The port used by the Postgres database. If the port is 0, each instance will be assigned a random port. If the port is unspecified, the database will not be exposed on any port, dependent on orchestrator support for that feature. @@ -14779,6 +14918,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -14919,6 +15059,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -15059,6 +15200,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: @@ -15121,6 +15263,7 @@ components: host_path: /Users/user/backups/host - destination_path: /backups/container host_path: /Users/user/backups/host + patroni_port: 8888 port: 5432 postgres_version: "17.6" postgresql_conf: diff --git a/changes/unreleased/Added-20260225-091421.yaml b/changes/unreleased/Added-20260225-091421.yaml new file mode 100644 index 00000000..feb955a8 --- /dev/null +++ b/changes/unreleased/Added-20260225-091421.yaml @@ -0,0 +1,3 @@ +kind: Added +body: Added `patroni_port` to the database and instance APIs for SystemD hosts. +time: 2026-02-25T09:14:21.937175-05:00 diff --git a/server/internal/api/apiv1/convert.go b/server/internal/api/apiv1/convert.go index f7d3a74c..a4d32bd3 100644 --- a/server/internal/api/apiv1/convert.go +++ b/server/internal/api/apiv1/convert.go @@ -97,6 +97,7 @@ func databaseNodesToAPI(nodes []*database.Node) []*api.DatabaseNodeSpec { HostIds: hostIDs, PostgresVersion: utils.NillablePointerTo(node.PostgresVersion), Port: node.Port, + PatroniPort: node.PatroniPort, Cpus: utils.NillablePointerTo(humanizeCPUs(node.CPUs)), Memory: utils.NillablePointerTo(humanizeBytes(node.MemoryBytes)), PostgresqlConf: node.PostgreSQLConf, @@ -253,6 +254,7 @@ func databaseSpecToAPI(d *database.Spec) *api.DatabaseSpec { PostgresVersion: utils.NillablePointerTo(d.PostgresVersion), SpockVersion: utils.NillablePointerTo(d.SpockVersion), Port: d.Port, + PatroniPort: d.PatroniPort, Cpus: utils.NillablePointerTo(humanizeCPUs(d.CPUs)), Memory: utils.NillablePointerTo(humanizeBytes(d.MemoryBytes)), Nodes: databaseNodesToAPI(d.Nodes), @@ -509,6 +511,7 @@ func apiToDatabaseNodes(apiNodes []*api.DatabaseNodeSpec) ([]*database.Node, err HostIDs: hostIDs, PostgresVersion: utils.FromPointer(apiNode.PostgresVersion), Port: apiNode.Port, + PatroniPort: apiNode.PatroniPort, CPUs: cpus, MemoryBytes: memory, PostgreSQLConf: apiNode.PostgresqlConf, @@ -742,6 +745,7 @@ func apiToDatabaseSpec(id, tID *api.Identifier, apiSpec *api.DatabaseSpec) (*dat PostgresVersion: utils.FromPointer(apiSpec.PostgresVersion), SpockVersion: utils.FromPointer(apiSpec.SpockVersion), Port: apiSpec.Port, + PatroniPort: apiSpec.PatroniPort, CPUs: cpus, MemoryBytes: memory, Nodes: nodes, diff --git a/server/internal/api/apiv1/validate.go b/server/internal/api/apiv1/validate.go index 2c6d5ac0..7319b87a 100644 --- a/server/internal/api/apiv1/validate.go +++ b/server/internal/api/apiv1/validate.go @@ -66,6 +66,7 @@ func validateDatabaseSpec(spec *api.DatabaseSpec) error { errs = append(errs, validateCPUs(spec.Cpus, []string{"cpus"})...) errs = append(errs, validateMemory(spec.Memory, []string{"memory"})...) + errs = append(errs, validatePorts(spec.Port, spec.PatroniPort, []string{"port"})) // Track node-name uniqueness and prepare set for cross-node checks. seenNodeNames := make(ds.Set[string], len(spec.Nodes)) @@ -194,6 +195,9 @@ func validateNode(node *api.DatabaseNodeSpec, path []string) []error { memPath := appendPath(path, "memory") errs = append(errs, validateMemory(node.Memory, memPath)...) + portPath := appendPath(path, "port") + errs = append(errs, validatePorts(node.Port, node.PatroniPort, portPath)) + seenHostIDs := make(ds.Set[string], len(node.HostIds)) for i, h := range node.HostIds { hostID := string(h) @@ -329,6 +333,17 @@ func validateMemory(value *string, path []string) []error { return errs } +func validatePorts(postgresPort, patroniPort *int, path []string) error { + postgres := utils.FromPointer(postgresPort) + patroni := utils.FromPointer(patroniPort) + + if postgres > 0 && postgres == patroni { + return newValidationError(errors.New("postgres and patroni ports must not conflict"), path) + } + + return nil +} + func validateBackupConfig(cfg *api.BackupConfigSpec, path []string) []error { var errs []error diff --git a/server/internal/api/apiv1/validate_test.go b/server/internal/api/apiv1/validate_test.go index 30725be0..dae34d9a 100644 --- a/server/internal/api/apiv1/validate_test.go +++ b/server/internal/api/apiv1/validate_test.go @@ -95,6 +95,66 @@ func TestValidateMemory(t *testing.T) { } } +func TestValidatePorts(t *testing.T) { + for _, tc := range []struct { + name string + postgresPort *int + patroniPort *int + expected string + }{ + { + name: "both nil", + postgresPort: nil, + patroniPort: nil, + }, + { + name: "postgres port nil", + postgresPort: nil, + patroniPort: utils.PointerTo(8888), + }, + { + name: "patroni port nil", + postgresPort: utils.PointerTo(8888), + patroniPort: nil, + }, + { + name: "both zero", + postgresPort: utils.PointerTo(0), + patroniPort: utils.PointerTo(0), + }, + { + name: "postgres port zero", + postgresPort: nil, + patroniPort: utils.PointerTo(0), + }, + { + name: "patroni port zero", + postgresPort: utils.PointerTo(0), + patroniPort: nil, + }, + { + name: "both defined non-equal", + postgresPort: utils.PointerTo(5432), + patroniPort: utils.PointerTo(8888), + }, + { + name: "conflicting", + postgresPort: utils.PointerTo(5432), + patroniPort: utils.PointerTo(5432), + expected: "postgres and patroni ports must not conflict", + }, + } { + t.Run(tc.name, func(t *testing.T) { + err := validatePorts(tc.postgresPort, tc.patroniPort, nil) + if tc.expected == "" { + assert.NoError(t, err) + } else { + assert.ErrorContains(t, err, tc.expected) + } + }) + } +} + func TestValidateRepoProperties(t *testing.T) { for _, tc := range []struct { name string @@ -628,8 +688,10 @@ func TestValidateDatabaseSpec(t *testing.T) { { name: "invalid", spec: &api.DatabaseSpec{ - Cpus: utils.PointerTo("0.00001"), - Memory: utils.PointerTo("%^&*"), + Cpus: utils.PointerTo("0.00001"), + Memory: utils.PointerTo("%^&*"), + Port: utils.PointerTo(5432), + PatroniPort: utils.PointerTo(5432), Nodes: []*api.DatabaseNodeSpec{ { Name: "n1", @@ -639,7 +701,9 @@ func TestValidateDatabaseSpec(t *testing.T) { }, }, { - Name: "n2", + Name: "n2", + Port: utils.PointerTo(8888), + PatroniPort: utils.PointerTo(8888), HostIds: []api.Identifier{ api.Identifier("host-2"), }, @@ -673,6 +737,8 @@ func TestValidateDatabaseSpec(t *testing.T) { "nodes[2]: node names must be unique within a database", "backup_config.repositories[0].base_path: base_path must be absolute for posix repositories", "restore_config.repository.base_path: base_path must be absolute for posix repositories", + "port: postgres and patroni ports must not conflict", + "nodes[1].port: postgres and patroni ports must not conflict", }, }, } { diff --git a/server/internal/database/spec.go b/server/internal/database/spec.go index 9e26928c..bc219b43 100644 --- a/server/internal/database/spec.go +++ b/server/internal/database/spec.go @@ -41,6 +41,7 @@ type Node struct { HostIDs []string `json:"host_ids"` PostgresVersion string `json:"postgres_version"` Port *int `json:"port"` + PatroniPort *int `json:"patroni_port"` CPUs float64 `json:"cpus"` MemoryBytes uint64 `json:"memory"` PostgreSQLConf map[string]any `json:"postgresql_conf"` @@ -59,6 +60,7 @@ func (n *Node) Clone() *Node { HostIDs: slices.Clone(n.HostIDs), PostgresVersion: n.PostgresVersion, Port: n.Port, + PatroniPort: n.PatroniPort, CPUs: n.CPUs, MemoryBytes: n.MemoryBytes, PostgreSQLConf: maps.Clone(n.PostgreSQLConf), @@ -285,6 +287,7 @@ type Spec struct { PostgresVersion string `json:"postgres_version"` SpockVersion string `json:"spock_version"` Port *int `json:"port"` + PatroniPort *int `json:"patroni_port"` CPUs float64 `json:"cpus"` MemoryBytes uint64 `json:"memory"` Nodes []*Node `json:"nodes"` @@ -371,6 +374,7 @@ func (s *Spec) Clone() *Spec { PostgresVersion: s.PostgresVersion, SpockVersion: s.SpockVersion, Port: s.Port, + PatroniPort: s.PatroniPort, CPUs: s.CPUs, MemoryBytes: s.MemoryBytes, PostgreSQLConf: maps.Clone(s.PostgreSQLConf), @@ -492,6 +496,7 @@ type InstanceSpec struct { NodeOrdinal int `json:"node_ordinal"` PgEdgeVersion *host.PgEdgeVersion `json:"pg_edge_version"` Port *int `json:"port"` + PatroniPort *int `json:"patroni_port"` CPUs float64 `json:"cpus"` MemoryBytes uint64 `json:"memory"` DatabaseUsers []*User `json:"database_users"` @@ -524,6 +529,7 @@ func (s *InstanceSpec) Clone() *InstanceSpec { NodeOrdinal: s.NodeOrdinal, PgEdgeVersion: s.PgEdgeVersion.Clone(), Port: utils.ClonePointer(s.Port), + PatroniPort: utils.ClonePointer(s.PatroniPort), CPUs: s.CPUs, MemoryBytes: s.MemoryBytes, DatabaseUsers: users, @@ -594,6 +600,7 @@ func (s *Spec) NodeInstances() ([]*NodeInstances, error) { NodeOrdinal: nodeOrdinal, PgEdgeVersion: nodeVersion, Port: overridableValue(s.Port, node.Port), + PatroniPort: overridableValue(s.PatroniPort, node.PatroniPort), CPUs: overridableValue(s.CPUs, node.CPUs), MemoryBytes: overridableValue(s.MemoryBytes, node.MemoryBytes), DatabaseUsers: s.DatabaseUsers,