From e066924971bb0dc4ebfa0c95c919969c9eba7064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Skyler=20M=C3=A4ntysaari?= Date: Thu, 25 May 2023 19:43:36 +0300 Subject: [PATCH] feat(manager/flux): Support OCI Helm repositories (#22291) Co-authored-by: Michael Kriese --- .../flux/__fixtures__/helmOCIRelease.yaml | 16 +++++++ .../flux/__fixtures__/helmOCIRelease2.yaml | 19 ++++++++ .../flux/__fixtures__/helmOCISource.yaml | 10 +++++ .../flux/__fixtures__/helmOCISource2.yaml | 8 ++++ lib/modules/manager/flux/extract.spec.ts | 43 +++++++++++++++++++ lib/modules/manager/flux/extract.ts | 26 ++++++++++- lib/modules/manager/flux/readme.md | 4 +- lib/modules/manager/flux/types.ts | 3 ++ 8 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 lib/modules/manager/flux/__fixtures__/helmOCIRelease.yaml create mode 100644 lib/modules/manager/flux/__fixtures__/helmOCIRelease2.yaml create mode 100644 lib/modules/manager/flux/__fixtures__/helmOCISource.yaml create mode 100644 lib/modules/manager/flux/__fixtures__/helmOCISource2.yaml diff --git a/lib/modules/manager/flux/__fixtures__/helmOCIRelease.yaml b/lib/modules/manager/flux/__fixtures__/helmOCIRelease.yaml new file mode 100644 index 00000000000000..99eb6c33723aae --- /dev/null +++ b/lib/modules/manager/flux/__fixtures__/helmOCIRelease.yaml @@ -0,0 +1,16 @@ +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: arc-assets + namespace: dev +spec: + interval: 30m + chart: + spec: + chart: actions-runner-controller-charts/gha-runner-scale-set + version: 0.4.0 + sourceRef: + kind: HelmRepository + name: actions-runner-controller + namespace: flux-system + interval: 30m diff --git a/lib/modules/manager/flux/__fixtures__/helmOCIRelease2.yaml b/lib/modules/manager/flux/__fixtures__/helmOCIRelease2.yaml new file mode 100644 index 00000000000000..411497075bd0d3 --- /dev/null +++ b/lib/modules/manager/flux/__fixtures__/helmOCIRelease2.yaml @@ -0,0 +1,19 @@ +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: kyverno + namespace: flux-system +spec: + interval: 6h + releaseName: kyverno + targetNamespace: kyverno + install: + createNamespace: true + chart: + spec: + chart: kyverno + version: 2.6.0 + interval: 6h + sourceRef: + kind: HelmRepository + name: kyverno diff --git a/lib/modules/manager/flux/__fixtures__/helmOCISource.yaml b/lib/modules/manager/flux/__fixtures__/helmOCISource.yaml new file mode 100644 index 00000000000000..a96a5a406f8692 --- /dev/null +++ b/lib/modules/manager/flux/__fixtures__/helmOCISource.yaml @@ -0,0 +1,10 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: actions-runner-controller + namespace: flux-system +spec: + type: oci + interval: 30m + url: oci://ghcr.io/actions + timeout: 3m diff --git a/lib/modules/manager/flux/__fixtures__/helmOCISource2.yaml b/lib/modules/manager/flux/__fixtures__/helmOCISource2.yaml new file mode 100644 index 00000000000000..7588d8f6810f18 --- /dev/null +++ b/lib/modules/manager/flux/__fixtures__/helmOCISource2.yaml @@ -0,0 +1,8 @@ +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: kyverno + namespace: flux-system +spec: + interval: 6h + url: oci://ghcr.io/kyverno/charts diff --git a/lib/modules/manager/flux/extract.spec.ts b/lib/modules/manager/flux/extract.spec.ts index f14307c3cc62c9..2775ec92127646 100644 --- a/lib/modules/manager/flux/extract.spec.ts +++ b/lib/modules/manager/flux/extract.spec.ts @@ -728,6 +728,49 @@ describe('modules/manager/flux/extract', () => { ]); }); + it('should handle HelmRepository with type OCI', async () => { + const result = await extractAllPackageFiles(config, [ + 'lib/modules/manager/flux/__fixtures__/helmOCISource.yaml', + 'lib/modules/manager/flux/__fixtures__/helmOCIRelease.yaml', + ]); + expect(result).toEqual([ + { + deps: [ + { + currentValue: '0.4.0', + datasource: DockerDatasource.id, + depName: 'actions-runner-controller-charts/gha-runner-scale-set', + packageName: + 'ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set', + }, + ], + packageFile: + 'lib/modules/manager/flux/__fixtures__/helmOCIRelease.yaml', + }, + ]); + }); + + it('should handle HelmRepository w/o type oci and url starts with oci', async () => { + const result = await extractAllPackageFiles(config, [ + 'lib/modules/manager/flux/__fixtures__/helmOCISource2.yaml', + 'lib/modules/manager/flux/__fixtures__/helmOCIRelease2.yaml', + ]); + expect(result).toEqual([ + { + deps: [ + { + currentValue: '2.6.0', + datasource: DockerDatasource.id, + depName: 'kyverno', + packageName: 'ghcr.io/kyverno/charts/kyverno', + }, + ], + packageFile: + 'lib/modules/manager/flux/__fixtures__/helmOCIRelease2.yaml', + }, + ]); + }); + it('ignores files that do not exist', async () => { const result = await extractAllPackageFiles(config, [ 'lib/modules/manager/flux/__fixtures__/bogus.yaml', diff --git a/lib/modules/manager/flux/extract.ts b/lib/modules/manager/flux/extract.ts index a15f5aa486fba1..5713498c6999f1 100644 --- a/lib/modules/manager/flux/extract.ts +++ b/lib/modules/manager/flux/extract.ts @@ -1,8 +1,10 @@ +import is from '@sindresorhus/is'; import { loadAll } from 'js-yaml'; import { logger } from '../../../logger'; import { readLocalFile } from '../../../util/fs'; import { regEx } from '../../../util/regex'; import { BitbucketTagsDatasource } from '../../datasource/bitbucket-tags'; +import { DockerDatasource } from '../../datasource/docker'; import { GitRefsDatasource } from '../../datasource/git-refs'; import { GitTagsDatasource } from '../../datasource/git-tags'; import { GithubReleasesDatasource } from '../../datasource/github-releases'; @@ -181,7 +183,29 @@ function resolveResourceManifest( resource.metadata?.namespace) ); if (matchingRepositories.length) { - dep.registryUrls = matchingRepositories.map((repo) => repo.spec.url); + dep.registryUrls = matchingRepositories + .map((repo) => { + if ( + repo.spec.type === 'oci' || + repo.spec.url.startsWith('oci://') + ) { + // Change datasource to Docker + dep.datasource = DockerDatasource.id; + // Ensure the URL is a valid OCI path + dep.packageName = `${repo.spec.url.replace('oci://', '')}/${ + resource.spec.chart.spec.chart + }`; + return null; + } else { + return repo.spec.url; + } + }) + .filter(is.string); + + // if registryUrls is empty, delete it from dep + if (!dep.registryUrls?.length) { + delete dep.registryUrls; + } } else { dep.skipReason = 'unknown-registry'; } diff --git a/lib/modules/manager/flux/readme.md b/lib/modules/manager/flux/readme.md index f8d9b60bd96bf2..55af102a1d4998 100644 --- a/lib/modules/manager/flux/readme.md +++ b/lib/modules/manager/flux/readme.md @@ -9,8 +9,8 @@ This manager parses [Flux](https://fluxcd.io/) YAML manifests and supports: Extracts `helm` dependencies from `HelmRelease` resources. -The `flux` manager only extracts `helm` dependencies for `HelmRelease` resources linked to `HelmRepository` or `GitRepository` sources. -Renovate does not support OCI `HelmRepository` sources, those with `type: oci`. +The `flux` manager extracts `helm` dependencies for `HelmRelease` resources linked to `HelmRepository` or `GitRepository` sources. +Renovate does support OCI `HelmRepository` sources, those with `type: oci`. In addition, for the `flux` manager to properly link `HelmRelease` and `HelmRepository` resources, _both_ of the following conditions must be met: diff --git a/lib/modules/manager/flux/types.ts b/lib/modules/manager/flux/types.ts index 7b18af8fdcddb0..9895abc28b29e6 100644 --- a/lib/modules/manager/flux/types.ts +++ b/lib/modules/manager/flux/types.ts @@ -30,10 +30,13 @@ export interface HelmRelease extends KubernetesResource { }; } +export type HelmRepositoryType = 'oci' | 'default'; + export interface HelmRepository extends KubernetesResource { kind: 'HelmRepository'; spec: { url: string; + type: HelmRepositoryType; }; }