Can create NAT networks

This commit is contained in:
2023-12-07 20:03:11 +01:00
parent 5f0f56a9f9
commit 54a3013c59
7 changed files with 210 additions and 12 deletions

@ -1,9 +1,16 @@
import { FormControl, InputLabel, MenuItem, Select } from "@mui/material";
import {
FormControl,
InputLabel,
MenuItem,
Select,
Typography,
} from "@mui/material";
import { TextInput } from "./TextInput";
export interface SelectOption {
value?: string;
label: string;
description?: string;
}
export function SelectInput(p: {
@ -33,7 +40,18 @@ export function SelectInput(p: {
value={e.value}
style={{ fontStyle: e.value === undefined ? "italic" : undefined }}
>
{e.label}
<div>
{e.label}
{e.description && (
<Typography
component={"div"}
variant="caption"
style={{ whiteSpace: "normal" }}
>
{e.description}
</Typography>
)}
</div>
</MenuItem>
))}
</Select>

@ -0,0 +1,116 @@
import { mdiNetworkOutline } from "@mdi/js";
import Icon from "@mdi/react";
import DeleteIcon from "@mui/icons-material/Delete";
import {
Avatar,
Button,
IconButton,
ListItem,
ListItemAvatar,
ListItemText,
Tooltip,
} from "@mui/material";
import { VMInfo, VMNetInterface } from "../../api/VMApi";
import { useConfirm } from "../../hooks/providers/ConfirmDialogProvider";
import { SelectInput } from "./SelectInput";
export function VMNetworksList(p: {
vm: VMInfo;
onChange?: () => void;
editable: boolean;
}): React.ReactElement {
const addNew = () => {
p.vm.networks.push({ type: "UserspaceSLIRPStack" });
p.onChange?.();
};
return (
<>
{/* networks list */}
{p.vm.networks.map((n, num) => (
<NetworkInfo
key={num}
editable={p.editable}
network={n}
onChange={p.onChange}
removeFromList={() => {
p.vm.networks.splice(num, 1);
p.onChange?.();
}}
/>
))}
{p.editable && (
<Button onClick={addNew}>Add a new network interface</Button>
)}
</>
);
}
function NetworkInfo(p: {
editable: boolean;
network: VMNetInterface;
onChange?: () => void;
removeFromList: () => void;
}): React.ReactElement {
const confirm = useConfirm();
const deleteNetwork = async () => {
if (
!(await confirm("Do you really want to remove this network interface?"))
)
return;
p.removeFromList();
p.onChange?.();
};
return (
<div>
<ListItem
secondaryAction={
p.editable && (
<IconButton
edge="end"
aria-label="remove network"
onClick={deleteNetwork}
>
<Tooltip title="Remove network">
<DeleteIcon />
</Tooltip>
</IconButton>
)
}
>
<ListItemAvatar>
<Avatar>
<Icon path={mdiNetworkOutline} />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={
p.editable ? (
<SelectInput
label=""
editable
value={p.network.type}
onValueChange={(v) => {
p.network.type = v as any;
}}
options={[
{
label: "Userspace SLIRP stack",
value: "UserspaceSLIRPStack",
description:
"Provides a virtual LAN with NAT to the outside world. The virtual network has DHCP & DNS services",
},
]}
/>
) : (
p.network.type
)
}
/>
</ListItem>
</div>
);
}