Can specify MAC addresses for domains

This commit is contained in:
2023-12-19 13:26:56 +01:00
parent 6c56b62833
commit 924c972984
9 changed files with 122 additions and 18 deletions

View File

@ -5,6 +5,7 @@ export interface ServerConfig {
local_auth_enabled: boolean;
oidc_auth_enabled: boolean;
iso_mimetypes: string[];
net_mac_prefix: string;
constraints: ServerConstraints;
}

View File

@ -34,10 +34,12 @@ export type VMNetInterface = VMNetUserspaceSLIRPStack | VMNetDefinedNetwork;
export interface VMNetUserspaceSLIRPStack {
type: "UserspaceSLIRPStack";
mac: string;
}
export interface VMNetDefinedNetwork {
type: "DefinedNetwork";
mac: string;
network: string;
}

View File

@ -0,0 +1,11 @@
/**
* Generate a random MAC address
*/
export function randomMacAddress(prefix: string | undefined): string {
let mac = "XX:XX:XX:XX:XX:XX";
mac = prefix + mac.slice(prefix?.length);
return mac.replace(/X/g, () =>
"0123456789abcdef".charAt(Math.floor(Math.random() * 16))
);
}

View File

@ -0,0 +1,46 @@
import { TextInput } from "./TextInput";
export function MACInput(p: {
label: string;
editable: boolean;
value?: string;
onValueChange?: (newVal: string | undefined) => void;
}): React.ReactElement {
const { onValueChange, ...props } = p;
return (
<TextInput
onValueChange={(v) => {
onValueChange?.(sanitizeMacAddress(v));
}}
{...props}
/>
);
}
function sanitizeMacAddress(s: string | undefined): string | undefined {
if (s === "" || s === undefined) return s;
const split = s.split(":");
if (split.length > 6) split.splice(6);
let needAnotherIteration = false;
const res = split
.map((e) => {
if (e === "") return e;
const num = parseInt(e, 16);
if (isNaN(num)) return "0";
let s = num.toString(16).padStart(2, "0");
if (num > 0xff) {
needAnotherIteration = true;
return s.slice(0, 2) + ":" + s.slice(2);
}
return s;
})
.join(":");
return needAnotherIteration ? sanitizeMacAddress(res) : res;
}

View File

@ -14,6 +14,9 @@ import { VMInfo, VMNetInterface } from "../../api/VMApi";
import { useConfirm } from "../../hooks/providers/ConfirmDialogProvider";
import { SelectInput } from "./SelectInput";
import { NetworkInfo } from "../../api/NetworksApi";
import { randomMacAddress } from "../../utils/RandUtils";
import { ServerApi } from "../../api/ServerApi";
import { MACInput } from "./MACInput";
export function VMNetworksList(p: {
vm: VMInfo;
@ -22,7 +25,10 @@ export function VMNetworksList(p: {
networksList: NetworkInfo[];
}): React.ReactElement {
const addNew = () => {
p.vm.networks.push({ type: "UserspaceSLIRPStack" });
p.vm.networks.push({
type: "UserspaceSLIRPStack",
mac: randomMacAddress(ServerApi.Config.net_mac_prefix),
});
p.onChange?.();
};
@ -120,6 +126,16 @@ function NetworkInfoWidget(p: {
/>
</ListItem>
<div style={{ marginLeft: "70px" }}>
<MACInput
editable={p.editable}
label="MAC Address"
value={p.network.mac}
onValueChange={(v) => {
p.network.mac = v!;
p.onChange?.();
}}
/>
{p.network.type === "DefinedNetwork" && (
<SelectInput
editable={p.editable}