mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Requested changes
This commit is contained in:
@@ -459,10 +459,9 @@ const getAppsFlyio = async ({ accessToken }: { accessToken: string }) => {
|
||||
* Return list of projects for CircleCI integration
|
||||
*/
|
||||
const getAppsCircleCI = async ({ accessToken }: { accessToken: string }) => {
|
||||
// Fetch collaborations (v2 API)
|
||||
const collaborations = (
|
||||
await request.get<{ id: string; name: string; slug: string }[]>(
|
||||
`${IntegrationUrls.CIRCLECI_API_URL}/v2/me/collaborations`,
|
||||
const res = (
|
||||
await request.get<{ reponame: string; username: string; vcs_url: string }[]>(
|
||||
`${IntegrationUrls.CIRCLECI_API_URL}/v1.1/projects`,
|
||||
{
|
||||
headers: {
|
||||
"Circle-Token": accessToken,
|
||||
@@ -472,9 +471,10 @@ const getAppsCircleCI = async ({ accessToken }: { accessToken: string }) => {
|
||||
)
|
||||
).data;
|
||||
|
||||
const apps = collaborations.map((a) => ({
|
||||
name: a.name,
|
||||
appId: a.id
|
||||
const apps = res.map((a) => ({
|
||||
owner: a.username, // username maps to unique organization name in CircleCI
|
||||
name: a.reponame, // reponame maps to project name within an organization in CircleCI
|
||||
appId: a.vcs_url.split("/").pop() // vcs_url maps to the project id in CircleCI
|
||||
}));
|
||||
|
||||
return apps;
|
||||
|
||||
@@ -143,12 +143,6 @@ export type TBitbucketWorkspace = {
|
||||
updated_on: string;
|
||||
};
|
||||
|
||||
export enum CircleCiVcsType {
|
||||
GitHub = "GitHub",
|
||||
CircleCI = "CircleCI",
|
||||
BitBucket = "BitBucket"
|
||||
}
|
||||
|
||||
export type TNorthflankSecretGroup = {
|
||||
id: string;
|
||||
name: string;
|
||||
|
||||
@@ -35,7 +35,7 @@ import { TCreateManySecretsRawFn, TUpdateManySecretsRawFn } from "@app/services/
|
||||
|
||||
import { TIntegrationDALFactory } from "../integration/integration-dal";
|
||||
import { IntegrationMetadataSchema } from "../integration/integration-schema";
|
||||
import { CircleCiVcsType, TIntegrationsWithEnvironment } from "./integration-auth-types";
|
||||
import { TIntegrationsWithEnvironment } from "./integration-auth-types";
|
||||
import {
|
||||
IntegrationInitialSyncBehavior,
|
||||
IntegrationMappingBehavior,
|
||||
@@ -1929,8 +1929,9 @@ const syncSecretsCircleCI = async ({
|
||||
secrets: Record<string, { value: string; comment?: string }>;
|
||||
accessToken: string;
|
||||
}) => {
|
||||
const circleciOrganizationDetail = (
|
||||
await request.get<{ slug: string; name: string }[]>(`${IntegrationUrls.CIRCLECI_API_URL}/v2/me/collaborations`, {
|
||||
let projectSlug: string | null = null;
|
||||
const projectDetails = (
|
||||
await request.get<{ slug: string }>(`${IntegrationUrls.CIRCLECI_API_URL}/v2/project/${integration.appId}`, {
|
||||
headers: {
|
||||
"Circle-Token": accessToken,
|
||||
"Accept-Encoding": "application/json"
|
||||
@@ -1938,30 +1939,7 @@ const syncSecretsCircleCI = async ({
|
||||
})
|
||||
).data;
|
||||
|
||||
let projectSlug: string | null = null;
|
||||
if (!integration.owner) {
|
||||
projectSlug = `${circleciOrganizationDetail[0].slug}/${integration.app}`;
|
||||
} else {
|
||||
const projectDetails = (
|
||||
await request.get<{ vcs_info: { provider: CircleCiVcsType } }>(
|
||||
`${IntegrationUrls.CIRCLECI_API_URL}/v2/project/${integration.app}`,
|
||||
{
|
||||
headers: {
|
||||
"Circle-Token": accessToken,
|
||||
"Accept-Encoding": "application/json"
|
||||
}
|
||||
}
|
||||
)
|
||||
).data;
|
||||
|
||||
const vcsProviderMap: Record<CircleCiVcsType, string> = {
|
||||
[CircleCiVcsType.GitHub]: "gh",
|
||||
[CircleCiVcsType.BitBucket]: "bb",
|
||||
[CircleCiVcsType.CircleCI]: "circleci"
|
||||
};
|
||||
|
||||
projectSlug = `${vcsProviderMap[projectDetails.vcs_info.provider]}/${integration.owner}/${integration.app}`;
|
||||
}
|
||||
projectSlug = `${projectDetails.slug}`;
|
||||
|
||||
// sync secrets to CircleCI
|
||||
await Promise.all(
|
||||
|
||||
@@ -69,7 +69,7 @@ export default function AWSParameterStoreAuthorizeIntegrationPage() {
|
||||
subTitle="After adding the details below, you will be prompted to set up an integration for a particular Infisical project and environment."
|
||||
>
|
||||
<div className="flex flex-row items-center">
|
||||
<div className="inline flex items-center">
|
||||
<div className="flex items-center">
|
||||
<Image
|
||||
src="/images/integrations/Amazon Web Services.png"
|
||||
height={35}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import queryString from "query-string";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { useCreateIntegration } from "@app/hooks/api";
|
||||
|
||||
import {
|
||||
@@ -48,7 +49,7 @@ export default function CircleCICreateIntegrationPage() {
|
||||
const [targetOrganization, setTargetOrganization] = useState("");
|
||||
const [secretPath, setSecretPath] = useState("/");
|
||||
|
||||
const [targetApp, setTargetApp] = useState("");
|
||||
const [targetProjectId, setTargetProjectId] = useState("");
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
@@ -62,18 +63,34 @@ export default function CircleCICreateIntegrationPage() {
|
||||
try {
|
||||
if (!integrationAuth?.id) return;
|
||||
|
||||
if (!targetApp || targetOrganization === "none") return;
|
||||
if (!targetProjectId || targetOrganization === "none") {
|
||||
createNotification({
|
||||
type: "error",
|
||||
text: "Please select a project"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
const selectedApp = integrationAuthApps?.find(
|
||||
(integrationAuthApp) => integrationAuthApp.appId === targetProjectId
|
||||
);
|
||||
|
||||
if (!selectedApp) {
|
||||
createNotification({
|
||||
type: "error",
|
||||
text: "Invalid project selected"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await mutateAsync({
|
||||
integrationAuthId: integrationAuth?.id,
|
||||
isActive: true,
|
||||
app: targetApp,
|
||||
owner: targetOrganization,
|
||||
appId: integrationAuthApps?.find(
|
||||
(integrationAuthApp) => integrationAuthApp.name === targetApp
|
||||
)?.appId,
|
||||
app: selectedApp.name, // project name
|
||||
owner: selectedApp.owner, // organization name
|
||||
appId: selectedApp.appId, // project id (used for syncing)
|
||||
sourceEnvironment: selectedSourceEnvironment,
|
||||
secretPath
|
||||
});
|
||||
@@ -86,6 +103,14 @@ export default function CircleCICreateIntegrationPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const filteredProjects = useMemo(() => {
|
||||
if (!integrationAuthApps) return [];
|
||||
|
||||
return integrationAuthApps.filter((integrationAuthApp) => {
|
||||
return integrationAuthApp.owner === targetOrganization;
|
||||
});
|
||||
}, [integrationAuthApps, targetOrganization]);
|
||||
|
||||
return integrationAuth && workspace && selectedSourceEnvironment && integrationAuthApps ? (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center">
|
||||
<Head>
|
||||
@@ -151,6 +176,7 @@ export default function CircleCICreateIntegrationPage() {
|
||||
value={targetOrganization}
|
||||
onValueChange={(val) => {
|
||||
setTargetOrganization(val);
|
||||
setTargetProjectId("none");
|
||||
}}
|
||||
className="w-full border border-mineshaft-500"
|
||||
isDisabled={integrationAuthApps.length === 0}
|
||||
@@ -158,10 +184,10 @@ export default function CircleCICreateIntegrationPage() {
|
||||
{integrationAuthApps.length > 0 ? (
|
||||
integrationAuthApps.map((integrationAuthApp) => (
|
||||
<SelectItem
|
||||
value={integrationAuthApp.appId!}
|
||||
value={integrationAuthApp.owner!}
|
||||
key={`target-org-${integrationAuthApp.owner}`}
|
||||
>
|
||||
{integrationAuthApp.name}
|
||||
{integrationAuthApp.owner}
|
||||
</SelectItem>
|
||||
))
|
||||
) : (
|
||||
@@ -174,11 +200,26 @@ export default function CircleCICreateIntegrationPage() {
|
||||
|
||||
{targetOrganization && (
|
||||
<FormControl label="CircleCI Project ID" className="px-6">
|
||||
<Input
|
||||
placeholder="55a2071d-97b5-4f71-b285-990d73c41268"
|
||||
value={targetApp}
|
||||
onChange={(evt) => setTargetApp(evt.target.value)}
|
||||
/>
|
||||
<Select
|
||||
value={targetProjectId}
|
||||
onValueChange={(val) => {
|
||||
setTargetProjectId(val);
|
||||
}}
|
||||
className="w-full border border-mineshaft-500"
|
||||
isDisabled={filteredProjects.length === 0}
|
||||
>
|
||||
{filteredProjects.length > 0 ? (
|
||||
filteredProjects.map((project) => (
|
||||
<SelectItem value={project.appId!} key={`target-project-${project.owner}`}>
|
||||
{project.name}
|
||||
</SelectItem>
|
||||
))
|
||||
) : (
|
||||
<SelectItem value="none" key="target-app-none">
|
||||
No projects found
|
||||
</SelectItem>
|
||||
)}
|
||||
</Select>
|
||||
</FormControl>
|
||||
)}
|
||||
<Button
|
||||
|
||||
@@ -99,7 +99,7 @@ export const ConfiguredIntegrationItem = ({
|
||||
<FormLabel
|
||||
label={
|
||||
(integration.integration === "qovery" && integration?.scope) ||
|
||||
(integration.integration === "circleci" && "Project ID") ||
|
||||
(integration.integration === "circleci" && "Project") ||
|
||||
(integration.integration === "aws-secret-manager" && "Secret") ||
|
||||
(["aws-parameter-store", "rundeck"].includes(integration.integration) && "Path") ||
|
||||
(integration?.integration === "terraform-cloud" && "Project") ||
|
||||
@@ -143,6 +143,14 @@ export const ConfiguredIntegrationItem = ({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{integration.integration === "circleci" && integration.owner && (
|
||||
<div className="ml-2">
|
||||
<FormLabel label="Organization" />
|
||||
<div className="rounded-md border border-mineshaft-700 bg-mineshaft-900 px-3 py-2 font-inter text-sm text-bunker-200">
|
||||
{integration.owner}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{integration.integration === "terraform-cloud" && integration.targetService && (
|
||||
<div className="ml-2">
|
||||
<FormLabel label="Category" />
|
||||
|
||||
Reference in New Issue
Block a user