diff --git a/Jenkinsfile b/Jenkinsfile index 8e190fc44..a7e6779f5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -162,8 +162,10 @@ node('high-cpu') { images[1].push(git.tag + '-dev') images[1].push('dev') images[1].push('latest-dev') + images[1].push('main-dev') images[0].push() images[0].push('latest') + images[0].push('main') images[0].push(git.tag) currentBuild.description = createImageName(git.tag) diff --git a/applications/argocd/nginx/helm-jenkins/Jenkinsfile.ftl b/applications/argocd/nginx/helm-jenkins/Jenkinsfile.ftl index d3988686e..4812d57e7 100644 --- a/applications/argocd/nginx/helm-jenkins/Jenkinsfile.ftl +++ b/applications/argocd/nginx/helm-jenkins/Jenkinsfile.ftl @@ -2,13 +2,16 @@ String getApplication() { "nginx-helm-jenkins" } String getScmManagerCredentials() { 'scmm-user' } -String getConfigRepositoryPRBaseUrl() { env.SCMM_URL } +String getConfigRepositoryPRBaseUrl() { env.${namePrefixForEnvVars}SCMM_URL } String getConfigRepositoryPRRepo() { '${namePrefix}argocd/example-apps' } <#noparse> -String getCesBuildLibRepo() { "${env.SCMM_URL}/repo/3rd-party-dependencies/ces-build-lib/" } + +String getCesBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/ces-build-lib/" } +String getGitOpsBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/gitops-build-lib" } + String getCesBuildLibVersion() { '2.5.0' } -String getGitOpsBuildLibRepo() { "${env.SCMM_URL}/repo/3rd-party-dependencies/gitops-build-lib" } String getGitOpsBuildLibVersion() { '0.7.0'} + String getHelmChartRepository() { "https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami" } String getHelmChartName() { "nginx" } String getHelmChartVersion() { "13.2.21" } @@ -104,4 +107,4 @@ node('docker') { def cesBuildLib def gitOpsBuildLib -</#noparse> +</#noparse> \ No newline at end of file diff --git a/applications/argocd/petclinic/helm/Jenkinsfile.ftl b/applications/argocd/petclinic/helm/Jenkinsfile.ftl index 5972ee7b6..7636950cf 100644 --- a/applications/argocd/petclinic/helm/Jenkinsfile.ftl +++ b/applications/argocd/petclinic/helm/Jenkinsfile.ftl @@ -2,7 +2,7 @@ String getApplication() { "spring-petclinic-helm" } String getScmManagerCredentials() { 'scmm-user' } -String getConfigRepositoryPRBaseUrl() { env.SCMM_URL } +String getConfigRepositoryPRBaseUrl() { env.${namePrefixForEnvVars}SCMM_URL } String getConfigRepositoryPRRepo() { '${namePrefix}argocd/example-apps' } String getDockerRegistryBaseUrl() { env.${namePrefixForEnvVars}REGISTRY_URL } @@ -15,11 +15,12 @@ String getDockerRegistryProxyCredentials() { 'registry-proxy-user' } </#if> <#noparse> -String getCesBuildLibRepo() { "${env.SCMM_URL}/repo/3rd-party-dependencies/ces-build-lib/" } + +String getCesBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/ces-build-lib/" } String getCesBuildLibVersion() { '2.5.0' } -String getGitOpsBuildLibRepo() { "${env.SCMM_URL}/repo/3rd-party-dependencies/gitops-build-lib" } +String getGitOpsBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/gitops-build-lib" } String getGitOpsBuildLibVersion() { '0.7.0'} -String getHelmChartRepository() { "${env.SCMM_URL}/repo/3rd-party-dependencies/spring-boot-helm-chart-with-dependency" } +String getHelmChartRepository() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/spring-boot-helm-chart-with-dependency" } String getHelmChartVersion() { "1.0.0" } String getMainBranch() { 'main' } @@ -196,4 +197,4 @@ String createImageTag() { def cesBuildLib def gitOpsBuildLib -</#noparse> +</#noparse> \ No newline at end of file diff --git a/applications/argocd/petclinic/plain-k8s/Jenkinsfile.ftl b/applications/argocd/petclinic/plain-k8s/Jenkinsfile.ftl index d95821f14..7558ee98a 100644 --- a/applications/argocd/petclinic/plain-k8s/Jenkinsfile.ftl +++ b/applications/argocd/petclinic/plain-k8s/Jenkinsfile.ftl @@ -3,7 +3,7 @@ String getApplication() { 'spring-petclinic-plain' } String getConfigRepositoryPRRepo() { '${namePrefix}argocd/example-apps' } String getScmManagerCredentials() { 'scmm-user' } -String getConfigRepositoryPRBaseUrl() { env.SCMM_URL } +String getConfigRepositoryPRBaseUrl() { env.${namePrefixForEnvVars}SCMM_URL } String getDockerRegistryBaseUrl() { env.${namePrefixForEnvVars}REGISTRY_URL } String getDockerRegistryPath() { env.${namePrefixForEnvVars}REGISTRY_PATH } @@ -15,9 +15,11 @@ String getDockerRegistryProxyCredentials() { 'registry-proxy-user' } </#if> <#noparse> -String getCesBuildLibRepo() { "${env.SCMM_URL}/repo/3rd-party-dependencies/ces-build-lib" } + +String getCesBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/ces-build-lib/" } +String getGitOpsBuildLibRepo() { configRepositoryPRBaseUrl+"/repo/3rd-party-dependencies/gitops-build-lib" } + String getCesBuildLibVersion() { '2.5.0' } -String getGitOpsBuildLibRepo() { "${env.SCMM_URL}/repo/3rd-party-dependencies/gitops-build-lib" } String getGitOpsBuildLibVersion() { '0.7.0'} loadLibraries() @@ -229,4 +231,4 @@ def loadLibraries() { def cesBuildLib def gitOpsBuildLib -</#noparse> +</#noparse> \ No newline at end of file diff --git a/applications/cluster-resources/monitoring/netpols/prometheus-allow-scraping.ftl.yaml b/applications/cluster-resources/monitoring/netpols/prometheus-allow-scraping.ftl.yaml index d78949111..faca308cd 100644 --- a/applications/cluster-resources/monitoring/netpols/prometheus-allow-scraping.ftl.yaml +++ b/applications/cluster-resources/monitoring/netpols/prometheus-allow-scraping.ftl.yaml @@ -9,7 +9,7 @@ spec: - from: - namespaceSelector: matchLabels: - kubernetes.io/metadata.name: ${namePrefix}monitoring + kubernetes.io/metadata.name: "${namePrefix}monitoring" podSelector: matchLabels: prometheus: kube-prometheus-stack-prometheus \ No newline at end of file diff --git a/argocd/argocd/operator/rbac/example-apps-production.yaml b/argocd/argocd/operator/rbac/example-apps-production.yaml index 3b4cf03af..4711830c8 100644 --- a/argocd/argocd/operator/rbac/example-apps-production.yaml +++ b/argocd/argocd/operator/rbac/example-apps-production.yaml @@ -1,7 +1,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - namespace: example-apps-production + namespace: "${namePrefix}example-apps-production" name: argocd rules: - apiGroups: @@ -166,7 +166,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: argocd - namespace: example-apps-production + namespace: "${namePrefix}example-apps-production" subjects: - kind: ServiceAccount name: argocd-argocd-server @@ -180,4 +180,4 @@ subjects: roleRef: kind: Role name: argocd - apiGroup: rbac.authorization.k8s.io + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/argocd/argocd/operator/rbac/example-apps-staging.yaml b/argocd/argocd/operator/rbac/example-apps-staging.yaml index 55cb14b7a..02b55934c 100644 --- a/argocd/argocd/operator/rbac/example-apps-staging.yaml +++ b/argocd/argocd/operator/rbac/example-apps-staging.yaml @@ -1,7 +1,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - namespace: example-apps-staging + namespace: "${namePrefix}example-apps-staging" name: argocd rules: - apiGroups: @@ -166,7 +166,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: argocd - namespace: example-apps-staging + namespace: "${namePrefix}example-apps-staging" subjects: - kind: ServiceAccount name: argocd-argocd-server @@ -180,4 +180,4 @@ subjects: roleRef: kind: Role name: argocd - apiGroup: rbac.authorization.k8s.io + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/argocd/argocd/operator/rbac/ingress-nginx.yaml b/argocd/argocd/operator/rbac/ingress-nginx.yaml index 1898c08f0..e2dc3f442 100644 --- a/argocd/argocd/operator/rbac/ingress-nginx.yaml +++ b/argocd/argocd/operator/rbac/ingress-nginx.yaml @@ -1,7 +1,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - namespace: ingress-nginx + namespace: "${namePrefix}ingress-nginx" name: argocd rules: - apiGroups: @@ -166,7 +166,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: argocd - namespace: ingress-nginx + namespace: "${namePrefix}ingress-nginx" subjects: - kind: ServiceAccount name: argocd-argocd-server @@ -180,4 +180,4 @@ subjects: roleRef: kind: Role name: argocd - apiGroup: rbac.authorization.k8s.io + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/argocd/argocd/operator/rbac/monitoring.yaml b/argocd/argocd/operator/rbac/monitoring.yaml index 97a145c6a..20a5850fc 100644 --- a/argocd/argocd/operator/rbac/monitoring.yaml +++ b/argocd/argocd/operator/rbac/monitoring.yaml @@ -1,7 +1,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - namespace: monitoring + namespace: "${namePrefix}monitoring" name: argocd rules: - apiGroups: @@ -166,7 +166,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: argocd - namespace: monitoring + namespace: "${namePrefix}monitoring" subjects: - kind: ServiceAccount name: argocd-argocd-server @@ -180,4 +180,4 @@ subjects: roleRef: kind: Role name: argocd - apiGroup: rbac.authorization.k8s.io + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/argocd/argocd/operator/rbac/secrets.yaml b/argocd/argocd/operator/rbac/secrets.yaml index 4d8cfd54f..e99bd265e 100644 --- a/argocd/argocd/operator/rbac/secrets.yaml +++ b/argocd/argocd/operator/rbac/secrets.yaml @@ -1,7 +1,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - namespace: secrets + namespace: "${namePrefix}secrets" name: argocd rules: - apiGroups: @@ -166,7 +166,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: argocd - namespace: secrets + namespace: "${namePrefix}secrets" subjects: - kind: ServiceAccount name: argocd-argocd-server @@ -180,4 +180,4 @@ subjects: roleRef: kind: Role name: argocd - apiGroup: rbac.authorization.k8s.io + apiGroup: rbac.authorization.k8s.io \ No newline at end of file diff --git a/scripts/init-cluster.sh b/scripts/init-cluster.sh index 3a6307701..22e3bc634 100755 --- a/scripts/init-cluster.sh +++ b/scripts/init-cluster.sh @@ -275,4 +275,4 @@ function echoHightlighted() { fi } -main "$@" +main "$@" \ No newline at end of file diff --git a/scripts/jenkins/init-jenkins.sh b/scripts/jenkins/init-jenkins.sh index e487eb8d0..bd4c69144 100755 --- a/scripts/jenkins/init-jenkins.sh +++ b/scripts/jenkins/init-jenkins.sh @@ -21,7 +21,7 @@ fi function initJenkins() { if [[ ${INTERNAL_JENKINS} == true ]]; then - setExternalHostnameIfNecessary "JENKINS" "jenkins" "default" + setExternalHostnameIfNecessary "JENKINS" "jenkins" "${NAME_PREFIX}jenkins" fi installPlugins diff --git a/scripts/scm-manager/init-scmm.sh b/scripts/scm-manager/init-scmm.sh index 3177774b8..7a4e9b92b 100755 --- a/scripts/scm-manager/init-scmm.sh +++ b/scripts/scm-manager/init-scmm.sh @@ -26,7 +26,7 @@ function initSCMM() { echo "SCM provider: ${SCM_PROVIDER}" if [[ ${INTERNAL_SCMM} == true ]]; then - setExternalHostnameIfNecessary 'SCMM' 'scmm-scm-manager' 'default' + setExternalHostnameIfNecessary 'SCMM' 'scmm-scm-manager' "${NAME_PREFIX}scm-manager" fi [[ "${SCMM_URL}" != *scm ]] && SCMM_URL=${SCMM_URL}/scm diff --git a/src/main/groovy/com/cloudogu/gitops/Application.groovy b/src/main/groovy/com/cloudogu/gitops/Application.groovy index 0126dc50e..2e45e8afc 100644 --- a/src/main/groovy/com/cloudogu/gitops/Application.groovy +++ b/src/main/groovy/com/cloudogu/gitops/Application.groovy @@ -12,12 +12,11 @@ class Application { final Config config Application(Config config, - List<Feature> features + List<Feature> features ) { - this.config=config + this.config = config // Order is important. Enforced by @Order-Annotation on the Singletons this.features = features - } def start() { @@ -36,15 +35,10 @@ class Application { void setNamespaceListToConfig(Config config) { Set<String> namespaces = new HashSet<>() - String namePrefix = config.application.namePrefix; + String namePrefix = config.application.namePrefix - if(config.registry.internal || config.scmm.internal || config.jenkins.internal){ - namespaces.add(namePrefix + "default") - } - if (config.features.argocd.active) { namespaces.addAll(Arrays.asList( - namePrefix + "argocd", namePrefix + "example-apps-staging", namePrefix + "example-apps-production" )) @@ -55,14 +49,9 @@ class Application { .collect { it.activeNamespaceFromFeature } .findAll { it } .unique() - .collect { "${namePrefix}${it}".toString() }) - - //TODO remove after Jenkins/SCMM/Registry got their own namespaces - if(config.application.openshift){ - namespaces.remove(namePrefix + "default") - } + .collect { "${it}".toString() }) log.debug("Active namespaces retrieved: {}", namespaces); config.application.activeNamespaces = namespaces.toList() } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/FeatureWithImage.groovy b/src/main/groovy/com/cloudogu/gitops/FeatureWithImage.groovy index 20bc7df97..c3236104b 100644 --- a/src/main/groovy/com/cloudogu/gitops/FeatureWithImage.groovy +++ b/src/main/groovy/com/cloudogu/gitops/FeatureWithImage.groovy @@ -15,12 +15,12 @@ trait FeatureWithImage { void createImagePullSecret() { if (config.registry.createImagePullSecrets) { - log.trace("Creating image pull secret 'proxy-registry' in namespace ${namespace}") + log.trace("Creating image pull secret 'proxy-registry' in namespace ${this.namespace}") String url = config.registry.proxyUrl ?: config.registry.url String user = config.registry.proxyUsername ?: config.registry.readOnlyUsername ?: config.registry.username String password = config.registry.proxyPassword ?: config.registry.readOnlyPassword ?: config.registry.password - k8sClient.createNamespace(namespace) + k8sClient.createNamespace(this.namespace) k8sClient.createImagePullSecret('proxy-registry', namespace, url, user, password) } } diff --git a/src/main/groovy/com/cloudogu/gitops/cli/GitopsPlaygroundCliMainScripted.groovy b/src/main/groovy/com/cloudogu/gitops/cli/GitopsPlaygroundCliMainScripted.groovy index bb62f9595..63c9b7367 100644 --- a/src/main/groovy/com/cloudogu/gitops/cli/GitopsPlaygroundCliMainScripted.groovy +++ b/src/main/groovy/com/cloudogu/gitops/cli/GitopsPlaygroundCliMainScripted.groovy @@ -19,7 +19,8 @@ import com.cloudogu.gitops.scmm.ScmmRepoProvider import com.cloudogu.gitops.utils.* import groovy.util.logging.Slf4j import io.micronaut.context.ApplicationContext -import jakarta.inject.Provider +import jakarta.inject.Provider + /** * Micronaut's dependency injection relies on statically compiled class files with seems incompatible with groovy * scripting/interpretation (without prior compilation). @@ -52,7 +53,7 @@ class GitopsPlaygroundCliMainScripted { def helmClient = new HelmClient(executor) def httpClientFactory = new HttpClientFactory() - + def scmmRepoProvider = new ScmmRepoProvider(config, fileSystemUtils) def retrofitFactory = new RetrofitFactory() @@ -72,7 +73,7 @@ class GitopsPlaygroundCliMainScripted { httpClientFactory.okHttpClient(httpClientFactory.createLoggingInterceptor(), jenkinsConfiguration, insecureSslContextProvider)) context.registerSingleton(k8sClient) - + if (config.application.destroy) { context.registerSingleton(new Destroyer([ new ArgoCDDestructionHandler(config, k8sClient, scmmRepoProvider, helmClient, fileSystemUtils), @@ -86,9 +87,9 @@ class GitopsPlaygroundCliMainScripted { def airGappedUtils = new AirGappedUtils(config, scmmRepoProvider, repoApi, fileSystemUtils, helmClient) - context.registerSingleton(new Application(config,[ + context.registerSingleton(new Application(config, [ new Registry(config, fileSystemUtils, k8sClient, helmStrategy), - new ScmManager(config, executor, fileSystemUtils, helmStrategy), + new ScmManager(config, executor, fileSystemUtils, helmStrategy, k8sClient), new Jenkins(config, executor, fileSystemUtils, new GlobalPropertyManager(jenkinsApiClient), new JobManager(jenkinsApiClient), new UserManager(jenkinsApiClient), new PrometheusConfigurator(jenkinsApiClient), helmStrategy, k8sClient), @@ -104,4 +105,4 @@ class GitopsPlaygroundCliMainScripted { } } } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/config/ApplicationConfigurator.groovy b/src/main/groovy/com/cloudogu/gitops/config/ApplicationConfigurator.groovy index 7de61cba5..3cf2cbb51 100644 --- a/src/main/groovy/com/cloudogu/gitops/config/ApplicationConfigurator.groovy +++ b/src/main/groovy/com/cloudogu/gitops/config/ApplicationConfigurator.groovy @@ -24,10 +24,11 @@ class ApplicationConfigurator { addAdditionalApplicationConfig(newConfig) + addNamePrefix(newConfig) + addScmmConfig(newConfig) - addJenkinsConfig(newConfig) - addNamePrefix(newConfig) + addJenkinsConfig(newConfig) addRegistryConfig(newConfig) @@ -113,12 +114,13 @@ class ApplicationConfigurator { newConfig.scmm.urlForJenkins = newConfig.scmm.url } else if (newConfig.application.runningInsideK8s) { log.debug("Setting scmm url to k8s service, since installation is running inside k8s") - newConfig.scmm.url = networkingUtils.createUrl("scmm-scm-manager.default.svc.cluster.local", "80", "/scm") + newConfig.scmm.url = networkingUtils.createUrl("scmm-scm-manager.${newConfig.application.namePrefix}scm-manager.svc.cluster.local", "80", "/scm") } else { log.debug("Setting internal configs for local single node cluster with internal scmm") def port = fileSystemUtils.getLineFromFile(fileSystemUtils.getRootDir() + "/scm-manager/values.ftl.yaml", "nodePort:").findAll(/\d+/)*.toString().get(0) String clusterBindAddress = networkingUtils.findClusterBindAddress() newConfig.scmm.url = networkingUtils.createUrl(clusterBindAddress, port, "/scm") + newConfig.scmm.urlForJenkins = "http://scmm-scm-manager.${newConfig.application.namePrefix}scm-manager.svc.cluster.local/scm" } String scmmUrl = newConfig.scmm.url @@ -150,12 +152,13 @@ class ApplicationConfigurator { newConfig.jenkins.urlForScmm = newConfig.jenkins.url } else if (newConfig.application.runningInsideK8s) { log.debug("Setting jenkins url to k8s service, since installation is running inside k8s") - newConfig.jenkins.url = networkingUtils.createUrl("jenkins.default.svc.cluster.local", "80") + newConfig.jenkins.url = networkingUtils.createUrl("jenkins.${newConfig.application.namePrefix}jenkins.svc.cluster.local", "80") } else { log.debug("Setting jenkins configs for local single node cluster with internal jenkins") def port = fileSystemUtils.getLineFromFile(fileSystemUtils.getRootDir() + "/jenkins/values.ftl.yaml", "nodePort:").findAll(/\d+/)*.toString().get(0) String clusterBindAddress = networkingUtils.findClusterBindAddress() newConfig.jenkins.url = networkingUtils.createUrl(clusterBindAddress, port) + newConfig.jenkins.urlForScmm = "http://jenkins.${newConfig.application.namePrefix}jenkins.svc.cluster.local" } if (newConfig.application.baseUrl) { @@ -346,4 +349,4 @@ class ApplicationConfigurator { } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/config/Config.groovy b/src/main/groovy/com/cloudogu/gitops/config/Config.groovy index cc3d90e64..db58ee86c 100644 --- a/src/main/groovy/com/cloudogu/gitops/config/Config.groovy +++ b/src/main/groovy/com/cloudogu/gitops/config/Config.groovy @@ -748,4 +748,4 @@ class Config { new YAMLMapper() } } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/features/CertManager.groovy b/src/main/groovy/com/cloudogu/gitops/features/CertManager.groovy index 50fdd4b1c..2b89729af 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/CertManager.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/CertManager.groovy @@ -28,7 +28,7 @@ class CertManager extends Feature implements FeatureWithImage { private AirGappedUtils airGappedUtils final K8sClient k8sClient final Config config - final String namespace = "cert-manager" + final String namespace = "${config.application.namePrefix}cert-manager" CertManager( Config config, @@ -82,7 +82,7 @@ class CertManager extends Feature implements FeatureWithImage { 'cert-manager', '.', certManagerVersion, - 'cert-manager', + namespace, 'cert-manager', tempValuesPath, DeploymentStrategy.RepoType.GIT) } else { @@ -91,7 +91,7 @@ class CertManager extends Feature implements FeatureWithImage { 'cert-manager', helmConfig.chart, helmConfig.version, - 'cert-manager', + namespace, 'cert-manager', tempValuesPath ) @@ -100,10 +100,10 @@ class CertManager extends Feature implements FeatureWithImage { private URI getScmmUri() { if (config.scmm.internal) { - new URI('http://scmm-scm-manager.default.svc.cluster.local/scm') + new URI("http://scmm-scm-manager.${config.application.namePrefix}scm-manager.svc.cluster.local/scm") } else { new URI("${config.scmm.url}") } } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/features/Content.groovy b/src/main/groovy/com/cloudogu/gitops/features/Content.groovy index dbf15e6f2..ec63ae033 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/Content.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/Content.groovy @@ -36,13 +36,12 @@ class Content extends Feature { String registryUsername = config.registry.readOnlyUsername ?: config.registry.username String registryPassword = config.registry.readOnlyPassword ?: config.registry.password - // Name prefix is added by k8sClient List exampleAppNamespaces = [ "example-apps-staging", "example-apps-production"] exampleAppNamespaces.each { - def namespace = it + String namespace = "${config.application.namePrefix}${it}" def registrySecretName = 'registry' - k8sClient.createNamespace(it) + k8sClient.createNamespace(namespace) k8sClient.createImagePullSecret(registrySecretName, namespace, config.registry.url /* Only domain matters, path would be ignored */, @@ -59,4 +58,4 @@ class Content extends Feature { } } } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/features/ExternalSecretsOperator.groovy b/src/main/groovy/com/cloudogu/gitops/features/ExternalSecretsOperator.groovy index 065e84e9f..35d493952 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/ExternalSecretsOperator.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/ExternalSecretsOperator.groovy @@ -23,7 +23,7 @@ class ExternalSecretsOperator extends Feature implements FeatureWithImage { static final String HELM_VALUES_PATH = 'applications/cluster-resources/secrets/external-secrets/values.ftl.yaml' - String namespace = 'secrets' + String namespace = "${config.application.namePrefix}secrets" Config config K8sClient k8sClient @@ -97,10 +97,10 @@ class ExternalSecretsOperator extends Feature implements FeatureWithImage { private URI getScmmUri() { if (config.scmm.internal) { - new URI('http://scmm-scm-manager.default.svc.cluster.local/scm') + new URI("http://scmm-scm-manager.${config.application.namePrefix}scm-manager.svc.cluster.local/scm") } else { new URI("${config.scmm.url}") } } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/features/IngressNginx.groovy b/src/main/groovy/com/cloudogu/gitops/features/IngressNginx.groovy index 70a0e2710..6cafaf53d 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/IngressNginx.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/IngressNginx.groovy @@ -23,7 +23,7 @@ class IngressNginx extends Feature implements FeatureWithImage { static final String HELM_VALUES_PATH = "applications/cluster-resources/ingress-nginx-helm-values.ftl.yaml" - String namespace = 'ingress-nginx' + String namespace = "${config.application.namePrefix}ingress-nginx" Config config K8sClient k8sClient @@ -95,9 +95,9 @@ class IngressNginx extends Feature implements FeatureWithImage { private URI getScmmUri() { if (config.scmm.internal) { - new URI('http://scmm-scm-manager.default.svc.cluster.local/scm') + new URI("http://scmm-scm-manager.${config.application.namePrefix}scm-manager.svc.cluster.local/scm") } else { new URI("${config.scmm.url}") } } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/features/Jenkins.groovy b/src/main/groovy/com/cloudogu/gitops/features/Jenkins.groovy index b1d761d96..103f22acb 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/Jenkins.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/Jenkins.groovy @@ -25,7 +25,7 @@ class Jenkins extends Feature { static final String HELM_VALUES_PATH = "jenkins/values.ftl.yaml" - String namespace = 'default' + String namespace = "${config.application.namePrefix}jenkins" private Config config private CommandExecutor commandExecutor @@ -69,6 +69,9 @@ class Jenkins extends Feature { void enable() { if (config.jenkins.internal) { + + k8sClient.createNamespace(namespace) + // Mark the first node for Jenkins and agents. See jenkins/values.ftl.yaml "agent.workingDir" for details. // Remove first (in case new nodes were added) k8sClient.labelRemove('node', '--all', '', 'node') @@ -113,7 +116,6 @@ class Jenkins extends Feature { JENKINS_PASSWORD : config.jenkins.password, // Used indirectly in utils.sh 😬 REMOTE_CLUSTER : config.application.remote, - //TODO SCMM wording SCM? SCMM_URL : config.scmm.urlForJenkins, SCMM_PASSWORD : config.scmm.password, SCM_PROVIDER : config.scmm.provider, @@ -123,7 +125,7 @@ class Jenkins extends Feature { ]) - globalPropertyManager.setGlobalProperty('SCMM_URL', config.scmm.url) + globalPropertyManager.setGlobalProperty("${config.application.namePrefixForEnvVars}SCMM_URL", config.scmm.urlForJenkins) if (config.jenkins.additionalEnvs) { for (entry in (config.jenkins.additionalEnvs as Map).entrySet()) { @@ -162,7 +164,6 @@ class Jenkins extends Feature { if (config.features.argocd.active) { String jobName = "${config.application.namePrefix}example-apps" - //TODO refactor and rename scmm->scm def credentialId = "scmm-user" jobManger.createJob(jobName, @@ -202,7 +203,6 @@ class Jenkins extends Feature { "${config.registry.proxyUsername}", "${config.registry.proxyPassword}", 'credentials for accessing the docker-registry that contains 3rd party or base images') - } // Once everything is set up, start the jobs. jobManger.startJob(jobName) diff --git a/src/main/groovy/com/cloudogu/gitops/features/Mailhog.groovy b/src/main/groovy/com/cloudogu/gitops/features/Mailhog.groovy index 440d90b88..d198cffb4 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/Mailhog.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/Mailhog.groovy @@ -26,7 +26,7 @@ class Mailhog extends Feature implements FeatureWithImage { static final String HELM_VALUES_PATH = "applications/cluster-resources/mailhog-helm-values.ftl.yaml" - String namespace = 'monitoring' + String namespace = "${config.application.namePrefix}monitoring" Config config K8sClient k8sClient @@ -113,9 +113,9 @@ class Mailhog extends Feature implements FeatureWithImage { private URI getScmmUri() { if (config.scmm.internal) { - new URI('http://scmm-scm-manager.default.svc.cluster.local/scm') + new URI("http://scmm-scm-manager.${config.application.namePrefix}scm-manager.svc.cluster.local/scm") } else { new URI("${config.scmm.url}") } } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/features/PrometheusStack.groovy b/src/main/groovy/com/cloudogu/gitops/features/PrometheusStack.groovy index a436fbec7..192224b90 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/PrometheusStack.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/PrometheusStack.groovy @@ -27,7 +27,7 @@ class PrometheusStack extends Feature implements FeatureWithImage { static final String RBAC_NAMESPACE_ISOLATION_TEMPLATE = 'applications/cluster-resources/monitoring/rbac/namespace-isolation-rbac.ftl.yaml' static final String NETWORK_POLICIES_PROMETHEUS_ALLOW_TEMPLATE = 'applications/cluster-resources/monitoring/netpols/prometheus-allow-scraping.ftl.yaml' - String namespace = 'monitoring' + String namespace = "${config.application.namePrefix}monitoring" Config config K8sClient k8sClient @@ -202,7 +202,7 @@ class PrometheusStack extends Feature implements FeatureWithImage { private URI getScmmUri() { if (config.scmm.internal) { - new URI('http://scmm-scm-manager.default.svc.cluster.local/scm') + new URI("http://scmm-scm-manager.${config.application.namePrefix}scm-manager.svc.cluster.local/scm") } else { new URI("${config.scmm.url}") } @@ -212,7 +212,7 @@ class PrometheusStack extends Feature implements FeatureWithImage { String path = 'prometheus' URI uri if (config.jenkins.internal) { - uri = new URI("http://jenkins.default.svc.cluster.local/${path}") + uri = new URI("http://jenkins.${config.application.namePrefix}jenkins.svc.cluster.local/${path}") } else { uri = new URI("${config.jenkins.url}/${path}") } @@ -224,4 +224,4 @@ class PrometheusStack extends Feature implements FeatureWithImage { path : uri.path ] } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/features/Registry.groovy b/src/main/groovy/com/cloudogu/gitops/features/Registry.groovy index c6a1c8bb0..6a8ba6741 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/Registry.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/Registry.groovy @@ -23,8 +23,8 @@ class Registry extends Feature { */ public static final String CONTAINER_PORT = '5000' - String namespace = 'default' - + String namespace = "${config.application.namePrefix}registry" + private Config config private DeploymentStrategy deployer private FileSystemUtils fileSystemUtils @@ -65,17 +65,28 @@ class Registry extends Feature { def tempValuesPath = fileSystemUtils.writeTempFile(mergedMap) log.trace("Helm yaml to be applied: ${yaml}") + + deployer.deployFeature( + helmConfig.repoURL, + 'registry', + helmConfig.chart, + helmConfig.version, + namespace, + 'docker-registry', + tempValuesPath + ) + if (config.registry.internalPort != Config.DEFAULT_REGISTRY_PORT) { /* Add additional node port 30000 is needed as a static by docker via port mapping of k3d, e.g. 32769 -> 30000 on server-0 container See "-p 30000" in init-cluster.sh e.g 32769 is needed so the kubelet can access the image inside the server-0 container */ - k8sClient.createServiceNodePort('docker-registry-internal-port', + k8sClient.createServiceNodePort('docker-registry-internal-port', CONTAINER_PORT, config.registry.internalPort.toString(), namespace) } - + deployer.deployFeature( helmConfig.repoURL, 'registry', @@ -87,4 +98,4 @@ class Registry extends Feature { ) } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/features/ScmManager.groovy b/src/main/groovy/com/cloudogu/gitops/features/ScmManager.groovy index 1d551273d..355367e8f 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/ScmManager.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/ScmManager.groovy @@ -6,6 +6,7 @@ import com.cloudogu.gitops.features.deployment.DeploymentStrategy import com.cloudogu.gitops.features.deployment.HelmStrategy import com.cloudogu.gitops.utils.CommandExecutor import com.cloudogu.gitops.utils.FileSystemUtils +import com.cloudogu.gitops.utils.K8sClient import com.cloudogu.gitops.utils.MapUtils import groovy.util.logging.Slf4j import io.micronaut.core.annotation.Order @@ -24,20 +25,22 @@ class ScmManager extends Feature { static final String HELM_VALUES_PATH = "scm-manager/values.ftl.yaml" - String namespace = 'default' + String namespace = "${config.application.namePrefix}scm-manager" private Config config private CommandExecutor commandExecutor private FileSystemUtils fileSystemUtils private DeploymentStrategy deployer private GitLabApi gitlabApi + private K8sClient k8sClient ScmManager( Config config, CommandExecutor commandExecutor, FileSystemUtils fileSystemUtils, // For now we deploy imperatively using helm to avoid order problems. In future we could deploy via argocd. - HelmStrategy deployer + HelmStrategy deployer, + K8sClient k8sClient ) { this.config = config this.commandExecutor = commandExecutor @@ -45,6 +48,7 @@ class ScmManager extends Feature { this.deployer = deployer this.gitlabApi = new GitLabApi(config.scmm.url, config.scmm.password) this.gitlabApi.enableRequestResponseLogging(Level.ALL) + this.k8sClient = k8sClient } @Override @@ -56,6 +60,9 @@ class ScmManager extends Feature { void enable() { if (config.scmm.internal) { + + k8sClient.createNamespace(namespace) + def helmConfig = config.scmm.helm def templatedMap = templateToMap(HELM_VALUES_PATH, [ diff --git a/src/main/groovy/com/cloudogu/gitops/features/Vault.groovy b/src/main/groovy/com/cloudogu/gitops/features/Vault.groovy index 72c065c78..6510af613 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/Vault.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/Vault.groovy @@ -21,12 +21,11 @@ class Vault extends Feature implements FeatureWithImage { static final String VAULT_START_SCRIPT_PATH = '/applications/cluster-resources/secrets/vault/dev-post-start.ftl.sh' static final String HELM_VALUES_PATH = 'applications/cluster-resources/secrets/vault/values.ftl.yaml' - String namespace = 'secrets' + String namespace = "${config.application.namePrefix}secrets" Config config K8sClient k8sClient private FileSystemUtils fileSystemUtils - private Path tmpHelmValues private DeploymentStrategy deployer private AirGappedUtils airGappedUtils @@ -71,14 +70,12 @@ class Vault extends Feature implements FeatureWithImage { def vaultPostStartConfigMap = 'vault-dev-post-start' def vaultPostStartVolume = 'dev-post-start' - def namePrefix = config.application.namePrefix - def templatedFile = fileSystemUtils.copyToTempDir(fileSystemUtils.getRootDir() + VAULT_START_SCRIPT_PATH) - def postStartScript = new TemplatingEngine().replaceTemplate(templatedFile.toFile(), [namePrefix: namePrefix]) + def postStartScript = new TemplatingEngine().replaceTemplate(templatedFile.toFile(), [namePrefix: config.application.namePrefix]) log.debug('Creating namespace for vault, so it can add its secrets there') - k8sClient.createNamespace('secrets') - k8sClient.createConfigMapFromFile(vaultPostStartConfigMap, 'secrets', postStartScript.absolutePath) + k8sClient.createNamespace(namespace) + k8sClient.createConfigMapFromFile(vaultPostStartConfigMap, namespace, postStartScript.absolutePath) templatedMap = MapUtils.deepMerge( [ @@ -158,9 +155,9 @@ class Vault extends Feature implements FeatureWithImage { private URI getScmmUri() { if (config.scmm.internal) { - new URI('http://scmm-scm-manager.default.svc.cluster.local/scm') + new URI("http://scmm-scm-manager.${config.application.namePrefix}scm-manager.svc.cluster.local/scm") } else { new URI("${config.scmm.url}") } } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/features/argocd/ArgoCD.groovy b/src/main/groovy/com/cloudogu/gitops/features/argocd/ArgoCD.groovy index ee3fc1d33..2c519fc0f 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/argocd/ArgoCD.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/argocd/ArgoCD.groovy @@ -24,14 +24,16 @@ class ArgoCD extends Feature { static final String OPERATOR_CONFIG_PATH = 'operator/argocd.yaml' static final String OPERATOR_RBAC_PATH = 'operator/rbac' static final String CHART_YAML_PATH = 'argocd/Chart.yaml' - static final String SCMM_URL_INTERNAL = 'http://scmm-scm-manager.default.svc.cluster.local/scm' static final String MONITORING_RESOURCES_PATH = '/misc/monitoring/' + private String namespace = "${config.application.namePrefix}argocd" private Config config private List<RepoInitializationAction> gitRepos = [] private String password + protected final String scmm_url_internal = "http://scmm-scm-manager.${config.application.namePrefix}scm-manager.svc.cluster.local/scm" + protected RepoInitializationAction argocdRepoInitializationAction protected RepoInitializationAction clusterResourcesInitializationAction protected RepoInitializationAction exampleAppsInitializationAction @@ -159,8 +161,8 @@ class ArgoCD extends Feature { if (!config.scmm.internal) { String externalScmmUrl = ScmmRepo.createScmmUrl(config) log.debug("Configuring all yaml files in gitops repos to use the external scmm url: ${externalScmmUrl}") - replaceFileContentInYamls(new File(clusterResourcesInitializationAction.repo.getAbsoluteLocalRepoTmpDir()), SCMM_URL_INTERNAL, externalScmmUrl) - replaceFileContentInYamls(new File(exampleAppsInitializationAction.repo.getAbsoluteLocalRepoTmpDir()), SCMM_URL_INTERNAL, externalScmmUrl) + replaceFileContentInYamls(new File(clusterResourcesInitializationAction.repo.getAbsoluteLocalRepoTmpDir()), scmm_url_internal, externalScmmUrl) + replaceFileContentInYamls(new File(exampleAppsInitializationAction.repo.getAbsoluteLocalRepoTmpDir()), scmm_url_internal, externalScmmUrl) } fileSystemUtils.copyDirectory("${fileSystemUtils.rootDir}/applications/argocd/nginx/helm-umbrella", @@ -196,7 +198,6 @@ class ArgoCD extends Feature { prepareArgoCdRepo() - def namePrefix = config.application.namePrefix def namespaceList = getNamespaceList() log.debug("Creating namespaces") @@ -207,31 +208,31 @@ class ArgoCD extends Feature { log.debug('Creating repo credential secret that is used by argocd to access repos in SCM-Manager') // Create secret imperatively here instead of values.yaml, because we don't want it to show in git repo def repoTemplateSecretName = 'argocd-repo-creds-scmm' - //TODO multi-tenancy - String scmmUrlForArgoCD = config.scmm.internal ? SCMM_URL_INTERNAL : ScmmRepo.createScmmUrl(config) - k8sClient.createSecret('generic', repoTemplateSecretName, 'argocd', + + String scmmUrlForArgoCD = config.scmm.internal ? scmm_url_internal : ScmmRepo.createScmmUrl(config) + k8sClient.createSecret('generic', repoTemplateSecretName, namespace, new Tuple2('url', scmmUrlForArgoCD), new Tuple2('username', config.scmm.username), new Tuple2('password', config.scmm.password) ) - k8sClient.label('secret', repoTemplateSecretName, 'argocd', + k8sClient.label('secret', repoTemplateSecretName, namespace, new Tuple2(' argocd.argoproj.io/secret-type', 'repo-creds')) if (config.features.mail.smtpUser || config.features.mail.smtpPassword) { k8sClient.createSecret( 'generic', 'argocd-notifications-secret', - 'argocd', + namespace, new Tuple2('email-username', config.features.mail.smtpUser), new Tuple2('email-password', config.features.mail.smtpPassword) ) } if (config.features.argocd.operator) { - deployWithOperator("argocd") + deployWithOperator() } else { - deployWithHelm(namePrefix, "argocd") + deployWithHelm() } // Bootstrap root application @@ -241,16 +242,17 @@ class ArgoCD extends Feature { // Delete helm-argo secrets to decouple from helm. // This does not delete Argo from the cluster, but you can no longer modify argo directly with helm // For development keeping it in helm makes it easier (e.g. for helm uninstall). - k8sClient.delete('secret', 'argocd', + k8sClient.delete('secret', namespace, new Tuple2('owner', 'helm'), new Tuple2('name', 'argocd')) } - private static List<String> getNamespaceList() { + private List<String> getNamespaceList() { def namespaceList = ["argocd", "monitoring", "ingress-nginx", "example-apps-staging", "example-apps-production", "secrets"] - return namespaceList + def prefixedNamespaces = namespaceList.collect { ns -> "${config.application.namePrefix}${ns}".toString() } + return prefixedNamespaces } - private void deployWithHelm(namePrefix, String argocdNamespace) { + private void deployWithHelm() { // Install umbrella chart from folder String umbrellaChartPath = Path.of(argocdRepoInitializationAction.repo.getAbsoluteLocalRepoTmpDir(), 'argocd/') // Even if the Chart.lock already contains the repo, we need to add it before resolving it @@ -259,41 +261,41 @@ class ArgoCD extends Feature { Path.of(argocdRepoInitializationAction.repo.getAbsoluteLocalRepoTmpDir(), CHART_YAML_PATH))['dependencies'] helmClient.addRepo('argo', helmDependencies[0]['repository'] as String) helmClient.dependencyBuild(umbrellaChartPath) - helmClient.upgrade('argocd', umbrellaChartPath, [namespace: "${namePrefix}${argocdNamespace}"]) + helmClient.upgrade('argocd', umbrellaChartPath, [namespace: "${namespace}"]) // Delete helm-argo secrets to decouple from helm. // This does not delete Argo from the cluster, but you can no longer modify argo directly with helm // For development keeping it in helm makes it easier (e.g. for helm uninstall). - k8sClient.delete('secret', 'argocd', + k8sClient.delete('secret', namespace, new Tuple2('owner', 'helm'), new Tuple2('name', 'argocd')) log.debug("Setting new argocd admin password") // Set admin password imperatively here instead of values.yaml, because we don't want it to show in git repo String bcryptArgoCDPassword = BCrypt.hashpw(password, BCrypt.gensalt(4)) - k8sClient.patch('secret', 'argocd-secret', 'argocd', + k8sClient.patch('secret', 'argocd-secret', namespace, [stringData: ['admin.password': bcryptArgoCDPassword]]) } - private void deployWithOperator(String argocdNamespace) { + private void deployWithOperator() { // Apply argocd yaml from operator folder String argocdConfigPath = Path.of(argocdRepoInitializationAction.repo.getAbsoluteLocalRepoTmpDir(), OPERATOR_CONFIG_PATH) k8sClient.applyYaml(argocdConfigPath) // ArgoCD is not installed until the ArgoCD-Operator did his job. // This can take some time, so we wait for the status of the custom resource to become "Available" - k8sClient.waitForResourcePhase("argocd", "argocd", argocdNamespace, "Available") + k8sClient.waitForResourcePhase("argocd", "argocd", namespace, "Available") if (!config.application.openshift) { // We need to patch the NodePrt of the Service, because the operator only supports setting type: NodePort but not the port itself - log.debug("Patching NodePorts for 'argocd-server' Service in namespace '{}' to HTTP: 9092 and HTTPS: 9093", argocdNamespace); - k8sClient.patchServiceNodePort("argocd-server", argocdNamespace, "http", 9092) - k8sClient.patchServiceNodePort("argocd-server", argocdNamespace, "https", 9093) + log.debug("Patching NodePorts for 'argocd-server' Service in namespace '{}' to HTTP: 9092 and HTTPS: 9093", namespace); + k8sClient.patchServiceNodePort("argocd-server", namespace, "http", 9092) + k8sClient.patchServiceNodePort("argocd-server", namespace, "https", 9093) } log.debug("Setting new argocd admin password") // Set admin password imperatively here instead of operator/argocd.yaml, because we don't want it to show in git repo // The Operator uses an extra secret to store the admin Password, which is not bcrypted - k8sClient.patch('secret', 'argocd-cluster', argocdNamespace, + k8sClient.patch('secret', 'argocd-cluster', namespace, [stringData: ['admin.password': password]]) // In newer Versions ArgoCD Operator uses the password in argocd-cluster secret only as generated initial password // but we want to set our own admin password so we set the password in both Secrets for consistency @@ -305,7 +307,7 @@ class ArgoCD extends Feature { // The ArgoCD instance installed via an operator only manages its deployment namespace. // To manage additional namespaces, we need to update the 'argocd-default-cluster-config' secret with all managed namespaces. def namespaceList = getNamespaceList() - k8sClient.patch('secret', 'argocd-default-cluster-config', argocdNamespace, + k8sClient.patch('secret', 'argocd-default-cluster-config', namespace, [stringData: ['namespaces': namespaceList.join(',')]]) log.debug("Add RBAC permissions for ArgoCD in all managed namespaces.") @@ -355,7 +357,7 @@ class ArgoCD extends Feature { if (!config.scmm.internal) { String externalScmmUrl = ScmmRepo.createScmmUrl(config) log.debug("Configuring all yaml files in argocd repo to use the external scmm url: ${externalScmmUrl}") - replaceFileContentInYamls(new File(argocdRepoInitializationAction.repo.getAbsoluteLocalRepoTmpDir()), SCMM_URL_INTERNAL, externalScmmUrl) + replaceFileContentInYamls(new File(argocdRepoInitializationAction.repo.getAbsoluteLocalRepoTmpDir()), scmm_url_internal, externalScmmUrl) } if (!config.application.remote) { @@ -468,8 +470,8 @@ class ArgoCD extends Feature { ], ], scmm : [ - baseUrl : config.scmm.internal ? 'http://scmm-scm-manager.default.svc.cluster.local/scm' : ScmmRepo.createScmmUrl(config), - host : config.scmm.internal ? 'scmm-scm-manager.default.svc.cluster.local' : config.scmm.host, + baseUrl : config.scmm.internal ? "http://scmm-scm-manager.${config.application.namePrefix}scm-manager.svc.cluster.local/scm" : ScmmRepo.createScmmUrl(config), + host : config.scmm.internal ? "http://scmm-scm-manager.${config.application.namePrefix}scm-manager.svc.cluster.local" : config.scmm.host, protocol: config.scmm.internal ? 'http' : config.scmm.protocol, repoUrl : ScmmRepo.createSCMBaseUrl(config), provider: config.scmm.provider @@ -495,4 +497,4 @@ class ArgoCD extends Feature { return repo } } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/features/deployment/ArgoCdApplicationStrategy.groovy b/src/main/groovy/com/cloudogu/gitops/features/deployment/ArgoCdApplicationStrategy.groovy index a464980b6..71dd35fbe 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/deployment/ArgoCdApplicationStrategy.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/deployment/ArgoCdApplicationStrategy.groovy @@ -47,7 +47,6 @@ class ArgoCdApplicationStrategy implements DeploymentStrategy { // Write chart, repoURL and version into a ArgoCD Application YAML def yamlMapper = YAMLMapper.builder().enable(YAMLGenerator.Feature.LITERAL_BLOCK_STYLE).build() - String prefixedNamespace = "${namePrefix}${namespace}" def yamlResult = yamlMapper.writeValueAsString([ apiVersion: "argoproj.io/v1alpha1", kind : "Application", @@ -58,7 +57,7 @@ class ArgoCdApplicationStrategy implements DeploymentStrategy { spec : [ destination: [ server : "https://kubernetes.default.svc", - namespace: prefixedNamespace + namespace: namespace ], project : "cluster-resources", sources : [ @@ -89,7 +88,7 @@ class ArgoCdApplicationStrategy implements DeploymentStrategy { clusterResourcesRepo.writeFile("argocd/${releaseName}.yaml", yamlResult) log.debug("Deploying helm release ${releaseName} basing on chart ${chartOrPath} from ${repoURL}, version " + - "${version}, into namespace ${prefixedNamespace}. Using Argo CD application:\n${yamlResult}") + "${version}, into namespace ${namespace}. Using Argo CD application:\n${yamlResult}") clusterResourcesRepo.commitAndPush("Added $repoName/$chartOrPath to ArgoCD") } @@ -103,4 +102,4 @@ class ArgoCdApplicationStrategy implements DeploymentStrategy { default: throw new RuntimeException("Repo type ${repoType} not implemented for ${this.class.simpleName}") } } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/features/deployment/HelmStrategy.groovy b/src/main/groovy/com/cloudogu/gitops/features/deployment/HelmStrategy.groovy index 84f274a13..ddc8b3eca 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/deployment/HelmStrategy.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/deployment/HelmStrategy.groovy @@ -28,17 +28,14 @@ class HelmStrategy implements DeploymentStrategy { throw new RuntimeException("Unable to deploy helm chart via Helm CLI from Git URL, because helm does not support this out of the box.\n" + "Repo URL: ${repoURL}") } - - def namePrefix = config.application.namePrefix - String prefixedNamespace = "${namePrefix}${namespace}" log.debug("Imperatively deploying helm release ${releaseName} basing on chart ${chartOrPath} from ${repoURL}, " + - "version ${version}, into namespace ${prefixedNamespace}. Using values:\n${helmValuesPath.toFile().text}") + "version ${version}, into namespace ${namespace}. Using values:\n${helmValuesPath.toFile().text}") helmClient.addRepo(repoName, repoURL) helmClient.upgrade(releaseName, "$repoName/$chartOrPath", - [namespace: prefixedNamespace, + [namespace: namespace, version : version, values : helmValuesPath.toString()]) } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/scmm/ScmmRepo.groovy b/src/main/groovy/com/cloudogu/gitops/scmm/ScmmRepo.groovy index 3e5077afb..f02a6cee8 100644 --- a/src/main/groovy/com/cloudogu/gitops/scmm/ScmmRepo.groovy +++ b/src/main/groovy/com/cloudogu/gitops/scmm/ScmmRepo.groovy @@ -66,7 +66,7 @@ class ScmmRepo { switch (config.scmm.provider) { case "scm-manager": if(config.scmm.internal){ - return "http://scmm-scm-manager.default.svc.cluster.local/scm/${config.scmm.rootPath}/${config.application.namePrefix}" + return "http://scmm-scm-manager.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/${config.scmm.rootPath}/${config.application.namePrefix}" } return createScmmUrl(config) + "/${config.scmm.rootPath}/${config.application.namePrefix}" case "gitlab": @@ -197,4 +197,4 @@ class ScmmRepo { protected String getGitRepositoryUrl() { return "${scmmUrl}/${rootPath}/${scmmRepoTarget}" } -} +} \ No newline at end of file diff --git a/src/main/groovy/com/cloudogu/gitops/utils/K8sClient.groovy b/src/main/groovy/com/cloudogu/gitops/utils/K8sClient.groovy index b5da58a6e..b4866cea5 100644 --- a/src/main/groovy/com/cloudogu/gitops/utils/K8sClient.groovy +++ b/src/main/groovy/com/cloudogu/gitops/utils/K8sClient.groovy @@ -109,20 +109,18 @@ class K8sClient { */ void createNamespace(String name) { validateNamespace(name) + + if (!exists(name)) { - String namespace = "${configProvider.get().application.namePrefix}${name}"; - - if (!exists(namespace)) { - - log.debug("Namespace ${namespace} does not exist, proceeding to create."); + log.debug("Namespace ${name} does not exist, proceeding to create.") // Create the namespace - String[] createNamespaceCommand = new Kubectl("create", "namespace", namespace).build(); + String[] createNamespaceCommand = new Kubectl("create", "namespace", name).build() try { - CommandExecutor.Output createNamespaceOutput = commandExecutor.execute(createNamespaceCommand); - log.debug("Namespace ${namespace} created successfully."); + CommandExecutor.Output createNamespaceOutput = commandExecutor.execute(createNamespaceCommand) + log.debug("Namespace ${name} created successfully.") } catch (Exception e) { - throw new RuntimeException("Failed to create namespace ${namespace} (possibly due to insufficient permissions)", e); + throw new RuntimeException("Failed to create namespace ${name} (possibly due to insufficient permissions)", e) } } @@ -131,11 +129,11 @@ class K8sClient { private boolean exists(String namespace) { // Check if the namespace already exists based on exitCode - String[] checkNamespaceCommand = new Kubectl("get", "namespace", namespace).build(); - CommandExecutor.Output checkNamespaceOutput = commandExecutor.execute(checkNamespaceCommand, false); + String[] checkNamespaceCommand = new Kubectl("get", "namespace", namespace).build() + CommandExecutor.Output checkNamespaceOutput = commandExecutor.execute(checkNamespaceCommand, false) if (checkNamespaceOutput.exitCode == 0) { - log.debug("Namespace ${namespace} already exists."); + log.debug("Namespace ${namespace} already exists.") return true } return false @@ -143,7 +141,7 @@ class K8sClient { private void validateNamespace(String name) { if (name == null || name.trim().isEmpty()) { - throw new IllegalArgumentException("Namespace name must be provided and cannot be null or empty."); + throw new IllegalArgumentException("Namespace name must be provided and cannot be null or empty.") } } @@ -157,7 +155,7 @@ class K8sClient { */ void createNamespaces(List<String> names) { if (names == null) { - throw new IllegalArgumentException("Namespaces must be provided and cannot be null."); + throw new IllegalArgumentException("Namespaces must be provided and cannot be null.") } names.each { name -> createNamespace(name) @@ -231,7 +229,7 @@ class K8sClient { throw new RuntimeException("Missing key-value-pairs") } String command = - "kubectl label ${resource} ${name}${namespace ? " -n ${configProvider.get().application.namePrefix}${namespace}" : ''} " + + "kubectl label ${resource} ${name}${namespace ? " -n ${namespace}" : ''} " + '--overwrite ' + // Make idempotent keyValues.collect { "${it.v1}${it.v2 ? "=${it.v2}" : ''}" }.join(' ') commandExecutor.execute(command) @@ -258,7 +256,7 @@ class K8sClient { // kubectl patch secret argocd-secret -p '{"stringData": { "admin.password": "'"${bcryptArgoCDPassword}"'"}}' || true String command = - "kubectl patch ${resource} ${name}${namespace ? " -n ${configProvider.get().application.namePrefix}${namespace}" : ''}" + + "kubectl patch ${resource} ${name}${namespace ? " -n ${namespace}" : ''}" + (type ? " --type=$type" : '') + " --patch-file=${patchYaml.absolutePath}" commandExecutor.execute(command) @@ -270,7 +268,7 @@ class K8sClient { } // kubectl delete secret -n argocd -l owner=helm,name=argocd String command = - "kubectl delete ${resource}${namespace ? " -n ${configProvider.get().application.namePrefix}${namespace}" : ''}" + + "kubectl delete ${resource}${namespace ? " -n ${namespace}" : ''}" + ' --ignore-not-found=true ' + // Make idempotent selectors.collect { "--selector=${it.v1}=${it.v2}" }.join(' ') @@ -279,7 +277,7 @@ class K8sClient { void delete(String resource, String namespace, String name) { String command = - "kubectl delete ${resource}${namespace ? " -n ${configProvider.get().application.namePrefix}${namespace}" : ''}" + + "kubectl delete ${resource}${namespace ? " -n ${namespace}" : ''}" + " $name" + ' --ignore-not-found=true ' // Make idempotent @@ -510,7 +508,7 @@ class K8sClient { Kubectl namespace(String namespace) { if (namespace) { - this.command += ['-n', K8sClient.this.configProvider.get().application.namePrefix + namespace] + this.command += ['-n', namespace] } return this } diff --git a/src/test/groovy/com/cloudogu/gitops/ApplicationConfiguratorTest.groovy b/src/test/groovy/com/cloudogu/gitops/ApplicationConfiguratorTest.groovy index 855ad6aea..d07aa0514 100644 --- a/src/test/groovy/com/cloudogu/gitops/ApplicationConfiguratorTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/ApplicationConfiguratorTest.groovy @@ -98,8 +98,8 @@ class ApplicationConfiguratorTest { withEnvironmentVariable("KUBERNETES_SERVICE_HOST", "127.0.0.1").execute { Config actualConfig = applicationConfigurator.initConfig(testConfig) - assertThat(actualConfig.scmm.url).isEqualTo("http://scmm-scm-manager.default.svc.cluster.local:80/scm") - assertThat(actualConfig.jenkins.url).isEqualTo("http://jenkins.default.svc.cluster.local:80") + assertThat(actualConfig.scmm.url).isEqualTo("http://scmm-scm-manager.scm-manager.svc.cluster.local:80/scm") + assertThat(actualConfig.jenkins.url).isEqualTo("http://jenkins.jenkins.svc.cluster.local:80") } } @@ -578,4 +578,4 @@ class ApplicationConfiguratorTest { } return keysList } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/ApplicationTest.groovy b/src/test/groovy/com/cloudogu/gitops/ApplicationTest.groovy index 105e9954a..9b8e342f5 100644 --- a/src/test/groovy/com/cloudogu/gitops/ApplicationTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/ApplicationTest.groovy @@ -29,12 +29,14 @@ class ApplicationTest { config.features.ingressNginx.active = true config.application.namePrefix = 'test1-' List<String> namespaceList = new ArrayList<>(Arrays.asList( - "test1-default", "test1-argocd", "test1-example-apps-staging", "test1-example-apps-production", "test1-ingress-nginx", - "test1-monitoring" + "test1-monitoring", + "test1-scm-manager", + "test1-registry", + "test1-jenkins" )) def application = ApplicationContext.run() .registerSingleton(config) @@ -54,7 +56,10 @@ class ApplicationTest { "test1-example-apps-staging", "test1-example-apps-production", "test1-ingress-nginx", - "test1-monitoring" + "test1-monitoring", + "test1-scm-manager", + "test1-registry", + "test1-jenkins" )) def application = ApplicationContext.run() .registerSingleton(config) @@ -62,4 +67,4 @@ class ApplicationTest { application.setNamespaceListToConfig(config) assertThat(config.application.getActiveNamespaces()).containsExactlyInAnyOrderElementsOf(namespaceList) } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/FeatureTest.groovy b/src/test/groovy/com/cloudogu/gitops/FeatureTest.groovy index d11fa869c..77650e5e9 100644 --- a/src/test/groovy/com/cloudogu/gitops/FeatureTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/FeatureTest.groovy @@ -9,7 +9,6 @@ class FeatureTest { Config config = new Config( application: new Config.ApplicationSchema( namePrefix: "foo-") - ) K8sClientForTest k8sClient = new K8sClientForTest( config) @@ -37,7 +36,7 @@ class FeatureTest { Feature feature = new FeatureWithImageForTest() feature.config = config feature.k8sClient = k8sClient - feature.namespace = 'my-ns' + feature.namespace = 'foo-my-ns' feature } @@ -82,4 +81,4 @@ class FeatureTest { return true } } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/features/CertManagerTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/CertManagerTest.groovy index 2b4143199..66527aa76 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/CertManagerTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/CertManagerTest.groovy @@ -87,7 +87,7 @@ class CertManagerTest { assertThat(helmConfig.value.version).isEqualTo(chartVersion) // important check: repoUrl is overridden with our values. verify(deploymentStrategy).deployFeature( - 'http://scmm-scm-manager.default.svc.cluster.local/scm/repo/a/b', + 'http://scmm-scm-manager.scm-manager.svc.cluster.local/scm/repo/a/b', 'cert-manager', '.', chartVersion, 'cert-manager', 'cert-manager', temporaryYamlFile, DeploymentStrategy.RepoType.GIT) } @@ -150,4 +150,4 @@ class CertManagerTest { def ys = new YamlSlurper() return ys.parse(temporaryYamlFile) as Map } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/features/ContentTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/ContentTest.groovy index 29a244664..de09cee59 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/ContentTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/ContentTest.groovy @@ -103,4 +103,4 @@ class ContentTest { } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/features/ExternalSecretsOperatorTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/ExternalSecretsOperatorTest.groovy index 721f4b594..fb4d9801c 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/ExternalSecretsOperatorTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/ExternalSecretsOperatorTest.groovy @@ -48,7 +48,7 @@ class ExternalSecretsOperatorTest { 'externalsecretsoperator', 'external-secrets', '0.9.16', - 'secrets', + 'foo-secrets', 'external-secrets', temporaryYamlFile ) @@ -124,8 +124,8 @@ class ExternalSecretsOperatorTest { assertThat(helmConfig.value.repoURL).isEqualTo('https://charts.external-secrets.io') assertThat(helmConfig.value.version).isEqualTo('0.9.16') verify(deploymentStrategy).deployFeature( - 'http://scmm-scm-manager.default.svc.cluster.local/scm/repo/a/b', - 'external-secrets', '.', '1.2.3', 'secrets', + 'http://scmm-scm-manager.foo-scm-manager.svc.cluster.local/scm/repo/a/b', + 'external-secrets', '.', '1.2.3', 'foo-secrets', 'external-secrets', temporaryYamlFile, DeploymentStrategy.RepoType.GIT) } @@ -169,4 +169,4 @@ class ExternalSecretsOperatorTest { def ys = new YamlSlurper() return ys.parse(temporaryYamlFile) as Map } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/features/IngressNginxTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/IngressNginxTest.groovy index 5e02fc32e..6ef681522 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/IngressNginxTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/IngressNginxTest.groovy @@ -42,7 +42,7 @@ class IngressNginxTest { assertThat(actual['controller']['replicaCount']).isEqualTo(2) verify(deploymentStrategy).deployFeature(config.features.ingressNginx.helm.repoURL, 'ingress-nginx', - config.features.ingressNginx.helm.chart, config.features.ingressNginx.helm.version,'ingress-nginx', + config.features.ingressNginx.helm.chart, config.features.ingressNginx.helm.version,'foo-ingress-nginx', 'ingress-nginx', temporaryYamlFile) assertThat(parseActualYaml()['controller']['resources']).isNull() assertThat(parseActualYaml()['controller']['metrics']).isNull() @@ -104,12 +104,12 @@ class IngressNginxTest { def helmConfig = ArgumentCaptor.forClass(Config.HelmConfig) verify(airGappedUtils).mirrorHelmRepoToGit(helmConfig.capture()) - assertThat(helmConfig.value.chart).isEqualTo(config.features.ingressNginx.helm.chart) - assertThat(helmConfig.value.repoURL).isEqualTo(config.features.ingressNginx.helm.repoURL) - assertThat(helmConfig.value.version).isEqualTo(config.features.ingressNginx.helm.version) + assertThat(helmConfig.value.chart).isEqualTo('ingress-nginx') + assertThat(helmConfig.value.repoURL).isEqualTo('https://kubernetes.github.io/ingress-nginx') + assertThat(helmConfig.value.version).isEqualTo('4.12.1') verify(deploymentStrategy).deployFeature( - 'http://scmm-scm-manager.default.svc.cluster.local/scm/repo/a/b', - 'ingress-nginx', '.', '1.2.3','ingress-nginx', + 'http://scmm-scm-manager.foo-scm-manager.svc.cluster.local/scm/repo/a/b', + 'ingress-nginx', '.', '1.2.3','foo-ingress-nginx', 'ingress-nginx', temporaryYamlFile, DeploymentStrategy.RepoType.GIT) } @@ -167,7 +167,7 @@ class IngressNginxTest { @Test void 'get namespace from feature'() { - assertThat(createIngressNginx().getActiveNamespaceFromFeature()).isEqualTo('ingress-nginx') + assertThat(createIngressNginx().getActiveNamespaceFromFeature()).isEqualTo('foo-ingress-nginx') config.features.ingressNginx.active = false assertThat(createIngressNginx().getActiveNamespaceFromFeature()).isEqualTo(null) } @@ -189,4 +189,4 @@ class IngressNginxTest { def ys = new YamlSlurper() return ys.parse(temporaryYamlFile) as Map } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/features/JenkinsTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/JenkinsTest.groovy index fdca58b71..83a503bad 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/JenkinsTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/JenkinsTest.groovy @@ -62,11 +62,11 @@ me:x:1000:''') jenkins.install() verify(deploymentStrategy).deployFeature('https://jen-repo', 'jenkins', - 'jen-chart', '4.8.1', 'default', + 'jen-chart', '4.8.1', 'jenkins', 'jenkins', temporaryYamlFile) verify(k8sClient).label('node', expectedNodeName, new Tuple2('node', 'jenkins')) verify(k8sClient).labelRemove('node', '--all', '', 'node') - verify(k8sClient).createSecret('generic', 'jenkins-credentials', 'default', + verify(k8sClient).createSecret('generic', 'jenkins-credentials', 'jenkins', new Tuple2('jenkins-admin-user', 'jenusr'), new Tuple2('jenkins-admin-password', 'jenpw')) @@ -195,7 +195,7 @@ me:x:1000:''') assertThat(env['SCMM_PASSWORD']).isEqualTo('scmm-pw') assertThat(env['INSTALL_ARGOCD']).isEqualTo('true') - verify(globalPropertyManager).setGlobalProperty('SCMM_URL', 'http://scmm') + verify(globalPropertyManager).setGlobalProperty('MY_PREFIX_SCMM_URL', 'http://scmm-scm-manager/scm') verify(globalPropertyManager).setGlobalProperty('MY_PREFIX_K8S_VERSION', Config.K8S_VERSION) verify(globalPropertyManager).setGlobalProperty('MY_PREFIX_REGISTRY_URL', 'reg-url') @@ -323,4 +323,4 @@ me:x:1000:''') def ys = new YamlSlurper() return ys.parse(temporaryYamlFile) as Map } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/features/MailhogTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/MailhogTest.groovy index 6e4548030..875006f4a 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/MailhogTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/MailhogTest.groovy @@ -99,7 +99,7 @@ class MailhogTest { 'mailhog', 'mailhog', '5.0.1', - 'monitoring', + 'foo-monitoring', 'mailhog', temporaryYamlFile ) @@ -183,8 +183,8 @@ class MailhogTest { assertThat(helmConfig.value.repoURL).isEqualTo('https://codecentric.github.io/helm-charts') assertThat(helmConfig.value.version).isEqualTo('5.0.1') verify(deploymentStrategy).deployFeature( - 'http://scmm-scm-manager.default.svc.cluster.local/scm/repo/a/b', - 'mailhog', '.', '1.2.3', 'monitoring', + 'http://scmm-scm-manager.foo-scm-manager.svc.cluster.local/scm/repo/a/b', + 'mailhog', '.', '1.2.3', 'foo-monitoring', 'mailhog', temporaryYamlFile, DeploymentStrategy.RepoType.GIT) } @@ -230,4 +230,4 @@ class MailhogTest { def ys = new YamlSlurper() return ys.parse(temporaryYamlFile) as Map } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/features/PrometheusStackTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/PrometheusStackTest.groovy index 6c7ff51c4..5010918e1 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/PrometheusStackTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/PrometheusStackTest.groovy @@ -299,7 +299,7 @@ policies: assertThat(additionalScrapeConfigs[0]['scheme']).isEqualTo('https') // scrape config for jenkins is unchanged - assertThat(((additionalScrapeConfigs[1]['static_configs'] as List)[0]['targets'] as List)[0]).isEqualTo('jenkins.default.svc.cluster.local') + assertThat(((additionalScrapeConfigs[1]['static_configs'] as List)[0]['targets'] as List)[0]).isEqualTo('jenkins.foo-jenkins.svc.cluster.local') assertThat(additionalScrapeConfigs[1]['scheme']).isEqualTo('http') assertThat(additionalScrapeConfigs[1]['metrics_path']).isEqualTo('/prometheus') } @@ -317,7 +317,7 @@ policies: assertThat(additionalScrapeConfigs[1]['scheme']).isEqualTo('https') // scrape config for scmm is unchanged - assertThat(((additionalScrapeConfigs[0]['static_configs'] as List)[0]['targets'] as List)[0]).isEqualTo('scmm-scm-manager.default.svc.cluster.local') + assertThat(((additionalScrapeConfigs[0]['static_configs'] as List)[0]['targets'] as List)[0]).isEqualTo('scmm-scm-manager.foo-scm-manager.svc.cluster.local') assertThat(additionalScrapeConfigs[0]['scheme']).isEqualTo('http') assertThat(additionalScrapeConfigs[0]['metrics_path']).isEqualTo('/scm/api/v2/metrics/prometheus') } @@ -396,7 +396,7 @@ policies: 'kubectl create secret generic prometheus-metrics-creds-scmm -n foo-monitoring --from-literal password=123 --dry-run=client -oyaml | kubectl apply -f-') verify(deploymentStrategy).deployFeature('https://prom', 'prometheusstack', - 'kube-prometheus-stack', '19.2.2', 'monitoring', + 'kube-prometheus-stack', '19.2.2', 'foo-monitoring', 'kube-prometheus-stack', temporaryYamlFilePrometheus) /* This corresponds to 'helm repo add prometheusstack https://prom' @@ -540,8 +540,8 @@ policies: assertThat(helmConfig.value.repoURL).isEqualTo('https://prom') assertThat(helmConfig.value.version).isEqualTo('19.2.2') verify(deploymentStrategy).deployFeature( - 'http://scmm-scm-manager.default.svc.cluster.local/scm/repo/a/b', - 'prometheusstack', '.', '1.2.3', 'monitoring', + 'http://scmm-scm-manager.foo-scm-manager.svc.cluster.local/scm/repo/a/b', + 'prometheusstack', '.', '1.2.3', 'foo-monitoring', 'kube-prometheus-stack', temporaryYamlFilePrometheus, RepoType.GIT) } @@ -629,4 +629,4 @@ matchExpressions: def ys = new YamlSlurper() return ys.parse(temporaryYamlFilePrometheus) as Map } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/features/RegistryTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/RegistryTest.groovy index 755bb8ba1..03c4b8f08 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/RegistryTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/RegistryTest.groovy @@ -42,7 +42,7 @@ class RegistryTest { 'helm upgrade -i docker-registry registry/docker-registry --create-namespace') assertThat(helmCommands.actualCommands[1].trim()).contains('--version') assertThat(helmCommands.actualCommands[1].trim()).contains("--values ${temporaryYamlFile}") - assertThat(helmCommands.actualCommands[1].trim()).contains('--namespace foo-default') + assertThat(helmCommands.actualCommands[1].trim()).contains('--namespace foo-registry') assertThat(k8sClient.commandExecutorForTest.actualCommands).isEmpty() } @@ -101,4 +101,4 @@ class RegistryTest { return ys.parse(temporaryYamlFile) as Map } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/features/ScmManagerTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/ScmManagerTest.groovy index d2b35ce4f..f46a9f3d4 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/ScmManagerTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/ScmManagerTest.groovy @@ -5,6 +5,8 @@ import com.cloudogu.gitops.features.deployment.HelmStrategy import com.cloudogu.gitops.utils.CommandExecutorForTest import com.cloudogu.gitops.utils.FileSystemUtils import com.cloudogu.gitops.utils.HelmClient +import com.cloudogu.gitops.utils.K8sClient +import com.cloudogu.gitops.utils.K8sClientForTest import groovy.yaml.YamlSlurper import org.junit.jupiter.api.Test @@ -82,7 +84,7 @@ class ScmManagerTest { 'helm upgrade -i scmm scm-manager/scm-manager-chart --create-namespace') assertThat(helmCommands.actualCommands[1].trim()).contains('--version 2.47.0') assertThat(helmCommands.actualCommands[1].trim()).contains(" --values ${temporaryYamlFile}") - assertThat(helmCommands.actualCommands[1].trim()).contains('--namespace foo-default') + assertThat(helmCommands.actualCommands[1].trim()).contains('--namespace foo-scm-manager') def env = getEnvAsMap() assertThat(commandExecutor.actualCommands[0] as String).isEqualTo( @@ -159,6 +161,6 @@ class ScmManagerTest { temporaryYamlFile = Path.of(ret.toString().replace(".ftl", "")) // Path after template invocation return ret } - }, new HelmStrategy(config, helmClient)) + }, new HelmStrategy(config, helmClient), new K8sClientForTest(config)) } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/features/VaultTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/VaultTest.groovy index 61ab649b0..4d5d12f12 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/VaultTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/VaultTest.groovy @@ -183,7 +183,7 @@ class VaultTest { 'vault', 'vault', '42.23.0', - 'secrets', + 'foo-secrets', 'vault', temporaryYamlFile ) @@ -219,8 +219,8 @@ class VaultTest { assertThat(helmConfig.value.repoURL).isEqualTo('https://vault-reg') assertThat(helmConfig.value.version).isEqualTo('42.23.0') verify(deploymentStrategy).deployFeature( - 'http://scmm-scm-manager.default.svc.cluster.local/scm/repo/a/b', - 'vault', '.', '1.2.3', 'secrets', + 'http://scmm-scm-manager.foo-scm-manager.svc.cluster.local/scm/repo/a/b', + 'vault', '.', '1.2.3', 'foo-secrets', 'vault', temporaryYamlFile, DeploymentStrategy.RepoType.GIT) } diff --git a/src/test/groovy/com/cloudogu/gitops/features/argocd/ArgoCDTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/argocd/ArgoCDTest.groovy index eebf700c9..304ff0a59 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/argocd/ArgoCDTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/argocd/ArgoCDTest.groovy @@ -121,7 +121,7 @@ class ArgoCDTest { k8sCommands.assertExecuted('kubectl create namespace argocd') // check values.yaml - List filesWithInternalSCMM = findFilesContaining(new File(argocdRepo.getAbsoluteLocalRepoTmpDir()), ArgoCD.SCMM_URL_INTERNAL) + List filesWithInternalSCMM = findFilesContaining(new File(argocdRepo.getAbsoluteLocalRepoTmpDir()), argocd.scmm_url_internal) assertThat(filesWithInternalSCMM).isNotEmpty() assertThat(parseActualYaml(actualHelmValuesFile)['argo-cd']['server']['service']['type']) .isEqualTo('NodePort') @@ -184,8 +184,9 @@ class ArgoCDTest { config.scmm.internal = false config.features.argocd.url = 'https://argo.cd' - createArgoCD().install() - List filesWithInternalSCMM = findFilesContaining(new File(argocdRepo.getAbsoluteLocalRepoTmpDir()), ArgoCD.SCMM_URL_INTERNAL) + def argocd = createArgoCD() + argocd.install() + List filesWithInternalSCMM = findFilesContaining(new File(argocdRepo.getAbsoluteLocalRepoTmpDir()), argocd.scmm_url_internal) assertThat(filesWithInternalSCMM).isEmpty() List filesWithExternalSCMM = findFilesContaining(new File(argocdRepo.getAbsoluteLocalRepoTmpDir()), "https://abc") assertThat(filesWithExternalSCMM).isNotEmpty() @@ -500,11 +501,11 @@ class ArgoCDTest { createArgoCD().install() Map repos = parseActualYaml(actualHelmValuesFile)['argo-cd']['configs']['repositories'] as Map - assertThat(repos['prometheus']['url']).isEqualTo('http://scmm-scm-manager.default.svc.cluster.local/scm/repo/3rd-party-dependencies/kube-prometheus-stack') + assertThat(repos['prometheus']['url']).isEqualTo('http://scmm-scm-manager.scm-manager.svc.cluster.local/scm/repo/3rd-party-dependencies/kube-prometheus-stack') def clusterRessourcesYaml = new YamlSlurper().parse(Path.of argocdRepo.getAbsoluteLocalRepoTmpDir(), 'projects/cluster-resources.yaml') assertThat(clusterRessourcesYaml['spec']['sourceRepos'] as List).contains( - 'http://scmm-scm-manager.default.svc.cluster.local/scm/repo/3rd-party-dependencies/kube-prometheus-stack') + 'http://scmm-scm-manager.scm-manager.svc.cluster.local/scm/repo/3rd-party-dependencies/kube-prometheus-stack') assertThat(clusterRessourcesYaml['spec']['sourceRepos'] as List).doesNotContain( 'https://prometheus-community.github.io/helm-charts') } @@ -574,20 +575,22 @@ class ArgoCDTest { @Test void 'For internal SCMM: Use service address in gitops repos'() { - createArgoCD().install() - List filesWithInternalSCMM = findFilesContaining(new File(clusterResourcesRepo.getAbsoluteLocalRepoTmpDir()), ArgoCD.SCMM_URL_INTERNAL) + def argocd = createArgoCD() + argocd.install() + List filesWithInternalSCMM = findFilesContaining(new File(clusterResourcesRepo.getAbsoluteLocalRepoTmpDir()), argocd.scmm_url_internal) assertThat(filesWithInternalSCMM).isNotEmpty() - filesWithInternalSCMM = findFilesContaining(new File(exampleAppsRepo.getAbsoluteLocalRepoTmpDir()), ArgoCD.SCMM_URL_INTERNAL) + filesWithInternalSCMM = findFilesContaining(new File(exampleAppsRepo.getAbsoluteLocalRepoTmpDir()), argocd.scmm_url_internal) assertThat(filesWithInternalSCMM).isNotEmpty() } @Test void 'For external SCMM: Use external address in gitops repos'() { config.scmm.internal = false - createArgoCD().install() - List filesWithInternalSCMM = findFilesContaining(new File(clusterResourcesRepo.getAbsoluteLocalRepoTmpDir()), ArgoCD.SCMM_URL_INTERNAL) + def argocd = createArgoCD() + argocd.install() + List filesWithInternalSCMM = findFilesContaining(new File(clusterResourcesRepo.getAbsoluteLocalRepoTmpDir()), argocd.scmm_url_internal) assertThat(filesWithInternalSCMM).isEmpty() - filesWithInternalSCMM = findFilesContaining(new File(exampleAppsRepo.getAbsoluteLocalRepoTmpDir()), ArgoCD.SCMM_URL_INTERNAL) + filesWithInternalSCMM = findFilesContaining(new File(exampleAppsRepo.getAbsoluteLocalRepoTmpDir()), argocd.scmm_url_internal) assertThat(filesWithInternalSCMM).isEmpty() List filesWithExternalSCMM = findFilesContaining(new File(clusterResourcesRepo.getAbsoluteLocalRepoTmpDir()), "https://abc") @@ -598,9 +601,10 @@ class ArgoCDTest { @Test void 'Pushes repos with empty name-prefix'() { - createArgoCD().install() + def argocd = createArgoCD() + argocd.install() - assertArgoCdYamlPrefixes(ArgoCD.SCMM_URL_INTERNAL, '') + assertArgoCdYamlPrefixes(argocd.scmm_url_internal, '') assertJenkinsEnvironmentVariablesPrefixes('') } @@ -618,9 +622,10 @@ class ArgoCDTest { config.application.namePrefix = 'abc-' config.application.namePrefixForEnvVars = 'ABC_' - createArgoCD().install() + def argocd = createArgoCD() + argocd.install() - assertArgoCdYamlPrefixes(ArgoCD.SCMM_URL_INTERNAL, 'abc-') + assertArgoCdYamlPrefixes(argocd.scmm_url_internal, 'abc-') assertJenkinsEnvironmentVariablesPrefixes('ABC_') } @@ -656,7 +661,7 @@ class ArgoCDTest { assertThat(image['registry']).isEqualTo('localhost:5000') assertThat(image['repository']).isEqualTo('nginx/nginx') assertThat(image['tag']).isEqualTo('latest') - + def deployment = parseActualYaml(brokenApplicationRepo.absoluteLocalRepoTmpDir + '/broken-application.yaml')[0] assertThat(deployment['kind']).as("Did not correctly fetch deployment from broken-application.yaml").isEqualTo("Deploymentz") assertThat((deployment['spec']['template']['spec']['containers'] as List)[0]['image']).isEqualTo('localhost:5000/nginx/nginx:latest') @@ -675,15 +680,15 @@ class ArgoCDTest { config.registry.proxyUrl = 'proxy-url' config.registry.proxyUsername = 'proxy-user' config.registry.proxyPassword = 'proxy-pw' - + createArgoCD().install() assertThat(parseActualYaml(nginxHelmJenkinsRepo.absoluteLocalRepoTmpDir + '/k8s/values-shared.yaml')['global']['imagePullSecrets']) .isEqualTo(['proxy-registry']) - + assertThat(parseActualYaml(new File(exampleAppsRepo.getAbsoluteLocalRepoTmpDir()), 'apps/nginx-helm-umbrella/values.yaml')['nginx']['global']['imagePullSecrets']) .isEqualTo(['proxy-registry']) - + def deployment = parseActualYaml(brokenApplicationRepo.absoluteLocalRepoTmpDir + '/broken-application.yaml')[0] assertThat(deployment['spec']['imagePullSecrets']).isEqualTo([[name: 'proxy-registry']]) @@ -693,7 +698,7 @@ class ArgoCDTest { - proxy-registry """) } - + @Test void 'Skips CRDs for argo cd'() { config.application.skipCrds = true @@ -784,7 +789,7 @@ class ArgoCDTest { assertThat(new File(argocdRepo.getAbsoluteLocalRepoTmpDir(), '/argocd/templates/allow-namespaces.yaml').text.contains("namespace: monitoring")) assertThat(new File(argocdRepo.getAbsoluteLocalRepoTmpDir(), '/argocd/templates/allow-namespaces.yaml').text.contains("namespace: default")) } - + @Test void 'set credentials for BuildImages'() { config.registry.twoRegistries = true @@ -916,7 +921,7 @@ class ArgoCDTest { def yaml = parseActualYaml(it.toString()) List yamlDocuments = yaml instanceof List ? yaml : [yaml] for (def document in yamlDocuments) { - // Check all YAMLs objects for proper namespace, but namespaces because they dont have namespace attributes + // Check all YAMLs objects for proper namespace, but namespaces because they dont have namespace attributes if (document && document['kind'] != 'Namespace') { def metadataNamespace = document['metadata']['namespace'] as String assertThat(metadataNamespace) @@ -989,7 +994,7 @@ class ArgoCDTest { if (!actualBuildImages) { fail("Missing build images in Jenkinsfile ${jenkinsfile}") } - + if (config.registry.twoRegistries) { for (Map.Entry image : actualBuildImages as Map) { assertThat(image.value['image']).isEqualTo(buildImages[image.key]) @@ -1429,5 +1434,4 @@ class ArgoCDTest { return ys.parse(yamlFile) as Map } -} - +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/features/deployment/ArgoCdApplicationStrategyTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/deployment/ArgoCdApplicationStrategyTest.groovy index 2047857a3..82bef1aaf 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/deployment/ArgoCdApplicationStrategyTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/deployment/ArgoCdApplicationStrategyTest.groovy @@ -23,7 +23,7 @@ param1: value1 param2: value2 """ strategy.deployFeature("repoURL", "repoName", "chartName", "version", - "namespace", "releaseName", valuesYaml.toPath()) + "foo-namespace", "releaseName", valuesYaml.toPath()) def argoCdApplicationYaml = new File("$localTempDir/argocd/releaseName.yaml") assertThat(argoCdApplicationYaml.text).isEqualTo("""--- @@ -135,4 +135,4 @@ spec: return new ArgoCdApplicationStrategy(config, new FileSystemUtils(), repoProvider) } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/features/deployment/HelmStrategyTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/deployment/HelmStrategyTest.groovy index 71e237ecd..7c99703bc 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/deployment/HelmStrategyTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/deployment/HelmStrategyTest.groovy @@ -21,7 +21,7 @@ class HelmStrategyTest { void 'deploys feature using helm client'() { Path valuesYaml = Files.createTempFile('', '') - createStrategy().deployFeature("repoURL", "repoName", "chart", "version", "namespace", "releaseName", valuesYaml) + createStrategy().deployFeature("repoURL", "repoName", "chart", "version", "foo-namespace", "releaseName", valuesYaml) verify(helmClient).addRepo("repoName", "repoURL") verify(helmClient).upgrade("releaseName", "repoName/chart", [ @@ -46,4 +46,4 @@ class HelmStrategyTest { protected HelmStrategy createStrategy() { new HelmStrategy(new Config([application: [namePrefix: "foo-"]]), helmClient) } -} +} \ No newline at end of file diff --git a/src/test/groovy/com/cloudogu/gitops/integration/GOPSmoketestsIT.groovy b/src/test/groovy/com/cloudogu/gitops/integration/GOPSmoketestsIT.groovy index 3ed2cb2d8..cce549163 100644 --- a/src/test/groovy/com/cloudogu/gitops/integration/GOPSmoketestsIT.groovy +++ b/src/test/groovy/com/cloudogu/gitops/integration/GOPSmoketestsIT.groovy @@ -1,11 +1,7 @@ package com.cloudogu.gitops.integration import com.cloudogu.gitops.integration.features.KubenetesApiTestSetup -import io.kubernetes.client.openapi.models.V1NamespaceList -import io.kubernetes.client.openapi.models.V1Pod -import io.kubernetes.client.openapi.models.V1PodList -import io.kubernetes.client.openapi.models.V1Service -import io.kubernetes.client.openapi.models.V1ServiceList +import io.kubernetes.client.openapi.models.* import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Test @@ -62,6 +58,9 @@ class GOPSmoketestsIT extends KubenetesApiTestSetup { void ensureNamespacesExists() { List<String> expectedNamespaces = ["argocd", "cert-manager", + "jenkins", + "registry", + "scm-manager", "default", "example-apps-production", "example-apps-staging", @@ -107,10 +106,10 @@ class GOPSmoketestsIT extends KubenetesApiTestSetup { V1ServiceList services = api.listServiceForAllNamespaces() .execute() if (list && !list.items.isEmpty() && - services && !services.items.isEmpty()) { + services && !services.items.isEmpty()) { - V1Pod argoPod = list.getItems().find { it.getMetadata().getName().startsWith("argo")} - V1Service service = services.getItems()find { it.getMetadata().getName().startsWith("ingress")} + V1Pod argoPod = list.getItems().find { it.getMetadata().getName().startsWith("argo") } + V1Service service = services.getItems() find { it.getMetadata().getName().startsWith("ingress") } if (argoPod && service) { return true diff --git a/src/test/groovy/com/cloudogu/gitops/utils/K8sClientTest.groovy b/src/test/groovy/com/cloudogu/gitops/utils/K8sClientTest.groovy index 765897893..61b9e36b3 100644 --- a/src/test/groovy/com/cloudogu/gitops/utils/K8sClientTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/utils/K8sClientTest.groovy @@ -9,7 +9,7 @@ import static org.assertj.core.api.Assertions.assertThat class K8sClientTest { - Config config = new Config(application: new Config.ApplicationSchema(namePrefix: "foo-")) + Config config = new Config(application: new Config.ApplicationSchema(namePrefix: "")) K8sClientForTest k8sClient = new K8sClientForTest(config) CommandExecutorForTest commandExecutor = k8sClient.commandExecutorForTest @@ -49,7 +49,7 @@ class K8sClientTest { new Tuple2('key1', 'value1'), new Tuple2('key2', 'value2')) assertThat(commandExecutor.actualCommands[0]).isEqualTo( - "kubectl create secret generic my-secret -n foo-my-ns --from-literal key1=value1 --from-literal key2=value2" + + "kubectl create secret generic my-secret -n my-ns --from-literal key1=value1 --from-literal key2=value2" + " --dry-run=client -oyaml | kubectl apply -f-") } @@ -74,10 +74,10 @@ class K8sClientTest { @Test void 'Creates imagePullSecret'() { - k8sClient.createImagePullSecret('my-reg', 'ns', 'host', 'user', 'pw') + k8sClient.createImagePullSecret('my-reg', 'my-ns', 'host', 'user', 'pw') assertThat(commandExecutor.actualCommands[0]).isEqualTo( - 'kubectl create secret docker-registry my-reg -n foo-ns' + + 'kubectl create secret docker-registry my-reg -n my-ns' + ' --docker-server host --docker-username user --docker-password pw' + ' --dry-run=client -oyaml | kubectl apply -f-') } @@ -105,7 +105,7 @@ class K8sClientTest { k8sClient.createConfigMapFromFile('my-map', 'my-ns', '/file') assertThat(commandExecutor.actualCommands[0]).isEqualTo( - "kubectl create configmap my-map -n foo-my-ns --from-file /file --dry-run=client -oyaml" + + "kubectl create configmap my-map -n my-ns --from-file /file --dry-run=client -oyaml" + " | kubectl apply -f-") } @@ -123,7 +123,7 @@ class K8sClientTest { k8sClient.createServiceNodePort('my-svc', '42:23', '32000', 'my-ns') assertThat(commandExecutor.actualCommands[0]).isEqualTo( - 'kubectl create service nodeport my-svc -n foo-my-ns --tcp 42:23 --node-port 32000' + + 'kubectl create service nodeport my-svc -n my-ns --tcp 42:23 --node-port 32000' + ' --dry-run=client -oyaml | kubectl apply -f-') } @@ -142,7 +142,7 @@ class K8sClientTest { new Tuple2('key1', 'value1'), new Tuple2('key2', 'value2')) assertThat(commandExecutor.actualCommands[0]).isEqualTo( - "kubectl label secret my-secret -n foo-my-ns --overwrite key1=value1 key2=value2") + "kubectl label secret my-secret -n my-ns --overwrite key1=value1 key2=value2") } @Test @@ -186,7 +186,7 @@ class K8sClientTest { def expectedYaml = [a: 'b'] k8sClient.patch('secret', 'my-secret', 'ns', expectedYaml) - assertThat(commandExecutor.actualCommands[0]).startsWith("kubectl patch secret my-secret -n foo-ns --patch-file=") + assertThat(commandExecutor.actualCommands[0]).startsWith("kubectl patch secret my-secret -n ns --patch-file=") String patchFile = (commandExecutor.actualCommands[0] =~ /--patch-file=([\S]+)/)?.findResult { (it as List)[1] } assertThat(parseActualYaml(patchFile)).isEqualTo(expectedYaml) @@ -212,7 +212,7 @@ class K8sClientTest { new Tuple2('key1', 'value1'), new Tuple2('key2', 'value2')) assertThat(commandExecutor.actualCommands[0]).isEqualTo( - "kubectl delete secret -n foo-my-ns --ignore-not-found=true --selector=key1=value1 --selector=key2=value2") + "kubectl delete secret -n my-ns --ignore-not-found=true --selector=key1=value1 --selector=key2=value2") } @Test @@ -234,7 +234,7 @@ class K8sClientTest { @Test void 'Gets custom resources with name prefix'() { - commandExecutor.enqueueOutput(new CommandExecutor.Output('', "foo-namespace,name\nfoo-namespace2,name2", 0)) + commandExecutor.enqueueOutput(new CommandExecutor.Output('', "namespace,name\nnamespace2,name2", 0)) def result = k8sClient.getCustomResource('foo') assertThat(result).isEqualTo([new K8sClient.CustomResource('namespace', 'name'), new K8sClient.CustomResource('namespace2', 'name2')]) @@ -285,14 +285,14 @@ class K8sClientTest { @Test void 'Creates namespace when it does not exist'() { // Simulate that the namespace does not exist (kubectl get returns a non-zero exit code) - commandExecutor.enqueueOutput(new CommandExecutor.Output('Error from server (NotFound): namespaces "foo-my-ns" not found', '', 1)) + commandExecutor.enqueueOutput(new CommandExecutor.Output('Error from server (NotFound): namespaces "my-ns" not found', '', 1)) // Attempt to create the namespace k8sClient.createNamespace('my-ns') // Assert that the correct kubectl command was issued to create the namespace assertThat(commandExecutor.actualCommands[1]).isEqualTo( - "kubectl create namespace foo-my-ns") + "kubectl create namespace my-ns") } @Test @@ -303,10 +303,10 @@ class K8sClientTest { // Attempt to create the namespace k8sClient.createNamespace('my-ns') - // Assert that no kubectl create command was issued except 'kubectl get namespace foo-my-ns' + // Assert that no kubectl create command was issued except 'kubectl get namespace my-ns' assertThat(commandExecutor.actualCommands.size()).is(1) assertThat(commandExecutor.actualCommands[0]).isEqualTo( - "kubectl get namespace foo-my-ns") + "kubectl get namespace my-ns") } @Test @@ -344,7 +344,7 @@ class K8sClientTest { } // Assert that the exception message is correct - assertThat(exception.message).contains("Failed to create namespace foo-my-ns (possibly due to insufficient permissions)") + assertThat(exception.message).contains("Failed to create namespace my-ns (possibly due to insufficient permissions)") } @Test @@ -360,7 +360,7 @@ class K8sClientTest { } // Assert that the exception message is correct - assertThat(exception.message).contains("Failed to create namespace foo-my-ns (possibly due to insufficient permissions)") + assertThat(exception.message).contains("Failed to create namespace my-ns (possibly due to insufficient permissions)") } @Test @@ -382,7 +382,7 @@ class K8sClientTest { // Assert that the correct kubectl patch command was issued assertThat(commandExecutor.actualCommands[1]).isEqualTo( - 'kubectl patch service my-service -n foo-my-namespace --type json -p [{"op":"replace","path":"/spec/ports/1/nodePort","value":32000}]' + 'kubectl patch service my-service -n my-namespace --type json -p [{"op":"replace","path":"/spec/ports/1/nodePort","value":32000}]' ) } @Test @@ -461,7 +461,7 @@ class K8sClientTest { k8sClient.patchServiceNodePort('my-service', 'my-namespace', 'http', 32000) } - assertThat(exception.message).contains("Executing command failed: kubectl patch service my-service -n foo-my-namespace --type json -p [{\"op\":\"replace\",\"path\":\"/spec/ports/0/nodePort\",\"value\":32000}]") + assertThat(exception.message).contains("Executing command failed: kubectl patch service my-service -n my-namespace --type json -p [{\"op\":\"replace\",\"path\":\"/spec/ports/0/nodePort\",\"value\":32000}]") } @Test @@ -476,7 +476,7 @@ class K8sClientTest { // Assert that the correct kubectl get command was issued and that the method returned successfully assertThat(commandExecutor.actualCommands).hasSize(2) assertThat(commandExecutor.actualCommands[0]).isEqualTo( - 'kubectl get pod my-pod -n foo-my-namespace -o jsonpath={.status.phase}') + 'kubectl get pod my-pod -n my-namespace -o jsonpath={.status.phase}') } @Test @@ -559,7 +559,7 @@ class K8sClientTest { // Assert that the command was executed only once and no retries occurred assertThat(commandExecutor.actualCommands).hasSize(1) assertThat(commandExecutor.actualCommands[0]).isEqualTo( - 'kubectl get pod my-pod -n foo-my-namespace -o jsonpath={.status.phase}') + 'kubectl get pod my-pod -n my-namespace -o jsonpath={.status.phase}') } @Test @@ -573,7 +573,7 @@ class K8sClientTest { void 'Runs a pod with params'() { k8sClient.run('my-pod', 'alpine', 'my-ns', '--rm') - assertThat(commandExecutor.actualCommands[0]).startsWith("kubectl run my-pod --image alpine -n foo-my-ns --rm") + assertThat(commandExecutor.actualCommands[0]).startsWith("kubectl run my-pod --image alpine -n my-ns --rm") } @Test @@ -590,7 +590,7 @@ class K8sClientTest { ] k8sClient.run('my-pod', 'alpine', 'my-ns', overrides, '--restart=Never', '-ti', '--rm', '--quiet') - assertThat(commandExecutor.actualCommands[0]).startsWith("kubectl run my-pod --image alpine -n foo-my-ns --restart=Never -ti --rm --quiet") + assertThat(commandExecutor.actualCommands[0]).startsWith("kubectl run my-pod --image alpine -n my-ns --restart=Never -ti --rm --quiet") assertThat(commandExecutor.actualCommands[0]).contains('{"spec":{"containers":[{"name":"tmp-docker-gid-grepper","image":"bash:5"}]}}'.toString().trim()) } @@ -610,4 +610,4 @@ class K8sClientTest { def ys = new YamlSlurper() return ys.parse(yamlFile) as Map } -} +} \ No newline at end of file