mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-25 14:05:03 +00:00
improvements: address feedback/requests
This commit is contained in:
Binary file not shown.
Before Width: | Height: | Size: 434 KiB After Width: | Height: | Size: 441 KiB |
@ -29,12 +29,18 @@ Prerequisites:
|
||||

|
||||
|
||||
<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.
|
||||
|
||||

|
||||
</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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||

|
||||
|
||||
Save your team changes by clicking on the **Save** button.
|
||||
|
@ -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),
|
||||
|
@ -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 }[];
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
)}
|
||||
|
@ -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")
|
||||
|
@ -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(", ");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
};
|
Reference in New Issue
Block a user