From 36c5e49030573ee923c6dd5886bf9ad5701226a2 Mon Sep 17 00:00:00 2001 From: Wilson Rivera Date: Thu, 19 Mar 2026 13:11:45 -0400 Subject: [PATCH 1/3] feat: introduce proxy for webhook requests --- controlplane/package.json | 1 + .../bufservices/contract/updateContract.ts | 1 + .../feature-flag/createFeatureFlag.ts | 1 + .../feature-flag/deleteFeatureFlag.ts | 1 + .../feature-flag/enableFeatureFlag.ts | 1 + .../feature-flag/updateFeatureFlag.ts | 1 + .../federated-graph/createFederatedGraph.ts | 1 + .../federated-graph/migrateFromApollo.ts | 1 + .../federated-graph/moveFederatedGraph.ts | 1 + .../federated-graph/updateFederatedGraph.ts | 1 + .../core/bufservices/graph/recomposeGraph.ts | 1 + .../bufservices/monograph/publishMonograph.ts | 1 + .../bufservices/monograph/updateMonograph.ts | 1 + .../bufservices/proposal/createProposal.ts | 1 + .../bufservices/proposal/updateProposal.ts | 2 + .../subgraph/checkSubgraphSchema.ts | 1 + .../subgraph/deleteFederatedSubgraph.ts | 1 + .../core/bufservices/subgraph/moveSubgraph.ts | 1 + .../subgraph/publishFederatedSubgraph.ts | 1 + .../bufservices/subgraph/updateSubgraph.ts | 1 + controlplane/src/core/build-server.ts | 9 +++- controlplane/src/core/env.schema.ts | 1 + controlplane/src/core/routes.ts | 1 + .../webhooks/OrganizationWebhookService.ts | 13 +++++ .../core/webhooks/PlatformWebhookService.ts | 14 ++++- controlplane/src/core/webhooks/utils.ts | 3 +- controlplane/src/index.ts | 2 + .../controlplane/templates/deployment.yaml | 5 ++ .../charts/controlplane/templates/secret.yaml | 1 + helm/cosmo/charts/controlplane/values.yaml | 1 + pnpm-lock.yaml | 54 +++++++++++++------ 31 files changed, 104 insertions(+), 21 deletions(-) diff --git a/controlplane/package.json b/controlplane/package.json index 56855a7d2e..692b190965 100644 --- a/controlplane/package.json +++ b/controlplane/package.json @@ -77,6 +77,7 @@ "fastify-plugin": "^4.5.1", "fastify-raw-body": "^4.3.0", "graphql": "^16.9.0", + "https-proxy-agent": "8.0.0", "ioredis": "^5.4.1", "isomorphic-dompurify": "^2.33.0", "jose": "^5.2.4", diff --git a/controlplane/src/core/bufservices/contract/updateContract.ts b/controlplane/src/core/bufservices/contract/updateContract.ts index 912035b4c4..ca99337b4f 100644 --- a/controlplane/src/core/bufservices/contract/updateContract.ts +++ b/controlplane/src/core/bufservices/contract/updateContract.ts @@ -42,6 +42,7 @@ export function updateContract( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); req.excludeTags = [...new Set(req.excludeTags)]; diff --git a/controlplane/src/core/bufservices/feature-flag/createFeatureFlag.ts b/controlplane/src/core/bufservices/feature-flag/createFeatureFlag.ts index 0ac581eb53..1a14b6f194 100644 --- a/controlplane/src/core/bufservices/feature-flag/createFeatureFlag.ts +++ b/controlplane/src/core/bufservices/feature-flag/createFeatureFlag.ts @@ -39,6 +39,7 @@ export function createFeatureFlag( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); req.namespace = req.namespace || DefaultNamespace; diff --git a/controlplane/src/core/bufservices/feature-flag/deleteFeatureFlag.ts b/controlplane/src/core/bufservices/feature-flag/deleteFeatureFlag.ts index 2312a4313a..a761d55746 100644 --- a/controlplane/src/core/bufservices/feature-flag/deleteFeatureFlag.ts +++ b/controlplane/src/core/bufservices/feature-flag/deleteFeatureFlag.ts @@ -39,6 +39,7 @@ export function deleteFeatureFlag( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); req.namespace = req.namespace || DefaultNamespace; diff --git a/controlplane/src/core/bufservices/feature-flag/enableFeatureFlag.ts b/controlplane/src/core/bufservices/feature-flag/enableFeatureFlag.ts index fa543dc05d..af2083ba27 100644 --- a/controlplane/src/core/bufservices/feature-flag/enableFeatureFlag.ts +++ b/controlplane/src/core/bufservices/feature-flag/enableFeatureFlag.ts @@ -40,6 +40,7 @@ export function enableFeatureFlag( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); req.namespace = req.namespace || DefaultNamespace; diff --git a/controlplane/src/core/bufservices/feature-flag/updateFeatureFlag.ts b/controlplane/src/core/bufservices/feature-flag/updateFeatureFlag.ts index bb52d9b2b8..ddd962172f 100644 --- a/controlplane/src/core/bufservices/feature-flag/updateFeatureFlag.ts +++ b/controlplane/src/core/bufservices/feature-flag/updateFeatureFlag.ts @@ -39,6 +39,7 @@ export function updateFeatureFlag( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); req.namespace = req.namespace || DefaultNamespace; diff --git a/controlplane/src/core/bufservices/federated-graph/createFederatedGraph.ts b/controlplane/src/core/bufservices/federated-graph/createFederatedGraph.ts index afed804970..4b961ee53e 100644 --- a/controlplane/src/core/bufservices/federated-graph/createFederatedGraph.ts +++ b/controlplane/src/core/bufservices/federated-graph/createFederatedGraph.ts @@ -40,6 +40,7 @@ export function createFederatedGraph( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); const fedGraphRepo = new FederatedGraphRepository(logger, opts.db, authContext.organizationId); const subgraphRepo = new SubgraphRepository(logger, opts.db, authContext.organizationId); diff --git a/controlplane/src/core/bufservices/federated-graph/migrateFromApollo.ts b/controlplane/src/core/bufservices/federated-graph/migrateFromApollo.ts index c800acffea..7c9a9e27b1 100644 --- a/controlplane/src/core/bufservices/federated-graph/migrateFromApollo.ts +++ b/controlplane/src/core/bufservices/federated-graph/migrateFromApollo.ts @@ -40,6 +40,7 @@ export function migrateFromApollo( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); const auditLogRepo = new AuditLogRepository(opts.db); const namespaceRepo = new NamespaceRepository(opts.db, authContext.organizationId); diff --git a/controlplane/src/core/bufservices/federated-graph/moveFederatedGraph.ts b/controlplane/src/core/bufservices/federated-graph/moveFederatedGraph.ts index 7889ef6ddb..de22aa0c41 100644 --- a/controlplane/src/core/bufservices/federated-graph/moveFederatedGraph.ts +++ b/controlplane/src/core/bufservices/federated-graph/moveFederatedGraph.ts @@ -41,6 +41,7 @@ export function moveFederatedGraph( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); const auditLogRepo = new AuditLogRepository(tx); const namespaceRepo = new NamespaceRepository(tx, authContext.organizationId); diff --git a/controlplane/src/core/bufservices/federated-graph/updateFederatedGraph.ts b/controlplane/src/core/bufservices/federated-graph/updateFederatedGraph.ts index baa1c5cf4e..73c03850eb 100644 --- a/controlplane/src/core/bufservices/federated-graph/updateFederatedGraph.ts +++ b/controlplane/src/core/bufservices/federated-graph/updateFederatedGraph.ts @@ -39,6 +39,7 @@ export function updateFederatedGraph( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); req.namespace = req.namespace || DefaultNamespace; diff --git a/controlplane/src/core/bufservices/graph/recomposeGraph.ts b/controlplane/src/core/bufservices/graph/recomposeGraph.ts index 6a9cf6fc48..9935a65eeb 100644 --- a/controlplane/src/core/bufservices/graph/recomposeGraph.ts +++ b/controlplane/src/core/bufservices/graph/recomposeGraph.ts @@ -30,6 +30,7 @@ export function recomposeGraph( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); const federatedGraphRepo = new FederatedGraphRepository(logger, opts.db, authContext.organizationId); const orgRepo = new OrganizationRepository(logger, opts.db, opts.billingDefaultPlanId); diff --git a/controlplane/src/core/bufservices/monograph/publishMonograph.ts b/controlplane/src/core/bufservices/monograph/publishMonograph.ts index bb30418df7..482fca9eac 100644 --- a/controlplane/src/core/bufservices/monograph/publishMonograph.ts +++ b/controlplane/src/core/bufservices/monograph/publishMonograph.ts @@ -32,6 +32,7 @@ export function publishMonograph( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); const namespaceRepo = new NamespaceRepository(opts.db, authContext.organizationId); const subgraphRepo = new SubgraphRepository(logger, opts.db, authContext.organizationId); diff --git a/controlplane/src/core/bufservices/monograph/updateMonograph.ts b/controlplane/src/core/bufservices/monograph/updateMonograph.ts index 9443ede21c..9a04597272 100644 --- a/controlplane/src/core/bufservices/monograph/updateMonograph.ts +++ b/controlplane/src/core/bufservices/monograph/updateMonograph.ts @@ -47,6 +47,7 @@ export function updateMonograph( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); if (req.subscriptionUrl && !isValidUrl(req.subscriptionUrl)) { diff --git a/controlplane/src/core/bufservices/proposal/createProposal.ts b/controlplane/src/core/bufservices/proposal/createProposal.ts index 393261bf50..dbb81cab9c 100644 --- a/controlplane/src/core/bufservices/proposal/createProposal.ts +++ b/controlplane/src/core/bufservices/proposal/createProposal.ts @@ -444,6 +444,7 @@ export function createProposal( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ), }); diff --git a/controlplane/src/core/bufservices/proposal/updateProposal.ts b/controlplane/src/core/bufservices/proposal/updateProposal.ts index d67ff05250..8976654c33 100644 --- a/controlplane/src/core/bufservices/proposal/updateProposal.ts +++ b/controlplane/src/core/bufservices/proposal/updateProposal.ts @@ -48,6 +48,7 @@ export function updateProposal( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); const namespaceRepo = new NamespaceRepository(opts.db, authContext.organizationId); @@ -512,6 +513,7 @@ export function updateProposal( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ), }); diff --git a/controlplane/src/core/bufservices/subgraph/checkSubgraphSchema.ts b/controlplane/src/core/bufservices/subgraph/checkSubgraphSchema.ts index 7807f22263..459ae6ab02 100644 --- a/controlplane/src/core/bufservices/subgraph/checkSubgraphSchema.ts +++ b/controlplane/src/core/bufservices/subgraph/checkSubgraphSchema.ts @@ -123,6 +123,7 @@ export function checkSubgraphSchema( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); let linkedSubgraph: diff --git a/controlplane/src/core/bufservices/subgraph/deleteFederatedSubgraph.ts b/controlplane/src/core/bufservices/subgraph/deleteFederatedSubgraph.ts index bf115bc853..67f05e6cba 100644 --- a/controlplane/src/core/bufservices/subgraph/deleteFederatedSubgraph.ts +++ b/controlplane/src/core/bufservices/subgraph/deleteFederatedSubgraph.ts @@ -40,6 +40,7 @@ export function deleteFederatedSubgraph( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); req.namespace = req.namespace || DefaultNamespace; diff --git a/controlplane/src/core/bufservices/subgraph/moveSubgraph.ts b/controlplane/src/core/bufservices/subgraph/moveSubgraph.ts index 64d26723d7..e5cfb923cb 100644 --- a/controlplane/src/core/bufservices/subgraph/moveSubgraph.ts +++ b/controlplane/src/core/bufservices/subgraph/moveSubgraph.ts @@ -33,6 +33,7 @@ export function moveSubgraph( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); const subgraph = await subgraphRepo.byName(req.name, req.namespace); diff --git a/controlplane/src/core/bufservices/subgraph/publishFederatedSubgraph.ts b/controlplane/src/core/bufservices/subgraph/publishFederatedSubgraph.ts index 6eff21a250..fcdd7c676a 100644 --- a/controlplane/src/core/bufservices/subgraph/publishFederatedSubgraph.ts +++ b/controlplane/src/core/bufservices/subgraph/publishFederatedSubgraph.ts @@ -54,6 +54,7 @@ export function publishFederatedSubgraph( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); const auditLogRepo = new AuditLogRepository(opts.db); const fedGraphRepo = new FederatedGraphRepository(logger, opts.db, authContext.organizationId); diff --git a/controlplane/src/core/bufservices/subgraph/updateSubgraph.ts b/controlplane/src/core/bufservices/subgraph/updateSubgraph.ts index f27bf0366e..6ed7e2eb10 100644 --- a/controlplane/src/core/bufservices/subgraph/updateSubgraph.ts +++ b/controlplane/src/core/bufservices/subgraph/updateSubgraph.ts @@ -46,6 +46,7 @@ export function updateSubgraph( authContext.organizationId, opts.logger, opts.billingDefaultPlanId, + opts.webhookProxyUrl, ); req.namespace = req.namespace || DefaultNamespace; diff --git a/controlplane/src/core/build-server.ts b/controlplane/src/core/build-server.ts index 76da5e0a0b..18b90ea916 100644 --- a/controlplane/src/core/build-server.ts +++ b/controlplane/src/core/build-server.ts @@ -94,6 +94,7 @@ export interface BuildConfig { webhook?: { url?: string; key?: string; + proxyUrl?: string; }; githubApp?: { webhookSecret?: string; @@ -350,7 +351,12 @@ export default async function build(opts: BuildConfig) { : (opts.s3Storage.useIndividualDeletes ?? false), }); - const platformWebhooks = new PlatformWebhookService(opts.webhook?.url, opts.webhook?.key, logger); + const platformWebhooks = new PlatformWebhookService( + opts.webhook?.url, + opts.webhook?.key, + logger, + opts.webhook?.proxyUrl, + ); const readmeQueue = new AIGraphReadmeQueue(logger, fastify.redisForQueue); @@ -531,6 +537,7 @@ export default async function build(opts: BuildConfig) { }, stripeSecretKey: opts.stripe?.secret, admissionWebhookJWTSecret: opts.admissionWebhook.secret, + webhookProxyUrl: opts.webhook?.proxyUrl, cdnBaseUrl: opts.cdnBaseUrl, }), contextValues(req) { diff --git a/controlplane/src/core/env.schema.ts b/controlplane/src/core/env.schema.ts index d244e9f95f..f505323d3f 100644 --- a/controlplane/src/core/env.schema.ts +++ b/controlplane/src/core/env.schema.ts @@ -97,6 +97,7 @@ export const envVariables = z */ WEBHOOK_URL: z.string().optional(), WEBHOOK_SECRET: z.string().optional(), + WEBHOOK_PROXY_URL: z.string().url().optional(), /** * GitHub Integration */ diff --git a/controlplane/src/core/routes.ts b/controlplane/src/core/routes.ts index d08fe04f42..fdc8112a0c 100644 --- a/controlplane/src/core/routes.ts +++ b/controlplane/src/core/routes.ts @@ -34,6 +34,7 @@ export interface RouterOptions { logger: pino.Logger; keycloakClient: Keycloak; platformWebhooks: IPlatformWebhookService; + webhookProxyUrl?: string; webBaseUrl: string; githubApp?: App; slack: { clientID?: string; clientSecret?: string }; diff --git a/controlplane/src/core/webhooks/OrganizationWebhookService.ts b/controlplane/src/core/webhooks/OrganizationWebhookService.ts index 2ae1bd0143..6c596fb88b 100644 --- a/controlplane/src/core/webhooks/OrganizationWebhookService.ts +++ b/controlplane/src/core/webhooks/OrganizationWebhookService.ts @@ -8,6 +8,7 @@ import pino from 'pino'; import { v4 } from 'uuid'; import * as z from 'zod'; import { LintSeverity, VCSContext } from '@wundergraph/cosmo-connect/dist/platform/v1/platform_pb'; +import { HttpsProxyAgent } from 'https-proxy-agent'; import * as schema from '../../db/schema.js'; import { FederatedGraphRepository } from '../repositories/FederatedGraphRepository.js'; import { OrganizationRepository } from '../repositories/OrganizationRepository.js'; @@ -129,11 +130,23 @@ export class OrganizationWebhookService { private organizationId: string, logger: pino.Logger, defaultBillingPlanId?: string, + proxyUrl?: string, ) { this.logger = logger.child({ organizationId }); this.defaultBillingPlanId = defaultBillingPlanId; + let agent: HttpsProxyAgent | undefined; + if (proxyUrl) { + try { + agent = new HttpsProxyAgent(proxyUrl, {}); + } catch (e) { + logger.error(e, 'Failed to create proxy agent'); + } + } + this.httpClient = axios.create({ + httpsAgent: agent, + httpAgent: agent, timeout: 30_000, maxContentLength: 5 * 1024 * 1024, // ~5mb }); diff --git a/controlplane/src/core/webhooks/PlatformWebhookService.ts b/controlplane/src/core/webhooks/PlatformWebhookService.ts index fdd5750918..7022cfb647 100644 --- a/controlplane/src/core/webhooks/PlatformWebhookService.ts +++ b/controlplane/src/core/webhooks/PlatformWebhookService.ts @@ -3,6 +3,7 @@ import { PlatformEventName } from '@wundergraph/cosmo-connect/dist/notifications import pino from 'pino'; import axios, { AxiosError, AxiosInstance } from 'axios'; import axiosRetry, { exponentialDelay } from 'axios-retry'; +import { HttpsProxyAgent } from 'https-proxy-agent'; import { webhookAxiosRetryCond } from '../util.js'; import { makeWebhookRequest } from './utils.js'; @@ -48,12 +49,23 @@ export class PlatformWebhookService implements IPlatformWebhookService { private logger: pino.Logger; private httpClient: AxiosInstance; - constructor(webhookURL = '', webhookKey = '', logger: pino.Logger) { + constructor(webhookURL = '', webhookKey = '', logger: pino.Logger, proxyUrl?: string) { this.url = webhookURL; this.key = webhookKey; this.logger = logger; + let agent: HttpsProxyAgent | undefined; + if (proxyUrl) { + try { + agent = new HttpsProxyAgent(proxyUrl); + } catch (e) { + logger.error(e, 'Could not create proxy agent'); + } + } + this.httpClient = axios.create({ + httpAgent: agent, + httpsAgent: agent, timeout: 10_000, }); axiosRetry(this.httpClient, { diff --git a/controlplane/src/core/webhooks/utils.ts b/controlplane/src/core/webhooks/utils.ts index 46cf7b8f66..36af81ad97 100644 --- a/controlplane/src/core/webhooks/utils.ts +++ b/controlplane/src/core/webhooks/utils.ts @@ -1,6 +1,5 @@ import { createHmac } from 'node:crypto'; -import { AxiosError, AxiosInstance } from 'axios'; -import pino from 'pino'; +import { AxiosInstance } from 'axios'; export const makeWebhookRequest = ( axiosInstance: AxiosInstance, diff --git a/controlplane/src/index.ts b/controlplane/src/index.ts index 5ac8cb6728..e541a48ce0 100644 --- a/controlplane/src/index.ts +++ b/controlplane/src/index.ts @@ -35,6 +35,7 @@ const { KC_ADMIN_USER, WEBHOOK_URL, WEBHOOK_SECRET, + WEBHOOK_PROXY_URL, GITHUB_APP_WEBHOOK_SECRET, GITHUB_APP_CLIENT_ID, GITHUB_APP_CLIENT_SECRET, @@ -114,6 +115,7 @@ const options: BuildConfig = { webhook: { url: WEBHOOK_URL, key: WEBHOOK_SECRET, + proxyUrl: WEBHOOK_PROXY_URL, }, cdnBaseUrl: CDN_BASE_URL, admissionWebhook: { diff --git a/helm/cosmo/charts/controlplane/templates/deployment.yaml b/helm/cosmo/charts/controlplane/templates/deployment.yaml index 514626fc3d..0f932ad817 100644 --- a/helm/cosmo/charts/controlplane/templates/deployment.yaml +++ b/helm/cosmo/charts/controlplane/templates/deployment.yaml @@ -188,6 +188,11 @@ spec: secretKeyRef: name: {{ include "controlplane.secretName" . }} key: webhookSecret + - name: WEBHOOK_PROXY_URL + valueFrom: + secretKeyRef: + name: {{ include "controlplane.secretName" . }} + key: webhookProxyUrl - name: GITHUB_APP_CLIENT_ID valueFrom: configMapKeyRef: diff --git a/helm/cosmo/charts/controlplane/templates/secret.yaml b/helm/cosmo/charts/controlplane/templates/secret.yaml index 1bba9daf65..ac228a6921 100644 --- a/helm/cosmo/charts/controlplane/templates/secret.yaml +++ b/helm/cosmo/charts/controlplane/templates/secret.yaml @@ -24,6 +24,7 @@ stringData: keycloakAdminUser: "{{ .Values.global.keycloak.adminUser }}" keycloakAdminPassword: "{{ .Values.global.keycloak.adminPassword }}" webhookSecret: "{{ .Values.configuration.webhookSecret }}" + webhookProxyUrl: "{{ .Values.configuration.webhookProxyUrl }}" githubAppClientSecret: "{{ .Values.configuration.githubAppClientSecret }}" githubAppPrivateKey: "{{ .Values.configuration.githubAppPrivateKey }}" githubAppWebhookSecret: "{{ .Values.configuration.githubAppWebhookSecret }}" diff --git a/helm/cosmo/charts/controlplane/values.yaml b/helm/cosmo/charts/controlplane/values.yaml index 82d16740b4..9adad77e1c 100644 --- a/helm/cosmo/charts/controlplane/values.yaml +++ b/helm/cosmo/charts/controlplane/values.yaml @@ -176,6 +176,7 @@ configuration: clickhouseMigrationDsn: 'clickhouse://default:changeme@cosmo-clickhouse:9000?database=cosmo' webhookUrl: '' webhookSecret: '' + webhookProxyUrl: '' githubAppClientId: '' githubAppClientSecret: '' githubAppId: '' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f49f749a19..6c4f596e6a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -562,6 +562,9 @@ importers: graphql: specifier: 16.9.0 version: 16.9.0(patch_hash=hafdlc54qtxpqvetpefk646rly) + https-proxy-agent: + specifier: 8.0.0 + version: 8.0.0 ioredis: specifier: ^5.4.1 version: 5.4.1 @@ -8057,6 +8060,10 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + agent-base@8.0.0: + resolution: {integrity: sha512-QT8i0hCz6C/KQ+KTAbSNwCHDGdmUJl2tp2ZpNlGSWCfhUNVbYG2WLE3MdZGBAgXPV4GAvjGMxo+C1hroyxmZEg==} + engines: {node: '>= 14'} + agentkeepalive@4.5.0: resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} engines: {node: '>= 8.0.0'} @@ -10609,6 +10616,10 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + https-proxy-agent@8.0.0: + resolution: {integrity: sha512-YYeW+iCnAS3xhvj2dvVoWgsbca3RfQy/IlaNHHOtDmU0jMqPI9euIq3Y9BJETdxk16h9NHHCKqp/KB9nIMStCQ==} + engines: {node: '>= 14'} + human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -14877,7 +14888,7 @@ snapshots: '@apm-js-collab/tracing-hooks@0.3.1': dependencies: '@apm-js-collab/code-transformer': 0.8.2 - debug: 4.3.7 + debug: 4.4.1 module-details-from-path: 1.0.4 transitivePeerDependencies: - supports-color @@ -15647,7 +15658,7 @@ snapshots: '@babel/helper-split-export-declaration': 7.22.6 '@babel/parser': 7.28.0 '@babel/types': 7.23.6 - debug: 4.3.7 + debug: 4.4.1 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -15659,7 +15670,7 @@ snapshots: '@babel/parser': 7.28.0 '@babel/template': 7.27.2 '@babel/types': 7.28.2 - debug: 4.3.7 + debug: 4.4.1 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -22515,7 +22526,7 @@ snapshots: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.7 + debug: 4.4.1 globby: 11.1.0 is-glob: 4.0.3 semver: 7.7.1 @@ -22547,7 +22558,7 @@ snapshots: '@typescript/vfs@1.5.0': dependencies: - debug: 4.3.7 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -22926,6 +22937,8 @@ snapshots: agent-base@7.1.4: {} + agent-base@8.0.0: {} + agentkeepalive@4.5.0: dependencies: humanize-ms: 1.2.1 @@ -23151,7 +23164,7 @@ snapshots: dependencies: '@fastify/error': 3.4.0 archy: 1.0.0 - debug: 4.3.7 + debug: 4.4.1 fastq: 1.17.1 transitivePeerDependencies: - supports-color @@ -23355,7 +23368,7 @@ snapshots: bun-types@1.2.12: dependencies: - '@types/node': 18.19.21 + '@types/node': 20.12.12 optional: true bun-types@1.2.3: @@ -24329,7 +24342,7 @@ snapshots: base64id: 2.0.0 cookie: 0.7.2 cors: 2.8.5 - debug: 4.3.7 + debug: 4.4.1 engine.io-parser: 5.2.3 ws: 8.17.1 transitivePeerDependencies: @@ -24724,7 +24737,7 @@ snapshots: eslint-import-resolver-node@0.3.7: dependencies: - debug: 4.3.7 + debug: 4.4.1 is-core-module: 2.12.1 resolve: 1.22.8 transitivePeerDependencies: @@ -24768,7 +24781,7 @@ snapshots: eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.5.2))(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.1): dependencies: - debug: 4.3.7 + debug: 4.4.1 optionalDependencies: '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.5.2) eslint: 8.57.1 @@ -24779,7 +24792,7 @@ snapshots: eslint-module-utils@2.8.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.5.2))(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.1): dependencies: - debug: 4.3.7 + debug: 4.4.1 optionalDependencies: '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.5.2) eslint: 8.57.1 @@ -25982,7 +25995,7 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 - debug: 4.3.7 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -25996,7 +26009,7 @@ snapshots: https-proxy-agent@7.0.5: dependencies: agent-base: 7.1.4 - debug: 4.3.7 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -26007,6 +26020,13 @@ snapshots: transitivePeerDependencies: - supports-color + https-proxy-agent@8.0.0: + dependencies: + agent-base: 8.0.0 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + human-signals@2.1.0: {} human-signals@4.3.1: {} @@ -28913,7 +28933,7 @@ snapshots: require-in-the-middle@7.5.2: dependencies: - debug: 4.3.7 + debug: 4.4.1 module-details-from-path: 1.0.3 resolve: 1.22.10 transitivePeerDependencies: @@ -29331,7 +29351,7 @@ snapshots: socket.io-adapter@2.5.5: dependencies: - debug: 4.3.7 + debug: 4.4.1 ws: 8.17.1 transitivePeerDependencies: - bufferutil @@ -29341,7 +29361,7 @@ snapshots: socket.io-parser@4.2.4: dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 + debug: 4.4.1 transitivePeerDependencies: - supports-color @@ -29350,7 +29370,7 @@ snapshots: accepts: 1.3.8 base64id: 2.0.0 cors: 2.8.5 - debug: 4.3.7 + debug: 4.4.1 engine.io: 6.6.4 socket.io-adapter: 2.5.5 socket.io-parser: 4.2.4 From 82cd9b64d88e7ed35bc5af1c29ff74827063b5e2 Mon Sep 17 00:00:00 2001 From: Wilson Rivera Date: Thu, 19 Mar 2026 13:23:47 -0400 Subject: [PATCH 2/3] chore: make `WEBHOOK_PROXY_URL` optional and update `README.md` --- helm/cosmo/charts/controlplane/README.md | 225 +++++++++--------- .../controlplane/templates/deployment.yaml | 2 + 2 files changed, 115 insertions(+), 112 deletions(-) diff --git a/helm/cosmo/charts/controlplane/README.md b/helm/cosmo/charts/controlplane/README.md index 4092ba75db..407c26edac 100644 --- a/helm/cosmo/charts/controlplane/README.md +++ b/helm/cosmo/charts/controlplane/README.md @@ -8,117 +8,118 @@ WunderGraph Cosmo Controlplane ## Values -| Key | Type | Default | Description | -|-----|------|---------|-------------| -| additionalJobLabels | object | `{}` | Pass additional labels to all jobs | -| affinity | object | `{}` | | -| autoscaling.enabled | bool | `false` | | -| autoscaling.maxReplicas | int | `100` | | -| autoscaling.minReplicas | int | `1` | | -| autoscaling.targetCPUUtilizationPercentage | int | `80` | | -| commonLabels | object | `{}` | Add labels to all deployed resources | -| configuration.allowedOrigins[0] | string | `"*"` | | -| configuration.authRedirectUri | string | `"http://controlplane.wundergraph.local/v1/auth/callback"` | | -| configuration.authSsoCookieDomain | string | `".wundergraph.local"` | The domain for the cookie used to store SSO authentication information | -| configuration.cdnBaseUrl | string | `"http://cosmo-cdn:8787"` | URL of the CDN to use for serving router configs and persistent operations | -| configuration.clickhouseDsn | string | `"http://default:changeme@cosmo-clickhouse:8123?database=cosmo"` | | -| configuration.clickhouseMigrationDsn | string | `"clickhouse://default:changeme@cosmo-clickhouse:9000?database=cosmo"` | | -| configuration.databaseTlsCa | string | `""` | When connecting to a postgres instance over TLS. Accept a cert in PEM format (as one-line with \n) or file. | -| configuration.databaseTlsCert | string | `""` | | -| configuration.databaseTlsKey | string | `""` | | -| configuration.databaseUrl | string | `"postgres://postgres:changeme@cosmo-postgresql:5432/controlplane"` | | -| configuration.debugSQL | bool | `false` | | -| configuration.defaultBillingPlan | string | `""` | The default billing plan, eg `developer@1` | -| configuration.githubAppClientId | string | `""` | | -| configuration.githubAppClientSecret | string | `""` | | -| configuration.githubAppId | string | `""` | | -| configuration.githubAppPrivateKey | string | `""` | | -| configuration.githubAppWebhookSecret | string | `""` | | -| configuration.logLevel | string | `"info"` | | -| configuration.openAiApiKey | string | `""` | | -| configuration.prometheus | object | `{"enabled":false,"gcpMonitoring":{"enabled":false,"interval":"60s","timeout":"50s"},"host":"127.0.0.1","path":"/metrics","port":8088}` | Use this section to configure prometheus metrics. | -| configuration.prometheus.enabled | bool | `false` | Enables prometheus metrics support. Default is false. | -| configuration.prometheus.gcpMonitoring.enabled | bool | `false` | Enables gcp support . Default is false. | -| configuration.prometheus.gcpMonitoring.interval | string | `"60s"` | Scrape interval. Default is "60s". | -| configuration.prometheus.gcpMonitoring.timeout | string | `"50s"` | Scrape timeout. Default is "50s". | -| configuration.prometheus.host | string | `"127.0.0.1"` | The host to bind to defautls to 127.0.0.1 to avoid opening the metrics endpoint by default. | -| configuration.prometheus.path | string | `"/metrics"` | The HTTP path where metrics are exposed. Default is "/metrics". | -| configuration.prometheus.port | int | `8088` | The port where metrics are exposed. Default is port 8088. | -| configuration.redisHost | string | `"cosmo-redis-master"` | | -| configuration.redisPassword | string | `""` | | -| configuration.redisPort | int | `6379` | | -| configuration.redisTlsCa | string | `""` | When connecting to a redis instance over TLS. Accept a cert in PEM format (as one-line with \n) or file. | -| configuration.redisTlsCert | string | `""` | | -| configuration.redisTlsKey | string | `""` | | -| configuration.s3AccessKeyId | string | `""` | s3 access key id, can be used instead of [username]:[password] in the url | -| configuration.s3Endpoint | string | `""` | The endpoint of the S3 bucket. | -| configuration.s3ForcePathStyle | string | `"true"` | Forces usage of path style urls for S3. Default is true. | -| configuration.s3Region | string | `"auto"` | The region where the S3 bucket is located. | -| configuration.s3SecretAccessKey | string | `""` | s3 secret access key, can be used instead of [username]:[password] in the url | -| configuration.s3StorageUrl | string | `"http://minio:changeme@cosmo-minio:9000/cosmo"` | | -| configuration.slackAppClientId | string | `""` | | -| configuration.slackAppClientSecret | string | `""` | | -| configuration.smtp | object | `{"enabled":false,"host":"smtp.postmarkapp.com","password":"","port":587,"requireTls":true,"secure":true,"username":""}` | Use this section to configure the smtp server. | -| configuration.smtp.enabled | bool | `false` | Enables the smtp server. Default is false. | -| configuration.smtp.host | string | `"smtp.postmarkapp.com"` | The host to connect to. Default is "smtp.postmarkapp.com". | -| configuration.smtp.password | string | `""` | The password to use. Default is "". | -| configuration.smtp.port | int | `587` | The port the smtp server listens to. Default is 587. | -| configuration.smtp.requireTls | bool | `true` | Forces the client to use STARTTLS. Default is true. | -| configuration.smtp.secure | bool | `true` | Defines if the connection should use SSL. Default is true. | -| configuration.smtp.username | string | `""` | The username to use. Default is "". | -| configuration.stripeSecretKey | string | `""` | | -| configuration.stripeWebhookSecret | string | `""` | | -| configuration.webhookSecret | string | `""` | | -| configuration.webhookUrl | string | `""` | | -| deploymentStrategy | object | `{}` | | -| existingSecret | string | `""` | Existing secret in the same namespace containing the ControlPlane Secrets. The secret keys have to match with current secret. | -| extraEnvVars | list | `[]` | Allows to set additional environment variables on the container. Useful for global application non-specific settings. | -| fullnameOverride | string | `""` | String to fully override common.names.fullname template | -| image.pullPolicy | string | `"IfNotPresent"` | | -| image.registry | string | `"ghcr.io"` | | -| image.repository | string | `"wundergraph/cosmo/controlplane"` | | -| imagePullSecrets | list | `[]` | | -| ingress.hosts | string | `nil` | | -| ingress.tls | list | `[]` | | -| jobs | object | `{"activateOrganization":{"additionalLabels":{},"enabled":false,"id":"123","slug":"foo"},"clickhouseMigration":{"additionalLabels":{}},"databaseMigration":{"additionalLabels":{}},"deactivateOrganization":{"additionalLabels":{},"enabled":false,"id":"123","reason":"","slug":"foo"},"deleteUser":{"additionalLabels":{},"email":"foo@wundergraph.com","enabled":false,"id":"123"},"seedOrganization":{"additionalLabels":{}}}` | Configure jobs to be executed in the control plane | -| jobs.activateOrganization | object | `{"additionalLabels":{},"enabled":false,"id":"123","slug":"foo"}` | Used to activate an organization and remove the scheduled deletion | -| jobs.activateOrganization.additionalLabels | object | `{}` | Adds additional labels to the job | -| jobs.activateOrganization.enabled | bool | `false` | Enables the job to be run | -| jobs.activateOrganization.id | string | `"123"` | The unique identifier of the organization | -| jobs.activateOrganization.slug | string | `"foo"` | The slug of the organization | -| jobs.clickhouseMigration.additionalLabels | object | `{}` | Adds additional labels to the clickhouse migration job (see: .Values.global.otelcollector) | -| jobs.databaseMigration.additionalLabels | object | `{}` | Adds additional labels to the database-migration job | -| jobs.deactivateOrganization | object | `{"additionalLabels":{},"enabled":false,"id":"123","reason":"","slug":"foo"}` | Used to deactivate an organization with a reason and schedule deletion | -| jobs.deactivateOrganization.additionalLabels | object | `{}` | Adds additional labels to the job | -| jobs.deactivateOrganization.enabled | bool | `false` | Enables the job to be run | -| jobs.deactivateOrganization.id | string | `"123"` | The unique identifier of the organization | -| jobs.deactivateOrganization.reason | string | `""` | The reason for deactivation | -| jobs.deactivateOrganization.slug | string | `"foo"` | The slug of the organization | -| jobs.deleteUser | object | `{"additionalLabels":{},"email":"foo@wundergraph.com","enabled":false,"id":"123"}` | Used to delete the user | -| jobs.deleteUser.additionalLabels | object | `{}` | Adds additional labels to the job | -| jobs.deleteUser.email | string | `"foo@wundergraph.com"` | The email of the user | -| jobs.deleteUser.enabled | bool | `false` | Enables the job to be run | -| jobs.deleteUser.id | string | `"123"` | The unique identifier of the user | -| jobs.seedOrganization.additionalLabels | object | `{}` | Adds additional labels to the job (see: .Values.global.seed) | -| nameOverride | string | `""` | String to partially override common.names.fullname template (will maintain the release name) | -| nodeSelector | object | `{}` | | -| podAnnotations | object | `{}` | | -| podDisruptionBudget | object | `{}` | Sets the [pod disruption budget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) for Deployment pods | -| podSecurityContext | object | `{}` | | -| priorityClassName | string | `""` | Set to existing PriorityClass name to control pod preemption by the scheduler | -| probes.liveness | object | `{"failureThreshold":5,"httpGet":{"path":"/health","port":"http"},"initialDelaySeconds":10,"periodSeconds":10,"timeoutSeconds":5}` | Configure liveness probe | -| probes.readiness | object | `{"failureThreshold":5,"httpGet":{"path":"/health","port":"http"},"initialDelaySeconds":5,"periodSeconds":5,"timeoutSeconds":3}` | Configure readiness probe | -| replicaCount | int | `1` | | -| resources | object | `{}` | | -| securityContext | object | `{}` | | -| service.port | int | `3001` | | -| service.type | string | `"ClusterIP"` | | -| serviceAccount.annotations | object | `{}` | Annotations to add to the service account | -| serviceAccount.create | bool | `true` | Specifies whether a service account should be created | -| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | -| serviceAnnotations | object | `{}` | | +| Key | Type | Default | Description | +|-----|------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| +| additionalJobLabels | object | `{}` | Pass additional labels to all jobs | +| affinity | object | `{}` | | +| autoscaling.enabled | bool | `false` | | +| autoscaling.maxReplicas | int | `100` | | +| autoscaling.minReplicas | int | `1` | | +| autoscaling.targetCPUUtilizationPercentage | int | `80` | | +| commonLabels | object | `{}` | Add labels to all deployed resources | +| configuration.allowedOrigins[0] | string | `"*"` | | +| configuration.authRedirectUri | string | `"http://controlplane.wundergraph.local/v1/auth/callback"` | | +| configuration.authSsoCookieDomain | string | `".wundergraph.local"` | The domain for the cookie used to store SSO authentication information | +| configuration.cdnBaseUrl | string | `"http://cosmo-cdn:8787"` | URL of the CDN to use for serving router configs and persistent operations | +| configuration.clickhouseDsn | string | `"http://default:changeme@cosmo-clickhouse:8123?database=cosmo"` | | +| configuration.clickhouseMigrationDsn | string | `"clickhouse://default:changeme@cosmo-clickhouse:9000?database=cosmo"` | | +| configuration.databaseTlsCa | string | `""` | When connecting to a postgres instance over TLS. Accept a cert in PEM format (as one-line with \n) or file. | +| configuration.databaseTlsCert | string | `""` | | +| configuration.databaseTlsKey | string | `""` | | +| configuration.databaseUrl | string | `"postgres://postgres:changeme@cosmo-postgresql:5432/controlplane"` | | +| configuration.debugSQL | bool | `false` | | +| configuration.defaultBillingPlan | string | `""` | The default billing plan, eg `developer@1` | +| configuration.githubAppClientId | string | `""` | | +| configuration.githubAppClientSecret | string | `""` | | +| configuration.githubAppId | string | `""` | | +| configuration.githubAppPrivateKey | string | `""` | | +| configuration.githubAppWebhookSecret | string | `""` | | +| configuration.logLevel | string | `"info"` | | +| configuration.openAiApiKey | string | `""` | | +| configuration.prometheus | object | `{"enabled":false,"gcpMonitoring":{"enabled":false,"interval":"60s","timeout":"50s"},"host":"127.0.0.1","path":"/metrics","port":8088}` | Use this section to configure prometheus metrics. | +| configuration.prometheus.enabled | bool | `false` | Enables prometheus metrics support. Default is false. | +| configuration.prometheus.gcpMonitoring.enabled | bool | `false` | Enables gcp support . Default is false. | +| configuration.prometheus.gcpMonitoring.interval | string | `"60s"` | Scrape interval. Default is "60s". | +| configuration.prometheus.gcpMonitoring.timeout | string | `"50s"` | Scrape timeout. Default is "50s". | +| configuration.prometheus.host | string | `"127.0.0.1"` | The host to bind to defautls to 127.0.0.1 to avoid opening the metrics endpoint by default. | +| configuration.prometheus.path | string | `"/metrics"` | The HTTP path where metrics are exposed. Default is "/metrics". | +| configuration.prometheus.port | int | `8088` | The port where metrics are exposed. Default is port 8088. | +| configuration.redisHost | string | `"cosmo-redis-master"` | | +| configuration.redisPassword | string | `""` | | +| configuration.redisPort | int | `6379` | | +| configuration.redisTlsCa | string | `""` | When connecting to a redis instance over TLS. Accept a cert in PEM format (as one-line with \n) or file. | +| configuration.redisTlsCert | string | `""` | | +| configuration.redisTlsKey | string | `""` | | +| configuration.s3AccessKeyId | string | `""` | s3 access key id, can be used instead of [username]:[password] in the url | +| configuration.s3Endpoint | string | `""` | The endpoint of the S3 bucket. | +| configuration.s3ForcePathStyle | string | `"true"` | Forces usage of path style urls for S3. Default is true. | +| configuration.s3Region | string | `"auto"` | The region where the S3 bucket is located. | +| configuration.s3SecretAccessKey | string | `""` | s3 secret access key, can be used instead of [username]:[password] in the url | +| configuration.s3StorageUrl | string | `"http://minio:changeme@cosmo-minio:9000/cosmo"` | | +| configuration.slackAppClientId | string | `""` | | +| configuration.slackAppClientSecret | string | `""` | | +| configuration.smtp | object | `{"enabled":false,"host":"smtp.postmarkapp.com","password":"","port":587,"requireTls":true,"secure":true,"username":""}` | Use this section to configure the smtp server. | +| configuration.smtp.enabled | bool | `false` | Enables the smtp server. Default is false. | +| configuration.smtp.host | string | `"smtp.postmarkapp.com"` | The host to connect to. Default is "smtp.postmarkapp.com". | +| configuration.smtp.password | string | `""` | The password to use. Default is "". | +| configuration.smtp.port | int | `587` | The port the smtp server listens to. Default is 587. | +| configuration.smtp.requireTls | bool | `true` | Forces the client to use STARTTLS. Default is true. | +| configuration.smtp.secure | bool | `true` | Defines if the connection should use SSL. Default is true. | +| configuration.smtp.username | string | `""` | The username to use. Default is "". | +| configuration.stripeSecretKey | string | `""` | | +| configuration.stripeWebhookSecret | string | `""` | | +| configuration.webhookProxyUrl | string | `""` | The URL to configure the proxy used when sending webhook requests | +| configuration.webhookSecret | string | `""` | | +| configuration.webhookUrl | string | `""` | | +| deploymentStrategy | object | `{}` | | +| existingSecret | string | `""` | Existing secret in the same namespace containing the ControlPlane Secrets. The secret keys have to match with current secret. | +| extraEnvVars | list | `[]` | Allows to set additional environment variables on the container. Useful for global application non-specific settings. | +| fullnameOverride | string | `""` | String to fully override common.names.fullname template | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.registry | string | `"ghcr.io"` | | +| image.repository | string | `"wundergraph/cosmo/controlplane"` | | +| imagePullSecrets | list | `[]` | | +| ingress.hosts | string | `nil` | | +| ingress.tls | list | `[]` | | +| jobs | object | `{"activateOrganization":{"additionalLabels":{},"enabled":false,"id":"123","slug":"foo"},"clickhouseMigration":{"additionalLabels":{}},"databaseMigration":{"additionalLabels":{}},"deactivateOrganization":{"additionalLabels":{},"enabled":false,"id":"123","reason":"","slug":"foo"},"deleteUser":{"additionalLabels":{},"email":"foo@wundergraph.com","enabled":false,"id":"123"},"seedOrganization":{"additionalLabels":{}}}` | Configure jobs to be executed in the control plane | +| jobs.activateOrganization | object | `{"additionalLabels":{},"enabled":false,"id":"123","slug":"foo"}` | Used to activate an organization and remove the scheduled deletion | +| jobs.activateOrganization.additionalLabels | object | `{}` | Adds additional labels to the job | +| jobs.activateOrganization.enabled | bool | `false` | Enables the job to be run | +| jobs.activateOrganization.id | string | `"123"` | The unique identifier of the organization | +| jobs.activateOrganization.slug | string | `"foo"` | The slug of the organization | +| jobs.clickhouseMigration.additionalLabels | object | `{}` | Adds additional labels to the clickhouse migration job (see: .Values.global.otelcollector) | +| jobs.databaseMigration.additionalLabels | object | `{}` | Adds additional labels to the database-migration job | +| jobs.deactivateOrganization | object | `{"additionalLabels":{},"enabled":false,"id":"123","reason":"","slug":"foo"}` | Used to deactivate an organization with a reason and schedule deletion | +| jobs.deactivateOrganization.additionalLabels | object | `{}` | Adds additional labels to the job | +| jobs.deactivateOrganization.enabled | bool | `false` | Enables the job to be run | +| jobs.deactivateOrganization.id | string | `"123"` | The unique identifier of the organization | +| jobs.deactivateOrganization.reason | string | `""` | The reason for deactivation | +| jobs.deactivateOrganization.slug | string | `"foo"` | The slug of the organization | +| jobs.deleteUser | object | `{"additionalLabels":{},"email":"foo@wundergraph.com","enabled":false,"id":"123"}` | Used to delete the user | +| jobs.deleteUser.additionalLabels | object | `{}` | Adds additional labels to the job | +| jobs.deleteUser.email | string | `"foo@wundergraph.com"` | The email of the user | +| jobs.deleteUser.enabled | bool | `false` | Enables the job to be run | +| jobs.deleteUser.id | string | `"123"` | The unique identifier of the user | +| jobs.seedOrganization.additionalLabels | object | `{}` | Adds additional labels to the job (see: .Values.global.seed) | +| nameOverride | string | `""` | String to partially override common.names.fullname template (will maintain the release name) | +| nodeSelector | object | `{}` | | +| podAnnotations | object | `{}` | | +| podDisruptionBudget | object | `{}` | Sets the [pod disruption budget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) for Deployment pods | +| podSecurityContext | object | `{}` | | +| priorityClassName | string | `""` | Set to existing PriorityClass name to control pod preemption by the scheduler | +| probes.liveness | object | `{"failureThreshold":5,"httpGet":{"path":"/health","port":"http"},"initialDelaySeconds":10,"periodSeconds":10,"timeoutSeconds":5}` | Configure liveness probe | +| probes.readiness | object | `{"failureThreshold":5,"httpGet":{"path":"/health","port":"http"},"initialDelaySeconds":5,"periodSeconds":5,"timeoutSeconds":3}` | Configure readiness probe | +| replicaCount | int | `1` | | +| resources | object | `{}` | | +| securityContext | object | `{}` | | +| service.port | int | `3001` | | +| service.type | string | `"ClusterIP"` | | +| serviceAccount.annotations | object | `{}` | Annotations to add to the service account | +| serviceAccount.create | bool | `true` | Specifies whether a service account should be created | +| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | +| serviceAnnotations | object | `{}` | | | terminationGracePeriodSeconds | int | `60` | Sets the [termination grace period](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution) for Deployment pods | -| tolerations | list | `[]` | | -| volumeMounts | list | `[]` | | -| volumes | list | `[]` | | +| tolerations | list | `[]` | | +| volumeMounts | list | `[]` | | +| volumes | list | `[]` | | diff --git a/helm/cosmo/charts/controlplane/templates/deployment.yaml b/helm/cosmo/charts/controlplane/templates/deployment.yaml index 0f932ad817..e4ea834acf 100644 --- a/helm/cosmo/charts/controlplane/templates/deployment.yaml +++ b/helm/cosmo/charts/controlplane/templates/deployment.yaml @@ -188,11 +188,13 @@ spec: secretKeyRef: name: {{ include "controlplane.secretName" . }} key: webhookSecret + {{- if .Values.configuration.webhookProxyUrl }} - name: WEBHOOK_PROXY_URL valueFrom: secretKeyRef: name: {{ include "controlplane.secretName" . }} key: webhookProxyUrl + {{- end }} - name: GITHUB_APP_CLIENT_ID valueFrom: configMapKeyRef: From d206b3fb03954cc39b5d3a745912830d246c2eaf Mon Sep 17 00:00:00 2001 From: Wilson Rivera Date: Thu, 19 Mar 2026 14:16:41 -0400 Subject: [PATCH 3/3] chore: fix `README.md` --- helm/cosmo/charts/controlplane/README.md | 226 +++++++++++------------ 1 file changed, 113 insertions(+), 113 deletions(-) diff --git a/helm/cosmo/charts/controlplane/README.md b/helm/cosmo/charts/controlplane/README.md index 407c26edac..b526e9e193 100644 --- a/helm/cosmo/charts/controlplane/README.md +++ b/helm/cosmo/charts/controlplane/README.md @@ -8,118 +8,118 @@ WunderGraph Cosmo Controlplane ## Values -| Key | Type | Default | Description | -|-----|------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| -| additionalJobLabels | object | `{}` | Pass additional labels to all jobs | -| affinity | object | `{}` | | -| autoscaling.enabled | bool | `false` | | -| autoscaling.maxReplicas | int | `100` | | -| autoscaling.minReplicas | int | `1` | | -| autoscaling.targetCPUUtilizationPercentage | int | `80` | | -| commonLabels | object | `{}` | Add labels to all deployed resources | -| configuration.allowedOrigins[0] | string | `"*"` | | -| configuration.authRedirectUri | string | `"http://controlplane.wundergraph.local/v1/auth/callback"` | | -| configuration.authSsoCookieDomain | string | `".wundergraph.local"` | The domain for the cookie used to store SSO authentication information | -| configuration.cdnBaseUrl | string | `"http://cosmo-cdn:8787"` | URL of the CDN to use for serving router configs and persistent operations | -| configuration.clickhouseDsn | string | `"http://default:changeme@cosmo-clickhouse:8123?database=cosmo"` | | -| configuration.clickhouseMigrationDsn | string | `"clickhouse://default:changeme@cosmo-clickhouse:9000?database=cosmo"` | | -| configuration.databaseTlsCa | string | `""` | When connecting to a postgres instance over TLS. Accept a cert in PEM format (as one-line with \n) or file. | -| configuration.databaseTlsCert | string | `""` | | -| configuration.databaseTlsKey | string | `""` | | -| configuration.databaseUrl | string | `"postgres://postgres:changeme@cosmo-postgresql:5432/controlplane"` | | -| configuration.debugSQL | bool | `false` | | -| configuration.defaultBillingPlan | string | `""` | The default billing plan, eg `developer@1` | -| configuration.githubAppClientId | string | `""` | | -| configuration.githubAppClientSecret | string | `""` | | -| configuration.githubAppId | string | `""` | | -| configuration.githubAppPrivateKey | string | `""` | | -| configuration.githubAppWebhookSecret | string | `""` | | -| configuration.logLevel | string | `"info"` | | -| configuration.openAiApiKey | string | `""` | | -| configuration.prometheus | object | `{"enabled":false,"gcpMonitoring":{"enabled":false,"interval":"60s","timeout":"50s"},"host":"127.0.0.1","path":"/metrics","port":8088}` | Use this section to configure prometheus metrics. | -| configuration.prometheus.enabled | bool | `false` | Enables prometheus metrics support. Default is false. | -| configuration.prometheus.gcpMonitoring.enabled | bool | `false` | Enables gcp support . Default is false. | -| configuration.prometheus.gcpMonitoring.interval | string | `"60s"` | Scrape interval. Default is "60s". | -| configuration.prometheus.gcpMonitoring.timeout | string | `"50s"` | Scrape timeout. Default is "50s". | -| configuration.prometheus.host | string | `"127.0.0.1"` | The host to bind to defautls to 127.0.0.1 to avoid opening the metrics endpoint by default. | -| configuration.prometheus.path | string | `"/metrics"` | The HTTP path where metrics are exposed. Default is "/metrics". | -| configuration.prometheus.port | int | `8088` | The port where metrics are exposed. Default is port 8088. | -| configuration.redisHost | string | `"cosmo-redis-master"` | | -| configuration.redisPassword | string | `""` | | -| configuration.redisPort | int | `6379` | | -| configuration.redisTlsCa | string | `""` | When connecting to a redis instance over TLS. Accept a cert in PEM format (as one-line with \n) or file. | -| configuration.redisTlsCert | string | `""` | | -| configuration.redisTlsKey | string | `""` | | -| configuration.s3AccessKeyId | string | `""` | s3 access key id, can be used instead of [username]:[password] in the url | -| configuration.s3Endpoint | string | `""` | The endpoint of the S3 bucket. | -| configuration.s3ForcePathStyle | string | `"true"` | Forces usage of path style urls for S3. Default is true. | -| configuration.s3Region | string | `"auto"` | The region where the S3 bucket is located. | -| configuration.s3SecretAccessKey | string | `""` | s3 secret access key, can be used instead of [username]:[password] in the url | -| configuration.s3StorageUrl | string | `"http://minio:changeme@cosmo-minio:9000/cosmo"` | | -| configuration.slackAppClientId | string | `""` | | -| configuration.slackAppClientSecret | string | `""` | | -| configuration.smtp | object | `{"enabled":false,"host":"smtp.postmarkapp.com","password":"","port":587,"requireTls":true,"secure":true,"username":""}` | Use this section to configure the smtp server. | -| configuration.smtp.enabled | bool | `false` | Enables the smtp server. Default is false. | -| configuration.smtp.host | string | `"smtp.postmarkapp.com"` | The host to connect to. Default is "smtp.postmarkapp.com". | -| configuration.smtp.password | string | `""` | The password to use. Default is "". | -| configuration.smtp.port | int | `587` | The port the smtp server listens to. Default is 587. | -| configuration.smtp.requireTls | bool | `true` | Forces the client to use STARTTLS. Default is true. | -| configuration.smtp.secure | bool | `true` | Defines if the connection should use SSL. Default is true. | -| configuration.smtp.username | string | `""` | The username to use. Default is "". | -| configuration.stripeSecretKey | string | `""` | | -| configuration.stripeWebhookSecret | string | `""` | | -| configuration.webhookProxyUrl | string | `""` | The URL to configure the proxy used when sending webhook requests | -| configuration.webhookSecret | string | `""` | | -| configuration.webhookUrl | string | `""` | | -| deploymentStrategy | object | `{}` | | -| existingSecret | string | `""` | Existing secret in the same namespace containing the ControlPlane Secrets. The secret keys have to match with current secret. | -| extraEnvVars | list | `[]` | Allows to set additional environment variables on the container. Useful for global application non-specific settings. | -| fullnameOverride | string | `""` | String to fully override common.names.fullname template | -| image.pullPolicy | string | `"IfNotPresent"` | | -| image.registry | string | `"ghcr.io"` | | -| image.repository | string | `"wundergraph/cosmo/controlplane"` | | -| imagePullSecrets | list | `[]` | | -| ingress.hosts | string | `nil` | | -| ingress.tls | list | `[]` | | -| jobs | object | `{"activateOrganization":{"additionalLabels":{},"enabled":false,"id":"123","slug":"foo"},"clickhouseMigration":{"additionalLabels":{}},"databaseMigration":{"additionalLabels":{}},"deactivateOrganization":{"additionalLabels":{},"enabled":false,"id":"123","reason":"","slug":"foo"},"deleteUser":{"additionalLabels":{},"email":"foo@wundergraph.com","enabled":false,"id":"123"},"seedOrganization":{"additionalLabels":{}}}` | Configure jobs to be executed in the control plane | -| jobs.activateOrganization | object | `{"additionalLabels":{},"enabled":false,"id":"123","slug":"foo"}` | Used to activate an organization and remove the scheduled deletion | -| jobs.activateOrganization.additionalLabels | object | `{}` | Adds additional labels to the job | -| jobs.activateOrganization.enabled | bool | `false` | Enables the job to be run | -| jobs.activateOrganization.id | string | `"123"` | The unique identifier of the organization | -| jobs.activateOrganization.slug | string | `"foo"` | The slug of the organization | -| jobs.clickhouseMigration.additionalLabels | object | `{}` | Adds additional labels to the clickhouse migration job (see: .Values.global.otelcollector) | -| jobs.databaseMigration.additionalLabels | object | `{}` | Adds additional labels to the database-migration job | -| jobs.deactivateOrganization | object | `{"additionalLabels":{},"enabled":false,"id":"123","reason":"","slug":"foo"}` | Used to deactivate an organization with a reason and schedule deletion | -| jobs.deactivateOrganization.additionalLabels | object | `{}` | Adds additional labels to the job | -| jobs.deactivateOrganization.enabled | bool | `false` | Enables the job to be run | -| jobs.deactivateOrganization.id | string | `"123"` | The unique identifier of the organization | -| jobs.deactivateOrganization.reason | string | `""` | The reason for deactivation | -| jobs.deactivateOrganization.slug | string | `"foo"` | The slug of the organization | -| jobs.deleteUser | object | `{"additionalLabels":{},"email":"foo@wundergraph.com","enabled":false,"id":"123"}` | Used to delete the user | -| jobs.deleteUser.additionalLabels | object | `{}` | Adds additional labels to the job | -| jobs.deleteUser.email | string | `"foo@wundergraph.com"` | The email of the user | -| jobs.deleteUser.enabled | bool | `false` | Enables the job to be run | -| jobs.deleteUser.id | string | `"123"` | The unique identifier of the user | -| jobs.seedOrganization.additionalLabels | object | `{}` | Adds additional labels to the job (see: .Values.global.seed) | -| nameOverride | string | `""` | String to partially override common.names.fullname template (will maintain the release name) | -| nodeSelector | object | `{}` | | -| podAnnotations | object | `{}` | | -| podDisruptionBudget | object | `{}` | Sets the [pod disruption budget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) for Deployment pods | -| podSecurityContext | object | `{}` | | -| priorityClassName | string | `""` | Set to existing PriorityClass name to control pod preemption by the scheduler | -| probes.liveness | object | `{"failureThreshold":5,"httpGet":{"path":"/health","port":"http"},"initialDelaySeconds":10,"periodSeconds":10,"timeoutSeconds":5}` | Configure liveness probe | -| probes.readiness | object | `{"failureThreshold":5,"httpGet":{"path":"/health","port":"http"},"initialDelaySeconds":5,"periodSeconds":5,"timeoutSeconds":3}` | Configure readiness probe | -| replicaCount | int | `1` | | -| resources | object | `{}` | | -| securityContext | object | `{}` | | -| service.port | int | `3001` | | -| service.type | string | `"ClusterIP"` | | -| serviceAccount.annotations | object | `{}` | Annotations to add to the service account | -| serviceAccount.create | bool | `true` | Specifies whether a service account should be created | -| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | -| serviceAnnotations | object | `{}` | | +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| additionalJobLabels | object | `{}` | Pass additional labels to all jobs | +| affinity | object | `{}` | | +| autoscaling.enabled | bool | `false` | | +| autoscaling.maxReplicas | int | `100` | | +| autoscaling.minReplicas | int | `1` | | +| autoscaling.targetCPUUtilizationPercentage | int | `80` | | +| commonLabels | object | `{}` | Add labels to all deployed resources | +| configuration.allowedOrigins[0] | string | `"*"` | | +| configuration.authRedirectUri | string | `"http://controlplane.wundergraph.local/v1/auth/callback"` | | +| configuration.authSsoCookieDomain | string | `".wundergraph.local"` | The domain for the cookie used to store SSO authentication information | +| configuration.cdnBaseUrl | string | `"http://cosmo-cdn:8787"` | URL of the CDN to use for serving router configs and persistent operations | +| configuration.clickhouseDsn | string | `"http://default:changeme@cosmo-clickhouse:8123?database=cosmo"` | | +| configuration.clickhouseMigrationDsn | string | `"clickhouse://default:changeme@cosmo-clickhouse:9000?database=cosmo"` | | +| configuration.databaseTlsCa | string | `""` | When connecting to a postgres instance over TLS. Accept a cert in PEM format (as one-line with \n) or file. | +| configuration.databaseTlsCert | string | `""` | | +| configuration.databaseTlsKey | string | `""` | | +| configuration.databaseUrl | string | `"postgres://postgres:changeme@cosmo-postgresql:5432/controlplane"` | | +| configuration.debugSQL | bool | `false` | | +| configuration.defaultBillingPlan | string | `""` | The default billing plan, eg `developer@1` | +| configuration.githubAppClientId | string | `""` | | +| configuration.githubAppClientSecret | string | `""` | | +| configuration.githubAppId | string | `""` | | +| configuration.githubAppPrivateKey | string | `""` | | +| configuration.githubAppWebhookSecret | string | `""` | | +| configuration.logLevel | string | `"info"` | | +| configuration.openAiApiKey | string | `""` | | +| configuration.prometheus | object | `{"enabled":false,"gcpMonitoring":{"enabled":false,"interval":"60s","timeout":"50s"},"host":"127.0.0.1","path":"/metrics","port":8088}` | Use this section to configure prometheus metrics. | +| configuration.prometheus.enabled | bool | `false` | Enables prometheus metrics support. Default is false. | +| configuration.prometheus.gcpMonitoring.enabled | bool | `false` | Enables gcp support . Default is false. | +| configuration.prometheus.gcpMonitoring.interval | string | `"60s"` | Scrape interval. Default is "60s". | +| configuration.prometheus.gcpMonitoring.timeout | string | `"50s"` | Scrape timeout. Default is "50s". | +| configuration.prometheus.host | string | `"127.0.0.1"` | The host to bind to defautls to 127.0.0.1 to avoid opening the metrics endpoint by default. | +| configuration.prometheus.path | string | `"/metrics"` | The HTTP path where metrics are exposed. Default is "/metrics". | +| configuration.prometheus.port | int | `8088` | The port where metrics are exposed. Default is port 8088. | +| configuration.redisHost | string | `"cosmo-redis-master"` | | +| configuration.redisPassword | string | `""` | | +| configuration.redisPort | int | `6379` | | +| configuration.redisTlsCa | string | `""` | When connecting to a redis instance over TLS. Accept a cert in PEM format (as one-line with \n) or file. | +| configuration.redisTlsCert | string | `""` | | +| configuration.redisTlsKey | string | `""` | | +| configuration.s3AccessKeyId | string | `""` | s3 access key id, can be used instead of [username]:[password] in the url | +| configuration.s3Endpoint | string | `""` | The endpoint of the S3 bucket. | +| configuration.s3ForcePathStyle | string | `"true"` | Forces usage of path style urls for S3. Default is true. | +| configuration.s3Region | string | `"auto"` | The region where the S3 bucket is located. | +| configuration.s3SecretAccessKey | string | `""` | s3 secret access key, can be used instead of [username]:[password] in the url | +| configuration.s3StorageUrl | string | `"http://minio:changeme@cosmo-minio:9000/cosmo"` | | +| configuration.slackAppClientId | string | `""` | | +| configuration.slackAppClientSecret | string | `""` | | +| configuration.smtp | object | `{"enabled":false,"host":"smtp.postmarkapp.com","password":"","port":587,"requireTls":true,"secure":true,"username":""}` | Use this section to configure the smtp server. | +| configuration.smtp.enabled | bool | `false` | Enables the smtp server. Default is false. | +| configuration.smtp.host | string | `"smtp.postmarkapp.com"` | The host to connect to. Default is "smtp.postmarkapp.com". | +| configuration.smtp.password | string | `""` | The password to use. Default is "". | +| configuration.smtp.port | int | `587` | The port the smtp server listens to. Default is 587. | +| configuration.smtp.requireTls | bool | `true` | Forces the client to use STARTTLS. Default is true. | +| configuration.smtp.secure | bool | `true` | Defines if the connection should use SSL. Default is true. | +| configuration.smtp.username | string | `""` | The username to use. Default is "". | +| configuration.stripeSecretKey | string | `""` | | +| configuration.stripeWebhookSecret | string | `""` | | +| configuration.webhookProxyUrl | string | `""` | | +| configuration.webhookSecret | string | `""` | | +| configuration.webhookUrl | string | `""` | | +| deploymentStrategy | object | `{}` | | +| existingSecret | string | `""` | Existing secret in the same namespace containing the ControlPlane Secrets. The secret keys have to match with current secret. | +| extraEnvVars | list | `[]` | Allows to set additional environment variables on the container. Useful for global application non-specific settings. | +| fullnameOverride | string | `""` | String to fully override common.names.fullname template | +| image.pullPolicy | string | `"IfNotPresent"` | | +| image.registry | string | `"ghcr.io"` | | +| image.repository | string | `"wundergraph/cosmo/controlplane"` | | +| imagePullSecrets | list | `[]` | | +| ingress.hosts | string | `nil` | | +| ingress.tls | list | `[]` | | +| jobs | object | `{"activateOrganization":{"additionalLabels":{},"enabled":false,"id":"123","slug":"foo"},"clickhouseMigration":{"additionalLabels":{}},"databaseMigration":{"additionalLabels":{}},"deactivateOrganization":{"additionalLabels":{},"enabled":false,"id":"123","reason":"","slug":"foo"},"deleteUser":{"additionalLabels":{},"email":"foo@wundergraph.com","enabled":false,"id":"123"},"seedOrganization":{"additionalLabels":{}}}` | Configure jobs to be executed in the control plane | +| jobs.activateOrganization | object | `{"additionalLabels":{},"enabled":false,"id":"123","slug":"foo"}` | Used to activate an organization and remove the scheduled deletion | +| jobs.activateOrganization.additionalLabels | object | `{}` | Adds additional labels to the job | +| jobs.activateOrganization.enabled | bool | `false` | Enables the job to be run | +| jobs.activateOrganization.id | string | `"123"` | The unique identifier of the organization | +| jobs.activateOrganization.slug | string | `"foo"` | The slug of the organization | +| jobs.clickhouseMigration.additionalLabels | object | `{}` | Adds additional labels to the clickhouse migration job (see: .Values.global.otelcollector) | +| jobs.databaseMigration.additionalLabels | object | `{}` | Adds additional labels to the database-migration job | +| jobs.deactivateOrganization | object | `{"additionalLabels":{},"enabled":false,"id":"123","reason":"","slug":"foo"}` | Used to deactivate an organization with a reason and schedule deletion | +| jobs.deactivateOrganization.additionalLabels | object | `{}` | Adds additional labels to the job | +| jobs.deactivateOrganization.enabled | bool | `false` | Enables the job to be run | +| jobs.deactivateOrganization.id | string | `"123"` | The unique identifier of the organization | +| jobs.deactivateOrganization.reason | string | `""` | The reason for deactivation | +| jobs.deactivateOrganization.slug | string | `"foo"` | The slug of the organization | +| jobs.deleteUser | object | `{"additionalLabels":{},"email":"foo@wundergraph.com","enabled":false,"id":"123"}` | Used to delete the user | +| jobs.deleteUser.additionalLabels | object | `{}` | Adds additional labels to the job | +| jobs.deleteUser.email | string | `"foo@wundergraph.com"` | The email of the user | +| jobs.deleteUser.enabled | bool | `false` | Enables the job to be run | +| jobs.deleteUser.id | string | `"123"` | The unique identifier of the user | +| jobs.seedOrganization.additionalLabels | object | `{}` | Adds additional labels to the job (see: .Values.global.seed) | +| nameOverride | string | `""` | String to partially override common.names.fullname template (will maintain the release name) | +| nodeSelector | object | `{}` | | +| podAnnotations | object | `{}` | | +| podDisruptionBudget | object | `{}` | Sets the [pod disruption budget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) for Deployment pods | +| podSecurityContext | object | `{}` | | +| priorityClassName | string | `""` | Set to existing PriorityClass name to control pod preemption by the scheduler | +| probes.liveness | object | `{"failureThreshold":5,"httpGet":{"path":"/health","port":"http"},"initialDelaySeconds":10,"periodSeconds":10,"timeoutSeconds":5}` | Configure liveness probe | +| probes.readiness | object | `{"failureThreshold":5,"httpGet":{"path":"/health","port":"http"},"initialDelaySeconds":5,"periodSeconds":5,"timeoutSeconds":3}` | Configure readiness probe | +| replicaCount | int | `1` | | +| resources | object | `{}` | | +| securityContext | object | `{}` | | +| service.port | int | `3001` | | +| service.type | string | `"ClusterIP"` | | +| serviceAccount.annotations | object | `{}` | Annotations to add to the service account | +| serviceAccount.create | bool | `true` | Specifies whether a service account should be created | +| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | +| serviceAnnotations | object | `{}` | | | terminationGracePeriodSeconds | int | `60` | Sets the [termination grace period](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution) for Deployment pods | -| tolerations | list | `[]` | | -| volumeMounts | list | `[]` | | -| volumes | list | `[]` | | +| tolerations | list | `[]` | | +| volumeMounts | list | `[]` | | +| volumes | list | `[]` | |