|
| 1 | +#!/usr/bin/env bash |
| 2 | +set -euo pipefail |
| 3 | + |
| 4 | +log_info() { echo -e "ℹ️ $*" >&2; } |
| 5 | +log_success() { echo -e "✅ $*" >&2; } |
| 6 | +log_error() { echo -e "❌ $*" >&2; } |
| 7 | + |
| 8 | + |
| 9 | +run_che_ca_bundle_e2e() { |
| 10 | + local che_ns="$1" |
| 11 | + local dw_ns="$2" |
| 12 | + local dw_name="$3" |
| 13 | + local cert_count="${4:-500}" |
| 14 | + local bundle_file="${5:-custom-ca-certificates.pem}" |
| 15 | + |
| 16 | + check_namespaces "${che_ns}" "${dw_ns}" |
| 17 | + generate_dummy_certs "${cert_count}" "${bundle_file}" |
| 18 | + create_che_ca_configmap "${che_ns}" "${bundle_file}" |
| 19 | + patch_checluster_disable_pki_mount "${che_ns}" |
| 20 | + restart_che "${che_ns}" |
| 21 | + create_devworkspace "${dw_ns}" "${dw_name}" |
| 22 | + |
| 23 | + local pod |
| 24 | + pod=$(wait_for_workspace_pod "${dw_ns}" "${dw_name}") |
| 25 | + |
| 26 | + verify_ca_bundle_in_workspace "${pod}" "${dw_ns}" "${cert_count}" |
| 27 | + cleanup_resources "${dw_ns}" "${dw_name}" |
| 28 | +} |
| 29 | + |
| 30 | +check_namespaces() { |
| 31 | + local che_ns="$1" |
| 32 | + local dw_ns="$2" |
| 33 | + |
| 34 | + log_info "Checking namespaces..." |
| 35 | + kubectl get ns "${che_ns}" >/dev/null |
| 36 | + kubectl get ns "${dw_ns}" >/dev/null |
| 37 | +} |
| 38 | + |
| 39 | +generate_dummy_certs() { |
| 40 | + local cert_count="$1" |
| 41 | + local bundle_file="$2" |
| 42 | + |
| 43 | + log_info "Generating ${cert_count} dummy CA certificates..." |
| 44 | + rm -f "${bundle_file}" |
| 45 | + |
| 46 | + for i in $(seq 1 "${cert_count}"); do |
| 47 | + openssl req -x509 -newkey rsa:2048 -nodes -days 1 \ |
| 48 | + -subj "/CN=dummy-ca-${i}" \ |
| 49 | + -keyout "dummy-ca-${i}.key" \ |
| 50 | + -out "dummy-ca-${i}.pem" \ |
| 51 | + >/dev/null 2>&1 |
| 52 | + |
| 53 | + cat "dummy-ca-${i}.pem" >> "${bundle_file}" |
| 54 | + done |
| 55 | + |
| 56 | + log_success "Created CA bundle: $(du -h "${bundle_file}" | cut -f1)" |
| 57 | +} |
| 58 | + |
| 59 | +create_che_ca_configmap() { |
| 60 | + local che_ns="$1" |
| 61 | + local bundle_file="$2" |
| 62 | + |
| 63 | + log_info "Creating Che CA bundle ConfigMap..." |
| 64 | + |
| 65 | + kubectl create configmap custom-ca-certificates \ |
| 66 | + --from-file=custom-ca-certificates.pem="${bundle_file}" \ |
| 67 | + -n "${che_ns}" \ |
| 68 | + --dry-run=client -o yaml \ |
| 69 | + | kubectl apply --server-side -f - |
| 70 | + |
| 71 | + kubectl label configmap custom-ca-certificates \ |
| 72 | + app.kubernetes.io/component=ca-bundle \ |
| 73 | + app.kubernetes.io/part-of=che.eclipse.org \ |
| 74 | + -n "${che_ns}" \ |
| 75 | + --overwrite |
| 76 | +} |
| 77 | + |
| 78 | +patch_checluster_disable_pki_mount() { |
| 79 | + local che_ns="$1" |
| 80 | + |
| 81 | + log_info "Configuring CheCluster..." |
| 82 | + local checluster |
| 83 | + checluster=$(kubectl get checluster -n "${che_ns}" -o jsonpath='{.items[0].metadata.name}') |
| 84 | + |
| 85 | + kubectl patch checluster "${checluster}" \ |
| 86 | + -n "${che_ns}" \ |
| 87 | + --type=merge \ |
| 88 | + -p '{ |
| 89 | + "spec": { |
| 90 | + "devEnvironments": { |
| 91 | + "trustedCerts": { |
| 92 | + "disableWorkspaceCaBundleMount": true |
| 93 | + } |
| 94 | + } |
| 95 | + } |
| 96 | + }' |
| 97 | +} |
| 98 | + |
| 99 | +restart_che() { |
| 100 | + local che_ns="$1" |
| 101 | + |
| 102 | + log_info "Restarting Che..." |
| 103 | + kubectl rollout status deploy/che -n "${che_ns}" --timeout=5m |
| 104 | + kubectl wait pod -n "${che_ns}" -l app=che --for=condition=Ready --timeout=5m |
| 105 | + |
| 106 | + log_success "Che restarted" |
| 107 | +} |
| 108 | + |
| 109 | +create_devworkspace() { |
| 110 | + local dw_ns="$1" |
| 111 | + local dw_name="$2" |
| 112 | + |
| 113 | + log_info "Creating DevWorkspace '${dw_name}'..." |
| 114 | + cat <<EOF | kubectl apply -n "${dw_ns}" -f - |
| 115 | +kind: DevWorkspace |
| 116 | +apiVersion: workspace.devfile.io/v1alpha2 |
| 117 | +metadata: |
| 118 | + name: ${dw_name} |
| 119 | + annotations: |
| 120 | + che.eclipse.org/che-editor: che-incubator/che-code/latest |
| 121 | + che.eclipse.org/devfile: | |
| 122 | + schemaVersion: 2.2.0 |
| 123 | + metadata: |
| 124 | + generateName: ${dw_name} |
| 125 | + che.eclipse.org/devfile-source: | |
| 126 | + url: |
| 127 | + location: https://github.com/che-samples/web-nodejs-sample.git |
| 128 | + factory: |
| 129 | + params: che-editor=che-incubator/che-code/latest |
| 130 | +spec: |
| 131 | + started: true |
| 132 | + template: |
| 133 | + projects: |
| 134 | + - name: web-nodejs-sample |
| 135 | + git: |
| 136 | + remotes: |
| 137 | + origin: "https://github.com/che-samples/web-nodejs-sample.git" |
| 138 | + components: |
| 139 | + - name: dev |
| 140 | + container: |
| 141 | + image: quay.io/devfile/universal-developer-image:latest |
| 142 | + memoryLimit: 512Mi |
| 143 | + memoryRequest: 256Mi |
| 144 | + cpuRequest: 1000m |
| 145 | + commands: |
| 146 | + - id: say-hello |
| 147 | + exec: |
| 148 | + component: dev |
| 149 | + commandLine: echo "Hello from \$(pwd)" |
| 150 | + workingDir: \${PROJECT_SOURCE}/app |
| 151 | + contributions: |
| 152 | + - name: che-code |
| 153 | + uri: https://eclipse-che.github.io/che-plugin-registry/main/v3/plugins/che-incubator/che-code/latest/devfile.yaml |
| 154 | + components: |
| 155 | + - name: che-code-runtime-description |
| 156 | + container: |
| 157 | + env: |
| 158 | + - name: CODE_HOST |
| 159 | + value: 0.0.0.0 |
| 160 | +EOF |
| 161 | + |
| 162 | + |
| 163 | + kubectl wait devworkspace/"${dw_name}" \ |
| 164 | + -n "${dw_ns}" \ |
| 165 | + --for=condition=Ready \ |
| 166 | + --timeout=5m |
| 167 | +} |
| 168 | + |
| 169 | +wait_for_workspace_pod() { |
| 170 | + local dw_ns="$1" |
| 171 | + local dw_name="$2" |
| 172 | + local pod_name |
| 173 | + |
| 174 | + log_info "Waiting for workspace pod..." |
| 175 | + |
| 176 | + kubectl wait pod \ |
| 177 | + -n "${dw_ns}" \ |
| 178 | + -l controller.devfile.io/devworkspace_name="${dw_name}" \ |
| 179 | + --for=condition=Ready \ |
| 180 | + --timeout=5m \ |
| 181 | + >/dev/stderr |
| 182 | + |
| 183 | + pod_name=$(kubectl get pod \ |
| 184 | + -n "${dw_ns}" \ |
| 185 | + -l controller.devfile.io/devworkspace_name="${dw_name}" \ |
| 186 | + -o jsonpath='{.items[0].metadata.name}') |
| 187 | + |
| 188 | + echo "${pod_name}" |
| 189 | +} |
| 190 | + |
| 191 | +verify_ca_bundle_in_workspace() { |
| 192 | + local pod_name="$1" |
| 193 | + local dw_ns="$2" |
| 194 | + local expected_count="$3" |
| 195 | + local cert_path="/public-certs/tls-ca-bundle.pem" |
| 196 | + |
| 197 | + log_info "Verifying CA bundle in workspace..." |
| 198 | + |
| 199 | + kubectl exec "${pod_name}" -n "${dw_ns}" -- test -f "${cert_path}" |
| 200 | + |
| 201 | + local mounted_count |
| 202 | + mounted_count=$(kubectl exec "${pod_name}" -n "${dw_ns}" -- \ |
| 203 | + sh -c "grep -c 'BEGIN CERTIFICATE' ${cert_path}") |
| 204 | + |
| 205 | + log_info "Generated certificates : ${expected_count}" |
| 206 | + log_info "Mounted certificates : ${mounted_count}" |
| 207 | + |
| 208 | + if [[ "${mounted_count}" -le "${expected_count}" ]]; then |
| 209 | + log_error "Mounted certificate count validation failed" |
| 210 | + return 1 |
| 211 | + fi |
| 212 | + |
| 213 | + log_success "CA bundle verification passed" |
| 214 | +} |
| 215 | + |
| 216 | +cleanup_resources() { |
| 217 | + local dw_ns="$1" |
| 218 | + local dw_name="$2" |
| 219 | + |
| 220 | + log_info "Cleaning up..." |
| 221 | + kubectl delete dw "${dw_name}" -n "${dw_ns}" --ignore-not-found |
| 222 | + rm -f *.pem *.key |
| 223 | +} |
0 commit comments