From 8c7928b75af8991bd4a5b42cd995aedd612bec4f Mon Sep 17 00:00:00 2001 From: Tarun Pothulapati Date: Tue, 8 Nov 2022 11:21:10 +0000 Subject: [PATCH] [werft] Update previews to use analytics token from secret Fixes https://github.com/gitpod-io/gitpod/issues/14509 Currently, Analytics in preview environments are broken through werft as we need to pass the write key through attributes which means we would leak it. This PR fixes that by instead updating weft to read them from a Kubernetes secret (This is already added into the cluster. See https://github.com/gitpod-io/ops/pull/6614). This means users now enable analytics by using setting `analytics: segment` and we read `segment-staging-write-key` to make it work. This secret is set to the staging segment source right now. Signed-off-by: Tarun Pothulapati --- .../build/deploy-to-preview-environment.ts | 12 ++---------- .werft/jobs/build/installer/installer.ts | 8 ++------ .werft/jobs/build/job-config.ts | 18 ++++++++++++++++-- dev/preview/workflow/preview/deploy-gitpod.sh | 12 ++++++++++-- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/.werft/jobs/build/deploy-to-preview-environment.ts b/.werft/jobs/build/deploy-to-preview-environment.ts index 5e257112b443ef..82ca3cbc690422 100644 --- a/.werft/jobs/build/deploy-to-preview-environment.ts +++ b/.werft/jobs/build/deploy-to-preview-environment.ts @@ -36,10 +36,10 @@ interface DeploymentConfig { domain: string; monitoringDomain: string; url: string; - analytics?: Analytics; cleanSlateDeployment: boolean; installEELicense: boolean; withObservability: boolean; + analytics: Analytics; } export async function deployToPreviewEnvironment(werft: Werft, jobConfig: JobConfig) { @@ -51,14 +51,6 @@ export async function deployToPreviewEnvironment(werft: Werft, jobConfig: JobCon const monitoringDomain = `${destname}.preview.gitpod-dev.com`; const url = `https://${domain}`; - let analytics: Analytics | null; - if ((jobConfig.analytics || "").startsWith("segment|")) { - analytics = { - type: "segment", - token: jobConfig.analytics!.substring("segment|".length), - }; - } - const deploymentConfig: DeploymentConfig = { version, destname, @@ -66,10 +58,10 @@ export async function deployToPreviewEnvironment(werft: Werft, jobConfig: JobCon domain, monitoringDomain, url, - analytics, cleanSlateDeployment, installEELicense, withObservability, + analytics: jobConfig.analytics, }; // We set all attributes to false as default and only set it to true once the each process is complete. diff --git a/.werft/jobs/build/installer/installer.ts b/.werft/jobs/build/installer/installer.ts index 11aa9a07125ecc..f8381e6c8cdecc 100644 --- a/.werft/jobs/build/installer/installer.ts +++ b/.werft/jobs/build/installer/installer.ts @@ -1,12 +1,8 @@ import { execStream } from "../../../util/shell"; import { Werft } from "../../../util/werft"; +import { Analytics } from "../job-config"; import { CORE_DEV_KUBECONFIG_PATH, PREVIEW_K3S_KUBECONFIG_PATH } from "../const"; -export type Analytics = { - type: string; - token: string; -}; - export type InstallerOptions = { werft: Werft; previewName: string; @@ -31,7 +27,7 @@ export class Installer { DEV_KUBE_CONTEXT: "gke_gitpod-core-dev_europe-west1-b_core-dev", PREVIEW_K3S_KUBE_PATH: PREVIEW_K3S_KUBECONFIG_PATH, PREVIEW_NAME: this.options.previewName, - GITPOD_ANALYTICS_SEGMENT_TOKEN: this.options.analytics?.token || "", + GITPOD_ANALYTICS: this.options.analytics, GITPOD_WORKSPACE_FEATURE_FLAGS: this.options.workspaceFeatureFlags.join(" "), GITPOD_WITH_SLOW_DATABASE: this.options.withSlowDatabase, GITPOD_WITH_EE_LICENSE: this.options.withEELicense, diff --git a/.werft/jobs/build/job-config.ts b/.werft/jobs/build/job-config.ts index 0df3e3639bf36b..3f22112939b738 100644 --- a/.werft/jobs/build/job-config.ts +++ b/.werft/jobs/build/job-config.ts @@ -4,8 +4,10 @@ import {previewNameFromBranchName} from "../../util/preview"; type WithIntegrationTests = "skip" | "all" | "workspace" | "ide" | "webapp"; +export type Analytics = "skip" | "segment"; + export interface JobConfig { - analytics: string; + analytics: Analytics; buildConfig: any; cleanSlateDeployment: boolean; cluster: string; @@ -93,7 +95,7 @@ export function jobConfig(werft: Werft, context: any): JobConfig { const publishToNpm = "publish-to-npm" in buildConfig || mainBuild; const publishToJBMarketplace = "publish-to-jb-marketplace" in buildConfig || mainBuild; const publishToKots = "publish-to-kots" in buildConfig || withSelfHostedPreview || mainBuild; - const analytics = buildConfig["analytics"]; + const localAppVersion = mainBuild || "with-localapp-version" in buildConfig ? version : "unknown"; const retag = "with-retag" in buildConfig ? "" : "--dont-retag"; const cleanSlateDeployment = mainBuild || "with-clean-slate-deployment" in buildConfig; @@ -105,6 +107,7 @@ export function jobConfig(werft: Werft, context: any): JobConfig { const recreateVm = mainBuild || "recreate-vm" in buildConfig; const withSlowDatabase = "with-slow-database" in buildConfig && !mainBuild; + const analytics = parseAnalytics(werft, sliceId, buildConfig["analytics"]) const withIntegrationTests = parseWithIntegrationTests(werft, sliceId, buildConfig["with-integration-tests"]); const withPreview = decideWithPreview({werft, sliceID: sliceId, buildConfig, mainBuild, withIntegrationTests}) @@ -225,6 +228,17 @@ function decideWithPreview(options: { werft: Werft, sliceID: string, buildConfig return false } +export function parseAnalytics(werft: Werft, sliceId: string, value: string): Analytics { + switch (value) { + case "segment": + return "segment" + } + + werft.log(sliceId, "Analytics is not enabled") + return "skip"; +} + + export function parseWithIntegrationTests(werft: Werft, sliceID: string, value?: string): WithIntegrationTests { switch (value) { case null: diff --git a/dev/preview/workflow/preview/deploy-gitpod.sh b/dev/preview/workflow/preview/deploy-gitpod.sh index 847c785c7badd9..d47d3416715c69 100755 --- a/dev/preview/workflow/preview/deploy-gitpod.sh +++ b/dev/preview/workflow/preview/deploy-gitpod.sh @@ -23,7 +23,7 @@ GITPOD_AGENT_SMITH_TOKEN_HASH="$(echo -n "$GITPOD_AGENT_SMITH_TOKEN" | sha256sum GITPOD_CONTAINER_REGISTRY_URL="eu.gcr.io/gitpod-core-dev/build/"; GITPOD_IMAGE_PULL_SECRET_NAME="gcp-sa-registry-auth"; GITPOD_PROXY_SECRET_NAME="proxy-config-certificates"; -GITPOD_ANALYTICS_SEGMENT_TOKEN="${GITPOD_ANALYTICS_SEGMENT_TOKEN:-}" +GITPOD_ANALYTICS="${GITPOD_ANALYTICS:-}" GITPOD_WITH_EE_LICENSE="${GITPOD_WITH_EE_LICENSE:-true}" GITPOD_WORKSPACE_FEATURE_FLAGS="${GITPOD_WORKSPACE_FEATURE_FLAGS:-}" GITPOD_WITH_SLOW_DATABASE="${GITPOD_WITH_SLOW_DATABASE:-false}" @@ -456,7 +456,15 @@ fi # # includeAnalytics # -if [[ -n "${GITPOD_ANALYTICS_SEGMENT_TOKEN}" ]]; then +if [[ "${GITPOD_ANALYTICS}" == "segment" ]]; then + + GITPOD_ANALYTICS_SEGMENT_TOKEN=$(kubectl \ + --kubeconfig "${DEV_KUBE_PATH}" \ + --context "${DEV_KUBE_CONTEXT}" \ + --namespace werft \ + get secret "segment-staging-write-key" -o jsonpath='{.data.token}' \ + | base64 -d) + yq w -i "${INSTALLER_CONFIG_PATH}" analytics.writer segment yq w -i "${INSTALLER_CONFIG_PATH}" analytics.segmentKey "${GITPOD_ANALYTICS_SEGMENT_TOKEN}" yq w -i "${INSTALLER_CONFIG_PATH}" 'workspace.templates.default.spec.containers.(name==workspace).env[+].name' "GITPOD_ANALYTICS_WRITER"