mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-11 14:36:25 +00:00
feat: helm-values manager (#5134)
This commit is contained in:
parent
515a70b206
commit
edf85d42bf
18 changed files with 582 additions and 9 deletions
|
@ -483,6 +483,19 @@ Note: you shouldn't usually need to configure this unless you really care about
|
||||||
|
|
||||||
Renovate supports updating Helm Chart references within `requirements.yaml` files. If your Helm charts make use of Aliases then you will need to configure an `aliases` object in your config to tell Renovate where to look for them.
|
Renovate supports updating Helm Chart references within `requirements.yaml` files. If your Helm charts make use of Aliases then you will need to configure an `aliases` object in your config to tell Renovate where to look for them.
|
||||||
|
|
||||||
|
## helm-values
|
||||||
|
|
||||||
|
Renovate supports updating of Docker dependencies within Helm Chart `values.yaml` files or other YAML
|
||||||
|
files that use the same format (via `fileMatch` configuration). Updates are performed if the files
|
||||||
|
follow the conventional format used in most of the `stable` Helm charts:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
image:
|
||||||
|
repository: 'some-docker/dependency'
|
||||||
|
tag: v1.0.0
|
||||||
|
registry: registry.example.com # optional key, will default to "docker.io"
|
||||||
|
```
|
||||||
|
|
||||||
## helmfile
|
## helmfile
|
||||||
|
|
||||||
## homebrew
|
## homebrew
|
||||||
|
|
|
@ -1753,6 +1753,18 @@ const options: RenovateOptions[] = [
|
||||||
mergeable: true,
|
mergeable: true,
|
||||||
cli: false,
|
cli: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'helm-values',
|
||||||
|
description: 'Configuration object for helm values.yaml files.',
|
||||||
|
stage: 'package',
|
||||||
|
type: 'object',
|
||||||
|
default: {
|
||||||
|
commitMessageTopic: 'helm values {{depName}}',
|
||||||
|
fileMatch: ['(^|/)values.yaml$'],
|
||||||
|
},
|
||||||
|
mergeable: true,
|
||||||
|
cli: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'helmfile',
|
name: 'helmfile',
|
||||||
description: 'Configuration object for helmfile helmfile.yaml files.',
|
description: 'Configuration object for helmfile helmfile.yaml files.',
|
||||||
|
|
|
@ -148,6 +148,7 @@ export interface Upgrade<T = Record<string, any>>
|
||||||
checksumUrl?: string;
|
checksumUrl?: string;
|
||||||
currentVersion?: string;
|
currentVersion?: string;
|
||||||
depGroup?: string;
|
depGroup?: string;
|
||||||
|
dockerRepository?: string;
|
||||||
downloadUrl?: string;
|
downloadUrl?: string;
|
||||||
localDir?: string;
|
localDir?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
|
60
lib/manager/helm-values/extract.ts
Normal file
60
lib/manager/helm-values/extract.ts
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import yaml from 'js-yaml';
|
||||||
|
import { logger } from '../../logger';
|
||||||
|
import { getDep } from '../dockerfile/extract';
|
||||||
|
|
||||||
|
import { PackageFile, PackageDependency } from '../common';
|
||||||
|
import {
|
||||||
|
matchesHelmValuesDockerHeuristic,
|
||||||
|
HelmDockerImageDependency,
|
||||||
|
} from './util';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively find all supported dependencies in the yaml object.
|
||||||
|
*
|
||||||
|
* @param parsedContent
|
||||||
|
*/
|
||||||
|
function findDependencies(
|
||||||
|
parsedContent: object | HelmDockerImageDependency,
|
||||||
|
packageDependencies: Array<PackageDependency>
|
||||||
|
): Array<PackageDependency> {
|
||||||
|
if (!parsedContent || typeof parsedContent !== 'object') {
|
||||||
|
return packageDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(parsedContent).forEach(key => {
|
||||||
|
if (matchesHelmValuesDockerHeuristic(key, parsedContent[key])) {
|
||||||
|
const currentItem = parsedContent[key];
|
||||||
|
|
||||||
|
const registry = currentItem.registry ? `${currentItem.registry}/` : '';
|
||||||
|
packageDependencies.push(
|
||||||
|
getDep(`${registry}${currentItem.repository}:${currentItem.tag}`)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
findDependencies(parsedContent[key], packageDependencies);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return packageDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function extractPackageFile(content: string): PackageFile {
|
||||||
|
try {
|
||||||
|
// a parser that allows extracting line numbers would be preferable, with
|
||||||
|
// the current approach we need to match anything we find again during the update
|
||||||
|
const parsedContent = yaml.safeLoad(content);
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
{ parsedContent },
|
||||||
|
'Trying to find dependencies in helm-values'
|
||||||
|
);
|
||||||
|
const deps = findDependencies(parsedContent, []);
|
||||||
|
|
||||||
|
if (deps.length) {
|
||||||
|
logger.debug({ deps }, 'Found dependencies in helm-values');
|
||||||
|
return { deps };
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
logger.error({ err }, 'Failed to parse helm-values file');
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
2
lib/manager/helm-values/index.ts
Normal file
2
lib/manager/helm-values/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export { extractPackageFile } from './extract';
|
||||||
|
export { updateDependency } from './update';
|
122
lib/manager/helm-values/update.ts
Normal file
122
lib/manager/helm-values/update.ts
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
import YAWN from 'yawn-yaml/cjs';
|
||||||
|
import { logger } from '../../logger';
|
||||||
|
import { Upgrade } from '../common';
|
||||||
|
import {
|
||||||
|
matchesHelmValuesDockerHeuristic,
|
||||||
|
HelmDockerImageDependency,
|
||||||
|
} from './util';
|
||||||
|
|
||||||
|
function shouldUpdate(
|
||||||
|
parentKey: string,
|
||||||
|
data: unknown | HelmDockerImageDependency,
|
||||||
|
dockerRepository: string,
|
||||||
|
currentValue: string,
|
||||||
|
originalRegistryValue: string
|
||||||
|
): boolean {
|
||||||
|
return (
|
||||||
|
matchesHelmValuesDockerHeuristic(parentKey, data) &&
|
||||||
|
data.repository === dockerRepository &&
|
||||||
|
data.tag === currentValue &&
|
||||||
|
((!data.registry && !originalRegistryValue) ||
|
||||||
|
data.registry === originalRegistryValue)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the originally set registry value if it is included in the depName.
|
||||||
|
*/
|
||||||
|
function getOriginalRegistryValue(
|
||||||
|
depName: string,
|
||||||
|
dockerRepository: string
|
||||||
|
): string {
|
||||||
|
if (depName.length > dockerRepository.length) {
|
||||||
|
return depName.substring(0, depName.lastIndexOf(dockerRepository) - 1);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursive function that walks the yaml strucuture
|
||||||
|
* and updates the first match of an 'image' key it finds,
|
||||||
|
* if it adheres to the supported structure.
|
||||||
|
*
|
||||||
|
* @param parsedContent The part of the yaml tree we should look at.
|
||||||
|
* @param dockerRepository The docker repository that should be updated.
|
||||||
|
* @param currentValue The current version that should be updated.
|
||||||
|
* @param newValue The update version that should be set instead of currentValue.
|
||||||
|
* @returns True if the parsedContent was updated, false otherwise.
|
||||||
|
*/
|
||||||
|
function updateDoc(
|
||||||
|
parsedContent: object | HelmDockerImageDependency,
|
||||||
|
dockerRepository: string,
|
||||||
|
currentValue: string,
|
||||||
|
newValue: string,
|
||||||
|
originalRegistryValue: string
|
||||||
|
): boolean {
|
||||||
|
for (const key of Object.keys(parsedContent)) {
|
||||||
|
if (
|
||||||
|
shouldUpdate(
|
||||||
|
key,
|
||||||
|
parsedContent[key],
|
||||||
|
dockerRepository,
|
||||||
|
currentValue,
|
||||||
|
originalRegistryValue
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// the next statement intentionally updates the passed in parameter
|
||||||
|
// with the updated dependency value
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
parsedContent[key].tag = newValue;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof parsedContent[key] === 'object') {
|
||||||
|
const foundMatch = updateDoc(
|
||||||
|
parsedContent[key],
|
||||||
|
dockerRepository,
|
||||||
|
currentValue,
|
||||||
|
newValue,
|
||||||
|
originalRegistryValue
|
||||||
|
);
|
||||||
|
if (foundMatch) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateDependency(
|
||||||
|
fileContent: string,
|
||||||
|
upgrade: Upgrade
|
||||||
|
): string | null {
|
||||||
|
if (
|
||||||
|
!upgrade ||
|
||||||
|
!upgrade.depName ||
|
||||||
|
!upgrade.newValue ||
|
||||||
|
!upgrade.currentValue ||
|
||||||
|
!upgrade.dockerRepository
|
||||||
|
) {
|
||||||
|
logger.debug('Failed to update dependency, invalid upgrade');
|
||||||
|
return fileContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
const yawn = new YAWN(fileContent);
|
||||||
|
const doc = yawn.json;
|
||||||
|
|
||||||
|
const originalRegistryValue = getOriginalRegistryValue(
|
||||||
|
upgrade.depName,
|
||||||
|
upgrade.dockerRepository
|
||||||
|
);
|
||||||
|
updateDoc(
|
||||||
|
doc,
|
||||||
|
upgrade.dockerRepository,
|
||||||
|
upgrade.currentValue,
|
||||||
|
upgrade.newValue,
|
||||||
|
originalRegistryValue
|
||||||
|
);
|
||||||
|
yawn.json = doc;
|
||||||
|
|
||||||
|
return yawn.yaml;
|
||||||
|
}
|
41
lib/manager/helm-values/util.ts
Normal file
41
lib/manager/helm-values/util.ts
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
export type HelmDockerImageDependency = {
|
||||||
|
registry?: string;
|
||||||
|
repository: string;
|
||||||
|
tag: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a workaround helper to allow the usage of 'unknown' in
|
||||||
|
* a type-guard function while checking that keys exist.
|
||||||
|
*
|
||||||
|
* @see https://github.com/microsoft/TypeScript/issues/21732
|
||||||
|
* @see https://stackoverflow.com/a/58630274
|
||||||
|
*/
|
||||||
|
function hasKey<K extends string>(k: K, o: {}): o is { [_ in K]: {} } {
|
||||||
|
return typeof o === 'object' && k in o;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type guard to determine whether a given partial Helm values.yaml object potentially
|
||||||
|
* defines a Helm Docker dependency.
|
||||||
|
*
|
||||||
|
* There is no exact standard of how Docker dependencies are defined in Helm
|
||||||
|
* values.yaml files (as of January 1st 2020), this function defines a
|
||||||
|
* heuristic based on the most commonly used format in the stable Helm charts:
|
||||||
|
*
|
||||||
|
* image:
|
||||||
|
* repository: 'something'
|
||||||
|
* tag: v1.0.0
|
||||||
|
*/
|
||||||
|
export function matchesHelmValuesDockerHeuristic(
|
||||||
|
parentKey: string,
|
||||||
|
data: unknown
|
||||||
|
): data is HelmDockerImageDependency {
|
||||||
|
return (
|
||||||
|
parentKey === 'image' &&
|
||||||
|
data &&
|
||||||
|
typeof data === 'object' &&
|
||||||
|
hasKey('repository', data) &&
|
||||||
|
hasKey('tag', data)
|
||||||
|
);
|
||||||
|
}
|
|
@ -1165,6 +1165,15 @@
|
||||||
},
|
},
|
||||||
"$ref": "#"
|
"$ref": "#"
|
||||||
},
|
},
|
||||||
|
"helm-values": {
|
||||||
|
"description": "Configuration object for helm values.yaml files.",
|
||||||
|
"type": "object",
|
||||||
|
"default": {
|
||||||
|
"commitMessageTopic": "helm values {{depName}}",
|
||||||
|
"fileMatch": ["(^|/)values.yaml$"]
|
||||||
|
},
|
||||||
|
"$ref": "#"
|
||||||
|
},
|
||||||
"helmfile": {
|
"helmfile": {
|
||||||
"description": "Configuration object for helmfile helmfile.yaml files.",
|
"description": "Configuration object for helmfile helmfile.yaml files.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`lib/manager/helm/extract extractPackageFile() parses simple requirements.yaml correctly 1`] = `
|
exports[`lib/manager/helm-requirements/extract extractPackageFile() parses simple requirements.yaml correctly 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"datasource": "helm",
|
"datasource": "helm",
|
||||||
"deps": Array [
|
"deps": Array [
|
||||||
|
@ -22,7 +22,7 @@ Object {
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`lib/manager/helm/extract extractPackageFile() resolves aliased registry urls 1`] = `
|
exports[`lib/manager/helm-requirements/extract extractPackageFile() resolves aliased registry urls 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"datasource": "helm",
|
"datasource": "helm",
|
||||||
"deps": Array [
|
"deps": Array [
|
||||||
|
@ -37,7 +37,7 @@ Object {
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`lib/manager/helm/extract extractPackageFile() skips invalid registry urls 1`] = `
|
exports[`lib/manager/helm-requirements/extract extractPackageFile() skips invalid registry urls 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"datasource": "helm",
|
"datasource": "helm",
|
||||||
"deps": Array [
|
"deps": Array [
|
||||||
|
@ -66,7 +66,7 @@ Object {
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`lib/manager/helm/extract extractPackageFile() skips local dependencies 1`] = `
|
exports[`lib/manager/helm-requirements/extract extractPackageFile() skips local dependencies 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"datasource": "helm",
|
"datasource": "helm",
|
||||||
"deps": Array [
|
"deps": Array [
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`lib/manager/helm/extract updateDependency() upgrades dependency if newValue version value is repeated 1`] = `
|
exports[`lib/manager/helm-requirements/update updateDependency() upgrades dependency if newValue version value is repeated 1`] = `
|
||||||
"
|
"
|
||||||
dependencies:
|
dependencies:
|
||||||
- version: 0.9.0
|
- version: 0.9.0
|
||||||
|
@ -12,7 +12,7 @@ exports[`lib/manager/helm/extract updateDependency() upgrades dependency if newV
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`lib/manager/helm/extract updateDependency() upgrades dependency if valid upgrade 1`] = `
|
exports[`lib/manager/helm-requirements/update updateDependency() upgrades dependency if valid upgrade 1`] = `
|
||||||
"
|
"
|
||||||
dependencies:
|
dependencies:
|
||||||
- name: redis
|
- name: redis
|
||||||
|
@ -24,7 +24,7 @@ exports[`lib/manager/helm/extract updateDependency() upgrades dependency if vali
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`lib/manager/helm/extract updateDependency() upgrades dependency if version field comes before name field 1`] = `
|
exports[`lib/manager/helm-requirements/update updateDependency() upgrades dependency if version field comes before name field 1`] = `
|
||||||
"
|
"
|
||||||
dependencies:
|
dependencies:
|
||||||
- version: 0.11.0
|
- version: 0.11.0
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { platform as _platform } from '../../../lib/platform';
|
||||||
|
|
||||||
const platform: any = _platform;
|
const platform: any = _platform;
|
||||||
|
|
||||||
describe('lib/manager/helm/extract', () => {
|
describe('lib/manager/helm-requirements/extract', () => {
|
||||||
describe('extractPackageFile()', () => {
|
describe('extractPackageFile()', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.resetAllMocks();
|
jest.resetAllMocks();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { updateDependency } from '../../../lib/manager/helm-requirements/update';
|
import { updateDependency } from '../../../lib/manager/helm-requirements/update';
|
||||||
|
|
||||||
describe('lib/manager/helm/extract', () => {
|
describe('lib/manager/helm-requirements/update', () => {
|
||||||
describe('updateDependency()', () => {
|
describe('updateDependency()', () => {
|
||||||
it('returns the same fileContent for undefined upgrade', () => {
|
it('returns the same fileContent for undefined upgrade', () => {
|
||||||
const content = `
|
const content = `
|
||||||
|
|
39
test/manager/helm-values/__snapshots__/extract.spec.ts.snap
Normal file
39
test/manager/helm-values/__snapshots__/extract.spec.ts.snap
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`lib/manager/helm-values/extract extractPackageFile() extracts from complex values file correctly" 1`] = `
|
||||||
|
Object {
|
||||||
|
"deps": Array [
|
||||||
|
Object {
|
||||||
|
"currentDigest": undefined,
|
||||||
|
"currentValue": "11.6.0-debian-9-r0",
|
||||||
|
"datasource": "docker",
|
||||||
|
"depName": "bitnami/postgresql",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"currentDigest": undefined,
|
||||||
|
"currentValue": "0.7.0-debian-9-r12",
|
||||||
|
"datasource": "docker",
|
||||||
|
"depName": "docker.io/bitnami/postgres-exporter",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"currentDigest": undefined,
|
||||||
|
"currentValue": "11.5.0-debian-9-r0",
|
||||||
|
"datasource": "docker",
|
||||||
|
"depName": "docker.io/bitnami/postgresql",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`lib/manager/helm-values/extract extractPackageFile() extracts from values.yaml correctly with same structure as "helm create" 1`] = `
|
||||||
|
Object {
|
||||||
|
"deps": Array [
|
||||||
|
Object {
|
||||||
|
"currentDigest": undefined,
|
||||||
|
"currentValue": "1.16.1",
|
||||||
|
"datasource": "docker",
|
||||||
|
"depName": "nginx",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`;
|
44
test/manager/helm-values/__snapshots__/update.spec.ts.snap
Normal file
44
test/manager/helm-values/__snapshots__/update.spec.ts.snap
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`lib/manager/helm-values/update updateDependency() upgrades correct dependency if registry included 1`] = `
|
||||||
|
"
|
||||||
|
db:
|
||||||
|
image:
|
||||||
|
image:
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
tag: 11.6.0-debian-9-r0
|
||||||
|
some-non-image-related-key: 'with-some-value'
|
||||||
|
warehouse:
|
||||||
|
image:
|
||||||
|
registry: docker.io
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
tag: 12.5.0
|
||||||
|
some-non-image-related-key: 'with-some-value'
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`lib/manager/helm-values/update updateDependency() upgrades dependency if newValue version value is repeated 1`] = `
|
||||||
|
"
|
||||||
|
db:
|
||||||
|
image:
|
||||||
|
image:
|
||||||
|
registry: docker.io
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
tag: 12.5.0
|
||||||
|
some-non-image-related-key: 'with-some-value'
|
||||||
|
warehouse:
|
||||||
|
image:
|
||||||
|
registry: docker.io
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
tag: 11.6.0-debian-9-r0
|
||||||
|
some-non-image-related-key: 'with-some-value'
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`lib/manager/helm-values/update updateDependency() upgrades dependency if valid upgrade 1`] = `
|
||||||
|
"
|
||||||
|
image:
|
||||||
|
repository: bitnami/postgres-exporter
|
||||||
|
tag: 0.8.0
|
||||||
|
"
|
||||||
|
`;
|
|
@ -0,0 +1,68 @@
|
||||||
|
# Default values for test-chart.
|
||||||
|
# This is a YAML-formatted file.
|
||||||
|
# Declare variables to be passed into your templates.
|
||||||
|
|
||||||
|
replicaCount: 1
|
||||||
|
|
||||||
|
image:
|
||||||
|
repository: nginx
|
||||||
|
tag: 1.16.1
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
imagePullSecrets: []
|
||||||
|
nameOverride: ""
|
||||||
|
fullnameOverride: ""
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
# Specifies whether a service account should be created
|
||||||
|
create: true
|
||||||
|
# The name of the service account to use.
|
||||||
|
# If not set and create is true, a name is generated using the fullname template
|
||||||
|
name:
|
||||||
|
|
||||||
|
podSecurityContext: {}
|
||||||
|
# fsGroup: 2000
|
||||||
|
|
||||||
|
securityContext: {}
|
||||||
|
# capabilities:
|
||||||
|
# drop:
|
||||||
|
# - ALL
|
||||||
|
# readOnlyRootFilesystem: true
|
||||||
|
# runAsNonRoot: true
|
||||||
|
# runAsUser: 1000
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 80
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: false
|
||||||
|
annotations: {}
|
||||||
|
# kubernetes.io/ingress.class: nginx
|
||||||
|
# kubernetes.io/tls-acme: "true"
|
||||||
|
hosts:
|
||||||
|
- host: chart-example.local
|
||||||
|
paths: []
|
||||||
|
|
||||||
|
tls: []
|
||||||
|
# - secretName: chart-example-tls
|
||||||
|
# hosts:
|
||||||
|
# - chart-example.local
|
||||||
|
|
||||||
|
resources: {}
|
||||||
|
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||||
|
# choice for the user. This also increases chances charts run on environments with little
|
||||||
|
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||||
|
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||||
|
# limits:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 128Mi
|
||||||
|
# requests:
|
||||||
|
# cpu: 100m
|
||||||
|
# memory: 128Mi
|
||||||
|
|
||||||
|
nodeSelector: {}
|
||||||
|
|
||||||
|
tolerations: []
|
||||||
|
|
||||||
|
affinity: {}
|
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
api:
|
||||||
|
image:
|
||||||
|
image:
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
tag: 11.6.0-debian-9-r0
|
||||||
|
some-non-image-related-key: 'with-some-value'
|
||||||
|
# https://github.com/helm/charts/blob/c5838636973a5546196db6e48ae46f99a55900c4/stable/postgresql/values.yaml#L426
|
||||||
|
metrics:
|
||||||
|
image:
|
||||||
|
registry: docker.io
|
||||||
|
repository: bitnami/postgres-exporter
|
||||||
|
tag: 0.7.0-debian-9-r12
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
someOtherKey:
|
||||||
|
- image:
|
||||||
|
registry: docker.io
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
tag: 11.5.0-debian-9-r0
|
||||||
|
some-non-image-related-key: 'with-some-value'
|
41
test/manager/helm-values/extract.spec.ts
Normal file
41
test/manager/helm-values/extract.spec.ts
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
|
|
||||||
|
import { extractPackageFile } from '../../../lib/manager/helm-values/extract';
|
||||||
|
|
||||||
|
const helmDefaultChartInitValues = readFileSync(
|
||||||
|
'test/manager/helm-values/_fixtures/default_chart_init_values.yaml',
|
||||||
|
'utf8'
|
||||||
|
);
|
||||||
|
|
||||||
|
const helmMultiAndNestedImageValues = readFileSync(
|
||||||
|
'test/manager/helm-values/_fixtures/multi_and_nested_image_values.yaml',
|
||||||
|
'utf8'
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('lib/manager/helm-values/extract', () => {
|
||||||
|
describe('extractPackageFile()', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetAllMocks();
|
||||||
|
});
|
||||||
|
it('returns null for invalid yaml file content', () => {
|
||||||
|
const result = extractPackageFile('nothing here: [');
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
it('returns null for empty yaml file content', () => {
|
||||||
|
const result = extractPackageFile('');
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
it('returns null for no file content', () => {
|
||||||
|
const result = extractPackageFile(null);
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
it('extracts from values.yaml correctly with same structure as "helm create"', () => {
|
||||||
|
const result = extractPackageFile(helmDefaultChartInitValues);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
it('extracts from complex values file correctly"', () => {
|
||||||
|
const result = extractPackageFile(helmMultiAndNestedImageValues);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
100
test/manager/helm-values/update.spec.ts
Normal file
100
test/manager/helm-values/update.spec.ts
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
import { updateDependency } from '../../../lib/manager/helm-values/update';
|
||||||
|
|
||||||
|
describe('lib/manager/helm-values/update', () => {
|
||||||
|
describe('updateDependency()', () => {
|
||||||
|
it('returns the same fileContent for undefined upgrade', () => {
|
||||||
|
const content = 'someKey: "someValue"';
|
||||||
|
const upgrade = undefined;
|
||||||
|
|
||||||
|
expect(updateDependency(content, upgrade)).toBe(content);
|
||||||
|
});
|
||||||
|
it('returns the same fileContent for invalid values.yaml file', () => {
|
||||||
|
const content = `
|
||||||
|
Invalid values.yaml content.
|
||||||
|
`;
|
||||||
|
const upgrade = {
|
||||||
|
depName: 'bitnami/postgres-exporter',
|
||||||
|
currentValue: '0.7.0-debian-9-r12',
|
||||||
|
datasource: 'docker',
|
||||||
|
newValue: '0.8.0',
|
||||||
|
dockerRepository: 'bitnami/postgres-exporter',
|
||||||
|
};
|
||||||
|
expect(updateDependency(content, upgrade)).toBe(content);
|
||||||
|
});
|
||||||
|
it('returns the same fileContent for empty upgrade', () => {
|
||||||
|
const content = 'someKey: "someValue"';
|
||||||
|
const upgrade = {};
|
||||||
|
expect(updateDependency(content, upgrade)).toBe(content);
|
||||||
|
});
|
||||||
|
it('returns the same fileContent for null content', () => {
|
||||||
|
const content = null;
|
||||||
|
const upgrade = {};
|
||||||
|
expect(updateDependency(content, upgrade)).toBe(content);
|
||||||
|
});
|
||||||
|
it('upgrades dependency if valid upgrade', () => {
|
||||||
|
const content = `
|
||||||
|
image:
|
||||||
|
repository: bitnami/postgres-exporter
|
||||||
|
tag: 0.7.0-debian-9-r12
|
||||||
|
`;
|
||||||
|
const upgrade = {
|
||||||
|
depName: 'bitnami/postgres-exporter',
|
||||||
|
currentValue: '0.7.0-debian-9-r12',
|
||||||
|
newValue: '0.8.0',
|
||||||
|
dockerRepository: 'bitnami/postgres-exporter',
|
||||||
|
};
|
||||||
|
expect(updateDependency(content, upgrade)).not.toBe(content);
|
||||||
|
expect(updateDependency(content, upgrade)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
it('upgrades dependency if newValue version value is repeated', () => {
|
||||||
|
const content = `
|
||||||
|
db:
|
||||||
|
image:
|
||||||
|
image:
|
||||||
|
registry: docker.io
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
tag: 11.6.0-debian-9-r0
|
||||||
|
some-non-image-related-key: 'with-some-value'
|
||||||
|
warehouse:
|
||||||
|
image:
|
||||||
|
registry: docker.io
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
tag: 11.6.0-debian-9-r0
|
||||||
|
some-non-image-related-key: 'with-some-value'
|
||||||
|
`;
|
||||||
|
const upgrade = {
|
||||||
|
depName: 'docker.io/bitnami/postgresql',
|
||||||
|
currentValue: '11.6.0-debian-9-r0',
|
||||||
|
newValue: '12.5.0',
|
||||||
|
dockerRepository: 'bitnami/postgresql',
|
||||||
|
};
|
||||||
|
expect(updateDependency(content, upgrade)).not.toBe(content);
|
||||||
|
expect(updateDependency(content, upgrade)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
it('upgrades correct dependency if registry included', () => {
|
||||||
|
const content = `
|
||||||
|
db:
|
||||||
|
image:
|
||||||
|
image:
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
tag: 11.6.0-debian-9-r0
|
||||||
|
some-non-image-related-key: 'with-some-value'
|
||||||
|
warehouse:
|
||||||
|
image:
|
||||||
|
registry: docker.io
|
||||||
|
repository: bitnami/postgresql
|
||||||
|
tag: 11.6.0-debian-9-r0
|
||||||
|
some-non-image-related-key: 'with-some-value'
|
||||||
|
`;
|
||||||
|
const upgrade = {
|
||||||
|
depName: 'docker.io/bitnami/postgresql',
|
||||||
|
currentValue: '11.6.0-debian-9-r0',
|
||||||
|
newValue: '12.5.0',
|
||||||
|
dockerRepository: 'bitnami/postgresql',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(updateDependency(content, upgrade)).not.toBe(content);
|
||||||
|
expect(updateDependency(content, upgrade)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue