From a2a8f057fb04090e6fa54e9065e5c924e7a8964c Mon Sep 17 00:00:00 2001 From: Jack Ottofaro Date: Mon, 28 Mar 2022 14:19:37 -0400 Subject: [PATCH 1/2] vendor: Bump library-go to pickup Include --- go.mod | 2 +- go.sum | 11 +- .../config/leaderelection/leaderelection.go | 13 ++- .../library-go/pkg/manifest/manifest.go | 100 ++++++++++++++++++ vendor/modules.txt | 2 +- 5 files changed, 116 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 0c41226a55..674061803d 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/imdario/mergo v0.3.8 // indirect github.com/openshift/api v0.0.0-20220325173635-8107b7a38e53 github.com/openshift/client-go v0.0.0-20211209144617-7385dd6338e3 - github.com/openshift/library-go v0.0.0-20211209153216-ed9bc958bd8a + github.com/openshift/library-go v0.0.0-20220329193146-715792ed530d github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.11.0 github.com/prometheus/client_model v0.2.0 diff --git a/go.sum b/go.sum index 0dbefea1eb..09e2929a89 100644 --- a/go.sum +++ b/go.sum @@ -64,6 +64,7 @@ github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/RangelReale/osincli v0.0.0-20160924135400-fababb0555f2/go.mod h1:XyjUkMA8GN+tOOPXvnbi3XuRxWFvTJntqvTFnjmhzbk= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -483,19 +484,15 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/openshift/api v0.0.0-20211209135129-c58d9f695577/go.mod h1:DoslCwtqUpr3d/gsbq4ZlkaMEdYqKxuypsDjorcHhME= -github.com/openshift/api v0.0.0-20220208222216-7e3ffb09accd h1:EaCz2jR4vZvtTBGXBLD4V3Lwg96DDAK+wsZvS8+1+EE= -github.com/openshift/api v0.0.0-20220208222216-7e3ffb09accd/go.mod h1:F/eU6jgr6Q2VhMu1mSpMmygxAELd7+BUxs3NHZ25jV4= -github.com/openshift/api v0.0.0-20220317153038-a2ca88c44400 h1:DMzrYI2PxPHFGQEWLSiHnAcF8l3wYDlGk1kUlEPhSC8= -github.com/openshift/api v0.0.0-20220317153038-a2ca88c44400/go.mod h1:F/eU6jgr6Q2VhMu1mSpMmygxAELd7+BUxs3NHZ25jV4= +github.com/openshift/api v0.0.0-20220315184754-d7c10d0b647e/go.mod h1:F/eU6jgr6Q2VhMu1mSpMmygxAELd7+BUxs3NHZ25jV4= github.com/openshift/api v0.0.0-20220325173635-8107b7a38e53 h1:WpOfczPbuY5llRH94DJRsGTsgm7d8iAA2b7m0+YXAqI= github.com/openshift/api v0.0.0-20220325173635-8107b7a38e53/go.mod h1:F/eU6jgr6Q2VhMu1mSpMmygxAELd7+BUxs3NHZ25jV4= github.com/openshift/build-machinery-go v0.0.0-20210712174854-1bb7fd1518d3/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= -github.com/openshift/build-machinery-go v0.0.0-20210806203541-4ea9b6da3a37/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/openshift/build-machinery-go v0.0.0-20211213093930-7e33a7eb4ce3/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/openshift/client-go v0.0.0-20211209144617-7385dd6338e3 h1:SG1aqwleU6bGD0X4mhkTNupjVnByMYYuW4XbnCPavQU= github.com/openshift/client-go v0.0.0-20211209144617-7385dd6338e3/go.mod h1:cwhyki5lqBmrT0m8Im+9I7PGFaraOzcYPtEz93RcsGY= -github.com/openshift/library-go v0.0.0-20211209153216-ed9bc958bd8a h1:MoAaYFrzB5QlYzO7phyjx/JBxghUrLitwb69RaulRAs= -github.com/openshift/library-go v0.0.0-20211209153216-ed9bc958bd8a/go.mod h1:M/Gi/GUUrMdSS07nrYtTiK43J6/VUAyk/+IfN4ZqUY4= +github.com/openshift/library-go v0.0.0-20220329193146-715792ed530d h1:uEOiLtoPeRfnsust0rTediph3fYqUxBVgJ5zWVMnxwY= +github.com/openshift/library-go v0.0.0-20220329193146-715792ed530d/go.mod h1:5a5oGzRGu6XjtAmChVlwstxp0MWDGh7fIXlN34mFiLA= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= diff --git a/vendor/github.com/openshift/library-go/pkg/config/leaderelection/leaderelection.go b/vendor/github.com/openshift/library-go/pkg/config/leaderelection/leaderelection.go index 5cec68257b..edbd10fb1d 100644 --- a/vendor/github.com/openshift/library-go/pkg/config/leaderelection/leaderelection.go +++ b/vendor/github.com/openshift/library-go/pkg/config/leaderelection/leaderelection.go @@ -22,8 +22,15 @@ import ( configv1 "github.com/openshift/api/config/v1" ) -// ToConfigMapLeaderElection returns a leader election config that you just need to fill in the Callback for. Don't forget the callbacks! -func ToConfigMapLeaderElection(clientConfig *rest.Config, config configv1.LeaderElection, component, identity string) (leaderelection.LeaderElectionConfig, error) { +// ToLeaderElectionWithConfigmapLease returns a "configmapsleases" based leader +// election config that you just need to fill in the Callback for. +// It is compatible with a "configmaps" based leader election and +// paves the way toward using "leases" based leader election. +// See https://github.com/kubernetes/kubernetes/issues/107454 for +// details on how to migrate to "leases" leader election. +// Don't forget the callbacks! +// TODO: In the next version we should switch to using "leases" +func ToLeaderElectionWithConfigmapLease(clientConfig *rest.Config, config configv1.LeaderElection, component, identity string) (leaderelection.LeaderElectionConfig, error) { kubeClient, err := kubernetes.NewForConfig(clientConfig) if err != nil { return leaderelection.LeaderElectionConfig{}, err @@ -50,7 +57,7 @@ func ToConfigMapLeaderElection(clientConfig *rest.Config, config configv1.Leader eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.CoreV1().RESTClient()).Events("")}) eventRecorder := eventBroadcaster.NewRecorder(clientgoscheme.Scheme, corev1.EventSource{Component: component}) rl, err := resourcelock.New( - resourcelock.ConfigMapsResourceLock, + resourcelock.ConfigMapsLeasesResourceLock, config.Namespace, config.Name, kubeClient.CoreV1(), diff --git a/vendor/github.com/openshift/library-go/pkg/manifest/manifest.go b/vendor/github.com/openshift/library-go/pkg/manifest/manifest.go index 820277f79b..3553295b3b 100644 --- a/vendor/github.com/openshift/library-go/pkg/manifest/manifest.go +++ b/vendor/github.com/openshift/library-go/pkg/manifest/manifest.go @@ -6,7 +6,9 @@ import ( "io" "os" "path/filepath" + "strings" + configv1 "github.com/openshift/api/config/v1" "github.com/pkg/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" @@ -15,6 +17,11 @@ import ( "k8s.io/client-go/kubernetes/scheme" ) +const ( + CapabilityAnnotation = "capability.openshift.io/name" + DefaultClusterProfile = "self-managed-high-availability" +) + // resourceId uniquely identifies a Kubernetes resource. // It is used to identify any duplicate resources within // a given set of manifests. @@ -98,6 +105,99 @@ func (m *Manifest) UnmarshalJSON(in []byte) error { return validateResourceId(m.id) } +// Include returns an error if the manifest fails an inclusion filter and should not be excluded from futher +// processing by cluster version operator. Pointer arguments can be set nil to avoid excluding based on that +// filter. For example, setting profile non-nil and capabilities nil will return an error if the manifest's +// profile does not match, but will never return an error about capability issues. +func (m *Manifest) Include(excludeIdentifier *string, includeTechPreview *bool, profile *string, capabilities *configv1.ClusterVersionCapabilitiesStatus) error { + + annotations := m.Obj.GetAnnotations() + if annotations == nil { + return fmt.Errorf("no annotations") + } + + if excludeIdentifier != nil { + excludeAnnotation := fmt.Sprintf("exclude.release.openshift.io/%s", *excludeIdentifier) + if v := annotations[excludeAnnotation]; v == "true" { + return fmt.Errorf("%s=%s", excludeAnnotation, v) + } + } + + if includeTechPreview != nil { + featureGateAnnotation := "release.openshift.io/feature-gate" + featureGateAnnotationValue, featureGateAnnotationExists := annotations[featureGateAnnotation] + if featureGateAnnotationValue == string(configv1.TechPreviewNoUpgrade) && !(*includeTechPreview) { + return fmt.Errorf("tech-preview excluded, and %s=%s", featureGateAnnotation, featureGateAnnotationValue) + } + // never include the manifest if the feature-gate annotation is outside of allowed values (only TechPreviewNoUpgrade is currently allowed) + if featureGateAnnotationExists && featureGateAnnotationValue != string(configv1.TechPreviewNoUpgrade) { + return fmt.Errorf("unrecognized value %s=%s", featureGateAnnotation, featureGateAnnotationValue) + } + } + + if profile != nil { + profileAnnotation := fmt.Sprintf("include.release.openshift.io/%s", *profile) + if val, ok := annotations[profileAnnotation]; ok && val != "true" { + return fmt.Errorf("unrecognized value %s=%s", profileAnnotation, val) + } else if !ok { + return fmt.Errorf("%s unset", profileAnnotation) + } + } + + // If there is no capabilities defined in a release then we do not need to check presence of capabilities in the manifest + if capabilities != nil { + return checkResourceEnablement(annotations, capabilities) + } + return nil +} + +// checkResourceEnablement, given resource annotations and defined cluster capabilities, checks if the capability +// annotation exists. If so, each capability name is validated against the known set of capabilities. Each valid +// capability is then checked if it is disabled. If any invalid capabilities are found an error is returned listing +// all invalid capabilities. Otherwise, if any disabled capabilities are found an error is returned listing all +// disabled capabilities. +func checkResourceEnablement(annotations map[string]string, capabilities *configv1.ClusterVersionCapabilitiesStatus) error { + val, ok := annotations[CapabilityAnnotation] + if !ok { + return nil + } + caps := strings.Split(val, "+") + numCaps := len(caps) + unknownCaps := make([]string, 0, numCaps) + disabledCaps := make([]string, 0, numCaps) + + var isKnownCap bool = false + var isEnabledCap bool = false + + for _, c := range caps { + for _, knownCapability := range capabilities.KnownCapabilities { + if c == string(knownCapability) { + isKnownCap = true + } + } + if !isKnownCap { + unknownCaps = append(unknownCaps, c) + continue + } + for _, enabledCapability := range capabilities.EnabledCapabilities { + if c == string(enabledCapability) { + isEnabledCap = true + } + + } + if !isEnabledCap { + disabledCaps = append(disabledCaps, c) + } + } + if len(unknownCaps) > 0 { + return fmt.Errorf("unrecognized capability names: %s", strings.Join(unknownCaps, ", ")) + } + if len(disabledCaps) > 0 { + return fmt.Errorf("disabled capabilities: %s", strings.Join(disabledCaps, ", ")) + } + return nil +} + // ManifestsFromFiles reads files and returns Manifests in the same order. // 'files' should be list of absolute paths for the manifests on disk. An // error is returned for each manifest that defines a duplicate resource diff --git a/vendor/modules.txt b/vendor/modules.txt index 69b51445b4..95d2aef6f7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -84,7 +84,7 @@ github.com/openshift/client-go/image/clientset/versioned/scheme github.com/openshift/client-go/image/clientset/versioned/typed/image/v1 github.com/openshift/client-go/security/clientset/versioned/scheme github.com/openshift/client-go/security/clientset/versioned/typed/security/v1 -# github.com/openshift/library-go v0.0.0-20211209153216-ed9bc958bd8a +# github.com/openshift/library-go v0.0.0-20220329193146-715792ed530d ## explicit github.com/openshift/library-go/pkg/config/clusterstatus github.com/openshift/library-go/pkg/config/leaderelection From 3a30caf7f18c931669550ba175fcd05f2f00da08 Mon Sep 17 00:00:00 2001 From: Jack Ottofaro Date: Mon, 28 Mar 2022 16:11:01 -0400 Subject: [PATCH 2/2] capability: disallow disabling, add enabling capabilities --- hack/cluster-version-util/task_graph.go | 3 +- lib/capability/capability.go | 95 +++--- lib/capability/capability_test.go | 139 +++------ pkg/cvo/cvo.go | 7 +- pkg/cvo/cvo_scenarios_test.go | 368 +++++++++++++++--------- pkg/cvo/cvo_test.go | 45 +++ pkg/cvo/status.go | 40 ++- pkg/cvo/status_test.go | 2 + pkg/cvo/sync_test.go | 82 +++++- pkg/cvo/sync_worker.go | 76 +++-- pkg/payload/payload.go | 44 +-- pkg/payload/payload_test.go | 135 +-------- pkg/payload/task_graph_test.go | 3 +- 13 files changed, 553 insertions(+), 486 deletions(-) diff --git a/hack/cluster-version-util/task_graph.go b/hack/cluster-version-util/task_graph.go index 6fe47e2059..9c4aae33b4 100644 --- a/hack/cluster-version-util/task_graph.go +++ b/hack/cluster-version-util/task_graph.go @@ -7,7 +7,6 @@ import ( "github.com/spf13/cobra" - "github.com/openshift/cluster-version-operator/lib/capability" "github.com/openshift/cluster-version-operator/pkg/payload" ) @@ -31,7 +30,7 @@ func newTaskGraphCmd() *cobra.Command { func runTaskGraphCmd(cmd *cobra.Command, args []string) error { manifestDir := args[0] - release, err := payload.LoadUpdate(manifestDir, "", "", false, payload.DefaultClusterProfile, capability.ClusterCapabilities{}) + release, err := payload.LoadUpdate(manifestDir, "", "", false, payload.DefaultClusterProfile, nil) if err != nil { return err } diff --git a/lib/capability/capability.go b/lib/capability/capability.go index b8c5207fcb..c182201721 100644 --- a/lib/capability/capability.go +++ b/lib/capability/capability.go @@ -1,9 +1,8 @@ package capability import ( - "fmt" + "reflect" "sort" - "strings" configv1 "github.com/openshift/api/config/v1" ) @@ -15,8 +14,13 @@ const ( ) type ClusterCapabilities struct { - KnownCapabilities map[configv1.ClusterVersionCapability]struct{} - EnabledCapabilities map[configv1.ClusterVersionCapability]struct{} + KnownCapabilities map[configv1.ClusterVersionCapability]struct{} + EnabledCapabilities map[configv1.ClusterVersionCapability]struct{} + ImplicitlyEnabledCapabilities []configv1.ClusterVersionCapability +} + +func (c *ClusterCapabilities) Equal(capabilities *ClusterCapabilities) bool { + return reflect.DeepEqual(c.EnabledCapabilities, capabilities.EnabledCapabilities) } type capabilitiesSort []configv1.ClusterVersionCapability @@ -25,14 +29,30 @@ func (caps capabilitiesSort) Len() int { return len(caps) } func (caps capabilitiesSort) Swap(i, j int) { caps[i], caps[j] = caps[j], caps[i] } func (caps capabilitiesSort) Less(i, j int) bool { return string(caps[i]) < string(caps[j]) } -// SetCapabilities populates and returns cluster capabilities from ClusterVersion capabilities spec. -func SetCapabilities(config *configv1.ClusterVersion) ClusterCapabilities { +// SetCapabilities populates and returns cluster capabilities from ClusterVersion capabilities spec. This method also +// ensures that no previousily enabled capability is now disabled and returns any such implicitly enabled capabilities. +func SetCapabilities(config *configv1.ClusterVersion, + existingEnabled map[configv1.ClusterVersionCapability]struct{}) ClusterCapabilities { + var capabilities ClusterCapabilities - capabilities.KnownCapabilities = setKnownCapabilities(config) - capabilities.EnabledCapabilities = setEnabledCapabilities(config) + capabilities.KnownCapabilities = setKnownCapabilities() + + capabilities.EnabledCapabilities, capabilities.ImplicitlyEnabledCapabilities = setEnabledCapabilities(config.Spec.Capabilities, + existingEnabled) + return capabilities } +// GetKnownCapabilities returns all known capabilities as defined in ClusterVersion. +func GetKnownCapabilities() []configv1.ClusterVersionCapability { + var known []configv1.ClusterVersionCapability + + for _, v := range configv1.ClusterVersionCapabilitySets { + known = append(known, v...) + } + return known +} + // GetCapabilitiesStatus populates and returns ClusterVersion capabilities status from given capabilities. func GetCapabilitiesStatus(capabilities ClusterCapabilities) configv1.ClusterVersionCapabilitiesStatus { var status configv1.ClusterVersionCapabilitiesStatus @@ -47,39 +67,8 @@ func GetCapabilitiesStatus(capabilities ClusterCapabilities) configv1.ClusterVer return status } -// CheckResourceEnablement, given resource annotations and defined cluster capabilities, checks if the capability -// annotation exists. If so, each capability name is validated against the known set of capabilities. Each valid -// capability is then checked if it is disabled. If any invalid capabilities are found an error is returned listing -// all invalid capabilities. Otherwise, if any disabled capabilities are found an error is returned listing all -// disabled capabilities. -func CheckResourceEnablement(annotations map[string]string, capabilities ClusterCapabilities) error { - val, ok := annotations[CapabilityAnnotation] - if !ok { - return nil - } - caps := strings.Split(val, "+") - numCaps := len(caps) - unknownCaps := make([]string, 0, numCaps) - disabledCaps := make([]string, 0, numCaps) - - for _, c := range caps { - if _, ok = capabilities.KnownCapabilities[configv1.ClusterVersionCapability(c)]; !ok { - unknownCaps = append(unknownCaps, c) - } else if _, ok = capabilities.EnabledCapabilities[configv1.ClusterVersionCapability(c)]; !ok { - disabledCaps = append(disabledCaps, c) - } - } - if len(unknownCaps) > 0 { - return fmt.Errorf("unrecognized capability names: %s", strings.Join(unknownCaps, ", ")) - } - if len(disabledCaps) > 0 { - return fmt.Errorf("disabled capabilities: %s", strings.Join(disabledCaps, ", ")) - } - return nil -} - // setKnownCapabilities populates a map keyed by capability from all known capabilities as defined in ClusterVersion. -func setKnownCapabilities(config *configv1.ClusterVersion) map[configv1.ClusterVersionCapability]struct{} { +func setKnownCapabilities() map[configv1.ClusterVersionCapability]struct{} { known := make(map[configv1.ClusterVersionCapability]struct{}) for _, v := range configv1.ClusterVersionCapabilitySets { @@ -94,27 +83,39 @@ func setKnownCapabilities(config *configv1.ClusterVersion) map[configv1.ClusterV } // setEnabledCapabilities populates a map keyed by capability from all enabled capabilities as defined in ClusterVersion. -// DefaultCapabilitySet is used if a baseline capability set is not defined by ClusterVersion. -func setEnabledCapabilities(config *configv1.ClusterVersion) map[configv1.ClusterVersionCapability]struct{} { +// DefaultCapabilitySet is used if a baseline capability set is not defined by ClusterVersion. A check is then made to +// ensure that no previousily enabled capability is now disabled and if any such capabilities are found each is enabled, +// saved, and returned. +func setEnabledCapabilities(capabilitiesSpec *configv1.ClusterVersionCapabilitiesSpec, + priorEnabled map[configv1.ClusterVersionCapability]struct{}) (map[configv1.ClusterVersionCapability]struct{}, + []configv1.ClusterVersionCapability) { + enabled := make(map[configv1.ClusterVersionCapability]struct{}) capSet := DefaultCapabilitySet - if config.Spec.Capabilities != nil && len(config.Spec.Capabilities.BaselineCapabilitySet) > 0 { - capSet = config.Spec.Capabilities.BaselineCapabilitySet + if capabilitiesSpec != nil && len(capabilitiesSpec.BaselineCapabilitySet) > 0 { + capSet = capabilitiesSpec.BaselineCapabilitySet } for _, v := range configv1.ClusterVersionCapabilitySets[capSet] { enabled[v] = struct{}{} } - if config.Spec.Capabilities != nil { - for _, v := range config.Spec.Capabilities.AdditionalEnabledCapabilities { + if capabilitiesSpec != nil { + for _, v := range capabilitiesSpec.AdditionalEnabledCapabilities { if _, ok := enabled[v]; ok { continue } enabled[v] = struct{}{} } } - return enabled + var implicitlyEnabled []configv1.ClusterVersionCapability + for k := range priorEnabled { + if _, ok := enabled[k]; !ok { + implicitlyEnabled = append(implicitlyEnabled, k) + enabled[k] = struct{}{} + } + } + return enabled, implicitlyEnabled } diff --git a/lib/capability/capability_test.go b/lib/capability/capability_test.go index 5465ee8809..94024f13d4 100644 --- a/lib/capability/capability_test.go +++ b/lib/capability/capability_test.go @@ -122,7 +122,7 @@ func TestSetCapabilities(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - caps := SetCapabilities(test.config) + caps := SetCapabilities(test.config, nil) if test.config.Spec.Capabilities == nil || (test.config.Spec.Capabilities != nil && len(test.config.Spec.Capabilities.BaselineCapabilitySet) == 0) { @@ -149,6 +149,46 @@ func TestSetCapabilities(t *testing.T) { } } +func TestSetCapabilitiesWithImplicitlyEnabled(t *testing.T) { + tests := []struct { + name string + config *configv1.ClusterVersion + wantImplicit []string + priorEnabled map[configv1.ClusterVersionCapability]struct{} + }{ + {name: "set capabilities 4_11 with additional", + config: &configv1.ClusterVersion{ + Spec: configv1.ClusterVersionSpec{ + Capabilities: &configv1.ClusterVersionCapabilitiesSpec{ + BaselineCapabilitySet: configv1.ClusterVersionCapabilitySet4_11, + }, + }, + }, + priorEnabled: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}, "cap3": {}}, + wantImplicit: []string{"cap1", "cap2", "cap3"}, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + caps := SetCapabilities(test.config, test.priorEnabled) + if len(caps.ImplicitlyEnabledCapabilities) != len(test.wantImplicit) { + t.Errorf("Incorrect number of implicitly enabled keys, wanted: %q. ImplicitlyEnabledCapabilities returned: %v", test.wantImplicit, caps.ImplicitlyEnabledCapabilities) + } + for _, wanted := range test.wantImplicit { + found := false + for _, have := range caps.ImplicitlyEnabledCapabilities { + if wanted == string(have) { + found = true + } + } + if !found { + t.Errorf("Missing ImplicitlyEnabledCapabilities key %q. ImplicitlyEnabledCapabilities returned : %v", wanted, caps.ImplicitlyEnabledCapabilities) + } + } + }) + } +} + func TestGetCapabilitiesStatus(t *testing.T) { tests := []struct { name string @@ -215,103 +255,6 @@ func TestGetCapabilitiesStatus(t *testing.T) { } } -func TestCheckResourceEnablement(t *testing.T) { - tests := []struct { - name string - annotations map[string]string - caps ClusterCapabilities - wantError string - }{ - {name: "empty annotations"}, - {name: "no capabilitity annotation", - annotations: map[string]string{"foo": "bar"}, - }, - {name: "known capabilitity annotation", - annotations: map[string]string{CapabilityAnnotation: string(configv1.ClusterVersionCapabilityOpenShiftSamples), "foo": "bar"}, - caps: ClusterCapabilities{ - KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}}, - EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}}, - }, - }, - {name: "multiple enabled capabilitities annotation", - annotations: map[string]string{CapabilityAnnotation: "cap1+cap2"}, - caps: ClusterCapabilities{ - KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}}, - EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}}, - }, - }, - {name: "multiple capabilitities annotation with spaces", - annotations: map[string]string{CapabilityAnnotation: " + cap1 +cap2+ "}, - caps: ClusterCapabilities{ - KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}}, - EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}}, - }, - wantError: "unrecognized capability names: , cap1 , ", - }, - {name: "unrecognized capabilitity annotation", - annotations: map[string]string{CapabilityAnnotation: "cap1"}, - caps: ClusterCapabilities{ - KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}}, - EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}}, - }, - wantError: "unrecognized capability names: cap1", - }, - {name: "unrecognized capabilitities, spaces", - annotations: map[string]string{CapabilityAnnotation: "cap1 + cap2"}, - caps: ClusterCapabilities{ - KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}}, - EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}}, - }, - wantError: "unrecognized capability names: cap1 , cap2", - }, - {name: "invalid capabilitity annotation divider", - annotations: map[string]string{CapabilityAnnotation: "cap1,cap2,cap3,cap4"}, - caps: ClusterCapabilities{ - KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}}, - EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}}, - }, - wantError: "unrecognized capability names: cap1,cap2,cap3,cap4", - }, - {name: "multiple unrecognized capabilitities annotation", - annotations: map[string]string{CapabilityAnnotation: "cap1+cap2+cap3+cap4"}, - caps: ClusterCapabilities{ - KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}}, - EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{configv1.ClusterVersionCapabilityOpenShiftSamples: {}}, - }, - wantError: "unrecognized capability names: cap1, cap2, cap3, cap4", - }, - {name: "disabled capabilitity annotation", - annotations: map[string]string{CapabilityAnnotation: "cap1"}, - caps: ClusterCapabilities{ - KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}}, - EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{}, - }, - wantError: "disabled capabilities: cap1", - }, - {name: "multiple disabled capabilitities annotation", - annotations: map[string]string{CapabilityAnnotation: "cap1+cap2+cap3+cap4+cap5+cap6"}, - caps: ClusterCapabilities{ - KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}, - "cap3": {}, "cap4": {}, "cap5": {}, "cap6": {}}, - EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}, "cap2": {}, "cap3": {}}, - }, - wantError: "disabled capabilities: cap4, cap5, cap6", - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - err := CheckResourceEnablement(test.annotations, test.caps) - if len(test.wantError) == 0 { - if err != nil { - t.Errorf("Wanted no error, got error %q", err.Error()) - } - } else if test.wantError != err.Error() { - t.Errorf("Wanted error %q, got error %q", test.wantError, err.Error()) - } - }) - } -} - func getDefaultCapabilities() []string { var caps []string diff --git a/pkg/cvo/cvo.go b/pkg/cvo/cvo.go index 1a48c79de5..fda11e5a3a 100644 --- a/pkg/cvo/cvo.go +++ b/pkg/cvo/cvo.go @@ -222,14 +222,12 @@ func New( // payload appears to be in error rather than continuing. func (optr *Operator) InitializeFromPayload(ctx context.Context, restConfig *rest.Config, burstRestConfig *rest.Config) error { - var config *configv1.ClusterVersion - // wait until cluster version object exists if err := wait.PollImmediateInfiniteWithContext(ctx, 3*time.Second, func(ctx context.Context) (bool, error) { var err error // ensure the cluster version exists - config, _, err = optr.getClusterVersion(ctx) + _, _, err = optr.getClusterVersion(ctx) if err != nil { if apierrors.IsNotFound(err) { klog.V(2).Infof("No cluster version object, waiting for one") @@ -241,10 +239,9 @@ func (optr *Operator) InitializeFromPayload(ctx context.Context, restConfig *res }); err != nil { return fmt.Errorf("Error when attempting to get cluster version object: %w", err) } - capabilities := capability.SetCapabilities(config) update, err := payload.LoadUpdate(optr.defaultPayloadDir(), optr.release.Image, optr.exclude, optr.includeTechPreview, - optr.clusterProfile, capabilities) + optr.clusterProfile, capability.GetKnownCapabilities()) if err != nil { return fmt.Errorf("the local release contents are invalid - no current version can be determined from disk: %v", err) diff --git a/pkg/cvo/cvo_scenarios_test.go b/pkg/cvo/cvo_scenarios_test.go index ed6f2698d6..ec90571389 100644 --- a/pkg/cvo/cvo_scenarios_test.go +++ b/pkg/cvo/cvo_scenarios_test.go @@ -164,6 +164,7 @@ func TestCVO_StartupAndSync(t *testing.T) { // empty because the operator release image is not set, so we have no input }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, // report back to the user that we don't have enough info to proceed {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Reason: "NoDesiredImage", Message: "No configured operator version, unable to update cluster"}, @@ -212,6 +213,7 @@ func TestCVO_StartupAndSync(t *testing.T) { KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, // cleared failing status and set progressing {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -262,9 +264,11 @@ func TestCVO_StartupAndSync(t *testing.T) { LastTransitionTime: time.Unix(3, 0), Release: configv1.Release{Version: "1.0.0-abc", Image: "image/image:1"}, }, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, }, SyncWorkerStatus{ @@ -286,9 +290,11 @@ func TestCVO_StartupAndSync(t *testing.T) { LastTransitionTime: time.Unix(4, 0), Release: configv1.Release{Version: "1.0.0-abc", Image: "image/image:1"}, }, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, }, SyncWorkerStatus{ @@ -310,9 +316,11 @@ func TestCVO_StartupAndSync(t *testing.T) { LastTransitionTime: time.Unix(5, 0), Release: configv1.Release{Version: "1.0.0-abc", Image: "image/image:1"}, }, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, }, SyncWorkerStatus{ @@ -335,9 +343,11 @@ func TestCVO_StartupAndSync(t *testing.T) { LastTransitionTime: time.Unix(6, 0), Release: configv1.Release{Version: "1.0.0-abc", Image: "image/image:1"}, }, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, }, ) @@ -384,6 +394,7 @@ func TestCVO_StartupAndSync(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:1", Version: "1.0.0-abc", StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 1.0.0-abc"}, @@ -408,9 +419,11 @@ func TestCVO_StartupAndSync(t *testing.T) { URL: configv1.URL("https://example.com/v1.0.0-abc"), Channels: []string{"channel-a", "channel-b", "channel-c"}, }, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -432,9 +445,11 @@ func TestCVO_StartupAndSync(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, LastProgress: time.Unix(1, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -456,9 +471,11 @@ func TestCVO_StartupAndSync(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, LastProgress: time.Unix(2, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -481,9 +498,11 @@ func TestCVO_StartupAndSync(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, LastProgress: time.Unix(3, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -562,6 +581,7 @@ func TestCVO_StartupAndSyncUnverifiedPayload(t *testing.T) { // empty because the operator release image is not set, so we have no input }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, // report back to the user that we don't have enough info to proceed {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Reason: "NoDesiredImage", Message: "No configured operator version, unable to update cluster"}, @@ -610,6 +630,7 @@ func TestCVO_StartupAndSyncUnverifiedPayload(t *testing.T) { KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, // cleared failing status and set progressing {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -657,9 +678,11 @@ func TestCVO_StartupAndSyncUnverifiedPayload(t *testing.T) { }, LastProgress: time.Unix(2, 0), Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -681,9 +704,11 @@ func TestCVO_StartupAndSyncUnverifiedPayload(t *testing.T) { }, LastProgress: time.Unix(3, 0), Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -705,9 +730,11 @@ func TestCVO_StartupAndSyncUnverifiedPayload(t *testing.T) { }, LastProgress: time.Unix(4, 0), Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -765,6 +792,7 @@ func TestCVO_StartupAndSyncUnverifiedPayload(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:1", Version: "1.0.0-abc", StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 1.0.0-abc"}, @@ -789,9 +817,11 @@ func TestCVO_StartupAndSyncUnverifiedPayload(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -813,9 +843,11 @@ func TestCVO_StartupAndSyncUnverifiedPayload(t *testing.T) { }, Generation: 1, LastProgress: time.Unix(1, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -837,9 +869,11 @@ func TestCVO_StartupAndSyncUnverifiedPayload(t *testing.T) { }, Generation: 1, LastProgress: time.Unix(2, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -862,9 +896,11 @@ func TestCVO_StartupAndSyncUnverifiedPayload(t *testing.T) { }, LastProgress: time.Unix(3, 0), Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -933,6 +969,7 @@ func TestCVO_StartupAndSyncPreconditionFailing(t *testing.T) { // empty because the operator release image is not set, so we have no input }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, // report back to the user that we don't have enough info to proceed {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Reason: "NoDesiredImage", Message: "No configured operator version, unable to update cluster"}, @@ -981,6 +1018,7 @@ func TestCVO_StartupAndSyncPreconditionFailing(t *testing.T) { KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, // cleared failing status and set progressing {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1034,9 +1072,11 @@ func TestCVO_StartupAndSyncPreconditionFailing(t *testing.T) { LastTransitionTime: time.Unix(3, 0), Release: configv1.Release{Version: "1.0.0-abc", Image: "image/image:1"}, }, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, }, SyncWorkerStatus{ @@ -1058,9 +1098,11 @@ func TestCVO_StartupAndSyncPreconditionFailing(t *testing.T) { LastTransitionTime: time.Unix(4, 0), Release: configv1.Release{Version: "1.0.0-abc", Image: "image/image:1"}, }, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, }, SyncWorkerStatus{ @@ -1076,9 +1118,11 @@ func TestCVO_StartupAndSyncPreconditionFailing(t *testing.T) { }, LastProgress: time.Unix(4, 0), Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -1135,6 +1179,7 @@ func TestCVO_StartupAndSyncPreconditionFailing(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:1", Version: "1.0.0-abc", StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 1.0.0-abc"}, @@ -1159,9 +1204,11 @@ func TestCVO_StartupAndSyncPreconditionFailing(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -1183,9 +1230,11 @@ func TestCVO_StartupAndSyncPreconditionFailing(t *testing.T) { }, LastProgress: time.Unix(1, 0), Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -1207,9 +1256,11 @@ func TestCVO_StartupAndSyncPreconditionFailing(t *testing.T) { }, LastProgress: time.Unix(2, 0), Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -1232,9 +1283,11 @@ func TestCVO_StartupAndSyncPreconditionFailing(t *testing.T) { }, LastProgress: time.Unix(3, 0), Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -1371,6 +1424,7 @@ func TestCVO_UpgradeUnverifiedPayload(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:0", Version: "1.0.0-abc", Verified: true, StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: DesiredReleaseAccepted, Status: configv1.ConditionFalse, Reason: "RetrievePayload", Message: "Retrieving payload failed version=\"1.0.1-abc\" image=\"image/image:1\" failure=The update cannot be verified: some random error"}, {Type: "Available", Status: "False"}, @@ -1444,9 +1498,11 @@ func TestCVO_UpgradeUnverifiedPayload(t *testing.T) { URL: configv1.URL("https://example.com/v1.0.1-abc"), }, Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -1498,6 +1554,7 @@ func TestCVO_UpgradeUnverifiedPayload(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:0", Version: "1.0.0-abc", Verified: true, StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: DesiredReleaseAccepted, Status: configv1.ConditionTrue, Reason: "PayloadLoaded", Message: "Payload loaded version=\"1.0.1-abc\" image=\"image/image:1\""}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.1-abc"}, @@ -1538,6 +1595,7 @@ func TestCVO_UpgradeUnverifiedPayloadRetrieveOnce(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:0", Version: "1.0.0-abc", Verified: true, StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 1.0.0-abc"}, @@ -1627,6 +1685,7 @@ func TestCVO_UpgradeUnverifiedPayloadRetrieveOnce(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:0", Version: "1.0.0-abc", Verified: true, StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, // cleared failing status and set progressing {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1701,9 +1760,11 @@ func TestCVO_UpgradeUnverifiedPayloadRetrieveOnce(t *testing.T) { URL: configv1.URL("https://example.com/v1.0.1-abc"), }, Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -1756,6 +1817,7 @@ func TestCVO_UpgradeUnverifiedPayloadRetrieveOnce(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:0", Version: "1.0.0-abc", Verified: true, StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 1.0.1-abc"}, @@ -1779,9 +1841,11 @@ func TestCVO_UpgradeUnverifiedPayloadRetrieveOnce(t *testing.T) { URL: configv1.URL("https://example.com/v1.0.1-abc"), }, Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -1802,9 +1866,11 @@ func TestCVO_UpgradeUnverifiedPayloadRetrieveOnce(t *testing.T) { }, Generation: 1, LastProgress: time.Unix(1, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -1825,9 +1891,11 @@ func TestCVO_UpgradeUnverifiedPayloadRetrieveOnce(t *testing.T) { }, Generation: 1, LastProgress: time.Unix(2, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -1849,9 +1917,11 @@ func TestCVO_UpgradeUnverifiedPayloadRetrieveOnce(t *testing.T) { }, LastProgress: time.Unix(3, 0), Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -1892,6 +1962,7 @@ func TestCVO_UpgradePreconditionFailing(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:0", Version: "1.0.0-abc", Verified: true, StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 1.0.0-abc"}, @@ -2019,9 +2090,11 @@ func TestCVO_UpgradePreconditionFailing(t *testing.T) { URL: configv1.URL("https://example.com/v1.0.1-abc"), }, Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2041,9 +2114,11 @@ func TestCVO_UpgradePreconditionFailing(t *testing.T) { }, LastProgress: time.Unix(1, 0), Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2063,9 +2138,11 @@ func TestCVO_UpgradePreconditionFailing(t *testing.T) { }, LastProgress: time.Unix(2, 0), Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2118,6 +2195,7 @@ func TestCVO_UpgradePreconditionFailing(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:0", Version: "1.0.0-abc", Verified: true, StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 1.0.1-abc"}, @@ -2158,6 +2236,7 @@ func TestCVO_UpgradeVerifiedPayload(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:0", Version: "1.0.0-abc", Verified: true, StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 1.0.0-abc"}, @@ -2224,6 +2303,7 @@ func TestCVO_UpgradeVerifiedPayload(t *testing.T) { KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, // cleared failing status and set progressing {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -2278,6 +2358,7 @@ func TestCVO_RestartAndReconcile(t *testing.T) { {State: configv1.PartialUpdate, StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 1.0.0-abc"}, @@ -2348,9 +2429,11 @@ func TestCVO_RestartAndReconcile(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, LastProgress: time.Unix(2, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2371,9 +2454,11 @@ func TestCVO_RestartAndReconcile(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, LastProgress: time.Unix(3, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2394,9 +2479,11 @@ func TestCVO_RestartAndReconcile(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, LastProgress: time.Unix(4, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2435,9 +2522,11 @@ func TestCVO_RestartAndReconcile(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, LastProgress: time.Unix(1, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2457,9 +2546,11 @@ func TestCVO_RestartAndReconcile(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, LastProgress: time.Unix(2, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2480,9 +2571,11 @@ func TestCVO_RestartAndReconcile(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, LastProgress: time.Unix(3, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2503,9 +2596,11 @@ func TestCVO_RestartAndReconcile(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, LastProgress: time.Unix(4, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2568,6 +2663,7 @@ func TestCVO_ErrorDuringReconcile(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:1", Version: "1.0.0-abc", Verified: true, StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 1.0.0-abc"}, @@ -2659,9 +2755,11 @@ func TestCVO_ErrorDuringReconcile(t *testing.T) { URL: configv1.URL("https://example.com/v1.0.0-abc"), Channels: []string{"channel-a", "channel-b", "channel-c"}, }, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2693,9 +2791,11 @@ func TestCVO_ErrorDuringReconcile(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, LastProgress: time.Unix(1, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2742,9 +2842,11 @@ func TestCVO_ErrorDuringReconcile(t *testing.T) { Channels: []string{"channel-a", "channel-b", "channel-c"}, }, LastProgress: time.Unix(1, 0), - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2790,6 +2892,7 @@ func TestCVO_ErrorDuringReconcile(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:1", Version: "1.0.0-abc", Verified: true, StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Reason: "UpdatePayloadFailed", Message: "Could not update test \"file-yml\" (3 of 3)"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Reason: "UpdatePayloadFailed", Message: "Error while reconciling 1.0.0-abc: the update could not be applied"}, @@ -2912,9 +3015,11 @@ func TestCVO_ParallelError(t *testing.T) { Actual: configv1.Release{Version: "1.0.0-abc", Image: "image/image:1"}, LastProgress: status.LastProgress, Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2945,9 +3050,11 @@ func TestCVO_ParallelError(t *testing.T) { Actual: configv1.Release{Version: "1.0.0-abc", Image: "image/image:1"}, LastProgress: status.LastProgress, Generation: 1, - CapabilitiesStatus: configv1.ClusterVersionCapabilitiesStatus{ - EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, - KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + CapabilitiesStatus: CapabilityStatus{ + Status: configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + KnownCapabilities: []configv1.ClusterVersionCapability{"baremetal", "marketplace", "openshift-samples"}, + }, }, loadPayloadStatus: LoadPayloadStatus{ Step: "PayloadLoaded", @@ -2995,6 +3102,7 @@ func TestCVO_ParallelError(t *testing.T) { {State: configv1.PartialUpdate, Image: "image/image:1", Version: "1.0.0-abc", StartedTime: defaultStartedTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: DesiredReleaseAccepted, Status: configv1.ConditionTrue, Reason: "PayloadLoaded", Message: "Payload loaded version=\"1.0.0-abc\" image=\"image/image:1\""}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, @@ -3040,6 +3148,7 @@ func TestCVO_VerifyInitializingPayloadState(t *testing.T) { {State: configv1.PartialUpdate, Image: "image/image:1", Version: "1.0.0-abc", StartedTime: defaultStartedTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 1.0.0-abc"}, @@ -3100,6 +3209,7 @@ func TestCVO_VerifyUpdatingPayloadState(t *testing.T) { {State: configv1.CompletedUpdate, Image: "image/image:0", Version: "1.0.0-abc.0", StartedTime: defaultStartedTime, CompletionTime: &defaultCompletionTime}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 1.0.0-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 1.0.0-abc"}, diff --git a/pkg/cvo/cvo_test.go b/pkg/cvo/cvo_test.go index a99a85c553..a562a70483 100644 --- a/pkg/cvo/cvo_test.go +++ b/pkg/cvo/cvo_test.go @@ -255,6 +255,7 @@ func TestOperator_sync(t *testing.T) { {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Reason: "UpdatePayloadIntegrity", Message: "unable to apply object"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Reason: "UpdatePayloadIntegrity", Message: "Unable to apply 0.0.1-abc: the contents of the update are invalid"}, {Type: configv1.RetrievedUpdates, Status: configv1.ConditionFalse}, + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, }, }, }) @@ -298,6 +299,7 @@ func TestOperator_sync(t *testing.T) { {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Reason: "UpdatePayloadIntegrity", Message: "unable to apply object"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Working towards 4.0.1"}, {Type: configv1.RetrievedUpdates, Status: configv1.ConditionFalse}, + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, }, }, }, @@ -329,6 +331,7 @@ func TestOperator_sync(t *testing.T) { {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Reason: "UpdatePayloadIntegrity", Message: "unable to apply object"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Reason: "UpdatePayloadIntegrity", Message: "Error while reconciling 0.0.1-abc: the contents of the update are invalid"}, {Type: configv1.RetrievedUpdates, Status: configv1.ConditionFalse}, + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, }, }, }) @@ -369,6 +372,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Version: "4.0.1", Image: "image/image:v4.0.1"}, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Reason: "UpdatePayloadIntegrity", Message: "unable to apply object"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Working towards 4.0.1"}, @@ -400,6 +404,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Version: "0.0.1-abc", Image: "image/image:v4.0.1"}, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Reason: "UpdatePayloadIntegrity", Message: "unable to apply object"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Reason: "UpdatePayloadIntegrity", Message: "Error while reconciling 0.0.1-abc: the contents of the update are invalid"}, @@ -439,6 +444,7 @@ func TestOperator_sync(t *testing.T) { }, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Message: "unable to apply object"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Working towards 4.0.1"}, @@ -471,6 +477,7 @@ func TestOperator_sync(t *testing.T) { }, VersionHash: "foo", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Message: "injected error"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Unable to apply 0.0.1-abc: an error occurred"}, @@ -525,6 +532,7 @@ func TestOperator_sync(t *testing.T) { }, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Message: "file does not exist"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Unable to apply 4.0.1: an error occurred"}, @@ -594,6 +602,7 @@ func TestOperator_sync(t *testing.T) { Conditions: []configv1.ClusterOperatorStatusCondition{ // the order of progressing in the conditions array is preserved {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Unable to apply 4.0.1: an error occurred"}, + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Message: "file does not exist"}, {Type: configv1.RetrievedUpdates, Status: configv1.ConditionFalse}, @@ -653,6 +662,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1"}, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Working towards image/image:v4.0.1"}, @@ -696,6 +706,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1"}, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Initializing, will work towards image/image:v4.0.1"}, @@ -739,6 +750,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.2", Version: "4.0.2"}, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Working towards 4.0.2"}, @@ -795,6 +807,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.2"}, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Working towards 4.0.2"}, @@ -848,6 +861,7 @@ func TestOperator_sync(t *testing.T) { }, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, // we don't reset the message here until the image is loaded @@ -908,6 +922,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1", Version: "4.0.1"}, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, // we don't reset the message here until the image is loaded @@ -959,6 +974,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1", Version: "4.0.1"}, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, // we correct the message that was incorrect from the previous state @@ -1059,6 +1075,7 @@ func TestOperator_sync(t *testing.T) { }, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, // we correct the message that was incorrect from the previous state @@ -1102,6 +1119,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1"}, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Initializing, will work towards image/image:v4.0.1"}, @@ -1134,6 +1152,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1", Version: "0.0.1-abc"}, VersionHash: "xyz", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Working towards 0.0.1-abc"}, @@ -1186,6 +1205,7 @@ func TestOperator_sync(t *testing.T) { VersionHash: "xyz", ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, @@ -1254,6 +1274,7 @@ func TestOperator_sync(t *testing.T) { Status: configv1.ClusterVersionStatus{ ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1300,6 +1321,7 @@ func TestOperator_sync(t *testing.T) { }, ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 0.0.1-abc"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1343,6 +1365,7 @@ func TestOperator_sync(t *testing.T) { Status: configv1.ClusterVersionStatus{ ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1375,6 +1398,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1", Version: "0.0.1-abc"}, ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 0.0.1-abc"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1420,6 +1444,7 @@ func TestOperator_sync(t *testing.T) { Status: configv1.ClusterVersionStatus{ ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1453,6 +1478,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1", Version: "0.0.1-abc"}, ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 0.0.1-abc"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1494,6 +1520,7 @@ func TestOperator_sync(t *testing.T) { Status: configv1.ClusterVersionStatus{ ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1529,6 +1556,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1", Version: "0.0.1-abc"}, ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 0.0.1-abc"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1578,6 +1606,7 @@ func TestOperator_sync(t *testing.T) { Status: configv1.ClusterVersionStatus{ ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1614,6 +1643,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1", Version: "0.0.1-abc"}, ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 0.0.1-abc"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1662,6 +1692,7 @@ func TestOperator_sync(t *testing.T) { Status: configv1.ClusterVersionStatus{ ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1694,6 +1725,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1", Version: "0.0.1-abc"}, ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 0.0.1-abc"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, @@ -1758,6 +1790,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1", Version: "4.0.1"}, ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 4.0.1"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 4.0.1"}, @@ -1833,6 +1866,7 @@ func TestOperator_sync(t *testing.T) { ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ {Type: ClusterVersionInvalid, Status: configv1.ConditionTrue, Reason: "InvalidClusterVersion", Message: "The cluster version is invalid: spec.desiredUpdate.version: Invalid value: \"4.0.4\": when image is empty the update must be a previous version or an available update"}, + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 4.0.1"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Reason: "InvalidClusterVersion", Message: "Stopped at 4.0.1: the cluster version is invalid"}, @@ -1910,6 +1944,7 @@ func TestOperator_sync(t *testing.T) { }, Conditions: []configv1.ClusterOperatorStatusCondition{ {Type: ClusterVersionInvalid, Status: configv1.ConditionTrue, Reason: "InvalidClusterVersion", Message: "The cluster version is invalid: spec.desiredUpdate.version: Invalid value: \"4.0.3\": there are multiple possible payloads for this version, specify the exact image"}, + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 4.0.1"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Reason: "InvalidClusterVersion", Message: "Stopped at 4.0.1: the cluster version is invalid"}, @@ -1963,6 +1998,7 @@ func TestOperator_sync(t *testing.T) { VersionHash: "y_Kc5IQiIyU=", ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, @@ -2025,6 +2061,7 @@ func TestOperator_sync(t *testing.T) { VersionHash: "unknown_hash", ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, @@ -2064,6 +2101,7 @@ func TestOperator_sync(t *testing.T) { ObservedGeneration: 2, VersionHash: "y_Kc5IQiIyU=", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Message: "Cluster version is 0.0.1-abc"}, @@ -2127,6 +2165,7 @@ func TestOperator_sync(t *testing.T) { VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ {Type: ClusterVersionInvalid, Status: configv1.ConditionTrue, Reason: "InvalidClusterVersion", Message: "The cluster version is invalid:\n* spec.upstream: Invalid value: \"#%GG\": must be a valid URL or empty\n* spec.clusterID: Invalid value: \"not-valid-cluster-id\": must be an RFC4122-variant UUID\n"}, + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying 0.0.1-abc"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Reason: "InvalidClusterVersion", Message: "Stopped at 0.0.1-abc: the cluster version is invalid"}, @@ -2165,6 +2204,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Image: "image/image:v4.0.1"}, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse, Reason: "InvalidClusterVersion", Message: "Stopped at image/image:v4.0.1: the cluster version is invalid"}, @@ -2204,6 +2244,7 @@ func TestOperator_sync(t *testing.T) { Desired: configv1.Release{Version: "0.0.1-abc", Image: "image/image:v4.0.1"}, VersionHash: "", Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionFalse}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Reason: "InvalidClusterVersion", Message: "Reconciling 0.0.1-abc: the cluster version is invalid"}, @@ -2427,6 +2468,7 @@ func TestOperator_availableUpdatesSync(t *testing.T) { {Image: "image/image:v4.0.1"}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying image/image:v4.0.1"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse}, @@ -2487,6 +2529,7 @@ func TestOperator_availableUpdatesSync(t *testing.T) { {Image: "image/image:v4.0.1"}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying image/image:v4.0.1"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse}, @@ -2551,6 +2594,7 @@ func TestOperator_availableUpdatesSync(t *testing.T) { {Image: "image/image:v4.0.1"}, }, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying image/image:v4.0.1"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse}, @@ -2609,6 +2653,7 @@ func TestOperator_availableUpdatesSync(t *testing.T) { }, ObservedGeneration: 2, Conditions: []configv1.ClusterOperatorStatusCondition{ + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, {Type: configv1.OperatorAvailable, Status: configv1.ConditionTrue, Message: "Done applying image/image:v4.0.1"}, {Type: ClusterStatusFailing, Status: configv1.ConditionFalse}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionFalse}, diff --git a/pkg/cvo/status.go b/pkg/cvo/status.go index ee711239ab..78b79b88d9 100644 --- a/pkg/cvo/status.go +++ b/pkg/cvo/status.go @@ -159,6 +159,12 @@ const ClusterVersionInvalid configv1.ClusterStatusConditionType = "Invalid" // and no failures occurred during image verification and precondition checking. const DesiredReleaseAccepted configv1.ClusterStatusConditionType = "ReleaseAccepted" +// ImplicitlyEnabledCapabilities is True if there are enabled capabilities which the user is not currently +// requesting via spec.capabilities, because the cluster version operator does not support uninstalling +// capabilities if any associated resources were previously managed by the CVO or disabling previousily +// enabled capabilities. +const ImplicitlyEnabledCapabilities configv1.ClusterStatusConditionType = "ImplicitlyEnabledCapabilities" + // syncStatus calculates the new status of the ClusterVersion based on the current sync state and any // validation errors found. We allow the caller to pass the original object to avoid DeepCopying twice. func (optr *Operator) syncStatus(ctx context.Context, original, config *configv1.ClusterVersion, status *SyncWorkerStatus, validationErrs field.ErrorList) error { @@ -201,7 +207,7 @@ func (optr *Operator) syncStatus(ctx context.Context, original, config *configv1 desired := optr.mergeReleaseMetadata(status.Actual) mergeOperatorHistory(config, desired, status.Verified, now, status.Completed > 0) - config.Status.Capabilities = status.CapabilitiesStatus + config.Status.Capabilities = status.CapabilitiesStatus.Status // update validation errors var reason string @@ -228,6 +234,9 @@ func (optr *Operator) syncStatus(ctx context.Context, original, config *configv1 resourcemerge.RemoveOperatorStatusCondition(&config.Status.Conditions, ClusterVersionInvalid) } + // set the implicitly enabled capabilities condition + setImplicitlyEnabledCapabilitiesCondition(config, status.CapabilitiesStatus.ImplicitlyEnabledCaps, now) + // set the desired release accepted condition setDesiredReleaseAcceptedCondition(config, status.loadPayloadStatus, now) @@ -354,6 +363,35 @@ func (optr *Operator) syncStatus(ctx context.Context, original, config *configv1 return err } +func setImplicitlyEnabledCapabilitiesCondition(config *configv1.ClusterVersion, implicitlyEnabled []configv1.ClusterVersionCapability, + now metav1.Time) { + + if len(implicitlyEnabled) > 0 { + message := "The following capabilities could not be disabled: " + caps := make([]string, len(implicitlyEnabled)) + for i, c := range implicitlyEnabled { + caps[i] = string(c) + } + message = message + strings.Join([]string(caps), ", ") + + resourcemerge.SetOperatorStatusCondition(&config.Status.Conditions, configv1.ClusterOperatorStatusCondition{ + Type: ImplicitlyEnabledCapabilities, + Status: configv1.ConditionTrue, + Reason: "CapabilitiesImplicitlyEnabled", + Message: message, + LastTransitionTime: now, + }) + } else { + resourcemerge.SetOperatorStatusCondition(&config.Status.Conditions, configv1.ClusterOperatorStatusCondition{ + Type: ImplicitlyEnabledCapabilities, + Status: configv1.ConditionFalse, + Reason: "AsExpected", + Message: "Capabilities match configured spec", + LastTransitionTime: now, + }) + } +} + func setDesiredReleaseAcceptedCondition(config *configv1.ClusterVersion, status LoadPayloadStatus, now metav1.Time) { if status.Step == "PayloadLoaded" { resourcemerge.SetOperatorStatusCondition(&config.Status.Conditions, configv1.ClusterOperatorStatusCondition{ diff --git a/pkg/cvo/status_test.go b/pkg/cvo/status_test.go index e0b57bd915..b9354e7b24 100644 --- a/pkg/cvo/status_test.go +++ b/pkg/cvo/status_test.go @@ -186,6 +186,7 @@ func TestOperator_syncFailingStatus(t *testing.T) { {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Reason: "UpdatePayloadIntegrity", Message: "unable to apply object"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Message: "Working towards 4.0.1"}, {Type: configv1.RetrievedUpdates, Status: configv1.ConditionFalse}, + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, }, }, }, @@ -226,6 +227,7 @@ func TestOperator_syncFailingStatus(t *testing.T) { {Type: ClusterStatusFailing, Status: configv1.ConditionTrue, Reason: "", Message: "bad"}, {Type: configv1.OperatorProgressing, Status: configv1.ConditionTrue, Reason: "", Message: "Error ensuring the cluster version is up to date: bad"}, {Type: configv1.RetrievedUpdates, Status: configv1.ConditionFalse}, + {Type: ImplicitlyEnabledCapabilities, Status: "False", Reason: "AsExpected", Message: "Capabilities match configured spec"}, }, }, }) diff --git a/pkg/cvo/sync_test.go b/pkg/cvo/sync_test.go index 3b1b92fc2f..721042f31f 100644 --- a/pkg/cvo/sync_test.go +++ b/pkg/cvo/sync_test.go @@ -3,6 +3,7 @@ package cvo import ( "context" "encoding/json" + "flag" "fmt" "reflect" "strings" @@ -22,6 +23,7 @@ import ( dynamicfake "k8s.io/client-go/dynamic/fake" "k8s.io/client-go/rest" clientgotesting "k8s.io/client-go/testing" + "k8s.io/klog/v2" configv1 "github.com/openshift/api/config/v1" configlistersv1 "github.com/openshift/client-go/config/listers/config/v1" @@ -33,6 +35,12 @@ import ( "github.com/openshift/library-go/pkg/manifest" ) +func init() { + klog.InitFlags(flag.CommandLine) + _ = flag.CommandLine.Lookup("v").Value.Set("2") + _ = flag.CommandLine.Lookup("alsologtostderr").Value.Set("true") +} + func Test_SyncWorker_apply(t *testing.T) { tests := []struct { manifests []string @@ -48,7 +56,10 @@ func Test_SyncWorker_apply(t *testing.T) { "kind": "TestA", "metadata": { "namespace": "default", - "name": "testa" + "name": "testa", + "annotations": { + "include.release.openshift.io/self-managed-high-availability": "true" + } } }`, `{ @@ -56,7 +67,10 @@ func Test_SyncWorker_apply(t *testing.T) { "kind": "TestB", "metadata": { "namespace": "default", - "name": "testb" + "name": "testb", + "annotations": { + "include.release.openshift.io/self-managed-high-availability": "true" + } } }`, }, @@ -81,7 +95,10 @@ func Test_SyncWorker_apply(t *testing.T) { "kind": "TestA", "metadata": { "namespace": "default", - "name": "testa" + "name": "testa", + "annotations": { + "include.release.openshift.io/self-managed-high-availability": "true" + } } }`, `{ @@ -89,7 +106,10 @@ func Test_SyncWorker_apply(t *testing.T) { "kind": "TestB", "metadata": { "namespace": "default", - "name": "testb" + "name": "testb", + "annotations": { + "include.release.openshift.io/self-managed-high-availability": "true" + } } }`, }, @@ -108,6 +128,28 @@ func Test_SyncWorker_apply(t *testing.T) { t.Fatalf("%s", diff.ObjectReflectDiff(exp, got)) } }, + }, { + manifests: []string{ + `{ + "apiVersion": "test.cvo.io/v1", + "kind": "TestA", + "metadata": { + "namespace": "default", + "name": "testa", + "annotations": { + "include.release.openshift.io/self-managed-high-availability": "true", + "capability.openshift.io/name": "openshift-samples+baremetal" + } + } + }`, + }, + reactors: map[action]error{}, + check: func(t *testing.T, actions []action) { + if len(actions) != 0 { + spew.Dump(actions) + t.Fatalf("unexpected %d actions", len(actions)) + } + }, }} for idx, test := range tests { t.Run(fmt.Sprintf("test#%d", idx), func(t *testing.T) { @@ -189,7 +231,10 @@ func Test_SyncWorker_apply_generic(t *testing.T) { "kind": "TestA", "metadata": { "namespace": "default", - "name": "testa" + "name": "testa", + "annotations": { + "include.release.openshift.io/self-managed-high-availability": "true" + } } }`, `{ @@ -197,7 +242,10 @@ func Test_SyncWorker_apply_generic(t *testing.T) { "kind": "TestB", "metadata": { "namespace": "default", - "name": "testb" + "name": "testb", + "annotations": { + "include.release.openshift.io/self-managed-high-availability": "true" + } } }`, }, @@ -216,6 +264,9 @@ func Test_SyncWorker_apply_generic(t *testing.T) { "metadata": map[string]interface{}{ "name": "testa", "namespace": "default", + "annotations": map[string]interface{}{ + "include.release.openshift.io/self-managed-high-availability": "true", + }, }, }, } @@ -231,6 +282,9 @@ func Test_SyncWorker_apply_generic(t *testing.T) { "metadata": map[string]interface{}{ "name": "testb", "namespace": "default", + "annotations": map[string]interface{}{ + "include.release.openshift.io/self-managed-high-availability": "true", + }, }, }, } @@ -256,7 +310,10 @@ func Test_SyncWorker_apply_generic(t *testing.T) { "kind": "TestA", "metadata": { "namespace": "default", - "name": "testa" + "name": "testa", + "annotations": { + "include.release.openshift.io/self-managed-high-availability": "true" + } } }`, `{ @@ -264,7 +321,10 @@ func Test_SyncWorker_apply_generic(t *testing.T) { "kind": "TestB", "metadata": { "namespace": "default", - "name": "testb" + "name": "testb", + "annotations": { + "include.release.openshift.io/self-managed-high-availability": "true" + } } }`, }, @@ -284,6 +344,9 @@ func Test_SyncWorker_apply_generic(t *testing.T) { "name": "testa", "namespace": "default", "labels": map[string]interface{}{"test/label": "a"}, + "annotations": map[string]interface{}{ + "include.release.openshift.io/self-managed-high-availability": "true", + }, }, }, } @@ -300,6 +363,9 @@ func Test_SyncWorker_apply_generic(t *testing.T) { "name": "testb", "namespace": "default", "labels": map[string]interface{}{"test/label": "a"}, + "annotations": map[string]interface{}{ + "include.release.openshift.io/self-managed-high-availability": "true", + }, }, }, } diff --git a/pkg/cvo/sync_worker.go b/pkg/cvo/sync_worker.go index 5400d350e9..9c72c65375 100644 --- a/pkg/cvo/sync_worker.go +++ b/pkg/cvo/sync_worker.go @@ -94,6 +94,11 @@ type LoadPayloadStatus struct { LastTransitionTime time.Time } +type CapabilityStatus struct { + Status configv1.ClusterVersionCapabilitiesStatus + ImplicitlyEnabledCaps []configv1.ClusterVersionCapability +} + // SyncWorkerStatus is the status of the sync worker at a given time. type SyncWorkerStatus struct { Generation int64 @@ -117,7 +122,7 @@ type SyncWorkerStatus struct { loadPayloadStatus LoadPayloadStatus - CapabilitiesStatus configv1.ClusterVersionCapabilitiesStatus + CapabilitiesStatus CapabilityStatus } // DeepCopy copies the worker status. @@ -269,7 +274,8 @@ func (w *SyncWorker) syncPayload(ctx context.Context, work *SyncWork, reporter S } w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeNormal, "LoadPayload", "Loading payload version=%q image=%q", desired.Version, desired.Image) - payloadUpdate, err := payload.LoadUpdate(info.Directory, desired.Image, w.exclude, w.includeTechPreview, w.clusterProfile, work.Capabilities) + payloadUpdate, err := payload.LoadUpdate(info.Directory, desired.Image, w.exclude, w.includeTechPreview, w.clusterProfile, + capability.GetKnownCapabilities()) if err != nil { msg := fmt.Sprintf("Loading payload failed version=%q image=%q failure=%v", desired.Version, desired.Image, err) w.eventRecorder.Eventf(cvoObjectRef, corev1.EventTypeWarning, "LoadPayloadFailed", msg) @@ -352,6 +358,7 @@ func (w *SyncWorker) syncPayload(ctx context.Context, work *SyncWork, reporter S // loadUpdatedPayload retrieves the image. If successfully retrieved it updates payload otherwise it returns an error. func (w *SyncWorker) loadUpdatedPayload(ctx context.Context, work *SyncWork, cvoOptrName string) error { + // reporter hides status updates that occur earlier than the previous failure, // so that we don't fail, then immediately start reporting an earlier status reporter := &statusWrapper{w: w, previousStatus: w.status.DeepCopy()} @@ -379,9 +386,12 @@ func (w *SyncWorker) Update(ctx context.Context, generation int64, desired confi Overrides: config.Spec.Overrides, } + var priorCaps map[configv1.ClusterVersionCapability]struct{} + // the sync worker’s generation should always be latest with every change if w.work != nil { w.work.Generation = generation + priorCaps = w.work.Capabilities.EnabledCapabilities } if work.Empty() { @@ -389,13 +399,16 @@ func (w *SyncWorker) Update(ctx context.Context, generation int64, desired confi return w.status.DeepCopy() } - work.Capabilities = capability.SetCapabilities(config) - versionEqual, overridesEqual := equalSyncWork(w.work, work, fmt.Sprintf("considering cluster version generation %d", generation)) + work.Capabilities = capability.SetCapabilities(config, priorCaps) - if versionEqual && overridesEqual { + versionEqual, overridesEqual, capabilitiesEqual := + equalSyncWork(w.work, work, fmt.Sprintf("considering cluster version generation %d", generation)) + + if versionEqual && overridesEqual && capabilitiesEqual { klog.V(2).Info("Update work is equal to current target; no change required") return w.status.DeepCopy() } + w.status.CapabilitiesStatus.ImplicitlyEnabledCaps = work.Capabilities.ImplicitlyEnabledCapabilities // initialize the reconciliation flag and the status the first time // update is invoked @@ -421,7 +434,7 @@ func (w *SyncWorker) Update(ctx context.Context, generation int64, desired confi } else if !versionEqual && state == payload.InitializingPayload { klog.Warningf("Ignoring detected version change from %v to %v during payload initialization", *oldDesired, work.Desired) w.work.Desired = *oldDesired - if overridesEqual { + if overridesEqual && capabilitiesEqual { return w.status.DeepCopy() } } @@ -433,7 +446,7 @@ func (w *SyncWorker) Update(ctx context.Context, generation int64, desired confi return w.status.DeepCopy() } - w.status.CapabilitiesStatus = capability.GetCapabilitiesStatus(w.work.Capabilities) + w.status.CapabilitiesStatus.Status = capability.GetCapabilitiesStatus(w.work.Capabilities) // notify the sync loop that we changed config if w.cancelFn != nil { @@ -610,8 +623,8 @@ func (w *SyncWorker) calculateNext(work *SyncWork) bool { w.lock.Lock() defer w.lock.Unlock() - sameVersion, sameOverrides := equalSyncWork(work, w.work, "calculating next work") - changed := !sameVersion || !sameOverrides + sameVersion, sameOverrides, sameCapabilities := equalSyncWork(work, w.work, "calculating next work") + changed := !sameVersion || !sameOverrides || !sameCapabilities // if this is the first time through the loop, initialize reconciling to // the state Update() calculated (to allow us to start in reconciling) @@ -627,6 +640,7 @@ func (w *SyncWorker) calculateNext(work *SyncWork) bool { if w.work != nil { work.Desired = w.work.Desired work.Overrides = w.work.Overrides + work.Capabilities = w.work.Capabilities } work.Generation = w.work.Generation @@ -665,32 +679,36 @@ func splitDigest(pullspec string) string { return parts[1] } -// equalSyncWork returns indications of whether release version has changed and whether overrides have changed. -func equalSyncWork(a, b *SyncWork, context string) (equalVersion, equalOverrides bool) { +// equalSyncWork returns indications of whether release version has changed, whether overrides have changed, +// and whether capabilities have changed. +func equalSyncWork(a, b *SyncWork, context string) (equalVersion, equalOverrides, equalCapabilities bool) { // if both `a` and `b` are the same then simply return true if a == b { - return true, true + return true, true, true } // if either `a` or `b` are nil then return false if a == nil || b == nil { - return false, false + return false, false, false } sameVersion := equalUpdate(a.Desired, b.Desired) sameOverrides := reflect.DeepEqual(a.Overrides, b.Overrides) + sameCapabilities := a.Capabilities.Equal(&b.Capabilities) - var detected string - if !sameVersion && !sameOverrides { - detected = fmt.Sprintf("version (from %v to %v) and overrides changes", a.Desired, b.Desired) - } else if !sameVersion { - detected = fmt.Sprintf("version change (from %v to %v)", a.Desired, b.Desired) - } else if !sameOverrides { - detected = fmt.Sprintf("overrides change (%v to %v)", a.Overrides, b.Overrides) + var msgs []string + if !sameVersion { + msgs = append(msgs, fmt.Sprintf("version changed (from %v to %v)", a.Desired, b.Desired)) + } + if !sameOverrides { + msgs = append(msgs, fmt.Sprintf("overrides changed (%v to %v)", a.Overrides, b.Overrides)) + } + if !sameCapabilities { + msgs = append(msgs, fmt.Sprintf("capabilities changed (%v to %v)", a.Capabilities, b.Capabilities)) } - if detected != "" { - klog.V(2).Infof("Detected while %s: %s", context, detected) + if len(msgs) > 0 { + klog.V(2).Infof("Detected while %s: %s", context, strings.Join(msgs, ", ")) } - return sameVersion, sameOverrides + return sameVersion, sameOverrides, sameCapabilities } // updateStatus records the current status of the sync action for observation @@ -763,6 +781,7 @@ func (w *SyncWorker) apply(ctx context.Context, work *SyncWork, maxWorkers int, if backoff.Steps > 1 && work.State == payload.InitializingPayload { backoff = wait.Backoff{Steps: 4, Factor: 2, Duration: time.Second} } + for i := range payloadUpdate.Manifests { tasks = append(tasks, &payload.Task{ Index: i + 1, @@ -771,6 +790,7 @@ func (w *SyncWorker) apply(ctx context.Context, work *SyncWork, maxWorkers int, Backoff: backoff, }) } + graph := payload.NewTaskGraph(tasks) graph.Split(payload.SplitOnJobs) var precreateObjects bool @@ -800,6 +820,7 @@ func (w *SyncWorker) apply(ctx context.Context, work *SyncWork, maxWorkers int, graph.Parallelize(payload.ByNumberAndComponent) precreateObjects = true } + capabilities := capability.GetCapabilitiesStatus(work.Capabilities) // update each object errs := payload.RunGraph(ctx, graph, maxWorkers, func(ctx context.Context, tasks []*payload.Task) error { @@ -818,6 +839,10 @@ func (w *SyncWorker) apply(ctx context.Context, work *SyncWork, maxWorkers int, klog.V(2).Infof("Skipping precreation of %s as unmanaged", task) continue } + if err := task.Manifest.Include(nil, nil, nil, &capabilities); err != nil { + klog.V(2).Infof("Skipping precreation of %s: %s", task, err) + continue + } if err := w.builder.Apply(ctx, task.Manifest, payload.PrecreatingPayload); err != nil { klog.V(2).Infof("Unable to precreate resource %s: %v", task, err) continue @@ -839,7 +864,10 @@ func (w *SyncWorker) apply(ctx context.Context, work *SyncWork, maxWorkers int, klog.V(2).Infof("Skipping %s as unmanaged", task) continue } - + if err := task.Manifest.Include(nil, nil, nil, &capabilities); err != nil { + klog.V(2).Infof("Skipping precreation of %s: %s", task, err) + continue + } if err := task.Run(ctx, payloadUpdate.Release.Version, w.builder, work.State); err != nil { return err } diff --git a/pkg/payload/payload.go b/pkg/payload/payload.go index 97086aabe2..b0ed3dbcb6 100644 --- a/pkg/payload/payload.go +++ b/pkg/payload/payload.go @@ -23,7 +23,6 @@ import ( configv1 "github.com/openshift/api/config/v1" imagev1 "github.com/openshift/api/image/v1" - "github.com/openshift/cluster-version-operator/lib/capability" "github.com/openshift/cluster-version-operator/lib/resourceread" "github.com/openshift/library-go/pkg/manifest" ) @@ -134,13 +133,19 @@ type metadata struct { } func LoadUpdate(dir, releaseImage, excludeIdentifier string, includeTechPreview bool, profile string, - capabilities capability.ClusterCapabilities) (*Update, error) { + knownCapabilities []configv1.ClusterVersionCapability) (*Update, error) { payload, tasks, err := loadUpdatePayloadMetadata(dir, releaseImage, profile) if err != nil { return nil, err } + // We only pass known capabilities at payload load time to avoid doing any capability + // enable filtering which only occurs during apply. + onlyKnownCaps := configv1.ClusterVersionCapabilitiesStatus{ + EnabledCapabilities: knownCapabilities, + KnownCapabilities: knownCapabilities} + var manifests []manifest.Manifest var errs []error for _, task := range tasks { @@ -190,7 +195,7 @@ func LoadUpdate(dir, releaseImage, excludeIdentifier string, includeTechPreview // Filter out manifests that should be excluded based on annotation filteredMs := []manifest.Manifest{} for _, manifest := range ms { - if err := include(excludeIdentifier, includeTechPreview, profile, capabilities, &manifest); err != nil { + if err := manifest.Include(&excludeIdentifier, &includeTechPreview, &profile, &onlyKnownCaps); err != nil { klog.V(2).Infof("excluding %s group=%s kind=%s namespace=%s name=%s: %v\n", manifest.OriginalFilename, manifest.GVK.Group, manifest.GVK.Kind, manifest.Obj.GetNamespace(), manifest.Obj.GetName(), err) continue } @@ -218,39 +223,6 @@ func LoadUpdate(dir, releaseImage, excludeIdentifier string, includeTechPreview return payload, nil } -func include(excludeIdentifier string, includeTechPreview bool, profile string, capabilities capability.ClusterCapabilities, - manifest *manifest.Manifest) error { - - annotations := manifest.Obj.GetAnnotations() - if annotations == nil { - return errors.New("no annotations") - } - - excludeAnnotation := fmt.Sprintf("exclude.release.openshift.io/%s", excludeIdentifier) - if v := annotations[excludeAnnotation]; v == "true" { - return fmt.Errorf("%s=%s", excludeAnnotation, v) - } - - featureGateAnnotation := "release.openshift.io/feature-gate" - featureGateAnnotationValue, featureGateAnnotationExists := annotations[featureGateAnnotation] - if featureGateAnnotationValue == "TechPreviewNoUpgrade" && !includeTechPreview { - return fmt.Errorf("tech-preview excluded, and %s=%s", featureGateAnnotation, featureGateAnnotationValue) - } - // never include the manifest if the feature-gate annotation is outside of allowed values (only TechPreviewNoUpgrade is currently allowed) - if featureGateAnnotationExists && featureGateAnnotationValue != "TechPreviewNoUpgrade" { - return fmt.Errorf("unrecognized value %s=%s", featureGateAnnotation, featureGateAnnotationValue) - } - - profileAnnotation := fmt.Sprintf("include.release.openshift.io/%s", profile) - if val, ok := annotations[profileAnnotation]; ok && val != "true" { - return fmt.Errorf("unrecognized value %s=%s", profileAnnotation, val) - } else if !ok { - return fmt.Errorf("%s unset", profileAnnotation) - } - - return capability.CheckResourceEnablement(annotations, capabilities) -} - // ValidateDirectory checks if a directory can be a candidate update by // looking for known files. It returns an error if the directory cannot // be an update. diff --git a/pkg/payload/payload_test.go b/pkg/payload/payload_test.go index 42d55605bb..ee9aa962a0 100644 --- a/pkg/payload/payload_test.go +++ b/pkg/payload/payload_test.go @@ -1,7 +1,6 @@ package payload import ( - "errors" "io/ioutil" "path/filepath" "reflect" @@ -16,7 +15,6 @@ import ( configv1 "github.com/openshift/api/config/v1" imagev1 "github.com/openshift/api/image/v1" - "github.com/openshift/cluster-version-operator/lib/capability" "github.com/openshift/library-go/pkg/manifest" ) @@ -115,7 +113,7 @@ func TestLoadUpdate(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := LoadUpdate(tt.args.dir, tt.args.releaseImage, "exclude-test", false, DefaultClusterProfile, capability.ClusterCapabilities{}) + got, err := LoadUpdate(tt.args.dir, tt.args.releaseImage, "exclude-test", false, DefaultClusterProfile, nil) if (err != nil) != tt.wantErr { t.Errorf("loadUpdatePayload() error = %v, wantErr %v", err, tt.wantErr) return @@ -137,134 +135,3 @@ func mustRead(path string) []byte { } return data } - -func Test_include(t *testing.T) { - tests := []struct { - name string - exclude string - includeTechPreview bool - profile string - annotations map[string]interface{} - caps capability.ClusterCapabilities - - expected error - }{ - { - name: "exclusion identifier set", - exclude: "identifier", - profile: DefaultClusterProfile, - annotations: map[string]interface{}{ - "exclude.release.openshift.io/identifier": "true", - "include.release.openshift.io/self-managed-high-availability": "true"}, - expected: errors.New("exclude.release.openshift.io/identifier=true"), - }, - { - name: "profile selection works", - profile: "single-node", - annotations: map[string]interface{}{"include.release.openshift.io/self-managed-high-availability": "true"}, - expected: errors.New("include.release.openshift.io/single-node unset"), - }, - { - name: "profile selection works included", - profile: DefaultClusterProfile, - annotations: map[string]interface{}{"include.release.openshift.io/self-managed-high-availability": "true"}, - }, - { - name: "correct techpreview value is excluded if techpreview off", - profile: DefaultClusterProfile, - annotations: map[string]interface{}{ - "include.release.openshift.io/self-managed-high-availability": "true", - "release.openshift.io/feature-gate": "TechPreviewNoUpgrade", - }, - expected: errors.New("tech-preview excluded, and release.openshift.io/feature-gate=TechPreviewNoUpgrade"), - }, - { - name: "correct techpreview value is included if techpreview on", - includeTechPreview: true, - profile: DefaultClusterProfile, - annotations: map[string]interface{}{ - "include.release.openshift.io/self-managed-high-availability": "true", - "release.openshift.io/feature-gate": "TechPreviewNoUpgrade", - }, - }, - { - name: "incorrect techpreview value is not excluded if techpreview off", - profile: DefaultClusterProfile, - annotations: map[string]interface{}{ - "include.release.openshift.io/self-managed-high-availability": "true", - "release.openshift.io/feature-gate": "Other", - }, - expected: errors.New("unrecognized value release.openshift.io/feature-gate=Other"), - }, - { - name: "incorrect techpreview value is not excluded if techpreview on", - includeTechPreview: true, - profile: DefaultClusterProfile, - annotations: map[string]interface{}{ - "include.release.openshift.io/self-managed-high-availability": "true", - "release.openshift.io/feature-gate": "Other", - }, - expected: errors.New("unrecognized value release.openshift.io/feature-gate=Other"), - }, - { - name: "default profile selection excludes without annotation", - profile: DefaultClusterProfile, - annotations: map[string]interface{}{}, - expected: errors.New("include.release.openshift.io/self-managed-high-availability unset"), - }, - { - name: "default profile selection excludes with no annotation", - profile: DefaultClusterProfile, - annotations: nil, - expected: errors.New("no annotations"), - }, - { - name: "unrecognized capability works", - profile: DefaultClusterProfile, - annotations: map[string]interface{}{ - "include.release.openshift.io/self-managed-high-availability": "true", - capability.CapabilityAnnotation: "cap1"}, - expected: errors.New("unrecognized capability names: cap1"), - }, - { - name: "disabled capability works", - profile: DefaultClusterProfile, - annotations: map[string]interface{}{ - "include.release.openshift.io/self-managed-high-availability": "true", - capability.CapabilityAnnotation: "cap1"}, - caps: capability.ClusterCapabilities{ - KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}}, - }, - expected: errors.New("disabled capabilities: cap1"), - }, - { - name: "enabled capability works", - profile: DefaultClusterProfile, - annotations: map[string]interface{}{ - "include.release.openshift.io/self-managed-high-availability": "true", - capability.CapabilityAnnotation: "cap1"}, - caps: capability.ClusterCapabilities{ - KnownCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}}, - EnabledCapabilities: map[configv1.ClusterVersionCapability]struct{}{"cap1": {}}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - metadata := map[string]interface{}{} - if tt.annotations != nil { - metadata["annotations"] = tt.annotations - } - err := include(tt.exclude, tt.includeTechPreview, tt.profile, tt.caps, &manifest.Manifest{ - Obj: &unstructured.Unstructured{ - Object: map[string]interface{}{ - "metadata": metadata, - }, - }, - }) - if !reflect.DeepEqual(err, tt.expected) { - t.Errorf("(exclude: %v, profile: %v, annotations: %v) expected %v, but got %v", tt.exclude, tt.profile, tt.annotations, tt.expected, err) - } - }) - } -} diff --git a/pkg/payload/task_graph_test.go b/pkg/payload/task_graph_test.go index 371c9b9547..fb96f750a5 100644 --- a/pkg/payload/task_graph_test.go +++ b/pkg/payload/task_graph_test.go @@ -15,7 +15,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/diff" - "github.com/openshift/cluster-version-operator/lib/capability" "github.com/openshift/library-go/pkg/manifest" ) @@ -488,7 +487,7 @@ func Test_TaskGraph_real(t *testing.T) { if len(path) == 0 { t.Skip("TEST_GRAPH_PATH unset") } - p, err := LoadUpdate(path, "arbitrary/image:1", "", false, DefaultClusterProfile, capability.ClusterCapabilities{}) + p, err := LoadUpdate(path, "arbitrary/image:1", "", false, DefaultClusterProfile, nil) if err != nil { t.Fatal(err) }