improvements: address feedback/requests

This commit is contained in:
Scott Wilson
2024-11-25 16:35:56 -08:00
parent b762816e66
commit b6c05a2f25
11 changed files with 145 additions and 22 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 KiB

After

Width:  |  Height:  |  Size: 441 KiB

View File

@ -29,12 +29,18 @@ Prerequisites:
![integrations octopus deploy
generate api key](/images/integrations/octopus-deploy/integrations-octopus-deploy-generate-api-key.png)
<Note>If you configure your access token to expire,
you will need to generate a new API key for Infisical prior to this date to keep your integration running.</Note>
Copy the generated **API Key** and click on the **Close** button.
![integrations octopus deploy
copy api key](/images/integrations/octopus-deploy/integrations-octopus-deploy-copy-api-key.png)
</Step>
<Step title="Create a Service Accounts Team and assign your Service Account">
<Note>You can skip creating a new team if you already have an Octopus Deploy team configured with
the **Project Contributor** role to assign your Service Account to.</Note>
Navigate to **Configuration** > **Teams** and click on the **Add Team** button.
![integrations octopus deploy
@ -47,7 +53,8 @@ Prerequisites:
On the **Members** tab, click on the **Add Member** button, add your **Infisical Service Account** and click on the **Add** button.
![integrations octopus deploy add service account to team](/images/integrations/octopus-deploy/integrations-octopus-deploy-add-to-team.png)
On the **User Roles** tab, click on the **Include User Role** button, add the **Project Contributor** role and click on the **Apply** button.
On the **User Roles** tab, click on the **Include User Role** button, and add the **Project Contributor** role. Optionally,
click on the **Define Scope** button to further refine what projects your Service Account has access to. Click on the **Apply** button once complete.
![integrations octopus deploy add user roles to team](/images/integrations/octopus-deploy/integrations-octopus-deploy-add-role.png)
Save your team changes by clicking on the **Save** button.

View File

@ -19,7 +19,7 @@ import {
Team,
TeamCityBuildConfig,
TGetIntegrationAuthOctopusDeployScopeValuesDTO,
TOctopusDeployScopeValues
TOctopusDeployVariableSetScopeValues
} from "./types";
const integrationAuthKeys = {
@ -503,7 +503,7 @@ const fetchIntegrationAuthOctopusDeployScopeValues = async ({
spaceId,
resourceId
}: TGetIntegrationAuthOctopusDeployScopeValuesDTO) => {
const { data } = await apiRequest.get<TOctopusDeployScopeValues>(
const { data } = await apiRequest.get<TOctopusDeployVariableSetScopeValues>(
`/api/v1/integration-auth/${integrationAuthId}/octopus-deploy/scope-values`,
{ params: { scope, spaceId, resourceId } }
);
@ -799,14 +799,18 @@ export const useGetIntegrationAuthBitBucketWorkspaces = (integrationAuthId: stri
export const useGetIntegrationAuthOctopusDeploySpaces = (integrationAuthId: string) => {
return useQuery({
queryKey: integrationAuthKeys.getIntegrationAuthBitBucketWorkspaces(integrationAuthId),
queryKey: integrationAuthKeys.getIntegrationAuthOctopusDeploySpaces(integrationAuthId),
queryFn: () => fetchIntegrationAuthOctopusDeploySpaces(integrationAuthId)
});
};
export const useGetIntegrationAuthOctopusDeployScopeValues = (
params: TGetIntegrationAuthOctopusDeployScopeValuesDTO,
options?: UseQueryOptions<TOctopusDeployScopeValues, unknown, TOctopusDeployScopeValues>
options?: UseQueryOptions<
TOctopusDeployVariableSetScopeValues,
unknown,
TOctopusDeployVariableSetScopeValues
>
) =>
useQuery({
queryKey: integrationAuthKeys.getIntegrationAuthOctopusDeployScopeValues(params),

View File

@ -112,7 +112,7 @@ export type TGetIntegrationAuthOctopusDeployScopeValuesDTO = {
scope: OctopusDeployScope;
};
export type TOctopusDeployScopeValues = {
export type TOctopusDeployVariableSetScopeValues = {
Environments: { Id: string; Name: string }[];
Machines: { Id: string; Name: string }[];
Actions: { Id: string; Name: string }[];

View File

@ -4,7 +4,7 @@ import { createNotification } from "@app/components/notifications";
import { apiRequest } from "@app/config/request";
import { workspaceKeys } from "../workspace";
import { TCloudIntegration, TIntegrationWithEnv } from "./types";
import { TCloudIntegration, TIntegrationWithEnv, TOctopusDeployScopeValues } from "./types";
export const integrationQueryKeys = {
getIntegrations: () => ["integrations"] as const,
@ -87,14 +87,7 @@ export const useCreateIntegration = () => {
shouldMaskSecrets?: boolean;
shouldProtectSecrets?: boolean;
shouldEnableDelete?: boolean;
octopusDeployScopeValues?: {
Environment?: string[];
Action?: string[];
Channel?: string[];
Machine?: string[];
ProcessOwner?: string[];
Role?: string[];
};
octopusDeployScopeValues?: TOctopusDeployScopeValues;
};
}) => {
const {

View File

@ -57,9 +57,20 @@ export type TIntegration = {
shouldMaskSecrets?: boolean;
shouldProtectSecrets?: boolean;
shouldEnableDelete?: boolean;
octopusDeployScopeValues?: TOctopusDeployScopeValues;
};
};
export type TOctopusDeployScopeValues = {
Environment?: string[];
Action?: string[];
Channel?: string[];
Machine?: string[];
ProcessOwner?: string[];
Role?: string[];
};
export type TIntegrationWithEnv = TIntegration & {
environment: {
id: string;

View File

@ -69,7 +69,7 @@ export default function OctopusDeployIntegrationPage() {
src="/images/integrations/Octopus Deploy.png"
height={30}
width={30}
alt="Databricks logo"
alt="Octopus Deploy logo"
/>
</div>
<span className="ml-1.5">Octopus Deploy Integration</span>

View File

@ -12,9 +12,9 @@ import {
CardTitle,
FilterableSelect,
FormControl,
Input,
Spinner
} from "@app/components/v2";
import { SecretPathInput } from "@app/components/v2/SecretPathInput";
import { useWorkspace } from "@app/context";
import { useCreateIntegration, useGetIntegrationAuthApps } from "@app/hooks/api";
import {
@ -63,6 +63,7 @@ export default function OctopusDeployCreateIntegrationPage() {
const currentSpace = watch("targetSpace", octopusDeploySpaces?.[0]);
const currentScope = watch("scope");
const sourceEnv = watch("sourceEnvironment");
const { data: octopusDeployResources, isLoading: isOctopusDeployResourcesLoading } =
useGetIntegrationAuthApps(
@ -195,11 +196,11 @@ export default function OctopusDeployCreateIntegrationPage() {
name="secretPath"
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl isError={Boolean(error)} label="Secrets Path">
<Input
className="mt-[1px] h-[2.46rem]"
<SecretPathInput
placeholder="/"
environment={sourceEnv?.slug}
value={value}
onChange={onChange}
placeholder={'Provide a path (defaults to "/")'}
/>
</FormControl>
)}

View File

@ -55,6 +55,8 @@ export const IntegrationConnectionSection = ({ integration }: Props) => {
return "Path";
case "bitbucket":
return "Repository";
case "octopus-deploy":
return "Project";
case "github":
if (["github-env", "github-repo"].includes(integration.scope!)) {
return "Repository";
@ -104,6 +106,16 @@ export const IntegrationConnectionSection = ({ integration }: Props) => {
</div>
);
}
if (integration.integration === "octopus-deploy") {
return (
<div>
<FormLabel className="text-sm font-semibold text-mineshaft-300" label="Space" />
<div className="text-sm text-mineshaft-300">{integration.targetEnvironment}</div>
</div>
);
}
if (
["vercel", "netlify", "railway", "gitlab", "teamcity"].includes(integration.integration) ||
(integration.integration === "github" && integration.scope === "github-env")

View File

@ -1,4 +1,5 @@
import { TIntegrationWithEnv } from "@app/hooks/api/integrations/types";
import { OctopusDeployScopeValues } from "@app/views/IntegrationsPage/IntegrationDetailsPage/components/OctopusDeployScopeValues";
type Props = {
integration: TIntegrationWithEnv;
@ -26,13 +27,17 @@ const metadataMappings: Record<keyof NonNullable<TIntegrationWithEnv["metadata"]
shouldDisableDelete: "AWS Secret Deletion Disabled",
shouldMaskSecrets: "GitLab Secrets Masking Enabled",
shouldProtectSecrets: "GitLab Secret Protection Enabled",
shouldEnableDelete: "GitHub Secret Deletion Enabled"
shouldEnableDelete: "GitHub Secret Deletion Enabled",
octopusDeployScopeValues: "Octopus Deploy Scope Values"
} as const;
export const IntegrationSettingsSection = ({ integration }: Props) => {
const renderValue = <K extends MetadataKey>(key: K, value: MetadataValue<K>) => {
if (!value) return null;
if (key === "octopusDeployScopeValues")
return <OctopusDeployScopeValues integration={integration} />;
// If it's a boolean, we render a generic "Yes" or "No" response.
if (typeof value === "boolean") {
return value ? "Yes" : "No";
@ -49,7 +54,7 @@ export const IntegrationSettingsSection = ({ integration }: Props) => {
}
if (key === "githubVisibilityRepoIds") {
return value.join(", ");
return (value as string[]).join(", ");
}
}

View File

@ -0,0 +1,90 @@
import { FormLabel, Spinner } from "@app/components/v2";
import { useGetIntegrationAuthOctopusDeployScopeValues } from "@app/hooks/api/integrationAuth/queries";
import {
OctopusDeployScope,
TOctopusDeployVariableSetScopeValues
} from "@app/hooks/api/integrationAuth/types";
import { TIntegration, TOctopusDeployScopeValues } from "@app/hooks/api/integrations/types";
type OctopusDeployScopeValuesProps = {
integration: TIntegration;
};
// remove plural since Octopus Deploy can decide whether they want to use singular or plural...
const modifyKey = (key: keyof TOctopusDeployVariableSetScopeValues) => {
switch (key) {
case "Processes":
return "ProcessOwner";
default:
return key.substring(0, key.length - 1);
}
};
export const OctopusDeployScopeValues = ({ integration }: OctopusDeployScopeValuesProps) => {
const hasScopeValues = Boolean(
Object.values(integration.metadata?.octopusDeployScopeValues ?? {}).some(
(values) => values.length > 0
)
);
const { data: scopeValues = {}, isLoading } = useGetIntegrationAuthOctopusDeployScopeValues(
{
scope: OctopusDeployScope.Project,
spaceId: integration.targetEnvironmentId!,
resourceId: integration.appId!,
integrationAuthId: integration.integrationAuthId
},
{
enabled: hasScopeValues
}
);
if (!integration.metadata?.octopusDeployScopeValues)
return <span className="text-sm text-mineshaft-400">Not Configured</span>;
if (isLoading) return <Spinner size="sm" className="mt-2 ml-2" />;
const scopeValuesMap = new Map(
Object.entries(scopeValues).map(([key, values]) => [
modifyKey(key as keyof TOctopusDeployVariableSetScopeValues),
new Map((values as { Name: string; Id: string }[]).map((value) => [value.Id, value.Name]))
])
);
return (
<>
{Object.entries(integration.metadata.octopusDeployScopeValues).map(([key, values]) => {
if (!values.length) return null;
const getLabel = (scope: string) => {
switch (scope as keyof TOctopusDeployScopeValues) {
case "Role":
return "Target Tags";
case "Machine":
return "Targets";
case "ProcessOwner":
return "Processes";
case "Action":
return "Steps";
default:
return `${scope}s`;
}
};
return (
<div className="mt-4" key={key}>
<FormLabel className="text-sm font-semibold text-mineshaft-200" label={getLabel(key)} />
<div className="text-sm text-mineshaft-300">
{values
.map((value) => scopeValuesMap.get(key)?.get(value)!)
.map((name) => (
<p key={name}>{name}</p>
))}
</div>
</div>
);
})}
</>
);
};