diff --git a/Makefile b/Makefile index 41397e9cc..15d9b1319 100644 --- a/Makefile +++ b/Makefile @@ -197,8 +197,10 @@ manifests: update-crds $(MANIFESTS) $(HELM) #EXHELP Generate OLMv1 manifests $(HELM) template olmv1 helm/olmv1 --set "options.openshift.enabled=true" > /dev/null .PHONY: generate -generate: $(CONTROLLER_GEN) #EXHELP Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. - @find api cmd hack internal -name "zz_generated.deepcopy.go" -not -path "*/vendor/*" -delete # Need to delete the files for them to be generated properly +generate: $(CONTROLLER_GEN) #EXHELP Generate code containing DeepCopy, DeepCopyInto, DeepCopyObject, and ApplyConfiguration type implementations. + # Need to delete the files for them to be generated properly + @find api cmd hack internal -name "zz_generated.deepcopy.go" -not -path "*/vendor/*" -delete && rm -rf applyconfigurations + $(CONTROLLER_GEN) --load-build-tags=$(GO_BUILD_TAGS) applyconfiguration:headerFile="hack/boilerplate.go.txt" paths="./api/..." $(CONTROLLER_GEN) --load-build-tags=$(GO_BUILD_TAGS) object:headerFile="hack/boilerplate.go.txt" paths="./..." .PHONY: verify diff --git a/api/v1/clustercatalog_types.go b/api/v1/clustercatalog_types.go index 7afe631db..c8690cbaf 100644 --- a/api/v1/clustercatalog_types.go +++ b/api/v1/clustercatalog_types.go @@ -44,6 +44,8 @@ const ( ReasonUserSpecifiedUnavailable = "UserSpecifiedUnavailable" ) +// +genclient +// +genclient:nonNamespaced //+kubebuilder:object:root=true //+kubebuilder:resource:scope=Cluster //+kubebuilder:subresource:status diff --git a/api/v1/clusterextension_types.go b/api/v1/clusterextension_types.go index 7b0a39ef1..ee55109f8 100644 --- a/api/v1/clusterextension_types.go +++ b/api/v1/clusterextension_types.go @@ -537,6 +537,8 @@ type ClusterExtensionInstallStatus struct { Bundle BundleMetadata `json:"bundle"` } +// +genclient +// +genclient:nonNamespaced // +kubebuilder:object:root=true // +kubebuilder:resource:scope=Cluster // +kubebuilder:subresource:status diff --git a/api/v1/clusterextensionrevision_types.go b/api/v1/clusterextensionrevision_types.go index f3416bf25..df4f61e09 100644 --- a/api/v1/clusterextensionrevision_types.go +++ b/api/v1/clusterextensionrevision_types.go @@ -224,6 +224,8 @@ type ClusterExtensionRevisionStatus struct { Conditions []metav1.Condition `json:"conditions,omitempty"` } +// +genclient +// +genclient:nonNamespaced // +kubebuilder:object:root=true // +kubebuilder:resource:scope=Cluster // +kubebuilder:subresource:status diff --git a/api/v1/groupversion_info.go b/api/v1/groupversion_info.go index f2e8582ee..39efbee0d 100644 --- a/api/v1/groupversion_info.go +++ b/api/v1/groupversion_info.go @@ -17,6 +17,8 @@ limitations under the License. // Package v1 contains API Schema definitions for the olm v1 API group // +kubebuilder:object:generate=true // +groupName=olm.operatorframework.io +// +kubebuilder:ac:generate=true +// +kubebuilder:ac:output:package=../../applyconfigurations package v1 import ( @@ -28,6 +30,10 @@ var ( // GroupVersion is group version used to register these objects GroupVersion = schema.GroupVersion{Group: "olm.operatorframework.io", Version: "v1"} + // SchemeGroupVersion is an alias for GroupVersion, required by the + // generated apply configuration code. + SchemeGroupVersion = GroupVersion + // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} diff --git a/applyconfigurations/api/v1/bundlemetadata.go b/applyconfigurations/api/v1/bundlemetadata.go new file mode 100644 index 000000000..acf9d152f --- /dev/null +++ b/applyconfigurations/api/v1/bundlemetadata.go @@ -0,0 +1,54 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +// BundleMetadataApplyConfiguration represents a declarative configuration of the BundleMetadata type for use +// with apply. +// +// BundleMetadata is a representation of the identifying attributes of a bundle. +type BundleMetadataApplyConfiguration struct { + // name is required and follows the DNS subdomain standard as defined in [RFC 1123]. + // It must contain only lowercase alphanumeric characters, hyphens (-) or periods (.), + // start and end with an alphanumeric character, and be no longer than 253 characters. + Name *string `json:"name,omitempty"` + // version is required and references the version that this bundle represents. + // It follows the semantic versioning standard as defined in https://semver.org/. + Version *string `json:"version,omitempty"` +} + +// BundleMetadataApplyConfiguration constructs a declarative configuration of the BundleMetadata type for use with +// apply. +func BundleMetadata() *BundleMetadataApplyConfiguration { + return &BundleMetadataApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *BundleMetadataApplyConfiguration) WithName(value string) *BundleMetadataApplyConfiguration { + b.Name = &value + return b +} + +// WithVersion sets the Version field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Version field is set to the value of the last call. +func (b *BundleMetadataApplyConfiguration) WithVersion(value string) *BundleMetadataApplyConfiguration { + b.Version = &value + return b +} diff --git a/applyconfigurations/api/v1/catalogfilter.go b/applyconfigurations/api/v1/catalogfilter.go new file mode 100644 index 000000000..4464897e0 --- /dev/null +++ b/applyconfigurations/api/v1/catalogfilter.go @@ -0,0 +1,232 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + apiv1 "github.com/operator-framework/operator-controller/api/v1" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// CatalogFilterApplyConfiguration represents a declarative configuration of the CatalogFilter type for use +// with apply. +// +// CatalogFilter defines the attributes used to identify and filter content from a catalog. +type CatalogFilterApplyConfiguration struct { + // packageName specifies the name of the package to be installed and is used to filter + // the content from catalogs. + // + // It is required, immutable, and follows the DNS subdomain standard as defined in [RFC 1123]. + // It must contain only lowercase alphanumeric characters, hyphens (-) or periods (.), + // start and end with an alphanumeric character, and be no longer than 253 characters. + // + // Some examples of valid values are: + // - some-package + // - 123-package + // - 1-package-2 + // - somepackage + // + // Some examples of invalid values are: + // - -some-package + // - some-package- + // - thisisareallylongpackagenamethatisgreaterthanthemaximumlength + // - some.package + // + // [RFC 1123]: https://tools.ietf.org/html/rfc1123 + PackageName *string `json:"packageName,omitempty"` + // version is an optional semver constraint (a specific version or range of versions). + // When unspecified, the latest version available is installed. + // + // Acceptable version ranges are no longer than 64 characters. + // Version ranges are composed of comma- or space-delimited values and one or more comparison operators, + // known as comparison strings. + // You can add additional comparison strings using the OR operator (||). + // + // # Range Comparisons + // + // To specify a version range, you can use a comparison string like ">=3.0, + // <3.6". When specifying a range, automatic updates will occur within that + // range. The example comparison string means "install any version greater than + // or equal to 3.0.0 but less than 3.6.0.". It also states intent that if any + // upgrades are available within the version range after initial installation, + // those upgrades should be automatically performed. + // + // # Pinned Versions + // + // To specify an exact version to install you can use a version range that + // "pins" to a specific version. When pinning to a specific version, no + // automatic updates will occur. An example of a pinned version range is + // "0.6.0", which means "only install version 0.6.0 and never + // upgrade from this version". + // + // # Basic Comparison Operators + // + // The basic comparison operators and their meanings are: + // - "=", equal (not aliased to an operator) + // - "!=", not equal + // - "<", less than + // - ">", greater than + // - ">=", greater than OR equal to + // - "<=", less than OR equal to + // + // # Wildcard Comparisons + // + // You can use the "x", "X", and "*" characters as wildcard characters in all + // comparison operations. Some examples of using the wildcard characters: + // - "1.2.x", "1.2.X", and "1.2.*" is equivalent to ">=1.2.0, < 1.3.0" + // - ">= 1.2.x", ">= 1.2.X", and ">= 1.2.*" is equivalent to ">= 1.2.0" + // - "<= 2.x", "<= 2.X", and "<= 2.*" is equivalent to "< 3" + // - "x", "X", and "*" is equivalent to ">= 0.0.0" + // + // # Patch Release Comparisons + // + // When you want to specify a minor version up to the next major version you + // can use the "~" character to perform patch comparisons. Some examples: + // - "~1.2.3" is equivalent to ">=1.2.3, <1.3.0" + // - "~1" and "~1.x" is equivalent to ">=1, <2" + // - "~2.3" is equivalent to ">=2.3, <2.4" + // - "~1.2.x" is equivalent to ">=1.2.0, <1.3.0" + // + // # Major Release Comparisons + // + // You can use the "^" character to make major release comparisons after a + // stable 1.0.0 version is published. If there is no stable version published, // minor versions define the stability level. Some examples: + // - "^1.2.3" is equivalent to ">=1.2.3, <2.0.0" + // - "^1.2.x" is equivalent to ">=1.2.0, <2.0.0" + // - "^2.3" is equivalent to ">=2.3, <3" + // - "^2.x" is equivalent to ">=2.0.0, <3" + // - "^0.2.3" is equivalent to ">=0.2.3, <0.3.0" + // - "^0.2" is equivalent to ">=0.2.0, <0.3.0" + // - "^0.0.3" is equvalent to ">=0.0.3, <0.0.4" + // - "^0.0" is equivalent to ">=0.0.0, <0.1.0" + // - "^0" is equivalent to ">=0.0.0, <1.0.0" + // + // # OR Comparisons + // You can use the "||" character to represent an OR operation in the version + // range. Some examples: + // - ">=1.2.3, <2.0.0 || >3.0.0" + // - "^0 || ^3 || ^5" + // + // For more information on semver, please see https://semver.org/ + Version *string `json:"version,omitempty"` + // channels is optional and specifies a set of channels belonging to the package + // specified in the packageName field. + // + // A channel is a package-author-defined stream of updates for an extension. + // + // Each channel in the list must follow the DNS subdomain standard as defined in [RFC 1123]. + // It must contain only lowercase alphanumeric characters, hyphens (-) or periods (.), + // start and end with an alphanumeric character, and be no longer than 253 characters. + // You can specify no more than 256 channels. + // + // When specified, it constrains the set of installable bundles and the automated upgrade path. + // This constraint is an AND operation with the version field. For example: + // - Given channel is set to "foo" + // - Given version is set to ">=1.0.0, <1.5.0" + // - Only bundles that exist in channel "foo" AND satisfy the version range comparison are considered installable + // - Automatic upgrades are constrained to upgrade edges defined by the selected channel + // + // When unspecified, upgrade edges across all channels are used to identify valid automatic upgrade paths. + // + // Some examples of valid values are: + // - 1.1.x + // - alpha + // - stable + // - stable-v1 + // - v1-stable + // - dev-preview + // - preview + // - community + // + // Some examples of invalid values are: + // - -some-channel + // - some-channel- + // - thisisareallylongchannelnamethatisgreaterthanthemaximumlength + // - original_40 + // - --default-channel + // + // [RFC 1123]: https://tools.ietf.org/html/rfc1123 + Channels []string `json:"channels,omitempty"` + // selector is optional and filters the set of ClusterCatalogs used in the bundle selection process. + // + // When unspecified, all ClusterCatalogs are used in the bundle selection process. + Selector *metav1.LabelSelectorApplyConfiguration `json:"selector,omitempty"` + // upgradeConstraintPolicy is optional and controls whether the upgrade paths defined in the catalog + // are enforced for the package referenced in the packageName field. + // + // Allowed values are "CatalogProvided", "SelfCertified", or omitted. + // + // When set to "CatalogProvided", automatic upgrades only occur when upgrade constraints specified by the package + // author are met. + // + // When set to "SelfCertified", the upgrade constraints specified by the package author are ignored. + // This allows upgrades and downgrades to any version of the package. + // This is considered a dangerous operation as it can lead to unknown and potentially disastrous outcomes, + // such as data loss. + // Use this option only if you have independently verified the changes. + // + // When omitted, the default value is "CatalogProvided". + UpgradeConstraintPolicy *apiv1.UpgradeConstraintPolicy `json:"upgradeConstraintPolicy,omitempty"` +} + +// CatalogFilterApplyConfiguration constructs a declarative configuration of the CatalogFilter type for use with +// apply. +func CatalogFilter() *CatalogFilterApplyConfiguration { + return &CatalogFilterApplyConfiguration{} +} + +// WithPackageName sets the PackageName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PackageName field is set to the value of the last call. +func (b *CatalogFilterApplyConfiguration) WithPackageName(value string) *CatalogFilterApplyConfiguration { + b.PackageName = &value + return b +} + +// WithVersion sets the Version field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Version field is set to the value of the last call. +func (b *CatalogFilterApplyConfiguration) WithVersion(value string) *CatalogFilterApplyConfiguration { + b.Version = &value + return b +} + +// WithChannels adds the given value to the Channels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Channels field. +func (b *CatalogFilterApplyConfiguration) WithChannels(values ...string) *CatalogFilterApplyConfiguration { + for i := range values { + b.Channels = append(b.Channels, values[i]) + } + return b +} + +// WithSelector sets the Selector field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Selector field is set to the value of the last call. +func (b *CatalogFilterApplyConfiguration) WithSelector(value *metav1.LabelSelectorApplyConfiguration) *CatalogFilterApplyConfiguration { + b.Selector = value + return b +} + +// WithUpgradeConstraintPolicy sets the UpgradeConstraintPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UpgradeConstraintPolicy field is set to the value of the last call. +func (b *CatalogFilterApplyConfiguration) WithUpgradeConstraintPolicy(value apiv1.UpgradeConstraintPolicy) *CatalogFilterApplyConfiguration { + b.UpgradeConstraintPolicy = &value + return b +} diff --git a/applyconfigurations/api/v1/catalogsource.go b/applyconfigurations/api/v1/catalogsource.go new file mode 100644 index 000000000..da1ca5cab --- /dev/null +++ b/applyconfigurations/api/v1/catalogsource.go @@ -0,0 +1,62 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + apiv1 "github.com/operator-framework/operator-controller/api/v1" +) + +// CatalogSourceApplyConfiguration represents a declarative configuration of the CatalogSource type for use +// with apply. +// +// CatalogSource is a discriminated union of possible sources for a Catalog. +// CatalogSource contains the sourcing information for a Catalog +type CatalogSourceApplyConfiguration struct { + // type is a required field that specifies the type of source for the catalog. + // + // The only allowed value is "Image". + // + // When set to "Image", the ClusterCatalog content is sourced from an OCI image. + // When using an image source, the image field must be set and must be the only field defined for this type. + Type *apiv1.SourceType `json:"type,omitempty"` + // image configures how catalog contents are sourced from an OCI image. + // It is required when type is Image, and forbidden otherwise. + Image *ImageSourceApplyConfiguration `json:"image,omitempty"` +} + +// CatalogSourceApplyConfiguration constructs a declarative configuration of the CatalogSource type for use with +// apply. +func CatalogSource() *CatalogSourceApplyConfiguration { + return &CatalogSourceApplyConfiguration{} +} + +// WithType sets the Type field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Type field is set to the value of the last call. +func (b *CatalogSourceApplyConfiguration) WithType(value apiv1.SourceType) *CatalogSourceApplyConfiguration { + b.Type = &value + return b +} + +// WithImage sets the Image field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Image field is set to the value of the last call. +func (b *CatalogSourceApplyConfiguration) WithImage(value *ImageSourceApplyConfiguration) *CatalogSourceApplyConfiguration { + b.Image = value + return b +} diff --git a/applyconfigurations/api/v1/clustercatalog.go b/applyconfigurations/api/v1/clustercatalog.go new file mode 100644 index 000000000..13a50c26b --- /dev/null +++ b/applyconfigurations/api/v1/clustercatalog.go @@ -0,0 +1,252 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + apismetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ClusterCatalogApplyConfiguration represents a declarative configuration of the ClusterCatalog type for use +// with apply. +// +// ClusterCatalog makes File-Based Catalog (FBC) data available to your cluster. +// For more information on FBC, see https://olm.operatorframework.io/docs/reference/file-based-catalogs/#docs +type ClusterCatalogApplyConfiguration struct { + metav1.TypeMetaApplyConfiguration `json:",inline"` + // metadata is the standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + *metav1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + // spec is a required field that defines the desired state of the ClusterCatalog. + // The controller ensures that the catalog is unpacked and served over the catalog content HTTP server. + Spec *ClusterCatalogSpecApplyConfiguration `json:"spec,omitempty"` + // status contains the following information about the state of the ClusterCatalog: + // - Whether the catalog contents are being served via the catalog content HTTP server + // - Whether the ClusterCatalog is progressing to a new state + // - A reference to the source from which the catalog contents were retrieved + Status *ClusterCatalogStatusApplyConfiguration `json:"status,omitempty"` +} + +// ClusterCatalog constructs a declarative configuration of the ClusterCatalog type for use with +// apply. +func ClusterCatalog(name string) *ClusterCatalogApplyConfiguration { + b := &ClusterCatalogApplyConfiguration{} + b.WithName(name) + b.WithKind("ClusterCatalog") + b.WithAPIVersion("olm.operatorframework.io/v1") + return b +} + +func (b ClusterCatalogApplyConfiguration) IsApplyConfiguration() {} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithKind(value string) *ClusterCatalogApplyConfiguration { + b.TypeMetaApplyConfiguration.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithAPIVersion(value string) *ClusterCatalogApplyConfiguration { + b.TypeMetaApplyConfiguration.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithName(value string) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithGenerateName(value string) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithNamespace(value string) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithUID(value types.UID) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithResourceVersion(value string) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithGeneration(value int64) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithCreationTimestamp(value apismetav1.Time) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithDeletionTimestamp(value apismetav1.Time) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ClusterCatalogApplyConfiguration) WithLabels(entries map[string]string) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ClusterCatalogApplyConfiguration) WithAnnotations(entries map[string]string) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ClusterCatalogApplyConfiguration) WithOwnerReferences(values ...*metav1.OwnerReferenceApplyConfiguration) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ClusterCatalogApplyConfiguration) WithFinalizers(values ...string) *ClusterCatalogApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) + } + return b +} + +func (b *ClusterCatalogApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &metav1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithSpec(value *ClusterCatalogSpecApplyConfiguration) *ClusterCatalogApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *ClusterCatalogApplyConfiguration) WithStatus(value *ClusterCatalogStatusApplyConfiguration) *ClusterCatalogApplyConfiguration { + b.Status = value + return b +} + +// GetKind retrieves the value of the Kind field in the declarative configuration. +func (b *ClusterCatalogApplyConfiguration) GetKind() *string { + return b.TypeMetaApplyConfiguration.Kind +} + +// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration. +func (b *ClusterCatalogApplyConfiguration) GetAPIVersion() *string { + return b.TypeMetaApplyConfiguration.APIVersion +} + +// GetName retrieves the value of the Name field in the declarative configuration. +func (b *ClusterCatalogApplyConfiguration) GetName() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Name +} + +// GetNamespace retrieves the value of the Namespace field in the declarative configuration. +func (b *ClusterCatalogApplyConfiguration) GetNamespace() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Namespace +} diff --git a/applyconfigurations/api/v1/clustercatalogspec.go b/applyconfigurations/api/v1/clustercatalogspec.go new file mode 100644 index 000000000..f4b2a8385 --- /dev/null +++ b/applyconfigurations/api/v1/clustercatalogspec.go @@ -0,0 +1,102 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + apiv1 "github.com/operator-framework/operator-controller/api/v1" +) + +// ClusterCatalogSpecApplyConfiguration represents a declarative configuration of the ClusterCatalogSpec type for use +// with apply. +// +// ClusterCatalogSpec defines the desired state of ClusterCatalog +type ClusterCatalogSpecApplyConfiguration struct { + // source is a required field that defines the source of a catalog. + // A catalog contains information on content that can be installed on a cluster. + // The catalog source makes catalog contents discoverable and usable by other on-cluster components. + // These components can present the content in a GUI dashboard or install content from the catalog on the cluster. + // The catalog source must contain catalog metadata in the File-Based Catalog (FBC) format. + // For more information on FBC, see https://olm.operatorframework.io/docs/reference/file-based-catalogs/#docs. + // + // Below is a minimal example of a ClusterCatalogSpec that sources a catalog from an image: + // + // source: + // type: Image + // image: + // ref: quay.io/operatorhubio/catalog:latest + Source *CatalogSourceApplyConfiguration `json:"source,omitempty"` + // priority is an optional field that defines a priority for this ClusterCatalog. + // + // Clients use the ClusterCatalog priority as a tie-breaker between ClusterCatalogs that meet their requirements. + // Higher numbers mean higher priority. + // + // Clients decide how to handle scenarios where multiple ClusterCatalogs with the same priority meet their requirements. + // Clients should prompt users for additional input to break the tie. + // + // When omitted, the default priority is 0. + // + // Use negative numbers to specify a priority lower than the default. + // Use positive numbers to specify a priority higher than the default. + // + // The lowest possible value is -2147483648. + // The highest possible value is 2147483647. + Priority *int32 `json:"priority,omitempty"` + // availabilityMode is an optional field that defines how the ClusterCatalog is made available to clients on the cluster. + // + // Allowed values are "Available", "Unavailable", or omitted. + // + // When omitted, the default value is "Available". + // + // When set to "Available", the catalog contents are unpacked and served over the catalog content HTTP server. + // Clients should consider this ClusterCatalog and its contents as usable. + // + // When set to "Unavailable", the catalog contents are no longer served over the catalog content HTTP server. + // Treat this the same as if the ClusterCatalog does not exist. + // Use "Unavailable" when you want to keep the ClusterCatalog but treat it as if it doesn't exist. + AvailabilityMode *apiv1.AvailabilityMode `json:"availabilityMode,omitempty"` +} + +// ClusterCatalogSpecApplyConfiguration constructs a declarative configuration of the ClusterCatalogSpec type for use with +// apply. +func ClusterCatalogSpec() *ClusterCatalogSpecApplyConfiguration { + return &ClusterCatalogSpecApplyConfiguration{} +} + +// WithSource sets the Source field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Source field is set to the value of the last call. +func (b *ClusterCatalogSpecApplyConfiguration) WithSource(value *CatalogSourceApplyConfiguration) *ClusterCatalogSpecApplyConfiguration { + b.Source = value + return b +} + +// WithPriority sets the Priority field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Priority field is set to the value of the last call. +func (b *ClusterCatalogSpecApplyConfiguration) WithPriority(value int32) *ClusterCatalogSpecApplyConfiguration { + b.Priority = &value + return b +} + +// WithAvailabilityMode sets the AvailabilityMode field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AvailabilityMode field is set to the value of the last call. +func (b *ClusterCatalogSpecApplyConfiguration) WithAvailabilityMode(value apiv1.AvailabilityMode) *ClusterCatalogSpecApplyConfiguration { + b.AvailabilityMode = &value + return b +} diff --git a/applyconfigurations/api/v1/clustercatalogstatus.go b/applyconfigurations/api/v1/clustercatalogstatus.go new file mode 100644 index 000000000..4bd82c89e --- /dev/null +++ b/applyconfigurations/api/v1/clustercatalogstatus.go @@ -0,0 +1,99 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + apismetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ClusterCatalogStatusApplyConfiguration represents a declarative configuration of the ClusterCatalogStatus type for use +// with apply. +// +// ClusterCatalogStatus defines the observed state of ClusterCatalog +type ClusterCatalogStatusApplyConfiguration struct { + // conditions represents the current state of this ClusterCatalog. + // + // The current condition types are Serving and Progressing. + // + // The Serving condition represents whether the catalog contents are being served via the HTTP(S) web server: + // - When status is True and reason is Available, the catalog contents are being served. + // - When status is False and reason is Unavailable, the catalog contents are not being served because the contents are not yet available. + // - When status is False and reason is UserSpecifiedUnavailable, the catalog contents are not being served because the catalog has been intentionally marked as unavailable. + // + // The Progressing condition represents whether the ClusterCatalog is progressing or is ready to progress towards a new state: + // - When status is True and reason is Retrying, an error occurred that may be resolved on subsequent reconciliation attempts. + // - When status is True and reason is Succeeded, the ClusterCatalog has successfully progressed to a new state and is ready to continue progressing. + // - When status is False and reason is Blocked, an error occurred that requires manual intervention for recovery. + // + // If the system initially fetched contents and polling identifies updates, both conditions can be active simultaneously: + // - The Serving condition remains True with reason Available because the previous contents are still served via the HTTP(S) web server. + // - The Progressing condition is True with reason Retrying because the system is working to serve the new version. + Conditions []metav1.ConditionApplyConfiguration `json:"conditions,omitempty"` + // resolvedSource contains information about the resolved source based on the source type. + ResolvedSource *ResolvedCatalogSourceApplyConfiguration `json:"resolvedSource,omitempty"` + // urls contains the URLs that can be used to access the catalog. + URLs *ClusterCatalogURLsApplyConfiguration `json:"urls,omitempty"` + // lastUnpacked represents the last time the catalog contents were extracted from their source format. + // For example, when using an Image source, the OCI image is pulled and image layers are written to a file-system backed cache. + // This extraction from the source format is called "unpacking". + LastUnpacked *apismetav1.Time `json:"lastUnpacked,omitempty"` +} + +// ClusterCatalogStatusApplyConfiguration constructs a declarative configuration of the ClusterCatalogStatus type for use with +// apply. +func ClusterCatalogStatus() *ClusterCatalogStatusApplyConfiguration { + return &ClusterCatalogStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *ClusterCatalogStatusApplyConfiguration) WithConditions(values ...*metav1.ConditionApplyConfiguration) *ClusterCatalogStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} + +// WithResolvedSource sets the ResolvedSource field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResolvedSource field is set to the value of the last call. +func (b *ClusterCatalogStatusApplyConfiguration) WithResolvedSource(value *ResolvedCatalogSourceApplyConfiguration) *ClusterCatalogStatusApplyConfiguration { + b.ResolvedSource = value + return b +} + +// WithURLs sets the URLs field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the URLs field is set to the value of the last call. +func (b *ClusterCatalogStatusApplyConfiguration) WithURLs(value *ClusterCatalogURLsApplyConfiguration) *ClusterCatalogStatusApplyConfiguration { + b.URLs = value + return b +} + +// WithLastUnpacked sets the LastUnpacked field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the LastUnpacked field is set to the value of the last call. +func (b *ClusterCatalogStatusApplyConfiguration) WithLastUnpacked(value apismetav1.Time) *ClusterCatalogStatusApplyConfiguration { + b.LastUnpacked = &value + return b +} diff --git a/applyconfigurations/api/v1/clustercatalogurls.go b/applyconfigurations/api/v1/clustercatalogurls.go new file mode 100644 index 000000000..99ec14042 --- /dev/null +++ b/applyconfigurations/api/v1/clustercatalogurls.go @@ -0,0 +1,50 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +// ClusterCatalogURLsApplyConfiguration represents a declarative configuration of the ClusterCatalogURLs type for use +// with apply. +// +// ClusterCatalogURLs contains the URLs that can be used to access the catalog. +type ClusterCatalogURLsApplyConfiguration struct { + // base is a cluster-internal URL that provides endpoints for accessing the catalog content. + // + // Clients should append the path for the endpoint they want to access. + // + // Currently, only a single endpoint is served and is accessible at the path /api/v1. + // + // The endpoints served for the v1 API are: + // - /all - this endpoint returns the entire catalog contents in the FBC format + // + // New endpoints may be added as needs evolve. + Base *string `json:"base,omitempty"` +} + +// ClusterCatalogURLsApplyConfiguration constructs a declarative configuration of the ClusterCatalogURLs type for use with +// apply. +func ClusterCatalogURLs() *ClusterCatalogURLsApplyConfiguration { + return &ClusterCatalogURLsApplyConfiguration{} +} + +// WithBase sets the Base field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Base field is set to the value of the last call. +func (b *ClusterCatalogURLsApplyConfiguration) WithBase(value string) *ClusterCatalogURLsApplyConfiguration { + b.Base = &value + return b +} diff --git a/applyconfigurations/api/v1/clusterextension.go b/applyconfigurations/api/v1/clusterextension.go new file mode 100644 index 000000000..b5826dd0d --- /dev/null +++ b/applyconfigurations/api/v1/clusterextension.go @@ -0,0 +1,247 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + apismetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ClusterExtensionApplyConfiguration represents a declarative configuration of the ClusterExtension type for use +// with apply. +// +// ClusterExtension is the Schema for the clusterextensions API +type ClusterExtensionApplyConfiguration struct { + metav1.TypeMetaApplyConfiguration `json:",inline"` + // metadata is the standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + *metav1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + // spec is an optional field that defines the desired state of the ClusterExtension. + Spec *ClusterExtensionSpecApplyConfiguration `json:"spec,omitempty"` + // status is an optional field that defines the observed state of the ClusterExtension. + Status *ClusterExtensionStatusApplyConfiguration `json:"status,omitempty"` +} + +// ClusterExtension constructs a declarative configuration of the ClusterExtension type for use with +// apply. +func ClusterExtension(name string) *ClusterExtensionApplyConfiguration { + b := &ClusterExtensionApplyConfiguration{} + b.WithName(name) + b.WithKind("ClusterExtension") + b.WithAPIVersion("olm.operatorframework.io/v1") + return b +} + +func (b ClusterExtensionApplyConfiguration) IsApplyConfiguration() {} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithKind(value string) *ClusterExtensionApplyConfiguration { + b.TypeMetaApplyConfiguration.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithAPIVersion(value string) *ClusterExtensionApplyConfiguration { + b.TypeMetaApplyConfiguration.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithName(value string) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithGenerateName(value string) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithNamespace(value string) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithUID(value types.UID) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithResourceVersion(value string) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithGeneration(value int64) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithCreationTimestamp(value apismetav1.Time) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithDeletionTimestamp(value apismetav1.Time) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ClusterExtensionApplyConfiguration) WithLabels(entries map[string]string) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ClusterExtensionApplyConfiguration) WithAnnotations(entries map[string]string) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ClusterExtensionApplyConfiguration) WithOwnerReferences(values ...*metav1.OwnerReferenceApplyConfiguration) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ClusterExtensionApplyConfiguration) WithFinalizers(values ...string) *ClusterExtensionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) + } + return b +} + +func (b *ClusterExtensionApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &metav1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithSpec(value *ClusterExtensionSpecApplyConfiguration) *ClusterExtensionApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *ClusterExtensionApplyConfiguration) WithStatus(value *ClusterExtensionStatusApplyConfiguration) *ClusterExtensionApplyConfiguration { + b.Status = value + return b +} + +// GetKind retrieves the value of the Kind field in the declarative configuration. +func (b *ClusterExtensionApplyConfiguration) GetKind() *string { + return b.TypeMetaApplyConfiguration.Kind +} + +// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration. +func (b *ClusterExtensionApplyConfiguration) GetAPIVersion() *string { + return b.TypeMetaApplyConfiguration.APIVersion +} + +// GetName retrieves the value of the Name field in the declarative configuration. +func (b *ClusterExtensionApplyConfiguration) GetName() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Name +} + +// GetNamespace retrieves the value of the Namespace field in the declarative configuration. +func (b *ClusterExtensionApplyConfiguration) GetNamespace() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Namespace +} diff --git a/applyconfigurations/api/v1/clusterextensionconfig.go b/applyconfigurations/api/v1/clusterextensionconfig.go new file mode 100644 index 000000000..1661031da --- /dev/null +++ b/applyconfigurations/api/v1/clusterextensionconfig.go @@ -0,0 +1,65 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + apiv1 "github.com/operator-framework/operator-controller/api/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" +) + +// ClusterExtensionConfigApplyConfiguration represents a declarative configuration of the ClusterExtensionConfig type for use +// with apply. +// +// ClusterExtensionConfig is a discriminated union which selects the source configuration values to be merged into +// the ClusterExtension's rendered manifests. +type ClusterExtensionConfigApplyConfiguration struct { + // configType is required and specifies the type of configuration source. + // + // The only allowed value is "Inline". + // + // When set to "Inline", the cluster extension configuration is defined inline within the ClusterExtension resource. + ConfigType *apiv1.ClusterExtensionConfigType `json:"configType,omitempty"` + // inline contains JSON or YAML values specified directly in the ClusterExtension. + // + // It is used to specify arbitrary configuration values for the ClusterExtension. + // It must be set if configType is 'Inline' and must be a valid JSON/YAML object containing at least one property. + // The configuration values are validated at runtime against a JSON schema provided by the bundle. + Inline *apiextensionsv1.JSON `json:"inline,omitempty"` +} + +// ClusterExtensionConfigApplyConfiguration constructs a declarative configuration of the ClusterExtensionConfig type for use with +// apply. +func ClusterExtensionConfig() *ClusterExtensionConfigApplyConfiguration { + return &ClusterExtensionConfigApplyConfiguration{} +} + +// WithConfigType sets the ConfigType field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ConfigType field is set to the value of the last call. +func (b *ClusterExtensionConfigApplyConfiguration) WithConfigType(value apiv1.ClusterExtensionConfigType) *ClusterExtensionConfigApplyConfiguration { + b.ConfigType = &value + return b +} + +// WithInline sets the Inline field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Inline field is set to the value of the last call. +func (b *ClusterExtensionConfigApplyConfiguration) WithInline(value apiextensionsv1.JSON) *ClusterExtensionConfigApplyConfiguration { + b.Inline = &value + return b +} diff --git a/applyconfigurations/api/v1/clusterextensioninstallconfig.go b/applyconfigurations/api/v1/clusterextensioninstallconfig.go new file mode 100644 index 000000000..4e38abc93 --- /dev/null +++ b/applyconfigurations/api/v1/clusterextensioninstallconfig.go @@ -0,0 +1,46 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +// ClusterExtensionInstallConfigApplyConfiguration represents a declarative configuration of the ClusterExtensionInstallConfig type for use +// with apply. +// +// 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. +type ClusterExtensionInstallConfigApplyConfiguration struct { + // preflight is optional and configures the checks that run before installation or upgrade + // of the content for the package specified in the packageName field. + // + // When specified, it replaces the default preflight configuration for install/upgrade actions. + // When not specified, the default configuration is used. + Preflight *PreflightConfigApplyConfiguration `json:"preflight,omitempty"` +} + +// ClusterExtensionInstallConfigApplyConfiguration constructs a declarative configuration of the ClusterExtensionInstallConfig type for use with +// apply. +func ClusterExtensionInstallConfig() *ClusterExtensionInstallConfigApplyConfiguration { + return &ClusterExtensionInstallConfigApplyConfiguration{} +} + +// WithPreflight sets the Preflight field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Preflight field is set to the value of the last call. +func (b *ClusterExtensionInstallConfigApplyConfiguration) WithPreflight(value *PreflightConfigApplyConfiguration) *ClusterExtensionInstallConfigApplyConfiguration { + b.Preflight = value + return b +} diff --git a/applyconfigurations/api/v1/clusterextensioninstallstatus.go b/applyconfigurations/api/v1/clusterextensioninstallstatus.go new file mode 100644 index 000000000..403b285d0 --- /dev/null +++ b/applyconfigurations/api/v1/clusterextensioninstallstatus.go @@ -0,0 +1,44 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +// ClusterExtensionInstallStatusApplyConfiguration represents a declarative configuration of the ClusterExtensionInstallStatus type for use +// with apply. +// +// ClusterExtensionInstallStatus is a representation of the status of the identified bundle. +type ClusterExtensionInstallStatusApplyConfiguration struct { + // bundle is required and represents the identifying attributes of a 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. + Bundle *BundleMetadataApplyConfiguration `json:"bundle,omitempty"` +} + +// ClusterExtensionInstallStatusApplyConfiguration constructs a declarative configuration of the ClusterExtensionInstallStatus type for use with +// apply. +func ClusterExtensionInstallStatus() *ClusterExtensionInstallStatusApplyConfiguration { + return &ClusterExtensionInstallStatusApplyConfiguration{} +} + +// WithBundle sets the Bundle field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Bundle field is set to the value of the last call. +func (b *ClusterExtensionInstallStatusApplyConfiguration) WithBundle(value *BundleMetadataApplyConfiguration) *ClusterExtensionInstallStatusApplyConfiguration { + b.Bundle = value + return b +} diff --git a/applyconfigurations/api/v1/clusterextensionrevision.go b/applyconfigurations/api/v1/clusterextensionrevision.go new file mode 100644 index 000000000..5ccee31c2 --- /dev/null +++ b/applyconfigurations/api/v1/clusterextensionrevision.go @@ -0,0 +1,252 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + apismetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ClusterExtensionRevisionApplyConfiguration represents a declarative configuration of the ClusterExtensionRevision type for use +// with apply. +// +// ClusterExtensionRevision represents an immutable snapshot of Kubernetes objects +// for a specific version of a ClusterExtension. Each revision contains objects +// organized into phases that roll out sequentially. The same object can only be managed by a single revision +// at a time. Ownership of objects is transitioned from one revision to the next as the extension is upgraded +// or reconfigured. Once the latest revision has rolled out successfully, previous active revisions are archived for +// posterity. +type ClusterExtensionRevisionApplyConfiguration struct { + metav1.TypeMetaApplyConfiguration `json:",inline"` + // metadata is the standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + *metav1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + // spec defines the desired state of the ClusterExtensionRevision. + Spec *ClusterExtensionRevisionSpecApplyConfiguration `json:"spec,omitempty"` + // status is optional and defines the observed state of the ClusterExtensionRevision. + Status *ClusterExtensionRevisionStatusApplyConfiguration `json:"status,omitempty"` +} + +// ClusterExtensionRevision constructs a declarative configuration of the ClusterExtensionRevision type for use with +// apply. +func ClusterExtensionRevision(name string) *ClusterExtensionRevisionApplyConfiguration { + b := &ClusterExtensionRevisionApplyConfiguration{} + b.WithName(name) + b.WithKind("ClusterExtensionRevision") + b.WithAPIVersion("olm.operatorframework.io/v1") + return b +} + +func (b ClusterExtensionRevisionApplyConfiguration) IsApplyConfiguration() {} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithKind(value string) *ClusterExtensionRevisionApplyConfiguration { + b.TypeMetaApplyConfiguration.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithAPIVersion(value string) *ClusterExtensionRevisionApplyConfiguration { + b.TypeMetaApplyConfiguration.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithName(value string) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithGenerateName(value string) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithNamespace(value string) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithUID(value types.UID) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithResourceVersion(value string) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithGeneration(value int64) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithCreationTimestamp(value apismetav1.Time) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithDeletionTimestamp(value apismetav1.Time) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ClusterExtensionRevisionApplyConfiguration) WithLabels(entries map[string]string) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ClusterExtensionRevisionApplyConfiguration) WithAnnotations(entries map[string]string) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ClusterExtensionRevisionApplyConfiguration) WithOwnerReferences(values ...*metav1.OwnerReferenceApplyConfiguration) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ClusterExtensionRevisionApplyConfiguration) WithFinalizers(values ...string) *ClusterExtensionRevisionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) + } + return b +} + +func (b *ClusterExtensionRevisionApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &metav1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithSpec(value *ClusterExtensionRevisionSpecApplyConfiguration) *ClusterExtensionRevisionApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *ClusterExtensionRevisionApplyConfiguration) WithStatus(value *ClusterExtensionRevisionStatusApplyConfiguration) *ClusterExtensionRevisionApplyConfiguration { + b.Status = value + return b +} + +// GetKind retrieves the value of the Kind field in the declarative configuration. +func (b *ClusterExtensionRevisionApplyConfiguration) GetKind() *string { + return b.TypeMetaApplyConfiguration.Kind +} + +// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration. +func (b *ClusterExtensionRevisionApplyConfiguration) GetAPIVersion() *string { + return b.TypeMetaApplyConfiguration.APIVersion +} + +// GetName retrieves the value of the Name field in the declarative configuration. +func (b *ClusterExtensionRevisionApplyConfiguration) GetName() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Name +} + +// GetNamespace retrieves the value of the Namespace field in the declarative configuration. +func (b *ClusterExtensionRevisionApplyConfiguration) GetNamespace() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Namespace +} diff --git a/applyconfigurations/api/v1/clusterextensionrevisionobject.go b/applyconfigurations/api/v1/clusterextensionrevisionobject.go new file mode 100644 index 000000000..1d9c92c17 --- /dev/null +++ b/applyconfigurations/api/v1/clusterextensionrevisionobject.go @@ -0,0 +1,74 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + apiv1 "github.com/operator-framework/operator-controller/api/v1" + unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +// ClusterExtensionRevisionObjectApplyConfiguration represents a declarative configuration of the ClusterExtensionRevisionObject type for use +// with apply. +// +// ClusterExtensionRevisionObject represents a Kubernetes object to be applied as part +// of a phase, along with its collision protection settings. +type ClusterExtensionRevisionObjectApplyConfiguration struct { + // object is a required embedded Kubernetes object to be applied. + // + // This object must be a valid Kubernetes resource with apiVersion, kind, and metadata fields. + Object *unstructured.Unstructured `json:"object,omitempty"` + // collisionProtection controls whether the operator can adopt and modify objects + // that already exist on the cluster. + // + // Allowed values are: "Prevent", "IfNoController", and "None". + // + // When set to "Prevent", the operator only manages objects it created itself. + // This prevents ownership collisions. + // + // When set to "IfNoController", the operator can adopt and modify pre-existing objects + // that are not owned by another controller. + // This is useful for taking over management of manually-created resources. + // + // When set to "None", the operator can adopt and modify any pre-existing object, even if + // owned by another controller. + // Use this setting with extreme caution as it may cause multiple controllers to fight over + // the same resource, resulting in increased load on the API server and etcd. + CollisionProtection *apiv1.CollisionProtection `json:"collisionProtection,omitempty"` +} + +// ClusterExtensionRevisionObjectApplyConfiguration constructs a declarative configuration of the ClusterExtensionRevisionObject type for use with +// apply. +func ClusterExtensionRevisionObject() *ClusterExtensionRevisionObjectApplyConfiguration { + return &ClusterExtensionRevisionObjectApplyConfiguration{} +} + +// WithObject sets the Object field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Object field is set to the value of the last call. +func (b *ClusterExtensionRevisionObjectApplyConfiguration) WithObject(value unstructured.Unstructured) *ClusterExtensionRevisionObjectApplyConfiguration { + b.Object = &value + return b +} + +// WithCollisionProtection sets the CollisionProtection field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CollisionProtection field is set to the value of the last call. +func (b *ClusterExtensionRevisionObjectApplyConfiguration) WithCollisionProtection(value apiv1.CollisionProtection) *ClusterExtensionRevisionObjectApplyConfiguration { + b.CollisionProtection = &value + return b +} diff --git a/applyconfigurations/api/v1/clusterextensionrevisionphase.go b/applyconfigurations/api/v1/clusterextensionrevisionphase.go new file mode 100644 index 000000000..2b9eb1962 --- /dev/null +++ b/applyconfigurations/api/v1/clusterextensionrevisionphase.go @@ -0,0 +1,67 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +// ClusterExtensionRevisionPhaseApplyConfiguration represents a declarative configuration of the ClusterExtensionRevisionPhase type for use +// with apply. +// +// ClusterExtensionRevisionPhase represents a group of objects that are applied together. The phase is considered +// complete only after all objects pass their status probes. +type ClusterExtensionRevisionPhaseApplyConfiguration struct { + // name is a required identifier for this phase. + // + // phase names must follow the DNS label standard as defined in [RFC 1123]. + // They must contain only lowercase alphanumeric characters or hyphens (-), + // start and end with an alphanumeric character, and be no longer than 63 characters. + // + // Common phase names include: namespaces, policies, rbac, crds, storage, deploy, publish. + // + // [RFC 1123]: https://tools.ietf.org/html/rfc1123 + Name *string `json:"name,omitempty"` + // objects is a required list of all Kubernetes objects that belong to this phase. + // + // All objects in this list are applied to the cluster in no particular order. The maximum number of objects per phase is 50. + Objects []ClusterExtensionRevisionObjectApplyConfiguration `json:"objects,omitempty"` +} + +// ClusterExtensionRevisionPhaseApplyConfiguration constructs a declarative configuration of the ClusterExtensionRevisionPhase type for use with +// apply. +func ClusterExtensionRevisionPhase() *ClusterExtensionRevisionPhaseApplyConfiguration { + return &ClusterExtensionRevisionPhaseApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ClusterExtensionRevisionPhaseApplyConfiguration) WithName(value string) *ClusterExtensionRevisionPhaseApplyConfiguration { + b.Name = &value + return b +} + +// WithObjects adds the given value to the Objects field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Objects field. +func (b *ClusterExtensionRevisionPhaseApplyConfiguration) WithObjects(values ...*ClusterExtensionRevisionObjectApplyConfiguration) *ClusterExtensionRevisionPhaseApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithObjects") + } + b.Objects = append(b.Objects, *values[i]) + } + return b +} diff --git a/applyconfigurations/api/v1/clusterextensionrevisionspec.go b/applyconfigurations/api/v1/clusterextensionrevisionspec.go new file mode 100644 index 000000000..fe2e323ea --- /dev/null +++ b/applyconfigurations/api/v1/clusterextensionrevisionspec.go @@ -0,0 +1,117 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + apiv1 "github.com/operator-framework/operator-controller/api/v1" +) + +// ClusterExtensionRevisionSpecApplyConfiguration represents a declarative configuration of the ClusterExtensionRevisionSpec type for use +// with apply. +// +// ClusterExtensionRevisionSpec defines the desired state of ClusterExtensionRevision. +type ClusterExtensionRevisionSpecApplyConfiguration struct { + // lifecycleState specifies the lifecycle state of the ClusterExtensionRevision. + // + // When set to "Active", the revision is actively managed and reconciled. + // When set to "Archived", the revision is inactive and any resources not managed by a subsequent revision are deleted. + // The revision is removed from the owner list of all objects previously under management. + // All objects that did not transition to a succeeding revision are deleted. + // + // Once a revision is set to "Archived", it cannot be un-archived. + // + // It is possible for more than one revision to be "Active" simultaneously. This will occur when + // moving from one revision to another. The old revision will not be set to "Archived" until the + // new revision has been completely rolled out. + LifecycleState *apiv1.ClusterExtensionRevisionLifecycleState `json:"lifecycleState,omitempty"` + // revision is a required, immutable sequence number representing a specific revision + // of the parent ClusterExtension. + // + // The revision field must be a positive integer. + // Each ClusterExtensionRevision belonging to the same parent ClusterExtension must have a unique revision number. + // The revision number must always be the previous revision number plus one, or 1 for the first revision. + Revision *int64 `json:"revision,omitempty"` + // phases is an optional, immutable list of phases that group objects to be applied together. + // + // Objects are organized into phases based on their Group-Kind. Common phases include: + // - namespaces: Namespace objects + // - policies: ResourceQuota, LimitRange, NetworkPolicy objects + // - rbac: ServiceAccount, Role, RoleBinding, ClusterRole, ClusterRoleBinding objects + // - crds: CustomResourceDefinition objects + // - storage: PersistentVolume, PersistentVolumeClaim, StorageClass objects + // - deploy: Deployment, StatefulSet, DaemonSet, Service, ConfigMap, Secret objects + // - publish: Ingress, APIService, Route, Webhook objects + // + // All objects in a phase are applied in no particular order. + // The revision progresses to the next phase only after all objects in the current phase pass their readiness probes. + // + // Once set, even if empty, the phases field is immutable. + // + // Each phase in the list must have a unique name. The maximum number of phases is 20. + Phases []ClusterExtensionRevisionPhaseApplyConfiguration `json:"phases,omitempty"` + // progressDeadlineMinutes is an optional field that defines the maximum period + // of time in minutes after which an installation should be considered failed and + // require manual intervention. This functionality is disabled when no value + // is provided. The minimum period is 10 minutes, and the maximum is 720 minutes (12 hours). + // + // + ProgressDeadlineMinutes *int32 `json:"progressDeadlineMinutes,omitempty"` +} + +// ClusterExtensionRevisionSpecApplyConfiguration constructs a declarative configuration of the ClusterExtensionRevisionSpec type for use with +// apply. +func ClusterExtensionRevisionSpec() *ClusterExtensionRevisionSpecApplyConfiguration { + return &ClusterExtensionRevisionSpecApplyConfiguration{} +} + +// WithLifecycleState sets the LifecycleState field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the LifecycleState field is set to the value of the last call. +func (b *ClusterExtensionRevisionSpecApplyConfiguration) WithLifecycleState(value apiv1.ClusterExtensionRevisionLifecycleState) *ClusterExtensionRevisionSpecApplyConfiguration { + b.LifecycleState = &value + return b +} + +// WithRevision sets the Revision field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Revision field is set to the value of the last call. +func (b *ClusterExtensionRevisionSpecApplyConfiguration) WithRevision(value int64) *ClusterExtensionRevisionSpecApplyConfiguration { + b.Revision = &value + return b +} + +// WithPhases adds the given value to the Phases field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Phases field. +func (b *ClusterExtensionRevisionSpecApplyConfiguration) WithPhases(values ...*ClusterExtensionRevisionPhaseApplyConfiguration) *ClusterExtensionRevisionSpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithPhases") + } + b.Phases = append(b.Phases, *values[i]) + } + return b +} + +// WithProgressDeadlineMinutes sets the ProgressDeadlineMinutes field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ProgressDeadlineMinutes field is set to the value of the last call. +func (b *ClusterExtensionRevisionSpecApplyConfiguration) WithProgressDeadlineMinutes(value int32) *ClusterExtensionRevisionSpecApplyConfiguration { + b.ProgressDeadlineMinutes = &value + return b +} diff --git a/applyconfigurations/api/v1/clusterextensionrevisionstatus.go b/applyconfigurations/api/v1/clusterextensionrevisionstatus.go new file mode 100644 index 000000000..f86797115 --- /dev/null +++ b/applyconfigurations/api/v1/clusterextensionrevisionstatus.go @@ -0,0 +1,68 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ClusterExtensionRevisionStatusApplyConfiguration represents a declarative configuration of the ClusterExtensionRevisionStatus type for use +// with apply. +// +// ClusterExtensionRevisionStatus defines the observed state of a ClusterExtensionRevision. +type ClusterExtensionRevisionStatusApplyConfiguration struct { + // conditions is an optional list of status conditions describing the state of the + // ClusterExtensionRevision. + // + // The Progressing condition represents whether the revision is actively rolling out: + // - When status is True and reason is RollingOut, the ClusterExtensionRevision rollout is actively making progress and is in transition. + // - When status is True and reason is Retrying, the ClusterExtensionRevision has encountered an error that could be resolved on subsequent reconciliation attempts. + // - When status is True and reason is Succeeded, the ClusterExtensionRevision has reached the desired state. + // - When status is False and reason is Blocked, the ClusterExtensionRevision has encountered an error that requires manual intervention for recovery. + // - When status is False and reason is Archived, the ClusterExtensionRevision is archived and not being actively reconciled. + // + // The Available condition represents whether the revision has been successfully rolled out and is available: + // - When status is True and reason is ProbesSucceeded, the ClusterExtensionRevision has been successfully rolled out and all objects pass their readiness probes. + // - When status is False and reason is ProbeFailure, one or more objects are failing their readiness probes during rollout. + // - When status is Unknown and reason is Reconciling, the ClusterExtensionRevision has encountered an error that prevented it from observing the probes. + // - When status is Unknown and reason is Archived, the ClusterExtensionRevision has been archived and its objects have been torn down. + // - When status is Unknown and reason is Migrated, the ClusterExtensionRevision was migrated from an existing release and object status probe results have not yet been observed. + // + // The Succeeded condition represents whether the revision has successfully completed its rollout: + // - When status is True and reason is Succeeded, the ClusterExtensionRevision has successfully completed its rollout. This condition is set once and persists even if the revision later becomes unavailable. + Conditions []metav1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// ClusterExtensionRevisionStatusApplyConfiguration constructs a declarative configuration of the ClusterExtensionRevisionStatus type for use with +// apply. +func ClusterExtensionRevisionStatus() *ClusterExtensionRevisionStatusApplyConfiguration { + return &ClusterExtensionRevisionStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *ClusterExtensionRevisionStatusApplyConfiguration) WithConditions(values ...*metav1.ConditionApplyConfiguration) *ClusterExtensionRevisionStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/applyconfigurations/api/v1/clusterextensionspec.go b/applyconfigurations/api/v1/clusterextensionspec.go new file mode 100644 index 000000000..56c653392 --- /dev/null +++ b/applyconfigurations/api/v1/clusterextensionspec.go @@ -0,0 +1,128 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +// ClusterExtensionSpecApplyConfiguration represents a declarative configuration of the ClusterExtensionSpec type for use +// with apply. +// +// ClusterExtensionSpec defines the desired state of ClusterExtension +type ClusterExtensionSpecApplyConfiguration struct { + // namespace specifies a Kubernetes namespace. + // This is the namespace where the provided ServiceAccount must exist. + // It also designates the default namespace where namespace-scoped resources for the extension are applied to the cluster. + // Some extensions may contain namespace-scoped resources to be applied in other namespaces. + // This namespace must exist. + // + // The namespace field is required, immutable, and follows the DNS label standard as defined in [RFC 1123]. + // It must contain only lowercase alphanumeric characters or hyphens (-), start and end with an alphanumeric character, + // and be no longer than 63 characters. + // + // [RFC 1123]: https://tools.ietf.org/html/rfc1123 + Namespace *string `json:"namespace,omitempty"` + // serviceAccount specifies a ServiceAccount used to perform all interactions with the cluster + // that are required to manage the extension. + // The ServiceAccount must be configured with the necessary permissions to perform these interactions. + // The ServiceAccount must exist in the namespace referenced in the spec. + // The serviceAccount field is required. + ServiceAccount *ServiceAccountReferenceApplyConfiguration `json:"serviceAccount,omitempty"` + // source is required and selects the installation source of content for this ClusterExtension. + // Set the sourceType field to perform the selection. + // + // Catalog is currently the only implemented sourceType. + // Setting sourceType to "Catalog" requires the catalog field to also be defined. + // + // Below is a minimal example of a source definition (in yaml): + // + // source: + // sourceType: Catalog + // catalog: + // packageName: example-package + Source *SourceConfigApplyConfiguration `json:"source,omitempty"` + // install is optional and configures installation options for the ClusterExtension, + // such as the pre-flight check configuration. + Install *ClusterExtensionInstallConfigApplyConfiguration `json:"install,omitempty"` + // config is optional and specifies bundle-specific configuration. + // Configuration is bundle-specific and a bundle may provide a configuration schema. + // When not specified, the default configuration of the resolved bundle is used. + // + // config is validated against a configuration schema provided by the resolved bundle. If the bundle does not provide + // a configuration schema the bundle is deemed to not be configurable. More information on how + // to configure bundles can be found in the OLM documentation associated with your current OLM version. + Config *ClusterExtensionConfigApplyConfiguration `json:"config,omitempty"` + // progressDeadlineMinutes is an optional field that defines the maximum period + // of time in minutes after which an installation should be considered failed and + // require manual intervention. This functionality is disabled when no value + // is provided. The minimum period is 10 minutes, and the maximum is 720 minutes (12 hours). + // + // + ProgressDeadlineMinutes *int32 `json:"progressDeadlineMinutes,omitempty"` +} + +// ClusterExtensionSpecApplyConfiguration constructs a declarative configuration of the ClusterExtensionSpec type for use with +// apply. +func ClusterExtensionSpec() *ClusterExtensionSpecApplyConfiguration { + return &ClusterExtensionSpecApplyConfiguration{} +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ClusterExtensionSpecApplyConfiguration) WithNamespace(value string) *ClusterExtensionSpecApplyConfiguration { + b.Namespace = &value + return b +} + +// WithServiceAccount sets the ServiceAccount field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ServiceAccount field is set to the value of the last call. +func (b *ClusterExtensionSpecApplyConfiguration) WithServiceAccount(value *ServiceAccountReferenceApplyConfiguration) *ClusterExtensionSpecApplyConfiguration { + b.ServiceAccount = value + return b +} + +// WithSource sets the Source field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Source field is set to the value of the last call. +func (b *ClusterExtensionSpecApplyConfiguration) WithSource(value *SourceConfigApplyConfiguration) *ClusterExtensionSpecApplyConfiguration { + b.Source = value + return b +} + +// WithInstall sets the Install field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Install field is set to the value of the last call. +func (b *ClusterExtensionSpecApplyConfiguration) WithInstall(value *ClusterExtensionInstallConfigApplyConfiguration) *ClusterExtensionSpecApplyConfiguration { + b.Install = value + return b +} + +// WithConfig sets the Config field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Config field is set to the value of the last call. +func (b *ClusterExtensionSpecApplyConfiguration) WithConfig(value *ClusterExtensionConfigApplyConfiguration) *ClusterExtensionSpecApplyConfiguration { + b.Config = value + return b +} + +// WithProgressDeadlineMinutes sets the ProgressDeadlineMinutes field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ProgressDeadlineMinutes field is set to the value of the last call. +func (b *ClusterExtensionSpecApplyConfiguration) WithProgressDeadlineMinutes(value int32) *ClusterExtensionSpecApplyConfiguration { + b.ProgressDeadlineMinutes = &value + return b +} diff --git a/applyconfigurations/api/v1/clusterextensionstatus.go b/applyconfigurations/api/v1/clusterextensionstatus.go new file mode 100644 index 000000000..dd76e76a1 --- /dev/null +++ b/applyconfigurations/api/v1/clusterextensionstatus.go @@ -0,0 +1,98 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ClusterExtensionStatusApplyConfiguration represents a declarative configuration of the ClusterExtensionStatus type for use +// with apply. +// +// ClusterExtensionStatus defines the observed state of a ClusterExtension. +type ClusterExtensionStatusApplyConfiguration struct { + // conditions represents the current state of the ClusterExtension. + // + // The set of condition types which apply to all spec.source variations are Installed and Progressing. + // + // The Installed condition represents whether the bundle has been installed for this ClusterExtension: + // - When Installed is True and the Reason is Succeeded, the bundle has been successfully installed. + // - When Installed is False and the Reason is Failed, the bundle has failed to install. + // + // The Progressing condition represents whether or not the ClusterExtension is advancing towards a new state. + // When Progressing is True and the Reason is Succeeded, the ClusterExtension is making progress towards a new state. + // When Progressing is True and the Reason is Retrying, the ClusterExtension has encountered an error that could be resolved on subsequent reconciliation attempts. + // When Progressing is False and the Reason is Blocked, the ClusterExtension has encountered an error that requires manual intervention for recovery. + // + // When Progressing is True and Reason is RollingOut, the ClusterExtension has one or more ClusterExtensionRevisions in active roll out. + // + // + // When the ClusterExtension is sourced from a catalog, it surfaces deprecation conditions based on catalog metadata. + // These are indications from a package owner to guide users away from a particular package, channel, or bundle: + // - BundleDeprecated is True if the installed bundle is marked deprecated, False if not deprecated, or Unknown if no bundle is installed yet or if catalog data is unavailable. + // - ChannelDeprecated is True if any requested channel is marked deprecated, False if not deprecated, or Unknown if catalog data is unavailable. + // - PackageDeprecated is True if the requested package is marked deprecated, False if not deprecated, or Unknown if catalog data is unavailable. + // - Deprecated is a rollup condition that is True when any deprecation exists, False when none exist, or Unknown when catalog data is unavailable. + Conditions []metav1.ConditionApplyConfiguration `json:"conditions,omitempty"` + // install is a representation of the current installation status for this ClusterExtension. + Install *ClusterExtensionInstallStatusApplyConfiguration `json:"install,omitempty"` + // activeRevisions holds a list of currently active (non-archived) ClusterExtensionRevisions, + // including both installed and rolling out revisions. + // + ActiveRevisions []RevisionStatusApplyConfiguration `json:"activeRevisions,omitempty"` +} + +// ClusterExtensionStatusApplyConfiguration constructs a declarative configuration of the ClusterExtensionStatus type for use with +// apply. +func ClusterExtensionStatus() *ClusterExtensionStatusApplyConfiguration { + return &ClusterExtensionStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *ClusterExtensionStatusApplyConfiguration) WithConditions(values ...*metav1.ConditionApplyConfiguration) *ClusterExtensionStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} + +// WithInstall sets the Install field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Install field is set to the value of the last call. +func (b *ClusterExtensionStatusApplyConfiguration) WithInstall(value *ClusterExtensionInstallStatusApplyConfiguration) *ClusterExtensionStatusApplyConfiguration { + b.Install = value + return b +} + +// WithActiveRevisions adds the given value to the ActiveRevisions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the ActiveRevisions field. +func (b *ClusterExtensionStatusApplyConfiguration) WithActiveRevisions(values ...*RevisionStatusApplyConfiguration) *ClusterExtensionStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithActiveRevisions") + } + b.ActiveRevisions = append(b.ActiveRevisions, *values[i]) + } + return b +} diff --git a/applyconfigurations/api/v1/crdupgradesafetypreflightconfig.go b/applyconfigurations/api/v1/crdupgradesafetypreflightconfig.go new file mode 100644 index 000000000..00c8c9f0f --- /dev/null +++ b/applyconfigurations/api/v1/crdupgradesafetypreflightconfig.go @@ -0,0 +1,52 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + apiv1 "github.com/operator-framework/operator-controller/api/v1" +) + +// CRDUpgradeSafetyPreflightConfigApplyConfiguration represents a declarative configuration of the CRDUpgradeSafetyPreflightConfig type for use +// with apply. +// +// CRDUpgradeSafetyPreflightConfig is the configuration for CRD upgrade safety preflight check. +type CRDUpgradeSafetyPreflightConfigApplyConfiguration struct { + // enforcement is required and configures the state of the CRD Upgrade Safety pre-flight check. + // + // Allowed values are "None" or "Strict". The default value is "Strict". + // + // When set to "None", the CRD Upgrade Safety pre-flight check is skipped during an upgrade operation. + // Use this option with caution as unintended consequences such as data loss can occur. + // + // When set to "Strict", the CRD Upgrade Safety pre-flight check runs during an upgrade operation. + Enforcement *apiv1.CRDUpgradeSafetyEnforcement `json:"enforcement,omitempty"` +} + +// CRDUpgradeSafetyPreflightConfigApplyConfiguration constructs a declarative configuration of the CRDUpgradeSafetyPreflightConfig type for use with +// apply. +func CRDUpgradeSafetyPreflightConfig() *CRDUpgradeSafetyPreflightConfigApplyConfiguration { + return &CRDUpgradeSafetyPreflightConfigApplyConfiguration{} +} + +// WithEnforcement sets the Enforcement field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Enforcement field is set to the value of the last call. +func (b *CRDUpgradeSafetyPreflightConfigApplyConfiguration) WithEnforcement(value apiv1.CRDUpgradeSafetyEnforcement) *CRDUpgradeSafetyPreflightConfigApplyConfiguration { + b.Enforcement = &value + return b +} diff --git a/applyconfigurations/api/v1/imagesource.go b/applyconfigurations/api/v1/imagesource.go new file mode 100644 index 000000000..e07b28ffc --- /dev/null +++ b/applyconfigurations/api/v1/imagesource.go @@ -0,0 +1,92 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +// ImageSourceApplyConfiguration represents a declarative configuration of the ImageSource type for use +// with apply. +// +// # ImageSource enables users to define the information required for sourcing a Catalog from an OCI image +// +// If we see that there is a possibly valid digest-based image reference AND pollIntervalMinutes is specified, +// reject the resource since there is no use in polling a digest-based image reference. +type ImageSourceApplyConfiguration struct { + // ref is a required field that defines the reference to a container image containing catalog contents. + // It cannot be more than 1000 characters. + // + // A reference has 3 parts: the domain, name, and identifier. + // + // The domain is typically the registry where an image is located. + // It must be alphanumeric characters (lowercase and uppercase) separated by the "." character. + // Hyphenation is allowed, but the domain must start and end with alphanumeric characters. + // Specifying a port to use is also allowed by adding the ":" character followed by numeric values. + // The port must be the last value in the domain. + // Some examples of valid domain values are "registry.mydomain.io", "quay.io", "my-registry.io:8080". + // + // The name is typically the repository in the registry where an image is located. + // It must contain lowercase alphanumeric characters separated only by the ".", "_", "__", "-" characters. + // Multiple names can be concatenated with the "/" character. + // The domain and name are combined using the "/" character. + // Some examples of valid name values are "operatorhubio/catalog", "catalog", "my-catalog.prod". + // An example of the domain and name parts of a reference being combined is "quay.io/operatorhubio/catalog". + // + // The identifier is typically the tag or digest for an image reference and is present at the end of the reference. + // It starts with a separator character used to distinguish the end of the name and beginning of the identifier. + // For a digest-based reference, the "@" character is the separator. + // For a tag-based reference, the ":" character is the separator. + // An identifier is required in the reference. + // + // Digest-based references must contain an algorithm reference immediately after the "@" separator. + // The algorithm reference must be followed by the ":" character and an encoded string. + // The algorithm must start with an uppercase or lowercase alpha character followed by alphanumeric characters and may contain the "-", "_", "+", and "." characters. + // Some examples of valid algorithm values are "sha256", "sha256+b64u", "multihash+base58". + // The encoded string following the algorithm must be hex digits (a-f, A-F, 0-9) and must be a minimum of 32 characters. + // + // Tag-based references must begin with a word character (alphanumeric + "_") followed by word characters or ".", and "-" characters. + // The tag must not be longer than 127 characters. + // + // An example of a valid digest-based image reference is "quay.io/operatorhubio/catalog@sha256:200d4ddb2a73594b91358fe6397424e975205bfbe44614f5846033cad64b3f05" + // An example of a valid tag-based image reference is "quay.io/operatorhubio/catalog:latest" + Ref *string `json:"ref,omitempty"` + // pollIntervalMinutes is an optional field that sets the interval, in minutes, at which the image source is polled for new content. + // You cannot specify pollIntervalMinutes when ref is a digest-based reference. + // + // When omitted, the image is not polled for new content. + PollIntervalMinutes *int `json:"pollIntervalMinutes,omitempty"` +} + +// ImageSourceApplyConfiguration constructs a declarative configuration of the ImageSource type for use with +// apply. +func ImageSource() *ImageSourceApplyConfiguration { + return &ImageSourceApplyConfiguration{} +} + +// WithRef sets the Ref field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Ref field is set to the value of the last call. +func (b *ImageSourceApplyConfiguration) WithRef(value string) *ImageSourceApplyConfiguration { + b.Ref = &value + return b +} + +// WithPollIntervalMinutes sets the PollIntervalMinutes field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PollIntervalMinutes field is set to the value of the last call. +func (b *ImageSourceApplyConfiguration) WithPollIntervalMinutes(value int) *ImageSourceApplyConfiguration { + b.PollIntervalMinutes = &value + return b +} diff --git a/applyconfigurations/api/v1/preflightconfig.go b/applyconfigurations/api/v1/preflightconfig.go new file mode 100644 index 000000000..91b533ade --- /dev/null +++ b/applyconfigurations/api/v1/preflightconfig.go @@ -0,0 +1,45 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +// PreflightConfigApplyConfiguration represents a declarative configuration of the PreflightConfig type for use +// with apply. +// +// PreflightConfig holds the configuration for the preflight checks. If used, at least one preflight check must be non-nil. +type PreflightConfigApplyConfiguration struct { + // crdUpgradeSafety configures the CRD Upgrade Safety pre-flight checks that run + // before upgrades of installed content. + // + // The CRD Upgrade Safety pre-flight check safeguards from unintended consequences of upgrading a CRD, + // such as data loss. + CRDUpgradeSafety *CRDUpgradeSafetyPreflightConfigApplyConfiguration `json:"crdUpgradeSafety,omitempty"` +} + +// PreflightConfigApplyConfiguration constructs a declarative configuration of the PreflightConfig type for use with +// apply. +func PreflightConfig() *PreflightConfigApplyConfiguration { + return &PreflightConfigApplyConfiguration{} +} + +// WithCRDUpgradeSafety sets the CRDUpgradeSafety field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CRDUpgradeSafety field is set to the value of the last call. +func (b *PreflightConfigApplyConfiguration) WithCRDUpgradeSafety(value *CRDUpgradeSafetyPreflightConfigApplyConfiguration) *PreflightConfigApplyConfiguration { + b.CRDUpgradeSafety = value + return b +} diff --git a/applyconfigurations/api/v1/resolvedcatalogsource.go b/applyconfigurations/api/v1/resolvedcatalogsource.go new file mode 100644 index 000000000..3897e5733 --- /dev/null +++ b/applyconfigurations/api/v1/resolvedcatalogsource.go @@ -0,0 +1,61 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + apiv1 "github.com/operator-framework/operator-controller/api/v1" +) + +// ResolvedCatalogSourceApplyConfiguration represents a declarative configuration of the ResolvedCatalogSource type for use +// with apply. +// +// ResolvedCatalogSource is a discriminated union of resolution information for a Catalog. +// ResolvedCatalogSource contains the information about a sourced Catalog +type ResolvedCatalogSourceApplyConfiguration struct { + // type is a required field that specifies the type of source for the catalog. + // + // The only allowed value is "Image". + // + // When set to "Image", information about the resolved image source is set in the image field. + Type *apiv1.SourceType `json:"type,omitempty"` + // image contains resolution information for a catalog sourced from an image. + // It must be set when type is Image, and forbidden otherwise. + Image *ResolvedImageSourceApplyConfiguration `json:"image,omitempty"` +} + +// ResolvedCatalogSourceApplyConfiguration constructs a declarative configuration of the ResolvedCatalogSource type for use with +// apply. +func ResolvedCatalogSource() *ResolvedCatalogSourceApplyConfiguration { + return &ResolvedCatalogSourceApplyConfiguration{} +} + +// WithType sets the Type field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Type field is set to the value of the last call. +func (b *ResolvedCatalogSourceApplyConfiguration) WithType(value apiv1.SourceType) *ResolvedCatalogSourceApplyConfiguration { + b.Type = &value + return b +} + +// WithImage sets the Image field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Image field is set to the value of the last call. +func (b *ResolvedCatalogSourceApplyConfiguration) WithImage(value *ResolvedImageSourceApplyConfiguration) *ResolvedCatalogSourceApplyConfiguration { + b.Image = value + return b +} diff --git a/applyconfigurations/api/v1/resolvedimagesource.go b/applyconfigurations/api/v1/resolvedimagesource.go new file mode 100644 index 000000000..87be653a4 --- /dev/null +++ b/applyconfigurations/api/v1/resolvedimagesource.go @@ -0,0 +1,43 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +// ResolvedImageSourceApplyConfiguration represents a declarative configuration of the ResolvedImageSource type for use +// with apply. +// +// ResolvedImageSource provides information about the resolved source of a Catalog sourced from an image. +type ResolvedImageSourceApplyConfiguration struct { + // ref contains the resolved image digest-based reference. + // The digest format allows you to use other tooling to fetch the exact OCI manifests + // that were used to extract the catalog contents. + Ref *string `json:"ref,omitempty"` +} + +// ResolvedImageSourceApplyConfiguration constructs a declarative configuration of the ResolvedImageSource type for use with +// apply. +func ResolvedImageSource() *ResolvedImageSourceApplyConfiguration { + return &ResolvedImageSourceApplyConfiguration{} +} + +// WithRef sets the Ref field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Ref field is set to the value of the last call. +func (b *ResolvedImageSourceApplyConfiguration) WithRef(value string) *ResolvedImageSourceApplyConfiguration { + b.Ref = &value + return b +} diff --git a/applyconfigurations/api/v1/revisionstatus.go b/applyconfigurations/api/v1/revisionstatus.go new file mode 100644 index 000000000..d8a2e248f --- /dev/null +++ b/applyconfigurations/api/v1/revisionstatus.go @@ -0,0 +1,63 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +import ( + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// RevisionStatusApplyConfiguration represents a declarative configuration of the RevisionStatus type for use +// with apply. +// +// RevisionStatus defines the observed state of a ClusterExtensionRevision. +type RevisionStatusApplyConfiguration struct { + // name of the ClusterExtensionRevision resource + Name *string `json:"name,omitempty"` + // conditions optionally expose Progressing and Available condition of the revision, + // in case when it is not yet marked as successfully installed (condition Succeeded is not set to True). + // Given that a ClusterExtension should remain available during upgrades, an observer may use these conditions + // to get more insights about reasons for its current state. + Conditions []metav1.ConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// RevisionStatusApplyConfiguration constructs a declarative configuration of the RevisionStatus type for use with +// apply. +func RevisionStatus() *RevisionStatusApplyConfiguration { + return &RevisionStatusApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *RevisionStatusApplyConfiguration) WithName(value string) *RevisionStatusApplyConfiguration { + b.Name = &value + return b +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *RevisionStatusApplyConfiguration) WithConditions(values ...*metav1.ConditionApplyConfiguration) *RevisionStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/applyconfigurations/api/v1/serviceaccountreference.go b/applyconfigurations/api/v1/serviceaccountreference.go new file mode 100644 index 000000000..436cab65f --- /dev/null +++ b/applyconfigurations/api/v1/serviceaccountreference.go @@ -0,0 +1,61 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +// ServiceAccountReferenceApplyConfiguration represents a declarative configuration of the ServiceAccountReference type for use +// with apply. +// +// ServiceAccountReference identifies the serviceAccount used fo install a ClusterExtension. +type ServiceAccountReferenceApplyConfiguration struct { + // name is a required, immutable reference to the name of the ServiceAccount used for installation + // and management of the content for the package specified in the packageName field. + // + // This ServiceAccount must exist in the installNamespace. + // + // The name field follows the DNS subdomain standard as defined in [RFC 1123]. + // It must contain only lowercase alphanumeric characters, hyphens (-) or periods (.), + // start and end with an alphanumeric character, and be no longer than 253 characters. + // + // 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- + // + // [RFC 1123]: https://tools.ietf.org/html/rfc1123 + Name *string `json:"name,omitempty"` +} + +// ServiceAccountReferenceApplyConfiguration constructs a declarative configuration of the ServiceAccountReference type for use with +// apply. +func ServiceAccountReference() *ServiceAccountReferenceApplyConfiguration { + return &ServiceAccountReferenceApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ServiceAccountReferenceApplyConfiguration) WithName(value string) *ServiceAccountReferenceApplyConfiguration { + b.Name = &value + return b +} diff --git a/applyconfigurations/api/v1/sourceconfig.go b/applyconfigurations/api/v1/sourceconfig.go new file mode 100644 index 000000000..13221594a --- /dev/null +++ b/applyconfigurations/api/v1/sourceconfig.go @@ -0,0 +1,58 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package v1 + +// SourceConfigApplyConfiguration represents a declarative configuration of the SourceConfig type for use +// with apply. +// +// SourceConfig is a discriminated union which selects the installation source. +type SourceConfigApplyConfiguration struct { + // sourceType is required and specifies the type of install source. + // + // The only allowed value is "Catalog". + // + // When set to "Catalog", information for determining the appropriate bundle of content to install + // is fetched from ClusterCatalog resources on the cluster. + // When using the Catalog sourceType, the catalog field must also be set. + SourceType *string `json:"sourceType,omitempty"` + // catalog configures how information is sourced from a catalog. + // It is required when sourceType is "Catalog", and forbidden otherwise. + Catalog *CatalogFilterApplyConfiguration `json:"catalog,omitempty"` +} + +// SourceConfigApplyConfiguration constructs a declarative configuration of the SourceConfig type for use with +// apply. +func SourceConfig() *SourceConfigApplyConfiguration { + return &SourceConfigApplyConfiguration{} +} + +// WithSourceType sets the SourceType field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the SourceType field is set to the value of the last call. +func (b *SourceConfigApplyConfiguration) WithSourceType(value string) *SourceConfigApplyConfiguration { + b.SourceType = &value + return b +} + +// WithCatalog sets the Catalog field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Catalog field is set to the value of the last call. +func (b *SourceConfigApplyConfiguration) WithCatalog(value *CatalogFilterApplyConfiguration) *SourceConfigApplyConfiguration { + b.Catalog = value + return b +} diff --git a/applyconfigurations/internal/internal.go b/applyconfigurations/internal/internal.go new file mode 100644 index 000000000..a296a1a64 --- /dev/null +++ b/applyconfigurations/internal/internal.go @@ -0,0 +1,61 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package internal + +import ( + fmt "fmt" + sync "sync" + + typed "sigs.k8s.io/structured-merge-diff/v6/typed" +) + +func Parser() *typed.Parser { + parserOnce.Do(func() { + var err error + parser, err = typed.NewParser(schemaYAML) + if err != nil { + panic(fmt.Sprintf("Failed to parse schema: %v", err)) + } + }) + return parser +} + +var parserOnce sync.Once +var parser *typed.Parser +var schemaYAML = typed.YAMLObject(`types: +- name: __untyped_atomic_ + scalar: untyped + list: + elementType: + namedType: __untyped_atomic_ + elementRelationship: atomic + map: + elementType: + namedType: __untyped_atomic_ + elementRelationship: atomic +- name: __untyped_deduced_ + scalar: untyped + list: + elementType: + namedType: __untyped_atomic_ + elementRelationship: atomic + map: + elementType: + namedType: __untyped_deduced_ + elementRelationship: separable +`) diff --git a/applyconfigurations/utils.go b/applyconfigurations/utils.go new file mode 100644 index 000000000..4c4a80e9f --- /dev/null +++ b/applyconfigurations/utils.go @@ -0,0 +1,93 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by controller-gen-v0.20. DO NOT EDIT. + +package applyconfigurations + +import ( + v1 "github.com/operator-framework/operator-controller/api/v1" + apiv1 "github.com/operator-framework/operator-controller/applyconfigurations/api/v1" + internal "github.com/operator-framework/operator-controller/applyconfigurations/internal" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" +) + +// ForKind returns an apply configuration type for the given GroupVersionKind, or nil if no +// apply configuration type exists for the given GroupVersionKind. +func ForKind(kind schema.GroupVersionKind) interface{} { + switch kind { + // Group=olm.operatorframework.io, Version=v1 + case v1.SchemeGroupVersion.WithKind("BundleMetadata"): + return &apiv1.BundleMetadataApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("CatalogFilter"): + return &apiv1.CatalogFilterApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("CatalogSource"): + return &apiv1.CatalogSourceApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterCatalog"): + return &apiv1.ClusterCatalogApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterCatalogSpec"): + return &apiv1.ClusterCatalogSpecApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterCatalogStatus"): + return &apiv1.ClusterCatalogStatusApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterCatalogURLs"): + return &apiv1.ClusterCatalogURLsApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterExtension"): + return &apiv1.ClusterExtensionApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterExtensionConfig"): + return &apiv1.ClusterExtensionConfigApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterExtensionInstallConfig"): + return &apiv1.ClusterExtensionInstallConfigApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterExtensionInstallStatus"): + return &apiv1.ClusterExtensionInstallStatusApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterExtensionRevision"): + return &apiv1.ClusterExtensionRevisionApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterExtensionRevisionObject"): + return &apiv1.ClusterExtensionRevisionObjectApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterExtensionRevisionPhase"): + return &apiv1.ClusterExtensionRevisionPhaseApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterExtensionRevisionSpec"): + return &apiv1.ClusterExtensionRevisionSpecApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterExtensionRevisionStatus"): + return &apiv1.ClusterExtensionRevisionStatusApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterExtensionSpec"): + return &apiv1.ClusterExtensionSpecApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ClusterExtensionStatus"): + return &apiv1.ClusterExtensionStatusApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("CRDUpgradeSafetyPreflightConfig"): + return &apiv1.CRDUpgradeSafetyPreflightConfigApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ImageSource"): + return &apiv1.ImageSourceApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("PreflightConfig"): + return &apiv1.PreflightConfigApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ResolvedCatalogSource"): + return &apiv1.ResolvedCatalogSourceApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ResolvedImageSource"): + return &apiv1.ResolvedImageSourceApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("RevisionStatus"): + return &apiv1.RevisionStatusApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("ServiceAccountReference"): + return &apiv1.ServiceAccountReferenceApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("SourceConfig"): + return &apiv1.SourceConfigApplyConfiguration{} + + } + return nil +} + +func NewTypeConverter(scheme *runtime.Scheme) managedfields.TypeConverter { + return managedfields.NewSchemeTypeConverter(scheme, internal.Parser()) +} diff --git a/cmd/operator-controller/main.go b/cmd/operator-controller/main.go index dd0bc98f6..9aab62868 100644 --- a/cmd/operator-controller/main.go +++ b/cmd/operator-controller/main.go @@ -610,13 +610,14 @@ func (c *boxcutterReconcilerConfigurator) Configure(ceReconciler *controllers.Cl Scheme: c.mgr.GetScheme(), ManifestProvider: c.regv1ManifestProvider, } + fieldOwner := fmt.Sprintf("%s/clusterextension-controller", fieldOwnerPrefix) appl := &applier.Boxcutter{ Client: c.mgr.GetClient(), Scheme: c.mgr.GetScheme(), RevisionGenerator: rg, Preflights: c.preflights, PreAuthorizer: preAuth, - FieldOwner: fmt.Sprintf("%s/clusterextension-controller", fieldOwnerPrefix), + FieldOwner: fieldOwner, } revisionStatesGetter := &controllers.BoxcutterRevisionStatesGetter{Reader: c.mgr.GetClient()} storageMigrator := &applier.BoxcutterStorageMigrator{ @@ -624,6 +625,7 @@ func (c *boxcutterReconcilerConfigurator) Configure(ceReconciler *controllers.Cl Scheme: c.mgr.GetScheme(), ActionClientGetter: acg, RevisionGenerator: rg, + FieldOwner: fieldOwner, } ceReconciler.ReconcileSteps = []controllers.ReconcileStepFunc{ controllers.HandleFinalizers(c.finalizers), diff --git a/go.mod b/go.mod index d604830a5..c92dc78d9 100644 --- a/go.mod +++ b/go.mod @@ -49,6 +49,7 @@ require ( sigs.k8s.io/controller-runtime v0.23.1 sigs.k8s.io/controller-tools v0.20.0 sigs.k8s.io/crdify v0.5.0 + sigs.k8s.io/structured-merge-diff/v6 v6.3.2 sigs.k8s.io/yaml v1.6.0 ) @@ -252,7 +253,6 @@ require ( sigs.k8s.io/kustomize/api v0.21.1 // indirect sigs.k8s.io/kustomize/kyaml v0.21.1 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect ) retract v1.5.0 // contains filename with ':' which causes failure creating module zip file diff --git a/internal/operator-controller/applier/boxcutter.go b/internal/operator-controller/applier/boxcutter.go index 04e59ca95..3ff6e3165 100644 --- a/internal/operator-controller/applier/boxcutter.go +++ b/internal/operator-controller/applier/boxcutter.go @@ -22,15 +22,16 @@ import ( "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/cli-runtime/pkg/printers" + metav1ac "k8s.io/client-go/applyconfigurations/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/yaml" helmclient "github.com/operator-framework/helm-operator-plugins/pkg/client" ocv1 "github.com/operator-framework/operator-controller/api/v1" + ocv1ac "github.com/operator-framework/operator-controller/applyconfigurations/api/v1" "github.com/operator-framework/operator-controller/internal/operator-controller/authorization" "github.com/operator-framework/operator-controller/internal/operator-controller/labels" "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle/source" @@ -42,12 +43,12 @@ const ( ) type ClusterExtensionRevisionGenerator interface { - GenerateRevision(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1.ClusterExtensionRevision, error) + GenerateRevision(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) GenerateRevisionFromHelmRelease( ctx context.Context, helmRelease *release.Release, ext *ocv1.ClusterExtension, objectLabels map[string]string, - ) (*ocv1.ClusterExtensionRevision, error) + ) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) } type SimpleRevisionGenerator struct { @@ -59,9 +60,9 @@ func (r *SimpleRevisionGenerator) GenerateRevisionFromHelmRelease( ctx context.Context, helmRelease *release.Release, ext *ocv1.ClusterExtension, objectLabels map[string]string, -) (*ocv1.ClusterExtensionRevision, error) { +) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) { docs := splitManifestDocuments(helmRelease.Manifest) - objs := make([]ocv1.ClusterExtensionRevisionObject, 0, len(docs)) + objs := make([]ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration, 0, len(docs)) for _, doc := range docs { obj := unstructured.Unstructured{} if err := yaml.Unmarshal([]byte(doc), &obj); err != nil { @@ -74,10 +75,9 @@ func (r *SimpleRevisionGenerator) GenerateRevisionFromHelmRelease( _ = cache.ApplyStripAnnotationsTransform(&obj) sanitizedUnstructured(ctx, &obj) - objs = append(objs, ocv1.ClusterExtensionRevisionObject{ - Object: obj, - CollisionProtection: ocv1.CollisionProtectionNone, // allow to adopt objects from previous release - }) + objs = append(objs, *ocv1ac.ClusterExtensionRevisionObject(). + WithObject(obj). + WithCollisionProtection(ocv1.CollisionProtectionNone)) } rev := r.buildClusterExtensionRevision(objs, ext, map[string]string{ @@ -86,8 +86,8 @@ func (r *SimpleRevisionGenerator) GenerateRevisionFromHelmRelease( labels.BundleVersionKey: helmRelease.Labels[labels.BundleVersionKey], labels.BundleReferenceKey: helmRelease.Labels[labels.BundleReferenceKey], }) - rev.Name = fmt.Sprintf("%s-1", ext.Name) - rev.Spec.Revision = 1 + rev.WithName(fmt.Sprintf("%s-1", ext.Name)) + rev.Spec.WithRevision(1) return rev, nil } @@ -95,7 +95,7 @@ func (r *SimpleRevisionGenerator) GenerateRevision( ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string, -) (*ocv1.ClusterExtensionRevision, error) { +) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) { // extract plain manifests plain, err := r.ManifestProvider.Get(bundleFS, ext) if err != nil { @@ -124,7 +124,7 @@ func (r *SimpleRevisionGenerator) GenerateRevision( } // objectLabels - objs := make([]ocv1.ClusterExtensionRevisionObject, 0, len(plain)) + objs := make([]ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration, 0, len(plain)) for _, obj := range plain { obj.SetLabels(mergeLabelMaps(obj.GetLabels(), objectLabels)) @@ -146,10 +146,9 @@ func (r *SimpleRevisionGenerator) GenerateRevision( } sanitizedUnstructured(ctx, &unstr) - objs = append(objs, ocv1.ClusterExtensionRevisionObject{ - Object: unstr, - CollisionProtection: ocv1.CollisionProtectionPrevent, - }) + objs = append(objs, *ocv1ac.ClusterExtensionRevisionObject(). + WithObject(unstr). + WithCollisionProtection(ocv1.CollisionProtectionPrevent)) } return r.buildClusterExtensionRevision(objs, ext, revisionAnnotations), nil } @@ -197,33 +196,32 @@ func sanitizedUnstructured(ctx context.Context, unstr *unstructured.Unstructured } func (r *SimpleRevisionGenerator) buildClusterExtensionRevision( - objects []ocv1.ClusterExtensionRevisionObject, + objects []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration, ext *ocv1.ClusterExtension, annotations map[string]string, -) *ocv1.ClusterExtensionRevision { +) *ocv1ac.ClusterExtensionRevisionApplyConfiguration { if annotations == nil { annotations = make(map[string]string) } annotations[labels.ServiceAccountNameKey] = ext.Spec.ServiceAccount.Name annotations[labels.ServiceAccountNamespaceKey] = ext.Spec.Namespace - cer := &ocv1.ClusterExtensionRevision{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: annotations, - Labels: map[string]string{ - labels.OwnerKindKey: ocv1.ClusterExtensionKind, - labels.OwnerNameKey: ext.Name, - }, - }, - Spec: ocv1.ClusterExtensionRevisionSpec{ - LifecycleState: ocv1.ClusterExtensionRevisionLifecycleStateActive, - Phases: PhaseSort(objects), - }, - } + phases := PhaseSort(objects) + + spec := ocv1ac.ClusterExtensionRevisionSpec(). + WithLifecycleState(ocv1.ClusterExtensionRevisionLifecycleStateActive). + WithPhases(phases...) if p := ext.Spec.ProgressDeadlineMinutes; p > 0 { - cer.Spec.ProgressDeadlineMinutes = p + spec.WithProgressDeadlineMinutes(p) } - return cer + + return ocv1ac.ClusterExtensionRevision(""). + WithAnnotations(annotations). + WithLabels(map[string]string{ + labels.OwnerKindKey: ocv1.ClusterExtensionKind, + labels.OwnerNameKey: ext.Name, + }). + WithSpec(spec) } // BoxcutterStorageMigrator migrates ClusterExtensions from Helm-based storage to @@ -233,12 +231,13 @@ type BoxcutterStorageMigrator struct { RevisionGenerator ClusterExtensionRevisionGenerator Client boxcutterStorageMigratorClient Scheme *runtime.Scheme + FieldOwner string } type boxcutterStorageMigratorClient interface { + Apply(ctx context.Context, obj runtime.ApplyConfiguration, opts ...client.ApplyOption) error List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error - Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error Status() client.StatusWriter } @@ -294,17 +293,22 @@ func (m *BoxcutterStorageMigrator) Migrate(ctx context.Context, ext *ocv1.Cluste // normal Boxcutter revisions. This label is critical for ensuring we only // set Succeeded=True status on actually-migrated revisions, not on revision 1 // created during normal Boxcutter operation. - if rev.Labels == nil { - rev.Labels = make(map[string]string) - } - rev.Labels[labels.MigratedFromHelmKey] = "true" + rev.WithLabels(map[string]string{labels.MigratedFromHelmKey: "true"}) // Set ownerReference for proper garbage collection when the ClusterExtension is deleted. - if err := controllerutil.SetControllerReference(ext, rev, m.Scheme); err != nil { - return fmt.Errorf("set ownerref: %w", err) + gvk, err := apiutil.GVKForObject(ext, m.Scheme) + if err != nil { + return fmt.Errorf("get GVK for owner: %w", err) } + rev.WithOwnerReferences(metav1ac.OwnerReference(). + WithAPIVersion(gvk.GroupVersion().String()). + WithKind(gvk.Kind). + WithName(ext.Name). + WithUID(ext.UID). + WithBlockOwnerDeletion(true). + WithController(true)) - if err := m.Client.Create(ctx, rev); err != nil { + if err := m.Client.Apply(ctx, rev, client.FieldOwner(m.FieldOwner), client.ForceOwnership); err != nil { return err } @@ -324,7 +328,7 @@ func (m *BoxcutterStorageMigrator) Migrate(ctx context.Context, ext *ocv1.Cluste // // Since we're creating this revision from a successfully deployed Helm release, we know it // represents a working installation and can safely mark it as succeeded immediately. - return m.ensureRevisionStatus(ctx, rev) + return m.ensureRevisionStatus(ctx, *rev.GetName()) } // ensureMigratedRevisionStatus checks if revision 1 exists and needs its status set. @@ -341,7 +345,7 @@ func (m *BoxcutterStorageMigrator) ensureMigratedRevisionStatus(ctx context.Cont } // Ensure revision 1 status is set correctly, including for previously migrated // revisions that may not carry the MigratedFromHelm label. - return m.ensureRevisionStatus(ctx, &revisions[i]) + return m.ensureRevisionStatus(ctx, revisions[i].Name) } // No revision 1 found - migration not applicable (revisions created by normal operation). return nil @@ -378,9 +382,9 @@ func (m *BoxcutterStorageMigrator) findLatestDeployedRelease(ac helmclient.Actio // ensureRevisionStatus ensures the revision has the Succeeded status condition set. // Returns nil if the status is already set or after successfully setting it. // Only sets status on revisions that were actually migrated from Helm (marked with MigratedFromHelmKey label). -func (m *BoxcutterStorageMigrator) ensureRevisionStatus(ctx context.Context, rev *ocv1.ClusterExtensionRevision) error { - // Re-fetch to get latest version before checking status - if err := m.Client.Get(ctx, client.ObjectKeyFromObject(rev), rev); err != nil { +func (m *BoxcutterStorageMigrator) ensureRevisionStatus(ctx context.Context, name string) error { + rev := &ocv1.ClusterExtensionRevision{} + if err := m.Client.Get(ctx, client.ObjectKey{Name: name}, rev); err != nil { return fmt.Errorf("getting existing revision for status check: %w", err) } @@ -421,53 +425,15 @@ type Boxcutter struct { FieldOwner string } -// createOrUpdate creates or updates the revision object. PreAuthorization checks are performed to ensure the -// user has sufficient permissions to manage the revision and its resources -func (bc *Boxcutter) createOrUpdate(ctx context.Context, user user.Info, rev *ocv1.ClusterExtensionRevision) error { - if rev.GetObjectKind().GroupVersionKind().Empty() { - gvk, err := apiutil.GVKForObject(rev, bc.Scheme) - if err != nil { - return err - } - rev.GetObjectKind().SetGroupVersionKind(gvk) - } - +// apply applies the revision object using server-side apply. PreAuthorization checks are performed +// to ensure the user has sufficient permissions to manage the revision and its resources. +func (bc *Boxcutter) apply(ctx context.Context, user user.Info, rev *ocv1ac.ClusterExtensionRevisionApplyConfiguration) error { // Run auth preflight checks if err := bc.runPreAuthorizationChecks(ctx, user, rev); err != nil { return err } - // DEPRECATION NOTICE: Using client.Apply (deprecated in controller-runtime v0.23.0+) - // - // WHY WE CAN'T FIX THIS YET: - // The recommended replacement is the new typed Apply() method that requires generated - // apply configurations (ApplyConfiguration types). However, this project does not - // currently generate these apply configurations for its API types. - // - // WHY WE NEED SERVER-SIDE APPLY SEMANTICS: - // This controller requires server-side apply with field ownership management to: - // 1. Track which controller owns which fields (via client.FieldOwner) - // 2. Take ownership of fields from other managers during upgrades (via client.ForceOwnership) - // 3. Automatically create-or-update without explicit Get/Create/Update logic - // - // WHY ALTERNATIVES DON'T WORK: - // - client.MergeFrom(): Lacks field ownership - causes conflicts during controller upgrades - // - client.StrategicMergePatch(): No field management - upgrade tests fail with ownership errors - // - Manual Create/Update: Loses server-side apply benefits, complex to implement correctly - // - // WHAT'S REQUIRED TO FIX PROPERLY: - // 1. Generate apply configurations for all API types (ClusterExtensionRevision, etc.) - // - Requires running controller-gen with --with-applyconfig flag - // - Generates ClusterExtensionRevisionApplyConfiguration types - // 2. Update all resource creation/update code to use typed Apply methods - // 3. Update all tests to work with new patterns - // This is a project-wide effort beyond the scope of the k8s v1.35 upgrade. - // - // MIGRATION PATH: - // Track in a future issue: "Generate apply configurations and migrate to typed Apply methods" - // - // nolint:staticcheck // SA1019: server-side apply required, needs generated apply configurations - return bc.Client.Patch(ctx, rev, client.Apply, client.FieldOwner(bc.FieldOwner), client.ForceOwnership) + return bc.Client.Apply(ctx, rev, client.FieldOwner(bc.FieldOwner), client.ForceOwnership) } func (bc *Boxcutter) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (bool, string, error) { @@ -500,9 +466,17 @@ func (bc *Boxcutter) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1.Clust return false, "", err } - if err := controllerutil.SetControllerReference(ext, desiredRevision, bc.Scheme); err != nil { - return false, "", fmt.Errorf("set ownerref: %w", err) + gvk, err := apiutil.GVKForObject(ext, bc.Scheme) + if err != nil { + return false, "", fmt.Errorf("get GVK for owner: %w", err) } + desiredRevision.WithOwnerReferences(metav1ac.OwnerReference(). + WithAPIVersion(gvk.GroupVersion().String()). + WithKind(gvk.Kind). + WithName(ext.Name). + WithUID(ext.UID). + WithBlockOwnerDeletion(true). + WithController(true)) currentRevision := &ocv1.ClusterExtensionRevision{} state := StateNeedsInstall @@ -510,10 +484,10 @@ func (bc *Boxcutter) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1.Clust if len(existingRevisions) > 0 { // try first to update the current revision. currentRevision = &existingRevisions[len(existingRevisions)-1] - desiredRevision.Spec.Revision = currentRevision.Spec.Revision - desiredRevision.Name = currentRevision.Name + desiredRevision.Spec.WithRevision(currentRevision.Spec.Revision) + desiredRevision.WithName(currentRevision.Name) - err := bc.createOrUpdate(ctx, getUserInfo(ext), desiredRevision) + err := bc.apply(ctx, getUserInfo(ext), desiredRevision) switch { case apierrors.IsInvalid(err): // We could not update the current revision due to trying to update an immutable field. @@ -523,7 +497,7 @@ func (bc *Boxcutter) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1.Clust // inplace patch was successful, no changes in phases state = StateUnchanged default: - return false, "", fmt.Errorf("patching %s Revision: %w", desiredRevision.Name, err) + return false, "", fmt.Errorf("patching %s Revision: %w", *desiredRevision.GetName(), err) } } @@ -556,14 +530,14 @@ func (bc *Boxcutter) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1.Clust prevRevisions := existingRevisions revisionNumber := latestRevisionNumber(prevRevisions) + 1 - desiredRevision.Name = fmt.Sprintf("%s-%d", ext.Name, revisionNumber) - desiredRevision.Spec.Revision = revisionNumber + desiredRevision.WithName(fmt.Sprintf("%s-%d", ext.Name, revisionNumber)) + desiredRevision.Spec.WithRevision(revisionNumber) if err = bc.garbageCollectOldRevisions(ctx, prevRevisions); err != nil { return false, "", fmt.Errorf("garbage collecting old revisions: %w", err) } - if err := bc.createOrUpdate(ctx, getUserInfo(ext), desiredRevision); err != nil { + if err := bc.apply(ctx, getUserInfo(ext), desiredRevision); err != nil { return false, "", fmt.Errorf("creating new Revision: %w", err) } } @@ -573,7 +547,7 @@ func (bc *Boxcutter) Apply(ctx context.Context, contentFS fs.FS, ext *ocv1.Clust // runPreAuthorizationChecks runs PreAuthorization checks if the PreAuthorizer is set. An error will be returned if // the ClusterExtension service account does not have the necessary permissions to manage the revision's resources -func (bc *Boxcutter) runPreAuthorizationChecks(ctx context.Context, user user.Info, rev *ocv1.ClusterExtensionRevision) error { +func (bc *Boxcutter) runPreAuthorizationChecks(ctx context.Context, user user.Info, rev *ocv1ac.ClusterExtensionRevisionApplyConfiguration) error { if bc.PreAuthorizer == nil { return nil } @@ -648,22 +622,27 @@ func splitManifestDocuments(file string) []string { } // getObjects returns a slice of all objects in the revision -func getObjects(rev *ocv1.ClusterExtensionRevision) []client.Object { +func getObjects(rev *ocv1ac.ClusterExtensionRevisionApplyConfiguration) []client.Object { + if rev.Spec == nil { + return nil + } totalObjects := 0 for _, phase := range rev.Spec.Phases { totalObjects += len(phase.Objects) } objs := make([]client.Object, 0, totalObjects) for _, phase := range rev.Spec.Phases { - for _, phaseObject := range phase.Objects { - objs = append(objs, &phaseObject.Object) + for i := range phase.Objects { + if phase.Objects[i].Object != nil { + objs = append(objs, phase.Objects[i].Object) + } } } return objs } // revisionManifestReader returns an io.Reader containing all manifests in the revision -func revisionManifestReader(rev *ocv1.ClusterExtensionRevision) (io.Reader, error) { +func revisionManifestReader(rev *ocv1ac.ClusterExtensionRevisionApplyConfiguration) (io.Reader, error) { printer := printers.YAMLPrinter{} buf := new(bytes.Buffer) for _, obj := range getObjects(rev) { @@ -675,12 +654,12 @@ func revisionManifestReader(rev *ocv1.ClusterExtensionRevision) (io.Reader, erro return buf, nil } -func revisionManagementPerms(rev *ocv1.ClusterExtensionRevision) func(user.Info) []authorizer.AttributesRecord { +func revisionManagementPerms(rev *ocv1ac.ClusterExtensionRevisionApplyConfiguration) func(user.Info) []authorizer.AttributesRecord { return func(user user.Info) []authorizer.AttributesRecord { return []authorizer.AttributesRecord{ { User: user, - Name: rev.Name, + Name: *rev.GetName(), APIGroup: ocv1.GroupVersion.Group, APIVersion: ocv1.GroupVersion.Version, Resource: "clusterextensionrevisions/finalizers", diff --git a/internal/operator-controller/applier/boxcutter_test.go b/internal/operator-controller/applier/boxcutter_test.go index 887dee4a9..777f56063 100644 --- a/internal/operator-controller/applier/boxcutter_test.go +++ b/internal/operator-controller/applier/boxcutter_test.go @@ -33,6 +33,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/interceptor" ocv1 "github.com/operator-framework/operator-controller/api/v1" + ocv1ac "github.com/operator-framework/operator-controller/applyconfigurations/api/v1" "github.com/operator-framework/operator-controller/internal/operator-controller/applier" "github.com/operator-framework/operator-controller/internal/operator-controller/authorization" "github.com/operator-framework/operator-controller/internal/operator-controller/labels" @@ -97,31 +98,28 @@ func Test_SimpleRevisionGenerator_GenerateRevisionFromHelmRelease(t *testing.T) rev, err := g.GenerateRevisionFromHelmRelease(t.Context(), helmRelease, ext, objectLabels) require.NoError(t, err) - assert.Equal(t, &ocv1.ClusterExtensionRevision{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-123-1", - Annotations: map[string]string{ - "olm.operatorframework.io/bundle-name": "my-bundle", - "olm.operatorframework.io/bundle-reference": "bundle-ref", - "olm.operatorframework.io/bundle-version": "1.2.0", - "olm.operatorframework.io/package-name": "my-package", - "olm.operatorframework.io/service-account-name": "test-sa", - "olm.operatorframework.io/service-account-namespace": "test-namespace", - }, - Labels: map[string]string{ - labels.OwnerKindKey: ocv1.ClusterExtensionKind, - labels.OwnerNameKey: "test-123", - }, - }, - Spec: ocv1.ClusterExtensionRevisionSpec{ - LifecycleState: ocv1.ClusterExtensionRevisionLifecycleStateActive, - Revision: 1, - Phases: []ocv1.ClusterExtensionRevisionPhase{ - { - Name: "deploy", - Objects: []ocv1.ClusterExtensionRevisionObject{ - { - Object: unstructured.Unstructured{ + expected := ocv1ac.ClusterExtensionRevision("test-123-1"). + WithAnnotations(map[string]string{ + "olm.operatorframework.io/bundle-name": "my-bundle", + "olm.operatorframework.io/bundle-reference": "bundle-ref", + "olm.operatorframework.io/bundle-version": "1.2.0", + "olm.operatorframework.io/package-name": "my-package", + "olm.operatorframework.io/service-account-name": "test-sa", + "olm.operatorframework.io/service-account-namespace": "test-namespace", + }). + WithLabels(map[string]string{ + labels.OwnerKindKey: ocv1.ClusterExtensionKind, + labels.OwnerNameKey: "test-123", + }). + WithSpec(ocv1ac.ClusterExtensionRevisionSpec(). + WithLifecycleState(ocv1.ClusterExtensionRevisionLifecycleStateActive). + WithRevision(1). + WithPhases( + ocv1ac.ClusterExtensionRevisionPhase(). + WithName("deploy"). + WithObjects( + ocv1ac.ClusterExtensionRevisionObject(). + WithObject(unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -131,11 +129,10 @@ func Test_SimpleRevisionGenerator_GenerateRevisionFromHelmRelease(t *testing.T) }, }, }, - }, - CollisionProtection: ocv1.CollisionProtectionNone, - }, - { - Object: unstructured.Unstructured{ + }). + WithCollisionProtection(ocv1.CollisionProtectionNone), + ocv1ac.ClusterExtensionRevisionObject(). + WithObject(unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -145,14 +142,12 @@ func Test_SimpleRevisionGenerator_GenerateRevisionFromHelmRelease(t *testing.T) }, }, }, - }, - CollisionProtection: ocv1.CollisionProtectionNone, - }, - }, - }, - }, - }, - }, rev) + }). + WithCollisionProtection(ocv1.CollisionProtectionNone), + ), + ), + ) + assert.Equal(t, expected, rev) } func Test_SimpleRevisionGenerator_GenerateRevision(t *testing.T) { @@ -213,15 +208,15 @@ func Test_SimpleRevisionGenerator_GenerateRevision(t *testing.T) { labels.OwnerKindKey: ocv1.ClusterExtensionKind, labels.OwnerNameKey: "test-extension", }, rev.Labels) - t.Log("by checking the revision number is 0") - require.Equal(t, int64(0), rev.Spec.Revision) + t.Log("by checking the revision number is not set (defaults to zero value)") + require.Nil(t, rev.Spec.Revision) t.Log("by checking the rendered objects are present in the correct phases") - require.Equal(t, []ocv1.ClusterExtensionRevisionPhase{ - { - Name: string(applier.PhaseDeploy), - Objects: []ocv1.ClusterExtensionRevisionObject{ - { - Object: unstructured.Unstructured{ + require.Equal(t, []ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration{ + *ocv1ac.ClusterExtensionRevisionPhase(). + WithName(string(applier.PhaseDeploy)). + WithObjects( + ocv1ac.ClusterExtensionRevisionObject(). + WithObject(unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Service", @@ -230,11 +225,10 @@ func Test_SimpleRevisionGenerator_GenerateRevision(t *testing.T) { }, "spec": map[string]interface{}{}, }, - }, - CollisionProtection: ocv1.CollisionProtectionPrevent, - }, - { - Object: unstructured.Unstructured{ + }). + WithCollisionProtection(ocv1.CollisionProtectionPrevent), + ocv1ac.ClusterExtensionRevisionObject(). + WithObject(unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -259,11 +253,9 @@ func Test_SimpleRevisionGenerator_GenerateRevision(t *testing.T) { "strategy": map[string]interface{}{}, }, }, - }, - CollisionProtection: ocv1.CollisionProtectionPrevent, - }, - }, - }, + }). + WithCollisionProtection(ocv1.CollisionProtectionPrevent), + ), }, rev.Spec.Phases) } @@ -443,7 +435,7 @@ func Test_SimpleRevisionGenerator_PropagatesProgressDeadlineMinutes(t *testing.T progressDeadlineMinutes *int32 } type want struct { - progressDeadlineMinutes int32 + progressDeadlineMinutes *int32 } type testCase struct { args args @@ -455,12 +447,12 @@ func Test_SimpleRevisionGenerator_PropagatesProgressDeadlineMinutes(t *testing.T progressDeadlineMinutes: ptr.To(int32(10)), }, want: want{ - progressDeadlineMinutes: 10, + progressDeadlineMinutes: ptr.To(int32(10)), }, }, "do not propagate when unset": { want: want{ - progressDeadlineMinutes: 0, + progressDeadlineMinutes: nil, }, }, } { @@ -554,17 +546,20 @@ func TestBoxcutter_Apply(t *testing.T) { allowedRevisionValue := func(revNum int64) *interceptor.Funcs { return &interceptor.Funcs{ - Patch: func(ctx context.Context, client client.WithWatch, obj client.Object, patch client.Patch, opts ...client.PatchOption) error { - cer, ok := obj.(*ocv1.ClusterExtensionRevision) + Apply: func(ctx context.Context, client client.WithWatch, obj runtime.ApplyConfiguration, opts ...client.ApplyOption) error { + cer, ok := obj.(*ocv1ac.ClusterExtensionRevisionApplyConfiguration) if !ok { - return fmt.Errorf("expected ClusterExtensionRevision, got %T", obj) + return fmt.Errorf("expected ClusterExtensionRevisionApplyConfiguration, got %T", obj) } - fmt.Println(cer.Spec.Revision) - if cer.Spec.Revision != revNum { - fmt.Println("AAA") - return apierrors.NewInvalid(cer.GroupVersionKind().GroupKind(), cer.GetName(), field.ErrorList{field.Invalid(field.NewPath("spec.phases"), "immutable", "spec.phases is immutable")}) + if cer.Spec == nil || cer.Spec.Revision == nil || *cer.Spec.Revision != revNum { + gk := ocv1.SchemeGroupVersion.WithKind("ClusterExtensionRevision").GroupKind() + name := "" + if n := cer.GetName(); n != nil { + name = *n + } + return apierrors.NewInvalid(gk, name, field.ErrorList{field.Invalid(field.NewPath("spec.phases"), "immutable", "spec.phases is immutable")}) } - return client.Patch(ctx, obj, patch, opts...) + return client.Apply(ctx, obj, opts...) }, } } @@ -579,21 +574,19 @@ func TestBoxcutter_Apply(t *testing.T) { { name: "first revision", mockBuilder: &mockBundleRevisionBuilder{ - makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1.ClusterExtensionRevision, error) { - return &ocv1.ClusterExtensionRevision{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: revisionAnnotations, - Labels: map[string]string{ - labels.OwnerNameKey: ext.Name, - }, - }, - Spec: ocv1.ClusterExtensionRevisionSpec{ - Phases: []ocv1.ClusterExtensionRevisionPhase{ - { - Name: string(applier.PhaseDeploy), - Objects: []ocv1.ClusterExtensionRevisionObject{ - { - Object: unstructured.Unstructured{ + makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) { + return ocv1ac.ClusterExtensionRevision(""). + WithAnnotations(revisionAnnotations). + WithLabels(map[string]string{ + labels.OwnerNameKey: ext.Name, + }). + WithSpec(ocv1ac.ClusterExtensionRevisionSpec(). + WithPhases( + ocv1ac.ClusterExtensionRevisionPhase(). + WithName(string(applier.PhaseDeploy)). + WithObjects( + ocv1ac.ClusterExtensionRevisionObject(). + WithObject(unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -601,13 +594,10 @@ func TestBoxcutter_Apply(t *testing.T) { "name": "test-cm", }, }, - }, - }, - }, - }, - }, - }, - }, nil + }), + ), + ), + ), nil }, }, validate: func(t *testing.T, c client.Client) { @@ -627,21 +617,19 @@ func TestBoxcutter_Apply(t *testing.T) { { name: "no change, revision exists", mockBuilder: &mockBundleRevisionBuilder{ - makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1.ClusterExtensionRevision, error) { - return &ocv1.ClusterExtensionRevision{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: revisionAnnotations, - Labels: map[string]string{ - labels.OwnerNameKey: ext.Name, - }, - }, - Spec: ocv1.ClusterExtensionRevisionSpec{ - Phases: []ocv1.ClusterExtensionRevisionPhase{ - { - Name: string(applier.PhaseDeploy), - Objects: []ocv1.ClusterExtensionRevisionObject{ - { - Object: unstructured.Unstructured{ + makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) { + return ocv1ac.ClusterExtensionRevision(""). + WithAnnotations(revisionAnnotations). + WithLabels(map[string]string{ + labels.OwnerNameKey: ext.Name, + }). + WithSpec(ocv1ac.ClusterExtensionRevisionSpec(). + WithPhases( + ocv1ac.ClusterExtensionRevisionPhase(). + WithName(string(applier.PhaseDeploy)). + WithObjects( + ocv1ac.ClusterExtensionRevisionObject(). + WithObject(unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -649,13 +637,10 @@ func TestBoxcutter_Apply(t *testing.T) { "name": "test-cm", }, }, - }, - }, - }, - }, - }, - }, - }, nil + }), + ), + ), + ), nil }, }, existingObjs: []client.Object{ @@ -673,21 +658,19 @@ func TestBoxcutter_Apply(t *testing.T) { { name: "new revision created when objects in new revision are different", mockBuilder: &mockBundleRevisionBuilder{ - makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1.ClusterExtensionRevision, error) { - return &ocv1.ClusterExtensionRevision{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: revisionAnnotations, - Labels: map[string]string{ - labels.OwnerNameKey: ext.Name, - }, - }, - Spec: ocv1.ClusterExtensionRevisionSpec{ - Phases: []ocv1.ClusterExtensionRevisionPhase{ - { - Name: string(applier.PhaseDeploy), - Objects: []ocv1.ClusterExtensionRevisionObject{ - { - Object: unstructured.Unstructured{ + makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) { + return ocv1ac.ClusterExtensionRevision(""). + WithAnnotations(revisionAnnotations). + WithLabels(map[string]string{ + labels.OwnerNameKey: ext.Name, + }). + WithSpec(ocv1ac.ClusterExtensionRevisionSpec(). + WithPhases( + ocv1ac.ClusterExtensionRevisionPhase(). + WithName(string(applier.PhaseDeploy)). + WithObjects( + ocv1ac.ClusterExtensionRevisionObject(). + WithObject(unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -695,13 +678,10 @@ func TestBoxcutter_Apply(t *testing.T) { "name": "new-secret", }, }, - }, - }, - }, - }, - }, - }, - }, nil + }), + ), + ), + ), nil }, }, clientIterceptor: allowedRevisionValue(2), @@ -731,7 +711,7 @@ func TestBoxcutter_Apply(t *testing.T) { { name: "error from GenerateRevision", mockBuilder: &mockBundleRevisionBuilder{ - makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1.ClusterExtensionRevision, error) { + makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) { return nil, errors.New("render boom") }, }, @@ -747,16 +727,13 @@ func TestBoxcutter_Apply(t *testing.T) { { name: "keep at most 5 past revisions", mockBuilder: &mockBundleRevisionBuilder{ - makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1.ClusterExtensionRevision, error) { - return &ocv1.ClusterExtensionRevision{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: revisionAnnotations, - Labels: map[string]string{ - labels.OwnerNameKey: ext.Name, - }, - }, - Spec: ocv1.ClusterExtensionRevisionSpec{}, - }, nil + makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) { + return ocv1ac.ClusterExtensionRevision(""). + WithAnnotations(revisionAnnotations). + WithLabels(map[string]string{ + labels.OwnerNameKey: ext.Name, + }). + WithSpec(ocv1ac.ClusterExtensionRevisionSpec()), nil }, }, existingObjs: []client.Object{ @@ -851,16 +828,13 @@ func TestBoxcutter_Apply(t *testing.T) { { name: "keep active revisions when they are out of limit", mockBuilder: &mockBundleRevisionBuilder{ - makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1.ClusterExtensionRevision, error) { - return &ocv1.ClusterExtensionRevision{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: revisionAnnotations, - Labels: map[string]string{ - labels.OwnerNameKey: ext.Name, - }, - }, - Spec: ocv1.ClusterExtensionRevisionSpec{}, - }, nil + makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) { + return ocv1ac.ClusterExtensionRevision(""). + WithAnnotations(revisionAnnotations). + WithLabels(map[string]string{ + labels.OwnerNameKey: ext.Name, + }). + WithSpec(ocv1ac.ClusterExtensionRevisionSpec()), nil }, }, existingObjs: []client.Object{ @@ -971,21 +945,19 @@ func TestBoxcutter_Apply(t *testing.T) { { name: "annotation-only update (same phases, different annotations)", mockBuilder: &mockBundleRevisionBuilder{ - makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1.ClusterExtensionRevision, error) { - return &ocv1.ClusterExtensionRevision{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: revisionAnnotations, - Labels: map[string]string{ - labels.OwnerNameKey: ext.Name, - }, - }, - Spec: ocv1.ClusterExtensionRevisionSpec{ - Phases: []ocv1.ClusterExtensionRevisionPhase{ - { - Name: string(applier.PhaseDeploy), - Objects: []ocv1.ClusterExtensionRevisionObject{ - { - Object: unstructured.Unstructured{ + makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) { + return ocv1ac.ClusterExtensionRevision(""). + WithAnnotations(revisionAnnotations). + WithLabels(map[string]string{ + labels.OwnerNameKey: ext.Name, + }). + WithSpec(ocv1ac.ClusterExtensionRevisionSpec(). + WithPhases( + ocv1ac.ClusterExtensionRevisionPhase(). + WithName(string(applier.PhaseDeploy)). + WithObjects( + ocv1ac.ClusterExtensionRevisionObject(). + WithObject(unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -993,13 +965,10 @@ func TestBoxcutter_Apply(t *testing.T) { "name": "test-cm", }, }, - }, - }, - }, - }, - }, - }, - }, nil + }), + ), + ), + ), nil }, }, existingObjs: []client.Object{ @@ -1131,15 +1100,15 @@ func Test_PreAuthorizer_Integration(t *testing.T) { } fakeClient := fake.NewClientBuilder().WithScheme(testScheme).Build() dummyGenerator := &mockBundleRevisionBuilder{ - makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotation map[string]string) (*ocv1.ClusterExtensionRevision, error) { - return &ocv1.ClusterExtensionRevision{ - Spec: ocv1.ClusterExtensionRevisionSpec{ - Phases: []ocv1.ClusterExtensionRevisionPhase{ - { - Name: "some-phase", - Objects: []ocv1.ClusterExtensionRevisionObject{ - { - Object: unstructured.Unstructured{ + makeRevisionFunc: func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotation map[string]string) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) { + return ocv1ac.ClusterExtensionRevision(""). + WithSpec(ocv1ac.ClusterExtensionRevisionSpec(). + WithPhases( + ocv1ac.ClusterExtensionRevisionPhase(). + WithName("some-phase"). + WithObjects( + ocv1ac.ClusterExtensionRevisionObject(). + WithObject(unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -1147,13 +1116,10 @@ func Test_PreAuthorizer_Integration(t *testing.T) { "test-data": "test-data", }, }, - }, - }, - }, - }, - }, - }, - }, nil + }), + ), + ), + ), nil }, } dummyBundleFs := fstest.MapFS{} @@ -1316,6 +1282,7 @@ func TestBoxcutterStorageMigrator(t *testing.T) { ActionClientGetter: mag, Client: client, Scheme: testScheme, + FieldOwner: "test-owner", } ext := &ocv1.ClusterExtension{ @@ -1326,16 +1293,12 @@ func TestBoxcutterStorageMigrator(t *testing.T) { On("List", mock.Anything, mock.AnythingOfType("*v1.ClusterExtensionRevisionList"), mock.Anything). Return(nil) client. - On("Create", mock.Anything, mock.AnythingOfType("*v1.ClusterExtensionRevision"), mock.Anything). + On("Apply", mock.Anything, mock.AnythingOfType("*v1.ClusterExtensionRevisionApplyConfiguration"), mock.Anything). Once(). Run(func(args mock.Arguments) { - // Verify the migration marker label is set before creation - rev := args.Get(1).(*ocv1.ClusterExtensionRevision) + // Verify the migration marker label is set before apply + rev := args.Get(1).(*ocv1ac.ClusterExtensionRevisionApplyConfiguration) require.Equal(t, "true", rev.Labels[labels.MigratedFromHelmKey], "Migration marker label should be set") - - // Simulate real Kubernetes behavior: Create() populates server-managed fields - rev.Generation = 1 - rev.ResourceVersion = "1" }). Return(nil) client. @@ -1344,8 +1307,12 @@ func TestBoxcutterStorageMigrator(t *testing.T) { Run(func(args mock.Arguments) { // Simulate Get() returning the created revision with server-managed fields rev := args.Get(2).(*ocv1.ClusterExtensionRevision) + rev.Name = "test-revision" rev.Generation = 1 rev.ResourceVersion = "1" + rev.Labels = map[string]string{ + labels.MigratedFromHelmKey: "true", + } }). Return(nil) @@ -1382,6 +1349,7 @@ func TestBoxcutterStorageMigrator(t *testing.T) { ActionClientGetter: mag, Client: client, Scheme: testScheme, + FieldOwner: "test-owner", } ext := &ocv1.ClusterExtension{ @@ -1436,6 +1404,7 @@ func TestBoxcutterStorageMigrator(t *testing.T) { ActionClientGetter: mag, Client: client, Scheme: testScheme, + FieldOwner: "test-owner", } ext := &ocv1.ClusterExtension{ @@ -1503,6 +1472,7 @@ func TestBoxcutterStorageMigrator(t *testing.T) { ActionClientGetter: mag, Client: client, Scheme: testScheme, + FieldOwner: "test-owner", } ext := &ocv1.ClusterExtension{ @@ -1580,6 +1550,7 @@ func TestBoxcutterStorageMigrator(t *testing.T) { ActionClientGetter: mag, Client: client, Scheme: testScheme, + FieldOwner: "test-owner", } ext := &ocv1.ClusterExtension{ @@ -1662,6 +1633,7 @@ func TestBoxcutterStorageMigrator(t *testing.T) { ActionClientGetter: mag, Client: client, Scheme: testScheme, + FieldOwner: "test-owner", } ext := &ocv1.ClusterExtension{ @@ -1673,16 +1645,12 @@ func TestBoxcutterStorageMigrator(t *testing.T) { Return(nil) client. - On("Create", mock.Anything, mock.AnythingOfType("*v1.ClusterExtensionRevision"), mock.Anything). + On("Apply", mock.Anything, mock.AnythingOfType("*v1.ClusterExtensionRevisionApplyConfiguration"), mock.Anything). Once(). Run(func(args mock.Arguments) { - // Verify the migration marker label is set before creation - rev := args.Get(1).(*ocv1.ClusterExtensionRevision) + // Verify the migration marker label is set before apply + rev := args.Get(1).(*ocv1ac.ClusterExtensionRevisionApplyConfiguration) require.Equal(t, "true", rev.Labels[labels.MigratedFromHelmKey], "Migration marker label should be set") - - // Simulate real Kubernetes behavior: Create() populates server-managed fields - rev.Generation = 1 - rev.ResourceVersion = "1" }). Return(nil) @@ -1751,6 +1719,7 @@ func TestBoxcutterStorageMigrator(t *testing.T) { ActionClientGetter: mag, Client: client, Scheme: testScheme, + FieldOwner: "test-owner", } ext := &ocv1.ClusterExtension{ @@ -1783,6 +1752,7 @@ func TestBoxcutterStorageMigrator(t *testing.T) { ActionClientGetter: mag, Client: client, Scheme: testScheme, + FieldOwner: "test-owner", } ext := &ocv1.ClusterExtension{ @@ -1802,12 +1772,12 @@ func TestBoxcutterStorageMigrator(t *testing.T) { // mockBundleRevisionBuilder is a mock implementation of the ClusterExtensionRevisionGenerator for testing. type mockBundleRevisionBuilder struct { - makeRevisionFunc func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotation map[string]string) (*ocv1.ClusterExtensionRevision, error) + makeRevisionFunc func(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotation map[string]string) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) generateRevisionFromHelmReleaseCalled bool helmReleaseUsed *release.Release } -func (m *mockBundleRevisionBuilder) GenerateRevision(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1.ClusterExtensionRevision, error) { +func (m *mockBundleRevisionBuilder) GenerateRevision(ctx context.Context, bundleFS fs.FS, ext *ocv1.ClusterExtension, objectLabels, revisionAnnotations map[string]string) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) { return m.makeRevisionFunc(ctx, bundleFS, ext, objectLabels, revisionAnnotations) } @@ -1815,18 +1785,14 @@ func (m *mockBundleRevisionBuilder) GenerateRevisionFromHelmRelease( ctx context.Context, helmRelease *release.Release, ext *ocv1.ClusterExtension, objectLabels map[string]string, -) (*ocv1.ClusterExtensionRevision, error) { +) (*ocv1ac.ClusterExtensionRevisionApplyConfiguration, error) { m.generateRevisionFromHelmReleaseCalled = true m.helmReleaseUsed = helmRelease - return &ocv1.ClusterExtensionRevision{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-revision", - Labels: map[string]string{ - labels.OwnerNameKey: ext.Name, - }, - }, - Spec: ocv1.ClusterExtensionRevisionSpec{}, - }, nil + return ocv1ac.ClusterExtensionRevision("test-revision"). + WithLabels(map[string]string{ + labels.OwnerNameKey: ext.Name, + }). + WithSpec(ocv1ac.ClusterExtensionRevisionSpec()), nil } type clientMock struct { @@ -1844,7 +1810,7 @@ func (m *clientMock) Get(ctx context.Context, key client.ObjectKey, obj client.O return args.Error(0) } -func (m *clientMock) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error { +func (m *clientMock) Apply(ctx context.Context, obj runtime.ApplyConfiguration, opts ...client.ApplyOption) error { args := m.Called(ctx, obj, opts) return args.Error(0) } diff --git a/internal/operator-controller/applier/phase.go b/internal/operator-controller/applier/phase.go index 5f6957506..fe92cd0dc 100644 --- a/internal/operator-controller/applier/phase.go +++ b/internal/operator-controller/applier/phase.go @@ -6,7 +6,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" - ocv1 "github.com/operator-framework/operator-controller/api/v1" + ocv1ac "github.com/operator-framework/operator-controller/applyconfigurations/api/v1" ) // The following, with modifications, is taken from: @@ -123,7 +123,7 @@ func init() { // to ensure consistent ordering regardless of input order. This is critical for // Helm-to-Boxcutter migration where the same resources may come from different sources // (Helm release manifest vs bundle manifest) and need to produce identical phases. -func compareClusterExtensionRevisionObjects(a, b ocv1.ClusterExtensionRevisionObject) int { +func compareClusterExtensionRevisionObjects(a, b ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration) int { aGVK := a.Object.GroupVersionKind() bGVK := b.Object.GroupVersionKind() @@ -139,9 +139,9 @@ func compareClusterExtensionRevisionObjects(a, b ocv1.ClusterExtensionRevisionOb // PhaseSort takes an unsorted list of objects and organizes them into sorted phases. // Each phase will be applied in order according to DefaultPhaseOrder. Objects // within a single phase are applied simultaneously. -func PhaseSort(unsortedObjs []ocv1.ClusterExtensionRevisionObject) []ocv1.ClusterExtensionRevisionPhase { - phasesSorted := make([]ocv1.ClusterExtensionRevisionPhase, 0) - phaseMap := make(map[Phase][]ocv1.ClusterExtensionRevisionObject, 0) +func PhaseSort(unsortedObjs []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration) []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration { + phasesSorted := make([]*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration, 0) + phaseMap := make(map[Phase][]ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration) for _, obj := range unsortedObjs { phase := determinePhase(obj.Object.GroupVersionKind().GroupKind()) @@ -153,10 +153,14 @@ func PhaseSort(unsortedObjs []ocv1.ClusterExtensionRevisionObject) []ocv1.Cluste // Sort objects within the phase deterministically slices.SortFunc(objs, compareClusterExtensionRevisionObjects) - phasesSorted = append(phasesSorted, ocv1.ClusterExtensionRevisionPhase{ - Name: string(phaseName), - Objects: objs, - }) + // Convert to pointers for WithObjects + objPtrs := make([]*ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration, len(objs)) + for i := range objs { + objPtrs[i] = &objs[i] + } + phasesSorted = append(phasesSorted, ocv1ac.ClusterExtensionRevisionPhase(). + WithName(string(phaseName)). + WithObjects(objPtrs...)) } } diff --git a/internal/operator-controller/applier/phase_test.go b/internal/operator-controller/applier/phase_test.go index 7ca493648..44c5e2555 100644 --- a/internal/operator-controller/applier/phase_test.go +++ b/internal/operator-controller/applier/phase_test.go @@ -5,22 +5,23 @@ import ( "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/utils/ptr" - v1 "github.com/operator-framework/operator-controller/api/v1" + ocv1ac "github.com/operator-framework/operator-controller/applyconfigurations/api/v1" "github.com/operator-framework/operator-controller/internal/operator-controller/applier" ) func Test_PhaseSort(t *testing.T) { for _, tt := range []struct { name string - objs []v1.ClusterExtensionRevisionObject - want []v1.ClusterExtensionRevisionPhase + objs []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration + want []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration }{ { name: "single deploy obj", - objs: []v1.ClusterExtensionRevisionObject{ + objs: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -28,12 +29,12 @@ func Test_PhaseSort(t *testing.T) { }, }, }, - want: []v1.ClusterExtensionRevisionPhase{ + want: []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration{ { - Name: string(applier.PhaseDeploy), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseDeploy)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -46,9 +47,9 @@ func Test_PhaseSort(t *testing.T) { }, { name: "all phases", - objs: []v1.ClusterExtensionRevisionObject{ + objs: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apiregistration.k8s.io/v1", "kind": "APIService", @@ -56,7 +57,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -64,7 +65,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Namespace", @@ -72,7 +73,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "some.api/v1", "kind": "SomeCustomResource", @@ -80,7 +81,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "ClusterRole", @@ -88,7 +89,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "ClusterRoleBinding", @@ -96,7 +97,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "RoleBinding", @@ -104,7 +105,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "Role", @@ -112,7 +113,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "PersistentVolume", @@ -120,7 +121,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "networking.k8s.io/v1", "kind": "NetworkPolicy", @@ -128,7 +129,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apiextensions.k8s.io/v1", "kind": "CustomResourceDefinition", @@ -136,12 +137,12 @@ func Test_PhaseSort(t *testing.T) { }, }, }, - want: []v1.ClusterExtensionRevisionPhase{ + want: []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration{ { - Name: string(applier.PhaseNamespaces), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseNamespaces)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Namespace", @@ -151,10 +152,10 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Name: string(applier.PhasePolicies), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhasePolicies)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "networking.k8s.io/v1", "kind": "NetworkPolicy", @@ -164,10 +165,10 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Name: string(applier.PhaseRBAC), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseRBAC)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "ClusterRole", @@ -175,7 +176,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "Role", @@ -185,10 +186,10 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Name: string(applier.PhaseRBACBindings), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseRBACBindings)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "ClusterRoleBinding", @@ -196,7 +197,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "RoleBinding", @@ -206,10 +207,10 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Name: string(applier.PhaseCRDs), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseCRDs)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apiextensions.k8s.io/v1", "kind": "CustomResourceDefinition", @@ -219,10 +220,10 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Name: string(applier.PhaseStorage), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseStorage)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "PersistentVolume", @@ -232,10 +233,10 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Name: string(applier.PhaseDeploy), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseDeploy)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -243,7 +244,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "some.api/v1", "kind": "SomeCustomResource", @@ -253,10 +254,10 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Name: string(applier.PhasePublish), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhasePublish)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apiregistration.k8s.io/v1", "kind": "APIService", @@ -269,9 +270,9 @@ func Test_PhaseSort(t *testing.T) { }, { name: "sorted and batched", - objs: []v1.ClusterExtensionRevisionObject{ + objs: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -279,7 +280,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -287,7 +288,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ServiceAccount", @@ -295,12 +296,12 @@ func Test_PhaseSort(t *testing.T) { }, }, }, - want: []v1.ClusterExtensionRevisionPhase{ + want: []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration{ { - Name: string(applier.PhaseRBAC), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseRBAC)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ServiceAccount", @@ -310,10 +311,10 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Name: string(applier.PhaseDeploy), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseDeploy)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -321,7 +322,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -334,14 +335,14 @@ func Test_PhaseSort(t *testing.T) { }, { name: "no objects", - objs: []v1.ClusterExtensionRevisionObject{}, - want: []v1.ClusterExtensionRevisionPhase{}, + objs: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{}, + want: []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration{}, }, { name: "sort by group within same phase", - objs: []v1.ClusterExtensionRevisionObject{ + objs: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -352,7 +353,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -363,12 +364,12 @@ func Test_PhaseSort(t *testing.T) { }, }, }, - want: []v1.ClusterExtensionRevisionPhase{ + want: []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration{ { - Name: string(applier.PhaseDeploy), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseDeploy)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -379,7 +380,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -395,9 +396,9 @@ func Test_PhaseSort(t *testing.T) { }, { name: "sort by version within same group and phase", - objs: []v1.ClusterExtensionRevisionObject{ + objs: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "batch/v1", "kind": "Job", @@ -408,7 +409,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "batch/v1beta1", "kind": "CronJob", @@ -419,12 +420,12 @@ func Test_PhaseSort(t *testing.T) { }, }, }, - want: []v1.ClusterExtensionRevisionPhase{ + want: []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration{ { - Name: string(applier.PhaseDeploy), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseDeploy)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "batch/v1", "kind": "Job", @@ -435,7 +436,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "batch/v1beta1", "kind": "CronJob", @@ -451,9 +452,9 @@ func Test_PhaseSort(t *testing.T) { }, { name: "sort by kind within same group, version, and phase", - objs: []v1.ClusterExtensionRevisionObject{ + objs: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Service", @@ -464,7 +465,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -475,7 +476,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -486,12 +487,12 @@ func Test_PhaseSort(t *testing.T) { }, }, }, - want: []v1.ClusterExtensionRevisionPhase{ + want: []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration{ { - Name: string(applier.PhaseDeploy), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseDeploy)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -502,7 +503,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -513,7 +514,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Service", @@ -529,9 +530,9 @@ func Test_PhaseSort(t *testing.T) { }, { name: "sort by namespace within same GVK and phase", - objs: []v1.ClusterExtensionRevisionObject{ + objs: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -543,7 +544,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -555,7 +556,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -567,12 +568,12 @@ func Test_PhaseSort(t *testing.T) { }, }, }, - want: []v1.ClusterExtensionRevisionPhase{ + want: []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration{ { - Name: string(applier.PhaseDeploy), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseDeploy)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -584,7 +585,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -596,7 +597,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -613,9 +614,9 @@ func Test_PhaseSort(t *testing.T) { }, { name: "sort by name within same GVK, namespace, and phase", - objs: []v1.ClusterExtensionRevisionObject{ + objs: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -627,7 +628,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -639,7 +640,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -651,12 +652,12 @@ func Test_PhaseSort(t *testing.T) { }, }, }, - want: []v1.ClusterExtensionRevisionPhase{ + want: []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration{ { - Name: string(applier.PhaseDeploy), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseDeploy)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -668,7 +669,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -680,7 +681,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -697,9 +698,9 @@ func Test_PhaseSort(t *testing.T) { }, { name: "comprehensive sorting - all dimensions", - objs: []v1.ClusterExtensionRevisionObject{ + objs: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -711,7 +712,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -723,7 +724,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -735,7 +736,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -747,7 +748,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -759,7 +760,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -771,12 +772,12 @@ func Test_PhaseSort(t *testing.T) { }, }, }, - want: []v1.ClusterExtensionRevisionPhase{ + want: []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration{ { - Name: string(applier.PhaseDeploy), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseDeploy)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -788,7 +789,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "ConfigMap", @@ -800,7 +801,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -812,7 +813,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", "kind": "Secret", @@ -824,7 +825,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -836,7 +837,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "apps/v1", "kind": "Deployment", @@ -853,9 +854,9 @@ func Test_PhaseSort(t *testing.T) { }, { name: "cluster-scoped vs namespaced resources - empty namespace sorts first", - objs: []v1.ClusterExtensionRevisionObject{ + objs: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "ClusterRole", @@ -866,7 +867,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "ClusterRole", @@ -877,7 +878,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "Role", @@ -889,12 +890,12 @@ func Test_PhaseSort(t *testing.T) { }, }, }, - want: []v1.ClusterExtensionRevisionPhase{ + want: []*ocv1ac.ClusterExtensionRevisionPhaseApplyConfiguration{ { - Name: string(applier.PhaseRBAC), - Objects: []v1.ClusterExtensionRevisionObject{ + Name: ptr.To(string(applier.PhaseRBAC)), + Objects: []ocv1ac.ClusterExtensionRevisionObjectApplyConfiguration{ { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "ClusterRole", @@ -905,7 +906,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "ClusterRole", @@ -916,7 +917,7 @@ func Test_PhaseSort(t *testing.T) { }, }, { - Object: unstructured.Unstructured{ + Object: &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "rbac.authorization.k8s.io/v1", "kind": "Role",