From bee448f901c2d10718c84ff7a02c515b636bcc3c Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 15:14:37 +0300 Subject: [PATCH 01/19] feat(tools): rename an upstream flux crd into the internal one Every identity is addressed by path rather than replaced as text: a document's descriptions must survive untouched, and a textual pass over thousands of lines would be impossible to review. Signed-off-by: Ilya Drey --- tools/internalcrds/go.mod | 3 + tools/internalcrds/rename.go | 147 +++++++++++++++++++++++++++++ tools/internalcrds/rename_test.go | 150 ++++++++++++++++++++++++++++++ 3 files changed, 300 insertions(+) create mode 100644 tools/internalcrds/go.mod create mode 100644 tools/internalcrds/rename.go create mode 100644 tools/internalcrds/rename_test.go diff --git a/tools/internalcrds/go.mod b/tools/internalcrds/go.mod new file mode 100644 index 00000000..52fb642e --- /dev/null +++ b/tools/internalcrds/go.mod @@ -0,0 +1,3 @@ +module github.com/deckhouse/operator-helm/tools/internalcrds + +go 1.26.3 diff --git a/tools/internalcrds/rename.go b/tools/internalcrds/rename.go new file mode 100644 index 00000000..a9cb2f3b --- /dev/null +++ b/tools/internalcrds/rename.go @@ -0,0 +1,147 @@ +/* +Copyright 2026 Flant JSC. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "errors" + "fmt" + "slices" + "strings" +) + +// internalPrefix is where every upstream flux group is mapped to. It matches the +// prefix the api rewriter uses, and the two must never diverge: a resource the +// proxy renames to a group no CustomResourceDefinition declares is simply not +// found, and that only shows up against a live cluster. +const internalPrefix = "internal.operator-helm.deckhouse.io" + +// InternalGroup maps an upstream flux API group to the internal one this module +// serves. Anything but the two flux groups is a programming error: the generator +// is fed a fixed list of upstream CustomResourceDefinitions. +func InternalGroup(group string) string { + switch group { + case "source.toolkit.fluxcd.io": + return "source." + internalPrefix + case "helm.toolkit.fluxcd.io": + return "helm." + internalPrefix + default: + return "" + } +} + +// upstreamKinds lists every kind the two upstream controllers declare, so a +// reference inside a schema can be recognised and renamed. A kind missing here +// silently stays unrenamed, which is why Rename fails on an unknown group +// rather than guessing. +var upstreamKinds = []string{ + "Bucket", + "ExternalArtifact", + "GitRepository", + "HelmChart", + "HelmRelease", + "HelmRepository", + "OCIRepository", +} + +// kindPrefix is prepended to every upstream kind. It carries the word "Nelm" +// for historical reasons: these are the names of live objects in every cluster +// running the module, and moving them would be a migration of its own. +const kindPrefix = "InternalNelmOperator" + +// Rename turns one upstream CustomResourceDefinition into the internal one this +// module serves. Everything it touches is addressed by path: the group, the +// names block, the object name, and the kind references inside the schemas. +// Descriptions and any other free text are left exactly as upstream wrote them. +func Rename(doc map[string]any) error { + spec, ok := doc["spec"].(map[string]any) + if !ok { + return errors.New("the document has no spec") + } + + group, _ := spec["group"].(string) + internal := InternalGroup(group) + if internal == "" { + return fmt.Errorf("unexpected api group %q", group) + } + spec["group"] = internal + + names, ok := spec["names"].(map[string]any) + if !ok { + return errors.New("the document has no spec.names") + } + + kind, _ := names["kind"].(string) + names["kind"] = kindPrefix + kind + if listKind, ok := names["listKind"].(string); ok { + names["listKind"] = kindPrefix + listKind + } + + plural, _ := names["plural"].(string) + names["plural"] = strings.ToLower(kindPrefix) + plural + if singular, ok := names["singular"].(string); ok { + names["singular"] = strings.ToLower(kindPrefix) + singular + } + + // Service objects: nobody types them, and the upstream values would take + // "hr", "hc" and the "all" category away from a real flux in the cluster. + delete(names, "shortNames") + delete(names, "categories") + + metadata, ok := doc["metadata"].(map[string]any) + if !ok { + return errors.New("the document has no metadata") + } + metadata["name"] = names["plural"].(string) + "." + internal + metadata["labels"] = map[string]any{ + "backup.deckhouse.io/cluster-config": "true", + "heritage": "deckhouse", + "module": "operator-helm", + } + + renameKindReferences(spec) + + return nil +} + +// renameKindReferences walks the schemas and renames every value that names an +// upstream kind. Those live in sourceRef and chartRef at several depths, as a +// default, as an enum entry, or as an example, so the walk is over the whole +// tree rather than a fixed list of paths. +func renameKindReferences(node any) { + switch typed := node.(type) { + case map[string]any: + for key, value := range typed { + if str, ok := value.(string); ok && key == "kind" && slices.Contains(upstreamKinds, str) { + typed[key] = kindPrefix + str + + continue + } + + renameKindReferences(value) + } + case []any: + for i, value := range typed { + if str, ok := value.(string); ok && slices.Contains(upstreamKinds, str) { + typed[i] = kindPrefix + str + + continue + } + + renameKindReferences(value) + } + } +} diff --git a/tools/internalcrds/rename_test.go b/tools/internalcrds/rename_test.go new file mode 100644 index 00000000..1f7c4a75 --- /dev/null +++ b/tools/internalcrds/rename_test.go @@ -0,0 +1,150 @@ +/* +Copyright 2026 Flant JSC. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "reflect" + "testing" +) + +func TestInternalGroup(t *testing.T) { + cases := map[string]string{ + "source.toolkit.fluxcd.io": "source.internal.operator-helm.deckhouse.io", + "helm.toolkit.fluxcd.io": "helm.internal.operator-helm.deckhouse.io", + } + + for in, want := range cases { + if got := InternalGroup(in); got != want { + t.Fatalf("InternalGroup(%q) = %q, want %q", in, got, want) + } + } +} + +func TestRenameRewritesEveryIdentity(t *testing.T) { + doc := map[string]any{ + "apiVersion": "apiextensions.k8s.io/v1", + "kind": "CustomResourceDefinition", + "metadata": map[string]any{ + "name": "helmreleases.helm.toolkit.fluxcd.io", + }, + "spec": map[string]any{ + "group": "helm.toolkit.fluxcd.io", + "names": map[string]any{ + "kind": "HelmRelease", + "listKind": "HelmReleaseList", + "plural": "helmreleases", + "singular": "helmrelease", + "shortNames": []any{"hr"}, + "categories": []any{"all", "fluxcd"}, + }, + }, + } + + if err := Rename(doc); err != nil { + t.Fatalf("Rename returned %v", err) + } + + spec := doc["spec"].(map[string]any) + names := spec["names"].(map[string]any) + meta := doc["metadata"].(map[string]any) + + if got := spec["group"]; got != "helm.internal.operator-helm.deckhouse.io" { + t.Fatalf("group = %v", got) + } + if got := names["kind"]; got != "InternalNelmOperatorHelmRelease" { + t.Fatalf("kind = %v", got) + } + if got := names["listKind"]; got != "InternalNelmOperatorHelmReleaseList" { + t.Fatalf("listKind = %v", got) + } + if got := names["plural"]; got != "internalnelmoperatorhelmreleases" { + t.Fatalf("plural = %v", got) + } + if got := names["singular"]; got != "internalnelmoperatorhelmrelease" { + t.Fatalf("singular = %v", got) + } + if got := meta["name"]; got != "internalnelmoperatorhelmreleases.helm.internal.operator-helm.deckhouse.io" { + t.Fatalf("metadata.name = %v", got) + } + + // Short names and categories are dropped rather than renamed: these are + // service objects, and the upstream values would collide with a real flux. + if _, ok := names["shortNames"]; ok { + t.Fatal("shortNames must be gone") + } + if _, ok := names["categories"]; ok { + t.Fatal("categories must be gone") + } +} + +func TestRenameRewritesNestedReferences(t *testing.T) { + doc := map[string]any{ + "spec": map[string]any{ + "group": "helm.toolkit.fluxcd.io", + "names": map[string]any{"kind": "HelmRelease", "plural": "helmreleases", "singular": "helmrelease"}, + "versions": []any{map[string]any{ + "schema": map[string]any{"openAPIV3Schema": map[string]any{ + "properties": map[string]any{"spec": map[string]any{ + "properties": map[string]any{"chartRef": map[string]any{ + "properties": map[string]any{ + "kind": map[string]any{ + "enum": []any{"OCIRepository", "HelmChart"}, + }, + }, + }}, + }}, + }}, + }}, + }, + "metadata": map[string]any{"name": "helmreleases.helm.toolkit.fluxcd.io"}, + } + + if err := Rename(doc); err != nil { + t.Fatalf("Rename returned %v", err) + } + + enum := doc["spec"].(map[string]any)["versions"].([]any)[0].(map[string]any)["schema"].(map[string]any)["openAPIV3Schema"].(map[string]any)["properties"].(map[string]any)["spec"].(map[string]any)["properties"].(map[string]any)["chartRef"].(map[string]any)["properties"].(map[string]any)["kind"].(map[string]any)["enum"].([]any) + + want := []any{"InternalNelmOperatorOCIRepository", "InternalNelmOperatorHelmChart"} + if !reflect.DeepEqual(enum, want) { + t.Fatalf("chartRef kind enum = %v, want %v", enum, want) + } +} + +func TestRenameLeavesUnrelatedStringsAlone(t *testing.T) { + doc := map[string]any{ + "spec": map[string]any{ + "group": "source.toolkit.fluxcd.io", + "names": map[string]any{"kind": "HelmChart", "plural": "helmcharts", "singular": "helmchart"}, + "versions": []any{map[string]any{ + "schema": map[string]any{"openAPIV3Schema": map[string]any{ + "description": "HelmChart is the Schema for the helmcharts API.", + }}, + }}, + }, + "metadata": map[string]any{"name": "helmcharts.source.toolkit.fluxcd.io"}, + } + + if err := Rename(doc); err != nil { + t.Fatalf("Rename returned %v", err) + } + + got := doc["spec"].(map[string]any)["versions"].([]any)[0].(map[string]any)["schema"].(map[string]any)["openAPIV3Schema"].(map[string]any)["description"] + if got != "HelmChart is the Schema for the helmcharts API." { + t.Fatalf("description was rewritten: %v", got) + } +} From a04ebd9bbce6baafcad6ba2fc4010c1898560569 Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 15:31:42 +0300 Subject: [PATCH 02/19] feat(tools): generate the internal definitions from upstream flux They were written by hand once, from the fork's output. Deriving them from a pinned upstream tag makes the next version bump a tag change, and lets a reviewer check the rename table instead of seven thousand lines of yaml. The generator also fails if any rendered document still names an upstream flux group, so a kind or nested group a future flux release adds in a place the rename table does not yet cover cannot slip through silently. Signed-off-by: Ilya Drey --- .github/workflows/lint.yaml | 3 + Taskfile.yaml | 27 + crds/embedded/helm-controller.yaml | 1710 ++------- crds/embedded/nelm-source-controller.yaml | 4165 --------------------- crds/embedded/source-controller.yaml | 2140 +++++++++++ tools/internalcrds/go.mod | 2 + tools/internalcrds/go.sum | 4 + tools/internalcrds/main.go | 158 + tools/internalcrds/main_test.go | 41 + 9 files changed, 2596 insertions(+), 5654 deletions(-) delete mode 100644 crds/embedded/nelm-source-controller.yaml create mode 100644 crds/embedded/source-controller.yaml create mode 100644 tools/internalcrds/go.sum create mode 100644 tools/internalcrds/main.go create mode 100644 tools/internalcrds/main_test.go diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 96d12c3b..560f8ee0 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -46,6 +46,9 @@ jobs: - name: Verify the generated files are committed run: task --yes ci:generate:api + - name: Verify the internal definitions are committed + run: task --yes ci:generate:internal-crds + lint: runs-on: [self-hosted, large] name: Lint diff --git a/Taskfile.yaml b/Taskfile.yaml index 754d9a2f..8e585e3a 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -59,6 +59,33 @@ tasks: cmds: - task: api:ci:generate + generate:internal-crds: + desc: "Regenerate the internal CustomResourceDefinitions from upstream flux." + vars: + helmControllerTag: v1.6.4 + sourceControllerTag: v1.9.5 + cmds: + - | + set -eu + work=$(mktemp -d) + trap 'rm -rf "$work"' EXIT + git clone --quiet --depth 1 --branch {{.helmControllerTag}} \ + https://github.com/fluxcd/helm-controller "$work/helm-controller" + git clone --quiet --depth 1 --branch {{.sourceControllerTag}} \ + https://github.com/fluxcd/source-controller "$work/source-controller" + cd tools/internalcrds + go run . -out ../../crds/embedded/helm-controller.yaml \ + "$work/helm-controller/config/crd/bases" + go run . -out ../../crds/embedded/source-controller.yaml \ + "$work/source-controller/config/crd/bases" + + ci:generate:internal-crds: + desc: "Regenerate the internal CustomResourceDefinitions and verify they are committed." + cmds: + - task: generate:internal-crds + - | + git diff --exit-code crds/embedded || (echo "Please run task generate:internal-crds and commit changes" && exit 1) + # The shared deps task installs golangci-lint through the upstream install.sh, # whose checksum lookup is an unanchored grep: releases now ship an SBOM entry # next to the archive, both lines match, and the verification fails for every diff --git a/crds/embedded/helm-controller.yaml b/crds/embedded/helm-controller.yaml index 20bd22c6..facf6740 100644 --- a/crds/embedded/helm-controller.yaml +++ b/crds/embedded/helm-controller.yaml @@ -1,8 +1,10 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.19.0 + controller-gen.kubebuilder.io/version: v0.21.0 + kustomize.toolkit.fluxcd.io/substitute: disabled labels: backup.deckhouse.io/cluster-config: "true" heritage: deckhouse @@ -58,9 +60,7 @@ spec: for this HelmRelease. properties: metadata: - description: - ObjectMeta holds the template for metadata like labels - and annotations. + description: ObjectMeta holds the template for metadata like labels and annotations. properties: annotations: additionalProperties: @@ -81,21 +81,15 @@ spec: type: object type: object spec: - description: - Spec holds the template for the v1.HelmChartSpec - for this HelmRelease. + description: Spec holds the template for the v1.HelmChartSpec for this HelmRelease. properties: chart: - description: - The name or path the Helm chart is available - at in the SourceRef. + description: The name or path the Helm chart is available at in the SourceRef. maxLength: 2048 minLength: 1 type: string ignoreMissingValuesFiles: - description: - IgnoreMissingValuesFiles controls whether to - silently ignore missing values files rather than failing. + description: IgnoreMissingValuesFiles controls whether to silently ignore missing values files rather than failing. type: boolean interval: description: |- @@ -115,9 +109,7 @@ spec: - Revision type: string sourceRef: - description: - The name and namespace of the v1.Source the chart - is available at. + description: The name and namespace of the v1.Source the chart is available at. properties: apiVersion: description: APIVersion of the referent. @@ -163,9 +155,7 @@ spec: properties: provider: default: cosign - description: - Provider specifies the technology used to - sign the OCI Helm chart. + description: Provider specifies the technology used to sign the OCI Helm chart. enum: - cosign - notation @@ -185,7 +175,7 @@ spec: - provider type: object version: - default: "*" + default: '*' description: |- Version semver expression, ignored for charts from v1.GitRepository and v1beta2.Bucket sources. Defaults to latest when omitted. @@ -251,17 +241,17 @@ spec: references to HelmRelease resources that must be ready before this HelmRelease can be reconciled. items: - description: - DependencyReference defines a HelmRelease dependency - on another HelmRelease resource. + description: |- + DependencyReference contains enough information to locate the referenced Kubernetes resource object + and optional CEL expression to assess its readiness. properties: name: description: Name of the referent. type: string namespace: description: |- - Namespace of the referent, defaults to the namespace of the HelmRelease - resource object that contains the reference. + Namespace of the referent, defaults to the namespace of the resource + object that contains the reference. type: string readyExpr: description: |- @@ -357,10 +347,44 @@ spec: - disabled type: string type: object + healthCheckExprs: + description: |- + HealthCheckExprs is a list of healthcheck expressions for evaluating the + health of custom resources using Common Expression Language (CEL). + The expressions are evaluated only when the specific Helm action + taking place has wait enabled, i.e. DisableWait is false, and the + 'poller' WaitStrategy is used. + items: + description: CustomHealthCheck defines the health check for custom resources. + properties: + apiVersion: + description: APIVersion of the custom resource under evaluation. + type: string + current: + description: |- + Current is the CEL expression that determines if the status + of the custom resource has reached the desired state. + type: string + failed: + description: |- + Failed is the CEL expression that determines if the status + of the custom resource has failed to reach the desired state. + type: string + inProgress: + description: |- + InProgress is the CEL expression that determines if the status + of the custom resource has not yet reached the desired state. + type: string + kind: + description: Kind of the custom resource under evaluation. + type: string + required: + - apiVersion + - current + type: object + type: array install: - description: - Install holds the configuration for Helm install actions - for this HelmRelease. + description: Install holds the configuration for Helm install actions for this HelmRelease. properties: crds: description: |- @@ -392,9 +416,7 @@ spec: On uninstall, the namespace will not be garbage collected. type: boolean disableHooks: - description: - DisableHooks prevents hooks from running during the - Helm install action. + description: DisableHooks prevents hooks from running during the Helm install action. type: boolean disableOpenAPIValidation: description: |- @@ -449,6 +471,11 @@ spec: Replace tells the Helm install action to re-use the 'ReleaseName', but only if that name is a deleted release which remains in the history. type: boolean + serverSideApply: + description: |- + ServerSideApply enables server-side apply for resources during install. + Defaults to true (or false when UseHelm3Defaults feature gate is enabled). + type: boolean skipCRDs: description: |- SkipCRDs tells the Helm install action to not install any CRDs. By default, @@ -459,7 +486,8 @@ spec: strategy: description: |- Strategy defines the install strategy to use for this HelmRelease. - Defaults to 'RemediateOnFailure'. + Defaults to 'RemediateOnFailure', or 'RetryOnFailure' when the + DefaultToRetryOnFailure feature gate is enabled. properties: name: description: Name of the install strategy. @@ -479,7 +507,7 @@ spec: type: object x-kubernetes-validations: - message: .retryInterval cannot be set when .name is 'RemediateOnFailure' - rule: "!has(self.retryInterval) || self.name != 'RemediateOnFailure'" + rule: '!has(self.retryInterval) || self.name != ''RemediateOnFailure''' timeout: description: |- Timeout is the time to wait for any individual Kubernetes operation (like @@ -552,9 +580,7 @@ spec: Kubernetes resources. Supported only for the generic provider. properties: key: - description: - Key in the Secret, when not specified an implementation-specific - default key is used. + description: Key in the Secret, when not specified an implementation-specific default key is used. type: string name: description: Name of the Secret. @@ -564,14 +590,10 @@ spec: type: object type: object x-kubernetes-validations: - - message: - exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef - must be specified + - message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef must be specified rule: has(self.configMapRef) || has(self.secretRef) - - message: - exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef - must be specified - rule: "!has(self.configMapRef) || !has(self.secretRef)" + - message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef must be specified + rule: '!has(self.configMapRef) || !has(self.secretRef)' maxHistory: description: |- MaxHistory is the number of revisions saved by Helm for this HelmRelease. @@ -591,6 +613,18 @@ spec: If not set, it defaults to true. type: boolean + postRenderStrategy: + description: |- + PostRenderStrategy defines the strategy for sending hooks to post-renderers. + Valid values are 'nohooks' (hooks not sent to post-renderers, Helm 3 behavior), + 'combined' (hooks and templates sent together, Helm 4 default), and 'separate' + (hooks and templates sent in separate streams, Helm 4.2 opt-in). + Defaults to 'combined', or 'nohooks' when the UseHelm3Defaults feature gate is enabled. + enum: + - nohooks + - combined + - separate + type: string postRenderers: description: |- PostRenderers holds an array of Helm PostRenderers, which will be applied in order @@ -607,10 +641,7 @@ spec: for changing image names, tags or digests. This can also be achieved with a patch, but this operator is simpler to specify. items: - description: - Image contains an image name, a new name, - a new tag or digest, which will replace the original - name and tag. + description: Image contains an image name, a new name, a new tag or digest, which will replace the original name and tag. properties: digest: description: |- @@ -621,14 +652,10 @@ spec: description: Name is a tag-less image name. type: string newName: - description: - NewName is the value used to replace - the original name. + description: NewName is the value used to replace the original name. type: string newTag: - description: - NewTag is the value used to replace the - original tag. + description: NewTag is the value used to replace the original tag. type: string required: - name @@ -649,9 +676,7 @@ spec: an array of operation objects. type: string target: - description: - Target points to the resources that the - patch document should be applied to. + description: Target points to the resources that the patch document should be applied to. properties: annotationSelector: description: |- @@ -706,9 +731,7 @@ spec: minLength: 1 type: string rollback: - description: - Rollback holds the configuration for Helm rollback actions - for this HelmRelease. + description: Rollback holds the configuration for Helm rollback actions for this HelmRelease. properties: cleanupOnFail: description: |- @@ -716,9 +739,7 @@ spec: rollback action when it fails. type: boolean disableHooks: - description: - DisableHooks prevents hooks from running during the - Helm rollback action. + description: DisableHooks prevents hooks from running during the Helm rollback action. type: boolean disableWait: description: |- @@ -731,15 +752,35 @@ spec: rollback has been performed. type: boolean force: - description: - Force forces resource updates through a replacement - strategy. + description: |- + Force forces resource updates through a replacement strategy + that avoids 3-way merge conflicts on client-side apply. + This field is ignored for server-side apply (which always + forces conflicts with other field managers). type: boolean recreate: - description: - Recreate performs pod restarts for the resource if - applicable. + description: |- + Recreate performs pod restarts for any managed workloads. + + Deprecated: This behavior was deprecated in Helm 3: + - Deprecation: https://github.com/helm/helm/pull/6463 + - Removal: https://github.com/helm/helm/pull/31023 + After helm-controller was upgraded to the Helm 4 SDK, + this field is no longer functional and will print a + warning if set to true. It will also be removed in a + future release. type: boolean + serverSideApply: + description: |- + ServerSideApply enables server-side apply for resources during rollback. + Can be "enabled", "disabled", or "auto". + When "auto", server-side apply usage will be based on the release's previous usage. + Defaults to "auto". + enum: + - enabled + - disabled + - auto + type: string timeout: description: |- Timeout is the time to wait for any individual Kubernetes operation (like @@ -775,9 +816,7 @@ spec: minLength: 1 type: string test: - description: - Test holds the configuration for Helm test actions for - this HelmRelease. + description: Test holds the configuration for Helm test actions for this HelmRelease. properties: enable: description: |- @@ -785,18 +824,12 @@ spec: or upgrade action has been performed. type: boolean filters: - description: - Filters is a list of tests to run or exclude from - running. + description: Filters is a list of tests to run or exclude from running. items: - description: - Filter holds the configuration for individual Helm - test filters. + description: Filter holds the configuration for individual Helm test filters. properties: exclude: - description: - Exclude specifies whether the named test should - be excluded. + description: Exclude specifies whether the named test should be excluded. type: boolean name: description: Name is the name of the test. @@ -827,9 +860,7 @@ spec: pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ type: string uninstall: - description: - Uninstall holds the configuration for Helm uninstall - actions for this HelmRelease. + description: Uninstall holds the configuration for Helm uninstall actions for this HelmRelease. properties: deletionPropagation: default: background @@ -842,9 +873,7 @@ spec: - orphan type: string disableHooks: - description: - DisableHooks prevents hooks from running during the - Helm rollback action. + description: DisableHooks prevents hooks from running during the Helm rollback action. type: boolean disableWait: description: |- @@ -865,10 +894,20 @@ spec: type: string type: object upgrade: - description: - Upgrade holds the configuration for Helm upgrade actions - for this HelmRelease. + description: Upgrade holds the configuration for Helm upgrade actions for this HelmRelease. properties: + chartNameChangeStrategy: + description: |- + ChartNameChangeStrategy defines the strategy to use when a Helm chart name changes. + Valid values are 'Reinstall' or 'InPlaceUpdate'. Defaults to 'Reinstall' if omitted. + + Reinstall: Reinstall the Helm release, uninstalling the existing Helm release. + + InPlaceUpdate: Update the Helm release in place. + enum: + - InPlaceUpdate + - Reinstall + type: string cleanupOnFail: description: |- CleanupOnFail allows deletion of new resources created during the Helm @@ -897,9 +936,7 @@ spec: - CreateReplace type: string disableHooks: - description: - DisableHooks prevents hooks from running during the - Helm upgrade action. + description: DisableHooks prevents hooks from running during the Helm upgrade action. type: boolean disableOpenAPIValidation: description: |- @@ -927,9 +964,11 @@ spec: upgrade has been performed. type: boolean force: - description: - Force forces resource updates through a replacement - strategy. + description: |- + Force forces resource updates through a replacement strategy + that avoids 3-way merge conflicts on client-side apply. + This field is ignored for server-side apply (which always + forces conflicts with other field managers). type: boolean preserveValues: description: |- @@ -960,18 +999,28 @@ spec: Defaults to '0', a negative integer equals to unlimited retries. type: integer strategy: - description: - Strategy to use for failure remediation. Defaults - to 'rollback'. + description: Strategy to use for failure remediation. Defaults to 'rollback'. enum: - rollback - uninstall type: string type: object + serverSideApply: + description: |- + ServerSideApply enables server-side apply for resources during upgrade. + Can be "enabled", "disabled", or "auto". + When "auto", server-side apply usage will be based on the release's previous usage. + Defaults to "auto". + enum: + - enabled + - disabled + - auto + type: string strategy: description: |- Strategy defines the upgrade strategy to use for this HelmRelease. - Defaults to 'RemediateOnFailure'. + Defaults to 'RemediateOnFailure', or 'RetryOnFailure' when the + DefaultToRetryOnFailure feature gate is enabled. properties: name: description: Name of the upgrade strategy. @@ -991,7 +1040,7 @@ spec: type: object x-kubernetes-validations: - message: .retryInterval can only be set when .name is 'RetryOnFailure' - rule: "!has(self.retryInterval) || self.name == 'RetryOnFailure'" + rule: '!has(self.retryInterval) || self.name == ''RetryOnFailure''' timeout: description: |- Timeout is the time to wait for any individual Kubernetes operation (like @@ -1013,13 +1062,22 @@ spec: and optionally the key they can be found at. properties: kind: - description: - Kind of the values referent, valid values are ('Secret', - 'ConfigMap'). + description: Kind of the values referent, valid values are ('Secret', 'ConfigMap'). enum: - Secret - ConfigMap type: string + literal: + description: |- + Literal marks this ValuesReference as a literal value. When set in + combination with TargetPath, the referenced value is merged at the target + path without interpreting Helm's `--set` syntax (commas, brackets, dots, + equal signs, etc.), mirroring the behavior of `helm --set-literal`. This + is the only safe way to inject arbitrary file content (config files, JSON + blobs, multi-line strings containing special characters) through + `valuesFrom`. Has no effect when TargetPath is empty: in that mode the + referenced value is always YAML-merged at the root. + type: boolean name: description: |- Name of the values referent. Should reside in the same namespace as the @@ -1053,14 +1111,32 @@ spec: - name type: object type: array + waitStrategy: + description: |- + WaitStrategy defines Helm's wait strategy for waiting for applied + resources to become ready. + properties: + name: + description: |- + Name is Helm's wait strategy for waiting for applied resources to + become ready. One of 'poller' or 'legacy'. The 'poller' strategy uses + kstatus to poll resource statuses, while the 'legacy' strategy uses + Helm v3's waiting logic. + Defaults to 'poller', or to 'legacy' when UseHelm3Defaults feature + gate is enabled. + enum: + - poller + - legacy + type: string + required: + - name + type: object required: - interval type: object x-kubernetes-validations: - message: either chart or chartRef must be set - rule: - (has(self.chart) && !has(self.chartRef)) || (!has(self.chart) - && has(self.chartRef)) + rule: (has(self.chart) && !has(self.chartRef)) || (!has(self.chart) && has(self.chartRef)) status: default: observedGeneration: -1 @@ -1069,9 +1145,7 @@ spec: conditions: description: Conditions holds the conditions for the HelmRelease. items: - description: - Condition contains details for one aspect of the current - state of this API Resource. + description: Condition contains details for one aspect of the current state of this API Resource. properties: lastTransitionTime: description: |- @@ -1144,21 +1218,20 @@ spec: Snapshot captures a point-in-time copy of the status information for a Helm release, as managed by the controller. properties: + action: + description: Action is the action that resulted in this snapshot being created. + type: string apiVersion: description: |- APIVersion is the API version of the Snapshot. - Provisional: when the calculation method of the Digest field is changed, - this field will be used to distinguish between the old and new methods. + When the calculation method of the Digest field is changed, this + field will be used to distinguish between the old and new methods. type: string appVersion: - description: - AppVersion is the chart app version of the release - object in storage. + description: AppVersion is the chart app version of the release object in storage. type: string chartName: - description: - ChartName is the chart name of the release object - in storage. + description: ChartName is the chart name of the release object in storage. type: string chartVersion: description: |- @@ -1192,14 +1265,10 @@ spec: description: Name is the name of the release. type: string namespace: - description: - Namespace is the namespace the release is deployed - to. + description: Namespace is the namespace the release is deployed to. type: string ociDigest: - description: - OCIDigest is the digest of the OCI artifact associated - with the release. + description: OCIDigest is the digest of the OCI artifact associated with the release. type: string status: description: Status is the current state of the release. @@ -1211,15 +1280,11 @@ spec: to be run by the controller. properties: lastCompleted: - description: - LastCompleted is the time the test hook last - completed. + description: LastCompleted is the time the test hook last completed. format: date-time type: string lastStarted: - description: - LastStarted is the time the test hook was - last started. + description: LastStarted is the time the test hook was last started. format: date-time type: string phase: @@ -1231,9 +1296,7 @@ spec: run by the controller. type: object version: - description: - Version is the version of the release object in - storage. + description: Version is the version of the release object in storage. type: integer required: - chartName @@ -1254,6 +1317,32 @@ spec: state. It is reset after a successful reconciliation. format: int64 type: integer + inventory: + description: |- + Inventory contains the list of Kubernetes resource object references + that have been applied for this release. + properties: + entries: + description: Entries of Kubernetes resource object references. + items: + description: ResourceRef contains the information necessary to locate a resource within a cluster. + properties: + id: + description: |- + ID is the string representation of the Kubernetes resource object's metadata, + in the format '___'. + type: string + v: + description: Version is the API version of the Kubernetes resource object's kind. + type: string + required: + - id + - v + type: object + type: array + required: + - entries + type: object lastAttemptedConfigDigest: description: |- LastAttemptedConfigDigest is the digest for the config (better known as @@ -1353,1360 +1442,3 @@ spec: storage: true subresources: status: {} - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - deprecated: true - deprecationWarning: v2beta2 HelmRelease is deprecated, upgrade to v2 - name: v2beta2 - schema: - openAPIV3Schema: - description: HelmRelease is the Schema for the helmreleases API - 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: HelmReleaseSpec defines the desired state of a Helm release. - properties: - chart: - description: |- - Chart defines the template of the v1beta2.HelmChart that should be created - for this HelmRelease. - properties: - metadata: - description: - ObjectMeta holds the template for metadata like labels - and annotations. - properties: - annotations: - additionalProperties: - type: string - description: |- - Annotations is an unstructured key value map stored with a resource that may be - set by external tools to store and retrieve arbitrary metadata. They are not - queryable and should be preserved when modifying objects. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ - type: object - labels: - additionalProperties: - type: string - description: |- - Map of string keys and values that can be used to organize and categorize - (scope and select) objects. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ - type: object - type: object - spec: - description: - Spec holds the template for the v1beta2.HelmChartSpec - for this HelmRelease. - properties: - chart: - description: - The name or path the Helm chart is available - at in the SourceRef. - maxLength: 2048 - minLength: 1 - type: string - ignoreMissingValuesFiles: - description: - IgnoreMissingValuesFiles controls whether to - silently ignore missing values files rather than failing. - type: boolean - interval: - description: |- - Interval at which to check the v1.Source for updates. Defaults to - 'HelmReleaseSpec.Interval'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - reconcileStrategy: - default: ChartVersion - description: |- - Determines what enables the creation of a new artifact. Valid values are - ('ChartVersion', 'Revision'). - See the documentation of the values for an explanation on their behavior. - Defaults to ChartVersion when omitted. - enum: - - ChartVersion - - Revision - type: string - sourceRef: - description: - The name and namespace of the v1.Source the chart - is available at. - properties: - apiVersion: - description: APIVersion of the referent. - type: string - kind: - description: Kind of the referent. - enum: - - InternalNelmOperatorHelmRepository - - InternalNelmOperatorGitRepository - - InternalNelmOperatorBucket - type: string - name: - description: Name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: Namespace of the referent. - maxLength: 63 - minLength: 1 - type: string - required: - - kind - - name - type: object - valuesFile: - description: |- - Alternative values file to use as the default chart values, expected to - be a relative path in the SourceRef. Deprecated in favor of ValuesFiles, - for backwards compatibility the file defined here is merged before the - ValuesFiles items. Ignored when omitted. - type: string - valuesFiles: - description: |- - Alternative list of values files to use as the chart values (values.yaml - is not included by default), expected to be a relative path in the SourceRef. - Values files are merged in the order of this list with the last file overriding - the first. Ignored when omitted. - items: - type: string - type: array - verify: - description: |- - Verify contains the secret name containing the trusted public keys - used to verify the signature and specifies which provider to use to check - whether OCI image is authentic. - This field is only supported for OCI sources. - Chart dependencies, which are not bundled in the umbrella chart artifact, - are not verified. - properties: - provider: - default: cosign - description: - Provider specifies the technology used to - sign the OCI Helm chart. - enum: - - cosign - - notation - type: string - secretRef: - description: |- - SecretRef specifies the Kubernetes Secret containing the - trusted public keys. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - provider - type: object - version: - default: "*" - description: |- - Version semver expression, ignored for charts from v1beta2.GitRepository and - v1beta2.Bucket sources. Defaults to latest when omitted. - type: string - required: - - chart - - sourceRef - type: object - required: - - spec - type: object - chartRef: - description: |- - ChartRef holds a reference to a source controller resource containing the - Helm chart artifact. - - Note: this field is provisional to the v2 API, and not actively used - by v2beta2 HelmReleases. - properties: - apiVersion: - description: APIVersion of the referent. - type: string - kind: - description: Kind of the referent. - enum: - - InternalNelmOperatorOCIRepository - - InternalNelmOperatorHelmChart - type: string - name: - description: Name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: |- - Namespace of the referent, defaults to the namespace of the Kubernetes - resource object that contains the reference. - maxLength: 63 - minLength: 1 - type: string - required: - - kind - - name - type: object - dependsOn: - description: |- - DependsOn may contain a meta.NamespacedObjectReference slice with - references to HelmRelease resources that must be ready before this HelmRelease - can be reconciled. - items: - description: |- - NamespacedObjectReference contains enough information to locate the referenced Kubernetes resource object in any - namespace. - properties: - name: - description: Name of the referent. - type: string - namespace: - description: - Namespace of the referent, when not specified it - acts as LocalObjectReference. - type: string - required: - - name - type: object - type: array - driftDetection: - description: |- - DriftDetection holds the configuration for detecting and handling - differences between the manifest in the Helm storage and the resources - currently existing in the cluster. - properties: - ignore: - description: |- - Ignore contains a list of rules for specifying which changes to ignore - during diffing. - items: - description: |- - IgnoreRule defines a rule to selectively disregard specific changes during - the drift detection process. - properties: - paths: - description: |- - Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from - consideration in a Kubernetes object. - items: - type: string - type: array - target: - description: |- - Target is a selector for specifying Kubernetes objects to which this - rule applies. - If Target is not set, the Paths will be ignored for all Kubernetes - objects within the manifest of the Helm release. - properties: - annotationSelector: - description: |- - AnnotationSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource annotations. - type: string - group: - description: |- - Group is the API group to select resources from. - Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - kind: - description: |- - Kind of the API Group to select resources from. - Together with Group and Version it is capable of unambiguously - identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - labelSelector: - description: |- - LabelSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource labels. - type: string - name: - description: Name to match resources with. - type: string - namespace: - description: Namespace to select resources from. - type: string - version: - description: |- - Version of the API Group to select resources from. - Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - type: object - required: - - paths - type: object - type: array - mode: - description: |- - Mode defines how differences should be handled between the Helm manifest - and the manifest currently applied to the cluster. - If not explicitly set, it defaults to DiffModeDisabled. - enum: - - enabled - - warn - - disabled - type: string - type: object - install: - description: - Install holds the configuration for Helm install actions - for this HelmRelease. - properties: - crds: - description: |- - CRDs upgrade CRDs from the Helm Chart's crds directory according - to the CRD upgrade policy provided here. Valid values are `Skip`, - `Create` or `CreateReplace`. Default is `Create` and if omitted - CRDs are installed but not updated. - - Skip: do neither install nor replace (update) any CRDs. - - Create: new CRDs are created, existing CRDs are neither updated nor deleted. - - CreateReplace: new CRDs are created, existing CRDs are updated (replaced) - but not deleted. - - By default, CRDs are applied (installed) during Helm install action. - With this option users can opt in to CRD replace existing CRDs on Helm - install actions, which is not (yet) natively supported by Helm. - https://helm.sh/docs/chart_best_practices/custom_resource_definitions. - enum: - - Skip - - Create - - CreateReplace - type: string - createNamespace: - description: |- - CreateNamespace tells the Helm install action to create the - HelmReleaseSpec.TargetNamespace if it does not exist yet. - On uninstall, the namespace will not be garbage collected. - type: boolean - disableHooks: - description: - DisableHooks prevents hooks from running during the - Helm install action. - type: boolean - disableOpenAPIValidation: - description: |- - DisableOpenAPIValidation prevents the Helm install action from validating - rendered templates against the Kubernetes OpenAPI Schema. - type: boolean - disableWait: - description: |- - DisableWait disables the waiting for resources to be ready after a Helm - install has been performed. - type: boolean - disableWaitForJobs: - description: |- - DisableWaitForJobs disables waiting for jobs to complete after a Helm - install has been performed. - type: boolean - remediation: - description: |- - Remediation holds the remediation configuration for when the Helm install - action for the HelmRelease fails. The default is to not perform any action. - properties: - ignoreTestFailures: - description: |- - IgnoreTestFailures tells the controller to skip remediation when the Helm - tests are run after an install action but fail. Defaults to - 'Test.IgnoreFailures'. - type: boolean - remediateLastFailure: - description: |- - RemediateLastFailure tells the controller to remediate the last failure, when - no retries remain. Defaults to 'false'. - type: boolean - retries: - description: |- - Retries is the number of retries that should be attempted on failures before - bailing. Remediation, using an uninstall, is performed between each attempt. - Defaults to '0', a negative integer equals to unlimited retries. - type: integer - type: object - replace: - description: |- - Replace tells the Helm install action to re-use the 'ReleaseName', but only - if that name is a deleted release which remains in the history. - type: boolean - skipCRDs: - description: |- - SkipCRDs tells the Helm install action to not install any CRDs. By default, - CRDs are installed if not already present. - - Deprecated use CRD policy (`crds`) attribute with value `Skip` instead. - type: boolean - timeout: - description: |- - Timeout is the time to wait for any individual Kubernetes operation (like - Jobs for hooks) during the performance of a Helm install action. Defaults to - 'HelmReleaseSpec.Timeout'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - type: object - interval: - description: Interval at which to reconcile the Helm release. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - kubeConfig: - description: |- - KubeConfig for reconciling the HelmRelease on a remote cluster. - When used in combination with HelmReleaseSpec.ServiceAccountName, - forces the controller to act on behalf of that Service Account at the - target cluster. - If the --default-service-account flag is set, its value will be used as - a controller level fallback for when HelmReleaseSpec.ServiceAccountName - is empty. - properties: - configMapRef: - description: |- - ConfigMapRef holds an optional name of a ConfigMap that contains - the following keys: - - - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or - `generic`. Required. - - `cluster`: the fully qualified resource name of the Kubernetes - cluster in the cloud provider API. Not used by the `generic` - provider. Required when one of `address` or `ca.crt` is not set. - - `address`: the address of the Kubernetes API server. Required - for `generic`. For the other providers, if not specified, the - first address in the cluster resource will be used, and if - specified, it must match one of the addresses in the cluster - resource. - If audiences is not set, will be used as the audience for the - `generic` provider. - - `ca.crt`: the optional PEM-encoded CA certificate for the - Kubernetes API server. If not set, the controller will use the - CA certificate from the cluster resource. - - `audiences`: the optional audiences as a list of - line-break-separated strings for the Kubernetes ServiceAccount - token. Defaults to the `address` for the `generic` provider, or - to specific values for the other providers depending on the - provider. - - `serviceAccountName`: the optional name of the Kubernetes - ServiceAccount in the same namespace that should be used - for authentication. If not specified, the controller - ServiceAccount will be used. - - Mutually exclusive with SecretRef. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - secretRef: - description: |- - SecretRef holds an optional name of a secret that contains a key with - the kubeconfig file as the value. If no key is set, the key will default - to 'value'. Mutually exclusive with ConfigMapRef. - It is recommended that the kubeconfig is self-contained, and the secret - is regularly updated if credentials such as a cloud-access-token expire. - Cloud specific `cmd-path` auth helpers will not function without adding - binaries and credentials to the Pod that is responsible for reconciling - Kubernetes resources. Supported only for the generic provider. - properties: - key: - description: - Key in the Secret, when not specified an implementation-specific - default key is used. - type: string - name: - description: Name of the Secret. - type: string - required: - - name - type: object - type: object - x-kubernetes-validations: - - message: - exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef - must be specified - rule: has(self.configMapRef) || has(self.secretRef) - - message: - exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef - must be specified - rule: "!has(self.configMapRef) || !has(self.secretRef)" - maxHistory: - description: |- - MaxHistory is the number of revisions saved by Helm for this HelmRelease. - Use '0' for an unlimited number of revisions; defaults to '5'. - type: integer - persistentClient: - description: |- - PersistentClient tells the controller to use a persistent Kubernetes - client for this release. When enabled, the client will be reused for the - duration of the reconciliation, instead of being created and destroyed - for each (step of a) Helm action. - - This can improve performance, but may cause issues with some Helm charts - that for example do create Custom Resource Definitions during installation - outside Helm's CRD lifecycle hooks, which are then not observed to be - available by e.g. post-install hooks. - - If not set, it defaults to true. - type: boolean - postRenderers: - description: |- - PostRenderers holds an array of Helm PostRenderers, which will be applied in order - of their definition. - items: - description: PostRenderer contains a Helm PostRenderer specification. - properties: - kustomize: - description: Kustomization to apply as PostRenderer. - properties: - images: - description: |- - Images is a list of (image name, new name, new tag or digest) - for changing image names, tags or digests. This can also be achieved with a - patch, but this operator is simpler to specify. - items: - description: - Image contains an image name, a new name, - a new tag or digest, which will replace the original - name and tag. - properties: - digest: - description: |- - Digest is the value used to replace the original image tag. - If digest is present NewTag value is ignored. - type: string - name: - description: Name is a tag-less image name. - type: string - newName: - description: - NewName is the value used to replace - the original name. - type: string - newTag: - description: - NewTag is the value used to replace the - original tag. - type: string - required: - - name - type: object - type: array - patches: - description: |- - Strategic merge and JSON patches, defined as inline YAML objects, - capable of targeting objects based on kind, label and annotation selectors. - items: - description: |- - Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should - be applied to. - properties: - patch: - description: |- - Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with - an array of operation objects. - type: string - target: - description: - Target points to the resources that the - patch document should be applied to. - properties: - annotationSelector: - description: |- - AnnotationSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource annotations. - type: string - group: - description: |- - Group is the API group to select resources from. - Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - kind: - description: |- - Kind of the API Group to select resources from. - Together with Group and Version it is capable of unambiguously - identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - labelSelector: - description: |- - LabelSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource labels. - type: string - name: - description: Name to match resources with. - type: string - namespace: - description: Namespace to select resources from. - type: string - version: - description: |- - Version of the API Group to select resources from. - Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - type: object - required: - - patch - type: object - type: array - patchesJson6902: - description: |- - JSON 6902 patches, defined as inline YAML objects. - - Deprecated: use Patches instead. - items: - description: - JSON6902Patch contains a JSON6902 patch and - the target the patch should be applied to. - properties: - patch: - description: - Patch contains the JSON6902 patch document - with an array of operation objects. - items: - description: |- - JSON6902 is a JSON6902 operation object. - https://datatracker.ietf.org/doc/html/rfc6902#section-4 - properties: - from: - description: |- - From contains a JSON-pointer value that references a location within the target document where the operation is - performed. The meaning of the value depends on the value of Op, and is NOT taken into account by all operations. - type: string - op: - description: |- - Op indicates the operation to perform. Its value MUST be one of "add", "remove", "replace", "move", "copy", or - "test". - https://datatracker.ietf.org/doc/html/rfc6902#section-4 - enum: - - test - - remove - - add - - replace - - move - - copy - type: string - path: - description: |- - Path contains the JSON-pointer value that references a location within the target document where the operation - is performed. The meaning of the value depends on the value of Op. - type: string - value: - description: |- - Value contains a valid JSON structure. The meaning of the value depends on the value of Op, and is NOT taken into - account by all operations. - x-kubernetes-preserve-unknown-fields: true - required: - - op - - path - type: object - type: array - target: - description: - Target points to the resources that the - patch document should be applied to. - properties: - annotationSelector: - description: |- - AnnotationSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource annotations. - type: string - group: - description: |- - Group is the API group to select resources from. - Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - kind: - description: |- - Kind of the API Group to select resources from. - Together with Group and Version it is capable of unambiguously - identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - labelSelector: - description: |- - LabelSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource labels. - type: string - name: - description: Name to match resources with. - type: string - namespace: - description: Namespace to select resources from. - type: string - version: - description: |- - Version of the API Group to select resources from. - Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - type: object - required: - - patch - - target - type: object - type: array - patchesStrategicMerge: - description: |- - Strategic merge patches, defined as inline YAML objects. - - Deprecated: use Patches instead. - items: - x-kubernetes-preserve-unknown-fields: true - type: array - type: object - type: object - type: array - releaseName: - description: |- - ReleaseName used for the Helm release. Defaults to a composition of - '[TargetNamespace-]Name'. - maxLength: 53 - minLength: 1 - type: string - rollback: - description: - Rollback holds the configuration for Helm rollback actions - for this HelmRelease. - properties: - cleanupOnFail: - description: |- - CleanupOnFail allows deletion of new resources created during the Helm - rollback action when it fails. - type: boolean - disableHooks: - description: - DisableHooks prevents hooks from running during the - Helm rollback action. - type: boolean - disableWait: - description: |- - DisableWait disables the waiting for resources to be ready after a Helm - rollback has been performed. - type: boolean - disableWaitForJobs: - description: |- - DisableWaitForJobs disables waiting for jobs to complete after a Helm - rollback has been performed. - type: boolean - force: - description: - Force forces resource updates through a replacement - strategy. - type: boolean - recreate: - description: - Recreate performs pod restarts for the resource if - applicable. - type: boolean - timeout: - description: |- - Timeout is the time to wait for any individual Kubernetes operation (like - Jobs for hooks) during the performance of a Helm rollback action. Defaults to - 'HelmReleaseSpec.Timeout'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - type: object - serviceAccountName: - description: |- - The name of the Kubernetes service account to impersonate - when reconciling this HelmRelease. - maxLength: 253 - minLength: 1 - type: string - storageNamespace: - description: |- - StorageNamespace used for the Helm storage. - Defaults to the namespace of the HelmRelease. - maxLength: 63 - minLength: 1 - type: string - suspend: - description: |- - Suspend tells the controller to suspend reconciliation for this HelmRelease, - it does not apply to already started reconciliations. Defaults to false. - type: boolean - targetNamespace: - description: |- - TargetNamespace to target when performing operations for the HelmRelease. - Defaults to the namespace of the HelmRelease. - maxLength: 63 - minLength: 1 - type: string - test: - description: - Test holds the configuration for Helm test actions for - this HelmRelease. - properties: - enable: - description: |- - Enable enables Helm test actions for this HelmRelease after an Helm install - or upgrade action has been performed. - type: boolean - filters: - description: - Filters is a list of tests to run or exclude from - running. - items: - description: - Filter holds the configuration for individual Helm - test filters. - properties: - exclude: - description: - Exclude specifies whether the named test should - be excluded. - type: boolean - name: - description: Name is the name of the test. - maxLength: 253 - minLength: 1 - type: string - required: - - name - type: object - type: array - ignoreFailures: - description: |- - IgnoreFailures tells the controller to skip remediation when the Helm tests - are run but fail. Can be overwritten for tests run after install or upgrade - actions in 'Install.IgnoreTestFailures' and 'Upgrade.IgnoreTestFailures'. - type: boolean - timeout: - description: |- - Timeout is the time to wait for any individual Kubernetes operation during - the performance of a Helm test action. Defaults to 'HelmReleaseSpec.Timeout'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - type: object - timeout: - description: |- - Timeout is the time to wait for any individual Kubernetes operation (like Jobs - for hooks) during the performance of a Helm action. Defaults to '5m0s'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - uninstall: - description: - Uninstall holds the configuration for Helm uninstall - actions for this HelmRelease. - properties: - deletionPropagation: - default: background - description: |- - DeletionPropagation specifies the deletion propagation policy when - a Helm uninstall is performed. - enum: - - background - - foreground - - orphan - type: string - disableHooks: - description: - DisableHooks prevents hooks from running during the - Helm rollback action. - type: boolean - disableWait: - description: |- - DisableWait disables waiting for all the resources to be deleted after - a Helm uninstall is performed. - type: boolean - keepHistory: - description: |- - KeepHistory tells Helm to remove all associated resources and mark the - release as deleted, but retain the release history. - type: boolean - timeout: - description: |- - Timeout is the time to wait for any individual Kubernetes operation (like - Jobs for hooks) during the performance of a Helm uninstall action. Defaults - to 'HelmReleaseSpec.Timeout'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - type: object - upgrade: - description: - Upgrade holds the configuration for Helm upgrade actions - for this HelmRelease. - properties: - cleanupOnFail: - description: |- - CleanupOnFail allows deletion of new resources created during the Helm - upgrade action when it fails. - type: boolean - crds: - description: |- - CRDs upgrade CRDs from the Helm Chart's crds directory according - to the CRD upgrade policy provided here. Valid values are `Skip`, - `Create` or `CreateReplace`. Default is `Skip` and if omitted - CRDs are neither installed nor upgraded. - - Skip: do neither install nor replace (update) any CRDs. - - Create: new CRDs are created, existing CRDs are neither updated nor deleted. - - CreateReplace: new CRDs are created, existing CRDs are updated (replaced) - but not deleted. - - By default, CRDs are not applied during Helm upgrade action. With this - option users can opt-in to CRD upgrade, which is not (yet) natively supported by Helm. - https://helm.sh/docs/chart_best_practices/custom_resource_definitions. - enum: - - Skip - - Create - - CreateReplace - type: string - disableHooks: - description: - DisableHooks prevents hooks from running during the - Helm upgrade action. - type: boolean - disableOpenAPIValidation: - description: |- - DisableOpenAPIValidation prevents the Helm upgrade action from validating - rendered templates against the Kubernetes OpenAPI Schema. - type: boolean - disableWait: - description: |- - DisableWait disables the waiting for resources to be ready after a Helm - upgrade has been performed. - type: boolean - disableWaitForJobs: - description: |- - DisableWaitForJobs disables waiting for jobs to complete after a Helm - upgrade has been performed. - type: boolean - force: - description: - Force forces resource updates through a replacement - strategy. - type: boolean - preserveValues: - description: |- - PreserveValues will make Helm reuse the last release's values and merge in - overrides from 'Values'. Setting this flag makes the HelmRelease - non-declarative. - type: boolean - remediation: - description: |- - Remediation holds the remediation configuration for when the Helm upgrade - action for the HelmRelease fails. The default is to not perform any action. - properties: - ignoreTestFailures: - description: |- - IgnoreTestFailures tells the controller to skip remediation when the Helm - tests are run after an upgrade action but fail. - Defaults to 'Test.IgnoreFailures'. - type: boolean - remediateLastFailure: - description: |- - RemediateLastFailure tells the controller to remediate the last failure, when - no retries remain. Defaults to 'false' unless 'Retries' is greater than 0. - type: boolean - retries: - description: |- - Retries is the number of retries that should be attempted on failures before - bailing. Remediation, using 'Strategy', is performed between each attempt. - Defaults to '0', a negative integer equals to unlimited retries. - type: integer - strategy: - description: - Strategy to use for failure remediation. Defaults - to 'rollback'. - enum: - - rollback - - uninstall - type: string - type: object - timeout: - description: |- - Timeout is the time to wait for any individual Kubernetes operation (like - Jobs for hooks) during the performance of a Helm upgrade action. Defaults to - 'HelmReleaseSpec.Timeout'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - type: object - values: - description: Values holds the values for this Helm release. - x-kubernetes-preserve-unknown-fields: true - valuesFrom: - description: |- - ValuesFrom holds references to resources containing Helm values for this HelmRelease, - and information about how they should be merged. - items: - description: |- - ValuesReference contains a reference to a resource containing Helm values, - and optionally the key they can be found at. - properties: - kind: - description: - Kind of the values referent, valid values are ('Secret', - 'ConfigMap'). - enum: - - Secret - - ConfigMap - type: string - name: - description: |- - Name of the values referent. Should reside in the same namespace as the - referring resource. - maxLength: 253 - minLength: 1 - type: string - optional: - description: |- - Optional marks this ValuesReference as optional. When set, a not found error - for the values reference is ignored, but any ValuesKey, TargetPath or - transient error will still result in a reconciliation failure. - type: boolean - targetPath: - description: |- - TargetPath is the YAML dot notation path the value should be merged at. When - set, the ValuesKey is expected to be a single flat value. Defaults to 'None', - which results in the values getting merged at the root. - maxLength: 250 - pattern: ^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$ - type: string - valuesKey: - description: |- - ValuesKey is the data key where the values.yaml or a specific value can be - found at. Defaults to 'values.yaml'. - maxLength: 253 - pattern: ^[\-._a-zA-Z0-9]+$ - type: string - required: - - kind - - name - type: object - type: array - required: - - interval - type: object - x-kubernetes-validations: - - message: either chart or chartRef must be set - rule: - (has(self.chart) && !has(self.chartRef)) || (!has(self.chart) - && has(self.chartRef)) - status: - default: - observedGeneration: -1 - description: HelmReleaseStatus defines the observed state of a HelmRelease. - properties: - conditions: - description: Conditions holds the conditions for the HelmRelease. - items: - description: - Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - failures: - description: |- - Failures is the reconciliation failure count against the latest desired - state. It is reset after a successful reconciliation. - format: int64 - type: integer - helmChart: - description: |- - HelmChart is the namespaced name of the HelmChart resource created by - the controller for the HelmRelease. - type: string - history: - description: |- - History holds the history of Helm releases performed for this HelmRelease - up to the last successfully completed release. - items: - description: |- - Snapshot captures a point-in-time copy of the status information for a Helm release, - as managed by the controller. - properties: - apiVersion: - description: |- - APIVersion is the API version of the Snapshot. - Provisional: when the calculation method of the Digest field is changed, - this field will be used to distinguish between the old and new methods. - type: string - appVersion: - description: - AppVersion is the chart app version of the release - object in storage. - type: string - chartName: - description: - ChartName is the chart name of the release object - in storage. - type: string - chartVersion: - description: |- - ChartVersion is the chart version of the release object in - storage. - type: string - configDigest: - description: |- - ConfigDigest is the checksum of the config (better known as - "values") of the release object in storage. - It has the format of `:`. - type: string - deleted: - description: Deleted is when the release was deleted. - format: date-time - type: string - digest: - description: |- - Digest is the checksum of the release object in storage. - It has the format of `:`. - type: string - firstDeployed: - description: FirstDeployed is when the release was first deployed. - format: date-time - type: string - lastDeployed: - description: LastDeployed is when the release was last deployed. - format: date-time - type: string - name: - description: Name is the name of the release. - type: string - namespace: - description: - Namespace is the namespace the release is deployed - to. - type: string - ociDigest: - description: - OCIDigest is the digest of the OCI artifact associated - with the release. - type: string - status: - description: Status is the current state of the release. - type: string - testHooks: - additionalProperties: - description: |- - TestHookStatus holds the status information for a test hook as observed - to be run by the controller. - properties: - lastCompleted: - description: - LastCompleted is the time the test hook last - completed. - format: date-time - type: string - lastStarted: - description: - LastStarted is the time the test hook was - last started. - format: date-time - type: string - phase: - description: Phase the test hook was observed to be in. - type: string - type: object - description: |- - TestHooks is the list of test hooks for the release as observed to be - run by the controller. - type: object - version: - description: - Version is the version of the release object in - storage. - type: integer - required: - - chartName - - chartVersion - - configDigest - - digest - - firstDeployed - - lastDeployed - - name - - namespace - - status - - version - type: object - type: array - installFailures: - description: |- - InstallFailures is the install failure count against the latest desired - state. It is reset after a successful reconciliation. - format: int64 - type: integer - lastAppliedRevision: - description: |- - LastAppliedRevision is the revision of the last successfully applied - source. - - Deprecated: the revision can now be found in the History. - type: string - lastAttemptedConfigDigest: - description: |- - LastAttemptedConfigDigest is the digest for the config (better known as - "values") of the last reconciliation attempt. - type: string - lastAttemptedGeneration: - description: |- - LastAttemptedGeneration is the last generation the controller attempted - to reconcile. - format: int64 - type: integer - lastAttemptedReleaseAction: - description: |- - LastAttemptedReleaseAction is the last release action performed for this - HelmRelease. It is used to determine the active remediation strategy. - enum: - - install - - upgrade - type: string - lastAttemptedRevision: - description: |- - LastAttemptedRevision is the Source revision of the last reconciliation - attempt. For OCIRepository sources, the 12 first characters of the digest are - appended to the chart version e.g. "1.2.3+1234567890ab". - type: string - lastAttemptedRevisionDigest: - description: |- - LastAttemptedRevisionDigest is the digest of the last reconciliation attempt. - This is only set for OCIRepository sources. - type: string - lastAttemptedValuesChecksum: - description: |- - LastAttemptedValuesChecksum is the SHA1 checksum for the values of the last - reconciliation attempt. - - Deprecated: Use LastAttemptedConfigDigest instead. - type: string - lastHandledForceAt: - description: |- - LastHandledForceAt holds the value of the most recent force request - value, so a change of the annotation value can be detected. - type: string - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - lastHandledResetAt: - description: |- - LastHandledResetAt holds the value of the most recent reset request - value, so a change of the annotation value can be detected. - type: string - lastReleaseRevision: - description: |- - LastReleaseRevision is the revision of the last successful Helm release. - - Deprecated: Use History instead. - type: integer - observedGeneration: - description: ObservedGeneration is the last observed generation. - format: int64 - type: integer - observedPostRenderersDigest: - description: |- - ObservedPostRenderersDigest is the digest for the post-renderers of - the last successful reconciliation attempt. - type: string - storageNamespace: - description: |- - StorageNamespace is the namespace of the Helm release storage for the - current release. - maxLength: 63 - minLength: 1 - type: string - upgradeFailures: - description: |- - UpgradeFailures is the upgrade failure count against the latest desired - state. It is reset after a successful reconciliation. - format: int64 - type: integer - type: object - type: object - served: true - storage: false - subresources: - status: {} diff --git a/crds/embedded/nelm-source-controller.yaml b/crds/embedded/nelm-source-controller.yaml deleted file mode 100644 index 08f3e509..00000000 --- a/crds/embedded/nelm-source-controller.yaml +++ /dev/null @@ -1,4165 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.19.0 - labels: - backup.deckhouse.io/cluster-config: "true" - heritage: deckhouse - module: operator-helm - name: internalnelmoperatorbuckets.source.internal.operator-helm.deckhouse.io -spec: - group: source.internal.operator-helm.deckhouse.io - names: - kind: InternalNelmOperatorBucket - listKind: InternalNelmOperatorBucketList - plural: internalnelmoperatorbuckets - singular: internalnelmoperatorbucket - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.endpoint - name: Endpoint - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - name: v1 - schema: - openAPIV3Schema: - description: Bucket is the Schema for the buckets API. - 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: |- - BucketSpec specifies the required configuration to produce an Artifact for - an object storage bucket. - properties: - bucketName: - description: BucketName is the name of the object storage bucket. - type: string - certSecretRef: - description: |- - CertSecretRef can be given the name of a Secret containing - either or both of - - - a PEM-encoded client certificate (`tls.crt`) and private - key (`tls.key`); - - a PEM-encoded CA certificate (`ca.crt`) - - and whichever are supplied, will be used for connecting to the - bucket. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. The Secret must - be of type `Opaque` or `kubernetes.io/tls`. - - This field is only supported for the `generic` provider. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - endpoint: - description: - Endpoint is the object storage address the BucketName - is located at. - type: string - ignore: - description: |- - 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. - type: string - insecure: - description: Insecure allows connecting to a non-TLS HTTP Endpoint. - type: boolean - interval: - description: |- - Interval at which the Bucket Endpoint is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - prefix: - description: - Prefix to use for server-side filtering of files in the - Bucket. - type: string - provider: - default: generic - description: |- - Provider of the object storage bucket. - Defaults to 'generic', which expects an S3 (API) compatible object - storage. - enum: - - generic - - aws - - gcp - - azure - type: string - proxySecretRef: - description: |- - ProxySecretRef specifies the Secret containing the proxy configuration - to use while communicating with the Bucket server. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - region: - description: - Region of the Endpoint where the BucketName is located - in. - type: string - secretRef: - description: |- - SecretRef specifies the Secret containing authentication credentials - for the Bucket. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - serviceAccountName: - description: |- - ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate - the bucket. This field is only supported for the 'gcp' and 'aws' providers. - For more information about workload identity: - https://fluxcd.io/flux/components/source/buckets/#workload-identity - type: string - sts: - description: |- - STS specifies the required configuration to use a Security Token - Service for fetching temporary credentials to authenticate in a - Bucket provider. - - This field is only supported for the `aws` and `generic` providers. - properties: - certSecretRef: - description: |- - CertSecretRef can be given the name of a Secret containing - either or both of - - - a PEM-encoded client certificate (`tls.crt`) and private - key (`tls.key`); - - a PEM-encoded CA certificate (`ca.crt`) - - and whichever are supplied, will be used for connecting to the - STS endpoint. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. The Secret must - be of type `Opaque` or `kubernetes.io/tls`. - - This field is only supported for the `ldap` provider. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - endpoint: - description: |- - Endpoint is the HTTP/S endpoint of the Security Token Service from - where temporary credentials will be fetched. - pattern: ^(http|https)://.*$ - type: string - provider: - description: Provider of the Security Token Service. - enum: - - aws - - ldap - type: string - secretRef: - description: |- - SecretRef specifies the Secret containing authentication credentials - for the STS endpoint. This Secret must contain the fields `username` - and `password` and is supported only for the `ldap` provider. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - endpoint - - provider - type: object - suspend: - description: |- - Suspend tells the controller to suspend the reconciliation of this - Bucket. - type: boolean - timeout: - default: 60s - description: Timeout for fetch operations, defaults to 60s. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - required: - - bucketName - - endpoint - - interval - type: object - x-kubernetes-validations: - - message: - STS configuration is only supported for the 'aws' and 'generic' - Bucket providers - rule: self.provider == 'aws' || self.provider == 'generic' || !has(self.sts) - - message: - "'aws' is the only supported STS provider for the 'aws' - Bucket provider" - rule: - self.provider != 'aws' || !has(self.sts) || self.sts.provider - == 'aws' - - message: - "'ldap' is the only supported STS provider for the 'generic' - Bucket provider" - rule: - self.provider != 'generic' || !has(self.sts) || self.sts.provider - == 'ldap' - - message: spec.sts.secretRef is not required for the 'aws' STS provider - rule: "!has(self.sts) || self.sts.provider != 'aws' || !has(self.sts.secretRef)" - - message: spec.sts.certSecretRef is not required for the 'aws' STS provider - rule: "!has(self.sts) || self.sts.provider != 'aws' || !has(self.sts.certSecretRef)" - - message: - ServiceAccountName is not supported for the 'generic' Bucket - provider - rule: self.provider != 'generic' || !has(self.serviceAccountName) - - message: cannot set both .spec.secretRef and .spec.serviceAccountName - rule: "!has(self.secretRef) || !has(self.serviceAccountName)" - status: - default: - observedGeneration: -1 - description: BucketStatus records the observed state of a Bucket. - properties: - artifact: - description: Artifact represents the last successful Bucket reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the Bucket. - items: - description: - Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: - ObservedGeneration is the last observed generation of - the Bucket object. - format: int64 - type: integer - observedIgnore: - description: |- - ObservedIgnore is the observed exclusion patterns used for constructing - the source artifact. - type: string - url: - description: |- - 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. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .spec.endpoint - name: Endpoint - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - deprecated: true - deprecationWarning: v1beta2 Bucket is deprecated, upgrade to v1 - name: v1beta2 - schema: - openAPIV3Schema: - description: Bucket is the Schema for the buckets API. - 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: |- - BucketSpec specifies the required configuration to produce an Artifact for - an object storage bucket. - properties: - accessFrom: - description: |- - AccessFrom specifies an Access Control List for allowing cross-namespace - references to this object. - NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 - properties: - namespaceSelectors: - description: |- - NamespaceSelectors is the list of namespace selectors to which this ACL applies. - Items in this list are evaluated using a logical OR operation. - items: - description: |- - NamespaceSelector selects the namespaces to which this ACL applies. - An empty map of MatchLabels matches all namespaces in a cluster. - properties: - matchLabels: - additionalProperties: - type: string - description: |- - MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - type: array - required: - - namespaceSelectors - type: object - bucketName: - description: BucketName is the name of the object storage bucket. - type: string - certSecretRef: - description: |- - CertSecretRef can be given the name of a Secret containing - either or both of - - - a PEM-encoded client certificate (`tls.crt`) and private - key (`tls.key`); - - a PEM-encoded CA certificate (`ca.crt`) - - and whichever are supplied, will be used for connecting to the - bucket. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. The Secret must - be of type `Opaque` or `kubernetes.io/tls`. - - This field is only supported for the `generic` provider. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - endpoint: - description: - Endpoint is the object storage address the BucketName - is located at. - type: string - ignore: - description: |- - 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. - type: string - insecure: - description: Insecure allows connecting to a non-TLS HTTP Endpoint. - type: boolean - interval: - description: |- - Interval at which the Bucket Endpoint is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - prefix: - description: - Prefix to use for server-side filtering of files in the - Bucket. - type: string - provider: - default: generic - description: |- - Provider of the object storage bucket. - Defaults to 'generic', which expects an S3 (API) compatible object - storage. - enum: - - generic - - aws - - gcp - - azure - type: string - proxySecretRef: - description: |- - ProxySecretRef specifies the Secret containing the proxy configuration - to use while communicating with the Bucket server. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - region: - description: - Region of the Endpoint where the BucketName is located - in. - type: string - secretRef: - description: |- - SecretRef specifies the Secret containing authentication credentials - for the Bucket. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - sts: - description: |- - STS specifies the required configuration to use a Security Token - Service for fetching temporary credentials to authenticate in a - Bucket provider. - - This field is only supported for the `aws` and `generic` providers. - properties: - certSecretRef: - description: |- - CertSecretRef can be given the name of a Secret containing - either or both of - - - a PEM-encoded client certificate (`tls.crt`) and private - key (`tls.key`); - - a PEM-encoded CA certificate (`ca.crt`) - - and whichever are supplied, will be used for connecting to the - STS endpoint. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. The Secret must - be of type `Opaque` or `kubernetes.io/tls`. - - This field is only supported for the `ldap` provider. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - endpoint: - description: |- - Endpoint is the HTTP/S endpoint of the Security Token Service from - where temporary credentials will be fetched. - pattern: ^(http|https)://.*$ - type: string - provider: - description: Provider of the Security Token Service. - enum: - - aws - - ldap - type: string - secretRef: - description: |- - SecretRef specifies the Secret containing authentication credentials - for the STS endpoint. This Secret must contain the fields `username` - and `password` and is supported only for the `ldap` provider. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - endpoint - - provider - type: object - suspend: - description: |- - Suspend tells the controller to suspend the reconciliation of this - Bucket. - type: boolean - timeout: - default: 60s - description: Timeout for fetch operations, defaults to 60s. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - required: - - bucketName - - endpoint - - interval - type: object - x-kubernetes-validations: - - message: - STS configuration is only supported for the 'aws' and 'generic' - Bucket providers - rule: self.provider == 'aws' || self.provider == 'generic' || !has(self.sts) - - message: - "'aws' is the only supported STS provider for the 'aws' - Bucket provider" - rule: - self.provider != 'aws' || !has(self.sts) || self.sts.provider - == 'aws' - - message: - "'ldap' is the only supported STS provider for the 'generic' - Bucket provider" - rule: - self.provider != 'generic' || !has(self.sts) || self.sts.provider - == 'ldap' - - message: spec.sts.secretRef is not required for the 'aws' STS provider - rule: "!has(self.sts) || self.sts.provider != 'aws' || !has(self.sts.secretRef)" - - message: spec.sts.certSecretRef is not required for the 'aws' STS provider - rule: "!has(self.sts) || self.sts.provider != 'aws' || !has(self.sts.certSecretRef)" - status: - default: - observedGeneration: -1 - description: BucketStatus records the observed state of a Bucket. - properties: - artifact: - description: Artifact represents the last successful Bucket reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the Bucket. - items: - description: - Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: - ObservedGeneration is the last observed generation of - the Bucket object. - format: int64 - type: integer - observedIgnore: - description: |- - ObservedIgnore is the observed exclusion patterns used for constructing - the source artifact. - type: string - url: - description: |- - 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. - type: string - type: object - type: object - served: true - storage: false - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.19.0 - labels: - backup.deckhouse.io/cluster-config: "true" - heritage: deckhouse - module: operator-helm - name: internalnelmoperatorexternalartifacts.source.internal.operator-helm.deckhouse.io -spec: - group: source.internal.operator-helm.deckhouse.io - names: - kind: InternalNelmOperatorExternalArtifact - listKind: InternalNelmOperatorExternalArtifactList - plural: internalnelmoperatorexternalartifacts - singular: internalnelmoperatorexternalartifact - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - - jsonPath: .spec.sourceRef.name - name: Source - type: string - name: v1 - schema: - openAPIV3Schema: - description: ExternalArtifact is the Schema for the external artifacts API - 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: ExternalArtifactSpec defines the desired state of ExternalArtifact - properties: - sourceRef: - description: |- - SourceRef points to the Kubernetes custom resource for - which the artifact is generated. - properties: - apiVersion: - description: - API version of the referent, if not specified the - Kubernetes preferred version will be used. - type: string - kind: - description: Kind of the referent. - type: string - name: - description: Name of the referent. - type: string - namespace: - description: - Namespace of the referent, when not specified it - acts as LocalObjectReference. - type: string - required: - - kind - - name - type: object - type: object - status: - description: ExternalArtifactStatus defines the observed state of ExternalArtifact - properties: - artifact: - description: - Artifact represents the output of an ExternalArtifact - reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the ExternalArtifact. - items: - description: - Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.19.0 - labels: - backup.deckhouse.io/cluster-config: "true" - heritage: deckhouse - module: operator-helm - name: internalnelmoperatorgitrepositories.source.internal.operator-helm.deckhouse.io -spec: - group: source.internal.operator-helm.deckhouse.io - names: - kind: InternalNelmOperatorGitRepository - listKind: InternalNelmOperatorGitRepositoryList - plural: internalnelmoperatorgitrepositories - singular: internalnelmoperatorgitrepository - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.url - name: URL - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - name: v1 - schema: - openAPIV3Schema: - description: GitRepository is the Schema for the gitrepositories API. - 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: |- - GitRepositorySpec specifies the required configuration to produce an - Artifact for a Git repository. - properties: - ignore: - description: |- - 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. - type: string - include: - description: |- - Include specifies a list of GitRepository resources which Artifacts - should be included in the Artifact produced for this GitRepository. - items: - description: |- - GitRepositoryInclude specifies a local reference to a GitRepository which - Artifact (sub-)contents must be included, and where they should be placed. - properties: - fromPath: - description: |- - FromPath specifies the path to copy contents from, defaults to the root - of the Artifact. - type: string - repository: - description: |- - GitRepositoryRef specifies the GitRepository which Artifact contents - must be included. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - toPath: - description: |- - ToPath specifies the path to copy contents to, defaults to the name of - the GitRepositoryRef. - type: string - required: - - repository - type: object - type: array - interval: - description: |- - Interval at which the GitRepository URL is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - provider: - description: |- - Provider used for authentication, can be 'azure', 'github', 'generic'. - When not specified, defaults to 'generic'. - enum: - - generic - - azure - - github - type: string - proxySecretRef: - description: |- - ProxySecretRef specifies the Secret containing the proxy configuration - to use while communicating with the Git server. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - recurseSubmodules: - description: |- - RecurseSubmodules enables the initialization of all submodules within - the GitRepository as cloned from the URL, using their default settings. - type: boolean - ref: - description: |- - Reference specifies the Git reference to resolve and monitor for - changes, defaults to the 'master' branch. - properties: - branch: - description: - Branch to check out, defaults to 'master' if no other - field is defined. - type: string - commit: - description: |- - Commit SHA to check out, takes precedence over all reference fields. - - This can be combined with Branch to shallow clone the branch, in which - the commit is expected to exist. - type: string - name: - description: |- - Name of the reference to check out; takes precedence over Branch, Tag and SemVer. - - It must be a valid Git reference: https://git-scm.com/docs/git-check-ref-format#_description - Examples: "refs/heads/main", "refs/tags/v0.1.0", "refs/pull/420/head", "refs/merge-requests/1/head" - type: string - semver: - description: - SemVer tag expression to check out, takes precedence - over Tag. - type: string - tag: - description: Tag to check out, takes precedence over Branch. - type: string - type: object - secretRef: - description: |- - SecretRef specifies the Secret containing authentication credentials for - the GitRepository. - For HTTPS repositories the Secret must contain 'username' and 'password' - fields for basic auth or 'bearerToken' field for token auth. - For SSH repositories the Secret must contain 'identity' - and 'known_hosts' fields. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - serviceAccountName: - description: |- - ServiceAccountName is the name of the Kubernetes ServiceAccount used to - authenticate to the GitRepository. This field is only supported for 'azure' provider. - type: string - sparseCheckout: - description: |- - SparseCheckout specifies a list of directories to checkout when cloning - the repository. If specified, only these directories are included in the - Artifact produced for this GitRepository. - items: - type: string - type: array - suspend: - description: |- - Suspend tells the controller to suspend the reconciliation of this - GitRepository. - type: boolean - timeout: - default: 60s - description: - Timeout for Git operations like cloning, defaults to - 60s. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - url: - description: - URL specifies the Git repository URL, it can be an HTTP/S - or SSH address. - pattern: ^(http|https|ssh)://.*$ - type: string - verify: - description: |- - Verification specifies the configuration to verify the Git commit - signature(s). - properties: - mode: - default: HEAD - description: |- - Mode specifies which Git object(s) should be verified. - - The variants "head" and "HEAD" both imply the same thing, i.e. verify - the commit that the HEAD of the Git repository points to. The variant - "head" solely exists to ensure backwards compatibility. - enum: - - head - - HEAD - - Tag - - TagAndHEAD - type: string - secretRef: - description: |- - SecretRef specifies the Secret containing the public keys of trusted Git - authors. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - secretRef - type: object - required: - - interval - - url - type: object - x-kubernetes-validations: - - message: serviceAccountName can only be set when provider is 'azure' - rule: - "!has(self.serviceAccountName) || (has(self.provider) && self.provider - == 'azure')" - status: - default: - observedGeneration: -1 - description: GitRepositoryStatus records the observed state of a Git repository. - properties: - artifact: - description: - Artifact represents the last successful GitRepository - reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the GitRepository. - items: - description: - Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - includedArtifacts: - description: |- - IncludedArtifacts contains a list of the last successfully included - Artifacts as instructed by GitRepositorySpec.Include. - items: - description: Artifact represents the output of a Source reconciliation. - properties: - digest: - description: - Digest is the digest of the file in the form of - ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: - Metadata holds upstream information such as OCI - annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: |- - ObservedGeneration is the last observed generation of the GitRepository - object. - format: int64 - type: integer - observedIgnore: - description: |- - ObservedIgnore is the observed exclusion patterns used for constructing - the source artifact. - type: string - observedInclude: - description: |- - ObservedInclude is the observed list of GitRepository resources used to - produce the current Artifact. - items: - description: |- - GitRepositoryInclude specifies a local reference to a GitRepository which - Artifact (sub-)contents must be included, and where they should be placed. - properties: - fromPath: - description: |- - FromPath specifies the path to copy contents from, defaults to the root - of the Artifact. - type: string - repository: - description: |- - GitRepositoryRef specifies the GitRepository which Artifact contents - must be included. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - toPath: - description: |- - ToPath specifies the path to copy contents to, defaults to the name of - the GitRepositoryRef. - type: string - required: - - repository - type: object - type: array - observedRecurseSubmodules: - description: |- - ObservedRecurseSubmodules is the observed resource submodules - configuration used to produce the current Artifact. - type: boolean - observedSparseCheckout: - description: |- - ObservedSparseCheckout is the observed list of directories used to - produce the current Artifact. - items: - type: string - type: array - sourceVerificationMode: - description: |- - SourceVerificationMode is the last used verification mode indicating - which Git object(s) have been verified. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .spec.url - name: URL - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - deprecated: true - deprecationWarning: v1beta2 GitRepository is deprecated, upgrade to v1 - name: v1beta2 - schema: - openAPIV3Schema: - description: GitRepository is the Schema for the gitrepositories API. - 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: |- - GitRepositorySpec specifies the required configuration to produce an - Artifact for a Git repository. - properties: - accessFrom: - description: |- - AccessFrom specifies an Access Control List for allowing cross-namespace - references to this object. - NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 - properties: - namespaceSelectors: - description: |- - NamespaceSelectors is the list of namespace selectors to which this ACL applies. - Items in this list are evaluated using a logical OR operation. - items: - description: |- - NamespaceSelector selects the namespaces to which this ACL applies. - An empty map of MatchLabels matches all namespaces in a cluster. - properties: - matchLabels: - additionalProperties: - type: string - description: |- - MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - type: array - required: - - namespaceSelectors - type: object - gitImplementation: - default: go-git - description: |- - GitImplementation specifies which Git client library implementation to - use. Defaults to 'go-git', valid values are ('go-git', 'libgit2'). - Deprecated: gitImplementation is deprecated now that 'go-git' is the - only supported implementation. - enum: - - go-git - - libgit2 - type: string - ignore: - description: |- - 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. - type: string - include: - description: |- - Include specifies a list of GitRepository resources which Artifacts - should be included in the Artifact produced for this GitRepository. - items: - description: |- - GitRepositoryInclude specifies a local reference to a GitRepository which - Artifact (sub-)contents must be included, and where they should be placed. - properties: - fromPath: - description: |- - FromPath specifies the path to copy contents from, defaults to the root - of the Artifact. - type: string - repository: - description: |- - GitRepositoryRef specifies the GitRepository which Artifact contents - must be included. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - toPath: - description: |- - ToPath specifies the path to copy contents to, defaults to the name of - the GitRepositoryRef. - type: string - required: - - repository - type: object - type: array - interval: - description: Interval at which to check the GitRepository for updates. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - recurseSubmodules: - description: |- - RecurseSubmodules enables the initialization of all submodules within - the GitRepository as cloned from the URL, using their default settings. - type: boolean - ref: - description: |- - Reference specifies the Git reference to resolve and monitor for - changes, defaults to the 'master' branch. - properties: - branch: - description: - Branch to check out, defaults to 'master' if no other - field is defined. - type: string - commit: - description: |- - Commit SHA to check out, takes precedence over all reference fields. - - This can be combined with Branch to shallow clone the branch, in which - the commit is expected to exist. - type: string - name: - description: |- - Name of the reference to check out; takes precedence over Branch, Tag and SemVer. - - It must be a valid Git reference: https://git-scm.com/docs/git-check-ref-format#_description - Examples: "refs/heads/main", "refs/tags/v0.1.0", "refs/pull/420/head", "refs/merge-requests/1/head" - type: string - semver: - description: - SemVer tag expression to check out, takes precedence - over Tag. - type: string - tag: - description: Tag to check out, takes precedence over Branch. - type: string - type: object - secretRef: - description: |- - SecretRef specifies the Secret containing authentication credentials for - the GitRepository. - For HTTPS repositories the Secret must contain 'username' and 'password' - fields for basic auth or 'bearerToken' field for token auth. - For SSH repositories the Secret must contain 'identity' - and 'known_hosts' fields. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - suspend: - description: |- - Suspend tells the controller to suspend the reconciliation of this - GitRepository. - type: boolean - timeout: - default: 60s - description: - Timeout for Git operations like cloning, defaults to - 60s. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - url: - description: - URL specifies the Git repository URL, it can be an HTTP/S - or SSH address. - pattern: ^(http|https|ssh)://.*$ - type: string - verify: - description: |- - Verification specifies the configuration to verify the Git commit - signature(s). - properties: - mode: - description: - Mode specifies what Git object should be verified, - currently ('head'). - enum: - - head - type: string - secretRef: - description: |- - SecretRef specifies the Secret containing the public keys of trusted Git - authors. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - mode - - secretRef - type: object - required: - - interval - - url - type: object - status: - default: - observedGeneration: -1 - description: GitRepositoryStatus records the observed state of a Git repository. - properties: - artifact: - description: - Artifact represents the last successful GitRepository - reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the GitRepository. - items: - description: - Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - contentConfigChecksum: - description: |- - ContentConfigChecksum is a checksum of all the configurations related to - the content of the source artifact: - - .spec.ignore - - .spec.recurseSubmodules - - .spec.included and the checksum of the included artifacts - observed in .status.observedGeneration version of the object. This can - be used to determine if the content of the included repository has - changed. - It has the format of `:`, for example: `sha256:`. - - Deprecated: Replaced with explicit fields for observed artifact content - config in the status. - type: string - includedArtifacts: - description: |- - IncludedArtifacts contains a list of the last successfully included - Artifacts as instructed by GitRepositorySpec.Include. - items: - description: Artifact represents the output of a Source reconciliation. - properties: - digest: - description: - Digest is the digest of the file in the form of - ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: - Metadata holds upstream information such as OCI - annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: |- - ObservedGeneration is the last observed generation of the GitRepository - object. - format: int64 - type: integer - observedIgnore: - description: |- - ObservedIgnore is the observed exclusion patterns used for constructing - the source artifact. - type: string - observedInclude: - description: |- - ObservedInclude is the observed list of GitRepository resources used to - to produce the current Artifact. - items: - description: |- - GitRepositoryInclude specifies a local reference to a GitRepository which - Artifact (sub-)contents must be included, and where they should be placed. - properties: - fromPath: - description: |- - FromPath specifies the path to copy contents from, defaults to the root - of the Artifact. - type: string - repository: - description: |- - GitRepositoryRef specifies the GitRepository which Artifact contents - must be included. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - toPath: - description: |- - ToPath specifies the path to copy contents to, defaults to the name of - the GitRepositoryRef. - type: string - required: - - repository - type: object - type: array - observedRecurseSubmodules: - description: |- - ObservedRecurseSubmodules is the observed resource submodules - configuration used to produce the current Artifact. - type: boolean - url: - description: |- - 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. - type: string - type: object - type: object - served: true - storage: false - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.19.0 - labels: - backup.deckhouse.io/cluster-config: "true" - heritage: deckhouse - module: operator-helm - name: internalnelmoperatorhelmcharts.source.internal.operator-helm.deckhouse.io -spec: - group: source.internal.operator-helm.deckhouse.io - names: - kind: InternalNelmOperatorHelmChart - listKind: InternalNelmOperatorHelmChartList - plural: internalnelmoperatorhelmcharts - singular: internalnelmoperatorhelmchart - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.chart - name: Chart - type: string - - jsonPath: .spec.version - name: Version - type: string - - jsonPath: .spec.sourceRef.kind - name: Source Kind - type: string - - jsonPath: .spec.sourceRef.name - name: Source Name - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - name: v1 - schema: - openAPIV3Schema: - description: HelmChart is the Schema for the helmcharts API. - 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 specifies the desired state of a Helm chart. - properties: - chart: - description: |- - Chart is the name or path the Helm chart is available at in the - SourceRef. - type: string - ignoreMissingValuesFiles: - description: |- - IgnoreMissingValuesFiles controls whether to silently ignore missing values - files rather than failing. - type: boolean - interval: - description: |- - Interval at which the HelmChart SourceRef is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - reconcileStrategy: - default: ChartVersion - description: |- - ReconcileStrategy determines what enables the creation of a new artifact. - Valid values are ('ChartVersion', 'Revision'). - See the documentation of the values for an explanation on their behavior. - Defaults to ChartVersion when omitted. - enum: - - ChartVersion - - Revision - type: string - sourceRef: - description: - SourceRef is the reference to the Source the chart is - available at. - properties: - apiVersion: - description: APIVersion of the referent. - type: string - kind: - description: |- - Kind of the referent, valid values are ('HelmRepository', 'GitRepository', - 'Bucket'). - enum: - - InternalNelmOperatorHelmRepository - - InternalNelmOperatorGitRepository - - InternalNelmOperatorBucket - type: string - name: - description: Name of the referent. - type: string - required: - - kind - - name - type: object - suspend: - description: |- - Suspend tells the controller to suspend the reconciliation of this - source. - type: boolean - valuesFiles: - description: |- - ValuesFiles is an alternative list of values files to use as the chart - values (values.yaml is not included by default), expected to be a - relative path in the SourceRef. - Values files are merged in the order of this list with the last file - overriding the first. Ignored when omitted. - items: - type: string - type: array - verify: - description: |- - Verify contains the secret name containing the trusted public keys - used to verify the signature and specifies which provider to use to check - whether OCI image is authentic. - This field is only supported when using HelmRepository source with spec.type 'oci'. - Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified. - properties: - matchOIDCIdentity: - description: |- - MatchOIDCIdentity specifies the identity matching criteria to use - while verifying an OCI artifact which was signed using Cosign keyless - signing. The artifact's identity is deemed to be verified if any of the - specified matchers match against the identity. - items: - description: |- - OIDCIdentityMatch specifies options for verifying the certificate identity, - i.e. the issuer and the subject of the certificate. - properties: - issuer: - description: |- - Issuer specifies the regex pattern to match against to verify - the OIDC issuer in the Fulcio certificate. The pattern must be a - valid Go regular expression. - type: string - subject: - description: |- - Subject specifies the regex pattern to match against to verify - the identity subject in the Fulcio certificate. The pattern must - be a valid Go regular expression. - type: string - required: - - issuer - - subject - type: object - type: array - provider: - default: cosign - description: - Provider specifies the technology used to sign the - OCI Artifact. - enum: - - cosign - - notation - type: string - secretRef: - description: |- - SecretRef specifies the Kubernetes Secret containing the - trusted public keys. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - provider - type: object - version: - default: "*" - description: |- - Version is the chart version semver expression, ignored for charts from - GitRepository and Bucket sources. Defaults to latest when omitted. - type: string - required: - - chart - - interval - - sourceRef - type: object - x-kubernetes-validations: - - message: spec.verify is only supported when spec.sourceRef.kind is 'HelmRepository' - rule: "!has(self.verify) || self.sourceRef.kind == 'HelmRepository'" - status: - default: - observedGeneration: -1 - description: HelmChartStatus records the observed state of the HelmChart. - properties: - artifact: - description: - Artifact represents the output of the last successful - reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the HelmChart. - items: - description: - Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedChartName: - description: |- - ObservedChartName is the last observed chart name as specified by the - resolved chart reference. - type: string - observedGeneration: - description: |- - ObservedGeneration is the last observed generation of the HelmChart - object. - format: int64 - type: integer - observedSourceArtifactRevision: - description: |- - ObservedSourceArtifactRevision is the last observed Artifact.Revision - of the HelmChartSpec.SourceRef. - type: string - observedValuesFiles: - description: |- - ObservedValuesFiles are the observed value files of the last successful - reconciliation. - It matches the chart in the last successfully reconciled artifact. - items: - type: string - type: array - url: - description: |- - 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. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .spec.chart - name: Chart - type: string - - jsonPath: .spec.version - name: Version - type: string - - jsonPath: .spec.sourceRef.kind - name: Source Kind - type: string - - jsonPath: .spec.sourceRef.name - name: Source Name - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - deprecated: true - deprecationWarning: v1beta2 HelmChart is deprecated, upgrade to v1 - name: v1beta2 - schema: - openAPIV3Schema: - description: HelmChart is the Schema for the helmcharts API. - 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 specifies the desired state of a Helm chart. - properties: - accessFrom: - description: |- - AccessFrom specifies an Access Control List for allowing cross-namespace - references to this object. - NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 - properties: - namespaceSelectors: - description: |- - NamespaceSelectors is the list of namespace selectors to which this ACL applies. - Items in this list are evaluated using a logical OR operation. - items: - description: |- - NamespaceSelector selects the namespaces to which this ACL applies. - An empty map of MatchLabels matches all namespaces in a cluster. - properties: - matchLabels: - additionalProperties: - type: string - description: |- - MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - type: array - required: - - namespaceSelectors - type: object - chart: - description: |- - Chart is the name or path the Helm chart is available at in the - SourceRef. - type: string - ignoreMissingValuesFiles: - description: |- - IgnoreMissingValuesFiles controls whether to silently ignore missing values - files rather than failing. - type: boolean - interval: - description: |- - Interval at which the HelmChart SourceRef is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - reconcileStrategy: - default: ChartVersion - description: |- - ReconcileStrategy determines what enables the creation of a new artifact. - Valid values are ('ChartVersion', 'Revision'). - See the documentation of the values for an explanation on their behavior. - Defaults to ChartVersion when omitted. - enum: - - ChartVersion - - Revision - type: string - sourceRef: - description: - SourceRef is the reference to the Source the chart is - available at. - properties: - apiVersion: - description: APIVersion of the referent. - type: string - kind: - description: |- - Kind of the referent, valid values are ('HelmRepository', 'GitRepository', - 'Bucket'). - enum: - - InternalNelmOperatorHelmRepository - - InternalNelmOperatorGitRepository - - InternalNelmOperatorBucket - type: string - name: - description: Name of the referent. - type: string - required: - - kind - - name - type: object - suspend: - description: |- - Suspend tells the controller to suspend the reconciliation of this - source. - type: boolean - valuesFile: - description: |- - ValuesFile is an alternative values file to use as the default chart - values, expected to be a relative path in the SourceRef. Deprecated in - favor of ValuesFiles, for backwards compatibility the file specified here - is merged before the ValuesFiles items. Ignored when omitted. - type: string - valuesFiles: - description: |- - ValuesFiles is an alternative list of values files to use as the chart - values (values.yaml is not included by default), expected to be a - relative path in the SourceRef. - Values files are merged in the order of this list with the last file - overriding the first. Ignored when omitted. - items: - type: string - type: array - verify: - description: |- - Verify contains the secret name containing the trusted public keys - used to verify the signature and specifies which provider to use to check - whether OCI image is authentic. - This field is only supported when using HelmRepository source with spec.type 'oci'. - Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified. - properties: - matchOIDCIdentity: - description: |- - MatchOIDCIdentity specifies the identity matching criteria to use - while verifying an OCI artifact which was signed using Cosign keyless - signing. The artifact's identity is deemed to be verified if any of the - specified matchers match against the identity. - items: - description: |- - OIDCIdentityMatch specifies options for verifying the certificate identity, - i.e. the issuer and the subject of the certificate. - properties: - issuer: - description: |- - Issuer specifies the regex pattern to match against to verify - the OIDC issuer in the Fulcio certificate. The pattern must be a - valid Go regular expression. - type: string - subject: - description: |- - Subject specifies the regex pattern to match against to verify - the identity subject in the Fulcio certificate. The pattern must - be a valid Go regular expression. - type: string - required: - - issuer - - subject - type: object - type: array - provider: - default: cosign - description: - Provider specifies the technology used to sign the - OCI Artifact. - enum: - - cosign - - notation - type: string - secretRef: - description: |- - SecretRef specifies the Kubernetes Secret containing the - trusted public keys. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - provider - type: object - version: - default: "*" - description: |- - Version is the chart version semver expression, ignored for charts from - GitRepository and Bucket sources. Defaults to latest when omitted. - type: string - required: - - chart - - interval - - sourceRef - type: object - status: - default: - observedGeneration: -1 - description: HelmChartStatus records the observed state of the HelmChart. - properties: - artifact: - description: - Artifact represents the output of the last successful - reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the HelmChart. - items: - description: - Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedChartName: - description: |- - ObservedChartName is the last observed chart name as specified by the - resolved chart reference. - type: string - observedGeneration: - description: |- - ObservedGeneration is the last observed generation of the HelmChart - object. - format: int64 - type: integer - observedSourceArtifactRevision: - description: |- - ObservedSourceArtifactRevision is the last observed Artifact.Revision - of the HelmChartSpec.SourceRef. - type: string - observedValuesFiles: - description: |- - ObservedValuesFiles are the observed value files of the last successful - reconciliation. - It matches the chart in the last successfully reconciled artifact. - items: - type: string - type: array - url: - description: |- - 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. - type: string - type: object - type: object - served: true - storage: false - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.19.0 - labels: - backup.deckhouse.io/cluster-config: "true" - heritage: deckhouse - module: operator-helm - name: internalnelmoperatorhelmrepositories.source.internal.operator-helm.deckhouse.io -spec: - group: source.internal.operator-helm.deckhouse.io - names: - kind: InternalNelmOperatorHelmRepository - listKind: InternalNelmOperatorHelmRepositoryList - plural: internalnelmoperatorhelmrepositories - singular: internalnelmoperatorhelmrepository - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.url - name: URL - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - name: v1 - schema: - openAPIV3Schema: - description: HelmRepository is the Schema for the helmrepositories API. - 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: |- - HelmRepositorySpec specifies the required configuration to produce an - Artifact for a Helm repository index YAML. - properties: - accessFrom: - description: |- - AccessFrom specifies an Access Control List for allowing cross-namespace - references to this object. - NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 - properties: - namespaceSelectors: - description: |- - NamespaceSelectors is the list of namespace selectors to which this ACL applies. - Items in this list are evaluated using a logical OR operation. - items: - description: |- - NamespaceSelector selects the namespaces to which this ACL applies. - An empty map of MatchLabels matches all namespaces in a cluster. - properties: - matchLabels: - additionalProperties: - type: string - description: |- - MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - type: array - required: - - namespaceSelectors - type: object - certSecretRef: - description: |- - CertSecretRef can be given the name of a Secret containing - either or both of - - - a PEM-encoded client certificate (`tls.crt`) and private - key (`tls.key`); - - a PEM-encoded CA certificate (`ca.crt`) - - and whichever are supplied, will be used for connecting to the - registry. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. The Secret must - be of type `Opaque` or `kubernetes.io/tls`. - - It takes precedence over the values specified in the Secret referred - to by `.spec.secretRef`. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - insecure: - description: |- - Insecure allows connecting to a non-TLS HTTP container registry. - This field is only taken into account if the .spec.type field is set to 'oci'. - type: boolean - interval: - description: |- - Interval at which the HelmRepository URL is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - passCredentials: - description: |- - PassCredentials allows the credentials from the SecretRef to be passed - on to a host that does not match the host as defined in URL. - This may be required if the host of the advertised chart URLs in the - index differ from the defined URL. - Enabling this should be done with caution, as it can potentially result - in credentials getting stolen in a MITM-attack. - type: boolean - provider: - default: generic - description: |- - Provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. - This field is optional, and only taken into account if the .spec.type field is set to 'oci'. - When not specified, defaults to 'generic'. - enum: - - generic - - aws - - azure - - gcp - type: string - secretRef: - description: |- - SecretRef specifies the Secret containing authentication credentials - for the HelmRepository. - For HTTP/S basic auth the secret must contain 'username' and 'password' - fields. - Support for TLS auth using the 'certFile' and 'keyFile', and/or 'caFile' - keys is deprecated. Please use `.spec.certSecretRef` instead. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - suspend: - description: |- - Suspend tells the controller to suspend the reconciliation of this - HelmRepository. - type: boolean - timeout: - description: |- - Timeout is used for the index fetch operation for an HTTPS helm repository, - and for remote OCI Repository operations like pulling for an OCI helm - chart by the associated HelmChart. - Its default value is 60s. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - type: - description: |- - Type of the HelmRepository. - When this field is set to "oci", the URL field value must be prefixed with "oci://". - enum: - - default - - oci - type: string - url: - description: |- - URL of the Helm repository, a valid URL contains at least a protocol and - host. - pattern: ^(http|https|oci)://.*$ - type: string - required: - - url - type: object - status: - default: - observedGeneration: -1 - description: HelmRepositoryStatus records the observed state of the HelmRepository. - properties: - artifact: - description: - Artifact represents the last successful HelmRepository - reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the HelmRepository. - items: - description: - Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: |- - ObservedGeneration is the last observed generation of the HelmRepository - object. - format: int64 - type: integer - url: - description: |- - 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. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .spec.url - name: URL - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - deprecated: true - deprecationWarning: v1beta2 HelmRepository is deprecated, upgrade to v1 - name: v1beta2 - schema: - openAPIV3Schema: - description: HelmRepository is the Schema for the helmrepositories API. - 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: |- - HelmRepositorySpec specifies the required configuration to produce an - Artifact for a Helm repository index YAML. - properties: - accessFrom: - description: |- - AccessFrom specifies an Access Control List for allowing cross-namespace - references to this object. - NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 - properties: - namespaceSelectors: - description: |- - NamespaceSelectors is the list of namespace selectors to which this ACL applies. - Items in this list are evaluated using a logical OR operation. - items: - description: |- - NamespaceSelector selects the namespaces to which this ACL applies. - An empty map of MatchLabels matches all namespaces in a cluster. - properties: - matchLabels: - additionalProperties: - type: string - description: |- - MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - type: array - required: - - namespaceSelectors - type: object - certSecretRef: - description: |- - CertSecretRef can be given the name of a Secret containing - either or both of - - - a PEM-encoded client certificate (`tls.crt`) and private - key (`tls.key`); - - a PEM-encoded CA certificate (`ca.crt`) - - and whichever are supplied, will be used for connecting to the - registry. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. The Secret must - be of type `Opaque` or `kubernetes.io/tls`. - - It takes precedence over the values specified in the Secret referred - to by `.spec.secretRef`. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - insecure: - description: |- - Insecure allows connecting to a non-TLS HTTP container registry. - This field is only taken into account if the .spec.type field is set to 'oci'. - type: boolean - interval: - description: |- - Interval at which the HelmRepository URL is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - passCredentials: - description: |- - PassCredentials allows the credentials from the SecretRef to be passed - on to a host that does not match the host as defined in URL. - This may be required if the host of the advertised chart URLs in the - index differ from the defined URL. - Enabling this should be done with caution, as it can potentially result - in credentials getting stolen in a MITM-attack. - type: boolean - provider: - default: generic - description: |- - Provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. - This field is optional, and only taken into account if the .spec.type field is set to 'oci'. - When not specified, defaults to 'generic'. - enum: - - generic - - aws - - azure - - gcp - type: string - secretRef: - description: |- - SecretRef specifies the Secret containing authentication credentials - for the HelmRepository. - For HTTP/S basic auth the secret must contain 'username' and 'password' - fields. - Support for TLS auth using the 'certFile' and 'keyFile', and/or 'caFile' - keys is deprecated. Please use `.spec.certSecretRef` instead. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - suspend: - description: |- - Suspend tells the controller to suspend the reconciliation of this - HelmRepository. - type: boolean - timeout: - description: |- - Timeout is used for the index fetch operation for an HTTPS helm repository, - and for remote OCI Repository operations like pulling for an OCI helm - chart by the associated HelmChart. - Its default value is 60s. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - type: - description: |- - Type of the HelmRepository. - When this field is set to "oci", the URL field value must be prefixed with "oci://". - enum: - - default - - oci - type: string - url: - description: |- - URL of the Helm repository, a valid URL contains at least a protocol and - host. - pattern: ^(http|https|oci)://.*$ - type: string - required: - - url - type: object - status: - default: - observedGeneration: -1 - description: HelmRepositoryStatus records the observed state of the HelmRepository. - properties: - artifact: - description: - Artifact represents the last successful HelmRepository - reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the HelmRepository. - items: - description: - Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: |- - ObservedGeneration is the last observed generation of the HelmRepository - object. - format: int64 - type: integer - url: - description: |- - 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. - type: string - type: object - type: object - served: true - storage: false - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.19.0 - labels: - backup.deckhouse.io/cluster-config: "true" - heritage: deckhouse - module: operator-helm - name: internalnelmoperatorocirepositories.source.internal.operator-helm.deckhouse.io -spec: - group: source.internal.operator-helm.deckhouse.io - names: - kind: InternalNelmOperatorOCIRepository - listKind: InternalNelmOperatorOCIRepositoryList - plural: internalnelmoperatorocirepositories - singular: internalnelmoperatorocirepository - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.url - name: URL - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1 - schema: - openAPIV3Schema: - description: OCIRepository is the Schema for the ocirepositories API - 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: OCIRepositorySpec defines the desired state of OCIRepository - properties: - certSecretRef: - description: |- - CertSecretRef can be given the name of a Secret containing - either or both of - - - a PEM-encoded client certificate (`tls.crt`) and private - key (`tls.key`); - - a PEM-encoded CA certificate (`ca.crt`) - - and whichever are supplied, will be used for connecting to the - registry. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. The Secret must - be of type `Opaque` or `kubernetes.io/tls`. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - ignore: - description: |- - 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. - type: string - insecure: - description: - Insecure allows connecting to a non-TLS HTTP container - registry. - type: boolean - interval: - description: |- - Interval at which the OCIRepository URL is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - layerSelector: - description: |- - LayerSelector specifies which layer should be extracted from the OCI artifact. - When not specified, the first layer found in the artifact is selected. - properties: - mediaType: - description: |- - MediaType specifies the OCI media type of the layer - which should be extracted from the OCI Artifact. The - first layer matching this type is selected. - type: string - operation: - description: |- - Operation specifies how the selected layer should be processed. - By default, the layer compressed content is extracted to storage. - When the operation is set to 'copy', the layer compressed content - is persisted to storage as it is. - enum: - - extract - - copy - type: string - type: object - provider: - default: generic - description: |- - The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. - When not specified, defaults to 'generic'. - enum: - - generic - - aws - - azure - - gcp - type: string - proxySecretRef: - description: |- - ProxySecretRef specifies the Secret containing the proxy configuration - to use while communicating with the container registry. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - ref: - description: |- - The OCI reference to pull and monitor for changes, - defaults to the latest tag. - properties: - digest: - description: |- - Digest is the image digest to pull, takes precedence over SemVer. - The value should be in the format 'sha256:'. - type: string - semver: - description: |- - SemVer is the range of tags to pull selecting the latest within - the range, takes precedence over Tag. - type: string - semverFilter: - description: - SemverFilter is a regex pattern to filter the tags - within the SemVer range. - type: string - tag: - description: Tag is the image tag to pull, defaults to latest. - type: string - type: object - secretRef: - description: |- - SecretRef contains the secret name containing the registry login - credentials to resolve image metadata. - The secret must be of type kubernetes.io/dockerconfigjson. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - serviceAccountName: - description: |- - ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate - the image pull if the service account has attached pull secrets. For more information: - https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account - type: string - suspend: - description: - This flag tells the controller to suspend the reconciliation - of this source. - type: boolean - timeout: - default: 60s - description: - The timeout for remote OCI Repository operations like - pulling, defaults to 60s. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - url: - description: |- - URL is a reference to an OCI artifact repository hosted - on a remote container registry. - pattern: ^oci://.*$ - type: string - verify: - description: |- - Verify contains the secret name containing the trusted public keys - used to verify the signature and specifies which provider to use to check - whether OCI image is authentic. - properties: - matchOIDCIdentity: - description: |- - MatchOIDCIdentity specifies the identity matching criteria to use - while verifying an OCI artifact which was signed using Cosign keyless - signing. The artifact's identity is deemed to be verified if any of the - specified matchers match against the identity. - items: - description: |- - OIDCIdentityMatch specifies options for verifying the certificate identity, - i.e. the issuer and the subject of the certificate. - properties: - issuer: - description: |- - Issuer specifies the regex pattern to match against to verify - the OIDC issuer in the Fulcio certificate. The pattern must be a - valid Go regular expression. - type: string - subject: - description: |- - Subject specifies the regex pattern to match against to verify - the identity subject in the Fulcio certificate. The pattern must - be a valid Go regular expression. - type: string - required: - - issuer - - subject - type: object - type: array - provider: - default: cosign - description: - Provider specifies the technology used to sign the - OCI Artifact. - enum: - - cosign - - notation - type: string - secretRef: - description: |- - SecretRef specifies the Kubernetes Secret containing the - trusted public keys. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - provider - type: object - required: - - interval - - url - type: object - status: - default: - observedGeneration: -1 - description: OCIRepositoryStatus defines the observed state of OCIRepository - properties: - artifact: - description: - Artifact represents the output of the last successful - OCI Repository sync. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the OCIRepository. - items: - description: - Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: ObservedGeneration is the last observed generation. - format: int64 - type: integer - observedIgnore: - description: |- - ObservedIgnore is the observed exclusion patterns used for constructing - the source artifact. - type: string - observedLayerSelector: - description: |- - ObservedLayerSelector is the observed layer selector used for constructing - the source artifact. - properties: - mediaType: - description: |- - MediaType specifies the OCI media type of the layer - which should be extracted from the OCI Artifact. The - first layer matching this type is selected. - type: string - operation: - description: |- - Operation specifies how the selected layer should be processed. - By default, the layer compressed content is extracted to storage. - When the operation is set to 'copy', the layer compressed content - is persisted to storage as it is. - enum: - - extract - - copy - type: string - type: object - url: - description: - URL is the download link for the artifact output of the - last OCI Repository sync. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .spec.url - name: URL - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - deprecated: true - deprecationWarning: v1beta2 OCIRepository is deprecated, upgrade to v1 - name: v1beta2 - schema: - openAPIV3Schema: - description: OCIRepository is the Schema for the ocirepositories API - 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: OCIRepositorySpec defines the desired state of OCIRepository - properties: - certSecretRef: - description: |- - CertSecretRef can be given the name of a Secret containing - either or both of - - - a PEM-encoded client certificate (`tls.crt`) and private - key (`tls.key`); - - a PEM-encoded CA certificate (`ca.crt`) - - and whichever are supplied, will be used for connecting to the - registry. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. The Secret must - be of type `Opaque` or `kubernetes.io/tls`. - - Note: Support for the `caFile`, `certFile` and `keyFile` keys have - been deprecated. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - ignore: - description: |- - 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. - type: string - insecure: - description: - Insecure allows connecting to a non-TLS HTTP container - registry. - type: boolean - interval: - description: |- - Interval at which the OCIRepository URL is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - layerSelector: - description: |- - LayerSelector specifies which layer should be extracted from the OCI artifact. - When not specified, the first layer found in the artifact is selected. - properties: - mediaType: - description: |- - MediaType specifies the OCI media type of the layer - which should be extracted from the OCI Artifact. The - first layer matching this type is selected. - type: string - operation: - description: |- - Operation specifies how the selected layer should be processed. - By default, the layer compressed content is extracted to storage. - When the operation is set to 'copy', the layer compressed content - is persisted to storage as it is. - enum: - - extract - - copy - type: string - type: object - provider: - default: generic - description: |- - The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. - When not specified, defaults to 'generic'. - enum: - - generic - - aws - - azure - - gcp - type: string - proxySecretRef: - description: |- - ProxySecretRef specifies the Secret containing the proxy configuration - to use while communicating with the container registry. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - ref: - description: |- - The OCI reference to pull and monitor for changes, - defaults to the latest tag. - properties: - digest: - description: |- - Digest is the image digest to pull, takes precedence over SemVer. - The value should be in the format 'sha256:'. - type: string - semver: - description: |- - SemVer is the range of tags to pull selecting the latest within - the range, takes precedence over Tag. - type: string - semverFilter: - description: - SemverFilter is a regex pattern to filter the tags - within the SemVer range. - type: string - tag: - description: Tag is the image tag to pull, defaults to latest. - type: string - type: object - secretRef: - description: |- - SecretRef contains the secret name containing the registry login - credentials to resolve image metadata. - The secret must be of type kubernetes.io/dockerconfigjson. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - serviceAccountName: - description: |- - ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate - the image pull if the service account has attached pull secrets. For more information: - https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account - type: string - suspend: - description: - This flag tells the controller to suspend the reconciliation - of this source. - type: boolean - timeout: - default: 60s - description: - The timeout for remote OCI Repository operations like - pulling, defaults to 60s. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - url: - description: |- - URL is a reference to an OCI artifact repository hosted - on a remote container registry. - pattern: ^oci://.*$ - type: string - verify: - description: |- - Verify contains the secret name containing the trusted public keys - used to verify the signature and specifies which provider to use to check - whether OCI image is authentic. - properties: - matchOIDCIdentity: - description: |- - MatchOIDCIdentity specifies the identity matching criteria to use - while verifying an OCI artifact which was signed using Cosign keyless - signing. The artifact's identity is deemed to be verified if any of the - specified matchers match against the identity. - items: - description: |- - OIDCIdentityMatch specifies options for verifying the certificate identity, - i.e. the issuer and the subject of the certificate. - properties: - issuer: - description: |- - Issuer specifies the regex pattern to match against to verify - the OIDC issuer in the Fulcio certificate. The pattern must be a - valid Go regular expression. - type: string - subject: - description: |- - Subject specifies the regex pattern to match against to verify - the identity subject in the Fulcio certificate. The pattern must - be a valid Go regular expression. - type: string - required: - - issuer - - subject - type: object - type: array - provider: - default: cosign - description: - Provider specifies the technology used to sign the - OCI Artifact. - enum: - - cosign - - notation - type: string - secretRef: - description: |- - SecretRef specifies the Kubernetes Secret containing the - trusted public keys. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - provider - type: object - required: - - interval - - url - type: object - status: - default: - observedGeneration: -1 - description: OCIRepositoryStatus defines the observed state of OCIRepository - properties: - artifact: - description: - Artifact represents the output of the last successful - OCI Repository sync. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - 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. - type: string - revision: - description: |- - 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. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - 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. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the OCIRepository. - items: - description: - Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - contentConfigChecksum: - description: |- - ContentConfigChecksum is a checksum of all the configurations related to - the content of the source artifact: - - .spec.ignore - - .spec.layerSelector - observed in .status.observedGeneration version of the object. This can - be used to determine if the content configuration has changed and the - artifact needs to be rebuilt. - It has the format of `:`, for example: `sha256:`. - - Deprecated: Replaced with explicit fields for observed artifact content - config in the status. - type: string - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: ObservedGeneration is the last observed generation. - format: int64 - type: integer - observedIgnore: - description: |- - ObservedIgnore is the observed exclusion patterns used for constructing - the source artifact. - type: string - observedLayerSelector: - description: |- - ObservedLayerSelector is the observed layer selector used for constructing - the source artifact. - properties: - mediaType: - description: |- - MediaType specifies the OCI media type of the layer - which should be extracted from the OCI Artifact. The - first layer matching this type is selected. - type: string - operation: - description: |- - Operation specifies how the selected layer should be processed. - By default, the layer compressed content is extracted to storage. - When the operation is set to 'copy', the layer compressed content - is persisted to storage as it is. - enum: - - extract - - copy - type: string - type: object - url: - description: - URL is the download link for the artifact output of the - last OCI Repository sync. - type: string - type: object - type: object - served: true - storage: false - subresources: - status: {} diff --git a/crds/embedded/source-controller.yaml b/crds/embedded/source-controller.yaml new file mode 100644 index 00000000..cf79a401 --- /dev/null +++ b/crds/embedded/source-controller.yaml @@ -0,0 +1,2140 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + kustomize.toolkit.fluxcd.io/substitute: disabled + labels: + backup.deckhouse.io/cluster-config: "true" + heritage: deckhouse + module: operator-helm + name: internalnelmoperatorbuckets.source.internal.operator-helm.deckhouse.io +spec: + group: source.internal.operator-helm.deckhouse.io + names: + kind: InternalNelmOperatorBucket + listKind: InternalNelmOperatorBucketList + plural: internalnelmoperatorbuckets + singular: internalnelmoperatorbucket + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.endpoint + name: Endpoint + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: Bucket is the Schema for the buckets API. + 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: |- + BucketSpec specifies the required configuration to produce an Artifact for + an object storage bucket. + properties: + bucketName: + description: BucketName is the name of the object storage bucket. + type: string + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + bucket. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + This field is only supported for the `generic` provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + endpoint: + description: Endpoint is the object storage address the BucketName is located at. + type: string + ignore: + description: |- + 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. + type: string + insecure: + description: Insecure allows connecting to a non-TLS HTTP Endpoint. + type: boolean + interval: + description: |- + Interval at which the Bucket Endpoint is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + prefix: + description: Prefix to use for server-side filtering of files in the Bucket. + type: string + provider: + default: generic + description: |- + Provider of the object storage bucket. + Defaults to 'generic', which expects an S3 (API) compatible object + storage. + enum: + - generic + - aws + - gcp + - azure + type: string + proxySecretRef: + description: |- + ProxySecretRef specifies the Secret containing the proxy configuration + to use while communicating with the Bucket server. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + region: + description: Region of the Endpoint where the BucketName is located in. + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials + for the Bucket. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate + the bucket. This field is only supported for the 'gcp' and 'aws' providers. + For more information about workload identity: + https://fluxcd.io/flux/components/source/buckets/#workload-identity + type: string + sts: + description: |- + STS specifies the required configuration to use a Security Token + Service for fetching temporary credentials to authenticate in a + Bucket provider. + + This field is only supported for the `aws` and `generic` providers. + properties: + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + STS endpoint. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + This field is only supported for the `ldap` provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + endpoint: + description: |- + Endpoint is the HTTP/S endpoint of the Security Token Service from + where temporary credentials will be fetched. + pattern: ^(http|https)://.*$ + type: string + provider: + description: Provider of the Security Token Service. + enum: + - aws + - ldap + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials + for the STS endpoint. This Secret must contain the fields `username` + and `password` and is supported only for the `ldap` provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - endpoint + - provider + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + Bucket. + type: boolean + timeout: + default: 60s + description: Timeout for fetch operations, defaults to 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + required: + - bucketName + - endpoint + - interval + type: object + x-kubernetes-validations: + - message: STS configuration is only supported for the 'aws' and 'generic' Bucket providers + rule: self.provider == 'aws' || self.provider == 'generic' || !has(self.sts) + - message: '''aws'' is the only supported STS provider for the ''aws'' Bucket provider' + rule: self.provider != 'aws' || !has(self.sts) || self.sts.provider == 'aws' + - message: '''ldap'' is the only supported STS provider for the ''generic'' Bucket provider' + rule: self.provider != 'generic' || !has(self.sts) || self.sts.provider == 'ldap' + - message: spec.sts.secretRef is not required for the 'aws' STS provider + rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.secretRef)' + - message: spec.sts.certSecretRef is not required for the 'aws' STS provider + rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.certSecretRef)' + - message: ServiceAccountName is not supported for the 'generic' Bucket provider + rule: self.provider != 'generic' || !has(self.serviceAccountName) + - message: cannot set both .spec.secretRef and .spec.serviceAccountName + rule: '!has(self.secretRef) || !has(self.serviceAccountName)' + status: + default: + observedGeneration: -1 + description: BucketStatus records the observed state of a Bucket. + properties: + artifact: + description: Artifact represents the last successful Bucket reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + 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. + type: string + revision: + description: |- + 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. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + 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. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the Bucket. + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation of the Bucket object. + format: int64 + type: integer + observedIgnore: + description: |- + ObservedIgnore is the observed exclusion patterns used for constructing + the source artifact. + type: string + url: + description: |- + 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. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + kustomize.toolkit.fluxcd.io/substitute: disabled + labels: + backup.deckhouse.io/cluster-config: "true" + heritage: deckhouse + module: operator-helm + name: internalnelmoperatorexternalartifacts.source.internal.operator-helm.deckhouse.io +spec: + group: source.internal.operator-helm.deckhouse.io + names: + kind: InternalNelmOperatorExternalArtifact + listKind: InternalNelmOperatorExternalArtifactList + plural: internalnelmoperatorexternalartifacts + singular: internalnelmoperatorexternalartifact + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + - jsonPath: .spec.sourceRef.name + name: Source + type: string + name: v1 + schema: + openAPIV3Schema: + description: ExternalArtifact is the Schema for the external artifacts API + 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: ExternalArtifactSpec defines the desired state of ExternalArtifact + properties: + sourceRef: + description: |- + SourceRef points to the Kubernetes custom resource for + which the artifact is generated. + properties: + apiVersion: + description: API version of the referent, if not specified the Kubernetes preferred version will be used. + type: string + kind: + description: Kind of the referent. + type: string + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it acts as LocalObjectReference. + type: string + required: + - kind + - name + type: object + type: object + status: + description: ExternalArtifactStatus defines the observed state of ExternalArtifact + properties: + artifact: + description: Artifact represents the output of an ExternalArtifact reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + 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. + type: string + revision: + description: |- + 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. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + 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. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the ExternalArtifact. + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + kustomize.toolkit.fluxcd.io/substitute: disabled + labels: + backup.deckhouse.io/cluster-config: "true" + heritage: deckhouse + module: operator-helm + name: internalnelmoperatorgitrepositories.source.internal.operator-helm.deckhouse.io +spec: + group: source.internal.operator-helm.deckhouse.io + names: + kind: InternalNelmOperatorGitRepository + listKind: InternalNelmOperatorGitRepositoryList + plural: internalnelmoperatorgitrepositories + singular: internalnelmoperatorgitrepository + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: GitRepository is the Schema for the gitrepositories API. + 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: |- + GitRepositorySpec specifies the required configuration to produce an + Artifact for a Git repository. + properties: + ignore: + description: |- + 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. + type: string + include: + description: |- + Include specifies a list of GitRepository resources which Artifacts + should be included in the Artifact produced for this GitRepository. + items: + description: |- + GitRepositoryInclude specifies a local reference to a GitRepository which + Artifact (sub-)contents must be included, and where they should be placed. + properties: + fromPath: + description: |- + FromPath specifies the path to copy contents from, defaults to the root + of the Artifact. + type: string + repository: + description: |- + GitRepositoryRef specifies the GitRepository which Artifact contents + must be included. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + toPath: + description: |- + ToPath specifies the path to copy contents to, defaults to the name of + the GitRepositoryRef. + type: string + required: + - repository + type: object + type: array + interval: + description: |- + Interval at which the GitRepository URL is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + provider: + description: |- + Provider used for authentication, can be 'aws', 'azure', 'github', 'generic'. + When not specified, defaults to 'generic'. + enum: + - generic + - aws + - azure + - github + type: string + proxySecretRef: + description: |- + ProxySecretRef specifies the Secret containing the proxy configuration + to use while communicating with the Git server. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + recurseSubmodules: + description: |- + RecurseSubmodules enables the initialization of all submodules within + the GitRepository as cloned from the URL, using their default settings. + type: boolean + ref: + description: |- + Reference specifies the Git reference to resolve and monitor for + changes, defaults to the 'master' branch. + properties: + branch: + description: Branch to check out, defaults to 'master' if no other field is defined. + type: string + commit: + description: |- + Commit SHA to check out, takes precedence over all reference fields. + + This can be combined with Branch to shallow clone the branch, in which + the commit is expected to exist. + type: string + name: + description: |- + Name of the reference to check out; takes precedence over Branch, Tag and SemVer. + + It must be a valid Git reference: https://git-scm.com/docs/git-check-ref-format#_description + Examples: "refs/heads/main", "refs/tags/v0.1.0", "refs/pull/420/head", "refs/merge-requests/1/head" + type: string + semver: + description: SemVer tag expression to check out, takes precedence over Tag. + type: string + tag: + description: Tag to check out, takes precedence over Branch. + type: string + type: object + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials for + the GitRepository. + For HTTPS repositories the Secret must contain 'username' and 'password' + fields for basic auth or 'bearerToken' field for token auth. + For SSH repositories the Secret must contain 'identity' + and 'known_hosts' fields. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the Kubernetes ServiceAccount used to + authenticate to the GitRepository. This field is only supported for 'azure' and 'aws' providers. + type: string + sparseCheckout: + description: |- + SparseCheckout specifies a list of directories to checkout when cloning + the repository. If specified, only these directories are included in the + Artifact produced for this GitRepository. + items: + type: string + type: array + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + GitRepository. + type: boolean + timeout: + default: 60s + description: Timeout for Git operations like cloning, defaults to 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + url: + description: URL specifies the Git repository URL, it can be an HTTP/S or SSH address. + pattern: ^(http|https|ssh)://.*$ + type: string + verify: + description: |- + Verification specifies the configuration to verify the Git commit + signature(s). + properties: + mode: + default: HEAD + description: |- + Mode specifies which Git object(s) should be verified. + + The variants "head" and "HEAD" both imply the same thing, i.e. verify + the commit that the HEAD of the Git repository points to. The variant + "head" solely exists to ensure backwards compatibility. + enum: + - head + - HEAD + - Tag + - TagAndHEAD + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing the public keys of trusted Git + authors. PGP public keys must be stored under keys with the .asc suffix, + and SSH public keys must be stored under keys with the .sshpub suffix. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - secretRef + type: object + required: + - interval + - url + type: object + x-kubernetes-validations: + - message: serviceAccountName can only be set when provider is 'azure' or 'aws' + rule: '!has(self.serviceAccountName) || (has(self.provider) && (self.provider == ''azure'' || self.provider == ''aws''))' + status: + default: + observedGeneration: -1 + description: GitRepositoryStatus records the observed state of a Git repository. + properties: + artifact: + description: Artifact represents the last successful GitRepository reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + 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. + type: string + revision: + description: |- + 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. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + 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. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the GitRepository. + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + includedArtifacts: + description: |- + IncludedArtifacts contains a list of the last successfully included + Artifacts as instructed by GitRepositorySpec.Include. + items: + description: Artifact represents the output of a Source reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + 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. + type: string + revision: + description: |- + 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. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + 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. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: |- + ObservedGeneration is the last observed generation of the GitRepository + object. + format: int64 + type: integer + observedIgnore: + description: |- + ObservedIgnore is the observed exclusion patterns used for constructing + the source artifact. + type: string + observedInclude: + description: |- + ObservedInclude is the observed list of GitRepository resources used to + produce the current Artifact. + items: + description: |- + GitRepositoryInclude specifies a local reference to a GitRepository which + Artifact (sub-)contents must be included, and where they should be placed. + properties: + fromPath: + description: |- + FromPath specifies the path to copy contents from, defaults to the root + of the Artifact. + type: string + repository: + description: |- + GitRepositoryRef specifies the GitRepository which Artifact contents + must be included. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + toPath: + description: |- + ToPath specifies the path to copy contents to, defaults to the name of + the GitRepositoryRef. + type: string + required: + - repository + type: object + type: array + observedRecurseSubmodules: + description: |- + ObservedRecurseSubmodules is the observed resource submodules + configuration used to produce the current Artifact. + type: boolean + observedSparseCheckout: + description: |- + ObservedSparseCheckout is the observed list of directories used to + produce the current Artifact. + items: + type: string + type: array + sourceVerificationMode: + description: |- + SourceVerificationMode is the last used verification mode indicating + which Git object(s) have been verified. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + kustomize.toolkit.fluxcd.io/substitute: disabled + labels: + backup.deckhouse.io/cluster-config: "true" + heritage: deckhouse + module: operator-helm + name: internalnelmoperatorhelmcharts.source.internal.operator-helm.deckhouse.io +spec: + group: source.internal.operator-helm.deckhouse.io + names: + kind: InternalNelmOperatorHelmChart + listKind: InternalNelmOperatorHelmChartList + plural: internalnelmoperatorhelmcharts + singular: internalnelmoperatorhelmchart + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.chart + name: Chart + type: string + - jsonPath: .spec.version + name: Version + type: string + - jsonPath: .spec.sourceRef.kind + name: Source Kind + type: string + - jsonPath: .spec.sourceRef.name + name: Source Name + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: HelmChart is the Schema for the helmcharts API. + 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 specifies the desired state of a Helm chart. + properties: + chart: + description: |- + Chart is the name or path the Helm chart is available at in the + SourceRef. + type: string + ignoreMissingValuesFiles: + description: |- + IgnoreMissingValuesFiles controls whether to silently ignore missing values + files rather than failing. + type: boolean + interval: + description: |- + Interval at which the HelmChart SourceRef is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + reconcileStrategy: + default: ChartVersion + description: |- + ReconcileStrategy determines what enables the creation of a new artifact. + Valid values are ('ChartVersion', 'Revision'). + See the documentation of the values for an explanation on their behavior. + Defaults to ChartVersion when omitted. + enum: + - ChartVersion + - Revision + type: string + sourceRef: + description: SourceRef is the reference to the Source the chart is available at. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: |- + Kind of the referent, valid values are ('HelmRepository', 'GitRepository', + 'Bucket'). + enum: + - InternalNelmOperatorHelmRepository + - InternalNelmOperatorGitRepository + - InternalNelmOperatorBucket + type: string + name: + description: Name of the referent. + type: string + required: + - kind + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + source. + type: boolean + valuesFiles: + description: |- + ValuesFiles is an alternative list of values files to use as the chart + values (values.yaml is not included by default), expected to be a + relative path in the SourceRef. + Values files are merged in the order of this list with the last file + overriding the first. Ignored when omitted. + items: + type: string + type: array + verify: + description: |- + Verify contains the secret name containing the trusted public keys + used to verify the signature and specifies which provider to use to check + whether OCI image is authentic. + This field is only supported when using HelmRepository source with spec.type 'oci'. + Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified. + properties: + matchOIDCIdentity: + description: |- + MatchOIDCIdentity specifies the identity matching criteria to use + while verifying an OCI artifact which was signed using Cosign keyless + signing. The artifact's identity is deemed to be verified if any of the + specified matchers match against the identity. + items: + description: |- + OIDCIdentityMatch specifies options for verifying the certificate identity, + i.e. the issuer and the subject of the certificate. + properties: + issuer: + description: |- + Issuer specifies the regex pattern to match against to verify + the OIDC issuer in the Fulcio certificate. The pattern must be a + valid Go regular expression. + type: string + subject: + description: |- + Subject specifies the regex pattern to match against to verify + the identity subject in the Fulcio certificate. The pattern must + be a valid Go regular expression. + type: string + required: + - issuer + - subject + type: object + type: array + provider: + default: cosign + description: Provider specifies the technology used to sign the OCI Artifact. + enum: + - cosign + - notation + type: string + secretRef: + description: |- + SecretRef specifies the Kubernetes Secret containing the + trusted public keys. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + version: + default: '*' + description: |- + Version is the chart version semver expression, ignored for charts from + GitRepository and Bucket sources. Defaults to latest when omitted. + type: string + required: + - chart + - interval + - sourceRef + type: object + x-kubernetes-validations: + - message: spec.verify is only supported when spec.sourceRef.kind is 'HelmRepository' + rule: '!has(self.verify) || self.sourceRef.kind == ''HelmRepository''' + status: + default: + observedGeneration: -1 + description: HelmChartStatus records the observed state of the HelmChart. + properties: + artifact: + description: Artifact represents the output of the last successful reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + 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. + type: string + revision: + description: |- + 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. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + 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. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the HelmChart. + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedChartName: + description: |- + ObservedChartName is the last observed chart name as specified by the + resolved chart reference. + type: string + observedGeneration: + description: |- + ObservedGeneration is the last observed generation of the HelmChart + object. + format: int64 + type: integer + observedSourceArtifactRevision: + description: |- + ObservedSourceArtifactRevision is the last observed Artifact.Revision + of the HelmChartSpec.SourceRef. + type: string + observedValuesFiles: + description: |- + ObservedValuesFiles are the observed value files of the last successful + reconciliation. + It matches the chart in the last successfully reconciled artifact. + items: + type: string + type: array + url: + description: |- + URL is the dynamic fetch link for the latest Artifact. + It is provided on a "best effort" basis, and using the precise + HelmChartStatus.Artifact data is recommended. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + kustomize.toolkit.fluxcd.io/substitute: disabled + labels: + backup.deckhouse.io/cluster-config: "true" + heritage: deckhouse + module: operator-helm + name: internalnelmoperatorhelmrepositories.source.internal.operator-helm.deckhouse.io +spec: + group: source.internal.operator-helm.deckhouse.io + names: + kind: InternalNelmOperatorHelmRepository + listKind: InternalNelmOperatorHelmRepositoryList + plural: internalnelmoperatorhelmrepositories + singular: internalnelmoperatorhelmrepository + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: HelmRepository is the Schema for the helmrepositories API. + 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: |- + HelmRepositorySpec specifies the required configuration to produce an + Artifact for a Helm repository index YAML. + properties: + accessFrom: + description: |- + AccessFrom specifies an Access Control List for allowing cross-namespace + references to this object. + NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 + properties: + namespaceSelectors: + description: |- + NamespaceSelectors is the list of namespace selectors to which this ACL applies. + Items in this list are evaluated using a logical OR operation. + items: + description: |- + NamespaceSelector selects the namespaces to which this ACL applies. + An empty map of MatchLabels matches all namespaces in a cluster. + properties: + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: array + required: + - namespaceSelectors + type: object + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + registry. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + It takes precedence over the values specified in the Secret referred + to by `.spec.secretRef`. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + insecure: + description: |- + Insecure allows connecting to a non-TLS HTTP container registry. + This field is only taken into account if the .spec.type field is set to 'oci'. + type: boolean + interval: + description: |- + Interval at which the HelmRepository URL is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + passCredentials: + description: |- + PassCredentials allows the credentials from the SecretRef to be passed + on to a host that does not match the host as defined in URL. + This may be required if the host of the advertised chart URLs in the + index differ from the defined URL. + Enabling this should be done with caution, as it can potentially result + in credentials getting stolen in a MITM-attack. + type: boolean + provider: + default: generic + description: |- + Provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. + This field is optional, and only taken into account if the .spec.type field is set to 'oci'. + When not specified, defaults to 'generic'. + enum: + - generic + - aws + - azure + - gcp + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials + for the HelmRepository. + For HTTP/S basic auth the secret must contain 'username' and 'password' + fields. + Support for TLS auth using the 'certFile' and 'keyFile', and/or 'caFile' + keys is deprecated. Please use `.spec.certSecretRef` instead. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + HelmRepository. + type: boolean + timeout: + description: |- + Timeout is used for the index fetch operation for an HTTPS helm repository, + and for remote OCI Repository operations like pulling for an OCI helm + chart by the associated HelmChart. + Its default value is 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + type: + description: |- + Type of the HelmRepository. + When this field is set to "oci", the URL field value must be prefixed with "oci://". + enum: + - default + - oci + type: string + url: + description: |- + URL of the Helm repository, a valid URL contains at least a protocol and + host. + pattern: ^(http|https|oci)://.*$ + type: string + required: + - url + type: object + status: + default: + observedGeneration: -1 + description: HelmRepositoryStatus records the observed state of the HelmRepository. + properties: + artifact: + description: Artifact represents the last successful HelmRepository reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + 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. + type: string + revision: + description: |- + 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. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + 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. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the HelmRepository. + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: |- + ObservedGeneration is the last observed generation of the HelmRepository + object. + format: int64 + type: integer + url: + description: |- + 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. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + kustomize.toolkit.fluxcd.io/substitute: disabled + labels: + backup.deckhouse.io/cluster-config: "true" + heritage: deckhouse + module: operator-helm + name: internalnelmoperatorocirepositories.source.internal.operator-helm.deckhouse.io +spec: + group: source.internal.operator-helm.deckhouse.io + names: + kind: InternalNelmOperatorOCIRepository + listKind: InternalNelmOperatorOCIRepositoryList + plural: internalnelmoperatorocirepositories + singular: internalnelmoperatorocirepository + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: OCIRepository is the Schema for the ocirepositories API + 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: OCIRepositorySpec defines the desired state of OCIRepository + properties: + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + registry. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + ignore: + description: |- + 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. + type: string + insecure: + description: Insecure allows connecting to a non-TLS HTTP container registry. + type: boolean + interval: + description: |- + Interval at which the OCIRepository URL is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + layerSelector: + description: |- + LayerSelector specifies which layer should be extracted from the OCI artifact. + When not specified, the first layer found in the artifact is selected. + properties: + mediaType: + description: |- + MediaType specifies the OCI media type of the layer + which should be extracted from the OCI Artifact. The + first layer matching this type is selected. + type: string + operation: + description: |- + Operation specifies how the selected layer should be processed. + By default, the layer compressed content is extracted to storage. + When the operation is set to 'copy', the layer compressed content + is persisted to storage as it is. + enum: + - extract + - copy + type: string + type: object + provider: + default: generic + description: |- + The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. + When not specified, defaults to 'generic'. + enum: + - generic + - aws + - azure + - gcp + type: string + proxySecretRef: + description: |- + ProxySecretRef specifies the Secret containing the proxy configuration + to use while communicating with the container registry. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + ref: + description: |- + The OCI reference to pull and monitor for changes, + defaults to the latest tag. + properties: + digest: + description: |- + Digest is the image digest to pull, takes precedence over SemVer. + The value should be in the format 'sha256:'. + type: string + semver: + description: |- + SemVer is the range of tags to pull selecting the latest within + the range, takes precedence over Tag. + type: string + semverFilter: + description: SemverFilter is a regex pattern to filter the tags within the SemVer range. + type: string + tag: + description: Tag is the image tag to pull, defaults to latest. + type: string + type: object + secretRef: + description: |- + SecretRef contains the secret name containing the registry login + credentials to resolve image metadata. + The secret must be of type kubernetes.io/dockerconfigjson. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate + the image pull if the service account has attached pull secrets. For more information: + https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account + type: string + suspend: + description: This flag tells the controller to suspend the reconciliation of this source. + type: boolean + timeout: + default: 60s + description: The timeout for remote OCI Repository operations like pulling, defaults to 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + url: + description: |- + URL is a reference to an OCI artifact repository hosted + on a remote container registry. + pattern: ^oci://.*$ + type: string + verify: + description: |- + Verify contains the secret name containing the trusted public keys + used to verify the signature and specifies which provider to use to check + whether OCI image is authentic. + properties: + matchOIDCIdentity: + description: |- + MatchOIDCIdentity specifies the identity matching criteria to use + while verifying an OCI artifact which was signed using Cosign keyless + signing. The artifact's identity is deemed to be verified if any of the + specified matchers match against the identity. + items: + description: |- + OIDCIdentityMatch specifies options for verifying the certificate identity, + i.e. the issuer and the subject of the certificate. + properties: + issuer: + description: |- + Issuer specifies the regex pattern to match against to verify + the OIDC issuer in the Fulcio certificate. The pattern must be a + valid Go regular expression. + type: string + subject: + description: |- + Subject specifies the regex pattern to match against to verify + the identity subject in the Fulcio certificate. The pattern must + be a valid Go regular expression. + type: string + required: + - issuer + - subject + type: object + type: array + provider: + default: cosign + description: Provider specifies the technology used to sign the OCI Artifact. + enum: + - cosign + - notation + type: string + secretRef: + description: |- + SecretRef specifies the Kubernetes Secret containing the + trusted public keys. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + trustedRootSecretRef: + description: |- + TrustedRootSecretRef specifies the Kubernetes Secret containing a + Sigstore trusted_root.json file. This enables verification against + self-hosted Sigstore infrastructure (custom Fulcio CA, self-hosted + Rekor instance). The Secret must contain a key named "trusted_root.json". + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + required: + - interval + - url + type: object + status: + default: + observedGeneration: -1 + description: OCIRepositoryStatus defines the observed state of OCIRepository + properties: + artifact: + description: Artifact represents the output of the last successful OCI Repository sync. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + 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. + type: string + revision: + description: |- + 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. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + 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. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the OCIRepository. + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + observedIgnore: + description: |- + ObservedIgnore is the observed exclusion patterns used for constructing + the source artifact. + type: string + observedLayerSelector: + description: |- + ObservedLayerSelector is the observed layer selector used for constructing + the source artifact. + properties: + mediaType: + description: |- + MediaType specifies the OCI media type of the layer + which should be extracted from the OCI Artifact. The + first layer matching this type is selected. + type: string + operation: + description: |- + Operation specifies how the selected layer should be processed. + By default, the layer compressed content is extracted to storage. + When the operation is set to 'copy', the layer compressed content + is persisted to storage as it is. + enum: + - extract + - copy + type: string + type: object + url: + description: URL is the download link for the artifact output of the last OCI Repository sync. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/tools/internalcrds/go.mod b/tools/internalcrds/go.mod index 52fb642e..d7154b01 100644 --- a/tools/internalcrds/go.mod +++ b/tools/internalcrds/go.mod @@ -1,3 +1,5 @@ module github.com/deckhouse/operator-helm/tools/internalcrds go 1.26.3 + +require go.yaml.in/yaml/v3 v3.0.4 diff --git a/tools/internalcrds/go.sum b/tools/internalcrds/go.sum new file mode 100644 index 00000000..56a75c76 --- /dev/null +++ b/tools/internalcrds/go.sum @@ -0,0 +1,4 @@ +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/tools/internalcrds/main.go b/tools/internalcrds/main.go new file mode 100644 index 00000000..8c9ee54e --- /dev/null +++ b/tools/internalcrds/main.go @@ -0,0 +1,158 @@ +/* +Copyright 2026 Flant JSC. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Command internalcrds turns the upstream flux CustomResourceDefinitions into +// the internal ones this module ships. It reads every yaml document from the +// input directories, renames it, and writes one file per controller. +// +// Usage: +// +// internalcrds -out crds/embedded/helm-controller.yaml ... +package main + +import ( + "bytes" + "flag" + "fmt" + "os" + "path/filepath" + "slices" + "strings" + + "go.yaml.in/yaml/v3" +) + +// forbiddenGroup must not survive into the rendered output. Its presence means +// some identity slipped past Rename: a kind or a nested group field a future +// flux version introduces in a place the rename table does not yet know about. +const forbiddenGroup = "toolkit.fluxcd.io" + +// allowedAnnotation is the sole legitimate survivor of forbiddenGroup: a +// kustomize substitution annotation key upstream declares as an example, not +// an identity this module renames. +const allowedAnnotation = "kustomize.toolkit.fluxcd.io/substitute" + +func main() { + out := flag.String("out", "", "file to write the renamed definitions to") + flag.Parse() + + if *out == "" || flag.NArg() == 0 { + fmt.Fprintln(os.Stderr, "usage: internalcrds -out ...") + os.Exit(2) + } + + if err := run(*out, flag.Args()); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func run(out string, dirs []string) error { + var docs []map[string]any + + for _, dir := range dirs { + entries, err := os.ReadDir(dir) + if err != nil { + return fmt.Errorf("reading %s: %w", dir, err) + } + + for _, entry := range entries { + if entry.IsDir() || filepath.Ext(entry.Name()) != ".yaml" { + continue + } + + raw, err := os.ReadFile(filepath.Join(dir, entry.Name())) + if err != nil { + return fmt.Errorf("reading %s: %w", entry.Name(), err) + } + + doc := map[string]any{} + if err := yaml.Unmarshal(raw, &doc); err != nil { + return fmt.Errorf("parsing %s: %w", entry.Name(), err) + } + if err := Rename(doc); err != nil { + return fmt.Errorf("renaming %s: %w", entry.Name(), err) + } + + docs = append(docs, doc) + } + } + + // A stable order, or every run produces a different file. + slices.SortFunc(docs, func(a, b map[string]any) int { + return strings.Compare(name(a), name(b)) + }) + + var buf bytes.Buffer + for _, doc := range docs { + encoded, err := marshal(doc) + if err != nil { + return fmt.Errorf("encoding %s: %w", name(doc), err) + } + + buf.WriteString("---\n") + buf.Write(encoded) + } + + if err := checkNoLeftoverUpstream(out, buf.Bytes()); err != nil { + return err + } + + return os.WriteFile(out, buf.Bytes(), 0o644) +} + +// marshal renders a document with the two-space indent kubectl and +// controller-gen use, so the committed files carry no unrelated whitespace +// diff on top of the actual rename: the library's own default is four spaces. +func marshal(doc map[string]any) ([]byte, error) { + var buf bytes.Buffer + + enc := yaml.NewEncoder(&buf) + enc.SetIndent(2) + + if err := enc.Encode(doc); err != nil { + return nil, err + } + if err := enc.Close(); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +func name(doc map[string]any) string { + metadata, _ := doc["metadata"].(map[string]any) + value, _ := metadata["name"].(string) + + return value +} + +// checkNoLeftoverUpstream fails if the rendered output still names an upstream +// flux group or kind: Rename addresses identities it knows by name, so a kind +// added by a future upstream release, or a group nested somewhere the walk +// does not visit, would otherwise slip through and ship silently unrenamed. +func checkNoLeftoverUpstream(path string, rendered []byte) error { + for i, line := range strings.Split(string(rendered), "\n") { + stripped := strings.ReplaceAll(line, allowedAnnotation, "") + if !strings.Contains(stripped, forbiddenGroup) { + continue + } + + return fmt.Errorf("%s:%d: leftover upstream identity: %s", path, i+1, strings.TrimSpace(line)) + } + + return nil +} diff --git a/tools/internalcrds/main_test.go b/tools/internalcrds/main_test.go new file mode 100644 index 00000000..4254db11 --- /dev/null +++ b/tools/internalcrds/main_test.go @@ -0,0 +1,41 @@ +/* +Copyright 2026 Flant JSC. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import "testing" + +func TestCheckNoLeftoverUpstreamFailsOnLeftoverGroup(t *testing.T) { + rendered := "spec:\n group: source.toolkit.fluxcd.io\n" + + err := checkNoLeftoverUpstream("out.yaml", []byte(rendered)) + if err == nil { + t.Fatal("expected an error, got nil") + } + + const want = `out.yaml:2: leftover upstream identity: group: source.toolkit.fluxcd.io` + if err.Error() != want { + t.Fatalf("error = %q, want %q", err.Error(), want) + } +} + +func TestCheckNoLeftoverUpstreamAllowsSubstituteAnnotation(t *testing.T) { + rendered := "metadata:\n annotations:\n kustomize.toolkit.fluxcd.io/substitute: \"true\"\n" + + if err := checkNoLeftoverUpstream("out.yaml", []byte(rendered)); err != nil { + t.Fatalf("checkNoLeftoverUpstream returned %v", err) + } +} From 8bfb9fca0a04d6eb091dda87b1a757ba2c849991 Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 15:47:52 +0300 Subject: [PATCH 03/19] fix(tools): close the kind gap in the internal CRD guard The leftover-string guard only ever caught an unrenamed group: a bare kind carries no toolkit.fluxcd.io substring for it to see. checkKnownKind now rejects a document whose spec.names.kind is not one Rename recognizes, which is where a new upstream kind first becomes visible, since it arrives as its own definition file. Also wires tools/internalcrds's tests into the root test:unit aggregate, so CI actually runs them, and drops the indent numbers from a comment per the no-constant-values-in-comments rule. Signed-off-by: Ilya Drey --- Taskfile.yaml | 1 + tools/internalcrds/main.go | 38 +++++++++++++++++++++++++-------- tools/internalcrds/main_test.go | 35 +++++++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 8e585e3a..240fd7fb 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -109,6 +109,7 @@ tasks: - task: operator-helm-controller:test:unit - task: chart-values-controller:test:unit - task: e2e:test:unit + - cd tools/internalcrds && go test ./... test:e2e:setup: desc: "Setup environment for e2e tests." diff --git a/tools/internalcrds/main.go b/tools/internalcrds/main.go index 8c9ee54e..e73f2d3f 100644 --- a/tools/internalcrds/main.go +++ b/tools/internalcrds/main.go @@ -36,8 +36,9 @@ import ( ) // forbiddenGroup must not survive into the rendered output. Its presence means -// some identity slipped past Rename: a kind or a nested group field a future -// flux version introduces in a place the rename table does not yet know about. +// a group slipped past Rename: one nested somewhere the walk does not visit, +// which a future flux version could introduce without the rename table +// noticing. const forbiddenGroup = "toolkit.fluxcd.io" // allowedAnnotation is the sole legitimate survivor of forbiddenGroup: a @@ -83,6 +84,9 @@ func run(out string, dirs []string) error { if err := yaml.Unmarshal(raw, &doc); err != nil { return fmt.Errorf("parsing %s: %w", entry.Name(), err) } + if err := checkKnownKind(entry.Name(), doc); err != nil { + return err + } if err := Rename(doc); err != nil { return fmt.Errorf("renaming %s: %w", entry.Name(), err) } @@ -114,9 +118,9 @@ func run(out string, dirs []string) error { return os.WriteFile(out, buf.Bytes(), 0o644) } -// marshal renders a document with the two-space indent kubectl and -// controller-gen use, so the committed files carry no unrelated whitespace -// diff on top of the actual rename: the library's own default is four spaces. +// marshal renders a document with the indent kubectl and controller-gen use, +// rather than the library's own default, so the committed files carry no +// unrelated whitespace diff on top of the actual rename. func marshal(doc map[string]any) ([]byte, error) { var buf bytes.Buffer @@ -140,10 +144,26 @@ func name(doc map[string]any) string { return value } -// checkNoLeftoverUpstream fails if the rendered output still names an upstream -// flux group or kind: Rename addresses identities it knows by name, so a kind -// added by a future upstream release, or a group nested somewhere the walk -// does not visit, would otherwise slip through and ship silently unrenamed. +// checkKnownKind fails when a document declares a kind Rename does not know +// about. A new upstream kind arrives as a new definition file, so this is +// where such an addition is caught, before Rename has a chance to leave a +// reference to it unrenamed elsewhere in the schema. +func checkKnownKind(entryName string, doc map[string]any) error { + spec, _ := doc["spec"].(map[string]any) + names, _ := spec["names"].(map[string]any) + kind, _ := names["kind"].(string) + + if !slices.Contains(upstreamKinds, kind) { + return fmt.Errorf("%s: unknown upstream kind %q", entryName, kind) + } + + return nil +} + +// checkNoLeftoverUpstream fails if the rendered output still names an +// upstream flux group: Rename addresses the group by path, so a group nested +// somewhere the walk does not visit would otherwise slip through and ship +// silently unrenamed. It says nothing about kinds; checkKnownKind covers those. func checkNoLeftoverUpstream(path string, rendered []byte) error { for i, line := range strings.Split(string(rendered), "\n") { stripped := strings.ReplaceAll(line, allowedAnnotation, "") diff --git a/tools/internalcrds/main_test.go b/tools/internalcrds/main_test.go index 4254db11..804fe835 100644 --- a/tools/internalcrds/main_test.go +++ b/tools/internalcrds/main_test.go @@ -16,7 +16,40 @@ limitations under the License. package main -import "testing" +import ( + "os" + "path/filepath" + "testing" +) + +func TestRunFailsOnUnknownKind(t *testing.T) { + dir := t.TempDir() + doc := ` +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: artifactgenerators.source.toolkit.fluxcd.io +spec: + group: source.toolkit.fluxcd.io + names: + kind: ArtifactGenerator + listKind: ArtifactGeneratorList + plural: artifactgenerators + singular: artifactgenerator +` + if err := os.WriteFile(filepath.Join(dir, "artifactgenerators.yaml"), []byte(doc), 0o644); err != nil { + t.Fatal(err) + } + + out := filepath.Join(t.TempDir(), "out.yaml") + if err := run(out, []string{dir}); err == nil { + t.Fatal("expected an error, got nil") + } + + if _, err := os.Stat(out); !os.IsNotExist(err) { + t.Fatal("run must not write the output file when a document declares an unknown kind") + } +} func TestCheckNoLeftoverUpstreamFailsOnLeftoverGroup(t *testing.T) { rendered := "spec:\n group: source.toolkit.fluxcd.io\n" From aaf9b528bdd80966f00fcf4bddaa6503bd1fe2fc Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 15:55:30 +0300 Subject: [PATCH 04/19] feat(rewriter): map the upstream flux groups Upstream serves one version per kind at the pinned tags; the beta versions the fork carried are gone, and declaring one would answer discovery for a version nothing can serve. Signed-off-by: Ilya Drey --- .../pkg/operatornelm/operatornelm_rules.go | 24 +++++----- .../operatornelm/operatornelm_rules_test.go | 47 +++++++++++++++++++ 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules.go b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules.go index e8e45e0c..8056de8d 100644 --- a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules.go +++ b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules.go @@ -68,10 +68,10 @@ var OperatorNelmRewriteRules = &RewriteRules{ } var OperatorNelmAPIGroupsRules = map[string]APIGroupRule{ - "source.werf.io": { + "source.toolkit.fluxcd.io": { GroupRule: GroupRule{ - Group: "source.werf.io", - Versions: []string{"v1beta1", "v1beta2", "v1"}, + Group: "source.toolkit.fluxcd.io", + Versions: []string{"v1"}, PreferredVersion: "v1", Renamed: "source." + internalPrefix, }, @@ -81,7 +81,7 @@ var OperatorNelmAPIGroupsRules = map[string]APIGroupRule{ ListKind: "BucketList", Plural: "buckets", Singular: "bucket", - Versions: []string{"v1beta2", "v1"}, + Versions: []string{"v1"}, PreferredVersion: "v1", Categories: []string{}, ShortNames: []string{}, @@ -101,7 +101,7 @@ var OperatorNelmAPIGroupsRules = map[string]APIGroupRule{ ListKind: "GitRepositoryList", Plural: "gitrepositories", Singular: "gitrepository", - Versions: []string{"v1beta2", "v1"}, + Versions: []string{"v1"}, PreferredVersion: "v1", Categories: []string{}, ShortNames: []string{"gitrepo"}, @@ -111,7 +111,7 @@ var OperatorNelmAPIGroupsRules = map[string]APIGroupRule{ ListKind: "HelmChartList", Plural: "helmcharts", Singular: "helmchart", - Versions: []string{"v1beta2", "v1"}, + Versions: []string{"v1"}, PreferredVersion: "v1", Categories: []string{}, ShortNames: []string{"hc"}, @@ -121,7 +121,7 @@ var OperatorNelmAPIGroupsRules = map[string]APIGroupRule{ ListKind: "HelmRepositoryList", Plural: "helmrepositories", Singular: "helmrepository", - Versions: []string{"v1beta2", "v1"}, + Versions: []string{"v1"}, PreferredVersion: "v1", Categories: []string{}, ShortNames: []string{"helmrepo"}, @@ -131,17 +131,17 @@ var OperatorNelmAPIGroupsRules = map[string]APIGroupRule{ ListKind: "OCIRepositoryList", Plural: "ocirepositories", Singular: "ocirepository", - Versions: []string{"v1beta2", "v1"}, + Versions: []string{"v1"}, PreferredVersion: "v1", Categories: []string{}, ShortNames: []string{"ocirepo"}, }, }, }, - "helm.werf.io": { + "helm.toolkit.fluxcd.io": { GroupRule: GroupRule{ - Group: "helm.werf.io", - Versions: []string{"v2beta1", "v2beta2", "v2"}, + Group: "helm.toolkit.fluxcd.io", + Versions: []string{"v2"}, PreferredVersion: "v2", Renamed: "helm." + internalPrefix, }, @@ -151,7 +151,7 @@ var OperatorNelmAPIGroupsRules = map[string]APIGroupRule{ ListKind: "HelmReleaseList", Plural: "helmreleases", Singular: "helmrelease", - Versions: []string{"v2beta1", "v2beta2", "v2"}, + Versions: []string{"v2"}, PreferredVersion: "v2", Categories: []string{}, ShortNames: []string{"hr"}, diff --git a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go index 876ed3f6..143cc73d 100644 --- a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go +++ b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go @@ -18,6 +18,7 @@ package operatornelm import ( "fmt" + "reflect" "testing" "sigs.k8s.io/yaml" @@ -31,3 +32,49 @@ func TestOperatorNelmRulesToYAML(t *testing.T) { fmt.Printf("%s\n", string(b)) } + +func TestRulesMapUpstreamGroups(t *testing.T) { + source, ok := OperatorNelmAPIGroupsRules["source.toolkit.fluxcd.io"] + if !ok { + t.Fatal("the upstream source group has no rule") + } + if source.GroupRule.Renamed != "source.internal.operator-helm.deckhouse.io" { + t.Fatalf("source group renamed to %q", source.GroupRule.Renamed) + } + + helm, ok := OperatorNelmAPIGroupsRules["helm.toolkit.fluxcd.io"] + if !ok { + t.Fatal("the upstream helm group has no rule") + } + if helm.GroupRule.Renamed != "helm.internal.operator-helm.deckhouse.io" { + t.Fatalf("helm group renamed to %q", helm.GroupRule.Renamed) + } + + if _, ok := OperatorNelmAPIGroupsRules["source.werf.io"]; ok { + t.Fatal("the fork group is still mapped") + } + if _, ok := OperatorNelmAPIGroupsRules["helm.werf.io"]; ok { + t.Fatal("the fork group is still mapped") + } +} + +// TestRulesServeOneVersionPerKind pins what upstream actually serves at the +// pinned tags: the beta versions are gone, and declaring one the api server does +// not know makes discovery answer for a version nothing can serve. +func TestRulesServeOneVersionPerKind(t *testing.T) { + source := OperatorNelmAPIGroupsRules["source.toolkit.fluxcd.io"] + if !reflect.DeepEqual(source.GroupRule.Versions, []string{"v1"}) { + t.Fatalf("source versions = %v, want [v1]", source.GroupRule.Versions) + } + + for name, rule := range source.ResourceRules { + if !reflect.DeepEqual(rule.Versions, []string{"v1"}) { + t.Fatalf("%s versions = %v, want [v1]", name, rule.Versions) + } + } + + helm := OperatorNelmAPIGroupsRules["helm.toolkit.fluxcd.io"] + if !reflect.DeepEqual(helm.GroupRule.Versions, []string{"v2"}) { + t.Fatalf("helm versions = %v, want [v2]", helm.GroupRule.Versions) + } +} From 7ef994a178641d8228ab443b3282fa1fc8e48f12 Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 16:11:03 +0300 Subject: [PATCH 05/19] feat(rewriter): follow upstream identifiers without moving stored ones Only the left side of the table changes: what upstream writes. The right side is what sits on objects in every cluster running the module, so moving it would need a migration. Reconnaissance also found reconcile.fluxcd.io/resetAt, an annotation the fork already wrote unrewritten under its own domain with no rule at all; it now maps to that same already-stored value instead of the internal one, so nothing already on live objects moves. Short names and the category are dropped along with it, since the generated definitions never carried them either. Signed-off-by: Ilya Drey --- .../pkg/operatornelm/operatornelm_rules.go | 38 +++++------ .../operatornelm/operatornelm_rules_test.go | 66 +++++++++++++++++++ 2 files changed, 84 insertions(+), 20 deletions(-) diff --git a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules.go b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules.go index 8056de8d..5b9f7d21 100644 --- a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules.go +++ b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules.go @@ -27,37 +27,35 @@ const ( var OperatorNelmRewriteRules = &RewriteRules{ KindPrefix: "InternalNelmOperator", ResourceTypePrefix: "internalnelmoperator", - ShortNamePrefix: "intnelm", - Categories: []string{"intnelm"}, Rules: OperatorNelmAPIGroupsRules, Webhooks: OperatorNelmWebhooks, Labels: MetadataReplace{ Names: []MetadataReplaceRule{ - {Original: "source.werf.io", Renamed: "source." + internalPrefix}, - {Original: "helm.werf.io", Renamed: "helm." + internalPrefix}, + {Original: "source.toolkit.fluxcd.io", Renamed: "source." + internalPrefix}, + {Original: "helm.toolkit.fluxcd.io", Renamed: "helm." + internalPrefix}, }, Prefixes: []MetadataReplaceRule{ - {Original: "source.werf.io", Renamed: "source." + internalPrefix}, - {Original: "helm.werf.io", Renamed: "helm." + internalPrefix}, + {Original: "source.toolkit.fluxcd.io", Renamed: "source." + internalPrefix}, + {Original: "helm.toolkit.fluxcd.io", Renamed: "helm." + internalPrefix}, }, }, - //reconcile.internal.operator-helm.deckhouse.io/forceAt Annotations: MetadataReplace{ Names: []MetadataReplaceRule{ - {Original: "reconcile.werf.io/forceAt", Renamed: "reconcile." + internalPrefix + "/forceAt"}, - {Original: "reconcile.werf.io/requestedAt", Renamed: "reconcile." + internalPrefix + "/requestedAt"}, + {Original: "reconcile.fluxcd.io/requestedAt", Renamed: "reconcile." + internalPrefix + "/requestedAt"}, + {Original: "reconcile.fluxcd.io/forceAt", Renamed: "reconcile." + internalPrefix + "/forceAt"}, + // The fork never had a rule renaming resetAt, so it already reaches + // clusters unrewritten, under the fork's own domain: keep that + // stored form rather than moving it to the internal one now. + {Original: "reconcile.fluxcd.io/resetAt", Renamed: "reconcile.werf.io/resetAt"}, }, Prefixes: []MetadataReplaceRule{ - {Original: "source.werf.io", Renamed: "source." + internalPrefix}, - {Original: "helm.werf.io", Renamed: "helm." + internalPrefix}, + {Original: "source.toolkit.fluxcd.io", Renamed: "source." + internalPrefix}, + {Original: "helm.toolkit.fluxcd.io", Renamed: "helm." + internalPrefix}, }, }, Finalizers: MetadataReplace{ Names: []MetadataReplaceRule{ - {Original: "finalizers.werf.io", Renamed: "finalizers." + internalPrefix}, - }, - Prefixes: []MetadataReplaceRule{ - {Original: "werf.io", Renamed: "werf." + internalPrefix}, + {Original: "finalizers.fluxcd.io", Renamed: "finalizers." + internalPrefix}, }, }, Excludes: []ExcludeRule{}, @@ -104,7 +102,7 @@ var OperatorNelmAPIGroupsRules = map[string]APIGroupRule{ Versions: []string{"v1"}, PreferredVersion: "v1", Categories: []string{}, - ShortNames: []string{"gitrepo"}, + ShortNames: []string{}, }, "helmcharts": { Kind: "HelmChart", @@ -114,7 +112,7 @@ var OperatorNelmAPIGroupsRules = map[string]APIGroupRule{ Versions: []string{"v1"}, PreferredVersion: "v1", Categories: []string{}, - ShortNames: []string{"hc"}, + ShortNames: []string{}, }, "helmrepositories": { Kind: "HelmRepository", @@ -124,7 +122,7 @@ var OperatorNelmAPIGroupsRules = map[string]APIGroupRule{ Versions: []string{"v1"}, PreferredVersion: "v1", Categories: []string{}, - ShortNames: []string{"helmrepo"}, + ShortNames: []string{}, }, "ocirepositories": { Kind: "OCIRepository", @@ -134,7 +132,7 @@ var OperatorNelmAPIGroupsRules = map[string]APIGroupRule{ Versions: []string{"v1"}, PreferredVersion: "v1", Categories: []string{}, - ShortNames: []string{"ocirepo"}, + ShortNames: []string{}, }, }, }, @@ -154,7 +152,7 @@ var OperatorNelmAPIGroupsRules = map[string]APIGroupRule{ Versions: []string{"v2"}, PreferredVersion: "v2", Categories: []string{}, - ShortNames: []string{"hr"}, + ShortNames: []string{}, }, }, }, diff --git a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go index 143cc73d..2db531e3 100644 --- a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go +++ b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go @@ -19,6 +19,7 @@ package operatornelm import ( "fmt" "reflect" + "strings" "testing" "sigs.k8s.io/yaml" @@ -78,3 +79,68 @@ func TestRulesServeOneVersionPerKind(t *testing.T) { t.Fatalf("helm versions = %v, want [v2]", helm.GroupRule.Versions) } } + +// TestMetadataRenamesKeepTheStoredSide pins the constraint the whole migration +// rests on: objects already live in clusters, so what is written into them must +// not move. Only the left side of the table follows upstream. +func TestMetadataRenamesKeepTheStoredSide(t *testing.T) { + const internal = "internal.operator-helm.deckhouse.io" + + wantAnnotations := map[string]string{ + "reconcile.fluxcd.io/requestedAt": "reconcile." + internal + "/requestedAt", + "reconcile.fluxcd.io/forceAt": "reconcile." + internal + "/forceAt", + // The fork never had a rule renaming resetAt, so it already reaches + // clusters under the fork's own domain: keep that stored form. + "reconcile.fluxcd.io/resetAt": "reconcile.werf.io/resetAt", + } + got := map[string]string{} + for _, rule := range OperatorNelmRewriteRules.Annotations.Names { + got[rule.Original] = rule.Renamed + } + if !reflect.DeepEqual(got, wantAnnotations) { + t.Fatalf("annotation names = %v, want %v", got, wantAnnotations) + } + + wantFinalizers := map[string]string{ + "finalizers.fluxcd.io": "finalizers." + internal, + } + got = map[string]string{} + for _, rule := range OperatorNelmRewriteRules.Finalizers.Names { + got[rule.Original] = rule.Renamed + } + if !reflect.DeepEqual(got, wantFinalizers) { + t.Fatalf("finalizer names = %v, want %v", got, wantFinalizers) + } + + for _, rule := range OperatorNelmRewriteRules.Labels.Names { + if !strings.HasSuffix(rule.Renamed, internal) { + t.Fatalf("label %q renamed to %q, outside the internal prefix", rule.Original, rule.Renamed) + } + if !strings.HasSuffix(rule.Original, "toolkit.fluxcd.io") { + t.Fatalf("label rule still matches the fork: %q", rule.Original) + } + } +} + +// TestNoShortNamesAndNoCategory pins that the internal kinds claim neither. The +// upstream short names would take "hr" and "hc" from a real flux in the cluster, +// and the upstream categories include "all". +func TestNoShortNamesAndNoCategory(t *testing.T) { + if OperatorNelmRewriteRules.ShortNamePrefix != "" { + t.Fatalf("short name prefix is %q, want none", OperatorNelmRewriteRules.ShortNamePrefix) + } + if len(OperatorNelmRewriteRules.Categories) != 0 { + t.Fatalf("categories = %v, want none", OperatorNelmRewriteRules.Categories) + } + + for group, rules := range OperatorNelmAPIGroupsRules { + for name, rule := range rules.ResourceRules { + if len(rule.ShortNames) != 0 { + t.Fatalf("%s/%s declares short names %v", group, name, rule.ShortNames) + } + if len(rule.Categories) != 0 { + t.Fatalf("%s/%s declares categories %v", group, name, rule.Categories) + } + } + } +} From 52c550ea144bcdf06fd169b1e997ccd15e9f0d4e Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 16:15:20 +0300 Subject: [PATCH 06/19] fix(rewriter): put resetAt in the internal namespace with its siblings This module never writes reconcile.fluxcd.io/resetAt (setReconcileRequestAnnotations only ever stamps forceAt and requestedAt), so unlike those two there is no value already stored under the fork's domain to preserve. Renaming it to the internal namespace keeps all three reconcile annotations consistent instead of leaving one permanently pinned to the domain this migration is removing. Signed-off-by: Ilya Drey --- .../pkg/operatornelm/operatornelm_rules.go | 9 +++++---- .../pkg/operatornelm/operatornelm_rules_test.go | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules.go b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules.go index 5b9f7d21..9beecb99 100644 --- a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules.go +++ b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules.go @@ -43,10 +43,11 @@ var OperatorNelmRewriteRules = &RewriteRules{ Names: []MetadataReplaceRule{ {Original: "reconcile.fluxcd.io/requestedAt", Renamed: "reconcile." + internalPrefix + "/requestedAt"}, {Original: "reconcile.fluxcd.io/forceAt", Renamed: "reconcile." + internalPrefix + "/forceAt"}, - // The fork never had a rule renaming resetAt, so it already reaches - // clusters unrewritten, under the fork's own domain: keep that - // stored form rather than moving it to the internal one now. - {Original: "reconcile.fluxcd.io/resetAt", Renamed: "reconcile.werf.io/resetAt"}, + // Unlike its siblings, resetAt is never written by this module: no + // live object carries it, so there is nothing stored to preserve. + // It joins them in the internal namespace instead of freezing on + // the fork's domain. + {Original: "reconcile.fluxcd.io/resetAt", Renamed: "reconcile." + internalPrefix + "/resetAt"}, }, Prefixes: []MetadataReplaceRule{ {Original: "source.toolkit.fluxcd.io", Renamed: "source." + internalPrefix}, diff --git a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go index 2db531e3..905b4ffd 100644 --- a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go +++ b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go @@ -89,9 +89,9 @@ func TestMetadataRenamesKeepTheStoredSide(t *testing.T) { wantAnnotations := map[string]string{ "reconcile.fluxcd.io/requestedAt": "reconcile." + internal + "/requestedAt", "reconcile.fluxcd.io/forceAt": "reconcile." + internal + "/forceAt", - // The fork never had a rule renaming resetAt, so it already reaches - // clusters under the fork's own domain: keep that stored form. - "reconcile.fluxcd.io/resetAt": "reconcile.werf.io/resetAt", + // Unlike its siblings, this module never writes resetAt, so there is no + // stored value to preserve; it moves into the internal namespace too. + "reconcile.fluxcd.io/resetAt": "reconcile." + internal + "/resetAt", } got := map[string]string{} for _, rule := range OperatorNelmRewriteRules.Annotations.Names { From 2039fcaecd628b32cb2ac2d85388543eefadc143 Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 16:35:07 +0300 Subject: [PATCH 07/19] feat(controller): build against upstream flux apis The fields the module sets on the internal HelmRelease are all standard in helm.toolkit.fluxcd.io/v2, so the swap is a change of module path. Signed-off-by: Ilya Drey --- .../cmd/chart-values-controller/main.go | 2 +- images/chart-values-controller/go.mod | 65 +++++++------ images/chart-values-controller/go.sum | 81 ++++++++++++++++ .../internal/controller/controller.go | 4 +- .../internal/resolver/resolver.go | 4 +- .../internal/resolver/resolver_test.go | 2 +- .../cmd/operator-helm-controller/main.go | 4 +- images/operator-helm-controller/go.mod | 83 +++++++++------- images/operator-helm-controller/go.sum | 96 +++++++++++++++++++ .../controller/helmapplication/controller.go | 4 +- .../helmapplicationrepository/controller.go | 2 +- .../controller/helmclusteraddon/controller.go | 4 +- .../helmclusteraddonrepository/controller.go | 2 +- .../controller.go | 2 +- .../internal/reconcile/release/reconciler.go | 7 +- .../reconcile/release/reconciler_test.go | 6 +- .../reconcile/repository/reconciler_test.go | 4 +- .../internal/services/base.go | 2 +- .../internal/services/chart_service.go | 4 +- .../internal/services/chart_service_test.go | 4 +- .../internal/services/force_service.go | 2 +- .../internal/services/force_service_test.go | 4 +- .../internal/services/helm_repo_service.go | 4 +- .../services/helm_repo_service_test.go | 2 +- .../internal/services/maintenance_service.go | 2 +- .../internal/services/oci_repo_service.go | 4 +- .../services/oci_repo_service_test.go | 4 +- .../internal/services/release_service.go | 4 +- .../internal/services/release_service_test.go | 4 +- 29 files changed, 309 insertions(+), 103 deletions(-) diff --git a/images/chart-values-controller/cmd/chart-values-controller/main.go b/images/chart-values-controller/cmd/chart-values-controller/main.go index df13083f..83ac809b 100644 --- a/images/chart-values-controller/cmd/chart-values-controller/main.go +++ b/images/chart-values-controller/cmd/chart-values-controller/main.go @@ -22,7 +22,7 @@ import ( "os" "time" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + sourcev1 "github.com/fluxcd/source-controller/api/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes" clientgoscheme "k8s.io/client-go/kubernetes/scheme" diff --git a/images/chart-values-controller/go.mod b/images/chart-values-controller/go.mod index 3da490be..49f48bd4 100644 --- a/images/chart-values-controller/go.mod +++ b/images/chart-values-controller/go.mod @@ -6,13 +6,13 @@ replace github.com/deckhouse/operator-helm/api => ../../api require ( github.com/deckhouse/operator-helm/api v0.0.0-00010101000000-000000000000 + github.com/fluxcd/pkg/apis/meta v1.30.2 + github.com/fluxcd/source-controller/api v1.9.5 github.com/google/go-containerregistry v0.20.6 - github.com/werf/3p-fluxcd-pkg/apis/meta v1.23.0-nelm.1 - github.com/werf/nelm-source-controller/api v0.1.5 - k8s.io/api v0.35.1 - k8s.io/apimachinery v0.35.1 - k8s.io/client-go v0.35.1 - sigs.k8s.io/controller-runtime v0.23.1 + k8s.io/api v0.36.1 + k8s.io/apimachinery v0.36.4 + k8s.io/client-go v0.36.0 + sigs.k8s.io/controller-runtime v0.24.1 ) require ( @@ -23,15 +23,27 @@ require ( github.com/docker/cli v28.2.2+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect + github.com/fluxcd/pkg/apis/acl v0.10.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.2 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.21.1 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/swag v0.23.1 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/go-cmp v0.7.0 // indirect @@ -50,35 +62,34 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.66.1 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/vbatts/tar-split v0.12.1 // indirect - github.com/werf/3p-fluxcd-pkg/apis/acl v0.9.0-nelm.1 // indirect github.com/x448/float16 v0.8.4 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - go.yaml.in/yaml/v2 v2.4.3 // indirect + go.uber.org/zap v1.27.1 // indirect + go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.48.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/term v0.39.0 // indirect - golang.org/x/text v0.33.0 // indirect - golang.org/x/time v0.12.0 // indirect + golang.org/x/net v0.56.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.21.0 // indirect + golang.org/x/sys v0.46.0 // indirect + golang.org/x/term v0.44.0 // indirect + golang.org/x/text v0.39.0 // indirect + golang.org/x/time v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/protobuf v1.36.8 // indirect + google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.35.1 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 // indirect - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + k8s.io/apiextensions-apiserver v0.36.0 // indirect + k8s.io/klog/v2 v2.140.0 // indirect + k8s.io/kube-openapi v0.0.0-20260603220949-865597e52e25 // indirect + k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.4.0 // indirect sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/images/chart-values-controller/go.sum b/images/chart-values-controller/go.sum index 1ce8ad9a..d9bcb4b1 100644 --- a/images/chart-values-controller/go.sum +++ b/images/chart-values-controller/go.sum @@ -1,5 +1,6 @@ github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -18,14 +19,24 @@ github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqI github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= +github.com/fluxcd/pkg/apis/acl v0.10.0 h1:KPfAmELNvtvaz8wixnm/MYXqa+MJf7ntVVMUU93Aenk= +github.com/fluxcd/pkg/apis/acl v0.10.0/go.mod h1:a87i2A7AlFO5N2J8CxtzaUCCDmuLLWOHwkKu3eJF5fY= +github.com/fluxcd/pkg/apis/meta v1.30.2 h1:FbSQsUqLZrnyFhGqc0uE5zJOOu42OQ8YpO0vXmj+g5o= +github.com/fluxcd/pkg/apis/meta v1.30.2/go.mod h1:xc7Z4qD5ikDVfjMDYgmFbLJiwJQaaXLkocqmxhywXzA= +github.com/fluxcd/source-controller/api v1.9.5 h1:QwOqmw6/NqOXUR+kGmBJ18CEvthD8DNrSRTtjQG+bHQ= +github.com/fluxcd/source-controller/api v1.9.5/go.mod h1:Y5mcHYzML/mJYjvSJRcIo7eLLjd+cZjnKR6WeIGrouE= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.2 h1:X4Ksno9+x3cz0TZv69ec1hxP/+tymuR8PXQJyDwfh78= +github.com/fxamacker/cbor/v2 v2.9.2/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= @@ -36,6 +47,30 @@ github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= @@ -79,8 +114,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/ginkgo/v2 v2.27.4 h1:fcEcQW/A++6aZAZQNUmNjvA9PSOzefMJBerHJ4t8v8Y= github.com/onsi/gomega v1.38.3 h1:eTX+W6dobAYfFeGC2PV6RwXRu/MyT+cQguijutvkpSM= github.com/onsi/gomega v1.38.3/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= +github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -96,8 +133,12 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -127,33 +168,55 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= +go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= +golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= +golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= +golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= +golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -168,25 +231,43 @@ gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= k8s.io/api v0.35.1 h1:0PO/1FhlK/EQNVK5+txc4FuhQibV25VLSdLMmGpDE/Q= k8s.io/api v0.35.1/go.mod h1:28uR9xlXWml9eT0uaGo6y71xK86JBELShLy4wR1XtxM= +k8s.io/api v0.36.1 h1:XbL/EMj8K2aJpJtePmqUyQMsM0D4QI2pvl7YKJ20FTY= +k8s.io/api v0.36.1/go.mod h1:KOWo4ey3TINlXjeHVuwB3i+tXXnu+UcwFBHlI/9dvEo= k8s.io/apiextensions-apiserver v0.35.1 h1:p5vvALkknlOcAqARwjS20kJffgzHqwyQRM8vHLwgU7w= k8s.io/apiextensions-apiserver v0.35.1/go.mod h1:2CN4fe1GZ3HMe4wBr25qXyJnJyZaquy4nNlNmb3R7AQ= +k8s.io/apiextensions-apiserver v0.36.0 h1:Wt7E8J+VBCbj4FjiBfDTK/neXDDjyJVJc7xfuOHImZ0= +k8s.io/apiextensions-apiserver v0.36.0/go.mod h1:kGDjH0msuiIB3tgsYRV0kS9GqpMYMUsQ3GHv7TApyug= k8s.io/apimachinery v0.35.1 h1:yxO6gV555P1YV0SANtnTjXYfiivaTPvCTKX6w6qdDsU= k8s.io/apimachinery v0.35.1/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/apimachinery v0.36.4 h1:PT2UzkupGuAx/+xT5XjiMJ1WGpY3fn9/hdAvjweRet4= +k8s.io/apimachinery v0.36.4/go.mod h1:p2I2dipt7JHG+quVwQ1d02d28O4GdDi77RByQ13MTpk= k8s.io/client-go v0.35.1 h1:+eSfZHwuo/I19PaSxqumjqZ9l5XiTEKbIaJ+j1wLcLM= k8s.io/client-go v0.35.1/go.mod h1:1p1KxDt3a0ruRfc/pG4qT/3oHmUj1AhSHEcxNSGg+OA= +k8s.io/client-go v0.36.0 h1:pOYi7C4RHChYjMiHpZSpSbIM6ZxVbRXBy7CuiIwqA3c= +k8s.io/client-go v0.36.0/go.mod h1:ZKKcpwF0aLYfkHFCjillCKaTK/yBkEDHTDXCFY6AS9Y= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= +k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 h1:HhDfevmPS+OalTjQRKbTHppRIz01AWi8s45TMXStgYY= k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/kube-openapi v0.0.0-20260603220949-865597e52e25 h1:mPMaPMpBij2V1Wv/fR+HW124vVGXXvOSS9ver/9yjWs= +k8s.io/kube-openapi v0.0.0-20260603220949-865597e52e25/go.mod h1:V/QaCUYDa+0QpcHhVVc5l99Uz56wEMEXBSj9oCDkNDY= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 h1:wU4tMEhLGgIbLvXQb1cfN+EcM0wf7zC6CPF+C79jroc= +k8s.io/utils v0.0.0-20260507154919-ff6756f316d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= +sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4= +sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 h1:2WOzJpHUBVrrkDjU4KBT8n5LDcj824eX0I5UKcgeRUs= sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/structured-merge-diff/v6 v6.4.0 h1:qmp2e3ZfFi1/jJbDGpD4mt3wyp6PE1NfKHCYLqgNQJo= +sigs.k8s.io/structured-merge-diff/v6 v6.4.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/images/chart-values-controller/internal/controller/controller.go b/images/chart-values-controller/internal/controller/controller.go index d9b23e41..b4ce9f87 100644 --- a/images/chart-values-controller/internal/controller/controller.go +++ b/images/chart-values-controller/internal/controller/controller.go @@ -24,8 +24,8 @@ import ( "sync" "time" - "github.com/werf/3p-fluxcd-pkg/apis/meta" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + "github.com/fluxcd/pkg/apis/meta" + sourcev1 "github.com/fluxcd/source-controller/api/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/images/chart-values-controller/internal/resolver/resolver.go b/images/chart-values-controller/internal/resolver/resolver.go index 345c418f..c99e30b4 100644 --- a/images/chart-values-controller/internal/resolver/resolver.go +++ b/images/chart-values-controller/internal/resolver/resolver.go @@ -25,8 +25,8 @@ import ( "strings" "time" - "github.com/werf/3p-fluxcd-pkg/apis/meta" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + "github.com/fluxcd/pkg/apis/meta" + sourcev1 "github.com/fluxcd/source-controller/api/v1" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" diff --git a/images/chart-values-controller/internal/resolver/resolver_test.go b/images/chart-values-controller/internal/resolver/resolver_test.go index 5a89a1f5..3c5b5f7e 100644 --- a/images/chart-values-controller/internal/resolver/resolver_test.go +++ b/images/chart-values-controller/internal/resolver/resolver_test.go @@ -23,7 +23,7 @@ import ( "testing" "time" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + sourcev1 "github.com/fluxcd/source-controller/api/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" diff --git a/images/operator-helm-controller/cmd/operator-helm-controller/main.go b/images/operator-helm-controller/cmd/operator-helm-controller/main.go index 8d5aeeef..39012f75 100644 --- a/images/operator-helm-controller/cmd/operator-helm-controller/main.go +++ b/images/operator-helm-controller/cmd/operator-helm-controller/main.go @@ -20,8 +20,8 @@ import ( "flag" "os" - helmv2 "github.com/werf/3p-helm-controller/api/v2" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + helmv2 "github.com/fluxcd/helm-controller/api/v2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/images/operator-helm-controller/go.mod b/images/operator-helm-controller/go.mod index 57e2b1e8..67213ec5 100644 --- a/images/operator-helm-controller/go.mod +++ b/images/operator-helm-controller/go.mod @@ -5,24 +5,41 @@ go 1.26.3 replace github.com/deckhouse/operator-helm/api => ../../api require ( - github.com/Masterminds/semver/v3 v3.4.0 + github.com/Masterminds/semver/v3 v3.5.0 github.com/deckhouse/operator-helm/api v0.0.0-00010101000000-000000000000 + github.com/fluxcd/helm-controller/api v1.6.4 + github.com/fluxcd/pkg/apis/meta v1.30.2 + github.com/fluxcd/pkg/chartutil v1.27.2 + github.com/fluxcd/source-controller/api v1.9.5 github.com/google/go-containerregistry v0.20.6 github.com/opencontainers/go-digest v1.0.0 github.com/samber/lo v1.53.0 - github.com/werf/3p-fluxcd-pkg/apis/meta v1.23.0-nelm.1 - github.com/werf/3p-fluxcd-pkg/chartutil v1.17.0-nelm.1 - github.com/werf/3p-helm-controller/api v0.1.5 - github.com/werf/nelm-source-controller/api v0.1.5 go.yaml.in/yaml/v3 v3.0.4 - golang.org/x/sync v0.19.0 + golang.org/x/sync v0.21.0 helm.sh/helm/v3 v3.20.2 - k8s.io/api v0.35.1 - k8s.io/apimachinery v0.35.1 - k8s.io/client-go v0.35.1 - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 + helm.sh/helm/v4 v4.2.2 + k8s.io/api v0.36.4 + k8s.io/apimachinery v0.36.4 + k8s.io/client-go v0.36.4 + k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 sigs.k8s.io/cli-utils v0.37.2 - sigs.k8s.io/controller-runtime v0.23.1 + sigs.k8s.io/controller-runtime v0.24.1 +) + +require ( + github.com/fluxcd/pkg/apis/acl v0.10.0 // indirect + github.com/fluxcd/pkg/apis/kustomize v1.19.2 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect ) require ( @@ -33,23 +50,23 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/docker/cli v29.2.0+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker-credential-helpers v0.9.3 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/docker/docker-credential-helpers v0.9.5 // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.2 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.21.1 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect - github.com/go-openapi/swag v0.23.1 // indirect + github.com/go-openapi/swag v0.25.4 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/mailru/easyjson v0.9.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -62,35 +79,33 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.66.1 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.5 // indirect + github.com/prometheus/procfs v0.20.1 // indirect github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect + github.com/sirupsen/logrus v1.9.4 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/vbatts/tar-split v0.12.1 // indirect - github.com/werf/3p-fluxcd-pkg/apis/acl v0.9.0-nelm.1 // indirect - github.com/werf/3p-fluxcd-pkg/apis/kustomize v1.14.0-nelm.1 // indirect github.com/x448/float16 v0.8.4 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - go.yaml.in/yaml/v2 v2.4.3 // indirect - golang.org/x/net v0.48.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/term v0.39.0 // indirect - golang.org/x/text v0.33.0 // indirect - golang.org/x/time v0.12.0 // indirect + go.uber.org/zap v1.27.1 // indirect + go.yaml.in/yaml/v2 v2.4.4 // indirect + golang.org/x/net v0.56.0 // indirect + golang.org/x/oauth2 v0.36.0 // indirect + golang.org/x/sys v0.46.0 // indirect + golang.org/x/term v0.44.0 // indirect + golang.org/x/text v0.39.0 // indirect + golang.org/x/time v0.15.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/protobuf v1.36.8 // indirect + google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.4.0 // indirect - k8s.io/apiextensions-apiserver v0.35.1 - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 // indirect + k8s.io/apiextensions-apiserver v0.36.4 + k8s.io/klog/v2 v2.140.0 // indirect + k8s.io/kube-openapi v0.0.0-20260603220949-865597e52e25 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.4.0 // indirect sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/images/operator-helm-controller/go.sum b/images/operator-helm-controller/go.sum index bbec7d6f..63dc9570 100644 --- a/images/operator-helm-controller/go.sum +++ b/images/operator-helm-controller/go.sum @@ -2,6 +2,8 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9 github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE= +github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -22,16 +24,34 @@ github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBi github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= +github.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY= +github.com/docker/docker-credential-helpers v0.9.5/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.9.11+incompatible h1:ixHHqfcGvxhWkniF1tWxBHA0yb4Z+d1UQi45df52xW8= github.com/evanphx/json-patch v5.9.11+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= +github.com/fluxcd/helm-controller/api v1.6.4 h1:jDgB87F6RRNF0QEZDAw+8+HPU13toF5IZpPsytA0Nuo= +github.com/fluxcd/helm-controller/api v1.6.4/go.mod h1:mYa4WKwgCCE59dMdYzOJI6B17/wofN6wtmtjWWEQesQ= +github.com/fluxcd/pkg/apis/acl v0.10.0 h1:KPfAmELNvtvaz8wixnm/MYXqa+MJf7ntVVMUU93Aenk= +github.com/fluxcd/pkg/apis/acl v0.10.0/go.mod h1:a87i2A7AlFO5N2J8CxtzaUCCDmuLLWOHwkKu3eJF5fY= +github.com/fluxcd/pkg/apis/kustomize v1.19.2 h1:/E8Nmn1XdAGUIqxI5vK60WemyBX3pIpfmP3mr/E3p9c= +github.com/fluxcd/pkg/apis/kustomize v1.19.2/go.mod h1:HryXaJ1GpvagUOmh5uMkVtXVlfXWdKjc3/5IlLsjyzI= +github.com/fluxcd/pkg/apis/meta v1.30.2 h1:FbSQsUqLZrnyFhGqc0uE5zJOOu42OQ8YpO0vXmj+g5o= +github.com/fluxcd/pkg/apis/meta v1.30.2/go.mod h1:xc7Z4qD5ikDVfjMDYgmFbLJiwJQaaXLkocqmxhywXzA= +github.com/fluxcd/pkg/chartutil v1.27.2 h1:Ghf0PRrJ5vKEgXRrbuti9/efpHnrw9Wh6QBRf0JxdfA= +github.com/fluxcd/pkg/chartutil v1.27.2/go.mod h1:NeLXZUTWI5KhIQZOzFtVCM3VTg6QiaoQSlTXKYUPz3U= +github.com/fluxcd/source-controller/api v1.9.5 h1:QwOqmw6/NqOXUR+kGmBJ18CEvthD8DNrSRTtjQG+bHQ= +github.com/fluxcd/source-controller/api v1.9.5/go.mod h1:Y5mcHYzML/mJYjvSJRcIo7eLLjd+cZjnKR6WeIGrouE= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.2 h1:X4Ksno9+x3cz0TZv69ec1hxP/+tymuR8PXQJyDwfh78= +github.com/fxamacker/cbor/v2 v2.9.2/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= @@ -42,6 +62,30 @@ github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= @@ -66,6 +110,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -90,8 +136,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/ginkgo/v2 v2.27.4 h1:fcEcQW/A++6aZAZQNUmNjvA9PSOzefMJBerHJ4t8v8Y= github.com/onsi/gomega v1.38.3 h1:eTX+W6dobAYfFeGC2PV6RwXRu/MyT+cQguijutvkpSM= github.com/onsi/gomega v1.38.3/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= +github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -107,8 +155,12 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= +github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/samber/lo v1.53.0 h1:t975lj2py4kJPQ6haz1QMgtId2gtmfktACxIXArw3HM= @@ -117,6 +169,8 @@ github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEV github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= +github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -149,8 +203,12 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= +go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -159,17 +217,24 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= +golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -177,19 +242,28 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= +golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= +golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= +golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= +golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -198,6 +272,8 @@ gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= +google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -212,29 +288,49 @@ gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= helm.sh/helm/v3 v3.20.2 h1:binM4rvPx5DcNsa1sIt7UZi55lRbu3pZUFmQkSoRh48= helm.sh/helm/v3 v3.20.2/go.mod h1:Fl1kBaWCpkUrM6IYXPjQ3bdZQfFrogKArqptvueZ6Ww= +helm.sh/helm/v4 v4.2.2 h1:E2zSCA2uUm9PNiZsSC/BioDVGsYk7nF2jNJFg/i+Dng= +helm.sh/helm/v4 v4.2.2/go.mod h1:dp3ihfy1AhCLKANDaPETmVWhqPkOmwvJtpK/biHfopE= k8s.io/api v0.35.1 h1:0PO/1FhlK/EQNVK5+txc4FuhQibV25VLSdLMmGpDE/Q= k8s.io/api v0.35.1/go.mod h1:28uR9xlXWml9eT0uaGo6y71xK86JBELShLy4wR1XtxM= +k8s.io/api v0.36.4 h1:RxrvqCL6vgH5/+UnTeu1IIFqYmGfy0hnyrod1rn35Oo= +k8s.io/api v0.36.4/go.mod h1:S2B3orCFBDhrgyWbLeuKcT2QdHIpQesBkCYSlWtwUOw= k8s.io/apiextensions-apiserver v0.35.1 h1:p5vvALkknlOcAqARwjS20kJffgzHqwyQRM8vHLwgU7w= k8s.io/apiextensions-apiserver v0.35.1/go.mod h1:2CN4fe1GZ3HMe4wBr25qXyJnJyZaquy4nNlNmb3R7AQ= +k8s.io/apiextensions-apiserver v0.36.4 h1:SfvCVt+4CqKWvzuVytYDT5g9hyb9MztoiYELIkPVrFc= +k8s.io/apiextensions-apiserver v0.36.4/go.mod h1:JT9V2Ju7ys1FY4zbSpmX9XOvKB3/BwsODc4hFQEa+Xo= k8s.io/apimachinery v0.35.1 h1:yxO6gV555P1YV0SANtnTjXYfiivaTPvCTKX6w6qdDsU= k8s.io/apimachinery v0.35.1/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/apimachinery v0.36.4 h1:PT2UzkupGuAx/+xT5XjiMJ1WGpY3fn9/hdAvjweRet4= +k8s.io/apimachinery v0.36.4/go.mod h1:p2I2dipt7JHG+quVwQ1d02d28O4GdDi77RByQ13MTpk= k8s.io/client-go v0.35.1 h1:+eSfZHwuo/I19PaSxqumjqZ9l5XiTEKbIaJ+j1wLcLM= k8s.io/client-go v0.35.1/go.mod h1:1p1KxDt3a0ruRfc/pG4qT/3oHmUj1AhSHEcxNSGg+OA= +k8s.io/client-go v0.36.4 h1:MDvfDNvMSt0Br94SK8neviVlwL9qifw9B26hJCpD1K0= +k8s.io/client-go v0.36.4/go.mod h1:pNK4WKELbwlEDvtbE8l22lEZL5THYF61H5EealokZmA= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= +k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 h1:HhDfevmPS+OalTjQRKbTHppRIz01AWi8s45TMXStgYY= k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/kube-openapi v0.0.0-20260603220949-865597e52e25 h1:mPMaPMpBij2V1Wv/fR+HW124vVGXXvOSS9ver/9yjWs= +k8s.io/kube-openapi v0.0.0-20260603220949-865597e52e25/go.mod h1:V/QaCUYDa+0QpcHhVVc5l99Uz56wEMEXBSj9oCDkNDY= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20260507154919-ff6756f316d2 h1:wU4tMEhLGgIbLvXQb1cfN+EcM0wf7zC6CPF+C79jroc= +k8s.io/utils v0.0.0-20260507154919-ff6756f316d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= sigs.k8s.io/cli-utils v0.37.2 h1:GOfKw5RV2HDQZDJlru5KkfLO1tbxqMoyn1IYUxqBpNg= sigs.k8s.io/cli-utils v0.37.2/go.mod h1:V+IZZr4UoGj7gMJXklWBg6t5xbdThFBcpj4MrZuCYco= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= +sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4= +sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 h1:2WOzJpHUBVrrkDjU4KBT8n5LDcj824eX0I5UKcgeRUs= sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/structured-merge-diff/v6 v6.4.0 h1:qmp2e3ZfFi1/jJbDGpD4mt3wyp6PE1NfKHCYLqgNQJo= +sigs.k8s.io/structured-merge-diff/v6 v6.4.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/images/operator-helm-controller/internal/controller/helmapplication/controller.go b/images/operator-helm-controller/internal/controller/helmapplication/controller.go index ee231b5c..eba75e84 100644 --- a/images/operator-helm-controller/internal/controller/helmapplication/controller.go +++ b/images/operator-helm-controller/internal/controller/helmapplication/controller.go @@ -22,8 +22,8 @@ limitations under the License. package helmapplication import ( - helmv2 "github.com/werf/3p-helm-controller/api/v2" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + helmv2 "github.com/fluxcd/helm-controller/api/v2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/controller" diff --git a/images/operator-helm-controller/internal/controller/helmapplicationrepository/controller.go b/images/operator-helm-controller/internal/controller/helmapplicationrepository/controller.go index 8f9060ac..b237b0e4 100644 --- a/images/operator-helm-controller/internal/controller/helmapplicationrepository/controller.go +++ b/images/operator-helm-controller/internal/controller/helmapplicationrepository/controller.go @@ -21,7 +21,7 @@ limitations under the License. package helmapplicationrepository import ( - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + sourcev1 "github.com/fluxcd/source-controller/api/v1" corev1 "k8s.io/api/core/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" diff --git a/images/operator-helm-controller/internal/controller/helmclusteraddon/controller.go b/images/operator-helm-controller/internal/controller/helmclusteraddon/controller.go index 831b55e6..3e4e413f 100644 --- a/images/operator-helm-controller/internal/controller/helmclusteraddon/controller.go +++ b/images/operator-helm-controller/internal/controller/helmclusteraddon/controller.go @@ -17,8 +17,8 @@ limitations under the License. package helmclusteraddon import ( - helmv2 "github.com/werf/3p-helm-controller/api/v2" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + helmv2 "github.com/fluxcd/helm-controller/api/v2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/controller" diff --git a/images/operator-helm-controller/internal/controller/helmclusteraddonrepository/controller.go b/images/operator-helm-controller/internal/controller/helmclusteraddonrepository/controller.go index e671df78..b0b89b8f 100644 --- a/images/operator-helm-controller/internal/controller/helmclusteraddonrepository/controller.go +++ b/images/operator-helm-controller/internal/controller/helmclusteraddonrepository/controller.go @@ -17,7 +17,7 @@ limitations under the License. package helmclusteraddonrepository import ( - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + sourcev1 "github.com/fluxcd/source-controller/api/v1" corev1 "k8s.io/api/core/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" diff --git a/images/operator-helm-controller/internal/controller/helmclusterapplicationrepository/controller.go b/images/operator-helm-controller/internal/controller/helmclusterapplicationrepository/controller.go index eadf5c56..fa3a6e11 100644 --- a/images/operator-helm-controller/internal/controller/helmclusterapplicationrepository/controller.go +++ b/images/operator-helm-controller/internal/controller/helmclusterapplicationrepository/controller.go @@ -19,7 +19,7 @@ limitations under the License. package helmclusterapplicationrepository import ( - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + sourcev1 "github.com/fluxcd/source-controller/api/v1" corev1 "k8s.io/api/core/v1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" diff --git a/images/operator-helm-controller/internal/reconcile/release/reconciler.go b/images/operator-helm-controller/internal/reconcile/release/reconciler.go index 42196a37..7bc1aea5 100644 --- a/images/operator-helm-controller/internal/reconcile/release/reconciler.go +++ b/images/operator-helm-controller/internal/reconcile/release/reconciler.go @@ -22,9 +22,10 @@ import ( "strings" "time" + "github.com/fluxcd/pkg/chartutil" "github.com/opencontainers/go-digest" - "github.com/werf/3p-fluxcd-pkg/chartutil" helmchartutil "helm.sh/helm/v3/pkg/chartutil" + helmcommon "helm.sh/helm/v4/pkg/chart/common" apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -664,7 +665,9 @@ func setStatusAttrs( } values, _ := helmchartutil.ReadValues(rawValues) - if latestRelease.Status == "deployed" && latestRelease.ConfigDigest == chartutil.DigestValues(digest.Canonical, values).String() { + // helm v3's chartutil.Values and helm v4's chart/common.Values are both + // map[string]any under the hood, so the conversion is safe. + if latestRelease.Status == "deployed" && latestRelease.ConfigDigest == chartutil.DigestValues(digest.Canonical, helmcommon.Values(values)).String() { if rel.Values() == nil { rel.SetLastAppliedValues(nil) } else { diff --git a/images/operator-helm-controller/internal/reconcile/release/reconciler_test.go b/images/operator-helm-controller/internal/reconcile/release/reconciler_test.go index 1b1c8a25..6ca6d31d 100644 --- a/images/operator-helm-controller/internal/reconcile/release/reconciler_test.go +++ b/images/operator-helm-controller/internal/reconcile/release/reconciler_test.go @@ -23,10 +23,10 @@ import ( "testing" "time" + helmv2 "github.com/fluxcd/helm-controller/api/v2" + fluxmeta "github.com/fluxcd/pkg/apis/meta" + sourcev1 "github.com/fluxcd/source-controller/api/v1" "github.com/go-logr/logr/funcr" - fluxmeta "github.com/werf/3p-fluxcd-pkg/apis/meta" - helmv2 "github.com/werf/3p-helm-controller/api/v2" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" apimeta "k8s.io/apimachinery/pkg/api/meta" diff --git a/images/operator-helm-controller/internal/reconcile/repository/reconciler_test.go b/images/operator-helm-controller/internal/reconcile/repository/reconciler_test.go index 27525043..8e545660 100644 --- a/images/operator-helm-controller/internal/reconcile/repository/reconciler_test.go +++ b/images/operator-helm-controller/internal/reconcile/repository/reconciler_test.go @@ -25,8 +25,8 @@ import ( "time" "github.com/Masterminds/semver/v3" - "github.com/werf/3p-fluxcd-pkg/apis/meta" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + "github.com/fluxcd/pkg/apis/meta" + sourcev1 "github.com/fluxcd/source-controller/api/v1" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" diff --git a/images/operator-helm-controller/internal/services/base.go b/images/operator-helm-controller/internal/services/base.go index d1cb6508..51690ca0 100644 --- a/images/operator-helm-controller/internal/services/base.go +++ b/images/operator-helm-controller/internal/services/base.go @@ -21,7 +21,7 @@ import ( "fmt" "time" - "github.com/werf/3p-fluxcd-pkg/apis/meta" + "github.com/fluxcd/pkg/apis/meta" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/images/operator-helm-controller/internal/services/chart_service.go b/images/operator-helm-controller/internal/services/chart_service.go index 8ef1ab16..52fe61d7 100644 --- a/images/operator-helm-controller/internal/services/chart_service.go +++ b/images/operator-helm-controller/internal/services/chart_service.go @@ -21,8 +21,8 @@ import ( "fmt" "maps" - "github.com/werf/3p-fluxcd-pkg/apis/meta" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + "github.com/fluxcd/pkg/apis/meta" + sourcev1 "github.com/fluxcd/source-controller/api/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" diff --git a/images/operator-helm-controller/internal/services/chart_service_test.go b/images/operator-helm-controller/internal/services/chart_service_test.go index ce6644d8..12546f76 100644 --- a/images/operator-helm-controller/internal/services/chart_service_test.go +++ b/images/operator-helm-controller/internal/services/chart_service_test.go @@ -20,8 +20,8 @@ import ( "context" "testing" - "github.com/werf/3p-fluxcd-pkg/apis/meta" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + "github.com/fluxcd/pkg/apis/meta" + sourcev1 "github.com/fluxcd/source-controller/api/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" diff --git a/images/operator-helm-controller/internal/services/force_service.go b/images/operator-helm-controller/internal/services/force_service.go index 077541ce..b24347d9 100644 --- a/images/operator-helm-controller/internal/services/force_service.go +++ b/images/operator-helm-controller/internal/services/force_service.go @@ -20,7 +20,7 @@ import ( "context" "fmt" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + sourcev1 "github.com/fluxcd/source-controller/api/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" diff --git a/images/operator-helm-controller/internal/services/force_service_test.go b/images/operator-helm-controller/internal/services/force_service_test.go index c41a42e1..25275e14 100644 --- a/images/operator-helm-controller/internal/services/force_service_test.go +++ b/images/operator-helm-controller/internal/services/force_service_test.go @@ -20,8 +20,8 @@ import ( "context" "testing" - "github.com/werf/3p-fluxcd-pkg/apis/meta" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + "github.com/fluxcd/pkg/apis/meta" + sourcev1 "github.com/fluxcd/source-controller/api/v1" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/deckhouse/operator-helm/internal/adapter" diff --git a/images/operator-helm-controller/internal/services/helm_repo_service.go b/images/operator-helm-controller/internal/services/helm_repo_service.go index 10731bcb..5d46b89a 100644 --- a/images/operator-helm-controller/internal/services/helm_repo_service.go +++ b/images/operator-helm-controller/internal/services/helm_repo_service.go @@ -21,8 +21,8 @@ import ( "fmt" "time" - "github.com/werf/3p-fluxcd-pkg/apis/meta" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + "github.com/fluxcd/pkg/apis/meta" + sourcev1 "github.com/fluxcd/source-controller/api/v1" corev1 "k8s.io/api/core/v1" apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/images/operator-helm-controller/internal/services/helm_repo_service_test.go b/images/operator-helm-controller/internal/services/helm_repo_service_test.go index 52fee0ed..2a03be93 100644 --- a/images/operator-helm-controller/internal/services/helm_repo_service_test.go +++ b/images/operator-helm-controller/internal/services/helm_repo_service_test.go @@ -21,7 +21,7 @@ import ( "errors" "testing" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + sourcev1 "github.com/fluxcd/source-controller/api/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" diff --git a/images/operator-helm-controller/internal/services/maintenance_service.go b/images/operator-helm-controller/internal/services/maintenance_service.go index 24dcf552..8cff6bd8 100644 --- a/images/operator-helm-controller/internal/services/maintenance_service.go +++ b/images/operator-helm-controller/internal/services/maintenance_service.go @@ -20,7 +20,7 @@ import ( "context" "fmt" - helmv2 "github.com/werf/3p-helm-controller/api/v2" + helmv2 "github.com/fluxcd/helm-controller/api/v2" apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/images/operator-helm-controller/internal/services/oci_repo_service.go b/images/operator-helm-controller/internal/services/oci_repo_service.go index 213d4406..78298544 100644 --- a/images/operator-helm-controller/internal/services/oci_repo_service.go +++ b/images/operator-helm-controller/internal/services/oci_repo_service.go @@ -21,8 +21,8 @@ import ( "fmt" "time" - "github.com/werf/3p-fluxcd-pkg/apis/meta" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + "github.com/fluxcd/pkg/apis/meta" + sourcev1 "github.com/fluxcd/source-controller/api/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/images/operator-helm-controller/internal/services/oci_repo_service_test.go b/images/operator-helm-controller/internal/services/oci_repo_service_test.go index 6649a1e2..99fc6f3f 100644 --- a/images/operator-helm-controller/internal/services/oci_repo_service_test.go +++ b/images/operator-helm-controller/internal/services/oci_repo_service_test.go @@ -21,8 +21,8 @@ import ( "errors" "testing" - "github.com/werf/3p-fluxcd-pkg/apis/meta" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + "github.com/fluxcd/pkg/apis/meta" + sourcev1 "github.com/fluxcd/source-controller/api/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" diff --git a/images/operator-helm-controller/internal/services/release_service.go b/images/operator-helm-controller/internal/services/release_service.go index 40b9f8fd..083c5b32 100644 --- a/images/operator-helm-controller/internal/services/release_service.go +++ b/images/operator-helm-controller/internal/services/release_service.go @@ -23,8 +23,8 @@ import ( "strings" "time" - helmv2 "github.com/werf/3p-helm-controller/api/v2" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + helmv2 "github.com/fluxcd/helm-controller/api/v2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" diff --git a/images/operator-helm-controller/internal/services/release_service_test.go b/images/operator-helm-controller/internal/services/release_service_test.go index 996b8c86..4a4f2988 100644 --- a/images/operator-helm-controller/internal/services/release_service_test.go +++ b/images/operator-helm-controller/internal/services/release_service_test.go @@ -20,8 +20,8 @@ import ( "context" "testing" - helmv2 "github.com/werf/3p-helm-controller/api/v2" - sourcev1 "github.com/werf/nelm-source-controller/api/v1" + helmv2 "github.com/fluxcd/helm-controller/api/v2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/controller-runtime/pkg/client" From 1418f19b9bf8257aef7aeecefa1fefc746e3685f Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 16:41:05 +0300 Subject: [PATCH 08/19] fix(controller): read release values with the helm v4 reader helm.sh/helm/v3 was only carried for chartutil.ReadValues, whose result was immediately converted to the v4 type. helm.sh/helm/v4/pkg/chart/common has the same ReadValues, so use it directly and drop the v3 dependency entirely. Signed-off-by: Ilya Drey --- images/operator-helm-controller/go.mod | 1 - .../internal/reconcile/release/reconciler.go | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/images/operator-helm-controller/go.mod b/images/operator-helm-controller/go.mod index 67213ec5..9cb6e476 100644 --- a/images/operator-helm-controller/go.mod +++ b/images/operator-helm-controller/go.mod @@ -16,7 +16,6 @@ require ( github.com/samber/lo v1.53.0 go.yaml.in/yaml/v3 v3.0.4 golang.org/x/sync v0.21.0 - helm.sh/helm/v3 v3.20.2 helm.sh/helm/v4 v4.2.2 k8s.io/api v0.36.4 k8s.io/apimachinery v0.36.4 diff --git a/images/operator-helm-controller/internal/reconcile/release/reconciler.go b/images/operator-helm-controller/internal/reconcile/release/reconciler.go index 7bc1aea5..19e5e62f 100644 --- a/images/operator-helm-controller/internal/reconcile/release/reconciler.go +++ b/images/operator-helm-controller/internal/reconcile/release/reconciler.go @@ -24,7 +24,6 @@ import ( "github.com/fluxcd/pkg/chartutil" "github.com/opencontainers/go-digest" - helmchartutil "helm.sh/helm/v3/pkg/chartutil" helmcommon "helm.sh/helm/v4/pkg/chart/common" apierrors "k8s.io/apimachinery/pkg/api/errors" apimeta "k8s.io/apimachinery/pkg/api/meta" @@ -664,10 +663,8 @@ func setStatusAttrs( rawValues = rel.Values().Raw } - values, _ := helmchartutil.ReadValues(rawValues) - // helm v3's chartutil.Values and helm v4's chart/common.Values are both - // map[string]any under the hood, so the conversion is safe. - if latestRelease.Status == "deployed" && latestRelease.ConfigDigest == chartutil.DigestValues(digest.Canonical, helmcommon.Values(values)).String() { + values, _ := helmcommon.ReadValues(rawValues) + if latestRelease.Status == "deployed" && latestRelease.ConfigDigest == chartutil.DigestValues(digest.Canonical, values).String() { if rel.Values() == nil { rel.SetLastAppliedValues(nil) } else { From f5719ddfb9a2c8a1d2ea16a7e2b1e7f251f223d1 Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 16:52:06 +0300 Subject: [PATCH 09/19] feat(build): build both controllers from upstream flux The source image loses the nelm in its name along with the fork it was named after. Signed-off-by: Ilya Drey --- images/helm-controller/werf.inc.yaml | 10 +++++----- .../werf.inc.yaml | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) rename images/{nelm-source-controller => source-controller}/werf.inc.yaml (74%) diff --git a/images/helm-controller/werf.inc.yaml b/images/helm-controller/werf.inc.yaml index 5619cf27..b251fa42 100644 --- a/images/helm-controller/werf.inc.yaml +++ b/images/helm-controller/werf.inc.yaml @@ -1,4 +1,4 @@ -{{- $helmControllerTag := "v0.1.5" }} +{{- $helmControllerTag := "v1.6.4" }} --- image: {{ .ModuleNamePrefix }}{{ .ImageName }}-src-artifact final: false @@ -8,8 +8,8 @@ secrets: value: {{ .SOURCE_REPO }} shell: install: - - git clone --branch {{ $helmControllerTag }} --single-branch $(cat /run/secrets/SOURCE_REPO)/werf/3p-helm-controller.git /src/3p-helm-controller - - rm -rf /src/3p-helm-controller/.git + - git clone --branch {{ $helmControllerTag }} --single-branch $(cat /run/secrets/SOURCE_REPO)/fluxcd/helm-controller.git /src/helm-controller + - rm -rf /src/helm-controller/.git --- image: {{ .ModuleNamePrefix }}{{ .ImageName }}-artifact @@ -27,7 +27,7 @@ import: before: install shell: install: - - cd /src/3p-helm-controller + - cd /src/helm-controller - | export GOOS=linux export GOARCH=amd64 @@ -39,7 +39,7 @@ image: {{ .ModuleNamePrefix }}{{ .ImageName }} fromImage: base/distroless import: - image: {{ .ModuleNamePrefix }}{{ .ImageName }}-artifact - add: /src/3p-helm-controller/helm-controller + add: /src/helm-controller/helm-controller to: /usr/bin/helm-controller before: install imageSpec: diff --git a/images/nelm-source-controller/werf.inc.yaml b/images/source-controller/werf.inc.yaml similarity index 74% rename from images/nelm-source-controller/werf.inc.yaml rename to images/source-controller/werf.inc.yaml index 573e684f..db14967f 100644 --- a/images/nelm-source-controller/werf.inc.yaml +++ b/images/source-controller/werf.inc.yaml @@ -1,4 +1,4 @@ -{{- $nelmSourceControllerTag := "v0.1.5" }} +{{- $sourceControllerTag := "v1.9.5" }} --- image: {{ .ModuleNamePrefix }}{{ .ImageName }}-src-artifact final: false @@ -8,8 +8,8 @@ secrets: value: {{ .SOURCE_REPO }} shell: install: - - git clone --branch {{ $nelmSourceControllerTag }} --single-branch $(cat /run/secrets/SOURCE_REPO)/werf/nelm-source-controller.git /src/nelm-source-controller - - rm -rf /src/nelm-source-controller/.git + - git clone --branch {{ $sourceControllerTag }} --single-branch $(cat /run/secrets/SOURCE_REPO)/fluxcd/source-controller.git /src/source-controller + - rm -rf /src/source-controller/.git --- image: {{ .ModuleNamePrefix }}{{ .ImageName }}-artifact final: false @@ -26,7 +26,7 @@ import: before: install shell: install: - - cd /src/nelm-source-controller + - cd /src/source-controller - | export GOOS=linux export GOARCH=amd64 @@ -38,7 +38,7 @@ image: {{ .ModuleNamePrefix }}{{ .ImageName }} fromImage: base/distroless import: - image: {{ .ModuleNamePrefix }}{{ .ImageName }}-artifact - add: /src/nelm-source-controller/source-controller + add: /src/source-controller/source-controller to: /usr/bin/source-controller before: install imageSpec: From 7575e4cd9aaa516db15f6b08af128d0096981e23 Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 17:04:48 +0300 Subject: [PATCH 10/19] feat(chart): rename the source image after its upstream The name appeared in four spellings plus two Helm template names, and the service account it names is listed in the admission policy: the old account is removed and the new one created, with no transitional period. oss.yaml and build/components/versions.yml now point both entries at the upstream fluxcd projects instead of the werf forks. Signed-off-by: Ilya Drey --- Taskfile.yaml | 2 +- build/components/versions.yml | 4 +- .../reconcile/release/reconciler_test.go | 2 +- .../internal/services/base.go | 2 +- .../internal/services/chart_service.go | 2 +- .../internal/services/helm_repo_service.go | 2 +- .../internal/services/oci_repo_service.go | 2 +- oss.yaml | 16 +++---- templates/admision-policy.yaml | 2 +- templates/rbac-to-us.yaml | 2 +- .../_helpers.tpl | 2 +- .../deployment.yaml | 44 +++++++++---------- .../rbac-for-us.yaml | 20 ++++----- .../service-metrics.yaml | 6 +-- .../service-monitor.yaml | 6 +-- .../service.yaml | 6 +-- tests/e2e/default_config.yaml | 6 +-- 17 files changed, 63 insertions(+), 63 deletions(-) rename templates/{nelm-source-controller => source-controller}/_helpers.tpl (75%) rename templates/{nelm-source-controller => source-controller}/deployment.yaml (76%) rename templates/{nelm-source-controller => source-controller}/rbac-for-us.yaml (86%) rename templates/{nelm-source-controller => source-controller}/service-metrics.yaml (52%) rename templates/{nelm-source-controller => source-controller}/service-monitor.yaml (64%) rename templates/{nelm-source-controller => source-controller}/service.yaml (53%) diff --git a/Taskfile.yaml b/Taskfile.yaml index 240fd7fb..75b1ee5d 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -10,7 +10,7 @@ vars: # Only the modules this repository authors are listed. images/kube-api-rewriter is a # separate upstream module vendored in for the build, and images/helm-controller and -# images/nelm-source-controller carry nothing but their werf files, so none of them is +# images/source-controller carry nothing but their werf files, so none of them is # ours to lint, format or test here. includes: api: diff --git a/build/components/versions.yml b/build/components/versions.yml index 06ab7266..06cb73da 100644 --- a/build/components/versions.yml +++ b/build/components/versions.yml @@ -1,4 +1,4 @@ core: - 3p-helm-controller: v0.1.3 - nelm-source-controller: v0.1.4 + helm-controller: v1.6.4 + source-controller: v1.9.5 package: diff --git a/images/operator-helm-controller/internal/reconcile/release/reconciler_test.go b/images/operator-helm-controller/internal/reconcile/release/reconciler_test.go index 6ca6d31d..7dbd99ac 100644 --- a/images/operator-helm-controller/internal/reconcile/release/reconciler_test.go +++ b/images/operator-helm-controller/internal/reconcile/release/reconciler_test.go @@ -448,7 +448,7 @@ func reconcileApplication(t *testing.T, r *Reconciler, app *helmv1alpha1.HelmApp } } -// markInternalChartReady stands in for nelm-source-controller: the internal +// markInternalChartReady stands in for source-controller: the internal // HelmChart only reports an artifact once that controller has pulled it, and the // release stage is reached only when it has. func markInternalChartReady(t *testing.T, c client.Client, name string) { diff --git a/images/operator-helm-controller/internal/services/base.go b/images/operator-helm-controller/internal/services/base.go index 51690ca0..fe2d0ffa 100644 --- a/images/operator-helm-controller/internal/services/base.go +++ b/images/operator-helm-controller/internal/services/base.go @@ -47,7 +47,7 @@ func (s *BaseService) ensureResourceDeleted(ctx context.Context, nn types.Namesp // deleteAndCheck issues a delete for the object if it is still present and reports // whether it still exists. A deletion may stay pending because a downstream -// controller (helm-controller, nelm-source-controller) holds a finalizer and has +// controller (helm-controller, source-controller) holds a finalizer and has // not finished tearing the resource down yet, so callers that must not proceed // until the resource is actually gone should keep requeuing while exists is true. func (s *BaseService) deleteAndCheck(ctx context.Context, nn types.NamespacedName, obj client.Object) (exists bool, err error) { diff --git a/images/operator-helm-controller/internal/services/chart_service.go b/images/operator-helm-controller/internal/services/chart_service.go index 52fe61d7..d448d65d 100644 --- a/images/operator-helm-controller/internal/services/chart_service.go +++ b/images/operator-helm-controller/internal/services/chart_service.go @@ -123,7 +123,7 @@ func (s *ChartService) EnsureHelmChart(ctx context.Context, rel source.Release, // CleanupHelmChart issues a delete for the internal HelmChart and returns it // while it is still present, so the caller can inspect its conditions and wait -// for nelm-source-controller to finish removing it. It returns nil once the +// for source-controller to finish removing it. It returns nil once the // HelmChart is gone. func (s *ChartService) CleanupHelmChart(ctx context.Context, names source.ReleaseNames) (*sourcev1.HelmChart, error) { nn := types.NamespacedName{Name: names.HelmChart, Namespace: s.TargetNamespace} diff --git a/images/operator-helm-controller/internal/services/helm_repo_service.go b/images/operator-helm-controller/internal/services/helm_repo_service.go index 5d46b89a..623b224b 100644 --- a/images/operator-helm-controller/internal/services/helm_repo_service.go +++ b/images/operator-helm-controller/internal/services/helm_repo_service.go @@ -123,7 +123,7 @@ func (s *HelmRepoService) RemoveHelmRepository(ctx context.Context, names source // CleanupHelmRepository removes the auth/TLS secrets (which have no finalizers // and disappear immediately) and issues a delete for the internal HelmRepository, // returning it while it is still present so the caller can inspect its conditions -// and wait for nelm-source-controller to finish removing it. It returns nil once +// and wait for source-controller to finish removing it. It returns nil once // the HelmRepository is gone. func (s *HelmRepoService) CleanupHelmRepository(ctx context.Context, names source.InternalNames) (*sourcev1.HelmRepository, error) { for _, name := range []string{names.AuthSecret, names.TLSSecret} { diff --git a/images/operator-helm-controller/internal/services/oci_repo_service.go b/images/operator-helm-controller/internal/services/oci_repo_service.go index 78298544..feea453d 100644 --- a/images/operator-helm-controller/internal/services/oci_repo_service.go +++ b/images/operator-helm-controller/internal/services/oci_repo_service.go @@ -280,7 +280,7 @@ func (s *OCIRepoService) CleanupOCIRepository(ctx context.Context, names source. // RemoveOCIRepository issues a delete for the internal OCIRepository and returns // it while it is still present, so the caller can inspect its conditions and wait -// for nelm-source-controller to finish removing it. It returns nil once the +// for source-controller to finish removing it. It returns nil once the // OCIRepository is gone. func (s *OCIRepoService) RemoveOCIRepository(ctx context.Context, names source.ReleaseNames) (*sourcev1.OCIRepository, error) { nn := types.NamespacedName{Name: names.OCIRepository, Namespace: s.TargetNamespace} diff --git a/oss.yaml b/oss.yaml index 23be831a..e1ad4d83 100644 --- a/oss.yaml +++ b/oss.yaml @@ -1,12 +1,12 @@ -- name: 3p-helm-controller - link: https://github.com/werf/3p-helm-controller +- name: helm-controller + link: https://github.com/fluxcd/helm-controller description: The helm-controller is a Kubernetes operator, allowing one to declaratively manage Helm chart releases. license: Apache License 2.0 - version: v0.1.5 - id: 3p-helm-controller -- name: nelm-source-controller - link: https://github.com/werf/nelm-source-controller + version: v1.6.4 + id: helm-controller +- name: source-controller + link: https://github.com/fluxcd/source-controller description: The source-controller is a Kubernetes operator, specialised in artifacts acquisition from external sources such as Git, OCI, Helm repositories and S3-compatible buckets. license: Apache License 2.0 - version: v0.1.5 - id: nelm-source-controller + version: v1.9.5 + id: source-controller diff --git a/templates/admision-policy.yaml b/templates/admision-policy.yaml index 41a5a19b..8947d774 100644 --- a/templates/admision-policy.yaml +++ b/templates/admision-policy.yaml @@ -60,7 +60,7 @@ spec: request.userInfo.username.startsWith("system:serviceaccount:d8-system:") || request.userInfo.username in [ "system:serviceaccount:d8-operator-helm:operator-helm-controller", - "system:serviceaccount:d8-operator-helm:nelm-source-controller", + "system:serviceaccount:d8-operator-helm:source-controller", "system:serviceaccount:d8-operator-helm:helm-controller", "system:serviceaccount:d8-operator-helm:chart-values-controller", ] diff --git a/templates/rbac-to-us.yaml b/templates/rbac-to-us.yaml index ead1ca56..fc15dd25 100644 --- a/templates/rbac-to-us.yaml +++ b/templates/rbac-to-us.yaml @@ -9,7 +9,7 @@ metadata: rules: - apiGroups: ["apps"] resources: ["deployments/prometheus-metrics"] - resourceNames: ["operator-helm-controller", "chart-values-controller", "helm-controller", "nelm-source-controller"] + resourceNames: ["operator-helm-controller", "chart-values-controller", "helm-controller", "source-controller"] verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1 diff --git a/templates/nelm-source-controller/_helpers.tpl b/templates/source-controller/_helpers.tpl similarity index 75% rename from templates/nelm-source-controller/_helpers.tpl rename to templates/source-controller/_helpers.tpl index e0b5dc43..175cde6d 100644 --- a/templates/nelm-source-controller/_helpers.tpl +++ b/templates/source-controller/_helpers.tpl @@ -1,4 +1,4 @@ -{{- define "nelm-source-controller.envs" -}} +{{- define "source-controller.envs" -}} - name: RUNTIME_NAMESPACE valueFrom: fieldRef: diff --git a/templates/nelm-source-controller/deployment.yaml b/templates/source-controller/deployment.yaml similarity index 76% rename from templates/nelm-source-controller/deployment.yaml rename to templates/source-controller/deployment.yaml index 593ad9d3..8534e196 100644 --- a/templates/nelm-source-controller/deployment.yaml +++ b/templates/source-controller/deployment.yaml @@ -1,6 +1,6 @@ {{- $priorityClassName := include "priorityClassName" . }} -{{- define "nelm_source_controller_resources" }} +{{- define "source_controller_resources" }} cpu: 50m memory: 64Mi {{- end }} @@ -10,23 +10,23 @@ memory: 64Mi apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler metadata: - name: nelm-source-controller + name: source-controller namespace: d8-{{ .Chart.Name }} - {{- include "helm_lib_module_labels" (list . (dict "app" "nelm-source-controller" "workload-resource-policy.deckhouse.io" "master")) | nindent 2 }} + {{- include "helm_lib_module_labels" (list . (dict "app" "source-controller" "workload-resource-policy.deckhouse.io" "master")) | nindent 2 }} spec: targetRef: apiVersion: "apps/v1" kind: Deployment - name: nelm-source-controller + name: source-controller updatePolicy: updateMode: {{ include "vpa.policyUpdateMode" . }} resourcePolicy: containerPolicies: {{- include "kube_api_rewriter.vpa_container_policy" . | nindent 4 }} {{- include "kube_rbac_proxy.vpa_container_policy" . | nindent 4 }} - - containerName: nelm-source-controller + - containerName: source-controller minAllowed: - {{- include "nelm_source_controller_resources" . | nindent 8 }} + {{- include "source_controller_resources" . | nindent 8 }} maxAllowed: cpu: 1000m memory: 1Gi @@ -36,22 +36,22 @@ spec: apiVersion: policy/v1 kind: PodDisruptionBudget metadata: - name: nelm-source-controller + name: source-controller namespace: d8-{{ .Chart.Name }} - {{- include "helm_lib_module_labels" (list . (dict "app" "nelm-source-controller" )) | nindent 2 }} + {{- include "helm_lib_module_labels" (list . (dict "app" "source-controller" )) | nindent 2 }} spec: minAvailable: {{ include "helm_lib_is_ha_to_value" (list . 1 0) }} selector: matchLabels: - app: nelm-source-controller + app: source-controller --- apiVersion: apps/v1 kind: Deployment metadata: - name: nelm-source-controller + name: source-controller namespace: d8-{{ .Chart.Name }} - {{- include "helm_lib_module_labels" (list . (dict "app" "nelm-source-controller")) | nindent 2 }} + {{- include "helm_lib_module_labels" (list . (dict "app" "source-controller")) | nindent 2 }} spec: replicas: 1 strategy: @@ -59,19 +59,19 @@ spec: revisionHistoryLimit: 2 selector: matchLabels: - app: nelm-source-controller + app: source-controller template: metadata: labels: - app: nelm-source-controller + app: source-controller annotations: - kubectl.kubernetes.io/default-container: nelm-source-controller + kubectl.kubernetes.io/default-container: source-controller spec: containers: {{- include "kube_api_rewriter.sidecar_container" . | nindent 8 }} - - name: nelm-source-controller + - name: source-controller {{- include "helm_lib_module_container_security_context_read_only_root_filesystem_capabilities_drop_all_pss_restricted" . | nindent 10 }} - image: {{ include "helm_lib_module_image" (list . "nelmSourceController") }} + image: {{ include "helm_lib_module_image" (list . "sourceController") }} imagePullPolicy: IfNotPresent args: - --watch-all-namespaces=false @@ -79,7 +79,7 @@ spec: - --enable-leader-election - --storage-path=/data - --storage-addr=:9091 - - --storage-adv-addr=nelm-source-controller.$(RUNTIME_NAMESPACE).svc.{{ .Values.global.discovery.clusterDomain }} + - --storage-adv-addr=source-controller.$(RUNTIME_NAMESPACE).svc.{{ .Values.global.discovery.clusterDomain }} volumeMounts: - mountPath: /data name: data @@ -100,11 +100,11 @@ spec: requests: {{- include "helm_lib_module_ephemeral_storage_only_logs" . | nindent 14 }} {{- if not ( .Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} - {{- include "nelm_source_controller_resources" . | nindent 14 }} + {{- include "source_controller_resources" . | nindent 14 }} {{- end }} env: {{- include "kube_api_rewriter.kubeconfig_env" . | nindent 12 }} - {{- include "nelm-source-controller.envs" . | nindent 12 }} + {{- include "source-controller.envs" . | nindent 12 }} livenessProbe: httpGet: path: /healthz @@ -123,19 +123,19 @@ spec: {{- $_ := set $kubeRbacProxySettings "listenPort" 8443 }} {{- $_ := set $kubeRbacProxySettings "portName" "rbac-proxy" }} {{- $_ := set $kubeRbacProxySettings "upstreams" (list - (dict "upstream" "http://127.0.0.1:8080/metrics" "path" "/metrics" "name" "nelm-source-controller") + (dict "upstream" "http://127.0.0.1:8080/metrics" "path" "/metrics" "name" "source-controller") (dict "upstream" "http://127.0.0.1:9090/metrics" "path" "/proxy/metrics" "name" "kube-api-rewriter") (dict "upstream" "http://127.0.0.1:9090/healthz" "path" "/proxy/healthz" "name" "kube-api-rewriter") (dict "upstream" "http://127.0.0.1:9090/readyz" "path" "/proxy/readyz" "name" "kube-api-rewriter") ) }} {{- include "kube_rbac_proxy.sidecar_container" (tuple . $kubeRbacProxySettings) | nindent 8 }} dnsPolicy: ClusterFirst - serviceAccountName: nelm-source-controller + serviceAccountName: source-controller {{- include "helm_lib_module_pod_security_context_run_as_user_deckhouse" . | nindent 6 }} {{- include "helm_lib_priority_class" (tuple . $priorityClassName) | nindent 6 }} {{- include "helm_lib_node_selector" (tuple . "system") | nindent 6 }} {{- include "helm_lib_tolerations" (tuple . "system") | nindent 6 }} - {{- include "helm_lib_pod_anti_affinity_for_ha" (list . (dict "app" "nelm-source-controller")) | nindent 6 }} + {{- include "helm_lib_pod_anti_affinity_for_ha" (list . (dict "app" "source-controller")) | nindent 6 }} volumes: - emptyDir: {} name: data diff --git a/templates/nelm-source-controller/rbac-for-us.yaml b/templates/source-controller/rbac-for-us.yaml similarity index 86% rename from templates/nelm-source-controller/rbac-for-us.yaml rename to templates/source-controller/rbac-for-us.yaml index 6c414ae9..96e9f446 100644 --- a/templates/nelm-source-controller/rbac-for-us.yaml +++ b/templates/source-controller/rbac-for-us.yaml @@ -2,9 +2,9 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: nelm-source-controller + name: source-controller namespace: d8-{{ .Chart.Name }} - {{- include "helm_lib_module_labels" (list . (dict "app" "nelm-source-controller")) | nindent 2 }} + {{- include "helm_lib_module_labels" (list . (dict "app" "source-controller")) | nindent 2 }} imagePullSecrets: - name: operator-helm-module-registry --- @@ -12,21 +12,21 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: {{- include "helm_lib_module_labels" (list .) | nindent 2 }} - name: d8:{{ .Chart.Name }}:nelm-source-controller + name: d8:{{ .Chart.Name }}:source-controller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: d8:{{ .Chart.Name }}:nelm-source-controller + name: d8:{{ .Chart.Name }}:source-controller subjects: - kind: ServiceAccount - name: nelm-source-controller + name: source-controller namespace: d8-{{ .Chart.Name }} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: {{- include "helm_lib_module_labels" (list .) | nindent 2 }} - name: d8:{{ .Chart.Name }}:nelm-source-controller + name: d8:{{ .Chart.Name }}:source-controller rules: - apiGroups: - authentication.k8s.io @@ -109,7 +109,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: {{- include "helm_lib_module_labels" (list .) | nindent 2 }} - name: nelm-source-controller + name: source-controller namespace: d8-{{ .Chart.Name }} rules: - apiGroups: @@ -155,12 +155,12 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: {{- include "helm_lib_module_labels" (list .) | nindent 2 }} - name: nelm-source-controller + name: source-controller namespace: d8-{{ .Chart.Name }} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: nelm-source-controller + name: source-controller subjects: - kind: ServiceAccount - name: nelm-source-controller + name: source-controller diff --git a/templates/nelm-source-controller/service-metrics.yaml b/templates/source-controller/service-metrics.yaml similarity index 52% rename from templates/nelm-source-controller/service-metrics.yaml rename to templates/source-controller/service-metrics.yaml index 361f572b..1bfed59f 100644 --- a/templates/nelm-source-controller/service-metrics.yaml +++ b/templates/source-controller/service-metrics.yaml @@ -2,9 +2,9 @@ apiVersion: v1 kind: Service metadata: - name: nelm-source-controller-metrics + name: source-controller-metrics namespace: d8-{{ .Chart.Name }} - {{- include "helm_lib_module_labels" (list . (dict "app" "nelm-source-controller")) | nindent 2 }} + {{- include "helm_lib_module_labels" (list . (dict "app" "source-controller")) | nindent 2 }} spec: ports: - name: metrics @@ -12,4 +12,4 @@ spec: protocol: TCP targetPort: rbac-proxy selector: - app: nelm-source-controller + app: source-controller diff --git a/templates/nelm-source-controller/service-monitor.yaml b/templates/source-controller/service-monitor.yaml similarity index 64% rename from templates/nelm-source-controller/service-monitor.yaml rename to templates/source-controller/service-monitor.yaml index 6e8e3065..c7f239cb 100644 --- a/templates/nelm-source-controller/service-monitor.yaml +++ b/templates/source-controller/service-monitor.yaml @@ -2,9 +2,9 @@ apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: - name: {{ .Chart.Name }}-nelm-source-controller + name: {{ .Chart.Name }}-source-controller namespace: d8-monitoring - {{- include "helm_lib_module_labels" (list . (dict "app" "nelm-source-controller" "prometheus" "main")) | nindent 2 }} + {{- include "helm_lib_module_labels" (list . (dict "app" "source-controller" "prometheus" "main")) | nindent 2 }} spec: endpoints: - bearerTokenSecret: @@ -20,4 +20,4 @@ spec: - d8-{{ .Chart.Name }} selector: matchLabels: - app: "nelm-source-controller" + app: "source-controller" diff --git a/templates/nelm-source-controller/service.yaml b/templates/source-controller/service.yaml similarity index 53% rename from templates/nelm-source-controller/service.yaml rename to templates/source-controller/service.yaml index 1d1bfa27..85df1709 100644 --- a/templates/nelm-source-controller/service.yaml +++ b/templates/source-controller/service.yaml @@ -2,9 +2,9 @@ apiVersion: v1 kind: Service metadata: - name: nelm-source-controller + name: source-controller namespace: d8-{{ .Chart.Name }} - {{- include "helm_lib_module_labels" (list . (dict "app" "nelm-source-controller")) | nindent 2 }} + {{- include "helm_lib_module_labels" (list . (dict "app" "source-controller")) | nindent 2 }} spec: ports: - name: controller @@ -12,4 +12,4 @@ spec: targetPort: controller protocol: TCP selector: - app: nelm-source-controller + app: source-controller diff --git a/tests/e2e/default_config.yaml b/tests/e2e/default_config.yaml index 0f7a32c9..85502703 100644 --- a/tests/e2e/default_config.yaml +++ b/tests/e2e/default_config.yaml @@ -30,11 +30,11 @@ controllers: logFilters: exclude: [] excludeRegexp: [] - - name: "nelm-source-controller" + - name: "source-controller" namespace: "d8-operator-helm" - labelSelector: "app=nelm-source-controller" + labelSelector: "app=source-controller" containers: - - "nelm-source-controller" + - "source-controller" logFilters: exclude: [] excludeRegexp: From 46d1c51e9e293fd17a8ecc3be973f13bb72873ce Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 17:45:21 +0300 Subject: [PATCH 11/19] fix(build): guard against upstream flux tag skew The helm-controller and source-controller tags were pinned in the Taskfile vars, the two werf.inc.yaml files, versions.yml and oss.yaml with nothing checking they agreed. Bumping the werf files without the Taskfile would build one version's binary while regenerating the internal CRDs from another's schema, silently. Make build/components/versions.yml the single source generate:internal-crds reads its tags from, and add a check-flux-tags task, run from ci:generate:internal-crds, that fails CI when either werf.inc.yaml literal drifts from versions.yml. Signed-off-by: Ilya Drey --- Taskfile.yaml | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 75b1ee5d..740d888a 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -61,17 +61,16 @@ tasks: generate:internal-crds: desc: "Regenerate the internal CustomResourceDefinitions from upstream flux." - vars: - helmControllerTag: v1.6.4 - sourceControllerTag: v1.9.5 cmds: - | set -eu + helmControllerTag=$(sed -n 's/^ *helm-controller: *//p' build/components/versions.yml) + sourceControllerTag=$(sed -n 's/^ *source-controller: *//p' build/components/versions.yml) work=$(mktemp -d) trap 'rm -rf "$work"' EXIT - git clone --quiet --depth 1 --branch {{.helmControllerTag}} \ + git clone --quiet --depth 1 --branch "$helmControllerTag" \ https://github.com/fluxcd/helm-controller "$work/helm-controller" - git clone --quiet --depth 1 --branch {{.sourceControllerTag}} \ + git clone --quiet --depth 1 --branch "$sourceControllerTag" \ https://github.com/fluxcd/source-controller "$work/source-controller" cd tools/internalcrds go run . -out ../../crds/embedded/helm-controller.yaml \ @@ -79,9 +78,29 @@ tasks: go run . -out ../../crds/embedded/source-controller.yaml \ "$work/source-controller/config/crd/bases" + check-flux-tags: + desc: "Verify the upstream flux tags pinned in werf.inc.yaml match build/components/versions.yml." + cmds: + - | + set -eu + helmControllerTag=$(sed -n 's/^ *helm-controller: *//p' build/components/versions.yml) + sourceControllerTag=$(sed -n 's/^ *source-controller: *//p' build/components/versions.yml) + helmWerfTag=$(sed -n 's/.*\$helmControllerTag := "\(.*\)".*/\1/p' images/helm-controller/werf.inc.yaml) + sourceWerfTag=$(sed -n 's/.*\$sourceControllerTag := "\(.*\)".*/\1/p' images/source-controller/werf.inc.yaml) + if [ "$helmControllerTag" != "$helmWerfTag" ]; then + echo "images/helm-controller/werf.inc.yaml pins helm-controller $helmWerfTag but build/components/versions.yml pins $helmControllerTag" >&2 + exit 1 + fi + if [ "$sourceControllerTag" != "$sourceWerfTag" ]; then + echo "images/source-controller/werf.inc.yaml pins source-controller $sourceWerfTag but build/components/versions.yml pins $sourceControllerTag" >&2 + exit 1 + fi + silent: true + ci:generate:internal-crds: desc: "Regenerate the internal CustomResourceDefinitions and verify they are committed." cmds: + - task: check-flux-tags - task: generate:internal-crds - | git diff --exit-code crds/embedded || (echo "Please run task generate:internal-crds and commit changes" && exit 1) From fcfae1c3e8dcabdd92f711cb4e4dae20276aca08 Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 17:49:56 +0300 Subject: [PATCH 12/19] chore(tools): wire tools/internalcrds into the repository's tasks tools/internalcrds is a Go module of its own now, but it was attached to test:unit as a raw shell line and absent from includes, so task format and task lint never touched it. Give it a Taskfile.dist.yaml and .golangci.yaml modeled on the sibling Go modules, include it from the root Taskfile, and reference it from format, lint and test:unit like every other module. Signed-off-by: Ilya Drey --- Taskfile.yaml | 15 ++-- tools/internalcrds/.golangci.yaml | 109 ++++++++++++++++++++++++++ tools/internalcrds/Taskfile.dist.yaml | 21 +++++ 3 files changed, 140 insertions(+), 5 deletions(-) create mode 100644 tools/internalcrds/.golangci.yaml create mode 100644 tools/internalcrds/Taskfile.dist.yaml diff --git a/Taskfile.yaml b/Taskfile.yaml index 740d888a..56382e9c 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -8,10 +8,10 @@ vars: VALIDATION_FILES: "tools/validation/{main,messages,diff,doc_changes}.go" golangciLintVersion: "v2.13.2" -# Only the modules this repository authors are listed. images/kube-api-rewriter is a -# separate upstream module vendored in for the build, and images/helm-controller and -# images/source-controller carry nothing but their werf files, so none of them is -# ours to lint, format or test here. +# Only the modules this repository authors are listed, including tools/internalcrds. +# images/kube-api-rewriter is a separate upstream module vendored in for the build, and +# images/helm-controller and images/source-controller carry nothing but their werf +# files, so none of them is ours to lint, format or test here. includes: api: taskfile: ./api/Taskfile.dist.yaml @@ -28,6 +28,9 @@ includes: chart-values-controller: taskfile: ./images/chart-values-controller/Taskfile.dist.yaml dir: ./images/chart-values-controller + internalcrds: + taskfile: ./tools/internalcrds/Taskfile.dist.yaml + dir: ./tools/internalcrds deps: taskfile: https://raw.githubusercontent.com/werf/common-ci/refs/heads/main/Taskfile.deps.yml @@ -128,7 +131,7 @@ tasks: - task: operator-helm-controller:test:unit - task: chart-values-controller:test:unit - task: e2e:test:unit - - cd tools/internalcrds && go test ./... + - task: internalcrds:test:unit test:e2e:setup: desc: "Setup environment for e2e tests." @@ -194,6 +197,7 @@ tasks: - task: operator-helm-controller:format - task: chart-values-controller:format - task: e2e:format + - task: internalcrds:format lint: deps: @@ -204,6 +208,7 @@ tasks: - task: operator-helm-controller:lint - task: chart-values-controller:lint - task: e2e:lint + - task: internalcrds:lint - task: lint:doc-ru lint:doc-ru: diff --git a/tools/internalcrds/.golangci.yaml b/tools/internalcrds/.golangci.yaml new file mode 100644 index 00000000..9e052264 --- /dev/null +++ b/tools/internalcrds/.golangci.yaml @@ -0,0 +1,109 @@ +# https://golangci-lint.run/usage/configuration/ +version: "2" + +run: + concurrency: 4 + timeout: 10m + +issues: + # Show all errors. + max-issues-per-linter: 0 + max-same-issues: 0 + exclude: + - "don't use an underscore in package name" + +output: + sort-results: true + +exclusions: + paths: + - "^zz_generated.*" + +formatters: + enable: + - gci + - gofmt + - gofumpt + - goimports + settings: + gci: + sections: + - standard + - default + - prefix(github.com/deckhouse/) + gofumpt: + extra-rules: true + goimports: + local-prefixes: github.com/deckhouse/ + +linters: + default: none + enable: + - asciicheck # checks that your code does not contain non-ASCII identifiers + - bidichk # checks for dangerous unicode character sequences + - bodyclose # checks whether HTTP response body is closed successfully + - contextcheck # [maybe too many false positives] checks the function whether use a non-inherited context + - dogsled # checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) + - errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases + - errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error + - errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13 + - copyloopvar # detects places where loop variables are copied (Go 1.22+) + - gocritic # provides diagnostics that check for bugs, performance and style issues + - govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string + - ineffassign # detects when assignments to existing variables are not used + - misspell # finds commonly misspelled English words in comments + - nolintlint # reports ill-formed or insufficient nolint directives + - reassign # checks that package variables are not reassigned + - revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint + - staticcheck # is a go vet on steroids, applying a ton of static analysis checks + - testifylint # checks usage of github.com/stretchr/testify + - unconvert # removes unnecessary type conversions + - unparam # reports unused function parameters + - unused # checks for unused constants, variables, functions and types + - usetesting # reports uses of functions with replacement inside the testing package + - testableexamples # checks if examples are testable (have an expected output) + - thelper # detects golang test helpers without t.Helper() call and checks the consistency of test helpers + - tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes + - whitespace # detects leading and trailing whitespace + - wastedassign # finds wasted assignment statements + - importas # checks import aliases against the configured convention + settings: + errcheck: + exclude-functions: + - "(*os.File).Close" + - "(*net.TCPConn).Close" + - "(io.ReadCloser).Close" + - "(net.Listener).Close" + - "(net.Conn).Close" + - "(net.Conn).Close" + - "(*golang.org/x/crypto/ssh.Session).Close" + - "(*github.com/fsnotify/fsnotify.Watcher).Close" + staticcheck: + dot-import-whitelist: + - github.com/onsi/ginkgo/v2 + - github.com/onsi/gomega + revive: + rules: + - name: dot-imports + disabled: true + - name: exported + disabled: true + - name: package-comments + disabled: true + nolintlint: + # Exclude following linters from requiring an explanation. + # Default: [] + allow-no-explanation: [funlen, gocognit, lll] + # Enable to require an explanation of nonzero length after each nolint directive. + # Default: false + require-explanation: true + # Enable to require nolint directives to mention the specific linter being suppressed. + # Default: false + require-specific: true + importas: + # Do not allow unaliased imports of aliased packages. + # Default: false + no-unaliased: true + # Do not allow non-required aliases. + # Default: false + no-extra-aliases: false diff --git a/tools/internalcrds/Taskfile.dist.yaml b/tools/internalcrds/Taskfile.dist.yaml new file mode 100644 index 00000000..7bf197ea --- /dev/null +++ b/tools/internalcrds/Taskfile.dist.yaml @@ -0,0 +1,21 @@ +version: "3" + +silent: true + +includes: + artifact: + taskfile: https://raw.githubusercontent.com/werf/common-ci/refs/heads/main/Taskfile.format_lint.yml + flatten: true + vars: + gciPrefix: '{{.gciPrefix | default "github.com/deckhouse/"}}' + golangciConfigPath: '{{.golangciConfigPath | default "./.golangci.yaml"}}' + golangciLintBinDir: '{{.golangciLintBinDir | default "../../bin"}}' + golangciLintVersion: '{{.golangciLintVersion | default "v2.13.2"}}' + golangciPaths: '{{.golangciPaths | default "./..."}}' + paths: '{{.paths | default "."}}' + +tasks: + test:unit: + desc: "Run the unit tests of this module." + cmds: + - go test ./... From 5675fc8ac16576c61052ec44f8c04c1ca568ec1e Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 17:53:21 +0300 Subject: [PATCH 13/19] fix(tools): correct stale comments and reject a missing CRD kind Three comments described something other than what the code does: the substitute annotation is a real instruction to flux's own kustomize-controller, not an example upstream declares; the slice branch of renameKindReferences matches any list element by value with no key to scope it, not just the sourceRef/chartRef enums it happens to reach today; and the resetAt rationale was duplicated verbatim between the rule and its test. Also make Rename fail when spec.names.kind is missing or not a string, instead of silently writing the bare kindPrefix: run already guarded this with checkKnownKind, but Rename is exported and called directly by tests, so the guard belongs in the function itself. Signed-off-by: Ilya Drey --- .../operatornelm/operatornelm_rules_test.go | 3 +-- tools/internalcrds/main.go | 7 ++--- tools/internalcrds/rename.go | 15 +++++++---- tools/internalcrds/rename_test.go | 27 +++++++++++++++++++ 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go index 905b4ffd..d0be66be 100644 --- a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go +++ b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_rules_test.go @@ -89,8 +89,7 @@ func TestMetadataRenamesKeepTheStoredSide(t *testing.T) { wantAnnotations := map[string]string{ "reconcile.fluxcd.io/requestedAt": "reconcile." + internal + "/requestedAt", "reconcile.fluxcd.io/forceAt": "reconcile." + internal + "/forceAt", - // Unlike its siblings, this module never writes resetAt, so there is no - // stored value to preserve; it moves into the internal namespace too. + // resetAt moves into the internal namespace too; see the rule's comment for why. "reconcile.fluxcd.io/resetAt": "reconcile." + internal + "/resetAt", } got := map[string]string{} diff --git a/tools/internalcrds/main.go b/tools/internalcrds/main.go index e73f2d3f..7b8baefd 100644 --- a/tools/internalcrds/main.go +++ b/tools/internalcrds/main.go @@ -41,9 +41,10 @@ import ( // noticing. const forbiddenGroup = "toolkit.fluxcd.io" -// allowedAnnotation is the sole legitimate survivor of forbiddenGroup: a -// kustomize substitution annotation key upstream declares as an example, not -// an identity this module renames. +// allowedAnnotation is the sole legitimate survivor of forbiddenGroup: a real +// annotation upstream carries on every one of these definitions, instructing a +// real flux kustomize-controller to leave the definition alone. It addresses +// that controller, not this module, so it is deliberately left unrenamed. const allowedAnnotation = "kustomize.toolkit.fluxcd.io/substitute" func main() { diff --git a/tools/internalcrds/rename.go b/tools/internalcrds/rename.go index a9cb2f3b..393265c7 100644 --- a/tools/internalcrds/rename.go +++ b/tools/internalcrds/rename.go @@ -84,7 +84,10 @@ func Rename(doc map[string]any) error { return errors.New("the document has no spec.names") } - kind, _ := names["kind"].(string) + kind, ok := names["kind"].(string) + if !ok { + return errors.New("the document has no spec.names.kind") + } names["kind"] = kindPrefix + kind if listKind, ok := names["listKind"].(string); ok { names["listKind"] = kindPrefix + listKind @@ -117,10 +120,12 @@ func Rename(doc map[string]any) error { return nil } -// renameKindReferences walks the schemas and renames every value that names an -// upstream kind. Those live in sourceRef and chartRef at several depths, as a -// default, as an enum entry, or as an example, so the walk is over the whole -// tree rather than a fixed list of paths. +// renameKindReferences walks the schemas and renames upstream kind references +// it finds: under a "kind" key in a map, and, with no key to scope the match, +// any plain string list element equal to an upstream kind. Today the only +// lists it reaches are the sourceRef and chartRef kind enums, so matching by +// value alone is safe; a future field whose string entries happened to equal +// an upstream kind's name would be renamed too. func renameKindReferences(node any) { switch typed := node.(type) { case map[string]any: diff --git a/tools/internalcrds/rename_test.go b/tools/internalcrds/rename_test.go index 1f7c4a75..a8be6015 100644 --- a/tools/internalcrds/rename_test.go +++ b/tools/internalcrds/rename_test.go @@ -125,6 +125,33 @@ func TestRenameRewritesNestedReferences(t *testing.T) { } } +func TestRenameFailsOnMissingOrInvalidKind(t *testing.T) { + cases := map[string]map[string]any{ + "missing": {"plural": "helmreleases", "singular": "helmrelease"}, + "non-string": {"kind": 1, "plural": "helmreleases", "singular": "helmrelease"}, + } + + for name, names := range cases { + doc := map[string]any{ + "spec": map[string]any{ + "group": "helm.toolkit.fluxcd.io", + "names": names, + }, + "metadata": map[string]any{"name": "helmreleases.helm.toolkit.fluxcd.io"}, + } + + err := Rename(doc) + if err == nil { + t.Fatalf("%s: expected an error, got nil", name) + } + + const want = "the document has no spec.names.kind" + if err.Error() != want { + t.Fatalf("%s: error = %q, want %q", name, err.Error(), want) + } + } +} + func TestRenameLeavesUnrelatedStringsAlone(t *testing.T) { doc := map[string]any{ "spec": map[string]any{ From 64bd0e8a2137119cdec1c0153acc7810f22e9cd8 Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Thu, 17 Sep 2026 18:00:47 +0300 Subject: [PATCH 14/19] fix(tools): make both version guards fail on a missing pin An empty pin on both sides compared equal and passed, and a definition without a plural produced the bare prefix as its resource name. Signed-off-by: Ilya Drey --- Taskfile.yaml | 6 ++++++ tools/internalcrds/rename.go | 5 ++++- tools/internalcrds/rename_test.go | 21 ++++++++++++--------- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 56382e9c..846387f3 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -90,6 +90,12 @@ tasks: sourceControllerTag=$(sed -n 's/^ *source-controller: *//p' build/components/versions.yml) helmWerfTag=$(sed -n 's/.*\$helmControllerTag := "\(.*\)".*/\1/p' images/helm-controller/werf.inc.yaml) sourceWerfTag=$(sed -n 's/.*\$sourceControllerTag := "\(.*\)".*/\1/p' images/source-controller/werf.inc.yaml) + for pin in "$helmControllerTag" "$sourceControllerTag" "$helmWerfTag" "$sourceWerfTag"; do + if [ -z "$pin" ]; then + echo "a version pin came out empty: build/components/versions.yml has '$helmControllerTag' and '$sourceControllerTag', the werf files have '$helmWerfTag' and '$sourceWerfTag'" >&2 + exit 1 + fi + done if [ "$helmControllerTag" != "$helmWerfTag" ]; then echo "images/helm-controller/werf.inc.yaml pins helm-controller $helmWerfTag but build/components/versions.yml pins $helmControllerTag" >&2 exit 1 diff --git a/tools/internalcrds/rename.go b/tools/internalcrds/rename.go index 393265c7..0a471367 100644 --- a/tools/internalcrds/rename.go +++ b/tools/internalcrds/rename.go @@ -93,7 +93,10 @@ func Rename(doc map[string]any) error { names["listKind"] = kindPrefix + listKind } - plural, _ := names["plural"].(string) + plural, ok := names["plural"].(string) + if !ok { + return errors.New("the document has no spec.names.plural") + } names["plural"] = strings.ToLower(kindPrefix) + plural if singular, ok := names["singular"].(string); ok { names["singular"] = strings.ToLower(kindPrefix) + singular diff --git a/tools/internalcrds/rename_test.go b/tools/internalcrds/rename_test.go index a8be6015..1fd9c87e 100644 --- a/tools/internalcrds/rename_test.go +++ b/tools/internalcrds/rename_test.go @@ -125,17 +125,21 @@ func TestRenameRewritesNestedReferences(t *testing.T) { } } -func TestRenameFailsOnMissingOrInvalidKind(t *testing.T) { - cases := map[string]map[string]any{ - "missing": {"plural": "helmreleases", "singular": "helmrelease"}, - "non-string": {"kind": 1, "plural": "helmreleases", "singular": "helmrelease"}, +func TestRenameFailsOnMissingNames(t *testing.T) { + cases := map[string]struct { + names map[string]any + want string + }{ + "kind missing": {map[string]any{"plural": "helmreleases", "singular": "helmrelease"}, "the document has no spec.names.kind"}, + "kind not a string": {map[string]any{"kind": 1, "plural": "helmreleases", "singular": "helmrelease"}, "the document has no spec.names.kind"}, + "plural missing": {map[string]any{"kind": "HelmRelease", "singular": "helmrelease"}, "the document has no spec.names.plural"}, } - for name, names := range cases { + for name, tc := range cases { doc := map[string]any{ "spec": map[string]any{ "group": "helm.toolkit.fluxcd.io", - "names": names, + "names": tc.names, }, "metadata": map[string]any{"name": "helmreleases.helm.toolkit.fluxcd.io"}, } @@ -145,9 +149,8 @@ func TestRenameFailsOnMissingOrInvalidKind(t *testing.T) { t.Fatalf("%s: expected an error, got nil", name) } - const want = "the document has no spec.names.kind" - if err.Error() != want { - t.Fatalf("%s: error = %q, want %q", name, err.Error(), want) + if err.Error() != tc.want { + t.Fatalf("%s: error = %q, want %q", name, err.Error(), tc.want) } } } From 753fde354fed7a0585507629cb4ecaa8fa8c9bbd Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Fri, 18 Sep 2026 13:39:12 +0300 Subject: [PATCH 15/19] fix(tools): rename kinds in the text of the internal definitions A validation rule comparing against an upstream kind could never hold once the enum beside it was renamed, and the documentation named kinds this cluster does not serve. The leftover guard now covers kinds as well. Signed-off-by: Ilya Drey --- crds/embedded/helm-controller.yaml | 70 +++++++-------- crds/embedded/source-controller.yaml | 126 +++++++++++++-------------- tools/internalcrds/main.go | 11 +-- tools/internalcrds/rename.go | 43 ++++++--- tools/internalcrds/rename_test.go | 55 +++++++++++- 5 files changed, 186 insertions(+), 119 deletions(-) diff --git a/crds/embedded/helm-controller.yaml b/crds/embedded/helm-controller.yaml index facf6740..9974d817 100644 --- a/crds/embedded/helm-controller.yaml +++ b/crds/embedded/helm-controller.yaml @@ -32,7 +32,7 @@ spec: name: v2 schema: openAPIV3Schema: - description: HelmRelease is the Schema for the helmreleases API + description: InternalNelmOperatorHelmRelease is the Schema for the helmreleases API properties: apiVersion: description: |- @@ -56,8 +56,8 @@ spec: properties: chart: description: |- - Chart defines the template of the v1.HelmChart that should be created - for this HelmRelease. + Chart defines the template of the v1.InternalNelmOperatorHelmChart that should be created + for this InternalNelmOperatorHelmRelease. properties: metadata: description: ObjectMeta holds the template for metadata like labels and annotations. @@ -81,7 +81,7 @@ spec: type: object type: object spec: - description: Spec holds the template for the v1.HelmChartSpec for this HelmRelease. + description: Spec holds the template for the v1.HelmChartSpec for this InternalNelmOperatorHelmRelease. properties: chart: description: The name or path the Helm chart is available at in the SourceRef. @@ -177,8 +177,8 @@ spec: version: default: '*' description: |- - Version semver expression, ignored for charts from v1.GitRepository and - v1beta2.Bucket sources. Defaults to latest when omitted. + Version semver expression, ignored for charts from v1.InternalNelmOperatorGitRepository and + v1beta2.InternalNelmOperatorBucket sources. Defaults to latest when omitted. type: string required: - chart @@ -238,7 +238,7 @@ spec: dependsOn: description: |- DependsOn may contain a DependencyReference slice with - references to HelmRelease resources that must be ready before this HelmRelease + references to InternalNelmOperatorHelmRelease resources that must be ready before this InternalNelmOperatorHelmRelease can be reconciled. items: description: |- @@ -384,7 +384,7 @@ spec: type: object type: array install: - description: Install holds the configuration for Helm install actions for this HelmRelease. + description: Install holds the configuration for Helm install actions for this InternalNelmOperatorHelmRelease. properties: crds: description: |- @@ -446,7 +446,7 @@ spec: remediation: description: |- Remediation holds the remediation configuration for when the Helm install - action for the HelmRelease fails. The default is to not perform any action. + action for the InternalNelmOperatorHelmRelease fails. The default is to not perform any action. properties: ignoreTestFailures: description: |- @@ -485,7 +485,7 @@ spec: type: boolean strategy: description: |- - Strategy defines the install strategy to use for this HelmRelease. + Strategy defines the install strategy to use for this InternalNelmOperatorHelmRelease. Defaults to 'RemediateOnFailure', or 'RetryOnFailure' when the DefaultToRetryOnFailure feature gate is enabled. properties: @@ -522,7 +522,7 @@ spec: type: string kubeConfig: description: |- - KubeConfig for reconciling the HelmRelease on a remote cluster. + KubeConfig for reconciling the InternalNelmOperatorHelmRelease on a remote cluster. When used in combination with HelmReleaseSpec.ServiceAccountName, forces the controller to act on behalf of that Service Account at the target cluster. @@ -596,7 +596,7 @@ spec: rule: '!has(self.configMapRef) || !has(self.secretRef)' maxHistory: description: |- - MaxHistory is the number of revisions saved by Helm for this HelmRelease. + MaxHistory is the number of revisions saved by Helm for this InternalNelmOperatorHelmRelease. Use '0' for an unlimited number of revisions; defaults to '5'. type: integer persistentClient: @@ -731,7 +731,7 @@ spec: minLength: 1 type: string rollback: - description: Rollback holds the configuration for Helm rollback actions for this HelmRelease. + description: Rollback holds the configuration for Helm rollback actions for this InternalNelmOperatorHelmRelease. properties: cleanupOnFail: description: |- @@ -792,35 +792,35 @@ spec: serviceAccountName: description: |- The name of the Kubernetes service account to impersonate - when reconciling this HelmRelease. + when reconciling this InternalNelmOperatorHelmRelease. maxLength: 253 minLength: 1 type: string storageNamespace: description: |- StorageNamespace used for the Helm storage. - Defaults to the namespace of the HelmRelease. + Defaults to the namespace of the InternalNelmOperatorHelmRelease. maxLength: 63 minLength: 1 type: string suspend: description: |- - Suspend tells the controller to suspend reconciliation for this HelmRelease, + Suspend tells the controller to suspend reconciliation for this InternalNelmOperatorHelmRelease, it does not apply to already started reconciliations. Defaults to false. type: boolean targetNamespace: description: |- - TargetNamespace to target when performing operations for the HelmRelease. - Defaults to the namespace of the HelmRelease. + TargetNamespace to target when performing operations for the InternalNelmOperatorHelmRelease. + Defaults to the namespace of the InternalNelmOperatorHelmRelease. maxLength: 63 minLength: 1 type: string test: - description: Test holds the configuration for Helm test actions for this HelmRelease. + description: Test holds the configuration for Helm test actions for this InternalNelmOperatorHelmRelease. properties: enable: description: |- - Enable enables Helm test actions for this HelmRelease after an Helm install + Enable enables Helm test actions for this InternalNelmOperatorHelmRelease after an Helm install or upgrade action has been performed. type: boolean filters: @@ -860,7 +860,7 @@ spec: pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ type: string uninstall: - description: Uninstall holds the configuration for Helm uninstall actions for this HelmRelease. + description: Uninstall holds the configuration for Helm uninstall actions for this InternalNelmOperatorHelmRelease. properties: deletionPropagation: default: background @@ -894,7 +894,7 @@ spec: type: string type: object upgrade: - description: Upgrade holds the configuration for Helm upgrade actions for this HelmRelease. + description: Upgrade holds the configuration for Helm upgrade actions for this InternalNelmOperatorHelmRelease. properties: chartNameChangeStrategy: description: |- @@ -973,13 +973,13 @@ spec: preserveValues: description: |- PreserveValues will make Helm reuse the last release's values and merge in - overrides from 'Values'. Setting this flag makes the HelmRelease + overrides from 'Values'. Setting this flag makes the InternalNelmOperatorHelmRelease non-declarative. type: boolean remediation: description: |- Remediation holds the remediation configuration for when the Helm upgrade - action for the HelmRelease fails. The default is to not perform any action. + action for the InternalNelmOperatorHelmRelease fails. The default is to not perform any action. properties: ignoreTestFailures: description: |- @@ -1018,7 +1018,7 @@ spec: type: string strategy: description: |- - Strategy defines the upgrade strategy to use for this HelmRelease. + Strategy defines the upgrade strategy to use for this InternalNelmOperatorHelmRelease. Defaults to 'RemediateOnFailure', or 'RetryOnFailure' when the DefaultToRetryOnFailure feature gate is enabled. properties: @@ -1054,7 +1054,7 @@ spec: x-kubernetes-preserve-unknown-fields: true valuesFrom: description: |- - ValuesFrom holds references to resources containing Helm values for this HelmRelease, + ValuesFrom holds references to resources containing Helm values for this InternalNelmOperatorHelmRelease, and information about how they should be merged. items: description: |- @@ -1140,10 +1140,10 @@ spec: status: default: observedGeneration: -1 - description: HelmReleaseStatus defines the observed state of a HelmRelease. + description: HelmReleaseStatus defines the observed state of a InternalNelmOperatorHelmRelease. properties: conditions: - description: Conditions holds the conditions for the HelmRelease. + description: Conditions holds the conditions for the InternalNelmOperatorHelmRelease. items: description: Condition contains details for one aspect of the current state of this API Resource. properties: @@ -1206,12 +1206,12 @@ spec: type: integer helmChart: description: |- - HelmChart is the namespaced name of the HelmChart resource created by - the controller for the HelmRelease. + InternalNelmOperatorHelmChart is the namespaced name of the InternalNelmOperatorHelmChart resource created by + the controller for the InternalNelmOperatorHelmRelease. type: string history: description: |- - History holds the history of Helm releases performed for this HelmRelease + History holds the history of Helm releases performed for this InternalNelmOperatorHelmRelease up to the last successfully completed release. items: description: |- @@ -1357,7 +1357,7 @@ spec: lastAttemptedReleaseAction: description: |- LastAttemptedReleaseAction is the last release action performed for this - HelmRelease. It is used to determine the active retry or remediation + InternalNelmOperatorHelmRelease. It is used to determine the active retry or remediation strategy. enum: - install @@ -1366,18 +1366,18 @@ spec: lastAttemptedReleaseActionDuration: description: |- LastAttemptedReleaseActionDuration is the duration of the last - release action performed for this HelmRelease. + release action performed for this InternalNelmOperatorHelmRelease. type: string lastAttemptedRevision: description: |- LastAttemptedRevision is the Source revision of the last reconciliation - attempt. For OCIRepository sources, the 12 first characters of the digest are + attempt. For InternalNelmOperatorOCIRepository sources, the 12 first characters of the digest are appended to the chart version e.g. "1.2.3+1234567890ab". type: string lastAttemptedRevisionDigest: description: |- LastAttemptedRevisionDigest is the digest of the last reconciliation attempt. - This is only set for OCIRepository sources. + This is only set for InternalNelmOperatorOCIRepository sources. type: string lastAttemptedValuesChecksum: description: |- diff --git a/crds/embedded/source-controller.yaml b/crds/embedded/source-controller.yaml index cf79a401..e219d2fa 100644 --- a/crds/embedded/source-controller.yaml +++ b/crds/embedded/source-controller.yaml @@ -35,7 +35,7 @@ spec: name: v1 schema: openAPIV3Schema: - description: Bucket is the Schema for the buckets API. + description: InternalNelmOperatorBucket is the Schema for the buckets API. properties: apiVersion: description: |- @@ -99,13 +99,13 @@ spec: type: boolean interval: description: |- - Interval at which the Bucket Endpoint is checked for updates. + Interval at which the InternalNelmOperatorBucket Endpoint is checked for updates. This interval is approximate and may be subject to jitter to ensure efficient use of resources. pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ type: string prefix: - description: Prefix to use for server-side filtering of files in the Bucket. + description: Prefix to use for server-side filtering of files in the InternalNelmOperatorBucket. type: string provider: default: generic @@ -122,7 +122,7 @@ spec: proxySecretRef: description: |- ProxySecretRef specifies the Secret containing the proxy configuration - to use while communicating with the Bucket server. + to use while communicating with the InternalNelmOperatorBucket server. properties: name: description: Name of the referent. @@ -136,7 +136,7 @@ spec: secretRef: description: |- SecretRef specifies the Secret containing authentication credentials - for the Bucket. + for the InternalNelmOperatorBucket. properties: name: description: Name of the referent. @@ -155,7 +155,7 @@ spec: description: |- STS specifies the required configuration to use a Security Token Service for fetching temporary credentials to authenticate in a - Bucket provider. + InternalNelmOperatorBucket provider. This field is only supported for the `aws` and `generic` providers. properties: @@ -213,7 +213,7 @@ spec: suspend: description: |- Suspend tells the controller to suspend the reconciliation of this - Bucket. + InternalNelmOperatorBucket. type: boolean timeout: default: 60s @@ -226,27 +226,27 @@ spec: - interval type: object x-kubernetes-validations: - - message: STS configuration is only supported for the 'aws' and 'generic' Bucket providers + - message: STS configuration is only supported for the 'aws' and 'generic' InternalNelmOperatorBucket providers rule: self.provider == 'aws' || self.provider == 'generic' || !has(self.sts) - - message: '''aws'' is the only supported STS provider for the ''aws'' Bucket provider' + - message: '''aws'' is the only supported STS provider for the ''aws'' InternalNelmOperatorBucket provider' rule: self.provider != 'aws' || !has(self.sts) || self.sts.provider == 'aws' - - message: '''ldap'' is the only supported STS provider for the ''generic'' Bucket provider' + - message: '''ldap'' is the only supported STS provider for the ''generic'' InternalNelmOperatorBucket provider' rule: self.provider != 'generic' || !has(self.sts) || self.sts.provider == 'ldap' - message: spec.sts.secretRef is not required for the 'aws' STS provider rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.secretRef)' - message: spec.sts.certSecretRef is not required for the 'aws' STS provider rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.certSecretRef)' - - message: ServiceAccountName is not supported for the 'generic' Bucket provider + - message: ServiceAccountName is not supported for the 'generic' InternalNelmOperatorBucket provider rule: self.provider != 'generic' || !has(self.serviceAccountName) - message: cannot set both .spec.secretRef and .spec.serviceAccountName rule: '!has(self.secretRef) || !has(self.serviceAccountName)' status: default: observedGeneration: -1 - description: BucketStatus records the observed state of a Bucket. + description: BucketStatus records the observed state of a InternalNelmOperatorBucket. properties: artifact: - description: Artifact represents the last successful Bucket reconciliation. + description: Artifact represents the last successful InternalNelmOperatorBucket reconciliation. properties: digest: description: Digest is the digest of the file in the form of ':'. @@ -292,7 +292,7 @@ spec: - url type: object conditions: - description: Conditions holds the conditions for the Bucket. + description: Conditions holds the conditions for the InternalNelmOperatorBucket. items: description: Condition contains details for one aspect of the current state of this API Resource. properties: @@ -354,7 +354,7 @@ spec: can be detected. type: string observedGeneration: - description: ObservedGeneration is the last observed generation of the Bucket object. + description: ObservedGeneration is the last observed generation of the InternalNelmOperatorBucket object. format: int64 type: integer observedIgnore: @@ -411,7 +411,7 @@ spec: name: v1 schema: openAPIV3Schema: - description: ExternalArtifact is the Schema for the external artifacts API + description: InternalNelmOperatorExternalArtifact is the Schema for the external artifacts API properties: apiVersion: description: |- @@ -431,7 +431,7 @@ spec: metadata: type: object spec: - description: ExternalArtifactSpec defines the desired state of ExternalArtifact + description: ExternalArtifactSpec defines the desired state of InternalNelmOperatorExternalArtifact properties: sourceRef: description: |- @@ -456,10 +456,10 @@ spec: type: object type: object status: - description: ExternalArtifactStatus defines the observed state of ExternalArtifact + description: ExternalArtifactStatus defines the observed state of InternalNelmOperatorExternalArtifact properties: artifact: - description: Artifact represents the output of an ExternalArtifact reconciliation. + description: Artifact represents the output of an InternalNelmOperatorExternalArtifact reconciliation. properties: digest: description: Digest is the digest of the file in the form of ':'. @@ -505,7 +505,7 @@ spec: - url type: object conditions: - description: Conditions holds the conditions for the ExternalArtifact. + description: Conditions holds the conditions for the InternalNelmOperatorExternalArtifact. items: description: Condition contains details for one aspect of the current state of this API Resource. properties: @@ -603,7 +603,7 @@ spec: name: v1 schema: openAPIV3Schema: - description: GitRepository is the Schema for the gitrepositories API. + description: InternalNelmOperatorGitRepository is the Schema for the gitrepositories API. properties: apiVersion: description: |- @@ -635,11 +635,11 @@ spec: type: string include: description: |- - Include specifies a list of GitRepository resources which Artifacts - should be included in the Artifact produced for this GitRepository. + Include specifies a list of InternalNelmOperatorGitRepository resources which Artifacts + should be included in the Artifact produced for this InternalNelmOperatorGitRepository. items: description: |- - GitRepositoryInclude specifies a local reference to a GitRepository which + GitRepositoryInclude specifies a local reference to a InternalNelmOperatorGitRepository which Artifact (sub-)contents must be included, and where they should be placed. properties: fromPath: @@ -649,7 +649,7 @@ spec: type: string repository: description: |- - GitRepositoryRef specifies the GitRepository which Artifact contents + GitRepositoryRef specifies the InternalNelmOperatorGitRepository which Artifact contents must be included. properties: name: @@ -669,7 +669,7 @@ spec: type: array interval: description: |- - Interval at which the GitRepository URL is checked for updates. + Interval at which the InternalNelmOperatorGitRepository URL is checked for updates. This interval is approximate and may be subject to jitter to ensure efficient use of resources. pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ @@ -698,7 +698,7 @@ spec: recurseSubmodules: description: |- RecurseSubmodules enables the initialization of all submodules within - the GitRepository as cloned from the URL, using their default settings. + the InternalNelmOperatorGitRepository as cloned from the URL, using their default settings. type: boolean ref: description: |- @@ -732,7 +732,7 @@ spec: secretRef: description: |- SecretRef specifies the Secret containing authentication credentials for - the GitRepository. + the InternalNelmOperatorGitRepository. For HTTPS repositories the Secret must contain 'username' and 'password' fields for basic auth or 'bearerToken' field for token auth. For SSH repositories the Secret must contain 'identity' @@ -747,20 +747,20 @@ spec: serviceAccountName: description: |- ServiceAccountName is the name of the Kubernetes ServiceAccount used to - authenticate to the GitRepository. This field is only supported for 'azure' and 'aws' providers. + authenticate to the InternalNelmOperatorGitRepository. This field is only supported for 'azure' and 'aws' providers. type: string sparseCheckout: description: |- SparseCheckout specifies a list of directories to checkout when cloning the repository. If specified, only these directories are included in the - Artifact produced for this GitRepository. + Artifact produced for this InternalNelmOperatorGitRepository. items: type: string type: array suspend: description: |- Suspend tells the controller to suspend the reconciliation of this - GitRepository. + InternalNelmOperatorGitRepository. type: boolean timeout: default: 60s @@ -818,7 +818,7 @@ spec: description: GitRepositoryStatus records the observed state of a Git repository. properties: artifact: - description: Artifact represents the last successful GitRepository reconciliation. + description: Artifact represents the last successful InternalNelmOperatorGitRepository reconciliation. properties: digest: description: Digest is the digest of the file in the form of ':'. @@ -864,7 +864,7 @@ spec: - url type: object conditions: - description: Conditions holds the conditions for the GitRepository. + description: Conditions holds the conditions for the InternalNelmOperatorGitRepository. items: description: Condition contains details for one aspect of the current state of this API Resource. properties: @@ -978,7 +978,7 @@ spec: type: string observedGeneration: description: |- - ObservedGeneration is the last observed generation of the GitRepository + ObservedGeneration is the last observed generation of the InternalNelmOperatorGitRepository object. format: int64 type: integer @@ -989,11 +989,11 @@ spec: type: string observedInclude: description: |- - ObservedInclude is the observed list of GitRepository resources used to + ObservedInclude is the observed list of InternalNelmOperatorGitRepository resources used to produce the current Artifact. items: description: |- - GitRepositoryInclude specifies a local reference to a GitRepository which + GitRepositoryInclude specifies a local reference to a InternalNelmOperatorGitRepository which Artifact (sub-)contents must be included, and where they should be placed. properties: fromPath: @@ -1003,7 +1003,7 @@ spec: type: string repository: description: |- - GitRepositoryRef specifies the GitRepository which Artifact contents + GitRepositoryRef specifies the InternalNelmOperatorGitRepository which Artifact contents must be included. properties: name: @@ -1090,7 +1090,7 @@ spec: name: v1 schema: openAPIV3Schema: - description: HelmChart is the Schema for the helmcharts API. + description: InternalNelmOperatorHelmChart is the Schema for the helmcharts API. properties: apiVersion: description: |- @@ -1124,7 +1124,7 @@ spec: type: boolean interval: description: |- - Interval at which the HelmChart SourceRef is checked for updates. + Interval at which the InternalNelmOperatorHelmChart SourceRef is checked for updates. This interval is approximate and may be subject to jitter to ensure efficient use of resources. pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ @@ -1148,8 +1148,8 @@ spec: type: string kind: description: |- - Kind of the referent, valid values are ('HelmRepository', 'GitRepository', - 'Bucket'). + Kind of the referent, valid values are ('InternalNelmOperatorHelmRepository', 'InternalNelmOperatorGitRepository', + 'InternalNelmOperatorBucket'). enum: - InternalNelmOperatorHelmRepository - InternalNelmOperatorGitRepository @@ -1182,7 +1182,7 @@ spec: Verify contains the secret name containing the trusted public keys used to verify the signature and specifies which provider to use to check whether OCI image is authentic. - This field is only supported when using HelmRepository source with spec.type 'oci'. + This field is only supported when using InternalNelmOperatorHelmRepository source with spec.type 'oci'. Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified. properties: matchOIDCIdentity: @@ -1238,7 +1238,7 @@ spec: default: '*' description: |- Version is the chart version semver expression, ignored for charts from - GitRepository and Bucket sources. Defaults to latest when omitted. + InternalNelmOperatorGitRepository and InternalNelmOperatorBucket sources. Defaults to latest when omitted. type: string required: - chart @@ -1246,12 +1246,12 @@ spec: - sourceRef type: object x-kubernetes-validations: - - message: spec.verify is only supported when spec.sourceRef.kind is 'HelmRepository' - rule: '!has(self.verify) || self.sourceRef.kind == ''HelmRepository''' + - message: spec.verify is only supported when spec.sourceRef.kind is 'InternalNelmOperatorHelmRepository' + rule: '!has(self.verify) || self.sourceRef.kind == ''InternalNelmOperatorHelmRepository''' status: default: observedGeneration: -1 - description: HelmChartStatus records the observed state of the HelmChart. + description: HelmChartStatus records the observed state of the InternalNelmOperatorHelmChart. properties: artifact: description: Artifact represents the output of the last successful reconciliation. @@ -1300,7 +1300,7 @@ spec: - url type: object conditions: - description: Conditions holds the conditions for the HelmChart. + description: Conditions holds the conditions for the InternalNelmOperatorHelmChart. items: description: Condition contains details for one aspect of the current state of this API Resource. properties: @@ -1368,7 +1368,7 @@ spec: type: string observedGeneration: description: |- - ObservedGeneration is the last observed generation of the HelmChart + ObservedGeneration is the last observed generation of the InternalNelmOperatorHelmChart object. format: int64 type: integer @@ -1434,7 +1434,7 @@ spec: name: v1 schema: openAPIV3Schema: - description: HelmRepository is the Schema for the helmrepositories API. + description: InternalNelmOperatorHelmRepository is the Schema for the helmrepositories API. properties: apiVersion: description: |- @@ -1517,7 +1517,7 @@ spec: type: boolean interval: description: |- - Interval at which the HelmRepository URL is checked for updates. + Interval at which the InternalNelmOperatorHelmRepository URL is checked for updates. This interval is approximate and may be subject to jitter to ensure efficient use of resources. pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ @@ -1546,7 +1546,7 @@ spec: secretRef: description: |- SecretRef specifies the Secret containing authentication credentials - for the HelmRepository. + for the InternalNelmOperatorHelmRepository. For HTTP/S basic auth the secret must contain 'username' and 'password' fields. Support for TLS auth using the 'certFile' and 'keyFile', and/or 'caFile' @@ -1561,19 +1561,19 @@ spec: suspend: description: |- Suspend tells the controller to suspend the reconciliation of this - HelmRepository. + InternalNelmOperatorHelmRepository. type: boolean timeout: description: |- Timeout is used for the index fetch operation for an HTTPS helm repository, and for remote OCI Repository operations like pulling for an OCI helm - chart by the associated HelmChart. + chart by the associated InternalNelmOperatorHelmChart. Its default value is 60s. pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ type: string type: description: |- - Type of the HelmRepository. + Type of the InternalNelmOperatorHelmRepository. When this field is set to "oci", the URL field value must be prefixed with "oci://". enum: - default @@ -1591,10 +1591,10 @@ spec: status: default: observedGeneration: -1 - description: HelmRepositoryStatus records the observed state of the HelmRepository. + description: HelmRepositoryStatus records the observed state of the InternalNelmOperatorHelmRepository. properties: artifact: - description: Artifact represents the last successful HelmRepository reconciliation. + description: Artifact represents the last successful InternalNelmOperatorHelmRepository reconciliation. properties: digest: description: Digest is the digest of the file in the form of ':'. @@ -1640,7 +1640,7 @@ spec: - url type: object conditions: - description: Conditions holds the conditions for the HelmRepository. + description: Conditions holds the conditions for the InternalNelmOperatorHelmRepository. items: description: Condition contains details for one aspect of the current state of this API Resource. properties: @@ -1703,7 +1703,7 @@ spec: type: string observedGeneration: description: |- - ObservedGeneration is the last observed generation of the HelmRepository + ObservedGeneration is the last observed generation of the InternalNelmOperatorHelmRepository object. format: int64 type: integer @@ -1756,7 +1756,7 @@ spec: name: v1 schema: openAPIV3Schema: - description: OCIRepository is the Schema for the ocirepositories API + description: InternalNelmOperatorOCIRepository is the Schema for the ocirepositories API properties: apiVersion: description: |- @@ -1776,7 +1776,7 @@ spec: metadata: type: object spec: - description: OCIRepositorySpec defines the desired state of OCIRepository + description: OCIRepositorySpec defines the desired state of InternalNelmOperatorOCIRepository properties: certSecretRef: description: |- @@ -1810,7 +1810,7 @@ spec: type: boolean interval: description: |- - Interval at which the OCIRepository URL is checked for updates. + Interval at which the InternalNelmOperatorOCIRepository URL is checked for updates. This interval is approximate and may be subject to jitter to ensure efficient use of resources. pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ @@ -1988,7 +1988,7 @@ spec: status: default: observedGeneration: -1 - description: OCIRepositoryStatus defines the observed state of OCIRepository + description: OCIRepositoryStatus defines the observed state of InternalNelmOperatorOCIRepository properties: artifact: description: Artifact represents the output of the last successful OCI Repository sync. @@ -2037,7 +2037,7 @@ spec: - url type: object conditions: - description: Conditions holds the conditions for the OCIRepository. + description: Conditions holds the conditions for the InternalNelmOperatorOCIRepository. items: description: Condition contains details for one aspect of the current state of this API Resource. properties: diff --git a/tools/internalcrds/main.go b/tools/internalcrds/main.go index 7b8baefd..c5c04203 100644 --- a/tools/internalcrds/main.go +++ b/tools/internalcrds/main.go @@ -161,14 +161,15 @@ func checkKnownKind(entryName string, doc map[string]any) error { return nil } -// checkNoLeftoverUpstream fails if the rendered output still names an -// upstream flux group: Rename addresses the group by path, so a group nested -// somewhere the walk does not visit would otherwise slip through and ship -// silently unrenamed. It says nothing about kinds; checkKnownKind covers those. +// checkNoLeftoverUpstream fails if the rendered output still names an upstream +// flux group or kind: Rename addresses both by path, so one nested somewhere +// the walk does not visit would otherwise slip through and ship silently +// unrenamed. A kind that survives in a validation expression is not merely +// untidy — the rule can no longer hold against the renamed enum beside it. func checkNoLeftoverUpstream(path string, rendered []byte) error { for i, line := range strings.Split(string(rendered), "\n") { stripped := strings.ReplaceAll(line, allowedAnnotation, "") - if !strings.Contains(stripped, forbiddenGroup) { + if !strings.Contains(stripped, forbiddenGroup) && !kindWord.MatchString(stripped) { continue } diff --git a/tools/internalcrds/rename.go b/tools/internalcrds/rename.go index 0a471367..6642872d 100644 --- a/tools/internalcrds/rename.go +++ b/tools/internalcrds/rename.go @@ -19,6 +19,7 @@ package main import ( "errors" "fmt" + "regexp" "slices" "strings" ) @@ -62,10 +63,17 @@ var upstreamKinds = []string{ // running the module, and moving them would be a migration of its own. const kindPrefix = "InternalNelmOperator" +// kindWord matches an upstream kind standing on its own as a word, which is +// how the schemas refer to one in prose and in validation expressions. The +// word boundaries keep it off the type names built from a kind — a +// HelmChartStatus is upstream's own type and is not served under any name +// here — and off a renamed kind, whose prefix leaves no boundary in front. +var kindWord = regexp.MustCompile(`\b(` + strings.Join(upstreamKinds, "|") + `)\b`) + // Rename turns one upstream CustomResourceDefinition into the internal one this -// module serves. Everything it touches is addressed by path: the group, the -// names block, the object name, and the kind references inside the schemas. -// Descriptions and any other free text are left exactly as upstream wrote them. +// module serves: the group, the names block, the object name, and every +// reference to a kind inside the schemas, whether it is a value the API server +// reads or text a reader does. func Rename(doc map[string]any) error { spec, ok := doc["spec"].(map[string]any) if !ok { @@ -123,23 +131,34 @@ func Rename(doc map[string]any) error { return nil } -// renameKindReferences walks the schemas and renames upstream kind references -// it finds: under a "kind" key in a map, and, with no key to scope the match, -// any plain string list element equal to an upstream kind. Today the only -// lists it reaches are the sourceRef and chartRef kind enums, so matching by -// value alone is safe; a future field whose string entries happened to equal -// an upstream kind's name would be renamed too. +// renameKindReferences walks the schemas and renames every upstream kind it +// finds: under a "kind" key in a map; with no key to scope the match, any +// plain string list element equal to a kind; and inside the three free-text +// fields that name kinds — the documentation a reader gets from kubectl +// explain, and the message and expression of a validation rule. Today the +// only lists it reaches are the sourceRef and chartRef kind enums, so +// matching a list element by value alone is safe; a future field whose string +// entries happened to equal an upstream kind's name would be renamed too. +// +// Renaming the expression of a rule is not cosmetic: a rule comparing against +// an upstream kind can never hold once the enum beside it is renamed. func renameKindReferences(node any) { switch typed := node.(type) { case map[string]any: for key, value := range typed { - if str, ok := value.(string); ok && key == "kind" && slices.Contains(upstreamKinds, str) { - typed[key] = kindPrefix + str + str, ok := value.(string) + if !ok { + renameKindReferences(value) continue } - renameKindReferences(value) + switch { + case key == "kind" && slices.Contains(upstreamKinds, str): + typed[key] = kindPrefix + str + case key == "description", key == "message", key == "rule": + typed[key] = kindWord.ReplaceAllString(str, kindPrefix+"${1}") + } } case []any: for i, value := range typed { diff --git a/tools/internalcrds/rename_test.go b/tools/internalcrds/rename_test.go index 1fd9c87e..7b5019bd 100644 --- a/tools/internalcrds/rename_test.go +++ b/tools/internalcrds/rename_test.go @@ -155,7 +155,7 @@ func TestRenameFailsOnMissingNames(t *testing.T) { } } -func TestRenameLeavesUnrelatedStringsAlone(t *testing.T) { +func TestRenameRewritesKindNamesInProse(t *testing.T) { doc := map[string]any{ "spec": map[string]any{ "group": "source.toolkit.fluxcd.io", @@ -163,6 +163,20 @@ func TestRenameLeavesUnrelatedStringsAlone(t *testing.T) { "versions": []any{map[string]any{ "schema": map[string]any{"openAPIV3Schema": map[string]any{ "description": "HelmChart is the Schema for the helmcharts API.", + "properties": map[string]any{"spec": map[string]any{ + "properties": map[string]any{"sourceRef": map[string]any{ + "properties": map[string]any{"kind": map[string]any{ + "description": "Kind of the referent, valid values are ('HelmRepository', 'GitRepository', 'Bucket').", + }}, + }}, + "x-kubernetes-validations": []any{map[string]any{ + "message": "spec.verify is only supported when spec.sourceRef.kind is 'HelmRepository'", + "rule": "!has(self.verify) || self.sourceRef.kind == 'HelmRepository'", + }}, + }}, + "status": map[string]any{ + "description": "HelmChartStatus records the observed state of the HelmChart.", + }, }}, }}, }, @@ -173,8 +187,41 @@ func TestRenameLeavesUnrelatedStringsAlone(t *testing.T) { t.Fatalf("Rename returned %v", err) } - got := doc["spec"].(map[string]any)["versions"].([]any)[0].(map[string]any)["schema"].(map[string]any)["openAPIV3Schema"].(map[string]any)["description"] - if got != "HelmChart is the Schema for the helmcharts API." { - t.Fatalf("description was rewritten: %v", got) + schema := doc["spec"].(map[string]any)["versions"].([]any)[0].(map[string]any)["schema"].(map[string]any)["openAPIV3Schema"].(map[string]any) + specSchema := schema["properties"].(map[string]any)["spec"].(map[string]any) + validation := specSchema["x-kubernetes-validations"].([]any)[0].(map[string]any) + + cases := map[string]struct { + got any + want string + }{ + "schema description": { + schema["description"], + "InternalNelmOperatorHelmChart is the Schema for the helmcharts API.", + }, + "referent description": { + specSchema["properties"].(map[string]any)["sourceRef"].(map[string]any)["properties"].(map[string]any)["kind"].(map[string]any)["description"], + "Kind of the referent, valid values are ('InternalNelmOperatorHelmRepository', 'InternalNelmOperatorGitRepository', 'InternalNelmOperatorBucket').", + }, + "validation message": { + validation["message"], + "spec.verify is only supported when spec.sourceRef.kind is 'InternalNelmOperatorHelmRepository'", + }, + "validation rule": { + validation["rule"], + "!has(self.verify) || self.sourceRef.kind == 'InternalNelmOperatorHelmRepository'", + }, + // A composite upstream type name is not a kind and stays as upstream + // wrote it; only the kind it is named after moves. + "composite type name": { + schema["status"].(map[string]any)["description"], + "HelmChartStatus records the observed state of the InternalNelmOperatorHelmChart.", + }, + } + + for name, tc := range cases { + if tc.got != tc.want { + t.Errorf("%s = %v, want %q", name, tc.got, tc.want) + } } } From 3dce4febbf7b787336efb5b26546d95ba408fae9 Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Fri, 18 Sep 2026 13:50:28 +0300 Subject: [PATCH 16/19] test(rewriter): check the rules against the generated definitions The rule table and the definitions are two halves of one agreement, and until now nothing compared them: a changed plural, a moved version or a missing definition passed both generator guards and surfaced only as a "not found" against a live cluster. Signed-off-by: Ilya Drey --- Taskfile.yaml | 15 +- .../operatornelm/operatornelm_crds_test.go | 154 ++++++++++++++++++ 2 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 images/kube-api-rewriter/pkg/operatornelm/operatornelm_crds_test.go diff --git a/Taskfile.yaml b/Taskfile.yaml index 846387f3..98d9ae61 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -11,7 +11,9 @@ vars: # Only the modules this repository authors are listed, including tools/internalcrds. # images/kube-api-rewriter is a separate upstream module vendored in for the build, and # images/helm-controller and images/source-controller carry nothing but their werf -# files, so none of them is ours to lint, format or test here. +# files, so none of them is ours to lint, format or test here. The one exception is +# the rewriter's operatornelm package, which is this module's own rule table: its +# tests run from test:rewrite-rules below. includes: api: taskfile: ./api/Taskfile.dist.yaml @@ -138,6 +140,17 @@ tasks: - task: chart-values-controller:test:unit - task: e2e:test:unit - task: internalcrds:test:unit + - task: test:rewrite-rules + + # The rule table and the generated definitions are two halves of one + # agreement, and only a live cluster reports a disagreement: a request the + # proxy renames to a group, kind or resource type no definition declares is + # answered "not found". The test compares the two, and reads the definitions + # from outside its own module, which the test cache does not track. + test:rewrite-rules: + desc: "Check the proxy rewrite rules against the generated definitions." + cmds: + - cd images/kube-api-rewriter && go test -count=1 ./pkg/operatornelm/... test:e2e:setup: desc: "Setup environment for e2e tests." diff --git a/images/kube-api-rewriter/pkg/operatornelm/operatornelm_crds_test.go b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_crds_test.go new file mode 100644 index 00000000..48c7bd2b --- /dev/null +++ b/images/kube-api-rewriter/pkg/operatornelm/operatornelm_crds_test.go @@ -0,0 +1,154 @@ +/* +Copyright 2024 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package operatornelm + +import ( + "os" + "path/filepath" + "reflect" + "regexp" + "strings" + "testing" + + "sigs.k8s.io/yaml" +) + +// definitionsGlob finds the definitions the generator writes from upstream +// flux. They are the other half of the rules in this package: the proxy +// renames a request to a group, kind and resource type, and one of these +// declares them. A resource renamed to something no definition declares is +// not found, and nothing but a live cluster says so. +const definitionsGlob = "../../../../crds/embedded/*.yaml" + +type definition struct { + Metadata struct { + Name string `json:"name"` + } `json:"metadata"` + Spec struct { + Group string `json:"group"` + Names struct { + Kind string `json:"kind"` + ListKind string `json:"listKind"` + Plural string `json:"plural"` + Singular string `json:"singular"` + ShortNames []string `json:"shortNames"` + Categories []string `json:"categories"` + } `json:"names"` + Versions []struct { + Name string `json:"name"` + Served bool `json:"served"` + Storage bool `json:"storage"` + } `json:"versions"` + } `json:"spec"` +} + +func TestRulesMatchGeneratedDefinitions(t *testing.T) { + paths, err := filepath.Glob(definitionsGlob) + if err != nil || len(paths) == 0 { + t.Fatalf("no definitions found at %s: %v", definitionsGlob, err) + } + + separator := regexp.MustCompile(`(?m)^---$`) + + // Keyed by the name the API server knows, which is the one thing both + // sides derive independently. + definitions := make(map[string]definition) + + for _, path := range paths { + raw, err := os.ReadFile(path) + if err != nil { + t.Fatalf("%s: %v", path, err) + } + + for _, doc := range separator.Split(string(raw), -1) { + if strings.TrimSpace(doc) == "" { + continue + } + + var parsed definition + if err := yaml.Unmarshal([]byte(doc), &parsed); err != nil { + t.Fatalf("%s: %v", path, err) + } + + definitions[parsed.Metadata.Name] = parsed + } + } + + matched := make(map[string]bool, len(definitions)) + + for group, groupRule := range OperatorNelmAPIGroupsRules { + for resourceType, rule := range groupRule.ResourceRules { + name := OperatorNelmRewriteRules.ResourceTypePrefix + resourceType + "." + groupRule.GroupRule.Renamed + + parsed, ok := definitions[name] + if !ok { + t.Errorf("%s/%s is renamed to %s, which no definition declares", group, resourceType, name) + + continue + } + + matched[name] = true + + checks := map[string][2]any{ + "group": {parsed.Spec.Group, groupRule.GroupRule.Renamed}, + "kind": {parsed.Spec.Names.Kind, OperatorNelmRewriteRules.KindPrefix + rule.Kind}, + "list kind": {parsed.Spec.Names.ListKind, OperatorNelmRewriteRules.KindPrefix + rule.ListKind}, + "plural": {parsed.Spec.Names.Plural, OperatorNelmRewriteRules.ResourceTypePrefix + rule.Plural}, + "singular": {parsed.Spec.Names.Singular, OperatorNelmRewriteRules.ResourceTypePrefix + rule.Singular}, + "short names": {len(parsed.Spec.Names.ShortNames), 0}, + "categories": {len(parsed.Spec.Names.Categories), 0}, + } + + for what, pair := range checks { + if pair[0] != pair[1] { + t.Errorf("%s: %s is %v, the rule says %v", name, what, pair[0], pair[1]) + } + } + + var served []string + + storage := "" + + for _, version := range parsed.Spec.Versions { + if version.Served { + served = append(served, version.Name) + } + + if version.Storage { + storage = version.Name + } + } + + if !reflect.DeepEqual(served, rule.Versions) { + t.Errorf("%s: serves %v, the rule offers %v", name, served, rule.Versions) + } + + // The proxy answers discovery with the preferred version, so a + // definition storing a different one would have every write land + // in a conversion the module never asked for. + if storage != rule.PreferredVersion { + t.Errorf("%s: stores %q, the rule prefers %q", name, storage, rule.PreferredVersion) + } + } + } + + for name := range definitions { + if !matched[name] { + t.Errorf("%s is declared but no rule renames anything to it", name) + } + } +} From 2dfb133cdf017e652c23c08edc2a7453f4511783 Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Fri, 18 Sep 2026 13:59:08 +0300 Subject: [PATCH 17/19] chore(lint): exempt the enums upstream flux added Four fields new to helm-controller since the fork spell their values in lower case, which the module linter rejects. The exemptions naming a second version go with it: no definition serves one any more. Signed-off-by: Ilya Drey --- .dmtlint.yaml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/.dmtlint.yaml b/.dmtlint.yaml index 3e864812..4502d8d3 100644 --- a/.dmtlint.yaml +++ b/.dmtlint.yaml @@ -4,20 +4,16 @@ linters-settings: enum: - "spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.sts.properties.provider" - "spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.provider" - - "spec.versions[1].schema.openAPIV3Schema.properties.spec.properties.provider" - - "spec.versions[1].schema.openAPIV3Schema.properties.spec.properties.sts.properties.provider" - "spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.upgrade.properties.remediation.properties.strategy.properties" - "spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.uninstall.properties.deletionPropagation" - "spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.driftDetection.properties.mode" - "spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.upgrade.properties.remediation.properties.strategy" - "spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.chart.properties.spec.properties.verify.properties.provider" - "spec.versions[0].schema.openAPIV3Schema.properties.status.properties.lastAttemptedReleaseAction" - - "spec.versions[1].schema.openAPIV3Schema.properties.spec.properties.chart.properties.spec.properties.verify.properties.provider" - - "spec.versions[1].schema.openAPIV3Schema.properties.spec.properties.driftDetection.properties.mode" - - "spec.versions[1].schema.openAPIV3Schema.properties.spec.properties.postRenderers.items.properties.kustomize.properties.patchesJson6902.items.properties.patch.items.properties.op" - - "spec.versions[1].schema.openAPIV3Schema.properties.spec.properties.uninstall.properties.deletionPropagation" - - "spec.versions[1].schema.openAPIV3Schema.properties.spec.properties.upgrade.properties.remediation.properties.strategy" - - "spec.versions[1].schema.openAPIV3Schema.properties.status.properties.lastAttemptedReleaseAction" + - "spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.upgrade.properties.serverSideApply" + - "spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.rollback.properties.serverSideApply" + - "spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.waitStrategy.properties.name" + - "spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.postRenderStrategy" - "properties.logLevel" - "properties.logFormat" rbac: From aa9a1890dcc7631937a1e1f1dcd98020d25308c8 Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Fri, 18 Sep 2026 14:32:40 +0300 Subject: [PATCH 18/19] chore: resolve dmt linter issues Signed-off-by: Ilya Drey --- docs/README.ru.md | 1 - docs/RELEASE_NOTES.md | 1 - docs/RELEASE_NOTES.ru.md | 1 - templates/chart-values-controller/deployment.yaml | 4 ++-- templates/helm-controller/deployment.yaml | 4 ++-- templates/kube-api-rewriter/_sidecar_helpers.tpl | 2 +- templates/operator-helm-controller/deployment.yaml | 4 ++-- templates/source-controller/deployment.yaml | 4 ++-- 8 files changed, 9 insertions(+), 12 deletions(-) diff --git a/docs/README.ru.md b/docs/README.ru.md index eb2954f1..c6f57409 100644 --- a/docs/README.ru.md +++ b/docs/README.ru.md @@ -18,7 +18,6 @@ weight: 10 - Поддержка проверки TLS-сертификатов и аутентификации для приватных OCI и Helm репозиториев. - Управление через CLI (`d8 k`) или веб-интерфейс Deckhouse. - ## Кастомные ресурсы Для управления Helm-чартами в модуле используются следующие кастомные ресурсы: diff --git a/docs/RELEASE_NOTES.md b/docs/RELEASE_NOTES.md index 460b4413..da74f8e4 100644 --- a/docs/RELEASE_NOTES.md +++ b/docs/RELEASE_NOTES.md @@ -105,4 +105,3 @@ description: "Release notes for Deckhouse operator-helm." ### New Features * initial release with basic capabilities - diff --git a/docs/RELEASE_NOTES.ru.md b/docs/RELEASE_NOTES.ru.md index ad77d863..d7ce3d27 100644 --- a/docs/RELEASE_NOTES.ru.md +++ b/docs/RELEASE_NOTES.ru.md @@ -105,4 +105,3 @@ description: "Релизы Deckhouse operator-helm." ### Новые возможности * выпущена первоначальная версия с базовыми возможностями - diff --git a/templates/chart-values-controller/deployment.yaml b/templates/chart-values-controller/deployment.yaml index 00361d54..596a11df 100644 --- a/templates/chart-values-controller/deployment.yaml +++ b/templates/chart-values-controller/deployment.yaml @@ -5,7 +5,7 @@ cpu: 50m memory: 64Mi {{- end }} -{{- if (.Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} +{{- if (.Values.global.enabledModules | has "vertical-pod-autoscaler") }} --- apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler @@ -102,7 +102,7 @@ spec: resources: requests: {{- include "helm_lib_module_ephemeral_storage_only_logs" . | nindent 14 }} - {{- if not ( .Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} + {{- if not ( .Values.global.enabledModules | has "vertical-pod-autoscaler") }} {{- include "operator_helm_chart_values_controller_resources" . | nindent 14 }} {{- end }} env: diff --git a/templates/helm-controller/deployment.yaml b/templates/helm-controller/deployment.yaml index 1a422ed8..e986e1a8 100644 --- a/templates/helm-controller/deployment.yaml +++ b/templates/helm-controller/deployment.yaml @@ -5,7 +5,7 @@ cpu: 100m memory: 64Mi {{- end }} -{{- if (.Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} +{{- if (.Values.global.enabledModules | has "vertical-pod-autoscaler") }} --- apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler @@ -95,7 +95,7 @@ spec: resources: requests: {{- include "helm_lib_module_ephemeral_storage_only_logs" . | nindent 14 }} - {{- if not ( .Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} + {{- if not ( .Values.global.enabledModules | has "vertical-pod-autoscaler") }} {{- include "helm_controller_resources" . | nindent 14 }} {{- end }} env: diff --git a/templates/kube-api-rewriter/_sidecar_helpers.tpl b/templates/kube-api-rewriter/_sidecar_helpers.tpl index 0dda0bf0..e22b90cb 100644 --- a/templates/kube-api-rewriter/_sidecar_helpers.tpl +++ b/templates/kube-api-rewriter/_sidecar_helpers.tpl @@ -160,7 +160,7 @@ spec: resources: requests: {{- include "helm_lib_module_ephemeral_storage_only_logs" . | nindent 6 }} - {{- if not ( $ctx.Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} + {{- if not ( $ctx.Values.global.enabledModules | has "vertical-pod-autoscaler") }} {{- include "kube_api_rewriter.resources" . | nindent 6 }} {{- end }} securityContext: diff --git a/templates/operator-helm-controller/deployment.yaml b/templates/operator-helm-controller/deployment.yaml index 41a92b93..08cb7c8a 100644 --- a/templates/operator-helm-controller/deployment.yaml +++ b/templates/operator-helm-controller/deployment.yaml @@ -5,7 +5,7 @@ cpu: 50m memory: 64Mi {{- end }} -{{- if (.Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} +{{- if (.Values.global.enabledModules | has "vertical-pod-autoscaler") }} --- apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler @@ -100,7 +100,7 @@ spec: resources: requests: {{- include "helm_lib_module_ephemeral_storage_only_logs" . | nindent 14 }} - {{- if not ( .Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} + {{- if not ( .Values.global.enabledModules | has "vertical-pod-autoscaler") }} {{- include "operator_helm_controller_resources" . | nindent 14 }} {{- end }} env: diff --git a/templates/source-controller/deployment.yaml b/templates/source-controller/deployment.yaml index 8534e196..6e474708 100644 --- a/templates/source-controller/deployment.yaml +++ b/templates/source-controller/deployment.yaml @@ -5,7 +5,7 @@ cpu: 50m memory: 64Mi {{- end }} -{{- if (.Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} +{{- if (.Values.global.enabledModules | has "vertical-pod-autoscaler") }} --- apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler @@ -99,7 +99,7 @@ spec: resources: requests: {{- include "helm_lib_module_ephemeral_storage_only_logs" . | nindent 14 }} - {{- if not ( .Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} + {{- if not ( .Values.global.enabledModules | has "vertical-pod-autoscaler") }} {{- include "source_controller_resources" . | nindent 14 }} {{- end }} env: From b0e6534dbc819954de28e5e9b8048bad4efce581 Mon Sep 17 00:00:00 2001 From: Ilya Drey Date: Fri, 18 Sep 2026 14:58:21 +0300 Subject: [PATCH 19/19] fix(tools): drop the kustomize substitute annotation It instructs a real flux kustomize-controller to leave the definition alone, and nothing applies these through one. Removing it leaves no upstream identity in the output at all, so the guard no longer needs its exception. Signed-off-by: Ilya Drey --- crds/embedded/helm-controller.yaml | 1 - crds/embedded/source-controller.yaml | 6 ---- tools/internalcrds/main.go | 9 +---- tools/internalcrds/main_test.go | 6 ++-- tools/internalcrds/rename.go | 12 +++++++ tools/internalcrds/rename_test.go | 50 ++++++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 18 deletions(-) diff --git a/crds/embedded/helm-controller.yaml b/crds/embedded/helm-controller.yaml index 9974d817..eb0e03ec 100644 --- a/crds/embedded/helm-controller.yaml +++ b/crds/embedded/helm-controller.yaml @@ -4,7 +4,6 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled labels: backup.deckhouse.io/cluster-config: "true" heritage: deckhouse diff --git a/crds/embedded/source-controller.yaml b/crds/embedded/source-controller.yaml index e219d2fa..2d5f8a6f 100644 --- a/crds/embedded/source-controller.yaml +++ b/crds/embedded/source-controller.yaml @@ -4,7 +4,6 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled labels: backup.deckhouse.io/cluster-config: "true" heritage: deckhouse @@ -380,7 +379,6 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled labels: backup.deckhouse.io/cluster-config: "true" heritage: deckhouse @@ -572,7 +570,6 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled labels: backup.deckhouse.io/cluster-config: "true" heritage: deckhouse @@ -1050,7 +1047,6 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled labels: backup.deckhouse.io/cluster-config: "true" heritage: deckhouse @@ -1403,7 +1399,6 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled labels: backup.deckhouse.io/cluster-config: "true" heritage: deckhouse @@ -1725,7 +1720,6 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled labels: backup.deckhouse.io/cluster-config: "true" heritage: deckhouse diff --git a/tools/internalcrds/main.go b/tools/internalcrds/main.go index c5c04203..fed07c32 100644 --- a/tools/internalcrds/main.go +++ b/tools/internalcrds/main.go @@ -41,12 +41,6 @@ import ( // noticing. const forbiddenGroup = "toolkit.fluxcd.io" -// allowedAnnotation is the sole legitimate survivor of forbiddenGroup: a real -// annotation upstream carries on every one of these definitions, instructing a -// real flux kustomize-controller to leave the definition alone. It addresses -// that controller, not this module, so it is deliberately left unrenamed. -const allowedAnnotation = "kustomize.toolkit.fluxcd.io/substitute" - func main() { out := flag.String("out", "", "file to write the renamed definitions to") flag.Parse() @@ -168,8 +162,7 @@ func checkKnownKind(entryName string, doc map[string]any) error { // untidy — the rule can no longer hold against the renamed enum beside it. func checkNoLeftoverUpstream(path string, rendered []byte) error { for i, line := range strings.Split(string(rendered), "\n") { - stripped := strings.ReplaceAll(line, allowedAnnotation, "") - if !strings.Contains(stripped, forbiddenGroup) && !kindWord.MatchString(stripped) { + if !strings.Contains(line, forbiddenGroup) && !kindWord.MatchString(line) { continue } diff --git a/tools/internalcrds/main_test.go b/tools/internalcrds/main_test.go index 804fe835..da682437 100644 --- a/tools/internalcrds/main_test.go +++ b/tools/internalcrds/main_test.go @@ -65,10 +65,10 @@ func TestCheckNoLeftoverUpstreamFailsOnLeftoverGroup(t *testing.T) { } } -func TestCheckNoLeftoverUpstreamAllowsSubstituteAnnotation(t *testing.T) { +func TestCheckNoLeftoverUpstreamRejectsSubstituteAnnotation(t *testing.T) { rendered := "metadata:\n annotations:\n kustomize.toolkit.fluxcd.io/substitute: \"true\"\n" - if err := checkNoLeftoverUpstream("out.yaml", []byte(rendered)); err != nil { - t.Fatalf("checkNoLeftoverUpstream returned %v", err) + if err := checkNoLeftoverUpstream("out.yaml", []byte(rendered)); err == nil { + t.Fatal("expected an error, got nil") } } diff --git a/tools/internalcrds/rename.go b/tools/internalcrds/rename.go index 6642872d..56076cf0 100644 --- a/tools/internalcrds/rename.go +++ b/tools/internalcrds/rename.go @@ -119,6 +119,18 @@ func Rename(doc map[string]any) error { if !ok { return errors.New("the document has no metadata") } + // Upstream tells a real flux kustomize-controller not to substitute + // variables into these definitions. Nothing applies them through one — + // Deckhouse installs them with the module — so the instruction has no + // reader here and only leaves an upstream identity on the object. + if annotations, ok := metadata["annotations"].(map[string]any); ok { + delete(annotations, "kustomize.toolkit.fluxcd.io/substitute") + + if len(annotations) == 0 { + delete(metadata, "annotations") + } + } + metadata["name"] = names["plural"].(string) + "." + internal metadata["labels"] = map[string]any{ "backup.deckhouse.io/cluster-config": "true", diff --git a/tools/internalcrds/rename_test.go b/tools/internalcrds/rename_test.go index 7b5019bd..cb3bbe62 100644 --- a/tools/internalcrds/rename_test.go +++ b/tools/internalcrds/rename_test.go @@ -225,3 +225,53 @@ func TestRenameRewritesKindNamesInProse(t *testing.T) { } } } + +func TestRenameDropsTheSubstituteAnnotation(t *testing.T) { + doc := map[string]any{ + "spec": map[string]any{ + "group": "helm.toolkit.fluxcd.io", + "names": map[string]any{"kind": "HelmRelease", "plural": "helmreleases", "singular": "helmrelease"}, + }, + "metadata": map[string]any{ + "name": "helmreleases.helm.toolkit.fluxcd.io", + "annotations": map[string]any{ + "controller-gen.kubebuilder.io/version": "v0.21.0", + "kustomize.toolkit.fluxcd.io/substitute": "disabled", + }, + }, + } + + if err := Rename(doc); err != nil { + t.Fatalf("Rename returned %v", err) + } + + annotations := doc["metadata"].(map[string]any)["annotations"].(map[string]any) + if _, ok := annotations["kustomize.toolkit.fluxcd.io/substitute"]; ok { + t.Error("the substitute annotation survived") + } + + if annotations["controller-gen.kubebuilder.io/version"] != "v0.21.0" { + t.Errorf("unrelated annotations = %v", annotations) + } +} + +func TestRenameDropsAnEmptiedAnnotationsBlock(t *testing.T) { + doc := map[string]any{ + "spec": map[string]any{ + "group": "helm.toolkit.fluxcd.io", + "names": map[string]any{"kind": "HelmRelease", "plural": "helmreleases", "singular": "helmrelease"}, + }, + "metadata": map[string]any{ + "name": "helmreleases.helm.toolkit.fluxcd.io", + "annotations": map[string]any{"kustomize.toolkit.fluxcd.io/substitute": "disabled"}, + }, + } + + if err := Rename(doc); err != nil { + t.Fatalf("Rename returned %v", err) + } + + if _, ok := doc["metadata"].(map[string]any)["annotations"]; ok { + t.Error("an empty annotations block was left behind") + } +}