mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat(secret-sync): HC Vault Secret Sync Gateway Support
This commit is contained in:
@@ -1,10 +1,13 @@
|
|||||||
import { isAxiosError } from "axios";
|
import { isAxiosError } from "axios";
|
||||||
|
|
||||||
import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service";
|
import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service";
|
||||||
import { request } from "@app/lib/config/request";
|
|
||||||
import { removeTrailingSlash } from "@app/lib/fn";
|
import { removeTrailingSlash } from "@app/lib/fn";
|
||||||
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
|
import {
|
||||||
import { getHCVaultAccessToken, getHCVaultInstanceUrl } from "@app/services/app-connection/hc-vault";
|
getHCVaultAccessToken,
|
||||||
|
getHCVaultInstanceUrl,
|
||||||
|
requestWithHCVaultGateway,
|
||||||
|
THCVaultConnection
|
||||||
|
} from "@app/services/app-connection/hc-vault";
|
||||||
import {
|
import {
|
||||||
THCVaultListVariables,
|
THCVaultListVariables,
|
||||||
THCVaultListVariablesResponse,
|
THCVaultListVariablesResponse,
|
||||||
@@ -15,19 +18,20 @@ import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors";
|
|||||||
import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns";
|
import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns";
|
||||||
import { TSecretMap } from "@app/services/secret-sync/secret-sync-types";
|
import { TSecretMap } from "@app/services/secret-sync/secret-sync-types";
|
||||||
|
|
||||||
const listHCVaultVariables = async ({ instanceUrl, namespace, mount, accessToken, path }: THCVaultListVariables) => {
|
const listHCVaultVariables = async (
|
||||||
await blockLocalAndPrivateIpAddresses(instanceUrl);
|
{ instanceUrl, namespace, mount, accessToken, path }: THCVaultListVariables,
|
||||||
|
connection: THCVaultConnection,
|
||||||
|
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
const { data } = await request.get<THCVaultListVariablesResponse>(
|
const { data } = await requestWithHCVaultGateway<THCVaultListVariablesResponse>(connection, gatewayService, {
|
||||||
`${instanceUrl}/v1/${removeTrailingSlash(mount)}/data/${path}`,
|
url: `${instanceUrl}/v1/${removeTrailingSlash(mount)}/data/${path}`,
|
||||||
{
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
"X-Vault-Token": accessToken,
|
"X-Vault-Token": accessToken,
|
||||||
...(namespace ? { "X-Vault-Namespace": namespace } : {})
|
...(namespace ? { "X-Vault-Namespace": namespace } : {})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
return data.data.data;
|
return data.data.data;
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
@@ -40,29 +44,21 @@ const listHCVaultVariables = async ({ instanceUrl, namespace, mount, accessToken
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Hashicorp Vault updates all variables in one batch. This is to respect their versioning
|
// Hashicorp Vault updates all variables in one batch. This is to respect their versioning
|
||||||
const updateHCVaultVariables = async ({
|
const updateHCVaultVariables = async (
|
||||||
path,
|
{ path, instanceUrl, namespace, accessToken, mount, data }: TPostHCVaultVariable,
|
||||||
instanceUrl,
|
connection: THCVaultConnection,
|
||||||
namespace,
|
gatewayService: Pick<TGatewayServiceFactory, "fnGetGatewayClientTlsByGatewayId">
|
||||||
accessToken,
|
) => {
|
||||||
mount,
|
return requestWithHCVaultGateway(connection, gatewayService, {
|
||||||
data
|
url: `${instanceUrl}/v1/${removeTrailingSlash(mount)}/data/${path}`,
|
||||||
}: TPostHCVaultVariable) => {
|
method: "POST",
|
||||||
await blockLocalAndPrivateIpAddresses(instanceUrl);
|
headers: {
|
||||||
|
"X-Vault-Token": accessToken,
|
||||||
return request.post(
|
...(namespace ? { "X-Vault-Namespace": namespace } : {}),
|
||||||
`${instanceUrl}/v1/${removeTrailingSlash(mount)}/data/${path}`,
|
"Content-Type": "application/json"
|
||||||
{
|
|
||||||
data
|
|
||||||
},
|
},
|
||||||
{
|
data: { data }
|
||||||
headers: {
|
});
|
||||||
"X-Vault-Token": accessToken,
|
|
||||||
...(namespace ? { "X-Vault-Namespace": namespace } : {}),
|
|
||||||
"Content-Type": "application/json"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const HCVaultSyncFns = {
|
export const HCVaultSyncFns = {
|
||||||
@@ -82,13 +78,17 @@ export const HCVaultSyncFns = {
|
|||||||
const accessToken = await getHCVaultAccessToken(connection, gatewayService);
|
const accessToken = await getHCVaultAccessToken(connection, gatewayService);
|
||||||
const instanceUrl = await getHCVaultInstanceUrl(connection);
|
const instanceUrl = await getHCVaultInstanceUrl(connection);
|
||||||
|
|
||||||
const variables = await listHCVaultVariables({
|
const variables = await listHCVaultVariables(
|
||||||
instanceUrl,
|
{
|
||||||
accessToken,
|
instanceUrl,
|
||||||
namespace,
|
accessToken,
|
||||||
mount,
|
namespace,
|
||||||
path
|
mount,
|
||||||
});
|
path
|
||||||
|
},
|
||||||
|
connection,
|
||||||
|
gatewayService
|
||||||
|
);
|
||||||
let tainted = false;
|
let tainted = false;
|
||||||
|
|
||||||
for (const entry of Object.entries(secretMap)) {
|
for (const entry of Object.entries(secretMap)) {
|
||||||
@@ -115,7 +115,11 @@ export const HCVaultSyncFns = {
|
|||||||
if (!tainted) return;
|
if (!tainted) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateHCVaultVariables({ accessToken, instanceUrl, namespace, mount, path, data: variables });
|
await updateHCVaultVariables(
|
||||||
|
{ accessToken, instanceUrl, namespace, mount, path, data: variables },
|
||||||
|
connection,
|
||||||
|
gatewayService
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new SecretSyncError({
|
throw new SecretSyncError({
|
||||||
error
|
error
|
||||||
@@ -136,7 +140,11 @@ export const HCVaultSyncFns = {
|
|||||||
const accessToken = await getHCVaultAccessToken(connection, gatewayService);
|
const accessToken = await getHCVaultAccessToken(connection, gatewayService);
|
||||||
const instanceUrl = await getHCVaultInstanceUrl(connection);
|
const instanceUrl = await getHCVaultInstanceUrl(connection);
|
||||||
|
|
||||||
const variables = await listHCVaultVariables({ instanceUrl, namespace, accessToken, mount, path });
|
const variables = await listHCVaultVariables(
|
||||||
|
{ instanceUrl, namespace, accessToken, mount, path },
|
||||||
|
connection,
|
||||||
|
gatewayService
|
||||||
|
);
|
||||||
|
|
||||||
for await (const [key] of Object.entries(variables)) {
|
for await (const [key] of Object.entries(variables)) {
|
||||||
if (key in secretMap) {
|
if (key in secretMap) {
|
||||||
@@ -145,7 +153,11 @@ export const HCVaultSyncFns = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await updateHCVaultVariables({ accessToken, instanceUrl, namespace, mount, path, data: variables });
|
await updateHCVaultVariables(
|
||||||
|
{ accessToken, instanceUrl, namespace, mount, path, data: variables },
|
||||||
|
connection,
|
||||||
|
gatewayService
|
||||||
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new SecretSyncError({
|
throw new SecretSyncError({
|
||||||
error
|
error
|
||||||
@@ -165,13 +177,17 @@ export const HCVaultSyncFns = {
|
|||||||
const accessToken = await getHCVaultAccessToken(connection, gatewayService);
|
const accessToken = await getHCVaultAccessToken(connection, gatewayService);
|
||||||
const instanceUrl = await getHCVaultInstanceUrl(connection);
|
const instanceUrl = await getHCVaultInstanceUrl(connection);
|
||||||
|
|
||||||
const variables = await listHCVaultVariables({
|
const variables = await listHCVaultVariables(
|
||||||
instanceUrl,
|
{
|
||||||
namespace,
|
instanceUrl,
|
||||||
accessToken,
|
namespace,
|
||||||
mount,
|
accessToken,
|
||||||
path
|
mount,
|
||||||
});
|
path
|
||||||
|
},
|
||||||
|
connection,
|
||||||
|
gatewayService
|
||||||
|
);
|
||||||
|
|
||||||
return Object.fromEntries(Object.entries(variables).map(([key, value]) => [key, { value }]));
|
return Object.fromEntries(Object.entries(variables).map(([key, value]) => [key, { value }]));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user