mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 15:27:27 +00:00
feat: added 1-N sink import pattern testing and fixed padding issue
This commit is contained in:
@@ -21,14 +21,15 @@ describe("Secret Import Router", async () => {
|
|||||||
expect(payload).toEqual(
|
expect(payload).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
importPath: expect.any(String),
|
importPath,
|
||||||
importEnv: expect.objectContaining({
|
importEnv: expect.objectContaining({
|
||||||
name: expect.any(String),
|
name: expect.any(String),
|
||||||
slug: expect.any(String),
|
slug: importEnv,
|
||||||
id: expect.any(String)
|
id: expect.any(String)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
await deleteSecretImport({
|
await deleteSecretImport({
|
||||||
id: payload.id,
|
id: payload.id,
|
||||||
workspaceId: seedData1.project.id,
|
workspaceId: seedData1.project.id,
|
||||||
@@ -76,10 +77,19 @@ describe("Secret Import Router", async () => {
|
|||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
importPath: expect.any(String),
|
importPath: "/",
|
||||||
importEnv: expect.objectContaining({
|
importEnv: expect.objectContaining({
|
||||||
name: expect.any(String),
|
name: expect.any(String),
|
||||||
slug: expect.any(String),
|
slug: "prod",
|
||||||
|
id: expect.any(String)
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
importPath: "/",
|
||||||
|
importEnv: expect.objectContaining({
|
||||||
|
name: expect.any(String),
|
||||||
|
slug: "staging",
|
||||||
id: expect.any(String)
|
id: expect.any(String)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -219,10 +229,10 @@ describe("Secret Import Router", async () => {
|
|||||||
expect(deletedImport).toEqual(
|
expect(deletedImport).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: expect.any(String),
|
id: expect.any(String),
|
||||||
importPath: expect.any(String),
|
importPath: "/",
|
||||||
importEnv: expect.objectContaining({
|
importEnv: expect.objectContaining({
|
||||||
name: expect.any(String),
|
name: expect.any(String),
|
||||||
slug: expect.any(String),
|
slug: "prod",
|
||||||
id: expect.any(String)
|
id: expect.any(String)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -461,7 +471,7 @@ describe.each([{ path: "/" }, { path: "/deep" }])(
|
|||||||
|
|
||||||
// dev <- stage, dev <- prod
|
// dev <- stage, dev <- prod
|
||||||
describe.each([{ path: "/" }, { path: "/deep" }])(
|
describe.each([{ path: "/" }, { path: "/deep" }])(
|
||||||
"Secret import 1-N pattern testing - %path",
|
"Secret import multiple destination to one source pattern testing - %path",
|
||||||
({ path: testSuitePath }) => {
|
({ path: testSuitePath }) => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
let prodFolder: { id: string };
|
let prodFolder: { id: string };
|
||||||
@@ -635,3 +645,164 @@ describe.each([{ path: "/" }, { path: "/deep" }])(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// dev -> stage, prod
|
||||||
|
describe.each([{ path: "/" }, { path: "/deep" }])(
|
||||||
|
"Secret import one source to multiple destination pattern testing - %path",
|
||||||
|
({ path: testSuitePath }) => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
let prodFolder: { id: string };
|
||||||
|
let stagingFolder: { id: string };
|
||||||
|
let devFolder: { id: string };
|
||||||
|
|
||||||
|
if (testSuitePath !== "/") {
|
||||||
|
prodFolder = await createFolder({
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
environmentSlug: "prod",
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
secretPath: "/",
|
||||||
|
name: "deep"
|
||||||
|
});
|
||||||
|
|
||||||
|
stagingFolder = await createFolder({
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
environmentSlug: "staging",
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
secretPath: "/",
|
||||||
|
name: "deep"
|
||||||
|
});
|
||||||
|
|
||||||
|
devFolder = await createFolder({
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
environmentSlug: seedData1.environment.slug,
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
secretPath: "/",
|
||||||
|
name: "deep"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const stageImportFromDev = await createSecretImport({
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
secretPath: testSuitePath,
|
||||||
|
environmentSlug: "staging",
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
importPath: testSuitePath,
|
||||||
|
importEnv: seedData1.environment.slug
|
||||||
|
});
|
||||||
|
|
||||||
|
const prodImportFromDev = await createSecretImport({
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
secretPath: testSuitePath,
|
||||||
|
environmentSlug: "prod",
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
importPath: testSuitePath,
|
||||||
|
importEnv: seedData1.environment.slug
|
||||||
|
});
|
||||||
|
|
||||||
|
return async () => {
|
||||||
|
await deleteSecretImport({
|
||||||
|
id: prodImportFromDev.id,
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
environmentSlug: "prod",
|
||||||
|
secretPath: testSuitePath,
|
||||||
|
authToken: jwtAuthToken
|
||||||
|
});
|
||||||
|
|
||||||
|
await deleteSecretImport({
|
||||||
|
id: stageImportFromDev.id,
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
environmentSlug: "staging",
|
||||||
|
secretPath: testSuitePath,
|
||||||
|
authToken: jwtAuthToken
|
||||||
|
});
|
||||||
|
|
||||||
|
if (prodFolder) {
|
||||||
|
await deleteFolder({
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
secretPath: "/",
|
||||||
|
id: prodFolder.id,
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
environmentSlug: "prod"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stagingFolder) {
|
||||||
|
await deleteFolder({
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
secretPath: "/",
|
||||||
|
id: stagingFolder.id,
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
environmentSlug: "staging"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devFolder) {
|
||||||
|
await deleteFolder({
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
secretPath: "/",
|
||||||
|
id: devFolder.id,
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
environmentSlug: seedData1.environment.slug
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Check imported secret exist", async () => {
|
||||||
|
await createSecretV2({
|
||||||
|
environmentSlug: seedData1.environment.slug,
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
secretPath: testSuitePath,
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
key: "STAGING_KEY",
|
||||||
|
value: "stage-value"
|
||||||
|
});
|
||||||
|
|
||||||
|
await createSecretV2({
|
||||||
|
environmentSlug: seedData1.environment.slug,
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
secretPath: testSuitePath,
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
key: "PROD_KEY",
|
||||||
|
value: "prod-value"
|
||||||
|
});
|
||||||
|
|
||||||
|
const stagingSecret = await getSecretByNameV2({
|
||||||
|
environmentSlug: "staging",
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
secretPath: testSuitePath,
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
key: "STAGING_KEY"
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(stagingSecret.secretKey).toBe("STAGING_KEY");
|
||||||
|
expect(stagingSecret.secretValue).toBe("stage-value");
|
||||||
|
|
||||||
|
const prodSecret = await getSecretByNameV2({
|
||||||
|
environmentSlug: "prod",
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
secretPath: testSuitePath,
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
key: "PROD_KEY"
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(prodSecret.secretKey).toBe("PROD_KEY");
|
||||||
|
expect(prodSecret.secretValue).toBe("prod-value");
|
||||||
|
|
||||||
|
await deleteSecretV2({
|
||||||
|
environmentSlug: seedData1.environment.slug,
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
secretPath: testSuitePath,
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
key: "STAGING_KEY"
|
||||||
|
});
|
||||||
|
await deleteSecretV2({
|
||||||
|
environmentSlug: seedData1.environment.slug,
|
||||||
|
workspaceId: seedData1.projectV3.id,
|
||||||
|
secretPath: testSuitePath,
|
||||||
|
authToken: jwtAuthToken,
|
||||||
|
key: "PROD_KEY"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|||||||
@@ -399,8 +399,8 @@ export const expandSecretReferencesFactory = ({
|
|||||||
const secrets = await secretDAL.findByFolderId(folder.id);
|
const secrets = await secretDAL.findByFolderId(folder.id);
|
||||||
|
|
||||||
const decryptedSecret = secrets.reduce<Record<string, string>>((prev, secret) => {
|
const decryptedSecret = secrets.reduce<Record<string, string>>((prev, secret) => {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line no-param-reassign
|
||||||
prev[secret.key] = decryptSecret(secret.encryptedValue) || "";
|
prev[secret.key] = decryptSecret(secret.encryptedValue) || "";
|
||||||
return prev;
|
return prev;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
@@ -417,21 +417,23 @@ export const expandSecretReferencesFactory = ({
|
|||||||
|
|
||||||
while (stack.length) {
|
while (stack.length) {
|
||||||
const { value, secretPath, environment, depth } = stack.pop()!;
|
const { value, secretPath, environment, depth } = stack.pop()!;
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line no-continue
|
||||||
if (depth > MAX_SECRET_REFERENCE_DEPTH) continue;
|
if (depth > MAX_SECRET_REFERENCE_DEPTH) continue;
|
||||||
const refs = value?.match(INTERPOLATION_SYNTAX_REG);
|
const refs = value?.match(INTERPOLATION_SYNTAX_REG);
|
||||||
|
|
||||||
if (refs) {
|
if (refs) {
|
||||||
for (const interpolationSyntax of refs) {
|
for (const interpolationSyntax of refs) {
|
||||||
const interpolationKey = interpolationSyntax.slice(2, interpolationSyntax.length - 1);
|
const interpolationKey = interpolationSyntax.slice(2, interpolationSyntax.length - 1);
|
||||||
const entities = interpolationKey.trim().split(".");
|
const entities = interpolationKey.trim().split(".");
|
||||||
// eslint-disable-next-line
|
|
||||||
if (!entities.length) continue;
|
// eslint-disable-next-line no-continue
|
||||||
|
if (!entities.length) continue;
|
||||||
|
|
||||||
if (entities.length === 1) {
|
if (entities.length === 1) {
|
||||||
const [secretKey] = entities;
|
const [secretKey] = entities;
|
||||||
// eslint-disable-next-line
|
|
||||||
const referedValue = await fetchSecret(environment, secretPath, secretKey);
|
// eslint-disable-next-line no-continue,no-await-in-loop
|
||||||
|
const referedValue = await fetchSecret(environment, secretPath, secretKey);
|
||||||
const cacheKey = getCacheUniqueKey(environment, secretPath);
|
const cacheKey = getCacheUniqueKey(environment, secretPath);
|
||||||
secretCache[cacheKey][secretKey] = referedValue;
|
secretCache[cacheKey][secretKey] = referedValue;
|
||||||
if (INTERPOLATION_SYNTAX_REG.test(referedValue)) {
|
if (INTERPOLATION_SYNTAX_REG.test(referedValue)) {
|
||||||
@@ -448,8 +450,8 @@ export const expandSecretReferencesFactory = ({
|
|||||||
const secretReferencePath = path.join("/", ...entities.slice(1, entities.length - 1));
|
const secretReferencePath = path.join("/", ...entities.slice(1, entities.length - 1));
|
||||||
const secretReferenceKey = entities[entities.length - 1];
|
const secretReferenceKey = entities[entities.length - 1];
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line no-await-in-loop
|
||||||
let referedValue = await fetchSecret(secretReferenceEnvironment, secretReferencePath, secretReferenceKey);
|
const referedValue = await fetchSecret(secretReferenceEnvironment, secretReferencePath, secretReferenceKey);
|
||||||
const cacheKey = getCacheUniqueKey(secretReferenceEnvironment, secretReferencePath);
|
const cacheKey = getCacheUniqueKey(secretReferenceEnvironment, secretReferencePath);
|
||||||
secretCache[cacheKey][secretReferenceKey] = referedValue;
|
secretCache[cacheKey][secretReferenceKey] = referedValue;
|
||||||
if (INTERPOLATION_SYNTAX_REG.test(referedValue)) {
|
if (INTERPOLATION_SYNTAX_REG.test(referedValue)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user