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