@@ -13,7 +13,6 @@ import (
13
13
"sync"
14
14
"time"
15
15
16
- jsonpatch "github.com/evanphx/json-patch"
17
16
"github.com/sirupsen/logrus"
18
17
acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
19
18
@@ -248,9 +247,10 @@ func (c *Cluster) Create() (err error) {
248
247
defer c .mu .Unlock ()
249
248
250
249
var (
251
- service * v1.Service
252
- ep * v1.Endpoints
253
- ss * appsv1.StatefulSet
250
+ pgCreateStatus * acidv1.Postgresql
251
+ service * v1.Service
252
+ ep * v1.Endpoints
253
+ ss * appsv1.StatefulSet
254
254
)
255
255
256
256
defer func () {
@@ -261,11 +261,15 @@ func (c *Cluster) Create() (err error) {
261
261
}
262
262
}()
263
263
264
- c .KubeClient .SetPostgresCRDStatus (c .clusterName (), acidv1 .ClusterStatusCreating )
264
+ pgCreateStatus , err = c .KubeClient .SetPostgresCRDStatus (c .clusterName (), acidv1 .ClusterStatusCreating )
265
+ if err != nil {
266
+ return fmt .Errorf ("could not set cluster status: %v" , err )
267
+ }
268
+ c .setSpec (pgCreateStatus )
269
+
265
270
if c .OpConfig .EnableFinalizers != nil && * c .OpConfig .EnableFinalizers {
266
- c .logger .Info ("Adding finalizer." )
267
- if err = c .AddFinalizer (); err != nil {
268
- return fmt .Errorf ("could not add Finalizer: %v" , err )
271
+ if err = c .addFinalizer (); err != nil {
272
+ return fmt .Errorf ("could not add finalizer: %v" , err )
269
273
}
270
274
}
271
275
c .eventRecorder .Event (c .GetReference (), v1 .EventTypeNormal , "Create" , "Started creation of new cluster resources" )
@@ -771,60 +775,45 @@ func (c *Cluster) compareServices(old, new *v1.Service) (bool, string) {
771
775
return true , ""
772
776
}
773
777
774
- // AddFinalizer patches the postgresql CR to add our finalizer.
775
- func (c * Cluster ) AddFinalizer () error {
776
- if c .HasFinalizer () {
777
- c .logger .Debugf ("Finalizer %s already exists." , finalizerName )
778
+ // addFinalizer patches the postgresql CR to add finalizer
779
+ func (c * Cluster ) addFinalizer () error {
780
+ if c .hasFinalizer () {
778
781
return nil
779
782
}
780
783
781
- currentSpec := c .DeepCopy ()
782
- newSpec := c .DeepCopy ()
783
- newSpec .ObjectMeta .SetFinalizers (append (newSpec .ObjectMeta .Finalizers , finalizerName ))
784
- patchBytes , err := getPatchBytes (currentSpec , newSpec )
785
- if err != nil {
786
- return fmt .Errorf ("Unable to produce patch to add finalizer: %v" , err )
787
- }
788
-
789
- updatedSpec , err := c .KubeClient .AcidV1ClientSet .AcidV1 ().Postgresqls (c .clusterNamespace ()).Patch (
790
- context .TODO (), c .Name , types .MergePatchType , patchBytes , metav1.PatchOptions {})
784
+ c .logger .Infof ("adding finalizer %s" , finalizerName )
785
+ finalizers := append (c .ObjectMeta .Finalizers , finalizerName )
786
+ newSpec , err := c .KubeClient .SetFinalizer (c .clusterName (), c .DeepCopy (), finalizers )
791
787
if err != nil {
792
- return fmt .Errorf ("Could not add finalizer: %v" , err )
788
+ return fmt .Errorf ("error adding finalizer: %v" , err )
793
789
}
794
790
795
- // update the spec, maintaining the new resourceVersion.
796
- c .setSpec (updatedSpec )
791
+ // update the spec, maintaining the new resourceVersion
792
+ c .setSpec (newSpec )
797
793
return nil
798
794
}
799
795
800
- // RemoveFinalizer patches postgresql CR to remove finalizer.
801
- func (c * Cluster ) RemoveFinalizer () error {
802
- if ! c .HasFinalizer () {
803
- c .logger .Debugf ("No finalizer %s exists to remove." , finalizerName )
796
+ // removeFinalizer patches postgresql CR to remove finalizer
797
+ func (c * Cluster ) removeFinalizer () error {
798
+ if ! c .hasFinalizer () {
804
799
return nil
805
800
}
806
- currentSpec := c .DeepCopy ()
807
- newSpec := c .DeepCopy ()
808
- newSpec .ObjectMeta .SetFinalizers (removeString (newSpec .ObjectMeta .Finalizers , finalizerName ))
809
- patchBytes , err := getPatchBytes (currentSpec , newSpec )
810
- if err != nil {
811
- return fmt .Errorf ("Unable to produce patch to remove finalizer: %v" , err )
812
- }
813
801
814
- updatedSpec , err := c .KubeClient .AcidV1ClientSet .AcidV1 ().Postgresqls (c .clusterNamespace ()).Patch (
815
- context .TODO (), c .Name , types .MergePatchType , patchBytes , metav1.PatchOptions {})
802
+ c .logger .Infof ("removing finalizer %s" , finalizerName )
803
+ finalizers := util .RemoveString (c .ObjectMeta .Finalizers , finalizerName )
804
+ newSpec , err := c .KubeClient .SetFinalizer (c .clusterName (), c .DeepCopy (), finalizers )
816
805
if err != nil {
817
- return fmt .Errorf ("Could not remove finalizer: %v" , err )
806
+ return fmt .Errorf ("error removing finalizer: %v" , err )
818
807
}
819
808
820
809
// update the spec, maintaining the new resourceVersion.
821
- c .setSpec (updatedSpec )
810
+ c .setSpec (newSpec )
822
811
823
812
return nil
824
813
}
825
814
826
- // HasFinalizer checks if our finalizer is currently set or not
827
- func (c * Cluster ) HasFinalizer () bool {
815
+ // hasFinalizer checks if finalizer is currently set or not
816
+ func (c * Cluster ) hasFinalizer () bool {
828
817
for _ , finalizer := range c .ObjectMeta .Finalizers {
829
818
if finalizer == finalizerName {
830
819
return true
@@ -833,36 +822,6 @@ func (c *Cluster) HasFinalizer() bool {
833
822
return false
834
823
}
835
824
836
- // Iterate through slice and remove certain string, then return cleaned slice
837
- func removeString (slice []string , s string ) (result []string ) {
838
- for _ , item := range slice {
839
- if item == s {
840
- continue
841
- }
842
- result = append (result , item )
843
- }
844
- return result
845
- }
846
-
847
- // getPatchBytes will produce a JSONpatch between the two parameters of type acidv1.Postgresql
848
- func getPatchBytes (oldSpec , newSpec * acidv1.Postgresql ) ([]byte , error ) {
849
- oldData , err := json .Marshal (oldSpec )
850
- if err != nil {
851
- return nil , fmt .Errorf ("failed to Marshal oldSpec for postgresql %s/%s: %v" , oldSpec .Namespace , oldSpec .Name , err )
852
- }
853
-
854
- newData , err := json .Marshal (newSpec )
855
- if err != nil {
856
- return nil , fmt .Errorf ("failed to Marshal newSpec for postgresql %s/%s: %v" , newSpec .Namespace , newSpec .Name , err )
857
- }
858
-
859
- patchBytes , err := jsonpatch .CreateMergePatch (oldData , newData )
860
- if err != nil {
861
- return nil , fmt .Errorf ("failed to CreateMergePatch for postgresl %s/%s: %v" , oldSpec .Namespace , oldSpec .Name , err )
862
- }
863
- return patchBytes , nil
864
- }
865
-
866
825
// Update changes Kubernetes objects according to the new specification. Unlike the sync case, the missing object
867
826
// (i.e. service) is treated as an error
868
827
// logical backup cron jobs are an exception: a user-initiated Update can enable a logical backup job
@@ -1106,40 +1065,41 @@ func syncResources(a, b *v1.ResourceRequirements) bool {
1106
1065
// before the pods, it will be re-created by the current master pod and will remain, obstructing the
1107
1066
// creation of the new cluster with the same name. Therefore, the endpoints should be deleted last.
1108
1067
func (c * Cluster ) Delete () error {
1068
+ var anyErrors = false
1109
1069
c .mu .Lock ()
1110
1070
defer c .mu .Unlock ()
1111
1071
c .eventRecorder .Event (c .GetReference (), v1 .EventTypeNormal , "Delete" , "Started deletion of cluster resources" )
1112
1072
1113
1073
if err := c .deleteStreams (); err != nil {
1074
+ anyErrors = true
1114
1075
c .logger .Warningf ("could not delete event streams: %v" , err )
1115
- c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "Could not delete event streams: %v" , err )
1076
+ c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "could not delete event streams: %v" , err )
1116
1077
}
1117
- var anyErrors = false
1118
1078
1119
1079
// delete the backup job before the stateful set of the cluster to prevent connections to non-existing pods
1120
1080
// deleting the cron job also removes pods and batch jobs it created
1121
1081
if err := c .deleteLogicalBackupJob (); err != nil {
1122
1082
anyErrors = true
1123
1083
c .logger .Warningf ("could not remove the logical backup k8s cron job; %v" , err )
1124
- c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "Could not remove the logical backup k8s cron job; %v" , err )
1084
+ c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "could not remove the logical backup k8s cron job; %v" , err )
1125
1085
}
1126
1086
1127
1087
if err := c .deleteStatefulSet (); err != nil {
1128
1088
anyErrors = true
1129
1089
c .logger .Warningf ("could not delete statefulset: %v" , err )
1130
- c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "Could not delete statefulset: %v" , err )
1090
+ c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "could not delete statefulset: %v" , err )
1131
1091
}
1132
1092
1133
1093
if err := c .deleteSecrets (); err != nil {
1134
1094
anyErrors = true
1135
1095
c .logger .Warningf ("could not delete secrets: %v" , err )
1136
- c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "Could not delete secrets: %v" , err )
1096
+ c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "could not delete secrets: %v" , err )
1137
1097
}
1138
1098
1139
1099
if err := c .deletePodDisruptionBudget (); err != nil {
1140
1100
anyErrors = true
1141
1101
c .logger .Warningf ("could not delete pod disruption budget: %v" , err )
1142
- c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "Could not delete pod disruption budget: %v" , err )
1102
+ c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "could not delete pod disruption budget: %v" , err )
1143
1103
}
1144
1104
1145
1105
for _ , role := range []PostgresRole {Master , Replica } {
@@ -1148,21 +1108,21 @@ func (c *Cluster) Delete() error {
1148
1108
if err := c .deleteEndpoint (role ); err != nil {
1149
1109
anyErrors = true
1150
1110
c .logger .Warningf ("could not delete %s endpoint: %v" , role , err )
1151
- c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "Could not delete %s endpoint: %v" , role , err )
1111
+ c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "could not delete %s endpoint: %v" , role , err )
1152
1112
}
1153
1113
}
1154
1114
1155
1115
if err := c .deleteService (role ); err != nil {
1156
1116
anyErrors = true
1157
1117
c .logger .Warningf ("could not delete %s service: %v" , role , err )
1158
- c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "Could not delete %s service: %v" , role , err )
1118
+ c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "could not delete %s service: %v" , role , err )
1159
1119
}
1160
1120
}
1161
1121
1162
1122
if err := c .deletePatroniClusterObjects (); err != nil {
1163
1123
anyErrors = true
1164
1124
c .logger .Warningf ("could not remove leftover patroni objects; %v" , err )
1165
- c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "Could not remove leftover patroni objects; %v" , err )
1125
+ c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "could not remove leftover patroni objects; %v" , err )
1166
1126
}
1167
1127
1168
1128
// Delete connection pooler objects anyway, even if it's not mentioned in the
@@ -1172,20 +1132,19 @@ func (c *Cluster) Delete() error {
1172
1132
if err := c .deleteConnectionPooler (role ); err != nil {
1173
1133
anyErrors = true
1174
1134
c .logger .Warningf ("could not remove connection pooler: %v" , err )
1175
- c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "Could not remove connection pooler: %v" , err )
1135
+ c .eventRecorder .Eventf (c .GetReference (), v1 .EventTypeWarning , "Delete" , "could not remove connection pooler: %v" , err )
1176
1136
}
1177
1137
}
1178
1138
1179
1139
// If we are done deleting our various resources we remove the finalizer to let K8S finally delete the Postgres CR
1180
1140
if anyErrors {
1181
- c .eventRecorder .Event (c .GetReference (), v1 .EventTypeWarning , "Delete" , "Some resources could be successfully deleted yet" )
1141
+ c .eventRecorder .Event (c .GetReference (), v1 .EventTypeWarning , "Delete" , "some resources could be successfully deleted yet" )
1182
1142
return fmt .Errorf ("some error(s) occured when deleting resources, NOT removing finalizer yet" )
1183
1143
}
1184
- if err := c .RemoveFinalizer (); err != nil {
1185
- return fmt .Errorf ("Done cleaning up, but error when trying to remove our finalizer: %v" , err )
1144
+ if err := c .removeFinalizer (); err != nil {
1145
+ return fmt .Errorf ("done cleaning up, but error when removing finalizer: %v" , err )
1186
1146
}
1187
1147
1188
- c .logger .Info ("Done cleaning up our resources, removed finalizer." )
1189
1148
return nil
1190
1149
}
1191
1150
0 commit comments