mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 15:40:47 +00:00
Support for namespaces (for HCP)
This commit is contained in:
@@ -1860,6 +1860,7 @@ export const AppConnections = {
|
||||
},
|
||||
HC_VAULT: {
|
||||
instanceUrl: "The Hashicrop Vault instance URL to connect with.",
|
||||
namespace: "The Hashicrop Vault namespace to connect with.",
|
||||
accessToken: "The access token used to connect with Hashicorp Vault.",
|
||||
roleId: "The Role ID used to connect with Hashicorp Vault.",
|
||||
secretId: "The Secret ID used to connect with Hashicorp Vault."
|
||||
|
||||
@@ -49,7 +49,12 @@ export const getHCVaultAccessToken = async (connection: TValidateHCVaultConnecti
|
||||
const tokenResp = await request.post<TokenRespData>(
|
||||
`${removeTrailingSlash(instanceUrl)}/v1/auth/approle/login`,
|
||||
{ role_id: roleId, secret_id: secretId },
|
||||
{ headers: { "Content-Type": "application/json" } }
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...(connection.credentials.namespace ? { "X-Vault-Namespace": connection.credentials.namespace } : {})
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (tokenResp.status !== 200) {
|
||||
@@ -95,7 +100,10 @@ export const listHCVaultMounts = async (appConnection: THCVaultConnection) => {
|
||||
const accessToken = await getHCVaultAccessToken(appConnection);
|
||||
|
||||
const { data } = await request.get<THCVaultMountResponse>(`${instanceUrl}/v1/sys/mounts`, {
|
||||
headers: { "X-Vault-Token": accessToken }
|
||||
headers: {
|
||||
"X-Vault-Token": accessToken,
|
||||
...(appConnection.credentials.namespace ? { "X-Vault-Namespace": appConnection.credentials.namespace } : {})
|
||||
}
|
||||
});
|
||||
|
||||
const mounts: string[] = [];
|
||||
|
||||
@@ -17,8 +17,11 @@ const InstanceUrlSchema = z
|
||||
.url("Invalid Instance URL")
|
||||
.describe(AppConnections.CREDENTIALS.HC_VAULT.instanceUrl);
|
||||
|
||||
const NamespaceSchema = z.string().trim().optional().describe(AppConnections.CREDENTIALS.HC_VAULT.namespace);
|
||||
|
||||
export const HCVaultConnectionAccessTokenCredentialsSchema = z.object({
|
||||
instanceUrl: InstanceUrlSchema,
|
||||
namespace: NamespaceSchema,
|
||||
accessToken: z
|
||||
.string()
|
||||
.trim()
|
||||
@@ -28,6 +31,7 @@ export const HCVaultConnectionAccessTokenCredentialsSchema = z.object({
|
||||
|
||||
export const HCVaultConnectionAppRoleCredentialsSchema = z.object({
|
||||
instanceUrl: InstanceUrlSchema,
|
||||
namespace: NamespaceSchema,
|
||||
roleId: z.string().trim().min(1, "Role ID required").describe(AppConnections.CREDENTIALS.HC_VAULT.roleId),
|
||||
secretId: z.string().trim().min(1, "Secret ID required").describe(AppConnections.CREDENTIALS.HC_VAULT.secretId)
|
||||
});
|
||||
|
||||
@@ -10,12 +10,13 @@ import {
|
||||
import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors";
|
||||
import { TSecretMap } from "@app/services/secret-sync/secret-sync-types";
|
||||
|
||||
const listHCVaultVariables = async ({ instanceUrl, mount, accessToken, path }: THCVaultListVariables) => {
|
||||
const listHCVaultVariables = async ({ instanceUrl, namespace, mount, accessToken, path }: THCVaultListVariables) => {
|
||||
const { data } = await request.get<THCVaultListVariablesResponse>(
|
||||
`${instanceUrl}/v1/${removeTrailingSlash(mount)}/data/${path}`,
|
||||
{
|
||||
headers: {
|
||||
"X-Vault-Token": accessToken
|
||||
"X-Vault-Token": accessToken,
|
||||
...(namespace ? { "X-Vault-Namespace": namespace } : {})
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -24,7 +25,14 @@ const listHCVaultVariables = async ({ instanceUrl, mount, accessToken, path }: T
|
||||
};
|
||||
|
||||
// Hashicorp Vault updates all variables in one batch. This is to respect their versioning
|
||||
const updateHCVaultVariables = async ({ path, instanceUrl, accessToken, mount, data }: TPostHCVaultVariable) =>
|
||||
const updateHCVaultVariables = async ({
|
||||
path,
|
||||
instanceUrl,
|
||||
namespace,
|
||||
accessToken,
|
||||
mount,
|
||||
data
|
||||
}: TPostHCVaultVariable) =>
|
||||
request.post(
|
||||
`${instanceUrl}/v1/${removeTrailingSlash(mount)}/data/${path}`,
|
||||
{
|
||||
@@ -33,6 +41,7 @@ const updateHCVaultVariables = async ({ path, instanceUrl, accessToken, mount, d
|
||||
{
|
||||
headers: {
|
||||
"X-Vault-Token": accessToken,
|
||||
...(namespace ? { "X-Vault-Namespace": namespace } : {}),
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
@@ -46,10 +55,17 @@ export const HCVaultSyncFns = {
|
||||
syncOptions: { disableSecretDeletion }
|
||||
} = secretSync;
|
||||
|
||||
const { namespace } = connection.credentials;
|
||||
const accessToken = await getHCVaultAccessToken(connection);
|
||||
const instanceUrl = await getHCVaultInstanceUrl(connection);
|
||||
|
||||
const variables = await listHCVaultVariables({ instanceUrl, accessToken, mount, path });
|
||||
const variables = await listHCVaultVariables({
|
||||
instanceUrl,
|
||||
accessToken,
|
||||
namespace,
|
||||
mount,
|
||||
path
|
||||
});
|
||||
let tainted = false;
|
||||
|
||||
for (const entry of Object.entries(secretMap)) {
|
||||
@@ -73,7 +89,7 @@ export const HCVaultSyncFns = {
|
||||
if (!tainted) return;
|
||||
|
||||
try {
|
||||
await updateHCVaultVariables({ accessToken, instanceUrl, mount, path, data: variables });
|
||||
await updateHCVaultVariables({ accessToken, instanceUrl, namespace, mount, path, data: variables });
|
||||
} catch (error) {
|
||||
throw new SecretSyncError({
|
||||
error
|
||||
@@ -86,10 +102,11 @@ export const HCVaultSyncFns = {
|
||||
destinationConfig: { mount, path }
|
||||
} = secretSync;
|
||||
|
||||
const { namespace } = connection.credentials;
|
||||
const accessToken = await getHCVaultAccessToken(connection);
|
||||
const instanceUrl = await getHCVaultInstanceUrl(connection);
|
||||
|
||||
const variables = await listHCVaultVariables({ instanceUrl, accessToken, mount, path });
|
||||
const variables = await listHCVaultVariables({ instanceUrl, namespace, accessToken, mount, path });
|
||||
|
||||
for await (const [key] of Object.entries(variables)) {
|
||||
if (key in secretMap) {
|
||||
@@ -98,7 +115,7 @@ export const HCVaultSyncFns = {
|
||||
}
|
||||
|
||||
try {
|
||||
await updateHCVaultVariables({ accessToken, instanceUrl, mount, path, data: variables });
|
||||
await updateHCVaultVariables({ accessToken, instanceUrl, namespace, mount, path, data: variables });
|
||||
} catch (error) {
|
||||
throw new SecretSyncError({
|
||||
error
|
||||
@@ -111,11 +128,13 @@ export const HCVaultSyncFns = {
|
||||
destinationConfig: { mount, path }
|
||||
} = secretSync;
|
||||
|
||||
const { namespace } = connection.credentials;
|
||||
const accessToken = await getHCVaultAccessToken(connection);
|
||||
const instanceUrl = await getHCVaultInstanceUrl(connection);
|
||||
|
||||
const variables = await listHCVaultVariables({
|
||||
instanceUrl,
|
||||
namespace,
|
||||
accessToken,
|
||||
mount,
|
||||
path
|
||||
|
||||
@@ -25,6 +25,7 @@ export type THCVaultListVariablesResponse = {
|
||||
export type THCVaultListVariables = {
|
||||
accessToken: string;
|
||||
instanceUrl: string;
|
||||
namespace?: string;
|
||||
mount: string;
|
||||
path: string;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user