Skip to content

Commit

Permalink
fix(instance): add name length check for instance name (creation/edit)
Browse files Browse the repository at this point in the history
Signed-off-by: lorumic <michele.lorusso@canonical.com>

Signed-off-by: lorumic <michele.lorusso@canonical.com>
  • Loading branch information
lorumic committed Apr 18, 2024
1 parent cfb9f91 commit ee2fd13
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 31 deletions.
17 changes: 2 additions & 15 deletions src/pages/instances/CreateInstance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
import { queryKeys } from "util/queryKeys";
import { LxdImageType, RemoteImage } from "types/image";
import { isContainerOnlyImage, isVmOnlyImage, LOCAL_ISO } from "util/images";
import { checkDuplicateName } from "util/helpers";
import { dump as dumpYaml } from "js-yaml";
import { yamlToObject } from "util/yaml";
import { Link, useLocation, useNavigate, useParams } from "react-router-dom";
Expand Down Expand Up @@ -75,6 +74,7 @@ import {
import FormFooterLayout from "components/forms/FormFooterLayout";
import { useToastNotification } from "context/toastNotificationProvider";
import { useDocs } from "context/useDocs";
import { instanceNameValidation } from "util/instances";

export type CreateInstanceFormValues = InstanceDetailsFormValues &
FormDeviceValues &
Expand Down Expand Up @@ -109,20 +109,7 @@ const CreateInstance: FC = () => {
}

const InstanceSchema = Yup.object().shape({
name: Yup.string()
.test(
"deduplicate",
"An instance with this name already exists",
(value) =>
checkDuplicateName(value, project, controllerState, "instances"),
)
.matches(/^[A-Za-z0-9-]+$/, {
message: "Only alphanumeric and hyphen characters are allowed",
})
.matches(/^[A-Za-z].*$/, {
message: "Instance name must start with a letter",
})
.optional(),
name: instanceNameValidation(project, controllerState).optional(),
instanceType: Yup.string().required("Instance type is required"),
});

Expand Down
20 changes: 4 additions & 16 deletions src/pages/instances/InstanceDetailHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { renameInstance } from "api/instances";
import InstanceStateActions from "pages/instances/actions/InstanceStateActions";
import { useFormik } from "formik";
import * as Yup from "yup";
import { checkDuplicateName } from "util/helpers";
import { useEventQueue } from "context/eventQueue";
import { useToastNotification } from "context/toastNotificationProvider";
import {
instanceLinkFromName,
instanceLinkFromOperation,
instanceNameValidation,
} from "util/instances";
import { getInstanceName } from "util/operations";
import InstanceLink from "pages/instances/InstanceLink";
Expand All @@ -30,21 +30,9 @@ const InstanceDetailHeader: FC<Props> = ({ name, instance, project }) => {
const controllerState = useState<AbortController | null>(null);

const RenameSchema = Yup.object().shape({
name: Yup.string()
.test(
"deduplicate",
"An instance with this name already exists",
(value) =>
instance?.name === value ||
checkDuplicateName(value, project, controllerState, "instances"),
)
.matches(/^[A-Za-z0-9-]+$/, {
message: "Only alphanumeric and hyphen characters are allowed",
})
.matches(/^[A-Za-z].*$/, {
message: "Instance name must start with a letter",
})
.required("Instance name is required"),
name: instanceNameValidation(project, controllerState).required(
"Instance name is required",
),
});

const formik = useFormik<RenameHeaderValues>({
Expand Down
8 changes: 8 additions & 0 deletions src/sass/_rename_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@
.cancel {
margin-right: $sph--small;
}

.p-form-validation__message {
font-variant-caps: initial;
font-variant-numeric: initial;
font-weight: initial;
letter-spacing: initial;
text-indent: initial;
}
}
}

Expand Down
22 changes: 22 additions & 0 deletions src/util/instances.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { LxdOperationResponse } from "types/operation";
import { getInstanceName } from "./operations";
import InstanceLink from "pages/instances/InstanceLink";
import { ReactNode } from "react";
import { AbortControllerState, checkDuplicateName } from "./helpers";
import * as Yup from "yup";

export const instanceLinkFromName = (args: {
instanceName: string;
Expand All @@ -24,3 +26,23 @@ export const instanceLinkFromOperation = (args: {
}
return <InstanceLink instance={{ name: linkText, project: project || "" }} />;
};

export const instanceNameValidation = (
project: string,
controllerState: AbortControllerState,
): Yup.StringSchema =>
Yup.string()
.test("deduplicate", "An instance with this name already exists", (value) =>
checkDuplicateName(value, project, controllerState, "instances"),
)
.test(
"size",
"Instance name must be between 1 and 63 characters",
(value) => !value || value.length < 64,
)
.matches(/^[A-Za-z0-9-]+$/, {
message: "Only alphanumeric and hyphen characters are allowed",
})
.matches(/^[A-Za-z].*$/, {
message: "Instance name must start with a letter",
});

0 comments on commit ee2fd13

Please sign in to comment.