From 78d52c492c558b8c77501e03a7b56be0b8bca312 Mon Sep 17 00:00:00 2001 From: Mason Malone Date: Mon, 16 Sep 2024 10:08:31 -0700 Subject: [PATCH] build(ui): support TLS for UI and Argo Server This adds a new `make start UI_SECURE=true` flag that can be used to test Argo with a TLS termination proxy in front, which is needed for https://github.com/argoproj/argo-workflows/issues/13031 Also, `make start SECURE=true UI=true` was broken because `ui/src/app/webpack.config.js` wasn't respecting the `ARGO_SECURE` flag, so I fixed that too. Signed-off-by: Mason Malone --- Makefile | 8 ++++-- dev/nix/conf.nix | 6 +++- docs/running-locally.md | 35 +++++++++++++++++++++++ manifests/quick-start/sso/dex/dex-cm.yaml | 1 + tasks.yaml | 3 ++ ui/src/app/webpack.config.js | 27 ++++++++--------- 6 files changed, 64 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index b540113196f53..de05ba293c62b 100644 --- a/Makefile +++ b/Makefile @@ -50,12 +50,16 @@ endif PROFILE ?= minimal KUBE_NAMESPACE ?= argo # namespace where Kubernetes resources/RBAC will be installed PLUGINS ?= $(shell [ $PROFILE = plugins ] && echo false || echo true) -UI ?= false # start the UI +UI ?= false # start the UI with HTTP +UI_SECURE ?= false # start the UI with HTTPS API ?= $(UI) # start the Argo Server TASKS := controller ifeq ($(API),true) TASKS := controller server endif +ifeq ($(UI_SECURE),true) +TASKS := controller server ui +endif ifeq ($(UI),true) TASKS := controller server ui endif @@ -561,7 +565,7 @@ endif grep '127.0.0.1.*postgres' /etc/hosts grep '127.0.0.1.*mysql' /etc/hosts ifeq ($(RUN_MODE),local) - env DEFAULT_REQUEUE_TIME=$(DEFAULT_REQUEUE_TIME) ARGO_SECURE=$(SECURE) ALWAYS_OFFLOAD_NODE_STATUS=$(ALWAYS_OFFLOAD_NODE_STATUS) ARGO_LOGLEVEL=$(LOG_LEVEL) UPPERIO_DB_DEBUG=$(UPPERIO_DB_DEBUG) ARGO_AUTH_MODE=$(AUTH_MODE) ARGO_NAMESPACED=$(NAMESPACED) ARGO_NAMESPACE=$(KUBE_NAMESPACE) ARGO_MANAGED_NAMESPACE=$(MANAGED_NAMESPACE) ARGO_EXECUTOR_PLUGINS=$(PLUGINS) ARGO_POD_STATUS_CAPTURE_FINALIZER=$(POD_STATUS_CAPTURE_FINALIZER) PROFILE=$(PROFILE) kit $(TASKS) + env DEFAULT_REQUEUE_TIME=$(DEFAULT_REQUEUE_TIME) ARGO_SECURE=$(SECURE) ALWAYS_OFFLOAD_NODE_STATUS=$(ALWAYS_OFFLOAD_NODE_STATUS) ARGO_LOGLEVEL=$(LOG_LEVEL) UPPERIO_DB_DEBUG=$(UPPERIO_DB_DEBUG) ARGO_AUTH_MODE=$(AUTH_MODE) ARGO_NAMESPACED=$(NAMESPACED) ARGO_NAMESPACE=$(KUBE_NAMESPACE) ARGO_MANAGED_NAMESPACE=$(MANAGED_NAMESPACE) ARGO_EXECUTOR_PLUGINS=$(PLUGINS) ARGO_POD_STATUS_CAPTURE_FINALIZER=$(POD_STATUS_CAPTURE_FINALIZER) ARGO_UI_SECURE=$(UI_SECURE) PROFILE=$(PROFILE) kit $(TASKS) endif .PHONY: wait diff --git a/dev/nix/conf.nix b/dev/nix/conf.nix index 68ca78dff0aa3..1850eb2d0f229 100644 --- a/dev/nix/conf.nix +++ b/dev/nix/conf.nix @@ -24,6 +24,7 @@ rec { LOGS = "true"; # same as CTRL - not acted upon UI = "true"; # same as CTRL API = "true"; # same as CTRL + UI_SECURE = "false"; PLUGINS = "false"; }; controller = { @@ -50,7 +51,10 @@ rec { args = "--loglevel ${env.LOG_LEVEL} server --namespaced=${env.NAMESPACED} --auth-mode ${env.AUTH_MODE} --secure=${env.SECURE} --x-frame-options=SAMEORIGIN"; }; ui = { - env = { }; + env = { + ARGO_UI_SECURE = "${env.UI_SECURE}"; + ARGO_SECURE = "${env.SECURE}"; + }; args = "--cwd ui start"; }; } diff --git a/docs/running-locally.md b/docs/running-locally.md index 8e5c53ced90d6..e3aa2b08cf1cd 100644 --- a/docs/running-locally.md +++ b/docs/running-locally.md @@ -154,6 +154,20 @@ To test SSO integration, use `PROFILE=sso`: make start UI=true PROFILE=sso ``` +## TLS + +By default, `make start` will start Argo in [plain text mode](./tls.md#plain-text). To simulate a TLS proxy in front of Argo, use `UI_SECURE=true` (which implies `UI=true`): + +```bash +make start UI_SECURE=true +``` + +To start Argo in [encrypted mode](./tls.md#encrypted), use `SECURE=true`, which can be combined with `UI_SECURE=true`: + +```bash +make start SECURE=true UI_SECURE=true +``` + ### Running E2E tests locally Start up Argo Workflows using the following: @@ -206,6 +220,27 @@ Tests often fail: that's good. To diagnose failure: If tests run slowly or time out, factory reset your Kubernetes cluster. +### Debugging using Visual Studio Code + +When using the Dev Container with VSCode, add the following launch configuration to `.vscode/launch.json`: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Attach to argo server", + "type": "go", + "request": "attach", + "mode": "local", + "processId": "argo" + } + ] +} +``` + +This will allow you to attach to the `argo` process and start a debug session, which you can use to inspect variables and set breakpoints. + ## Committing Before you commit code and raise a PR, always run: diff --git a/manifests/quick-start/sso/dex/dex-cm.yaml b/manifests/quick-start/sso/dex/dex-cm.yaml index a99d186a28c28..689db0affb909 100644 --- a/manifests/quick-start/sso/dex/dex-cm.yaml +++ b/manifests/quick-start/sso/dex/dex-cm.yaml @@ -20,6 +20,7 @@ data: redirectURIs: - http://localhost:2746/oauth2/callback - http://localhost:8080/oauth2/callback + - https://localhost:8080/oauth2/callback name: Argo Server secret: ZXhhbXBsZS1hcHAtc2VjcmV0 connectors: diff --git a/tasks.yaml b/tasks.yaml index 246f1993ebe5e..462e67436a77c 100644 --- a/tasks.yaml +++ b/tasks.yaml @@ -81,6 +81,9 @@ spec: command: yarn start workingDir: ui dependencies: ui-deps + env: + - ARGO_UI_SECURE=false + - ARGO_SECURE=false ports: "8080" - name: executor command: make argoexec-image diff --git a/ui/src/app/webpack.config.js b/ui/src/app/webpack.config.js index b2bb70d6973ce..08f893bce8935 100644 --- a/ui/src/app/webpack.config.js +++ b/ui/src/app/webpack.config.js @@ -7,10 +7,11 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); const isProd = process.env.NODE_ENV === 'production'; -const proxyConf = { - target: isProd ? '' : 'http://localhost:2746', - secure: false -}; +let proxyTarget = ''; +if (!isProd) { + const isSecure = process.env.ARGO_SECURE === 'true'; + proxyTarget = `${isSecure ? 'https' : 'http'}://localhost:2746`; +} console.log(`Bundling for ${isProd ? 'production' : 'development'}...`); @@ -99,6 +100,7 @@ const config = { ], devServer: { + server: process.env.ARGO_UI_SECURE === 'true' ? 'https' : 'http', // this needs to be disabled to allow EventSource to work compress: false, historyApiFallback: { @@ -107,15 +109,14 @@ const config = { headers: { 'X-Frame-Options': 'SAMEORIGIN' }, - proxy: { - '/api/v1': proxyConf, - '/artifact-files': proxyConf, - '/artifacts': proxyConf, - '/input-artifacts': proxyConf, - '/artifacts-by-uid': proxyConf, - '/input-artifacts-by-uid': proxyConf, - '/oauth2': proxyConf - } + proxy: [ + { + context: ['/api', '/artifact-files', '/artifacts', '/input-artifacts', '/artifacts-by-uid', '/input-artifacts-by-uid', '/oauth2'], + target: proxyTarget, + secure: false, + xfwd: true // add the x-forwarded-* headers + } + ] } };