Can define IP reservations for networks
This commit is contained in:
		
							
								
								
									
										141
									
								
								virtweb_frontend/src/widgets/net/DHCPHostReservations.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								virtweb_frontend/src/widgets/net/DHCPHostReservations.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
			
		||||
import { mdiIp } from "@mdi/js";
 | 
			
		||||
import Icon from "@mdi/react";
 | 
			
		||||
import DeleteIcon from "@mui/icons-material/Delete";
 | 
			
		||||
import {
 | 
			
		||||
  Avatar,
 | 
			
		||||
  Button,
 | 
			
		||||
  IconButton,
 | 
			
		||||
  ListItem,
 | 
			
		||||
  ListItemAvatar,
 | 
			
		||||
  ListItemText,
 | 
			
		||||
  Paper,
 | 
			
		||||
  Tooltip,
 | 
			
		||||
} from "@mui/material";
 | 
			
		||||
import { DHCPConfig, DHCPHost } from "../../api/NetworksApi";
 | 
			
		||||
import { ServerApi } from "../../api/ServerApi";
 | 
			
		||||
import { useConfirm } from "../../hooks/providers/ConfirmDialogProvider";
 | 
			
		||||
import { IPInput } from "../forms/IPInput";
 | 
			
		||||
import { MACInput } from "../forms/MACInput";
 | 
			
		||||
import { TextInput } from "../forms/TextInput";
 | 
			
		||||
 | 
			
		||||
