1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-31 03:09:44 +02:00

feat(service): duplication validation for configs and secrets EE-1974 (#6266)

feat(service): check if configs or secrets are duplicated
This commit is contained in:
Hao Zhang 2021-12-17 20:22:50 +08:00 committed by GitHub
parent c30292cedd
commit c5fe994cd2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 3 deletions

View file

@ -165,6 +165,7 @@ angular.module('portainer.docker').controller('CreateServiceController', [
$scope.removeConfig = function (index) { $scope.removeConfig = function (index) {
$scope.formValues.Configs.splice(index, 1); $scope.formValues.Configs.splice(index, 1);
$scope.checkIfConfigDuplicated();
}; };
$scope.addSecret = function () { $scope.addSecret = function () {
@ -173,6 +174,7 @@ angular.module('portainer.docker').controller('CreateServiceController', [
$scope.removeSecret = function (index) { $scope.removeSecret = function (index) {
$scope.formValues.Secrets.splice(index, 1); $scope.formValues.Secrets.splice(index, 1);
$scope.checkIfSecretDuplicated();
}; };
$scope.addPlacementConstraint = function () { $scope.addPlacementConstraint = function () {
@ -215,6 +217,36 @@ angular.module('portainer.docker').controller('CreateServiceController', [
$scope.formValues.LogDriverOpts.splice(index, 1); $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) { function prepareImageConfig(config, input) {
var imageConfig = ImageHelper.createImageConfigForContainer(input.RegistryModel); var imageConfig = ImageHelper.createImageConfigForContainer(input.RegistryModel);
config.TaskTemplate.ContainerSpec.Image = imageConfig.fromImage; config.TaskTemplate.ContainerSpec.Image = imageConfig.fromImage;
@ -511,7 +543,7 @@ angular.module('portainer.docker').controller('CreateServiceController', [
function validateForm(accessControlData, isAdmin) { function validateForm(accessControlData, isAdmin) {
$scope.state.formValidationError = ''; $scope.state.formValidationError = '';
var error = ''; var error = '';
error = FormValidator.validateAccessControl(accessControlData, isAdmin); error = FormValidator.validateAccessControl(accessControlData, isAdmin) || $scope.formValues.Secrets.$error || $scope.formValues.Configs.$error;
if (error) { if (error) {
$scope.state.formValidationError = error; $scope.state.formValidationError = error;

View file

@ -4,11 +4,17 @@
<label class="control-label text-left">Configs</label> <label class="control-label text-left">Configs</label>
<span class="label label-default interactive" style="margin-left: 10px;" ng-click="addConfig()"> <i class="fa fa-plus-circle" aria-hidden="true"></i> add a config </span> <span class="label label-default interactive" style="margin-left: 10px;" ng-click="addConfig()"> <i class="fa fa-plus-circle" aria-hidden="true"></i> add a config </span>
</div> </div>
<!-- info message -->
<div class="form-group" ng-show="formValues.Configs.$invalid" style="margin-bottom: 0px;">
<div class="col-sm-12 small text-warning" style="padding-left: 35px; padding-top: 20px;">
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i> {{ formValues.Configs.$error }}
</div>
</div>
<div class="col-sm-12 form-inline" style="margin-top: 10px;"> <div class="col-sm-12 form-inline" style="margin-top: 10px;">
<div ng-repeat="config in formValues.Configs" style="margin-top: 2px;"> <div ng-repeat="config in formValues.Configs" style="margin-top: 2px;">
<div class="input-group col-sm-4 input-group-sm"> <div class="input-group col-sm-4 input-group-sm">
<span class="input-group-addon">config</span> <span class="input-group-addon">config</span>
<select class="form-control" ng-model="config.model" ng-options="config.Name for config in availableConfigs | orderBy: 'Name'"> <select class="form-control" ng-model="config.model" ng-change="checkIfConfigDuplicated()" ng-options="config.Name for config in availableConfigs | orderBy: 'Name'">
<option value="" selected="selected">Select a config</option> <option value="" selected="selected">Select a config</option>
</select> </select>
</div> </div>

View file

@ -10,11 +10,17 @@
<label class="control-label text-left">Secrets</label> <label class="control-label text-left">Secrets</label>
<span class="label label-default interactive" style="margin-left: 10px;" ng-click="addSecret()"> <i class="fa fa-plus-circle" aria-hidden="true"></i> add a secret </span> <span class="label label-default interactive" style="margin-left: 10px;" ng-click="addSecret()"> <i class="fa fa-plus-circle" aria-hidden="true"></i> add a secret </span>
</div> </div>
<!-- info message -->
<div class="form-group" ng-show="formValues.Secrets.$invalid" style="margin-bottom: 0px;">
<div class="col-sm-12 small text-warning" style="padding-left: 35px; padding-top: 20px;">
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i> {{ formValues.Secrets.$error }}
</div>
</div>
<div class="col-sm-12 form-inline" style="margin-top: 10px;"> <div class="col-sm-12 form-inline" style="margin-top: 10px;">
<div ng-repeat="secret in formValues.Secrets track by $index" style="margin-top: 4px;"> <div ng-repeat="secret in formValues.Secrets track by $index" style="margin-top: 4px;">
<div class="input-group col-sm-4 input-group-sm"> <div class="input-group col-sm-4 input-group-sm">
<span class="input-group-addon">secret</span> <span class="input-group-addon">secret</span>
<select class="form-control" ng-model="secret.model" ng-options="secret.Name for secret in availableSecrets | orderBy: 'Name'"> <select class="form-control" ng-model="secret.model" ng-change="checkIfSecretDuplicated()" ng-options="secret.Name for secret in availableSecrets | orderBy: 'Name'">
<option value="" selected="selected">Select a secret</option> <option value="" selected="selected">Select a secret</option>
</select> </select>
</div> </div>