Skip to content

Commit ed564ce

Browse files
Merge pull request #1596 from abays/OSPRH-19707
[OSPRH-19707] Prioritize surfacing warn/error severity sub-statuses
2 parents 9ad9305 + 99b000e commit ed564ce

25 files changed

Lines changed: 556 additions & 183 deletions

config/manifests/bases/openstack-operator.clusterserviceversion.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ metadata:
1111
features.operators.openshift.io/token-auth-aws: "false"
1212
features.operators.openshift.io/token-auth-azure: "false"
1313
features.operators.openshift.io/token-auth-gcp: "false"
14-
operators.openshift.io/valid-subscription: '["OpenShift Container Platform", "OpenShift Platform Plus"]'
1514
operatorframework.io/suggested-namespace: openstack-operators
15+
operators.openshift.io/valid-subscription: '["OpenShift Container Platform", "OpenShift
16+
Platform Plus"]'
1617
operators.operatorframework.io/builder: operator-sdk-v1.31.0
1718
operators.operatorframework.io/internal-objects: '["openstackclients.client.openstack.org","openstackdataplaneservices.dataplane.openstack.org"]'
1819
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3

controllers/core/openstackcontrolplane_controller.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -369,15 +369,19 @@ func (r *OpenStackControlPlaneReconciler) Reconcile(ctx context.Context, req ctr
369369
}
370370

