From 667a791f4bac4c4f0d73e4f85165a6ad750bc0cc Mon Sep 17 00:00:00 2001 From: Philipp Markiewka Date: Mon, 20 Oct 2025 11:06:03 +0200 Subject: [PATCH 01/21] temp commit --- .../argocd/applications/example-apps.yaml | 23 +++++++++++++ .../argocd/projects/example-apps.ftl.yaml | 32 +++++++++++++++++++ .../argocd/argocd/projects/example-apps.yaml | 32 +++++++++++++++++++ .../argocd/mt-appset.ftl.yaml | 23 +++++++++++++ .../argocd/tenants/tenant1/config.yaml | 4 +++ .../argocd/tenants/values.yaml | 25 +++++++++++++++ examples/init-multi-tenancy/config.yaml | 12 +++++++ 7 files changed, 151 insertions(+) create mode 100644 examples/init-multi-tenancy/argocd/argocd/applications/example-apps.yaml create mode 100644 examples/init-multi-tenancy/argocd/argocd/projects/example-apps.ftl.yaml create mode 100644 examples/init-multi-tenancy/argocd/argocd/projects/example-apps.yaml create mode 100644 examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml create mode 100644 examples/init-multi-tenancy/argocd/tenants/tenant1/config.yaml create mode 100644 examples/init-multi-tenancy/argocd/tenants/values.yaml create mode 100644 examples/init-multi-tenancy/config.yaml diff --git a/examples/init-multi-tenancy/argocd/argocd/applications/example-apps.yaml b/examples/init-multi-tenancy/argocd/argocd/applications/example-apps.yaml new file mode 100644 index 000000000..9d9bdcf1b --- /dev/null +++ b/examples/init-multi-tenancy/argocd/argocd/applications/example-apps.yaml @@ -0,0 +1,23 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: example-apps + namespace: ${config.application.namePrefix}argocd +# finalizer disabled, because otherwise everything under this Application would be deleted as well, if this Application is deleted by accident +# finalizers: +# - resources-finalizer.argocd.argoproj.io +spec: + destination: + namespace: ${config.application.namePrefix}argocd + server: https://kubernetes.default.svc + project: argocd + source: + path: argocd/ + repoURL: "http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/example-apps" + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: false # is set to false to prevent projects to be deleted by accident + selfHeal: true diff --git a/examples/init-multi-tenancy/argocd/argocd/projects/example-apps.ftl.yaml b/examples/init-multi-tenancy/argocd/argocd/projects/example-apps.ftl.yaml new file mode 100644 index 000000000..17ce5a9a5 --- /dev/null +++ b/examples/init-multi-tenancy/argocd/argocd/projects/example-apps.ftl.yaml @@ -0,0 +1,32 @@ +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: example-apps + namespace: ${config.application.namePrefix}argocd + annotations: +spec: + description: Contains examples of end-user applications + destinations: + - namespace: ${config.application.namePrefix}example-apps-production + server: https://kubernetes.default.svc + - namespace: ${config.application.namePrefix}example-apps-staging + server: https://kubernetes.default.svc + sourceRepos: + - http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/example-apps + - http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/nginx-helm-umbrella + + + # allow to only see application resources from the specified namespace + sourceNamespaces: + - ${config.application.namePrefix}example-apps-staging + - ${config.application.namePrefix}example-apps-production + - ${config.application.namePrefix}argocd + + + # Allow all namespaced-scoped resources to be created + namespaceResourceWhitelist: + - group: '*' + kind: '*' + + # Deny all cluster-scoped resources from being created. Least privilege. + clusterResourceWhitelist: diff --git a/examples/init-multi-tenancy/argocd/argocd/projects/example-apps.yaml b/examples/init-multi-tenancy/argocd/argocd/projects/example-apps.yaml new file mode 100644 index 000000000..17ce5a9a5 --- /dev/null +++ b/examples/init-multi-tenancy/argocd/argocd/projects/example-apps.yaml @@ -0,0 +1,32 @@ +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: example-apps + namespace: ${config.application.namePrefix}argocd + annotations: +spec: + description: Contains examples of end-user applications + destinations: + - namespace: ${config.application.namePrefix}example-apps-production + server: https://kubernetes.default.svc + - namespace: ${config.application.namePrefix}example-apps-staging + server: https://kubernetes.default.svc + sourceRepos: + - http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/example-apps + - http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/nginx-helm-umbrella + + + # allow to only see application resources from the specified namespace + sourceNamespaces: + - ${config.application.namePrefix}example-apps-staging + - ${config.application.namePrefix}example-apps-production + - ${config.application.namePrefix}argocd + + + # Allow all namespaced-scoped resources to be created + namespaceResourceWhitelist: + - group: '*' + kind: '*' + + # Deny all cluster-scoped resources from being created. Least privilege. + clusterResourceWhitelist: diff --git a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml new file mode 100644 index 000000000..9d9bdcf1b --- /dev/null +++ b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml @@ -0,0 +1,23 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: example-apps + namespace: ${config.application.namePrefix}argocd +# finalizer disabled, because otherwise everything under this Application would be deleted as well, if this Application is deleted by accident +# finalizers: +# - resources-finalizer.argocd.argoproj.io +spec: + destination: + namespace: ${config.application.namePrefix}argocd + server: https://kubernetes.default.svc + project: argocd + source: + path: argocd/ + repoURL: "http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/example-apps" + targetRevision: main + directory: + recurse: true + syncPolicy: + automated: + prune: false # is set to false to prevent projects to be deleted by accident + selfHeal: true diff --git a/examples/init-multi-tenancy/argocd/tenants/tenant1/config.yaml b/examples/init-multi-tenancy/argocd/tenants/tenant1/config.yaml new file mode 100644 index 000000000..23c79b255 --- /dev/null +++ b/examples/init-multi-tenancy/argocd/tenants/tenant1/config.yaml @@ -0,0 +1,4 @@ +name: tenant1 + +global: + url: "http://tenant1.localhost" \ No newline at end of file diff --git a/examples/init-multi-tenancy/argocd/tenants/values.yaml b/examples/init-multi-tenancy/argocd/tenants/values.yaml new file mode 100644 index 000000000..4cc234f50 --- /dev/null +++ b/examples/init-multi-tenancy/argocd/tenants/values.yaml @@ -0,0 +1,25 @@ +image: + tag: "latest" + +global: + url: "http://localhost" + skipCrds: true + password: "admin" + insecure: true + namespaceIsolation: false + +registry: + url: "localhost:30000" + +jenkins: + url: "http://172.18.0.2:35888" + username: "admin" + password: "admin" + +scmm: + url: "http://172.18.0.2:44309/scm" + username: "admin" + password: "admin" + +monitoring: + enabled: false \ No newline at end of file diff --git a/examples/init-multi-tenancy/config.yaml b/examples/init-multi-tenancy/config.yaml new file mode 100644 index 000000000..eb36006b9 --- /dev/null +++ b/examples/init-multi-tenancy/config.yaml @@ -0,0 +1,12 @@ +content: + repos: + - url: https://github.com/cloudogu/gitops-playground + path: examples/init-multi-tenancy/ + ref: main + templating: true + type: FOLDER_BASED + overwriteMode: UPGRADE + + namespaces: + - tenant-argocd + variables: From fd1309a7ad76e023988102aa47f2f02d2e0f7d6f Mon Sep 17 00:00:00 2001 From: Philipp Markiewka Date: Wed, 22 Oct 2025 23:32:28 +0200 Subject: [PATCH 02/21] temp commit --- argocd/argocd/operator/argocd.ftl.yaml | 4 +- .../argocd/applications/example-apps.yaml | 23 ----------- .../argocd/projects/example-apps.ftl.yaml | 32 ---------------- .../argocd/argocd/projects/example-apps.yaml | 32 ---------------- .../argocd/mt-appset.ftl.yaml | 23 ----------- .../cluster-resources/argocd/mt-appset.yaml | 38 +++++++++++++++++++ .../tenants/tenant1/config.yaml | 4 ++ .../argocd/tenant-configs/tenants/values.yaml | 23 +++++++++++ .../argocd/tenants/tenant1/config.yaml | 4 -- .../argocd/tenants/values.yaml | 25 ------------ examples/init-multi-tenancy/config.yaml | 33 ++++++++++++++-- .../com/cloudogu/gitops/config/Config.groovy | 4 ++ .../gitops/config/ConfigConstants.groovy | 1 + .../gitops/features/argocd/ArgoCD.groovy | 14 +++++++ .../kubernetes/rbac/RbacDefinition.groovy | 26 +++++++++++-- .../gitops/kubernetes/rbac/Role.groovy | 9 ++++- .../gitops/kubernetes/rbac/RoleBinding.groovy | 11 ++++++ .../kubernetes/rbac/rolebinding.ftl.yaml | 4 +- 18 files changed, 159 insertions(+), 151 deletions(-) delete mode 100644 examples/init-multi-tenancy/argocd/argocd/applications/example-apps.yaml delete mode 100644 examples/init-multi-tenancy/argocd/argocd/projects/example-apps.ftl.yaml delete mode 100644 examples/init-multi-tenancy/argocd/argocd/projects/example-apps.yaml delete mode 100644 examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml create mode 100644 examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml create mode 100644 examples/init-multi-tenancy/argocd/tenant-configs/tenants/tenant1/config.yaml create mode 100644 examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml delete mode 100644 examples/init-multi-tenancy/argocd/tenants/tenant1/config.yaml delete mode 100644 examples/init-multi-tenancy/argocd/tenants/values.yaml diff --git a/argocd/argocd/operator/argocd.ftl.yaml b/argocd/argocd/operator/argocd.ftl.yaml index 6506db8dd..1f52009bc 100644 --- a/argocd/argocd/operator/argocd.ftl.yaml +++ b/argocd/argocd/operator/argocd.ftl.yaml @@ -151,6 +151,7 @@ spec: - name: bitnami type: helm url: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami +<#if !config.application.clusterAdmin> resourceInclusions: | - apiGroups: - "batch" @@ -250,4 +251,5 @@ spec: - "Probe" clusters: - "https://kubernetes.default.svc" - - "${config.features.argocd.resourceInclusionsCluster}" \ No newline at end of file + - "${config.features.argocd.resourceInclusionsCluster}" + \ No newline at end of file diff --git a/examples/init-multi-tenancy/argocd/argocd/applications/example-apps.yaml b/examples/init-multi-tenancy/argocd/argocd/applications/example-apps.yaml deleted file mode 100644 index 9d9bdcf1b..000000000 --- a/examples/init-multi-tenancy/argocd/argocd/applications/example-apps.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: example-apps - namespace: ${config.application.namePrefix}argocd -# finalizer disabled, because otherwise everything under this Application would be deleted as well, if this Application is deleted by accident -# finalizers: -# - resources-finalizer.argocd.argoproj.io -spec: - destination: - namespace: ${config.application.namePrefix}argocd - server: https://kubernetes.default.svc - project: argocd - source: - path: argocd/ - repoURL: "http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/example-apps" - targetRevision: main - directory: - recurse: true - syncPolicy: - automated: - prune: false # is set to false to prevent projects to be deleted by accident - selfHeal: true diff --git a/examples/init-multi-tenancy/argocd/argocd/projects/example-apps.ftl.yaml b/examples/init-multi-tenancy/argocd/argocd/projects/example-apps.ftl.yaml deleted file mode 100644 index 17ce5a9a5..000000000 --- a/examples/init-multi-tenancy/argocd/argocd/projects/example-apps.ftl.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: AppProject -metadata: - name: example-apps - namespace: ${config.application.namePrefix}argocd - annotations: -spec: - description: Contains examples of end-user applications - destinations: - - namespace: ${config.application.namePrefix}example-apps-production - server: https://kubernetes.default.svc - - namespace: ${config.application.namePrefix}example-apps-staging - server: https://kubernetes.default.svc - sourceRepos: - - http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/example-apps - - http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/nginx-helm-umbrella - - - # allow to only see application resources from the specified namespace - sourceNamespaces: - - ${config.application.namePrefix}example-apps-staging - - ${config.application.namePrefix}example-apps-production - - ${config.application.namePrefix}argocd - - - # Allow all namespaced-scoped resources to be created - namespaceResourceWhitelist: - - group: '*' - kind: '*' - - # Deny all cluster-scoped resources from being created. Least privilege. - clusterResourceWhitelist: diff --git a/examples/init-multi-tenancy/argocd/argocd/projects/example-apps.yaml b/examples/init-multi-tenancy/argocd/argocd/projects/example-apps.yaml deleted file mode 100644 index 17ce5a9a5..000000000 --- a/examples/init-multi-tenancy/argocd/argocd/projects/example-apps.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: AppProject -metadata: - name: example-apps - namespace: ${config.application.namePrefix}argocd - annotations: -spec: - description: Contains examples of end-user applications - destinations: - - namespace: ${config.application.namePrefix}example-apps-production - server: https://kubernetes.default.svc - - namespace: ${config.application.namePrefix}example-apps-staging - server: https://kubernetes.default.svc - sourceRepos: - - http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/example-apps - - http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/nginx-helm-umbrella - - - # allow to only see application resources from the specified namespace - sourceNamespaces: - - ${config.application.namePrefix}example-apps-staging - - ${config.application.namePrefix}example-apps-production - - ${config.application.namePrefix}argocd - - - # Allow all namespaced-scoped resources to be created - namespaceResourceWhitelist: - - group: '*' - kind: '*' - - # Deny all cluster-scoped resources from being created. Least privilege. - clusterResourceWhitelist: diff --git a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml deleted file mode 100644 index 9d9bdcf1b..000000000 --- a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: example-apps - namespace: ${config.application.namePrefix}argocd -# finalizer disabled, because otherwise everything under this Application would be deleted as well, if this Application is deleted by accident -# finalizers: -# - resources-finalizer.argocd.argoproj.io -spec: - destination: - namespace: ${config.application.namePrefix}argocd - server: https://kubernetes.default.svc - project: argocd - source: - path: argocd/ - repoURL: "http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/example-apps" - targetRevision: main - directory: - recurse: true - syncPolicy: - automated: - prune: false # is set to false to prevent projects to be deleted by accident - selfHeal: true diff --git a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml new file mode 100644 index 000000000..ea1d0827f --- /dev/null +++ b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml @@ -0,0 +1,38 @@ +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: gop-multi-tenancy + namespace: argocd +spec: + goTemplate: true + goTemplateOptions: + - missingkey=error + generators: + - git: + repoURL: http://scmm.scm-manager.svc.cluster.local/scm/repo/argocd/tenant-configs + revision: HEAD + files: + - path: "tenants/*/config.yaml" + template: + metadata: + name: gop-tenant-{{.config.application.namePrefix}} + spec: + project: argocd + sources: + - repoURL: http://scmm.scm-manager.svc.cluster.local/scm/repo/3rd-party-dependencies/gop-helm + path: . + targetRevision: HEAD + helm: + valueFiles: + - $valuesRef/tenants/values.yaml + - $valuesRef/{{ .path.path }}/config.yaml + - repoURL: http://scmm.scm-manager.svc.cluster.local/scm/repo/argocd/tenant-configs + targetRevision: HEAD + ref: valuesRef + destination: + server: https://kubernetes.default.svc + namespace: argocd + syncPolicy: + automated: + selfHeal: true + prune: true \ No newline at end of file diff --git a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/tenant1/config.yaml b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/tenant1/config.yaml new file mode 100644 index 000000000..3c3ffff63 --- /dev/null +++ b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/tenant1/config.yaml @@ -0,0 +1,4 @@ +config: + application: + baseUrl: "http://tenant1.localhost" + namePrefix: "tenant1" \ No newline at end of file diff --git a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml new file mode 100644 index 000000000..c9d95d71c --- /dev/null +++ b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml @@ -0,0 +1,23 @@ +image: + tag: 7a31651e +config: + application: + baseUrl: "http://localhost" + insecure: true + username: "admin" + password: "admin" + namePrefix: "" + namespaceIsolation: true + skipCrds: true + jenkins: + active: true + features: + monitoring: + active: false + argocd: + active: true + operator: true + env: [ ] + resourceInclusionsCluster: "https://10.43.0.1:443" + ingressNginx: + active: false diff --git a/examples/init-multi-tenancy/argocd/tenants/tenant1/config.yaml b/examples/init-multi-tenancy/argocd/tenants/tenant1/config.yaml deleted file mode 100644 index 23c79b255..000000000 --- a/examples/init-multi-tenancy/argocd/tenants/tenant1/config.yaml +++ /dev/null @@ -1,4 +0,0 @@ -name: tenant1 - -global: - url: "http://tenant1.localhost" \ No newline at end of file diff --git a/examples/init-multi-tenancy/argocd/tenants/values.yaml b/examples/init-multi-tenancy/argocd/tenants/values.yaml deleted file mode 100644 index 4cc234f50..000000000 --- a/examples/init-multi-tenancy/argocd/tenants/values.yaml +++ /dev/null @@ -1,25 +0,0 @@ -image: - tag: "latest" - -global: - url: "http://localhost" - skipCrds: true - password: "admin" - insecure: true - namespaceIsolation: false - -registry: - url: "localhost:30000" - -jenkins: - url: "http://172.18.0.2:35888" - username: "admin" - password: "admin" - -scmm: - url: "http://172.18.0.2:44309/scm" - username: "admin" - password: "admin" - -monitoring: - enabled: false \ No newline at end of file diff --git a/examples/init-multi-tenancy/config.yaml b/examples/init-multi-tenancy/config.yaml index eb36006b9..528cb7732 100644 --- a/examples/init-multi-tenancy/config.yaml +++ b/examples/init-multi-tenancy/config.yaml @@ -1,12 +1,37 @@ +application: + baseUrl: "http://localhost" + insecure: true + username: "admin" + password: "admin" + "yes": true + namePrefix: "" + namespaceIsolation: false + skipCrds: true + clusterAdmin: true +jenkins: + active: false +features: + monitoring: + active: false + argocd: + active: true + operator: false + env: [] + resourceInclusionsCluster: "https://10.43.0.1:443" + ingressNginx: + active: false content: repos: - - url: https://github.com/cloudogu/gitops-playground - path: examples/init-multi-tenancy/ - ref: main + - url: https://github.com/cloudogu/gop-helm + target: 3rd-party-dependencies/gop-helm + overwriteMode: RESET + - url: file:///home/pmarkiewka/gitops-playground + path: examples/init-multi-tenancy + ref: feature/init-multi-tenancy templating: true type: FOLDER_BASED overwriteMode: UPGRADE namespaces: - - tenant-argocd + variables: diff --git a/src/main/groovy/com/cloudogu/gitops/config/Config.groovy b/src/main/groovy/com/cloudogu/gitops/config/Config.groovy index 53e69110d..4e3c159f3 100644 --- a/src/main/groovy/com/cloudogu/gitops/config/Config.groovy +++ b/src/main/groovy/com/cloudogu/gitops/config/Config.groovy @@ -399,6 +399,10 @@ class Config { @JsonPropertyDescription(NETPOLS_DESCRIPTION) Boolean netpols = false + @Option(names = ['--cluster-admin'], description = CLUSTER_ADMIN_DESCRIPTION) + @JsonPropertyDescription(CLUSTER_ADMIN_DESCRIPTION) + Boolean clusterAdmin = false + static class NamespaceSchema { LinkedHashSet dedicatedNamespaces = new LinkedHashSet<>() LinkedHashSet tenantNamespaces = new LinkedHashSet<>() diff --git a/src/main/groovy/com/cloudogu/gitops/config/ConfigConstants.groovy b/src/main/groovy/com/cloudogu/gitops/config/ConfigConstants.groovy index 834c1055d..e9408c5d9 100644 --- a/src/main/groovy/com/cloudogu/gitops/config/ConfigConstants.groovy +++ b/src/main/groovy/com/cloudogu/gitops/config/ConfigConstants.groovy @@ -88,6 +88,7 @@ interface ConfigConstants { String NAMESPACE_ISOLATION_DESCRIPTION = 'Configure tools to explicitly work with the given namespaces only, and not cluster-wide. This way GOP can be installed without having cluster-admin permissions.' String MIRROR_REPOS_DESCRIPTION = 'Changes the sources of deployed tools so they are not pulled from the internet, but are pulled from git and work in air-gapped environments.' String NETPOLS_DESCRIPTION = 'Sets Network Policies' + String CLUSTER_ADMIN_DESCRIPTION = 'Binds ArgoCD controllers to cluster-admin ClusterRole' String OPENSHIFT_DESCRIPTION = 'When set, openshift specific resources and configurations are applied' // group metrics 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 58dc1cf81..75ac53c4d 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/argocd/ArgoCD.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/argocd/ArgoCD.groovy @@ -328,6 +328,20 @@ class ArgoCD extends Feature { .withSubfolder(OPERATOR_RBAC_PATH) .generate() } + + if(config.application.clusterAdmin) { + new RbacDefinition(Role.Variant.CLUSTER_ADMIN) + .withName("argocd-cluster-admin") + .withNamespace(namespace) + .withServiceAccountsFrom( + namespace, + ["argocd-argocd-server", "argocd-argocd-application-controller", "argocd-applicationset-controller"] + ) + .withConfig(config) + .withRepo(argocdRepoInitializationAction.repo) + .withSubfolder(OPERATOR_RBAC_PATH) + .generate() + } } } diff --git a/src/main/groovy/com/cloudogu/gitops/kubernetes/rbac/RbacDefinition.groovy b/src/main/groovy/com/cloudogu/gitops/kubernetes/rbac/RbacDefinition.groovy index adbba381d..10ab03fe6 100644 --- a/src/main/groovy/com/cloudogu/gitops/kubernetes/rbac/RbacDefinition.groovy +++ b/src/main/groovy/com/cloudogu/gitops/kubernetes/rbac/RbacDefinition.groovy @@ -63,19 +63,37 @@ class RbacDefinition { throw new IllegalStateException("SCMM repo must be set using withRepo() before calling generate()") } - def role = new Role(name, namespace, variant, config) - def binding = new RoleBinding(name, namespace, name, serviceAccounts) - log.trace("Generating RBAC for name='${name}', namespace='${namespace}', subfolder='${subfolder}'") - def outputDir = Path.of(repo.absoluteLocalRepoTmpDir, subfolder).toFile() + File outputDir = Path.of(repo.absoluteLocalRepoTmpDir, subfolder).toFile() outputDir.mkdirs() + generateRole(outputDir) + + generateRoleBinding(outputDir) + } + + private void generateRole(File outputDir) { + if(variant == Role.Variant.CLUSTER_ADMIN) { + log.trace("Skipping creation of ClusterRole cluster-admin") + return + } + + def role = new Role(name, namespace, variant, config) + templater.template( role.getTemplateFile(), role.getOutputFile(outputDir), role.toTemplateParams() ) + } + + private void generateRoleBinding(File outputDir) { + String roleName = name + if(variant == Role.Variant.CLUSTER_ADMIN) { + roleName = "cluster-admin" + } + def binding = new RoleBinding(name, namespace, roleName, serviceAccounts) templater.template( binding.getTemplateFile(), diff --git a/src/main/groovy/com/cloudogu/gitops/kubernetes/rbac/Role.groovy b/src/main/groovy/com/cloudogu/gitops/kubernetes/rbac/Role.groovy index 150d29ab1..9e31cf129 100644 --- a/src/main/groovy/com/cloudogu/gitops/kubernetes/rbac/Role.groovy +++ b/src/main/groovy/com/cloudogu/gitops/kubernetes/rbac/Role.groovy @@ -21,7 +21,8 @@ class Role { } enum Variant { - ARGOCD("templates/kubernetes/rbac/argocd-role.ftl.yaml") + ARGOCD("templates/kubernetes/rbac/argocd-role.ftl.yaml"), + CLUSTER_ADMIN("") final String templatePath @@ -39,10 +40,16 @@ class Role { } File getTemplateFile() { + if(variant == Variant.CLUSTER_ADMIN) { + throw new IllegalStateException("cluster-admin role shall not be created") + } return new File(variant.getTemplatePath()) } File getOutputFile(File outputDir) { + if(variant == Variant.CLUSTER_ADMIN) { + throw new IllegalStateException("cluster-admin role shall not be created") + } String filename = "role-${name}-${namespace}.yaml" return new File(outputDir, filename) } diff --git a/src/main/groovy/com/cloudogu/gitops/kubernetes/rbac/RoleBinding.groovy b/src/main/groovy/com/cloudogu/gitops/kubernetes/rbac/RoleBinding.groovy index fc5794b88..5b7cd36f9 100644 --- a/src/main/groovy/com/cloudogu/gitops/kubernetes/rbac/RoleBinding.groovy +++ b/src/main/groovy/com/cloudogu/gitops/kubernetes/rbac/RoleBinding.groovy @@ -2,8 +2,10 @@ package com.cloudogu.gitops.kubernetes.rbac class RoleBinding { String name + String kind String namespace String roleName + String roleKind List serviceAccounts RoleBinding(String name, String namespace, String roleName, List serviceAccounts) { @@ -13,16 +15,25 @@ class RoleBinding { if (!serviceAccounts || serviceAccounts.isEmpty()) throw new IllegalArgumentException("At least one service account is required") this.name = name + this.kind = "RoleBinding" this.namespace = namespace this.roleName = roleName + this.roleKind = "Role" this.serviceAccounts = serviceAccounts + + if(roleName == "cluster-admin") { + this.kind = "ClusterRoleBinding" + this.roleKind = "ClusterRole" + } } Map toTemplateParams() { return [ name : name, + kind : kind, namespace : namespace, roleName : roleName, + roleKind : roleKind, serviceAccounts: serviceAccounts.collect { it.toMap() } ] } diff --git a/templates/kubernetes/rbac/rolebinding.ftl.yaml b/templates/kubernetes/rbac/rolebinding.ftl.yaml index 78e7d462a..384ecdde7 100644 --- a/templates/kubernetes/rbac/rolebinding.ftl.yaml +++ b/templates/kubernetes/rbac/rolebinding.ftl.yaml @@ -1,5 +1,5 @@ apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding +kind: ${kind} metadata: name: ${name} namespace: ${namespace} @@ -10,6 +10,6 @@ subjects: namespace: ${sa.namespace} roleRef: - kind: Role + kind: ${roleKind} name: ${roleName} apiGroup: rbac.authorization.k8s.io From 8c0ab1ab8f55d91b652d4d19cdaf2ea218a88dc3 Mon Sep 17 00:00:00 2001 From: Philipp Markiewka Date: Wed, 22 Oct 2025 23:49:11 +0200 Subject: [PATCH 03/21] temp commit --- argocd/argocd/argocd/values.ftl.yaml | 2 +- .../argocd/tenant-configs/tenants/values.yaml | 2 +- examples/init-multi-tenancy/config.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/argocd/argocd/argocd/values.ftl.yaml b/argocd/argocd/argocd/values.ftl.yaml index 85f22b52c..73212f3f7 100644 --- a/argocd/argocd/argocd/values.ftl.yaml +++ b/argocd/argocd/argocd/values.ftl.yaml @@ -53,7 +53,7 @@ argo-cd: # Unfortunately, as of argocd 2.6 this leads to failing notifications # https://github.com/argoproj/argo-cd/issues/11252 params: - application.namespaces: "*" + application.namespaces: "${config.application.namePrefix}argocd" server.insecure: true # tls terminated in ingress # Repo credential templates are created dynamically in groovy, so they are not stored in git diff --git a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml index c9d95d71c..9ea2cf5b5 100644 --- a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml +++ b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml @@ -16,7 +16,7 @@ config: active: false argocd: active: true - operator: true + operator: false env: [ ] resourceInclusionsCluster: "https://10.43.0.1:443" ingressNginx: diff --git a/examples/init-multi-tenancy/config.yaml b/examples/init-multi-tenancy/config.yaml index 528cb7732..13a4a1de3 100644 --- a/examples/init-multi-tenancy/config.yaml +++ b/examples/init-multi-tenancy/config.yaml @@ -19,7 +19,7 @@ features: env: [] resourceInclusionsCluster: "https://10.43.0.1:443" ingressNginx: - active: false + active: true content: repos: - url: https://github.com/cloudogu/gop-helm From 07e8cb91794575e5fc1dfcfa12ed252dc49fcc13 Mon Sep 17 00:00:00 2001 From: Philipp Markiewka Date: Thu, 23 Oct 2025 12:19:46 +0200 Subject: [PATCH 04/21] temp commit --- examples/init-multi-tenancy/config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/init-multi-tenancy/config.yaml b/examples/init-multi-tenancy/config.yaml index 13a4a1de3..6d3c4465d 100644 --- a/examples/init-multi-tenancy/config.yaml +++ b/examples/init-multi-tenancy/config.yaml @@ -6,7 +6,7 @@ application: "yes": true namePrefix: "" namespaceIsolation: false - skipCrds: true + skipCrds: false clusterAdmin: true jenkins: active: false From ccd5bf0b3b833fb20e821b18fdc72bb9954f5cd1 Mon Sep 17 00:00:00 2001 From: Thomas Michael Date: Mon, 10 Nov 2025 09:47:21 +0100 Subject: [PATCH 05/21] adopt configuration --- .../argocd/tenant-configs/tenants/values.yaml | 2 +- examples/init-multi-tenancy/config.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml index 9ea2cf5b5..c9d95d71c 100644 --- a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml +++ b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml @@ -16,7 +16,7 @@ config: active: false argocd: active: true - operator: false + operator: true env: [ ] resourceInclusionsCluster: "https://10.43.0.1:443" ingressNginx: diff --git a/examples/init-multi-tenancy/config.yaml b/examples/init-multi-tenancy/config.yaml index 6d3c4465d..f8e5300de 100644 --- a/examples/init-multi-tenancy/config.yaml +++ b/examples/init-multi-tenancy/config.yaml @@ -6,7 +6,7 @@ application: "yes": true namePrefix: "" namespaceIsolation: false - skipCrds: false + skipCrds: true clusterAdmin: true jenkins: active: false @@ -25,7 +25,7 @@ content: - url: https://github.com/cloudogu/gop-helm target: 3rd-party-dependencies/gop-helm overwriteMode: RESET - - url: file:///home/pmarkiewka/gitops-playground + - url: file:///home/cloudogu/develop/workspace/gitops-playground path: examples/init-multi-tenancy ref: feature/init-multi-tenancy templating: true @@ -33,5 +33,5 @@ content: overwriteMode: UPGRADE namespaces: - + - tenant1-argocd variables: From ecaf5514893ebab6d65c2a5c6a8c4c3ca9aba123 Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Tue, 11 Nov 2025 16:27:32 +0100 Subject: [PATCH 06/21] test --- examples/init-multi-tenancy/config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/init-multi-tenancy/config.yaml b/examples/init-multi-tenancy/config.yaml index f8e5300de..dd9fec5f8 100644 --- a/examples/init-multi-tenancy/config.yaml +++ b/examples/init-multi-tenancy/config.yaml @@ -15,7 +15,7 @@ features: active: false argocd: active: true - operator: false + operator: true env: [] resourceInclusionsCluster: "https://10.43.0.1:443" ingressNginx: @@ -25,7 +25,7 @@ content: - url: https://github.com/cloudogu/gop-helm target: 3rd-party-dependencies/gop-helm overwriteMode: RESET - - url: file:///home/cloudogu/develop/workspace/gitops-playground + - url: file:///home/pmarkiewka/gitops-playground path: examples/init-multi-tenancy ref: feature/init-multi-tenancy templating: true From d6be64bc2ddcbd952dfbe2f0a3e37f66cfef80fb Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Wed, 12 Nov 2025 10:30:19 +0100 Subject: [PATCH 07/21] test --- examples/init-multi-tenancy/config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/init-multi-tenancy/config.yaml b/examples/init-multi-tenancy/config.yaml index dd9fec5f8..bb82c9ed5 100644 --- a/examples/init-multi-tenancy/config.yaml +++ b/examples/init-multi-tenancy/config.yaml @@ -25,7 +25,7 @@ content: - url: https://github.com/cloudogu/gop-helm target: 3rd-party-dependencies/gop-helm overwriteMode: RESET - - url: file:///home/pmarkiewka/gitops-playground + - url: file:///home/cl-pc-0087/src/gitops-playground path: examples/init-multi-tenancy ref: feature/init-multi-tenancy templating: true From 14572277a0ff582cb49a3aba0fef740f78f709f2 Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Wed, 12 Nov 2025 10:40:23 +0100 Subject: [PATCH 08/21] test --- examples/init-multi-tenancy/config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/init-multi-tenancy/config.yaml b/examples/init-multi-tenancy/config.yaml index bb82c9ed5..5203aaa34 100644 --- a/examples/init-multi-tenancy/config.yaml +++ b/examples/init-multi-tenancy/config.yaml @@ -15,7 +15,7 @@ features: active: false argocd: active: true - operator: true + operator: false env: [] resourceInclusionsCluster: "https://10.43.0.1:443" ingressNginx: From 8190ce875f747f7921200a875c22a8a748617055 Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Wed, 12 Nov 2025 10:53:40 +0100 Subject: [PATCH 09/21] add content examples --- .../argocd/tenant-configs/tenants/tenant1/config.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/tenant1/config.yaml b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/tenant1/config.yaml index 3c3ffff63..229f36159 100644 --- a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/tenant1/config.yaml +++ b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/tenant1/config.yaml @@ -1,4 +1,6 @@ config: application: baseUrl: "http://tenant1.localhost" - namePrefix: "tenant1" \ No newline at end of file + namePrefix: "tenant1" + content: + examples: true \ No newline at end of file From 6c100eedc5ddf9adeb85ab595dad4ba41b8261ec Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Wed, 12 Nov 2025 11:05:07 +0100 Subject: [PATCH 10/21] switch source repos --- .../argocd/cluster-resources/argocd/mt-appset.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml index ea1d0827f..f89dfd206 100644 --- a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml +++ b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml @@ -19,6 +19,9 @@ spec: spec: project: argocd sources: + - repoURL: http://scmm.scm-manager.svc.cluster.local/scm/repo/argocd/tenant-configs + targetRevision: HEAD + ref: valuesRef - repoURL: http://scmm.scm-manager.svc.cluster.local/scm/repo/3rd-party-dependencies/gop-helm path: . targetRevision: HEAD @@ -26,9 +29,6 @@ spec: valueFiles: - $valuesRef/tenants/values.yaml - $valuesRef/{{ .path.path }}/config.yaml - - repoURL: http://scmm.scm-manager.svc.cluster.local/scm/repo/argocd/tenant-configs - targetRevision: HEAD - ref: valuesRef destination: server: https://kubernetes.default.svc namespace: argocd From 459b82c6c7b8a92e0140cf6da9316e278cf236d9 Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Wed, 12 Nov 2025 11:25:06 +0100 Subject: [PATCH 11/21] configure --- .../argocd/cluster-resources/argocd/mt-appset.yaml | 2 +- .../tenant-configs/tenants/{values.yaml => globalValues.yaml} | 2 +- .../argocd/tenant-configs/tenants/tenant1/config.yaml | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) rename examples/init-multi-tenancy/argocd/tenant-configs/tenants/{values.yaml => globalValues.yaml} (96%) diff --git a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml index f89dfd206..44d67d989 100644 --- a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml +++ b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml @@ -27,7 +27,7 @@ spec: targetRevision: HEAD helm: valueFiles: - - $valuesRef/tenants/values.yaml + - $valuesRef/tenants/globalValues.yaml - $valuesRef/{{ .path.path }}/config.yaml destination: server: https://kubernetes.default.svc diff --git a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/globalValues.yaml similarity index 96% rename from examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml rename to examples/init-multi-tenancy/argocd/tenant-configs/tenants/globalValues.yaml index c9d95d71c..8d93bf971 100644 --- a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/values.yaml +++ b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/globalValues.yaml @@ -1,5 +1,5 @@ image: - tag: 7a31651e + tag: latest config: application: baseUrl: "http://localhost" diff --git a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/tenant1/config.yaml b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/tenant1/config.yaml index 229f36159..bf078b650 100644 --- a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/tenant1/config.yaml +++ b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/tenant1/config.yaml @@ -2,5 +2,7 @@ config: application: baseUrl: "http://tenant1.localhost" namePrefix: "tenant1" + registry: + active: true content: examples: true \ No newline at end of file From 67711c6b9681e6b0a701847681d11f63ee866bdd Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Wed, 12 Nov 2025 13:50:50 +0100 Subject: [PATCH 12/21] rename global config file for better understanding prepare multi-tenancny config switch --- .../init-multi-tenancy/{config.yaml => managementConfig.yaml} | 0 src/main/groovy/com/cloudogu/gitops/config/Config.groovy | 4 ++++ 2 files changed, 4 insertions(+) rename examples/init-multi-tenancy/{config.yaml => managementConfig.yaml} (100%) diff --git a/examples/init-multi-tenancy/config.yaml b/examples/init-multi-tenancy/managementConfig.yaml similarity index 100% rename from examples/init-multi-tenancy/config.yaml rename to examples/init-multi-tenancy/managementConfig.yaml diff --git a/src/main/groovy/com/cloudogu/gitops/config/Config.groovy b/src/main/groovy/com/cloudogu/gitops/config/Config.groovy index 4e3c159f3..019058019 100644 --- a/src/main/groovy/com/cloudogu/gitops/config/Config.groovy +++ b/src/main/groovy/com/cloudogu/gitops/config/Config.groovy @@ -88,6 +88,10 @@ class Config { @JsonPropertyDescription(CONTENT_EXAMPLES_DESCRIPTION) Boolean examples = false + @Option(names = ['--multi-tenancy-examples'], description = CONTENT_EXAMPLES_DESCRIPTION) + @JsonPropertyDescription(CONTENT_EXAMPLES_DESCRIPTION) + Boolean multitenancyExamples = false + @JsonPropertyDescription(CONTENT_NAMESPACES_DESCRIPTION) List namespaces = [] From a0df3b6d61312db78a23fb23af805de667482a3f Mon Sep 17 00:00:00 2001 From: Philipp Markiewka Date: Tue, 21 Oct 2025 14:05:30 +0200 Subject: [PATCH 13/21] feat(content): laod example-apps via content-loader functionality - Move example-app definitions from `argocd/example-apps` and `applications/` into `examples/example-apps-via-content-loader` - Adjust Dockerfile to initialize example-apps folder as standalone git repo for content-loader - Update `GitopsPlaygroundCli` to include content examples via `--content.examples` flag - Extend config merging logic (`MapUtils.deepMerge`) to support additional example content source - Update schema, configurator, and tests to handle example-apps path and validation - Clean up redundant templates and adjust paths accordingly This refactor isolates example application definitions into a dedicated content-loader directory, simplifying configuration handling and enabling dynamic content loading via the CLI. --- docs/configuration.schema.json | 8 ++++ .../argocd/projects/example-apps.ftl.yaml | 13 ++---- .../apps/nginx-helm-umbrella/Chart.yaml | 7 --- .../apps/nginx-helm-umbrella/values.ftl.yaml | 43 ------------------- .../argocd/example-apps/argocd/misc.ftl.yaml | 1 + .../argocd/helm-umbrella/README.md | 0 .../config.yaml | 2 +- .../gitops/features/argocd/ArgoCD.groovy | 6 +++ .../features/ScmManagerSetupTest.groovy | 1 - .../gitops/features/argocd/ArgoCDTest.groovy | 7 ++- 10 files changed, 26 insertions(+), 62 deletions(-) delete mode 100644 examples/example-apps-via-content-loader/argocd/example-apps/apps/nginx-helm-umbrella/Chart.yaml delete mode 100644 examples/example-apps-via-content-loader/argocd/example-apps/apps/nginx-helm-umbrella/values.ftl.yaml create mode 100644 examples/example-apps-via-content-loader/argocd/helm-umbrella/README.md diff --git a/docs/configuration.schema.json b/docs/configuration.schema.json index 06ed0ea52..7193f603c 100644 --- a/docs/configuration.schema.json +++ b/docs/configuration.schema.json @@ -50,6 +50,10 @@ "type" : [ "string", "null" ], "description" : "the external base url (TLD) for all tools, e.g. https://example.com or http://localhost:8080. The individual -url params for argocd, grafana, vault and mailhog take precedence." }, + "clusterAdmin" : { + "type" : [ "boolean", "null" ], + "description" : "Binds ArgoCD controllers to cluster-admin ClusterRole" + }, "destroy" : { "type" : [ "boolean", "null" ], "description" : "Unroll playground" @@ -132,6 +136,10 @@ "type" : [ "boolean", "null" ], "description" : "Deploy example content: source repos, GitOps repos, Jenkins Job, Argo CD apps/project" }, + "multitenancyExamples" : { + "type" : [ "boolean", "null" ], + "description" : "Deploy example content: source repos, GitOps repos, Jenkins Job, Argo CD apps/project" + }, "namespaces" : { "description" : "Additional kubernetes namespaces. These are authorized to Argo CD, supplied with image pull secrets, monitored by prometheus, etc. Namespaces can be templates, e.g. ${config.application.namePrefix}staging", "type" : [ "array", "null" ], diff --git a/examples/example-apps-via-content-loader/argocd/argocd/projects/example-apps.ftl.yaml b/examples/example-apps-via-content-loader/argocd/argocd/projects/example-apps.ftl.yaml index 23901dd58..42cd7f116 100644 --- a/examples/example-apps-via-content-loader/argocd/argocd/projects/example-apps.ftl.yaml +++ b/examples/example-apps-via-content-loader/argocd/argocd/projects/example-apps.ftl.yaml @@ -4,9 +4,6 @@ metadata: name: example-apps namespace: ${config.application.namePrefix}argocd annotations: -<#if config.features.mail.active?? && config.features.mail.active> - notifications.argoproj.io/subscribe.email: ${config.features.argocd.emailToUser} - spec: description: Contains examples of end-user applications destinations: @@ -21,11 +18,9 @@ spec: # allow to only see application resources from the specified namespace sourceNamespaces: - - '${config.application.namePrefix}example-apps-staging' - - '${config.application.namePrefix}example-apps-production' - <#if config.features.argocd.operator> - - '${config.application.namePrefix}argocd' - + - ${config.application.namePrefix}example-apps-staging + - ${config.application.namePrefix}example-apps-production + - ${config.application.namePrefix}argocd # Allow all namespaced-scoped resources to be created @@ -34,4 +29,4 @@ spec: kind: '*' # Deny all cluster-scoped resources from being created. Least privilege. - clusterResourceWhitelist: \ No newline at end of file + clusterResourceWhitelist: diff --git a/examples/example-apps-via-content-loader/argocd/example-apps/apps/nginx-helm-umbrella/Chart.yaml b/examples/example-apps-via-content-loader/argocd/example-apps/apps/nginx-helm-umbrella/Chart.yaml deleted file mode 100644 index a585d698d..000000000 --- a/examples/example-apps-via-content-loader/argocd/example-apps/apps/nginx-helm-umbrella/Chart.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v2 -version: 13.2.21 -name: nginx -dependencies: - - name: nginx - version: 13.2.21 - repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami \ No newline at end of file diff --git a/examples/example-apps-via-content-loader/argocd/example-apps/apps/nginx-helm-umbrella/values.ftl.yaml b/examples/example-apps-via-content-loader/argocd/example-apps/apps/nginx-helm-umbrella/values.ftl.yaml deleted file mode 100644 index 554b3a5ca..000000000 --- a/examples/example-apps-via-content-loader/argocd/example-apps/apps/nginx-helm-umbrella/values.ftl.yaml +++ /dev/null @@ -1,43 +0,0 @@ -<#assign DockerImageParser=statics['com.cloudogu.gitops.utils.DockerImageParser']> -nginx: -<#if config.content.variables.images.nginx?has_content> -<#assign nginxImageObject = DockerImageParser.parse(config.content.variables.images.nginx)> - image: - registry: ${nginxImageObject.registry} - repository: ${nginxImageObject.repository} - tag: ${nginxImageObject.tag} -<#else> - image: - repository: bitnamilegacy/nginx - - - <#if config.registry.createImagePullSecrets == true> - - global: - imagePullSecrets: - - proxy-registry - - service: - ports: - http: 80 - type: <#if config.application.remote>LoadBalancer<#else>ClusterIP -<#if config.application.podResources == true> - resources: - limits: - cpu: 100m - memory: 30Mi - requests: - cpu: 30m - memory: 15Mi - - -<#if config.content.variables.nginx.baseDomain?has_content> - ingress: - enabled: true - pathType: Prefix - <#if config.application.urlSeparatorHyphen> - hostname: production-nginx-helm-umbrella-${config.content.variables.nginx.baseDomain} - <#else> - hostname: production.nginx-helm-umbrella.${config.content.variables.nginx.baseDomain} - - diff --git a/examples/example-apps-via-content-loader/argocd/example-apps/argocd/misc.ftl.yaml b/examples/example-apps-via-content-loader/argocd/example-apps/argocd/misc.ftl.yaml index 09aea4331..9af26c713 100644 --- a/examples/example-apps-via-content-loader/argocd/example-apps/argocd/misc.ftl.yaml +++ b/examples/example-apps-via-content-loader/argocd/example-apps/argocd/misc.ftl.yaml @@ -15,6 +15,7 @@ spec: source: path: misc/ repoURL: ${scm.repoUrl}argocd/example-apps.git + repoURL: "http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/example-apps" targetRevision: main directory: recurse: true diff --git a/examples/example-apps-via-content-loader/argocd/helm-umbrella/README.md b/examples/example-apps-via-content-loader/argocd/helm-umbrella/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/examples/example-apps-via-content-loader/config.yaml b/examples/example-apps-via-content-loader/config.yaml index ce4f90854..44689aa01 100644 --- a/examples/example-apps-via-content-loader/config.yaml +++ b/examples/example-apps-via-content-loader/config.yaml @@ -44,4 +44,4 @@ content: yamllint: "cytopia/yamllint:1.25-0.7" nginx: "" petclinic: "eclipse-temurin:17-jre-alpine" - maven: "" + maven: "" \ 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 75ac53c4d..94cd79e6e 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/argocd/ArgoCD.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/argocd/ArgoCD.groovy @@ -197,6 +197,12 @@ class ArgoCD extends Feature { FileSystemUtils.deleteFile clusterResourcesInitializationAction.repo.getAbsoluteLocalRepoTmpDir() + MONITORING_RESOURCES_PATH + 'ingress-nginx-dashboard-requests-handling.yaml' } + if (!config.scmm.internal) { + String externalScmmUrl = ScmUrlResolver.externalHost(config) + log.debug("Configuring all yaml files in gitops repos to use the external scmm url: ${externalScmmUrl}") + replaceFileContentInYamls(new File(clusterResourcesInitializationAction.repo.getAbsoluteLocalRepoTmpDir()), scmmUrlInternal, externalScmmUrl) + + } } private void deployWithHelm() { diff --git a/src/test/groovy/com/cloudogu/gitops/features/ScmManagerSetupTest.groovy b/src/test/groovy/com/cloudogu/gitops/features/ScmManagerSetupTest.groovy index dd13fe5d3..10f6bc5c8 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/ScmManagerSetupTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/ScmManagerSetupTest.groovy @@ -108,7 +108,6 @@ class ScmManagerSetupTest { assertThat(env['INSTALL_ARGOCD']).isEqualTo('true') assertThat(env['NAME_PREFIX']).isEqualTo('foo-') assertThat(env['INSECURE']).isEqualTo('false') - assertThat(env['CONTENT_EXAMPLES']).isEqualTo('false') assertThat(env['SKIP_PLUGINS']).isEqualTo('true') assertThat(env['SKIP_RESTART']).isEqualTo('true') } 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 0cbe270c1..243b922b3 100644 --- a/src/test/groovy/com/cloudogu/gitops/features/argocd/ArgoCDTest.groovy +++ b/src/test/groovy/com/cloudogu/gitops/features/argocd/ArgoCDTest.groovy @@ -65,7 +65,12 @@ class ArgoCDTest { useDedicatedInstance: false ], content: [ - examples: true + examples: true, + variables: [ + images: [ + buildImages + [petclinic: 'petclinic-value'] + ] + ] ], features: [ argocd : [ From 6a828d54fcdb534dc88b1a847af68b9b9028da53 Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Mon, 27 Oct 2025 15:59:25 +0100 Subject: [PATCH 14/21] add config.yaml referenced origin feature branch until it get merged back to main for test evaluation --- examples/example-apps-via-content-loader/config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example-apps-via-content-loader/config.yaml b/examples/example-apps-via-content-loader/config.yaml index 44689aa01..351888eb6 100644 --- a/examples/example-apps-via-content-loader/config.yaml +++ b/examples/example-apps-via-content-loader/config.yaml @@ -23,7 +23,7 @@ content: createJenkinsJob: true - url: https://github.com/cloudogu/gitops-playground path: examples/example-apps-via-content-loader/ - ref: main + ref: feature/extract-example-apps templating: true type: FOLDER_BASED overwriteMode: UPGRADE From bbbfa5af7560fe2e7052720b294f3a2e1bb3dd4c Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Wed, 12 Nov 2025 15:56:07 +0100 Subject: [PATCH 15/21] add cli argument --multi-tenancy-examples to enable multi tenancy --- examples/init-multi-tenancy/managementConfig.yaml | 3 ++- .../cloudogu/gitops/cli/GitopsPlaygroundCli.groovy | 12 ++++++++++-- .../groovy/com/cloudogu/gitops/config/Config.groovy | 4 ++-- .../cloudogu/gitops/config/ConfigConstants.groovy | 2 ++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/examples/init-multi-tenancy/managementConfig.yaml b/examples/init-multi-tenancy/managementConfig.yaml index 5203aaa34..76588607f 100644 --- a/examples/init-multi-tenancy/managementConfig.yaml +++ b/examples/init-multi-tenancy/managementConfig.yaml @@ -25,7 +25,8 @@ content: - url: https://github.com/cloudogu/gop-helm target: 3rd-party-dependencies/gop-helm overwriteMode: RESET - - url: file:///home/cl-pc-0087/src/gitops-playground + - url: https://github.com/cloudogu/gitops-playground +# - url: file:///home/cl-pc-0087/src/gitops-playground path: examples/init-multi-tenancy ref: feature/init-multi-tenancy templating: true diff --git a/src/main/groovy/com/cloudogu/gitops/cli/GitopsPlaygroundCli.groovy b/src/main/groovy/com/cloudogu/gitops/cli/GitopsPlaygroundCli.groovy index 1b48725fd..2d32c8a19 100644 --- a/src/main/groovy/com/cloudogu/gitops/cli/GitopsPlaygroundCli.groovy +++ b/src/main/groovy/com/cloudogu/gitops/cli/GitopsPlaygroundCli.groovy @@ -189,10 +189,12 @@ class GitopsPlaygroundCli { String configFilePath = cliParams.application.configFile String configMapName = cliParams.application.configMap Boolean contentExamples = cliParams.content.examples + Boolean multiTenancyExamples = cliParams.content.multitenancyExamples Map configFile = [:] Map configMap = [:] Map contentExamplesFile = [:] + Map multiTenancyContentExamplesFile = [:] if (configFilePath) { log.debug("Reading config file ${configFilePath}") @@ -205,14 +207,20 @@ class GitopsPlaygroundCli { configMap = validateConfig(configValues) } - if(contentExamples) { + if (contentExamples) { String contentExamplesConfigPath = "examples/example-apps-via-content-loader/config.yaml" log.debug("Adding example-apps-via-content-loader configuration from '${contentExamplesConfigPath}'") contentExamplesFile = validateConfig(new File(contentExamplesConfigPath).text) } + if (multiTenancyExamples) { + String multiTenancyContentExamplesConfigPath = "examples/init-multi-tenancy/managementConfig.yaml" + log.debug("Adding multi tenancy example-apps config loader from '${multiTenancyContentExamplesConfigPath}'") + multiTenancyContentExamplesFile = validateConfig(new File(multiTenancyContentExamplesConfigPath).text) + } + // Last one takes precedence - def configPrecedence = [configMap, configFile, contentExamplesFile] + def configPrecedence = [configMap, configFile, contentExamplesFile, multiTenancyContentExamplesFile] Map mergedConfigs = [:] configPrecedence.each { deepMerge(it, mergedConfigs) diff --git a/src/main/groovy/com/cloudogu/gitops/config/Config.groovy b/src/main/groovy/com/cloudogu/gitops/config/Config.groovy index 019058019..d1060ec4f 100644 --- a/src/main/groovy/com/cloudogu/gitops/config/Config.groovy +++ b/src/main/groovy/com/cloudogu/gitops/config/Config.groovy @@ -88,8 +88,8 @@ class Config { @JsonPropertyDescription(CONTENT_EXAMPLES_DESCRIPTION) Boolean examples = false - @Option(names = ['--multi-tenancy-examples'], description = CONTENT_EXAMPLES_DESCRIPTION) - @JsonPropertyDescription(CONTENT_EXAMPLES_DESCRIPTION) + @Option(names = ['--multi-tenancy-examples'], description = CONTENT_MULTI_TENANCY_EXAMPLES_DESCRIPTION) + @JsonPropertyDescription(CONTENT_MULTI_TENANCY_EXAMPLES_DESCRIPTION) Boolean multitenancyExamples = false @JsonPropertyDescription(CONTENT_NAMESPACES_DESCRIPTION) diff --git a/src/main/groovy/com/cloudogu/gitops/config/ConfigConstants.groovy b/src/main/groovy/com/cloudogu/gitops/config/ConfigConstants.groovy index e9408c5d9..d319da958 100644 --- a/src/main/groovy/com/cloudogu/gitops/config/ConfigConstants.groovy +++ b/src/main/groovy/com/cloudogu/gitops/config/ConfigConstants.groovy @@ -29,6 +29,8 @@ interface ConfigConstants { // ContentLoader String CONTENT_EXAMPLES_DESCRIPTION = 'Deploy example content: source repos, GitOps repos, Jenkins Job, Argo CD apps/project' + String CONTENT_MULTI_TENANCY_EXAMPLES_DESCRIPTION = "Deploy multi tenancy example content: source repos, GitOps repos, Jenkins Job, Argo CD apps/project" + String CONTENT_NAMESPACES_DESCRIPTION = 'Additional kubernetes namespaces. These are authorized to Argo CD, supplied with image pull secrets, monitored by prometheus, etc. Namespaces can be templates, e.g. ${config.application.namePrefix}staging' String CONTENT_REPO_DESCRIPTION = "ContentLoader repos to push into target environment" String CONTENT_REPO_URL_DESCRIPTION = "URL of the content repo. Mandatory for each type." From effc8bbcb4d7e6668a8431ef3b3cf31847585d1c Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Mon, 24 Nov 2025 16:04:02 +0100 Subject: [PATCH 16/21] small adjustments: remove umbrella and scmm condition --- .../argocd/helm-umbrella/README.md | 0 .../argocd/cluster-resources/argocd/mt-appset.yaml | 4 ++-- .../com/cloudogu/gitops/features/argocd/ArgoCD.groovy | 6 ------ 3 files changed, 2 insertions(+), 8 deletions(-) delete mode 100644 examples/example-apps-via-content-loader/argocd/helm-umbrella/README.md diff --git a/examples/example-apps-via-content-loader/argocd/helm-umbrella/README.md b/examples/example-apps-via-content-loader/argocd/helm-umbrella/README.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml index 44d67d989..8c6277713 100644 --- a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml +++ b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml @@ -19,10 +19,10 @@ spec: spec: project: argocd sources: - - repoURL: http://scmm.scm-manager.svc.cluster.local/scm/repo/argocd/tenant-configs + - repoURL: ${scm.repoUrl}argocd/tenant-configs.git targetRevision: HEAD ref: valuesRef - - repoURL: http://scmm.scm-manager.svc.cluster.local/scm/repo/3rd-party-dependencies/gop-helm + - repoURL: ${scm.repoUrl}3rd-party-dependencies/gop-helm.git path: . targetRevision: HEAD helm: 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 94cd79e6e..75ac53c4d 100644 --- a/src/main/groovy/com/cloudogu/gitops/features/argocd/ArgoCD.groovy +++ b/src/main/groovy/com/cloudogu/gitops/features/argocd/ArgoCD.groovy @@ -197,12 +197,6 @@ class ArgoCD extends Feature { FileSystemUtils.deleteFile clusterResourcesInitializationAction.repo.getAbsoluteLocalRepoTmpDir() + MONITORING_RESOURCES_PATH + 'ingress-nginx-dashboard-requests-handling.yaml' } - if (!config.scmm.internal) { - String externalScmmUrl = ScmUrlResolver.externalHost(config) - log.debug("Configuring all yaml files in gitops repos to use the external scmm url: ${externalScmmUrl}") - replaceFileContentInYamls(new File(clusterResourcesInitializationAction.repo.getAbsoluteLocalRepoTmpDir()), scmmUrlInternal, externalScmmUrl) - - } } private void deployWithHelm() { From 09ecfa206272c6a8cff05f0fd380b05357d52dbf Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Tue, 25 Nov 2025 11:01:42 +0100 Subject: [PATCH 17/21] make appset templateable and add nameprefix --- .../argocd/{mt-appset.yaml => mt-appset.ftl.yaml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename examples/init-multi-tenancy/argocd/cluster-resources/argocd/{mt-appset.yaml => mt-appset.ftl.yaml} (95%) diff --git a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml similarity index 95% rename from examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml rename to examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml index 8c6277713..cbc1cae3a 100644 --- a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.yaml +++ b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml @@ -2,7 +2,7 @@ apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: gop-multi-tenancy - namespace: argocd + namespace: ${config.application.namePrefix}argocd spec: goTemplate: true goTemplateOptions: From 865fced88688ea5d84a7fd800ac1a5e4f929f73f Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Tue, 25 Nov 2025 15:50:23 +0100 Subject: [PATCH 18/21] add name-prefix to appset and add useDedicatedInstances --- .../argocd/cluster-resources/argocd/mt-appset.ftl.yaml | 4 ++-- .../argocd/tenant-configs/tenants/globalValues.yaml | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml index cbc1cae3a..c68318500 100644 --- a/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml +++ b/examples/init-multi-tenancy/argocd/cluster-resources/argocd/mt-appset.ftl.yaml @@ -9,7 +9,7 @@ spec: - missingkey=error generators: - git: - repoURL: http://scmm.scm-manager.svc.cluster.local/scm/repo/argocd/tenant-configs + repoURL: ${scm.repoUrl}argocd/tenant-configs.git revision: HEAD files: - path: "tenants/*/config.yaml" @@ -31,7 +31,7 @@ spec: - $valuesRef/{{ .path.path }}/config.yaml destination: server: https://kubernetes.default.svc - namespace: argocd + namespace: ${config.application.namePrefix}argocd syncPolicy: automated: selfHeal: true diff --git a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/globalValues.yaml b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/globalValues.yaml index 8d93bf971..e0e0d9679 100644 --- a/examples/init-multi-tenancy/argocd/tenant-configs/tenants/globalValues.yaml +++ b/examples/init-multi-tenancy/argocd/tenant-configs/tenants/globalValues.yaml @@ -21,3 +21,5 @@ config: resourceInclusionsCluster: "https://10.43.0.1:443" ingressNginx: active: false +multiTenant: + useDedicatedInstance: true \ No newline at end of file From 88e6b9a0f6465e8348515a0b420a1c5c6dae4aa6 Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Wed, 26 Nov 2025 09:19:38 +0100 Subject: [PATCH 19/21] regenerate schema to make tests work again --- docs/configuration.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.schema.json b/docs/configuration.schema.json index 7193f603c..398dc8280 100644 --- a/docs/configuration.schema.json +++ b/docs/configuration.schema.json @@ -138,7 +138,7 @@ }, "multitenancyExamples" : { "type" : [ "boolean", "null" ], - "description" : "Deploy example content: source repos, GitOps repos, Jenkins Job, Argo CD apps/project" + "description" : "Deploy multi tenancy example content: source repos, GitOps repos, Jenkins Job, Argo CD apps/project" }, "namespaces" : { "description" : "Additional kubernetes namespaces. These are authorized to Argo CD, supplied with image pull secrets, monitored by prometheus, etc. Namespaces can be templates, e.g. ${config.application.namePrefix}staging", From 4095901b3362d79700ad6c6ef48167f303d5ed4a Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Wed, 26 Nov 2025 13:25:42 +0100 Subject: [PATCH 20/21] solve incorrect merged file --- .../argocd/example-apps/argocd/misc.ftl.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/example-apps-via-content-loader/argocd/example-apps/argocd/misc.ftl.yaml b/examples/example-apps-via-content-loader/argocd/example-apps/argocd/misc.ftl.yaml index 9af26c713..09aea4331 100644 --- a/examples/example-apps-via-content-loader/argocd/example-apps/argocd/misc.ftl.yaml +++ b/examples/example-apps-via-content-loader/argocd/example-apps/argocd/misc.ftl.yaml @@ -15,7 +15,6 @@ spec: source: path: misc/ repoURL: ${scm.repoUrl}argocd/example-apps.git - repoURL: "http://scmm.${config.application.namePrefix}scm-manager.svc.cluster.local/scm/repo/${config.application.namePrefix}argocd/example-apps" targetRevision: main directory: recurse: true From 2f38cb89f1b601977ea9777b1fc37d928d74d17d Mon Sep 17 00:00:00 2001 From: Marco Droll Date: Wed, 26 Nov 2025 13:36:32 +0100 Subject: [PATCH 21/21] solve failing jenkins --- examples/example-apps-via-content-loader/config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example-apps-via-content-loader/config.yaml b/examples/example-apps-via-content-loader/config.yaml index 351888eb6..44689aa01 100644 --- a/examples/example-apps-via-content-loader/config.yaml +++ b/examples/example-apps-via-content-loader/config.yaml @@ -23,7 +23,7 @@ content: createJenkinsJob: true - url: https://github.com/cloudogu/gitops-playground path: examples/example-apps-via-content-loader/ - ref: feature/extract-example-apps + ref: main templating: true type: FOLDER_BASED overwriteMode: UPGRADE