diff --git a/.github/workflows/helm-chart-test.yml b/.github/workflows/helm-chart-test.yml index 674031795..42408e0e3 100644 --- a/.github/workflows/helm-chart-test.yml +++ b/.github/workflows/helm-chart-test.yml @@ -13,8 +13,9 @@ jobs: name: Test Helm charts runs-on: ubuntu-latest strategy: + fail-fast: false matrix: - test-strategy: [chart_test, chart_test_parallel_autoscaling] + test-strategy: [chart_test, chart_test_parallel_autoscaling, chart_test_https_tls] steps: - uses: actions/checkout@v4 - name: Output Docker info @@ -24,6 +25,11 @@ jobs: with: python-version: '3.11' check-latest: true + - name: Install CA certificates + run: | + sudo apt install openssl -y + sudo apt install ca-certificates -y + sudo update-ca-certificates --fresh - name: Get branch name (only for push to branch) if: github.event_name == 'push' run: echo "BRANCH=$(echo ${PUSH_BRANCH##*/})" >> $GITHUB_ENV diff --git a/Distributor/start-selenium-grid-distributor.sh b/Distributor/start-selenium-grid-distributor.sh index b0782c3c3..c9af77f71 100755 --- a/Distributor/start-selenium-grid-distributor.sh +++ b/Distributor/start-selenium-grid-distributor.sh @@ -59,6 +59,35 @@ if [ ! -z "$SE_LOG_LEVEL" ]; then SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" fi +if [ ! -z "$SE_EXTERNAL_URL" ]; then + echo "Appending Selenium options: --external-url ${SE_EXTERNAL_URL}" + SE_OPTS="$SE_OPTS --external-url ${SE_EXTERNAL_URL}" +fi + +if [ ! -z "$SE_HTTPS_CERTIFICATE" ]; then + echo "Appending Selenium options: --https-certificate ${SE_HTTPS_CERTIFICATE}" + SE_OPTS="$SE_OPTS --https-certificate ${SE_HTTPS_CERTIFICATE}" +fi + +if [ ! -z "$SE_HTTPS_PRIVATE_KEY" ]; then + echo "Appending Selenium options: --https-private-key ${SE_HTTPS_PRIVATE_KEY}" + SE_OPTS="$SE_OPTS --https-private-key ${SE_HTTPS_PRIVATE_KEY}" +fi + +if [ ! -z "$SE_JAVA_SSL_TRUST_STORE" ]; then + echo "Appending Java options: -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + echo "Appending Java options: -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + echo "Appending Java options: -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" +fi + +if [ ! -z "$SE_REGISTRATION_SECRET" ]; then + echo "Appending Selenium options: --registration-secret ${SE_REGISTRATION_SECRET}" + SE_OPTS="$SE_OPTS --registration-secret ${SE_REGISTRATION_SECRET}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/EventBus/start-selenium-grid-eventbus.sh b/EventBus/start-selenium-grid-eventbus.sh index a8af2c040..25c43f10c 100755 --- a/EventBus/start-selenium-grid-eventbus.sh +++ b/EventBus/start-selenium-grid-eventbus.sh @@ -24,6 +24,30 @@ if [ ! -z "$SE_LOG_LEVEL" ]; then SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" fi +if [ ! -z "$SE_EXTERNAL_URL" ]; then + echo "Appending Selenium options: --external-url ${SE_EXTERNAL_URL}" + SE_OPTS="$SE_OPTS --external-url ${SE_EXTERNAL_URL}" +fi + +if [ ! -z "$SE_HTTPS_CERTIFICATE" ]; then + echo "Appending Selenium options: --https-certificate ${SE_HTTPS_CERTIFICATE}" + SE_OPTS="$SE_OPTS --https-certificate ${SE_HTTPS_CERTIFICATE}" +fi + +if [ ! -z "$SE_HTTPS_PRIVATE_KEY" ]; then + echo "Appending Selenium options: --https-private-key ${SE_HTTPS_PRIVATE_KEY}" + SE_OPTS="$SE_OPTS --https-private-key ${SE_HTTPS_PRIVATE_KEY}" +fi + +if [ ! -z "$SE_JAVA_SSL_TRUST_STORE" ]; then + echo "Appending Java options: -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + echo "Appending Java options: -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + echo "Appending Java options: -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/Hub/start-selenium-grid-hub.sh b/Hub/start-selenium-grid-hub.sh index e25fe16d4..682b28e50 100755 --- a/Hub/start-selenium-grid-hub.sh +++ b/Hub/start-selenium-grid-hub.sh @@ -27,6 +27,35 @@ if [ ! -z "$SE_LOG_LEVEL" ]; then SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" fi +if [ ! -z "$SE_EXTERNAL_URL" ]; then + echo "Appending Selenium options: --external-url ${SE_EXTERNAL_URL}" + SE_OPTS="$SE_OPTS --external-url ${SE_EXTERNAL_URL}" +fi + +if [ ! -z "$SE_HTTPS_CERTIFICATE" ]; then + echo "Appending Selenium options: --https-certificate ${SE_HTTPS_CERTIFICATE}" + SE_OPTS="$SE_OPTS --https-certificate ${SE_HTTPS_CERTIFICATE}" +fi + +if [ ! -z "$SE_HTTPS_PRIVATE_KEY" ]; then + echo "Appending Selenium options: --https-private-key ${SE_HTTPS_PRIVATE_KEY}" + SE_OPTS="$SE_OPTS --https-private-key ${SE_HTTPS_PRIVATE_KEY}" +fi + +if [ ! -z "$SE_JAVA_SSL_TRUST_STORE" ]; then + echo "Appending Java options: -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + echo "Appending Java options: -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + echo "Appending Java options: -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" +fi + +if [ ! -z "$SE_REGISTRATION_SECRET" ]; then + echo "Appending Selenium options: --registration-secret ${SE_REGISTRATION_SECRET}" + SE_OPTS="$SE_OPTS --registration-secret ${SE_REGISTRATION_SECRET}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/Makefile b/Makefile index f9e55dd2c..39a4723ec 100644 --- a/Makefile +++ b/Makefile @@ -397,6 +397,10 @@ chart_test_edge: chart_test_parallel_autoscaling: VERSION=$(TAG_VERSION) NAMESPACE=$(NAMESPACE) ./tests/charts/make/chart_test.sh JobAutoscaling +chart_test_https_tls: + VERSION=$(TAG_VERSION) NAMESPACE=$(NAMESPACE) SELENIUM_GRID_PROTOCOL=https SELENIUM_GRID_PORT=443 \ + ./tests/charts/make/chart_test.sh JobAutoscaling + .PHONY: \ all \ base \ diff --git a/NodeBase/start-selenium-node.sh b/NodeBase/start-selenium-node.sh index 21cd7b946..65402cbec 100755 --- a/NodeBase/start-selenium-node.sh +++ b/NodeBase/start-selenium-node.sh @@ -32,8 +32,8 @@ if [ ! -z "$SE_OPTS" ]; then fi if [ ! -z "$SE_NODE_SESSION_TIMEOUT" ]; then - SE_OPTS="$SE_OPTS --session-timeout $SE_NODE_SESSION_TIMEOUT" - echo "Appending Selenium node session timeout via SE_OPTS: ${SE_OPTS}" + echo "Appending Selenium options: --session-timeout ${SE_NODE_SESSION_TIMEOUT}" + SE_OPTS="$SE_OPTS --session-timeout ${SE_NODE_SESSION_TIMEOUT}" fi if [ ! -z "$SE_LOG_LEVEL" ]; then @@ -41,6 +41,35 @@ if [ ! -z "$SE_LOG_LEVEL" ]; then SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" fi +if [ ! -z "$SE_EXTERNAL_URL" ]; then + echo "Appending Selenium options: --external-url ${SE_EXTERNAL_URL}" + SE_OPTS="$SE_OPTS --external-url ${SE_EXTERNAL_URL}" +fi + +if [ ! -z "$SE_HTTPS_CERTIFICATE" ]; then + echo "Appending Selenium options: --https-certificate ${SE_HTTPS_CERTIFICATE}" + SE_OPTS="$SE_OPTS --https-certificate ${SE_HTTPS_CERTIFICATE}" +fi + +if [ ! -z "$SE_HTTPS_PRIVATE_KEY" ]; then + echo "Appending Selenium options: --https-private-key ${SE_HTTPS_PRIVATE_KEY}" + SE_OPTS="$SE_OPTS --https-private-key ${SE_HTTPS_PRIVATE_KEY}" +fi + +if [ ! -z "$SE_JAVA_SSL_TRUST_STORE" ]; then + echo "Appending Java options: -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + echo "Appending Java options: -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + echo "Appending Java options: -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" +fi + +if [ ! -z "$SE_REGISTRATION_SECRET" ]; then + echo "Appending Selenium options: --registration-secret ${SE_REGISTRATION_SECRET}" + SE_OPTS="$SE_OPTS --registration-secret ${SE_REGISTRATION_SECRET}" +fi + if [ "$GENERATE_CONFIG" = true ]; then echo "Generating Selenium Config" /opt/bin/generate_config diff --git a/NodeDocker/start-selenium-grid-docker.sh b/NodeDocker/start-selenium-grid-docker.sh index a811780e7..935fbee46 100755 --- a/NodeDocker/start-selenium-grid-docker.sh +++ b/NodeDocker/start-selenium-grid-docker.sh @@ -34,6 +34,30 @@ if [ ! -z "$SE_LOG_LEVEL" ]; then SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" fi +if [ ! -z "$SE_EXTERNAL_URL" ]; then + echo "Appending Selenium options: --external-url ${SE_EXTERNAL_URL}" + SE_OPTS="$SE_OPTS --external-url ${SE_EXTERNAL_URL}" +fi + +if [ ! -z "$SE_HTTPS_CERTIFICATE" ]; then + echo "Appending Selenium options: --https-certificate ${SE_HTTPS_CERTIFICATE}" + SE_OPTS="$SE_OPTS --https-certificate ${SE_HTTPS_CERTIFICATE}" +fi + +if [ ! -z "$SE_HTTPS_PRIVATE_KEY" ]; then + echo "Appending Selenium options: --https-private-key ${SE_HTTPS_PRIVATE_KEY}" + SE_OPTS="$SE_OPTS --https-private-key ${SE_HTTPS_PRIVATE_KEY}" +fi + +if [ ! -z "$SE_JAVA_SSL_TRUST_STORE" ]; then + echo "Appending Java options: -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + echo "Appending Java options: -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + echo "Appending Java options: -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/Router/start-selenium-grid-router.sh b/Router/start-selenium-grid-router.sh index bb848a1c7..6a7c0bc78 100755 --- a/Router/start-selenium-grid-router.sh +++ b/Router/start-selenium-grid-router.sh @@ -59,6 +59,35 @@ if [ ! -z "$SE_LOG_LEVEL" ]; then SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" fi +if [ ! -z "$SE_EXTERNAL_URL" ]; then + echo "Appending Selenium options: --external-url ${SE_EXTERNAL_URL}" + SE_OPTS="$SE_OPTS --external-url ${SE_EXTERNAL_URL}" +fi + +if [ ! -z "$SE_HTTPS_CERTIFICATE" ]; then + echo "Appending Selenium options: --https-certificate ${SE_HTTPS_CERTIFICATE}" + SE_OPTS="$SE_OPTS --https-certificate ${SE_HTTPS_CERTIFICATE}" +fi + +if [ ! -z "$SE_HTTPS_PRIVATE_KEY" ]; then + echo "Appending Selenium options: --https-private-key ${SE_HTTPS_PRIVATE_KEY}" + SE_OPTS="$SE_OPTS --https-private-key ${SE_HTTPS_PRIVATE_KEY}" +fi + +if [ ! -z "$SE_JAVA_SSL_TRUST_STORE" ]; then + echo "Appending Java options: -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + echo "Appending Java options: -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + echo "Appending Java options: -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" +fi + +if [ ! -z "$SE_REGISTRATION_SECRET" ]; then + echo "Appending Selenium options: --registration-secret ${SE_REGISTRATION_SECRET}" + SE_OPTS="$SE_OPTS --registration-secret ${SE_REGISTRATION_SECRET}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/SessionQueue/start-selenium-grid-session-queue.sh b/SessionQueue/start-selenium-grid-session-queue.sh index 11074afb9..ac6f5a763 100755 --- a/SessionQueue/start-selenium-grid-session-queue.sh +++ b/SessionQueue/start-selenium-grid-session-queue.sh @@ -24,6 +24,30 @@ if [ ! -z "$SE_LOG_LEVEL" ]; then SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" fi +if [ ! -z "$SE_EXTERNAL_URL" ]; then + echo "Appending Selenium options: --external-url ${SE_EXTERNAL_URL}" + SE_OPTS="$SE_OPTS --external-url ${SE_EXTERNAL_URL}" +fi + +if [ ! -z "$SE_HTTPS_CERTIFICATE" ]; then + echo "Appending Selenium options: --https-certificate ${SE_HTTPS_CERTIFICATE}" + SE_OPTS="$SE_OPTS --https-certificate ${SE_HTTPS_CERTIFICATE}" +fi + +if [ ! -z "$SE_HTTPS_PRIVATE_KEY" ]; then + echo "Appending Selenium options: --https-private-key ${SE_HTTPS_PRIVATE_KEY}" + SE_OPTS="$SE_OPTS --https-private-key ${SE_HTTPS_PRIVATE_KEY}" +fi + +if [ ! -z "$SE_JAVA_SSL_TRUST_STORE" ]; then + echo "Appending Java options: -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + echo "Appending Java options: -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + echo "Appending Java options: -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/Sessions/start-selenium-grid-sessions.sh b/Sessions/start-selenium-grid-sessions.sh index 4d34a1a5b..3a6112388 100755 --- a/Sessions/start-selenium-grid-sessions.sh +++ b/Sessions/start-selenium-grid-sessions.sh @@ -39,6 +39,30 @@ if [ ! -z "$SE_LOG_LEVEL" ]; then SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" fi +if [ ! -z "$SE_EXTERNAL_URL" ]; then + echo "Appending Selenium options: --external-url ${SE_EXTERNAL_URL}" + SE_OPTS="$SE_OPTS --external-url ${SE_EXTERNAL_URL}" +fi + +if [ ! -z "$SE_HTTPS_CERTIFICATE" ]; then + echo "Appending Selenium options: --https-certificate ${SE_HTTPS_CERTIFICATE}" + SE_OPTS="$SE_OPTS --https-certificate ${SE_HTTPS_CERTIFICATE}" +fi + +if [ ! -z "$SE_HTTPS_PRIVATE_KEY" ]; then + echo "Appending Selenium options: --https-private-key ${SE_HTTPS_PRIVATE_KEY}" + SE_OPTS="$SE_OPTS --https-private-key ${SE_HTTPS_PRIVATE_KEY}" +fi + +if [ ! -z "$SE_JAVA_SSL_TRUST_STORE" ]; then + echo "Appending Java options: -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + echo "Appending Java options: -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + echo "Appending Java options: -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/Standalone/start-selenium-standalone.sh b/Standalone/start-selenium-standalone.sh index 955cb15f4..9f8c50baa 100755 --- a/Standalone/start-selenium-standalone.sh +++ b/Standalone/start-selenium-standalone.sh @@ -16,6 +16,30 @@ if [ ! -z "$SE_LOG_LEVEL" ]; then SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" fi +if [ ! -z "$SE_EXTERNAL_URL" ]; then + echo "Appending Selenium options: --external-url ${SE_EXTERNAL_URL}" + SE_OPTS="$SE_OPTS --external-url ${SE_EXTERNAL_URL}" +fi + +if [ ! -z "$SE_HTTPS_CERTIFICATE" ]; then + echo "Appending Selenium options: --https-certificate ${SE_HTTPS_CERTIFICATE}" + SE_OPTS="$SE_OPTS --https-certificate ${SE_HTTPS_CERTIFICATE}" +fi + +if [ ! -z "$SE_HTTPS_PRIVATE_KEY" ]; then + echo "Appending Selenium options: --https-private-key ${SE_HTTPS_PRIVATE_KEY}" + SE_OPTS="$SE_OPTS --https-private-key ${SE_HTTPS_PRIVATE_KEY}" +fi + +if [ ! -z "$SE_JAVA_SSL_TRUST_STORE" ]; then + echo "Appending Java options: -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + echo "Appending Java options: -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + echo "Appending Java options: -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" +fi + /opt/bin/generate_config echo "Selenium Grid Standalone configuration: " diff --git a/StandaloneDocker/start-selenium-grid-docker.sh b/StandaloneDocker/start-selenium-grid-docker.sh index 8571abc7a..cf75e5279 100755 --- a/StandaloneDocker/start-selenium-grid-docker.sh +++ b/StandaloneDocker/start-selenium-grid-docker.sh @@ -19,6 +19,30 @@ if [ ! -z "$SE_LOG_LEVEL" ]; then SE_OPTS="$SE_OPTS --log-level ${SE_LOG_LEVEL}" fi +if [ ! -z "$SE_EXTERNAL_URL" ]; then + echo "Appending Selenium options: --external-url ${SE_EXTERNAL_URL}" + SE_OPTS="$SE_OPTS --external-url ${SE_EXTERNAL_URL}" +fi + +if [ ! -z "$SE_HTTPS_CERTIFICATE" ]; then + echo "Appending Selenium options: --https-certificate ${SE_HTTPS_CERTIFICATE}" + SE_OPTS="$SE_OPTS --https-certificate ${SE_HTTPS_CERTIFICATE}" +fi + +if [ ! -z "$SE_HTTPS_PRIVATE_KEY" ]; then + echo "Appending Selenium options: --https-private-key ${SE_HTTPS_PRIVATE_KEY}" + SE_OPTS="$SE_OPTS --https-private-key ${SE_HTTPS_PRIVATE_KEY}" +fi + +if [ ! -z "$SE_JAVA_SSL_TRUST_STORE" ]; then + echo "Appending Java options: -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStore=${SE_JAVA_SSL_TRUST_STORE}" + echo "Appending Java options: -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djavax.net.ssl.trustStorePassword=${SE_JAVA_SSL_TRUST_STORE_PASSWORD}" + echo "Appending Java options: -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" + SE_JAVA_OPTS="$SE_JAVA_OPTS -Djdk.internal.httpclient.disableHostnameVerification=${SE_JAVA_DISABLE_HOSTNAME_VERIFICATION:-true}" +fi + EXTRA_LIBS="" if [ ! -z "$SE_ENABLE_TRACING" ]; then diff --git a/charts/selenium-grid/README.md b/charts/selenium-grid/README.md index 3568d4cd5..5368ca2ea 100644 --- a/charts/selenium-grid/README.md +++ b/charts/selenium-grid/README.md @@ -21,6 +21,9 @@ This chart enables the creation of a Selenium Grid Server in Kubernetes. * [Configuration of Nodes](#configuration-of-nodes) * [Container ports and Service ports](#container-ports-and-service-ports) * [Probes](#probes) + * [Configuration of Secure Communication (HTTPS)](#configuration-of-secure-communication-https) + * [Secure Communication](#secure-communication) + * [Node Registration](#node-registration) * [Configuration of Selenium Grid chart](#configuration-of-selenium-grid-chart) * [Configuration of KEDA](#configuration-of-keda) * [Configuration of Ingress NGINX Controller](#configuration-of-ingress-nginx-controller) @@ -228,6 +231,23 @@ nginx.ingress.kubernetes.io/client-body-buffer-size nginx.ingress.kubernetes.io/proxy-buffers-number ``` +You can generate a dummy self-signed certificate specify for your `hostname`, assign it to spec `ingress.tls` and NGINX ingress controller default certificate (if it is enabled inline). For example: + +```yaml +tls: + ingress: + generateTLS: true + +ingress: + hostname: "your.domain.com" + +ingress-nginx: + enabled: true + controller: + extraArgs: + default-ssl-certificate: '$(POD_NAMESPACE)/selenium-tls-secret' +``` + ## Configuration ### Configuration global @@ -342,6 +362,78 @@ edgeNode: periodSeconds: 5 ``` +### Configuration of Secure Communication (HTTPS) + +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 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`. + +There are multiple ways to configure your certificate, private key, truststore to the components. You can choose one of them or combine them together. + +- 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. + +- 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: + + ```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" + ``` + 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: + + ```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" + ``` + +- Using Helm CLI `--set-file` to pass your own file to particular config key. For example: + + ```bash + helm upgrade -i test 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 + ``` + +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: + +```yaml +tls: + enabled: true + +ingress-nginx: + enabled: true + controller: + extraArgs: + default-ssl-certificate: '$(POD_NAMESPACE)/selenium-tls-secret' +``` + +#### Node Registration + +In order 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: + +```yaml +tls: + enabled: true + registrationSecret: + enabled: true + value: "matchThisSecret" +``` + ### Configuration of Selenium Grid chart This table contains the configuration parameters of the chart and their default values: diff --git a/charts/selenium-grid/certs/cert.sh b/charts/selenium-grid/certs/cert.sh new file mode 100755 index 000000000..d170d262a --- /dev/null +++ b/charts/selenium-grid/certs/cert.sh @@ -0,0 +1,61 @@ +# 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 + +# Remove existing files +rm -f ${CERTNAME}.* + +# 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= +# Dummy cert without correct SAN, DNS, to skip hostname verification by JAVA_OPTS -Djdk.internal.httpclient.disableHostnameVerification=true +keytool -genkeypair \ + -alias ${ALIAS} \ + -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" \ + -validity 3650 \ + -storepass ${STOREPASS} \ + -keypass ${KEYPASS} \ + -keystore ${CERTNAME}.jks + +# Base64 encode JKS file (for Kubernetes Secret) +#base64 -i ${CERTNAME}.jks -w 0 > ${CERTNAME}.jks.base64 + +# Create PKCS12 from JKS +keytool -importkeystore -srckeystore ${CERTNAME}.jks \ + -destkeystore ${CERTNAME}.p12 \ + -srcstoretype jks \ + -storepass ${STOREPASS} -keypass ${KEYPASS} -srcstorepass ${STOREPASS} \ + -deststoretype pkcs12 + +# Create private key PEM 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 + +# Create certificate PEM 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 + +# Base64 encode Certificate PEM file (for Kubernetes Secret) +#base64 -i ${CERTNAME}.pem -w 0 > ${CERTNAME}.pem.base64 + +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 +fi diff --git a/charts/selenium-grid/certs/selenium.jks b/charts/selenium-grid/certs/selenium.jks new file mode 100644 index 000000000..f3ea9229b Binary files /dev/null and b/charts/selenium-grid/certs/selenium.jks differ diff --git a/charts/selenium-grid/certs/selenium.pem b/charts/selenium-grid/certs/selenium.pem new file mode 100644 index 000000000..b870d2900 --- /dev/null +++ b/charts/selenium-grid/certs/selenium.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID4jCCAsqgAwIBAgIJAJcK6V/XPo7CMA0GCSqGSIb3DQEBCwUAMIGHMRAwDgYD +VQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3du +MRMwEQYDVQQKEwpTZWxlbml1bUhRMSUwIwYDVQQLExxTb2Z0d2FyZSBGcmVlZG9t +IENvbnNlcnZhbmN5MRMwEQYDVQQDEwpTZWxlbml1bUhRMB4XDTI0MDEwNDA2MzMx +MloXDTM0MDEwMTA2MzMxMlowgYcxEDAOBgNVBAYTB1Vua25vd24xEDAOBgNVBAgT +B1Vua25vd24xEDAOBgNVBAcTB1Vua25vd24xEzARBgNVBAoTClNlbGVuaXVtSFEx +JTAjBgNVBAsTHFNvZnR3YXJlIEZyZWVkb20gQ29uc2VydmFuY3kxEzARBgNVBAMT +ClNlbGVuaXVtSFEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCekj09 +xvrD4+nkKmZf10h3TntIFqKI75x35Z2GxwHE2Kqt3eNwbqUrni2zRbYIalddnawW +bOqc2pgEnLtM7VRoCgxlYzARaevfI2uY+EBI4QjgzSTZstuWksPqSmHrLOo4q75w +OSYFUtfaa+6l7ijnVQLKWo4wCnGssk9UBJWvNU9ZMdTzEqLvIMr2Hi0LmKXs9k/F +bIM+XIAAynf8aG4awq0s/eZTirmEqbhmi2udwMNMV60IaC8ZNo53k4VJ+lQWOOwB +/Q1CHRWotjvD4WFt2XI9cCAjbDMpkZONaaCIA70XjTG+5DiGDOUAlap6LFlBrUh4 +3YHQHvXEIKZe2tVDAgMBAAGjTzBNMB0GA1UdDgQWBBRpoVLPxMaU/3QI5x3KUl0x +wL4bVjAsBgNVHREBAf8EIjAggglsb2NhbGhvc3SCE3NlbGVuaXVtLWdyaWQubG9j +YWwwDQYJKoZIhvcNAQELBQADggEBAByNMqeuoiSG1BxnoUGKYiPEurKl8wdsJH8+ +doL5loA7PUnUFY8Vpd4IRHf/RMgTCkSGyLDI/y9lLNLkwkyzt+Wlnfh6sPVXT6DL +cHMrPYavBXZFNStvawS4BztSpcOPOGq6Y2W0gkcVUun8dpS2Dx/w5CW56HzmbPVu +iL9ZW3D6rSm/Qz4cay3rN9MA7WPzTLA3g1YizQLhkvk9JIwNphO16X28qEMIoD2Q +vCGFDdS3xtxmRBj3x/4nGU19WTqECG7eOS4+1Xp5faYietKZVkfhl5rue53wv6lu +v+QNozSyg5nW3YcydA3SeRuf2/kwkvyP61zey4HMHThR+vPKz9U= +-----END CERTIFICATE----- diff --git a/charts/selenium-grid/certs/selenium.pkcs8.base64 b/charts/selenium-grid/certs/selenium.pkcs8.base64 new file mode 100644 index 000000000..f661b989d --- /dev/null +++ b/charts/selenium-grid/certs/selenium.pkcs8.base64 @@ -0,0 +1 @@ +LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2VrajA5eHZyRDQrbmsKS21aZjEwaDNUbnRJRnFLSTc1eDM1WjJHeHdIRTJLcXQzZU53YnFVcm5pMnpSYllJYWxkZG5hd1diT3FjMnBnRQpuTHRNN1ZSb0NneGxZekFSYWV2ZkkydVkrRUJJNFFqZ3pTVFpzdHVXa3NQcVNtSHJMT280cTc1d09TWUZVdGZhCmErNmw3aWpuVlFMS1dvNHdDbkdzc2s5VUJKV3ZOVTlaTWRUekVxTHZJTXIySGkwTG1LWHM5ay9GYklNK1hJQUEKeW5mOGFHNGF3cTBzL2VaVGlybUVxYmhtaTJ1ZHdNTk1WNjBJYUM4Wk5vNTNrNFZKK2xRV09Pd0IvUTFDSFJXbwp0anZENFdGdDJYSTljQ0FqYkRNcGtaT05hYUNJQTcwWGpURys1RGlHRE9VQWxhcDZMRmxCclVoNDNZSFFIdlhFCklLWmUydFZEQWdNQkFBRUNnZ0VBSmpSNXlONmVJSUJUSkFRTE1tQStOM0NUUjJVY3QvMXpKM2dOSWlIa2pUYmUKdUpGVGNRMVhnbERVRmZOZnpsdEF2Vzkxdk5sMUZXR2RhczhRV1pKODJheENIRk52aTJLSHovVkt3VXBld3JCbApZVFJNQXArVFJJNEw0ZkVWOG9HWjFSbWNBcEhpVlRvR2c3dXBmaFVKaWVMemp5bU9SSWpmcG9vM2pyaWtEOWhZCnMzTTJXaHNHdDBwZ1FwZVEreHNTeXRxNjFhT21xdnpLZUE5OUVxZE9keUJ2QkxSMDZyN0FDdlpmeTJvUVpHYXAKUEJ3ZHZIWmNQdXZlUGxVNUpDQWhEcWhlbFIyTHd2dzVhN3FLbjBvTkRFTG5zVnFWblJ3Q0ErUUhjYVBTbG40Nwp0SzI2YUxVdUZLSFg0QW5idDZaNWNMTWdNUzR2bGV3R0h0OG9JUXVCa1FLQmdRQzE1N2NWRkhPc3poUkh6LzBBCkhIVGNqcXB4ditzSUFNVnNCWUlJTVozKzI3MjlVeGFoMllPN1crZjEzVTJlakVsMk1qaW5jTnF1QWVpSmEveWYKTklqcFJtbFJVaWRScUpUUHNQdVJJcEZOWmNCNjh0MnpudFNMa0NkUDJDVTBZaFRpdklVY1RYOEJDRWZ6VDdwSwpjTyt3cTArc0FpRFhoS3pRSUJGaW9sNVZsd0tCZ1FEZktWM0w4V2ZLemFvODFhYndJQkd4M0dnK3BNNElnaTNWCldwMW40TVRuY05mRUJwZ251bVhDa00zSEMvT0VaUnRoYTU0QXdFOWwxUy9vN2RUWEZNNXRWQVQwNXpjNDZuL04KdkFCNUhuYnplS1hDTk5lakI4S1JZNjlvR0U2Ulptb0kxczhvd3ZQUHpCeGE4anN5V3p6M0VoZXY2Z2xHUXBGTwpyVmhWN0h0ck5RS0JnRmpjZEJ5UkhCMExvdTZkMVJzTHk2Nis1dGFnaVdFa2Qwell0L2ZtdlNiMkU0OThHbTlBClFkRHlDYk9hdzBNemh1TjlqeDJFek43NlFhMTRHalZ2eFg0bmptVlNlN0N4YU5pNHZYdmQ1aHRvSElvelFFaHgKeTZUTjY5WmVZWFpnZjVGdnhKclo1TFFOWnBDZW53T2tmZ0xRL1IrcS9uNHA2djNVM0lsUmhrSExBb0dCQU11SgpzVEVYNXpERDBHZFgvc0M0bnlyMyttUlljRXEyWVJOZGFIK2NORHRiWXBBNTY0RWdzenQ0VXhjZXdXYVp5UlZiCjBHcWkvRWZHMzhHMVdoRXB1dlZnVW4wRWZndDlaai9CSHpWWklla0N1enljY2FrU3BOVnlkRU9mRjlucDdRQk8KMi9jemlLaVlZNnhYanNKcEVQdlFGcWF0OFBPU04zSHBETTZodUJlWkFvR0FSZE9IRzlVWXA3M25DQ3d4VHJjKwpnNk91eXI5aXFacVBsalFDK1V4MmtySC9HMTkrSE96RHJLWWFSRElqQk4wTHRyeXJpcVZFQWJWZjZQNHNnNVpCCitjVS9pbDZLb1k2ditQa2tydnZJRVUyVUZHRnpmcnNVZklFQURrdHR5OEdIcTFja0tobjAxWGlNNDJnaGZaSEsKK0lYRExZYzRCMDZ5dFY1bmFZYU9US1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K \ No newline at end of file diff --git a/charts/selenium-grid/templates/_helpers.tpl b/charts/selenium-grid/templates/_helpers.tpl index baa2bc3be..e033bdac4 100644 --- a/charts/selenium-grid/templates/_helpers.tpl +++ b/charts/selenium-grid/templates/_helpers.tpl @@ -1,3 +1,33 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "seleniumGrid.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "seleniumGrid.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "seleniumGrid.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + {{/* Common labels */}} @@ -6,7 +36,7 @@ app.kubernetes.io/managed-by: {{ .Release.Service | lower }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/version: {{ .Chart.AppVersion }} app.kubernetes.io/component: {{ printf "selenium-grid-%s" .Chart.AppVersion }} -helm.sh/chart: {{ printf "%s-%s" .Chart.Name (.Chart.Version | replace "+" "_") }} +helm.sh/chart: {{ include "seleniumGrid.chart" . }} {{- end -}} {{/* @@ -72,7 +102,6 @@ Edge node fullname {{- default "selenium-edge-node" .Values.edgeNode.nameOverride | trunc 63 | trimSuffix "-" -}} {{- end -}} - {{/* Ingress fullname */}} @@ -80,11 +109,18 @@ Ingress fullname {{- default "selenium-ingress" .Values.ingress.nameOverride | trunc 63 | trimSuffix "-" -}} {{- end -}} +{{/* +Protocol of server components +*/}} +{{- define "seleniumGrid.server.protocol" -}} +{{- .Values.tls.enabled | ternary "https" "http" -}} +{{- end -}} + {{/* Probe httpGet schema */}} {{- define "seleniumGrid.probe.httpGet.schema" -}} -{{- "HTTP" -}} +{{- .Values.tls.enabled | ternary "HTTPS" "HTTP" -}} {{- end -}} {{/* @@ -130,6 +166,40 @@ Get probe settings {{- $settings | toYaml -}} {{- end -}} +{{/* +Secret TLS fullname +*/}} +{{- define "seleniumGrid.tls.fullname" -}} +{{- default "selenium-tls-secret" .Values.tls.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Is registration secret enabled +*/}} +{{- define "seleniumGrid.tls.registrationSecret.enabled" -}} +{{- and .Values.tls.enabled .Values.tls.registrationSecret.enabled | ternary "true" "" -}} +{{- end -}} + +{{/* +Get default certificate file name in chart +*/}} +{{- define "seleniumGrid.tls.getDefaultFile" -}} +{{- $value := index . 0 -}} +{{- $global := index . 1 -}} +{{- $content := $global.Files.Get $value -}} +{{- if (contains "base64" (lower $value)) -}} + {{- $content = $content | b64dec -}} +{{- end -}} +{{- $content -}} +{{- end -}} + +{{/* +Common secrets cross components +*/}} +{{- define "seleniumGrid.common.secrets" -}} +{{- default "selenium-secrets" .Values.secrets.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + {{- define "seleniumGrid.ingress.nginx.annotations.default" -}} {{- with .Values.ingress.nginx }} {{- with .proxyTimeout }} @@ -151,6 +221,10 @@ nginx.ingress.kubernetes.io/proxy-buffers-number: {{ . | quote }} {{- end }} {{- end }} {{- end }} +{{- if .Values.tls.enabled }} +nginx.ingress.kubernetes.io/ssl-passthrough: "true" +nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" +{{- end }} {{- end -}} {{/* @@ -262,6 +336,10 @@ template: name: {{ .Values.nodeConfigMap.name }} - configMapRef: name: {{ .Values.loggingConfigMap.name }} + - configMapRef: + name: {{ .Values.serverConfigMap.name }} + - secretRef: + name: {{ include "seleniumGrid.common.secrets" $ | quote }} {{- with .node.extraEnvFrom }} {{- tpl (toYaml .) $ | nindent 10 }} {{- end }} @@ -285,6 +363,11 @@ template: - name: {{ .Values.nodeConfigMap.scriptVolumeMountName }} mountPath: /opt/selenium/{{ .Values.nodeConfigMap.preStopScript }} subPath: {{ .Values.nodeConfigMap.preStopScript }} + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" $ | quote }} + mountPath: {{ .Values.serverConfigMap.certVolumeMountPath }} + readOnly: true + {{- end }} {{- if .node.extraVolumeMounts }} {{- tpl (toYaml .node.extraVolumeMounts) $ | nindent 10 }} {{- end }} @@ -302,7 +385,7 @@ template: {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} {{- else }} httpGet: - scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" $) .schema }} path: {{ .path }} port: {{ default ($.node.port) .port }} {{- end }} @@ -318,7 +401,7 @@ template: {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 12 }} {{- else }} httpGet: - scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" $) .schema }} path: {{ .path }} port: {{ default ($.node.port) .port }} {{- end }} @@ -334,7 +417,7 @@ template: {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} {{- else }} httpGet: - scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" $) .schema }} path: {{ .path }} port: {{ default ($.node.port) .port }} {{- end }} @@ -438,6 +521,11 @@ template: emptyDir: medium: Memory sizeLimit: {{ default "1Gi" .node.dshmVolumeSizeLimit }} + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" $ | quote }} + secret: + secretName: {{ include "seleniumGrid.tls.fullname" $ | quote }} + {{- end }} {{- if .node.extraVolumes }} {{ tpl (toYaml .node.extraVolumes) $ | nindent 6 }} {{- end }} @@ -456,7 +544,9 @@ Get the url of the grid. If the external url can be figured out from the ingress {{- define "seleniumGrid.url.schema" -}} {{- $schema := "http" -}} -{{- if .Values.ingress.enabled -}} +{{- if .Values.tls.enabled -}} + {{- $schema = "https" -}} +{{- else if .Values.ingress.enabled -}} {{- if .Values.ingress.tls -}} {{- $schema = "https" -}} {{- end -}} @@ -522,14 +612,14 @@ Get the url of the grid. If the external url can be figured out from the ingress Graphql Url of the hub or the router */}} {{- define "seleniumGrid.graphqlURL" -}} -{{- printf "http://%s%s%s/graphql" (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))) -}} +{{- 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 "false" "true" (contains (include "seleniumGrid.graphqlURL" .) "https")) -}} +{{- $unsafeSsl := printf "%s" (ternary "true" "false" .Values.serverConfigMap.disableHostnameVerification) -}} {{- $unsafeSsl }} {{- end -}} diff --git a/charts/selenium-grid/templates/distributor-deployment.yaml b/charts/selenium-grid/templates/distributor-deployment.yaml index 990e519fb..52578d6c7 100644 --- a/charts/selenium-grid/templates/distributor-deployment.yaml +++ b/charts/selenium-grid/templates/distributor-deployment.yaml @@ -49,9 +49,19 @@ spec: name: {{ .Values.busConfigMap.name }} - configMapRef: name: {{ .Values.loggingConfigMap.name }} + - configMapRef: + name: {{ .Values.serverConfigMap.name }} + - secretRef: + name: {{ include "seleniumGrid.common.secrets" $ | quote }} {{- with .Values.components.extraEnvFrom }} {{- toYaml . | nindent 12 }} {{- end }} + volumeMounts: + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" . | quote }} + mountPath: {{ .Values.serverConfigMap.certVolumeMountPath | quote }} + readOnly: true + {{- end }} ports: - containerPort: {{ .Values.components.distributor.port }} protocol: TCP @@ -78,4 +88,10 @@ spec: {{- with .Values.components.distributor.priorityClassName }} priorityClassName: {{ . }} {{- end }} + volumes: + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" . | quote }} + secret: + secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} + {{- end }} {{- end }} diff --git a/charts/selenium-grid/templates/event-bus-deployment.yaml b/charts/selenium-grid/templates/event-bus-deployment.yaml index 498570c9b..ef29a6908 100644 --- a/charts/selenium-grid/templates/event-bus-deployment.yaml +++ b/charts/selenium-grid/templates/event-bus-deployment.yaml @@ -45,9 +45,19 @@ spec: envFrom: - configMapRef: name: {{ .Values.loggingConfigMap.name }} + - configMapRef: + name: {{ .Values.serverConfigMap.name }} + - secretRef: + name: {{ include "seleniumGrid.common.secrets" $ | quote }} {{- with .Values.components.extraEnvFrom }} {{- toYaml . | nindent 12 }} {{- end }} + volumeMounts: + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" . | quote }} + mountPath: {{ .Values.serverConfigMap.certVolumeMountPath | quote }} + readOnly: true + {{- end }} {{- with .Values.components.eventBus.resources }} resources: {{- toYaml . | nindent 12 }} {{- end }} @@ -71,4 +81,10 @@ spec: {{- with .Values.components.eventBus.priorityClassName }} priorityClassName: {{ . }} {{- end }} + volumes: + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" . | quote }} + secret: + secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} + {{- end }} {{- end }} diff --git a/charts/selenium-grid/templates/hub-deployment.yaml b/charts/selenium-grid/templates/hub-deployment.yaml index 71473b209..e952215a4 100644 --- a/charts/selenium-grid/templates/hub-deployment.yaml +++ b/charts/selenium-grid/templates/hub-deployment.yaml @@ -49,7 +49,7 @@ spec: {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} {{- else }} httpGet: - scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" $) .schema }} path: {{ .path }} port: {{ default ($.Values.hub.port) .port }} {{- end }} @@ -65,7 +65,7 @@ spec: {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} {{- else }} httpGet: - scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" $) .schema }} path: {{ .path }} port: {{ default ($.Values.hub.port) .port }} {{- end }} @@ -81,7 +81,7 @@ spec: {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} {{- else }} httpGet: - scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" $) .schema }} path: {{ .path }} port: {{ default ($.Values.hub.port) .port }} {{- end }} @@ -95,23 +95,26 @@ spec: - name: SE_SUB_PATH value: {{ . | quote }} {{- end }} - {{- if eq .Values.basicAuth.enabled true}} - - name: ROUTER_USERNAME - value: {{ .Values.basicAuth.username }} - - name: ROUTER_PASSWORD - value: {{ .Values.basicAuth.password }} - {{- end }} {{- with .Values.hub.extraEnvironmentVariables }} {{- tpl (toYaml .) $ | nindent 12 }} {{- end }} envFrom: - configMapRef: name: {{ .Values.loggingConfigMap.name }} + - configMapRef: + name: {{ .Values.serverConfigMap.name }} + - secretRef: + name: {{ include "seleniumGrid.common.secrets" $ | quote }} {{- with .Values.hub.extraEnvFrom }} {{- toYaml . | nindent 12 }} {{- end }} - {{- with .Values.hub.extraVolumeMounts }} volumeMounts: + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" . | quote }} + mountPath: {{ .Values.serverConfigMap.certVolumeMountPath | quote }} + readOnly: true + {{- end }} + {{- with .Values.hub.extraVolumeMounts }} {{- tpl (toYaml .) $ | nindent 12 }} {{- end }} {{- with .Values.hub.resources }} @@ -137,8 +140,13 @@ spec: {{- with .Values.hub.priorityClassName }} priorityClassName: {{ . }} {{- end }} - {{- with .Values.hub.extraVolumes }} volumes: + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" . | quote }} + secret: + secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} + {{- end }} + {{- with .Values.hub.extraVolumes }} {{- tpl (toYaml .) $ | nindent 8 }} {{- end }} {{- end }} diff --git a/charts/selenium-grid/templates/ingress.yaml b/charts/selenium-grid/templates/ingress.yaml index 215cfbace..2f8195b6e 100644 --- a/charts/selenium-grid/templates/ingress.yaml +++ b/charts/selenium-grid/templates/ingress.yaml @@ -32,14 +32,19 @@ spec: {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} ingressClassName: {{ .Values.ingress.className }} {{- end }} - {{- if .Values.ingress.tls }} + {{- if and (or .Values.tls.enabled .Values.tls.ingress.generateTLS) .Values.ingress.hostname (not .Values.ingress.tls) }} + tls: + - hosts: + - {{ .Values.ingress.hostname | quote }} + secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} + {{- else if .Values.ingress.tls }} tls: {{- range .Values.ingress.tls }} - hosts: {{- range .hosts }} - {{ . | quote }} {{- end }} - secretName: {{ .secretName }} + secretName: {{ tpl (.secretName) $ | quote }} {{- end }} {{- end }} rules: diff --git a/charts/selenium-grid/templates/router-deployment.yaml b/charts/selenium-grid/templates/router-deployment.yaml index e02829d46..a57e2682c 100644 --- a/charts/selenium-grid/templates/router-deployment.yaml +++ b/charts/selenium-grid/templates/router-deployment.yaml @@ -49,21 +49,25 @@ spec: - name: SE_SUB_PATH value: {{ . | quote }} {{- end }} - {{- if eq .Values.basicAuth.enabled true}} - - name: ROUTER_USERNAME - value: {{ .Values.basicAuth.username }} - - name: ROUTER_PASSWORD - value: {{ .Values.basicAuth.password }} - {{- end }} {{- with .Values.components.extraEnvironmentVariables }} {{- tpl (toYaml .) $ | nindent 12 }} {{- end }} envFrom: - configMapRef: name: {{ .Values.loggingConfigMap.name }} + - configMapRef: + name: {{ .Values.serverConfigMap.name }} + - secretRef: + name: {{ include "seleniumGrid.common.secrets" $ | quote }} {{- with .Values.components.extraEnvFrom }} {{- toYaml . | nindent 12 }} {{- end }} + volumeMounts: + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" . | quote }} + mountPath: {{ .Values.serverConfigMap.certVolumeMountPath | quote }} + readOnly: true + {{- end }} ports: - containerPort: {{ .Values.components.router.port }} protocol: TCP @@ -74,7 +78,7 @@ spec: {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} {{- else }} httpGet: - scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" $) .schema }} path: {{ .path }} port: {{ default ($.Values.components.router.port) .port }} {{- end }} @@ -90,7 +94,7 @@ spec: {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} {{- else }} httpGet: - scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" $) .schema }} path: {{ .path }} port: {{ default ($.Values.components.router.port) .port }} {{- end }} @@ -107,7 +111,7 @@ spec: {{- include "seleniumGrid.probe.fromUserDefine" . | nindent 10 }} {{- else }} httpGet: - scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" .) .schema }} + scheme: {{ default (include "seleniumGrid.probe.httpGet.schema" $) .schema }} path: {{ .path }} port: {{ default ($.Values.components.router.port) .port }} {{- end }} @@ -139,4 +143,10 @@ spec: {{- with .Values.components.router.priorityClassName }} priorityClassName: {{ . }} {{- end }} + volumes: + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" . | quote }} + secret: + secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} + {{- end }} {{- end }} diff --git a/charts/selenium-grid/templates/secrets.yaml b/charts/selenium-grid/templates/secrets.yaml new file mode 100644 index 000000000..06881d15a --- /dev/null +++ b/charts/selenium-grid/templates/secrets.yaml @@ -0,0 +1,33 @@ +{{- if .Values.secrets.create }} +apiVersion: v1 +kind: Secret +metadata: +{{- with .Values.secrets.annotations }} + annotations: {{- toYaml . | nindent 4 }} +{{- end }} + name: {{ include "seleniumGrid.common.secrets" . }} + labels: + {{- include "seleniumGrid.commonLabels" . | nindent 4 }} + {{- with .Values.customLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: +{{- range $name, $value := .Values.secrets.env }} +{{- if not (empty $value) }} + {{- $_ := set $ "name" $name }} + {{- $_ := set $ "value" $value }} + {{ $name }}: {{ tpl ($value) $ | b64enc }} +{{- end }} +{{- end }} +{{- if eq .Values.basicAuth.enabled true }} + 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 }} +{{- end }} +{{- if (include "seleniumGrid.tls.registrationSecret.enabled" $) }} + SE_REGISTRATION_SECRET: {{ .Values.tls.registrationSecret.value | b64enc }} +{{- end }} +{{- end }} diff --git a/charts/selenium-grid/templates/server-configmap.yaml b/charts/selenium-grid/templates/server-configmap.yaml new file mode 100644 index 000000000..3e4e4b766 --- /dev/null +++ b/charts/selenium-grid/templates/server-configmap.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.serverConfigMap.name }} + namespace: {{ .Release.Namespace }} +{{- with .Values.busConfigMap.annotations }} + annotations: {{- toYaml . | nindent 4 }} +{{- end }} + labels: + {{- include "seleniumGrid.commonLabels" . | nindent 4 }} + {{- with .Values.customLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +data: +{{- 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 2edd701e2..27d120540 100644 --- a/charts/selenium-grid/templates/session-map-deployment.yaml +++ b/charts/selenium-grid/templates/session-map-deployment.yaml @@ -38,11 +38,21 @@ spec: envFrom: - configMapRef: name: {{ .Values.loggingConfigMap.name }} + - configMapRef: + name: {{ .Values.serverConfigMap.name }} + - secretRef: + name: {{ include "seleniumGrid.common.secrets" $ | quote }} - configMapRef: name: {{ .Values.busConfigMap.name }} {{- with .Values.components.extraEnvFrom }} {{- toYaml . | nindent 12 }} {{- end }} + volumeMounts: + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" . | quote }} + mountPath: {{ .Values.serverConfigMap.certVolumeMountPath | quote }} + readOnly: true + {{- end }} ports: - containerPort: {{ .Values.components.sessionMap.port }} protocol: TCP @@ -69,4 +79,10 @@ spec: {{- with .Values.components.sessionMap.priorityClassName }} priorityClassName: {{ . }} {{- end }} + volumes: + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" . | quote }} + secret: + secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} + {{- end }} {{- end }} diff --git a/charts/selenium-grid/templates/session-queuer-deployment.yaml b/charts/selenium-grid/templates/session-queuer-deployment.yaml index 379285038..546090e43 100644 --- a/charts/selenium-grid/templates/session-queuer-deployment.yaml +++ b/charts/selenium-grid/templates/session-queuer-deployment.yaml @@ -38,9 +38,19 @@ spec: envFrom: - configMapRef: name: {{ .Values.loggingConfigMap.name }} + - configMapRef: + name: {{ .Values.serverConfigMap.name }} + - secretRef: + name: {{ include "seleniumGrid.common.secrets" $ | quote }} {{- with .Values.components.extraEnvFrom }} {{- toYaml . | nindent 12 }} {{- end }} + volumeMounts: + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" . | quote }} + mountPath: {{ .Values.serverConfigMap.certVolumeMountPath | quote }} + readOnly: true + {{- end }} ports: - containerPort: {{ .Values.components.sessionQueue.port }} protocol: TCP @@ -67,4 +77,10 @@ spec: {{- with .Values.components.sessionQueue.priorityClassName }} priorityClassName: {{ . }} {{- end }} + volumes: + {{- if .Values.tls.enabled }} + - name: {{ include "seleniumGrid.tls.fullname" . | quote }} + secret: + secretName: {{ include "seleniumGrid.tls.fullname" . | quote }} + {{- end }} {{- end }} diff --git a/charts/selenium-grid/templates/tls-cert-secret.yaml b/charts/selenium-grid/templates/tls-cert-secret.yaml new file mode 100644 index 000000000..000a1e5a7 --- /dev/null +++ b/charts/selenium-grid/templates/tls-cert-secret.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Secret +metadata: + annotations: + "restartOnUpdate": "true" + name: {{ include "seleniumGrid.tls.fullname" . }} + labels: + {{- include "seleniumGrid.commonLabels" . | nindent 4 }} + {{- with .Values.customLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: +{{- if and .Values.ingress.enabled .Values.tls.ingress.generateTLS (not .Values.tls.enabled) }} + {{- $name := default "SeleniumHQ" .Values.tls.ingress.defaultName -}} + {{- $days := default 365 (.Values.tls.ingress.defaultDays | int) -}} + {{- $cn := ternary .Values.tls.ingress.defaultCN .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 }} +{{- 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 f4a094c16..fa29d28b9 100644 --- a/charts/selenium-grid/values.yaml +++ b/charts/selenium-grid/values.yaml @@ -17,6 +17,31 @@ global: # Log level for all components. Possible values describe here: https://www.selenium.dev/documentation/grid/configuration/cli_options/#logging logLevel: INFO +tls: + enabled: false + ingress: + generateTLS: false + defaultName: "SeleniumHQ" + defaultDays: 3650 + defaultCN: "www.selenium.dev" + # or *.domain.com + defaultSANList: [] + # - 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" + # Basic auth settings for Selenium Grid basicAuth: # Enable or disable basic auth @@ -89,6 +114,26 @@ loggingConfigMap: # Custom annotations for configmap annotations: {} +# ConfigMap that contains common environment variables for Server (https://www.selenium.dev/documentation/grid/configuration/cli_options/#server) +serverConfigMap: + name: selenium-server-config + 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 + # Custom annotations for configmap + annotations: {} + +# Secrets for all components. Components environment variables contain sensitive data should be stored in secrets. +secrets: + create: true + name: selenium-secrets + env: + SE_VNC_PASSWORD: "secret" + annotations: {} + # Configuration for isolated components (applied only if `isolateComponents: true`) components: diff --git a/tests/SeleniumTests/__init__.py b/tests/SeleniumTests/__init__.py index 4ca352683..0938d6939 100644 --- a/tests/SeleniumTests/__init__.py +++ b/tests/SeleniumTests/__init__.py @@ -10,6 +10,7 @@ from selenium.webdriver.edge.options import Options as EdgeOptions from selenium.webdriver.chrome.options import Options as ChromeOptions +SELENIUM_GRID_PROTOCOL = os.environ.get('SELENIUM_GRID_PROTOCOL', 'http') SELENIUM_GRID_HOST = os.environ.get('SELENIUM_GRID_HOST', 'localhost') SELENIUM_GRID_PORT = os.environ.get('SELENIUM_GRID_PORT', '4444') WEB_DRIVER_WAIT_TIMEOUT = int(os.environ.get('WEB_DRIVER_WAIT_TIMEOUT', 60)) @@ -95,7 +96,7 @@ def setUp(self): options.add_argument('disable-features=DownloadBubble,DownloadBubbleV2') self.driver = webdriver.Remote( options=options, - command_executor="http://%s:%s" % (SELENIUM_GRID_HOST,SELENIUM_GRID_PORT) + command_executor="%s://%s:%s" % (SELENIUM_GRID_PROTOCOL,SELENIUM_GRID_HOST,SELENIUM_GRID_PORT) ) class EdgeTests(SeleniumGenericTests): @@ -105,7 +106,7 @@ def setUp(self): options.add_argument('disable-features=DownloadBubble,DownloadBubbleV2') self.driver = webdriver.Remote( options=options, - command_executor="http://%s:%s" % (SELENIUM_GRID_HOST,SELENIUM_GRID_PORT) + command_executor="%s://%s:%s" % (SELENIUM_GRID_PROTOCOL,SELENIUM_GRID_HOST,SELENIUM_GRID_PORT) ) @@ -119,7 +120,7 @@ def setUp(self): options.enable_downloads = True self.driver = webdriver.Remote( options=options, - command_executor="http://%s:%s" % (SELENIUM_GRID_HOST,SELENIUM_GRID_PORT) + command_executor="%s://%s:%s" % (SELENIUM_GRID_PROTOCOL,SELENIUM_GRID_HOST,SELENIUM_GRID_PORT) ) def test_title_and_maximize_window(self): diff --git a/tests/SmokeTests/__init__.py b/tests/SmokeTests/__init__.py index a2f74c7fa..2cd737017 100644 --- a/tests/SmokeTests/__init__.py +++ b/tests/SmokeTests/__init__.py @@ -2,12 +2,13 @@ import unittest import time import json - +from ssl import _create_unverified_context try: from urllib2 import urlopen except ImportError: from urllib.request import urlopen +SELENIUM_GRID_PROTOCOL = os.environ.get('SELENIUM_GRID_PROTOCOL', 'http') SELENIUM_GRID_HOST = os.environ.get('SELENIUM_GRID_HOST', 'localhost') SELENIUM_GRID_PORT = os.environ.get('SELENIUM_GRID_PORT', '4444') SELENIUM_GRID_AUTOSCALING = os.environ.get('SELENIUM_GRID_AUTOSCALING', 'false') @@ -28,7 +29,7 @@ def smoke_test_container(self, port): while current_attempts < max_attempts: current_attempts = current_attempts + 1 try: - response = urlopen('http://%s:%s/status' % (SELENIUM_GRID_HOST, port)) + response = urlopen('%s://%s:%s/status' % (SELENIUM_GRID_PROTOCOL, SELENIUM_GRID_HOST, port), context=_create_unverified_context()) status_json = json.loads(response.read()) if not auto_scaling or (auto_scaling and auto_scaling_min_replica > 0): self.assertTrue(status_json['value']['ready'], "Container is not ready on port %s" % port) diff --git a/tests/bootstrap.sh b/tests/bootstrap.sh index 7ce7b8cf4..3d02bf550 100755 --- a/tests/bootstrap.sh +++ b/tests/bootstrap.sh @@ -11,6 +11,10 @@ python -m pip install selenium==4.16.0 \ docker===6.1.3 \ | grep -v 'Requirement already satisfied' +if [ "${SELENIUM_GRID_PROTOCOL}" = "https" ]; then + export REQUESTS_CA_BUNDLE="${CHART_CERT_PATH}" +fi + python test.py $1 ret_code=$? diff --git a/tests/charts/ci/DeploymentAutoScaling-values.yaml b/tests/charts/ci/DeploymentAutoScaling-values.yaml index b9e5b120e..08dcf1cb0 100644 --- a/tests/charts/ci/DeploymentAutoScaling-values.yaml +++ b/tests/charts/ci/DeploymentAutoScaling-values.yaml @@ -35,14 +35,13 @@ chromeNode: extraEnvironmentVariables: &extraEnvironmentVariables - name: SE_OPTS value: "--enable-managed-downloads true" - - name: SE_DRAIN_AFTER_SESSION_COUNT - value: "0" readinessProbe: enabled: &readinessProbe true livenessProbe: enabled: &livenessProbe true # Configuration for edge nodes edgeNode: + port: 8888 # (test): user is able to define extra container ports ports: - containerPort: 5900 diff --git a/tests/charts/ci/JobAutoscaling-values.yaml b/tests/charts/ci/JobAutoscaling-values.yaml index d8fc0bc79..35742e41a 100644 --- a/tests/charts/ci/JobAutoscaling-values.yaml +++ b/tests/charts/ci/JobAutoscaling-values.yaml @@ -11,7 +11,7 @@ autoscaling: # Configuration for chrome nodes chromeNode: nameOverride: my-chrome-name - extraEnvironmentVariables: + extraEnvironmentVariables: &extraEnvironmentVariables - name: SE_OPTS value: "--enable-managed-downloads true" readinessProbe: @@ -21,9 +21,7 @@ chromeNode: # Configuration for edge nodes edgeNode: nameOverride: my-edge-name - extraEnvironmentVariables: - - name: SE_OPTS - value: "--enable-managed-downloads true" + extraEnvironmentVariables: *extraEnvironmentVariables readinessProbe: enabled: *readinessProbe livenessProbe: @@ -31,20 +29,8 @@ edgeNode: # Configuration for firefox nodes firefoxNode: nameOverride: my-firefox-name - extraEnvironmentVariables: - - name: SE_OPTS - value: "--enable-managed-downloads true" + extraEnvironmentVariables: *extraEnvironmentVariables readinessProbe: enabled: *readinessProbe livenessProbe: enabled: *livenessProbe - -ingress: - paths: - - path: /selenium(/|$)(.*) - pathType: ImplementationSpecific - backend: - service: - name: '{{ template "seleniumGrid.hub.fullname" $ }}' - port: - number: 4444 diff --git a/tests/charts/ci/auth-ingress-values.yaml b/tests/charts/ci/auth-ingress-values.yaml index 38bc87e1b..4ccd0a6f2 100644 --- a/tests/charts/ci/auth-ingress-values.yaml +++ b/tests/charts/ci/auth-ingress-values.yaml @@ -1,5 +1,7 @@ global: K8S_PUBLIC_IP: localhost + seleniumGrid: + logLevel: INFO ingress: annotations: @@ -17,7 +19,7 @@ ingress: pathType: ImplementationSpecific backend: service: - name: '{{ template "seleniumGrid.router.fullname" $ }}' + name: '{{ ternary (include "seleniumGrid.router.fullname" $ ) (include "seleniumGrid.hub.fullname" $ ) $.Values.isolateComponents }}' port: number: 4444 diff --git a/tests/charts/ci/tls-values.yaml b/tests/charts/ci/tls-values.yaml new file mode 100644 index 000000000..0f7439251 --- /dev/null +++ b/tests/charts/ci/tls-values.yaml @@ -0,0 +1,11 @@ +tls: + enabled: true + generateTLS: false + registrationSecret: + enabled: true + value: "HappyTestOps" + +ingress-nginx: + controller: + extraArgs: + default-ssl-certificate: '$(POD_NAMESPACE)/selenium-tls-secret' diff --git a/tests/charts/make/chart_test.sh b/tests/charts/make/chart_test.sh index 194bb6056..617d3ef6e 100755 --- a/tests/charts/make/chart_test.sh +++ b/tests/charts/make/chart_test.sh @@ -11,6 +11,7 @@ INGRESS_NAMESPACE=${INGRESS_NAMESPACE:-"ingress-nginx"} SUB_PATH=${SUB_PATH:-"/selenium"} CHART_PATH=${CHART_PATH:-"charts/selenium-grid"} TEST_VALUES_PATH=${TEST_VALUES_PATH:-"tests/charts/ci"} +SELENIUM_GRID_PROTOCOL=${SELENIUM_GRID_PROTOCOL:-"http"} SELENIUM_GRID_HOST=${SELENIUM_GRID_HOST:-"localhost"} SELENIUM_GRID_PORT=${SELENIUM_GRID_PORT:-"80"} MATRIX_BROWSER=${1:-"NodeChrome"} @@ -20,6 +21,8 @@ WAIT_TIMEOUT=${WAIT_TIMEOUT:-"90s"} HUB_CHECKS_INTERVAL=${HUB_CHECKS_INTERVAL:-45} WEB_DRIVER_WAIT_TIMEOUT=${WEB_DRIVER_WAIT_TIMEOUT:-120} SKIP_CLEANUP=${SKIP_CLEANUP:-"false"} # For debugging purposes, retain the cluster after the test run +CHART_CERT_PATH=${CHART_CERT_PATH:-"${CHART_PATH}/certs/selenium.pem"} +SSL_CERT_DIR=${SSL_CERT_DIR:-"/etc/ssl/certs"} cleanup() { if [ "${SKIP_CLEANUP}" = "false" ]; then @@ -49,11 +52,17 @@ if [ "${SELENIUM_GRID_AUTOSCALING}" = "true" ]; then --set autoscaling.scaledOptions.minReplicaCount=${SELENIUM_GRID_AUTOSCALING_MIN_REPLICA}" fi +HELM_COMMAND_SET_TLS="" +if [ "${SELENIUM_GRID_PROTOCOL}" = "https" ]; then + HELM_COMMAND_SET_TLS="--values ${TEST_VALUES_PATH}/tls-values.yaml" +fi + HELM_COMMAND_ARGS="${RELEASE_NAME} \ --values ${TEST_VALUES_PATH}/auth-ingress-values.yaml \ --values ${TEST_VALUES_PATH}/tracing-values.yaml \ ---values ${TEST_VALUES_PATH}/${MATRIX_BROWSER}-values.yaml \ ${HELM_COMMAND_SET_AUTOSCALING} \ +${HELM_COMMAND_SET_TLS} \ +--values ${TEST_VALUES_PATH}/${MATRIX_BROWSER}-values.yaml \ --set global.seleniumGrid.imageTag=${VERSION} --set global.seleniumGrid.imageRegistry=${NAMESPACE} \ --set global.seleniumGrid.nodesImageTag=${VERSION} \ ${CHART_PATH} --namespace ${SELENIUM_NAMESPACE} --create-namespace" @@ -65,6 +74,8 @@ echo "Deploy Selenium Grid Chart" helm upgrade --install ${HELM_COMMAND_ARGS} echo "Run Tests" +export CHART_CERT_PATH=$(readlink -f ${CHART_CERT_PATH}) +export SELENIUM_GRID_PROTOCOL=${SELENIUM_GRID_PROTOCOL} export SELENIUM_GRID_HOST=${SELENIUM_GRID_HOST} export SELENIUM_GRID_PORT=${SELENIUM_GRID_PORT}""${SUB_PATH} export SELENIUM_GRID_AUTOSCALING=${SELENIUM_GRID_AUTOSCALING} diff --git a/tests/charts/refValues/sample-aws.yaml b/tests/charts/refValues/sample-aws.yaml index 06172f0e3..097eb4277 100644 --- a/tests/charts/refValues/sample-aws.yaml +++ b/tests/charts/refValues/sample-aws.yaml @@ -22,7 +22,7 @@ ingress: pathType: ImplementationSpecific backend: service: - name: '{{ template "seleniumGrid.router.fullname" $ }}' + name: '{{ ternary (include "seleniumGrid.router.fullname" $ ) (include "seleniumGrid.hub.fullname" $ ) $.Values.isolateComponents }}' port: number: 4444 diff --git a/tests/charts/refValues/simplex-minikube.yaml b/tests/charts/refValues/simplex-minikube.yaml index 5239714c7..a67b0bbf2 100644 --- a/tests/charts/refValues/simplex-minikube.yaml +++ b/tests/charts/refValues/simplex-minikube.yaml @@ -14,6 +14,11 @@ global: # nodesImageTag: latest # videoImageTag: latest +tls: +# enabled: true + ingress: + generateTLS: true + ingress: enabled: true annotations: @@ -28,7 +33,7 @@ ingress: pathType: ImplementationSpecific backend: service: - name: '{{ template "seleniumGrid.router.fullname" $ }}' + name: '{{ ternary (include "seleniumGrid.router.fullname" $ ) (include "seleniumGrid.hub.fullname" $ ) $.Values.isolateComponents }}' port: number: 4444 @@ -38,7 +43,8 @@ basicAuth: isolateComponents: true autoscaling: - enabled: true +# enabled: true + enableWithExistingKEDA: true scalingType: job annotations: helm.sh/hook: post-install,post-upgrade,post-rollback @@ -82,6 +88,9 @@ videoRecorder: ingress-nginx: enabled: true controller: + # Set controller default certificate use the same with Selenium Grid + extraArgs: + default-ssl-certificate: '$(POD_NAMESPACE)/selenium-tls-secret' hostNetwork: true kind: DaemonSet service: diff --git a/tests/charts/templates/render/dummy.yaml b/tests/charts/templates/render/dummy.yaml index 42864d78f..b5b2ef971 100644 --- a/tests/charts/templates/render/dummy.yaml +++ b/tests/charts/templates/render/dummy.yaml @@ -18,6 +18,10 @@ basicAuth: username: sysadmin password: strongPassword +tls: + enabled: true + generateTLS: false + ingress: nginx: proxyTimeout: 360 # Set different proxy timout @@ -39,14 +43,14 @@ ingress: pathType: ImplementationSpecific backend: service: - name: '{{ template "seleniumGrid.router.fullname" $ }}' + name: '{{ ternary (include "seleniumGrid.router.fullname" $ ) (include "seleniumGrid.hub.fullname" $ ) $.Values.isolateComponents }}' port: number: 4444 - path: /(/?)(session/.*/se/vnc) pathType: ImplementationSpecific backend: service: - name: '{{ template "seleniumGrid.router.fullname" $ }}' + name: '{{ ternary (include "seleniumGrid.router.fullname" $ ) (include "seleniumGrid.hub.fullname" $ ) $.Values.isolateComponents }}' port: number: 4444 diff --git a/tests/charts/templates/test.py b/tests/charts/templates/test.py index 8587b42d7..a40cbd22d 100644 --- a/tests/charts/templates/test.py +++ b/tests/charts/templates/test.py @@ -51,7 +51,7 @@ def test_sub_path_append_to_node_grid_url(self): for doc in LIST_OF_DOCUMENTS: if doc['metadata']['name'] in resources_name and doc['kind'] == 'ConfigMap': logger.info(f"Assert subPath is appended to node grid url") - self.assertTrue(doc['data']['SE_NODE_GRID_URL'] == 'http://sysadmin:strongPassword@10.10.10.10:8081/selenium') + self.assertTrue(doc['data']['SE_NODE_GRID_URL'] == 'https://sysadmin:strongPassword@10.10.10.10:8443/selenium') count += 1 self.assertEqual(count, len(resources_name), "No node config resources found") @@ -84,8 +84,9 @@ def test_log_level_set_to_logging_config_map(self): logger.info(f"Assert logging ConfigMap is set to envFrom in resource {doc['metadata']['name']}") list_env_from = doc['spec']['template']['spec']['containers'][0]['envFrom'] for env in list_env_from: - if env['configMapRef']['name'] == 'selenium-logging-config': - is_present = True + if env.get('configMapRef') is not None: + if env['configMapRef']['name'] == 'selenium-logging-config': + is_present = True self.assertTrue(is_present, "envFrom doesn't contain logging ConfigMap") count += 1 self.assertEqual(count, len(resources_name), "Logging ConfigMap is not present in expected resources")