diff --git a/api/core/v1alpha1/clustercatalog_types.go b/api/core/v1alpha1/clustercatalog_types.go index 5944bcb5..d70fcac3 100644 --- a/api/core/v1alpha1/clustercatalog_types.go +++ b/api/core/v1alpha1/clustercatalog_types.go @@ -119,15 +119,18 @@ type ClusterCatalogSpec struct { // A ClusterCatalog's priority is used by clients as a tie-breaker between ClusterCatalogs that meet the client's requirements. // It is up to clients to decide how to handle scenarios where multiple ClusterCatalogs with the same priority meet // For example, in the case where multiple ClusterCatalogs provide the same bundle. - // A higher number means higher priority. Negative numbers are also accepted. + // A higher number means higher priority. // - // When omitted, the default priority is 0. + // When omitted, the default priority is 0 because that is the zero value of integers. + // + // Negative numbers can be used to specify a priority lower than the default. + // Positive numbers can be used to specify a priority higher than the default. // // +kubebuilder:default:=0 // +optional Priority int32 `json:"priority"` - // availabilityMode allows users to define the of the ClusterCatalog. + // availabilityMode allows users to define how the ClusterCatalog is made available to clients on the cluster. // availabilityMode is optional. // // Allowed values are "Available" and "Unavailable" and omitted. @@ -138,8 +141,7 @@ type ClusterCatalogSpec struct { // Setting the availabilityMode to "Available" tells clients that they should consider this ClusterCatalog // and its contents as usable. // - // When set to "Unavailable", the catalog contents will no longer be served over the catalog content HTTP server and - // all the content will no longer cached. + // When set to "Unavailable", the catalog contents will no longer be served over the catalog content HTTP server. // When set to this availabilityMode it should be interpreted the same as the ClusterCatalog not existing. // Setting the availabilityMode to "Unavailable" can be useful in scenarios where a user may not want // to delete the ClusterCatalog all together, but would still like it to be treated as if it doesn't exist. @@ -192,7 +194,7 @@ type ClusterCatalogStatus struct { // ClusterCatalogURLs contains the URLs that can be used to access the catalog. // +kubebuilder:validation:XValidation:rule="isURL(self.base)",message="base must be a valid URL" -// +kubebuilder:validation:XValidation:rule="url(self.base).getScheme() == \"http\" || url(self.base).getScheme == \"https\"",message="scheme must be one of [http, https]" +// +kubebuilder:validation:XValidation:rule="url(self.base).getScheme() == \"http\" || url(self.base).getScheme == \"https\"",message="base is invalid, scheme must be one of [http, https]" type ClusterCatalogURLs struct { // base is a cluster-internal URL that provides REST API endpoints for // accessing the content of the catalog. @@ -262,10 +264,10 @@ type ResolvedCatalogSource struct { // ResolvedImageSource provides information about the resolved source of a Catalog sourced from an image. // +kubebuilder:validation:XValidation:rule="self.ref.matches('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])((\\\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?\\\\b')",message="ref is invalid, it must start with a valid domain" // +kubebuilder:validation:XValidation:rule="self.ref.find('(\\\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)') != \"\"",message="ref is invalid, a valid name is required" -// +kubebuilder:validation:XValidation:rule="self.ref.matches('(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:][0-9A-Fa-f]{32,})')",message="digest is invalid" +// +kubebuilder:validation:XValidation:rule="self.ref.matches('(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:][0-9A-Fa-f]{32,})')",message="ref is invalid, digest is invalid" type ResolvedImageSource struct { - // ref contains the resolved image reference for the catalog in the sha256 digest format. - // The sha256 digest format is used so users can use other tooling to fetch the exact + // ref contains the resolved image digest-based reference. + // The digest format is used so users can use other tooling to fetch the exact // OCI manifests that were used to extract the catalog contents. // +kubebuilder:validation:Required // +kubebuilder:validation:MaxLength:1000 @@ -273,11 +275,11 @@ type ResolvedImageSource struct { } // ImageSource enables users to define the information required for sourcing a Catalog from an OCI image -// +kubebuilder:validation:XValidation:rule="!has(self.pollIntervalMinutes) || (self.ref.contains('@'))",message="cannot specify PollIntervalMinutes while using digest-based image" +// +kubebuilder:validation:XValidation:rule="!has(self.pollIntervalMinutes) || (self.ref.contains('@'))",message="cannot specify pollIntervalMinutes while using digest-based image" // +kubebuilder:validation:XValidation:rule="self.ref.matches('^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])((\\\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(:[0-9]+)?\\\\b')",message="ref is invalid, it must start with a valid domain" // +kubebuilder:validation:XValidation:rule="self.ref.find('(\\\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)') != \"\"",message="ref is invalid, a valid name is required" // +kubebuilder:validation:XValidation:rule="self.ref.contains('@') || self.ref.find(':[\\\\w][\\\\w.-]{0,127}$') != \"\"",message="ref is invalid, must end with a digest or a tag" -// +kubebuilder:validation:XValidation:rule="self.ref.contains('@') ? self.ref.matches('(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:][0-9A-Fa-f]{32,})') : self.ref.substring(self.ref.lastIndexOf(\":\")+1).matches('[\\\\w][\\\\w.-]{0,127}')",message="tag or digest is invalid" +// +kubebuilder:validation:XValidation:rule="self.ref.contains('@') ? self.ref.matches('(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:][0-9A-Fa-f]{32,})') : self.ref.substring(self.ref.lastIndexOf(\":\")+1).matches('[\\\\w][\\\\w.-]{0,127}')",message="ref is invalid, tag or digest is invalid" type ImageSource struct { // ref allows users to define the reference to a container image containing Catalog contents. // ref is required. diff --git a/config/base/crd/bases/olm.operatorframework.io_clustercatalogs.yaml b/config/base/crd/bases/olm.operatorframework.io_clustercatalogs.yaml index a1020cb2..3a7b3d21 100644 --- a/config/base/crd/bases/olm.operatorframework.io_clustercatalogs.yaml +++ b/config/base/crd/bases/olm.operatorframework.io_clustercatalogs.yaml @@ -56,7 +56,7 @@ spec: availabilityMode: default: Available description: |- - availabilityMode allows users to define the of the ClusterCatalog. + availabilityMode allows users to define how the ClusterCatalog is made available to clients on the cluster. availabilityMode is optional. Allowed values are "Available" and "Unavailable" and omitted. @@ -67,8 +67,7 @@ spec: Setting the availabilityMode to "Available" tells clients that they should consider this ClusterCatalog and its contents as usable. - When set to "Unavailable", the catalog contents will no longer be served over the catalog content HTTP server and - all the content will no longer cached. + When set to "Unavailable", the catalog contents will no longer be served over the catalog content HTTP server. When set to this availabilityMode it should be interpreted the same as the ClusterCatalog not existing. Setting the availabilityMode to "Unavailable" can be useful in scenarios where a user may not want to delete the ClusterCatalog all together, but would still like it to be treated as if it doesn't exist. @@ -85,9 +84,12 @@ spec: A ClusterCatalog's priority is used by clients as a tie-breaker between ClusterCatalogs that meet the client's requirements. It is up to clients to decide how to handle scenarios where multiple ClusterCatalogs with the same priority meet For example, in the case where multiple ClusterCatalogs provide the same bundle. - A higher number means higher priority. Negative numbers are also accepted. + A higher number means higher priority. - When omitted, the default priority is 0. + When omitted, the default priority is 0 because that is the zero value of integers. + + Negative numbers can be used to specify a priority lower than the default. + Positive numbers can be used to specify a priority higher than the default. format: int32 type: integer source: @@ -164,7 +166,7 @@ spec: - ref type: object x-kubernetes-validations: - - message: cannot specify PollIntervalMinutes while using digest-based + - message: cannot specify pollIntervalMinutes while using digest-based image rule: '!has(self.pollIntervalMinutes) || (self.ref.contains(''@''))' - message: ref is invalid, it must start with a valid domain @@ -175,7 +177,7 @@ spec: - message: ref is invalid, must end with a digest or a tag rule: self.ref.contains('@') || self.ref.find(':[\\w][\\w.-]{0,127}$') != "" - - message: tag or digest is invalid + - message: ref is invalid, tag or digest is invalid rule: 'self.ref.contains(''@'') ? self.ref.matches(''(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:][0-9A-Fa-f]{32,})'') : self.ref.substring(self.ref.lastIndexOf(":")+1).matches(''[\\w][\\w.-]{0,127}'')' type: @@ -306,8 +308,8 @@ spec: properties: ref: description: |- - ref contains the resolved image reference for the catalog in the sha256 digest format. - The sha256 digest format is used so users can use other tooling to fetch the exact + ref contains the resolved image digest-based reference. + The digest format is used so users can use other tooling to fetch the exact OCI manifests that were used to extract the catalog contents. type: string required: @@ -319,7 +321,7 @@ spec: - message: ref is invalid, a valid name is required rule: self.ref.find('(\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)') != "" - - message: digest is invalid + - message: ref is invalid, digest is invalid rule: self.ref.matches('(@[A-Za-z][A-Za-z0-9]*([-_+.][A-Za-z][A-Za-z0-9]*)*[:][0-9A-Fa-f]{32,})') type: description: |- @@ -369,7 +371,7 @@ spec: x-kubernetes-validations: - message: base must be a valid URL rule: isURL(self.base) - - message: scheme must be one of [http, https] + - message: base is invalid, scheme must be one of [http, https] rule: url(self.base).getScheme() == "http" || url(self.base).getScheme == "https" type: object