mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-10-19 18:01:46 +02:00
Bootstrapped databases with best practice role setup (#843)
* PreparedDatabases with default role setup * merge changes from master * include preparedDatabases spec check when syncing databases * create a default preparedDB if not specified * add more default privileges for schemas * use empty brackets block for undefined objects * cover more default privilege scenarios and always define admin role * add DefaultUsers flag * support extensions and defaultUsers for preparedDatabases * remove exact version in deployment manifest * enable CRD validation for new field * update generated code * reflect code review * fix typo in SQL command * add documentation for preparedDatabases feature + minor changes * some datname should stay * add unit tests * reflect some feedback * init users for preparedDatabases also on update * only change DB default privileges on creation * add one more section in user docs * one more sentence
This commit is contained in:
@@ -421,6 +421,43 @@ var PostgresCRDResourceValidation = apiextv1beta1.CustomResourceValidation{
|
||||
},
|
||||
},
|
||||
},
|
||||
"preparedDatabases": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"defaultUsers": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"extensions": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"schemas": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"defaultUsers": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"defaultRoles": {
|
||||
Type: "boolean",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"replicaLoadBalancer": {
|
||||
Type: "boolean",
|
||||
Description: "Deprecated",
|
||||
|
||||
@@ -50,24 +50,25 @@ type PostgresSpec struct {
|
||||
// load balancers' source ranges are the same for master and replica services
|
||||
AllowedSourceRanges []string `json:"allowedSourceRanges"`
|
||||
|
||||
NumberOfInstances int32 `json:"numberOfInstances"`
|
||||
Users map[string]UserFlags `json:"users"`
|
||||
MaintenanceWindows []MaintenanceWindow `json:"maintenanceWindows,omitempty"`
|
||||
Clone CloneDescription `json:"clone"`
|
||||
ClusterName string `json:"-"`
|
||||
Databases map[string]string `json:"databases,omitempty"`
|
||||
Tolerations []v1.Toleration `json:"tolerations,omitempty"`
|
||||
Sidecars []Sidecar `json:"sidecars,omitempty"`
|
||||
InitContainers []v1.Container `json:"initContainers,omitempty"`
|
||||
PodPriorityClassName string `json:"podPriorityClassName,omitempty"`
|
||||
ShmVolume *bool `json:"enableShmVolume,omitempty"`
|
||||
EnableLogicalBackup bool `json:"enableLogicalBackup,omitempty"`
|
||||
LogicalBackupSchedule string `json:"logicalBackupSchedule,omitempty"`
|
||||
StandbyCluster *StandbyDescription `json:"standby"`
|
||||
PodAnnotations map[string]string `json:"podAnnotations"`
|
||||
ServiceAnnotations map[string]string `json:"serviceAnnotations"`
|
||||
TLS *TLSDescription `json:"tls"`
|
||||
AdditionalVolumes []AdditionalVolume `json:"additionalVolumes,omitempty"`
|
||||
NumberOfInstances int32 `json:"numberOfInstances"`
|
||||
Users map[string]UserFlags `json:"users"`
|
||||
MaintenanceWindows []MaintenanceWindow `json:"maintenanceWindows,omitempty"`
|
||||
Clone CloneDescription `json:"clone"`
|
||||
ClusterName string `json:"-"`
|
||||
Databases map[string]string `json:"databases,omitempty"`
|
||||
PreparedDatabases map[string]PreparedDatabase `json:"preparedDatabases,omitempty"`
|
||||
Tolerations []v1.Toleration `json:"tolerations,omitempty"`
|
||||
Sidecars []Sidecar `json:"sidecars,omitempty"`
|
||||
InitContainers []v1.Container `json:"initContainers,omitempty"`
|
||||
PodPriorityClassName string `json:"podPriorityClassName,omitempty"`
|
||||
ShmVolume *bool `json:"enableShmVolume,omitempty"`
|
||||
EnableLogicalBackup bool `json:"enableLogicalBackup,omitempty"`
|
||||
LogicalBackupSchedule string `json:"logicalBackupSchedule,omitempty"`
|
||||
StandbyCluster *StandbyDescription `json:"standby"`
|
||||
PodAnnotations map[string]string `json:"podAnnotations"`
|
||||
ServiceAnnotations map[string]string `json:"serviceAnnotations"`
|
||||
TLS *TLSDescription `json:"tls"`
|
||||
AdditionalVolumes []AdditionalVolume `json:"additionalVolumes,omitempty"`
|
||||
|
||||
// deprecated json tags
|
||||
InitContainersOld []v1.Container `json:"init_containers,omitempty"`
|
||||
@@ -84,6 +85,19 @@ type PostgresqlList struct {
|
||||
Items []Postgresql `json:"items"`
|
||||
}
|
||||
|
||||
// PreparedDatabase describes elements to be bootstrapped
|
||||
type PreparedDatabase struct {
|
||||
PreparedSchemas map[string]PreparedSchema `json:"schemas,omitempty"`
|
||||
DefaultUsers bool `json:"defaultUsers,omitempty" defaults:"false"`
|
||||
Extensions map[string]string `json:"extensions,omitempty"`
|
||||
}
|
||||
|
||||
// PreparedSchema describes elements to be bootstrapped per schema
|
||||
type PreparedSchema struct {
|
||||
DefaultRoles *bool `json:"defaultRoles,omitempty" defaults:"true"`
|
||||
DefaultUsers bool `json:"defaultUsers,omitempty" defaults:"false"`
|
||||
}
|
||||
|
||||
// MaintenanceWindow describes the time window when the operator is allowed to do maintenance on a cluster.
|
||||
type MaintenanceWindow struct {
|
||||
Everyday bool
|
||||
|
||||
@@ -570,6 +570,13 @@ func (in *PostgresSpec) DeepCopyInto(out *PostgresSpec) {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.PreparedDatabases != nil {
|
||||
in, out := &in.PreparedDatabases, &out.PreparedDatabases
|
||||
*out = make(map[string]PreparedDatabase, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.Tolerations != nil {
|
||||
in, out := &in.Tolerations, &out.Tolerations
|
||||
*out = make([]corev1.Toleration, len(*in))
|
||||
@@ -763,6 +770,57 @@ func (in *PostgresqlParam) DeepCopy() *PostgresqlParam {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PreparedDatabase) DeepCopyInto(out *PreparedDatabase) {
|
||||
*out = *in
|
||||
if in.PreparedSchemas != nil {
|
||||
in, out := &in.PreparedSchemas, &out.PreparedSchemas
|
||||
*out = make(map[string]PreparedSchema, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.Extensions != nil {
|
||||
in, out := &in.Extensions, &out.Extensions
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreparedDatabase.
|
||||
func (in *PreparedDatabase) DeepCopy() *PreparedDatabase {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PreparedDatabase)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PreparedSchema) DeepCopyInto(out *PreparedSchema) {
|
||||
*out = *in
|
||||
if in.DefaultRoles != nil {
|
||||
in, out := &in.DefaultRoles, &out.DefaultRoles
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreparedSchema.
|
||||
func (in *PreparedSchema) DeepCopy() *PreparedSchema {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PreparedSchema)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceDescription) DeepCopyInto(out *ResourceDescription) {
|
||||
*out = *in
|
||||
|
||||
Reference in New Issue
Block a user