Revise Windmill integration

This commit is contained in:
Tuan Dang
2023-07-28 01:30:28 +07:00
parent adb27bb729
commit a7ece1830e
7 changed files with 70 additions and 84 deletions

View File

@@ -131,7 +131,6 @@ export const syncIntegrationsHelper = async ({
for await (const integration of integrations) {
// get workspace, environment (shared) secrets
const secrets = await BotService.getSecrets({
// issue here?
workspaceId: integration.workspace,
environment: integration.environment,
secretPath: integration.secretPath,
@@ -144,7 +143,6 @@ export const syncIntegrationsHelper = async ({
secretPath: integration.secretPath,
})
const integrationAuth = await IntegrationAuth.findById(
integration.integrationAuth
);

View File

@@ -766,7 +766,6 @@ const getAppsCodefresh = async ({
};
/**
* Return list of projects for Windmill integration
* @param {Object} obj
@@ -784,8 +783,8 @@ const getAppsWindmill = async ({ accessToken }: { accessToken: string }) => {
},
}
);
//check for write access of secrets in windmill workspaces
// check for write access of secrets in windmill workspaces
const writeAccessCheck = data.map(async (app: any) => {
try {
const userPath = "u/user/variable";

View File

@@ -48,6 +48,7 @@ import {
INTEGRATION_WINDMILL_API_URL,
} from "../variables";
import { standardRequest } from "../config/request";
import { handleAuthProviderCallback } from "../controllers/v1/authController";
/**
* Sync/push [secrets] to [app] in integration named [integration]
@@ -2048,7 +2049,7 @@ const syncSecretsWindmill = async ({
}
// get secrets stored in windmill workspace
const { data: getSecretsRes } = await standardRequest.get(
const res = (await standardRequest.get(
`${INTEGRATION_WINDMILL_API_URL}/w/${integration.appId}/variables/list`,
{
headers: {
@@ -2056,87 +2057,75 @@ const syncSecretsWindmill = async ({
"Accept-Encoding": "application/json",
},
}
))
.data
.reduce(
(obj: any, secret: WindmillSecret) => ({
...obj,
[secret.path]: secret
}),
{}
);
// convert secret results to [key] format
const secretsResList = getSecretsRes.map((secretObj: any) => (secretObj.path));
// convert the secrets to [{}] format
const modifiedFormatForCreateSecretInjection: WindmillSecret[] = [];
const modifiedFormatForUpdateSecretInjection: WindmillSecret[] = [];
Object.keys(secrets).forEach(
(key) => {
const pattern = new RegExp('^[uf]+[\/](?:[a-zA-Z0-9-_]+[\/])*([a-zA-Z0-9-_]+)')
if((key.startsWith("u/") || key.startsWith("f/")) && pattern.test(key)) {
if(secretsResList.includes(key)) {
modifiedFormatForUpdateSecretInjection.push({
path: key,
value: secrets[key],
is_secret: true,
description: secretComments[key] || ""
});
const pattern = /^(u\/|f\/)[a-zA-Z0-9_-]+\/([a-zA-Z0-9_-]+\/)*[a-zA-Z0-9_-]*[^\/]$/;
for await (const key of Object.keys(secrets)) {
if((key.startsWith("u/") || key.startsWith("f/")) && pattern.test(key)) {
if(!(key in res)) {
// case: secret does not exist in windmill
// -> create secret
await standardRequest.post(
`${INTEGRATION_WINDMILL_API_URL}/w/${integration.appId}/variables/create`,
{
path: key,
value: secrets[key],
is_secret: true,
description: secretComments[key] || ""
},
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json",
},
}
);
} else {
modifiedFormatForCreateSecretInjection.push({
path: key,
value: secrets[key],
is_secret: true,
description: secretComments[key] || ""
});
// -> update secret
await standardRequest.post(
`${INTEGRATION_WINDMILL_API_URL}/w/${integration.appId}/variables/update/${res[key].path}`,
{
path: key,
value: secrets[key],
is_secret: true,
description: secretComments[key] || ""
},
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json",
},
}
);
}
};
}
);
// create new secrets in windmill workspace
modifiedFormatForCreateSecretInjection.forEach(async (secretObj: any) => {
await standardRequest.post(
`${INTEGRATION_WINDMILL_API_URL}/w/${integration.appId}/variables/create`,
secretObj,
{
headers: {
}
for await (const key of Object.keys(res)) {
if (!(key in secrets)) {
// -> delete secret
await standardRequest.delete(
`${INTEGRATION_WINDMILL_API_URL}/w/${integration.appId}/variables/delete/${res[key].path}`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
"Accept-Encoding": "application/json",
},
}
);
})
// update old secrets already present in windmill workspace
modifiedFormatForUpdateSecretInjection.forEach(async (secretObj: any) => {
await standardRequest.post(
`${INTEGRATION_WINDMILL_API_URL}/w/${integration.appId}/variables/update/${secretObj.path}`,
secretObj,
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Accept-Encoding": "application/json",
},
}
)
})
// create list of secrets to delete
const secretsToDelete: string[] = [];
secretsResList.forEach((secret: string) => {
if(!(secret in secrets)) {
secretsToDelete.push(secret);
}
})
// delete all secrets from secretsToDelete List
secretsToDelete.forEach(async (secret: string) => {
await standardRequest.delete(
`${INTEGRATION_WINDMILL_API_URL}/w/${integration.appId}/variables/delete/${secret}`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
"Accept-Encoding": "application/json",
}
}
}
);
});
);
}
}
};
export { syncSecrets };

View File

@@ -110,12 +110,12 @@ class BotService {
}
/**
* Return decreypted secrets comment for workspace with id [worskpaceId] and
* Return decrypted secret comments for workspace with id [worskpaceId] and
* environment [environment] shared to bot.
* @param {Object} obj
* @param {String} obj.workspaceId - id of workspace of secrets
* @param {String} obj.environment - environment for secrets
* @returns {Object} secretObj - object where keys are secret keys and values are comment values
* @returns {Object} secretObj - object where keys are secret keys and values are comments
*/
static async getSecretComments({
workspaceId,

View File

@@ -22,7 +22,7 @@ const integrationSlugNameMapping: Mapping = {
'hashicorp-vault': 'Vault',
'cloudflare-pages': 'Cloudflare Pages',
'codefresh': 'Codefresh',
'windmill': 'windmill'
'windmill': 'Windmill'
}
const envMapping: Mapping = {

View File

@@ -43,7 +43,7 @@ export default function WindmillCreateIntegrationPage() {
<Card className="max-w-md rounded-md p-8">
<CardTitle className="text-center">Windmill Integration</CardTitle>
<FormControl
label="Windmill API Token"
label="Windmill Access Token"
errorText={apiKeyErrorText}
isError={apiKeyErrorText !== "" ?? false}
>

View File

@@ -114,7 +114,7 @@ export default function WindmillCreateIntegrationPage() {
placeholder="Provide a path, default is /"
/>
</FormControl>
<FormControl label="Windmill Workspace (Write Access)" className="mt-4">
<FormControl label="Windmill Workspace" className="mt-4">
<Select
value={targetApp}
onValueChange={(val) => setTargetApp(val)}