@@ -106,6 +106,16 @@ func checkForUnexpectedFieldChange(a, b operatorsv1alpha1.Operator) bool {
106
106
func (r * OperatorReconciler ) reconcile (ctx context.Context , op * operatorsv1alpha1.Operator ) (ctrl.Result , error ) {
107
107
// validate spec
108
108
if err := validators .ValidateOperatorSpec (op ); err != nil {
109
+ // Set the TypeInstalled condition to Unknown to indicate that the resolution
110
+ // hasn't been attempted yet, due to the spec being invalid.
111
+ op .Status .InstalledBundleSource = ""
112
+ apimeta .SetStatusCondition (& op .Status .Conditions , metav1.Condition {
113
+ Type : operatorsv1alpha1 .TypeInstalled ,
114
+ Status : metav1 .ConditionUnknown ,
115
+ Reason : operatorsv1alpha1 .ReasonInstallationStatusUnknown ,
116
+ Message : "installation has not been attempted as spec is invalid" ,
117
+ ObservedGeneration : op .GetGeneration (),
118
+ })
109
119
// Set the TypeResolved condition to Unknown to indicate that the resolution
110
120
// hasn't been attempted yet, due to the spec being invalid.
111
121
op .Status .ResolvedBundleResource = ""
@@ -121,6 +131,14 @@ func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha
121
131
// run resolution
122
132
solution , err := r .Resolver .Resolve (ctx )
123
133
if err != nil {
134
+ op .Status .InstalledBundleSource = ""
135
+ apimeta .SetStatusCondition (& op .Status .Conditions , metav1.Condition {
136
+ Type : operatorsv1alpha1 .TypeInstalled ,
137
+ Status : metav1 .ConditionUnknown ,
138
+ Reason : operatorsv1alpha1 .ReasonInstallationStatusUnknown ,
139
+ Message : "installation has not been attempted as resolution failed" ,
140
+ ObservedGeneration : op .GetGeneration (),
141
+ })
124
142
op .Status .ResolvedBundleResource = ""
125
143
apimeta .SetStatusCondition (& op .Status .Conditions , metav1.Condition {
126
144
Type : operatorsv1alpha1 .TypeResolved ,
@@ -136,6 +154,14 @@ func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha
136
154
// Operator's desired package name.
137
155
bundleEntity , err := r .getBundleEntityFromSolution (solution , op .Spec .PackageName )
138
156
if err != nil {
157
+ op .Status .InstalledBundleSource = ""
158
+ apimeta .SetStatusCondition (& op .Status .Conditions , metav1.Condition {
159
+ Type : operatorsv1alpha1 .TypeInstalled ,
160
+ Status : metav1 .ConditionUnknown ,
161
+ Reason : operatorsv1alpha1 .ReasonInstallationStatusUnknown ,
162
+ Message : "installation has not been attempted as resolution failed" ,
163
+ ObservedGeneration : op .GetGeneration (),
164
+ })
139
165
op .Status .ResolvedBundleResource = ""
140
166
apimeta .SetStatusCondition (& op .Status .Conditions , metav1.Condition {
141
167
Type : operatorsv1alpha1 .TypeResolved ,
@@ -150,6 +176,14 @@ func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha
150
176
// Get the bundle image reference for the bundle
151
177
bundleImage , err := bundleEntity .BundlePath ()
152
178
if err != nil {
179
+ op .Status .InstalledBundleSource = ""
180
+ apimeta .SetStatusCondition (& op .Status .Conditions , metav1.Condition {
181
+ Type : operatorsv1alpha1 .TypeInstalled ,
182
+ Status : metav1 .ConditionUnknown ,
183
+ Reason : operatorsv1alpha1 .ReasonInstallationStatusUnknown ,
184
+ Message : "installation has not been attempted as resolution failed" ,
185
+ ObservedGeneration : op .GetGeneration (),
186
+ })
153
187
op .Status .ResolvedBundleResource = ""
154
188
apimeta .SetStatusCondition (& op .Status .Conditions , metav1.Condition {
155
189
Type : operatorsv1alpha1 .TypeResolved ,
@@ -176,20 +210,93 @@ func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha
176
210
dep := r .generateExpectedBundleDeployment (* op , bundleImage )
177
211
if err := r .ensureBundleDeployment (ctx , dep ); err != nil {
178
212
// originally Reason: operatorsv1alpha1.ReasonInstallationFailed
213
+ op .Status .InstalledBundleSource = ""
214
+ apimeta .SetStatusCondition (& op .Status .Conditions , metav1.Condition {
215
+ Type : operatorsv1alpha1 .TypeInstalled ,
216
+ Status : metav1 .ConditionFalse ,
217
+ Reason : operatorsv1alpha1 .ReasonInstallationFailed ,
218
+ Message : err .Error (),
219
+ ObservedGeneration : op .GetGeneration (),
220
+ })
179
221
return ctrl.Result {}, err
180
222
}
181
223
182
224
// convert existing unstructured object into bundleDeployment for easier mapping of status.
183
225
existingTypedBundleDeployment := & rukpakv1alpha1.BundleDeployment {}
184
226
if err := runtime .DefaultUnstructuredConverter .FromUnstructured (dep .UnstructuredContent (), existingTypedBundleDeployment ); err != nil {
185
227
// originally Reason: operatorsv1alpha1.ReasonInstallationStatusUnknown
228
+ op .Status .InstalledBundleSource = ""
229
+ apimeta .SetStatusCondition (& op .Status .Conditions , metav1.Condition {
230
+ Type : operatorsv1alpha1 .TypeInstalled ,
231
+ Status : metav1 .ConditionUnknown ,
232
+ Reason : operatorsv1alpha1 .ReasonInstallationStatusUnknown ,
233
+ Message : err .Error (),
234
+ ObservedGeneration : op .GetGeneration (),
235
+ })
186
236
return ctrl.Result {}, err
187
237
}
188
238
239
+ // Let's set the proper Installed condition and installedBundleSource field based on the
240
+ // existing BundleDeployment object status.
241
+ installedCond , installedBundleSource := mapBDStatusToInstalledCondition (existingTypedBundleDeployment , op )
242
+ apimeta .SetStatusCondition (& op .Status .Conditions , installedCond )
243
+ op .Status .InstalledBundleSource = installedBundleSource
244
+
189
245
// set the status of the operator based on the respective bundle deployment status conditions.
190
246
return ctrl.Result {}, nil
191
247
}
192
248
249
+ func mapBDStatusToInstalledCondition (existingTypedBundleDeployment * rukpakv1alpha1.BundleDeployment , op * operatorsv1alpha1.Operator ) (metav1.Condition , string ) {
250
+ bundleDeploymentReady := apimeta .FindStatusCondition (existingTypedBundleDeployment .Status .Conditions , rukpakv1alpha1 .TypeInstalled )
251
+ if bundleDeploymentReady == nil {
252
+ return metav1.Condition {
253
+ Type : operatorsv1alpha1 .TypeInstalled ,
254
+ Status : metav1 .ConditionUnknown ,
255
+ Reason : operatorsv1alpha1 .ReasonInstallationStatusUnknown ,
256
+ Message : "bundledeployment status is unknown" ,
257
+ ObservedGeneration : op .GetGeneration (),
258
+ }, ""
259
+ }
260
+
261
+ if bundleDeploymentReady .Status != metav1 .ConditionTrue {
262
+ return metav1.Condition {
263
+ Type : operatorsv1alpha1 .TypeInstalled ,
264
+ Status : metav1 .ConditionFalse ,
265
+ Reason : operatorsv1alpha1 .ReasonInstallationFailed ,
266
+ Message : fmt .Sprintf ("bundledeployment not ready: %s" , bundleDeploymentReady .Message ),
267
+ ObservedGeneration : op .GetGeneration (),
268
+ }, ""
269
+ }
270
+
271
+ bundleDeploymentSource := existingTypedBundleDeployment .Spec .Template .Spec .Source
272
+ switch bundleDeploymentSource .Type {
273
+ case rukpakv1alpha1 .SourceTypeImage :
274
+ return metav1.Condition {
275
+ Type : operatorsv1alpha1 .TypeInstalled ,
276
+ Status : metav1 .ConditionTrue ,
277
+ Reason : operatorsv1alpha1 .ReasonSuccess ,
278
+ Message : fmt .Sprintf ("installed from %q" , bundleDeploymentSource .Image .Ref ),
279
+ ObservedGeneration : op .GetGeneration (),
280
+ }, bundleDeploymentSource .Image .Ref
281
+ case rukpakv1alpha1 .SourceTypeGit :
282
+ return metav1.Condition {
283
+ Type : operatorsv1alpha1 .TypeInstalled ,
284
+ Status : metav1 .ConditionTrue ,
285
+ Reason : operatorsv1alpha1 .ReasonSuccess ,
286
+ Message : fmt .Sprintf ("installed from %q" , bundleDeploymentSource .Git .Repository + "@" + bundleDeploymentSource .Git .Ref .Commit ),
287
+ ObservedGeneration : op .GetGeneration (),
288
+ }, bundleDeploymentSource .Git .Repository + "@" + bundleDeploymentSource .Git .Ref .Commit
289
+ default :
290
+ return metav1.Condition {
291
+ Type : operatorsv1alpha1 .TypeInstalled ,
292
+ Status : metav1 .ConditionUnknown ,
293
+ Reason : operatorsv1alpha1 .ReasonInstallationStatusUnknown ,
294
+ Message : fmt .Sprintf ("unknown bundledeployment source type %q" , bundleDeploymentSource .Type ),
295
+ ObservedGeneration : op .GetGeneration (),
296
+ }, ""
297
+ }
298
+ }
299
+
193
300
func (r * OperatorReconciler ) getBundleEntityFromSolution (solution * solver.Solution , packageName string ) (* entity.BundleEntity , error ) {
194
301
for _ , variable := range solution .SelectedVariables () {
195
302
switch v := variable .(type ) {
0 commit comments