From 4cc20386419aecffac924860bed56c2938b49537 Mon Sep 17 00:00:00 2001 From: Viet Nguyen Duc Date: Tue, 16 Jul 2024 16:02:11 +0700 Subject: [PATCH] chart(breaking change): refactoring config keys to enable secure connection (#2306) Signed-off-by: Viet Nguyen Duc --- Base/Dockerfile | 3 +- Makefile | 18 +- charts/selenium-grid/README.md | 180 ++++++++++++++---- charts/selenium-grid/certs/cert.sh | 99 +++++++--- charts/selenium-grid/certs/selenium.jks | Bin 2735 -> 0 bytes charts/selenium-grid/certs/selenium.pem | 24 --- .../selenium-grid/certs/selenium.pkcs8.base64 | 1 - charts/selenium-grid/certs/server.jks | Bin 0 -> 2896 bytes charts/selenium-grid/certs/tls.crt | 24 +++ charts/selenium-grid/certs/tls.key | 28 +++ .../SeleniumGrid_TLS_SSL-Passthrough.png | Bin 0 -> 25624 bytes .../SeleniumGrid_TLS_SSL-Termination.png | Bin 0 -> 25618 bytes .../images/SeleniumGrid_TLS_WithoutProxy.png | Bin 0 -> 25727 bytes charts/selenium-grid/templates/_helpers.tpl | 85 +++++++-- .../templates/distributor-deployment.yaml | 6 +- .../templates/event-bus-deployment.yaml | 6 +- .../templates/hub-deployment.yaml | 7 +- charts/selenium-grid/templates/ingress.yaml | 2 +- .../templates/node-configmap.yaml | 4 +- .../templates/router-deployment.yaml | 6 +- charts/selenium-grid/templates/secrets.yaml | 8 +- .../templates/server-configmap.yaml | 12 +- .../templates/session-map-deployment.yaml | 6 +- .../templates/session-queuer-deployment.yaml | 6 +- .../templates/tls-cert-secret.yaml | 29 ++- charts/selenium-grid/values.yaml | 39 ++-- tests/charts/ci/base-recorder-values.yaml | 5 - tests/charts/ci/base-tls-values.yaml | 7 +- tests/charts/make/chart_cluster_setup.sh | 13 +- tests/charts/make/chart_test.sh | 71 ++++++- tests/customCACert/bootstrap.sh | 4 +- 31 files changed, 487 insertions(+), 206 deletions(-) delete mode 100644 charts/selenium-grid/certs/selenium.jks delete mode 100644 charts/selenium-grid/certs/selenium.pem delete mode 100644 charts/selenium-grid/certs/selenium.pkcs8.base64 create mode 100644 charts/selenium-grid/certs/server.jks create mode 100644 charts/selenium-grid/certs/tls.crt create mode 100644 charts/selenium-grid/certs/tls.key create mode 100644 charts/selenium-grid/images/SeleniumGrid_TLS_SSL-Passthrough.png create mode 100644 charts/selenium-grid/images/SeleniumGrid_TLS_SSL-Termination.png create mode 100644 charts/selenium-grid/images/SeleniumGrid_TLS_WithoutProxy.png diff --git a/Base/Dockerfile b/Base/Dockerfile index 8cde08e92..2372628f0 100644 --- a/Base/Dockerfile +++ b/Base/Dockerfile @@ -8,6 +8,7 @@ ARG AUTHORS=SeleniumHQ # Default value should be aligned with upstream Selenium (https://github.com/SeleniumHQ/selenium/blob/trunk/java/maven_deps.bzl) ARG OPENTELEMETRY_VERSION=1.38.0 ARG GRPC_VERSION=1.64.0 +ARG NETTY_VERSION=4.1.108.Final ARG CS_VERSION=2.1.10 #Arguments to define the user running Selenium @@ -120,7 +121,7 @@ RUN if [ "$(dpkg --print-architecture)" = "amd64" ]; then \ && if [ -f "/tmp/cs" ]; then \ java -jar /tmp/cs fetch --classpath --cache /external_jars \ io.opentelemetry:opentelemetry-exporter-otlp:${OPENTELEMETRY_VERSION} \ - io.grpc:grpc-netty:${GRPC_VERSION} > /external_jars/.classpath.txt \ + io.grpc:grpc-netty:${GRPC_VERSION} io.netty:netty-codec-http:${NETTY_VERSION} > /external_jars/.classpath.txt \ && chmod 664 /external_jars/.classpath.txt ; \ fi \ && rm -fr /root/.cache/* \ diff --git a/Makefile b/Makefile index 510f8f586..297bb63c5 100644 --- a/Makefile +++ b/Makefile @@ -762,34 +762,40 @@ chart_test_template: ./tests/charts/bootstrap.sh chart_test_autoscaling_disabled: - PLATFORMS=$(PLATFORMS) SELENIUM_GRID_AUTOSCALING=false TEST_DELAY_AFTER_TEST=15 CHART_ENABLE_TRACING=true SELENIUM_GRID_HOST=$$(hostname -i) RELEASE_NAME=selenium \ + PLATFORMS=$(PLATFORMS) RELEASE_NAME=selenium SELENIUM_GRID_AUTOSCALING=false TEST_DELAY_AFTER_TEST=15 CHART_ENABLE_TRACING=true \ + SECURE_INGRESS_ONLY_GENERATE=true SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_HOST=$$(hostname -i) SELENIUM_GRID_PORT=443 \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) \ ./tests/charts/make/chart_test.sh NoAutoscaling chart_test_autoscaling_deployment_https: - PLATFORMS=$(PLATFORMS) CHART_FULL_DISTRIBUTED_MODE=true CHART_ENABLE_INGRESS_HOSTNAME=true CHART_ENABLE_BASIC_AUTH=true SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_PORT=443 \ + PLATFORMS=$(PLATFORMS) CHART_FULL_DISTRIBUTED_MODE=true CHART_ENABLE_BASIC_AUTH=true \ + SECURE_INGRESS_ONLY_DEFAULT=true SELENIUM_GRID_PROTOCOL=https CHART_ENABLE_INGRESS_HOSTNAME=true SELENIUM_GRID_PORT=443 \ SELENIUM_GRID_AUTOSCALING_MIN_REPLICA=1 \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) \ ./tests/charts/make/chart_test.sh DeploymentAutoscaling chart_test_autoscaling_deployment: - PLATFORMS=$(PLATFORMS) CHART_ENABLE_TRACING=true SELENIUM_GRID_HOST=$$(hostname -i) RELEASE_NAME=selenium \ + PLATFORMS=$(PLATFORMS) RELEASE_NAME=selenium CHART_ENABLE_TRACING=true \ + SECURE_CONNECTION_SERVER=true SECURE_USE_EXTERNAL_CERT=true SERVICE_TYPE_NODEPORT=true SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_HOST=$$(hostname -i) SELENIUM_GRID_PORT=31444 \ SELENIUM_GRID_AUTOSCALING_MIN_REPLICA=1 \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) \ ./tests/charts/make/chart_test.sh DeploymentAutoscaling chart_test_autoscaling_job_https: - PLATFORMS=$(PLATFORMS) SELENIUM_GRID_PROTOCOL=https CHART_ENABLE_BASIC_AUTH=true RELEASE_NAME=selenium SELENIUM_GRID_PORT=443 SUB_PATH=/ \ + PLATFORMS=$(PLATFORMS) RELEASE_NAME=selenium CHART_ENABLE_BASIC_AUTH=true \ + SECURE_CONNECTION_SERVER=true SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_PORT=443 SUB_PATH=/ \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) \ ./tests/charts/make/chart_test.sh JobAutoscaling chart_test_autoscaling_job_hostname: - PLATFORMS=$(PLATFORMS) CHART_ENABLE_TRACING=true CHART_ENABLE_INGRESS_HOSTNAME=true CHART_ENABLE_BASIC_AUTH=true \ + PLATFORMS=$(PLATFORMS) CHART_ENABLE_TRACING=true CHART_ENABLE_BASIC_AUTH=true \ + SECURE_INGRESS_ONLY_DEFAULT=true SECURE_USE_EXTERNAL_CERT=true SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_HOST=$$(hostname -i) SELENIUM_GRID_PORT=443 \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) \ ./tests/charts/make/chart_test.sh JobAutoscaling chart_test_autoscaling_job: - PLATFORMS=$(PLATFORMS) CHART_ENABLE_TRACING=true CHART_FULL_DISTRIBUTED_MODE=true CHART_ENABLE_INGRESS_HOSTNAME=true SELENIUM_GRID_HOST=selenium-grid.local RELEASE_NAME=selenium SUB_PATH=/ \ + PLATFORMS=$(PLATFORMS) RELEASE_NAME=selenium CHART_ENABLE_TRACING=true CHART_FULL_DISTRIBUTED_MODE=true \ + SECURE_INGRESS_ONLY_GENERATE=true CHART_ENABLE_INGRESS_HOSTNAME=true SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_HOST=selenium-grid.prod SUB_PATH=/ SELENIUM_GRID_PORT=443 \ VERSION=$(TAG_VERSION) VIDEO_TAG=$(FFMPEG_TAG_VERSION)-$(BUILD_DATE) NAMESPACE=$(NAMESPACE) BINDING_VERSION=$(BINDING_VERSION) \ ./tests/charts/make/chart_test.sh JobAutoscaling diff --git a/charts/selenium-grid/README.md b/charts/selenium-grid/README.md index 60809aea7..065fafcfb 100644 --- a/charts/selenium-grid/README.md +++ b/charts/selenium-grid/README.md @@ -31,9 +31,11 @@ This chart enables the creation of a Selenium Grid Server in Kubernetes. * [Configuration of video recorder and video uploader](#configuration-of-video-recorder-and-video-uploader) * [Video recorder](#video-recorder) * [Video uploader](#video-uploader) - * [Configuration of Secure Communication (HTTPS)](#configuration-of-secure-communication-https) - * [Secure Communication](#secure-communication) - * [Node Registration](#node-registration) + * [Configuration of Secure Communication](#configuration-of-secure-communication) + * [Create TLS Secret](#create-tls-secret) + * [Secure Connection to Selenium Grid components](#secure-connection-to-selenium-grid-components) + * [Secure Connection to the Ingress proxy](#secure-connection-to-the-ingress-proxy) + * [Node Registration](#node-registration) * [Configuration of tracing observability](#configuration-of-tracing-observability) * [Configuration of Selenium Grid chart](#configuration-of-selenium-grid-chart) * [Configuration of KEDA](#configuration-of-keda) @@ -600,76 +602,172 @@ videoRecorder: imageTag: latest ``` -### Configuration of Secure Communication (HTTPS) +### Configuration of Secure Communication Selenium Grid supports secure communication between components. Refer to the [instructions](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/commands/security.txt) and [options](https://www.selenium.dev/documentation/grid/configuration/cli_options/#server) are able to configure the secure communication. Below is the details on how to enable secure communication in Selenium Grid chart. -#### Secure Communication +In the chart, there is directory [certs](./certs) contains the default self-signed certificate, private key (as PKCS8 format), and Java Keystore (JKS) to teach Java about secure connection (since we are using a non-standard CA) for your trial, local testing purpose. You can generate your own self-signed certificate put them in that default directory by using script [certs/cert.sh](./certs/cert.sh) with adjust needed information. The certificate, private key, truststore are mounted to the components via `Secret`. -In the chart, there is directory [certs](./certs) contains the default certificate, private key (as PKCS8 format), and Java Keystore (JKS) to teach Java about secure connection (since we are using a non-standard CA) for your trial, local testing purpose. You can generate your own self-signed certificate put them in that default directory by using script [cert.sh](./certs/cert.sh) with adjust needed information. The certificate, private key, truststore are mounted to the components via `Secret`. +Usage of [certs/cert.sh](./certs/cert.sh) script: -There are multiple ways to configure your certificate, private key, truststore to the components. You can choose one of them or combine them. +```bash +# Generate self-signed to target directory +./certs/cert.sh -d /path/to/your/ +# Add current host IP to the certificate +ADD_IP_ADDRESS=hostname ./certs/cert.sh -d /path/to/your/ +# Add multiple IP addresses to the certificate (comma-separated) +ADD_IP_ADDRESS=",IP:10.10.10.10,IP:10.10.11.11" ./certs/cert.sh -d /path/to/your/ +# Other environment variables that script consumes +# CERTNAME, STOREPASS, KEYPASS, ALIAS, SERVER_KEYSTORE, BASE64_ONLY +``` -- Use the default directory [certs](./certs). Rename your own files to be same as the default files and replace them. Give `--set tls.enabled=true` to enable secure communication. +#### Create TLS Secret -- Use the default directory [certs](./certs). Copy your own files to there and adjust the file name under config `tls.defaultFile`, those will be picked up when installing chart. For example: +There are multiple ways to insert your certificate, private key, truststore to the components. You can choose one of following ways: - ```yaml - tls: - enabled: true - trustStorePassword: "your_truststore_password" - defaultFile: - certificate: "certs/your_cert.pem" - privateKey: "certs/your_private_key.pkcs8" - trustStore: "certs/your_truststore.jks" +1. Replace your certificate, private key, truststore to the default directory [certs](./certs) in chart with the same name before deploying the chart. + +2. Use Helm CLI to pass your certificate, private key, truststore via `--set-file` when deploying the chart. For example (replace `$RELEASENAME` and `$NAMESPACE` with your values): + + ```bash + helm upgrade -i $RELEASENAME -n $NAMESPACE docker-selenium/selenium-grid \ + --set tls.enabled=true \ + --set-file tls.secretFiles.tls\.crt=/path/to/your/tls.crt \ + --set-file tls.secretFiles.tls\.key=/path/to/your/tls.key \ + --set-file tls.secretFiles.server\.jks=/path/to/your/server.jks ``` - For some security reasons, you may not able to put private key in your source code or your customization chart package. You can provide files with contents are encoded in Base64 format, just append `.base64` to the file name for chart able to know and decode them. For example: + +3. Create your own TLS Secret with your certificate, private key, truststore and pass the Secret name via `tls.nameOverride` when deploying the chart. For example (replace `$RELEASENAME` and `$NAMESPACE` with your values): + + ```bash + # Steps to prepare your self-signed certificate + ./certs/cert.sh -d /path/to/your/ + # Create TLS Secret with your certificate, private key, truststore + kubectl create secret generic -n $NAMESPACE my-external-tls-secret \ + --from-file=tls.crt=/path/to/your/tls.crt \ + --from-file=tls.key=/path/to/your/tls.key \ + --from-file=server.jks=/path/to/your/server.jks + # Deploy chart with your external TLS Secret + helm upgrade -i $RELEASENAME -n $NAMESPACE docker-selenium/selenium-grid \ + --set tls.enabled=true --set tls.nameOverride=my-external-tls-secret + ``` + + In case your external secret contains key file names are different with default, you can instruct server to use them via following values: ```yaml tls: enabled: true - trustStorePassword: "your_truststore_password" - defaultFile: - certificate: "certs/your_cert.pem.base64" - privateKey: "certs/your_private_key.pkcs8.base64" - trustStore: "certs/your_truststore.jks.base64" + nameOverride: my-external-tls-secret + certificateFile: "my-tls.crt" + privateKeyFile: "my-tls.key" + trustStoreFile: "my-server.jks" + trustStorePassword: "mytruststorepassword" ``` -- Using Helm CLI `--set-file` to pass your own file to particular config key. For example: +#### Secure Connection to Selenium Grid components - ```bash - helm upgrade -i test selenium-grid \ +When enabling secure communication between Selenium Grid server components, you need to set the following values: + +```yaml +tls: + enabled: true +``` + +In additional, if the ingress is enabled, and approach SSL Passthrough is used to ensure the request forwards to the backend components via an encrypted connection. +With `ingress.hostname` is set, the default server TLS secret is also used for hosts TLS secretName when `ingress.tls` is empty. Once you specify `ingress.tls`, your specified secret will be used for hosts TLS secretName. + +![SeleniumGrid_TLS_SSL-Passthrough](./images/SeleniumGrid_TLS_SSL-Passthrough.png) + +Moreover, when sub-chart `ingress-nginx` is enabled (deploy Ingress NGINX Controller together), the default server TLS secret can also be assigned via `ingress-nginx.controller.extraArgs.default-ssl-certificate`. +For example (replace `$RELEASENAME` and `$NAMESPACE` with your values): + +```bash +helm upgrade -i $RELEASENAME -n $NAMESPACE docker-selenium/selenium-grid \ --set tls.enabled=true \ - --set-file tls.certificate=/path/to/your_cert\.pem \ - --set-file tls.privateKey=/path/to/your_private_key\.pkcs8 \ - --set-file tls.trustStore=/path/to/your_truststore\.jks \ - --set-string tls.trustStorePassword=your_truststore_password - ``` + --set ingress-nginx.enabled=true \ + --set ingress-nginx.controller.extraArgs.default-ssl-certificate=$NAMESPACE/$RELEASENAME-selenium-tls-secret +``` + +Below is an example of Grid UI accessible via NodePort with secure connection, and using external TLS Secret (replace `$RELEASENAME` and `$NAMESPACE` with your values): + +```bash +helm upgrade -i $RELEASENAME -n $NAMESPACE docker-selenium/selenium-grid \ + --set ingress.enabled=false \ + --set isolateComponents=true \ + --set components.router.serviceType=NodePort \ + --set tls.enabled=true \ + --set tls.nameOverride=my-external-tls-secret +``` -If you start NGINX ingress controller inline with Selenium Grid chart, you can configure the default certificate of NGINX ingress controller to use the same certificate as Selenium Grid. For example: +Grid UI can be accessed via HTTPS address `https://your.host.public.ip:30444`. + +![SeleniumGrid_TLS_WithoutProxy](./images/SeleniumGrid_TLS_WithoutProxy.png) + +#### Secure Connection to the Ingress proxy + +When enabling secure communication via HTTPS/TLS between the client and the Ingress proxy only (SSL Offloading / aka SSL Termination). The proxy will terminate the TLS connection, decrypt incoming HTTPS traffic and send it to the backend components without encryption. The backend Selenium Grid components doesn't need to understand HTTPS. To enable this mode, you need to set the following values: ```yaml tls: - enabled: true + ingress: + enabled: true +``` -ingress-nginx: +![SeleniumGrid_TLS_SSL-Termination](./images/SeleniumGrid_TLS_SSL-Termination.png) + +In additional, a self-signed certificate and private key can be generated runtime during the chart deployment for Ingress TLS by setting these values (replace `$RELEASENAME` with your value): + +```yaml +tls: + ingress: + generateTLS: true + defaultName: "MySelfSignedCert" + defaultDays: 3650 + defaultCN: "www.domain.com" # Common Name + defaultSANList: + - selenium-grid.prod.domain.com # Subject Alternative Name + - selenium-grid.staging.domain.com + defaultIPList: + - 10.87.99.100 # Public IP of the host running K8s or LoadBalancer IP + - 10.87.100.101 + +ingress-ngnix: enabled: true controller: extraArgs: - default-ssl-certificate: '$(POD_NAMESPACE)/selenium-tls-secret' + default-ssl-certificate: $(POD_NAMESPACE)/$RELEASENAME-selenium-tls-secret ``` -#### Node Registration +You can get the `tls.crt` and `tls.key` from the Secret after the chart is deployed. For example (replace `$RELEASENAME` and `$NAMESPACE` with your values): + +```bash +kubectl get secret $RELEASENAME-selenium-tls-secret -n $NAMESPACE -o jsonpath="{.data.tls\.crt}" | base64 -d > ./tls.crt +kubectl get secret $RELEASENAME-selenium-tls-secret -n $NAMESPACE -o jsonpath="{.data.tls\.key}" | base64 -d > ./tls.key +``` + +Below is an example of Grid UI accessible via secure connection to the Ingress proxy with self-signed certificate in external TLS Secret (replace `$RELEASENAME` and `$NAMESPACE` with your values): + +```bash +helm upgrade -i $RELEASENAME -n $NAMESPACE docker-selenium/selenium-grid \ + --set ingress.enabled=true \ + --set ingress.hostname="selenium-grid.prod.domain.com" \ + --set tls.ingress.enabled=true \ + --set tls.nameOverride=my-external-tls-secret \ + --set ingress-nginx.enabled=true \ + --set ingress-nginx.controller.extraArgs.default-ssl-certificate=$NAMESPACE/my-external-tls-secret +``` + +Grid UI can be accessed via HTTPS address `https://selenium-grid.prod.domain.com`. + +### Node Registration To enable secure in the node registration to make sure that the node is one you control and not a rouge node, you can enable and provide a registration secret string to Distributor, Router and -Node servers in config `tls.registrationSecret`. For example: +Node servers in config `registrationSecret`. For example: ```yaml -tls: +registrationSecret: enabled: true - registrationSecret: - enabled: true - value: "matchThisSecret" + value: "matchThisSecret" ``` ### Configuration of tracing observability diff --git a/charts/selenium-grid/certs/cert.sh b/charts/selenium-grid/certs/cert.sh index c38572caa..79adb6bf3 100755 --- a/charts/selenium-grid/certs/cert.sh +++ b/charts/selenium-grid/certs/cert.sh @@ -1,13 +1,39 @@ +#!/bin/bash # README: This script is used to generate a self-signed certificate for enabling HTTPS/TLS in Selenium Grid -CERTNAME=${1:-selenium} -STOREPASS=${2:-changeit} -KEYPASS=${3:-changeit} -ALIAS=${4:-SeleniumHQ} -BASE64_ONLY=1 +# Initialize default values +DIRECTORY_PATH="" +# Parse command-line options +# -d directory_path: Specify the directory path to store the generated certificate files +while getopts "d:" opt; do + case ${opt} in + d ) + DIRECTORY_PATH=$OPTARG + ;; + \? ) + echo "Usage: cmd [-d directory_path]" + exit 1 + ;; + esac +done + +# Shift out the option and argument to leave only the positional parameters +shift $((OPTIND-1)) + +CERTNAME=${CERTNAME:-tls} +STOREPASS=${STOREPASS:-seleniumkeystore} +KEYPASS=${KEYPASS:-seleniumkeystore} +ALIAS=${ALIAS:-SeleniumHQ} +SERVER_KEYSTORE=${SERVER_KEYSTORE:-server.jks} +BASE64_ONLY=${BASE64_ONLY:-0} +if [ -n "${ADD_IP_ADDRESS}" ] && [ "${ADD_IP_ADDRESS}" = "hostname" ]; then + ADD_IP_ADDRESS=",IP:$(hostname -I | awk '{print $1}')" +else + ADD_IP_ADDRESS=${ADD_IP_ADDRESS} +fi # Remove existing files -rm -f ${CERTNAME}.* +rm -f ${CERTNAME}.* ${SERVER_KEYSTORE} # Create JKS (Java Keystore) - this is used to set for JAVA_OPTS -Djavax.net.ssl.trustStore= # The key pass set to JAVA_OPTS -Djavax.net.ssl.trustStorePassword= @@ -17,45 +43,70 @@ keytool -genkeypair \ -keyalg RSA \ -v \ -dname "CN=SeleniumHQ,OU=Software Freedom Conservancy,O=SeleniumHQ,L=Unknown,ST=Unknown,C=Unknown" \ - -ext "SAN:c=DNS:localhost,DNS:selenium-grid.local,DNS:selenium-grid.prod,DNS:selenium.dev" \ + -ext "SAN:c=DNS:localhost,DNS:selenium-grid.local,DNS:selenium-grid.prod,DNS:selenium.dev${ADD_IP_ADDRESS}" \ -validity 3650 \ -storepass ${STOREPASS} \ -keypass ${KEYPASS} \ - -keystore ${CERTNAME}.jks + -keystore ${SERVER_KEYSTORE} -# Base64 encode JKS file (for Kubernetes Secret) -#base64 -i ${CERTNAME}.jks -w 0 > ${CERTNAME}.jks.base64 +if [ ${BASE64_ONLY} -eq 1 ]; then + # Base64 encode JKS file (for Kubernetes Secret) + base64 -i ${SERVER_KEYSTORE} -w 0 > ${SERVER_KEYSTORE}.base64 +fi # Create PKCS12 from JKS -keytool -importkeystore -srckeystore ${CERTNAME}.jks \ +keytool -importkeystore -srckeystore ${SERVER_KEYSTORE} \ -destkeystore ${CERTNAME}.p12 \ -srcstoretype jks \ -storepass ${STOREPASS} -keypass ${KEYPASS} -srcstorepass ${STOREPASS} \ -deststoretype pkcs12 -# Create private key PEM from PKCS12 +# Create private key from PKCS12 openssl pkcs12 -nodes -in ${CERTNAME}.p12 -out ${CERTNAME}.key \ -passin pass:${KEYPASS} # Create private key PKCS8 format (this is used to set for option --https-private-key) openssl pkcs8 -in ${CERTNAME}.key -topk8 -nocrypt -out ${CERTNAME}.pkcs8 -# Base64 encode PKCS8 file (for Kubernetes Secret) -base64 -i ${CERTNAME}.pkcs8 -w 0 > ${CERTNAME}.pkcs8.base64 +# Remove source file PKCS12 (prevent sensitive data leak) +rm -f ${CERTNAME}.p12 + +# Rename PKCS8 file to .key extension (most compatible extension for private key) +mv ${CERTNAME}.pkcs8 ${CERTNAME}.key -# Create certificate PEM from JKS (this is used to set for option --https-certificate) +if [ ${BASE64_ONLY} -eq 1 ]; then + # Base64 encode PKCS8 file (for Kubernetes Secret) + base64 -i ${CERTNAME}.key -w 0 > ${CERTNAME}.key.base64 +fi + +# Create certificate CRT from JKS (this is used to set for option --https-certificate) keytool -exportcert -alias ${ALIAS} \ -storepass ${STOREPASS} -keypass ${KEYPASS} \ - -keystore ${CERTNAME}.jks -rfc -file ${CERTNAME}.pem + -keystore ${SERVER_KEYSTORE} -rfc -file ${CERTNAME}.crt -# Base64 encode Certificate PEM file (for Kubernetes Secret) -#base64 -i ${CERTNAME}.pem -w 0 > ${CERTNAME}.pem.base64 +if [ ${BASE64_ONLY} -eq 1 ]; then + # Base64 encode Certificate CRT file (for Kubernetes Secret) + base64 -i ${CERTNAME}.crt -w 0 > ${CERTNAME}.crt.base64 +fi if [ ${BASE64_ONLY} -eq 1 ]; then - # Remove source files (prevent sensitive data leak) - rm -f ${CERTNAME}.key - rm -f ${CERTNAME}.p12 - rm -f ${CERTNAME}.pkcs8 - # Retain ${CERTNAME}.jks for Java client establishing HTTPS connection - # Retain ${CERTNAME}.pem for client establishing HTTPS connection + rm -rf ${CERTNAME}.key + rm -rf ${SERVER_KEYSTORE} + rm -rf ${CERTNAME}.crt +fi + +if [ -n "${DIRECTORY_PATH}" ]; then + # Create the specified directory if it does not exist + mkdir -p ${DIRECTORY_PATH} + # Move the generated certificate files to the specified directory + if [ ${BASE64_ONLY} -eq 1 ]; then + mv ${SERVER_KEYSTORE}.base64 ${DIRECTORY_PATH}/ + mv ${CERTNAME}.key.base64 ${DIRECTORY_PATH}/ + mv ${CERTNAME}.crt.base64 ${DIRECTORY_PATH}/ + else + mv ${CERTNAME}.key ${DIRECTORY_PATH}/ + mv ${SERVER_KEYSTORE} ${DIRECTORY_PATH}/ + mv ${CERTNAME}.crt ${DIRECTORY_PATH}/ + fi + echo "Self-signed certificate files have been generated and stored in: ${DIRECTORY_PATH}" fi diff --git a/charts/selenium-grid/certs/selenium.jks b/charts/selenium-grid/certs/selenium.jks deleted file mode 100644 index 3c9c531af358ae4cf46b60fc6eedad62a8433733..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2735 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 b*Irx3tqL60_G0<6#Pd53egHW+5+D8>HTDdE diff --git a/charts/selenium-grid/certs/selenium.pem b/charts/selenium-grid/certs/selenium.pem deleted file mode 100644 index 3818978d4..000000000 --- a/charts/selenium-grid/certs/selenium.pem +++ /dev/null @@ -1,24 +0,0 @@ ------BEGIN CERTIFICATE----- -MIID/zCCAuegAwIBAgIEbybT1DANBgkqhkiG9w0BAQsFADCBhzEQMA4GA1UEBhMH -VW5rbm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjETMBEG -A1UEChMKU2VsZW5pdW1IUTElMCMGA1UECxMcU29mdHdhcmUgRnJlZWRvbSBDb25z -ZXJ2YW5jeTETMBEGA1UEAxMKU2VsZW5pdW1IUTAeFw0yNDAzMDExMDQwMTVaFw0z -NDAyMjcxMDQwMTVaMIGHMRAwDgYDVQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtu -b3duMRAwDgYDVQQHEwdVbmtub3duMRMwEQYDVQQKEwpTZWxlbml1bUhRMSUwIwYD -VQQLExxTb2Z0d2FyZSBGcmVlZG9tIENvbnNlcnZhbmN5MRMwEQYDVQQDEwpTZWxl -bml1bUhRMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuhrHCWD8ZApZ -JbFGBcf5Gu/WdH0v+PUWvW4ZHoVclFktnYF4Je3DXCDrvDOf5AtBqS7YzCr1uZML -fYLRvMJBxpHtYS+W7XiIUGOXavw3DN2DBysp2uMgMmumD3C9PWk7O+BJ3Ej/CQev -WuMLK/3F6PRhNEYdB6kqAbP3fqN40fu+3w+yUHwprHmo8Uo37QhJejGfFnhdxhTq -vElvrGlSpIidLs7wPOFVqQyTXAR+K7/vhWy1asZE0bZ5fQhDnFPsNFdkoA/dDPga -dGM5U7A4WYQdmVtJ5RSZHUb9jfUQ1LQyuR1FQ5DudstXKtNONqA3yqUPusQpIaYW -PbIimVI4lQIDAQABo3EwbzAdBgNVHQ4EFgQU/S73OMhN3yV4ustP37TY9upJQFYw -TgYDVR0RAQH/BEQwQoIJbG9jYWxob3N0ghNzZWxlbml1bS1ncmlkLmxvY2FsghJz -ZWxlbml1bS1ncmlkLnByb2SCDHNlbGVuaXVtLmRldjANBgkqhkiG9w0BAQsFAAOC -AQEAs8CCz5kQnuWjcFQojkjbMk9L92HBWV89ME+YL4o/TJk56EYW3UurEALgO6MJ -h14vdXOAYO6TERUMNKaSO5CydfbuKp5JpJhpY/qbHKPE/wJYIfMEO2hicYefjEKi -wxy4TE1FrfbmHV+MKmS21u7JTTyoqpqD+dWoURikdwBwm6cvyPx9Hntc2uHMc53D -BQtveBxkr4fMT+dcAommWfY+LHWg2bvEWzTJxELK7D5b63z/AI3MAL5XEznbqoV7 -ibZpC2D8wZ4N2E3tOT7iruMVuGVI98N40ytSuSwrUNjn7CT+htnpn1zVWZx3FpiT -pez6yj8ecncxrGOgp2Ty6r5Quw== ------END CERTIFICATE----- diff --git a/charts/selenium-grid/certs/selenium.pkcs8.base64 b/charts/selenium-grid/certs/selenium.pkcs8.base64 deleted file mode 100644 index 2325100f3..000000000 --- a/charts/selenium-grid/certs/selenium.pkcs8.base64 +++ /dev/null @@ -1 +0,0 @@ -LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQzZHc2NKWVB4a0Nsa2wKc1VZRngva2E3OVowZlMvNDlSYTliaGtlaFZ5VVdTMmRnWGdsN2NOY0lPdThNNS9rQzBHcEx0ak1Ldlc1a3d0OQpndEc4d2tIR2tlMWhMNWJ0ZUloUVk1ZHEvRGNNM1lNSEt5bmE0eUF5YTZZUGNMMDlhVHM3NEVuY1NQOEpCNjlhCjR3c3IvY1hvOUdFMFJoMEhxU29Ccy9kK28zalIrNzdmRDdKUWZDbXNlYWp4U2pmdENFbDZNWjhXZUYzR0ZPcTgKU1crc2FWS2tpSjB1enZBODRWV3BESk5jQkg0cnYrK0ZiTFZxeGtUUnRubDlDRU9jVSt3MFYyU2dEOTBNK0JwMApZemxUc0RoWmhCMlpXMG5sRkprZFJ2Mk45UkRVdERLNUhVVkRrTzUyeTFjcTAwNDJvRGZLcFErNnhDa2hwaFk5CnNpS1pVamlWQWdNQkFBRUNnZ0VBU1ZGaFZvMlNBV3VlUVY0OG91eHNkRE5HdnEvUEpYcVJFZUg5SFd3VzFBN3EKREtKRURsVkVZTmhMWnVMRHZCaS9Mb0xaUUY0d1hvTFN4UWl6em5TTmEwaDBSNVJ6Rm0wazd0NjllWldScm96YQpJUW5kUEhHOGJvREFkRmJMQnhXZEUzTENSbm12bUFRaURtRmlObHVOQzhDelJ0L1VjZjh3SUdtaE9JLzRlbWpSCm5Uekw2aVR6WEJ4QUQ1VVJ4NWdSWnpETHE4S2JpaVc5c0NsUkEvSDhITGNrQmxqbUtVQVpZdnNIbjZ5Qit5WDEKN2dIQ0lqaE9yeTVtSS9vTlpWWDhVOXJOOFhMWU1OTHdvZmxSdUNuZHBwbnN5NHpRVUtSOWlKdUpCNGNubVZWZAprcVFmSTQ1V0Z4dkE2bzNIbGE0TDh6WVRvUmF0T2I3OCtOcFFhdmhkd1FLQmdRRHg3L1h2ZTJwSHVqUWVqY1NOCnlsSXZKV2FIRmhKUHM3WmYvek92cUswOTNabHc5bkpUanI0eHl0U3NGVWdxUVdVY0dTa1VRUVlYWFpjWDZuWGUKNHVKdzRSWVBPc3R2c002NkZ5amx0bFl0a3N5LzhPTUN3T0hRam13RFllWkNxU0o4YXdWTjRzUEpCNGJ5TVQxRAozM2NoOXlFc2RRbmZiMXdCaEl3R0lDR0JVUUtCZ1FERTdBWFprWUpZY1N1QzlEdWRUSHhKbUNVcUpBMEdDdnJPCmlpRjg1V29BczZxa1A1eEt6SmdYM3JDdkk3YkUwQ1pJMlVQTDlRd1J2RitvZGx4N0huSUh5UVEzNmswbGJiMXMKNDAwbUR6M1lYT0xIemliQnNzcGRiRzNmekE2bnhoWnlrd3Y3SmlzT2I5cU10a0ZRVmtxbTNPZVRtaTZoSk9XVgpYODl1RjZNU0JRS0JnRTNJUmh0ZVpFYjNPSFp5UWJVTVRPdlhiR1VWMVlGR1YrWDVHRmJyTmZkajNVY1NGS09FCml1VmJQcENzcnV6VzVYanBKZW5iRmVoQk1LaUJ1cStUNWhWQWFHVXhFK0t1eDJmUXRsZFVEZFRORTRMS0lWSHIKVFM1Tis3QUNzNUxPNmNWeWF0d2xnYWlLQVBxd2xlL1NVbXpiRlJGRDk0NmNNTXBVSU9oL1FBWmhBb0dBSlNwcQpuRHFEUUUvenAxNlRGY2dHdVJrWEFwSVZSeXV4VkdQcm1CZndYcnVLSEQvSkxyRFlqOEMrMWY5R2tuUzZsUXMwCmFYMFJUeE9mZGpzSWoxQWFzMjl6OVYycU84TXZlaXFZTi9PdWQzUm9kTTlxcnlvZ1dXdUtmUytWSUlNWlgzeHoKU1c1VnQvN1NYN1pTTTJobDVJSlN6cC9ONXlvQWpxV3JqNXEwYzBVQ2dZRUFvbDdaMW1UYXhoWng2cWpScis1MAo5T1NnMElBK3YvSHZoM1pPRkRTUE5xdHlESTl1eGo3K0dDb3JTYjExRmJzaU1obXkxT0tGMlRiSnN6YkNPTFhUCjNzelFpVjVWenNyWUVsR3V1d2NqNkpwU3ZCb2VFTmF2NzhVRVlncTNoQW9MSXNmMGlHN3ozME5OYXAwQ25JZ2QKSnFRRGt3K3pNT0JXY3p2S04rbVQ0NDA9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K \ No newline at end of file diff --git a/charts/selenium-grid/certs/server.jks b/charts/selenium-grid/certs/server.jks new file mode 100644 index 0000000000000000000000000000000000000000..395afe9fcb38ad25d91dce7825973f48984624fa GIT binary patch literal 2896 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 Pwd67ue&xje3yJ>(t$;Zf literal 0 HcmV?d00001 diff --git a/charts/selenium-grid/certs/tls.crt b/charts/selenium-grid/certs/tls.crt new file mode 100644 index 000000000..58feb852f --- /dev/null +++ b/charts/selenium-grid/certs/tls.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEBDCCAuygAwIBAgIJAODdnzzdFPoKMA0GCSqGSIb3DQEBCwUAMIGHMRAwDgYD +VQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3du +MRMwEQYDVQQKEwpTZWxlbml1bUhRMSUwIwYDVQQLExxTb2Z0d2FyZSBGcmVlZG9t +IENvbnNlcnZhbmN5MRMwEQYDVQQDEwpTZWxlbml1bUhRMB4XDTI0MDcxNTEwMDQy +MloXDTM0MDcxMzEwMDQyMlowgYcxEDAOBgNVBAYTB1Vua25vd24xEDAOBgNVBAgT +B1Vua25vd24xEDAOBgNVBAcTB1Vua25vd24xEzARBgNVBAoTClNlbGVuaXVtSFEx +JTAjBgNVBAsTHFNvZnR3YXJlIEZyZWVkb20gQ29uc2VydmFuY3kxEzARBgNVBAMT +ClNlbGVuaXVtSFEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUMWXA +7Ka8y5Wzo/2cA6JkxlxqRtxrAm+YWKzXb4WWB0nX2ZsqWxnNTSDENPlCpLdCNIuG +qTmjucYJGQKvnzeS8N1R594YP3dpkatwYHuHH/J5bABZmHwk45CDj4WZqdpvucop +EM5TRXm+zKEt3b/Up/jVHtP6UvOkuM/uPoB4RKSQjwrb5BHmMQyaupQkVk137zN2 +QTc7r8IZMR4YOYYC+uaMwbLNWJFxdkk8f3CtgUttQWRqwIbqC8KFBWMBbYQpiHsb +9cLfEcbJ5A5LpTRU47n5xaT56HLFMqhGw5W9Bnwbj9RbCRaipPJqtqJikXJWodMe +IpsnzOZ5x9WgqmhDAgMBAAGjcTBvMB0GA1UdDgQWBBRqc4VlFLrOKMyWJDsNYrbT +qKp5tzBOBgNVHREBAf8ERDBCgglsb2NhbGhvc3SCE3NlbGVuaXVtLWdyaWQubG9j +YWyCEnNlbGVuaXVtLWdyaWQucHJvZIIMc2VsZW5pdW0uZGV2MA0GCSqGSIb3DQEB +CwUAA4IBAQAGknPZv+3i+VXXThyq7yDHzuVkSYs3EAcvKZeobesp+aDdjmigE/bO +emOrSjoktnhFrFa58qQmiURPZRTkQfRcKKxwJj8tvNJHxT9X6i4trGCLy+KvPQtp +UKEheiM5p7mnoMeF25SoztPtWXcy4OZ6pDc+2FJ++rpEeoBXlzt9yoc+jy4WGEMh +G7rIpDN5K/4lltENrcChoG/SoUYSVGDFAnpHn5/aM7aUoa9LMmYz8cSVlMOBWnDL +MYI8Fejvw7Ke46aoNe8S+r8ruZwPn1AweZWIfEoPx6sJcD/BvA22Jh+FlTZijzD0 +IadxdSDxTcNg0fYa1+UfEAGX4Ts589Rg +-----END CERTIFICATE----- diff --git a/charts/selenium-grid/certs/tls.key b/charts/selenium-grid/certs/tls.key new file mode 100644 index 000000000..c2cf88afb --- /dev/null +++ b/charts/selenium-grid/certs/tls.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDUMWXA7Ka8y5Wz +o/2cA6JkxlxqRtxrAm+YWKzXb4WWB0nX2ZsqWxnNTSDENPlCpLdCNIuGqTmjucYJ +GQKvnzeS8N1R594YP3dpkatwYHuHH/J5bABZmHwk45CDj4WZqdpvucopEM5TRXm+ +zKEt3b/Up/jVHtP6UvOkuM/uPoB4RKSQjwrb5BHmMQyaupQkVk137zN2QTc7r8IZ +MR4YOYYC+uaMwbLNWJFxdkk8f3CtgUttQWRqwIbqC8KFBWMBbYQpiHsb9cLfEcbJ +5A5LpTRU47n5xaT56HLFMqhGw5W9Bnwbj9RbCRaipPJqtqJikXJWodMeIpsnzOZ5 +x9WgqmhDAgMBAAECggEAAoJAuJc4Rge9mxay/X5fyt7yGMZv/d0Ly5XlYvj6AjeG +ISBYYLxlStgcUexp2FRxFj4ozLo4DWLwVsIOFhMysroPdh0FahGxdXTu4fnUV33L +fdZP6r9FE+qTutXnkwvRWVetkxNLOKMb76xt+2zYVX/m6mdMDJmgw0HQs4vXWQJe +8msDQlegojE7PJuJwDxIiGy88OHl5Wnwozwj5NprMDYUu8xrCWWZ4EW5JGTj7mGT +gRkrUj4i3XOhzlb+Cmap1K1jBB8lyj1RCXRHmNjXftXmcOrDcsQMToPG+ZyDOnGl +lBYSEDXCVFxsQhSJSc9WVPBZIOitWEPrWbCn8xHAgQKBgQD6NR4IRxGWMtApq8hZ +r5jxykhihYncnc3BS9chEZjCfnl+gA9+YbN4ra1HBc190lx1sli0XdsVIaktRixw +hL+9DlNTdBDY9gBHIluVSA8tMVBtnxd5Yi28J61dDQ0THEaeXGSjLVXujfF90mRv +pCoGG/3//BfHrPhrGMUlie3iLQKBgQDZGvuYON8Xy67DLOWOKkAf+bEgQ2mZJRxq +s/xCLDA7GNpkaHIF8dpjGH7pufz61k2+8mEvraRSxLptU1nD9jdUWcRcBNHH2PBS +X4vmtOd45cHipQsfkjtluK3E6gYXXK8+x2cVbZHYd0jF5FR7ySWtRUVQExj+98Tw +drgj6HyqLwKBgQD4Dt1de4gWDv6Nsb+KGytY3CFze804KkMpVlVMdbOrb9Rn8/Jo +a9iQ1i8qcLhP+9Sq40xKVZq0kpC1UBMS4qltd9xoqnNhhlK0M330vGI/fdqtM8ME +FrAdEIEx9ZR209u3eQZVOMcvIQ7AnWvxuyHmuK3TskypK/WFyCL8moh7aQKBgQDG +4CLMxHwIjjqe64e0/RsUr2QEC/y1nvsy+4D/FP9xg0i7ZbndnDjTQeMwM4F8Pcem +PN2uEUBP2Yp1Dz9RdUAl8r0fFgMdMKqkqoW7ZsgLRVygQ1O3LftfKRd1JHND/1FB +DuRtCpvpUQvGy2xgoFf1K1ldCsGA/nLXW8k+i393XQKBgAE6O3Mha5cXnsOgvLOW +TketAyamgo0DCJGxCP796tJGL0molsMR07oEVR/qulNSojJJk03EibKe9czTRPmM +MSCL0Ts4/mj5b1nkjZA4OW1vpXiuJN/1AXJapmykQVQQSAUGMTnDBaAtTW4J25Nu +n2W3pwo3jPpXcQWf57AGiNbq +-----END PRIVATE KEY----- diff --git a/charts/selenium-grid/images/SeleniumGrid_TLS_SSL-Passthrough.png b/charts/selenium-grid/images/SeleniumGrid_TLS_SSL-Passthrough.png new file mode 100644 index 0000000000000000000000000000000000000000..86a369600d0b5dec34be27a39d7462eac6146f8a GIT binary patch literal 25624 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

tH3ncM84|)L;e$ z2x=e7J2D}+;#(0leHK9ab`8elT1LTLrgX_LC_z9gg8!F;Epf;uqo}Tls97JWgAOHKM0PNEE?6>jX?@IW8 f@+}YVAI{5E-_BmoNXsjRdj9C)lZSE+oD2L9fHVMH literal 0 HcmV?d00001 diff --git a/charts/selenium-grid/images/SeleniumGrid_TLS_SSL-Termination.png b/charts/selenium-grid/images/SeleniumGrid_TLS_SSL-Termination.png new file mode 100644 index 0000000000000000000000000000000000000000..68822f93727fef85ffc0bb3e75b8ba758dbc8c66 GIT binary patch literal 25618 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 literal 0 HcmV?d00001 diff --git a/charts/selenium-grid/images/SeleniumGrid_TLS_WithoutProxy.png b/charts/selenium-grid/images/SeleniumGrid_TLS_WithoutProxy.png new file mode 100644 index 0000000000000000000000000000000000000000..3153e76f1b40e1d621a6aec9fedfa66ccb8813ec GIT binary patch literal 25727 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 EUjxKg{Qv*} literal 0 HcmV?d00001 diff --git a/charts/selenium-grid/templates/_helpers.tpl b/charts/selenium-grid/templates/_helpers.tpl index be74a65ee..df56b7266 100644 --- a/charts/selenium-grid/templates/_helpers.tpl +++ b/charts/selenium-grid/templates/_helpers.tpl @@ -1,16 +1,29 @@ +{{/* +Server secure connection +*/}} +{{- define "seleniumGrid.server.secureConnection" -}} +{{- $.Values.tls.enabled | ternary "true" "" -}} +{{- end -}} + +{{/* +Ingress proxy forward secure connection +*/}} +{{- define "seleniumGrid.ingress.secureConnection" -}} +{{- or $.Values.tls.enabled $.Values.tls.ingress.enabled $.Values.tls.ingress.generateTLS | ternary "true" "" -}} +{{- end -}} {{/* Protocol of server components */}} {{- define "seleniumGrid.server.protocol" -}} -{{- .Values.tls.enabled | ternary "https" "http" -}} +{{- (eq (include "seleniumGrid.server.secureConnection" $) "true") | ternary "https" "http" -}} {{- end -}} {{/* Probe httpGet schema */}} {{- define "seleniumGrid.probe.httpGet.schema" -}} -{{- .Values.tls.enabled | ternary "HTTPS" "HTTP" -}} +{{- (eq (include "seleniumGrid.server.secureConnection" $) "true") | ternary "HTTPS" "HTTP" -}} {{- end -}} {{/* @@ -69,8 +82,8 @@ Get probe settings {{/* Is registration secret enabled */}} -{{- define "seleniumGrid.tls.registrationSecret.enabled" -}} -{{- .Values.tls.registrationSecret.enabled | ternary "true" "" -}} +{{- define "seleniumGrid.registrationSecret.enabled" -}} +{{- .Values.registrationSecret.enabled | ternary "true" "" -}} {{- end -}} {{/* @@ -106,8 +119,11 @@ nginx.ingress.kubernetes.io/client-body-buffer-size: {{ . | quote }} nginx.ingress.kubernetes.io/proxy-buffers-number: {{ . | quote }} {{- end }} {{- end }} + {{- if .websocket }} +nginx.org/websocket-services: {{ include ($.Values.isolateComponents | ternary "seleniumGrid.router.fullname" "seleniumGrid.hub.fullname") $ | quote }} + {{- end }} {{- end }} -{{- if .Values.tls.enabled }} +{{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} nginx.ingress.kubernetes.io/ssl-passthrough: "true" nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" {{- end }} @@ -285,9 +301,9 @@ template: mountPath: {{ $.Values.nodeConfigMap.extraScriptsDirectory }}/{{ $fileName }} subPath: {{ $fileName }} {{- end }} - {{- if $.Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" $ | quote }} - mountPath: {{ $.Values.serverConfigMap.certVolumeMountPath }} + mountPath: {{ $.Values.tls.certVolumeMountPath }} readOnly: true {{- end }} {{- if .node.extraVolumeMounts }} @@ -479,7 +495,7 @@ template: emptyDir: medium: Memory sizeLimit: {{ default "1Gi" .node.dshmVolumeSizeLimit }} - {{- if $.Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" $ | quote }} secret: secretName: {{ include "seleniumGrid.tls.fullname" $ | quote }} @@ -500,14 +516,33 @@ Get the url of the grid. If the external url can be figured out from the ingress {{- $url }} {{- end -}} +{{/* +Get the url of the grid server in the cluster +*/}} +{{- define "seleniumGrid.server.url" -}} +{{- $url := printf "%s://%s%s%s%s" (include "seleniumGrid.server.url.schema" .) (include "seleniumGrid.url.basicAuth" .) (include "seleniumGrid.server.url.host" .) (include "seleniumGrid.server.url.port" .) (include "seleniumGrid.url.subPath" .) -}} +{{- $url }} +{{- end -}} + +{{/* +Graphql Url of the hub or the router +*/}} +{{- define "seleniumGrid.graphqlURL" -}} +{{- printf "%s/graphql" (include "seleniumGrid.server.url" $) -}} +{{- end -}} + {{- define "seleniumGrid.url.schema" -}} {{- $schema := "http" -}} -{{- if .Values.tls.enabled -}} +{{- if or (eq (include "seleniumGrid.server.secureConnection" $) "true") (eq (include "seleniumGrid.ingress.secureConnection" $) "true") -}} + {{- $schema = "https" -}} +{{- end -}} +{{- $schema }} +{{- end -}} + +{{- define "seleniumGrid.server.url.schema" -}} +{{- $schema := "http" -}} +{{- if eq (include "seleniumGrid.server.secureConnection" $) "true" -}} {{- $schema = "https" -}} -{{- else if .Values.ingress.enabled -}} - {{- if .Values.ingress.tls -}} - {{- $schema = "https" -}} - {{- end -}} {{- end -}} {{- $schema }} {{- end -}} @@ -534,6 +569,11 @@ Get the url of the grid. If the external url can be figured out from the ingress {{- $host }} {{- end -}} +{{- define "seleniumGrid.server.url.host" -}} +{{- $host := printf "%s.%s" (include ($.Values.isolateComponents | ternary "seleniumGrid.router.fullname" "seleniumGrid.hub.fullname") $ ) (.Release.Namespace) -}} +{{- $host }} +{{- end -}} + {{- define "seleniumGrid.url.port" -}} {{- $port := ":4444" -}} {{- if .Values.ingress.enabled -}} @@ -558,6 +598,16 @@ Get the url of the grid. If the external url can be figured out from the ingress {{- $port }} {{- end -}} +{{- define "seleniumGrid.server.url.port" -}} +{{- $port := ":4444" -}} +{{- if .Values.isolateComponents -}} + {{- $port = printf ":%s" (.Values.components.router.port | toString) -}} +{{- else -}} + {{- $port = printf ":%s" (.Values.hub.port | toString) -}} +{{- end -}} +{{- $port }} +{{- end -}} + {{- define "seleniumGrid.url.subPath" -}} {{- $subPath := "" -}} {{- if $.Values.isolateComponents -}} @@ -568,18 +618,11 @@ Get the url of the grid. If the external url can be figured out from the ingress {{- $subPath }} {{- end -}} -{{/* -Graphql Url of the hub or the router -*/}} -{{- define "seleniumGrid.graphqlURL" -}} -{{- printf "%s://%s%s%s/graphql" (include "seleniumGrid.server.protocol" .) (include "seleniumGrid.url.basicAuth" .) (printf "%s.%s" (include ($.Values.isolateComponents | ternary "seleniumGrid.router.fullname" "seleniumGrid.hub.fullname") $) (.Release.Namespace)) (printf ":%s" ($.Values.isolateComponents | ternary ($.Values.components.router.port | toString) ($.Values.hub.port | toString))) -}} -{{- end -}} - {{/* Graphql unsafeSsl of the hub or the router */}} {{- define "seleniumGrid.graphqlURL.unsafeSsl" -}} -{{- $unsafeSsl := printf "%s" (ternary "true" "false" .Values.serverConfigMap.disableHostnameVerification) -}} +{{- $unsafeSsl := printf "%s" (ternary "true" "false" .Values.tls.disableHostnameVerification) -}} {{- $unsafeSsl }} {{- end -}} diff --git a/charts/selenium-grid/templates/distributor-deployment.yaml b/charts/selenium-grid/templates/distributor-deployment.yaml index f727581b1..5f22ac6fe 100644 --- a/charts/selenium-grid/templates/distributor-deployment.yaml +++ b/charts/selenium-grid/templates/distributor-deployment.yaml @@ -83,9 +83,9 @@ spec: mountPath: {{ $.Values.distributorConfigMap.extraScriptsDirectory }}/{{ $fileName }} subPath: {{ $fileName }} {{- end }} - {{- if .Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" . | quote }} - mountPath: {{ .Values.serverConfigMap.certVolumeMountPath | quote }} + mountPath: {{ .Values.tls.certVolumeMountPath | quote }} readOnly: true {{- end }} ports: @@ -170,7 +170,7 @@ spec: configMap: name: {{ template "seleniumGrid.distributor.configmap.fullname" $ }} defaultMode: {{ $.Values.distributorConfigMap.defaultMode }} - {{- if .Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" . | quote }} secret: secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} diff --git a/charts/selenium-grid/templates/event-bus-deployment.yaml b/charts/selenium-grid/templates/event-bus-deployment.yaml index 7946577d0..f48998843 100644 --- a/charts/selenium-grid/templates/event-bus-deployment.yaml +++ b/charts/selenium-grid/templates/event-bus-deployment.yaml @@ -64,9 +64,9 @@ spec: {{- toYaml . | nindent 12 }} {{- end }} volumeMounts: - {{- if .Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" . | quote }} - mountPath: {{ .Values.serverConfigMap.certVolumeMountPath | quote }} + mountPath: {{ .Values.tls.certVolumeMountPath | quote }} readOnly: true {{- end }} {{- with .Values.components.eventBus.resources }} @@ -93,7 +93,7 @@ spec: priorityClassName: {{ . }} {{- end }} volumes: - {{- if .Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" . | quote }} secret: secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} diff --git a/charts/selenium-grid/templates/hub-deployment.yaml b/charts/selenium-grid/templates/hub-deployment.yaml index 0a231e8a2..dc4363a84 100644 --- a/charts/selenium-grid/templates/hub-deployment.yaml +++ b/charts/selenium-grid/templates/hub-deployment.yaml @@ -28,6 +28,7 @@ spec: checksum/server-configmap: {{ include (print $.Template.BasePath "/server-configmap.yaml") . | sha256sum }} checksum/distributor-configmap: {{ include (print $.Template.BasePath "/distributor-configmap.yaml") . | sha256sum }} checksum/secrets: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }} + checksum/tls-cert-secret: {{ include (print $.Template.BasePath "/tls-cert-secret.yaml") . | sha256sum }} {{- with .Values.hub.annotations }} {{- toYaml . | nindent 8 }} {{- end }} @@ -141,9 +142,9 @@ spec: mountPath: {{ $.Values.distributorConfigMap.extraScriptsDirectory }}/{{ $fileName }} subPath: {{ $fileName }} {{- end }} - {{- if .Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" . | quote }} - mountPath: {{ .Values.serverConfigMap.certVolumeMountPath | quote }} + mountPath: {{ .Values.tls.certVolumeMountPath | quote }} readOnly: true {{- end }} {{- with .Values.hub.extraVolumeMounts }} @@ -177,7 +178,7 @@ spec: configMap: name: {{ template "seleniumGrid.distributor.configmap.fullname" $ }} defaultMode: {{ $.Values.distributorConfigMap.defaultMode }} - {{- if .Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" . | quote }} secret: secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} diff --git a/charts/selenium-grid/templates/ingress.yaml b/charts/selenium-grid/templates/ingress.yaml index 9f40cb929..c45c86fd0 100644 --- a/charts/selenium-grid/templates/ingress.yaml +++ b/charts/selenium-grid/templates/ingress.yaml @@ -32,7 +32,7 @@ spec: {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} ingressClassName: {{ .Values.ingress.className }} {{- end }} - {{- if and (or .Values.tls.enabled .Values.tls.ingress.generateTLS) (tpl .Values.ingress.hostname $) (not .Values.ingress.tls) }} + {{- if and (eq (include "seleniumGrid.ingress.secureConnection" $) "true") (tpl .Values.ingress.hostname $) (not .Values.ingress.tls) }} tls: - hosts: - {{ tpl .Values.ingress.hostname $ | quote }} diff --git a/charts/selenium-grid/templates/node-configmap.yaml b/charts/selenium-grid/templates/node-configmap.yaml index 43f5c13dc..24709c623 100644 --- a/charts/selenium-grid/templates/node-configmap.yaml +++ b/charts/selenium-grid/templates/node-configmap.yaml @@ -24,8 +24,8 @@ data: SE_BASIC_AUTH: '{{ template "seleniumGrid.url.basicAuth" $ }}' SE_SUB_PATH: '{{ template "seleniumGrid.url.subPath" $ }}' SE_DRAIN_AFTER_SESSION_COUNT: '{{- and (eq (include "seleniumGrid.useKEDA" .) "true") (eq .Values.autoscaling.scalingType "job") | ternary "1" "0" -}}' - SE_NODE_GRID_URL: '{{ include "seleniumGrid.url" .}}' - SE_NODE_GRID_GRAPHQL_URL: '{{ include "seleniumGrid.graphqlURL" . }}' + SE_NODE_GRID_URL: '{{ include "seleniumGrid.url" $ }}' + SE_NODE_GRID_GRAPHQL_URL: '{{ include "seleniumGrid.graphqlURL" $ }}' {{- if $.Values.nodeConfigMap.leftoversCleanup.enabled }} SE_ENABLE_BROWSER_LEFTOVERS_CLEANUP: 'true' {{- with $.Values.nodeConfigMap.leftoversCleanup.jobIntervalInSecs }} diff --git a/charts/selenium-grid/templates/router-deployment.yaml b/charts/selenium-grid/templates/router-deployment.yaml index 0c76bbfc7..d1587cb5e 100644 --- a/charts/selenium-grid/templates/router-deployment.yaml +++ b/charts/selenium-grid/templates/router-deployment.yaml @@ -83,9 +83,9 @@ spec: mountPath: {{ $.Values.routerConfigMap.extraScriptsDirectory }}/{{ $fileName }} subPath: {{ $fileName }} {{- end }} - {{- if .Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" . | quote }} - mountPath: {{ .Values.serverConfigMap.certVolumeMountPath | quote }} + mountPath: {{ .Values.tls.certVolumeMountPath | quote }} readOnly: true {{- end }} ports: @@ -170,7 +170,7 @@ spec: configMap: name: {{ template "seleniumGrid.router.configmap.fullname" $ }} defaultMode: {{ $.Values.routerConfigMap.defaultMode }} - {{- if .Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" . | quote }} secret: secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} diff --git a/charts/selenium-grid/templates/secrets.yaml b/charts/selenium-grid/templates/secrets.yaml index 87c57d8ff..f3f8038a1 100644 --- a/charts/selenium-grid/templates/secrets.yaml +++ b/charts/selenium-grid/templates/secrets.yaml @@ -24,11 +24,11 @@ data: ROUTER_USERNAME: {{ .Values.basicAuth.username | b64enc }} ROUTER_PASSWORD: {{ .Values.basicAuth.password | b64enc }} {{- end }} -{{- if .Values.tls.enabled }} - SE_JAVA_SSL_TRUST_STORE_PASSWORD: {{ .Values.tls.trustStorePassword | b64enc }} +{{- with $.Values.tls.trustStorePassword }} + SE_JAVA_SSL_TRUST_STORE_PASSWORD: {{ . | b64enc }} {{- end }} -{{- if (include "seleniumGrid.tls.registrationSecret.enabled" $) }} - SE_REGISTRATION_SECRET: {{ .Values.tls.registrationSecret.value | b64enc }} +{{- if (include "seleniumGrid.registrationSecret.enabled" $) }} + SE_REGISTRATION_SECRET: {{ .Values.registrationSecret.value | b64enc }} {{- end }} {{- if .Values.videoRecorder.uploader.secrets }} {{- range $name, $value := .Values.videoRecorder.uploader.secrets }} diff --git a/charts/selenium-grid/templates/server-configmap.yaml b/charts/selenium-grid/templates/server-configmap.yaml index e7eda96ed..5c2489a83 100644 --- a/charts/selenium-grid/templates/server-configmap.yaml +++ b/charts/selenium-grid/templates/server-configmap.yaml @@ -13,12 +13,12 @@ metadata: {{- end }} data: SE_SERVER_PROTOCOL: {{ include "seleniumGrid.server.protocol" . | quote }} +{{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} + SE_HTTPS_CERTIFICATE: {{ printf "%s/%s" .Values.tls.certVolumeMountPath .Values.tls.certificateFile | quote }} + SE_HTTPS_PRIVATE_KEY: {{ printf "%s/%s" .Values.tls.certVolumeMountPath .Values.tls.privateKeyFile | quote }} + SE_JAVA_SSL_TRUST_STORE: {{ printf "%s/%s" .Values.tls.certVolumeMountPath .Values.tls.trustStoreFile | quote }} + SE_JAVA_DISABLE_HOSTNAME_VERIFICATION: {{ .Values.tls.disableHostnameVerification | quote }} +{{- end }} {{- range $key, $value := .Values.serverConfigMap.env }} {{ $key }}: {{ $value | quote }} {{- end }} -{{- if .Values.tls.enabled }} - SE_HTTPS_CERTIFICATE: {{ printf "%s/%s" .Values.serverConfigMap.certVolumeMountPath .Values.serverConfigMap.certificateFile | quote }} - SE_HTTPS_PRIVATE_KEY: {{ printf "%s/%s" .Values.serverConfigMap.certVolumeMountPath .Values.serverConfigMap.privateKeyFile | quote }} - SE_JAVA_SSL_TRUST_STORE: {{ printf "%s/%s" .Values.serverConfigMap.certVolumeMountPath .Values.serverConfigMap.trustStoreFile | quote }} - SE_JAVA_DISABLE_HOSTNAME_VERIFICATION: {{ .Values.serverConfigMap.disableHostnameVerification | quote }} -{{- end }} diff --git a/charts/selenium-grid/templates/session-map-deployment.yaml b/charts/selenium-grid/templates/session-map-deployment.yaml index 3b77d760e..7ad705ade 100644 --- a/charts/selenium-grid/templates/session-map-deployment.yaml +++ b/charts/selenium-grid/templates/session-map-deployment.yaml @@ -60,9 +60,9 @@ spec: {{- toYaml . | nindent 12 }} {{- end }} volumeMounts: - {{- if .Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" . | quote }} - mountPath: {{ .Values.serverConfigMap.certVolumeMountPath | quote }} + mountPath: {{ .Values.tls.certVolumeMountPath | quote }} readOnly: true {{- end }} ports: @@ -92,7 +92,7 @@ spec: priorityClassName: {{ . }} {{- end }} volumes: - {{- if .Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" . | quote }} secret: secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} diff --git a/charts/selenium-grid/templates/session-queuer-deployment.yaml b/charts/selenium-grid/templates/session-queuer-deployment.yaml index 4fcce05ac..999dc95f5 100644 --- a/charts/selenium-grid/templates/session-queuer-deployment.yaml +++ b/charts/selenium-grid/templates/session-queuer-deployment.yaml @@ -57,9 +57,9 @@ spec: {{- toYaml . | nindent 12 }} {{- end }} volumeMounts: - {{- if .Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" . | quote }} - mountPath: {{ .Values.serverConfigMap.certVolumeMountPath | quote }} + mountPath: {{ .Values.tls.certVolumeMountPath | quote }} readOnly: true {{- end }} ports: @@ -89,7 +89,7 @@ spec: priorityClassName: {{ . }} {{- end }} volumes: - {{- if .Values.tls.enabled }} + {{- if eq (include "seleniumGrid.server.secureConnection" $) "true" }} - name: {{ include "seleniumGrid.tls.fullname" . | quote }} secret: secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} diff --git a/charts/selenium-grid/templates/tls-cert-secret.yaml b/charts/selenium-grid/templates/tls-cert-secret.yaml index 1ed202e1f..038fb19e2 100644 --- a/charts/selenium-grid/templates/tls-cert-secret.yaml +++ b/charts/selenium-grid/templates/tls-cert-secret.yaml @@ -1,3 +1,4 @@ +{{- if and (not $.Values.tls.nameOverride) (or (eq (include "seleniumGrid.ingress.secureConnection" $) "true") (eq (include "seleniumGrid.server.secureConnection" $) "true")) }} apiVersion: v1 kind: Secret metadata: @@ -9,21 +10,31 @@ metadata: {{- with .Values.customLabels }} {{- toYaml . | nindent 4 }} {{- end }} -type: Opaque +type: kubernetes.io/tls data: -{{- if and .Values.ingress.enabled .Values.tls.ingress.generateTLS (not .Values.tls.enabled) }} +{{- if and (eq (include "seleniumGrid.ingress.secureConnection" $) "true") $.Values.tls.ingress.generateTLS }} {{- $name := default "SeleniumHQ" .Values.tls.ingress.defaultName -}} {{- $days := default 365 (.Values.tls.ingress.defaultDays | int) -}} {{- $cn := ternary .Values.tls.ingress.defaultCN (tpl .Values.ingress.hostname $) (empty .Values.ingress.hostname) -}} {{- $server := genSelfSignedCert $cn ( default nil .Values.tls.ingress.defaultIPList ) ( default nil .Values.tls.ingress.defaultSANList ) $days }} tls.crt: {{ $server.Cert | b64enc }} tls.key: {{ $server.Key | b64enc }} -{{- else if and .Values.ingress.enabled .Values.tls.enabled }} - tls.crt: {{ default (include "seleniumGrid.tls.getDefaultFile" (list .Values.tls.defaultFile.certificate $)) .Values.tls.certificate | b64enc }} - tls.key: {{ default (include "seleniumGrid.tls.getDefaultFile" (list .Values.tls.defaultFile.privateKey $)) .Values.tls.privateKey | b64enc }} +{{- else if or (eq (include "seleniumGrid.ingress.secureConnection" $) "true") (eq (include "seleniumGrid.server.secureConnection" $) "true") }} +{{- $fileProceeded := list -}} +{{- range $path, $_ := .Files.Glob $.Values.tls.secretFilesImportFrom }} + {{- $fileName := base $path -}} + {{- $value := index $.Values.tls.secretFiles $fileName -}} + {{- if empty $value }} +{{- $fileName | nindent 2 -}}: {{- toYaml ($.Files.Get $path | b64enc) | indent 4 }} + {{- else }} +{{- $fileName | nindent 2 -}}: {{- toYaml ($value | b64enc) | indent 4 }} + {{- end }} + {{- $fileProceeded = append $fileProceeded $fileName -}} +{{- end }} +{{- range $fileName, $value := .Values.tls.secretFiles }} + {{- if not (has $fileName $fileProceeded) }} +{{- $fileName | nindent 2 -}}: {{- toYaml (default "" $value | b64enc) | indent 4 }} + {{- end }} +{{- end }} {{- end }} -{{- if .Values.tls.enabled }} - {{ .Values.serverConfigMap.privateKeyFile }}: {{ default (include "seleniumGrid.tls.getDefaultFile" (list .Values.tls.defaultFile.privateKey $)) .Values.tls.privateKey | b64enc }} - {{ .Values.serverConfigMap.certificateFile }}: {{ default (include "seleniumGrid.tls.getDefaultFile" (list .Values.tls.defaultFile.certificate $)) .Values.tls.certificate | b64enc }} - {{ .Values.serverConfigMap.trustStoreFile }}: {{ default (include "seleniumGrid.tls.getDefaultFile" (list .Values.tls.defaultFile.trustStore $)) .Values.tls.trustStore | b64enc }} {{- end }} diff --git a/charts/selenium-grid/values.yaml b/charts/selenium-grid/values.yaml index 97a574a73..ec3b39ea5 100644 --- a/charts/selenium-grid/values.yaml +++ b/charts/selenium-grid/values.yaml @@ -29,29 +29,37 @@ global: stdoutProbeLog: false tls: + # Name of external secret containing the TLS certificate and key + # nameOverride: enabled: false ingress: + enabled: false generateTLS: false defaultName: "SeleniumHQ" defaultDays: 3650 defaultCN: "www.selenium.dev" # or *.domain.com defaultSANList: [] - # - domain.com + # - staging.domain.com # - production.domain.com defaultIPList: [] # - 10.10.10.10 - defaultFile: - certificate: "certs/selenium.pem" - privateKey: "certs/selenium.pkcs8.base64" - trustStore: "certs/selenium.jks" - certificate: - privateKey: - trustStore: - trustStorePassword: "changeit" - registrationSecret: - enabled: false - value: "HappyTesting" + secretFiles: + tls.crt: "" + tls.key: "" + server.jks: "" + secretFilesImportFrom: "certs/**" + certVolumeMountPath: /etc/ssl/certs/selenium + certificateFile: tls.crt + privateKeyFile: tls.key + trustStoreFile: server.jks + trustStorePassword: "seleniumkeystore" + # Disable verification the hostname included in the server's TLS/SSL certificates matches the hostnames provided + disableHostnameVerification: true + +registrationSecret: + enabled: false + value: "HappyTesting" # Basic auth settings for Selenium Grid basicAuth: @@ -108,6 +116,7 @@ ingress: className: "" # Refer to list nginx annotations: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md#annotations nginx: + websocket: true proxyTimeout: 3600 proxyBuffer: size: 512M @@ -236,12 +245,6 @@ loggingConfigMap: # ConfigMap that contains common environment variables for Server (https://www.selenium.dev/documentation/grid/configuration/cli_options/#server) serverConfigMap: # nameOverride: - certVolumeMountPath: /etc/ssl/certs/selenium - certificateFile: selenium.pem - privateKeyFile: selenium.pkcs8 - trustStoreFile: selenium.jks - # Disable verification the hostname included in the server's TLS/SSL certificates matches the hostnames provided - disableHostnameVerification: true env: SE_JAVA_OPTS: "-XX:+UseZGC" # Custom annotations for configmap diff --git a/tests/charts/ci/base-recorder-values.yaml b/tests/charts/ci/base-recorder-values.yaml index 9ffa5d657..b9d11c36d 100644 --- a/tests/charts/ci/base-recorder-values.yaml +++ b/tests/charts/ci/base-recorder-values.yaml @@ -39,8 +39,3 @@ videoRecorder: RCLONE_CONFIG_GS_SECRET_ACCESS_KEY: "${GS_SECRET_ACCESS_KEY}" RCLONE_CONFIG_GS_ENDPOINT: "https://storage.googleapis.com" RCLONE_CONFIG_GS_NO_CHECK_BUCKET: "true" - -ingress-nginx: - controller: - extraArgs: - default-ssl-certificate: '$(POD_NAMESPACE)/${SELENIUM_TLS_SECRET_NAME}' diff --git a/tests/charts/ci/base-tls-values.yaml b/tests/charts/ci/base-tls-values.yaml index 4a572bb9f..45c6cc3ae 100644 --- a/tests/charts/ci/base-tls-values.yaml +++ b/tests/charts/ci/base-tls-values.yaml @@ -1,9 +1,6 @@ -tls: +registrationSecret: enabled: true - generateTLS: false - registrationSecret: - enabled: true - value: "HappyTestOps" + value: "HappyTestOps" monitoring: enabled: false diff --git a/tests/charts/make/chart_cluster_setup.sh b/tests/charts/make/chart_cluster_setup.sh index d2b806770..1a55f60f5 100755 --- a/tests/charts/make/chart_cluster_setup.sh +++ b/tests/charts/make/chart_cluster_setup.sh @@ -38,17 +38,6 @@ on_failure() { # Trap ERR signal and call on_failure function trap 'on_failure' ERR -# Limit the number of resources to avoid host OOM -CPUs=$(grep -c ^processor /proc/cpuinfo) -if [ "${CPUs}" -gt 1 ]; then - CPUs=$((CPUs-1)) -fi - -MEMORY=$(free -m | awk '/^Mem:/{print $7}') -if [ "${MEMORY}" = "" ]; then - MEMORY=$(free -m | awk '/^Mem:/{print $2}') -fi - if [ "${CLUSTER}" = "kind" ]; then echo "Start Kind cluster" kind create cluster --image kindest/node:${KUBERNETES_VERSION} --wait ${WAIT_TIMEOUT} --name ${CLUSTER_NAME} --config tests/charts/config/kind-cluster.yaml @@ -56,7 +45,7 @@ elif [ "${CLUSTER}" = "minikube" ]; then echo "Start Minikube cluster" sudo chmod 777 /tmp export CHANGE_MINIKUBE_NONE_USER=true - sudo -SE minikube start --vm-driver=none --cpus ${CPUs} --memory ${MEMORY} \ + sudo -SE minikube start --vm-driver=none \ --kubernetes-version=${KUBERNETES_VERSION} --network-plugin=cni --cni=${CNI} --container-runtime=${CONTAINER_RUNTIME} --wait=all sudo chown -R $USER $HOME/.kube $HOME/.minikube fi diff --git a/tests/charts/make/chart_test.sh b/tests/charts/make/chart_test.sh index 76efcb8aa..f2d94bf74 100755 --- a/tests/charts/make/chart_test.sh +++ b/tests/charts/make/chart_test.sh @@ -23,7 +23,7 @@ HUB_CHECKS_MAX_ATTEMPTS=${HUB_CHECKS_MAX_ATTEMPTS:-6} WEB_DRIVER_WAIT_TIMEOUT=${WEB_DRIVER_WAIT_TIMEOUT:-120} AUTOSCALING_POLL_INTERVAL=${AUTOSCALING_POLL_INTERVAL:-20} SKIP_CLEANUP=${SKIP_CLEANUP:-"true"} # For debugging purposes, retain the cluster after the test run -CHART_CERT_PATH=${CHART_CERT_PATH:-"${CHART_PATH}/certs/selenium.pem"} +CHART_CERT_PATH=${CHART_CERT_PATH:-"${CHART_PATH}/certs/tls.crt"} SSL_CERT_DIR=${SSL_CERT_DIR:-"/etc/ssl/certs"} VIDEO_TAG=${VIDEO_TAG:-"latest"} CHART_ENABLE_TRACING=${CHART_ENABLE_TRACING:-"false"} @@ -39,6 +39,12 @@ TEST_UPGRADE_CHART=${TEST_UPGRADE_CHART:-"false"} TEST_PV_CLAIM_NAME=${TEST_PV_CLAIM_NAME:-"selenium-grid-pvc-local"} LIMIT_RESOURCES=${LIMIT_RESOURCES:-"true"} TEST_PLATFORMS=${PLATFORMS:-"linux/amd64"} +if [ "${RELEASE_NAME}" = "selenium" ]; then + SELENIUM_TLS_SECRET_NAME="selenium-tls-secret" +else + SELENIUM_TLS_SECRET_NAME="${RELEASE_NAME}-selenium-tls-secret" +fi +EXTERNAL_TLS_SECRET_NAME=${EXTERNAL_TLS_SECRET_NAME:-"external-tls-secret"} cleanup() { # Get the list of pods @@ -83,11 +89,6 @@ export RELEASE_NAME=${RELEASE_NAME} export SELENIUM_NAMESPACE=${SELENIUM_NAMESPACE} export TEST_PV_CLAIM_NAME=${TEST_PV_CLAIM_NAME} export HOST_PATH=$(realpath ./tests/videos) -if [ "${RELEASE_NAME}" = "selenium" ]; then - export SELENIUM_TLS_SECRET_NAME="selenium-tls-secret" -else - export SELENIUM_TLS_SECRET_NAME="${RELEASE_NAME}-selenium-tls-secret" -fi RECORDER_VALUES_FILE=${TEST_VALUES_PATH}/base-recorder-values.yaml envsubst < ${RECORDER_VALUES_FILE} > ./tests/tests/base-recorder-values.yaml RECORDER_VALUES_FILE=./tests/tests/base-recorder-values.yaml @@ -173,6 +174,59 @@ if [ "${TEST_PLATFORMS}" != "linux/amd64" ]; then " fi +if [ "${SERVICE_TYPE_NODEPORT}" = "true" ]; then + HELM_COMMAND_SET_IMAGES="${HELM_COMMAND_SET_IMAGES} \ + --set ingress.enabled=false \ + --set hub.serviceType=NodePort \ + --set components.router.serviceType=NodePort \ + " +fi + +if [ "${SECURE_INGRESS_ONLY_GENERATE}" = "true" ]; then + HELM_COMMAND_SET_IMAGES="${HELM_COMMAND_SET_IMAGES} \ + --set tls.ingress.generateTLS=true \ + --set tls.ingress.defaultCN=${SELENIUM_GRID_HOST} \ + --set tls.ingress.defaultSANList[0]=${SELENIUM_GRID_HOST} \ + --set tls.ingress.defaultIPList[0]=$(hostname -I | awk '{print $1}') \ + " + kubectl get secret ${SELENIUM_TLS_SECRET_NAME} -n ${SELENIUM_NAMESPACE} -o jsonpath="{.data.tls\.crt}" | base64 -d > ./tests/tests/tls.crt + CHART_CERT_PATH="./tests/tests/tls.crt" +fi + +if [ "${SECURE_INGRESS_ONLY_DEFAULT}" = "true" ]; then + HELM_COMMAND_SET_IMAGES="${HELM_COMMAND_SET_IMAGES} \ + --set tls.ingress.enabled=true \ + " +fi + +if [ "${SECURE_CONNECTION_SERVER}" = "true" ]; then + HELM_COMMAND_SET_IMAGES="${HELM_COMMAND_SET_IMAGES} \ + --set tls.enabled=true \ + " +fi + +if [ "${SECURE_USE_EXTERNAL_CERT}" = "true" ]; then + HELM_COMMAND_SET_IMAGES="${HELM_COMMAND_SET_IMAGES} \ + --set tls.nameOverride=${EXTERNAL_TLS_SECRET_NAME} \ + " + cert_dir="./tests/tests" + ADD_IP_ADDRESS=hostname ./${CHART_PATH}/certs/cert.sh -d ${cert_dir} + kubectl delete secret -n ${SELENIUM_NAMESPACE} ${EXTERNAL_TLS_SECRET_NAME} --ignore-not-found=true + kubectl create secret generic -n ${SELENIUM_NAMESPACE} ${EXTERNAL_TLS_SECRET_NAME} --from-file=tls.crt=${cert_dir}/tls.crt \ + --from-file=tls.key=${cert_dir}/tls.key --from-file=server.jks=${cert_dir}/server.jks + CHART_CERT_PATH="./tests/tests/tls.crt" +fi + +if [ "${SECURE_USE_EXTERNAL_CERT}" = "true" ]; then + HELM_COMMAND_SET_IMAGES="${HELM_COMMAND_SET_IMAGES} \ + --set ingress-nginx.controller.extraArgs.default-ssl-certificate=${SELENIUM_NAMESPACE}/${EXTERNAL_TLS_SECRET_NAME} \ + " +else + HELM_COMMAND_SET_IMAGES="${HELM_COMMAND_SET_IMAGES} \ + --set ingress-nginx.controller.extraArgs.default-ssl-certificate=${SELENIUM_NAMESPACE}/${SELENIUM_TLS_SECRET_NAME} \ + " +fi + if [ "${SELENIUM_GRID_AUTOSCALING}" = "true" ]; then HELM_COMMAND_SET_AUTOSCALING=" \ --set autoscaling.scaledOptions.minReplicaCount=${SELENIUM_GRID_AUTOSCALING_MIN_REPLICA} \ @@ -229,6 +283,11 @@ if [ "${TEST_UPGRADE_CHART}" = "true" ]; then exit 0 fi +if [ "${SECURE_INGRESS_ONLY_GENERATE}" = "true" ]; then + kubectl get secret ${SELENIUM_TLS_SECRET_NAME} -n ${SELENIUM_NAMESPACE} -o jsonpath="{.data.tls\.crt}" | base64 -d > ./tests/tests/tls.crt + CHART_CERT_PATH="./tests/tests/tls.crt" +fi + echo "Run Tests" export CHART_CERT_PATH=$(readlink -f ${CHART_CERT_PATH}) export SELENIUM_GRID_PROTOCOL=${SELENIUM_GRID_PROTOCOL} diff --git a/tests/customCACert/bootstrap.sh b/tests/customCACert/bootstrap.sh index cd83a37de..67f6983cc 100755 --- a/tests/customCACert/bootstrap.sh +++ b/tests/customCACert/bootstrap.sh @@ -13,7 +13,7 @@ trap 'on_failure' ERR NAMESPACE=${NAME:-"selenium"} VERSION=${VERSION:-$TAG_VERSION} -CERT_FILE=${CERT_FILE:-"./charts/selenium-grid/certs/*.pem"} +CERT_FILE=${CERT_FILE:-"./charts/selenium-grid/certs/*.crt"} CERT_SCRIPT=${CERT_SCRIPT:-"./tests/customCACert/cert-script.sh"} COMMON_BUILD_ARGS="--build-arg NAMESPACE=${NAMESPACE} --build-arg VERSION=${VERSION} --build-arg CERT_FILE=${CERT_FILE} --build-arg CERT_SCRIPT=${CERT_SCRIPT}" @@ -22,7 +22,7 @@ docker build ${COMMON_BUILD_ARGS} --build-arg BASE=node-chrome -t ${NAMESPACE}/n docker build ${COMMON_BUILD_ARGS} --build-arg BASE=node-firefox -t ${NAMESPACE}/node-firefox:${VERSION} -f ./tests/customCACert/Dockerfile . docker build ${COMMON_BUILD_ARGS} --build-arg BASE=node-edge -t ${NAMESPACE}/node-edge:${VERSION} -f ./tests/customCACert/Dockerfile . -list_cert_files=($(find ./charts/selenium-grid/certs/ -name "*.pem")) +list_cert_files=($(find ./charts/selenium-grid/certs/ -name "*.crt")) for cert_file_path in "${list_cert_files[@]}"; do cert_file_name="$(basename ${cert_file_path})" cert_name="${cert_file_name%.*}"