diff --git a/local/start-component.sh b/local/start-component.sh index 540224f518..d70e352678 100755 --- a/local/start-component.sh +++ b/local/start-component.sh @@ -65,6 +65,14 @@ function project_dir() { function start_config_encryption() { cd "$(project_dir 'config-encryption')" + + # This is part of a hack to allow the oauth edge function to call the config-encryption service locally. + # The _other_ part of the hack is down in `start_oauth_edge`. + # This container exists to do nothing other than to attach to the supabase docker network and expose port 8765, which + # is what config-encryption listens on. The pause container exists for just these kinds of shennanigans. + # Per: https://stackoverflow.com/a/44739847 the `docker start` will return 0 if the container is already running + docker start config_encryption_hack_proxy || \ + must_run docker run --rm --name config_encryption_hack_proxy -p 8765 --network supabase_network_flow --detach google/pause:latest must_run cargo run -- --gcp-kms "$TEST_KMS_KEY" } @@ -132,7 +140,22 @@ function start_control_plane_agent() { function start_oauth_edge() { cd "$(project_dir 'flow')" - must_run supabase functions serve oauth + # We need to do some weird crap to allow the oauth edge function to connect to the config-encryption + # service running on localhost (outside of docker). The hostname that's used for config-encyrption + # will be set to the gateway IP of the docker network. A dummy container, which is attached to that network + # and listening on port 8765, ensures that port 8765 will be exposed on the host at that address. + # Determine the gateway IP of the supabase docker network: + local gateway_ip="$(docker network inspect supabase_network_flow -f '{{ (index .IPAM.Config 0).Gateway }}' )" + # lol I guess this is a way to trim whitespace from a bash variable: https://stackoverflow.com/a/12973694 + gateway_ip="$(echo "$gateway_ip" | xargs echo )" + if [[ -z "$gateway_ip" ]]; then + bail "unable to determine docker network gateway ip" + fi + # put this file in /var/tmp/ because macs have issues mounting other files into a docker container, which is + # what I _think_ supabase functions serve is doing? + echo "CONFIG_ENCRYPTION_URL=http://${gateway_ip}:8765/v1/encrypt-config" > /var/tmp/config-encryption-hack-proxy-addr + must_run supabase functions serve oauth --env-file /var/tmp/config-encryption-hack-proxy-addr + } function start_schema_inference() { diff --git a/supabase/functions/oauth/encrypt-config.ts b/supabase/functions/oauth/encrypt-config.ts index 715c6a1151..7d94e5bc2e 100644 --- a/supabase/functions/oauth/encrypt-config.ts +++ b/supabase/functions/oauth/encrypt-config.ts @@ -3,8 +3,17 @@ import { corsHeaders } from "../_shared/cors.ts"; import { returnPostgresError } from "../_shared/helpers.ts"; import { supabaseClient } from "../_shared/supabaseClient.ts"; -const ENCRYPTION_SERVICE = - "https://config-encryption.estuary.dev/v1/encrypt-config"; +const config_encryption_url = () => { + const env = Deno.env.get('CONFIG_ENCRYPTION_URL'); + // A more principled approach would be to require that this url is always provided by the + // env var. But that would require using a supabase secret to set the value in prod, + // and _that_ seemed like a whole ordeal that I don't have time for right now. + if (env) { + return env + } else { + return "https://config-encryption.estuary.dev/v1/encrypt-config" + } +} const CREDENTIALS_KEY = "credentials"; @@ -58,7 +67,7 @@ export async function encryptConfig(req: Record) { const { endpoint_spec_schema } = connectorTagData as ConnectorTagsResponse; - const response = await fetch(ENCRYPTION_SERVICE, { + const response = await fetch(config_encryption_url(), { method: "POST", body: JSON.stringify({ config,