diff --git a/api/v1alpha1/clusterextension_types.go b/api/v1alpha1/clusterextension_types.go index c26ad991c..fb8903a34 100644 --- a/api/v1alpha1/clusterextension_types.go +++ b/api/v1alpha1/clusterextension_types.go @@ -61,12 +61,53 @@ type ClusterExtensionSpec struct { // Source SourceConfig `json:"source"` - // installNamespace is a reference to the Namespace in which the bundle of + // install is a required field used to configure the installation options + // for the ClusterExtension such as the installation namespace, + // the service account and the pre-flight check configuration. + // + // Below is a minimal example of an installation definition (in yaml): + // install: + // namespace: example-namespace + // serviceAccount: + // name: example-sa + Install ClusterExtensionInstallConfig `json:"install"` +} + +const SourceTypeCatalog = "Catalog" + +// SourceConfig is a discriminated union which selects the installation source. +// +union +// +kubebuilder:validation:XValidation:rule="self.sourceType == 'Catalog' && has(self.catalog)",message="sourceType Catalog requires catalog field" +type SourceConfig struct { + // sourceType is a required reference to the type of install source. + // + // Allowed values are ["Catalog"] + // + // When this field is set to "Catalog", information for determining the appropriate + // bundle of content to install will be fetched from ClusterCatalog resources existing + // on the cluster. When using the Catalog sourceType, the catalog field must also be set. + // + // +unionDiscriminator + // +kubebuilder:validation:Enum:="Catalog" + SourceType string `json:"sourceType"` + + // catalog is used to configure how information is sourced from a catalog. This field must be defined when sourceType is set to "Catalog", + // and must be the only field defined for this sourceType. + // + // +optional. + Catalog *CatalogSource `json:"catalog,omitempty"` +} + +// ClusterExtensionInstallConfig is a union which selects the clusterExtension installation config. +// ClusterExtensionInstallConfig requires the namespace and serviceAccount which should be used for the installation of packages. +// +union +type ClusterExtensionInstallConfig struct { + // namespace is a reference to the Namespace in which the bundle of // content for the package referenced in the packageName field will be applied. // The bundle may contain cluster-scoped resources or resources that are // applied to other Namespaces. This Namespace is expected to exist. // - // installNamespace is required, immutable, and follows the DNS label standard + // namespace is required, immutable, and follows the DNS label standard // as defined in [RFC 1123]. This means that valid values: // - Contain no more than 63 characters // - Contain only lowercase alphanumeric characters or '-' @@ -89,17 +130,8 @@ type ClusterExtensionSpec struct { // //+kubebuilder:validation:Pattern:=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ //+kubebuilder:validation:MaxLength:=63 - //+kubebuilder:validation:XValidation:rule="self == oldSelf",message="installNamespace is immutable" - InstallNamespace string `json:"installNamespace"` - - // preflight is an optional field that can be used to configure the preflight checks run before installation or upgrade of the content for the package specified in the packageName field. - // - // When specified, it overrides the default configuration of the preflight checks that are required to execute successfully during an install/upgrade operation. - // - // When not specified, the default configuration for each preflight check will be used. - // - //+optional - Preflight *PreflightConfig `json:"preflight,omitempty"` + //+kubebuilder:validation:XValidation:rule="self == oldSelf",message="namespace is immutable" + Namespace string `json:"namespace"` // serviceAccount is a required reference to a ServiceAccount that exists // in the installNamespace. The provided ServiceAccount is used to install and @@ -110,31 +142,15 @@ type ClusterExtensionSpec struct { // appropriate permissions to perform the necessary operations on all the // resources that are included in the bundle of content being applied. ServiceAccount ServiceAccountReference `json:"serviceAccount"` -} - -const SourceTypeCatalog = "Catalog" -// SourceConfig is a discriminated union which selects the installation source. -// +union -// +kubebuilder:validation:XValidation:rule="self.sourceType == 'Catalog' && has(self.catalog)",message="sourceType Catalog requires catalog field" -type SourceConfig struct { - // sourceType is a required reference to the type of install source. - // - // Allowed values are ["Catalog"] + // preflight is an optional field that can be used to configure the preflight checks run before installation or upgrade of the content for the package specified in the packageName field. // - // When this field is set to "Catalog", information for determining the appropriate - // bundle of content to install will be fetched from ClusterCatalog resources existing - // on the cluster. When using the Catalog sourceType, the catalog field must also be set. + // When specified, it overrides the default configuration of the preflight checks that are required to execute successfully during an install/upgrade operation. // - // +unionDiscriminator - // +kubebuilder:validation:Enum:="Catalog" - SourceType string `json:"sourceType"` - - // catalog is used to configure how information is sourced from a catalog. This field must be defined when sourceType is set to "Catalog", - // and must be the only field defined for this sourceType. + // When not specified, the default configuration for each preflight check will be used. // - // +optional. - Catalog *CatalogSource `json:"catalog,omitempty"` + //+optional + Preflight *PreflightConfig `json:"preflight,omitempty"` } // CatalogSource defines the required fields for catalog source. @@ -463,24 +479,9 @@ type BundleMetadata struct { // ClusterExtensionStatus defines the observed state of ClusterExtension. type ClusterExtensionStatus struct { - // installedBundle is a representation of the currently installed bundle. - // - // A "bundle" is a versioned set of content that represents the resources that - // need to be applied to a cluster to install a package. - // - // This field is only updated once a bundle has been successfully installed and - // once set will only be updated when a new version of the bundle has - // successfully replaced the currently installed version. - // - //+optional - InstalledBundle *BundleMetadata `json:"installedBundle,omitempty"` + Install *ClusterExtensionInstallStatus `json:"install,omitempty"` - // resolvedBundle is a representation of the bundle that was identified during - // resolution to meet all installation/upgrade constraints and is slated to be - // installed or upgraded to. - // - //+optional - ResolvedBundle *BundleMetadata `json:"resolvedBundle,omitempty"` + Resolution *ClusterExtensionResolutionStatus `json:"resolution,omitempty"` // conditions is a representation of the current state for this ClusterExtension. // The status is represented by a set of "conditions". @@ -514,6 +515,29 @@ type ClusterExtensionStatus struct { Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` } +type ClusterExtensionInstallStatus struct { + // bundle is a representation of the currently installed bundle. + // + // A "bundle" is a versioned set of content that represents the resources that + // need to be applied to a cluster to install a package. + // + // This field is only updated once a bundle has been successfully installed and + // once set will only be updated when a new version of the bundle has + // successfully replaced the currently installed version. + // + //+optional + Bundle *BundleMetadata `json:"bundle,omitempty"` +} + +type ClusterExtensionResolutionStatus struct { + // bundle is a representation of the bundle that was identified during + // resolution to meet all installation/upgrade constraints and is slated to be + // installed or upgraded to. + // + //+optional + Bundle *BundleMetadata `json:"bundle,omitempty"` +} + //+kubebuilder:object:root=true //+kubebuilder:resource:scope=Cluster //+kubebuilder:subresource:status diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 8e86e1dba..0d57be29f 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -98,6 +98,47 @@ func (in *ClusterExtension) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterExtensionInstallConfig) DeepCopyInto(out *ClusterExtensionInstallConfig) { + *out = *in + out.ServiceAccount = in.ServiceAccount + if in.Preflight != nil { + in, out := &in.Preflight, &out.Preflight + *out = new(PreflightConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterExtensionInstallConfig. +func (in *ClusterExtensionInstallConfig) DeepCopy() *ClusterExtensionInstallConfig { + if in == nil { + return nil + } + out := new(ClusterExtensionInstallConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterExtensionInstallStatus) DeepCopyInto(out *ClusterExtensionInstallStatus) { + *out = *in + if in.Bundle != nil { + in, out := &in.Bundle, &out.Bundle + *out = new(BundleMetadata) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterExtensionInstallStatus. +func (in *ClusterExtensionInstallStatus) DeepCopy() *ClusterExtensionInstallStatus { + if in == nil { + return nil + } + out := new(ClusterExtensionInstallStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterExtensionList) DeepCopyInto(out *ClusterExtensionList) { *out = *in @@ -130,16 +171,31 @@ func (in *ClusterExtensionList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterExtensionResolutionStatus) DeepCopyInto(out *ClusterExtensionResolutionStatus) { + *out = *in + if in.Bundle != nil { + in, out := &in.Bundle, &out.Bundle + *out = new(BundleMetadata) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterExtensionResolutionStatus. +func (in *ClusterExtensionResolutionStatus) DeepCopy() *ClusterExtensionResolutionStatus { + if in == nil { + return nil + } + out := new(ClusterExtensionResolutionStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterExtensionSpec) DeepCopyInto(out *ClusterExtensionSpec) { *out = *in in.Source.DeepCopyInto(&out.Source) - if in.Preflight != nil { - in, out := &in.Preflight, &out.Preflight - *out = new(PreflightConfig) - (*in).DeepCopyInto(*out) - } - out.ServiceAccount = in.ServiceAccount + in.Install.DeepCopyInto(&out.Install) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterExtensionSpec. @@ -155,15 +211,15 @@ func (in *ClusterExtensionSpec) DeepCopy() *ClusterExtensionSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterExtensionStatus) DeepCopyInto(out *ClusterExtensionStatus) { *out = *in - if in.InstalledBundle != nil { - in, out := &in.InstalledBundle, &out.InstalledBundle - *out = new(BundleMetadata) - **out = **in + if in.Install != nil { + in, out := &in.Install, &out.Install + *out = new(ClusterExtensionInstallStatus) + (*in).DeepCopyInto(*out) } - if in.ResolvedBundle != nil { - in, out := &in.ResolvedBundle, &out.ResolvedBundle - *out = new(BundleMetadata) - **out = **in + if in.Resolution != nil { + in, out := &in.Resolution, &out.Resolution + *out = new(ClusterExtensionResolutionStatus) + (*in).DeepCopyInto(*out) } if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 9f2e93678..7b8ad62f6 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -172,7 +172,7 @@ func main() { helmclient.StorageDriverMapper(action.ChunkedStorageDriverMapper(coreClient, mgr.GetAPIReader(), systemNamespace)), helmclient.ClientNamespaceMapper(func(obj client.Object) (string, error) { ext := obj.(*ocv1alpha1.ClusterExtension) - return ext.Spec.InstallNamespace, nil + return ext.Spec.Install.Namespace, nil }), helmclient.ClientRestConfigMapper(clientRestConfigMapper), ) diff --git a/config/base/crd/bases/olm.operatorframework.io_clusterextensions.yaml b/config/base/crd/bases/olm.operatorframework.io_clusterextensions.yaml index fe19b30dd..b55d0b328 100644 --- a/config/base/crd/bases/olm.operatorframework.io_clusterextensions.yaml +++ b/config/base/crd/bases/olm.operatorframework.io_clusterextensions.yaml @@ -39,129 +39,145 @@ spec: spec: description: ClusterExtensionSpec defines the desired state of ClusterExtension properties: - installNamespace: + install: description: |- - installNamespace is a reference to the Namespace in which the bundle of - content for the package referenced in the packageName field will be applied. - The bundle may contain cluster-scoped resources or resources that are - applied to other Namespaces. This Namespace is expected to exist. - - installNamespace is required, immutable, and follows the DNS label standard - as defined in [RFC 1123]. This means that valid values: - - Contain no more than 63 characters - - Contain only lowercase alphanumeric characters or '-' - - Start with an alphanumeric character - - End with an alphanumeric character - - Some examples of valid values are: - - some-namespace - - 123-namespace - - 1-namespace-2 - - somenamespace - - Some examples of invalid values are: - - -some-namespace - - some-namespace- - - thisisareallylongnamespacenamethatisgreaterthanthemaximumlength - - some.namespace - - [RFC 1123]: https://tools.ietf.org/html/rfc1123 - maxLength: 63 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - x-kubernetes-validations: - - message: installNamespace is immutable - rule: self == oldSelf - preflight: - description: |- - preflight is an optional field that can be used to configure the preflight checks run before installation or upgrade of the content for the package specified in the packageName field. + install is a required field used to configure the installation options + for the ClusterExtension such as the installation namespace, + the service account and the pre-flight check configuration. + + Below is a minimal example of an installation definition (in yaml): + install: + namespace: example-namespace + serviceAccount: + name: example-sa + properties: + namespace: + description: |- + namespace is a reference to the Namespace in which the bundle of + content for the package referenced in the packageName field will be applied. + The bundle may contain cluster-scoped resources or resources that are + applied to other Namespaces. This Namespace is expected to exist. + + namespace is required, immutable, and follows the DNS label standard + as defined in [RFC 1123]. This means that valid values: + - Contain no more than 63 characters + - Contain only lowercase alphanumeric characters or '-' + - Start with an alphanumeric character + - End with an alphanumeric character - When specified, it overrides the default configuration of the preflight checks that are required to execute successfully during an install/upgrade operation. + Some examples of valid values are: + - some-namespace + - 123-namespace + - 1-namespace-2 + - somenamespace - When not specified, the default configuration for each preflight check will be used. - properties: - crdUpgradeSafety: + Some examples of invalid values are: + - -some-namespace + - some-namespace- + - thisisareallylongnamespacenamethatisgreaterthanthemaximumlength + - some.namespace + + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + maxLength: 63 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + x-kubernetes-validations: + - message: namespace is immutable + rule: self == oldSelf + preflight: description: |- - crdUpgradeSafety is used to configure the CRD Upgrade Safety pre-flight - checks that run prior to upgrades of installed content. + preflight is an optional field that can be used to configure the preflight checks run before installation or upgrade of the content for the package specified in the packageName field. - The CRD Upgrade Safety pre-flight check safeguards from unintended - consequences of upgrading a CRD, such as data loss. + When specified, it overrides the default configuration of the preflight checks that are required to execute successfully during an install/upgrade operation. - This field is required if the spec.preflight field is specified. + When not specified, the default configuration for each preflight check will be used. properties: - policy: - default: Enabled + crdUpgradeSafety: description: |- - policy is used to configure the state of the CRD Upgrade Safety pre-flight check. + crdUpgradeSafety is used to configure the CRD Upgrade Safety pre-flight + checks that run prior to upgrades of installed content. + + The CRD Upgrade Safety pre-flight check safeguards from unintended + consequences of upgrading a CRD, such as data loss. - This field is required when the spec.preflight.crdUpgradeSafety field is - specified. + This field is required if the spec.preflight field is specified. + properties: + policy: + default: Enabled + description: |- + policy is used to configure the state of the CRD Upgrade Safety pre-flight check. - Allowed values are ["Enabled", "Disabled"]. The default value is "Enabled". + This field is required when the spec.preflight.crdUpgradeSafety field is + specified. - When set to "Disabled", the CRD Upgrade Safety pre-flight check will be skipped - when performing an upgrade operation. This should be used with caution as - unintended consequences such as data loss can occur. + Allowed values are ["Enabled", "Disabled"]. The default value is "Enabled". - When set to "Enabled", the CRD Upgrade Safety pre-flight check will be run when - performing an upgrade operation. - enum: - - Enabled - - Disabled - type: string + When set to "Disabled", the CRD Upgrade Safety pre-flight check will be skipped + when performing an upgrade operation. This should be used with caution as + unintended consequences such as data loss can occur. + + When set to "Enabled", the CRD Upgrade Safety pre-flight check will be run when + performing an upgrade operation. + enum: + - Enabled + - Disabled + type: string + required: + - policy + type: object required: - - policy + - crdUpgradeSafety type: object - required: - - crdUpgradeSafety - type: object - serviceAccount: - description: |- - serviceAccount is a required reference to a ServiceAccount that exists - in the installNamespace. The provided ServiceAccount is used to install and - manage the content for the package specified in the packageName field. - - In order to successfully install and manage the content for the package, - the ServiceAccount provided via this field should be configured with the - appropriate permissions to perform the necessary operations on all the - resources that are included in the bundle of content being applied. - properties: - name: + serviceAccount: description: |- - name is a required, immutable reference to the name of the ServiceAccount - to be used for installation and management of the content for the package - specified in the packageName field. + serviceAccount is a required reference to a ServiceAccount that exists + in the installNamespace. The provided ServiceAccount is used to install and + manage the content for the package specified in the packageName field. + + In order to successfully install and manage the content for the package, + the ServiceAccount provided via this field should be configured with the + appropriate permissions to perform the necessary operations on all the + resources that are included in the bundle of content being applied. + properties: + name: + description: |- + name is a required, immutable reference to the name of the ServiceAccount + to be used for installation and management of the content for the package + specified in the packageName field. - This ServiceAccount is expected to exist in the installNamespace. + This ServiceAccount is expected to exist in the installNamespace. - This field follows the DNS subdomain name standard as defined in [RFC - 1123]. This means that valid values: - - Contain no more than 253 characters - - Contain only lowercase alphanumeric characters, '-', or '.' - - Start with an alphanumeric character - - End with an alphanumeric character + This field follows the DNS subdomain name standard as defined in [RFC + 1123]. This means that valid values: + - Contain no more than 253 characters + - Contain only lowercase alphanumeric characters, '-', or '.' + - Start with an alphanumeric character + - End with an alphanumeric character - Some examples of valid values are: - - some-serviceaccount - - 123-serviceaccount - - 1-serviceaccount-2 - - someserviceaccount - - some.serviceaccount + Some examples of valid values are: + - some-serviceaccount + - 123-serviceaccount + - 1-serviceaccount-2 + - someserviceaccount + - some.serviceaccount - Some examples of invalid values are: - - -some-serviceaccount - - some-serviceaccount- + Some examples of invalid values are: + - -some-serviceaccount + - some-serviceaccount- - [RFC 1123]: https://tools.ietf.org/html/rfc1123 - maxLength: 253 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - x-kubernetes-validations: - - message: name is immutable - rule: self == oldSelf + [RFC 1123]: https://tools.ietf.org/html/rfc1123 + maxLength: 253 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + x-kubernetes-validations: + - message: name is immutable + rule: self == oldSelf + required: + - name + type: object required: - - name + - namespace + - serviceAccount type: object source: description: |- @@ -435,8 +451,7 @@ spec: - message: sourceType Catalog requires catalog field rule: self.sourceType == 'Catalog' && has(self.catalog) required: - - installNamespace - - serviceAccount + - install - source type: object status: @@ -526,50 +541,56 @@ spec: x-kubernetes-list-map-keys: - type x-kubernetes-list-type: map - installedBundle: - description: |- - installedBundle is a representation of the currently installed bundle. - - A "bundle" is a versioned set of content that represents the resources that - need to be applied to a cluster to install a package. - - This field is only updated once a bundle has been successfully installed and - once set will only be updated when a new version of the bundle has - successfully replaced the currently installed version. + install: properties: - name: - description: |- - name is a required field and is a reference - to the name of a bundle - type: string - version: + bundle: description: |- - version is a required field and is a reference - to the version that this bundle represents - type: string - required: - - name - - version + bundle is a representation of the currently installed bundle. + + A "bundle" is a versioned set of content that represents the resources that + need to be applied to a cluster to install a package. + + This field is only updated once a bundle has been successfully installed and + once set will only be updated when a new version of the bundle has + successfully replaced the currently installed version. + properties: + name: + description: |- + name is a required field and is a reference + to the name of a bundle + type: string + version: + description: |- + version is a required field and is a reference + to the version that this bundle represents + type: string + required: + - name + - version + type: object type: object - resolvedBundle: - description: |- - resolvedBundle is a representation of the bundle that was identified during - resolution to meet all installation/upgrade constraints and is slated to be - installed or upgraded to. + resolution: properties: - name: - description: |- - name is a required field and is a reference - to the name of a bundle - type: string - version: + bundle: description: |- - version is a required field and is a reference - to the version that this bundle represents - type: string - required: - - name - - version + bundle is a representation of the bundle that was identified during + resolution to meet all installation/upgrade constraints and is slated to be + installed or upgraded to. + properties: + name: + description: |- + name is a required field and is a reference + to the name of a bundle + type: string + version: + description: |- + version is a required field and is a reference + to the version that this bundle represents + type: string + required: + - name + - version + type: object type: object type: object type: object diff --git a/config/samples/olm_v1alpha1_clusterextension.yaml b/config/samples/olm_v1alpha1_clusterextension.yaml index 46a9eb555..fdd117d58 100644 --- a/config/samples/olm_v1alpha1_clusterextension.yaml +++ b/config/samples/olm_v1alpha1_clusterextension.yaml @@ -272,11 +272,12 @@ kind: ClusterExtension metadata: name: argocd spec: - installNamespace: argocd source: sourceType: Catalog catalog: packageName: argocd-operator version: 0.6.0 - serviceAccount: - name: argocd-installer + install: + namespace: argocd + serviceAccount: + name: argocd-installer diff --git a/docs/Tasks/installing-an-extension.md b/docs/Tasks/installing-an-extension.md index 8fef2bc35..680b8ca80 100644 --- a/docs/Tasks/installing-an-extension.md +++ b/docs/Tasks/installing-an-extension.md @@ -30,6 +30,10 @@ After you add a catalog to your cluster, you can install an extension by creatin packageName: channel: version: "" + install: + namespace: + serviceAccount: + name: ``` `extension_name` @@ -44,6 +48,15 @@ After you add a catalog to your cluster, you can install an extension by creatin `version` : Optional: Specifies the version or version range you want installed, such as `1.3.1` or `"<2"`. If you use a comparison string to define a version range, the string must be surrounded by double quotes (`"`). + + `namespace_name` + : Specifies a name for the namespace in which the bundle of content for the package referenced + in the packageName field will be applied. + + `serviceAccount_name` + : serviceAccount name is a required reference to a ServiceAccount that exists + in the installNamespace. The provided ServiceAccount is used to install and + manage the content for the package specified in the packageName field. !!! warning Currently, the following limitations affect the installation of extensions: diff --git a/docs/drafts/upgrade-support.md b/docs/drafts/upgrade-support.md index 4f938a8fd..6c458bb33 100644 --- a/docs/drafts/upgrade-support.md +++ b/docs/drafts/upgrade-support.md @@ -67,4 +67,8 @@ spec: packageName: argocd-operator version: 0.6.0 upgradeConstraintPolicy: Ignore + install: + namespace: argocd + serviceAccout: + name: argocd-installer ``` diff --git a/docs/refs/crd-upgrade-safety.md b/docs/refs/crd-upgrade-safety.md index 2421550d9..47ad18d7b 100644 --- a/docs/refs/crd-upgrade-safety.md +++ b/docs/refs/crd-upgrade-safety.md @@ -61,15 +61,18 @@ kind: ClusterExtension metadata: name: clusterextension-sample spec: - installNamespace: default source: sourceType: Catalog catalog: packageName: argocd-operator version: 0.6.0 - preflight: + install: + namespace: default + serviceAccount: + name: argocd-installer + preflight: crdUpgradeSafety: - disabled: true + disabled: true ``` You cannot disable individual field validators. If you disable the CRD Upgrade Safety preflight check, all field validators are disabled. diff --git a/hack/test/pre-upgrade-setup.sh b/hack/test/pre-upgrade-setup.sh index c5072c60d..8eed4c81d 100755 --- a/hack/test/pre-upgrade-setup.sh +++ b/hack/test/pre-upgrade-setup.sh @@ -133,14 +133,15 @@ kind: ClusterExtension metadata: name: ${TEST_CLUSTER_EXTENSION_NAME} spec: - installNamespace: default source: sourceType: Catalog catalog: packageName: prometheus version: 1.0.0 - serviceAccount: - name: upgrade-e2e + install: + namespace: default + serviceAccount: + name: upgrade-e2e EOF kubectl wait --for=condition=Unpacked --timeout=60s ClusterCatalog $TEST_CLUSTER_CATALOG_NAME diff --git a/internal/action/restconfig.go b/internal/action/restconfig.go index a93432fa0..a034ebb21 100644 --- a/internal/action/restconfig.go +++ b/internal/action/restconfig.go @@ -16,8 +16,8 @@ func ServiceAccountRestConfigMapper(tokenGetter *authentication.TokenGetter) fun return func(ctx context.Context, o client.Object, c *rest.Config) (*rest.Config, error) { cExt := o.(*ocv1alpha1.ClusterExtension) saKey := types.NamespacedName{ - Name: cExt.Spec.ServiceAccount.Name, - Namespace: cExt.Spec.InstallNamespace, + Name: cExt.Spec.Install.ServiceAccount.Name, + Namespace: cExt.Spec.Install.Namespace, } saConfig := rest.AnonymousClientConfig(c) saConfig.Wrap(func(rt http.RoundTripper) http.RoundTripper { diff --git a/internal/applier/helm.go b/internal/applier/helm.go index 0d764a0d6..6bdc88ae2 100644 --- a/internal/applier/helm.go +++ b/internal/applier/helm.go @@ -52,7 +52,7 @@ type Helm struct { } func (h *Helm) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1alpha1.ClusterExtension, labels map[string]string) ([]client.Object, string, error) { - chrt, err := convert.RegistryV1ToHelmChart(ctx, contentFS, ext.Spec.InstallNamespace, []string{corev1.NamespaceAll}) + chrt, err := convert.RegistryV1ToHelmChart(ctx, contentFS, ext.Spec.Install.Namespace, []string{corev1.NamespaceAll}) if err != nil { return nil, "", err } @@ -69,8 +69,8 @@ func (h *Helm) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1alpha1.Clust } for _, preflight := range h.Preflights { - if ext.Spec.Preflight != nil && ext.Spec.Preflight.CRDUpgradeSafety != nil { - if _, ok := preflight.(*crdupgradesafety.Preflight); ok && ext.Spec.Preflight.CRDUpgradeSafety.Policy == ocv1alpha1.CRDUpgradeSafetyPolicyDisabled { + if ext.Spec.Install.Preflight != nil && ext.Spec.Install.Preflight.CRDUpgradeSafety != nil { + if _, ok := preflight.(*crdupgradesafety.Preflight); ok && ext.Spec.Install.Preflight.CRDUpgradeSafety.Policy == ocv1alpha1.CRDUpgradeSafetyPolicyDisabled { // Skip this preflight check because it is of type *crdupgradesafety.Preflight and the CRD Upgrade Safety // preflight check has been disabled continue @@ -92,7 +92,7 @@ func (h *Helm) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1alpha1.Clust switch state { case StateNeedsInstall: - rel, err = ac.Install(ext.GetName(), ext.Spec.InstallNamespace, chrt, values, func(install *action.Install) error { + rel, err = ac.Install(ext.GetName(), ext.Spec.Install.Namespace, chrt, values, func(install *action.Install) error { install.CreateNamespace = false install.Labels = labels return nil @@ -101,7 +101,7 @@ func (h *Helm) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1alpha1.Clust return nil, state, err } case StateNeedsUpgrade: - rel, err = ac.Upgrade(ext.GetName(), ext.Spec.InstallNamespace, chrt, values, func(upgrade *action.Upgrade) error { + rel, err = ac.Upgrade(ext.GetName(), ext.Spec.Install.Namespace, chrt, values, func(upgrade *action.Upgrade) error { upgrade.MaxHistory = maxHelmReleaseHistory upgrade.Labels = labels return nil @@ -135,7 +135,7 @@ func (h *Helm) getReleaseState(cl helmclient.ActionInterface, ext *ocv1alpha1.Cl } if errors.Is(err, driver.ErrReleaseNotFound) { - desiredRelease, err := cl.Install(ext.GetName(), ext.Spec.InstallNamespace, chrt, values, func(i *action.Install) error { + desiredRelease, err := cl.Install(ext.GetName(), ext.Spec.Install.Namespace, chrt, values, func(i *action.Install) error { i.DryRun = true i.DryRunOption = "server" i.Labels = labels @@ -146,7 +146,7 @@ func (h *Helm) getReleaseState(cl helmclient.ActionInterface, ext *ocv1alpha1.Cl } return nil, desiredRelease, StateNeedsInstall, nil } - desiredRelease, err := cl.Upgrade(ext.GetName(), ext.Spec.InstallNamespace, chrt, values, func(upgrade *action.Upgrade) error { + desiredRelease, err := cl.Upgrade(ext.GetName(), ext.Spec.Install.Namespace, chrt, values, func(upgrade *action.Upgrade) error { upgrade.MaxHistory = maxHelmReleaseHistory upgrade.DryRun = true upgrade.DryRunOption = "server" diff --git a/internal/controllers/clusterextension_admission_test.go b/internal/controllers/clusterextension_admission_test.go index 60fa0e3b6..15cb0fd33 100644 --- a/internal/controllers/clusterextension_admission_test.go +++ b/internal/controllers/clusterextension_admission_test.go @@ -43,9 +43,11 @@ func TestClusterExtensionSourceConfig(t *testing.T) { PackageName: "test-package", }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: "default", + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: "default", + }, }, })) } @@ -54,9 +56,11 @@ func TestClusterExtensionSourceConfig(t *testing.T) { Source: ocv1alpha1.SourceConfig{ SourceType: tc.sourceType, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: "default", + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: "default", + }, }, })) } @@ -113,9 +117,11 @@ func TestClusterExtensionAdmissionPackageName(t *testing.T) { PackageName: tc.pkgName, }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: "default", + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: "default", + }, }, })) if tc.errMsg == "" { @@ -211,9 +217,11 @@ func TestClusterExtensionAdmissionVersion(t *testing.T) { Version: tc.version, }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: "default", + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: "default", + }, }, })) if tc.errMsg == "" { @@ -266,9 +274,11 @@ func TestClusterExtensionAdmissionChannel(t *testing.T) { Channel: tc.channelName, }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: "default", + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: "default", + }, }, })) if tc.errMsg == "" { @@ -282,13 +292,13 @@ func TestClusterExtensionAdmissionChannel(t *testing.T) { } func TestClusterExtensionAdmissionInstallNamespace(t *testing.T) { - tooLongError := "spec.installNamespace: Too long: may not be longer than 63" - regexMismatchError := "spec.installNamespace in body should match" + tooLongError := "spec.install.namespace: Too long: may not be longer than 63" + regexMismatchError := "spec.install.namespace in body should match" testCases := []struct { - name string - installNamespace string - errMsg string + name string + namespace string + errMsg string }{ {"just alphanumeric", "justalphanumberic1", ""}, {"hypen-separated", "hyphenated-name", ""}, @@ -319,13 +329,15 @@ func TestClusterExtensionAdmissionInstallNamespace(t *testing.T) { PackageName: "package", }, }, - InstallNamespace: tc.installNamespace, - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: "default", + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: tc.namespace, + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: "default", + }, }, })) if tc.errMsg == "" { - require.NoError(t, err, "unexpected error for installNamespace %q: %w", tc.installNamespace, err) + require.NoError(t, err, "unexpected error for namespace %q: %w", tc.namespace, err) } else { require.Error(t, err) require.Contains(t, err.Error(), tc.errMsg) @@ -335,8 +347,8 @@ func TestClusterExtensionAdmissionInstallNamespace(t *testing.T) { } func TestClusterExtensionAdmissionServiceAccount(t *testing.T) { - tooLongError := "spec.serviceAccount.name: Too long: may not be longer than 253" - regexMismatchError := "spec.serviceAccount.name in body should match" + tooLongError := "spec.install.serviceAccount.name: Too long: may not be longer than 253" + regexMismatchError := "spec.install.serviceAccount.name in body should match" testCases := []struct { name string @@ -373,9 +385,11 @@ func TestClusterExtensionAdmissionServiceAccount(t *testing.T) { PackageName: "package", }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: tc.serviceAccount, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: tc.serviceAccount, + }, }, })) if tc.errMsg == "" { diff --git a/internal/controllers/clusterextension_controller.go b/internal/controllers/clusterextension_controller.go index 176a5dc6e..e6c006aea 100644 --- a/internal/controllers/clusterextension_controller.go +++ b/internal/controllers/clusterextension_controller.go @@ -187,8 +187,8 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp // This is not ideal, and we should consider a more nuanced approach that resolves // as much status as possible before returning, or at least keeps previous state if // it is properly labeled with its observed generation. - ext.Status.ResolvedBundle = nil - ext.Status.InstalledBundle = nil + setInstallStatus(ext, nil) + setResolutionStatus(ext, nil) setResolvedStatusConditionFailed(ext, err.Error()) ensureAllConditionsWithReason(ext, ocv1alpha1.ReasonResolutionFailed, err.Error()) return ctrl.Result{}, err @@ -202,7 +202,7 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp l.V(1).Info("getting installed bundle") installedBundle, err := r.InstalledBundleGetter.GetInstalledBundle(ctx, ext) if err != nil { - ext.Status.InstalledBundle = nil + setInstallStatus(ext, nil) // TODO: use Installed=Unknown setInstalledStatusConditionFailed(ext, err.Error()) return ctrl.Result{}, err @@ -213,8 +213,8 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp resolvedBundle, resolvedBundleVersion, resolvedDeprecation, err := r.Resolver.Resolve(ctx, ext, installedBundle) if err != nil { // Note: We don't distinguish between resolution-specific errors and generic errors - ext.Status.ResolvedBundle = nil - ext.Status.InstalledBundle = nil + setInstallStatus(ext, nil) + setResolutionStatus(ext, nil) setResolvedStatusConditionFailed(ext, err.Error()) ensureAllConditionsWithReason(ext, ocv1alpha1.ReasonResolutionFailed, err.Error()) return ctrl.Result{}, err @@ -236,7 +236,10 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp // all catalogs? SetDeprecationStatus(ext, resolvedBundle.Name, resolvedDeprecation) - ext.Status.ResolvedBundle = bundleutil.MetadataFor(resolvedBundle.Name, *resolvedBundleVersion) + resStatus := &ocv1alpha1.ClusterExtensionResolutionStatus{ + Bundle: bundleutil.MetadataFor(resolvedBundle.Name, *resolvedBundleVersion), + } + setResolutionStatus(ext, resStatus) setResolvedStatusConditionSuccess(ext, fmt.Sprintf("resolved to %q", resolvedBundle.Image)) bundleSource := &rukpaksource.BundleSource{ @@ -295,13 +298,16 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp if state != applier.StateUnchanged { l.V(1).Info("watching managed objects") if err := r.Watcher.Watch(ctx, r.controller, ext, managedObjs); err != nil { - ext.Status.InstalledBundle = nil + setInstallStatus(ext, nil) setInstalledStatusConditionFailed(ext, fmt.Sprintf("%s:%v", ocv1alpha1.ReasonInstallationFailed, err)) return ctrl.Result{}, err } } - ext.Status.InstalledBundle = bundleutil.MetadataFor(resolvedBundle.Name, *resolvedBundleVersion) + installStatus := &ocv1alpha1.ClusterExtensionInstallStatus{ + Bundle: bundleutil.MetadataFor(resolvedBundle.Name, *resolvedBundleVersion), + } + setInstallStatus(ext, installStatus) setInstalledStatusConditionSuccess(ext, fmt.Sprintf("Installed bundle %s successfully", resolvedBundle.Image)) return ctrl.Result{}, nil diff --git a/internal/controllers/clusterextension_controller_test.go b/internal/controllers/clusterextension_controller_test.go index a92ea3c38..b5d241b3e 100644 --- a/internal/controllers/clusterextension_controller_test.go +++ b/internal/controllers/clusterextension_controller_test.go @@ -59,9 +59,11 @@ func TestClusterExtensionResolutionFails(t *testing.T) { PackageName: pkgName, }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: "default", + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: "default", + }, }, }, } @@ -77,8 +79,8 @@ func TestClusterExtensionResolutionFails(t *testing.T) { require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) t.Log("By checking the status fields") - require.Empty(t, clusterExtension.Status.ResolvedBundle) - require.Empty(t, clusterExtension.Status.InstalledBundle) + require.Empty(t, clusterExtension.Status.Resolution) + require.Empty(t, clusterExtension.Status.Install) t.Log("By checking the expected conditions") cond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeResolved) @@ -107,7 +109,7 @@ func TestClusterExtensionResolutionSucceeds(t *testing.T) { pkgName := "prometheus" pkgVer := "1.0.0" pkgChan := "beta" - installNamespace := fmt.Sprintf("test-ns-%s", rand.String(8)) + namespace := fmt.Sprintf("test-ns-%s", rand.String(8)) serviceAccount := fmt.Sprintf("test-sa-%s", rand.String(8)) clusterExtension := &ocv1alpha1.ClusterExtension{ @@ -121,9 +123,11 @@ func TestClusterExtensionResolutionSucceeds(t *testing.T) { Channel: pkgChan, }, }, - InstallNamespace: installNamespace, - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: serviceAccount, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: namespace, + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: serviceAccount, + }, }, }, } @@ -148,8 +152,8 @@ func TestClusterExtensionResolutionSucceeds(t *testing.T) { require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) t.Log("By checking the status fields") - require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.ResolvedBundle) - require.Empty(t, clusterExtension.Status.InstalledBundle) + require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.Resolution.Bundle) + require.Empty(t, clusterExtension.Status.Install) t.Log("By checking the expected conditions") resolvedCond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeResolved) @@ -181,7 +185,7 @@ func TestClusterExtensionUnpackFails(t *testing.T) { pkgName := "prometheus" pkgVer := "1.0.0" pkgChan := "beta" - installNamespace := fmt.Sprintf("test-ns-%s", rand.String(8)) + namespace := fmt.Sprintf("test-ns-%s", rand.String(8)) serviceAccount := fmt.Sprintf("test-sa-%s", rand.String(8)) clusterExtension := &ocv1alpha1.ClusterExtension{ @@ -195,9 +199,11 @@ func TestClusterExtensionUnpackFails(t *testing.T) { Channel: pkgChan, }, }, - InstallNamespace: installNamespace, - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: serviceAccount, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: namespace, + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: serviceAccount, + }, }, }, } @@ -222,8 +228,8 @@ func TestClusterExtensionUnpackFails(t *testing.T) { require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) t.Log("By checking the status fields") - require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.ResolvedBundle) - require.Empty(t, clusterExtension.Status.InstalledBundle) + require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.Resolution.Bundle) + require.Empty(t, clusterExtension.Status.Install) t.Log("By checking the expected conditions") resolvedCond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeResolved) @@ -257,7 +263,7 @@ func TestClusterExtensionUnpackUnexpectedState(t *testing.T) { pkgName := "prometheus" pkgVer := "1.0.0" pkgChan := "beta" - installNamespace := fmt.Sprintf("test-ns-%s", rand.String(8)) + namespace := fmt.Sprintf("test-ns-%s", rand.String(8)) serviceAccount := fmt.Sprintf("test-sa-%s", rand.String(8)) clusterExtension := &ocv1alpha1.ClusterExtension{ @@ -271,9 +277,11 @@ func TestClusterExtensionUnpackUnexpectedState(t *testing.T) { Channel: pkgChan, }, }, - InstallNamespace: installNamespace, - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: serviceAccount, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: namespace, + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: serviceAccount, + }, }, }, } @@ -298,8 +306,8 @@ func TestClusterExtensionUnpackUnexpectedState(t *testing.T) { require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) t.Log("By checking the status fields") - require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.ResolvedBundle) - require.Empty(t, clusterExtension.Status.InstalledBundle) + require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.Resolution.Bundle) + require.Empty(t, clusterExtension.Status.Install) t.Log("By checking the expected conditions") resolvedCond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeResolved) @@ -334,7 +342,7 @@ func TestClusterExtensionUnpackSucceeds(t *testing.T) { pkgName := "prometheus" pkgVer := "1.0.0" pkgChan := "beta" - installNamespace := fmt.Sprintf("test-ns-%s", rand.String(8)) + namespace := fmt.Sprintf("test-ns-%s", rand.String(8)) serviceAccount := fmt.Sprintf("test-sa-%s", rand.String(8)) clusterExtension := &ocv1alpha1.ClusterExtension{ @@ -348,9 +356,11 @@ func TestClusterExtensionUnpackSucceeds(t *testing.T) { Channel: pkgChan, }, }, - InstallNamespace: installNamespace, - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: serviceAccount, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: namespace, + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: serviceAccount, + }, }, }, } @@ -378,8 +388,8 @@ func TestClusterExtensionUnpackSucceeds(t *testing.T) { require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) t.Log("By checking the status fields") - require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.ResolvedBundle) - require.Empty(t, clusterExtension.Status.InstalledBundle) + require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.Resolution.Bundle) + require.Empty(t, clusterExtension.Status.Install) t.Log("By checking the expected resolution conditions") resolvedCond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeResolved) @@ -414,7 +424,7 @@ func TestClusterExtensionInstallationFailedApplierFails(t *testing.T) { pkgName := "prometheus" pkgVer := "1.0.0" pkgChan := "beta" - installNamespace := fmt.Sprintf("test-ns-%s", rand.String(8)) + namespace := fmt.Sprintf("test-ns-%s", rand.String(8)) serviceAccount := fmt.Sprintf("test-sa-%s", rand.String(8)) clusterExtension := &ocv1alpha1.ClusterExtension{ @@ -428,9 +438,11 @@ func TestClusterExtensionInstallationFailedApplierFails(t *testing.T) { Channel: pkgChan, }, }, - InstallNamespace: installNamespace, - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: serviceAccount, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: namespace, + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: serviceAccount, + }, }, }, } @@ -458,8 +470,8 @@ func TestClusterExtensionInstallationFailedApplierFails(t *testing.T) { require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) t.Log("By checking the status fields") - require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.ResolvedBundle) - require.Empty(t, clusterExtension.Status.InstalledBundle) + require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.Resolution.Bundle) + require.Empty(t, clusterExtension.Status.Install) t.Log("By checking the expected resolution conditions") resolvedCond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeResolved) @@ -500,7 +512,7 @@ func TestClusterExtensionInstallationFailedWatcherFailed(t *testing.T) { pkgName := "prometheus" pkgVer := "1.0.0" pkgChan := "beta" - installNamespace := fmt.Sprintf("test-ns-%s", rand.String(8)) + namespace := fmt.Sprintf("test-ns-%s", rand.String(8)) serviceAccount := fmt.Sprintf("test-sa-%s", rand.String(8)) clusterExtension := &ocv1alpha1.ClusterExtension{ @@ -514,9 +526,11 @@ func TestClusterExtensionInstallationFailedWatcherFailed(t *testing.T) { Channel: pkgChan, }, }, - InstallNamespace: installNamespace, - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: serviceAccount, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: namespace, + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: serviceAccount, + }, }, }, } @@ -547,8 +561,8 @@ func TestClusterExtensionInstallationFailedWatcherFailed(t *testing.T) { require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) t.Log("By checking the status fields") - require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.ResolvedBundle) - require.Empty(t, clusterExtension.Status.InstalledBundle) + require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.Resolution.Bundle) + require.Empty(t, clusterExtension.Status.Install) t.Log("By checking the expected resolution conditions") resolvedCond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeResolved) @@ -589,7 +603,7 @@ func TestClusterExtensionInstallationSucceeds(t *testing.T) { pkgName := "prometheus" pkgVer := "1.0.0" pkgChan := "beta" - installNamespace := fmt.Sprintf("test-ns-%s", rand.String(8)) + namespace := fmt.Sprintf("test-ns-%s", rand.String(8)) serviceAccount := fmt.Sprintf("test-sa-%s", rand.String(8)) clusterExtension := &ocv1alpha1.ClusterExtension{ @@ -603,9 +617,11 @@ func TestClusterExtensionInstallationSucceeds(t *testing.T) { Channel: pkgChan, }, }, - InstallNamespace: installNamespace, - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: serviceAccount, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: namespace, + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: serviceAccount, + }, }, }, } @@ -634,8 +650,8 @@ func TestClusterExtensionInstallationSucceeds(t *testing.T) { require.NoError(t, cl.Get(ctx, extKey, clusterExtension)) t.Log("By checking the status fields") - require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.ResolvedBundle) - require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.InstalledBundle) + require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.Resolution.Bundle) + require.Equal(t, &ocv1alpha1.BundleMetadata{Name: "prometheus.v1.0.0", Version: "1.0.0"}, clusterExtension.Status.Install.Bundle) t.Log("By checking the expected resolution conditions") resolvedCond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1alpha1.TypeResolved) diff --git a/internal/controllers/common_controller.go b/internal/controllers/common_controller.go index 90f409742..05fb7bcd2 100644 --- a/internal/controllers/common_controller.go +++ b/internal/controllers/common_controller.go @@ -68,7 +68,7 @@ func setInstalledStatusConditionFailed(ext *ocv1alpha1.ClusterExtension, message } func setStatusUnpackFailed(ext *ocv1alpha1.ClusterExtension, message string) { - ext.Status.InstalledBundle = nil + setInstallStatus(ext, nil) apimeta.SetStatusCondition(&ext.Status.Conditions, metav1.Condition{ Type: ocv1alpha1.TypeUnpacked, Status: metav1.ConditionFalse, @@ -87,3 +87,11 @@ func setStatusUnpacked(ext *ocv1alpha1.ClusterExtension, message string) { ObservedGeneration: ext.GetGeneration(), }) } + +func setResolutionStatus(ext *ocv1alpha1.ClusterExtension, resStatus *ocv1alpha1.ClusterExtensionResolutionStatus) { + ext.Status.Resolution = resStatus +} + +func setInstallStatus(ext *ocv1alpha1.ClusterExtension, installStatus *ocv1alpha1.ClusterExtensionInstallStatus) { + ext.Status.Install = installStatus +} diff --git a/internal/resolve/catalog_test.go b/internal/resolve/catalog_test.go index 373fa1214..46c279a2a 100644 --- a/internal/resolve/catalog_test.go +++ b/internal/resolve/catalog_test.go @@ -646,8 +646,10 @@ func buildFooClusterExtension(pkg, channel, version string, upgradeConstraintPol Name: pkg, }, Spec: ocv1alpha1.ClusterExtensionSpec{ - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{Name: "default"}, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{Name: "default"}, + }, Source: ocv1alpha1.SourceConfig{ SourceType: "Catalog", Catalog: &ocv1alpha1.CatalogSource{ diff --git a/test/e2e/cluster_extension_install_test.go b/test/e2e/cluster_extension_install_test.go index 8e9b61f11..3f7954424 100644 --- a/test/e2e/cluster_extension_install_test.go +++ b/test/e2e/cluster_extension_install_test.go @@ -236,9 +236,11 @@ func TestClusterExtensionInstallRegistry(t *testing.T) { }, }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: sa.Name, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: sa.Name, + }, }, } t.Log("It resolves the specified package with correct bundle path") @@ -256,7 +258,13 @@ func TestClusterExtensionInstallRegistry(t *testing.T) { assert.Equal(ct, metav1.ConditionTrue, cond.Status) assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "resolved to") - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.2.0", Version: "1.2.0"}, clusterExtension.Status.ResolvedBundle) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionResolutionStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.1.2.0", + Version: "1.2.0", + }}, + clusterExtension.Status.Resolution, + ) }, pollDuration, pollInterval) t.Log("By eventually reporting a successful unpacked") @@ -281,7 +289,7 @@ func TestClusterExtensionInstallRegistry(t *testing.T) { assert.Equal(ct, metav1.ConditionTrue, cond.Status) assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "Installed bundle") - assert.NotEmpty(ct, clusterExtension.Status.InstalledBundle) + assert.NotEmpty(ct, clusterExtension.Status.Install.Bundle) }, pollDuration, pollInterval) } @@ -299,9 +307,11 @@ func TestClusterExtensionInstallRegistryMultipleBundles(t *testing.T) { PackageName: "prometheus", }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: sa.Name, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: sa.Name, + }, }, } t.Log("It resolves to multiple bundle paths") @@ -319,7 +329,7 @@ func TestClusterExtensionInstallRegistryMultipleBundles(t *testing.T) { assert.Equal(ct, metav1.ConditionFalse, cond.Status) assert.Equal(ct, ocv1alpha1.ReasonResolutionFailed, cond.Reason) assert.Contains(ct, cond.Message, "matching packages found in multiple catalogs") - assert.Nil(ct, clusterExtension.Status.ResolvedBundle) + assert.Nil(ct, clusterExtension.Status.Resolution) }, pollDuration, pollInterval) } @@ -341,9 +351,11 @@ func TestClusterExtensionBlockInstallNonSuccessorVersion(t *testing.T) { // No Selector since this is an exact version match }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: sa.Name, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: sa.Name, + }, }, } require.NoError(t, c.Create(context.Background(), clusterExtension)) @@ -356,8 +368,20 @@ func TestClusterExtensionBlockInstallNonSuccessorVersion(t *testing.T) { } assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "resolved to") - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.0.0", Version: "1.0.0"}, clusterExtension.Status.ResolvedBundle) - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.0.0", Version: "1.0.0"}, clusterExtension.Status.InstalledBundle) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionResolutionStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.1.0.0", + Version: "1.0.0", + }}, + clusterExtension.Status.Resolution, + ) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionInstallStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.1.0.0", + Version: "1.0.0", + }}, + clusterExtension.Status.Install, + ) }, pollDuration, pollInterval) t.Log("It does not allow to upgrade the ClusterExtension to a non-successor version") @@ -374,7 +398,7 @@ func TestClusterExtensionBlockInstallNonSuccessorVersion(t *testing.T) { } assert.Equal(ct, ocv1alpha1.ReasonResolutionFailed, cond.Reason) assert.Equal(ct, "error upgrading from currently installed version \"1.0.0\": no package \"prometheus\" matching version \"1.2.0\" found", cond.Message) - assert.Empty(ct, clusterExtension.Status.ResolvedBundle) + assert.Empty(ct, clusterExtension.Status.Resolution) }, pollDuration, pollInterval) } @@ -395,9 +419,11 @@ func TestClusterExtensionForceInstallNonSuccessorVersion(t *testing.T) { Version: "1.0.0", }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: sa.Name, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: sa.Name, + }, }, } require.NoError(t, c.Create(context.Background(), clusterExtension)) @@ -410,7 +436,13 @@ func TestClusterExtensionForceInstallNonSuccessorVersion(t *testing.T) { } assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "resolved to") - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.0.0", Version: "1.0.0"}, clusterExtension.Status.ResolvedBundle) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionResolutionStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.1.0.0", + Version: "1.0.0", + }}, + clusterExtension.Status.Resolution, + ) }, pollDuration, pollInterval) t.Log("It allows to upgrade the ClusterExtension to a non-successor version") @@ -428,7 +460,13 @@ func TestClusterExtensionForceInstallNonSuccessorVersion(t *testing.T) { } assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "resolved to") - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.2.0", Version: "1.2.0"}, clusterExtension.Status.ResolvedBundle) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionResolutionStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.1.2.0", + Version: "1.2.0", + }}, + clusterExtension.Status.Resolution, + ) }, pollDuration, pollInterval) } @@ -448,9 +486,11 @@ func TestClusterExtensionInstallSuccessorVersion(t *testing.T) { Version: "1.0.0", }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: sa.Name, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: sa.Name, + }, }, } require.NoError(t, c.Create(context.Background(), clusterExtension)) @@ -463,7 +503,13 @@ func TestClusterExtensionInstallSuccessorVersion(t *testing.T) { } assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "resolved to") - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.0.0", Version: "1.0.0"}, clusterExtension.Status.ResolvedBundle) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionResolutionStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.1.0.0", + Version: "1.0.0", + }}, + clusterExtension.Status.Resolution, + ) }, pollDuration, pollInterval) t.Log("It does allow to upgrade the ClusterExtension to any of the successor versions within non-zero major version") @@ -480,7 +526,13 @@ func TestClusterExtensionInstallSuccessorVersion(t *testing.T) { } assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "resolved to") - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.0.1", Version: "1.0.1"}, clusterExtension.Status.ResolvedBundle) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionResolutionStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.1.0.1", + Version: "1.0.1", + }}, + clusterExtension.Status.Resolution, + ) }, pollDuration, pollInterval) } @@ -507,9 +559,11 @@ func TestClusterExtensionInstallReResolvesWhenCatalogIsPatched(t *testing.T) { }, }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: sa.Name, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: sa.Name, + }, }, } t.Log("It resolves the specified package with correct bundle path") @@ -527,7 +581,13 @@ func TestClusterExtensionInstallReResolvesWhenCatalogIsPatched(t *testing.T) { assert.Equal(ct, metav1.ConditionTrue, cond.Status) assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "resolved to") - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.2.0", Version: "1.2.0"}, clusterExtension.Status.ResolvedBundle) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionResolutionStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.1.2.0", + Version: "1.2.0", + }}, + clusterExtension.Status.Resolution, + ) }, pollDuration, pollInterval) // patch imageRef tag on test-catalog image with v2 image @@ -556,7 +616,13 @@ func TestClusterExtensionInstallReResolvesWhenCatalogIsPatched(t *testing.T) { assert.Equal(ct, metav1.ConditionTrue, cond.Status) assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "resolved to") - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.2.0.0", Version: "2.0.0"}, clusterExtension.Status.ResolvedBundle) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionResolutionStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.2.0.0", + Version: "2.0.0", + }}, + clusterExtension.Status.Resolution, + ) }, pollDuration, pollInterval) } @@ -595,9 +661,11 @@ func TestClusterExtensionInstallReResolvesWhenNewCatalog(t *testing.T) { }, }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: sa.Name, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: sa.Name, + }, }, } t.Log("It resolves the specified package with correct bundle path") @@ -615,7 +683,13 @@ func TestClusterExtensionInstallReResolvesWhenNewCatalog(t *testing.T) { assert.Equal(ct, metav1.ConditionTrue, cond.Status) assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "resolved to") - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.2.0", Version: "1.2.0"}, clusterExtension.Status.ResolvedBundle) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionResolutionStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.1.2.0", + Version: "1.2.0", + }}, + clusterExtension.Status.Resolution, + ) }, pollDuration, pollInterval) // update tag on test-catalog image with v2 image @@ -644,7 +718,13 @@ func TestClusterExtensionInstallReResolvesWhenNewCatalog(t *testing.T) { assert.Equal(ct, metav1.ConditionTrue, cond.Status) assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "resolved to") - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.2.0.0", Version: "2.0.0"}, clusterExtension.Status.ResolvedBundle) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionResolutionStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.1.2.0", + Version: "1.2.0", + }}, + clusterExtension.Status.Resolution, + ) }, pollDuration, pollInterval) } @@ -665,9 +745,11 @@ func TestClusterExtensionInstallReResolvesWhenManagedContentChanged(t *testing.T }, }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: sa.Name, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: sa.Name, + }, }, } t.Log("It installs the specified package with correct bundle path") @@ -684,14 +766,20 @@ func TestClusterExtensionInstallReResolvesWhenManagedContentChanged(t *testing.T } assert.Equal(ct, metav1.ConditionTrue, cond.Status) assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.2.0", Version: "1.2.0"}, clusterExtension.Status.InstalledBundle) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionResolutionStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.1.2.0", + Version: "1.2.0", + }}, + clusterExtension.Status.Resolution, + ) }, pollDuration, pollInterval) t.Log("By deleting a managed resource") prometheusService := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: "prometheus-operator", - Namespace: clusterExtension.Spec.InstallNamespace, + Namespace: clusterExtension.Spec.Install.Namespace, }, } require.NoError(t, c.Delete(context.Background(), prometheusService)) @@ -730,9 +818,11 @@ func TestClusterExtensionRecoversFromInitialInstallFailedWhenFailureFixed(t *tes }, }, }, - InstallNamespace: "default", - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: sa.Name, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: "default", + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: sa.Name, + }, }, } t.Log("It resolves the specified package with correct bundle path") @@ -750,7 +840,13 @@ func TestClusterExtensionRecoversFromInitialInstallFailedWhenFailureFixed(t *tes assert.Equal(ct, metav1.ConditionTrue, cond.Status) assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "resolved to") - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.2.0", Version: "1.2.0"}, clusterExtension.Status.ResolvedBundle) + assert.Equal(ct, + &ocv1alpha1.ClusterExtensionResolutionStatus{Bundle: &ocv1alpha1.BundleMetadata{ + Name: "prometheus-operator.1.2.0", + Version: "1.2.0", + }}, + clusterExtension.Status.Resolution, + ) }, pollDuration, pollInterval) t.Log("By eventually reporting a successful unpacked") @@ -794,7 +890,7 @@ func TestClusterExtensionRecoversFromInitialInstallFailedWhenFailureFixed(t *tes assert.Equal(ct, metav1.ConditionTrue, cond.Status) assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "Installed bundle") - assert.NotEmpty(ct, clusterExtension.Status.InstalledBundle) + assert.NotEmpty(ct, clusterExtension.Status.Install) }, pollDuration, pollInterval) } diff --git a/test/extension-developer-e2e/extension_developer_test.go b/test/extension-developer-e2e/extension_developer_test.go index 0a80db17e..91e7391a9 100644 --- a/test/extension-developer-e2e/extension_developer_test.go +++ b/test/extension-developer-e2e/extension_developer_test.go @@ -76,9 +76,11 @@ func TestExtensionDeveloper(t *testing.T) { PackageName: os.Getenv("REG_PKG_NAME"), }, }, - InstallNamespace: installNamespace, - ServiceAccount: ocv1alpha1.ServiceAccountReference{ - Name: sa.Name, + Install: ocv1alpha1.ClusterExtensionInstallConfig{ + Namespace: installNamespace, + ServiceAccount: ocv1alpha1.ServiceAccountReference{ + Name: sa.Name, + }, }, }, } diff --git a/test/upgrade-e2e/post_upgrade_test.go b/test/upgrade-e2e/post_upgrade_test.go index f8675d4bf..11bbf7544 100644 --- a/test/upgrade-e2e/post_upgrade_test.go +++ b/test/upgrade-e2e/post_upgrade_test.go @@ -86,12 +86,12 @@ func TestClusterExtensionAfterOLMUpgrade(t *testing.T) { assert.Equal(ct, metav1.ConditionTrue, cond.Status) assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "Installed bundle") - if assert.NotEmpty(ct, clusterExtension.Status.InstalledBundle) { - assert.NotEmpty(ct, clusterExtension.Status.InstalledBundle.Version) + if assert.NotEmpty(ct, clusterExtension.Status.Install.Bundle) { + assert.NotEmpty(ct, clusterExtension.Status.Install.Bundle.Version) } }, time.Minute, time.Second) - previousVersion := clusterExtension.Status.InstalledBundle.Version + previousVersion := clusterExtension.Status.Install.Bundle.Version t.Log("Updating the ClusterExtension to change version") // Make sure that after we upgrade OLM itself we can still reconcile old objects if we change them @@ -107,9 +107,9 @@ func TestClusterExtensionAfterOLMUpgrade(t *testing.T) { } assert.Equal(ct, ocv1alpha1.ReasonSuccess, cond.Reason) assert.Contains(ct, cond.Message, "Installed bundle") - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.0.1", Version: "1.0.1"}, clusterExtension.Status.ResolvedBundle) - assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.0.1", Version: "1.0.1"}, clusterExtension.Status.InstalledBundle) - assert.NotEqual(ct, previousVersion, clusterExtension.Status.InstalledBundle.Version) + assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.0.1", Version: "1.0.1"}, clusterExtension.Status.Resolution.Bundle) + assert.Equal(ct, &ocv1alpha1.BundleMetadata{Name: "prometheus-operator.1.0.1", Version: "1.0.1"}, clusterExtension.Status.Install.Bundle) + assert.NotEqual(ct, previousVersion, clusterExtension.Status.Install.Bundle.Version) }, time.Minute, time.Second) }