Merge branch 'main' into feat/addGroupsToSshHosts

This commit is contained in:
carlosmonastyrski
2025-05-05 14:51:01 -03:00
393 changed files with 17201 additions and 2453 deletions
@@ -27,6 +27,7 @@ import {
useListWorkspaceSshHosts,
useUpdateSshHost
} from "@app/hooks/api";
import { LoginMappingSource } from "@app/hooks/api/sshHost/types";
import { UsePopUpState } from "@app/hooks/usePopUp";
type Props = {
@@ -56,7 +57,8 @@ const schema = z
value: z.string().trim().min(1)
})
)
.default([])
.default([]),
source: z.nativeEnum(LoginMappingSource)
})
.array()
.default([])
@@ -108,7 +110,7 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
hostname: sshHost.hostname,
alias: sshHost.alias ?? "",
userCertTtl: sshHost.userCertTtl,
loginMappings: sshHost.loginMappings.map(({ loginUser, allowedPrincipals }) => ({
loginMappings: sshHost.loginMappings.map(({ loginUser, allowedPrincipals, source }) => ({
loginUser,
allowedPrincipals: [
...(allowedPrincipals.usernames || []).map((username) => ({
@@ -119,7 +121,8 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
type: "group" as const,
value: group
}))
]
],
source
}))
});
@@ -140,6 +143,11 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
try {
if (!projectId) return;
// Filter out login mappings that are from host groups
const hostLoginMappings = loginMappings.filter(
(mapping) => mapping.source === LoginMappingSource.HOST
);
// check if there is already a different host with the same hostname
const existingHostnames =
sshHosts?.filter((h) => h.id !== sshHost?.id).map((h) => h.hostname) || [];
@@ -169,7 +177,7 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
}
}
const transformedLoginMappings = loginMappings.map(({ loginUser, allowedPrincipals }) => {
const transformedLoginMappings = hostLoginMappings.map(({ loginUser, allowedPrincipals }) => {
const usernames = allowedPrincipals
.filter((p) => p.type === "user" && p.value)
.map((p) => p.value);
@@ -300,7 +308,11 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
variant="outline_bg"
onClick={() => {
const newIndex = loginMappingsFormFields.fields.length;
loginMappingsFormFields.append({ loginUser: "", allowedPrincipals: [] });
loginMappingsFormFields.append({
loginUser: "",
allowedPrincipals: [],
source: LoginMappingSource.HOST
});
setExpandedMappings((prev) => ({
...prev,
[newIndex]: true
@@ -333,6 +345,12 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
render={({ field }) => (
<span className="text-sm font-medium leading-tight">
{field.value || "New Login Mapping"}
{loginMappingsFormFields.fields[i].source ===
LoginMappingSource.HOST_GROUP && (
<span className="ml-2 text-xs text-mineshaft-400">
(inherited from host group)
</span>
)}
</span>
)}
/>
@@ -341,6 +359,9 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
ariaLabel="delete login mapping"
variant="plain"
onClick={() => loginMappingsFormFields.remove(i)}
isDisabled={
loginMappingsFormFields.fields[i].source === LoginMappingSource.HOST_GROUP
}
>
<FontAwesomeIcon icon={faTrash} />
</IconButton>
@@ -362,11 +383,24 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
<Input
{...field}
placeholder="ec2-user"
isDisabled={
loginMappingsFormFields.fields[i].source ===
LoginMappingSource.HOST_GROUP
}
onChange={(e) => {
if (
loginMappingsFormFields.fields[i].source ===
LoginMappingSource.HOST_GROUP
)
return;
const newValue = e.target.value;
const loginMappings = getValues("loginMappings");
const isDuplicate = loginMappings.some(
(mapping, index) => index !== i && mapping.loginUser === newValue
(mapping, index) =>
index !== i &&
mapping.loginUser === newValue &&
mapping.source === LoginMappingSource.HOST
);
if (isDuplicate) {
@@ -390,20 +424,23 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
label="Allowed Principals"
className="text-xs text-mineshaft-400"
/>
<Button
leftIcon={<FontAwesomeIcon icon={faPlus} />}
size="xs"
variant="outline_bg"
onClick={() => {
const current = getValues(`loginMappings.${i}.allowedPrincipals`) ?? [];
setValue(`loginMappings.${i}.allowedPrincipals`, [
...current,
{ type: "user", value: "" }
]);
}}
>
Add Principal
</Button>
{loginMappingsFormFields.fields[i].source === LoginMappingSource.HOST && (
<Button
leftIcon={<FontAwesomeIcon icon={faPlus} />}
size="xs"
variant="outline_bg"
onClick={() => {
const current =
getValues(`loginMappings.${i}.allowedPrincipals`) ?? [];
setValue(`loginMappings.${i}.allowedPrincipals`, [
...current,
{ type: "user", value: "" }
]);
}}
>
Add Principal
</Button>
)}
</div>
<Controller
control={control}
@@ -427,6 +464,10 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
};
onChange(newPrincipals);
}}
isDisabled={
loginMappingsFormFields.fields[i].source ===
LoginMappingSource.HOST_GROUP
}
>
<SelectItem value="user">User</SelectItem>
<SelectItem value="group">Group</SelectItem>
@@ -436,6 +477,11 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
<Select
value={principal.value}
onValueChange={(newValue) => {
if (
loginMappingsFormFields.fields[i].source ===
LoginMappingSource.HOST_GROUP
)
return;
if (isPrincipalDuplicate(i, principal.type, newValue)) {
createNotification({
text: `This ${principal.type} is already added`,
@@ -452,6 +498,10 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
}}
placeholder={`Select a ${principal.type}`}
className="w-full"
isDisabled={
loginMappingsFormFields.fields[i].source ===
LoginMappingSource.HOST_GROUP
}
>
{principal.type === "user"
? members.map((member) => (
@@ -479,11 +529,21 @@ export const SshHostModal = ({ popUp, handlePopUpToggle }: Props) => {
variant="plain"
className="h-9"
onClick={() => {
if (
loginMappingsFormFields.fields[i].source ===
LoginMappingSource.HOST_GROUP
)
return;
const newPrincipals = value.filter(
(_, idx) => idx !== principalIndex
);
onChange([...newPrincipals]);
}}
isDisabled={
loginMappingsFormFields.fields[i].source ===
LoginMappingSource.HOST_GROUP
}
>
<FontAwesomeIcon icon={faTrash} />
</IconButton>