diff --git a/pkg/apis/acid.zalan.do/v1/const.go b/pkg/apis/acid.zalan.do/v1/const.go index 59d6c1406..4972ab848 100644 --- a/pkg/apis/acid.zalan.do/v1/const.go +++ b/pkg/apis/acid.zalan.do/v1/const.go @@ -2,14 +2,14 @@ package v1 // ClusterStatusUnknown etc : status of a Postgres cluster known to the operator const ( - ClusterStatusUnknown PostgresStatus = "" - ClusterStatusCreating PostgresStatus = "Creating" - ClusterStatusUpdating PostgresStatus = "Updating" - ClusterStatusUpdateFailed PostgresStatus = "UpdateFailed" - ClusterStatusSyncFailed PostgresStatus = "SyncFailed" - ClusterStatusAddFailed PostgresStatus = "CreateFailed" - ClusterStatusRunning PostgresStatus = "Running" - ClusterStatusInvalid PostgresStatus = "Invalid" + ClusterStatusUnknown PostgresClusterStatus = "" + ClusterStatusCreating PostgresClusterStatus = "Creating" + ClusterStatusUpdating PostgresClusterStatus = "Updating" + ClusterStatusUpdateFailed PostgresClusterStatus = "UpdateFailed" + ClusterStatusSyncFailed PostgresClusterStatus = "SyncFailed" + ClusterStatusAddFailed PostgresClusterStatus = "CreateFailed" + ClusterStatusRunning PostgresClusterStatus = "Running" + ClusterStatusInvalid PostgresClusterStatus = "Invalid" ) const ( diff --git a/pkg/apis/acid.zalan.do/v1/marshal.go b/pkg/apis/acid.zalan.do/v1/marshal.go index d53db0290..4dc6e5369 100644 --- a/pkg/apis/acid.zalan.do/v1/marshal.go +++ b/pkg/apis/acid.zalan.do/v1/marshal.go @@ -81,7 +81,7 @@ func (p *Postgresql) UnmarshalJSON(data []byte) error { } tmp.Error = err.Error() - tmp.PostgresClusterStatus = ClusterStatusInvalid + tmp.Status = PostgresStatus{PostgresClusterStatus: ClusterStatusInvalid} *p = Postgresql(tmp) @@ -91,10 +91,10 @@ func (p *Postgresql) UnmarshalJSON(data []byte) error { if clusterName, err := extractClusterName(tmp2.ObjectMeta.Name, tmp2.Spec.TeamID); err != nil { tmp2.Error = err.Error() - tmp2.PostgresClusterStatus = ClusterStatusInvalid + tmp2.Status = PostgresStatus{PostgresClusterStatus: ClusterStatusInvalid} } else if err := validateCloneClusterDescription(&tmp2.Spec.Clone); err != nil { tmp2.Error = err.Error() - tmp2.PostgresClusterStatus = ClusterStatusInvalid + tmp2.Status = PostgresStatus{PostgresClusterStatus: ClusterStatusInvalid} } else { tmp2.Spec.ClusterName = clusterName } diff --git a/pkg/apis/acid.zalan.do/v1/postgresql_type.go b/pkg/apis/acid.zalan.do/v1/postgresql_type.go index 3f669a8dc..75f57e011 100644 --- a/pkg/apis/acid.zalan.do/v1/postgresql_type.go +++ b/pkg/apis/acid.zalan.do/v1/postgresql_type.go @@ -15,9 +15,9 @@ type Postgresql struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec PostgresSpec `json:"spec"` - PostgresClusterStatus PostgresStatus `json:"status,omitempty"` - Error string `json:"-"` + Spec PostgresSpec `json:"spec"` + Status PostgresStatus `json:"status,omitempty"` + Error string `json:"-"` } // PostgresSpec defines the specification for the PostgreSQL TPR. @@ -129,4 +129,9 @@ type Sidecar struct { type UserFlags []string // PostgresStatus contains status of the PostgreSQL cluster (running, creation failed etc.) -type PostgresStatus string +type PostgresStatus struct { + PostgresClusterStatus PostgresClusterStatus `json:"PostgresClusterStatus"` +} + +// PostgresClusterStatus defines the status of the PostgreSQL cluster (running, creation failed etc.) +type PostgresClusterStatus string diff --git a/pkg/apis/acid.zalan.do/v1/util.go b/pkg/apis/acid.zalan.do/v1/util.go index 6e0a9d863..68c9e7427 100644 --- a/pkg/apis/acid.zalan.do/v1/util.go +++ b/pkg/apis/acid.zalan.do/v1/util.go @@ -85,12 +85,12 @@ func validateCloneClusterDescription(clone *CloneDescription) error { } // Success of the current Status -func (postgresClusterStatus PostgresStatus) Success() bool { - return postgresClusterStatus != ClusterStatusAddFailed && - postgresClusterStatus != ClusterStatusUpdateFailed && - postgresClusterStatus != ClusterStatusSyncFailed +func (postgresStatus PostgresStatus) Success() bool { + return postgresStatus.PostgresClusterStatus != ClusterStatusAddFailed && + postgresStatus.PostgresClusterStatus != ClusterStatusUpdateFailed && + postgresStatus.PostgresClusterStatus != ClusterStatusSyncFailed } -func (postgresClusterStatus PostgresStatus) String() string { - return string(postgresClusterStatus) +func (postgresStatus PostgresStatus) String() string { + return string(postgresStatus.PostgresClusterStatus) } diff --git a/pkg/apis/acid.zalan.do/v1/util_test.go b/pkg/apis/acid.zalan.do/v1/util_test.go index cb5e1298e..fcb8042e6 100644 --- a/pkg/apis/acid.zalan.do/v1/util_test.go +++ b/pkg/apis/acid.zalan.do/v1/util_test.go @@ -128,11 +128,11 @@ var unmarshalCluster = []struct { ObjectMeta: metav1.ObjectMeta{ Name: "acid-testcluster1", }, - PostgresClusterStatus: ClusterStatusInvalid, + Status: PostgresStatus{PostgresClusterStatus: ClusterStatusInvalid}, // This error message can vary between Go versions, so compute it for the current version. Error: json.Unmarshal([]byte(`{"teamId": 0}`), &PostgresSpec{}).Error(), }, - []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"","parameters":null},"volume":{"size":"","storageClass":""},"patroni":{"initdb":null,"pg_hba":null,"ttl":0,"loop_wait":0,"retry_timeout":0,"maximum_lag_on_failover":0,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{}},"status":"Invalid"}`), nil}, + []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"","parameters":null},"volume":{"size":"","storageClass":""},"patroni":{"initdb":null,"pg_hba":null,"ttl":0,"loop_wait":0,"retry_timeout":0,"maximum_lag_on_failover":0,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{}},"status":{"PostgresClusterStatus":"Invalid"}}`), nil}, {[]byte(`{ "kind": "Postgresql", "apiVersion": "acid.zalan.do/v1", @@ -273,7 +273,7 @@ var unmarshalCluster = []struct { }, Error: "", }, - []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"9.6","parameters":{"log_statement":"all","max_connections":"10","shared_buffers":"32MB"}},"volume":{"size":"5Gi","storageClass":"SSD"},"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"}}}`), nil}, + []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"9.6","parameters":{"log_statement":"all","max_connections":"10","shared_buffers":"32MB"}},"volume":{"size":"5Gi","storageClass":"SSD"},"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":""}}`), nil}, { []byte(`{"kind": "Postgresql","apiVersion": "acid.zalan.do/v1","metadata": {"name": "teapot-testcluster1"}, "spec": {"teamId": "acid"}}`), Postgresql{ @@ -284,11 +284,11 @@ var unmarshalCluster = []struct { ObjectMeta: metav1.ObjectMeta{ Name: "teapot-testcluster1", }, - Spec: PostgresSpec{TeamID: "acid"}, - PostgresClusterStatus: ClusterStatusInvalid, - Error: errors.New("name must match {TEAM}-{NAME} format").Error(), + Spec: PostgresSpec{TeamID: "acid"}, + Status: PostgresStatus{PostgresClusterStatus: ClusterStatusInvalid}, + Error: errors.New("name must match {TEAM}-{NAME} format").Error(), }, - []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"teapot-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"","parameters":null},"volume":{"size":"","storageClass":""},"patroni":{"initdb":null,"pg_hba":null,"ttl":0,"loop_wait":0,"retry_timeout":0,"maximum_lag_on_failover":0,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"acid","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{}},"status":"Invalid"}`), nil}, + []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"teapot-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"","parameters":null},"volume":{"size":"","storageClass":""},"patroni":{"initdb":null,"pg_hba":null,"ttl":0,"loop_wait":0,"retry_timeout":0,"maximum_lag_on_failover":0,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"acid","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{}},"status":{"PostgresClusterStatus":"Invalid"}}`), nil}, { in: []byte(`{"kind": "Postgresql","apiVersion": "acid.zalan.do/v1","metadata": {"name": "acid-testcluster1"}, "spec": {"teamId": "acid", "clone": {"cluster": "team-batman"}}}`), out: Postgresql{ @@ -308,12 +308,12 @@ var unmarshalCluster = []struct { }, Error: "", }, - marshal: []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"","parameters":null},"volume":{"size":"","storageClass":""},"patroni":{"initdb":null,"pg_hba":null,"ttl":0,"loop_wait":0,"retry_timeout":0,"maximum_lag_on_failover":0,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"acid","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{"cluster":"team-batman"}}}`), err: nil}, + marshal: []byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster1","creationTimestamp":null},"spec":{"postgresql":{"version":"","parameters":null},"volume":{"size":"","storageClass":""},"patroni":{"initdb":null,"pg_hba":null,"ttl":0,"loop_wait":0,"retry_timeout":0,"maximum_lag_on_failover":0,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"acid","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{"cluster":"team-batman"}},"status":{"PostgresClusterStatus":""}}`), err: nil}, {[]byte(`{"kind": "Postgresql","apiVersion": "acid.zalan.do/v1"`), Postgresql{}, []byte{}, errors.New("unexpected end of JSON input")}, - {[]byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster","creationTimestamp":qaz},"spec":{"postgresql":{"version":"","parameters":null},"volume":{"size":"","storageClass":""},"patroni":{"initdb":null,"pg_hba":null,"ttl":0,"loop_wait":0,"retry_timeout":0,"maximum_lag_on_failover":0,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"acid","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{}},"status":"Invalid"}`), + {[]byte(`{"kind":"Postgresql","apiVersion":"acid.zalan.do/v1","metadata":{"name":"acid-testcluster","creationTimestamp":qaz},"spec":{"postgresql":{"version":"","parameters":null},"volume":{"size":"","storageClass":""},"patroni":{"initdb":null,"pg_hba":null,"ttl":0,"loop_wait":0,"retry_timeout":0,"maximum_lag_on_failover":0,"slots":null},"resources":{"requests":{"cpu":"","memory":""},"limits":{"cpu":"","memory":""}},"teamId":"acid","allowedSourceRanges":null,"numberOfInstances":0,"users":null,"clone":{}},"status":{"PostgresClusterStatus":"Invalid"}}`), Postgresql{}, []byte{}, errors.New("invalid character 'q' looking for beginning of value")}} @@ -350,8 +350,10 @@ var postgresqlList = []struct { AllowedSourceRanges: []string{"185.85.220.0/22"}, NumberOfInstances: 1, }, - PostgresClusterStatus: ClusterStatusRunning, - Error: "", + Status: PostgresStatus{ + PostgresClusterStatus: ClusterStatusRunning, + }, + Error: "", }}, }, nil}, diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index 66a65cf18..fe17f6b96 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -149,13 +149,13 @@ func (c *Cluster) setProcessName(procName string, args ...interface{}) { } } -func (c *Cluster) setPostgresClusterStatus(postgresClusterStatus acidv1.PostgresStatus) { +func (c *Cluster) setStatus(status acidv1.PostgresClusterStatus) { // TODO: eventually switch to updateStatus() for kubernetes 1.11 and above var ( err error b []byte ) - if b, err = json.Marshal(postgresClusterStatus); err != nil { + if b, err = json.Marshal(status); err != nil { c.logger.Errorf("could not marshal Postgres cluster status: %v", err) } @@ -172,7 +172,7 @@ func (c *Cluster) setPostgresClusterStatus(postgresClusterStatus acidv1.Postgres } func (c *Cluster) isNewCluster() bool { - return c.PostgresClusterStatus == acidv1.ClusterStatusCreating + return c.Status == acidv1.PostgresStatus{PostgresClusterStatus: acidv1.ClusterStatusCreating} } // initUsers populates c.systemUsers and c.pgUsers maps. @@ -214,13 +214,13 @@ func (c *Cluster) Create() error { defer func() { if err == nil { - c.setPostgresClusterStatus(acidv1.ClusterStatusRunning) //TODO: are you sure it's running? + c.setStatus(acidv1.ClusterStatusRunning) //TODO: are you sure it's running? } else { - c.setPostgresClusterStatus(acidv1.ClusterStatusAddFailed) + c.setStatus(acidv1.ClusterStatusAddFailed) } }() - c.setPostgresClusterStatus(acidv1.ClusterStatusCreating) + c.setStatus(acidv1.ClusterStatusCreating) for _, role := range []PostgresRole{Master, Replica} { @@ -487,14 +487,14 @@ func (c *Cluster) Update(oldSpec, newSpec *acidv1.Postgresql) error { c.mu.Lock() defer c.mu.Unlock() - c.setPostgresClusterStatus(acidv1.ClusterStatusUpdating) + c.setStatus(acidv1.ClusterStatusUpdating) c.setSpec(newSpec) defer func() { if updateFailed { - c.setPostgresClusterStatus(acidv1.ClusterStatusUpdateFailed) + c.setStatus(acidv1.ClusterStatusUpdateFailed) } else { - c.setPostgresClusterStatus(acidv1.ClusterStatusRunning) + c.setStatus(acidv1.ClusterStatusRunning) } }() @@ -633,7 +633,7 @@ func (c *Cluster) Delete() { func (c *Cluster) NeedsRepair() (bool, acidv1.PostgresStatus) { c.specMu.RLock() defer c.specMu.RUnlock() - return !c.PostgresClusterStatus.Success(), c.PostgresClusterStatus + return !c.Status.Success(), c.Status } @@ -853,12 +853,12 @@ func (c *Cluster) GetCurrentProcess() Process { } // GetStatus provides status of the cluster -func (c *Cluster) GetPostgresClusterStatus() *ClusterStatus { +func (c *Cluster) GetStatus() *ClusterStatus { return &ClusterStatus{ - Cluster: c.Spec.ClusterName, - Team: c.Spec.TeamID, - PostgresClusterStatus: c.PostgresClusterStatus, - Spec: c.Spec, + Cluster: c.Spec.ClusterName, + Team: c.Spec.TeamID, + Status: c.Status, + Spec: c.Spec, MasterService: c.GetServiceMaster(), ReplicaService: c.GetServiceReplica(), diff --git a/pkg/cluster/sync.go b/pkg/cluster/sync.go index 7a3ea169a..272347d01 100644 --- a/pkg/cluster/sync.go +++ b/pkg/cluster/sync.go @@ -27,9 +27,9 @@ func (c *Cluster) Sync(newSpec *acidv1.Postgresql) error { defer func() { if err != nil { c.logger.Warningf("error while syncing cluster state: %v", err) - c.setPostgresClusterStatus(acidv1.ClusterStatusSyncFailed) - } else if c.PostgresClusterStatus != acidv1.ClusterStatusRunning { - c.setPostgresClusterStatus(acidv1.ClusterStatusRunning) + c.setStatus(acidv1.ClusterStatusSyncFailed) + } else if (c.Status != acidv1.PostgresStatus{PostgresClusterStatus: acidv1.ClusterStatusRunning}) { + c.setStatus(acidv1.ClusterStatusRunning) } }() diff --git a/pkg/cluster/types.go b/pkg/cluster/types.go index 43ca75dd9..5fd5029db 100644 --- a/pkg/cluster/types.go +++ b/pkg/cluster/types.go @@ -63,9 +63,9 @@ type ClusterStatus struct { StatefulSet *v1beta1.StatefulSet PodDisruptionBudget *policybeta1.PodDisruptionBudget - CurrentProcess Process - Worker uint32 - PostgresClusterStatus acidv1.PostgresStatus - Spec acidv1.PostgresSpec - Error error + CurrentProcess Process + Worker uint32 + Status acidv1.PostgresStatus + Spec acidv1.PostgresSpec + Error error } diff --git a/pkg/controller/logs_and_api.go b/pkg/controller/logs_and_api.go index 36484d1a9..24e73fabe 100644 --- a/pkg/controller/logs_and_api.go +++ b/pkg/controller/logs_and_api.go @@ -29,7 +29,7 @@ func (c *Controller) ClusterStatus(team, namespace, cluster string) (*cluster.Cl return nil, fmt.Errorf("could not find cluster") } - status := cl.GetPostgresClusterStatus() + status := cl.GetStatus() status.Worker = c.clusterWorkerID(clusterName) return status, nil diff --git a/pkg/controller/postgresql.go b/pkg/controller/postgresql.go index b3333491f..dc082ffab 100644 --- a/pkg/controller/postgresql.go +++ b/pkg/controller/postgresql.go @@ -89,7 +89,7 @@ func (c *Controller) queueEvents(list *acidv1.PostgresqlList, event EventType) { activeClustersCnt++ // check if that cluster needs repair if event == EventRepair { - if pg.PostgresClusterStatus.Success() { + if pg.Status.Success() { continue } else { clustersToRepair++