mirror of https://github.com/portainer/portainer
fix(stack): validate original containers names [EE-4520] (#7978)
parent
ff10588383
commit
2868da296a
|
@ -23,7 +23,13 @@ angular.module('portainer.app').factory('StackHelper', [
|
|||
);
|
||||
}
|
||||
|
||||
helper.validateYAML = function (yaml, containerNames) {
|
||||
helper.validateYAML = validateYAML;
|
||||
|
||||
return helper;
|
||||
},
|
||||
]);
|
||||
|
||||
function validateYAML(yaml, containerNames, originalContainersNames = []) {
|
||||
let yamlObject;
|
||||
|
||||
try {
|
||||
|
@ -33,9 +39,12 @@ angular.module('portainer.app').factory('StackHelper', [
|
|||
}
|
||||
|
||||
const names = _.uniq(GenericHelper.findDeepAll(yamlObject, 'container_name'));
|
||||
const duplicateContainers = _.intersection(containerNames, names);
|
||||
|
||||
if (duplicateContainers.length === 0) return;
|
||||
const duplicateContainers = _.intersection(_.difference(containerNames, originalContainersNames), names);
|
||||
|
||||
if (duplicateContainers.length === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (
|
||||
(duplicateContainers.length === 1 ? 'This container name is' : 'These container names are') +
|
||||
|
@ -43,8 +52,16 @@ angular.module('portainer.app').factory('StackHelper', [
|
|||
_.join(duplicateContainers, ', ') +
|
||||
'.'
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
return helper;
|
||||
},
|
||||
]);
|
||||
export function extractContainerNames(yaml = '') {
|
||||
let yamlObject;
|
||||
|
||||
try {
|
||||
yamlObject = YAML.parse(yaml);
|
||||
} catch (err) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return _.uniq(GenericHelper.findDeepAll(yamlObject, 'container_name'));
|
||||
}
|
||||
|
|
|
@ -141,6 +141,9 @@
|
|||
<span class="col-sm-12 text-muted small">
|
||||
You can get more information about Compose file format in the <a href="https://docs.docker.com/compose/compose-file/" target="_blank">official documentation</a>.
|
||||
</span>
|
||||
<div class="col-sm-12" ng-if="state.yamlError">
|
||||
<span class="text-danger small">{{ state.yamlError }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
|
|
|
@ -3,6 +3,7 @@ import { AccessControlFormData } from 'Portainer/components/accessControlForm/po
|
|||
import { FeatureId } from 'Portainer/feature-flags/enums';
|
||||
import { getEnvironments } from '@/react/portainer/environments/environment.service';
|
||||
import { StackStatus, StackType } from '@/react/docker/stacks/types';
|
||||
import { extractContainerNames } from '@/portainer/helpers/stackHelper';
|
||||
|
||||
angular.module('portainer.app').controller('StackController', [
|
||||
'$async',
|
||||
|
@ -275,7 +276,7 @@ angular.module('portainer.app').controller('StackController', [
|
|||
if ($scope.stackFileContent.replace(/(\r\n|\n|\r)/gm, '') !== cm.getValue().replace(/(\r\n|\n|\r)/gm, '')) {
|
||||
$scope.state.isEditorDirty = true;
|
||||
$scope.stackFileContent = cm.getValue();
|
||||
$scope.state.yamlError = StackHelper.validateYAML($scope.stackFileContent, $scope.containerNames);
|
||||
$scope.state.yamlError = StackHelper.validateYAML($scope.stackFileContent, $scope.containerNames, $scope.state.originalContainerNames);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -365,8 +366,9 @@ angular.module('portainer.app').controller('StackController', [
|
|||
if (isSwarm && $scope.stack.Status === StackStatus.Active) {
|
||||
assignSwarmStackResources(data.resources, agentProxy);
|
||||
}
|
||||
$scope.state.originalContainerNames = extractContainerNames($scope.stackFileContent);
|
||||
|
||||
$scope.state.yamlError = StackHelper.validateYAML($scope.stackFileContent, $scope.containerNames);
|
||||
$scope.state.yamlError = StackHelper.validateYAML($scope.stackFileContent, $scope.containerNames, $scope.state.originalContainerNames);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Notifications.error('Failure', err, 'Unable to retrieve stack details');
|
||||
|
|
Loading…
Reference in New Issue