From 251539d40e89b3bc91dea14ed6afb311788962df Mon Sep 17 00:00:00 2001 From: mo khan Date: Mon, 12 May 2025 13:24:37 -0600 Subject: refactor: mimic target deployment filesystem --- .gitignore | 2 +- Dockerfile | 10 +-- Makefile | 10 +-- bin/envoy.sh | 33 ++++++++++ bin/init.sh | 8 +++ envoy.yml | 174 ---------------------------------------------------- etc/envoy/envoy.yml | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++ share/man/.keep | 0 start.sh | 31 ---------- 9 files changed, 227 insertions(+), 215 deletions(-) create mode 100755 bin/envoy.sh create mode 100755 bin/init.sh delete mode 100644 envoy.yml create mode 100644 etc/envoy/envoy.yml create mode 100644 share/man/.keep delete mode 100644 start.sh diff --git a/.gitignore b/.gitignore index 6df0c24..a61311f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/sparkled +/bin/sparkled .env.* /tmp /log diff --git a/Dockerfile b/Dockerfile index 8764125..a67eedf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,9 @@ EXPOSE 8080 9901 10000 WORKDIR /var/www/ COPY --from=build /bin/sparkled /usr/local/bin/sparkled COPY --from=build /app/public /var/www/public -COPY envoy.yml /etc/envoy/envoy.yaml -COPY start.sh /start.sh -RUN chmod +x /start.sh -CMD ["/start.sh"] +COPY etc/envoy/envoy.yml /etc/envoy/envoy.yaml +COPY bin/envoy.sh /usr/local/bin/envoy.sh +COPY bin/init.sh /usr/local/bin/init.sh +RUN chmod +x /usr/local/bin/envoy.sh +RUN chmod +x /usr/local/bin/init.sh +CMD ["/usr/local/bin/init.sh"] diff --git a/Makefile b/Makefile index c3b2307..6f6b9c4 100644 --- a/Makefile +++ b/Makefile @@ -4,11 +4,11 @@ IMAGE_TAG := $(PROJECT_NAME):$(GIT_BRANCH) .PHONY: clean setup build test run -sparkled: - @go build -o sparkled ./cmd/sparkled/main.go +bin/sparkled: + @go build -o ./bin/sparkled ./cmd/sparkled/main.go clean: - @rm -f sparkled + @rm -f ./bin/sparkled @go clean -testcache @docker image rm -f $(IMAGE_TAG) @@ -18,7 +18,7 @@ setup: @command -v godotenv @command -v yamlfmt -build: sparkled +build: bin/sparkled test-unit: @go test -shuffle=on ./... @@ -35,7 +35,7 @@ build-builder-image: @docker build --target build --tag $(IMAGE_TAG) . run: clean build - @godotenv -f .env.local,.env ./sparkled + @godotenv -f .env.local,.env ./bin/sparkled run-image: clean build-image @docker run --rm --network host --env-file .env.local -p 10000:10000 -p 9901:9901 -p 8080:8080 -it $(IMAGE_TAG) diff --git a/bin/envoy.sh b/bin/envoy.sh new file mode 100755 index 0000000..a123c62 --- /dev/null +++ b/bin/envoy.sh @@ -0,0 +1,33 @@ +#!/bin/sh +set -e + +[ -n "$DEBUG" ] && set -x + +oidc_scheme=$(echo "$OIDC_ISSUER" | awk -F[/:] '{print $1}') +oidc_host=$(echo "$OIDC_ISSUER" | awk -F[/:] '{print $4}') +yaml=$(sed -e "s/OAUTH_CLIENT_ID/$OAUTH_CLIENT_ID/" /etc/envoy/envoy.yaml) +yaml=$(echo "$yaml" | sed -e "s,https://example.com,$OIDC_ISSUER,") +yaml=$(echo "$yaml" | sed -e "s/example.com/$oidc_host/") + +# For http://gdk.test:3000 +if [ "$oidc_scheme" = "http" ]; then + yaml=$(echo "$yaml" | sed -e '/transport_socket:/,+4d') + oidc_port=$(echo "$OIDC_ISSUER" | awk -F[/:] '{print $5}') + yaml=$(echo "$yaml" | sed -e "s/port_value: 443/port_value: $oidc_port/") +fi + +# I need an adult with access to vault to set this +if [ -z "$OAUTH_CLIENT_SECRET" ]; then + export OAUTH_CLIENT_SECRET="secret" +fi + +# and this. +if [ -z "$HMAC_SESSION_SECRET" ]; then + export HMAC_SESSION_SECRET="$OAUTH_CLIENT_SECRET" +fi + +echo "[$(date "+%H:%M:%S")] ==> Starting…" +envoy \ + --config-yaml "$yaml" \ + --log-level warn \ + --component-log-level oauth2:trace diff --git a/bin/init.sh b/bin/init.sh new file mode 100755 index 0000000..105c85a --- /dev/null +++ b/bin/init.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -e + +[ -n "$DEBUG" ] && set -x + +echo "[$(date "+%H:%M:%S")] ==> Starting…" +/usr/local/bin/sparkled & /usr/local/bin/envoy.sh diff --git a/envoy.yml b/envoy.yml deleted file mode 100644 index 3c8df3a..0000000 --- a/envoy.yml +++ /dev/null @@ -1,174 +0,0 @@ -admin: - address: - socket_address: - address: 0.0.0.0 - port_value: 9901 -static_resources: - clusters: - - name: sparkle - connect_timeout: 0.25s - type: STRICT_DNS - lb_policy: ROUND_ROBIN - load_assignment: - cluster_name: sparkle - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: localhost - port_value: 8080 - - name: oidc - connect_timeout: 5s - type: LOGICAL_DNS - lb_policy: ROUND_ROBIN - load_assignment: - cluster_name: oidc - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: example.com - port_value: 443 - hostname: example.com - transport_socket: - name: envoy.transport_sockets.tls - typed_config: - "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext - sni: example.com - listeners: - - name: listener_0 - address: - socket_address: - protocol: TCP - address: 0.0.0.0 - port_value: 10000 - filter_chains: - - filters: - - name: envoy.filters.network.http_connection_manager - typed_config: - "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager - access_log: - - name: envoy.access_loggers.stdout - typed_config: - "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog - log_format: - json_format: - timestamp: "%START_TIME%" - client_ip: "%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%" - authority: "%REQ(:AUTHORITY)%" - protocol: "%PROTOCOL%" - method: "%REQ(:METHOD)%" - path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%" - request_id: "%REQ(X-REQUEST-ID)%" - response_code: "%RESPONSE_CODE%" - bytes_received: "%BYTES_RECEIVED%" - bytes_sent: "%BYTES_SENT%" - duration: "%DURATION%" - forwarded_for: "%REQ(X-FORWARDED-FOR)%" - user_agent: "%REQ(USER-AGENT)%" - codec_type: AUTO - http_filters: - - name: envoy.filters.http.oauth2 - typed_config: - "@type": type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2 - config: - auth_scopes: - - email - - openid - - profile - auth_type: BASIC_AUTH - authorization_endpoint: "https://example.com/oauth/authorize" - credentials: - client_id: "OAUTH_CLIENT_ID" - cookie_names: - bearer_token: bearer_token - oauth_hmac: oauth_hmac - oauth_expires: oauth_expires - id_token: id_token - refresh_token: refresh_token - oauth_nonce: oauth_nonce - # code_verifier: code_verifier - token_secret: - name: client_secret - hmac_secret: - name: hmac_secret - forward_bearer_token: true - pass_through_matcher: - - name: ":path" - safe_regex_match: - regex: .*\\.(css|js|png|html|ico)$ - - name: ":path" - string_match: - exact: "/health" - - name: ":path" - string_match: - exact: "/" - - name: ":path" - string_match: - exact: "/sparkles" - - name: ":path" - string_match: - exact: "/sparkles/restore" - - name: ":path" - string_match: - exact: "/dashboard/nav" - redirect_path_matcher: - path: - exact: /callback - redirect_uri: "%REQ(x-forwarded-proto)%://%REQ(:authority)%/callback" - signout_path: - path: - exact: /signout - token_endpoint: - cluster: oidc - uri: "https://example.com/oauth/token" - timeout: 5s - use_refresh_token: true - - name: envoy.filters.http.router - typed_config: - "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router - upstream_log: - - name: envoy.access_loggers.stdout - typed_config: - "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog - log_format: - json_format: - timestamp: "%START_TIME%" - client_ip: "%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%" - authority: "%REQ(:AUTHORITY)%" - protocol: "%PROTOCOL%" - method: "%REQ(:METHOD)%" - path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%" - request_id: "%REQ(X-REQUEST-ID)%" - response_code: "%RESPONSE_CODE%" - bytes_received: "%BYTES_RECEIVED%" - bytes_sent: "%BYTES_SENT%" - duration: "%DURATION%" - forwarded_for: "%REQ(X-FORWARDED-FOR)%" - user_agent: "%REQ(USER-AGENT)%" - suppress_envoy_headers: true - route_config: - virtual_hosts: - - name: local - domains: ["*"] - routes: - - match: - prefix: "/" - route: - cluster: sparkle - timeout: 5s - retry_policy: - retry_on: "5xx" - num_retries: 3 - stat_prefix: ingress_http - secrets: - - name: client_secret - generic_secret: - secret: - environment_variable: OAUTH_CLIENT_SECRET - - name: hmac_secret - generic_secret: - secret: - environment_variable: HMAC_SESSION_SECRET diff --git a/etc/envoy/envoy.yml b/etc/envoy/envoy.yml new file mode 100644 index 0000000..3c8df3a --- /dev/null +++ b/etc/envoy/envoy.yml @@ -0,0 +1,174 @@ +admin: + address: + socket_address: + address: 0.0.0.0 + port_value: 9901 +static_resources: + clusters: + - name: sparkle + connect_timeout: 0.25s + type: STRICT_DNS + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: sparkle + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: localhost + port_value: 8080 + - name: oidc + connect_timeout: 5s + type: LOGICAL_DNS + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: oidc + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: example.com + port_value: 443 + hostname: example.com + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + sni: example.com + listeners: + - name: listener_0 + address: + socket_address: + protocol: TCP + address: 0.0.0.0 + port_value: 10000 + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + access_log: + - name: envoy.access_loggers.stdout + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog + log_format: + json_format: + timestamp: "%START_TIME%" + client_ip: "%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%" + authority: "%REQ(:AUTHORITY)%" + protocol: "%PROTOCOL%" + method: "%REQ(:METHOD)%" + path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%" + request_id: "%REQ(X-REQUEST-ID)%" + response_code: "%RESPONSE_CODE%" + bytes_received: "%BYTES_RECEIVED%" + bytes_sent: "%BYTES_SENT%" + duration: "%DURATION%" + forwarded_for: "%REQ(X-FORWARDED-FOR)%" + user_agent: "%REQ(USER-AGENT)%" + codec_type: AUTO + http_filters: + - name: envoy.filters.http.oauth2 + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2 + config: + auth_scopes: + - email + - openid + - profile + auth_type: BASIC_AUTH + authorization_endpoint: "https://example.com/oauth/authorize" + credentials: + client_id: "OAUTH_CLIENT_ID" + cookie_names: + bearer_token: bearer_token + oauth_hmac: oauth_hmac + oauth_expires: oauth_expires + id_token: id_token + refresh_token: refresh_token + oauth_nonce: oauth_nonce + # code_verifier: code_verifier + token_secret: + name: client_secret + hmac_secret: + name: hmac_secret + forward_bearer_token: true + pass_through_matcher: + - name: ":path" + safe_regex_match: + regex: .*\\.(css|js|png|html|ico)$ + - name: ":path" + string_match: + exact: "/health" + - name: ":path" + string_match: + exact: "/" + - name: ":path" + string_match: + exact: "/sparkles" + - name: ":path" + string_match: + exact: "/sparkles/restore" + - name: ":path" + string_match: + exact: "/dashboard/nav" + redirect_path_matcher: + path: + exact: /callback + redirect_uri: "%REQ(x-forwarded-proto)%://%REQ(:authority)%/callback" + signout_path: + path: + exact: /signout + token_endpoint: + cluster: oidc + uri: "https://example.com/oauth/token" + timeout: 5s + use_refresh_token: true + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + upstream_log: + - name: envoy.access_loggers.stdout + typed_config: + "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog + log_format: + json_format: + timestamp: "%START_TIME%" + client_ip: "%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%" + authority: "%REQ(:AUTHORITY)%" + protocol: "%PROTOCOL%" + method: "%REQ(:METHOD)%" + path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%" + request_id: "%REQ(X-REQUEST-ID)%" + response_code: "%RESPONSE_CODE%" + bytes_received: "%BYTES_RECEIVED%" + bytes_sent: "%BYTES_SENT%" + duration: "%DURATION%" + forwarded_for: "%REQ(X-FORWARDED-FOR)%" + user_agent: "%REQ(USER-AGENT)%" + suppress_envoy_headers: true + route_config: + virtual_hosts: + - name: local + domains: ["*"] + routes: + - match: + prefix: "/" + route: + cluster: sparkle + timeout: 5s + retry_policy: + retry_on: "5xx" + num_retries: 3 + stat_prefix: ingress_http + secrets: + - name: client_secret + generic_secret: + secret: + environment_variable: OAUTH_CLIENT_SECRET + - name: hmac_secret + generic_secret: + secret: + environment_variable: HMAC_SESSION_SECRET diff --git a/share/man/.keep b/share/man/.keep new file mode 100644 index 0000000..e69de29 diff --git a/start.sh b/start.sh deleted file mode 100644 index f4d8b9a..0000000 --- a/start.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -set -e - -[ -n "$DEBUG" ] && set -x - -oidc_scheme=$(echo "$OIDC_ISSUER" | awk -F[/:] '{print $1}') -oidc_host=$(echo "$OIDC_ISSUER" | awk -F[/:] '{print $4}') -yaml=$(sed -e "s/OAUTH_CLIENT_ID/$OAUTH_CLIENT_ID/" /etc/envoy/envoy.yaml) -yaml=$(echo "$yaml" | sed -e "s,https://example.com,$OIDC_ISSUER,") -yaml=$(echo "$yaml" | sed -e "s/example.com/$oidc_host/") - -# For http://gdk.test:3000 -if [ "$oidc_scheme" = "http" ]; then - yaml=$(echo "$yaml" | sed -e '/transport_socket:/,+4d') - oidc_port=$(echo "$OIDC_ISSUER" | awk -F[/:] '{print $5}') - yaml=$(echo "$yaml" | sed -e "s/port_value: 443/port_value: $oidc_port/") -fi - -# I need an adult with access to vault to set this -if [ -z "$OAUTH_CLIENT_SECRET" ]; then - export OAUTH_CLIENT_SECRET="secret" -fi - -# and this. -if [ -z "$HMAC_SESSION_SECRET" ]; then - export HMAC_SESSION_SECRET="$OAUTH_CLIENT_SECRET" -fi - -echo "[$(date "+%H:%M:%S")] ==> Starting…" -/usr/local/bin/sparkled & /usr/local/bin/envoy --config-yaml "$yaml" --log-level warn --component-log-level oauth2:trace -- cgit v1.2.3