diff --git a/app/kubernetes/react/components/index.ts b/app/kubernetes/react/components/index.ts index 94e8f9394..e47d6d58e 100644 --- a/app/kubernetes/react/components/index.ts +++ b/app/kubernetes/react/components/index.ts @@ -142,7 +142,14 @@ export const ngModule = angular ), { stackName: 'setStackName' } ), - ['setStackName', 'stackName', 'stacks', 'inputClassName', 'textTip'] + [ + 'setStackName', + 'stackName', + 'stacks', + 'inputClassName', + 'textTip', + 'error', + ] ) ) .component( diff --git a/app/kubernetes/views/applications/create/createApplication.html b/app/kubernetes/views/applications/create/createApplication.html index 23ca602cf..0dffb4380 100644 --- a/app/kubernetes/views/applications/create/createApplication.html +++ b/app/kubernetes/views/applications/create/createApplication.html @@ -172,6 +172,7 @@ text-tip="'Enter or select a \'stack\' name to group multiple deployments together, or else leave empty to ignore.'" stacks="ctrl.stacks" input-class-name="'col-lg-10 col-sm-9'" + error="ctrl.state.stackNameError" > @@ -234,6 +235,7 @@ text-tip="'Enter or select a \'stack\' name to group multiple deployments together, or else leave empty to ignore.'" stacks="ctrl.stacks" input-class-name="'col-lg-10 col-sm-9'" + error="ctrl.state.stackNameError" > diff --git a/app/kubernetes/views/applications/create/createApplicationController.js b/app/kubernetes/views/applications/create/createApplicationController.js index c998d5e0a..79e1fdba5 100644 --- a/app/kubernetes/views/applications/create/createApplicationController.js +++ b/app/kubernetes/views/applications/create/createApplicationController.js @@ -28,6 +28,7 @@ import { confirmUpdateAppIngress } from '@/react/kubernetes/applications/CreateV import { confirm, confirmUpdate, confirmWebEditorDiscard } from '@@/modals/confirm'; import { buildConfirmButton } from '@@/modals/utils'; import { ModalType } from '@@/modals'; +import { KUBE_STACK_NAME_VALIDATION_REGEX } from '@/react/kubernetes/DeployView/StackName/constants'; class KubernetesCreateApplicationController { /* #region CONSTRUCTOR */ @@ -127,6 +128,7 @@ class KubernetesCreateApplicationController { // a validation message will be shown. isExistingCPUReservationUnchanged and isExistingMemoryReservationUnchanged (with available resources being exceeded) is used to decide whether to show the message or not. isExistingCPUReservationUnchanged: false, isExistingMemoryReservationUnchanged: false, + stackNameError: '', }; this.isAdmin = this.Authentication.isAdmin(); @@ -186,9 +188,16 @@ class KubernetesCreateApplicationController { } /* #endregion */ - onChangeStackName(stackName) { + onChangeStackName(name) { return this.$async(async () => { - this.formValues.StackName = stackName; + if (KUBE_STACK_NAME_VALIDATION_REGEX.test(name) || name === '') { + this.state.stackNameError = ''; + } else { + this.state.stackNameError = + "Stack must consist of alphanumeric characters, '-', '_' or '.', must start and end with an alphanumeric character and must be 63 characters or less (e.g. 'my-name', or 'abc-123')."; + } + + this.formValues.StackName = name; }); } @@ -644,7 +653,8 @@ class KubernetesCreateApplicationController { const invalid = !this.isValid(); const hasNoChanges = this.isEditAndNoChangesMade(); const nonScalable = this.isNonScalable(); - return overflow || autoScalerOverflow || inProgress || invalid || hasNoChanges || nonScalable; + const stackNameInvalid = this.state.stackNameError !== ''; + return overflow || autoScalerOverflow || inProgress || invalid || hasNoChanges || nonScalable || stackNameInvalid; } isUpdateApplicationViaWebEditorButtonDisabled() { diff --git a/app/kubernetes/views/deploy/deploy.html b/app/kubernetes/views/deploy/deploy.html index 27ec85ee2..8dd33791a 100644 --- a/app/kubernetes/views/deploy/deploy.html +++ b/app/kubernetes/views/deploy/deploy.html @@ -90,7 +90,12 @@