diff --git a/backend/src/services/app-connection/humanitec/humanitec-connection-fns.ts b/backend/src/services/app-connection/humanitec/humanitec-connection-fns.ts index 55094629b..0eeb9bfbf 100644 --- a/backend/src/services/app-connection/humanitec/humanitec-connection-fns.ts +++ b/backend/src/services/app-connection/humanitec/humanitec-connection-fns.ts @@ -2,7 +2,6 @@ import { AxiosError, AxiosResponse } from "axios"; import { request } from "@app/lib/config/request"; import { BadRequestError, InternalServerError } from "@app/lib/errors"; -import { logger } from "@app/lib/logger"; import { AppConnection } from "@app/services/app-connection/app-connection-enums"; import { IntegrationUrls } from "@app/services/integration-auth/integration-list"; @@ -73,30 +72,23 @@ export const listOrganizations = async (appConnection: THumanitecConnection): Pr const orgsWithApps: HumanitecOrgWithApps[] = []; for (const org of orgs) { - try { - // eslint-disable-next-line no-await-in-loop - const appsResponse = await request.get( - `${IntegrationUrls.HUMANITEC_API_URL}/orgs/${org.id}/apps`, - { - headers: { - Authorization: `Bearer ${apiToken}` - } - } - ); - - if (appsResponse.data) { - const apps = appsResponse.data; - orgsWithApps.push({ - ...org, - apps: apps.map((app) => ({ - name: app.name, - id: app.id, - envs: app.envs - })) - }); + // eslint-disable-next-line no-await-in-loop + const appsResponse = await request.get(`${IntegrationUrls.HUMANITEC_API_URL}/orgs/${org.id}/apps`, { + headers: { + Authorization: `Bearer ${apiToken}` } - } catch (error) { - logger.error(error, `Failed to get apps for organization ${org.name}`); + }); + + if (appsResponse.data) { + const apps = appsResponse.data; + orgsWithApps.push({ + ...org, + apps: apps.map((app) => ({ + name: app.name, + id: app.id, + envs: app.envs + })) + }); } } return orgsWithApps; diff --git a/backend/src/services/secret-sync/humanitec/humanitec-sync-fns.ts b/backend/src/services/secret-sync/humanitec/humanitec-sync-fns.ts index 5b22572cc..a07d2d0b5 100644 --- a/backend/src/services/secret-sync/humanitec/humanitec-sync-fns.ts +++ b/backend/src/services/secret-sync/humanitec/humanitec-sync-fns.ts @@ -1,4 +1,5 @@ import { request } from "@app/lib/config/request"; +import { logger } from "@app/lib/logger"; import { IntegrationUrls } from "@app/services/integration-auth/integration-list"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; import { SECRET_SYNC_NAME_MAP } from "@app/services/secret-sync/secret-sync-maps"; @@ -39,6 +40,13 @@ const deleteSecret = async (secretSync: THumanitecSyncWithCredentials, encrypted } } = secretSync; + if (destinationConfig.scope === HumanitecSyncScope.Environment && encryptedSecret.source === "app") { + logger.info( + `Humanitec secret ${encryptedSecret.key} on app ${destinationConfig.app} has no environment override, not deleted as it is an app-level secret` + ); + return; + } + try { let url = `${IntegrationUrls.HUMANITEC_API_URL}/orgs/${destinationConfig.org}/apps/${destinationConfig.app}`; if (destinationConfig.scope === HumanitecSyncScope.Environment) { @@ -69,11 +77,12 @@ const createSecret = async (secretSync: THumanitecSyncWithCredentials, secretMap } } = secretSync; + const appLevelSecret = destinationConfig.scope === HumanitecSyncScope.Application ? secretMap[key].value : ""; await request.post( `${IntegrationUrls.HUMANITEC_API_URL}/orgs/${destinationConfig.org}/apps/${destinationConfig.app}/values`, { key, - value: "", + value: appLevelSecret, description: secretMap[key].comment || "", is_secret: true }, diff --git a/docs/api-reference/endpoints/app-connections/humanitec/create.mdx b/docs/api-reference/endpoints/app-connections/humanitec/create.mdx deleted file mode 100644 index 328af9cd9..000000000 --- a/docs/api-reference/endpoints/app-connections/humanitec/create.mdx +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: "Create" -openapi: "POST /api/v1/app-connections/humanitec" ---- - - - Humanitec Connections must be created through the Infisical UI. - Check out the configuration docs for [Humanitec Connections](/integrations/app-connections/humanitec) for a step-by-step - guide. - \ No newline at end of file diff --git a/docs/api-reference/endpoints/app-connections/humanitec/update.mdx b/docs/api-reference/endpoints/app-connections/humanitec/update.mdx deleted file mode 100644 index 023264bb3..000000000 --- a/docs/api-reference/endpoints/app-connections/humanitec/update.mdx +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: "Update" -openapi: "PATCH /api/v1/app-connections/humanitec/{connectionId}" ---- - - - Humanitec Connections must be updated through the Infisical UI. - Check out the configuration docs for [Humanitec Connections](/integrations/app-connections/humanitec) for a step-by-step - guide. - diff --git a/docs/integrations/app-connections/humanitec.mdx b/docs/integrations/app-connections/humanitec.mdx index 14fdd9bfe..570d3ba5d 100644 --- a/docs/integrations/app-connections/humanitec.mdx +++ b/docs/integrations/app-connections/humanitec.mdx @@ -22,8 +22,10 @@ Infisical supports connecting to Humanitec using a service user. Create the API token for the service user. - If you configure an expiry date for your API token you will need to manually rotate to a new token prior to expiration to avoid integration downtime. This token's permission will be limited to the **Service User** role. + + If you configure an expiry date for your API token you will need to manually rotate to a new token prior to expiration to avoid integration downtime. + ![Humanitec Create API Token](/images/app-connections/humanitec/humanitec-create-api-token.png) diff --git a/docs/mint.json b/docs/mint.json index 8f4c22bd1..1796a17df 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -908,8 +908,6 @@ "api-reference/endpoints/app-connections/humanitec/available", "api-reference/endpoints/app-connections/humanitec/get-by-id", "api-reference/endpoints/app-connections/humanitec/get-by-name", - "api-reference/endpoints/app-connections/humanitec/create", - "api-reference/endpoints/app-connections/humanitec/update", "api-reference/endpoints/app-connections/humanitec/delete" ] } diff --git a/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/HumanitecSyncFields.tsx b/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/HumanitecSyncFields.tsx index f6db55693..229f54b01 100644 --- a/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/HumanitecSyncFields.tsx +++ b/frontend/src/components/secret-syncs/forms/SecretSyncDestinationFields/HumanitecSyncFields.tsx @@ -45,58 +45,6 @@ export const HumanitecSyncFields = () => { setValue("destinationConfig.env", ""); }} /> - ( - -

- Specify how Infisical should manage secrets from Humanitec. The following options - are available: -

-
    - {Object.values(HUMANITEC_SYNC_SCOPES).map(({ name, description }) => { - return ( -
  • -

    - {name}: {description} -

    -
  • - ); - })} -
- - } - > - -
- )} - /> { )} /> + ( + +

+ Specify how Infisical should manage secrets from Humanitec. The following options + are available: +

+
    + {Object.values(HUMANITEC_SYNC_SCOPES).map(({ name, description }) => { + return ( +
  • +

    + {name}: {description} +

    +
  • + ); + })} +
+ + } + > + +
+ )} + /> {currentScope === HumanitecSyncScope.Environment && (