From 62487db0ec59f9db6b54627b33ccba93f3e9fb71 Mon Sep 17 00:00:00 2001 From: Santosh Kaluskar Date: Tue, 6 Sep 2022 17:50:00 +0530 Subject: [PATCH] WIP: Adding CRD validation Signed-off-by: Santosh Kaluskar --- api/v1beta1/bucket_types.go | 14 ++++++++++++++ api/v1beta1/gitrepository_types.go | 20 ++++++++++++++++++++ api/v1beta1/helmchart_types.go | 12 ++++++++++++ api/v1beta1/helmrepository_types.go | 6 ++++++ api/v1beta2/artifact_types.go | 10 ++++++++++ api/v1beta2/bucket_types.go | 13 +++++++++++++ api/v1beta2/gitrepository_types.go | 19 +++++++++++++++++++ api/v1beta2/helmchart_types.go | 17 +++++++++++++++++ api/v1beta2/helmrepository_types.go | 6 ++++++ api/v1beta2/ocirepository_types.go | 1 + 10 files changed, 118 insertions(+) diff --git a/api/v1beta1/bucket_types.go b/api/v1beta1/bucket_types.go index 0d5f3de81..4477ee87a 100644 --- a/api/v1beta1/bucket_types.go +++ b/api/v1beta1/bucket_types.go @@ -38,10 +38,16 @@ type BucketSpec struct { Provider string `json:"provider,omitempty"` // The bucket name. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +required BucketName string `json:"bucketName"` // The bucket endpoint address. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=250 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +required Endpoint string `json:"endpoint"` @@ -50,6 +56,8 @@ type BucketSpec struct { Insecure bool `json:"insecure,omitempty"` // The bucket region. + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional Region string `json:"region,omitempty"` @@ -70,6 +78,9 @@ type BucketSpec struct { // Ignore overrides the set of excluded patterns in the .sourceignore format // (which is the same as .gitignore). If not provided, a default will be used, // consult the documentation for your version to find out what those are. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional Ignore *string `json:"ignore,omitempty"` @@ -99,6 +110,8 @@ type BucketStatus struct { Conditions []metav1.Condition `json:"conditions,omitempty"` // URL is the download link for the artifact output of the last Bucket sync. + // +kubebuilder:validation:MaxLength=250 + // +kubebuilder:validation:Pattern="^(http|https|ssh)://.*$" // +optional URL string `json:"url,omitempty"` @@ -206,6 +219,7 @@ type Bucket struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // +kubebuilder:validation:required Spec BucketSpec `json:"spec,omitempty"` // +kubebuilder:default={"observedGeneration":-1} Status BucketStatus `json:"status,omitempty"` diff --git a/api/v1beta1/gitrepository_types.go b/api/v1beta1/gitrepository_types.go index c84055e03..6c471dfaa 100644 --- a/api/v1beta1/gitrepository_types.go +++ b/api/v1beta1/gitrepository_types.go @@ -37,6 +37,9 @@ const ( // GitRepositorySpec defines the desired state of a Git repository. type GitRepositorySpec struct { // The repository URL, can be a HTTP/S or SSH address. + + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 // +kubebuilder:validation:Pattern="^(http|https|ssh)://.*$" // +required URL string `json:"url"` @@ -70,6 +73,8 @@ type GitRepositorySpec struct { // Ignore overrides the set of excluded patterns in the .sourceignore format // (which is the same as .gitignore). If not provided, a default will be used, // consult the documentation for your version to find out what those are. + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional Ignore *string `json:"ignore,omitempty"` @@ -115,10 +120,14 @@ type GitRepositoryInclude struct { GitRepositoryRef meta.LocalObjectReference `json:"repository"` // The path to copy contents from, defaults to the root directory. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional FromPath string `json:"fromPath"` // The path to copy contents to, defaults to the name of the source ref. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional ToPath string `json:"toPath"` } @@ -126,18 +135,26 @@ type GitRepositoryInclude struct { // GitRepositoryRef defines the Git ref used for pull and checkout operations. type GitRepositoryRef struct { // The Git branch to checkout, defaults to master. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^[\-._a-zA-Z0-9]+$` // +optional Branch string `json:"branch,omitempty"` // The Git tag to checkout, takes precedence over Branch. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^[\-._0-9]+$` // +optional Tag string `json:"tag,omitempty"` // The Git tag semver expression, takes precedence over Tag. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^[\-._0-9]+$` // +optional SemVer string `json:"semver,omitempty"` // The Git commit SHA to checkout, if specified Tag filters will be ignored. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$ // +optional Commit string `json:"commit,omitempty"` } @@ -164,6 +181,8 @@ type GitRepositoryStatus struct { // URL is the download link for the artifact output of the last repository // sync. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern="^(http|https|ssh)://.*$" // +optional URL string `json:"url,omitempty"` @@ -279,6 +298,7 @@ type GitRepository struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // +kubebuilder:validation:required Spec GitRepositorySpec `json:"spec,omitempty"` // +kubebuilder:default={"observedGeneration":-1} Status GitRepositoryStatus `json:"status,omitempty"` diff --git a/api/v1beta1/helmchart_types.go b/api/v1beta1/helmchart_types.go index 8d4c0a02d..b073568f9 100644 --- a/api/v1beta1/helmchart_types.go +++ b/api/v1beta1/helmchart_types.go @@ -30,12 +30,17 @@ const HelmChartKind = "HelmChart" // HelmChartSpec defines the desired state of a Helm chart. type HelmChartSpec struct { // The name or path the Helm chart is available at in the SourceRef. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +required Chart string `json:"chart"` // The chart version semver expression, ignored for charts from GitRepository // and Bucket sources. Defaults to latest when omitted. // +kubebuilder:default:=* + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional Version string `json:"version,omitempty"` @@ -92,6 +97,9 @@ const ( // the typed referenced object at namespace level. type LocalHelmChartSourceReference struct { // APIVersion of the referent. + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` + // +optional APIVersion string `json:"apiVersion,omitempty"` @@ -102,6 +110,9 @@ type LocalHelmChartSourceReference struct { Kind string `json:"kind"` // Name of the referent. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +required Name string `json:"name"` } @@ -248,6 +259,7 @@ type HelmChart struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // +kubebuilder:validation:required Spec HelmChartSpec `json:"spec,omitempty"` // +kubebuilder:default={"observedGeneration":-1} Status HelmChartStatus `json:"status,omitempty"` diff --git a/api/v1beta1/helmrepository_types.go b/api/v1beta1/helmrepository_types.go index 62b0e9a6d..2e08b84b2 100644 --- a/api/v1beta1/helmrepository_types.go +++ b/api/v1beta1/helmrepository_types.go @@ -35,6 +35,9 @@ const ( // HelmRepositorySpec defines the reference to a Helm repository. type HelmRepositorySpec struct { // The Helm repository URL, a valid URL contains at least a protocol and host. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern="^(http|https|ssh)://.*$" // +required URL string `json:"url"` @@ -85,6 +88,8 @@ type HelmRepositoryStatus struct { Conditions []metav1.Condition `json:"conditions,omitempty"` // URL is the download link for the last index fetched. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern="^(http|https|ssh)://.*$" // +optional URL string `json:"url,omitempty"` @@ -195,6 +200,7 @@ type HelmRepository struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // +kubebuilder:validation:required Spec HelmRepositorySpec `json:"spec,omitempty"` // +kubebuilder:default={"observedGeneration":-1} Status HelmRepositoryStatus `json:"status,omitempty"` diff --git a/api/v1beta2/artifact_types.go b/api/v1beta2/artifact_types.go index 0832b6ce5..1d2f088c6 100644 --- a/api/v1beta2/artifact_types.go +++ b/api/v1beta2/artifact_types.go @@ -28,21 +28,31 @@ type Artifact struct { // Path is the relative file path of the Artifact. It can be used to locate // the file in the root of the Artifact storage on the local file system of // the controller managing the Source. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +required Path string `json:"path"` // URL is the HTTP address of the Artifact as exposed by the controller // managing the Source. It can be used to retrieve the Artifact for // consumption, e.g. by another controller applying the Artifact contents. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern="^(http|https|ssh)://.*$" // +required URL string `json:"url"` // Revision is a human-readable identifier traceable in the origin source // system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional Revision string `json:"revision"` // Checksum is the SHA256 checksum of the Artifact file. + // +kubebuilder:validation:MaxLength=250 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional Checksum string `json:"checksum"` diff --git a/api/v1beta2/bucket_types.go b/api/v1beta2/bucket_types.go index 2ea66e465..2a05403b9 100644 --- a/api/v1beta2/bucket_types.go +++ b/api/v1beta2/bucket_types.go @@ -57,10 +57,16 @@ type BucketSpec struct { Provider string `json:"provider,omitempty"` // BucketName is the name of the object storage bucket. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +required BucketName string `json:"bucketName"` // Endpoint is the object storage address the BucketName is located at. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=250 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +required Endpoint string `json:"endpoint"` @@ -69,6 +75,8 @@ type BucketSpec struct { Insecure bool `json:"insecure,omitempty"` // Region of the Endpoint where the BucketName is located in. + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional Region string `json:"region,omitempty"` @@ -89,6 +97,8 @@ type BucketSpec struct { // Ignore overrides the set of excluded patterns in the .sourceignore format // (which is the same as .gitignore). If not provided, a default will be used, // consult the documentation for your version to find out what those are. + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional Ignore *string `json:"ignore,omitempty"` @@ -117,6 +127,8 @@ type BucketStatus struct { // URL is the dynamic fetch link for the latest Artifact. // It is provided on a "best effort" basis, and using the precise // BucketStatus.Artifact data is recommended. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern="^(http|https|ssh)://.*$" // +optional URL string `json:"url,omitempty"` @@ -172,6 +184,7 @@ type Bucket struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // +kubebuilder:validation:required Spec BucketSpec `json:"spec,omitempty"` // +kubebuilder:default={"observedGeneration":-1} Status BucketStatus `json:"status,omitempty"` diff --git a/api/v1beta2/gitrepository_types.go b/api/v1beta2/gitrepository_types.go index de736c861..410406c08 100644 --- a/api/v1beta2/gitrepository_types.go +++ b/api/v1beta2/gitrepository_types.go @@ -48,6 +48,8 @@ const ( // Artifact for a Git repository. type GitRepositorySpec struct { // URL specifies the Git repository URL, it can be an HTTP/S or SSH address. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 // +kubebuilder:validation:Pattern="^(http|https|ssh)://.*$" // +required URL string `json:"url"` @@ -83,6 +85,8 @@ type GitRepositorySpec struct { // Ignore overrides the set of excluded patterns in the .sourceignore format // (which is the same as .gitignore). If not provided, a default will be used, // consult the documentation for your version to find out what those are. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional Ignore *string `json:"ignore,omitempty"` @@ -124,11 +128,15 @@ type GitRepositoryInclude struct { // FromPath specifies the path to copy contents from, defaults to the root // of the Artifact. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional FromPath string `json:"fromPath"` // ToPath specifies the path to copy contents to, defaults to the name of // the GitRepositoryRef. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional ToPath string `json:"toPath"` } @@ -153,14 +161,20 @@ type GitRepositoryRef struct { // // When GitRepositorySpec.GitImplementation is set to 'go-git', a shallow // clone of the specified branch is performed. + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional Branch string `json:"branch,omitempty"` // Tag to check out, takes precedence over Branch. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^[\-._0-9]+$` // +optional Tag string `json:"tag,omitempty"` // SemVer tag expression to check out, takes precedence over Tag. + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^[\-._0-9]+$` // +optional SemVer string `json:"semver,omitempty"` @@ -169,6 +183,8 @@ type GitRepositoryRef struct { // When GitRepositorySpec.GitImplementation is set to 'go-git', this can be // combined with Branch to shallow clone the branch, in which the commit is // expected to exist. + // +kubebuilder:validation:MaxLength=250 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional Commit string `json:"commit,omitempty"` } @@ -199,6 +215,8 @@ type GitRepositoryStatus struct { // URL is the dynamic fetch link for the latest Artifact. // It is provided on a "best effort" basis, and using the precise // GitRepositoryStatus.Artifact data is recommended. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern="^(http|https|ssh)://.*$" // +optional URL string `json:"url,omitempty"` @@ -274,6 +292,7 @@ type GitRepository struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // +kubebuilder:validation:required Spec GitRepositorySpec `json:"spec,omitempty"` // +kubebuilder:default={"observedGeneration":-1} Status GitRepositoryStatus `json:"status,omitempty"` diff --git a/api/v1beta2/helmchart_types.go b/api/v1beta2/helmchart_types.go index 2ce5a942f..b4fa7edd2 100644 --- a/api/v1beta2/helmchart_types.go +++ b/api/v1beta2/helmchart_types.go @@ -32,12 +32,17 @@ const HelmChartKind = "HelmChart" type HelmChartSpec struct { // Chart is the name or path the Helm chart is available at in the // SourceRef. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +required Chart string `json:"chart"` // Version is the chart version semver expression, ignored for charts from // GitRepository and Bucket sources. Defaults to latest when omitted. // +kubebuilder:default:=* + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^[\-._0-9]+$` // +optional Version string `json:"version,omitempty"` @@ -98,6 +103,8 @@ const ( // the typed referenced object at namespace level. type LocalHelmChartSourceReference struct { // APIVersion of the referent. + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional APIVersion string `json:"apiVersion,omitempty"` @@ -108,6 +115,9 @@ type LocalHelmChartSourceReference struct { Kind string `json:"kind"` // Name of the referent. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=63 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +required Name string `json:"name"` } @@ -121,11 +131,15 @@ type HelmChartStatus struct { // ObservedSourceArtifactRevision is the last observed Artifact.Revision // of the HelmChartSpec.SourceRef. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional ObservedSourceArtifactRevision string `json:"observedSourceArtifactRevision,omitempty"` // ObservedChartName is the last observed chart name as specified by the // resolved chart reference. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern=`^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$` // +optional ObservedChartName string `json:"observedChartName,omitempty"` @@ -136,6 +150,8 @@ type HelmChartStatus struct { // URL is the dynamic fetch link for the latest Artifact. // It is provided on a "best effort" basis, and using the precise // BucketStatus.Artifact data is recommended. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern="^(http|https|ssh)://.*$" // +optional URL string `json:"url,omitempty"` @@ -208,6 +224,7 @@ type HelmChart struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // +kubebuilder:validation:required Spec HelmChartSpec `json:"spec,omitempty"` // +kubebuilder:default={"observedGeneration":-1} Status HelmChartStatus `json:"status,omitempty"` diff --git a/api/v1beta2/helmrepository_types.go b/api/v1beta2/helmrepository_types.go index d9d72b0b9..c29b9e18b 100644 --- a/api/v1beta2/helmrepository_types.go +++ b/api/v1beta2/helmrepository_types.go @@ -43,6 +43,9 @@ const ( type HelmRepositorySpec struct { // URL of the Helm repository, a valid URL contains at least a protocol and // host. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern="^(http|https|ssh)://.*$" // +required URL string `json:"url"` @@ -115,6 +118,8 @@ type HelmRepositoryStatus struct { // URL is the dynamic fetch link for the latest Artifact. // It is provided on a "best effort" basis, and using the precise // HelmRepositoryStatus.Artifact data is recommended. + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:Pattern="^(http|https|ssh)://.*$" // +optional URL string `json:"url,omitempty"` @@ -169,6 +174,7 @@ type HelmRepository struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // +kubebuilder:validation:required Spec HelmRepositorySpec `json:"spec,omitempty"` // +kubebuilder:default={"observedGeneration":-1} Status HelmRepositoryStatus `json:"status,omitempty"` diff --git a/api/v1beta2/ocirepository_types.go b/api/v1beta2/ocirepository_types.go index 7e1e755ae..aa484424a 100644 --- a/api/v1beta2/ocirepository_types.go +++ b/api/v1beta2/ocirepository_types.go @@ -235,6 +235,7 @@ type OCIRepository struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // +kubebuilder:validation:required Spec OCIRepositorySpec `json:"spec,omitempty"` // +kubebuilder:default={"observedGeneration":-1} Status OCIRepositoryStatus `json:"status,omitempty"`