Merge e00ac08d50 into 3ca1884876
This commit is contained in:
commit
b93ccdd193
|
|
@ -324,6 +324,12 @@ explanation of `ttl` and `loop_wait` parameters.
|
||||||
custom `pg_hba` should include the pam line to avoid breaking pam
|
custom `pg_hba` should include the pam line to avoid breaking pam
|
||||||
authentication. Optional.
|
authentication. Optional.
|
||||||
|
|
||||||
|
* **pg_ident**
|
||||||
|
list of custom `pg_ident` lines defining user name maps for external
|
||||||
|
authentication methods (e.g. cert, gss, peer). Each line is of the form
|
||||||
|
`mapname system-username pg-username`. Patroni manages `pg_ident.conf`
|
||||||
|
and reloads PostgreSQL when this list changes. Optional.
|
||||||
|
|
||||||
* **ttl**
|
* **ttl**
|
||||||
Patroni `ttl` parameter value, optional. The default is set by the Spilo
|
Patroni `ttl` parameter value, optional. The default is set by the Spilo
|
||||||
Docker image. Optional.
|
Docker image. Optional.
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,9 @@ spec:
|
||||||
# pg_hba:
|
# pg_hba:
|
||||||
# - hostssl all all 0.0.0.0/0 md5
|
# - hostssl all all 0.0.0.0/0 md5
|
||||||
# - host all all 0.0.0.0/0 md5
|
# - host all all 0.0.0.0/0 md5
|
||||||
|
# pg_ident:
|
||||||
|
# - mymap /^(.*)@example\.com$ \1
|
||||||
|
# - mymap admin@example.com postgres
|
||||||
# slots:
|
# slots:
|
||||||
# permanent_physical_1:
|
# permanent_physical_1:
|
||||||
# type: physical
|
# type: physical
|
||||||
|
|
|
||||||
|
|
@ -3484,6 +3484,10 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
pg_ident:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
retry_timeout:
|
retry_timeout:
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
|
|
|
||||||
|
|
@ -3484,6 +3484,10 @@ spec:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
type: array
|
type: array
|
||||||
|
pg_ident:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
retry_timeout:
|
retry_timeout:
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,7 @@ type Resources struct {
|
||||||
type Patroni struct {
|
type Patroni struct {
|
||||||
InitDB map[string]string `json:"initdb,omitempty"`
|
InitDB map[string]string `json:"initdb,omitempty"`
|
||||||
PgHba []string `json:"pg_hba,omitempty"`
|
PgHba []string `json:"pg_hba,omitempty"`
|
||||||
|
PgIdent []string `json:"pg_ident,omitempty"`
|
||||||
TTL uint32 `json:"ttl,omitempty"`
|
TTL uint32 `json:"ttl,omitempty"`
|
||||||
LoopWait uint32 `json:"loop_wait,omitempty"`
|
LoopWait uint32 `json:"loop_wait,omitempty"`
|
||||||
RetryTimeout uint32 `json:"retry_timeout,omitempty"`
|
RetryTimeout uint32 `json:"retry_timeout,omitempty"`
|
||||||
|
|
|
||||||
|
|
@ -257,6 +257,10 @@ var unmarshalCluster = []struct {
|
||||||
"hostssl all all 0.0.0.0/0 md5",
|
"hostssl all all 0.0.0.0/0 md5",
|
||||||
"host all all 0.0.0.0/0 md5"
|
"host all all 0.0.0.0/0 md5"
|
||||||
],
|
],
|
||||||
|
"pg_ident": [
|
||||||
|
"mymap user1 dbuser1",
|
||||||
|
"mymap user2 dbuser2"
|
||||||
|
],
|
||||||
"ttl": 30,
|
"ttl": 30,
|
||||||
"loop_wait": 10,
|
"loop_wait": 10,
|
||||||
"retry_timeout": 10,
|
"retry_timeout": 10,
|
||||||
|
|
@ -307,6 +311,7 @@ var unmarshalCluster = []struct {
|
||||||
"data-checksums": "true",
|
"data-checksums": "true",
|
||||||
},
|
},
|
||||||
PgHba: []string{"hostssl all all 0.0.0.0/0 md5", "host all all 0.0.0.0/0 md5"},
|
PgHba: []string{"hostssl all all 0.0.0.0/0 md5", "host all all 0.0.0.0/0 md5"},
|
||||||
|
PgIdent: []string{"mymap user1 dbuser1", "mymap user2 dbuser2"},
|
||||||
TTL: 30,
|
TTL: 30,
|
||||||
LoopWait: 10,
|
LoopWait: 10,
|
||||||
RetryTimeout: 10,
|
RetryTimeout: 10,
|
||||||
|
|
@ -346,7 +351,7 @@ var unmarshalCluster = []struct {
|
||||||
},
|
},
|
||||||
Error: "",
|
Error: "",
|
||||||
},
|
},
|
||||||
marshal: []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"18","parameters":{"log_statement":"all","max_connections":"10","shared_buffers":"32MB"}},"pod_priority_class_name":"spilo-pod-priority","volume":{"size":"5Gi","storageClass":"SSD", "subPath": "subdir"},"enableShmVolume":false,"patroni":{"initdb":{"data-checksums":"true","encoding":"UTF8","locale":"en_US.UTF-8"},"pg_hba":["hostssl all all 0.0.0.0/0 md5","host all all 0.0.0.0/0 md5"],"ttl":30,"loop_wait":10,"retry_timeout":10,"maximum_lag_on_failover":33554432,"slots":{"permanent_logical_1":{"database":"foo","plugin":"pgoutput","type":"logical"}}},"resources":{"requests":{"cpu":"10m","memory":"50Mi"},"limits":{"cpu":"300m","memory":"3000Mi"}},"teamId":"acid","allowedSourceRanges":["127.0.0.1/32"],"numberOfInstances":2,"users":{"zalando":["superuser","createdb"]},"maintenanceWindows":["Mon:01:00-06:00","Sat:00:00-04:00","05:00-05:15"],"clone":{"cluster":"acid-batman"}},"status":{"PostgresClusterStatus":""}}`),
|
marshal: []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"18","parameters":{"log_statement":"all","max_connections":"10","shared_buffers":"32MB"}},"pod_priority_class_name":"spilo-pod-priority","volume":{"size":"5Gi","storageClass":"SSD", "subPath": "subdir"},"enableShmVolume":false,"patroni":{"initdb":{"data-checksums":"true","encoding":"UTF8","locale":"en_US.UTF-8"},"pg_hba":["hostssl all all 0.0.0.0/0 md5","host all all 0.0.0.0/0 md5"],"pg_ident":["mymap user1 dbuser1","mymap user2 dbuser2"],"ttl":30,"loop_wait":10,"retry_timeout":10,"maximum_lag_on_failover":33554432,"slots":{"permanent_logical_1":{"database":"foo","plugin":"pgoutput","type":"logical"}}},"resources":{"requests":{"cpu":"10m","memory":"50Mi"},"limits":{"cpu":"300m","memory":"3000Mi"}},"teamId":"acid","allowedSourceRanges":["127.0.0.1/32"],"numberOfInstances":2,"users":{"zalando":["superuser","createdb"]},"maintenanceWindows":["Mon:01:00-06:00","Sat:00:00-04:00","05:00-05:15"],"clone":{"cluster":"acid-batman"}},"status":{"PostgresClusterStatus":""}}`),
|
||||||
err: nil},
|
err: nil},
|
||||||
{
|
{
|
||||||
about: "example with clone",
|
about: "example with clone",
|
||||||
|
|
|
||||||
|
|
@ -587,6 +587,11 @@ func (in *Patroni) DeepCopyInto(out *Patroni) {
|
||||||
*out = make([]string, len(*in))
|
*out = make([]string, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
|
if in.PgIdent != nil {
|
||||||
|
in, out := &in.PgIdent, &out.PgIdent
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
if in.Slots != nil {
|
if in.Slots != nil {
|
||||||
in, out := &in.Slots, &out.Slots
|
in, out := &in.Slots, &out.Slots
|
||||||
*out = make(map[string]map[string]string, len(*in))
|
*out = make(map[string]map[string]string, len(*in))
|
||||||
|
|
|
||||||
|
|
@ -35,15 +35,16 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
pgBinariesLocationTemplate = "/usr/lib/postgresql/%v/bin"
|
pgBinariesLocationTemplate = "/usr/lib/postgresql/%v/bin"
|
||||||
patroniPGBinariesParameterName = "bin_dir"
|
patroniPGBinariesParameterName = "bin_dir"
|
||||||
patroniPGHBAConfParameterName = "pg_hba"
|
patroniPGHBAConfParameterName = "pg_hba"
|
||||||
localHost = "127.0.0.1/32"
|
patroniPGIdentConfParameterName = "pg_ident"
|
||||||
scalyrSidecarName = "scalyr-sidecar"
|
localHost = "127.0.0.1/32"
|
||||||
logicalBackupContainerName = "logical-backup"
|
scalyrSidecarName = "scalyr-sidecar"
|
||||||
connectionPoolerContainer = "connection-pooler"
|
logicalBackupContainerName = "logical-backup"
|
||||||
pgPort = 5432
|
connectionPoolerContainer = "connection-pooler"
|
||||||
operatorPort = 8080
|
pgPort = 5432
|
||||||
|
operatorPort = 8080
|
||||||
)
|
)
|
||||||
|
|
||||||
type patroniDCS struct {
|
type patroniDCS struct {
|
||||||
|
|
@ -469,12 +470,16 @@ PatroniInitDBParams:
|
||||||
config.Bootstrap.DCS.PGBootstrapConfiguration[constants.PatroniPGParametersParameterName] = bootstrap
|
config.Bootstrap.DCS.PGBootstrapConfiguration[constants.PatroniPGParametersParameterName] = bootstrap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Patroni gives us a choice of writing pg_hba.conf to either the bootstrap section or to the local postgresql one.
|
|
||||||
// We choose the local one, because we need Patroni to change pg_hba.conf in PostgreSQL after the user changes the
|
// Patroni gives us a choice of writing pg_hba.conf and pg_ident.conf to either the bootstrap section or to the local postgresql one.
|
||||||
|
// We choose the local one, because we need Patroni to change them in PostgreSQL after the user changes the
|
||||||
// relevant section in the manifest.
|
// relevant section in the manifest.
|
||||||
if len(patroni.PgHba) > 0 {
|
if len(patroni.PgHba) > 0 {
|
||||||
config.PgLocalConfiguration[patroniPGHBAConfParameterName] = patroni.PgHba
|
config.PgLocalConfiguration[patroniPGHBAConfParameterName] = patroni.PgHba
|
||||||
}
|
}
|
||||||
|
if len(patroni.PgIdent) > 0 {
|
||||||
|
config.PgLocalConfiguration[patroniPGIdentConfParameterName] = patroni.PgIdent
|
||||||
|
}
|
||||||
|
|
||||||
res, err := json.Marshal(config)
|
res, err := json.Marshal(config)
|
||||||
return string(res), err
|
return string(res), err
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,7 @@ func TestGenerateSpiloJSONConfiguration(t *testing.T) {
|
||||||
"data-checksums": "true",
|
"data-checksums": "true",
|
||||||
},
|
},
|
||||||
PgHba: []string{"hostssl all all 0.0.0.0/0 md5", "host all all 0.0.0.0/0 md5"},
|
PgHba: []string{"hostssl all all 0.0.0.0/0 md5", "host all all 0.0.0.0/0 md5"},
|
||||||
|
PgIdent: []string{"mymap user1 dbuser1", "mymap user2 dbuser2"},
|
||||||
TTL: 30,
|
TTL: 30,
|
||||||
LoopWait: 10,
|
LoopWait: 10,
|
||||||
RetryTimeout: 10,
|
RetryTimeout: 10,
|
||||||
|
|
@ -102,7 +103,7 @@ func TestGenerateSpiloJSONConfiguration(t *testing.T) {
|
||||||
FailsafeMode: util.True(),
|
FailsafeMode: util.True(),
|
||||||
},
|
},
|
||||||
opConfig: &config.Config{},
|
opConfig: &config.Config{},
|
||||||
result: `{"postgresql":{"bin_dir":"/usr/lib/postgresql/18/bin","pg_hba":["hostssl all all 0.0.0.0/0 md5","host all all 0.0.0.0/0 md5"]},"bootstrap":{"initdb":[{"auth-host":"md5"},{"auth-local":"trust"},"data-checksums",{"encoding":"UTF8"},{"locale":"en_US.UTF-8"}],"dcs":{"ttl":30,"loop_wait":10,"retry_timeout":10,"maximum_lag_on_failover":33554432,"synchronous_mode":true,"synchronous_mode_strict":true,"synchronous_node_count":1,"slots":{"permanent_logical_1":{"database":"foo","plugin":"pgoutput","type":"logical"}},"failsafe_mode":true}}}`,
|
result: `{"postgresql":{"bin_dir":"/usr/lib/postgresql/18/bin","pg_hba":["hostssl all all 0.0.0.0/0 md5","host all all 0.0.0.0/0 md5"],"pg_ident":["mymap user1 dbuser1","mymap user2 dbuser2"]},"bootstrap":{"initdb":[{"auth-host":"md5"},{"auth-local":"trust"},"data-checksums",{"encoding":"UTF8"},{"locale":"en_US.UTF-8"}],"dcs":{"ttl":30,"loop_wait":10,"retry_timeout":10,"maximum_lag_on_failover":33554432,"synchronous_mode":true,"synchronous_mode_strict":true,"synchronous_node_count":1,"slots":{"permanent_logical_1":{"database":"foo","plugin":"pgoutput","type":"logical"}},"failsafe_mode":true}}}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
subtest: "Patroni failsafe_mode configured globally",
|
subtest: "Patroni failsafe_mode configured globally",
|
||||||
|
|
|
||||||
|
|
@ -917,6 +917,9 @@ func (c *Cluster) checkAndSetGlobalPostgreSQLConfiguration(pod *v1.Pod, effectiv
|
||||||
if desiredPatroniConfig.PgHba != nil && !reflect.DeepEqual(desiredPatroniConfig.PgHba, effectivePatroniConfig.PgHba) {
|
if desiredPatroniConfig.PgHba != nil && !reflect.DeepEqual(desiredPatroniConfig.PgHba, effectivePatroniConfig.PgHba) {
|
||||||
configToSet["pg_hba"] = desiredPatroniConfig.PgHba
|
configToSet["pg_hba"] = desiredPatroniConfig.PgHba
|
||||||
}
|
}
|
||||||
|
if desiredPatroniConfig.PgIdent != nil && !reflect.DeepEqual(desiredPatroniConfig.PgIdent, effectivePatroniConfig.PgIdent) {
|
||||||
|
configToSet["pg_ident"] = desiredPatroniConfig.PgIdent
|
||||||
|
}
|
||||||
if desiredPatroniConfig.RetryTimeout > 0 && desiredPatroniConfig.RetryTimeout != effectivePatroniConfig.RetryTimeout {
|
if desiredPatroniConfig.RetryTimeout > 0 && desiredPatroniConfig.RetryTimeout != effectivePatroniConfig.RetryTimeout {
|
||||||
configToSet["retry_timeout"] = desiredPatroniConfig.RetryTimeout
|
configToSet["retry_timeout"] = desiredPatroniConfig.RetryTimeout
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue