mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 06:27:40 +00:00
review fixes
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
// Code generated by automation script, DO NOT EDIT.
|
||||||
|
// Automated by pulling database and generating zod schema
|
||||||
|
// To update. Just run npm run generate:schema
|
||||||
|
// Written by akhilmhdh.
|
||||||
|
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { TImmutableDBKeys } from "./models";
|
||||||
|
|
||||||
|
export const IdentityOciAuthsSchema = z.object({
|
||||||
|
id: z.string().uuid(),
|
||||||
|
accessTokenTTL: z.coerce.number().default(7200),
|
||||||
|
accessTokenMaxTTL: z.coerce.number().default(7200),
|
||||||
|
accessTokenNumUsesLimit: z.coerce.number().default(0),
|
||||||
|
accessTokenTrustedIps: z.unknown(),
|
||||||
|
createdAt: z.date(),
|
||||||
|
updatedAt: z.date(),
|
||||||
|
identityId: z.string().uuid(),
|
||||||
|
type: z.string(),
|
||||||
|
tenancyOcid: z.string(),
|
||||||
|
allowedUsernames: z.string().nullable().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
export type TIdentityOciAuths = z.infer<typeof IdentityOciAuthsSchema>;
|
||||||
|
export type TIdentityOciAuthsInsert = Omit<z.input<typeof IdentityOciAuthsSchema>, TImmutableDBKeys>;
|
||||||
|
export type TIdentityOciAuthsUpdate = Partial<Omit<z.input<typeof IdentityOciAuthsSchema>, TImmutableDBKeys>>;
|
||||||
@@ -117,18 +117,19 @@ export const listOCIVaults = async (appConnection: TOCIConnection, compartmentOc
|
|||||||
export const listOCIVaultKeys = async (appConnection: TOCIConnection, compartmentOcid: string, vaultOcid: string) => {
|
export const listOCIVaultKeys = async (appConnection: TOCIConnection, compartmentOcid: string, vaultOcid: string) => {
|
||||||
const provider = await getOCIProvider(appConnection);
|
const provider = await getOCIProvider(appConnection);
|
||||||
|
|
||||||
const vaultIdMatch = vaultOcid.match(/ocid1\.vault\.[^.]+\.[^.]+\.([^.]+)/);
|
const kmsVaultClient = new keymanagement.KmsVaultClient({
|
||||||
if (!vaultIdMatch || !vaultIdMatch[1]) {
|
authenticationDetailsProvider: provider
|
||||||
throw new BadRequestError({
|
});
|
||||||
message: "Invalid vault OCID format"
|
|
||||||
});
|
const vault = await kmsVaultClient.getVault({
|
||||||
}
|
vaultId: vaultOcid
|
||||||
|
});
|
||||||
|
|
||||||
const keyManagementClient = new keymanagement.KmsManagementClient({
|
const keyManagementClient = new keymanagement.KmsManagementClient({
|
||||||
authenticationDetailsProvider: provider
|
authenticationDetailsProvider: provider
|
||||||
});
|
});
|
||||||
|
|
||||||
keyManagementClient.endpoint = `https://${vaultIdMatch[1].replace(/[^a-zA-Z0-9]/g, "")}-management.kms.${appConnection.credentials.region}.oraclecloud.com`;
|
keyManagementClient.endpoint = vault.vault.managementEndpoint;
|
||||||
|
|
||||||
const keys = await keyManagementClient.listKeys({
|
const keys = await keyManagementClient.listKeys({
|
||||||
compartmentId: compartmentOcid
|
compartmentId: compartmentOcid
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { secrets, vault } from "oci-sdk";
|
import { secrets, vault } from "oci-sdk";
|
||||||
|
|
||||||
|
import { delay } from "@app/lib/delay";
|
||||||
import { getOCIProvider } from "@app/services/app-connection/oci";
|
import { getOCIProvider } from "@app/services/app-connection/oci";
|
||||||
import {
|
import {
|
||||||
TCreateOCIVaultVariable,
|
TCreateOCIVaultVariable,
|
||||||
@@ -121,11 +122,28 @@ export const OCIVaultSyncFns = {
|
|||||||
const provider = await getOCIProvider(connection);
|
const provider = await getOCIProvider(connection);
|
||||||
const variables = await listOCIVaultVariables({ provider, compartmentId: compartmentOcid, vaultId: vaultOcid });
|
const variables = await listOCIVaultVariables({ provider, compartmentId: compartmentOcid, vaultId: vaultOcid });
|
||||||
|
|
||||||
|
// Throw an error if any keys are updating in OCI vault to prevent skipped updates
|
||||||
|
if (
|
||||||
|
Object.entries(variables).some(
|
||||||
|
([, secret]) =>
|
||||||
|
secret.lifecycleState === vault.models.SecretSummary.LifecycleState.Updating ||
|
||||||
|
secret.lifecycleState === vault.models.SecretSummary.LifecycleState.CancellingDeletion ||
|
||||||
|
secret.lifecycleState === vault.models.SecretSummary.LifecycleState.Creating ||
|
||||||
|
secret.lifecycleState === vault.models.SecretSummary.LifecycleState.Deleting ||
|
||||||
|
secret.lifecycleState === vault.models.SecretSummary.LifecycleState.SchedulingDeletion
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new SecretSyncError({
|
||||||
|
error: "Cannot sync while keys are updating in OCI Vault."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Create secrets
|
// Create secrets
|
||||||
for await (const entry of Object.entries(secretMap)) {
|
for await (const entry of Object.entries(secretMap)) {
|
||||||
const [key, { value }] = entry;
|
const [key, { value }] = entry;
|
||||||
|
const existingVariable = Object.values(variables).find((v) => v.secretName === key);
|
||||||
|
|
||||||
if (!Object.values(variables).some((v) => v.secretName === key)) {
|
if (!existingVariable) {
|
||||||
try {
|
try {
|
||||||
await createOCIVaultVariable({
|
await createOCIVaultVariable({
|
||||||
compartmentId: compartmentOcid,
|
compartmentId: compartmentOcid,
|
||||||
@@ -141,27 +159,45 @@ export const OCIVaultSyncFns = {
|
|||||||
secretKey: key
|
secretKey: key
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else if (existingVariable.lifecycleState === vault.models.SecretSummary.LifecycleState.PendingDeletion) {
|
||||||
// If a secret exists but is pending deletion, cancel the deletion and update the secret
|
// If a secret exists but is pending deletion, cancel the deletion and update the secret
|
||||||
const secretPendingDeletion = Object.values(variables).find(
|
await unmarkOCIVaultVariableFromDeletion({
|
||||||
(s) => s.secretName === key && s.lifecycleState === vault.models.SecretSummary.LifecycleState.PendingDeletion
|
provider,
|
||||||
);
|
compartmentId: compartmentOcid,
|
||||||
|
vaultId: vaultOcid,
|
||||||
|
secretId: existingVariable.id
|
||||||
|
});
|
||||||
|
|
||||||
if (secretPendingDeletion) {
|
const vaultsClient = new vault.VaultsClient({ authenticationDetailsProvider: provider });
|
||||||
await unmarkOCIVaultVariableFromDeletion({
|
const MAX_RETRIES = 10;
|
||||||
provider,
|
|
||||||
compartmentId: compartmentOcid,
|
for (let i = 0; i < MAX_RETRIES; i += 1) {
|
||||||
vaultId: vaultOcid,
|
// eslint-disable-next-line no-await-in-loop
|
||||||
secretId: secretPendingDeletion.id
|
await delay(5000);
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
const secret = await vaultsClient.getSecret({
|
||||||
|
secretId: existingVariable.id
|
||||||
});
|
});
|
||||||
|
|
||||||
await updateOCIVaultVariable({
|
if (secret.secret.lifecycleState === vault.models.SecretSummary.LifecycleState.Active) {
|
||||||
provider,
|
// eslint-disable-next-line no-await-in-loop
|
||||||
compartmentId: compartmentOcid,
|
await updateOCIVaultVariable({
|
||||||
vaultId: vaultOcid,
|
provider,
|
||||||
secretId: secretPendingDeletion.id,
|
compartmentId: compartmentOcid,
|
||||||
value
|
vaultId: vaultOcid,
|
||||||
});
|
secretId: existingVariable.id,
|
||||||
|
value
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i === MAX_RETRIES - 1) {
|
||||||
|
throw new SecretSyncError({
|
||||||
|
error: "Failed to update secret after cancelling deletion.",
|
||||||
|
secretKey: key
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,3 +157,21 @@ description: "Learn how to configure an Oracle Cloud Infrastructure Vault Sync f
|
|||||||
```
|
```
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
<AccordionGroup>
|
||||||
|
<Accordion title="How are non-active lifecycle states treated?">
|
||||||
|
When Infisical attempts to sync secrets, the sync will fail and attempt to re-sync if **any secret** has one of the following lifecycle states:
|
||||||
|
- SchedulingDeletion
|
||||||
|
- CancellingDeletion
|
||||||
|
- Deleting
|
||||||
|
- Creating
|
||||||
|
- Updating
|
||||||
|
|
||||||
|
We do this to prevent any desync issues.
|
||||||
|
</Accordion>
|
||||||
|
<Accordion title="What happens if I create / update a variable that's scheduled for deletion in OCI Vault?">
|
||||||
|
In the case that a variable is created or updated while it's scheduled for deletion in OCI Vault, we cancel the deletion and update the variable. This action may take up to a minute since Infisical must wait for OCI to completely cancel the deletion and then update the variable.
|
||||||
|
</Accordion>
|
||||||
|
</AccordionGroup>
|
||||||
|
|||||||
@@ -1,37 +1,33 @@
|
|||||||
import { faHome } from '@fortawesome/free-solid-svg-icons'
|
import { faHome } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import {
|
import { createFileRoute, linkOptions, stripSearchParams } from "@tanstack/react-router";
|
||||||
createFileRoute,
|
import { zodValidator } from "@tanstack/zod-adapter";
|
||||||
linkOptions,
|
import { z } from "zod";
|
||||||
stripSearchParams,
|
|
||||||
} from '@tanstack/react-router'
|
|
||||||
import { zodValidator } from '@tanstack/zod-adapter'
|
|
||||||
import { z } from 'zod'
|
|
||||||
|
|
||||||
import { SettingsPage } from './SettingsPage'
|
import { SettingsPage } from "./SettingsPage";
|
||||||
|
|
||||||
const SettingsPageQueryParams = z.object({
|
const SettingsPageQueryParams = z.object({
|
||||||
selectedTab: z.string().catch(''),
|
selectedTab: z.string().catch("")
|
||||||
})
|
});
|
||||||
|
|
||||||
export const Route = createFileRoute(
|
export const Route = createFileRoute(
|
||||||
'/_authenticate/_inject-org-details/_org-layout/organization/settings/',
|
"/_authenticate/_inject-org-details/_org-layout/organization/settings/"
|
||||||
)({
|
)({
|
||||||
component: SettingsPage,
|
component: SettingsPage,
|
||||||
validateSearch: zodValidator(SettingsPageQueryParams),
|
validateSearch: zodValidator(SettingsPageQueryParams),
|
||||||
search: {
|
search: {
|
||||||
middlewares: [stripSearchParams({ selectedTab: '' })],
|
middlewares: [stripSearchParams({ selectedTab: "" })]
|
||||||
},
|
},
|
||||||
context: () => ({
|
context: () => ({
|
||||||
breadcrumbs: [
|
breadcrumbs: [
|
||||||
{
|
{
|
||||||
label: 'Home',
|
label: "Home",
|
||||||
icon: () => <FontAwesomeIcon icon={faHome} />,
|
icon: () => <FontAwesomeIcon icon={faHome} />,
|
||||||
link: linkOptions({ to: '/' }),
|
link: linkOptions({ to: "/" })
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Settings',
|
label: "Settings"
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
}),
|
})
|
||||||
})
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user