mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 21:51:56 +00:00
Merge pull request #2713 from scott-ray-wilson/bitbucket-integration-additions
Feature: Add Support for Deployment Environment Scope for Bitbucket Integration
This commit is contained in:
@@ -891,6 +891,48 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider)
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/:integrationAuthId/bitbucket/environments",
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
schema: {
|
||||
params: z.object({
|
||||
integrationAuthId: z.string().trim()
|
||||
}),
|
||||
querystring: z.object({
|
||||
workspaceSlug: z.string().trim().min(1, { message: "Workspace slug required" }),
|
||||
repoSlug: z.string().trim().min(1, { message: "Repo slug required" })
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
environments: z
|
||||
.object({
|
||||
name: z.string(),
|
||||
slug: z.string(),
|
||||
uuid: z.string(),
|
||||
type: z.string()
|
||||
})
|
||||
.array()
|
||||
})
|
||||
}
|
||||
},
|
||||
handler: async (req) => {
|
||||
const environments = await server.services.integrationAuth.getBitbucketEnvironments({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
id: req.params.integrationAuthId,
|
||||
workspaceSlug: req.query.workspaceSlug,
|
||||
repoSlug: req.query.repoSlug
|
||||
});
|
||||
return { environments };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/:integrationAuthId/northflank/secret-groups",
|
||||
|
||||
@@ -20,6 +20,7 @@ import { getApps } from "./integration-app-list";
|
||||
import { TIntegrationAuthDALFactory } from "./integration-auth-dal";
|
||||
import { IntegrationAuthMetadataSchema, TIntegrationAuthMetadata } from "./integration-auth-schema";
|
||||
import {
|
||||
TBitbucketEnvironment,
|
||||
TBitbucketWorkspace,
|
||||
TChecklyGroups,
|
||||
TDeleteIntegrationAuthByIdDTO,
|
||||
@@ -30,6 +31,7 @@ import {
|
||||
THerokuPipelineCoupling,
|
||||
TIntegrationAuthAppsDTO,
|
||||
TIntegrationAuthAwsKmsKeyDTO,
|
||||
TIntegrationAuthBitbucketEnvironmentsDTO,
|
||||
TIntegrationAuthBitbucketWorkspaceDTO,
|
||||
TIntegrationAuthChecklyGroupsDTO,
|
||||
TIntegrationAuthGithubEnvsDTO,
|
||||
@@ -1261,6 +1263,55 @@ export const integrationAuthServiceFactory = ({
|
||||
return workspaces;
|
||||
};
|
||||
|
||||
const getBitbucketEnvironments = async ({
|
||||
workspaceSlug,
|
||||
repoSlug,
|
||||
actorId,
|
||||
actor,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
id
|
||||
}: TIntegrationAuthBitbucketEnvironmentsDTO) => {
|
||||
const integrationAuth = await integrationAuthDAL.findById(id);
|
||||
if (!integrationAuth) throw new NotFoundError({ message: `Integration auth with ID '${id}' not found` });
|
||||
|
||||
const { permission } = await permissionService.getProjectPermission(
|
||||
actor,
|
||||
actorId,
|
||||
integrationAuth.projectId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
|
||||
const { shouldUseSecretV2Bridge, botKey } = await projectBotService.getBotKey(integrationAuth.projectId);
|
||||
const { accessToken } = await getIntegrationAccessToken(integrationAuth, shouldUseSecretV2Bridge, botKey);
|
||||
const environments: TBitbucketEnvironment[] = [];
|
||||
let hasNextPage = true;
|
||||
|
||||
let environmentsUrl = `${IntegrationUrls.BITBUCKET_API_URL}/2.0/repositories/${workspaceSlug}/${repoSlug}/environments`;
|
||||
|
||||
while (hasNextPage) {
|
||||
// eslint-disable-next-line
|
||||
const { data }: { data: { values: TBitbucketEnvironment[]; next: string } } = await request.get(environmentsUrl, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
"Accept-Encoding": "application/json"
|
||||
}
|
||||
});
|
||||
|
||||
if (data?.values.length > 0) {
|
||||
environments.push(...data.values);
|
||||
}
|
||||
|
||||
if (data.next) {
|
||||
environmentsUrl = data.next;
|
||||
} else {
|
||||
hasNextPage = false;
|
||||
}
|
||||
}
|
||||
return environments;
|
||||
};
|
||||
|
||||
const getNorthFlankSecretGroups = async ({
|
||||
id,
|
||||
actor,
|
||||
@@ -1499,6 +1550,7 @@ export const integrationAuthServiceFactory = ({
|
||||
getNorthFlankSecretGroups,
|
||||
getTeamcityBuildConfigs,
|
||||
getBitbucketWorkspaces,
|
||||
getBitbucketEnvironments,
|
||||
getIntegrationAccessToken,
|
||||
duplicateIntegrationAuth
|
||||
};
|
||||
|
||||
@@ -99,6 +99,12 @@ export type TIntegrationAuthBitbucketWorkspaceDTO = {
|
||||
id: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TIntegrationAuthBitbucketEnvironmentsDTO = {
|
||||
workspaceSlug: string;
|
||||
repoSlug: string;
|
||||
id: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TIntegrationAuthNorthflankSecretGroupDTO = {
|
||||
id: string;
|
||||
appId: string;
|
||||
@@ -148,6 +154,13 @@ export type TBitbucketWorkspace = {
|
||||
updated_on: string;
|
||||
};
|
||||
|
||||
export type TBitbucketEnvironment = {
|
||||
type: string;
|
||||
uuid: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
};
|
||||
|
||||
export type TNorthflankSecretGroup = {
|
||||
id: string;
|
||||
name: string;
|
||||
|
||||
@@ -334,7 +334,7 @@ export const getIntegrationOptions = async () => {
|
||||
docsLink: ""
|
||||
},
|
||||
{
|
||||
name: "BitBucket",
|
||||
name: "Bitbucket",
|
||||
slug: "bitbucket",
|
||||
image: "BitBucket.png",
|
||||
isAvailable: true,
|
||||
|
||||
@@ -3631,7 +3631,14 @@ const syncSecretsBitBucket = async ({
|
||||
const res: { [key: string]: BitbucketVariable } = {};
|
||||
|
||||
let hasNextPage = true;
|
||||
let variablesUrl = `${IntegrationUrls.BITBUCKET_API_URL}/2.0/repositories/${integration.targetEnvironmentId}/${integration.appId}/pipelines_config/variables`;
|
||||
|
||||
const rootUrl = integration.targetServiceId
|
||||
? // scope: deployment environment
|
||||
`${IntegrationUrls.BITBUCKET_API_URL}/2.0/repositories/${integration.targetEnvironmentId}/${integration.appId}/deployments_config/environments/${integration.targetServiceId}/variables`
|
||||
: // scope: repository
|
||||
`${IntegrationUrls.BITBUCKET_API_URL}/2.0/repositories/${integration.targetEnvironmentId}/${integration.appId}/pipelines_config/variables`;
|
||||
|
||||
let variablesUrl = rootUrl;
|
||||
|
||||
while (hasNextPage) {
|
||||
const { data }: { data: VariablesResponse } = await request.get(variablesUrl, {
|
||||
@@ -3658,7 +3665,7 @@ const syncSecretsBitBucket = async ({
|
||||
if (key in res) {
|
||||
// update existing secret
|
||||
await request.put(
|
||||
`${variablesUrl}/${res[key].uuid}`,
|
||||
`${rootUrl}/${res[key].uuid}`,
|
||||
{
|
||||
key,
|
||||
value: secrets[key].value,
|
||||
@@ -3674,7 +3681,7 @@ const syncSecretsBitBucket = async ({
|
||||
} else {
|
||||
// create new secret
|
||||
await request.post(
|
||||
variablesUrl,
|
||||
rootUrl,
|
||||
{
|
||||
key,
|
||||
value: secrets[key].value,
|
||||
|
||||
Reference in New Issue
Block a user