Skip to content

Commit 959ddca

Browse files
Ensure that we set Deprecation False
1 parent 3f12a0f commit 959ddca

File tree

12 files changed

+223
-99
lines changed

12 files changed

+223
-99
lines changed

api/v1/clusterextension_types.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -500,13 +500,12 @@ type ClusterExtensionStatus struct {
500500
// When Progressing is True and Reason is RollingOut, the ClusterExtension has one or more ClusterExtensionRevisions in active roll out.
501501
// </opcon:experimental:description>
502502
//
503-
// When the ClusterExtension is sourced from a catalog, it may surface deprecation conditions based on catalog metadata.
504-
// These are indications from a package owner to guide users away from a particular package, channel, or bundle.
505-
// Deprecation conditions are only present when there's something to report - absence means "not deprecated".
506-
// - BundleDeprecated is set to True if the installed bundle is marked as deprecated in the catalog, or Unknown if no bundle is installed yet.
507-
// - ChannelDeprecated is set to True if any requested channel is marked as deprecated in the catalog, or Unknown if the channel is not found.
508-
// - PackageDeprecated is set to True if the requested package is marked as deprecated in the catalog, or Unknown if the package is not found.
509-
// - Deprecated is a rollup condition that is present only when at least one deprecation exists (True) or when catalog information is unavailable (Unknown).
503+
// When the ClusterExtension is sourced from a catalog, it surfaces deprecation conditions based on catalog metadata.
504+
// These are indications from a package owner to guide users away from a particular package, channel, or bundle:
505+
// - BundleDeprecated is True if the installed bundle is marked deprecated, False if not deprecated, or Unknown if no bundle is installed yet or if catalog data is unavailable.
506+
// - ChannelDeprecated is True if any requested channel is marked deprecated, False if not deprecated, or Unknown if catalog data is unavailable.
507+
// - PackageDeprecated is True if the requested package is marked deprecated, False if not deprecated, or Unknown if catalog data is unavailable.
508+
// - Deprecated is a rollup condition that is True when any deprecation exists, False when none exist, or Unknown when catalog data is unavailable.
510509
//
511510
// +listType=map
512511
// +listMapKey=type

api/v1/common_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const (
3030

3131
// Deprecation reasons
3232
ReasonDeprecated = "Deprecated"
33+
ReasonNotDeprecated = "NotDeprecated"
3334
ReasonDeprecationStatusUnknown = "DeprecationStatusUnknown"
3435

3536
// Common reasons

docs/api-reference/olmv1-api-reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ _Appears in:_
360360

361361
| Field | Description | Default | Validation |
362362
| --- | --- | --- | --- |
363-
| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | conditions represents the current state of the ClusterExtension.<br />The set of condition types which apply to all spec.source variations are Installed and Progressing.<br />The Installed condition represents whether the bundle has been installed for this ClusterExtension:<br /> - When Installed is True and the Reason is Succeeded, the bundle has been successfully installed.<br /> - When Installed is False and the Reason is Failed, the bundle has failed to install.<br />The Progressing condition represents whether or not the ClusterExtension is advancing towards a new state.<br />When Progressing is True and the Reason is Succeeded, the ClusterExtension is making progress towards a new state.<br />When Progressing is True and the Reason is Retrying, the ClusterExtension has encountered an error that could be resolved on subsequent reconciliation attempts.<br />When Progressing is False and the Reason is Blocked, the ClusterExtension has encountered an error that requires manual intervention for recovery.<br /><opcon:experimental:description><br />When Progressing is True and Reason is RollingOut, the ClusterExtension has one or more ClusterExtensionRevisions in active roll out.<br /></opcon:experimental:description><br />When the ClusterExtension is sourced from a catalog, it may surface deprecation conditions based on catalog metadata.<br />These are indications from a package owner to guide users away from a particular package, channel, or bundle.<br />Deprecation conditions are only present when there's something to report - absence means "not deprecated".<br /> - BundleDeprecated is set to True if the installed bundle is marked as deprecated in the catalog, or Unknown if no bundle is installed yet.<br /> - ChannelDeprecated is set to True if any requested channel is marked as deprecated in the catalog, or Unknown if the channel is not found.<br /> - PackageDeprecated is set to True if the requested package is marked as deprecated in the catalog, or Unknown if the package is not found.<br /> - Deprecated is a rollup condition that is present only when at least one deprecation exists (True) or when catalog information is unavailable (Unknown). | | |
363+
| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | conditions represents the current state of the ClusterExtension.<br />The set of condition types which apply to all spec.source variations are Installed and Progressing.<br />The Installed condition represents whether the bundle has been installed for this ClusterExtension:<br /> - When Installed is True and the Reason is Succeeded, the bundle has been successfully installed.<br /> - When Installed is False and the Reason is Failed, the bundle has failed to install.<br />The Progressing condition represents whether or not the ClusterExtension is advancing towards a new state.<br />When Progressing is True and the Reason is Succeeded, the ClusterExtension is making progress towards a new state.<br />When Progressing is True and the Reason is Retrying, the ClusterExtension has encountered an error that could be resolved on subsequent reconciliation attempts.<br />When Progressing is False and the Reason is Blocked, the ClusterExtension has encountered an error that requires manual intervention for recovery.<br /><opcon:experimental:description><br />When Progressing is True and Reason is RollingOut, the ClusterExtension has one or more ClusterExtensionRevisions in active roll out.<br /></opcon:experimental:description><br />When the ClusterExtension is sourced from a catalog, it surfaces deprecation conditions based on catalog metadata.<br />These are indications from a package owner to guide users away from a particular package, channel, or bundle:<br /> - BundleDeprecated is True if the installed bundle is marked deprecated, False if not deprecated, or Unknown if no bundle is installed yet or if catalog data is unavailable.<br /> - ChannelDeprecated is True if any requested channel is marked deprecated, False if not deprecated, or Unknown if catalog data is unavailable.<br /> - PackageDeprecated is True if the requested package is marked deprecated, False if not deprecated, or Unknown if catalog data is unavailable.<br /> - Deprecated is a rollup condition that is True when any deprecation exists, False when none exist, or Unknown when catalog data is unavailable. | | |
364364
| `install` _[ClusterExtensionInstallStatus](#clusterextensioninstallstatus)_ | install is a representation of the current installation status for this ClusterExtension. | | |
365365
| `activeRevisions` _[RevisionStatus](#revisionstatus) array_ | activeRevisions holds a list of currently active (non-archived) ClusterExtensionRevisions,<br />including both installed and rolling out revisions.<br /><opcon:experimental> | | |
366366

helm/olmv1/base/operator-controller/crd/experimental/olm.operatorframework.io_clusterextensions.yaml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -601,13 +601,12 @@ spec:
601601
602602
When Progressing is True and Reason is RollingOut, the ClusterExtension has one or more ClusterExtensionRevisions in active roll out.
603603
604-
When the ClusterExtension is sourced from a catalog, it may surface deprecation conditions based on catalog metadata.
605-
These are indications from a package owner to guide users away from a particular package, channel, or bundle.
606-
Deprecation conditions are only present when there's something to report - absence means "not deprecated".
607-
- BundleDeprecated is set to True if the installed bundle is marked as deprecated in the catalog, or Unknown if no bundle is installed yet.
608-
- ChannelDeprecated is set to True if any requested channel is marked as deprecated in the catalog, or Unknown if the channel is not found.
609-
- PackageDeprecated is set to True if the requested package is marked as deprecated in the catalog, or Unknown if the package is not found.
610-
- Deprecated is a rollup condition that is present only when at least one deprecation exists (True) or when catalog information is unavailable (Unknown).
604+
When the ClusterExtension is sourced from a catalog, it surfaces deprecation conditions based on catalog metadata.
605+
These are indications from a package owner to guide users away from a particular package, channel, or bundle:
606+
- BundleDeprecated is True if the installed bundle is marked deprecated, False if not deprecated, or Unknown if no bundle is installed yet or if catalog data is unavailable.
607+
- ChannelDeprecated is True if any requested channel is marked deprecated, False if not deprecated, or Unknown if catalog data is unavailable.
608+
- PackageDeprecated is True if the requested package is marked deprecated, False if not deprecated, or Unknown if catalog data is unavailable.
609+
- Deprecated is a rollup condition that is True when any deprecation exists, False when none exist, or Unknown when catalog data is unavailable.
611610
items:
612611
description: Condition contains details for one aspect of the current
613612
state of this API Resource.

helm/olmv1/base/operator-controller/crd/standard/olm.operatorframework.io_clusterextensions.yaml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -507,13 +507,12 @@ spec:
507507
When Progressing is True and the Reason is Retrying, the ClusterExtension has encountered an error that could be resolved on subsequent reconciliation attempts.
508508
When Progressing is False and the Reason is Blocked, the ClusterExtension has encountered an error that requires manual intervention for recovery.
509509
510-
When the ClusterExtension is sourced from a catalog, it may surface deprecation conditions based on catalog metadata.
511-
These are indications from a package owner to guide users away from a particular package, channel, or bundle.
512-
Deprecation conditions are only present when there's something to report - absence means "not deprecated".
513-
- BundleDeprecated is set to True if the installed bundle is marked as deprecated in the catalog, or Unknown if no bundle is installed yet.
514-
- ChannelDeprecated is set to True if any requested channel is marked as deprecated in the catalog, or Unknown if the channel is not found.
515-
- PackageDeprecated is set to True if the requested package is marked as deprecated in the catalog, or Unknown if the package is not found.
516-
- Deprecated is a rollup condition that is present only when at least one deprecation exists (True) or when catalog information is unavailable (Unknown).
510+
When the ClusterExtension is sourced from a catalog, it surfaces deprecation conditions based on catalog metadata.
511+
These are indications from a package owner to guide users away from a particular package, channel, or bundle:
512+
- BundleDeprecated is True if the installed bundle is marked deprecated, False if not deprecated, or Unknown if no bundle is installed yet or if catalog data is unavailable.
513+
- ChannelDeprecated is True if any requested channel is marked deprecated, False if not deprecated, or Unknown if catalog data is unavailable.
514+
- PackageDeprecated is True if the requested package is marked deprecated, False if not deprecated, or Unknown if catalog data is unavailable.
515+
- Deprecated is a rollup condition that is True when any deprecation exists, False when none exist, or Unknown when catalog data is unavailable.
517516
items:
518517
description: Condition contains details for one aspect of the current
519518
state of this API Resource.

internal/operator-controller/conditionsets/conditionsets.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ var ConditionTypes = []string{
3636
var ConditionReasons = []string{
3737
ocv1.ReasonSucceeded,
3838
ocv1.ReasonDeprecated,
39+
ocv1.ReasonNotDeprecated,
3940
ocv1.ReasonDeprecationStatusUnknown,
4041
ocv1.ReasonFailed,
4142
ocv1.ReasonBlocked,

internal/operator-controller/controllers/clusterextension_controller.go

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,11 @@ func ensureFailureConditionsWithReason(ext *ocv1.ClusterExtension, reason v1alph
196196

197197
// SetDeprecationStatus updates deprecation conditions based on catalog metadata.
198198
//
199-
// Behavior:
200-
// - IS deprecated condition True with Reason: Deprecated
201-
// - NOT deprecated condition absent (clean YAML)
202-
// - Can't check (no catalog) condition Unknown with Reason: DeprecationStatusUnknown
203-
// - No bundle installed BundleDeprecated Unknown with Reason: Absent
199+
// Behavior (following Kubernetes API conventions - conditions always present):
200+
// - IS deprecated -> condition True with Reason: Deprecated
201+
// - NOT deprecated -> condition False with Reason: NotDeprecated
202+
// - Can't check (no catalog) -> condition Unknown with Reason: DeprecationStatusUnknown
203+
// - No bundle installed -> BundleDeprecated Unknown with Reason: Absent
204204
//
205205
// This keeps deprecation conditions focused on catalog data. Install/validation errors
206206
// never appear here - they belong in Progressing/Installed conditions.
@@ -210,11 +210,12 @@ func SetDeprecationStatus(ext *ocv1.ClusterExtension, installedBundleName string
210210
channelMessages := collectDeprecationMessages(info.ChannelEntries)
211211
bundleMessages := collectDeprecationMessages(info.BundleEntries)
212212

213-
// Strategy: Only remove conditions when we're NOT going to re-add them.
214-
// If we're setting a condition, call SetStatusCondition directly - it preserves
215-
// lastTransitionTime when status/reason/message haven't changed, preventing
216-
// infinite reconciliation loops.
217-
// Absence of a deprecation condition means "not deprecated" - keeps output clean.
213+
// Strategy: Always set deprecation conditions (following Kubernetes API conventions).
214+
// SetStatusCondition preserves lastTransitionTime when status/reason/message haven't changed,
215+
// preventing infinite reconciliation loops.
216+
// - True = deprecated
217+
// - False = not deprecated (verified via catalog)
218+
// - Unknown = cannot verify (no catalog data or no bundle installed)
218219

219220
if !hasCatalogData {
220221
// When catalog is unavailable, set all to Unknown.
@@ -256,8 +257,7 @@ func SetDeprecationStatus(ext *ocv1.ClusterExtension, installedBundleName string
256257
return
257258
}
258259

259-
// Handle catalog data available: set conditions to True when deprecated,
260-
// or remove them when not deprecated (absence = not deprecated).
260+
// Handle catalog data available: set conditions to True when deprecated, False when not.
261261
messages := slices.Concat(packageMessages, channelMessages, bundleMessages)
262262
if len(messages) > 0 {
263263
SetStatusCondition(&ext.Status.Conditions, metav1.Condition{
@@ -268,8 +268,13 @@ func SetDeprecationStatus(ext *ocv1.ClusterExtension, installedBundleName string
268268
ObservedGeneration: ext.GetGeneration(),
269269
})
270270
} else {
271-
// Only remove if we're not setting it - prevents unnecessary lastTransitionTime updates
272-
apimeta.RemoveStatusCondition(&ext.Status.Conditions, ocv1.TypeDeprecated)
271+
SetStatusCondition(&ext.Status.Conditions, metav1.Condition{
272+
Type: ocv1.TypeDeprecated,
273+
Status: metav1.ConditionFalse,
274+
Reason: ocv1.ReasonNotDeprecated,
275+
Message: "not deprecated",
276+
ObservedGeneration: ext.GetGeneration(),
277+
})
273278
}
274279

275280
if len(packageMessages) > 0 {
@@ -281,7 +286,13 @@ func SetDeprecationStatus(ext *ocv1.ClusterExtension, installedBundleName string
281286
ObservedGeneration: ext.GetGeneration(),
282287
})
283288
} else {
284-
apimeta.RemoveStatusCondition(&ext.Status.Conditions, ocv1.TypePackageDeprecated)
289+
SetStatusCondition(&ext.Status.Conditions, metav1.Condition{
290+
Type: ocv1.TypePackageDeprecated,
291+
Status: metav1.ConditionFalse,
292+
Reason: ocv1.ReasonNotDeprecated,
293+
Message: "package not deprecated",
294+
ObservedGeneration: ext.GetGeneration(),
295+
})
285296
}
286297

287298
if len(channelMessages) > 0 {
@@ -293,10 +304,16 @@ func SetDeprecationStatus(ext *ocv1.ClusterExtension, installedBundleName string
293304
ObservedGeneration: ext.GetGeneration(),
294305
})
295306
} else {
296-
apimeta.RemoveStatusCondition(&ext.Status.Conditions, ocv1.TypeChannelDeprecated)
307+
SetStatusCondition(&ext.Status.Conditions, metav1.Condition{
308+
Type: ocv1.TypeChannelDeprecated,
309+
Status: metav1.ConditionFalse,
310+
Reason: ocv1.ReasonNotDeprecated,
311+
Message: "channel not deprecated",
312+
ObservedGeneration: ext.GetGeneration(),
313+
})
297314
}
298315

299-
// BundleDeprecated: Unknown when no bundle installed, True when deprecated, absent otherwise
316+
// BundleDeprecated: Unknown when no bundle installed, True when deprecated, False when not
300317
if info.BundleStatus == metav1.ConditionUnknown {
301318
SetStatusCondition(&ext.Status.Conditions, metav1.Condition{
302319
Type: ocv1.TypeBundleDeprecated,
@@ -314,7 +331,13 @@ func SetDeprecationStatus(ext *ocv1.ClusterExtension, installedBundleName string
314331
ObservedGeneration: ext.GetGeneration(),
315332
})
316333
} else {
317-
apimeta.RemoveStatusCondition(&ext.Status.Conditions, ocv1.TypeBundleDeprecated)
334+
SetStatusCondition(&ext.Status.Conditions, metav1.Condition{
335+
Type: ocv1.TypeBundleDeprecated,
336+
Status: metav1.ConditionFalse,
337+
Reason: ocv1.ReasonNotDeprecated,
338+
Message: "bundle not deprecated",
339+
ObservedGeneration: ext.GetGeneration(),
340+
})
318341
}
319342
}
320343

0 commit comments

Comments
 (0)