From f6be86a26bf5ef6f000f1dcecdfa8546b9a4340e Mon Sep 17 00:00:00 2001 From: Vladyslav Matsiiako Date: Tue, 29 Aug 2023 22:17:48 -0700 Subject: [PATCH] Added suffixes to integrations --- backend/src/controllers/v1/integrationController.ts | 4 +++- backend/src/integrations/sync.ts | 2 +- backend/src/models/integration.ts | 6 ++++++ .../integrations/syncSecretsToThirdPartyServices.ts | 10 +++++++++- backend/src/routes/v1/integration.ts | 1 + docs/integrations/cloud/checkly.mdx | 6 ++++++ frontend/src/hooks/api/integrations/queries.tsx | 7 +++++-- frontend/src/hooks/api/integrations/types.ts | 1 + frontend/src/pages/integrations/checkly/create.tsx | 11 ++++++++++- .../IntegrationsSection/IntegrationsSection.tsx | 8 ++++++++ 10 files changed, 50 insertions(+), 6 deletions(-) diff --git a/backend/src/controllers/v1/integrationController.ts b/backend/src/controllers/v1/integrationController.ts index e5f6e7393..3c665fbea 100644 --- a/backend/src/controllers/v1/integrationController.ts +++ b/backend/src/controllers/v1/integrationController.ts @@ -30,7 +30,8 @@ export const createIntegration = async (req: Request, res: Response) => { owner, path, region, - secretPath + secretPath, + secretSuffix } = req.body; const folders = await Folder.findOne({ @@ -64,6 +65,7 @@ export const createIntegration = async (req: Request, res: Response) => { path, region, secretPath, + secretSuffix, integration: req.integrationAuth.integration, integrationAuth: new Types.ObjectId(integrationAuthId) }).save(); diff --git a/backend/src/integrations/sync.ts b/backend/src/integrations/sync.ts index 1803a37bb..c0aca4056 100644 --- a/backend/src/integrations/sync.ts +++ b/backend/src/integrations/sync.ts @@ -2066,7 +2066,7 @@ const syncSecretsCheckly = async ({ } for await (const key of Object.keys(getSecretsRes)) { - if (!(key in secrets)) { + if (!(key in secrets) && key.endsWith(integration?.secretSuffix)) { // delete secret await standardRequest.delete(`${INTEGRATION_CHECKLY_API_URL}/v1/variables/${key}`, { headers: { diff --git a/backend/src/models/integration.ts b/backend/src/models/integration.ts index b5c467458..6c4bf7b13 100644 --- a/backend/src/models/integration.ts +++ b/backend/src/models/integration.ts @@ -45,6 +45,7 @@ export interface IIntegration { path: string; region: string; secretPath: string; + secretSuffix: string; integration: | "azure-key-vault" | "aws-parameter-store" @@ -183,6 +184,11 @@ const integrationSchema = new Schema( type: String, required: true, default: "/", + }, + secretSuffix: { + type: String, + required: false, + default: "", } }, { diff --git a/backend/src/queues/integrations/syncSecretsToThirdPartyServices.ts b/backend/src/queues/integrations/syncSecretsToThirdPartyServices.ts index 2a12c0e5d..f9675fa45 100644 --- a/backend/src/queues/integrations/syncSecretsToThirdPartyServices.ts +++ b/backend/src/queues/integrations/syncSecretsToThirdPartyServices.ts @@ -36,6 +36,14 @@ syncSecretsToThirdPartyServices.process(async (job: Job) => { secretPath: integration.secretPath }); + const suffixedSecrets: any = {}; + if (integration?.secretSuffix) { + for (const key in secrets) { + const newKey = key + integration?.secretSuffix; + suffixedSecrets[newKey] = secrets[key]; + } + } + const integrationAuth = await IntegrationAuth.findById(integration.integrationAuth); if (!integrationAuth) throw new Error("Failed to find integration auth"); @@ -49,7 +57,7 @@ syncSecretsToThirdPartyServices.process(async (job: Job) => { await syncSecrets({ integration, integrationAuth, - secrets, + secrets: Object.keys(suffixedSecrets).length !== 0 ? suffixedSecrets : secrets, accessId: access.accessId === undefined ? null : access.accessId, accessToken: access.accessToken }); diff --git a/backend/src/routes/v1/integration.ts b/backend/src/routes/v1/integration.ts index dc97e66c0..d5709dcc3 100644 --- a/backend/src/routes/v1/integration.ts +++ b/backend/src/routes/v1/integration.ts @@ -29,6 +29,7 @@ router.post( body("isActive").exists().isBoolean(), body("appId").trim(), body("secretPath").default("/").isString().trim(), + body("secretSuffix").default("").isString().trim(), body("sourceEnvironment").trim(), body("targetEnvironment").trim(), body("targetEnvironmentId").trim(), diff --git a/docs/integrations/cloud/checkly.mdx b/docs/integrations/cloud/checkly.mdx index 90c0850d3..315764ce8 100644 --- a/docs/integrations/cloud/checkly.mdx +++ b/docs/integrations/cloud/checkly.mdx @@ -35,3 +35,9 @@ Select which Infisical environment secrets you want to sync to Checkly and press ![integrations checkly](../../images/integrations-checkly-create.png) ![integrations checkly](../../images/integrations-checkly.png) + + + In the new version of the Checkly integration, you are able to specify suffixes that depend on the secrets' environment and path. + If you choose to do so, you should utilize such suffixes for ALL Checkly integrations – otherwise the integration system + might run into issues with deleting secrets from the wrong environments. + diff --git a/frontend/src/hooks/api/integrations/queries.tsx b/frontend/src/hooks/api/integrations/queries.tsx index bfca2f407..3e1882f6e 100644 --- a/frontend/src/hooks/api/integrations/queries.tsx +++ b/frontend/src/hooks/api/integrations/queries.tsx @@ -40,7 +40,8 @@ export const useCreateIntegration = () => { owner, path, region, - secretPath + secretPath, + secretSuffix }: { integrationAuthId: string; isActive: boolean; @@ -55,6 +56,7 @@ export const useCreateIntegration = () => { owner: string | null; path: string | null; region: string | null; + secretSuffix: string; }) => { const { data: { integration } } = await apiRequest.post("/api/v1/integration", { integrationAuthId, @@ -69,7 +71,8 @@ export const useCreateIntegration = () => { owner, path, region, - secretPath + secretPath, + secretSuffix }); return integration; diff --git a/frontend/src/hooks/api/integrations/types.ts b/frontend/src/hooks/api/integrations/types.ts index 5ff2bbac7..89dbfea66 100644 --- a/frontend/src/hooks/api/integrations/types.ts +++ b/frontend/src/hooks/api/integrations/types.ts @@ -27,6 +27,7 @@ export type TIntegration = { integration: string; integrationAuth: string; secretPath: string; + secretSuffix: string; createdAt: string; updatedAt: string; __v: number; diff --git a/frontend/src/pages/integrations/checkly/create.tsx b/frontend/src/pages/integrations/checkly/create.tsx index 7f3b5397b..92d6ae323 100644 --- a/frontend/src/pages/integrations/checkly/create.tsx +++ b/frontend/src/pages/integrations/checkly/create.tsx @@ -35,6 +35,7 @@ export default function ChecklyCreateIntegrationPage() { const [selectedSourceEnvironment, setSelectedSourceEnvironment] = useState(""); const [secretPath, setSecretPath] = useState("/"); + const [secretSuffix, setSecretSuffix] = useState(""); const [targetApp, setTargetApp] = useState(""); const [targetAppId, setTargetAppId] = useState(""); @@ -78,7 +79,8 @@ export default function ChecklyCreateIntegrationPage() { owner: null, path: null, region: null, - secretPath + secretPath, + secretSuffix }); setIsLoading(false); @@ -148,6 +150,13 @@ export default function ChecklyCreateIntegrationPage() { )} + + setSecretSuffix(evt.target.value)} + placeholder="Provide a suffix for secret names, default is no suffix" + /> +