From c5fe994cd244eb8721e2b77f28098e4df0508902 Mon Sep 17 00:00:00 2001 From: Hao Zhang Date: Fri, 17 Dec 2021 20:22:50 +0800 Subject: [PATCH] feat(service): duplication validation for configs and secrets EE-1974 (#6266) feat(service): check if configs or secrets are duplicated --- .../create/createServiceController.js | 34 ++++++++++++++++++- .../services/create/includes/config.html | 8 ++++- .../services/create/includes/secret.html | 8 ++++- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/app/docker/views/services/create/createServiceController.js b/app/docker/views/services/create/createServiceController.js index 046d248e6..2602d407d 100644 --- a/app/docker/views/services/create/createServiceController.js +++ b/app/docker/views/services/create/createServiceController.js @@ -165,6 +165,7 @@ angular.module('portainer.docker').controller('CreateServiceController', [ $scope.removeConfig = function (index) { $scope.formValues.Configs.splice(index, 1); + $scope.checkIfConfigDuplicated(); }; $scope.addSecret = function () { @@ -173,6 +174,7 @@ angular.module('portainer.docker').controller('CreateServiceController', [ $scope.removeSecret = function (index) { $scope.formValues.Secrets.splice(index, 1); + $scope.checkIfSecretDuplicated(); }; $scope.addPlacementConstraint = function () { @@ -215,6 +217,36 @@ angular.module('portainer.docker').controller('CreateServiceController', [ $scope.formValues.LogDriverOpts.splice(index, 1); }; + $scope.checkIfSecretDuplicated = function () { + $scope.formValues.Secrets.$invalid = false; + [...$scope.formValues.Secrets] + .sort((a, b) => a.model.Id.localeCompare(b.model.Id)) + .sort((a, b) => { + if (a.model.Id === b.model.Id) { + $scope.formValues.Secrets.$invalid = true; + $scope.formValues.Secrets.$error = 'Secret ' + a.model.Name + ' cannot be assigned multiple times.'; + } + }); + if (!$scope.formValues.Secrets.$invalid) { + $scope.formValues.Secrets.$error = ''; + } + }; + + $scope.checkIfConfigDuplicated = function () { + $scope.formValues.Configs.$invalid = false; + [...$scope.formValues.Configs] + .sort((a, b) => a.model.Id.localeCompare(b.model.Id)) + .sort((a, b) => { + if (a.model.Id === b.model.Id) { + $scope.formValues.Configs.$invalid = true; + $scope.formValues.Configs.$error = 'Config ' + a.model.Name + ' cannot be assigned multiple times.'; + } + }); + if (!$scope.formValues.Configs.$invalid) { + $scope.formValues.Configs.$error = ''; + } + }; + function prepareImageConfig(config, input) { var imageConfig = ImageHelper.createImageConfigForContainer(input.RegistryModel); config.TaskTemplate.ContainerSpec.Image = imageConfig.fromImage; @@ -511,7 +543,7 @@ angular.module('portainer.docker').controller('CreateServiceController', [ function validateForm(accessControlData, isAdmin) { $scope.state.formValidationError = ''; var error = ''; - error = FormValidator.validateAccessControl(accessControlData, isAdmin); + error = FormValidator.validateAccessControl(accessControlData, isAdmin) || $scope.formValues.Secrets.$error || $scope.formValues.Configs.$error; if (error) { $scope.state.formValidationError = error; diff --git a/app/docker/views/services/create/includes/config.html b/app/docker/views/services/create/includes/config.html index 0fbd8dd30..2e10eb722 100644 --- a/app/docker/views/services/create/includes/config.html +++ b/app/docker/views/services/create/includes/config.html @@ -4,11 +4,17 @@ add a config + +
+
+ {{ formValues.Configs.$error }} +
+
config -
diff --git a/app/docker/views/services/create/includes/secret.html b/app/docker/views/services/create/includes/secret.html index 394dd9766..7f0a2fe9d 100644 --- a/app/docker/views/services/create/includes/secret.html +++ b/app/docker/views/services/create/includes/secret.html @@ -10,11 +10,17 @@ add a secret
+ +
+
+ {{ formValues.Secrets.$error }} +
+
secret -