diff --git a/api/v1/clustercatalog_types.go b/api/v1/clustercatalog_types.go index fbd9a2dce5..7afe631db4 100644 --- a/api/v1/clustercatalog_types.go +++ b/api/v1/clustercatalog_types.go @@ -62,7 +62,7 @@ type ClusterCatalog struct { // 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. - // +kubebuilder:validation:Required + // +required Spec ClusterCatalogSpec `json:"spec"` // status contains the following information about the state of the ClusterCatalog: @@ -85,7 +85,7 @@ type ClusterCatalogList struct { // items is a list of ClusterCatalogs. // items is required. - // +kubebuilder:validation:Required + // +required Items []ClusterCatalog `json:"items"` } @@ -105,7 +105,7 @@ type ClusterCatalogSpec struct { // image: // ref: quay.io/operatorhubio/catalog:latest // - // +kubebuilder:validation:Required + // +required Source CatalogSource `json:"source"` // priority is an optional field that defines a priority for this ClusterCatalog. @@ -199,7 +199,7 @@ type ClusterCatalogURLs struct { // // New endpoints may be added as needs evolve. // - // +kubebuilder:validation:Required + // +required // +kubebuilder:validation:MaxLength:=525 // +kubebuilder:validation:XValidation:rule="isURL(self)",message="must be a valid URL" // +kubebuilder:validation:XValidation:rule="isURL(self) ? (url(self).getScheme() == \"http\" || url(self).getScheme() == \"https\") : true",message="scheme must be either http or https" @@ -220,7 +220,7 @@ type CatalogSource struct { // // +unionDiscriminator // +kubebuilder:validation:Enum:="Image" - // +kubebuilder:validation:Required + // +required Type SourceType `json:"type"` // image configures how catalog contents are sourced from an OCI image. // It is required when type is Image, and forbidden otherwise. @@ -241,7 +241,7 @@ type ResolvedCatalogSource struct { // // +unionDiscriminator // +kubebuilder:validation:Enum:="Image" - // +kubebuilder:validation:Required + // +required Type SourceType `json:"type"` // image contains resolution information for a catalog sourced from an image. // It must be set when type is Image, and forbidden otherwise. @@ -253,7 +253,7 @@ type ResolvedImageSource 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. - // +kubebuilder:validation:Required + // +required // +kubebuilder:validation:MaxLength:=1000 // +kubebuilder:validation:XValidation:rule="self.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="must start with a valid domain. valid domains must be alphanumeric characters (lowercase and uppercase) separated by the \".\" character." // +kubebuilder:validation:XValidation:rule="self.find('(\\\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)') != \"\"",message="a valid name is required. valid names must contain lowercase alphanumeric characters separated only by the \".\", \"_\", \"__\", \"-\" characters." @@ -307,7 +307,7 @@ type ImageSource struct { // 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" // - // +kubebuilder:validation:Required + // +required // +kubebuilder:validation:MaxLength:=1000 // +kubebuilder:validation:XValidation:rule="self.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="must start with a valid domain. valid domains must be alphanumeric characters (lowercase and uppercase) separated by the \".\" character." // +kubebuilder:validation:XValidation:rule="self.find('(\\\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?((\\\\/[a-z0-9]+((([._]|__|[-]*)[a-z0-9]+)+)?)+)?)') != \"\"",message="a valid name is required. valid names must contain lowercase alphanumeric characters separated only by the \".\", \"_\", \"__\", \"-\" characters." diff --git a/api/v1/clusterextension_types.go b/api/v1/clusterextension_types.go index f9a25bc77a..7b0a39ef12 100644 --- a/api/v1/clusterextension_types.go +++ b/api/v1/clusterextension_types.go @@ -63,7 +63,7 @@ type ClusterExtensionSpec struct { // +kubebuilder:validation:MaxLength:=63 // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="namespace is immutable" // +kubebuilder:validation:XValidation:rule="self.matches(\"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\")",message="namespace must be a valid DNS1123 label" - // +kubebuilder:validation:Required + // +required Namespace string `json:"namespace"` // serviceAccount specifies a ServiceAccount used to perform all interactions with the cluster @@ -72,7 +72,7 @@ type ClusterExtensionSpec struct { // The ServiceAccount must exist in the namespace referenced in the spec. // The serviceAccount field is required. // - // +kubebuilder:validation:Required + // +required ServiceAccount ServiceAccountReference `json:"serviceAccount"` // source is required and selects the installation source of content for this ClusterExtension. @@ -88,7 +88,7 @@ type ClusterExtensionSpec struct { // catalog: // packageName: example-package // - // +kubebuilder:validation:Required + // +required Source SourceConfig `json:"source"` // install is optional and configures installation options for the ClusterExtension, @@ -137,7 +137,7 @@ type SourceConfig struct { // // +unionDiscriminator // +kubebuilder:validation:Enum:="Catalog" - // +kubebuilder:validation:Required + // +required SourceType string `json:"sourceType"` // catalog configures how information is sourced from a catalog. @@ -177,7 +177,7 @@ type ClusterExtensionConfig struct { // // +unionDiscriminator // +kubebuilder:validation:Enum:="Inline" - // +kubebuilder:validation:Required + // +required ConfigType ClusterExtensionConfigType `json:"configType"` // inline contains JSON or YAML values specified directly in the ClusterExtension. @@ -220,7 +220,7 @@ type CatalogFilter struct { // +kubebuilder:validation:MaxLength:=253 // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="packageName is immutable" // +kubebuilder:validation:XValidation:rule="self.matches(\"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\")",message="packageName must be a valid DNS1123 subdomain. It must contain only lowercase alphanumeric characters, hyphens (-) or periods (.), start and end with an alphanumeric character, and be no longer than 253 characters" - // +kubebuilder:validation:Required + // +required PackageName string `json:"packageName"` // version is an optional semver constraint (a specific version or range of versions). @@ -403,7 +403,7 @@ type ServiceAccountReference struct { // +kubebuilder:validation:MaxLength:=253 // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="name is immutable" // +kubebuilder:validation:XValidation:rule="self.matches(\"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\")",message="name must be a valid DNS1123 subdomain. It must contain only lowercase alphanumeric characters, hyphens (-) or periods (.), start and end with an alphanumeric character, and be no longer than 253 characters" - // +kubebuilder:validation:Required + // +required Name string `json:"name"` } @@ -431,7 +431,7 @@ type CRDUpgradeSafetyPreflightConfig struct { // When set to "Strict", the CRD Upgrade Safety pre-flight check runs during an upgrade operation. // // +kubebuilder:validation:Enum:="None";"Strict" - // +kubebuilder:validation:Required + // +required Enforcement CRDUpgradeSafetyEnforcement `json:"enforcement"` } @@ -455,14 +455,14 @@ type BundleMetadata struct { // It must contain only lowercase alphanumeric characters, hyphens (-) or periods (.), // start and end with an alphanumeric character, and be no longer than 253 characters. // - // +kubebuilder:validation:Required + // +required // +kubebuilder:validation:XValidation:rule="self.matches(\"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\")",message="packageName must be a valid DNS1123 subdomain. 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"` // version is required and references the version that this bundle represents. // It follows the semantic versioning standard as defined in https://semver.org/. // - // +kubebuilder:validation:Required + // +required // +kubebuilder:validation:XValidation:rule="self.matches(\"^([0-9]+)(\\\\.[0-9]+)?(\\\\.[0-9]+)?(-([-0-9A-Za-z]+(\\\\.[-0-9A-Za-z]+)*))?(\\\\+([-0-9A-Za-z]+(-\\\\.[-0-9A-Za-z]+)*))?\")",message="version must be well-formed semver" Version string `json:"version"` } @@ -533,7 +533,7 @@ type ClusterExtensionInstallStatus struct { // A "bundle" is a versioned set of content that represents the resources that need to be applied // to a cluster to install a package. // - // +kubebuilder:validation:Required + // +required Bundle BundleMetadata `json:"bundle"` } @@ -575,7 +575,7 @@ type ClusterExtensionList struct { // items is a required list of ClusterExtension objects. // - // +kubebuilder:validation:Required + // +required Items []ClusterExtension `json:"items"` } diff --git a/api/v1/clusterextensionrevision_types.go b/api/v1/clusterextensionrevision_types.go index 0d733be61f..0f41ab3195 100644 --- a/api/v1/clusterextensionrevision_types.go +++ b/api/v1/clusterextensionrevision_types.go @@ -61,7 +61,7 @@ type ClusterExtensionRevisionSpec struct { // 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. // - // +kubebuilder:validation:Required + // +required // +kubebuilder:validation:Minimum:=1 // +kubebuilder:validation:XValidation:rule="self == oldSelf", message="revision is immutable" Revision int64 `json:"revision"` @@ -253,7 +253,7 @@ type ClusterExtensionRevisionList struct { // items is a required list of ClusterExtensionRevision objects. // - // +kubebuilder:validation:Required + // +required Items []ClusterExtensionRevision `json:"items"` } diff --git a/hack/tools/crd-generator/testdata/api/v1/clusterextension_types.go b/hack/tools/crd-generator/testdata/api/v1/clusterextension_types.go index 8e134a3429..bd0de61d7a 100644 --- a/hack/tools/crd-generator/testdata/api/v1/clusterextension_types.go +++ b/hack/tools/crd-generator/testdata/api/v1/clusterextension_types.go @@ -60,7 +60,7 @@ type ClusterExtensionSpec struct { // // // +kubebuilder:validation:XValidation:rule="self.matches(\"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$\")",message="namespace must be a valid DNS1123 label" - // +kubebuilder:validation:Required + // +required Namespace string `json:"namespace"` // serviceAccount is a reference to a ServiceAccount used to perform all interactions @@ -69,7 +69,7 @@ type ClusterExtensionSpec struct { // The ServiceAccount must exist in the namespace referenced in the spec. // serviceAccount is required. // - // +kubebuilder:validation:Required + // +required ServiceAccount ServiceAccountReference `json:"serviceAccount"` // source is a required field which selects the installation source of content @@ -85,7 +85,7 @@ type ClusterExtensionSpec struct { // catalog: // packageName: example-package // - // +kubebuilder:validation:Required + // +required Source SourceConfig `json:"source"` // install is an optional field used to configure the installation options @@ -114,7 +114,7 @@ type SourceConfig struct { // +unionDiscriminator // // - // +kubebuilder:validation:Required + // +required SourceType string `json:"sourceType"` // catalog is used to configure how information is sourced from a catalog. @@ -180,7 +180,7 @@ type CatalogFilter struct { // +kubebuilder:validation:MaxLength:=253 // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="packageName is immutable" // +kubebuilder:validation:XValidation:rule="self.matches(\"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\")",message="packageName must be a valid DNS1123 subdomain. It must contain only lowercase alphanumeric characters, hyphens (-) or periods (.), start and end with an alphanumeric character, and be no longer than 253 characters" - // +kubebuilder:validation:Required + // +required PackageName string `json:"packageName"` // version is an optional semver constraint (a specific version or range of versions). When unspecified, the latest version available will be installed. @@ -370,7 +370,7 @@ type ServiceAccountReference struct { // +kubebuilder:validation:MaxLength:=253 // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="name is immutable" // +kubebuilder:validation:XValidation:rule="self.matches(\"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\")",message="name must be a valid DNS1123 subdomain. It must contain only lowercase alphanumeric characters, hyphens (-) or periods (.), start and end with an alphanumeric character, and be no longer than 253 characters" - // +kubebuilder:validation:Required + // +required Name string `json:"name"` } @@ -400,7 +400,7 @@ type CRDUpgradeSafetyPreflightConfig struct { // performing an upgrade operation. // // +kubebuilder:validation:Enum:="None";"Strict" - // +kubebuilder:validation:Required + // +required Enforcement CRDUpgradeSafetyEnforcement `json:"enforcement"` } @@ -425,14 +425,14 @@ type BundleMetadata struct { // hyphens (-) or periods (.), start and end with an alphanumeric character, // and be no longer than 253 characters. // - // +kubebuilder:validation:Required + // +required // +kubebuilder:validation:XValidation:rule="self.matches(\"^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\")",message="packageName must be a valid DNS1123 subdomain. 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"` // version is a required field and is a reference to the version that this bundle represents // version follows the semantic versioning standard as defined in https://semver.org/. // - // +kubebuilder:validation:Required + // +required // +kubebuilder:validation:XValidation:rule="self.matches(\"^([0-9]+)(\\\\.[0-9]+)?(\\\\.[0-9]+)?(-([-0-9A-Za-z]+(\\\\.[-0-9A-Za-z]+)*))?(\\\\+([-0-9A-Za-z]+(-\\\\.[-0-9A-Za-z]+)*))?\")",message="version must be well-formed semver" Version string `json:"version"` } @@ -475,7 +475,7 @@ type ClusterExtensionInstallStatus struct { // A "bundle" is a versioned set of content that represents the resources that // need to be applied to a cluster to install a package. // - // +kubebuilder:validation:Required + // +required Bundle BundleMetadata `json:"bundle"` } @@ -513,7 +513,7 @@ type ClusterExtensionList struct { // items is a required list of ClusterExtension objects. // - // +kubebuilder:validation:Required + // +required Items []ClusterExtension `json:"items"` }