Skip to content

Commit

Permalink
feat: Adds input validation to network slices and device groups (#241)
Browse files Browse the repository at this point in the history
  • Loading branch information
gruyaume authored Dec 7, 2023
1 parent a032634 commit 17d377f
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 18 deletions.
48 changes: 36 additions & 12 deletions components/DeviceGroupModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import * as Yup from "yup";
import { useFormik } from "formik";

const regexIp =
/^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)$/;
/^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)$/;

const regexpCIDR =
/^((25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\/([1-9]|[1-2][0-9]|3[0-2])$/;
/^((25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\/([1-9]|[1-2][0-9]|3[0-2])$/;

interface DeviceGroupValues {
name: string;
Expand All @@ -39,14 +39,28 @@ const DeviceGroupModal = ({
const [apiError, setApiError] = useState<string | null>(null);

const DeviceGroupSchema = Yup.object().shape({
name: Yup.string().min(1).max(20, "Name should not exceed 20 characters.")
.matches(/^[a-zA-Z0-9-_]+$/, { message: 'Only alphanumeric characters, dashes and underscores.'})
name: Yup.string()
.min(1)
.max(20, "Name should not exceed 20 characters.")
.matches(/^[a-zA-Z0-9-_]+$/, {
message: "Only alphanumeric characters, dashes and underscores.",
})
.required("Name is required."),
ueIpPool: Yup.string().required("IP is required").matches(regexpCIDR, "Invalid IP Address Pool."),
dns: Yup.string().required("IP is required").matches(regexIp, "Invalid IP Address."),
ueIpPool: Yup.string()
.required("IP is required")
.matches(regexpCIDR, "Invalid IP Address Pool."),
dns: Yup.string()
.required("IP is required")
.matches(regexIp, "Invalid IP Address."),
mtu: Yup.number().min(1200).max(65535).required("Invalid MTU."),
MBRDownstreamMbps: Yup.number().min(0).max(1000000).required("Value should be between 0 and 1,000,000."),
MBRUpstreamMbps: Yup.number().min(0).max(1000000).required("Value should be between 0 and 1,000,000."),
MBRDownstreamMbps: Yup.number()
.min(0)
.max(1000000)
.required("Value should be between 0 and 1,000,000."),
MBRUpstreamMbps: Yup.number()
.min(0)
.max(1000000)
.required("Value should be between 0 and 1,000,000."),
});

const formik = useFormik<DeviceGroupValues>({
Expand Down Expand Up @@ -76,7 +90,9 @@ const DeviceGroupModal = ({
toggleModal();
} catch (error) {
console.error(error);
setApiError("Failed to create device group.");
setApiError(
(error as Error).message || "An unexpected error occurred.",
);
}
},
});
Expand All @@ -88,7 +104,7 @@ const DeviceGroupModal = ({
buttonRow={
<ActionButton
appearance="positive"
className="mt-8 u-no-margin--bottom"
className="u-no-margin--bottom mt-8"
onClick={formik.submitForm}
disabled={!(formik.isValid && formik.dirty)}
loading={formik.isSubmitting}
Expand Down Expand Up @@ -153,7 +169,11 @@ const DeviceGroupModal = ({
required
label="Downstream"
{...formik.getFieldProps("MBRDownstreamMbps")}
error={formik.touched.MBRDownstreamMbps ? formik.errors.MBRDownstreamMbps : null}
error={
formik.touched.MBRDownstreamMbps
? formik.errors.MBRDownstreamMbps
: null
}
/>
<Input
placeholder="5"
Expand All @@ -163,7 +183,11 @@ const DeviceGroupModal = ({
required
label="Upstream"
{...formik.getFieldProps("MBRUpstreamMbps")}
error={formik.touched.MBRUpstreamMbps ? formik.errors.MBRUpstreamMbps : null}
error={
formik.touched.MBRUpstreamMbps
? formik.errors.MBRUpstreamMbps
: null
}
/>
</fieldset>
</Form>
Expand Down
3 changes: 2 additions & 1 deletion pages/api/device-group/[name].ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ async function handleGET(req: NextApiRequest, res: NextApiResponse) {
});

if (!response.ok) {
throw new Error(`Error getting device group. Error code: ${response.status}`);
res.status(response.status).json({ error: "Error retrieving network slice." });
return;
}

const data = await response.json();
Expand Down
5 changes: 2 additions & 3 deletions pages/api/network-slice/[name].ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ async function handleGET(req: NextApiRequest, res: NextApiResponse) {


if (!response.ok) {
throw new Error(
`Error getting network slice. Error code: ${response.status}`
);
res.status(response.status).json({ error: "Error retrieving network slice." });
return;
}

const data = await response.json();
Expand Down
19 changes: 17 additions & 2 deletions utils/createDeviceGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ export const createDeviceGroup = async ({
};

try {
const checkResponse = await fetch(`/api/device-group/${name}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});

if (checkResponse.ok) {
throw new Error("Device group already exists");
}

const response = await fetch(`/api/device-group/${name}`, {
method: "POST",
headers: {
Expand Down Expand Up @@ -91,8 +102,12 @@ export const createDeviceGroup = async ({
}

return true;
} catch (error) {
} catch (error: unknown) {
console.error(error);
throw new Error("Failed to create device group.");
const details =
error instanceof Error
? error.message
: "Failed to configure the network.";
throw new Error(details);
}
};
11 changes: 11 additions & 0 deletions utils/createNetworkSlice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ export const createNetworkSlice = async ({
};

try {
const checkResponse = await fetch(`/api/network-slice/${name}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});

if (checkResponse.ok) {
throw new Error("Network slice already exists");
}

const networksliceResponse = await fetch(`/api/network-slice/${name}`, {
method: "POST",
headers: {
Expand Down

0 comments on commit 17d377f

Please sign in to comment.