4
4
"context"
5
5
"fmt"
6
6
7
+ "github.com/ydb-platform/ydb-go-sdk/v3"
7
8
corev1 "k8s.io/api/core/v1"
8
9
apierrors "k8s.io/apimachinery/pkg/api/errors"
9
10
"k8s.io/apimachinery/pkg/api/meta"
@@ -62,9 +63,76 @@ func (r *Reconciler) setInitDatabaseCompleted(
62
63
Reason : ReasonCompleted ,
63
64
Message : message ,
64
65
})
66
+ meta .SetStatusCondition (& database .Status .Conditions , metav1.Condition {
67
+ Type : CreateDatabaseOperationCondition ,
68
+ Status : metav1 .ConditionTrue ,
69
+ Reason : ReasonCompleted ,
70
+ Message : "Tenant creation operation is completed" ,
71
+ })
65
72
return r .updateStatus (ctx , database , StatusUpdateRequeueDelay )
66
73
}
67
74
75
+ func (r * Reconciler ) checkCreateTenantOperation (
76
+ ctx context.Context ,
77
+ database * resources.DatabaseBuilder ,
78
+ tenant * cms.Tenant ,
79
+ ydbOptions ydb.Option ,
80
+ ) (bool , ctrl.Result , error ) {
81
+ condition := meta .FindStatusCondition (database .Status .Conditions , CreateDatabaseOperationCondition )
82
+ if condition == nil || len (condition .Message ) == 0 {
83
+ // Something is wrong with the condition where we save operation id
84
+ // retry create tenant
85
+ meta .SetStatusCondition (& database .Status .Conditions , metav1.Condition {
86
+ Type : CreateDatabaseOperationCondition ,
87
+ Status : metav1 .ConditionTrue ,
88
+ Reason : ReasonNotRequired ,
89
+ })
90
+ return r .updateStatus (ctx , database , DatabaseInitializationRequeueDelay )
91
+ }
92
+ operationID := condition .Message
93
+ finished , operationErr , err := tenant .CheckCreateOperation (ctx , operationID , ydbOptions )
94
+ if err != nil {
95
+ r .Recorder .Event (
96
+ database ,
97
+ corev1 .EventTypeWarning ,
98
+ "InitializingFailed" ,
99
+ fmt .Sprintf ("Error creating tenant %s: %s" , tenant .Path , err ),
100
+ )
101
+ return Stop , ctrl.Result {RequeueAfter : DatabaseInitializationRequeueDelay }, err
102
+ }
103
+ if operationErr != nil {
104
+ // Creation operation failed - retry Create Tenant
105
+ r .Recorder .Event (
106
+ database ,
107
+ corev1 .EventTypeWarning ,
108
+ "InitializingFailed" ,
109
+ fmt .Sprintf ("Error creating tenant %s: %s" , tenant .Path , operationErr ),
110
+ )
111
+ meta .SetStatusCondition (& database .Status .Conditions , metav1.Condition {
112
+ Type : CreateDatabaseOperationCondition ,
113
+ Status : metav1 .ConditionTrue ,
114
+ Reason : ReasonNotRequired ,
115
+ })
116
+ return r .updateStatus (ctx , database , DatabaseInitializationRequeueDelay )
117
+ }
118
+ if ! finished {
119
+ r .Recorder .Event (
120
+ database ,
121
+ corev1 .EventTypeWarning ,
122
+ "Pending" ,
123
+ fmt .Sprintf ("Tenant creation operation is not completed, operationID: %s" , operationID ),
124
+ )
125
+ return Stop , ctrl.Result {RequeueAfter : DatabaseInitializationRequeueDelay }, nil
126
+ }
127
+ r .Recorder .Event (
128
+ database ,
129
+ corev1 .EventTypeNormal ,
130
+ "Initialized" ,
131
+ fmt .Sprintf ("Tenant %s created" , tenant .Path ),
132
+ )
133
+ return r .setInitDatabaseCompleted (ctx , database , "Database initialized successfully" )
134
+ }
135
+
68
136
func (r * Reconciler ) initializeTenant (
69
137
ctx context.Context ,
70
138
database * resources.DatabaseBuilder ,
@@ -139,8 +207,9 @@ func (r *Reconciler) initializeTenant(
139
207
return Stop , ctrl.Result {RequeueAfter : DefaultRequeueDelay }, ErrIncorrectDatabaseResourcesConfiguration
140
208
}
141
209
142
- tenant := cms.Tenant {
210
+ tenant := & cms.Tenant {
143
211
StorageEndpoint : database .Spec .StorageEndpoint ,
212
+ Domain : database .Spec .Domain ,
144
213
Path : path ,
145
214
StorageUnits : storageUnits ,
146
215
Shared : shared ,
@@ -167,19 +236,33 @@ func (r *Reconciler) initializeTenant(
167
236
)
168
237
return Stop , ctrl.Result {RequeueAfter : DefaultRequeueDelay }, err
169
238
}
239
+ ydbOpts := ydb .MergeOptions (ydb .WithCredentials (creds ), tlsOptions )
170
240
171
- err = tenant .Create (ctx , database , creds , tlsOptions )
241
+ if meta .IsStatusConditionFalse (database .Status .Conditions , CreateDatabaseOperationCondition ) {
242
+ return r .checkCreateTenantOperation (ctx , database , tenant , ydbOpts )
243
+ }
244
+ operationID , err := tenant .Create (ctx , ydb .WithCredentials (creds ), tlsOptions )
172
245
if err != nil {
173
246
r .Recorder .Event (
174
247
database ,
175
248
corev1 .EventTypeWarning ,
176
249
"InitializingFailed" ,
177
250
fmt .Sprintf ("Error creating tenant %s: %s" , tenant .Path , err ),
178
251
)
252
+ return Stop , ctrl.Result {RequeueAfter : DatabaseInitializationRequeueDelay }, err
253
+ }
254
+ if len (operationID ) > 0 {
255
+ r .Recorder .Event (
256
+ database ,
257
+ corev1 .EventTypeWarning ,
258
+ "Pending" ,
259
+ fmt .Sprintf ("Tenant creation operation in progress, operationID: %s" , operationID ),
260
+ )
179
261
meta .SetStatusCondition (& database .Status .Conditions , metav1.Condition {
180
- Type : DatabaseInitializedCondition ,
181
- Status : metav1 .ConditionFalse ,
182
- Reason : ReasonInProgress ,
262
+ Type : CreateDatabaseOperationCondition ,
263
+ Status : metav1 .ConditionFalse ,
264
+ Reason : ReasonInProgress ,
265
+ Message : operationID ,
183
266
})
184
267
return r .updateStatus (ctx , database , DatabaseInitializationRequeueDelay )
185
268
}
0 commit comments