export function DHCPHostReservations(p: {
 | 
			
		||||
  editable: boolean;
 | 
			
		||||
  dhcp: DHCPConfig;
 | 
			
		||||
  version: 4 | 6;
 | 
			
		||||
  onChange?: (d: DHCPConfig) => void;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  const addHost = () => {
 | 
			
		||||
    p.dhcp.hosts.push({
 | 
			
		||||
      ip: p.version === 4 ? "192.168.1.30" : "fd00::b200",
 | 
			
		||||
      name: "host",
 | 
			
		||||
      mac: p.version === 4 ? "00:00:00:00:00:00" : undefined,
 | 
			
		||||
    });
 | 
			
		||||
    p.onChange?.(p.dhcp);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      {p.dhcp.hosts.map((h, num) => (
 | 
			
		||||
        <HostReservationWidget
 | 
			
		||||
          key={num}
 | 
			
		||||
          {...p}
 | 
			
		||||
          onChange={() => {
 | 
			
		||||
            p.onChange?.(p.dhcp);
 | 
			
		||||
          }}
 | 
			
		||||
          host={h}
 | 
			
		||||
          onRemove={() => {
 | 
			
		||||
            p.dhcp.hosts.splice(num, 1);
 | 
			
		||||
            p.onChange?.(p.dhcp);
 | 
			
		||||
          }}
 | 
			
		||||
        />
 | 
			
		||||
      ))}
 | 
			
		||||
 | 
			
		||||
      {p.editable && (
 | 
			
		||||
        <Button onClick={addHost}>Add new host reservation</Button>
 | 
			
		||||
      )}
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function HostReservationWidget(p: {
 | 
			
		||||
  editable: boolean;
 | 
			
		||||
  host: DHCPHost;
 | 
			
		||||
  version: 4 | 6;
 | 
			
		||||
  onChange: () => void;
 | 
			
		||||
  onRemove: () => void;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  const confirm = useConfirm();
 | 
			
		||||
  const deleteReservation = async () => {
 | 
			
		||||
    if (
 | 
			
		||||
      !(await confirm("Do you really want to remove this host IP reservation?"))
 | 
			
		||||
    )
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
    p.onRemove();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Paper elevation={3} style={{ padding: "10px", marginTop: "20px" }}>
 | 
			
		||||
      <ListItem
 | 
			
		||||
        secondaryAction={
 | 
			
		||||
          p.editable && (
 | 
			
		||||
            <IconButton
 | 
			
		||||
              edge="end"
 | 
			
		||||
              aria-label="remove network"
 | 
			
		||||
              onClick={deleteReservation}
 | 
			
		||||
            >
 | 
			
		||||
              <Tooltip title="Remove host IP allocation">
 | 
			
		||||
                <DeleteIcon />
 | 
			
		||||
              </Tooltip>
 | 
			
		||||
            </IconButton>
 | 
			
		||||
          )
 | 
			
		||||
        }
 | 
			
		||||
      >
 | 
			
		||||
        <ListItemAvatar>
 | 
			
		||||
          <Avatar>
 | 
			
		||||
            <Icon path={mdiIp} />
 | 
			
		||||
          </Avatar>
 | 
			
		||||
        </ListItemAvatar>
 | 
			
		||||
        <ListItemText
 | 
			
		||||
          primary={
 | 
			
		||||
            <TextInput
 | 
			
		||||
              editable={p.editable}
 | 
			
		||||
              label="Host name"
 | 
			
		||||
              value={p.host.name}
 | 
			
		||||
              onValueChange={(v) => {
 | 
			
		||||
                p.host.name = v!;
 | 
			
		||||
                p.onChange();
 | 
			
		||||
              }}
 | 
			
		||||
              type="text"
 | 
			
		||||
              size={ServerApi.Config.constraints.dhcp_reservation_host_name}
 | 
			
		||||
            />
 | 
			
		||||
          }
 | 
			
		||||
        />
 | 
			
		||||
      </ListItem>
 | 
			
		||||
      <div style={{ marginLeft: "70px" }}>
 | 
			
		||||
        {p.version === 4 && (
 | 
			
		||||
          <MACInput
 | 
			
		||||
            editable={p.editable}
 | 
			
		||||
            label="MAC Address"
 | 
			
		||||
            value={p.host.mac}
 | 
			
		||||
            onValueChange={(v) => {
 | 
			
		||||
              p.host.mac = v!;
 | 
			
		||||
              p.onChange?.();
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
        )}
 | 
			
		||||
 | 
			
		||||
        <IPInput
 | 
			
		||||
          editable={p.editable}
 | 
			
		||||
          label="IP address"
 | 
			
		||||
          version={p.version}
 | 
			
		||||
          value={p.host.ip}
 | 
			
		||||
          onValueChange={(v) => {
 | 
			
		||||
            p.host.ip = v!;
 | 
			
		||||
            p.onChange?.();
 | 
			
		||||
          }}
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
    </Paper>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import { Checkbox, Grid } from "@mui/material";
 | 
			
		||||
import { Checkbox, Grid, Paper } from "@mui/material";
 | 
			
		||||
import React from "react";
 | 
			
		||||
import { IpConfig, NetworkApi, NetworkInfo } from "../../api/NetworksApi";
 | 
			
		||||
import { ServerApi } from "../../api/ServerApi";
 | 
			
		||||
@@ -10,6 +10,7 @@ import { TextInput } from "../forms/TextInput";
 | 
			
		||||
import { useConfirm } from "../../hooks/providers/ConfirmDialogProvider";
 | 
			
		||||
import { CheckboxInput } from "../forms/CheckboxInput";
 | 
			
		||||
import { ResAutostartInput } from "../forms/ResAutostartInput";
 | 
			
		||||
import { DHCPHostReservations } from "./DHCPHostReservations";
 | 
			
		||||
 | 
			
		||||
interface DetailsProps {
 | 
			
		||||
  net: NetworkInfo;
 | 
			
		||||
@@ -239,44 +240,59 @@ function IPSection(p: {
 | 
			
		||||
          />
 | 
			
		||||
 | 
			
		||||
          <CheckboxInput
 | 
			
		||||
            checked={!!p.config.dhcp_range}
 | 
			
		||||
            checked={!!p.config.dhcp}
 | 
			
		||||
            editable={p.editable}
 | 
			
		||||
            label="Enable DHCP"
 | 
			
		||||
            onValueChange={(v) => {
 | 
			
		||||
              if (v)
 | 
			
		||||
                p.config!.dhcp_range =
 | 
			
		||||
                p.config!.dhcp =
 | 
			
		||||
                  p.version === 4
 | 
			
		||||
                    ? ["192.168.1.100", "192.168.1.200"]
 | 
			
		||||
                    : ["fd00::100", "fd00::f00"];
 | 
			
		||||
              else p.config!.dhcp_range = undefined;
 | 
			
		||||
                    ? {
 | 
			
		||||
                        start: "192.168.1.100",
 | 
			
		||||
                        end: "192.168.1.200",
 | 
			
		||||
                        hosts: [],
 | 
			
		||||
                      }
 | 
			
		||||
                    : { start: "fd00::100", end: "fd00::f00", hosts: [] };
 | 
			
		||||
              else p.config!.dhcp = undefined;
 | 
			
		||||
              p.onChange?.(p.config);
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
        </>
 | 
			
		||||
      )}
 | 
			
		||||
 | 
			
		||||
      {p.config?.dhcp_range && (
 | 
			
		||||
      {p.config?.dhcp && (
 | 
			
		||||
        <>
 | 
			
		||||
          <IPInput
 | 
			
		||||
            label="DHCP allocation start"
 | 
			
		||||
            editable={p.editable}
 | 
			
		||||
            version={p.version}
 | 
			
		||||
            value={p.config.dhcp_range[0]}
 | 
			
		||||
            onValueChange={(v) => {
 | 
			
		||||
              p.config!.dhcp_range![0] = v!;
 | 
			
		||||
              p.onChange(p.config);
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
          <IPInput
 | 
			
		||||
            label="DHCP allocation end"
 | 
			
		||||
            editable={p.editable}
 | 
			
		||||
            version={p.version}
 | 
			
		||||
            value={p.config.dhcp_range[1]}
 | 
			
		||||
            onValueChange={(v) => {
 | 
			
		||||
              p.config!.dhcp_range![1] = v!;
 | 
			
		||||
              p.onChange(p.config);
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
          <Paper elevation={3} style={{ padding: "10px" }}>
 | 
			
		||||
            <IPInput
 | 
			
		||||
              label="DHCP allocation start"
 | 
			
		||||
              editable={p.editable}
 | 
			
		||||
              version={p.version}
 | 
			
		||||
              value={p.config.dhcp.start}
 | 
			
		||||
              onValueChange={(v) => {
 | 
			
		||||
                p.config!.dhcp!.start = v!;
 | 
			
		||||
                p.onChange(p.config);
 | 
			
		||||
              }}
 | 
			
		||||
            />
 | 
			
		||||
            <IPInput
 | 
			
		||||
              label="DHCP allocation end"
 | 
			
		||||
              editable={p.editable}
 | 
			
		||||
              version={p.version}
 | 
			
		||||
              value={p.config.dhcp.end}
 | 
			
		||||
              onValueChange={(v) => {
 | 
			
		||||
                p.config!.dhcp!.end = v!;
 | 
			
		||||
                p.onChange(p.config);
 | 
			
		||||
              }}
 | 
			
		||||
            />
 | 
			
		||||
 | 
			
		||||
            <DHCPHostReservations
 | 
			
		||||
              {...p}
 | 
			
		||||
              dhcp={p.config.dhcp}
 | 
			
		||||
              onChange={(d) => {
 | 
			
		||||
                p.config!.dhcp = d;
 | 
			
		||||
                p.onChange?.(p.config);
 | 
			
		||||
              }}
 | 
			
		||||
            />
 | 
			
		||||
          </Paper>
 | 
			
		||||
        </>
 | 
			
		||||
      )}
 | 
			
		||||
    </EditSection>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user