From 0f10d4c91a7fb8cef21c04898ef6d000ae35e88f Mon Sep 17 00:00:00 2001 From: Brad Davidson Date: Wed, 2 Jul 2025 20:48:46 +0000 Subject: [PATCH] Rework CRD generation to add docs and `kubectl explain` support - Convert CRD generation to controller-gen - Add CRD docs Signed-off-by: Brad Davidson --- Dockerfile | 1 + README.md | 11 +- crd-ref-docs.yaml | 5 + doc/helmchart.md | 199 +++++ generate.go | 4 - hack/crdgen.go | 13 - main.go | 6 + pkg/apis/helm.cattle.io/v1/types.go | 140 +++- pkg/cmd/cmd.go | 35 +- pkg/controllers/chart/chart.go | 8 +- pkg/crd/crds.go | 24 - pkg/crds/crds.go | 84 +++ .../helm.cattle.io_helmchartconfigs.yaml | 91 +++ .../generated/helm.cattle.io_helmcharts.yaml | 700 ++++++++++++++++++ .../clientset/versioned/clientset.go | 4 +- .../v1/fake/fake_helm.cattle.io_client.go | 4 +- .../helm.cattle.io/v1/fake/fake_helmchart.go | 137 +--- .../v1/fake/fake_helmchartconfig.go | 126 +--- .../v1/helm.cattle.io_client.go | 10 +- .../typed/helm.cattle.io/v1/helmchart.go | 25 +- .../helm.cattle.io/v1/helmchartconfig.go | 23 +- scripts/package | 2 +- test/framework/controller.go | 5 +- test/framework/framework.go | 19 +- 24 files changed, 1317 insertions(+), 359 deletions(-) create mode 100644 crd-ref-docs.yaml create mode 100644 doc/helmchart.md delete mode 100644 generate.go delete mode 100644 hack/crdgen.go delete mode 100644 pkg/crd/crds.go create mode 100644 pkg/crds/crds.go create mode 100644 pkg/crds/yaml/generated/helm.cattle.io_helmchartconfigs.yaml create mode 100644 pkg/crds/yaml/generated/helm.cattle.io_helmcharts.yaml diff --git a/Dockerfile b/Dockerfile index e912d3c9..30d6b977 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,6 +18,7 @@ ARG ARCH ENV ARCH=$ARCH RUN apk add --no-cache bash git gcc musl-dev curl RUN GOPROXY=direct go install golang.org/x/tools/cmd/goimports@gopls/v0.18.1 +RUN GOPROXY=direct go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.17.3 RUN if [ "${ARCH}" != "arm" ]; then \ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.64.7; \ fi diff --git a/README.md b/README.md index 94e041f8..cd59f1db 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,7 @@ helm-controller ======== -_NOTE: this repository has been recently (2020-10-06) moved out of the github.com/rancher org to github.com/k3s-io -supporting the [acceptance of K3s as a CNCF sandbox project](https://github.com/cncf/toc/pull/447)_. - ---- - -A simple way to manage helm charts (v2 and v3) with Custom Resource Definitions in k8s. +A simple way to manage helm charts with Custom Resource Definitions in k8s. ## Manifests and Deploying The `./manifests` folder contains useful YAML manifests to use for deploying and developing the Helm Controller. This simple YAML deployment creates a HelmChart CRD + a Deployment using the `rancher/helm-controller` container. The YAML might need some modifications for your environment so read below for Namespaced vs Cluster deployments and how to use them properly. @@ -17,6 +12,10 @@ Use the `deploy-namespaced.yaml` to create a namespace and add the Helm Controll #### Cluster Scoped Deploys If you'd like your helm controller to watch the entire cluster for HelmChart CRD changes use the `deploy-cluster-scoped.yaml` deploy manifest. By default it will add the helm-controller to the `kube-system` so update `metadata.namespace` for your needs. +## API Documentation + +Autogenerated API docs for `helm.cattle.io/v1 HelmChart` and `HelmChartConfig` are available at [doc/helmchart.md](doc/helmchart.md#HelmChart) + ## Uninstalling To remove the Helm Controller run `kubectl delete` and pass the deployment YAML used using to create the Deployment `-f` parameter. diff --git a/crd-ref-docs.yaml b/crd-ref-docs.yaml new file mode 100644 index 00000000..2873f458 --- /dev/null +++ b/crd-ref-docs.yaml @@ -0,0 +1,5 @@ +processor: + ignoreFields: + - "TypeMeta$" +render: + kubernetesVersion: 1.32 diff --git a/doc/helmchart.md b/doc/helmchart.md new file mode 100644 index 00000000..dae3d315 --- /dev/null +++ b/doc/helmchart.md @@ -0,0 +1,199 @@ +# API Reference + +## Packages +- [helm.cattle.io/v1](#helmcattleiov1) + + +## helm.cattle.io/v1 + + + + + + +#### FailurePolicy + +_Underlying type:_ _string_ + + + +_Validation:_ +- Enum: [abort reinstall] + +_Appears in:_ +- [HelmChartConfigSpec](#helmchartconfigspec) +- [HelmChartSpec](#helmchartspec) + + + +#### HelmChart + + + +HelmChart represents configuration and state for the deployment of a Helm chart. + + + +_Appears in:_ +- [HelmChartList](#helmchartlist) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | | +| `spec` _[HelmChartSpec](#helmchartspec)_ | | | | +| `status` _[HelmChartStatus](#helmchartstatus)_ | | | | + + +#### HelmChartCondition + + + + + + + +_Appears in:_ +- [HelmChartStatus](#helmchartstatus) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `type` _[HelmChartConditionType](#helmchartconditiontype)_ | Type of job condition. | | | +| `status` _[ConditionStatus](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#conditionstatus-v1-core)_ | Status of the condition, one of True, False, Unknown. | | | +| `reason` _string_ | (brief) reason for the condition's last transition. | | | +| `message` _string_ | Human readable message indicating details about last transition. | | | + + +#### HelmChartConditionType + +_Underlying type:_ _string_ + + + + + +_Appears in:_ +- [HelmChartCondition](#helmchartcondition) + +| Field | Description | +| --- | --- | +| `JobCreated` | | +| `Failed` | | + + +#### HelmChartConfig + + + +HelmChartConfig represents additional configuration for the installation of Helm chart release. +This resource is intended for use when additional configuration needs to be passed to a HelmChart +that is managed by an external system. + + + +_Appears in:_ +- [HelmChartConfigList](#helmchartconfiglist) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | | +| `spec` _[HelmChartConfigSpec](#helmchartconfigspec)_ | | | | + + + + +#### HelmChartConfigSpec + + + +HelmChartConfigSpec represents additional user-configurable details of an installed and configured Helm chart release. +These fields are merged with or override the corresponding fields on the related HelmChart resource. + + + +_Appears in:_ +- [HelmChartConfig](#helmchartconfig) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `valuesContent` _string_ | Override complex Chart values via inline YAML content.
Helm CLI positional argument/flag: `--values` | | | +| `valuesSecrets` _[SecretSpec](#secretspec) array_ | Override complex Chart values via references to external Secrets.
Helm CLI positional argument/flag: `--values` | | | +| `failurePolicy` _[FailurePolicy](#failurepolicy)_ | Configures handling of failed chart installation or upgrades.
- `reinstall` will perform a clean uninstall and reinstall of the chart.
- `abort` will take no action and leave the chart in a failed state so that the administrator can manually resolve the error. | reinstall | Enum: [abort reinstall]
| + + + + +#### HelmChartSpec + + + +HelmChartSpec represents the user-configurable details for installation and upgrade of a Helm chart release. + + + +_Appears in:_ +- [HelmChart](#helmchart) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `targetNamespace` _string_ | Helm Chart target namespace.
Helm CLI positional argument/flag: `--namespace` | | | +| `createNamespace` _boolean_ | Create target namespace if not present.
Helm CLI positional argument/flag: `--create-namespace` | | | +| `chart` _string_ | Helm Chart name in repository, or complete HTTPS URL to chart archive (.tgz)
Helm CLI positional argument/flag: `CHART` | | | +| `version` _string_ | Helm Chart version. Only used when installing from repository; ignored when .spec.chart or .spec.chartContent is used to install a specific chart archive.
Helm CLI positional argument/flag: `--version` | | | +| `repo` _string_ | Helm Chart repository URL.
Helm CLI positional argument/flag: `--repo` | | | +| `repoCA` _string_ | Verify certificates of HTTPS-enabled servers using this CA bundle. Should be a string containing one or more PEM-encoded CA Certificates.
Helm CLI positional argument/flag: `--ca-file` | | | +| `repoCAConfigMap` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#localobjectreference-v1-core)_ | Reference to a ConfigMap containing CA Certificates to be be trusted by Helm. Can be used along with or instead of `.spec.repoCA`
Helm CLI positional argument/flag: `--ca-file` | | | +| `set` _object (keys:string, values:[IntOrString](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#intorstring-intstr-util))_ | Override simple Chart values. These take precedence over options set via valuesContent.
Helm CLI positional argument/flag: `--set`, `--set-string` | | | +| `valuesContent` _string_ | Override complex Chart values via inline YAML content.
Helm CLI positional argument/flag: `--values` | | | +| `valuesSecrets` _[SecretSpec](#secretspec) array_ | Override complex Chart values via references to external Secrets.
Helm CLI positional argument/flag: `--values` | | | +| `helmVersion` _string_ | DEPRECATED. Helm version to use. Only v3 is currently supported. | | | +| `bootstrap` _boolean_ | Set to True if this chart is needed to bootstrap the cluster (Cloud Controller Manager, CNI, etc) | | | +| `chartContent` _string_ | Base64-encoded chart archive .tgz; overides `.spec.chart` and `.spec.version`
Helm CLI positional argument/flag: `CHART` | | | +| `jobImage` _string_ | Specify the image to use for tht helm job pod when installing or upgrading the helm chart. | | | +| `backOffLimit` _integer_ | Specify the number of retries before considering the helm job failed. | | | +| `timeout` _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#duration-v1-meta)_ | Timeout for Helm operations.
Helm CLI positional argument/flag: `--timeout` | | | +| `failurePolicy` _[FailurePolicy](#failurepolicy)_ | Configures handling of failed chart installation or upgrades.
- `reinstall` will perform a clean uninstall and reinstall of the chart.
- `abort` will take no action and leave the chart in a failed state so that the administrator can manually resolve the error. | reinstall | Enum: [abort reinstall]
| +| `authSecret` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#localobjectreference-v1-core)_ | Reference to Secret of type kubernetes.io/basic-auth holding Basic auth credentials for the Chart repo. | | | +| `authPassCredentials` _boolean_ | Pass Basic auth credentials to all domains.
Helm CLI positional argument/flag: `--pass-credentials` | | | +| `insecureSkipTLSVerify` _boolean_ | Skip TLS certificate checks for the chart download.
Helm CLI positional argument/flag: `--insecure-skip-tls-verify` | | | +| `plainHTTP` _boolean_ | Use insecure HTTP connections for the chart download.
Helm CLI positional argument/flag: `--plain-http` | | | +| `dockerRegistrySecret` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#localobjectreference-v1-core)_ | Reference to Secret of type kubernetes.io/dockerconfigjson holding Docker auth credentials for the OCI-based registry acting as the Chart repo. | | | +| `podSecurityContext` _[PodSecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#podsecuritycontext-v1-core)_ | Custom PodSecurityContext for the helm job pod. | | | +| `securityContext` _[SecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#securitycontext-v1-core)_ | custom SecurityContext for the helm job pod. | | | + + +#### HelmChartStatus + + + +HelmChartStatus represents the resulting state from processing HelmChart events + + + +_Appears in:_ +- [HelmChart](#helmchart) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `jobName` _string_ | The name of the job created to install or upgrade the chart. | | | +| `conditions` _[HelmChartCondition](#helmchartcondition) array_ | `JobCreated` indicates that a job has been created to install or upgrade the chart.
`Failed` indicates that the helm job has failed and the failure policy is set to `abort`. | | | + + +#### SecretSpec + + + +SecretSpec describes a key in a secret to load chart values from. + + + +_Appears in:_ +- [HelmChartConfigSpec](#helmchartconfigspec) +- [HelmChartSpec](#helmchartspec) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `name` _string_ | Name of the secret. Must be in the same namespace as the HelmChart resource. | | | +| `keys` _string array_ | Keys to read values content from. If no keys are specified, the secret is not used. | | | +| `ignoreUpdates` _boolean_ | Ignore changes to the secret, and mark the secret as optional.
By default, the secret must exist, and changes to the secret will trigger an upgrade of the chart to apply the updated values.
If `ignoreUpdates` is true, the secret is optional, and changes to the secret will not trigger an upgrade of the chart. | | | + + diff --git a/generate.go b/generate.go deleted file mode 100644 index 56df3acb..00000000 --- a/generate.go +++ /dev/null @@ -1,4 +0,0 @@ -//go:generate go run pkg/codegen/cleanup/main.go -//go:generate go run pkg/codegen/main.go - -package main diff --git a/hack/crdgen.go b/hack/crdgen.go deleted file mode 100644 index a168a997..00000000 --- a/hack/crdgen.go +++ /dev/null @@ -1,13 +0,0 @@ -package main - -import ( - "os" - - "github.com/k3s-io/helm-controller/pkg/crd" - _ "github.com/k3s-io/helm-controller/pkg/generated/controllers/helm.cattle.io/v1" - wcrd "github.com/rancher/wrangler/v3/pkg/crd" -) - -func main() { - wcrd.Print(os.Stdout, crd.List()) -} diff --git a/main.go b/main.go index ed832682..218ea505 100644 --- a/main.go +++ b/main.go @@ -1,3 +1,9 @@ +//go:generate go run pkg/codegen/cleanup/main.go +//go:generate rm -rf pkg/generated pkg/crds/yaml/generated +//go:generate go run pkg/codegen/main.go +//go:generate controller-gen crd:generateEmbeddedObjectMeta=true paths=./pkg/apis/... output:crd:dir=./pkg/crds/yaml/generated +//go:generate crd-ref-docs --config=crd-ref-docs.yaml --renderer=markdown --output-path=doc/helmchart.md + package main import ( diff --git a/pkg/apis/helm.cattle.io/v1/types.go b/pkg/apis/helm.cattle.io/v1/types.go index fe8e2182..d4d53305 100644 --- a/pkg/apis/helm.cattle.io/v1/types.go +++ b/pkg/apis/helm.cattle.io/v1/types.go @@ -7,9 +7,21 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" ) +// +kubebuilder:validation:Enum={"abort","reinstall"} +type FailurePolicy string + // +genclient +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Repo",type=string,JSONPath=`.spec.repo` +// +kubebuilder:printcolumn:name="Chart",type=string,JSONPath=`.spec.chart` +// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.spec.version` +// +kubebuilder:printcolumn:name="TargetNamespace",type=string,JSONPath=`.spec.targetNamespace` +// +kubebuilder:printcolumn:name="Bootstrap",type=boolean,JSONPath=`.spec.bootstrap` +// +kubebuilder:printcolumn:name="Failed",type=string,JSONPath=`.status.conditions[?(@.type=='Failed')].status` +// +kubebuilder:printcolumn:name="Job",type=string,JSONPath=`.status.jobName`,priority=10 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// HelmChart represents configuration and state for the deployment of a Helm chart. type HelmChart struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -18,43 +30,96 @@ type HelmChart struct { Status HelmChartStatus `json:"status,omitempty"` } +// HelmChartSpec represents the user-configurable details for installation and upgrade of a Helm chart release. type HelmChartSpec struct { - TargetNamespace string `json:"targetNamespace,omitempty"` - CreateNamespace bool `json:"createNamespace,omitempty"` - Chart string `json:"chart,omitempty"` - Version string `json:"version,omitempty"` - Repo string `json:"repo,omitempty"` - RepoCA string `json:"repoCA,omitempty"` - RepoCAConfigMap *corev1.LocalObjectReference `json:"repoCAConfigMap,omitempty"` - Set map[string]intstr.IntOrString `json:"set,omitempty"` - ValuesContent string `json:"valuesContent,omitempty"` - ValuesSecrets []SecretSpec `json:"valuesSecrets,omitempty"` - HelmVersion string `json:"helmVersion,omitempty"` - Bootstrap bool `json:"bootstrap,omitempty"` - ChartContent string `json:"chartContent,omitempty"` - JobImage string `json:"jobImage,omitempty"` - BackOffLimit *int32 `json:"backOffLimit,omitempty"` - Timeout *metav1.Duration `json:"timeout,omitempty"` - FailurePolicy string `json:"failurePolicy,omitempty"` - AuthSecret *corev1.LocalObjectReference `json:"authSecret,omitempty"` - - AuthPassCredentials bool `json:"authPassCredentials,omitempty"` + // Helm Chart target namespace. + // Helm CLI positional argument/flag: `--namespace` + TargetNamespace string `json:"targetNamespace,omitempty"` + // Create target namespace if not present. + // Helm CLI positional argument/flag: `--create-namespace` + CreateNamespace bool `json:"createNamespace,omitempty"` + // Helm Chart name in repository, or complete HTTPS URL to chart archive (.tgz) + // Helm CLI positional argument/flag: `CHART` + Chart string `json:"chart,omitempty"` + // Helm Chart version. Only used when installing from repository; ignored when .spec.chart or .spec.chartContent is used to install a specific chart archive. + // Helm CLI positional argument/flag: `--version` + Version string `json:"version,omitempty"` + // Helm Chart repository URL. + // Helm CLI positional argument/flag: `--repo` + Repo string `json:"repo,omitempty"` + // Verify certificates of HTTPS-enabled servers using this CA bundle. Should be a string containing one or more PEM-encoded CA Certificates. + // Helm CLI positional argument/flag: `--ca-file` + RepoCA string `json:"repoCA,omitempty"` + // Reference to a ConfigMap containing CA Certificates to be be trusted by Helm. Can be used along with or instead of `.spec.repoCA` + // Helm CLI positional argument/flag: `--ca-file` + RepoCAConfigMap *corev1.LocalObjectReference `json:"repoCAConfigMap,omitempty"` + // Override simple Chart values. These take precedence over options set via valuesContent. + // Helm CLI positional argument/flag: `--set`, `--set-string` + Set map[string]intstr.IntOrString `json:"set,omitempty"` + // Override complex Chart values via inline YAML content. + // Helm CLI positional argument/flag: `--values` + ValuesContent string `json:"valuesContent,omitempty"` + // Override complex Chart values via references to external Secrets. + // Helm CLI positional argument/flag: `--values` + ValuesSecrets []SecretSpec `json:"valuesSecrets,omitempty"` + // DEPRECATED. Helm version to use. Only v3 is currently supported. + HelmVersion string `json:"helmVersion,omitempty"` + // Set to True if this chart is needed to bootstrap the cluster (Cloud Controller Manager, CNI, etc) + Bootstrap bool `json:"bootstrap,omitempty"` + // Base64-encoded chart archive .tgz; overides `.spec.chart` and `.spec.version` + // Helm CLI positional argument/flag: `CHART` + ChartContent string `json:"chartContent,omitempty"` + // Specify the image to use for tht helm job pod when installing or upgrading the helm chart. + JobImage string `json:"jobImage,omitempty"` + // Specify the number of retries before considering the helm job failed. + BackOffLimit *int32 `json:"backOffLimit,omitempty"` + // Timeout for Helm operations. + // Helm CLI positional argument/flag: `--timeout` + Timeout *metav1.Duration `json:"timeout,omitempty"` + // Configures handling of failed chart installation or upgrades. + // - `reinstall` will perform a clean uninstall and reinstall of the chart. + // - `abort` will take no action and leave the chart in a failed state so that the administrator can manually resolve the error. + // +kubebuilder:default=reinstall + FailurePolicy FailurePolicy `json:"failurePolicy,omitempty"` + // Reference to Secret of type kubernetes.io/basic-auth holding Basic auth credentials for the Chart repo. + AuthSecret *corev1.LocalObjectReference `json:"authSecret,omitempty"` + // Pass Basic auth credentials to all domains. + // Helm CLI positional argument/flag: `--pass-credentials` + AuthPassCredentials bool `json:"authPassCredentials,omitempty"` + // Skip TLS certificate checks for the chart download. + // Helm CLI positional argument/flag: `--insecure-skip-tls-verify` InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify,omitempty"` - PlainHTTP bool `json:"plainHTTP,omitempty"` - + // Use insecure HTTP connections for the chart download. + // Helm CLI positional argument/flag: `--plain-http` + PlainHTTP bool `json:"plainHTTP,omitempty"` + // Reference to Secret of type kubernetes.io/dockerconfigjson holding Docker auth credentials for the OCI-based registry acting as the Chart repo. DockerRegistrySecret *corev1.LocalObjectReference `json:"dockerRegistrySecret,omitempty"` - PodSecurityContext *corev1.PodSecurityContext `json:"podSecurityContext,omitempty"` - SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"` + // Custom PodSecurityContext for the helm job pod. + PodSecurityContext *corev1.PodSecurityContext `json:"podSecurityContext,omitempty"` + // custom SecurityContext for the helm job pod. + SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"` } +// HelmChartStatus represents the resulting state from processing HelmChart events type HelmChartStatus struct { - JobName string `json:"jobName,omitempty"` + // The name of the job created to install or upgrade the chart. + JobName string `json:"jobName,omitempty"` + // `JobCreated` indicates that a job has been created to install or upgrade the chart. + // `Failed` indicates that the helm job has failed and the failure policy is set to `abort`. + // +optional + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type Conditions []HelmChartCondition `json:"conditions,omitempty"` } // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// HelmChartConfig represents additional configuration for the installation of Helm chart release. +// This resource is intended for use when additional configuration needs to be passed to a HelmChart +// that is managed by an external system. type HelmChartConfig struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -62,10 +127,20 @@ type HelmChartConfig struct { Spec HelmChartConfigSpec `json:"spec,omitempty"` } +// HelmChartConfigSpec represents additional user-configurable details of an installed and configured Helm chart release. +// These fields are merged with or override the corresponding fields on the related HelmChart resource. type HelmChartConfigSpec struct { - ValuesContent string `json:"valuesContent,omitempty"` + // Override complex Chart values via inline YAML content. + // Helm CLI positional argument/flag: `--values` + ValuesContent string `json:"valuesContent,omitempty"` + // Override complex Chart values via references to external Secrets. + // Helm CLI positional argument/flag: `--values` ValuesSecrets []SecretSpec `json:"valuesSecrets,omitempty"` - FailurePolicy string `json:"failurePolicy,omitempty"` + // Configures handling of failed chart installation or upgrades. + // - `reinstall` will perform a clean uninstall and reinstall of the chart. + // - `abort` will take no action and leave the chart in a failed state so that the administrator can manually resolve the error. + // +kubebuilder:default=reinstall + FailurePolicy FailurePolicy `json:"failurePolicy,omitempty"` } type HelmChartConditionType string @@ -90,7 +165,12 @@ type HelmChartCondition struct { // SecretSpec describes a key in a secret to load chart values from. type SecretSpec struct { - Name string `json:"name,omitempty"` - Keys []string `json:"keys,omitempty"` - IgnoreUpdates bool `json:"ignoreUpdates,omitempty"` + // Name of the secret. Must be in the same namespace as the HelmChart resource. + Name string `json:"name,omitempty"` + // Keys to read values content from. If no keys are specified, the secret is not used. + Keys []string `json:"keys,omitempty"` + // Ignore changes to the secret, and mark the secret as optional. + // By default, the secret must exist, and changes to the secret will trigger an upgrade of the chart to apply the updated values. + // If `ignoreUpdates` is true, the secret is optional, and changes to the secret will not trigger an upgrade of the chart. + IgnoreUpdates bool `json:"ignoreUpdates,omitempty"` } diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 99076b0b..28da9bcb 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -3,22 +3,26 @@ package cmd import ( "flag" "fmt" - - "github.com/sirupsen/logrus" - "k8s.io/klog/v2" - "log" "net/http" + "time" "github.com/k3s-io/helm-controller/pkg/controllers" "github.com/k3s-io/helm-controller/pkg/controllers/common" - "github.com/k3s-io/helm-controller/pkg/crd" - wcrd "github.com/rancher/wrangler/v3/pkg/crd" + "github.com/k3s-io/helm-controller/pkg/crds" + "github.com/rancher/wrangler/v3/pkg/crd" "github.com/rancher/wrangler/v3/pkg/kubeconfig" - "github.com/rancher/wrangler/v3/pkg/ratelimit" + "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" + "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" "k8s.io/client-go/tools/clientcmd" clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + "k8s.io/klog/v2" +) + +const ( + // readyDuration time to wait for CRDs to be ready. + readyDuration = time.Minute * 1 ) type HelmController struct { @@ -71,14 +75,19 @@ func (hc *HelmController) Run(app *cli.Context) error { } cfg := hc.GetNonInteractiveClientConfig() - - clientConfig, err := cfg.ClientConfig() + rest, err := cfg.ClientConfig() if err != nil { return err } - clientConfig.RateLimiter = ratelimit.None + client, err := clientset.NewForConfig(rest) + if err != nil { + return err + } + ctx := app.Context - if err := wcrd.Create(ctx, clientConfig, crd.List()); err != nil { + + crds, err := crds.List() + if err != nil { return err } @@ -93,6 +102,10 @@ func (hc *HelmController) Run(app *cli.Context) error { return err } + if err := crd.BatchCreateCRDs(ctx, client.ApiextensionsV1().CustomResourceDefinitions(), nil, readyDuration, crds); err != nil { + return err + } + if err := controllers.Register(ctx, hc.Namespace, hc.ControllerName, cfg, opts); err != nil { return err } diff --git a/pkg/controllers/chart/chart.go b/pkg/controllers/chart/chart.go index 07dca190..f8da2c35 100644 --- a/pkg/controllers/chart/chart.go +++ b/pkg/controllers/chart/chart.go @@ -438,8 +438,8 @@ func (c *Controller) shouldManage(chart *v1.HelmChart) (bool, error) { func (c *Controller) getJobAndRelatedResources(chart *v1.HelmChart) (*batch.Job, []runtime.Object, error) { // set a default failure policy failurePolicy := DefaultFailurePolicy - if chart.Spec.FailurePolicy != "" { - failurePolicy = chart.Spec.FailurePolicy + if fp := string(chart.Spec.FailurePolicy); fp != "" { + failurePolicy = fp } // override default backOffLimit if specified @@ -473,8 +473,8 @@ func (c *Controller) getJobAndRelatedResources(chart *v1.HelmChart) (*batch.Job, valuesSecretAddConfig(job, valuesSecret, config) // Override the failure policy to what is provided in the HelmChartConfig - if config.Spec.FailurePolicy != "" { - failurePolicy = config.Spec.FailurePolicy + if fp := string(config.Spec.FailurePolicy); fp != "" { + failurePolicy = fp } // make sure that changes to HelmChart ValuesSecrets triger change to hash diff --git a/pkg/crd/crds.go b/pkg/crd/crds.go deleted file mode 100644 index 1178df80..00000000 --- a/pkg/crd/crds.go +++ /dev/null @@ -1,24 +0,0 @@ -package crd - -import ( - v1 "github.com/k3s-io/helm-controller/pkg/apis/helm.cattle.io/v1" - "github.com/rancher/wrangler/v3/pkg/crd" -) - -func List() []crd.CRD { - chart := crd.NamespacedType("HelmChart.helm.cattle.io/v1"). - WithSchemaFromStruct(v1.HelmChart{}). - WithColumn("Job", ".status.jobName"). - WithColumn("Chart", ".spec.chart"). - WithColumn("TargetNamespace", ".spec.targetNamespace"). - WithColumn("Version", ".spec.version"). - WithColumn("Repo", ".spec.repo"). - WithColumn("HelmVersion", ".spec.helmVersion"). - WithColumn("Bootstrap", ".spec.bootstrap"). - WithStatus() - - config := crd.NamespacedType("HelmChartConfig.helm.cattle.io/v1"). - WithSchemaFromStruct(v1.HelmChartConfig{}) - - return []crd.CRD{chart, config} -} diff --git a/pkg/crds/crds.go b/pkg/crds/crds.go new file mode 100644 index 00000000..35d69792 --- /dev/null +++ b/pkg/crds/crds.go @@ -0,0 +1,84 @@ +package crds + +import ( + "embed" + "fmt" + "path/filepath" + + "github.com/rancher/wrangler/v3/pkg/yaml" + apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" +) + +const ( + baseDir = "." + crdKind = "CustomResourceDefinition" +) + +var ( + //go:embed yaml + crdFS embed.FS + + errDuplicate = fmt.Errorf("duplicate CRD") +) + +func List() ([]*apiextv1.CustomResourceDefinition, error) { + crdMap, err := crdsFromDir(baseDir) + if err != nil { + return nil, err + } + crds := make([]*apiextv1.CustomResourceDefinition, 0, len(crdMap)) + for _, crd := range crdMap { + crds = append(crds, crd) + } + return crds, nil +} + +// crdsFromDir recursively traverses the embedded yaml directory and find all CRD yamls. +// cribbed from https://github.com/rancher/rancher/blob/v2.11.2/pkg/crds/crds.go +func crdsFromDir(dirName string) (map[string]*apiextv1.CustomResourceDefinition, error) { + // read all entries in the embedded directory + crdFiles, err := crdFS.ReadDir(dirName) + if err != nil { + return nil, fmt.Errorf("failed to read embedded dir '%s': %w", dirName, err) + } + + allCRDs := map[string]*apiextv1.CustomResourceDefinition{} + for _, dirEntry := range crdFiles { + fullPath := filepath.Join(dirName, dirEntry.Name()) + if dirEntry.IsDir() { + // if the entry is the dir recurse into that folder to get all crds + subCRDs, err := crdsFromDir(fullPath) + if err != nil { + return nil, err + } + for k, v := range subCRDs { + if _, ok := allCRDs[k]; ok { + return nil, fmt.Errorf("%w for '%s", errDuplicate, k) + } + allCRDs[k] = v + } + continue + } + + // read the file and convert it to a crd object + file, err := crdFS.Open(fullPath) + if err != nil { + return nil, fmt.Errorf("failed to open embedded file '%s': %w", fullPath, err) + } + crdObjs, err := yaml.UnmarshalWithJSONDecoder[*apiextv1.CustomResourceDefinition](file) + if err != nil { + return nil, fmt.Errorf("failed to convert embedded file '%s' to yaml: %w", fullPath, err) + } + for _, crdObj := range crdObjs { + if crdObj.Kind != crdKind { + // if the yaml is not a CRD return an error + return nil, fmt.Errorf("decoded object is not '%s' instead found Kind='%s'", crdKind, crdObj.Kind) + } + if _, ok := allCRDs[crdObj.Name]; ok { + return nil, fmt.Errorf("%w for '%s", errDuplicate, crdObj.Name) + } + allCRDs[crdObj.Name] = crdObj + } + } + return allCRDs, nil +} diff --git a/pkg/crds/yaml/generated/helm.cattle.io_helmchartconfigs.yaml b/pkg/crds/yaml/generated/helm.cattle.io_helmchartconfigs.yaml new file mode 100644 index 00000000..b2deb102 --- /dev/null +++ b/pkg/crds/yaml/generated/helm.cattle.io_helmchartconfigs.yaml @@ -0,0 +1,91 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: helmchartconfigs.helm.cattle.io +spec: + group: helm.cattle.io + names: + kind: HelmChartConfig + listKind: HelmChartConfigList + plural: helmchartconfigs + singular: helmchartconfig + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: |- + HelmChartConfig represents additional configuration for the installation of Helm chart release. + This resource is intended for use when additional configuration needs to be passed to a HelmChart + that is managed by an external system. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + HelmChartConfigSpec represents additional user-configurable details of an installed and configured Helm chart release. + These fields are merged with or override the corresponding fields on the related HelmChart resource. + properties: + failurePolicy: + default: reinstall + description: |- + Configures handling of failed chart installation or upgrades. + - `reinstall` will perform a clean uninstall and reinstall of the chart. + - `abort` will take no action and leave the chart in a failed state so that the administrator can manually resolve the error. + enum: + - abort + - reinstall + type: string + valuesContent: + description: |- + Override complex Chart values via inline YAML content. + Helm CLI positional argument/flag: `--values` + type: string + valuesSecrets: + description: |- + Override complex Chart values via references to external Secrets. + Helm CLI positional argument/flag: `--values` + items: + description: SecretSpec describes a key in a secret to load chart + values from. + properties: + ignoreUpdates: + description: |- + Ignore changes to the secret, and mark the secret as optional. + By default, the secret must exist, and changes to the secret will trigger an upgrade of the chart to apply the updated values. + If `ignoreUpdates` is true, the secret is optional, and changes to the secret will not trigger an upgrade of the chart. + type: boolean + keys: + description: Keys to read values content from. If no keys are + specified, the secret is not used. + items: + type: string + type: array + name: + description: Name of the secret. Must be in the same namespace + as the HelmChart resource. + type: string + type: object + type: array + type: object + type: object + served: true + storage: true diff --git a/pkg/crds/yaml/generated/helm.cattle.io_helmcharts.yaml b/pkg/crds/yaml/generated/helm.cattle.io_helmcharts.yaml new file mode 100644 index 00000000..333aadb4 --- /dev/null +++ b/pkg/crds/yaml/generated/helm.cattle.io_helmcharts.yaml @@ -0,0 +1,700 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: helmcharts.helm.cattle.io +spec: + group: helm.cattle.io + names: + kind: HelmChart + listKind: HelmChartList + plural: helmcharts + singular: helmchart + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.repo + name: Repo + type: string + - jsonPath: .spec.chart + name: Chart + type: string + - jsonPath: .spec.version + name: Version + type: string + - jsonPath: .spec.targetNamespace + name: TargetNamespace + type: string + - jsonPath: .spec.bootstrap + name: Bootstrap + type: boolean + - jsonPath: .status.conditions[?(@.type=='Failed')].status + name: Failed + type: string + - jsonPath: .status.jobName + name: Job + priority: 10 + type: string + name: v1 + schema: + openAPIV3Schema: + description: HelmChart represents configuration and state for the deployment + of a Helm chart. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: HelmChartSpec represents the user-configurable details for + installation and upgrade of a Helm chart release. + properties: + authPassCredentials: + description: |- + Pass Basic auth credentials to all domains. + Helm CLI positional argument/flag: `--pass-credentials` + type: boolean + authSecret: + description: Reference to Secret of type kubernetes.io/basic-auth + holding Basic auth credentials for the Chart repo. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + backOffLimit: + description: Specify the number of retries before considering the + helm job failed. + format: int32 + type: integer + bootstrap: + description: Set to True if this chart is needed to bootstrap the + cluster (Cloud Controller Manager, CNI, etc) + type: boolean + chart: + description: |- + Helm Chart name in repository, or complete HTTPS URL to chart archive (.tgz) + Helm CLI positional argument/flag: `CHART` + type: string + chartContent: + description: |- + Base64-encoded chart archive .tgz; overides `.spec.chart` and `.spec.version` + Helm CLI positional argument/flag: `CHART` + type: string + createNamespace: + description: |- + Create target namespace if not present. + Helm CLI positional argument/flag: `--create-namespace` + type: boolean + dockerRegistrySecret: + description: Reference to Secret of type kubernetes.io/dockerconfigjson + holding Docker auth credentials for the OCI-based registry acting + as the Chart repo. + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + failurePolicy: + default: reinstall + description: |- + Configures handling of failed chart installation or upgrades. + - `reinstall` will perform a clean uninstall and reinstall of the chart. + - `abort` will take no action and leave the chart in a failed state so that the administrator can manually resolve the error. + enum: + - abort + - reinstall + type: string + helmVersion: + description: DEPRECATED. Helm version to use. Only v3 is currently + supported. + type: string + insecureSkipTLSVerify: + description: |- + Skip TLS certificate checks for the chart download. + Helm CLI positional argument/flag: `--insecure-skip-tls-verify` + type: boolean + jobImage: + description: Specify the image to use for tht helm job pod when installing + or upgrading the helm chart. + type: string + plainHTTP: + description: |- + Use insecure HTTP connections for the chart download. + Helm CLI positional argument/flag: `--plain-http` + type: boolean + podSecurityContext: + description: Custom PodSecurityContext for the helm job pod. + properties: + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + fsGroup: + description: |- + A special supplemental group that applies to all containers in a pod. + Some volume types allow the Kubelet to change the ownership of that volume + to be owned by the pod: + + 1. The owning GID will be the FSGroup + 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- + + If unset, the Kubelet will not modify the ownership and permissions of any volume. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + fsGroupChangePolicy: + description: |- + fsGroupChangePolicy defines behavior of changing ownership and permission of the volume + before being exposed inside Pod. This field will only apply to + volume types which support fsGroup based ownership(and permissions). + It will have no effect on ephemeral volume types such as: secret, configmaps + and emptydir. + Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. + Note that this field cannot be set when spec.os.name is windows. + type: string + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence + for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxChangePolicy: + description: |- + seLinuxChangePolicy defines how the container's SELinux label is applied to all volumes used by the Pod. + It has no effect on nodes that do not support SELinux or to volumes does not support SELinux. + Valid values are "MountOption" and "Recursive". + + "Recursive" means relabeling of all files on all Pod volumes by the container runtime. + This may be slow for large volumes, but allows mixing privileged and unprivileged Pods sharing the same volume on the same node. + + "MountOption" mounts all eligible Pod volumes with `-o context` mount option. + This requires all Pods that share the same volume to use the same SELinux label. + It is not possible to share the same volume among privileged and unprivileged Pods. + Eligible volumes are in-tree FibreChannel and iSCSI volumes, and all CSI volumes + whose CSI driver announces SELinux support by setting spec.seLinuxMount: true in their + CSIDriver instance. Other volumes are always re-labelled recursively. + "MountOption" value is allowed only when SELinuxMount feature gate is enabled. + + If not specified and SELinuxMount feature gate is enabled, "MountOption" is used. + If not specified and SELinuxMount feature gate is disabled, "MountOption" is used for ReadWriteOncePod volumes + and "Recursive" for all other volumes. + + This field affects only Pods that have SELinux label set, either in PodSecurityContext or in SecurityContext of all containers. + + All Pods that use the same volume should use the same seLinuxChangePolicy, otherwise some pods can get stuck in ContainerCreating state. + Note that this field cannot be set when spec.os.name is windows. + type: string + seLinuxOptions: + description: |- + The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in SecurityContext. If set in + both SecurityContext and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by the containers in this pod. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + supplementalGroups: + description: |- + A list of groups applied to the first process run in each container, in + addition to the container's primary GID and fsGroup (if specified). If + the SupplementalGroupsPolicy feature is enabled, the + supplementalGroupsPolicy field determines whether these are in addition + to or instead of any group memberships defined in the container image. + If unspecified, no additional groups are added, though group memberships + defined in the container image may still be used, depending on the + supplementalGroupsPolicy field. + Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + description: |- + Defines how supplemental groups of the first container processes are calculated. + Valid values are "Merge" and "Strict". If not specified, "Merge" is used. + (Alpha) Using the field requires the SupplementalGroupsPolicy feature gate to be enabled + and the container runtime must implement support for this feature. + Note that this field cannot be set when spec.os.name is windows. + type: string + sysctls: + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + repo: + description: |- + Helm Chart repository URL. + Helm CLI positional argument/flag: `--repo` + type: string + repoCA: + description: |- + Verify certificates of HTTPS-enabled servers using this CA bundle. Should be a string containing one or more PEM-encoded CA Certificates. + Helm CLI positional argument/flag: `--ca-file` + type: string + repoCAConfigMap: + description: |- + Reference to a ConfigMap containing CA Certificates to be be trusted by Helm. Can be used along with or instead of `.spec.repoCA` + Helm CLI positional argument/flag: `--ca-file` + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + securityContext: + description: custom SecurityContext for the helm job pod. + properties: + allowPrivilegeEscalation: + description: |- + AllowPrivilegeEscalation controls whether a process can gain more + privileges than its parent process. This bool directly controls if + the no_new_privs flag will be set on the container process. + AllowPrivilegeEscalation is true always when the container is: + 1) run as Privileged + 2) has CAP_SYS_ADMIN + Note that this field cannot be set when spec.os.name is windows. + type: boolean + appArmorProfile: + description: |- + appArmorProfile is the AppArmor options to use by this container. If set, this profile + overrides the pod's appArmorProfile. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile loaded on the node that should be used. + The profile must be preconfigured on the node to work. + Must match the loaded name of the profile. + Must be set if and only if type is "Localhost". + type: string + type: + description: |- + type indicates which kind of AppArmor profile will be applied. + Valid options are: + Localhost - a profile pre-loaded on the node. + RuntimeDefault - the container runtime's default profile. + Unconfined - no AppArmor enforcement. + type: string + required: + - type + type: object + capabilities: + description: |- + The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by the container runtime. + Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + description: |- + Run container in privileged mode. + Processes in privileged containers are essentially equivalent to root on the host. + Defaults to false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: |- + procMount denotes the type of proc mount to use for the containers. + The default value is Default which uses the container runtime defaults for + readonly paths and masked paths. + This requires the ProcMountType feature flag to be enabled. + Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: |- + Whether this container has a read-only root filesystem. + Default is false. + Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: |- + The GID to run the entrypoint of the container process. + Uses runtime default if unset. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: |- + Indicates that the container must run as a non-root user. + If true, the Kubelet will validate the image at runtime to ensure that it + does not run as UID 0 (root) and fail to start the container if it does. + If unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: |- + The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: |- + The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a random SELinux context for each + container. May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: |- + The seccomp options to use by this container. If seccomp options are + provided at both the pod & container level, the container options + override the pod options. + Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: |- + localhostProfile indicates a profile defined in a file on the node should be used. + The profile must be preconfigured on the node to work. + Must be a descending path, relative to the kubelet's configured seccomp profile location. + Must be set if type is "Localhost". Must NOT be set for any other type. + type: string + type: + description: |- + type indicates which kind of seccomp profile will be applied. + Valid options are: + + Localhost - a profile defined in a file on the node should be used. + RuntimeDefault - the container runtime default profile should be used. + Unconfined - no profile should be applied. + type: string + required: + - type + type: object + windowsOptions: + description: |- + The Windows specific settings applied to all containers. + If unspecified, the options from the PodSecurityContext will be used. + If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: |- + GMSACredentialSpec is where the GMSA admission webhook + (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the + GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: |- + HostProcess determines if a container should be run as a 'Host Process' container. + All of a Pod's containers must have the same effective HostProcess value + (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). + In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: |- + The UserName in Windows to run the entrypoint of the container process. + Defaults to the user specified in image metadata if unspecified. + May also be set in PodSecurityContext. If set in both SecurityContext and + PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + set: + additionalProperties: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + description: |- + Override simple Chart values. These take precedence over options set via valuesContent. + Helm CLI positional argument/flag: `--set`, `--set-string` + type: object + targetNamespace: + description: |- + Helm Chart target namespace. + Helm CLI positional argument/flag: `--namespace` + type: string + timeout: + description: |- + Timeout for Helm operations. + Helm CLI positional argument/flag: `--timeout` + type: string + valuesContent: + description: |- + Override complex Chart values via inline YAML content. + Helm CLI positional argument/flag: `--values` + type: string + valuesSecrets: + description: |- + Override complex Chart values via references to external Secrets. + Helm CLI positional argument/flag: `--values` + items: + description: SecretSpec describes a key in a secret to load chart + values from. + properties: + ignoreUpdates: + description: |- + Ignore changes to the secret, and mark the secret as optional. + By default, the secret must exist, and changes to the secret will trigger an upgrade of the chart to apply the updated values. + If `ignoreUpdates` is true, the secret is optional, and changes to the secret will not trigger an upgrade of the chart. + type: boolean + keys: + description: Keys to read values content from. If no keys are + specified, the secret is not used. + items: + type: string + type: array + name: + description: Name of the secret. Must be in the same namespace + as the HelmChart resource. + type: string + type: object + type: array + version: + description: |- + Helm Chart version. Only used when installing from repository; ignored when .spec.chart or .spec.chartContent is used to install a specific chart archive. + Helm CLI positional argument/flag: `--version` + type: string + type: object + status: + description: HelmChartStatus represents the resulting state from processing + HelmChart events + properties: + conditions: + description: |- + `JobCreated` indicates that a job has been created to install or upgrade the chart. + `Failed` indicates that the helm job has failed and the failure policy is set to `abort`. + items: + properties: + message: + description: Human readable message indicating details about + last transition. + type: string + reason: + description: (brief) reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of job condition. + type: string + required: + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + jobName: + description: The name of the job created to install or upgrade the + chart. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/pkg/generated/clientset/versioned/clientset.go b/pkg/generated/clientset/versioned/clientset.go index 8712088e..81f46a6e 100644 --- a/pkg/generated/clientset/versioned/clientset.go +++ b/pkg/generated/clientset/versioned/clientset.go @@ -19,8 +19,8 @@ limitations under the License. package versioned import ( - "fmt" - "net/http" + fmt "fmt" + http "net/http" helmv1 "github.com/k3s-io/helm-controller/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1" discovery "k8s.io/client-go/discovery" diff --git a/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/fake/fake_helm.cattle.io_client.go b/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/fake/fake_helm.cattle.io_client.go index 90921882..fa8f616c 100644 --- a/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/fake/fake_helm.cattle.io_client.go +++ b/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/fake/fake_helm.cattle.io_client.go @@ -29,11 +29,11 @@ type FakeHelmV1 struct { } func (c *FakeHelmV1) HelmCharts(namespace string) v1.HelmChartInterface { - return &FakeHelmCharts{c, namespace} + return newFakeHelmCharts(c, namespace) } func (c *FakeHelmV1) HelmChartConfigs(namespace string) v1.HelmChartConfigInterface { - return &FakeHelmChartConfigs{c, namespace} + return newFakeHelmChartConfigs(c, namespace) } // RESTClient returns a RESTClient that is used to communicate diff --git a/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/fake/fake_helmchart.go b/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/fake/fake_helmchart.go index e692b13b..889124aa 100644 --- a/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/fake/fake_helmchart.go +++ b/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/fake/fake_helmchart.go @@ -19,129 +19,30 @@ limitations under the License. package fake import ( - "context" - v1 "github.com/k3s-io/helm-controller/pkg/apis/helm.cattle.io/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" + helmcattleiov1 "github.com/k3s-io/helm-controller/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1" + gentype "k8s.io/client-go/gentype" ) -// FakeHelmCharts implements HelmChartInterface -type FakeHelmCharts struct { +// fakeHelmCharts implements HelmChartInterface +type fakeHelmCharts struct { + *gentype.FakeClientWithList[*v1.HelmChart, *v1.HelmChartList] Fake *FakeHelmV1 - ns string -} - -var helmchartsResource = v1.SchemeGroupVersion.WithResource("helmcharts") - -var helmchartsKind = v1.SchemeGroupVersion.WithKind("HelmChart") - -// Get takes name of the helmChart, and returns the corresponding helmChart object, and an error if there is any. -func (c *FakeHelmCharts) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.HelmChart, err error) { - emptyResult := &v1.HelmChart{} - obj, err := c.Fake. - Invokes(testing.NewGetActionWithOptions(helmchartsResource, c.ns, name, options), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1.HelmChart), err -} - -// List takes label and field selectors, and returns the list of HelmCharts that match those selectors. -func (c *FakeHelmCharts) List(ctx context.Context, opts metav1.ListOptions) (result *v1.HelmChartList, err error) { - emptyResult := &v1.HelmChartList{} - obj, err := c.Fake. - Invokes(testing.NewListActionWithOptions(helmchartsResource, helmchartsKind, c.ns, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1.HelmChartList{ListMeta: obj.(*v1.HelmChartList).ListMeta} - for _, item := range obj.(*v1.HelmChartList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested helmCharts. -func (c *FakeHelmCharts) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewWatchActionWithOptions(helmchartsResource, c.ns, opts)) - -} - -// Create takes the representation of a helmChart and creates it. Returns the server's representation of the helmChart, and an error, if there is any. -func (c *FakeHelmCharts) Create(ctx context.Context, helmChart *v1.HelmChart, opts metav1.CreateOptions) (result *v1.HelmChart, err error) { - emptyResult := &v1.HelmChart{} - obj, err := c.Fake. - Invokes(testing.NewCreateActionWithOptions(helmchartsResource, c.ns, helmChart, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1.HelmChart), err -} - -// Update takes the representation of a helmChart and updates it. Returns the server's representation of the helmChart, and an error, if there is any. -func (c *FakeHelmCharts) Update(ctx context.Context, helmChart *v1.HelmChart, opts metav1.UpdateOptions) (result *v1.HelmChart, err error) { - emptyResult := &v1.HelmChart{} - obj, err := c.Fake. - Invokes(testing.NewUpdateActionWithOptions(helmchartsResource, c.ns, helmChart, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1.HelmChart), err -} - -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeHelmCharts) UpdateStatus(ctx context.Context, helmChart *v1.HelmChart, opts metav1.UpdateOptions) (result *v1.HelmChart, err error) { - emptyResult := &v1.HelmChart{} - obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceActionWithOptions(helmchartsResource, "status", c.ns, helmChart, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1.HelmChart), err -} - -// Delete takes name of the helmChart and deletes it. Returns an error if one occurs. -func (c *FakeHelmCharts) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(helmchartsResource, c.ns, name, opts), &v1.HelmChart{}) - - return err } -// DeleteCollection deletes a collection of objects. -func (c *FakeHelmCharts) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { - action := testing.NewDeleteCollectionActionWithOptions(helmchartsResource, c.ns, opts, listOpts) - - _, err := c.Fake.Invokes(action, &v1.HelmChartList{}) - return err -} - -// Patch applies the patch and returns the patched helmChart. -func (c *FakeHelmCharts) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.HelmChart, err error) { - emptyResult := &v1.HelmChart{} - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceActionWithOptions(helmchartsResource, c.ns, name, pt, data, opts, subresources...), emptyResult) - - if obj == nil { - return emptyResult, err +func newFakeHelmCharts(fake *FakeHelmV1, namespace string) helmcattleiov1.HelmChartInterface { + return &fakeHelmCharts{ + gentype.NewFakeClientWithList[*v1.HelmChart, *v1.HelmChartList]( + fake.Fake, + namespace, + v1.SchemeGroupVersion.WithResource("helmcharts"), + v1.SchemeGroupVersion.WithKind("HelmChart"), + func() *v1.HelmChart { return &v1.HelmChart{} }, + func() *v1.HelmChartList { return &v1.HelmChartList{} }, + func(dst, src *v1.HelmChartList) { dst.ListMeta = src.ListMeta }, + func(list *v1.HelmChartList) []*v1.HelmChart { return gentype.ToPointerSlice(list.Items) }, + func(list *v1.HelmChartList, items []*v1.HelmChart) { list.Items = gentype.FromPointerSlice(items) }, + ), + fake, } - return obj.(*v1.HelmChart), err } diff --git a/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/fake/fake_helmchartconfig.go b/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/fake/fake_helmchartconfig.go index 29d933a8..1590a091 100644 --- a/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/fake/fake_helmchartconfig.go +++ b/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/fake/fake_helmchartconfig.go @@ -19,116 +19,32 @@ limitations under the License. package fake import ( - "context" - v1 "github.com/k3s-io/helm-controller/pkg/apis/helm.cattle.io/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" + helmcattleiov1 "github.com/k3s-io/helm-controller/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1" + gentype "k8s.io/client-go/gentype" ) -// FakeHelmChartConfigs implements HelmChartConfigInterface -type FakeHelmChartConfigs struct { +// fakeHelmChartConfigs implements HelmChartConfigInterface +type fakeHelmChartConfigs struct { + *gentype.FakeClientWithList[*v1.HelmChartConfig, *v1.HelmChartConfigList] Fake *FakeHelmV1 - ns string -} - -var helmchartconfigsResource = v1.SchemeGroupVersion.WithResource("helmchartconfigs") - -var helmchartconfigsKind = v1.SchemeGroupVersion.WithKind("HelmChartConfig") - -// Get takes name of the helmChartConfig, and returns the corresponding helmChartConfig object, and an error if there is any. -func (c *FakeHelmChartConfigs) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.HelmChartConfig, err error) { - emptyResult := &v1.HelmChartConfig{} - obj, err := c.Fake. - Invokes(testing.NewGetActionWithOptions(helmchartconfigsResource, c.ns, name, options), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1.HelmChartConfig), err -} - -// List takes label and field selectors, and returns the list of HelmChartConfigs that match those selectors. -func (c *FakeHelmChartConfigs) List(ctx context.Context, opts metav1.ListOptions) (result *v1.HelmChartConfigList, err error) { - emptyResult := &v1.HelmChartConfigList{} - obj, err := c.Fake. - Invokes(testing.NewListActionWithOptions(helmchartconfigsResource, helmchartconfigsKind, c.ns, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1.HelmChartConfigList{ListMeta: obj.(*v1.HelmChartConfigList).ListMeta} - for _, item := range obj.(*v1.HelmChartConfigList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested helmChartConfigs. -func (c *FakeHelmChartConfigs) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewWatchActionWithOptions(helmchartconfigsResource, c.ns, opts)) - -} - -// Create takes the representation of a helmChartConfig and creates it. Returns the server's representation of the helmChartConfig, and an error, if there is any. -func (c *FakeHelmChartConfigs) Create(ctx context.Context, helmChartConfig *v1.HelmChartConfig, opts metav1.CreateOptions) (result *v1.HelmChartConfig, err error) { - emptyResult := &v1.HelmChartConfig{} - obj, err := c.Fake. - Invokes(testing.NewCreateActionWithOptions(helmchartconfigsResource, c.ns, helmChartConfig, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1.HelmChartConfig), err -} - -// Update takes the representation of a helmChartConfig and updates it. Returns the server's representation of the helmChartConfig, and an error, if there is any. -func (c *FakeHelmChartConfigs) Update(ctx context.Context, helmChartConfig *v1.HelmChartConfig, opts metav1.UpdateOptions) (result *v1.HelmChartConfig, err error) { - emptyResult := &v1.HelmChartConfig{} - obj, err := c.Fake. - Invokes(testing.NewUpdateActionWithOptions(helmchartconfigsResource, c.ns, helmChartConfig, opts), emptyResult) - - if obj == nil { - return emptyResult, err - } - return obj.(*v1.HelmChartConfig), err -} - -// Delete takes name of the helmChartConfig and deletes it. Returns an error if one occurs. -func (c *FakeHelmChartConfigs) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewDeleteActionWithOptions(helmchartconfigsResource, c.ns, name, opts), &v1.HelmChartConfig{}) - - return err } -// DeleteCollection deletes a collection of objects. -func (c *FakeHelmChartConfigs) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { - action := testing.NewDeleteCollectionActionWithOptions(helmchartconfigsResource, c.ns, opts, listOpts) - - _, err := c.Fake.Invokes(action, &v1.HelmChartConfigList{}) - return err -} - -// Patch applies the patch and returns the patched helmChartConfig. -func (c *FakeHelmChartConfigs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.HelmChartConfig, err error) { - emptyResult := &v1.HelmChartConfig{} - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceActionWithOptions(helmchartconfigsResource, c.ns, name, pt, data, opts, subresources...), emptyResult) - - if obj == nil { - return emptyResult, err +func newFakeHelmChartConfigs(fake *FakeHelmV1, namespace string) helmcattleiov1.HelmChartConfigInterface { + return &fakeHelmChartConfigs{ + gentype.NewFakeClientWithList[*v1.HelmChartConfig, *v1.HelmChartConfigList]( + fake.Fake, + namespace, + v1.SchemeGroupVersion.WithResource("helmchartconfigs"), + v1.SchemeGroupVersion.WithKind("HelmChartConfig"), + func() *v1.HelmChartConfig { return &v1.HelmChartConfig{} }, + func() *v1.HelmChartConfigList { return &v1.HelmChartConfigList{} }, + func(dst, src *v1.HelmChartConfigList) { dst.ListMeta = src.ListMeta }, + func(list *v1.HelmChartConfigList) []*v1.HelmChartConfig { return gentype.ToPointerSlice(list.Items) }, + func(list *v1.HelmChartConfigList, items []*v1.HelmChartConfig) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, } - return obj.(*v1.HelmChartConfig), err } diff --git a/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/helm.cattle.io_client.go b/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/helm.cattle.io_client.go index 8b28d681..e8ae97de 100644 --- a/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/helm.cattle.io_client.go +++ b/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/helm.cattle.io_client.go @@ -19,10 +19,10 @@ limitations under the License. package v1 import ( - "net/http" + http "net/http" - v1 "github.com/k3s-io/helm-controller/pkg/apis/helm.cattle.io/v1" - "github.com/k3s-io/helm-controller/pkg/generated/clientset/versioned/scheme" + helmcattleiov1 "github.com/k3s-io/helm-controller/pkg/apis/helm.cattle.io/v1" + scheme "github.com/k3s-io/helm-controller/pkg/generated/clientset/versioned/scheme" rest "k8s.io/client-go/rest" ) @@ -90,10 +90,10 @@ func New(c rest.Interface) *HelmV1Client { } func setConfigDefaults(config *rest.Config) error { - gv := v1.SchemeGroupVersion + gv := helmcattleiov1.SchemeGroupVersion config.GroupVersion = &gv config.APIPath = "/apis" - config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion() if config.UserAgent == "" { config.UserAgent = rest.DefaultKubernetesUserAgent() diff --git a/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/helmchart.go b/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/helmchart.go index ec300c78..998f7be7 100644 --- a/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/helmchart.go +++ b/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/helmchart.go @@ -19,9 +19,9 @@ limitations under the License. package v1 import ( - "context" + context "context" - v1 "github.com/k3s-io/helm-controller/pkg/apis/helm.cattle.io/v1" + helmcattleiov1 "github.com/k3s-io/helm-controller/pkg/apis/helm.cattle.io/v1" scheme "github.com/k3s-io/helm-controller/pkg/generated/clientset/versioned/scheme" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" @@ -37,33 +37,34 @@ type HelmChartsGetter interface { // HelmChartInterface has methods to work with HelmChart resources. type HelmChartInterface interface { - Create(ctx context.Context, helmChart *v1.HelmChart, opts metav1.CreateOptions) (*v1.HelmChart, error) - Update(ctx context.Context, helmChart *v1.HelmChart, opts metav1.UpdateOptions) (*v1.HelmChart, error) + Create(ctx context.Context, helmChart *helmcattleiov1.HelmChart, opts metav1.CreateOptions) (*helmcattleiov1.HelmChart, error) + Update(ctx context.Context, helmChart *helmcattleiov1.HelmChart, opts metav1.UpdateOptions) (*helmcattleiov1.HelmChart, error) // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). - UpdateStatus(ctx context.Context, helmChart *v1.HelmChart, opts metav1.UpdateOptions) (*v1.HelmChart, error) + UpdateStatus(ctx context.Context, helmChart *helmcattleiov1.HelmChart, opts metav1.UpdateOptions) (*helmcattleiov1.HelmChart, error) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error - Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.HelmChart, error) - List(ctx context.Context, opts metav1.ListOptions) (*v1.HelmChartList, error) + Get(ctx context.Context, name string, opts metav1.GetOptions) (*helmcattleiov1.HelmChart, error) + List(ctx context.Context, opts metav1.ListOptions) (*helmcattleiov1.HelmChartList, error) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.HelmChart, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *helmcattleiov1.HelmChart, err error) HelmChartExpansion } // helmCharts implements HelmChartInterface type helmCharts struct { - *gentype.ClientWithList[*v1.HelmChart, *v1.HelmChartList] + *gentype.ClientWithList[*helmcattleiov1.HelmChart, *helmcattleiov1.HelmChartList] } // newHelmCharts returns a HelmCharts func newHelmCharts(c *HelmV1Client, namespace string) *helmCharts { return &helmCharts{ - gentype.NewClientWithList[*v1.HelmChart, *v1.HelmChartList]( + gentype.NewClientWithList[*helmcattleiov1.HelmChart, *helmcattleiov1.HelmChartList]( "helmcharts", c.RESTClient(), scheme.ParameterCodec, namespace, - func() *v1.HelmChart { return &v1.HelmChart{} }, - func() *v1.HelmChartList { return &v1.HelmChartList{} }), + func() *helmcattleiov1.HelmChart { return &helmcattleiov1.HelmChart{} }, + func() *helmcattleiov1.HelmChartList { return &helmcattleiov1.HelmChartList{} }, + ), } } diff --git a/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/helmchartconfig.go b/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/helmchartconfig.go index 5809a084..bf851fd3 100644 --- a/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/helmchartconfig.go +++ b/pkg/generated/clientset/versioned/typed/helm.cattle.io/v1/helmchartconfig.go @@ -19,9 +19,9 @@ limitations under the License. package v1 import ( - "context" + context "context" - v1 "github.com/k3s-io/helm-controller/pkg/apis/helm.cattle.io/v1" + helmcattleiov1 "github.com/k3s-io/helm-controller/pkg/apis/helm.cattle.io/v1" scheme "github.com/k3s-io/helm-controller/pkg/generated/clientset/versioned/scheme" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" @@ -37,31 +37,32 @@ type HelmChartConfigsGetter interface { // HelmChartConfigInterface has methods to work with HelmChartConfig resources. type HelmChartConfigInterface interface { - Create(ctx context.Context, helmChartConfig *v1.HelmChartConfig, opts metav1.CreateOptions) (*v1.HelmChartConfig, error) - Update(ctx context.Context, helmChartConfig *v1.HelmChartConfig, opts metav1.UpdateOptions) (*v1.HelmChartConfig, error) + Create(ctx context.Context, helmChartConfig *helmcattleiov1.HelmChartConfig, opts metav1.CreateOptions) (*helmcattleiov1.HelmChartConfig, error) + Update(ctx context.Context, helmChartConfig *helmcattleiov1.HelmChartConfig, opts metav1.UpdateOptions) (*helmcattleiov1.HelmChartConfig, error) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error - Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.HelmChartConfig, error) - List(ctx context.Context, opts metav1.ListOptions) (*v1.HelmChartConfigList, error) + Get(ctx context.Context, name string, opts metav1.GetOptions) (*helmcattleiov1.HelmChartConfig, error) + List(ctx context.Context, opts metav1.ListOptions) (*helmcattleiov1.HelmChartConfigList, error) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) - Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.HelmChartConfig, err error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *helmcattleiov1.HelmChartConfig, err error) HelmChartConfigExpansion } // helmChartConfigs implements HelmChartConfigInterface type helmChartConfigs struct { - *gentype.ClientWithList[*v1.HelmChartConfig, *v1.HelmChartConfigList] + *gentype.ClientWithList[*helmcattleiov1.HelmChartConfig, *helmcattleiov1.HelmChartConfigList] } // newHelmChartConfigs returns a HelmChartConfigs func newHelmChartConfigs(c *HelmV1Client, namespace string) *helmChartConfigs { return &helmChartConfigs{ - gentype.NewClientWithList[*v1.HelmChartConfig, *v1.HelmChartConfigList]( + gentype.NewClientWithList[*helmcattleiov1.HelmChartConfig, *helmcattleiov1.HelmChartConfigList]( "helmchartconfigs", c.RESTClient(), scheme.ParameterCodec, namespace, - func() *v1.HelmChartConfig { return &v1.HelmChartConfig{} }, - func() *v1.HelmChartConfigList { return &v1.HelmChartConfigList{} }), + func() *helmcattleiov1.HelmChartConfig { return &helmcattleiov1.HelmChartConfig{} }, + func() *helmcattleiov1.HelmChartConfigList { return &helmcattleiov1.HelmChartConfigList{} }, + ), } } diff --git a/scripts/package b/scripts/package index 195089ef..48855ffe 100755 --- a/scripts/package +++ b/scripts/package @@ -19,7 +19,7 @@ reset-kustomization() { if [ "$ARCH" = "amd64" ]; then trap reset-kustomization EXIT - go run hack/crdgen.go > manifests/crd.yaml + cat ./pkg/crds/yaml/*/* > manifests/crd.yaml kustomize edit set image "rancher/helm-controller=${REPO}/helm-controller:${VERSION}" kustomize build > ./dist/artifacts/deploy-cluster-scoped.yaml diff --git a/test/framework/controller.go b/test/framework/controller.go index 0b1f60e1..9b7f1ef7 100644 --- a/test/framework/controller.go +++ b/test/framework/controller.go @@ -6,6 +6,7 @@ import ( "time" "github.com/k3s-io/helm-controller/pkg/controllers/chart" + "github.com/rancher/wrangler/v3/pkg/crd" "github.com/sirupsen/logrus" v1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -32,7 +33,7 @@ func (f *Framework) setupController(ctx context.Context) error { return err } - if err := f.crdFactory.BatchCreateCRDs(ctx, f.crds...).BatchWait(); err != nil { + if err := crd.BatchCreateCRDs(ctx, f.ClientExt.ApiextensionsV1().CustomResourceDefinitions(), nil, time.Minute, f.crds); err != nil { return err } @@ -195,7 +196,7 @@ func (f *Framework) teardownController(ctx context.Context) error { return err } - err = f.crdFactory.CRDClient.ApiextensionsV1().CustomResourceDefinitions().Delete(ctx, chart.CRDName, metav1.DeleteOptions{}) + err = f.ClientExt.ApiextensionsV1().CustomResourceDefinitions().Delete(ctx, chart.CRDName, metav1.DeleteOptions{}) if err != nil && !errors.IsNotFound(err) { return err } diff --git a/test/framework/framework.go b/test/framework/framework.go index bda7e65b..507909bd 100644 --- a/test/framework/framework.go +++ b/test/framework/framework.go @@ -13,14 +13,15 @@ import ( v1 "github.com/k3s-io/helm-controller/pkg/apis/helm.cattle.io/v1" "github.com/k3s-io/helm-controller/pkg/controllers/common" - helmcrd "github.com/k3s-io/helm-controller/pkg/crd" + helmcrd "github.com/k3s-io/helm-controller/pkg/crds" helmcln "github.com/k3s-io/helm-controller/pkg/generated/clientset/versioned" "github.com/onsi/ginkgo/v2" "github.com/rancher/wrangler/v3/pkg/condition" - "github.com/rancher/wrangler/v3/pkg/crd" "github.com/sirupsen/logrus" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" + apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + extclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -37,8 +38,8 @@ var ( type Framework struct { HelmClientSet *helmcln.Clientset ClientSet *kubernetes.Clientset - crdFactory *crd.Factory - crds []crd.CRD + ClientExt *extclient.Clientset + crds []*apiextv1.CustomResourceDefinition Kubeconfig string Name string Namespace string @@ -96,14 +97,14 @@ func (f *Framework) beforeFramework() { errExit("Failed to initiate helm client", err) clientset, err := kubernetes.NewForConfig(config) errExit("Failed to initiate a client set", err) - crdFactory, err := crd.NewFactoryFromClient(config) - errExit("Failed initiate factory client", err) - f.crds = helmcrd.List() - errExit("Failed to construct helm crd", err) + clientext, err := extclient.NewForConfig(config) + errExit("Failed to initiate a extension-apiserver client set", err) + f.crds, err = helmcrd.List() + errExit("Failed to construct helm crds", err) f.HelmClientSet = helmcln f.ClientSet = clientset - f.crdFactory = crdFactory + f.ClientExt = clientext f.Name = common.Name f.Namespace = common.Name