Checkpoint GCP secret manager integration

This commit is contained in:
Tuan Dang
2023-08-25 00:34:46 +07:00
parent 0616f24923
commit ab3533ce1c
10 changed files with 406 additions and 48 deletions
+2
View File
@@ -37,6 +37,7 @@ export const getClientIdNetlify = async () => (await client.getSecret("CLIENT_ID
export const getClientIdGitHub = async () => (await client.getSecret("CLIENT_ID_GITHUB")).secretValue;
export const getClientIdGitLab = async () => (await client.getSecret("CLIENT_ID_GITLAB")).secretValue;
export const getClientIdBitBucket = async () => (await client.getSecret("CLIENT_ID_BITBUCKET")).secretValue;
export const getClientIdGCPSecretManager = async () => (await client.getSecret("CLIENT_ID_GCP_SECRET_MANAGER")).secretValue;
export const getClientSecretAzure = async () => (await client.getSecret("CLIENT_SECRET_AZURE")).secretValue;
export const getClientSecretHeroku = async () => (await client.getSecret("CLIENT_SECRET_HEROKU")).secretValue;
export const getClientSecretVercel = async () => (await client.getSecret("CLIENT_SECRET_VERCEL")).secretValue;
@@ -44,6 +45,7 @@ export const getClientSecretNetlify = async () => (await client.getSecret("CLIEN
export const getClientSecretGitHub = async () => (await client.getSecret("CLIENT_SECRET_GITHUB")).secretValue;
export const getClientSecretGitLab = async () => (await client.getSecret("CLIENT_SECRET_GITLAB")).secretValue;
export const getClientSecretBitBucket = async () => (await client.getSecret("CLIENT_SECRET_BITBUCKET")).secretValue;
export const getClientSecretGCPSecretManager = async () => (await client.getSecret("CLIENT_SECRET_GCP_SECRET_MANAGER")).secretValue;
export const getClientSlugVercel = async () => (await client.getSecret("CLIENT_SLUG_VERCEL")).secretValue;
export const getClientIdGoogleLogin = async () => (await client.getSecret("CLIENT_ID_GOOGLE_LOGIN")).secretValue;
+92
View File
@@ -1,4 +1,6 @@
import {
INTEGRATION_GCP_SECRET_MANAGER,
INTEGRATION_GCP_API_URL,
INTEGRATION_AWS_PARAMETER_STORE,
INTEGRATION_AWS_SECRET_MANAGER,
INTEGRATION_AZURE_KEY_VAULT,
@@ -79,6 +81,11 @@ const getApps = async ({
}) => {
let apps: App[] = [];
switch (integrationAuth.integration) {
case INTEGRATION_GCP_SECRET_MANAGER:
apps = await getAppsGCPSecretManager({
accessToken,
});
break;
case INTEGRATION_AZURE_KEY_VAULT:
apps = [];
break;
@@ -210,6 +217,91 @@ const getApps = async ({
return apps;
};
/**
* Return list of apps for Heroku integration
* @param {Object} obj
* @param {String} obj.accessToken - access token for Heroku API
* @returns {Object[]} apps - names of Heroku apps
* @returns {String} apps.name - name of Heroku app
*/
const getAppsGCPSecretManager = async ({ accessToken }: { accessToken: string }) => {
console.log("getAppsGCPSecretManager");
console.log("getAppsGCPSecretManager accessToken: ", accessToken);
let apps: any = [];
interface GCPApp {
projectNumber: string;
projectId: string;
lifecycleState: "ACTIVE" | "LIFECYCLE_STATE_UNSPECIFIED" | "DELETE_REQUESTED" | "DELETE_IN_PROGRESS";
name: string;
createTime: string;
parent: {
type: "organization" | "folder" | "project";
id: string;
}
}
interface GCPRes {
projects: GCPApp[];
nextPageToken?: string;
}
const pageSize = 10;
let pageToken: string | undefined;
let hasMorePages = true;
while (hasMorePages) {
console.log("iterrr");
const params = new URLSearchParams({
pageSize: String(pageSize),
...(pageToken ? { pageToken } : {})
});
console.log("params: ", params);
const res: GCPRes = (await standardRequest.get(`${INTEGRATION_GCP_API_URL}/v1/projects`, {
params,
headers: {
"Authorization": `Bearer ${accessToken}`,
"Accept-Encoding": "application/json"
}
})
)
.data;
res.projects.forEach((project) => {
apps.push({
name: project.name,
appId: project.projectId
});
});
if (!res.nextPageToken) {
hasMorePages = false;
}
pageToken = res.nextPageToken;
}
// const projects: GCPApp[] = (
// .projects
// console.log("res: ", res);
// .filter((project: GCPApp) => project.lifecycleState === "ACTIVE");
// console.log("projects: ", projects);
// const apps = projects.map((project) => ({
// name: project.name,
// appId: project.projectId
// }));
console.log("apps: ", apps);
return [];
};
/**
* Return list of apps for Heroku integration
* @param {Object} obj
+43
View File
@@ -14,8 +14,12 @@ import {
INTEGRATION_NETLIFY_TOKEN_URL,
INTEGRATION_VERCEL,
INTEGRATION_VERCEL_TOKEN_URL,
INTEGRATION_GCP_SECRET_MANAGER,
INTEGRATION_GCP_TOKEN_URL
} from "../variables";
import {
getClientIdGCPSecretManager,
getClientSecretGCPSecretManager,
getClientIdAzure,
getClientIdBitBucket,
getClientIdGitHub,
@@ -113,6 +117,11 @@ const exchangeCode = async ({
let obj = {} as any;
switch (integration) {
case INTEGRATION_GCP_SECRET_MANAGER:
obj = await exchangeCodeGCP({
code,
});
break;
case INTEGRATION_AZURE_KEY_VAULT:
obj = await exchangeCodeAzure({
code,
@@ -153,6 +162,40 @@ const exchangeCode = async ({
return obj;
};
/**
* Return [accessToken] for GCP OAuth2 code-token exchange
* @param {Object} obj
* @param {String} obj.code - code for code-token exchange
* @returns {Object} obj2
* @returns {String} obj2.accessToken - access token for GCP API
* @returns {String} obj2.refreshToken - refresh token for GCP API
* @returns {Date} obj2.accessExpiresAt - date of expiration for access token
*/
const exchangeCodeGCP = async ({ code }: { code: string }) => {
const accessExpiresAt = new Date();
const res: ExchangeCodeAzureResponse = (
await standardRequest.post(
INTEGRATION_GCP_TOKEN_URL,
new URLSearchParams({
grant_type: "authorization_code",
code: code,
client_id: await getClientIdGCPSecretManager(),
client_secret: await getClientSecretGCPSecretManager(),
redirect_uri: `${await getSiteURL()}/integrations/gcp-secret-manager/oauth2/callback`,
} as any)
)
).data;
accessExpiresAt.setSeconds(accessExpiresAt.getSeconds() + res.expires_in);
return {
accessToken: res.access_token,
refreshToken: res.refresh_token,
accessExpiresAt,
};
};
/**
* Return [accessToken] for Azure OAuth2 code-token exchange
* @param param0
+6 -3
View File
@@ -24,7 +24,8 @@ import {
INTEGRATION_TERRAFORM_CLOUD,
INTEGRATION_TRAVISCI,
INTEGRATION_VERCEL,
INTEGRATION_WINDMILL
INTEGRATION_WINDMILL,
INTEGRATION_GCP_SECRET_MANAGER
} from "../variables";
import { Schema, Types, model } from "mongoose";
@@ -70,7 +71,8 @@ export interface IIntegration {
| "digital-ocean-app-platform"
| "cloud-66"
| "northflank"
| "windmill";
| "windmill"
| "gcp-secret-manager";
integrationAuth: Types.ObjectId;
}
@@ -167,7 +169,8 @@ const integrationSchema = new Schema<IIntegration>(
INTEGRATION_BITBUCKET,
INTEGRATION_DIGITAL_OCEAN_APP_PLATFORM,
INTEGRATION_CLOUD_66,
INTEGRATION_NORTHFLANK
INTEGRATION_NORTHFLANK,
INTEGRATION_GCP_SECRET_MANAGER
],
required: true,
},
+6 -3
View File
@@ -26,7 +26,8 @@ import {
INTEGRATION_TERRAFORM_CLOUD,
INTEGRATION_TRAVISCI,
INTEGRATION_VERCEL,
INTEGRATION_WINDMILL
INTEGRATION_WINDMILL,
INTEGRATION_GCP_SECRET_MANAGER
} from "../variables";
import { Document, Schema, Types, model } from "mongoose";
@@ -58,7 +59,8 @@ export interface IIntegrationAuth extends Document {
| "terraform-cloud"
| "teamcity"
| "northflank"
| "windmill";
| "windmill"
| "gcp-secret-manager";
teamId: string;
accountId: string;
url: string;
@@ -111,7 +113,8 @@ const integrationAuthSchema = new Schema<IIntegrationAuth>(
INTEGRATION_BITBUCKET,
INTEGRATION_DIGITAL_OCEAN_APP_PLATFORM,
INTEGRATION_CLOUD_66,
INTEGRATION_NORTHFLANK
INTEGRATION_NORTHFLANK,
INTEGRATION_GCP_SECRET_MANAGER
],
required: true,
},
+32 -27
View File
@@ -6,12 +6,14 @@ import {
getClientIdHeroku,
getClientIdNetlify,
getClientSlugVercel,
getClientIdGCPSecretManager
} from "../config";
// integrations
export const INTEGRATION_AZURE_KEY_VAULT = "azure-key-vault";
export const INTEGRATION_AWS_PARAMETER_STORE = "aws-parameter-store";
export const INTEGRATION_AWS_SECRET_MANAGER = "aws-secret-manager";
export const INTEGRATION_GCP_SECRET_MANAGER = "gcp-secret-manager";
export const INTEGRATION_HEROKU = "heroku";
export const INTEGRATION_VERCEL = "vercel";
export const INTEGRATION_NETLIFY = "netlify";
@@ -36,35 +38,37 @@ export const INTEGRATION_DIGITAL_OCEAN_APP_PLATFORM = "digital-ocean-app-platfor
export const INTEGRATION_CLOUD_66 = "cloud-66";
export const INTEGRATION_NORTHFLANK = "northflank";
export const INTEGRATION_SET = new Set([
INTEGRATION_GCP_SECRET_MANAGER,
INTEGRATION_AZURE_KEY_VAULT,
INTEGRATION_HEROKU,
INTEGRATION_VERCEL,
INTEGRATION_NETLIFY,
INTEGRATION_GITHUB,
INTEGRATION_GITLAB,
INTEGRATION_RENDER,
INTEGRATION_FLYIO,
INTEGRATION_CIRCLECI,
INTEGRATION_LARAVELFORGE,
INTEGRATION_TRAVISCI,
INTEGRATION_TEAMCITY,
INTEGRATION_SUPABASE,
INTEGRATION_CHECKLY,
INTEGRATION_TERRAFORM_CLOUD,
INTEGRATION_HASHICORP_VAULT,
INTEGRATION_CLOUDFLARE_PAGES,
INTEGRATION_CODEFRESH,
INTEGRATION_WINDMILL,
INTEGRATION_BITBUCKET,
INTEGRATION_DIGITAL_OCEAN_APP_PLATFORM,
INTEGRATION_CLOUD_66,
INTEGRATION_NORTHFLANK
INTEGRATION_HEROKU,
INTEGRATION_VERCEL,
INTEGRATION_NETLIFY,
INTEGRATION_GITHUB,
INTEGRATION_GITLAB,
INTEGRATION_RENDER,
INTEGRATION_FLYIO,
INTEGRATION_CIRCLECI,
INTEGRATION_LARAVELFORGE,
INTEGRATION_TRAVISCI,
INTEGRATION_TEAMCITY,
INTEGRATION_SUPABASE,
INTEGRATION_CHECKLY,
INTEGRATION_TERRAFORM_CLOUD,
INTEGRATION_HASHICORP_VAULT,
INTEGRATION_CLOUDFLARE_PAGES,
INTEGRATION_CODEFRESH,
INTEGRATION_WINDMILL,
INTEGRATION_BITBUCKET,
INTEGRATION_DIGITAL_OCEAN_APP_PLATFORM,
INTEGRATION_CLOUD_66,
INTEGRATION_NORTHFLANK
]);
// integration types
export const INTEGRATION_OAUTH2 = "oauth2";
// integration oauth endpoints
export const INTEGRATION_GCP_TOKEN_URL = "https://accounts.google.com/o/oauth2/token";
export const INTEGRATION_AZURE_TOKEN_URL = "https://login.microsoftonline.com/common/oauth2/v2.0/token";
export const INTEGRATION_HEROKU_TOKEN_URL = "https://id.heroku.com/oauth/token";
export const INTEGRATION_VERCEL_TOKEN_URL =
@@ -76,6 +80,7 @@ export const INTEGRATION_GITLAB_TOKEN_URL = "https://gitlab.com/oauth/token";
export const INTEGRATION_BITBUCKET_TOKEN_URL = "https://bitbucket.org/site/oauth2/access_token"
// integration apps endpoints
export const INTEGRATION_GCP_API_URL = "https://cloudresourcemanager.googleapis.com";
export const INTEGRATION_HEROKU_API_URL = "https://api.heroku.com";
export const INTEGRATION_GITLAB_API_URL = "https://gitlab.com/api";
export const INTEGRATION_VERCEL_API_URL = "https://api.vercel.com";
@@ -272,12 +277,12 @@ export const getIntegrationOptions = async () => {
docsLink: "",
},
{
name: "Google Cloud Platform",
slug: "gcp",
name: "GCP Secret Manager",
slug: "gcp-secret-manager",
image: "Google Cloud Platform.png",
isAvailable: false,
type: "",
clientId: "",
isAvailable: true,
type: "oauth",
clientId: await getClientIdGCPSecretManager(),
docsLink: ""
},
{