Skip to content

Commit d84278c

Browse files
(fix): report Unknown for deprecation status when catalog unavailable and prevent error leak
When a catalog is removed or unreachable, deprecation conditions now correctly show Unknown instead of False. BundleDeprecated now reflects the installed bundle and uses the correct reason. Assisted-by: Cursor
1 parent c06f27f commit d84278c

File tree

13 files changed

+772
-158
lines changed

13 files changed

+772
-158
lines changed

api/v1/clusterextension_types.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,12 @@ type ClusterExtensionStatus struct {
483483
// When Progressing is True and the Reason is Retrying, the ClusterExtension has encountered an error that could be resolved on subsequent reconciliation attempts.
484484
// When Progressing is False and the Reason is Blocked, the ClusterExtension has encountered an error that requires manual intervention for recovery.
485485
//
486-
// When the ClusterExtension is sourced from a catalog, if may also communicate a deprecation condition.
486+
// When the ClusterExtension is sourced from a catalog, it may surface deprecation conditions based on catalog metadata.
487487
// These are indications from a package owner to guide users away from a particular package, channel, or bundle.
488-
// BundleDeprecated is set if the requested bundle version is marked deprecated in the catalog.
489-
// ChannelDeprecated is set if the requested channel is marked deprecated in the catalog.
490-
// PackageDeprecated is set if the requested package is marked deprecated in the catalog.
491-
// Deprecated is a rollup condition that is present when any of the deprecated conditions are present.
488+
// - PackageDeprecated is set to True if the requested package is marked as deprecated in the catalog, False if it is not, or Unknown if the package is not found in the catalog.
489+
// - ChannelDeprecated is set to True if the requested channel is marked as deprecated in the catalog, False if it is not, or Unknown if the channel is not found in the catalog.
490+
// - BundleDeprecated is set to True if the installed bundle is marked as deprecated in the catalog, False if it is not, or Unknown if the bundle is not found in the catalog or could not be installed.
491+
// Deprecated is a rollup condition that is True when any individual deprecation condition is True, False when all deprecation conditions are False, and Unknown when we have no catalog information to report.
492492
//
493493
// +listType=map
494494
// +listMapKey=type

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

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

360360
| Field | Description | Default | Validation |
361361
| --- | --- | --- | --- |
362-
| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | The set of condition types which apply to all spec.source variations are Installed and Progressing.<br />The Installed condition represents whether or not 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 />When the ClusterExtension is sourced from a catalog, if may also communicate a deprecation condition.<br />These are indications from a package owner to guide users away from a particular package, channel, or bundle.<br />BundleDeprecated is set if the requested bundle version is marked deprecated in the catalog.<br />ChannelDeprecated is set if the requested channel is marked deprecated in the catalog.<br />PackageDeprecated is set if the requested package is marked deprecated in the catalog.<br />Deprecated is a rollup condition that is present when any of the deprecated conditions are present. | | |
362+
| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#condition-v1-meta) array_ | The set of condition types which apply to all spec.source variations are Installed and Progressing.<br />The Installed condition represents whether or not 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 />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 />- PackageDeprecated is set to True if the requested package is marked as deprecated in the catalog, False if it is not, or Unknown if the package is not found in the catalog.<br />- ChannelDeprecated is set to True if the requested channel is marked as deprecated in the catalog, False if it is not, or Unknown if the channel is not found in the catalog.<br />- BundleDeprecated is set to True if the installed bundle is marked as deprecated in the catalog, False if it is not, or Unknown if the bundle is not found in the catalog or could not be installed.<br />Deprecated is a rollup condition that is True when any individual deprecation condition is True, False when all deprecation conditions are False, and Unknown when we have no catalog information to report. | | |
363363
| `install` _[ClusterExtensionInstallStatus](#clusterextensioninstallstatus)_ | install is a representation of the current installation status for this ClusterExtension. | | |
364364

365365

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -518,12 +518,12 @@ spec:
518518
When Progressing is True and the Reason is Retrying, the ClusterExtension has encountered an error that could be resolved on subsequent reconciliation attempts.
519519
When Progressing is False and the Reason is Blocked, the ClusterExtension has encountered an error that requires manual intervention for recovery.
520520
521-
When the ClusterExtension is sourced from a catalog, if may also communicate a deprecation condition.
521+
When the ClusterExtension is sourced from a catalog, it may surface deprecation conditions based on catalog metadata.
522522
These are indications from a package owner to guide users away from a particular package, channel, or bundle.
523-
BundleDeprecated is set if the requested bundle version is marked deprecated in the catalog.
524-
ChannelDeprecated is set if the requested channel is marked deprecated in the catalog.
525-
PackageDeprecated is set if the requested package is marked deprecated in the catalog.
526-
Deprecated is a rollup condition that is present when any of the deprecated conditions are present.
523+
- PackageDeprecated is set to True if the requested package is marked as deprecated in the catalog, False if it is not, or Unknown if the package is not found in the catalog.
524+
- ChannelDeprecated is set to True if the requested channel is marked as deprecated in the catalog, False if it is not, or Unknown if the channel is not found in the catalog.
525+
- BundleDeprecated is set to True if the installed bundle is marked as deprecated in the catalog, False if it is not, or Unknown if the bundle is not found in the catalog or could not be installed.
526+
Deprecated is a rollup condition that is True when any individual deprecation condition is True, False when all deprecation conditions are False, and Unknown when we have no catalog information to report.
527527
items:
528528
description: Condition contains details for one aspect of the current
529529
state of this API Resource.

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -479,12 +479,12 @@ spec:
479479
When Progressing is True and the Reason is Retrying, the ClusterExtension has encountered an error that could be resolved on subsequent reconciliation attempts.
480480
When Progressing is False and the Reason is Blocked, the ClusterExtension has encountered an error that requires manual intervention for recovery.
481481
482-
When the ClusterExtension is sourced from a catalog, if may also communicate a deprecation condition.
482+
When the ClusterExtension is sourced from a catalog, it may surface deprecation conditions based on catalog metadata.
483483
These are indications from a package owner to guide users away from a particular package, channel, or bundle.
484-
BundleDeprecated is set if the requested bundle version is marked deprecated in the catalog.
485-
ChannelDeprecated is set if the requested channel is marked deprecated in the catalog.
486-
PackageDeprecated is set if the requested package is marked deprecated in the catalog.
487-
Deprecated is a rollup condition that is present when any of the deprecated conditions are present.
484+
- PackageDeprecated is set to True if the requested package is marked as deprecated in the catalog, False if it is not, or Unknown if the package is not found in the catalog.
485+
- ChannelDeprecated is set to True if the requested channel is marked as deprecated in the catalog, False if it is not, or Unknown if the channel is not found in the catalog.
486+
- BundleDeprecated is set to True if the installed bundle is marked as deprecated in the catalog, False if it is not, or Unknown if the bundle is not found in the catalog or could not be installed.
487+
Deprecated is a rollup condition that is True when any individual deprecation condition is True, False when all deprecation conditions are False, and Unknown when we have no catalog information to report.
488488
items:
489489
description: Condition contains details for one aspect of the current
490490
state of this API Resource.

internal/operator-controller/controllers/clusterextension_admission_test.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,20 @@ import (
1313
)
1414

1515
func TestClusterExtensionSourceConfig(t *testing.T) {
16-
sourceTypeEmptyError := "Invalid value: null"
16+
sourceTypeEmptyErrors := []string{"Invalid value: \"null\"", "Invalid value: null"}
1717
sourceTypeMismatchError := "spec.source.sourceType: Unsupported value"
1818
sourceConfigInvalidError := "spec.source: Invalid value"
1919
// unionField represents the required Catalog or (future) Bundle field required by SourceConfig
2020
testCases := []struct {
2121
name string
2222
sourceType string
2323
unionField string
24-
errMsg string
24+
errMsgs []string
2525
}{
26-
{"sourceType is null", "", "Catalog", sourceTypeEmptyError},
27-
{"sourceType is invalid", "Invalid", "Catalog", sourceTypeMismatchError},
28-
{"catalog field does not exist", "Catalog", "", sourceConfigInvalidError},
29-
{"sourceConfig has required fields", "Catalog", "Catalog", ""},
26+
{"sourceType is null", "", "Catalog", sourceTypeEmptyErrors},
27+
{"sourceType is invalid", "Invalid", "Catalog", []string{sourceTypeMismatchError}},
28+
{"catalog field does not exist", "Catalog", "", []string{sourceConfigInvalidError}},
29+
{"sourceConfig has required fields", "Catalog", "Catalog", nil},
3030
}
3131

3232
t.Parallel()
@@ -62,12 +62,20 @@ func TestClusterExtensionSourceConfig(t *testing.T) {
6262
}))
6363
}
6464

65-
if tc.errMsg == "" {
65+
if len(tc.errMsgs) == 0 {
6666
require.NoError(t, err, "unexpected error for sourceType %q: %w", tc.sourceType, err)
67-
} else {
68-
require.Error(t, err)
69-
require.Contains(t, err.Error(), tc.errMsg)
67+
return
68+
}
69+
70+
require.Error(t, err)
71+
matched := false
72+
for _, msg := range tc.errMsgs {
73+
if strings.Contains(err.Error(), msg) {
74+
matched = true
75+
break
76+
}
7077
}
78+
require.True(t, matched, "expected one of %v in error %q", tc.errMsgs, err)
7179
})
7280
}
7381
}

0 commit comments

Comments
 (0)