371371
func (r *OpenStackControlPlaneReconciler) reconcileOVNControllers(ctx context.Context, instance *corev1beta1.OpenStackControlPlane, version *corev1beta1.OpenStackVersion, helper *common_helper.Helper) (ctrl.Result, error) {
372-
OVNControllerReady, err := openstack.ReconcileOVNController(ctx, instance, version, helper)
372+
OVNControllerReady, OVNControllerConditions, err := openstack.ReconcileOVNController(ctx, instance, version, helper)
373373
if err != nil {
374374
return ctrl.Result{}, err
375375
} else if !OVNControllerReady {
376-
instance.Status.Conditions.Set(condition.FalseCondition(
377-
corev1beta1.OpenStackControlPlaneOVNReadyCondition,
378-
condition.RequestedReason,
379-
condition.SeverityInfo,
380-
corev1beta1.OpenStackControlPlaneOVNReadyRunningMessage))
376+
if len(OVNControllerConditions) > 0 {
377+
openstack.MirrorSubResourceCondition(OVNControllerConditions, corev1beta1.OpenStackControlPlaneOVNReadyCondition, instance, "OVN")
378+
} else {
379+
instance.Status.Conditions.Set(condition.FalseCondition(
380+
corev1beta1.OpenStackControlPlaneOVNReadyCondition,
381+
condition.RequestedReason,
382+
condition.SeverityInfo,
383+
corev1beta1.OpenStackControlPlaneOVNReadyRunningMessage))
384+
}
381385
} else {
382386
instance.Status.Conditions.MarkTrue(corev1beta1.OpenStackControlPlaneOVNReadyCondition, corev1beta1.OpenStackControlPlaneOVNReadyMessage)
383387
}

pkg/openstack/barbican.go

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -156,18 +156,31 @@ func ReconcileBarbican(ctx context.Context, instance *corev1beta1.OpenStackContr
156156
helper.GetLogger().Info(fmt.Sprintf("barbican %s - %s", barbican.Name, op))
157157
}
158158

159-
if barbican.IsReady() {
159+
if barbican.Status.ObservedGeneration == barbican.Generation && barbican.IsReady() {
160+
helper.GetLogger().Info("Barbican ready condition is true")
161+
instance.Status.ContainerImages.BarbicanAPIImage = version.Status.ContainerImages.BarbicanAPIImage
162+
instance.Status.ContainerImages.BarbicanWorkerImage = version.Status.ContainerImages.BarbicanWorkerImage
163+
instance.Status.ContainerImages.BarbicanKeystoneListenerImage = version.Status.ContainerImages.BarbicanKeystoneListenerImage
160164
instance.Status.Conditions.MarkTrue(corev1beta1.OpenStackControlPlaneBarbicanReadyCondition, corev1beta1.OpenStackControlPlaneBarbicanReadyMessage)
161165
} else {
162-
instance.Status.Conditions.Set(condition.FalseCondition(
163-
corev1beta1.OpenStackControlPlaneBarbicanReadyCondition,
164-
condition.RequestedReason,
165-
condition.SeverityInfo,
166-
corev1beta1.OpenStackControlPlaneBarbicanReadyRunningMessage))
166+
// We want to mirror the condition of the highest priority from the Barbican resource into the instance
167+
// under the condition of type OpenStackControlPlaneBarbicanReadyCondition, but only if the sub-resource
168+
// currently has any conditions (which won't be true for the initial creation of the sub-resource, since
169+
// it has not gone through a reconcile loop yet to have any conditions). If this condition ends up being
170+
// the highest priority condition in the OpenStackControlPlane, it will appear in the OpenStackControlPlane's
171+
// "Ready" condition at the end of the reconciliation loop, clearly surfacing the condition to the user in
172+
// the "oc get oscontrolplane -n <namespace>" output.
173+
if len(barbican.Status.Conditions) > 0 {
174+
MirrorSubResourceCondition(barbican.Status.Conditions, corev1beta1.OpenStackControlPlaneBarbicanReadyCondition, instance, barbican.Kind)
175+
} else {
176+
// Default to the associated "running" condition message for the sub-resource if it currently lacks any conditions for mirroring
177+
instance.Status.Conditions.Set(condition.FalseCondition(
178+
corev1beta1.OpenStackControlPlaneBarbicanReadyCondition,
179+
condition.RequestedReason,
180+
condition.SeverityInfo,
181+
corev1beta1.OpenStackControlPlaneBarbicanReadyRunningMessage))
182+
}
167183
}
168-
instance.Status.ContainerImages.BarbicanAPIImage = version.Status.ContainerImages.BarbicanAPIImage
169-
instance.Status.ContainerImages.BarbicanWorkerImage = version.Status.ContainerImages.BarbicanWorkerImage
170-
instance.Status.ContainerImages.BarbicanKeystoneListenerImage = version.Status.ContainerImages.BarbicanKeystoneListenerImage
171184

172185
return ctrl.Result{}, nil
173186
}

pkg/openstack/cinder.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,17 +195,30 @@ func ReconcileCinder(ctx context.Context, instance *corev1beta1.OpenStackControl
195195
}
196196

197197
if cinder.Status.ObservedGeneration == cinder.Generation && cinder.IsReady() {
198+
Log.Info("Cinder ready condition is true")
198199
instance.Status.ContainerImages.CinderAPIImage = version.Status.ContainerImages.CinderAPIImage
199200
instance.Status.ContainerImages.CinderSchedulerImage = version.Status.ContainerImages.CinderSchedulerImage
200201
instance.Status.ContainerImages.CinderBackupImage = version.Status.ContainerImages.CinderBackupImage
201202
instance.Status.ContainerImages.CinderVolumeImages = version.Status.ContainerImages.DeepCopy().CinderVolumeImages
202203
instance.Status.Conditions.MarkTrue(corev1beta1.OpenStackControlPlaneCinderReadyCondition, corev1beta1.OpenStackControlPlaneCinderReadyMessage)
203204
} else {
204-
instance.Status.Conditions.Set(condition.FalseCondition(
205-
corev1beta1.OpenStackControlPlaneCinderReadyCondition,
206-
condition.RequestedReason,
207-
condition.SeverityInfo,
208-
corev1beta1.OpenStackControlPlaneCinderReadyRunningMessage))
205+
// We want to mirror the condition of the highest priority from the Cinder resource into the instance
206+
// under the condition of type OpenStackControlPlaneCinderReadyCondition, but only if the sub-resource
207+
// currently has any conditions (which won't be true for the initial creation of the sub-resource, since
208+
// it has not gone through a reconcile loop yet to have any conditions). If this condition ends up being
209+
// the highest priority condition in the OpenStackControlPlane, it will appear in the OpenStackControlPlane's
210+
// "Ready" condition at the end of the reconciliation loop, clearly surfacing the condition to the user in
211+
// the "oc get oscontrolplane -n <namespace>" output.
212+
if len(cinder.Status.Conditions) > 0 {
213+
MirrorSubResourceCondition(cinder.Status.Conditions, corev1beta1.OpenStackControlPlaneCinderReadyCondition, instance, cinder.Kind)
214+
} else {
215+
// Default to the associated "running" condition message for the sub-resource if it currently lacks any conditions for mirroring
216+
instance.Status.Conditions.Set(condition.FalseCondition(
217+
corev1beta1.OpenStackControlPlaneCinderReadyCondition,
218+
condition.RequestedReason,
219+
condition.SeverityInfo,
220+
corev1beta1.OpenStackControlPlaneCinderReadyRunningMessage))
221+
}
209222
}
210223

211224
return ctrl.Result{}, nil

pkg/openstack/common.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,3 +915,21 @@ func DeleteCertsAndRoutes(
915915

916916
return ctrl.Result{}, nil
917917
}
918+
919+
// MirrorSubResourceCondition -
920+
// 1. Mirrors the condition of the highest priority from subResource to the instance,
921+
// placing it in the condition of type targetCondition of the instance
922+
// 2. If passed, prepends the kind of the subResource to the message associated with the
923+
// condition, which, while perhaps redundant for the targetCondition, will help provide
924+
// clarity in the case that the targetCondition ends up being the highest priority
925+
// condition in the OpenStackControlPlane (and thus appears in the
926+
// OpenStackControlPlane's "Ready" condition at the end of the reconciliation loop)
927+
func MirrorSubResourceCondition(conditions condition.Conditions, targetCondition condition.Type, instance *corev1beta1.OpenStackControlPlane, subResource string) {
928+
myCondition := conditions.Mirror(targetCondition)
929+
if subResource != "" {
930+
// Prepend the kind of the subResource to the message associated with the condition
931+
// if one was passed
932+
myCondition.Message = fmt.Sprintf("%s: %s", subResource, myCondition.Message)
933+
}
934+
instance.Status.Conditions.Set(myCondition)
935+
}

pkg/openstack/designate.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ func ReconcileDesignate(ctx context.Context, instance *corev1beta1.OpenStackCont
186186
}
187187

188188
if designate.Status.ObservedGeneration == designate.Generation && designate.IsReady() {
189+
helper.GetLogger().Info("Designate ready condition is true")
189190
instance.Status.ContainerImages.DesignateAPIImage = version.Status.ContainerImages.DesignateAPIImage
190191
instance.Status.ContainerImages.DesignateCentralImage = version.Status.ContainerImages.DesignateCentralImage
191192
instance.Status.ContainerImages.DesignateMdnsImage = version.Status.ContainerImages.DesignateMdnsImage
@@ -196,11 +197,23 @@ func ReconcileDesignate(ctx context.Context, instance *corev1beta1.OpenStackCont
196197
instance.Status.ContainerImages.NetUtilsImage = version.Status.ContainerImages.NetUtilsImage
197198
instance.Status.Conditions.MarkTrue(corev1beta1.OpenStackControlPlaneDesignateReadyCondition, corev1beta1.OpenStackControlPlaneDesignateReadyMessage)
198199
} else {
199-
instance.Status.Conditions.Set(condition.FalseCondition(
200-
corev1beta1.OpenStackControlPlaneDesignateReadyCondition,
201-
condition.RequestedReason,
202-
condition.SeverityInfo,
203-
corev1beta1.OpenStackControlPlaneDesignateReadyRunningMessage))
200+
// We want to mirror the condition of the highest priority from the Designate resource into the instance
201+
// under the condition of type OpenStackControlPlaneDesignateReadyCondition, but only if the sub-resource
202+
// currently has any conditions (which won't be true for the initial creation of the sub-resource, since
203+
// it has not gone through a reconcile loop yet to have any conditions). If this condition ends up being
204+
// the highest priority condition in the OpenStackControlPlane, it will appear in the OpenStackControlPlane's
205+
// "Ready" condition at the end of the reconciliation loop, clearly surfacing the condition to the user in
206+
// the "oc get oscontrolplane -n <namespace>" output.
207+
if len(designate.Status.Conditions) > 0 {
208+
MirrorSubResourceCondition(designate.Status.Conditions, corev1beta1.OpenStackControlPlaneDesignateReadyCondition, instance, designate.Kind)
209+
} else {
210+
// Default to the associated "running" condition message for the sub-resource if it currently lacks any conditions for mirroring
211+
instance.Status.Conditions.Set(condition.FalseCondition(
212+
corev1beta1.OpenStackControlPlaneDesignateReadyCondition,
213+
condition.RequestedReason,
214+
condition.SeverityInfo,
215+
corev1beta1.OpenStackControlPlaneDesignateReadyRunningMessage))
216+
}
204217
}
205218

206219
return ctrl.Result{}, nil

pkg/openstack/dnsmasq.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,27 @@ func ReconcileDNSMasqs(ctx context.Context, instance *corev1beta1.OpenStackContr
7777
}
7878

7979
if dnsmasq.Status.ObservedGeneration == dnsmasq.Generation && dnsmasq.IsReady() {
80+
Log.Info("DNSMasq ready condition is true")
8081
instance.Status.ContainerImages.InfraDnsmasqImage = version.Status.ContainerImages.InfraDnsmasqImage
8182
instance.Status.Conditions.MarkTrue(corev1beta1.OpenStackControlPlaneDNSReadyCondition, corev1beta1.OpenStackControlPlaneDNSReadyMessage)
8283
} else {
83-
instance.Status.Conditions.Set(condition.FalseCondition(
84-
corev1beta1.OpenStackControlPlaneDNSReadyCondition,
85-
condition.RequestedReason,
86-
condition.SeverityInfo,
87-
corev1beta1.OpenStackControlPlaneDNSReadyRunningMessage))
84+
// We want to mirror the condition of the highest priority from the DNSMasq resource into the instance
85+
// under the condition of type OpenStackControlPlaneDNSReadyCondition, but only if the sub-resource
86+
// currently has any conditions (which won't be true for the initial creation of the sub-resource, since
87+
// it has not gone through a reconcile loop yet to have any conditions). If this condition ends up being
88+
// the highest priority condition in the OpenStackControlPlane, it will appear in the OpenStackControlPlane's
89+
// "Ready" condition at the end of the reconciliation loop, clearly surfacing the condition to the user in
90+
// the "oc get oscontrolplane -n <namespace>" output.
91+
if len(dnsmasq.Status.Conditions) > 0 {
92+
MirrorSubResourceCondition(dnsmasq.Status.Conditions, corev1beta1.OpenStackControlPlaneDNSReadyCondition, instance, dnsmasq.Kind)
93+
} else {
94+
// Default to the associated "running" condition message for the sub-resource if it currently lacks any conditions for mirroring
95+
instance.Status.Conditions.Set(condition.FalseCondition(
96+
corev1beta1.OpenStackControlPlaneDNSReadyCondition,
97+
condition.RequestedReason,
98+
condition.SeverityInfo,
99+
corev1beta1.OpenStackControlPlaneDNSReadyRunningMessage))
100+
}
88101
}
89102

90103
return ctrl.Result{}, nil

pkg/openstack/galera.go

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"reflect"
78
"strings"
89

910
certmgrv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
@@ -98,6 +99,9 @@ func ReconcileGaleras(
9899
instance.Spec.Galera.Templates = ptr.To(map[string]mariadbv1.GaleraSpecCore{})
99100
}
100101

102+
// List of conditions to consider later for mirroring
103+
conditions := condition.Conditions{}
104+
101105
for name, spec := range *instance.Spec.Galera.Templates {
102106
hostname := fmt.Sprintf("%s.%s.svc", name, instance.Namespace)
103107
hostnameHeadless := fmt.Sprintf("%s-galera.%s.svc", name, instance.Namespace)
@@ -151,7 +155,14 @@ func ReconcileGaleras(
151155
spec.TLS.Ca.CaBundleSecretName = instance.Status.TLS.CaBundleSecretName
152156
spec.TLS.SecretName = ptr.To(certSecret.Name)
153157

154-
status, err := reconcileGalera(ctx, instance, version, helper, name, &spec)
158+
status, galera, err := reconcileGalera(ctx, instance, version, helper, name, &spec)
159+
160+
// Add the conditions to the list of conditions to consider later for mirroring.
161+
// It doesn't matter if the conditions are already in the list, they will be
162+
// deduplicated later during the MirrorSubResourceCondition call.
163+
if galera != nil && galera.Status.Conditions != nil {
164+
conditions = append(conditions, galera.Status.Conditions...)
165+
}
155166

156167
switch status {
157168
case galeraFailed:
@@ -178,11 +189,22 @@ func ReconcileGaleras(
178189

179190
} else if len(inprogress) > 0 {
180191
log.Info("Galera in progress")
181-
instance.Status.Conditions.Set(condition.FalseCondition(
182-
corev1beta1.OpenStackControlPlaneMariaDBReadyCondition,
183-
condition.RequestedReason,
184-
condition.SeverityInfo,
185-
corev1beta1.OpenStackControlPlaneMariaDBReadyRunningMessage))
192+
// We want to mirror the condition of the highest priority from the Galera resources into the instance
193+
// under the condition of type OpenStackControlPlaneMariaDBReadyCondition, but only if the sub-resources
194+
// currently have any conditions (which won't be true for the initial creation of the sub-resources, since
195+
// they have not gone through a reconcile loop yet to have any conditions). If this condition ends up being
196+
// the highest priority condition in the OpenStackControlPlane, it will appear in the OpenStackControlPlane's
197+
// "Ready" condition at the end of the reconciliation loop, clearly surfacing the condition to the user in
198+
// the "oc get oscontrolplane -n <namespace>" output.
199+
if len(conditions) > 0 {
200+
MirrorSubResourceCondition(conditions, corev1beta1.OpenStackControlPlaneMariaDBReadyCondition, instance, reflect.TypeOf(mariadbv1.Galera{}).Name())
201+
} else {
202+
instance.Status.Conditions.Set(condition.FalseCondition(
203+
corev1beta1.OpenStackControlPlaneMariaDBReadyCondition,
204+
condition.RequestedReason,
205+
condition.SeverityInfo,
206+
corev1beta1.OpenStackControlPlaneMariaDBReadyRunningMessage))
207+
}
186208
} else {
187209
log.Info("Galera ready condition is true")
188210
instance.Status.Conditions.MarkTrue(
@@ -213,7 +235,7 @@ func reconcileGalera(
213235
helper *helper.Helper,
214236
name string,
215237
spec *mariadbv1.GaleraSpecCore,
216-
) (galeraStatus, error) {
238+
) (galeraStatus, *mariadbv1.Galera, error) {
217239
galera := &mariadbv1.Galera{
218240
ObjectMeta: metav1.ObjectMeta{
219241
Name: name,
@@ -224,11 +246,11 @@ func reconcileGalera(
224246

225247
if !instance.Spec.Galera.Enabled {
226248
if _, err := EnsureDeleted(ctx, helper, galera); err != nil {
227-
return galeraFailed, err
249+
return galeraFailed, galera, err
228250
}
229251
instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneMariaDBReadyCondition)
230252
instance.Status.ContainerImages.MariadbImage = nil
231-
return galeraReady, nil
253+
return galeraReady, galera, nil
232254
}
233255

234256
if spec.NodeSelector == nil {
@@ -256,18 +278,18 @@ func reconcileGalera(
256278
})
257279

258280
if err != nil {
259-
return galeraFailed, err
281+
return galeraFailed, galera, err
260282
}
261283
if op != controllerutil.OperationResultNone {
262284
log.Info(fmt.Sprintf("Galera %s - %s", galera.Name, op))
263285
}
264286

265287
if galera.Status.ObservedGeneration == galera.Generation && galera.IsReady() {
266288
instance.Status.ContainerImages.MariadbImage = version.Status.ContainerImages.MariadbImage
267-
return galeraReady, nil
289+
return galeraReady, galera, nil
268290
}
269291

270-
return galeraCreating, nil
292+
return galeraCreating, galera, nil
271293
}
272294

273295
// GaleraImageMatch - return true if the Galera images match on the ControlPlane and Version, or if Galera is not enabled

pkg/openstack/glance.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,27 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl
220220
}
221221

222222
if glance.Status.ObservedGeneration == glance.Generation && glance.IsReady() {
223+
Log.Info("Glance ready condition is true")
223224
instance.Status.ContainerImages.GlanceAPIImage = version.Status.ContainerImages.GlanceAPIImage
224225
instance.Status.Conditions.MarkTrue(corev1beta1.OpenStackControlPlaneGlanceReadyCondition, corev1beta1.OpenStackControlPlaneGlanceReadyMessage)
225226
} else {
226-
instance.Status.Conditions.Set(condition.FalseCondition(
227-
corev1beta1.OpenStackControlPlaneGlanceReadyCondition,
228-
condition.RequestedReason,
229-
condition.SeverityInfo,
230-
corev1beta1.OpenStackControlPlaneGlanceReadyRunningMessage))
227+
// We want to mirror the condition of the highest priority from the Glance resource into the instance
228+
// under the condition of type OpenStackControlPlaneGlanceReadyCondition, but only if the sub-resource
229+
// currently has any conditions (which won't be true for the initial creation of the sub-resource, since
230+
// it has not gone through a reconcile loop yet to have any conditions). If this condition ends up being
231+
// the highest priority condition in the OpenStackControlPlane, it will appear in the OpenStackControlPlane's
232+
// "Ready" condition at the end of the reconciliation loop, clearly surfacing the condition to the user in
233+
// the "oc get oscontrolplane -n <namespace>" output.
234+
if len(glance.Status.Conditions) > 0 {
235+
MirrorSubResourceCondition(glance.Status.Conditions, corev1beta1.OpenStackControlPlaneGlanceReadyCondition, instance, glance.Kind)
236+
} else {
237+
// Default to the associated "running" condition message for the sub-resource if it currently lacks any conditions for mirroring
238+
instance.Status.Conditions.Set(condition.FalseCondition(
239+
corev1beta1.OpenStackControlPlaneGlanceReadyCondition,
240+
condition.RequestedReason,
241+
condition.SeverityInfo,
242+
corev1beta1.OpenStackControlPlaneGlanceReadyRunningMessage))
243+
}
231244
}
232245

233246
return ctrl.Result{}, nil

0 commit comments

Comments
 (0)