Merge branch 'master' into fes-support
This commit is contained in:
commit
bdf87da1fe
|
|
@ -131,6 +131,10 @@ spec:
|
||||||
major_version_upgrade_mode:
|
major_version_upgrade_mode:
|
||||||
type: string
|
type: string
|
||||||
default: "off"
|
default: "off"
|
||||||
|
major_version_upgrade_team_allow_list:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
minimal_major_version:
|
minimal_major_version:
|
||||||
type: string
|
type: string
|
||||||
default: "9.6"
|
default: "9.6"
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,10 @@ configUsers:
|
||||||
configMajorVersionUpgrade:
|
configMajorVersionUpgrade:
|
||||||
# "off": no upgrade, "manual": manifest triggers action, "full": minimal version violation triggers too
|
# "off": no upgrade, "manual": manifest triggers action, "full": minimal version violation triggers too
|
||||||
major_version_upgrade_mode: "off"
|
major_version_upgrade_mode: "off"
|
||||||
|
# upgrades will only be carried out for clusters of listed teams when mode is "off"
|
||||||
|
# major_version_upgrade_team_allow_list:
|
||||||
|
# - acid
|
||||||
|
|
||||||
# minimal Postgres major version that will not automatically be upgraded
|
# minimal Postgres major version that will not automatically be upgraded
|
||||||
minimal_major_version: "9.6"
|
minimal_major_version: "9.6"
|
||||||
# target Postgres major version when upgrading clusters automatically
|
# target Postgres major version when upgrading clusters automatically
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,10 @@ CRD-configuration, they are grouped under the `major_version_upgrade` key.
|
||||||
Note, that with all three modes increasing the version in the manifest will
|
Note, that with all three modes increasing the version in the manifest will
|
||||||
trigger a rolling update of the pods. The default is `"off"`.
|
trigger a rolling update of the pods. The default is `"off"`.
|
||||||
|
|
||||||
|
* **major_version_upgrade_team_allow_list**
|
||||||
|
Upgrades will only be carried out for clusters of listed teams when mode is
|
||||||
|
set to "off". The default is empty.
|
||||||
|
|
||||||
* **minimal_major_version**
|
* **minimal_major_version**
|
||||||
The minimal Postgres major version that will not automatically be upgraded
|
The minimal Postgres major version that will not automatically be upgraded
|
||||||
when `major_version_upgrade_mode` is set to `"full"`. The default is `"9.6"`.
|
when `major_version_upgrade_mode` is set to `"full"`. The default is `"9.6"`.
|
||||||
|
|
|
||||||
|
|
@ -603,10 +603,9 @@ spec:
|
||||||
```
|
```
|
||||||
|
|
||||||
Some extensions require SUPERUSER rights on creation unless they are not
|
Some extensions require SUPERUSER rights on creation unless they are not
|
||||||
whitelisted by the [pgextwlist](https://github.com/dimitri/pgextwlist)
|
allowed by the [pgextwlist](https://github.com/dimitri/pgextwlist) extension,
|
||||||
extension, that is shipped with the Spilo image. To see which extensions are
|
that is shipped with the Spilo image. To see which extensions are on the list
|
||||||
on the list check the `extwlist.extension` parameter in the postgresql.conf
|
check the `extwlist.extension` parameter in the postgresql.conf file.
|
||||||
file.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
SHOW extwlist.extensions;
|
SHOW extwlist.extensions;
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ data:
|
||||||
logical_backup_s3_sse: "AES256"
|
logical_backup_s3_sse: "AES256"
|
||||||
logical_backup_schedule: "30 00 * * *"
|
logical_backup_schedule: "30 00 * * *"
|
||||||
major_version_upgrade_mode: "manual"
|
major_version_upgrade_mode: "manual"
|
||||||
|
# major_version_upgrade_team_allow_list: ""
|
||||||
master_dns_name_format: "{cluster}.{team}.{hostedzone}"
|
master_dns_name_format: "{cluster}.{team}.{hostedzone}"
|
||||||
# master_pod_move_timeout: 20m
|
# master_pod_move_timeout: 20m
|
||||||
# max_instances: "-1"
|
# max_instances: "-1"
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,10 @@ spec:
|
||||||
major_version_upgrade_mode:
|
major_version_upgrade_mode:
|
||||||
type: string
|
type: string
|
||||||
default: "off"
|
default: "off"
|
||||||
|
major_version_upgrade_team_allow_list:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
minimal_major_version:
|
minimal_major_version:
|
||||||
type: string
|
type: string
|
||||||
default: "9.6"
|
default: "9.6"
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ configuration:
|
||||||
super_username: postgres
|
super_username: postgres
|
||||||
major_version_upgrade:
|
major_version_upgrade:
|
||||||
major_version_upgrade_mode: "off"
|
major_version_upgrade_mode: "off"
|
||||||
|
# major_version_upgrade_team_allow_list:
|
||||||
|
# - acid
|
||||||
minimal_major_version: "9.6"
|
minimal_major_version: "9.6"
|
||||||
target_major_version: "14"
|
target_major_version: "14"
|
||||||
kubernetes:
|
kubernetes:
|
||||||
|
|
|
||||||
|
|
@ -1052,6 +1052,14 @@ var OperatorConfigCRDResourceValidation = apiextv1.CustomResourceValidation{
|
||||||
"major_version_upgrade_mode": {
|
"major_version_upgrade_mode": {
|
||||||
Type: "string",
|
Type: "string",
|
||||||
},
|
},
|
||||||
|
"major_version_upgrade_team_allow_list": {
|
||||||
|
Type: "array",
|
||||||
|
Items: &apiextv1.JSONSchemaPropsOrArray{
|
||||||
|
Schema: &apiextv1.JSONSchemaProps{
|
||||||
|
Type: "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
"minimal_major_version": {
|
"minimal_major_version": {
|
||||||
Type: "string",
|
Type: "string",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,10 @@ type PostgresUsersConfiguration struct {
|
||||||
|
|
||||||
// MajorVersionUpgradeConfiguration defines how to execute major version upgrades of Postgres.
|
// MajorVersionUpgradeConfiguration defines how to execute major version upgrades of Postgres.
|
||||||
type MajorVersionUpgradeConfiguration struct {
|
type MajorVersionUpgradeConfiguration struct {
|
||||||
MajorVersionUpgradeMode string `json:"major_version_upgrade_mode" default:"off"` // off - no actions, manual - manifest triggers action, full - manifest and minimal version violation trigger upgrade
|
MajorVersionUpgradeMode string `json:"major_version_upgrade_mode" default:"off"` // off - no actions, manual - manifest triggers action, full - manifest and minimal version violation trigger upgrade
|
||||||
MinimalMajorVersion string `json:"minimal_major_version" default:"9.6"`
|
MajorVersionUpgradeTeamAllowList []string `json:"major_version_upgrade_team_allow_list,omitempty"`
|
||||||
TargetMajorVersion string `json:"target_major_version" default:"14"`
|
MinimalMajorVersion string `json:"minimal_major_version" default:"9.6"`
|
||||||
|
TargetMajorVersion string `json:"target_major_version" default:"14"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubernetesMetaConfiguration defines k8s conf required for all Postgres clusters and the operator itself
|
// KubernetesMetaConfiguration defines k8s conf required for all Postgres clusters and the operator itself
|
||||||
|
|
|
||||||
|
|
@ -318,6 +318,11 @@ func (in *MaintenanceWindow) DeepCopy() *MaintenanceWindow {
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *MajorVersionUpgradeConfiguration) DeepCopyInto(out *MajorVersionUpgradeConfiguration) {
|
func (in *MajorVersionUpgradeConfiguration) DeepCopyInto(out *MajorVersionUpgradeConfiguration) {
|
||||||
*out = *in
|
*out = *in
|
||||||
|
if in.MajorVersionUpgradeTeamAllowList != nil {
|
||||||
|
in, out := &in.MajorVersionUpgradeTeamAllowList, &out.MajorVersionUpgradeTeamAllowList
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -386,7 +391,7 @@ func (in *OperatorConfigurationData) DeepCopyInto(out *OperatorConfigurationData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.PostgresUsersConfiguration = in.PostgresUsersConfiguration
|
out.PostgresUsersConfiguration = in.PostgresUsersConfiguration
|
||||||
out.MajorVersionUpgrade = in.MajorVersionUpgrade
|
in.MajorVersionUpgrade.DeepCopyInto(&out.MajorVersionUpgrade)
|
||||||
in.Kubernetes.DeepCopyInto(&out.Kubernetes)
|
in.Kubernetes.DeepCopyInto(&out.Kubernetes)
|
||||||
out.PostgresPodResources = in.PostgresPodResources
|
out.PostgresPodResources = in.PostgresPodResources
|
||||||
out.Timeouts = in.Timeouts
|
out.Timeouts = in.Timeouts
|
||||||
|
|
|
||||||
|
|
@ -712,7 +712,8 @@ func (c *Cluster) syncConnectionPooler(oldSpec, newSpec *acidv1.Postgresql, Look
|
||||||
if (!needSync && len(masterChanges) <= 0 && len(replicaChanges) <= 0) &&
|
if (!needSync && len(masterChanges) <= 0 && len(replicaChanges) <= 0) &&
|
||||||
((!needConnectionPooler(&newSpec.Spec) && (c.ConnectionPooler == nil || !needConnectionPooler(&oldSpec.Spec))) ||
|
((!needConnectionPooler(&newSpec.Spec) && (c.ConnectionPooler == nil || !needConnectionPooler(&oldSpec.Spec))) ||
|
||||||
(c.ConnectionPooler != nil && needConnectionPooler(&newSpec.Spec) &&
|
(c.ConnectionPooler != nil && needConnectionPooler(&newSpec.Spec) &&
|
||||||
(c.ConnectionPooler[Master].LookupFunction || c.ConnectionPooler[Replica].LookupFunction))) {
|
((c.ConnectionPooler[Master] != nil && c.ConnectionPooler[Master].LookupFunction) ||
|
||||||
|
(c.ConnectionPooler[Replica] != nil && c.ConnectionPooler[Replica].LookupFunction)))) {
|
||||||
c.logger.Debugln("syncing pooler is not required")
|
c.logger.Debugln("syncing pooler is not required")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/zalando/postgres-operator/pkg/spec"
|
"github.com/zalando/postgres-operator/pkg/spec"
|
||||||
|
"github.com/zalando/postgres-operator/pkg/util"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -44,9 +45,25 @@ func (c *Cluster) GetDesiredMajorVersion() string {
|
||||||
return c.Spec.PgVersion
|
return c.Spec.PgVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Cluster) isUpgradeAllowedForTeam(owningTeam string) bool {
|
||||||
|
allowedTeams := c.OpConfig.MajorVersionUpgradeTeamAllowList
|
||||||
|
|
||||||
|
if len(allowedTeams) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return util.SliceContains(allowedTeams, owningTeam)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Execute upgrade when mode is set to manual or full or when the owning team is allowed for upgrade (and mode is "off").
|
||||||
|
|
||||||
|
Manual upgrade means, it is triggered by the user via manifest version change
|
||||||
|
Full upgrade means, operator also determines the minimal version used accross all clusters and upgrades violators.
|
||||||
|
*/
|
||||||
func (c *Cluster) majorVersionUpgrade() error {
|
func (c *Cluster) majorVersionUpgrade() error {
|
||||||
|
|
||||||
if c.OpConfig.MajorVersionUpgradeMode == "off" {
|
if c.OpConfig.MajorVersionUpgradeMode == "off" && !c.isUpgradeAllowedForTeam(c.Spec.TeamID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -496,18 +496,17 @@ func (c *Cluster) deleteEndpoint(role PostgresRole) error {
|
||||||
|
|
||||||
func (c *Cluster) deleteSecrets() error {
|
func (c *Cluster) deleteSecrets() error {
|
||||||
c.setProcessName("deleting secrets")
|
c.setProcessName("deleting secrets")
|
||||||
var errors []string
|
errors := make([]string, 0)
|
||||||
errorCount := 0
|
|
||||||
for uid, secret := range c.Secrets {
|
for uid, secret := range c.Secrets {
|
||||||
err := c.deleteSecret(uid, *secret)
|
err := c.deleteSecret(uid, *secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errors = append(errors, fmt.Sprintf("%v", err))
|
errors = append(errors, fmt.Sprintf("%v", err))
|
||||||
errorCount++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if errorCount > 0 {
|
if len(errors) > 0 {
|
||||||
return fmt.Errorf("could not delete all secrets: %v", errors)
|
return fmt.Errorf("could not delete all secrets: %v", strings.Join(errors, `', '`))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -196,17 +196,15 @@ func TestCheckAndSetGlobalPostgreSQLConfiguration(t *testing.T) {
|
||||||
cluster.patroni = p
|
cluster.patroni = p
|
||||||
mockPod := newMockPod("192.168.100.1")
|
mockPod := newMockPod("192.168.100.1")
|
||||||
|
|
||||||
// simulate existing config that differs with cluster.Spec
|
// simulate existing config that differs from cluster.Spec
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
subtest string
|
subtest string
|
||||||
pod *v1.Pod
|
|
||||||
patroni acidv1.Patroni
|
patroni acidv1.Patroni
|
||||||
pgParams map[string]string
|
pgParams map[string]string
|
||||||
restartMaster bool
|
restartMaster bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
subtest: "Patroni and Postgresql.Parameters differ - restart replica first",
|
subtest: "Patroni and Postgresql.Parameters differ - restart replica first",
|
||||||
pod: mockPod,
|
|
||||||
patroni: acidv1.Patroni{
|
patroni: acidv1.Patroni{
|
||||||
TTL: 30, // desired 20
|
TTL: 30, // desired 20
|
||||||
},
|
},
|
||||||
|
|
@ -218,7 +216,6 @@ func TestCheckAndSetGlobalPostgreSQLConfiguration(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
subtest: "multiple Postgresql.Parameters differ - restart replica first",
|
subtest: "multiple Postgresql.Parameters differ - restart replica first",
|
||||||
pod: mockPod,
|
|
||||||
patroni: acidv1.Patroni{
|
patroni: acidv1.Patroni{
|
||||||
TTL: 20,
|
TTL: 20,
|
||||||
},
|
},
|
||||||
|
|
@ -230,7 +227,6 @@ func TestCheckAndSetGlobalPostgreSQLConfiguration(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
subtest: "desired max_connections bigger - restart replica first",
|
subtest: "desired max_connections bigger - restart replica first",
|
||||||
pod: mockPod,
|
|
||||||
patroni: acidv1.Patroni{
|
patroni: acidv1.Patroni{
|
||||||
TTL: 20,
|
TTL: 20,
|
||||||
},
|
},
|
||||||
|
|
@ -242,7 +238,6 @@ func TestCheckAndSetGlobalPostgreSQLConfiguration(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
subtest: "desired max_connections smaller - restart master first",
|
subtest: "desired max_connections smaller - restart master first",
|
||||||
pod: mockPod,
|
|
||||||
patroni: acidv1.Patroni{
|
patroni: acidv1.Patroni{
|
||||||
TTL: 20,
|
TTL: 20,
|
||||||
},
|
},
|
||||||
|
|
@ -255,7 +250,7 @@ func TestCheckAndSetGlobalPostgreSQLConfiguration(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
requireMasterRestart, err := cluster.checkAndSetGlobalPostgreSQLConfiguration(tt.pod, tt.patroni, cluster.Spec.Patroni, tt.pgParams, cluster.Spec.Parameters)
|
requireMasterRestart, err := cluster.checkAndSetGlobalPostgreSQLConfiguration(mockPod, tt.patroni, cluster.Spec.Patroni, tt.pgParams, cluster.Spec.Parameters)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
if requireMasterRestart != tt.restartMaster {
|
if requireMasterRestart != tt.restartMaster {
|
||||||
t.Errorf("%s - %s: unexpect master restart strategy, got %v, expected %v", testName, tt.subtest, requireMasterRestart, tt.restartMaster)
|
t.Errorf("%s - %s: unexpect master restart strategy, got %v, expected %v", testName, tt.subtest, requireMasterRestart, tt.restartMaster)
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ func (c *Cluster) syncUnderlyingEBSVolume() error {
|
||||||
awsGp3 := aws.String("gp3")
|
awsGp3 := aws.String("gp3")
|
||||||
awsIo2 := aws.String("io2")
|
awsIo2 := aws.String("io2")
|
||||||
|
|
||||||
errors := []string{}
|
errors := make([]string, 0)
|
||||||
|
|
||||||
for _, volume := range c.EBSVolumes {
|
for _, volume := range c.EBSVolumes {
|
||||||
var modifyIops *int64
|
var modifyIops *int64
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
||||||
|
|
||||||
// major version upgrade config
|
// major version upgrade config
|
||||||
result.MajorVersionUpgradeMode = util.Coalesce(fromCRD.MajorVersionUpgrade.MajorVersionUpgradeMode, "off")
|
result.MajorVersionUpgradeMode = util.Coalesce(fromCRD.MajorVersionUpgrade.MajorVersionUpgradeMode, "off")
|
||||||
|
result.MajorVersionUpgradeTeamAllowList = fromCRD.MajorVersionUpgrade.MajorVersionUpgradeTeamAllowList
|
||||||
result.MinimalMajorVersion = util.Coalesce(fromCRD.MajorVersionUpgrade.MinimalMajorVersion, "9.6")
|
result.MinimalMajorVersion = util.Coalesce(fromCRD.MajorVersionUpgrade.MinimalMajorVersion, "9.6")
|
||||||
result.TargetMajorVersion = util.Coalesce(fromCRD.MajorVersionUpgrade.TargetMajorVersion, "14")
|
result.TargetMajorVersion = util.Coalesce(fromCRD.MajorVersionUpgrade.TargetMajorVersion, "14")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -195,13 +195,12 @@ func (c *Controller) getInfrastructureRoleDefinitions() []*config.Infrastructure
|
||||||
|
|
||||||
func (c *Controller) getInfrastructureRoles(
|
func (c *Controller) getInfrastructureRoles(
|
||||||
rolesSecrets []*config.InfrastructureRole) (
|
rolesSecrets []*config.InfrastructureRole) (
|
||||||
map[string]spec.PgUser, []error) {
|
map[string]spec.PgUser, error) {
|
||||||
|
|
||||||
var errors []error
|
|
||||||
var noRolesProvided = true
|
|
||||||
|
|
||||||
|
errors := make([]string, 0)
|
||||||
|
noRolesProvided := true
|
||||||
roles := []spec.PgUser{}
|
roles := []spec.PgUser{}
|
||||||
uniqRoles := map[string]spec.PgUser{}
|
uniqRoles := make(map[string]spec.PgUser)
|
||||||
|
|
||||||
// To be compatible with the legacy implementation we need to return nil if
|
// To be compatible with the legacy implementation we need to return nil if
|
||||||
// the provided secret name is empty. The equivalent situation in the
|
// the provided secret name is empty. The equivalent situation in the
|
||||||
|
|
@ -214,37 +213,39 @@ func (c *Controller) getInfrastructureRoles(
|
||||||
}
|
}
|
||||||
|
|
||||||
if noRolesProvided {
|
if noRolesProvided {
|
||||||
return nil, nil
|
return uniqRoles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, secret := range rolesSecrets {
|
for _, secret := range rolesSecrets {
|
||||||
infraRoles, err := c.getInfrastructureRole(secret)
|
infraRoles, err := c.getInfrastructureRole(secret)
|
||||||
|
|
||||||
if err != nil || infraRoles == nil {
|
if err != nil || infraRoles == nil {
|
||||||
c.logger.Debugf("Cannot get infrastructure role: %+v", *secret)
|
c.logger.Debugf("cannot get infrastructure role: %+v", *secret)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errors = append(errors, err)
|
errors = append(errors, fmt.Sprintf("%v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range infraRoles {
|
roles = append(roles, infraRoles...)
|
||||||
roles = append(roles, r)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range roles {
|
for _, r := range roles {
|
||||||
if _, exists := uniqRoles[r.Name]; exists {
|
if _, exists := uniqRoles[r.Name]; exists {
|
||||||
msg := "Conflicting infrastructure roles: roles[%s] = (%q, %q)"
|
msg := "conflicting infrastructure roles: roles[%s] = (%q, %q)"
|
||||||
c.logger.Debugf(msg, r.Name, uniqRoles[r.Name], r)
|
c.logger.Debugf(msg, r.Name, uniqRoles[r.Name], r)
|
||||||
}
|
}
|
||||||
|
|
||||||
uniqRoles[r.Name] = r
|
uniqRoles[r.Name] = r
|
||||||
}
|
}
|
||||||
|
|
||||||
return uniqRoles, errors
|
if len(errors) > 0 {
|
||||||
|
return uniqRoles, fmt.Errorf(strings.Join(errors, `', '`))
|
||||||
|
}
|
||||||
|
|
||||||
|
return uniqRoles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate list of users representing one infrastructure role based on its
|
// Generate list of users representing one infrastructure role based on its
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
b64 "encoding/base64"
|
b64 "encoding/base64"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/zalando/postgres-operator/pkg/spec"
|
"github.com/zalando/postgres-operator/pkg/spec"
|
||||||
"github.com/zalando/postgres-operator/pkg/util/config"
|
"github.com/zalando/postgres-operator/pkg/util/config"
|
||||||
"github.com/zalando/postgres-operator/pkg/util/k8sutil"
|
"github.com/zalando/postgres-operator/pkg/util/k8sutil"
|
||||||
|
|
@ -90,21 +91,21 @@ func TestClusterWorkerID(t *testing.T) {
|
||||||
// not exist, or empty) and the old format.
|
// not exist, or empty) and the old format.
|
||||||
func TestOldInfrastructureRoleFormat(t *testing.T) {
|
func TestOldInfrastructureRoleFormat(t *testing.T) {
|
||||||
var testTable = []struct {
|
var testTable = []struct {
|
||||||
secretName spec.NamespacedName
|
secretName spec.NamespacedName
|
||||||
expectedRoles map[string]spec.PgUser
|
expectedRoles map[string]spec.PgUser
|
||||||
expectedErrors []error
|
expectedError error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
// empty secret name
|
// empty secret name
|
||||||
spec.NamespacedName{},
|
spec.NamespacedName{},
|
||||||
nil,
|
map[string]spec.PgUser{},
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// secret does not exist
|
// secret does not exist
|
||||||
spec.NamespacedName{Namespace: v1.NamespaceDefault, Name: "null"},
|
spec.NamespacedName{Namespace: v1.NamespaceDefault, Name: "null"},
|
||||||
map[string]spec.PgUser{},
|
map[string]spec.PgUser{},
|
||||||
[]error{fmt.Errorf(`could not get infrastructure roles secret default/null: NotFound`)},
|
fmt.Errorf(`could not get infrastructure roles secret default/null: NotFound`),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
spec.NamespacedName{
|
spec.NamespacedName{
|
||||||
|
|
@ -129,7 +130,7 @@ func TestOldInfrastructureRoleFormat(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range testTable {
|
for _, test := range testTable {
|
||||||
roles, errors := utilTestController.getInfrastructureRoles(
|
roles, err := utilTestController.getInfrastructureRoles(
|
||||||
[]*config.InfrastructureRole{
|
[]*config.InfrastructureRole{
|
||||||
&config.InfrastructureRole{
|
&config.InfrastructureRole{
|
||||||
SecretName: test.secretName,
|
SecretName: test.secretName,
|
||||||
|
|
@ -140,22 +141,9 @@ func TestOldInfrastructureRoleFormat(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
if len(errors) != len(test.expectedErrors) {
|
if err != nil && err.Error() != test.expectedError.Error() {
|
||||||
t.Errorf("expected error '%v' does not match the actual error '%v'",
|
t.Errorf("expected error '%v' does not match the actual error '%v'",
|
||||||
test.expectedErrors, errors)
|
test.expectedError, err)
|
||||||
}
|
|
||||||
|
|
||||||
for idx := range errors {
|
|
||||||
err := errors[idx]
|
|
||||||
expectedErr := test.expectedErrors[idx]
|
|
||||||
|
|
||||||
if err != expectedErr {
|
|
||||||
if err != nil && expectedErr != nil && err.Error() == expectedErr.Error() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Errorf("expected error '%v' does not match the actual error '%v'",
|
|
||||||
expectedErr, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(roles, test.expectedRoles) {
|
if !reflect.DeepEqual(roles, test.expectedRoles) {
|
||||||
|
|
@ -169,9 +157,8 @@ func TestOldInfrastructureRoleFormat(t *testing.T) {
|
||||||
// corresponding secrets. Here we test the new format.
|
// corresponding secrets. Here we test the new format.
|
||||||
func TestNewInfrastructureRoleFormat(t *testing.T) {
|
func TestNewInfrastructureRoleFormat(t *testing.T) {
|
||||||
var testTable = []struct {
|
var testTable = []struct {
|
||||||
secrets []spec.NamespacedName
|
secrets []spec.NamespacedName
|
||||||
expectedRoles map[string]spec.PgUser
|
expectedRoles map[string]spec.PgUser
|
||||||
expectedErrors []error
|
|
||||||
}{
|
}{
|
||||||
// one secret with one configmap
|
// one secret with one configmap
|
||||||
{
|
{
|
||||||
|
|
@ -196,7 +183,6 @@ func TestNewInfrastructureRoleFormat(t *testing.T) {
|
||||||
Flags: []string{"createdb"},
|
Flags: []string{"createdb"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nil,
|
|
||||||
},
|
},
|
||||||
// multiple standalone secrets
|
// multiple standalone secrets
|
||||||
{
|
{
|
||||||
|
|
@ -224,7 +210,6 @@ func TestNewInfrastructureRoleFormat(t *testing.T) {
|
||||||
MemberOf: []string{"new-test-inrole2"},
|
MemberOf: []string{"new-test-inrole2"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nil,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range testTable {
|
for _, test := range testTable {
|
||||||
|
|
@ -239,27 +224,8 @@ func TestNewInfrastructureRoleFormat(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
roles, errors := utilTestController.getInfrastructureRoles(definitions)
|
roles, err := utilTestController.getInfrastructureRoles(definitions)
|
||||||
if len(errors) != len(test.expectedErrors) {
|
assert.NoError(t, err)
|
||||||
t.Errorf("expected error does not match the actual error:\n%+v\n%+v",
|
|
||||||
test.expectedErrors, errors)
|
|
||||||
|
|
||||||
// Stop and do not do any further checks
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for idx := range errors {
|
|
||||||
err := errors[idx]
|
|
||||||
expectedErr := test.expectedErrors[idx]
|
|
||||||
|
|
||||||
if err != expectedErr {
|
|
||||||
if err != nil && expectedErr != nil && err.Error() == expectedErr.Error() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.Errorf("expected error '%v' does not match the actual error '%v'",
|
|
||||||
expectedErr, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(roles, test.expectedRoles) {
|
if !reflect.DeepEqual(roles, test.expectedRoles) {
|
||||||
t.Errorf("expected roles output/the actual:\n%#v\n%#v",
|
t.Errorf("expected roles output/the actual:\n%#v\n%#v",
|
||||||
|
|
|
||||||
|
|
@ -212,6 +212,7 @@ type Config struct {
|
||||||
EnablePgVersionEnvVar bool `name:"enable_pgversion_env_var" default:"true"`
|
EnablePgVersionEnvVar bool `name:"enable_pgversion_env_var" default:"true"`
|
||||||
EnableSpiloWalPathCompat bool `name:"enable_spilo_wal_path_compat" default:"false"`
|
EnableSpiloWalPathCompat bool `name:"enable_spilo_wal_path_compat" default:"false"`
|
||||||
MajorVersionUpgradeMode string `name:"major_version_upgrade_mode" default:"off"`
|
MajorVersionUpgradeMode string `name:"major_version_upgrade_mode" default:"off"`
|
||||||
|
MajorVersionUpgradeTeamAllowList []string `name:"major_version_upgrade_team_allow_list" default:""`
|
||||||
MinimalMajorVersion string `name:"minimal_major_version" default:"9.6"`
|
MinimalMajorVersion string `name:"minimal_major_version" default:"9.6"`
|
||||||
TargetMajorVersion string `name:"target_major_version" default:"14"`
|
TargetMajorVersion string `name:"target_major_version" default:"14"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ func (strategy DefaultUserSyncStrategy) ProduceSyncRequests(dbUsers spec.PgUserM
|
||||||
// ExecuteSyncRequests makes actual database changes from the requests passed in its arguments.
|
// ExecuteSyncRequests makes actual database changes from the requests passed in its arguments.
|
||||||
func (strategy DefaultUserSyncStrategy) ExecuteSyncRequests(requests []spec.PgSyncUserRequest, db *sql.DB) error {
|
func (strategy DefaultUserSyncStrategy) ExecuteSyncRequests(requests []spec.PgSyncUserRequest, db *sql.DB) error {
|
||||||
var reqretries []spec.PgSyncUserRequest
|
var reqretries []spec.PgSyncUserRequest
|
||||||
var errors []string
|
errors := make([]string, 0)
|
||||||
for _, request := range requests {
|
for _, request := range requests {
|
||||||
switch request.Kind {
|
switch request.Kind {
|
||||||
case spec.PGSyncUserAdd:
|
case spec.PGSyncUserAdd:
|
||||||
|
|
@ -138,7 +138,7 @@ func (strategy DefaultUserSyncStrategy) ExecuteSyncRequests(requests []spec.PgSy
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("could not execute sync requests for users: %v", errors)
|
return fmt.Errorf("could not execute sync requests for users: %v", strings.Join(errors, `', '`))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue