Skip to content

Commit 5355320

Browse files
Merge pull request #200 from cloudogu/feature/airgapped-helm-charts
feature helm charts for airgapped gop
2 parents 1e82a50 + f5e233a commit 5355320

File tree

12 files changed

+473
-124
lines changed

12 files changed

+473
-124
lines changed

argocd/argocd/projects/cluster-resources.ftl.yaml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,19 @@ spec:
1515
server: https://kubernetes.default.svc
1616
sourceRepos:
1717
- ${scmm.baseUrl}/repo/${namePrefix}argocd/cluster-resources
18-
- https://codecentric.github.io/helm-charts
19-
- https://charts.external-secrets.io
20-
- https://helm.releases.hashicorp.com
21-
- https://kubernetes.github.io/ingress-nginx
18+
2219
<#if mirrorRepos>
2320
- ${scmm.baseUrl}/repo/3rd-party-dependencies/kube-prometheus-stack
21+
- ${scmm.baseUrl}/repo/3rd-party-dependencies/mailhog
22+
- ${scmm.baseUrl}/repo/3rd-party-dependencies/ingress-nginx
23+
- ${scmm.baseUrl}/repo/3rd-party-dependencies/external-secrets
24+
- ${scmm.baseUrl}/repo/3rd-party-dependencies/vault
2425
<#else>
2526
- https://prometheus-community.github.io/helm-charts
27+
- https://codecentric.github.io/helm-charts
28+
- https://kubernetes.github.io/ingress-nginx
29+
- https://helm.releases.hashicorp.com
30+
- https://charts.external-secrets.io
2631
</#if>
2732

2833
# allow to only see application resources from the specified namespace

scripts/downloadHelmCharts.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#!/usr/bin/env bash
22
set -o errexit -o nounset -o pipefail
33

4-
#charts=( 'monitoring' 'externalSecrets' 'vault' 'mailhog' 'ingressNginx' )
5-
charts=( 'monitoring' )
4+
charts=( 'monitoring' 'externalSecrets' 'vault' 'mailhog' 'ingressNginx')
65
APPLICATION_CONFIGURATOR_GROOVY="${1:-src/main/groovy/com/cloudogu/gitops/config/ApplicationConfigurator.groovy}"
76

87
tmpRepoFile="$(mktemp)"
@@ -17,7 +16,7 @@ for chart in "${charts[@]}"; do
1716
chart=$(echo "$chartDetails" | grep -oP "chart\s*:\s*'\K[^']+")
1817
version=$(echo "$chartDetails" | grep -oP "version\s*:\s*'\K[^']+")
1918

20-
helm repo add "$chart" "$repo" --repository-config="${tmpRepoFile}"
19+
helm repo add "$chart" "$repo" --repository-config="${tmpRepoFile}"
2120
helm pull --untar --untardir ./charts "$chart/$chart" --version "$version" --repository-config="${tmpRepoFile}"
2221
# Note that keeping charts as tgx would need only 1/10 of storage
2322
# But untaring them in groovy would need additional libraries.

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

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,42 @@ package com.cloudogu.gitops.features
33
import com.cloudogu.gitops.Feature
44
import com.cloudogu.gitops.config.Configuration
55
import com.cloudogu.gitops.features.deployment.DeploymentStrategy
6+
import com.cloudogu.gitops.utils.AirGappedUtils
67
import com.cloudogu.gitops.utils.DockerImageParser
78
import com.cloudogu.gitops.utils.FileSystemUtils
9+
import com.cloudogu.gitops.utils.K8sClient
810
import com.cloudogu.gitops.utils.MapUtils
911
import com.cloudogu.gitops.utils.TemplatingEngine
1012
import groovy.util.logging.Slf4j
1113
import groovy.yaml.YamlSlurper
1214
import io.micronaut.core.annotation.Order
1315
import jakarta.inject.Singleton
1416

17+
import java.nio.file.Path
18+
1519
@Slf4j
1620
@Singleton
1721
@Order(400)
1822
class ExternalSecretsOperator extends Feature {
1923
private Map config
2024
private FileSystemUtils fileSystemUtils
2125
private DeploymentStrategy deployer
26+
private K8sClient k8sClient
27+
private AirGappedUtils airGappedUtils
2228
static final String HELM_VALUES_PATH = 'applications/cluster-resources/secrets/external-secrets/values.ftl.yaml'
2329

2430
ExternalSecretsOperator(
2531
Configuration config,
2632
FileSystemUtils fileSystemUtils,
27-
DeploymentStrategy deployer
33+
DeploymentStrategy deployer,
34+
K8sClient k8sClient,
35+
AirGappedUtils airGappedUtils
2836
) {
2937
this.deployer = deployer
3038
this.config = config.getConfig()
3139
this.fileSystemUtils = fileSystemUtils
40+
this.k8sClient = k8sClient
41+
this.airGappedUtils = airGappedUtils
3242
}
3343

3444
@Override
@@ -82,14 +92,41 @@ class ExternalSecretsOperator extends Feature {
8292
def tmpHelmValues = fileSystemUtils.createTempFile()
8393
fileSystemUtils.writeYaml(helmValuesYaml, tmpHelmValues.toFile())
8494

85-
deployer.deployFeature(
95+
if (config.application['mirrorRepos']) {
96+
log.debug("Mirroring repos: Deploying externalSecretsOperator from local git repo")
97+
98+
def repoNamespaceAndName = airGappedUtils.mirrorHelmRepoToGit(config['features']['secrets']['externalSecrets']['helm'] as Map)
99+
100+
String externalSecretsVersion =
101+
new YamlSlurper().parse(Path.of("${config.application['localHelmChartFolder']}/${helmConfig['chart']}",
102+
'Chart.yaml'))['version']
103+
104+
deployer.deployFeature(
105+
"${scmmUri}/repo/${repoNamespaceAndName}",
106+
"external-secrets",
107+
'.',
108+
externalSecretsVersion,
109+
'secrets',
110+
'external-secrets',
111+
tmpHelmValues, DeploymentStrategy.RepoType.GIT
112+
)
113+
} else {
114+
deployer.deployFeature(
86115
helmConfig['repoURL'] as String,
87116
"externalsecretsoperator",
88117
helmConfig['chart'] as String,
89118
helmConfig['version'] as String,
90119
'secrets',
91120
'external-secrets',
92121
tmpHelmValues
93-
)
122+
)
123+
}
124+
}
125+
private URI getScmmUri() {
126+
if (config.scmm['internal']) {
127+
new URI('http://scmm-scm-manager.default.svc.cluster.local/scm')
128+
} else {
129+
new URI("${config.scmm['url']}/scm")
130+
}
94131
}
95132
}

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

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,43 @@ package com.cloudogu.gitops.features
33
import com.cloudogu.gitops.Feature
44
import com.cloudogu.gitops.config.Configuration
55
import com.cloudogu.gitops.features.deployment.DeploymentStrategy
6+
import com.cloudogu.gitops.utils.AirGappedUtils
67
import com.cloudogu.gitops.utils.FileSystemUtils
8+
import com.cloudogu.gitops.utils.K8sClient
79
import com.cloudogu.gitops.utils.MapUtils
810
import com.cloudogu.gitops.utils.TemplatingEngine
911
import groovy.util.logging.Slf4j
1012
import groovy.yaml.YamlSlurper
1113
import io.micronaut.core.annotation.Order
1214
import jakarta.inject.Singleton
1315

16+
import java.nio.file.Path
17+
1418
@Slf4j
1519
@Singleton
1620
@Order(150)
1721
class IngressNginx extends Feature {
22+
1823
static final String HELM_VALUES_PATH = "applications/cluster-resources/ingress-nginx-helm-values.ftl.yaml"
1924

2025
private Map config
2126
private FileSystemUtils fileSystemUtils
2227
private DeploymentStrategy deployer
28+
private AirGappedUtils airGappedUtils
29+
private K8sClient k8sClient
2330

2431
IngressNginx(
2532
Configuration config,
2633
FileSystemUtils fileSystemUtils,
27-
DeploymentStrategy deployer
34+
DeploymentStrategy deployer,
35+
K8sClient k8sClient,
36+
AirGappedUtils airGappedUtils
2837
) {
2938
this.deployer = deployer
3039
this.config = config.getConfig()
3140
this.fileSystemUtils = fileSystemUtils
41+
this.k8sClient = k8sClient
42+
this.airGappedUtils = airGappedUtils
3243
}
3344

3445
@Override
@@ -38,15 +49,15 @@ class IngressNginx extends Feature {
3849

3950
@Override
4051
void enable() {
41-
52+
4253
def templatedMap = new YamlSlurper().parseText(
4354
new TemplatingEngine().template(new File(HELM_VALUES_PATH),
4455
[
4556
podResources: config.application['podResources'],
4657
])) as Map
4758

4859
def valuesFromConfig = config['features']['ingressNginx']['helm']['values'] as Map
49-
60+
5061
def mergedMap = MapUtils.deepMerge(valuesFromConfig, templatedMap)
5162

5263
def tmpHelmValues = fileSystemUtils.createTempFile()
@@ -58,14 +69,40 @@ class IngressNginx extends Feature {
5869

5970
def helmConfig = config['features']['ingressNginx']['helm']
6071

61-
deployer.deployFeature(
62-
helmConfig['repoURL'] as String,
63-
'ingress-nginx',
64-
helmConfig['chart'] as String,
65-
helmConfig['version'] as String,
66-
'ingress-nginx',
67-
'ingress-nginx',
68-
tmpHelmValues)
72+
if (config.application['mirrorRepos']) {
73+
log.debug("Mirroring repos: Deploying IngressNginx from local git repo")
6974

75+
def repoNamespaceAndName = airGappedUtils.mirrorHelmRepoToGit(config['features']['ingressNginx']['helm'] as Map)
76+
77+
String ingressNginxVersion =
78+
new YamlSlurper().parse(Path.of("${config.application['localHelmChartFolder']}/${helmConfig['chart']}",
79+
'Chart.yaml'))['version']
80+
81+
deployer.deployFeature(
82+
"${scmmUri}/repo/${repoNamespaceAndName}",
83+
'ingress-nginx',
84+
'.',
85+
ingressNginxVersion,
86+
'ingress-nginx',
87+
'ingress-nginx',
88+
tmpHelmValues, DeploymentStrategy.RepoType.GIT)
89+
} else {
90+
deployer.deployFeature(
91+
helmConfig['repoURL'] as String,
92+
'ingress-nginx',
93+
helmConfig['chart'] as String,
94+
helmConfig['version'] as String,
95+
'ingress-nginx',
96+
'ingress-nginx',
97+
tmpHelmValues
98+
)
99+
}
100+
}
101+
private URI getScmmUri() {
102+
if (config.scmm['internal']) {
103+
new URI('http://scmm-scm-manager.default.svc.cluster.local/scm')
104+
} else {
105+
new URI("${config.scmm['url']}/scm")
106+
}
70107
}
71108
}

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

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@ package com.cloudogu.gitops.features
33
import com.cloudogu.gitops.Feature
44
import com.cloudogu.gitops.config.Configuration
55
import com.cloudogu.gitops.features.deployment.DeploymentStrategy
6+
import com.cloudogu.gitops.utils.AirGappedUtils
67
import com.cloudogu.gitops.utils.FileSystemUtils
8+
import com.cloudogu.gitops.utils.K8sClient
79
import com.cloudogu.gitops.utils.TemplatingEngine
810
import groovy.util.logging.Slf4j
11+
import groovy.yaml.YamlSlurper
912
import io.micronaut.core.annotation.Order
1013
import jakarta.inject.Singleton
1114
import org.springframework.security.crypto.bcrypt.BCrypt
1215

16+
import java.nio.file.Path
17+
1318
@Slf4j
1419
@Singleton
1520
@Order(200)
@@ -22,19 +27,26 @@ class Mailhog extends Feature {
2227
private String password
2328
private FileSystemUtils fileSystemUtils
2429
private DeploymentStrategy deployer
30+
private AirGappedUtils airGappedUtils
31+
private K8sClient k8sClient
2532

2633
Mailhog(
2734
Configuration config,
2835
FileSystemUtils fileSystemUtils,
29-
DeploymentStrategy deployer
36+
DeploymentStrategy deployer,
37+
K8sClient k8sClient,
38+
AirGappedUtils airGappedUtils
3039
) {
3140
this.deployer = deployer
3241
this.config = config.getConfig()
3342
this.username = this.config.application["username"]
3443
this.password = this.config.application["password"]
44+
this.k8sClient = k8sClient
3545
this.fileSystemUtils = fileSystemUtils
46+
this.airGappedUtils = airGappedUtils
3647
}
3748

49+
3850
@Override
3951
boolean isEnabled() {
4052
return config.features['mail']['mailhog']
@@ -44,25 +56,53 @@ class Mailhog extends Feature {
4456
void enable() {
4557
String bcryptMailhogPassword = BCrypt.hashpw(password, BCrypt.gensalt(4))
4658
def tmpHelmValues = new TemplatingEngine().replaceTemplate(fileSystemUtils.copyToTempDir(HELM_VALUES_PATH).toFile(), [
47-
mail: [
59+
mail : [
4860
// Note that passing the URL object here leads to problems in Graal Native image, see Git history
4961
host: config.features['mail']['mailhogUrl'] ? new URL(config.features['mail']['mailhogUrl'] as String).host : "",
5062
],
51-
image: config['features']['mail']['helm']['image'] as String,
52-
isRemote: config.application['remote'],
53-
username: username,
63+
image : config['features']['mail']['helm']['image'] as String,
64+
isRemote : config.application['remote'],
65+
username : username,
5466
passwordCrypt: bcryptMailhogPassword,
5567
podResources: config.application['podResources'],
5668
]).toPath()
5769

5870
def helmConfig = config['features']['mail']['helm']
59-
deployer.deployFeature(
60-
helmConfig['repoURL'] as String,
61-
'mailhog',
62-
helmConfig['chart'] as String,
63-
helmConfig['version'] as String,
64-
'monitoring',
65-
'mailhog',
66-
tmpHelmValues)
71+
72+
if (config.application['mirrorRepos']) {
73+
log.debug("Mirroring repos: Deploying mailhog from local git repo")
74+
75+
def repoNamespaceAndName = airGappedUtils.mirrorHelmRepoToGit(config['features']['mail']['helm'] as Map)
76+
77+
String mailhogVersion =
78+
new YamlSlurper().parse(Path.of("${config.application['localHelmChartFolder']}/${helmConfig['chart']}",
79+
'Chart.yaml'))['version']
80+
81+
deployer.deployFeature(
82+
"${scmmUri}/repo/${repoNamespaceAndName}",
83+
'mailhog',
84+
'.',
85+
mailhogVersion,
86+
'monitoring',
87+
'mailhog',
88+
tmpHelmValues, DeploymentStrategy.RepoType.GIT)
89+
} else {
90+
deployer.deployFeature(
91+
helmConfig['repoURL'] as String,
92+
'mailhog',
93+
helmConfig['chart'] as String,
94+
helmConfig['version'] as String,
95+
'monitoring',
96+
'mailhog',
97+
tmpHelmValues)
98+
}
99+
}
100+
101+
private URI getScmmUri() {
102+
if (config.scmm['internal']) {
103+
new URI('http://scmm-scm-manager.default.svc.cluster.local/scm')
104+
} else {
105+
new URI("${config.scmm['url']}/scm")
106+
}
67107
}
68108
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.cloudogu.gitops.features
33
import com.cloudogu.gitops.Feature
44
import com.cloudogu.gitops.config.Configuration
55
import com.cloudogu.gitops.features.deployment.DeploymentStrategy
6+
import com.cloudogu.gitops.utils.AirGappedUtils
67
import com.cloudogu.gitops.utils.*
78
import groovy.util.logging.Slf4j
89
import groovy.yaml.YamlSlurper
@@ -121,6 +122,7 @@ class PrometheusStack extends Feature {
121122
def helmConfig = config['features']['monitoring']['helm']
122123
setCustomImages(helmConfig, helmValuesYaml)
123124

125+
fileSystemUtils.writeYaml(helmValuesYaml, tmpHelmValues.toFile())
124126

125127
if (config.application['mirrorRepos']) {
126128
log.debug("Mirroring repos: Deploying prometheus from local git repo")
@@ -140,8 +142,7 @@ class PrometheusStack extends Feature {
140142
'kube-prometheus-stack',
141143
tmpHelmValues, RepoType.GIT)
142144
} else {
143-
fileSystemUtils.writeYaml(helmValuesYaml, tmpHelmValues.toFile())
144-
145+
145146
deployer.deployFeature(
146147
helmConfig['repoURL'] as String,
147148
'prometheusstack',

0 commit comments

Comments
 (0)