Skip to content

Commit 75a18a2

Browse files
nihussmannThomas Michael
andauthored
Adds Helm values functionality to SCM Manager and other features (#251)
* feat: add Helm values functionality to SCM Manager and other features - Introduced the `helmValues` function for SCM Manager to simplify configuration management. - Set `initialDelaySeconds` directly in values giving more time for startup. - Applied the same Helm values functionality to other features for consistency across the helm charts. * add new configuration schema * feat: add Helm values functionality to SCM Manager and other features - Introduced the `helmValues` function for SCM Manager to simplify configuration management. - Set `initialDelaySeconds` directly in values giving more time for startup. - Applied the same Helm values functionality to other features for consistency across the helm charts. --------- Co-authored-by: Thomas Michael <[email protected]>
1 parent 79080b6 commit 75a18a2

21 files changed

+271
-211
lines changed

docs/configuration.schema.json

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@
1111
},
1212
"additionalProperties" : false
1313
},
14+
"HelmConfigWithValues-nullable" : {
15+
"type" : [ "object", "null" ],
16+
"properties" : {
17+
"values" : {
18+
"$ref" : "#/$defs/Map(String,Object)-nullable",
19+
"description" : "Helm values of the chart, allows overriding defaults and setting values that are not exposed as explicit configuration"
20+
}
21+
},
22+
"additionalProperties" : false
23+
},
1424
"Map(String,Object)-nullable" : {
1525
"type" : [ "object", "null" ]
1626
},
@@ -262,6 +272,10 @@
262272
"image" : {
263273
"type" : [ "string", "null" ],
264274
"description" : "The image of the Helm chart to be installed"
275+
},
276+
"values" : {
277+
"$ref" : "#/$defs/Map(String,Object)-nullable",
278+
"description" : "Helm values of the chart, allows overriding defaults and setting values that are not exposed as explicit configuration"
265279
}
266280
},
267281
"additionalProperties" : false,
@@ -366,6 +380,10 @@
366380
"type" : [ "string", "null" ],
367381
"description" : "Sets image for external secrets operator"
368382
},
383+
"values" : {
384+
"$ref" : "#/$defs/Map(String,Object)-nullable",
385+
"description" : "Helm values of the chart, allows overriding defaults and setting values that are not exposed as explicit configuration"
386+
},
369387
"webhookImage" : {
370388
"type" : [ "string", "null" ],
371389
"description" : "Sets image for external secrets operator's webhook"
@@ -387,6 +405,10 @@
387405
"image" : {
388406
"type" : [ "string", "null" ],
389407
"description" : "Sets image for vault"
408+
},
409+
"values" : {
410+
"$ref" : "#/$defs/Map(String,Object)-nullable",
411+
"description" : "Helm values of the chart, allows overriding defaults and setting values that are not exposed as explicit configuration"
390412
}
391413
},
392414
"additionalProperties" : false,
@@ -517,8 +539,7 @@
517539
"description" : "Create image pull secrets for registry and proxy-registry for all GOP namespaces and helm charts. Uses proxy-username, read-only-username or registry-username (in this order). Use this if your cluster is not auto-provisioned with credentials for your private registries or if you configure individual helm images to be pulled from the proxy-registry that requires authentication."
518540
},
519541
"helm" : {
520-
"type" : [ "object", "null" ],
521-
"additionalProperties" : false,
542+
"$ref" : "#/$defs/HelmConfigWithValues-nullable",
522543
"description" : "Common Config parameters for the Helm package manager: Name of Chart (chart), URl of Helm-Repository (repoURL) and Chart Version (version). Note: These config is intended to obtain the chart from a different source (e.g. in air-gapped envs), not to use a different version of a helm chart. Using a different helm chart or version to the one used in the GOP version will likely cause errors."
523544
},
524545
"internalPort" : {
@@ -592,14 +613,7 @@
592613
"type" : [ "object", "null" ],
593614
"properties" : {
594615
"helm" : {
595-
"type" : [ "object", "null" ],
596-
"properties" : {
597-
"values" : {
598-
"$ref" : "#/$defs/Map(String,Object)-nullable",
599-
"description" : "Helm values of the chart, allows overriding defaults and setting values that are not exposed as explicit configuration"
600-
}
601-
},
602-
"additionalProperties" : false,
616+
"$ref" : "#/$defs/HelmConfigWithValues-nullable",
603617
"description" : "Common Config parameters for the Helm package manager: Name of Chart (chart), URl of Helm-Repository (repoURL) and Chart Version (version). Note: These config is intended to obtain the chart from a different source (e.g. in air-gapped envs), not to use a different version of a helm chart. Using a different helm chart or version to the one used in the GOP version will likely cause errors."
604618
},
605619
"password" : {

scm-manager/values.ftl.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
persistence:
22
size: 1Gi
33

4-
<#if helm.values['initialDelaySeconds']??>
4+
#increased startup time for slower devices
55
livenessProbe:
6-
initialDelaySeconds: ${helm.values.initialDelaySeconds}
7-
</#if>
6+
initialDelaySeconds: 120
7+
88

99
extraEnv: |
1010
- name: SCM_WEBAPP_INITIALUSER

src/main/groovy/com/cloudogu/gitops/Feature.groovy

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package com.cloudogu.gitops
22

3+
import com.cloudogu.gitops.utils.MapUtils
4+
import com.cloudogu.gitops.utils.TemplatingEngine
35
import groovy.util.logging.Slf4j
6+
import groovy.yaml.YamlSlurper
7+
8+
import java.nio.file.Path
49

510
/**
611
* A single tool to be deployed by GOP.
@@ -55,6 +60,16 @@ abstract class Feature {
5560
return null
5661
}
5762

63+
static Map templateToMap(String filePath, Map parameters) {
64+
def hydratedString = new TemplatingEngine().template(new File(filePath), parameters)
65+
66+
if (hydratedString.trim().isEmpty()) {
67+
// Otherwise YamlSlurper returns an empty array, whereas we expect a Map
68+
return [:]
69+
}
70+
return new YamlSlurper().parseText(hydratedString) as Map
71+
}
72+
5873
abstract boolean isEnabled()
5974

6075
/*

src/main/groovy/com/cloudogu/gitops/config/Config.groovy

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ class Config {
146146
Boolean createImagePullSecrets = false
147147

148148
@JsonPropertyDescription(HELM_CONFIG_DESCRIPTION)
149-
HelmConfig helm = new HelmConfig(
149+
HelmConfigWithValues helm = new HelmConfigWithValues(
150150
chart: 'docker-registry',
151151
repoURL: 'https://helm.twun.io',
152152
version: '2.2.3')
@@ -240,9 +240,8 @@ class Config {
240240
chart: 'scm-manager',
241241
repoURL: 'https://packages.scm-manager.org/repository/helm-v2-releases/',
242242
version: '3.2.1',
243-
values: [
244-
initialDelaySeconds: 120
245-
])
243+
values: [:]
244+
)
246245
}
247246

248247
static class ApplicationSchema {
@@ -511,7 +510,7 @@ class Config {
511510
repoURL: 'https://codecentric.github.io/helm-charts',
512511
version: '5.0.1')
513512

514-
static class MailHelmSchema extends HelmConfig {
513+
static class MailHelmSchema extends HelmConfigWithValues {
515514
@Option(names = ['--mailhog-image'], description = HELM_CONFIG_IMAGE_DESCRIPTION)
516515
@JsonPropertyDescription(HELM_CONFIG_IMAGE_DESCRIPTION)
517516
String image = 'ghcr.io/cloudogu/mailhog:v1.0.1'
@@ -589,7 +588,7 @@ class Config {
589588
repoURL: 'https://charts.external-secrets.io',
590589
version: '0.9.16'
591590
)
592-
static class ESOHelmSchema extends HelmConfig {
591+
static class ESOHelmSchema extends HelmConfigWithValues {
593592
@Option(names = ['--external-secrets-image'], description = EXTERNAL_SECRETS_IMAGE_DESCRIPTION)
594593
@JsonPropertyDescription(EXTERNAL_SECRETS_IMAGE_DESCRIPTION)
595594
String image = ''
@@ -620,7 +619,7 @@ class Config {
620619
repoURL: 'https://helm.releases.hashicorp.com',
621620
version: '0.25.0'
622621
)
623-
static class VaultHelmSchema extends HelmConfig {
622+
static class VaultHelmSchema extends HelmConfigWithValues {
624623
@Option(names = ['--vault-image'], description = VAULT_IMAGE_DESCRIPTION)
625624
@JsonPropertyDescription(VAULT_IMAGE_DESCRIPTION)
626625
String image = ''

src/main/groovy/com/cloudogu/gitops/features/CertManager.groovy

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ package com.cloudogu.gitops.features
33
import com.cloudogu.gitops.Feature
44
import com.cloudogu.gitops.FeatureWithImage
55
import com.cloudogu.gitops.config.Config
6-
76
import com.cloudogu.gitops.features.deployment.DeploymentStrategy
8-
import com.cloudogu.gitops.utils.*
7+
import com.cloudogu.gitops.utils.AirGappedUtils
8+
import com.cloudogu.gitops.utils.FileSystemUtils
9+
import com.cloudogu.gitops.utils.K8sClient
10+
import com.cloudogu.gitops.utils.MapUtils
911
import freemarker.template.DefaultObjectWrapperBuilder
1012
import groovy.util.logging.Slf4j
1113
import groovy.yaml.YamlSlurper
@@ -17,7 +19,7 @@ import java.nio.file.Path
1719
@Slf4j
1820
@Singleton
1921
@Order(160)
20-
class CertManager extends Feature implements FeatureWithImage{
22+
class CertManager extends Feature implements FeatureWithImage {
2123

2224
static final String HELM_VALUES_PATH = "applications/cluster-resources/certManager-helm-values.ftl.yaml"
2325

@@ -26,7 +28,7 @@ class CertManager extends Feature implements FeatureWithImage{
2628
private AirGappedUtils airGappedUtils
2729
final K8sClient k8sClient
2830
final Config config
29-
final String namespace ="cert-manager"
31+
final String namespace = "cert-manager"
3032

3133
CertManager(
3234
Config config,
@@ -50,22 +52,20 @@ class CertManager extends Feature implements FeatureWithImage{
5052
@Override
5153
void enable() {
5254

53-
def templatedMap = new YamlSlurper().parseText(
54-
new TemplatingEngine().template(new File(HELM_VALUES_PATH),
55-
[config: config,
56-
// Allow for using static classes inside the templates
57-
statics: new DefaultObjectWrapperBuilder(freemarker.template.Configuration.VERSION_2_3_32).build()
58-
.getStaticModels(),
59-
])) as Map
60-
55+
def templatedMap = templateToMap(HELM_VALUES_PATH,
56+
[
57+
config : config,
58+
// Allow for using static classes inside the templates
59+
statics: new DefaultObjectWrapperBuilder(freemarker.template.Configuration.VERSION_2_3_32).build()
60+
.getStaticModels(),
61+
]) as Map
6162

6263

6364
def valuesFromConfig = config.features.certManager.helm.values
6465

6566
def mergedMap = MapUtils.deepMerge(valuesFromConfig, templatedMap)
6667

67-
def tmpHelmValues = fileSystemUtils.createTempFile()
68-
fileSystemUtils.writeYaml(mergedMap, tmpHelmValues.toFile())
68+
def tempValuesPath = fileSystemUtils.writeTempFile(mergedMap)
6969

7070
def helmConfig = config.features.certManager.helm
7171
if (config.application.mirrorRepos) {
@@ -84,7 +84,7 @@ class CertManager extends Feature implements FeatureWithImage{
8484
certManagerVersion,
8585
'cert-manager',
8686
'cert-manager',
87-
tmpHelmValues, DeploymentStrategy.RepoType.GIT)
87+
tempValuesPath, DeploymentStrategy.RepoType.GIT)
8888
} else {
8989
deployer.deployFeature(
9090
helmConfig.repoURL,
@@ -93,10 +93,11 @@ class CertManager extends Feature implements FeatureWithImage{
9393
helmConfig.version,
9494
'cert-manager',
9595
'cert-manager',
96-
tmpHelmValues
96+
tempValuesPath
9797
)
9898
}
9999
}
100+
100101
private URI getScmmUri() {
101102
if (config.scmm.internal) {
102103
new URI('http://scmm-scm-manager.default.svc.cluster.local/scm')

src/main/groovy/com/cloudogu/gitops/features/ExternalSecretsOperator.groovy

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@ package com.cloudogu.gitops.features
33
import com.cloudogu.gitops.Feature
44
import com.cloudogu.gitops.FeatureWithImage
55
import com.cloudogu.gitops.config.Config
6-
76
import com.cloudogu.gitops.features.deployment.DeploymentStrategy
87
import com.cloudogu.gitops.utils.AirGappedUtils
98
import com.cloudogu.gitops.utils.FileSystemUtils
109
import com.cloudogu.gitops.utils.K8sClient
11-
import com.cloudogu.gitops.utils.TemplatingEngine
10+
import com.cloudogu.gitops.utils.MapUtils
1211
import freemarker.template.DefaultObjectWrapperBuilder
1312
import groovy.util.logging.Slf4j
1413
import groovy.yaml.YamlSlurper
@@ -21,13 +20,13 @@ import java.nio.file.Path
2120
@Singleton
2221
@Order(400)
2322
class ExternalSecretsOperator extends Feature implements FeatureWithImage {
24-
23+
2524
static final String HELM_VALUES_PATH = 'applications/cluster-resources/secrets/external-secrets/values.ftl.yaml'
26-
25+
2726
String namespace = 'secrets'
2827
Config config
2928
K8sClient k8sClient
30-
29+
3130
private FileSystemUtils fileSystemUtils
3231
private DeploymentStrategy deployer
3332
private AirGappedUtils airGappedUtils
@@ -54,15 +53,16 @@ class ExternalSecretsOperator extends Feature implements FeatureWithImage {
5453
@Override
5554
void enable() {
5655

57-
def helmConfig = config.features.secrets.externalSecrets.helm as Config.HelmConfig
58-
def helmValuesYaml = templateToMap(HELM_VALUES_PATH, [
59-
config: config,
60-
// Allow for using static classes inside the templates
61-
statics: new DefaultObjectWrapperBuilder(freemarker.template.Configuration.VERSION_2_3_32).build().getStaticModels()
62-
])
56+
def templatedMap = templateToMap(HELM_VALUES_PATH, [
57+
config : config,
58+
// Allow for using static classes inside the templates
59+
statics: new DefaultObjectWrapperBuilder(freemarker.template.Configuration.VERSION_2_3_32).build().getStaticModels()
60+
])
61+
62+
def helmConfig = config.features.secrets.externalSecrets.helm
63+
def mergedMap = MapUtils.deepMerge(helmConfig.values, templatedMap)
64+
def tempValuesPath = fileSystemUtils.writeTempFile(mergedMap)
6365

64-
def tmpHelmValues = fileSystemUtils.createTempFile()
65-
fileSystemUtils.writeYaml(helmValuesYaml, tmpHelmValues.toFile())
6666

6767
if (config.application.mirrorRepos) {
6868
log.debug("Mirroring repos: Deploying externalSecretsOperator from local git repo")
@@ -80,20 +80,21 @@ class ExternalSecretsOperator extends Feature implements FeatureWithImage {
8080
externalSecretsVersion,
8181
namespace,
8282
'external-secrets',
83-
tmpHelmValues, DeploymentStrategy.RepoType.GIT
83+
tempValuesPath, DeploymentStrategy.RepoType.GIT
8484
)
8585
} else {
8686
deployer.deployFeature(
87-
helmConfig.repoURL,
88-
"externalsecretsoperator",
89-
helmConfig.chart,
90-
helmConfig.version,
87+
helmConfig.repoURL,
88+
"externalsecretsoperator",
89+
helmConfig.chart,
90+
helmConfig.version,
9191
namespace,
92-
'external-secrets',
93-
tmpHelmValues
92+
'external-secrets',
93+
tempValuesPath
9494
)
9595
}
9696
}
97+
9798
private URI getScmmUri() {
9899
if (config.scmm.internal) {
99100
new URI('http://scmm-scm-manager.default.svc.cluster.local/scm')
@@ -102,13 +103,4 @@ class ExternalSecretsOperator extends Feature implements FeatureWithImage {
102103
}
103104
}
104105

105-
Map templateToMap(String filePath, Map parameters) {
106-
def hydratedString = new TemplatingEngine().template(new File(filePath), parameters)
107-
108-
if (hydratedString.trim().isEmpty()) {
109-
// Otherwise YamlSlurper returns an empty array, whereas we expect a Map
110-
return [:]
111-
}
112-
return new YamlSlurper().parseText(hydratedString) as Map
113-
}
114106
}

0 commit comments

Comments
 (0)