Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions controlplane/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export function updateContract(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
);

req.excludeTags = [...new Set(req.excludeTags)];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export function createFeatureFlag(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
);

req.namespace = req.namespace || DefaultNamespace;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export function deleteFeatureFlag(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
);

req.namespace = req.namespace || DefaultNamespace;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export function enableFeatureFlag(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
);

req.namespace = req.namespace || DefaultNamespace;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export function updateFeatureFlag(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
);

req.namespace = req.namespace || DefaultNamespace;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export function updateFederatedGraph(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
);

req.namespace = req.namespace || DefaultNamespace;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export function updateMonograph(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
);

if (req.subscriptionUrl && !isValidUrl(req.subscriptionUrl)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ export function createProposal(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export function updateProposal(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
);
const namespaceRepo = new NamespaceRepository(opts.db, authContext.organizationId);

Expand Down Expand Up @@ -512,6 +513,7 @@ export function updateProposal(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export function checkSubgraphSchema(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
);

let linkedSubgraph:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export function deleteFederatedSubgraph(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
);

req.namespace = req.namespace || DefaultNamespace;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export function moveSubgraph(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
);

const subgraph = await subgraphRepo.byName(req.name, req.namespace);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export function updateSubgraph(
authContext.organizationId,
opts.logger,
opts.billingDefaultPlanId,
opts.webhookProxyUrl,
);

req.namespace = req.namespace || DefaultNamespace;
Expand Down
9 changes: 8 additions & 1 deletion controlplane/src/core/build-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export interface BuildConfig {
webhook?: {
url?: string;
key?: string;
proxyUrl?: string;
};
githubApp?: {
webhookSecret?: string;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions controlplane/src/core/env.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
1 change: 1 addition & 0 deletions controlplane/src/core/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down
13 changes: 13 additions & 0 deletions controlplane/src/core/webhooks/OrganizationWebhookService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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<string> | undefined;
Comment thread
pepol marked this conversation as resolved.
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
});
Expand Down
14 changes: 13 additions & 1 deletion controlplane/src/core/webhooks/PlatformWebhookService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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<string> | 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, {
Expand Down
3 changes: 1 addition & 2 deletions controlplane/src/core/webhooks/utils.ts
Original file line number Diff line number Diff line change
@@ -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 = <Data = any, TResponse = any>(
axiosInstance: AxiosInstance,
Expand Down
2 changes: 2 additions & 0 deletions controlplane/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -114,6 +115,7 @@ const options: BuildConfig = {
webhook: {
url: WEBHOOK_URL,
key: WEBHOOK_SECRET,
proxyUrl: WEBHOOK_PROXY_URL,
},
cdnBaseUrl: CDN_BASE_URL,
admissionWebhook: {
Expand Down
Loading
Loading