diff --git a/CHANGELOG.md b/CHANGELOG.md index 261ddd7d..1f63d045 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- use ecosystem-core instead of k8e-ces-setup to install cluster + + ## [4.3.0](https://github.com/cloudogu/ces-build-lib/releases/tag/4.3.0) - 2025-08-21 ### Changed - Updates the BATS shell test image to 1.12 which supports the `--report-formatter` switch @@ -256,6 +259,4 @@ the login data used for the dogu-registry; #75 - Add gpg class to perform gpp based task such as signing; #64 - Add option to upload artifacts to a GitHub release; #64 -## v0.0.1 - v1.47.1 / previous versions - -Up till version v1.47.1 there was no change log +## v0.0.1 - v1.47.1 / diff --git a/src/com/cloudogu/ces/cesbuildlib/K3d.groovy b/src/com/cloudogu/ces/cesbuildlib/K3d.groovy index beaaf5fc..e8ad36b6 100644 --- a/src/com/cloudogu/ces/cesbuildlib/K3d.groovy +++ b/src/com/cloudogu/ces/cesbuildlib/K3d.groovy @@ -1,6 +1,7 @@ package com.cloudogu.ces.cesbuildlib import com.cloudbees.groovy.cps.NonCPS +import groovy.json.JsonSlurper class K3d { /** @@ -12,10 +13,17 @@ class K3d { */ private static String K3D_VERSION = "5.6.0" private static String K3D_LOG_FILENAME = "k8sLogs" - private static String K3D_SETUP_JSON_FILE = "k3d_setup.json" private static String K3D_VALUES_YAML_FILE = "k3d_values.yaml" + private static String K3D_BLUEPRINT_FILE = "k3d_blueprint.yaml" private static String YQ_VERSION = "4.40.5" + private static String VERSION_ECOSYSTEM_CORE = "1.2.0" + private static String VERSION_K8s_COMPONENT_OPERATOR_CRD = "1.10.1" + private static String VERSION_K8S_DOGU_OPERATOR = "3.15.0" + private static String VERSION_K8S_DOGU_OPERATOR_CRD = "2.10.0" + private static String VERSION_K8S_BLUEPRINT_OPERATOR = "3.0.2" + private static String VERSION_K8S_BLUEPRINT_OPERATOR_CRD = "3.1.0" + private String clusterName private script private String path @@ -36,14 +44,14 @@ class K3d { adminGroup : "CesAdministrators", dependencies : ["official/ldap", "official/cas", - "k8s/nginx-ingress", - "k8s/nginx-static", "official/postfix", "official/usermgt"], defaultDogu : "", additionalDependencies : [], registryConfig : "", - registryConfigEncrypted: "" + registryConfigEncrypted: "", + "enableBackup" : false, + "enableMonitoring" : false ] String getRegistryName() { @@ -254,15 +262,53 @@ class K3d { } } - void configureSetupJson(config = [:]) { - String setupJsonConfigKey = ".setup_json" + /** + * override component versions + */ + static void setComponentVersions(String dogu_op = VERSION_K8S_DOGU_OPERATOR, String dogu_op_crd = VERSION_K8S_DOGU_OPERATOR_CRD, String blue_op = VERSION_K8S_BLUEPRINT_OPERATOR, String blue_op_crd = VERSION_K8S_BLUEPRINT_OPERATOR_CRD) { + if (dogu_op != null) { + VERSION_K8S_DOGU_OPERATOR = dogu_op + } + if (dogu_op_crd != null) { + VERSION_K8S_DOGU_OPERATOR_CRD = dogu_op_crd + } + if (blue_op != null) { + VERSION_K8S_BLUEPRINT_OPERATOR = blue_op + } + if (blue_op_crd != null) { + VERSION_K8S_BLUEPRINT_OPERATOR_CRD = blue_op_crd + } + } - script.echo "configuring setup..." + void configureEcosystemCoreValues(config = [:]) { // Merge default config with the one passed as parameter config = defaultSetupConfig << config - writeSetupJson(config) - appendFileToYamlFile(K3D_VALUES_YAML_FILE, setupJsonConfigKey, K3D_SETUP_JSON_FILE) + yqEvalYamlFile(K3D_VALUES_YAML_FILE, ".defaultConfig.env.waitTimeoutMinutes = 5") + appendToYamlFile(K3D_VALUES_YAML_FILE, ".components.k8s-dogu-operator-crd.version", VERSION_K8S_DOGU_OPERATOR_CRD) + appendToYamlFile(K3D_VALUES_YAML_FILE, ".components.k8s-dogu-operator.version", VERSION_K8S_DOGU_OPERATOR) + + appendToYamlFile(K3D_VALUES_YAML_FILE, ".components.k8s-blueprint-operator-crd.version", VERSION_K8S_BLUEPRINT_OPERATOR_CRD) + appendToYamlFile(K3D_VALUES_YAML_FILE, ".components.k8s-blueprint-operator.version", VERSION_K8S_BLUEPRINT_OPERATOR) + + yqEvalYamlFile(K3D_VALUES_YAML_FILE, ".components.k8s-ces-control.disabled = true") + + yqEvalYamlFile(K3D_VALUES_YAML_FILE, ".components.k8s-blueprint-operator.valuesObject.healthConfig.components.required = [{\\\"name\\\": \\\"k8s-dogu-operator\\\"}, {\\\"name\\\": \\\"k8s-service-discovery\\\"}]") + + + appendToYamlFile(K3D_VALUES_YAML_FILE, ".components.k8s-service-discovery.valuesObject.loadBalancerService.internalTrafficPolicy", "Cluster") + appendToYamlFile(K3D_VALUES_YAML_FILE, ".components.k8s-service-discovery.valuesObject.loadBalancerService.externalTrafficPolicy", "Cluster") + + yqEvalYamlFile(K3D_VALUES_YAML_FILE, ".backup.enabled = ${config.enableBackup}") + yqEvalYamlFile(K3D_VALUES_YAML_FILE, ".monitoring.enabled = ${config.enableMonitoring}") + + script.echo "configuring ecosystem core..." + writeBlueprintYaml(config) + } + + @Deprecated + void configureSetupJson(config = [:]) { + configureEcosystemCoreValues(config) } void configureSetupImage(String image) { @@ -320,22 +366,30 @@ class K3d { helm("registry login ${registryUrl} --username '${script.env.HARBOR_USERNAME}' --password '${script.env.HARBOR_PASSWORD}'") } - helm("install -f ${K3D_VALUES_YAML_FILE} k8s-ces-setup oci://${registryUrl}/${registryNamespace}/k8s-ces-setup --version ${tag} --namespace default") - helm("registry logout ${registryUrl}") + // install crd first + helm("install k8s-component-operator-crd oci://${registryUrl}/${registryNamespace}/k8s-component-operator-crd --version ${VERSION_K8s_COMPONENT_OPERATOR_CRD} --namespace default") - script.echo "Wait for dogu-operator to be ready..." - waitForDeploymentRollout("k8s-dogu-operator-controller-manager", timeout, interval) + kubectl("--namespace default create configmap global-config --from-literal=config.yaml='fqdn: ${externalIP}'") + + helm("install -f ${K3D_VALUES_YAML_FILE} ecosystem-core oci://${registryUrl}/${registryNamespace}/ecosystem-core --version ${VERSION_ECOSYSTEM_CORE} --namespace default --timeout 15m") + + script.echo "Wait for blueprint-operator to be ready..." + waitForDeploymentRollout("k8s-blueprint-operator-controller-manager", timeout, interval) + + kubectl("apply -f ${K3D_BLUEPRINT_FILE} --namespace default") script.echo "Wait for setup-finisher to be executed..." waitForSetupToFinish(timeout, interval) script.echo "Wait for dogus to be ready..." waitForDogusToBeRolledOut(timeout, interval) + + helm("registry logout ${registryUrl}") } void waitForDogusToBeRolledOut(Integer timeout, Integer interval) { String dogus = kubectl("get dogus --template '{{range .items}}{{.metadata.name}}{{\"\\n\"}}{{end}}'", true) - String[] doguList = dogus.split("\n") + String[] doguList = dogus.trim().split("\n") for (String dogu : doguList) { script.echo "Wait for $dogu to be rolled out..." waitForDeploymentRollout(dogu, timeout, interval) @@ -345,13 +399,14 @@ class K3d { void waitForSetupToFinish(Integer timeout, Integer interval) { for (int i = 0; i < timeout / interval; i++) { script.sh("sleep ${interval}s") - String deploys = kubectl("get deployments --template '{{range .items}}{{.metadata.name}}{{\"\\n\"}}{{end}}'", true) - if (!deploys.contains("k8s-ces-setup")) { + String blueprintReady = kubectl("get blueprint -n=default blueprint-ces-module -o jsonpath='{.status.conditions[?(@.type==\"EcosystemHealthy\")].status}{\" \"}{.status.conditions[?(@.type==\"Completed\")].status}'", true) + script.echo blueprintReady + if (blueprintReady == "True True") { return } } - this.script.error "failed to wait for setup to finish: timeout" + this.script.error "failed to wait for ecosystem-core setup to finish: timeout" } /** @@ -363,7 +418,7 @@ class K3d { */ void setup(String tag, config = [:], Integer timout = 300, Integer interval = 5) { assignExternalIP() - configureSetupJson(config) + configureEcosystemCoreValues(config) installAndTriggerSetup(tag, timout, interval) } @@ -606,66 +661,90 @@ data: return [registryIp, registryPort] } - static String formatDependencies(List deps) { + String formatDependencies(List deps) { String formatted = "" - for (int i = 0; i < deps.size(); i++) { - formatted += "\"${deps[i]}\"" - + String[] parts = deps[i].split(":") + String version; + // "latest" needs to be replaced with actual last version + if (parts.length != 2 || parts[1] == "latest") { + String tags = "{}"; + script.withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: this.backendCredentialsID, usernameVariable: 'TOKEN_ID', passwordVariable: 'TOKEN_SECRET']]) { + tags = this.sh.returnStdOut("curl https://registry.cloudogu.com/v2/${parts[0]}/tags/list -u ${script.env.TOKEN_ID}:${script.env.TOKEN_SECRET}").trim() + } + def obj = new JsonSlurper().parseText(tags) + version = obj.tags.max { t -> parseTag("${t}") } + } else { + version = parts[1] + } + formatted += " - name: ${parts[0]}\n" + + " version: ${version}" if ((i + 1) < deps.size()) { - formatted += ', ' + formatted += '\n' } } return formatted } - private void writeSetupJson(config) { - List deps = config.dependencies + config.additionalDependencies - String formattedDeps = formatDependencies(deps) + private String parseTag(String tag) { + def m = (tag =~ /^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-(\d+))?$/) + if (!m.matches()) { + // Fallback: set all to 0 to ingnore invalid tags + return "00000.00000.00000.00000" + } + def major = (m[0][1] ?: "0") as int + def minor = (m[0][2] ?: "0") as int + def patch = (m[0][3] ?: "0") as int + def build = (m[0][4] ?: "0") as int - script.writeFile file: K3D_SETUP_JSON_FILE, text: """ -{ - "naming":{ - "fqdn":"${externalIP}", - "hostname":"ces", - "domain":"ces.local", - "certificateType":"selfsigned", - "relayHost":"mail.ces.local", - "completed":true - }, - "dogus":{ - "defaultDogu":"${config.defaultDogu}", - "install":[ - ${formattedDeps} - ], - "completed":true - }, - "admin":{ - "username":"${config.adminUsername}", - "mail":"ces-admin@cloudogu.com", - "password":"${config.adminPassword}", - "adminGroup":"${config.adminGroup}", - "adminMember":true, - "completed":true - }, - "userBackend":{ - "port":"389", - "useUserConnectionToFetchAttributes":true, - "dsType":"embedded", - "attributeID":"uid", - "attributeFullname":"cn", - "attributeMail":"mail", - "attributeGroup":"memberOf", - "searchFilter":"(objectClass=person)", - "host":"ldap", - "completed":true - }, - "registryConfig": {${config.registryConfig}}, - "registryConfigEncrypted": {${config.registryConfigEncrypted}} -}""" + // Zero-padding → lexicographically sortable + return sprintf("%05d.%05d.%05d.%05d", major, minor, patch, build) } + private void writeBlueprintYaml(config) { + List deps = config.dependencies + config.additionalDependencies + String formattedDeps = formatDependencies(deps) + script.writeFile file: K3D_BLUEPRINT_FILE, text: """ +apiVersion: k8s.cloudogu.com/v3 +kind: Blueprint +metadata: + labels: + app: ces + app.kubernetes.io/name: k8s-blueprint-lib + name: blueprint-ces-module + namespace: default +spec: + displayName: "Blueprint K3D CES-Module" + blueprint: + dogus: +${formattedDeps} + config: + dogus: + ldap: + - key: admin_username + value: "${config.adminUsername}" + - key: admin_mail + value: "ces-admin@cloudogu.com" + - key: admin_member + value: "true" + - key: admin_password + value: "${config.adminPassword}" + global: + - key: fqdn + value: "${externalIP}" + - key: domain + value: "ces.local" + - key: certificate/type + value: "selfsigned" + - key: k8s/use_internal_ip + value: "false" + - key: internalIp + value: "" + - key: admin_group + value: "${config.adminGroup}" +""" + } /** * Collects all necessary resources and log information used to identify problems with our kubernetes cluster. @@ -677,7 +756,9 @@ data: script.deleteDir() } script.sh("rm -rf ${K3D_LOG_FILENAME}.zip".toString()) - script.sh("rm -rf ${K3D_SETUP_JSON_FILE}".toString()) + script.archiveArtifacts(artifacts: K3D_BLUEPRINT_FILE) + script.sh("rm -rf ${K3D_BLUEPRINT_FILE}".toString()) + script.archiveArtifacts(artifacts: K3D_VALUES_YAML_FILE) script.sh("rm -rf ${K3D_VALUES_YAML_FILE}".toString()) collectResourcesSummaries() diff --git a/test/com/cloudogu/ces/cesbuildlib/K3dTest.groovy b/test/com/cloudogu/ces/cesbuildlib/K3dTest.groovy index 60a456e1..6138c74f 100644 --- a/test/com/cloudogu/ces/cesbuildlib/K3dTest.groovy +++ b/test/com/cloudogu/ces/cesbuildlib/K3dTest.groovy @@ -214,16 +214,25 @@ class K3dTest { def workspaceEnvDir = "leK3dWorkSpace" String tag = "v0.6.0" def scriptMock = new ScriptMock() + scriptMock.expectedShRetValueForScript.put("curl -H \"Metadata-Flavor: Google\" http://169.254.169.254/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip", "192.168.56.2") + scriptMock.expectedShRetValueForScript.put("curl https://registry.cloudogu.com/v2/official/ldap/tags/list -u null:null", "{\"tags\": [\"1.0.0\"]}") + scriptMock.expectedShRetValueForScript.put("curl https://registry.cloudogu.com/v2/official/cas/tags/list -u null:null", "{\"tags\": [\"2.0.0\"]}") + scriptMock.expectedShRetValueForScript.put("curl https://registry.cloudogu.com/v2/official/postfix/tags/list -u null:null", "{\"tags\": [\"3.0.0\"]}") + scriptMock.expectedShRetValueForScript.put("curl https://registry.cloudogu.com/v2/official/usermgt/tags/list -u null:null", "{\"tags\": [\"4.0.0\"]}") + + scriptMock.expectedShRetValueForScript.put("whoami", "jenkins") scriptMock.expectedShRetValueForScript.put("cat /etc/passwd | grep jenkins", "jenkins:x:1000:1000:jenkins,,,:/home/jenkins:/bin/bash") scriptMock.expectedShRetValueForScript.put("yq -i '.setup_json = load_str(\"k3d_setup.json\")' k3d_values.yaml", "foo") - scriptMock.expectedShRetValueForScript.put("curl -s https://raw.githubusercontent.com/cloudogu/k8s-ces-setup/${tag}/k8s/k8s-ces-setup.yaml".toString(), "fake setup yaml with {{ .Namespace }}") scriptMock.expectedShRetValueForScript.put("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl rollout status deployment/k8s-dogu-operator-controller-manager".toString(), "successfully rolled out") - scriptMock.expectedShRetValueForScript.put("curl -H \"Metadata-Flavor: Google\" http://169.254.169.254/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip", "192.168.56.2") + scriptMock.expectedShRetValueForScript.put("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl rollout status deployment/k8s-blueprint-operator-controller-manager".toString(), "successfully rolled out") + scriptMock.expectedShRetValueForScript.put("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl get blueprint -n=default blueprint-ces-module -o jsonpath='{.status.conditions[?(@.type==\"EcosystemHealthy\")].status}{\" \"}{.status.conditions[?(@.type==\"Completed\")].status}'".toString(), "True True") + + scriptMock.expectedShRetValueForScript.put("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl get deployments --template '{{range .items}}{{.metadata.name}}{{\"\\n\"}}{{end}}'".toString(), "k8s-dogu-operator\nk8s-service-discovery") - scriptMock.expectedShRetValueForScript.put("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl get dogus --template '{{range .items}}{{.metadata.name}}{{\"\\n\"}}{{end}}'".toString(), "cas\nnginx-ingress") + scriptMock.expectedShRetValueForScript.put("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl get dogus --template '{{range .items}}{{.metadata.name}}{{\"\\n\"}}{{end}}'".toString(), "cas\nldap") scriptMock.expectedShRetValueForScript.put("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl rollout status deployment/cas".toString(), "successfully rolled out") - scriptMock.expectedShRetValueForScript.put("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl rollout status deployment/nginx-ingress".toString(), "successfully rolled out") + scriptMock.expectedShRetValueForScript.put("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl rollout status deployment/ldap".toString(), "successfully rolled out") K3d sut = new K3d(scriptMock, "leWorkSpace", "leK3dWorkSpace", "path") @@ -232,31 +241,17 @@ class K3dTest { sut.setup(tag, [:], 1, 1) // then - assertThat(scriptMock.actualEcho.get(0)).isEqualTo("configuring setup...") - assertThat(scriptMock.actualEcho.get(1)).isEqualTo("create values.yaml for setup deployment") - assertThat(scriptMock.actualEcho.get(2)).isEqualTo("Installing setup...") - assertThat(scriptMock.actualEcho.get(3)).isEqualTo("Wait for dogu-operator to be ready...") - assertThat(scriptMock.actualEcho.get(4)).isEqualTo("Wait for setup-finisher to be executed...") - assertThat(scriptMock.actualEcho.get(5)).isEqualTo("Wait for dogus to be ready...") - assertThat(scriptMock.actualEcho.get(6)).isEqualTo("Wait for cas to be rolled out...") - assertThat(scriptMock.actualEcho.get(7)).isEqualTo("Wait for nginx-ingress to be rolled out...") - - assertThat(scriptMock.allActualArgs[0].trim()).isEqualTo("curl -H \"Metadata-Flavor: Google\" http://169.254.169.254/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip") - assertThat(scriptMock.allActualArgs[1].trim()).isEqualTo("whoami".trim()) - assertThat(scriptMock.allActualArgs[2].trim()).isEqualTo("cat /etc/passwd | grep jenkins".trim()) - assertThat(scriptMock.allActualArgs[3].trim()).isEqualTo("yq -i '.setup_json = load_str(\"k3d_setup.json\")' k3d_values.yaml".trim()) - assertThat(scriptMock.allActualArgs[4].trim()).isEqualTo("sudo KUBECONFIG=leK3dWorkSpace/.k3d/.kube/config helm registry login registry.cloudogu.com --username 'null' --password 'null'".trim()) - assertThat(scriptMock.allActualArgs[5].trim()).isEqualTo("sudo KUBECONFIG=leK3dWorkSpace/.k3d/.kube/config helm install -f k3d_values.yaml k8s-ces-setup oci://registry.cloudogu.com/k8s/k8s-ces-setup --version v0.6.0 --namespace default".trim()) - assertThat(scriptMock.allActualArgs[6].trim()).isEqualTo("sudo KUBECONFIG=leK3dWorkSpace/.k3d/.kube/config helm registry logout registry.cloudogu.com".trim()) - assertThat(scriptMock.allActualArgs[7].trim()).isEqualTo("sleep 1s") - assertThat(scriptMock.allActualArgs[8].trim()).isEqualTo("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl rollout status deployment/k8s-dogu-operator-controller-manager".trim()) - assertThat(scriptMock.allActualArgs[9].trim()).isEqualTo("sleep 1s") - assertThat(scriptMock.allActualArgs[10].trim()).isEqualTo("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl get deployments --template '{{range .items}}{{.metadata.name}}{{\"\\n\"}}{{end}}'") - assertThat(scriptMock.allActualArgs[11].trim()).isEqualTo("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl get dogus --template '{{range .items}}{{.metadata.name}}{{\"\\n\"}}{{end}}'") - assertThat(scriptMock.allActualArgs[12].trim()).isEqualTo("sleep 1s") - assertThat(scriptMock.allActualArgs[13].trim()).isEqualTo("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl rollout status deployment/cas") - assertThat(scriptMock.allActualArgs[14].trim()).isEqualTo("sleep 1s") - assertThat(scriptMock.allActualArgs[15].trim()).isEqualTo("sudo KUBECONFIG=${workspaceEnvDir}/.k3d/.kube/config kubectl rollout status deployment/nginx-ingress") + for (int i = 0; i < 10; i++) { + assertThat(scriptMock.actualEcho.get(i)).isEqualTo("create values.yaml for setup deployment") + } + assertThat(scriptMock.actualEcho.get(10)).isEqualTo("configuring ecosystem core...") + assertThat(scriptMock.actualEcho.get(11)).isEqualTo("Installing setup...") + assertThat(scriptMock.actualEcho.get(12)).isEqualTo("Wait for blueprint-operator to be ready...") + assertThat(scriptMock.actualEcho.get(13)).isEqualTo("Wait for setup-finisher to be executed...") + assertThat(scriptMock.actualEcho.get(14)).isEqualTo("True True") + assertThat(scriptMock.actualEcho.get(15)).isEqualTo("Wait for dogus to be ready...") + assertThat(scriptMock.actualEcho.get(16)).isEqualTo("Wait for cas to be rolled out...") + assertThat(scriptMock.actualEcho.get(17)).isEqualTo("Wait for ldap to be rolled out...") assertThat(scriptMock.writeFileParams.get(0)).isNotNull() String setupYaml = scriptMock.writeFileParams.get(1) @@ -273,6 +268,11 @@ class K3dTest { scriptMock.expectedShRetValueForScript.put("whoami", "jenkins") scriptMock.expectedShRetValueForScript.put("cat /etc/passwd | grep jenkins", "jenkins:x:1000:1000:jenkins,,,:/home/jenkins:/bin/bash") scriptMock.expectedShRetValueForScript.put("yq -i '.setup_json = load_str(\"k3d_setup.json\")' k3d_values.yaml", "fake") + scriptMock.expectedShRetValueForScript.put("curl -H \"Metadata-Flavor: Google\" http://169.254.169.254/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip", "192.168.56.2") + scriptMock.expectedShRetValueForScript.put("curl https://registry.cloudogu.com/v2/official/ldap/tags/list -u null:null", "{\"tags\": [\"1.0.0\"]}") + scriptMock.expectedShRetValueForScript.put("curl https://registry.cloudogu.com/v2/official/cas/tags/list -u null:null", "{\"tags\": [\"2.0.0\"]}") + scriptMock.expectedShRetValueForScript.put("curl https://registry.cloudogu.com/v2/official/postfix/tags/list -u null:null", "{\"tags\": [\"3.0.0\"]}") + scriptMock.expectedShRetValueForScript.put("curl https://registry.cloudogu.com/v2/official/usermgt/tags/list -u null:null", "{\"tags\": [\"4.0.0\"]}") K3d sut = new K3d(scriptMock, "leWorkSpace", "leK3dWorkSpace", "path") @@ -283,10 +283,10 @@ class K3dTest { } // then - assertThat(errorMsg.getMessage()).isEqualTo("failed to wait for deployment/k8s-dogu-operator-controller-manager rollout: timeout") + assertThat(errorMsg.getMessage()).isEqualTo("failed to wait for deployment/k8s-blueprint-operator-controller-manager rollout: timeout") - assertThat(scriptMock.actualEcho.get(0)).isEqualTo("configuring setup...") - assertThat(scriptMock.actualEcho.get(1)).isEqualTo("create values.yaml for setup deployment") + assertThat(scriptMock.actualEcho.get(10)).isEqualTo("configuring ecosystem core...") + assertThat(scriptMock.actualEcho.get(11)).isEqualTo("Installing setup...") assertThat(scriptMock.allActualArgs[0].trim()).isEqualTo("curl -H \"Metadata-Flavor: Google\" http://169.254.169.254/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip") assertThat(scriptMock.allActualArgs[1].trim()).isEqualTo("whoami".trim()) @@ -433,7 +433,7 @@ spec: int fileCounter = 0 assertThat(scriptMock.allActualArgs[i++].trim()).contains("called deleteDir()") assertThat(scriptMock.allActualArgs[i++].trim()).contains("rm -rf k8sLogs.zip") - assertThat(scriptMock.allActualArgs[i++].trim()).contains("rm -rf k3d_setup.json") + assertThat(scriptMock.allActualArgs[i++].trim()).contains("rm -rf k3d_blueprint.yaml") assertThat(scriptMock.allActualArgs[i++].trim()).contains("rm -rf k3d_values.yaml") assertThat(scriptMock.allActualArgs[i++].trim()).contains("sudo KUBECONFIG=leK3dWorkSpace/.k3d/.kube/config kubectl get persistentvolumeclaim --show-kind --ignore-not-found -l app=ces -o yaml || true") @@ -514,8 +514,10 @@ spec: assertThat(scriptMock.zipParams.size()).isEqualTo(1) assertThat(scriptMock.zipParams[0]).isEqualTo(["archive":"false", "dir":"k8sLogs", "zipFile":"k8sLogs.zip"]) - assertThat(scriptMock.archivedArtifacts.size()).isEqualTo(1) - assertThat(scriptMock.archivedArtifacts[0]).isEqualTo(["allowEmptyArchive":"true", "artifacts":"k8sLogs.zip"]) + assertThat(scriptMock.archivedArtifacts.size()).isEqualTo(3) + assertThat(scriptMock.archivedArtifacts[0]).isEqualTo(["artifacts":"k3d_blueprint.yaml"]) + assertThat(scriptMock.archivedArtifacts[1]).isEqualTo(["artifacts":"k3d_values.yaml"]) + assertThat(scriptMock.archivedArtifacts[2]).isEqualTo(["allowEmptyArchive":"true", "artifacts":"k8sLogs.zip"]) assertThat(scriptMock.allActualArgs.size()).isEqualTo(i) assertThat(scriptMock.writeFileParams.size()).isEqualTo(25) @@ -583,6 +585,69 @@ spec: assertThat(scriptMock.allActualArgs[8].trim()).isEqualTo("yq -i \".setup.image.tag = \\\"1.2.3\\\"\" k3d_values.yaml".trim()) } + @Test + void testK3d_parseTags() { + // given + def workspaceDir = "leWorkspace" + def k3dWorkspaceDir = "leK3dWorkSpace" + def scriptMock = new ScriptMock() + K3d sut = new K3d(scriptMock, workspaceDir, k3dWorkspaceDir, "path") + + scriptMock.expectedShRetValueForScript.put("curl https://registry.cloudogu.com/v2/official/ldap/tags/list -u null:null", "{\"tags\": [\"1.0.0\", \"1.0.1\"]}") + scriptMock.expectedShRetValueForScript.put("curl https://registry.cloudogu.com/v2/official/cas/tags/list -u null:null", "{\"tags\": [\"2.0.0\", \"invalid\", \"2.0.1\"]}") + + List deps = new ArrayList<>() + deps.add("official/cas") + deps.add("official/ldap:latest") + deps.add("official/usermgt:3.0.0") + + // when + String formatted = sut.formatDependencies(deps) + + // then + assertThat(scriptMock.allActualArgs[0].trim()).isEqualTo("curl https://registry.cloudogu.com/v2/official/cas/tags/list -u null:null".trim()) + assertThat(scriptMock.allActualArgs[1].trim()).isEqualTo("curl https://registry.cloudogu.com/v2/official/ldap/tags/list -u null:null".trim()) + assertThat(formatted.contains("cas\n version: 2.0.1")) + assertThat(formatted.contains("ldap\n version: 1.0.1")) + assertThat(formatted.contains("usermgt\n version: 3.0.0")) + + } + + @Test + void testK3d_setComponentVersion() { + // given + + // when + K3d.setComponentVersions("1.0.0", "2.0.0", "3.0.0", "4.0.0") + + // then + assertThat("1.0.0".equals(K3d.@VERSION_K8S_DOGU_OPERATOR)) + assertThat("2.0.0".equals(K3d.@VERSION_K8S_DOGU_OPERATOR_CRD)) + assertThat("3.0.0".equals(K3d.@VERSION_K8S_BLUEPRINT_OPERATOR)) + assertThat("4.0.0".equals(K3d.@VERSION_K8S_BLUEPRINT_OPERATOR_CRD)) + + K3d.setComponentVersions() + + // then + assertThat("1.0.0".equals(K3d.@VERSION_K8S_DOGU_OPERATOR)) + assertThat("2.0.0".equals(K3d.@VERSION_K8S_DOGU_OPERATOR_CRD)) + assertThat("3.0.0".equals(K3d.@VERSION_K8S_BLUEPRINT_OPERATOR)) + assertThat("4.0.0".equals(K3d.@VERSION_K8S_BLUEPRINT_OPERATOR_CRD)) + + K3d.@VERSION_K8S_DOGU_OPERATOR = "5.0.0" + K3d.@VERSION_K8S_DOGU_OPERATOR_CRD = "6.0.0" + K3d.@VERSION_K8S_BLUEPRINT_OPERATOR = "7.0.0" + K3d.@VERSION_K8S_BLUEPRINT_OPERATOR_CRD = "8.0.0" + + K3d.setComponentVersions(null, null, null, null) + + // then + assertThat("5.0.0".equals(K3d.@VERSION_K8S_DOGU_OPERATOR)) + assertThat("6.0.0".equals(K3d.@VERSION_K8S_DOGU_OPERATOR_CRD)) + assertThat("7.0.0".equals(K3d.@VERSION_K8S_BLUEPRINT_OPERATOR)) + assertThat("8.0.0".equals(K3d.@VERSION_K8S_BLUEPRINT_OPERATOR_CRD)) + } + @Test void testK3d_configureComponentOperatorVersion() { // given