From e58acd7dd651600cb6b2dd8a0927235cf5abbe9f Mon Sep 17 00:00:00 2001 From: Chaim Lev-Ari Date: Wed, 22 Aug 2018 18:33:06 +0300 Subject: [PATCH 01/32] * chore(eslint): update esllint and remove unused variables * chore(eslint-config): change no-unused-vars to warn * chore(eslint): remove unused variables * chore(eslint): allow unused globals * fixup! chore(eslint): allow unused globals * chore(eslint): remove commented unused vars * fixup! chore(eslint): remove commented unused vars --- .eslintrc.yml | 5 ++++- app/app.js | 2 +- app/azure/models/container_group.js | 2 +- app/azure/services/azureService.js | 2 +- .../create/createContainerInstanceController.js | 2 +- .../containersDatatableController.js | 2 +- .../imagesDatatableController.js | 2 +- .../serviceTasksDatatableController.js | 2 +- .../servicesDatatableActionsController.js | 4 ++-- .../volumesDatatableController.js | 2 +- .../components/log-viewer/logViewerController.js | 1 - app/docker/helpers/containerHelper.js | 6 ------ app/docker/models/service.js | 2 +- app/docker/services/volumeService.js | 2 +- .../views/configs/edit/configController.js | 2 +- .../console/containerConsoleController.js | 8 ++++---- .../create/createContainerController.js | 16 ++++++++-------- .../views/containers/edit/containerController.js | 10 +++++----- .../containers/logs/containerLogsController.js | 4 ---- app/docker/views/images/edit/imageController.js | 6 +++--- app/docker/views/images/imagesController.js | 2 +- .../views/networks/edit/networkController.js | 10 +++++----- app/docker/views/nodes/edit/nodeController.js | 2 +- .../views/secrets/edit/secretController.js | 2 +- .../services/create/createServiceController.js | 3 +-- .../views/services/edit/serviceController.js | 14 +++++++------- .../volumes/create/createVolumeController.js | 2 +- .../views/volumes/edit/volumeController.js | 2 +- app/extensions/storidge/services/chartService.js | 2 +- .../storidge/views/monitor/monitorController.js | 4 ++-- .../profiles/create/createProfileController.js | 2 +- .../views/profiles/edit/profileController.js | 4 ++-- .../views/profiles/profilesController.js | 2 +- .../porAccessControlPanelController.js | 4 ++-- .../porAccessManagementController.js | 8 ++++---- .../components/endpoint-list/endpoint-list.js | 2 -- app/portainer/components/header-content.js | 2 +- app/portainer/components/header-title.js | 4 ++-- .../tag-selector/tagSelectorController.js | 4 +--- app/portainer/helpers/templateHelper.js | 4 ++-- app/portainer/services/api/stackService.js | 6 +++--- app/portainer/services/api/teamService.js | 2 +- app/portainer/services/api/userService.js | 4 ++-- app/portainer/services/chartService.js | 4 ++-- app/portainer/services/fileUpload.js | 2 +- app/portainer/services/modalService.js | 2 +- app/portainer/services/stateManager.js | 4 ++-- .../endpoints/create/createEndpointController.js | 2 -- .../views/endpoints/edit/endpointController.js | 2 +- .../views/groups/edit/groupController.js | 2 +- app/portainer/views/home/homeController.js | 2 +- .../init/endpoint/initEndpointController.js | 13 +++---------- app/portainer/views/main/mainController.js | 2 +- .../create/createRegistryController.js | 2 +- .../views/registries/edit/registryController.js | 2 +- .../views/registries/registriesController.js | 6 +++--- .../settingsAuthenticationController.js | 8 ++++---- .../views/settings/settingsController.js | 6 +++--- .../views/stacks/create/createStackController.js | 2 +- .../views/stacks/edit/stackController.js | 4 ++-- app/portainer/views/tags/tagsController.js | 2 +- app/portainer/views/teams/edit/teamController.js | 8 ++++---- app/portainer/views/teams/teamsController.js | 2 +- .../views/templates/templatesController.js | 8 +++----- app/portainer/views/users/edit/userController.js | 6 +++--- app/portainer/views/users/usersController.js | 2 +- gruntfile.js | 1 - 67 files changed, 121 insertions(+), 146 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 47be470b1..bc803c2e5 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -141,7 +141,10 @@ rules: no-undef-init: error no-undef: off no-undefined: off - no-unused-vars: off + no-unused-vars: + - warn + - + vars: local no-use-before-define: off # Node.js and CommonJS diff --git a/app/app.js b/app/app.js index 0ed1166fe..a32633fe2 100644 --- a/app/app.js +++ b/app/app.js @@ -48,7 +48,7 @@ function initAnalytics(Analytics, $rootScope) { Analytics.offline(false); Analytics.registerScriptTags(); Analytics.registerTrackers(); - $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) { + $rootScope.$on('$stateChangeSuccess', function (event, toState) { Analytics.trackPage(toState.url); Analytics.pageView(); }); diff --git a/app/azure/models/container_group.js b/app/azure/models/container_group.js index 0ba06a690..9a855129f 100644 --- a/app/azure/models/container_group.js +++ b/app/azure/models/container_group.js @@ -15,7 +15,7 @@ function ContainerGroupDefaultModel() { this.Memory = 1; } -function ContainerGroupViewModel(data, subscriptionId, resourceGroupName) { +function ContainerGroupViewModel(data) { this.Id = data.id; this.Name = data.name; this.Location = data.location; diff --git a/app/azure/services/azureService.js b/app/azure/services/azureService.js index 8d7def765..d0fa0468c 100644 --- a/app/azure/services/azureService.js +++ b/app/azure/services/azureService.js @@ -30,7 +30,7 @@ function AzureServiceFactory($q, Azure, SubscriptionService, ResourceGroupServic service.aggregate = function(resourcesBySubcription) { var aggregatedResources = []; - Object.keys(resourcesBySubcription).forEach(function(key, index) { + Object.keys(resourcesBySubcription).forEach(function(key) { aggregatedResources = aggregatedResources.concat(resourcesBySubcription[key]); }); return aggregatedResources; diff --git a/app/azure/views/containerinstances/create/createContainerInstanceController.js b/app/azure/views/containerinstances/create/createContainerInstanceController.js index b3a7ed173..a7ecab9e8 100644 --- a/app/azure/views/containerinstances/create/createContainerInstanceController.js +++ b/app/azure/views/containerinstances/create/createContainerInstanceController.js @@ -31,7 +31,7 @@ function ($q, $scope, $state, AzureService, Notifications) { $scope.state.actionInProgress = true; AzureService.createContainerGroup(model, subscriptionId, resourceGroupName) - .then(function success(data) { + .then(function success() { Notifications.success('Container successfully created', model.Name); $state.go('azure.containerinstances'); }) diff --git a/app/docker/components/datatables/containers-datatable/containersDatatableController.js b/app/docker/components/datatables/containers-datatable/containersDatatableController.js index f7125d7b8..7151e5d64 100644 --- a/app/docker/components/datatables/containers-datatable/containersDatatableController.js +++ b/app/docker/components/datatables/containers-datatable/containersDatatableController.js @@ -141,7 +141,7 @@ function (PaginationService, DatatableService, EndpointProvider) { PaginationService.setPaginationLimit(this.tableKey, this.state.paginatedItemLimit); }; - this.applyFilters = function(value, index, array) { + this.applyFilters = function(value) { var container = value; var filters = ctrl.filters; for (var i = 0; i < filters.state.values.length; i++) { diff --git a/app/docker/components/datatables/images-datatable/imagesDatatableController.js b/app/docker/components/datatables/images-datatable/imagesDatatableController.js index c7850a63b..f5254a47b 100644 --- a/app/docker/components/datatables/images-datatable/imagesDatatableController.js +++ b/app/docker/components/datatables/images-datatable/imagesDatatableController.js @@ -52,7 +52,7 @@ function (PaginationService, DatatableService) { PaginationService.setPaginationLimit(this.tableKey, this.state.paginatedItemLimit); }; - this.applyFilters = function(value, index, array) { + this.applyFilters = function(value) { var image = value; var filters = ctrl.filters; if ((image.ContainerCount === 0 && filters.usage.showUnusedImages) diff --git a/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatableController.js b/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatableController.js index 33eecffc4..b0a8da0b2 100644 --- a/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatableController.js +++ b/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatableController.js @@ -15,7 +15,7 @@ function (DatatableService) { } }; - this.applyFilters = function(item, index, array) { + this.applyFilters = function(item) { var filters = ctrl.filters; for (var i = 0; i < filters.state.values.length; i++) { var filter = filters.state.values[i]; diff --git a/app/docker/components/datatables/services-datatable/actions/servicesDatatableActionsController.js b/app/docker/components/datatables/services-datatable/actions/servicesDatatableActionsController.js index e2a394e58..dff0d034c 100644 --- a/app/docker/components/datatables/services-datatable/actions/servicesDatatableActionsController.js +++ b/app/docker/components/datatables/services-datatable/actions/servicesDatatableActionsController.js @@ -6,7 +6,7 @@ function ($state, ServiceService, ServiceHelper, Notifications, ModalService, Im var config = ServiceHelper.serviceToConfig(service.Model); config.Mode.Replicated.Replicas = service.Replicas; ServiceService.update(service, config) - .then(function success(data) { + .then(function success() { Notifications.success('Service successfully scaled', 'New replica count: ' + service.Replicas); $state.reload(); }) @@ -53,7 +53,7 @@ function ($state, ServiceService, ServiceHelper, Notifications, ModalService, Im // value or an increment of the counter value to force an update. config.TaskTemplate.ForceUpdate++; ServiceService.update(service, config) - .then(function success(data) { + .then(function success() { Notifications.success('Service successfully updated', service.Name); }) .catch(function error(err) { diff --git a/app/docker/components/datatables/volumes-datatable/volumesDatatableController.js b/app/docker/components/datatables/volumes-datatable/volumesDatatableController.js index f146f107e..38b3ebbff 100644 --- a/app/docker/components/datatables/volumes-datatable/volumesDatatableController.js +++ b/app/docker/components/datatables/volumes-datatable/volumesDatatableController.js @@ -52,7 +52,7 @@ function (PaginationService, DatatableService) { PaginationService.setPaginationLimit(this.tableKey, this.state.paginatedItemLimit); }; - this.applyFilters = function(value, index, array) { + this.applyFilters = function(value) { var volume = value; var filters = ctrl.filters; if ((volume.dangling && filters.usage.showUnusedVolumes) diff --git a/app/docker/components/log-viewer/logViewerController.js b/app/docker/components/log-viewer/logViewerController.js index f85c20852..9de38f318 100644 --- a/app/docker/components/log-viewer/logViewerController.js +++ b/app/docker/components/log-viewer/logViewerController.js @@ -1,7 +1,6 @@ angular.module('portainer.docker') .controller('LogViewerController', ['clipboard', function (clipboard) { - var ctrl = this; this.state = { copySupported: clipboard.supported, diff --git a/app/docker/helpers/containerHelper.js b/app/docker/helpers/containerHelper.js index c30af02c6..1e5d45ff6 100644 --- a/app/docker/helpers/containerHelper.js +++ b/app/docker/helpers/containerHelper.js @@ -35,12 +35,6 @@ angular.module('portainer.docker') for (var v in container.Mounts) { if ({}.hasOwnProperty.call(container.Mounts, v)) { var mount = container.Mounts[v]; - var volume = { - 'type': mount.Type, - 'name': mount.Name || mount.Source, - 'containerPath': mount.Destination, - 'readOnly': mount.RW === false - }; var name = mount.Name || mount.Source; var containerPath = mount.Destination; if (name && containerPath) { diff --git a/app/docker/models/service.js b/app/docker/models/service.js index 07a769156..a49392f2c 100644 --- a/app/docker/models/service.js +++ b/app/docker/models/service.js @@ -1,4 +1,4 @@ -function ServiceViewModel(data, runningTasks, allTasks, nodes) { +function ServiceViewModel(data, runningTasks, allTasks) { this.Model = data; this.Id = data.ID; this.Tasks = []; diff --git a/app/docker/services/volumeService.js b/app/docker/services/volumeService.js index d52b60528..449ec661c 100644 --- a/app/docker/services/volumeService.js +++ b/app/docker/services/volumeService.js @@ -1,5 +1,5 @@ angular.module('portainer.docker') -.factory('VolumeService', ['$q', 'Volume', 'VolumeHelper', 'ResourceControlService', 'UserService', 'TeamService', function VolumeServiceFactory($q, Volume, VolumeHelper, ResourceControlService, UserService, TeamService) { +.factory('VolumeService', ['$q', 'Volume', 'VolumeHelper', 'ResourceControlService', function VolumeServiceFactory($q, Volume, VolumeHelper, ResourceControlService) { 'use strict'; var service = {}; diff --git a/app/docker/views/configs/edit/configController.js b/app/docker/views/configs/edit/configController.js index 3e0ad0178..2457c9609 100644 --- a/app/docker/views/configs/edit/configController.js +++ b/app/docker/views/configs/edit/configController.js @@ -4,7 +4,7 @@ function ($scope, $transition$, $state, ConfigService, Notifications) { $scope.removeConfig = function removeConfig(configId) { ConfigService.remove(configId) - .then(function success(data) { + .then(function success() { Notifications.success('Config successfully removed'); $state.go('docker.configs', {}); }) diff --git a/app/docker/views/containers/console/containerConsoleController.js b/app/docker/views/containers/console/containerConsoleController.js index 9f29e11dd..812e5b567 100644 --- a/app/docker/views/containers/console/containerConsoleController.js +++ b/app/docker/views/containers/console/containerConsoleController.js @@ -12,7 +12,7 @@ function ($scope, $transition$, ContainerService, ImageService, EndpointProvider $scope.containerCommands = []; // Ensure the socket is closed before leaving the view - $scope.$on('$stateChangeStart', function (event, next, current) { + $scope.$on('$stateChangeStart', function () { if (socket && socket !== null) { socket.close(); } @@ -69,7 +69,7 @@ function ($scope, $transition$, ContainerService, ImageService, EndpointProvider socket = new WebSocket(url); $scope.state.connected = true; - socket.onopen = function(evt) { + socket.onopen = function() { term = new Terminal(); term.on('data', function (data) { @@ -88,10 +88,10 @@ function ($scope, $transition$, ContainerService, ImageService, EndpointProvider socket.onmessage = function (e) { term.write(e.data); }; - socket.onerror = function (error) { + socket.onerror = function () { $scope.state.connected = false; }; - socket.onclose = function(evt) { + socket.onclose = function() { $scope.state.connected = false; }; }; diff --git a/app/docker/views/containers/create/createContainerController.js b/app/docker/views/containers/create/createContainerController.js index 54d2ae6bb..83b153e44 100644 --- a/app/docker/views/containers/create/createContainerController.js +++ b/app/docker/views/containers/create/createContainerController.js @@ -282,8 +282,8 @@ function ($q, $scope, $state, $timeout, $transition$, $filter, Container, Contai return config; } - - function loadFromContainerCmd(d) { + + function loadFromContainerCmd() { if ($scope.config.Cmd) { $scope.config.Cmd = ContainerHelper.commandArrayToString($scope.config.Cmd); } else { @@ -291,7 +291,7 @@ function ($q, $scope, $state, $timeout, $transition$, $filter, Container, Contai } } - function loadFromContainerPortBindings(d) { + function loadFromContainerPortBindings() { var bindings = []; for (var p in $scope.config.HostConfig.PortBindings) { if ({}.hasOwnProperty.call($scope.config.HostConfig.PortBindings, p)) { @@ -386,7 +386,7 @@ function ($q, $scope, $state, $timeout, $transition$, $filter, Container, Contai } } - function loadFromContainerEnvironmentVariables(d) { + function loadFromContainerEnvironmentVariables() { var envArr = []; for (var e in $scope.config.Env) { if ({}.hasOwnProperty.call($scope.config.Env, e)) { @@ -397,7 +397,7 @@ function ($q, $scope, $state, $timeout, $transition$, $filter, Container, Contai $scope.config.Env = envArr; } - function loadFromContainerLabels(d) { + function loadFromContainerLabels() { for (var l in $scope.config.Labels) { if ({}.hasOwnProperty.call($scope.config.Labels, l)) { $scope.formValues.Labels.push({ name: l, value: $scope.config.Labels[l]}); @@ -405,7 +405,7 @@ function ($q, $scope, $state, $timeout, $transition$, $filter, Container, Contai } } - function loadFromContainerConsole(d) { + function loadFromContainerConsole() { if ($scope.config.OpenStdin && $scope.config.Tty) { $scope.formValues.Console = 'both'; } else if (!$scope.config.OpenStdin && $scope.config.Tty) { @@ -417,7 +417,7 @@ function ($q, $scope, $state, $timeout, $transition$, $filter, Container, Contai } } - function loadFromContainerDevices(d) { + function loadFromContainerDevices() { var path = []; for (var dev in $scope.config.HostConfig.Devices) { if ({}.hasOwnProperty.call($scope.config.HostConfig.Devices, dev)) { @@ -428,7 +428,7 @@ function ($q, $scope, $state, $timeout, $transition$, $filter, Container, Contai $scope.config.HostConfig.Devices = path; } - function loadFromContainerImageConfig(d) { + function loadFromContainerImageConfig() { var imageInfo = ImageHelper.extractImageAndRegistryFromRepository($scope.config.Image); RegistryService.retrieveRegistryFromRepository($scope.config.Image) .then(function success(data) { diff --git a/app/docker/views/containers/edit/containerController.js b/app/docker/views/containers/edit/containerController.js index 0efe59f1e..e7b1a988b 100644 --- a/app/docker/views/containers/edit/containerController.js +++ b/app/docker/views/containers/edit/containerController.js @@ -56,7 +56,7 @@ function ($q, $scope, $state, $transition$, $filter, Commit, ContainerHelper, Co function executeContainerAction(id, action, successMessage, errorMessage) { action(id) - .then(function success(data) { + .then(function success() { Notifications.success(successMessage, id); update(); }) @@ -104,7 +104,7 @@ function ($q, $scope, $state, $transition$, $filter, Commit, ContainerHelper, Co $scope.renameContainer = function () { var container = $scope.container; ContainerService.renameContainer($transition$.params().id, container.newContainerName) - .then(function success(data) { + .then(function success() { container.Name = container.newContainerName; Notifications.success('Container successfully renamed', container.Name); }) @@ -120,7 +120,7 @@ function ($q, $scope, $state, $transition$, $filter, Commit, ContainerHelper, Co $scope.containerLeaveNetwork = function containerLeaveNetwork(container, networkId) { $scope.state.leaveNetworkInProgress = true; NetworkService.disconnectContainer(networkId, container.Id, false) - .then(function success(data) { + .then(function success() { Notifications.success('Container left network', container.Id); $state.reload(); }) @@ -135,7 +135,7 @@ function ($q, $scope, $state, $transition$, $filter, Commit, ContainerHelper, Co $scope.containerJoinNetwork = function containerJoinNetwork(container, networkId) { $scope.state.joinNetworkInProgress = true; NetworkService.connectContainer(networkId, container.Id) - .then(function success(data) { + .then(function success() { Notifications.success('Container joined network', container.Id); $state.reload(); }) @@ -151,7 +151,7 @@ function ($q, $scope, $state, $transition$, $filter, Commit, ContainerHelper, Co var image = $scope.config.Image; var registry = $scope.config.Registry; var imageConfig = ImageHelper.createImageConfigForCommit(image, registry.URL); - Commit.commitContainer({id: $transition$.params().id, tag: imageConfig.tag, repo: imageConfig.repo}, function (d) { + Commit.commitContainer({id: $transition$.params().id, tag: imageConfig.tag, repo: imageConfig.repo}, function () { update(); Notifications.success('Container commited', $transition$.params().id); }, function (e) { diff --git a/app/docker/views/containers/logs/containerLogsController.js b/app/docker/views/containers/logs/containerLogsController.js index 2141a1f3b..1d23adeb8 100644 --- a/app/docker/views/containers/logs/containerLogsController.js +++ b/app/docker/views/containers/logs/containerLogsController.js @@ -27,10 +27,6 @@ function ($scope, $transition$, $interval, ContainerService, Notifications, Http } } - function update(logs) { - $scope.logs = logs; - } - function setUpdateRepeater(skipHeaders) { var refreshRate = $scope.state.refreshRate; $scope.repeater = $interval(function() { diff --git a/app/docker/views/images/edit/imageController.js b/app/docker/views/images/edit/imageController.js index d89cd4dc3..29d91d8da 100644 --- a/app/docker/views/images/edit/imageController.js +++ b/app/docker/views/images/edit/imageController.js @@ -29,7 +29,7 @@ function ($q, $scope, $transition$, $state, $timeout, ImageService, RegistryServ var registry = $scope.formValues.Registry; ImageService.tagImage($transition$.params().id, image, registry.URL) - .then(function success(data) { + .then(function success() { Notifications.success('Image successfully tagged'); $state.go('docker.images.image', {id: $transition$.params().id}, {reload: true}); }) @@ -45,7 +45,7 @@ function ($q, $scope, $transition$, $state, $timeout, ImageService, RegistryServ var registry = data; return ImageService.pushImage(repository, registry); }) - .then(function success(data) { + .then(function success() { Notifications.success('Image successfully pushed', repository); }) .catch(function error(err) { @@ -63,7 +63,7 @@ function ($q, $scope, $transition$, $state, $timeout, ImageService, RegistryServ var registry = data; return ImageService.pullImage(repository, registry, false); }) - .then(function success(data) { + .then(function success() { Notifications.success('Image successfully pulled', repository); }) .catch(function error(err) { diff --git a/app/docker/views/images/imagesController.js b/app/docker/views/images/imagesController.js index cb364edad..f495f4185 100644 --- a/app/docker/views/images/imagesController.js +++ b/app/docker/views/images/imagesController.js @@ -21,7 +21,7 @@ function ($scope, $state, ImageService, Notifications, ModalService, HttpRequest $scope.state.actionInProgress = true; ImageService.pullImage(image, registry, false) - .then(function success(data) { + .then(function success() { Notifications.success('Image successfully pulled', image); $state.reload(); }) diff --git a/app/docker/views/networks/edit/networkController.js b/app/docker/views/networks/edit/networkController.js index 0ba905c2a..9ca04092e 100644 --- a/app/docker/views/networks/edit/networkController.js +++ b/app/docker/views/networks/edit/networkController.js @@ -1,10 +1,10 @@ angular.module('portainer.docker') -.controller('NetworkController', ['$scope', '$state', '$transition$', '$filter', 'NetworkService', 'Container', 'ContainerHelper', 'Notifications', 'HttpRequestHelper', -function ($scope, $state, $transition$, $filter, NetworkService, Container, ContainerHelper, Notifications, HttpRequestHelper) { +.controller('NetworkController', ['$scope', '$state', '$transition$', '$filter', 'NetworkService', 'Container', 'Notifications', 'HttpRequestHelper', +function ($scope, $state, $transition$, $filter, NetworkService, Container, Notifications, HttpRequestHelper) { - $scope.removeNetwork = function removeNetwork(networkId) { + $scope.removeNetwork = function removeNetwork() { NetworkService.remove($transition$.params().id, $transition$.params().id) - .then(function success(data) { + .then(function success() { Notifications.success('Network removed', $transition$.params().id); $state.go('docker.networks', {}); }) @@ -16,7 +16,7 @@ function ($scope, $state, $transition$, $filter, NetworkService, Container, Cont $scope.containerLeaveNetwork = function containerLeaveNetwork(network, container) { HttpRequestHelper.setPortainerAgentTargetHeader(container.NodeName); NetworkService.disconnectContainer($transition$.params().id, container.Id, false) - .then(function success(data) { + .then(function success() { Notifications.success('Container left network', $transition$.params().id); $state.go('docker.networks.network', { id: network.Id }, { reload: true }); }) diff --git a/app/docker/views/nodes/edit/nodeController.js b/app/docker/views/nodes/edit/nodeController.js index bdb59984e..30f210b2a 100644 --- a/app/docker/views/nodes/edit/nodeController.js +++ b/app/docker/views/nodes/edit/nodeController.js @@ -52,7 +52,7 @@ function ($scope, $state, $transition$, LabelHelper, Node, NodeHelper, Task, Not config.Role = node.Role; config.Labels = LabelHelper.fromKeyValueToLabelHash(node.Labels); - Node.update({ id: node.Id, version: node.Version }, config, function (data) { + Node.update({ id: node.Id, version: node.Version }, config, function () { Notifications.success('Node successfully updated', 'Node updated'); $state.go('docker.nodes.node', {id: node.Id}, {reload: true}); }, function (e) { diff --git a/app/docker/views/secrets/edit/secretController.js b/app/docker/views/secrets/edit/secretController.js index 3be0614f9..15aecfc1f 100644 --- a/app/docker/views/secrets/edit/secretController.js +++ b/app/docker/views/secrets/edit/secretController.js @@ -4,7 +4,7 @@ function ($scope, $transition$, $state, SecretService, Notifications) { $scope.removeSecret = function removeSecret(secretId) { SecretService.remove(secretId) - .then(function success(data) { + .then(function success() { Notifications.success('Secret successfully removed'); $state.go('docker.secrets', {}); }) diff --git a/app/docker/views/services/create/createServiceController.js b/app/docker/views/services/create/createServiceController.js index 8a2fd3e4e..e56dc1e4c 100644 --- a/app/docker/views/services/create/createServiceController.js +++ b/app/docker/views/services/create/createServiceController.js @@ -142,7 +142,7 @@ function ($q, $scope, $state, $timeout, Service, ServiceHelper, ConfigService, C $scope.formValues.ContainerLabels.splice(index, 1); }; - $scope.addLogDriverOpt = function(value) { + $scope.addLogDriverOpt = function() { $scope.formValues.LogDriverOpts.push({ name: '', value: ''}); }; @@ -492,7 +492,6 @@ function ($q, $scope, $state, $timeout, Service, ServiceHelper, ConfigService, C function initView() { var apiVersion = $scope.applicationState.endpoint.apiVersion; - var provider = $scope.applicationState.endpoint.mode.provider; $q.all({ volumes: VolumeService.volumes(), diff --git a/app/docker/views/services/edit/serviceController.js b/app/docker/views/services/edit/serviceController.js index f7dcb9c59..c13f06112 100644 --- a/app/docker/views/services/edit/serviceController.js +++ b/app/docker/views/services/edit/serviceController.js @@ -125,7 +125,7 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll, updateServiceArray(service, 'ServiceMounts', service.ServiceMounts); } }; - $scope.updateMount = function updateMount(service, mount) { + $scope.updateMount = function updateMount(service) { updateServiceArray(service, 'ServiceMounts', service.ServiceMounts); }; $scope.addPlacementConstraint = function addPlacementConstraint(service) { @@ -138,7 +138,7 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll, updateServiceArray(service, 'ServiceConstraints', service.ServiceConstraints); } }; - $scope.updatePlacementConstraint = function(service, constraint) { + $scope.updatePlacementConstraint = function(service) { updateServiceArray(service, 'ServiceConstraints', service.ServiceConstraints); }; @@ -152,7 +152,7 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll, updateServiceArray(service, 'ServicePreferences', service.ServicePreferences); } }; - $scope.updatePlacementPreference = function(service, constraint) { + $scope.updatePlacementPreference = function(service) { updateServiceArray(service, 'ServicePreferences', service.ServicePreferences); }; @@ -162,7 +162,7 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll, } service.Ports.push({ PublishedPort: '', TargetPort: '', Protocol: 'tcp', PublishMode: 'ingress' }); }; - $scope.updatePublishedPort = function updatePublishedPort(service, portMapping) { + $scope.updatePublishedPort = function updatePublishedPort(service) { updateServiceArray(service, 'Ports', service.Ports); }; $scope.removePortPublishedBinding = function removePortPublishedBinding(service, index) { @@ -203,7 +203,7 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll, updateServiceArray(service, 'Hosts', service.Hosts); } }; - $scope.updateHostsEntry = function(service, entry) { + $scope.updateHostsEntry = function(service) { updateServiceArray(service, 'Hosts', service.Hosts); }; @@ -340,7 +340,7 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll, function removeService() { $scope.state.deletionInProgress = true; ServiceService.remove($scope.service) - .then(function success(data) { + .then(function success() { Notifications.success('Service successfully deleted'); $state.go('docker.services', {}); }) @@ -377,7 +377,7 @@ function ($q, $scope, $transition$, $state, $location, $timeout, $anchorScroll, config.TaskTemplate.ForceUpdate++; $scope.state.updateInProgress = true; ServiceService.update(service, config) - .then(function success(data) { + .then(function success() { Notifications.success('Service successfully updated', service.Name); $scope.cancelChanges({}); initView(); diff --git a/app/docker/views/volumes/create/createVolumeController.js b/app/docker/views/volumes/create/createVolumeController.js index a9ccec09b..ef5fc60ca 100644 --- a/app/docker/views/volumes/create/createVolumeController.js +++ b/app/docker/views/volumes/create/createVolumeController.js @@ -82,7 +82,7 @@ function ($q, $scope, $state, VolumeService, PluginService, ResourceControlServi var userId = userDetails.ID; return ResourceControlService.applyResourceControl('volume', volumeIdentifier, userId, accessControlData, []); }) - .then(function success(data) { + .then(function success() { Notifications.success('Volume successfully created'); $state.go('docker.volumes', {}, {reload: true}); }) diff --git a/app/docker/views/volumes/edit/volumeController.js b/app/docker/views/volumes/edit/volumeController.js index f314c1b3b..384490b7a 100644 --- a/app/docker/views/volumes/edit/volumeController.js +++ b/app/docker/views/volumes/edit/volumeController.js @@ -4,7 +4,7 @@ function ($scope, $state, $transition$, VolumeService, ContainerService, Notific $scope.removeVolume = function removeVolume() { VolumeService.remove($scope.volume) - .then(function success(data) { + .then(function success() { Notifications.success('Volume successfully removed', $transition$.params().id); $state.go('docker.volumes', {}); }) diff --git a/app/extensions/storidge/services/chartService.js b/app/extensions/storidge/services/chartService.js index de99a9c97..7dd468a38 100644 --- a/app/extensions/storidge/services/chartService.js +++ b/app/extensions/storidge/services/chartService.js @@ -178,7 +178,7 @@ angular.module('extension.storidge') return label + ': ' + processedValue + '/s'; } - function bytePerSecBasedAxisLabel(value, index, values) { + function bytePerSecBasedAxisLabel(value) { if (value > 5) { return filesize(value, {base: 10, round: 1}); } diff --git a/app/extensions/storidge/views/monitor/monitorController.js b/app/extensions/storidge/views/monitor/monitorController.js index 21c0f788d..d8dc5eda6 100644 --- a/app/extensions/storidge/views/monitor/monitorController.js +++ b/app/extensions/storidge/views/monitor/monitorController.js @@ -1,6 +1,6 @@ angular.module('extension.storidge') -.controller('StoridgeMonitorController', ['$q', '$scope', '$interval', '$document', 'Notifications', 'StoridgeClusterService', 'StoridgeChartService', 'ModalService', -function ($q, $scope, $interval, $document, Notifications, StoridgeClusterService, StoridgeChartService, ModalService) { +.controller('StoridgeMonitorController', ['$q', '$scope', '$interval', '$document', 'Notifications', 'StoridgeClusterService', 'StoridgeChartService', +function ($q, $scope, $interval, $document, Notifications, StoridgeClusterService, StoridgeChartService) { $scope.$on('$destroy', function() { stopRepeater(); diff --git a/app/extensions/storidge/views/profiles/create/createProfileController.js b/app/extensions/storidge/views/profiles/create/createProfileController.js index 6f8f05a7c..0246d1716 100644 --- a/app/extensions/storidge/views/profiles/create/createProfileController.js +++ b/app/extensions/storidge/views/profiles/create/createProfileController.js @@ -30,7 +30,7 @@ function ($scope, $state, $transition$, Notifications, StoridgeProfileService) { $scope.state.actionInProgress = true; StoridgeProfileService.create(profile) - .then(function success(data) { + .then(function success() { Notifications.success('Profile successfully created'); $state.go('storidge.profiles'); }) diff --git a/app/extensions/storidge/views/profiles/edit/profileController.js b/app/extensions/storidge/views/profiles/edit/profileController.js index 87db55c95..ff6aecfc0 100644 --- a/app/extensions/storidge/views/profiles/edit/profileController.js +++ b/app/extensions/storidge/views/profiles/edit/profileController.js @@ -31,7 +31,7 @@ function ($scope, $state, $transition$, Notifications, StoridgeProfileService, M $scope.state.updateInProgress = true; StoridgeProfileService.update(profile) - .then(function success(data) { + .then(function success() { Notifications.success('Profile successfully updated'); $state.go('storidge.profiles'); }) @@ -58,7 +58,7 @@ function ($scope, $state, $transition$, Notifications, StoridgeProfileService, M $scope.state.deleteInProgress = true; StoridgeProfileService.delete(profile.Name) - .then(function success(data) { + .then(function success() { Notifications.success('Profile successfully deleted'); $state.go('storidge.profiles'); }) diff --git a/app/extensions/storidge/views/profiles/profilesController.js b/app/extensions/storidge/views/profiles/profilesController.js index 0d6ba5fc6..25276b1f5 100644 --- a/app/extensions/storidge/views/profiles/profilesController.js +++ b/app/extensions/storidge/views/profiles/profilesController.js @@ -38,7 +38,7 @@ function ($q, $scope, $state, Notifications, StoridgeProfileService) { $scope.state.actionInProgress = true; StoridgeProfileService.create(model) - .then(function success(data) { + .then(function success() { Notifications.success('Profile successfully created'); $state.reload(); }) diff --git a/app/portainer/components/accessControlPanel/porAccessControlPanelController.js b/app/portainer/components/accessControlPanel/porAccessControlPanelController.js index 142603304..eab4a8960 100644 --- a/app/portainer/components/accessControlPanel/porAccessControlPanelController.js +++ b/app/portainer/components/accessControlPanel/porAccessControlPanelController.js @@ -22,7 +22,7 @@ function ($q, $state, UserService, TeamService, ResourceControlService, Notifica ctrl.authorizedTeams = []; ctrl.availableTeams = []; - ctrl.confirmUpdateOwnership = function (force) { + ctrl.confirmUpdateOwnership = function () { if (!validateForm()) { return; } @@ -77,7 +77,7 @@ function ($q, $state, UserService, TeamService, ResourceControlService, Notifica ResourceControlService.applyResourceControlChange(ctrl.resourceType, resourceId, ctrl.resourceControl, ownershipParameters) - .then(function success(data) { + .then(function success() { Notifications.success('Access control successfully updated'); $state.reload(); }) diff --git a/app/portainer/components/accessManagement/porAccessManagementController.js b/app/portainer/components/accessManagement/porAccessManagementController.js index dcf870498..666ec3628 100644 --- a/app/portainer/components/accessManagement/porAccessManagementController.js +++ b/app/portainer/components/accessManagement/porAccessManagementController.js @@ -52,7 +52,7 @@ function (AccessService, Notifications) { } ctrl.updateAccess({ userAccesses: authorizedUserIDs, teamAccesses: authorizedTeamIDs }) - .then(function success(data) { + .then(function success() { removeFromAccesses(access, ctrl.accesses); ctrl.authorizedAccesses.push(access); Notifications.success('Accesses successfully updated'); @@ -74,7 +74,7 @@ function (AccessService, Notifications) { } ctrl.updateAccess({ userAccesses: authorizedUserIDs, teamAccesses: authorizedTeamIDs }) - .then(function success(data) { + .then(function success() { removeFromAccesses(access, ctrl.authorizedAccesses); ctrl.accesses.push(access); Notifications.success('Accesses successfully updated'); @@ -96,7 +96,7 @@ function (AccessService, Notifications) { ctrl.unauthorizeAllAccesses = function() { ctrl.updateAccess({ userAccesses: [], teamAccesses: [] }) - .then(function success(data) { + .then(function success() { moveAccesses(ctrl.authorizedAccesses, ctrl.accesses); Notifications.success('Accesses successfully updated'); }) @@ -111,7 +111,7 @@ function (AccessService, Notifications) { var authorizedTeamIDs = accessData.teamIDs; ctrl.updateAccess({ userAccesses: authorizedUserIDs, teamAccesses: authorizedTeamIDs }) - .then(function success(data) { + .then(function success() { moveAccesses(ctrl.accesses, ctrl.authorizedAccesses); Notifications.success('Accesses successfully updated'); }) diff --git a/app/portainer/components/endpoint-list/endpoint-list.js b/app/portainer/components/endpoint-list/endpoint-list.js index 319d6ef08..d11d7611d 100644 --- a/app/portainer/components/endpoint-list/endpoint-list.js +++ b/app/portainer/components/endpoint-list/endpoint-list.js @@ -1,8 +1,6 @@ angular.module('portainer.app').component('endpointList', { templateUrl: 'app/portainer/components/endpoint-list/endpointList.html', controller: function() { - var ctrl = this; - this.state = { textFilter: '' }; diff --git a/app/portainer/components/header-content.js b/app/portainer/components/header-content.js index 638e78d50..18273fffe 100644 --- a/app/portainer/components/header-content.js +++ b/app/portainer/components/header-content.js @@ -3,7 +3,7 @@ angular.module('portainer.app') var directive = { requires: '^rdHeader', transclude: true, - link: function (scope, iElement, iAttrs) { + link: function (scope) { scope.username = Authentication.getUserDetails().username; }, template: '', diff --git a/app/portainer/components/header-title.js b/app/portainer/components/header-title.js index c79cd1f2d..6cfac7182 100644 --- a/app/portainer/components/header-title.js +++ b/app/portainer/components/header-title.js @@ -1,11 +1,11 @@ angular.module('portainer.app') -.directive('rdHeaderTitle', ['Authentication', 'StateManager', function rdHeaderTitle(Authentication, StateManager) { +.directive('rdHeaderTitle', ['Authentication', function rdHeaderTitle(Authentication) { var directive = { requires: '^rdHeader', scope: { titleText: '@' }, - link: function (scope, iElement, iAttrs) { + link: function (scope) { scope.username = Authentication.getUserDetails().username; }, transclude: true, diff --git a/app/portainer/components/tag-selector/tagSelectorController.js b/app/portainer/components/tag-selector/tagSelectorController.js index b7c18c2ca..2bf96d105 100644 --- a/app/portainer/components/tag-selector/tagSelectorController.js +++ b/app/portainer/components/tag-selector/tagSelectorController.js @@ -1,8 +1,6 @@ angular.module('portainer.app') .controller('TagSelectorController', function () { - var ctrl = this; - this.$onChanges = function(changes) { if(angular.isDefined(changes.tags.currentValue)) { this.tags = _.difference(changes.tags.currentValue, this.model); @@ -14,7 +12,7 @@ angular.module('portainer.app') noResult: false }; - this.selectTag = function($item, $model, $label) { + this.selectTag = function($item) { this.state.selectedValue = ''; this.model.push($item); this.tags = _.remove(this.tags, function(item) { diff --git a/app/portainer/helpers/templateHelper.js b/app/portainer/helpers/templateHelper.js index 9f2dbde97..9c07dd661 100644 --- a/app/portainer/helpers/templateHelper.js +++ b/app/portainer/helpers/templateHelper.js @@ -1,5 +1,5 @@ angular.module('portainer.app') -.factory('TemplateHelper', ['$filter', function TemplateHelperFactory($filter) { +.factory('TemplateHelper', [function TemplateHelperFactory() { 'use strict'; var helper = {}; @@ -57,7 +57,7 @@ angular.module('portainer.app') return labels; }; - helper.EnvToStringArray = function(templateEnvironment, containerMapping) { + helper.EnvToStringArray = function(templateEnvironment) { var env = []; templateEnvironment.forEach(function(envvar) { if (envvar.value || envvar.set) { diff --git a/app/portainer/services/api/stackService.js b/app/portainer/services/api/stackService.js index e21da318c..dafbc4379 100644 --- a/app/portainer/services/api/stackService.js +++ b/app/portainer/services/api/stackService.js @@ -48,7 +48,7 @@ function StackServiceFactory($q, Stack, ResourceControlService, FileUploadServic return Stack.migrate({ id: stack.Id, endpointId: stack.EndpointId }, { EndpointID: targetEndpointId, SwarmID: swarm.Id }).$promise; }) - .then(function success(data) { + .then(function success() { deferred.resolve(); }) .catch(function error(err) { @@ -67,7 +67,7 @@ function StackServiceFactory($q, Stack, ResourceControlService, FileUploadServic EndpointProvider.setEndpointID(targetEndpointId); Stack.migrate({ id: stack.Id, endpointId: stack.EndpointId }, { EndpointID: targetEndpointId }).$promise - .then(function success(data) { + .then(function success() { deferred.resolve(); }) .catch(function error(err) { @@ -204,7 +204,7 @@ function StackServiceFactory($q, Stack, ResourceControlService, FileUploadServic var deferred = $q.defer(); Stack.remove({ id: stack.Id ? stack.Id : stack.Name, external: external, endpointId: endpointId }).$promise - .then(function success(data) { + .then(function success() { if (stack.ResourceControl && stack.ResourceControl.Id) { return ResourceControlService.deleteResourceControl(stack.ResourceControl.Id); } diff --git a/app/portainer/services/api/teamService.js b/app/portainer/services/api/teamService.js index d13ff8ffd..4a78931d3 100644 --- a/app/portainer/services/api/teamService.js +++ b/app/portainer/services/api/teamService.js @@ -58,7 +58,7 @@ angular.module('portainer.app') return Teams.remove({id: id}).$promise; }; - service.updateTeam = function(id, name, members, leaders) { + service.updateTeam = function(id, name) { var payload = { Name: name }; diff --git a/app/portainer/services/api/userService.js b/app/portainer/services/api/userService.js index 1c3d0c2ff..4ed381843 100644 --- a/app/portainer/services/api/userService.js +++ b/app/portainer/services/api/userService.js @@ -83,7 +83,7 @@ angular.module('portainer.app') return service.updateUser(id, newPassword, undefined); } }) - .then(function success(data) { + .then(function success() { deferred.resolve(); }) .catch(function error(err) { @@ -142,7 +142,7 @@ angular.module('portainer.app') var deferred = $q.defer(); Users.checkAdminUser({}).$promise - .then(function success(data) { + .then(function success() { deferred.resolve(true); }) .catch(function error(err) { diff --git a/app/portainer/services/chartService.js b/app/portainer/services/chartService.js index 7fb1e21a1..4b10c9a83 100644 --- a/app/portainer/services/chartService.js +++ b/app/portainer/services/chartService.js @@ -139,14 +139,14 @@ angular.module('portainer.app') return label + ': ' + processedValue; } - function byteBasedAxisLabel(value, index, values) { + function byteBasedAxisLabel(value) { if (value > 5) { return filesize(value, {base: 10, round: 1}); } return value.toFixed(1) + 'B'; } - function percentageBasedAxisLabel(value, index, values) { + function percentageBasedAxisLabel(value) { if (value > 1) { return Math.round(value) + '%'; } diff --git a/app/portainer/services/fileUpload.js b/app/portainer/services/fileUpload.js index d74cb8f8b..fdbf9ff54 100644 --- a/app/portainer/services/fileUpload.js +++ b/app/portainer/services/fileUpload.js @@ -21,7 +21,7 @@ angular.module('portainer.app') dockerfile: path }, ignoreLoadingBar: true, - transformResponse: function(data, headers) { + transformResponse: function(data) { return jsonObjectsToArrayHandler(data); } }); diff --git a/app/portainer/services/modalService.js b/app/portainer/services/modalService.js index 1a16b8e55..f08a02962 100644 --- a/app/portainer/services/modalService.js +++ b/app/portainer/services/modalService.js @@ -59,7 +59,7 @@ angular.module('portainer.app') box.find('.bootbox-input-checkbox').prop('checked', optionToggled); }; - service.confirmAccessControlUpdate = function(callback, msg) { + service.confirmAccessControlUpdate = function(callback) { service.confirm({ title: 'Are you sure ?', message: 'Changing the ownership of this resource will potentially restrict its management to some users.', diff --git a/app/portainer/services/stateManager.js b/app/portainer/services/stateManager.js index 2b80109fe..787f67328 100644 --- a/app/portainer/services/stateManager.js +++ b/app/portainer/services/stateManager.js @@ -97,7 +97,7 @@ function StateManagerFactory($q, SystemService, InfoHelper, LocalStorage, Settin var cacheValidity = now - applicationState.validity; if (cacheValidity > APPLICATION_CACHE_VALIDITY) { loadApplicationState() - .then(function success(data) { + .then(function success() { deferred.resolve(state); }) .catch(function error(err) { @@ -110,7 +110,7 @@ function StateManagerFactory($q, SystemService, InfoHelper, LocalStorage, Settin } } else { loadApplicationState() - .then(function success(data) { + .then(function success() { deferred.resolve(state); }) .catch(function error(err) { diff --git a/app/portainer/views/endpoints/create/createEndpointController.js b/app/portainer/views/endpoints/create/createEndpointController.js index 6453902e9..13fc1ad16 100644 --- a/app/portainer/views/endpoints/create/createEndpointController.js +++ b/app/portainer/views/endpoints/create/createEndpointController.js @@ -60,8 +60,6 @@ function ($q, $scope, $state, $filter, EndpointService, GroupService, TagService }; function createAzureEndpoint(name, applicationId, tenantId, authenticationKey, groupId, tags) { - var endpoint; - $scope.state.actionInProgress = true; EndpointService.createAzureEndpoint(name, applicationId, tenantId, authenticationKey, groupId, tags) .then(function success() { diff --git a/app/portainer/views/endpoints/edit/endpointController.js b/app/portainer/views/endpoints/edit/endpointController.js index 137bac012..d091bf635 100644 --- a/app/portainer/views/endpoints/edit/endpointController.js +++ b/app/portainer/views/endpoints/edit/endpointController.js @@ -45,7 +45,7 @@ function ($q, $scope, $state, $transition$, $filter, EndpointService, GroupServi $scope.state.actionInProgress = true; EndpointService.updateEndpoint(endpoint.Id, payload) - .then(function success(data) { + .then(function success() { Notifications.success('Endpoint updated', $scope.endpoint.Name); EndpointProvider.setEndpointPublicURL(endpoint.PublicURL); $state.go('portainer.endpoints', {}, {reload: true}); diff --git a/app/portainer/views/groups/edit/groupController.js b/app/portainer/views/groups/edit/groupController.js index f242dfb09..1022b9b48 100644 --- a/app/portainer/views/groups/edit/groupController.js +++ b/app/portainer/views/groups/edit/groupController.js @@ -17,7 +17,7 @@ function ($q, $scope, $state, $transition$, GroupService, EndpointService, TagSe $scope.state.actionInProgress = true; GroupService.updateGroup(model, associatedEndpoints) - .then(function success(data) { + .then(function success() { Notifications.success('Group successfully updated'); $state.go('portainer.groups', {}, {reload: true}); }) diff --git a/app/portainer/views/home/homeController.js b/app/portainer/views/home/homeController.js index 318e9e2c9..684c1ff7e 100644 --- a/app/portainer/views/home/homeController.js +++ b/app/portainer/views/home/homeController.js @@ -22,7 +22,7 @@ function ($q, $scope, $state, Authentication, EndpointService, EndpointHelper, G function triggerSnapshot() { EndpointService.snapshot() - .then(function success(data) { + .then(function success() { Notifications.success('Success', 'Endpoints updated'); $state.reload(); }) diff --git a/app/portainer/views/init/endpoint/initEndpointController.js b/app/portainer/views/init/endpoint/initEndpointController.js index 9a7b64276..a621d014e 100644 --- a/app/portainer/views/init/endpoint/initEndpointController.js +++ b/app/portainer/views/init/endpoint/initEndpointController.js @@ -29,13 +29,9 @@ function ($scope, $state, EndpointService, StateManager, Notifications) { }; $scope.createLocalEndpoint = function() { - var name = 'local'; - var URL = ''; - var endpoint; - $scope.state.actionInProgress = true; EndpointService.createLocalEndpoint() - .then(function success(data) { + .then(function success() { $state.go('portainer.home'); }) .catch(function error(err) { @@ -78,11 +74,9 @@ function ($scope, $state, EndpointService, StateManager, Notifications) { }; function createAzureEndpoint(name, applicationId, tenantId, authenticationKey) { - var endpoint; - $scope.state.actionInProgress = true; EndpointService.createAzureEndpoint(name, applicationId, tenantId, authenticationKey, 1, []) - .then(function success(data) { + .then(function success() { $state.go('portainer.home'); }) .catch(function error(err) { @@ -94,10 +88,9 @@ function ($scope, $state, EndpointService, StateManager, Notifications) { } function createRemoteEndpoint(name, type, URL, PublicURL, TLS, TLSSkipVerify, TLSSKipClientVerify, TLSCAFile, TLSCertFile, TLSKeyFile) { - var endpoint; $scope.state.actionInProgress = true; EndpointService.createRemoteEndpoint(name, type, URL, PublicURL, 1, [], TLS, TLSSkipVerify, TLSSKipClientVerify, TLSCAFile, TLSCertFile, TLSKeyFile) - .then(function success(data) { + .then(function success() { $state.go('portainer.home'); }) .catch(function error(err) { diff --git a/app/portainer/views/main/mainController.js b/app/portainer/views/main/mainController.js index 3af2a6d95..3eb3e9cde 100644 --- a/app/portainer/views/main/mainController.js +++ b/app/portainer/views/main/mainController.js @@ -12,7 +12,7 @@ function ($scope, $cookieStore, StateManager) { $scope.applicationState = StateManager.getState(); - $scope.$watch($scope.getWidth, function(newValue, oldValue) { + $scope.$watch($scope.getWidth, function(newValue) { if (newValue >= mobileView) { if (angular.isDefined($cookieStore.get('toggle'))) { $scope.toggle = ! $cookieStore.get('toggle') ? false : true; diff --git a/app/portainer/views/registries/create/createRegistryController.js b/app/portainer/views/registries/create/createRegistryController.js index 2dd0f021a..ef6212087 100644 --- a/app/portainer/views/registries/create/createRegistryController.js +++ b/app/portainer/views/registries/create/createRegistryController.js @@ -36,7 +36,7 @@ function ($scope, $state, RegistryService, Notifications) { $scope.state.actionInProgress = true; RegistryService.createRegistry(registryName, registryURL, authentication, username, password) - .then(function success(data) { + .then(function success() { Notifications.success('Registry successfully created'); $state.go('portainer.registries'); }) diff --git a/app/portainer/views/registries/edit/registryController.js b/app/portainer/views/registries/edit/registryController.js index 7cee10785..5dc3a2a5a 100644 --- a/app/portainer/views/registries/edit/registryController.js +++ b/app/portainer/views/registries/edit/registryController.js @@ -15,7 +15,7 @@ function ($scope, $state, $transition$, $filter, RegistryService, Notifications) registry.Password = $scope.formValues.Password; $scope.state.actionInProgress = true; RegistryService.updateRegistry(registry) - .then(function success(data) { + .then(function success() { Notifications.success('Registry successfully updated'); $state.go('portainer.registries'); }) diff --git a/app/portainer/views/registries/registriesController.js b/app/portainer/views/registries/registriesController.js index 9c92354e5..317091841 100644 --- a/app/portainer/views/registries/registriesController.js +++ b/app/portainer/views/registries/registriesController.js @@ -1,6 +1,6 @@ angular.module('portainer.app') -.controller('RegistriesController', ['$q', '$scope', '$state', 'RegistryService', 'DockerHubService', 'ModalService', 'Notifications', 'PaginationService', -function ($q, $scope, $state, RegistryService, DockerHubService, ModalService, Notifications, PaginationService) { +.controller('RegistriesController', ['$q', '$scope', '$state', 'RegistryService', 'DockerHubService', 'ModalService', 'Notifications', +function ($q, $scope, $state, RegistryService, DockerHubService, ModalService, Notifications) { $scope.state = { actionInProgress: false @@ -15,7 +15,7 @@ function ($q, $scope, $state, RegistryService, DockerHubService, ModalService, N dockerhub.Password = $scope.formValues.dockerHubPassword; $scope.state.actionInProgress = true; DockerHubService.update(dockerhub) - .then(function success(data) { + .then(function success() { Notifications.success('DockerHub registry updated'); }) .catch(function error(err) { diff --git a/app/portainer/views/settings/authentication/settingsAuthenticationController.js b/app/portainer/views/settings/authentication/settingsAuthenticationController.js index 8c617678b..1eea8dda3 100644 --- a/app/portainer/views/settings/authentication/settingsAuthenticationController.js +++ b/app/portainer/views/settings/authentication/settingsAuthenticationController.js @@ -39,11 +39,11 @@ function ($q, $scope, Notifications, SettingsService, FileUploadService) { $scope.state.connectivityCheckInProgress = true; $q.when(!uploadRequired || FileUploadService.uploadLDAPTLSFiles(TLSCAFile, null, null)) - .then(function success(data) { + .then(function success() { addLDAPDefaultPort(settings, $scope.LDAPSettings.TLSConfig.TLS); return SettingsService.checkLDAPConnectivity(settings); }) - .then(function success(data) { + .then(function success() { $scope.state.failedConnectivityCheck = false; $scope.state.successfulConnectivityCheck = true; Notifications.success('Connection to LDAP successful'); @@ -68,11 +68,11 @@ function ($q, $scope, Notifications, SettingsService, FileUploadService) { $scope.state.actionInProgress = true; $q.when(!uploadRequired || FileUploadService.uploadLDAPTLSFiles(TLSCAFile, null, null)) - .then(function success(data) { + .then(function success() { addLDAPDefaultPort(settings, $scope.LDAPSettings.TLSConfig.TLS); return SettingsService.update(settings); }) - .then(function success(data) { + .then(function success() { Notifications.success('Authentication settings updated'); }) .catch(function error(err) { diff --git a/app/portainer/views/settings/settingsController.js b/app/portainer/views/settings/settingsController.js index 7e8819e43..e1b7156e2 100644 --- a/app/portainer/views/settings/settingsController.js +++ b/app/portainer/views/settings/settingsController.js @@ -1,6 +1,6 @@ angular.module('portainer.app') -.controller('SettingsController', ['$scope', '$state', 'Notifications', 'SettingsService', 'StateManager', 'DEFAULT_TEMPLATES_URL', -function ($scope, $state, Notifications, SettingsService, StateManager, DEFAULT_TEMPLATES_URL) { +.controller('SettingsController', ['$scope', '$state', 'Notifications', 'SettingsService', 'StateManager', +function ($scope, $state, Notifications, SettingsService, StateManager) { $scope.state = { actionInProgress: false @@ -53,7 +53,7 @@ function ($scope, $state, Notifications, SettingsService, StateManager, DEFAULT_ function updateSettings(settings) { SettingsService.update(settings) - .then(function success(data) { + .then(function success() { Notifications.success('Settings updated'); StateManager.updateLogo(settings.LogoURL); StateManager.updateSnapshotInterval(settings.SnapshotInterval); diff --git a/app/portainer/views/stacks/create/createStackController.js b/app/portainer/views/stacks/create/createStackController.js index 17c2f39f3..5f7d1a892 100644 --- a/app/portainer/views/stacks/create/createStackController.js +++ b/app/portainer/views/stacks/create/createStackController.js @@ -114,7 +114,7 @@ function ($scope, $state, StackService, Authentication, Notifications, FormValid } $scope.state.actionInProgress = true; action(name, method) - .then(function success(data) { + .then(function success() { return ResourceControlService.applyResourceControl('stack', name, userId, accessControlData, []); }) .then(function success() { diff --git a/app/portainer/views/stacks/edit/stackController.js b/app/portainer/views/stacks/edit/stackController.js index 6b9d54ee0..50a8651b2 100644 --- a/app/portainer/views/stacks/edit/stackController.js +++ b/app/portainer/views/stacks/edit/stackController.js @@ -65,7 +65,7 @@ function ($q, $scope, $state, $transition$, StackService, NodeService, ServiceSe $scope.state.migrationInProgress = true; migrateRequest(stack, targetEndpointId) - .then(function success(data) { + .then(function success() { Notifications.success('Stack successfully migrated', stack.Name); $state.go('portainer.stacks', {}, {reload: true}); }) @@ -108,7 +108,7 @@ function ($q, $scope, $state, $transition$, StackService, NodeService, ServiceSe $scope.state.actionInProgress = true; StackService.updateStack(stack, stackFile, env, prune) - .then(function success(data) { + .then(function success() { Notifications.success('Stack successfully deployed'); $state.reload(); }) diff --git a/app/portainer/views/tags/tagsController.js b/app/portainer/views/tags/tagsController.js index 37f5eb5d0..1b1d59699 100644 --- a/app/portainer/views/tags/tagsController.js +++ b/app/portainer/views/tags/tagsController.js @@ -45,7 +45,7 @@ function ($scope, $state, TagService, Notifications) { $scope.createTag = function() { var tagName = $scope.formValues.Name; TagService.createTag(tagName) - .then(function success(data) { + .then(function success() { Notifications.success('Tag successfully created', tagName); $state.reload(); }) diff --git a/app/portainer/views/teams/edit/teamController.js b/app/portainer/views/teams/edit/teamController.js index 15079b834..f07054607 100644 --- a/app/portainer/views/teams/edit/teamController.js +++ b/app/portainer/views/teams/edit/teamController.js @@ -45,7 +45,7 @@ function ($q, $scope, $state, $transition$, TeamService, UserService, TeamMember $scope.promoteToLeader = function(user) { TeamMembershipService.updateMembership(user.MembershipId, user.Id, $scope.team.Id, 1) - .then(function success(data) { + .then(function success() { $scope.leaderCount++; user.TeamRole = 'Leader'; Notifications.success('User is now team leader', user.Username); @@ -57,7 +57,7 @@ function ($q, $scope, $state, $transition$, TeamService, UserService, TeamMember $scope.demoteToMember = function(user) { TeamMembershipService.updateMembership(user.MembershipId, user.Id, $scope.team.Id, 2) - .then(function success(data) { + .then(function success() { user.TeamRole = 'Member'; $scope.leaderCount--; Notifications.success('User is now team member', user.Username); @@ -109,7 +109,7 @@ function ($q, $scope, $state, $transition$, TeamService, UserService, TeamMember teamMembershipQueries.push(TeamMembershipService.deleteMembership(user.MembershipId)); }); $q.all(teamMembershipQueries) - .then(function success(data) { + .then(function success() { $scope.users = $scope.users.concat($scope.teamMembers); $scope.teamMembers = []; Notifications.success('All users successfully removed'); @@ -133,7 +133,7 @@ function ($q, $scope, $state, $transition$, TeamService, UserService, TeamMember function deleteTeam() { TeamService.deleteTeam($scope.team.Id) - .then(function success(data) { + .then(function success() { Notifications.success('Team successfully deleted', $scope.team.Name); $state.go('portainer.teams'); }) diff --git a/app/portainer/views/teams/teamsController.js b/app/portainer/views/teams/teamsController.js index ef9196743..9b63b234e 100644 --- a/app/portainer/views/teams/teamsController.js +++ b/app/portainer/views/teams/teamsController.js @@ -30,7 +30,7 @@ function ($q, $scope, $state, TeamService, UserService, ModalService, Notificati $scope.state.actionInProgress = true; TeamService.createTeam(teamName, leaderIds) - .then(function success(data) { + .then(function success() { Notifications.success('Team successfully created', teamName); $state.reload(); }) diff --git a/app/portainer/views/templates/templatesController.js b/app/portainer/views/templates/templatesController.js index 286d4fe43..948e54b3c 100644 --- a/app/portainer/views/templates/templatesController.js +++ b/app/portainer/views/templates/templatesController.js @@ -65,7 +65,6 @@ function ($scope, $q, $state, $transition$, $anchorScroll, ContainerService, Ima var generatedVolumeIds = []; VolumeService.createXAutoGeneratedLocalVolumes(generatedVolumeCount) .then(function success(data) { - var volumeResourceControlQueries = []; angular.forEach(data, function (volume) { var volumeId = volume.Id; generatedVolumeIds.push(volumeId); @@ -73,7 +72,7 @@ function ($scope, $q, $state, $transition$, $anchorScroll, ContainerService, Ima TemplateService.updateContainerConfigurationWithVolumes(templateConfiguration, template, data); return ImageService.pullImage(template.Image, { URL: template.Registry }, true); }) - .then(function success(data) { + .then(function success() { return ContainerService.createAndStartContainer(templateConfiguration); }) .then(function success(data) { @@ -109,7 +108,7 @@ function ($scope, $q, $state, $transition$, $anchorScroll, ContainerService, Ima var endpointId = EndpointProvider.endpointID(); StackService.createComposeStackFromGitRepository(stackName, repositoryOptions, template.Env, endpointId) - .then(function success(data) { + .then(function success() { return ResourceControlService.applyResourceControl('stack', stackName, userId, accessControlData, []); }) .then(function success() { @@ -141,7 +140,7 @@ function ($scope, $q, $state, $transition$, $anchorScroll, ContainerService, Ima var endpointId = EndpointProvider.endpointID(); StackService.createSwarmStackFromGitRepository(stackName, repositoryOptions, template.Env, endpointId) - .then(function success(data) { + .then(function success() { return ResourceControlService.applyResourceControl('stack', stackName, userId, accessControlData, []); }) .then(function success() { @@ -167,7 +166,6 @@ function ($scope, $q, $state, $transition$, $anchorScroll, ContainerService, Ima } var template = $scope.state.selectedTemplate; - var templatesKey = $scope.templatesKey; $scope.state.actionInProgress = true; if (template.Type === 2) { diff --git a/app/portainer/views/users/edit/userController.js b/app/portainer/views/users/edit/userController.js index 01c41109e..e935aa466 100644 --- a/app/portainer/views/users/edit/userController.js +++ b/app/portainer/views/users/edit/userController.js @@ -25,7 +25,7 @@ function ($q, $scope, $state, $transition$, UserService, ModalService, Notificat $scope.updatePermissions = function() { var role = $scope.formValues.Administrator ? 1 : 2; UserService.updateUser($scope.user.Id, undefined, role) - .then(function success(data) { + .then(function success() { var newRole = role === 1 ? 'administrator' : 'user'; Notifications.success('Permissions successfully updated', $scope.user.Username + ' is now ' + newRole); $state.reload(); @@ -37,7 +37,7 @@ function ($q, $scope, $state, $transition$, UserService, ModalService, Notificat $scope.updatePassword = function() { UserService.updateUser($scope.user.Id, $scope.formValues.newPassword, undefined) - .then(function success(data) { + .then(function success() { Notifications.success('Password successfully updated'); $state.reload(); }) @@ -48,7 +48,7 @@ function ($q, $scope, $state, $transition$, UserService, ModalService, Notificat function deleteUser() { UserService.deleteUser($scope.user.Id) - .then(function success(data) { + .then(function success() { Notifications.success('User successfully deleted', $scope.user.Username); $state.go('portainer.users'); }) diff --git a/app/portainer/views/users/usersController.js b/app/portainer/views/users/usersController.js index a01ac14c8..3fb6de991 100644 --- a/app/portainer/views/users/usersController.js +++ b/app/portainer/views/users/usersController.js @@ -38,7 +38,7 @@ function ($q, $scope, $state, $sanitize, UserService, TeamService, TeamMembershi teamIds.push(team.Id); }); UserService.createUser(username, password, role, teamIds) - .then(function success(data) { + .then(function success() { Notifications.success('User successfully created', username); $state.reload(); }) diff --git a/gruntfile.js b/gruntfile.js index a68ca4722..79e05c95d 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -106,7 +106,6 @@ module.exports = function (grunt) { var autoprefixer = require('autoprefixer'); var cssnano = require('cssnano'); -var fs = require('fs'); gruntfile_cfg.config = { dev: { options: { variables: { 'environment': 'development' }}}, From 8cd3964d759be8c6906d2dedad4ae4342c830fa0 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Thu, 23 Aug 2018 17:10:18 +0200 Subject: [PATCH 02/32] feat(security): update secured headers and sanitize team name (#2167) --- api/http/handler/file/handler.go | 4 ++++ api/http/security/bouncer.go | 3 ++- app/portainer/views/teams/teamsController.js | 6 +++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/api/http/handler/file/handler.go b/api/http/handler/file/handler.go index 15ec1417f..464062be1 100644 --- a/api/http/handler/file/handler.go +++ b/api/http/handler/file/handler.go @@ -33,5 +33,9 @@ func (handler *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } else { w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") } + + w.Header().Add("X-Frame-Options", "DENY") + w.Header().Add("X-XSS-Protection", "1; mode=block") + w.Header().Add("X-Content-Type-Options", "nosniff") handler.Handler.ServeHTTP(w, r) } diff --git a/api/http/security/bouncer.go b/api/http/security/bouncer.go index 798d37f7b..5aad463f1 100644 --- a/api/http/security/bouncer.go +++ b/api/http/security/bouncer.go @@ -114,8 +114,9 @@ func (bouncer *RequestBouncer) EndpointAccess(r *http.Request, endpoint *portain // mwSecureHeaders provides secure headers middleware for handlers. func mwSecureHeaders(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("X-Content-Type-Options", "nosniff") w.Header().Add("X-Frame-Options", "DENY") + w.Header().Add("X-XSS-Protection", "1; mode=block") + w.Header().Add("X-Content-Type-Options", "nosniff") next.ServeHTTP(w, r) }) } diff --git a/app/portainer/views/teams/teamsController.js b/app/portainer/views/teams/teamsController.js index 9b63b234e..6c01427ac 100644 --- a/app/portainer/views/teams/teamsController.js +++ b/app/portainer/views/teams/teamsController.js @@ -1,6 +1,6 @@ angular.module('portainer.app') -.controller('TeamsController', ['$q', '$scope', '$state', 'TeamService', 'UserService', 'ModalService', 'Notifications', 'Authentication', -function ($q, $scope, $state, TeamService, UserService, ModalService, Notifications, Authentication) { +.controller('TeamsController', ['$q', '$scope', '$state', '$sanitize', 'TeamService', 'UserService', 'ModalService', 'Notifications', 'Authentication', +function ($q, $scope, $state, $sanitize, TeamService, UserService, ModalService, Notifications, Authentication) { $scope.state = { actionInProgress: false }; @@ -22,7 +22,7 @@ function ($q, $scope, $state, TeamService, UserService, ModalService, Notificati }; $scope.addTeam = function() { - var teamName = $scope.formValues.Name; + var teamName = $sanitize($scope.formValues.Name); var leaderIds = []; angular.forEach($scope.formValues.Leaders, function(user) { leaderIds.push(user.Id); From 4b05699e66d51d267743dcde8385964068fae016 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Fri, 24 Aug 2018 10:40:05 +0200 Subject: [PATCH 03/32] chore(codeclimate): update .codeclimate.yml (#2212) * chore(codeclimate): update .codeclimate.yml * chore(codeclimate): update .codeclimate.yml * chore(codeclimate): update .codeclimate.yml --- .codeclimate.yml | 48 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/.codeclimate.yml b/.codeclimate.yml index 84d9c8eda..845dacc08 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -1,5 +1,42 @@ ---- -engines: +version: "2" +checks: + argument-count: + enabled: true + config: + threshold: 4 + complex-logic: + enabled: true + config: + threshold: 4 + file-lines: + enabled: true + config: + threshold: 300 + method-complexity: + enabled: false + method-count: + enabled: true + config: + threshold: 20 + method-lines: + enabled: true + config: + threshold: 50 + nested-control-flow: + enabled: true + config: + threshold: 4 + return-statements: + enabled: false + similar-code: + enabled: true + config: + threshold: #language-specific defaults. overrides affect all languages. + identical-code: + enabled: true + config: + threshold: #language-specific defaults. overrides affect all languages. +plugins: gofmt: enabled: true golint: @@ -20,10 +57,5 @@ engines: config: .eslintrc.yml fixme: enabled: true -ratings: - paths: - - "**.css" - - "**.js" - - "**.go" -exclude_paths: +exclude_patterns: - test/ From c941fac2cc7c41d09d72b58712e8226831a32bb7 Mon Sep 17 00:00:00 2001 From: William Easton Date: Fri, 24 Aug 2018 06:08:46 -0500 Subject: [PATCH 04/32] fix(api): set templatesURL in settings when using the --templates flag Re-add the CLI for external template management --- api/cmd/portainer/main.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index e706907d7..b3918d1eb 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -178,6 +178,10 @@ func initSettings(settingsService portainer.SettingsService, flags *portainer.CL SnapshotInterval: *flags.SnapshotInterval, } + if *flags.Templates != "" { + settings.TemplatesURL = *flags.Templates + } + if *flags.Labels != nil { settings.BlackListedLabels = *flags.Labels } else { From 538a2b5ee27ddf48775a6aae91b8cc542167dbfc Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Fri, 24 Aug 2018 14:30:41 +0200 Subject: [PATCH 05/32] fix(service-details): disable auto-focus on task datatable (#2214) * fix(service-details): disable auto-focus on task datatable * refactor(api): gofmt main.go --- api/cmd/portainer/main.go | 2 +- .../components/datatables/tasks-datatable/tasksDatatable.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index b3918d1eb..c7997bf14 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -181,7 +181,7 @@ func initSettings(settingsService portainer.SettingsService, flags *portainer.CL if *flags.Templates != "" { settings.TemplatesURL = *flags.Templates } - + if *flags.Labels != nil { settings.BlackListedLabels = *flags.Labels } else { diff --git a/app/docker/components/datatables/tasks-datatable/tasksDatatable.html b/app/docker/components/datatables/tasks-datatable/tasksDatatable.html index bbb0e7d18..db3d50ebb 100644 --- a/app/docker/components/datatables/tasks-datatable/tasksDatatable.html +++ b/app/docker/components/datatables/tasks-datatable/tasksDatatable.html @@ -8,7 +8,7 @@
From bfccf55729d497897c505c65433661507e9e7265 Mon Sep 17 00:00:00 2001 From: aksappy Date: Mon, 27 Aug 2018 15:43:58 -0400 Subject: [PATCH 06/32] fix(images): Fix upload modal to allow both tar and tar.gz images (#2218) --- app/docker/views/images/import/importimage.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/docker/views/images/import/importimage.html b/app/docker/views/images/import/importimage.html index 7615080f6..6a6b20f31 100644 --- a/app/docker/views/images/import/importimage.html +++ b/app/docker/views/images/import/importimage.html @@ -21,7 +21,7 @@
- + {{ formValues.UploadFile.name }} From 812f3e3e8532f1c23df251d8eaa0c6c1a1089ec6 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Tue, 28 Aug 2018 10:13:01 +0200 Subject: [PATCH 07/32] feat(auth): remove sanitization calls and ask for password update if needed (#2222) * wip * feat(auth): remove sanitization calls and ask for password update if needed --- app/portainer/__module.js | 90 +++++++++++-------- .../views/account/accountController.js | 8 +- app/portainer/views/auth/authController.js | 54 ++++++----- .../views/init/admin/initAdminController.js | 8 +- .../views/update-password/updatePassword.html | 64 +++++++++++++ .../updatePasswordController.js | 40 +++++++++ app/portainer/views/users/usersController.js | 8 +- index.html | 4 +- 8 files changed, 203 insertions(+), 73 deletions(-) create mode 100644 app/portainer/views/update-password/updatePassword.html create mode 100644 app/portainer/views/update-password/updatePasswordController.js diff --git a/app/portainer/__module.js b/app/portainer/__module.js index a2ad9053d..6ddfb5f2a 100644 --- a/app/portainer/__module.js +++ b/app/portainer/__module.js @@ -65,40 +65,6 @@ angular.module('portainer.app', []) } }; - var init = { - name: 'portainer.init', - abstract: true, - url: '/init', - data: { - requiresLogin: false - }, - views: { - 'sidebar@': {} - } - }; - - var initEndpoint = { - name: 'portainer.init.endpoint', - url: '/endpoint', - views: { - 'content@': { - templateUrl: 'app/portainer/views/init/endpoint/initEndpoint.html', - controller: 'InitEndpointController' - } - } - }; - - var initAdmin = { - name: 'portainer.init.admin', - url: '/admin', - views: { - 'content@': { - templateUrl: 'app/portainer/views/init/admin/initAdmin.html', - controller: 'InitAdminController' - } - } - }; - var endpoints = { name: 'portainer.endpoints', url: '/endpoints', @@ -198,6 +164,40 @@ angular.module('portainer.app', []) } }; + var init = { + name: 'portainer.init', + abstract: true, + url: '/init', + data: { + requiresLogin: false + }, + views: { + 'sidebar@': {} + } + }; + + var initEndpoint = { + name: 'portainer.init.endpoint', + url: '/endpoint', + views: { + 'content@': { + templateUrl: 'app/portainer/views/init/endpoint/initEndpoint.html', + controller: 'InitEndpointController' + } + } + }; + + var initAdmin = { + name: 'portainer.init.admin', + url: '/admin', + views: { + 'content@': { + templateUrl: 'app/portainer/views/init/admin/initAdmin.html', + controller: 'InitAdminController' + } + } + }; + var registries = { name: 'portainer.registries', url: '/registries', @@ -318,6 +318,21 @@ angular.module('portainer.app', []) } }; + var updatePassword = { + name: 'portainer.updatePassword', + url: '/update-password', + views: { + 'content@': { + templateUrl: 'app/portainer/views/update-password/updatePassword.html', + controller: 'UpdatePasswordController' + }, + 'sidebar@': {} + }, + params: { + password: '' + } + }; + var users = { name: 'portainer.users', url: '/users', @@ -404,9 +419,6 @@ angular.module('portainer.app', []) $stateRegistryProvider.register(about); $stateRegistryProvider.register(account); $stateRegistryProvider.register(authentication); - $stateRegistryProvider.register(init); - $stateRegistryProvider.register(initEndpoint); - $stateRegistryProvider.register(initAdmin); $stateRegistryProvider.register(endpoints); $stateRegistryProvider.register(endpoint); $stateRegistryProvider.register(endpointAccess); @@ -416,6 +428,9 @@ angular.module('portainer.app', []) $stateRegistryProvider.register(groupAccess); $stateRegistryProvider.register(groupCreation); $stateRegistryProvider.register(home); + $stateRegistryProvider.register(init); + $stateRegistryProvider.register(initEndpoint); + $stateRegistryProvider.register(initAdmin); $stateRegistryProvider.register(registries); $stateRegistryProvider.register(registry); $stateRegistryProvider.register(registryAccess); @@ -427,6 +442,7 @@ angular.module('portainer.app', []) $stateRegistryProvider.register(stackCreation); $stateRegistryProvider.register(support); $stateRegistryProvider.register(tags); + $stateRegistryProvider.register(updatePassword); $stateRegistryProvider.register(users); $stateRegistryProvider.register(user); $stateRegistryProvider.register(teams); diff --git a/app/portainer/views/account/accountController.js b/app/portainer/views/account/accountController.js index b842b7317..304fd2586 100644 --- a/app/portainer/views/account/accountController.js +++ b/app/portainer/views/account/accountController.js @@ -1,6 +1,6 @@ angular.module('portainer.app') -.controller('AccountController', ['$scope', '$state', '$sanitize', 'Authentication', 'UserService', 'Notifications', 'SettingsService', -function ($scope, $state, $sanitize, Authentication, UserService, Notifications, SettingsService) { +.controller('AccountController', ['$scope', '$state', 'Authentication', 'UserService', 'Notifications', 'SettingsService', +function ($scope, $state, Authentication, UserService, Notifications, SettingsService) { $scope.formValues = { currentPassword: '', newPassword: '', @@ -9,10 +9,8 @@ function ($scope, $state, $sanitize, Authentication, UserService, Notifications, $scope.updatePassword = function() { $scope.invalidPassword = false; - var currentPassword = $sanitize($scope.formValues.currentPassword); - var newPassword = $sanitize($scope.formValues.newPassword); - UserService.updateUserPassword($scope.userID, currentPassword, newPassword) + UserService.updateUserPassword($scope.userID, $scope.formValues.currentPassword, $scope.formValues.newPassword) .then(function success() { Notifications.success('Success', 'Password successfully updated'); $state.reload(); diff --git a/app/portainer/views/auth/authController.js b/app/portainer/views/auth/authController.js index 90d5e85a2..3b18d600c 100644 --- a/app/portainer/views/auth/authController.js +++ b/app/portainer/views/auth/authController.js @@ -1,6 +1,6 @@ angular.module('portainer.app') -.controller('AuthenticationController', ['$scope', '$state', '$transition$', '$sanitize', 'Authentication', 'UserService', 'EndpointService', 'StateManager', 'Notifications', 'SettingsService', -function ($scope, $state, $transition$, $sanitize, Authentication, UserService, EndpointService, StateManager, Notifications, SettingsService) { +.controller('AuthenticationController', ['$q', '$scope', '$state', '$transition$', '$sanitize', 'Authentication', 'UserService', 'EndpointService', 'StateManager', 'Notifications', 'SettingsService', +function ($q, $scope, $state, $transition$, $sanitize, Authentication, UserService, EndpointService, StateManager, Notifications, SettingsService) { $scope.logo = StateManager.getState().application.logo; @@ -13,6 +13,31 @@ function ($scope, $state, $transition$, $sanitize, Authentication, UserService, AuthenticationError: '' }; + $scope.authenticateUser = function() { + var username = $scope.formValues.Username; + var password = $scope.formValues.Password; + + Authentication.login(username, password) + .then(function success() { + checkForEndpoints(); + }) + .catch(function error() { + SettingsService.publicSettings() + .then(function success(settings) { + if (settings.AuthenticationMethod === 1) { + return Authentication.login($sanitize(username), $sanitize(password)); + } + return $q.reject(); + }) + .then(function success() { + $state.go('portainer.updatePassword', { password: $sanitize(password) }); + }) + .catch(function error() { + $scope.state.AuthenticationError = 'Invalid credentials'; + }); + }); + }; + function unauthenticatedFlow() { EndpointService.endpoints() .then(function success(endpoints) { @@ -39,35 +64,22 @@ function ($scope, $state, $transition$, $sanitize, Authentication, UserService, }); } - $scope.authenticateUser = function() { - var username = $scope.formValues.Username; - var password = $scope.formValues.Password; - - SettingsService.publicSettings() - .then(function success(data) { - var settings = data; - if (settings.AuthenticationMethod === 1) { - username = $sanitize(username); - password = $sanitize(password); - } - return Authentication.login(username, password); - }) - .then(function success() { - return EndpointService.endpoints(); - }) + function checkForEndpoints() { + EndpointService.endpoints() .then(function success(data) { var endpoints = data; var userDetails = Authentication.getUserDetails(); + if (endpoints.length === 0 && userDetails.role === 1) { $state.go('portainer.init.endpoint'); } else { $state.go('portainer.home'); } }) - .catch(function error() { - $scope.state.AuthenticationError = 'Invalid credentials'; + .catch(function error(err) { + Notifications.error('Failure', err, 'Unable to retrieve endpoints'); }); - }; + } function initView() { if ($transition$.params().logout || $transition$.params().error) { diff --git a/app/portainer/views/init/admin/initAdminController.js b/app/portainer/views/init/admin/initAdminController.js index e43f8a0ec..569bb1491 100644 --- a/app/portainer/views/init/admin/initAdminController.js +++ b/app/portainer/views/init/admin/initAdminController.js @@ -1,6 +1,6 @@ angular.module('portainer.app') -.controller('InitAdminController', ['$scope', '$state', '$sanitize', 'Notifications', 'Authentication', 'StateManager', 'UserService', 'EndpointService', -function ($scope, $state, $sanitize, Notifications, Authentication, StateManager, UserService, EndpointService) { +.controller('InitAdminController', ['$scope', '$state', 'Notifications', 'Authentication', 'StateManager', 'UserService', 'EndpointService', +function ($scope, $state, Notifications, Authentication, StateManager, UserService, EndpointService) { $scope.logo = StateManager.getState().application.logo; @@ -15,8 +15,8 @@ function ($scope, $state, $sanitize, Notifications, Authentication, StateManager }; $scope.createAdminUser = function() { - var username = $sanitize($scope.formValues.Username); - var password = $sanitize($scope.formValues.Password); + var username = $scope.formValues.Username; + var password = $scope.formValues.Password; $scope.state.actionInProgress = true; UserService.initAdministrator(username, password) diff --git a/app/portainer/views/update-password/updatePassword.html b/app/portainer/views/update-password/updatePassword.html new file mode 100644 index 000000000..62c726a61 --- /dev/null +++ b/app/portainer/views/update-password/updatePassword.html @@ -0,0 +1,64 @@ +
+ +
+
+ +
+
+
+ +
+
+ + Your password must be updated. + +
+
+ + +
+ +
+ +
+
+ + +
+ +
+
+ + +
+
+
+ + +
+
+ + + The password must be at least 8 characters long + +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ +
diff --git a/app/portainer/views/update-password/updatePasswordController.js b/app/portainer/views/update-password/updatePasswordController.js new file mode 100644 index 000000000..6809d1a34 --- /dev/null +++ b/app/portainer/views/update-password/updatePasswordController.js @@ -0,0 +1,40 @@ +angular.module('portainer.app') +.controller('UpdatePasswordController', ['$scope', '$state', '$transition$', 'UserService', 'Authentication', 'Notifications', +function UpdatePasswordController($scope, $state, $transition$, UserService, Authentication, Notifications) { + + $scope.formValues = { + Password: '', + ConfirmPassword: '' + }; + + $scope.state = { + actionInProgress: false, + currentPassword: '' + }; + + $scope.updatePassword = function() { + var userId = Authentication.getUserDetails().ID; + + $scope.state.actionInProgress = true; + UserService.updateUserPassword(userId, $scope.state.currentPassword, $scope.formValues.Password) + .then(function success() { + $state.go('portainer.home'); + }) + .catch(function error(err) { + Notifications.error('Failure', err, 'Unable to update password'); + }) + .finally(function final() { + $scope.state.actionInProgress = false; + }); + }; + + function initView() { + if (!Authentication.isAuthenticated()) { + $state.go('portainer.auth'); + } + + $scope.state.currentPassword = $transition$.params().password; + } + + initView(); +}]); diff --git a/app/portainer/views/users/usersController.js b/app/portainer/views/users/usersController.js index 3fb6de991..ea9bb425d 100644 --- a/app/portainer/views/users/usersController.js +++ b/app/portainer/views/users/usersController.js @@ -1,6 +1,6 @@ angular.module('portainer.app') -.controller('UsersController', ['$q', '$scope', '$state', '$sanitize', 'UserService', 'TeamService', 'TeamMembershipService', 'ModalService', 'Notifications', 'Authentication', 'SettingsService', -function ($q, $scope, $state, $sanitize, UserService, TeamService, TeamMembershipService, ModalService, Notifications, Authentication, SettingsService) { +.controller('UsersController', ['$q', '$scope', '$state', 'UserService', 'TeamService', 'TeamMembershipService', 'ModalService', 'Notifications', 'Authentication', 'SettingsService', +function ($q, $scope, $state, UserService, TeamService, TeamMembershipService, ModalService, Notifications, Authentication, SettingsService) { $scope.state = { userCreationError: '', validUsername: false, @@ -30,8 +30,8 @@ function ($q, $scope, $state, $sanitize, UserService, TeamService, TeamMembershi $scope.addUser = function() { $scope.state.actionInProgress = true; $scope.state.userCreationError = ''; - var username = $sanitize($scope.formValues.Username); - var password = $sanitize($scope.formValues.Password); + var username = $scope.formValues.Username; + var password = $scope.formValues.Password; var role = $scope.formValues.Administrator ? 1 : 2; var teamIds = []; angular.forEach($scope.formValues.Teams, function(team) { diff --git a/index.html b/index.html index cb5540b9a..0ec14b658 100644 --- a/index.html +++ b/index.html @@ -36,8 +36,8 @@
From a5d6ab0410bdc71a262de68f945260c2cda1d52e Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Tue, 28 Aug 2018 10:50:15 +0200 Subject: [PATCH 08/32] refactor(app): remove unused params in templates state declaration --- app/portainer/__module.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/portainer/__module.js b/app/portainer/__module.js index 6ddfb5f2a..bb94d395d 100644 --- a/app/portainer/__module.js +++ b/app/portainer/__module.js @@ -385,10 +385,6 @@ angular.module('portainer.app', []) templateUrl: 'app/portainer/views/templates/templates.html', controller: 'TemplatesController' } - }, - params: { - key: 'containers', - hide_descriptions: false } }; From 887c16c5807e6a99be2a6823da1dafd094d341d1 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Thu, 30 Aug 2018 12:21:53 +0200 Subject: [PATCH 09/32] feat(api): display details in error response (#2228) --- api/http/error/error.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/http/error/error.go b/api/http/error/error.go index b9153a8a6..244397fdf 100644 --- a/api/http/error/error.go +++ b/api/http/error/error.go @@ -16,7 +16,8 @@ type ( Err error } errorResponse struct { - Err string `json:"err,omitempty"` + Err string `json:"err,omitempty"` + Details string `json:"details,omitempty"` } ) @@ -31,7 +32,7 @@ func writeErrorResponse(rw http.ResponseWriter, err *HandlerError) { log.Printf("http error: %s (err=%s) (code=%d)\n", err.Message, err.Err, err.StatusCode) rw.Header().Set("Content-Type", "application/json") rw.WriteHeader(err.StatusCode) - json.NewEncoder(rw).Encode(&errorResponse{Err: err.Message}) + json.NewEncoder(rw).Encode(&errorResponse{Err: err.Message, Details: err.Err.Error()}) } // WriteError is a convenience function that creates a new HandlerError before calling writeErrorResponse. From 84fc3119a0b369ed48b7233bbd27e6a88d888a20 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Thu, 30 Aug 2018 13:11:15 +0200 Subject: [PATCH 10/32] docs(swagger): update StackCreate operation parameter --- api/swagger.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/swagger.yaml b/api/swagger.yaml index f589efd7f..17785d43e 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -1336,7 +1336,7 @@ paths: in: "formData" type: "string" description: "Swarm cluster identifier. Required when method equals file and type equals 1." - - name: "StackFileContent" + - name: "file" in: "formData" type: "file" description: "Stack file. Required when method equals file." From e17c873e73ed0e66f4dc2cd6bcd58be49e5ac994 Mon Sep 17 00:00:00 2001 From: classmember Date: Sat, 1 Sep 2018 04:09:24 -0400 Subject: [PATCH 11/32] refactor(build-system): update build_in_container.sh (#2230) wrapped `$(pwd)/api:/src` in `"` quotes to prevent word splitting on the `-tv` option --- build/build_in_container.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build_in_container.sh b/build/build_in_container.sh index 91186ca50..a827bddfd 100755 --- a/build/build_in_container.sh +++ b/build/build_in_container.sh @@ -4,7 +4,7 @@ binary="portainer-$1-$2" mkdir -p dist -docker run --rm -tv $(pwd)/api:/src -e BUILD_GOOS="$1" -e BUILD_GOARCH="$2" portainer/golang-builder:cross-platform /src/cmd/portainer +docker run --rm -tv "$(pwd)/api:/src" -e BUILD_GOOS="$1" -e BUILD_GOARCH="$2" portainer/golang-builder:cross-platform /src/cmd/portainer mv "api/cmd/portainer/$binary" dist/ #sha256sum "dist/$binary" > portainer-checksum.txt From d5facde9d4f735d3268a1f1f955352056426a392 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Sun, 2 Sep 2018 10:35:05 +0200 Subject: [PATCH 12/32] fix(api): fix invalid error message in endpoint creation handler (#2233) --- api/http/handler/endpoints/endpoint_create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/http/handler/endpoints/endpoint_create.go b/api/http/handler/endpoints/endpoint_create.go index 3ce3bd6d4..277f6bd0f 100644 --- a/api/http/handler/endpoints/endpoint_create.go +++ b/api/http/handler/endpoints/endpoint_create.go @@ -35,7 +35,7 @@ type endpointCreatePayload struct { func (payload *endpointCreatePayload) Validate(r *http.Request) error { name, err := request.RetrieveMultiPartFormValue(r, "Name", false) if err != nil { - return portainer.Error("Invalid stack name") + return portainer.Error("Invalid endpoint name") } payload.Name = name From 0efeeaf1858b3c0ff8fe03498479484ce024962c Mon Sep 17 00:00:00 2001 From: Kendrick Date: Mon, 3 Sep 2018 03:08:03 -0700 Subject: [PATCH 13/32] feat(webhooks): add support for service update webhooks (#2161) * Initial pass at adding webhook controller and routes * Moving some objects around * Cleaning up comments * Fixing syntax, switching to using the docker sdk over building an http client * Adding delete and list functionality * Updating the handler to use the correct permissions. Updating some comments * Fixing some comments * Code cleanup per pull request comments * Cleanup per PR feedback. Syntax error fix * Initial creation of webhook app code * Moving ClientFactory creation out of handler code and instead using the one created by the main process. Removing webhookInspect method and updating the list function to use json filters * Delete now works on the webhook ID vs service ID * WIP - Service creates a webhook. Display will show an existing webhook URL. * Adding the webhook field to the service view. There is now the ability to add or remove a webhook from a service * Moving all api calls to be webhooks vs webhook * Code cleanup. Moving all api calls to be webhooks vs webhook * More conversion of webhook to webhooks? * Moving UI elements around. Starting function for copying to clipboard * Finalizing function for copying to clipboard. Adding button that calls function and copies webhook to clipboard. * Fixing UI issues. Hiding field entirely when there is no webhook * Moving URL crafting to a helper method. The edit pane for service now creates/deletes webhooks immidiately. * style(service-details): update webhook line * feat(api): strip sha when updating an image via the update webhook * Fixing up some copy. Only displying the port if it is not http or https * Fixing tooltip copy. Setting the forceupdate to be true to require an update to occur * Fixing code climate errors * Adding WebhookType field and setting to ServiceWebhook for new webhooks. Renaming ServiceID to resourceID so future work can add new types of webhooks in other resource areas. * Adding the webhook type to the payload to support more types of webhooks in the future. Setting the type correctly when creating one for a service * feat(webhooks): changes related to webhook management * API code cleanup, removing unneeded functions, and updating validation logic * Incorrectly ignoring the error that the webhook did not exist * Re-adding missing error handling. Changing error response to be a 404 vs 500 when token can't find an object * fix(webhooks): close Docker client after service webhook execution --- api/bolt/datastore.go | 8 + api/bolt/webhook/webhook.go | 151 ++++++++++++++++++ api/cmd/portainer/main.go | 2 + api/errors.go | 6 + api/http/handler/handler.go | 4 + api/http/handler/webhooks/handler.go | 35 ++++ api/http/handler/webhooks/webhook_create.go | 66 ++++++++ api/http/handler/webhooks/webhook_delete.go | 25 +++ api/http/handler/webhooks/webhook_execute.go | 71 ++++++++ api/http/handler/webhooks/webhook_list.go | 47 ++++++ api/http/server.go | 10 ++ api/portainer.go | 31 ++++ app/constants.js | 1 + .../servicesDatatableActionsController.js | 11 +- .../create/createServiceController.js | 16 +- .../views/services/create/createservice.html | 16 ++ app/docker/views/services/edit/service.html | 20 ++- .../views/services/edit/serviceController.js | 47 +++++- app/portainer/helpers/webhookHelper.js | 13 ++ app/portainer/models/webhook.js | 7 + app/portainer/rest/webhooks.js | 10 ++ app/portainer/services/api/webhookService.js | 33 ++++ 22 files changed, 619 insertions(+), 11 deletions(-) create mode 100644 api/bolt/webhook/webhook.go create mode 100644 api/http/handler/webhooks/handler.go create mode 100644 api/http/handler/webhooks/webhook_create.go create mode 100644 api/http/handler/webhooks/webhook_delete.go create mode 100644 api/http/handler/webhooks/webhook_execute.go create mode 100644 api/http/handler/webhooks/webhook_list.go create mode 100644 app/portainer/helpers/webhookHelper.js create mode 100644 app/portainer/models/webhook.js create mode 100644 app/portainer/rest/webhooks.js create mode 100644 app/portainer/services/api/webhookService.js diff --git a/api/bolt/datastore.go b/api/bolt/datastore.go index a6a921acf..192bc0271 100644 --- a/api/bolt/datastore.go +++ b/api/bolt/datastore.go @@ -21,6 +21,7 @@ import ( "github.com/portainer/portainer/bolt/template" "github.com/portainer/portainer/bolt/user" "github.com/portainer/portainer/bolt/version" + "github.com/portainer/portainer/bolt/webhook" ) const ( @@ -47,6 +48,7 @@ type Store struct { TemplateService *template.Service UserService *user.Service VersionService *version.Service + WebhookService *webhook.Service } // NewStore initializes a new Store and the associated services @@ -232,5 +234,11 @@ func (store *Store) initServices() error { } store.VersionService = versionService + webhookService, err := webhook.NewService(store.db) + if err != nil { + return err + } + store.WebhookService = webhookService + return nil } diff --git a/api/bolt/webhook/webhook.go b/api/bolt/webhook/webhook.go new file mode 100644 index 000000000..94ebe61c5 --- /dev/null +++ b/api/bolt/webhook/webhook.go @@ -0,0 +1,151 @@ +package webhook + +import ( + "github.com/portainer/portainer" + "github.com/portainer/portainer/bolt/internal" + + "github.com/boltdb/bolt" +) + +const ( + // BucketName represents the name of the bucket where this service stores data. + BucketName = "webhooks" +) + +// Service represents a service for managing webhook data. +type Service struct { + db *bolt.DB +} + +// NewService creates a new instance of a service. +func NewService(db *bolt.DB) (*Service, error) { + err := internal.CreateBucket(db, BucketName) + if err != nil { + return nil, err + } + + return &Service{ + db: db, + }, nil +} + +//Webhooks returns an array of all webhooks +func (service *Service) Webhooks() ([]portainer.Webhook, error) { + var webhooks = make([]portainer.Webhook, 0) + + err := service.db.View(func(tx *bolt.Tx) error { + bucket := tx.Bucket([]byte(BucketName)) + + cursor := bucket.Cursor() + for k, v := cursor.First(); k != nil; k, v = cursor.Next() { + var webhook portainer.Webhook + err := internal.UnmarshalObject(v, &webhook) + if err != nil { + return err + } + webhooks = append(webhooks, webhook) + } + + return nil + }) + + return webhooks, err +} + +// Webhook returns a webhook by ID. +func (service *Service) Webhook(ID portainer.WebhookID) (*portainer.Webhook, error) { + var webhook portainer.Webhook + identifier := internal.Itob(int(ID)) + + err := internal.GetObject(service.db, BucketName, identifier, &webhook) + if err != nil { + return nil, err + } + + return &webhook, nil +} + +// WebhookByResourceID returns a webhook by the ResourceID it is associated with. +func (service *Service) WebhookByResourceID(ID string) (*portainer.Webhook, error) { + var webhook *portainer.Webhook + + err := service.db.View(func(tx *bolt.Tx) error { + bucket := tx.Bucket([]byte(BucketName)) + cursor := bucket.Cursor() + + for k, v := cursor.First(); k != nil; k, v = cursor.Next() { + var w portainer.Webhook + err := internal.UnmarshalObject(v, &w) + if err != nil { + return err + } + + if w.ResourceID == ID { + webhook = &w + break + } + } + + if webhook == nil { + return portainer.ErrObjectNotFound + } + + return nil + }) + + return webhook, err +} + +// WebhookByToken returns a webhook by the random token it is associated with. +func (service *Service) WebhookByToken(token string) (*portainer.Webhook, error) { + var webhook *portainer.Webhook + + err := service.db.View(func(tx *bolt.Tx) error { + bucket := tx.Bucket([]byte(BucketName)) + cursor := bucket.Cursor() + + for k, v := cursor.First(); k != nil; k, v = cursor.Next() { + var w portainer.Webhook + err := internal.UnmarshalObject(v, &w) + if err != nil { + return err + } + + if w.Token == token { + webhook = &w + break + } + } + + if webhook == nil { + return portainer.ErrObjectNotFound + } + + return nil + }) + + return webhook, err +} + +// DeleteWebhook deletes a webhook. +func (service *Service) DeleteWebhook(ID portainer.WebhookID) error { + identifier := internal.Itob(int(ID)) + return internal.DeleteObject(service.db, BucketName, identifier) +} + +// CreateWebhook assign an ID to a new webhook and saves it. +func (service *Service) CreateWebhook(webhook *portainer.Webhook) error { + return service.db.Update(func(tx *bolt.Tx) error { + bucket := tx.Bucket([]byte(BucketName)) + + id, _ := bucket.NextSequence() + webhook.ID = portainer.WebhookID(id) + + data, err := internal.MarshalObject(webhook) + if err != nil { + return err + } + + return bucket.Put(internal.Itob(int(webhook.ID)), data) + }) +} diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index c7997bf14..cecf986b7 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -505,6 +505,7 @@ func main() { StackService: store.StackService, TagService: store.TagService, TemplateService: store.TemplateService, + WebhookService: store.WebhookService, SwarmStackManager: swarmStackManager, ComposeStackManager: composeStackManager, CryptoService: cryptoService, @@ -518,6 +519,7 @@ func main() { SSL: *flags.SSL, SSLCert: *flags.SSLCert, SSLKey: *flags.SSLKey, + DockerClientFactory: clientFactory, } log.Printf("Starting Portainer %s on %s", portainer.APIVersion, *flags.Addr) diff --git a/api/errors.go b/api/errors.go index 37552f104..e348aaf48 100644 --- a/api/errors.go +++ b/api/errors.go @@ -93,3 +93,9 @@ type Error string // Error returns the error message. func (e Error) Error() string { return string(e) } + +// Webhook errors +const ( + ErrWebhookAlreadyExists = Error("A webhook for this resource already exists") + ErrUnsupportedWebhookType = Error("Webhooks for this resource are not currently supported") +) diff --git a/api/http/handler/handler.go b/api/http/handler/handler.go index 342230396..40ae9f57d 100644 --- a/api/http/handler/handler.go +++ b/api/http/handler/handler.go @@ -22,6 +22,7 @@ import ( "github.com/portainer/portainer/http/handler/templates" "github.com/portainer/portainer/http/handler/upload" "github.com/portainer/portainer/http/handler/users" + "github.com/portainer/portainer/http/handler/webhooks" "github.com/portainer/portainer/http/handler/websocket" ) @@ -47,6 +48,7 @@ type Handler struct { UploadHandler *upload.Handler UserHandler *users.Handler WebSocketHandler *websocket.Handler + WebhookHandler *webhooks.Handler } // ServeHTTP delegates a request to the appropriate subhandler. @@ -95,6 +97,8 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.StripPrefix("/api", h.TeamMembershipHandler).ServeHTTP(w, r) case strings.HasPrefix(r.URL.Path, "/api/websocket"): http.StripPrefix("/api", h.WebSocketHandler).ServeHTTP(w, r) + case strings.HasPrefix(r.URL.Path, "/api/webhooks"): + http.StripPrefix("/api", h.WebhookHandler).ServeHTTP(w, r) case strings.HasPrefix(r.URL.Path, "/"): h.FileHandler.ServeHTTP(w, r) } diff --git a/api/http/handler/webhooks/handler.go b/api/http/handler/webhooks/handler.go new file mode 100644 index 000000000..fe60f3fdb --- /dev/null +++ b/api/http/handler/webhooks/handler.go @@ -0,0 +1,35 @@ +package webhooks + +import ( + "net/http" + + "github.com/gorilla/mux" + portainer "github.com/portainer/portainer" + "github.com/portainer/portainer/docker" + httperror "github.com/portainer/portainer/http/error" + "github.com/portainer/portainer/http/security" +) + +// Handler is the HTTP handler used to handle webhook operations. +type Handler struct { + *mux.Router + WebhookService portainer.WebhookService + EndpointService portainer.EndpointService + DockerClientFactory *docker.ClientFactory +} + +// NewHandler creates a handler to manage settings operations. +func NewHandler(bouncer *security.RequestBouncer) *Handler { + h := &Handler{ + Router: mux.NewRouter(), + } + h.Handle("/webhooks", + bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.webhookCreate))).Methods(http.MethodPost) + h.Handle("/webhooks", + bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.webhookList))).Methods(http.MethodGet) + h.Handle("/webhooks/{id}", + bouncer.AuthenticatedAccess(httperror.LoggerHandler(h.webhookDelete))).Methods(http.MethodDelete) + h.Handle("/webhooks/{token}", + bouncer.PublicAccess(httperror.LoggerHandler(h.webhookExecute))).Methods(http.MethodPost) + return h +} diff --git a/api/http/handler/webhooks/webhook_create.go b/api/http/handler/webhooks/webhook_create.go new file mode 100644 index 000000000..c74db0c6e --- /dev/null +++ b/api/http/handler/webhooks/webhook_create.go @@ -0,0 +1,66 @@ +package webhooks + +import ( + "net/http" + + "github.com/asaskevich/govalidator" + "github.com/portainer/portainer" + httperror "github.com/portainer/portainer/http/error" + "github.com/portainer/portainer/http/request" + "github.com/portainer/portainer/http/response" + "github.com/satori/go.uuid" +) + +type webhookCreatePayload struct { + ResourceID string + EndpointID int + WebhookType int +} + +func (payload *webhookCreatePayload) Validate(r *http.Request) error { + if govalidator.IsNull(payload.ResourceID) { + return portainer.Error("Invalid ResourceID") + } + if payload.EndpointID == 0 { + return portainer.Error("Invalid EndpointID") + } + if payload.WebhookType != 1 { + return portainer.Error("Invalid WebhookType") + } + return nil +} + +func (handler *Handler) webhookCreate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { + var payload webhookCreatePayload + err := request.DecodeAndValidateJSONPayload(r, &payload) + if err != nil { + return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err} + } + + webhook, err := handler.WebhookService.WebhookByResourceID(payload.ResourceID) + if err != nil && err != portainer.ErrObjectNotFound { + return &httperror.HandlerError{http.StatusInternalServerError, "An error occurred retrieving webhooks from the database", err} + } + if webhook != nil { + return &httperror.HandlerError{http.StatusConflict, "A webhook for this resource already exists", portainer.ErrWebhookAlreadyExists} + } + + token, err := uuid.NewV4() + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Error creating unique token", err} + } + + webhook = &portainer.Webhook{ + Token: token.String(), + ResourceID: payload.ResourceID, + EndpointID: portainer.EndpointID(payload.EndpointID), + WebhookType: portainer.WebhookType(payload.WebhookType), + } + + err = handler.WebhookService.CreateWebhook(webhook) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist the webhook inside the database", err} + } + + return response.JSON(w, webhook) +} diff --git a/api/http/handler/webhooks/webhook_delete.go b/api/http/handler/webhooks/webhook_delete.go new file mode 100644 index 000000000..b81a445e1 --- /dev/null +++ b/api/http/handler/webhooks/webhook_delete.go @@ -0,0 +1,25 @@ +package webhooks + +import ( + "net/http" + + "github.com/portainer/portainer" + httperror "github.com/portainer/portainer/http/error" + "github.com/portainer/portainer/http/request" + "github.com/portainer/portainer/http/response" +) + +// DELETE request on /api/webhook/:serviceID +func (handler *Handler) webhookDelete(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { + id, err := request.RetrieveNumericRouteVariableValue(r, "id") + if err != nil { + return &httperror.HandlerError{http.StatusBadRequest, "Invalid webhook id", err} + } + + err = handler.WebhookService.DeleteWebhook(portainer.WebhookID(id)) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to remove the webhook from the database", err} + } + + return response.Empty(w) +} diff --git a/api/http/handler/webhooks/webhook_execute.go b/api/http/handler/webhooks/webhook_execute.go new file mode 100644 index 000000000..395be9999 --- /dev/null +++ b/api/http/handler/webhooks/webhook_execute.go @@ -0,0 +1,71 @@ +package webhooks + +import ( + "context" + "net/http" + "strings" + + dockertypes "github.com/docker/docker/api/types" + "github.com/portainer/portainer" + httperror "github.com/portainer/portainer/http/error" + "github.com/portainer/portainer/http/request" + "github.com/portainer/portainer/http/response" +) + +// Acts on a passed in token UUID to restart the docker service +func (handler *Handler) webhookExecute(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { + + webhookToken, err := request.RetrieveRouteVariableValue(r, "token") + + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Invalid service id parameter", err} + } + + webhook, err := handler.WebhookService.WebhookByToken(webhookToken) + + if err == portainer.ErrObjectNotFound { + return &httperror.HandlerError{http.StatusNotFound, "Unable to find a webhook with this token", err} + } else if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve webhook from the database", err} + } + + resourceID := webhook.ResourceID + endpointID := webhook.EndpointID + webhookType := webhook.WebhookType + + endpoint, err := handler.EndpointService.Endpoint(portainer.EndpointID(endpointID)) + if err == portainer.ErrObjectNotFound { + return &httperror.HandlerError{http.StatusNotFound, "Unable to find an endpoint with the specified identifier inside the database", err} + } else if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err} + } + switch webhookType { + case portainer.ServiceWebhook: + return handler.executeServiceWebhook(w, endpoint, resourceID) + default: + return &httperror.HandlerError{http.StatusInternalServerError, "Unsupported webhook type", portainer.ErrUnsupportedWebhookType} + } + +} + +func (handler *Handler) executeServiceWebhook(w http.ResponseWriter, endpoint *portainer.Endpoint, resourceID string) *httperror.HandlerError { + dockerClient, err := handler.DockerClientFactory.CreateClient(endpoint) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Error creating docker client", err} + } + defer dockerClient.Close() + + service, _, err := dockerClient.ServiceInspectWithRaw(context.Background(), resourceID, dockertypes.ServiceInspectOptions{InsertDefaults: true}) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Error looking up service", err} + } + + service.Spec.TaskTemplate.ForceUpdate++ + + service.Spec.TaskTemplate.ContainerSpec.Image = strings.Split(service.Spec.TaskTemplate.ContainerSpec.Image, "@sha")[0] + _, err = dockerClient.ServiceUpdate(context.Background(), resourceID, service.Version, service.Spec, dockertypes.ServiceUpdateOptions{QueryRegistry: true}) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Error updating service", err} + } + return response.Empty(w) +} diff --git a/api/http/handler/webhooks/webhook_list.go b/api/http/handler/webhooks/webhook_list.go new file mode 100644 index 000000000..288bdcd65 --- /dev/null +++ b/api/http/handler/webhooks/webhook_list.go @@ -0,0 +1,47 @@ +package webhooks + +import ( + "net/http" + + "github.com/portainer/portainer" + httperror "github.com/portainer/portainer/http/error" + "github.com/portainer/portainer/http/request" + "github.com/portainer/portainer/http/response" +) + +type webhookListOperationFilters struct { + ResourceID string `json:"ResourceID"` + EndpointID int `json:"EndpointID"` +} + +// GET request on /api/webhooks?(filters=) +func (handler *Handler) webhookList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { + var filters webhookListOperationFilters + err := request.RetrieveJSONQueryParameter(r, "filters", &filters, true) + if err != nil { + return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: filters", err} + } + + webhooks, err := handler.WebhookService.Webhooks() + webhooks = filterWebhooks(webhooks, &filters) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve webhooks from the database", err} + } + + return response.JSON(w, webhooks) +} + +func filterWebhooks(webhooks []portainer.Webhook, filters *webhookListOperationFilters) []portainer.Webhook { + if filters.EndpointID == 0 && filters.ResourceID == "" { + return webhooks + } + + filteredWebhooks := make([]portainer.Webhook, 0, len(webhooks)) + for _, webhook := range webhooks { + if webhook.EndpointID == portainer.EndpointID(filters.EndpointID) && webhook.ResourceID == string(filters.ResourceID) { + filteredWebhooks = append(filteredWebhooks, webhook) + } + } + + return filteredWebhooks +} diff --git a/api/http/server.go b/api/http/server.go index 116a6c1ec..b9f1f2bb7 100644 --- a/api/http/server.go +++ b/api/http/server.go @@ -4,6 +4,7 @@ import ( "time" "github.com/portainer/portainer" + "github.com/portainer/portainer/docker" "github.com/portainer/portainer/http/handler" "github.com/portainer/portainer/http/handler/auth" "github.com/portainer/portainer/http/handler/dockerhub" @@ -23,6 +24,7 @@ import ( "github.com/portainer/portainer/http/handler/templates" "github.com/portainer/portainer/http/handler/upload" "github.com/portainer/portainer/http/handler/users" + "github.com/portainer/portainer/http/handler/webhooks" "github.com/portainer/portainer/http/handler/websocket" "github.com/portainer/portainer/http/proxy" "github.com/portainer/portainer/http/security" @@ -60,10 +62,12 @@ type Server struct { TeamMembershipService portainer.TeamMembershipService TemplateService portainer.TemplateService UserService portainer.UserService + WebhookService portainer.WebhookService Handler *handler.Handler SSL bool SSLCert string SSLKey string + DockerClientFactory *docker.ClientFactory } // Start starts the HTTP server @@ -171,6 +175,11 @@ func (server *Server) Start() error { websocketHandler.EndpointService = server.EndpointService websocketHandler.SignatureService = server.SignatureService + var webhookHandler = webhooks.NewHandler(requestBouncer) + webhookHandler.WebhookService = server.WebhookService + webhookHandler.EndpointService = server.EndpointService + webhookHandler.DockerClientFactory = server.DockerClientFactory + server.Handler = &handler.Handler{ AuthHandler: authHandler, DockerHubHandler: dockerHubHandler, @@ -191,6 +200,7 @@ func (server *Server) Start() error { UploadHandler: uploadHandler, UserHandler: userHandler, WebSocketHandler: websocketHandler, + WebhookHandler: webhookHandler, } if server.SSL { diff --git a/api/portainer.go b/api/portainer.go index 49f87c652..839abea7a 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -220,6 +220,21 @@ type ( TLSKeyPath string `json:"TLSKey,omitempty"` } + // WebhookID represents an webhook identifier. + WebhookID int + + // WebhookType represents the type of resource a webhook is related to + WebhookType int + + // Webhook represents a url webhook that can be used to update a service + Webhook struct { + ID WebhookID `json:"Id"` + Token string `json:"Token"` + ResourceID string `json:"ResourceId"` + EndpointID EndpointID `json:"EndpointId"` + WebhookType WebhookType `json:"Type"` + } + // AzureCredentials represents the credentials used to connect to an Azure // environment. AzureCredentials struct { @@ -506,6 +521,16 @@ type ( StoreDBVersion(version int) error } + // WebhookService represents a service for managing webhook data. + WebhookService interface { + Webhooks() ([]Webhook, error) + Webhook(ID WebhookID) (*Webhook, error) + CreateWebhook(portainer *Webhook) error + WebhookByResourceID(resourceID string) (*Webhook, error) + WebhookByToken(token string) (*Webhook, error) + DeleteWebhook(serviceID WebhookID) error + } + // ResourceControlService represents a service for managing resource control data ResourceControlService interface { ResourceControl(ID ResourceControlID) (*ResourceControl, error) @@ -732,3 +757,9 @@ const ( // EndpointStatusDown is used to represent an unavailable endpoint EndpointStatusDown ) + +const ( + _ WebhookType = iota + // ServiceWebhook is a webhook for restarting a docker service + ServiceWebhook +) diff --git a/app/constants.js b/app/constants.js index de9631ddd..b20d44649 100644 --- a/app/constants.js +++ b/app/constants.js @@ -14,6 +14,7 @@ angular.module('portainer') .constant('API_ENDPOINT_TEAMS', 'api/teams') .constant('API_ENDPOINT_TEAM_MEMBERSHIPS', 'api/team_memberships') .constant('API_ENDPOINT_TEMPLATES', 'api/templates') +.constant('API_ENDPOINT_WEBHOOKS', 'api/webhooks') .constant('DEFAULT_TEMPLATES_URL', 'https://raw.githubusercontent.com/portainer/templates/master/templates.json') .constant('PAGINATION_MAX_ITEMS', 10) .constant('APPLICATION_CACHE_VALIDITY', 3600) diff --git a/app/docker/components/datatables/services-datatable/actions/servicesDatatableActionsController.js b/app/docker/components/datatables/services-datatable/actions/servicesDatatableActionsController.js index dff0d034c..2f5ce7ce4 100644 --- a/app/docker/components/datatables/services-datatable/actions/servicesDatatableActionsController.js +++ b/app/docker/components/datatables/services-datatable/actions/servicesDatatableActionsController.js @@ -1,6 +1,6 @@ angular.module('portainer.docker') -.controller('ServicesDatatableActionsController', ['$state', 'ServiceService', 'ServiceHelper', 'Notifications', 'ModalService', 'ImageHelper', -function ($state, ServiceService, ServiceHelper, Notifications, ModalService, ImageHelper) { +.controller('ServicesDatatableActionsController', ['$q', '$state', 'ServiceService', 'ServiceHelper', 'Notifications', 'ModalService', 'ImageHelper','WebhookService','EndpointProvider', +function ($q, $state, ServiceService, ServiceHelper, Notifications, ModalService, ImageHelper, WebhookService, EndpointProvider) { this.scaleAction = function scaleService(service) { var config = ServiceHelper.serviceToConfig(service.Model); @@ -71,7 +71,14 @@ function ($state, ServiceService, ServiceHelper, Notifications, ModalService, Im function removeServices(services) { var actionCount = services.length; angular.forEach(services, function (service) { + ServiceService.remove(service) + .then(function success() { + return WebhookService.webhooks(service.Id, EndpointProvider.endpointID()); + }) + .then(function success(data) { + return $q.when(data.length !== 0 && WebhookService.deleteWebhook(data[0].Id)); + }) .then(function success() { Notifications.success('Service successfully removed', service.Name); }) diff --git a/app/docker/views/services/create/createServiceController.js b/app/docker/views/services/create/createServiceController.js index e56dc1e4c..9f69ad0b5 100644 --- a/app/docker/views/services/create/createServiceController.js +++ b/app/docker/views/services/create/createServiceController.js @@ -1,6 +1,6 @@ -angular.module('portainer.docker') -.controller('CreateServiceController', ['$q', '$scope', '$state', '$timeout', 'Service', 'ServiceHelper', 'ConfigService', 'ConfigHelper', 'SecretHelper', 'SecretService', 'VolumeService', 'NetworkService', 'ImageHelper', 'LabelHelper', 'Authentication', 'ResourceControlService', 'Notifications', 'FormValidator', 'PluginService', 'RegistryService', 'HttpRequestHelper', 'NodeService', 'SettingsService', -function ($q, $scope, $state, $timeout, Service, ServiceHelper, ConfigService, ConfigHelper, SecretHelper, SecretService, VolumeService, NetworkService, ImageHelper, LabelHelper, Authentication, ResourceControlService, Notifications, FormValidator, PluginService, RegistryService, HttpRequestHelper, NodeService, SettingsService) { + angular.module('portainer.docker') +.controller('CreateServiceController', ['$q', '$scope', '$state', '$timeout', 'Service', 'ServiceHelper', 'ConfigService', 'ConfigHelper', 'SecretHelper', 'SecretService', 'VolumeService', 'NetworkService', 'ImageHelper', 'LabelHelper', 'Authentication', 'ResourceControlService', 'Notifications', 'FormValidator', 'PluginService', 'RegistryService', 'HttpRequestHelper', 'NodeService', 'SettingsService', 'WebhookService','EndpointProvider', +function ($q, $scope, $state, $timeout, Service, ServiceHelper, ConfigService, ConfigHelper, SecretHelper, SecretService, VolumeService, NetworkService, ImageHelper, LabelHelper, Authentication, ResourceControlService, Notifications, FormValidator, PluginService, RegistryService, HttpRequestHelper, NodeService, SettingsService, WebhookService,EndpointProvider) { $scope.formValues = { Name: '', @@ -40,7 +40,8 @@ function ($q, $scope, $state, $timeout, Service, ServiceHelper, ConfigService, C RestartMaxAttempts: 0, RestartWindow: '0s', LogDriverName: '', - LogDriverOpts: [] + LogDriverOpts: [], + Webhook: false }; $scope.state = { @@ -422,9 +423,14 @@ function ($q, $scope, $state, $timeout, Service, ServiceHelper, ConfigService, C var registry = $scope.formValues.Registry; var authenticationDetails = registry.Authentication ? RegistryService.encodedCredentials(registry) : ''; HttpRequestHelper.setRegistryAuthenticationHeader(authenticationDetails); + + var serviceIdentifier; Service.create(config).$promise .then(function success(data) { - var serviceIdentifier = data.ID; + serviceIdentifier = data.ID; + return $q.when($scope.formValues.Webhook && WebhookService.createServiceWebhook(serviceIdentifier, EndpointProvider.endpointID())); + }) + .then(function success() { var userId = Authentication.getUserDetails().ID; return ResourceControlService.applyResourceControl('service', serviceIdentifier, userId, accessControlData, []); }) diff --git a/app/docker/views/services/create/createservice.html b/app/docker/views/services/create/createservice.html index d9481adb1..40d830f1a 100644 --- a/app/docker/views/services/create/createservice.html +++ b/app/docker/views/services/create/createservice.html @@ -101,6 +101,22 @@
+ +
+ Webhooks +
+
+
+ + +
+
+ diff --git a/app/docker/views/services/edit/service.html b/app/docker/views/services/edit/service.html index e0b2b49de..0b3e2e854 100644 --- a/app/docker/views/services/edit/service.html +++ b/app/docker/views/services/edit/service.html @@ -71,6 +71,24 @@ ng-model="service.Image" ng-change="updateServiceAttribute(service, 'Image')" id="image_name" ng-disabled="isUpdating"> +
+ + +
+ Service webhook + + + + {{ webhookURL | truncatelr }} + + + + +
Service logs @@ -93,7 +111,7 @@

-
-
- - Current password is not valid -
-
diff --git a/app/portainer/views/account/accountController.js b/app/portainer/views/account/accountController.js index 304fd2586..c3ef8402b 100644 --- a/app/portainer/views/account/accountController.js +++ b/app/portainer/views/account/accountController.js @@ -8,19 +8,13 @@ function ($scope, $state, Authentication, UserService, Notifications, SettingsSe }; $scope.updatePassword = function() { - $scope.invalidPassword = false; - UserService.updateUserPassword($scope.userID, $scope.formValues.currentPassword, $scope.formValues.newPassword) .then(function success() { Notifications.success('Success', 'Password successfully updated'); $state.reload(); }) .catch(function error(err) { - if (err.invalidPassword) { - $scope.invalidPassword = true; - } else { - Notifications.error('Failure', err, err.msg); - } + Notifications.error('Failure', err, err.msg); }); }; diff --git a/app/portainer/views/auth/authController.js b/app/portainer/views/auth/authController.js index 3b18d600c..055d359be 100644 --- a/app/portainer/views/auth/authController.js +++ b/app/portainer/views/auth/authController.js @@ -30,7 +30,7 @@ function ($q, $scope, $state, $transition$, $sanitize, Authentication, UserServi return $q.reject(); }) .then(function success() { - $state.go('portainer.updatePassword', { password: $sanitize(password) }); + $state.go('portainer.updatePassword'); }) .catch(function error() { $scope.state.AuthenticationError = 'Invalid credentials'; diff --git a/app/portainer/views/update-password/updatePassword.html b/app/portainer/views/update-password/updatePassword.html index 62c726a61..0f9d10acd 100644 --- a/app/portainer/views/update-password/updatePassword.html +++ b/app/portainer/views/update-password/updatePassword.html @@ -15,11 +15,19 @@
+ +
+ +
+ +
+
+
- +
diff --git a/app/portainer/views/update-password/updatePasswordController.js b/app/portainer/views/update-password/updatePasswordController.js index 6809d1a34..991bf6f33 100644 --- a/app/portainer/views/update-password/updatePasswordController.js +++ b/app/portainer/views/update-password/updatePasswordController.js @@ -1,22 +1,22 @@ angular.module('portainer.app') -.controller('UpdatePasswordController', ['$scope', '$state', '$transition$', 'UserService', 'Authentication', 'Notifications', -function UpdatePasswordController($scope, $state, $transition$, UserService, Authentication, Notifications) { +.controller('UpdatePasswordController', ['$scope', '$state', '$transition$', '$sanitize', 'UserService', 'Authentication', 'Notifications', +function UpdatePasswordController($scope, $state, $transition$, $sanitize, UserService, Authentication, Notifications) { $scope.formValues = { + CurrentPassword: '', Password: '', ConfirmPassword: '' }; $scope.state = { - actionInProgress: false, - currentPassword: '' + actionInProgress: false }; $scope.updatePassword = function() { var userId = Authentication.getUserDetails().ID; $scope.state.actionInProgress = true; - UserService.updateUserPassword(userId, $scope.state.currentPassword, $scope.formValues.Password) + UserService.updateUserPassword(userId, $sanitize($scope.formValues.CurrentPassword), $scope.formValues.Password) .then(function success() { $state.go('portainer.home'); }) @@ -32,8 +32,6 @@ function UpdatePasswordController($scope, $state, $transition$, UserService, Aut if (!Authentication.isAuthenticated()) { $state.go('portainer.auth'); } - - $scope.state.currentPassword = $transition$.params().password; } initView(); From 42f5aec6a544941e5c84d8b357fa1ea7650c0e20 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Fri, 7 Sep 2018 11:24:18 +0200 Subject: [PATCH 17/32] feat(container-console): increase hijacked tcp connection reader size (#2259) --- api/http/handler/websocket/websocket_exec.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/http/handler/websocket/websocket_exec.go b/api/http/handler/websocket/websocket_exec.go index 80c62b9d9..58d734072 100644 --- a/api/http/handler/websocket/websocket_exec.go +++ b/api/http/handler/websocket/websocket_exec.go @@ -252,7 +252,7 @@ func streamFromWebsocketConnToTCPConn(websocketConn *websocket.Conn, tcpConn net func streamFromTCPConnToWebsocketConn(websocketConn *websocket.Conn, br *bufio.Reader, errorChan chan error) { for { - out := make([]byte, 1024) + out := make([]byte, 2048) _, err := br.Read(out) if err != nil { errorChan <- err From b24891a6bc57bc76faf73d3566260de04dc219f4 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Mon, 10 Sep 2018 12:01:38 +0200 Subject: [PATCH 18/32] refactor(api): introduce libhttp usage (#2263) --- api/http/error/error.go | 42 ----- api/http/handler/auth/authenticate.go | 6 +- api/http/handler/auth/handler.go | 2 +- .../handler/dockerhub/dockerhub_inspect.go | 4 +- .../handler/dockerhub/dockerhub_update.go | 6 +- api/http/handler/dockerhub/handler.go | 2 +- .../endpointgroups/endpointgroup_create.go | 6 +- .../endpointgroups/endpointgroup_delete.go | 6 +- .../endpointgroups/endpointgroup_inspect.go | 6 +- .../endpointgroups/endpointgroup_list.go | 4 +- .../endpointgroups/endpointgroup_update.go | 6 +- .../endpointgroup_update_access.go | 6 +- api/http/handler/endpointgroups/handler.go | 2 +- api/http/handler/endpointproxy/handler.go | 2 +- api/http/handler/endpointproxy/proxy_azure.go | 4 +- .../handler/endpointproxy/proxy_docker.go | 4 +- .../handler/endpointproxy/proxy_storidge.go | 4 +- api/http/handler/endpoints/endpoint_create.go | 12 +- api/http/handler/endpoints/endpoint_delete.go | 6 +- .../endpoints/endpoint_extension_add.go | 6 +- .../endpoints/endpoint_extension_remove.go | 6 +- .../handler/endpoints/endpoint_inspect.go | 6 +- api/http/handler/endpoints/endpoint_list.go | 4 +- .../handler/endpoints/endpoint_snapshot.go | 4 +- api/http/handler/endpoints/endpoint_update.go | 6 +- .../endpoints/endpoint_update_access.go | 6 +- api/http/handler/endpoints/handler.go | 2 +- api/http/handler/motd/motd.go | 2 +- api/http/handler/registries/handler.go | 2 +- .../handler/registries/registry_create.go | 6 +- .../handler/registries/registry_delete.go | 6 +- .../handler/registries/registry_inspect.go | 6 +- api/http/handler/registries/registry_list.go | 4 +- .../handler/registries/registry_update.go | 6 +- .../registries/registry_update_access.go | 6 +- api/http/handler/resourcecontrols/handler.go | 2 +- .../resourcecontrol_create.go | 6 +- .../resourcecontrol_delete.go | 6 +- .../resourcecontrol_update.go | 6 +- api/http/handler/settings/handler.go | 2 +- api/http/handler/settings/settings_inspect.go | 4 +- .../handler/settings/settings_ldap_check.go | 6 +- api/http/handler/settings/settings_public.go | 4 +- api/http/handler/settings/settings_update.go | 6 +- .../handler/stacks/create_compose_stack.go | 8 +- api/http/handler/stacks/create_swarm_stack.go | 8 +- api/http/handler/stacks/handler.go | 2 +- api/http/handler/stacks/stack_create.go | 11 +- api/http/handler/stacks/stack_delete.go | 6 +- api/http/handler/stacks/stack_file.go | 6 +- api/http/handler/stacks/stack_inspect.go | 6 +- api/http/handler/stacks/stack_list.go | 6 +- api/http/handler/stacks/stack_migrate.go | 6 +- api/http/handler/stacks/stack_update.go | 6 +- api/http/handler/status/handler.go | 2 +- api/http/handler/status/status_inspect.go | 4 +- api/http/handler/tags/handler.go | 2 +- api/http/handler/tags/tag_create.go | 6 +- api/http/handler/tags/tag_delete.go | 6 +- api/http/handler/tags/tag_list.go | 4 +- api/http/handler/teammemberships/handler.go | 2 +- .../teammemberships/teammembership_create.go | 6 +- .../teammemberships/teammembership_delete.go | 6 +- .../teammemberships/teammembership_list.go | 4 +- .../teammemberships/teammembership_update.go | 6 +- api/http/handler/teams/handler.go | 2 +- api/http/handler/teams/team_create.go | 6 +- api/http/handler/teams/team_delete.go | 6 +- api/http/handler/teams/team_inspect.go | 6 +- api/http/handler/teams/team_list.go | 4 +- api/http/handler/teams/team_memberships.go | 6 +- api/http/handler/teams/team_update.go | 6 +- api/http/handler/templates/handler.go | 2 +- api/http/handler/templates/template_create.go | 6 +- api/http/handler/templates/template_delete.go | 6 +- .../handler/templates/template_inspect.go | 6 +- api/http/handler/templates/template_list.go | 4 +- api/http/handler/templates/template_update.go | 6 +- api/http/handler/upload/handler.go | 2 +- api/http/handler/upload/upload_tls.go | 8 +- api/http/handler/users/admin_check.go | 4 +- api/http/handler/users/admin_init.go | 6 +- api/http/handler/users/handler.go | 2 +- api/http/handler/users/user_create.go | 6 +- api/http/handler/users/user_delete.go | 6 +- api/http/handler/users/user_inspect.go | 6 +- api/http/handler/users/user_list.go | 4 +- api/http/handler/users/user_memberships.go | 6 +- api/http/handler/users/user_update.go | 6 +- .../handler/users/user_update_password.go | 6 +- api/http/handler/webhooks/handler.go | 2 +- api/http/handler/webhooks/webhook_create.go | 6 +- api/http/handler/webhooks/webhook_delete.go | 6 +- api/http/handler/webhooks/webhook_execute.go | 6 +- api/http/handler/webhooks/webhook_list.go | 6 +- api/http/handler/websocket/handler.go | 2 +- api/http/handler/websocket/websocket_exec.go | 4 +- api/http/proxy/local.go | 2 +- api/http/request/request.go | 163 ------------------ api/http/response/response.go | 25 --- api/http/security/bouncer.go | 2 +- api/http/security/rate_limiter.go | 2 +- 102 files changed, 244 insertions(+), 473 deletions(-) delete mode 100644 api/http/error/error.go delete mode 100644 api/http/request/request.go delete mode 100644 api/http/response/response.go diff --git a/api/http/error/error.go b/api/http/error/error.go deleted file mode 100644 index 244397fdf..000000000 --- a/api/http/error/error.go +++ /dev/null @@ -1,42 +0,0 @@ -package error - -import ( - "encoding/json" - "log" - "net/http" -) - -type ( - // LoggerHandler defines a HTTP handler that includes a HandlerError return pointer - LoggerHandler func(http.ResponseWriter, *http.Request) *HandlerError - // HandlerError represents an error raised inside a HTTP handler - HandlerError struct { - StatusCode int - Message string - Err error - } - errorResponse struct { - Err string `json:"err,omitempty"` - Details string `json:"details,omitempty"` - } -) - -func (handler LoggerHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) { - err := handler(rw, r) - if err != nil { - writeErrorResponse(rw, err) - } -} - -func writeErrorResponse(rw http.ResponseWriter, err *HandlerError) { - log.Printf("http error: %s (err=%s) (code=%d)\n", err.Message, err.Err, err.StatusCode) - rw.Header().Set("Content-Type", "application/json") - rw.WriteHeader(err.StatusCode) - json.NewEncoder(rw).Encode(&errorResponse{Err: err.Message, Details: err.Err.Error()}) -} - -// WriteError is a convenience function that creates a new HandlerError before calling writeErrorResponse. -// For use outside of the standard http handlers. -func WriteError(rw http.ResponseWriter, code int, message string, err error) { - writeErrorResponse(rw, &HandlerError{code, message, err}) -} diff --git a/api/http/handler/auth/authenticate.go b/api/http/handler/auth/authenticate.go index cf928357b..d5562edd3 100644 --- a/api/http/handler/auth/authenticate.go +++ b/api/http/handler/auth/authenticate.go @@ -6,10 +6,10 @@ import ( "strings" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type authenticatePayload struct { diff --git a/api/http/handler/auth/handler.go b/api/http/handler/auth/handler.go index 87be85429..1f0769e08 100644 --- a/api/http/handler/auth/handler.go +++ b/api/http/handler/auth/handler.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/gorilla/mux" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/dockerhub/dockerhub_inspect.go b/api/http/handler/dockerhub/dockerhub_inspect.go index 25be6617c..b149a2a35 100644 --- a/api/http/handler/dockerhub/dockerhub_inspect.go +++ b/api/http/handler/dockerhub/dockerhub_inspect.go @@ -3,8 +3,8 @@ package dockerhub import ( "net/http" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" ) // GET request on /api/dockerhub diff --git a/api/http/handler/dockerhub/dockerhub_update.go b/api/http/handler/dockerhub/dockerhub_update.go index 7bd37bce5..69d82ee50 100644 --- a/api/http/handler/dockerhub/dockerhub_update.go +++ b/api/http/handler/dockerhub/dockerhub_update.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type dockerhubUpdatePayload struct { diff --git a/api/http/handler/dockerhub/handler.go b/api/http/handler/dockerhub/handler.go index cd2f5ae50..9ad93232d 100644 --- a/api/http/handler/dockerhub/handler.go +++ b/api/http/handler/dockerhub/handler.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/gorilla/mux" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/endpointgroups/endpointgroup_create.go b/api/http/handler/endpointgroups/endpointgroup_create.go index e2d7bd0c0..cc7a23054 100644 --- a/api/http/handler/endpointgroups/endpointgroup_create.go +++ b/api/http/handler/endpointgroups/endpointgroup_create.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type endpointGroupCreatePayload struct { diff --git a/api/http/handler/endpointgroups/endpointgroup_delete.go b/api/http/handler/endpointgroups/endpointgroup_delete.go index 01123d850..b436b4f2f 100644 --- a/api/http/handler/endpointgroups/endpointgroup_delete.go +++ b/api/http/handler/endpointgroups/endpointgroup_delete.go @@ -3,10 +3,10 @@ package endpointgroups import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // DELETE request on /api/endpoint_groups/:id diff --git a/api/http/handler/endpointgroups/endpointgroup_inspect.go b/api/http/handler/endpointgroups/endpointgroup_inspect.go index 168d8cb8b..46a6895e8 100644 --- a/api/http/handler/endpointgroups/endpointgroup_inspect.go +++ b/api/http/handler/endpointgroups/endpointgroup_inspect.go @@ -3,10 +3,10 @@ package endpointgroups import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // GET request on /api/endpoint_groups/:id diff --git a/api/http/handler/endpointgroups/endpointgroup_list.go b/api/http/handler/endpointgroups/endpointgroup_list.go index fa7a35ec4..7acb696a8 100644 --- a/api/http/handler/endpointgroups/endpointgroup_list.go +++ b/api/http/handler/endpointgroups/endpointgroup_list.go @@ -3,8 +3,8 @@ package endpointgroups import ( "net/http" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/endpointgroups/endpointgroup_update.go b/api/http/handler/endpointgroups/endpointgroup_update.go index ee31e3066..ec24b801f 100644 --- a/api/http/handler/endpointgroups/endpointgroup_update.go +++ b/api/http/handler/endpointgroups/endpointgroup_update.go @@ -3,10 +3,10 @@ package endpointgroups import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type endpointGroupUpdatePayload struct { diff --git a/api/http/handler/endpointgroups/endpointgroup_update_access.go b/api/http/handler/endpointgroups/endpointgroup_update_access.go index 7a3b3038e..6e859a4df 100644 --- a/api/http/handler/endpointgroups/endpointgroup_update_access.go +++ b/api/http/handler/endpointgroups/endpointgroup_update_access.go @@ -3,10 +3,10 @@ package endpointgroups import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type endpointGroupUpdateAccessPayload struct { diff --git a/api/http/handler/endpointgroups/handler.go b/api/http/handler/endpointgroups/handler.go index f31a40a27..3b731e911 100644 --- a/api/http/handler/endpointgroups/handler.go +++ b/api/http/handler/endpointgroups/handler.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/gorilla/mux" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/endpointproxy/handler.go b/api/http/handler/endpointproxy/handler.go index cd17e0733..eaef36b1b 100644 --- a/api/http/handler/endpointproxy/handler.go +++ b/api/http/handler/endpointproxy/handler.go @@ -2,8 +2,8 @@ package endpointproxy import ( "github.com/gorilla/mux" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/proxy" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/endpointproxy/proxy_azure.go b/api/http/handler/endpointproxy/proxy_azure.go index dc46bfb3f..dcbe96f4b 100644 --- a/api/http/handler/endpointproxy/proxy_azure.go +++ b/api/http/handler/endpointproxy/proxy_azure.go @@ -3,9 +3,9 @@ package endpointproxy import ( "strconv" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" "net/http" ) diff --git a/api/http/handler/endpointproxy/proxy_docker.go b/api/http/handler/endpointproxy/proxy_docker.go index 01a56e017..f03ca8e67 100644 --- a/api/http/handler/endpointproxy/proxy_docker.go +++ b/api/http/handler/endpointproxy/proxy_docker.go @@ -3,9 +3,9 @@ package endpointproxy import ( "strconv" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" "net/http" ) diff --git a/api/http/handler/endpointproxy/proxy_storidge.go b/api/http/handler/endpointproxy/proxy_storidge.go index a582b561d..86375f091 100644 --- a/api/http/handler/endpointproxy/proxy_storidge.go +++ b/api/http/handler/endpointproxy/proxy_storidge.go @@ -3,9 +3,9 @@ package endpointproxy import ( "strconv" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" "net/http" ) diff --git a/api/http/handler/endpoints/endpoint_create.go b/api/http/handler/endpoints/endpoint_create.go index 277f6bd0f..a3eeeb114 100644 --- a/api/http/handler/endpoints/endpoint_create.go +++ b/api/http/handler/endpoints/endpoint_create.go @@ -6,12 +6,12 @@ import ( "runtime" "strconv" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" "github.com/portainer/portainer/crypto" "github.com/portainer/portainer/http/client" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type endpointCreatePayload struct { @@ -71,7 +71,7 @@ func (payload *endpointCreatePayload) Validate(r *http.Request) error { payload.TLSSkipClientVerify = skipTLSClientVerification if !payload.TLSSkipVerify { - caCert, err := request.RetrieveMultiPartFormFile(r, "TLSCACertFile") + caCert, _, err := request.RetrieveMultiPartFormFile(r, "TLSCACertFile") if err != nil { return portainer.Error("Invalid CA certificate file. Ensure that the file is uploaded correctly") } @@ -79,13 +79,13 @@ func (payload *endpointCreatePayload) Validate(r *http.Request) error { } if !payload.TLSSkipClientVerify { - cert, err := request.RetrieveMultiPartFormFile(r, "TLSCertFile") + cert, _, err := request.RetrieveMultiPartFormFile(r, "TLSCertFile") if err != nil { return portainer.Error("Invalid certificate file. Ensure that the file is uploaded correctly") } payload.TLSCertFile = cert - key, err := request.RetrieveMultiPartFormFile(r, "TLSKeyFile") + key, _, err := request.RetrieveMultiPartFormFile(r, "TLSKeyFile") if err != nil { return portainer.Error("Invalid key file. Ensure that the file is uploaded correctly") } diff --git a/api/http/handler/endpoints/endpoint_delete.go b/api/http/handler/endpoints/endpoint_delete.go index 40f18f348..865c2055b 100644 --- a/api/http/handler/endpoints/endpoint_delete.go +++ b/api/http/handler/endpoints/endpoint_delete.go @@ -4,10 +4,10 @@ import ( "net/http" "strconv" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // DELETE request on /api/endpoints/:id diff --git a/api/http/handler/endpoints/endpoint_extension_add.go b/api/http/handler/endpoints/endpoint_extension_add.go index 009083190..9a9eebbda 100644 --- a/api/http/handler/endpoints/endpoint_extension_add.go +++ b/api/http/handler/endpoints/endpoint_extension_add.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type endpointExtensionAddPayload struct { diff --git a/api/http/handler/endpoints/endpoint_extension_remove.go b/api/http/handler/endpoints/endpoint_extension_remove.go index 2e238a89e..8b265dc6c 100644 --- a/api/http/handler/endpoints/endpoint_extension_remove.go +++ b/api/http/handler/endpoints/endpoint_extension_remove.go @@ -3,10 +3,10 @@ package endpoints import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // DELETE request on /api/endpoints/:id/extensions/:extensionType diff --git a/api/http/handler/endpoints/endpoint_inspect.go b/api/http/handler/endpoints/endpoint_inspect.go index e382b3f16..dd0d3485b 100644 --- a/api/http/handler/endpoints/endpoint_inspect.go +++ b/api/http/handler/endpoints/endpoint_inspect.go @@ -3,10 +3,10 @@ package endpoints import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // GET request on /api/endpoints/:id diff --git a/api/http/handler/endpoints/endpoint_list.go b/api/http/handler/endpoints/endpoint_list.go index 3348c630e..5c1436ac9 100644 --- a/api/http/handler/endpoints/endpoint_list.go +++ b/api/http/handler/endpoints/endpoint_list.go @@ -3,8 +3,8 @@ package endpoints import ( "net/http" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/endpoints/endpoint_snapshot.go b/api/http/handler/endpoints/endpoint_snapshot.go index 51a18293e..720f4c072 100644 --- a/api/http/handler/endpoints/endpoint_snapshot.go +++ b/api/http/handler/endpoints/endpoint_snapshot.go @@ -4,9 +4,9 @@ import ( "log" "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" ) // POST request on /api/endpoints/snapshot diff --git a/api/http/handler/endpoints/endpoint_update.go b/api/http/handler/endpoints/endpoint_update.go index 769267449..5244cdc98 100644 --- a/api/http/handler/endpoints/endpoint_update.go +++ b/api/http/handler/endpoints/endpoint_update.go @@ -4,11 +4,11 @@ import ( "net/http" "strconv" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" "github.com/portainer/portainer/http/client" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type endpointUpdatePayload struct { diff --git a/api/http/handler/endpoints/endpoint_update_access.go b/api/http/handler/endpoints/endpoint_update_access.go index bedf559ff..47a7d414b 100644 --- a/api/http/handler/endpoints/endpoint_update_access.go +++ b/api/http/handler/endpoints/endpoint_update_access.go @@ -3,10 +3,10 @@ package endpoints import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type endpointUpdateAccessPayload struct { diff --git a/api/http/handler/endpoints/handler.go b/api/http/handler/endpoints/handler.go index fc1bc1e6c..779cd9390 100644 --- a/api/http/handler/endpoints/handler.go +++ b/api/http/handler/endpoints/handler.go @@ -1,8 +1,8 @@ package endpoints import ( + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/proxy" "github.com/portainer/portainer/http/security" diff --git a/api/http/handler/motd/motd.go b/api/http/handler/motd/motd.go index b2599be2d..fbe8b5acd 100644 --- a/api/http/handler/motd/motd.go +++ b/api/http/handler/motd/motd.go @@ -3,10 +3,10 @@ package motd import ( "net/http" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" "github.com/portainer/portainer/crypto" "github.com/portainer/portainer/http/client" - "github.com/portainer/portainer/http/response" ) type motdResponse struct { diff --git a/api/http/handler/registries/handler.go b/api/http/handler/registries/handler.go index 7a21561db..33a161932 100644 --- a/api/http/handler/registries/handler.go +++ b/api/http/handler/registries/handler.go @@ -1,8 +1,8 @@ package registries import ( + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" "net/http" diff --git a/api/http/handler/registries/registry_create.go b/api/http/handler/registries/registry_create.go index 781f172bf..ad4acb58a 100644 --- a/api/http/handler/registries/registry_create.go +++ b/api/http/handler/registries/registry_create.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type registryCreatePayload struct { diff --git a/api/http/handler/registries/registry_delete.go b/api/http/handler/registries/registry_delete.go index 2e968539b..ac463af5f 100644 --- a/api/http/handler/registries/registry_delete.go +++ b/api/http/handler/registries/registry_delete.go @@ -3,10 +3,10 @@ package registries import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // DELETE request on /api/registries/:id diff --git a/api/http/handler/registries/registry_inspect.go b/api/http/handler/registries/registry_inspect.go index a60f24288..96cdf84ac 100644 --- a/api/http/handler/registries/registry_inspect.go +++ b/api/http/handler/registries/registry_inspect.go @@ -3,10 +3,10 @@ package registries import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // GET request on /api/registries/:id diff --git a/api/http/handler/registries/registry_list.go b/api/http/handler/registries/registry_list.go index 9986ce820..7f75427cc 100644 --- a/api/http/handler/registries/registry_list.go +++ b/api/http/handler/registries/registry_list.go @@ -3,8 +3,8 @@ package registries import ( "net/http" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/registries/registry_update.go b/api/http/handler/registries/registry_update.go index 1a3743fb5..cd3a7ae67 100644 --- a/api/http/handler/registries/registry_update.go +++ b/api/http/handler/registries/registry_update.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type registryUpdatePayload struct { diff --git a/api/http/handler/registries/registry_update_access.go b/api/http/handler/registries/registry_update_access.go index a43ccb2f9..77f6fe08e 100644 --- a/api/http/handler/registries/registry_update_access.go +++ b/api/http/handler/registries/registry_update_access.go @@ -3,10 +3,10 @@ package registries import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type registryUpdateAccessPayload struct { diff --git a/api/http/handler/resourcecontrols/handler.go b/api/http/handler/resourcecontrols/handler.go index 4ad474f6b..60757ef28 100644 --- a/api/http/handler/resourcecontrols/handler.go +++ b/api/http/handler/resourcecontrols/handler.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/gorilla/mux" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/resourcecontrols/resourcecontrol_create.go b/api/http/handler/resourcecontrols/resourcecontrol_create.go index 10bde9a4f..97c3d5ef1 100644 --- a/api/http/handler/resourcecontrols/resourcecontrol_create.go +++ b/api/http/handler/resourcecontrols/resourcecontrol_create.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/resourcecontrols/resourcecontrol_delete.go b/api/http/handler/resourcecontrols/resourcecontrol_delete.go index 48fd8a972..04ba8d5d4 100644 --- a/api/http/handler/resourcecontrols/resourcecontrol_delete.go +++ b/api/http/handler/resourcecontrols/resourcecontrol_delete.go @@ -3,10 +3,10 @@ package resourcecontrols import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/resourcecontrols/resourcecontrol_update.go b/api/http/handler/resourcecontrols/resourcecontrol_update.go index 69299fcee..c46247c5d 100644 --- a/api/http/handler/resourcecontrols/resourcecontrol_update.go +++ b/api/http/handler/resourcecontrols/resourcecontrol_update.go @@ -3,10 +3,10 @@ package resourcecontrols import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/settings/handler.go b/api/http/handler/settings/handler.go index 58c020877..9440aedd5 100644 --- a/api/http/handler/settings/handler.go +++ b/api/http/handler/settings/handler.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/gorilla/mux" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/settings/settings_inspect.go b/api/http/handler/settings/settings_inspect.go index 48da08612..c922e1f47 100644 --- a/api/http/handler/settings/settings_inspect.go +++ b/api/http/handler/settings/settings_inspect.go @@ -3,8 +3,8 @@ package settings import ( "net/http" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" ) // GET request on /api/settings diff --git a/api/http/handler/settings/settings_ldap_check.go b/api/http/handler/settings/settings_ldap_check.go index 80d058e33..a8466e285 100644 --- a/api/http/handler/settings/settings_ldap_check.go +++ b/api/http/handler/settings/settings_ldap_check.go @@ -3,11 +3,11 @@ package settings import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" "github.com/portainer/portainer/filesystem" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type settingsLDAPCheckPayload struct { diff --git a/api/http/handler/settings/settings_public.go b/api/http/handler/settings/settings_public.go index 07d9c7d75..549cf999e 100644 --- a/api/http/handler/settings/settings_public.go +++ b/api/http/handler/settings/settings_public.go @@ -3,9 +3,9 @@ package settings import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" ) type publicSettingsResponse struct { diff --git a/api/http/handler/settings/settings_update.go b/api/http/handler/settings/settings_update.go index 6c171917b..18513931f 100644 --- a/api/http/handler/settings/settings_update.go +++ b/api/http/handler/settings/settings_update.go @@ -4,11 +4,11 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" "github.com/portainer/portainer/filesystem" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type settingsUpdatePayload struct { diff --git a/api/http/handler/stacks/create_compose_stack.go b/api/http/handler/stacks/create_compose_stack.go index a343c96fa..a6a8ddcfd 100644 --- a/api/http/handler/stacks/create_compose_stack.go +++ b/api/http/handler/stacks/create_compose_stack.go @@ -6,11 +6,11 @@ import ( "strings" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" "github.com/portainer/portainer/filesystem" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) @@ -194,7 +194,7 @@ func (payload *composeStackFromFileUploadPayload) Validate(r *http.Request) erro } payload.Name = name - composeFileContent, err := request.RetrieveMultiPartFormFile(r, "file") + composeFileContent, _, err := request.RetrieveMultiPartFormFile(r, "file") if err != nil { return portainer.Error("Invalid Compose file. Ensure that the Compose file is uploaded correctly") } diff --git a/api/http/handler/stacks/create_swarm_stack.go b/api/http/handler/stacks/create_swarm_stack.go index 87c94e6ef..017122026 100644 --- a/api/http/handler/stacks/create_swarm_stack.go +++ b/api/http/handler/stacks/create_swarm_stack.go @@ -6,11 +6,11 @@ import ( "strings" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" "github.com/portainer/portainer/filesystem" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) @@ -211,7 +211,7 @@ func (payload *swarmStackFromFileUploadPayload) Validate(r *http.Request) error } payload.SwarmID = swarmID - composeFileContent, err := request.RetrieveMultiPartFormFile(r, "file") + composeFileContent, _, err := request.RetrieveMultiPartFormFile(r, "file") if err != nil { return portainer.Error("Invalid Compose file. Ensure that the Compose file is uploaded correctly") } diff --git a/api/http/handler/stacks/handler.go b/api/http/handler/stacks/handler.go index ba231ebfe..7f2fd4bc0 100644 --- a/api/http/handler/stacks/handler.go +++ b/api/http/handler/stacks/handler.go @@ -5,8 +5,8 @@ import ( "sync" "github.com/gorilla/mux" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/stacks/stack_create.go b/api/http/handler/stacks/stack_create.go index c0b9d9ce0..0fe7e07ad 100644 --- a/api/http/handler/stacks/stack_create.go +++ b/api/http/handler/stacks/stack_create.go @@ -1,12 +1,13 @@ package stacks import ( + "errors" "log" "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" ) func (handler *Handler) cleanUp(stack *portainer.Stack, doCleanUp *bool) error { @@ -57,7 +58,7 @@ func (handler *Handler) stackCreate(w http.ResponseWriter, r *http.Request) *htt return handler.createComposeStack(w, r, method, endpoint) } - return &httperror.HandlerError{http.StatusBadRequest, "Invalid value for query parameter: type. Value must be one of: 1 (Swarm stack) or 2 (Compose stack)", request.ErrInvalidQueryParameter} + return &httperror.HandlerError{http.StatusBadRequest, "Invalid value for query parameter: type. Value must be one of: 1 (Swarm stack) or 2 (Compose stack)", errors.New(request.ErrInvalidQueryParameter)} } func (handler *Handler) createComposeStack(w http.ResponseWriter, r *http.Request, method string, endpoint *portainer.Endpoint) *httperror.HandlerError { @@ -71,7 +72,7 @@ func (handler *Handler) createComposeStack(w http.ResponseWriter, r *http.Reques return handler.createComposeStackFromFileUpload(w, r, endpoint) } - return &httperror.HandlerError{http.StatusBadRequest, "Invalid value for query parameter: method. Value must be one of: string, repository or file", request.ErrInvalidQueryParameter} + return &httperror.HandlerError{http.StatusBadRequest, "Invalid value for query parameter: method. Value must be one of: string, repository or file", errors.New(request.ErrInvalidQueryParameter)} } func (handler *Handler) createSwarmStack(w http.ResponseWriter, r *http.Request, method string, endpoint *portainer.Endpoint) *httperror.HandlerError { @@ -84,5 +85,5 @@ func (handler *Handler) createSwarmStack(w http.ResponseWriter, r *http.Request, return handler.createSwarmStackFromFileUpload(w, r, endpoint) } - return &httperror.HandlerError{http.StatusBadRequest, "Invalid value for query parameter: method. Value must be one of: string, repository or file", request.ErrInvalidQueryParameter} + return &httperror.HandlerError{http.StatusBadRequest, "Invalid value for query parameter: method. Value must be one of: string, repository or file", errors.New(request.ErrInvalidQueryParameter)} } diff --git a/api/http/handler/stacks/stack_delete.go b/api/http/handler/stacks/stack_delete.go index f481f808a..8f8fc25e8 100644 --- a/api/http/handler/stacks/stack_delete.go +++ b/api/http/handler/stacks/stack_delete.go @@ -4,11 +4,11 @@ import ( "net/http" "strconv" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/proxy" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/stacks/stack_file.go b/api/http/handler/stacks/stack_file.go index b86888a37..b0b247cef 100644 --- a/api/http/handler/stacks/stack_file.go +++ b/api/http/handler/stacks/stack_file.go @@ -4,11 +4,11 @@ import ( "net/http" "path" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/proxy" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/stacks/stack_inspect.go b/api/http/handler/stacks/stack_inspect.go index 380482149..e5377f654 100644 --- a/api/http/handler/stacks/stack_inspect.go +++ b/api/http/handler/stacks/stack_inspect.go @@ -3,11 +3,11 @@ package stacks import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/proxy" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/stacks/stack_list.go b/api/http/handler/stacks/stack_list.go index fc4732e06..337b204a7 100644 --- a/api/http/handler/stacks/stack_list.go +++ b/api/http/handler/stacks/stack_list.go @@ -3,11 +3,11 @@ package stacks import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/proxy" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/stacks/stack_migrate.go b/api/http/handler/stacks/stack_migrate.go index b6fed5a96..8a0ec0c69 100644 --- a/api/http/handler/stacks/stack_migrate.go +++ b/api/http/handler/stacks/stack_migrate.go @@ -3,11 +3,11 @@ package stacks import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/proxy" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/stacks/stack_update.go b/api/http/handler/stacks/stack_update.go index 456612249..03999a557 100644 --- a/api/http/handler/stacks/stack_update.go +++ b/api/http/handler/stacks/stack_update.go @@ -5,11 +5,11 @@ import ( "strconv" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/proxy" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/status/handler.go b/api/http/handler/status/handler.go index 692c64130..4d26fcd3a 100644 --- a/api/http/handler/status/handler.go +++ b/api/http/handler/status/handler.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/gorilla/mux" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/status/status_inspect.go b/api/http/handler/status/status_inspect.go index 93d379179..1892ddd7d 100644 --- a/api/http/handler/status/status_inspect.go +++ b/api/http/handler/status/status_inspect.go @@ -3,8 +3,8 @@ package status import ( "net/http" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" ) // GET request on /api/status diff --git a/api/http/handler/tags/handler.go b/api/http/handler/tags/handler.go index a700f7c3e..b38bd28f3 100644 --- a/api/http/handler/tags/handler.go +++ b/api/http/handler/tags/handler.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/gorilla/mux" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/tags/tag_create.go b/api/http/handler/tags/tag_create.go index f75c050b9..50b9261ba 100644 --- a/api/http/handler/tags/tag_create.go +++ b/api/http/handler/tags/tag_create.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type tagCreatePayload struct { diff --git a/api/http/handler/tags/tag_delete.go b/api/http/handler/tags/tag_delete.go index eed7f6410..e74b5ef12 100644 --- a/api/http/handler/tags/tag_delete.go +++ b/api/http/handler/tags/tag_delete.go @@ -3,10 +3,10 @@ package tags import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // DELETE request on /api/tags/:id diff --git a/api/http/handler/tags/tag_list.go b/api/http/handler/tags/tag_list.go index b572add68..a19aa48e7 100644 --- a/api/http/handler/tags/tag_list.go +++ b/api/http/handler/tags/tag_list.go @@ -3,8 +3,8 @@ package tags import ( "net/http" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" ) // GET request on /api/tags diff --git a/api/http/handler/teammemberships/handler.go b/api/http/handler/teammemberships/handler.go index c50773a85..10cd63a83 100644 --- a/api/http/handler/teammemberships/handler.go +++ b/api/http/handler/teammemberships/handler.go @@ -1,8 +1,8 @@ package teammemberships import ( + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" "net/http" diff --git a/api/http/handler/teammemberships/teammembership_create.go b/api/http/handler/teammemberships/teammembership_create.go index 49783d767..37216df6a 100644 --- a/api/http/handler/teammemberships/teammembership_create.go +++ b/api/http/handler/teammemberships/teammembership_create.go @@ -3,10 +3,10 @@ package teammemberships import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/teammemberships/teammembership_delete.go b/api/http/handler/teammemberships/teammembership_delete.go index a1263745f..846fb7892 100644 --- a/api/http/handler/teammemberships/teammembership_delete.go +++ b/api/http/handler/teammemberships/teammembership_delete.go @@ -3,10 +3,10 @@ package teammemberships import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/teammemberships/teammembership_list.go b/api/http/handler/teammemberships/teammembership_list.go index 0f9267a10..4136053d6 100644 --- a/api/http/handler/teammemberships/teammembership_list.go +++ b/api/http/handler/teammemberships/teammembership_list.go @@ -3,9 +3,9 @@ package teammemberships import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/teammemberships/teammembership_update.go b/api/http/handler/teammemberships/teammembership_update.go index 6d08bc90a..0e400e975 100644 --- a/api/http/handler/teammemberships/teammembership_update.go +++ b/api/http/handler/teammemberships/teammembership_update.go @@ -3,10 +3,10 @@ package teammemberships import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/teams/handler.go b/api/http/handler/teams/handler.go index 2b8cd7c3b..946a071d7 100644 --- a/api/http/handler/teams/handler.go +++ b/api/http/handler/teams/handler.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/gorilla/mux" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/teams/team_create.go b/api/http/handler/teams/team_create.go index d865e56c5..16b230ec4 100644 --- a/api/http/handler/teams/team_create.go +++ b/api/http/handler/teams/team_create.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type teamCreatePayload struct { diff --git a/api/http/handler/teams/team_delete.go b/api/http/handler/teams/team_delete.go index 623c29c4c..00146d698 100644 --- a/api/http/handler/teams/team_delete.go +++ b/api/http/handler/teams/team_delete.go @@ -3,10 +3,10 @@ package teams import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // DELETE request on /api/teams/:id diff --git a/api/http/handler/teams/team_inspect.go b/api/http/handler/teams/team_inspect.go index 4030a391e..b8aa83da1 100644 --- a/api/http/handler/teams/team_inspect.go +++ b/api/http/handler/teams/team_inspect.go @@ -3,10 +3,10 @@ package teams import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/teams/team_list.go b/api/http/handler/teams/team_list.go index 7c4268e13..4acc5eabb 100644 --- a/api/http/handler/teams/team_list.go +++ b/api/http/handler/teams/team_list.go @@ -3,8 +3,8 @@ package teams import ( "net/http" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/teams/team_memberships.go b/api/http/handler/teams/team_memberships.go index d09abe7d5..450458e35 100644 --- a/api/http/handler/teams/team_memberships.go +++ b/api/http/handler/teams/team_memberships.go @@ -3,10 +3,10 @@ package teams import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/teams/team_update.go b/api/http/handler/teams/team_update.go index 8c0961c31..dea180b6a 100644 --- a/api/http/handler/teams/team_update.go +++ b/api/http/handler/teams/team_update.go @@ -3,10 +3,10 @@ package teams import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type teamUpdatePayload struct { diff --git a/api/http/handler/templates/handler.go b/api/http/handler/templates/handler.go index c193b1def..660991d8d 100644 --- a/api/http/handler/templates/handler.go +++ b/api/http/handler/templates/handler.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/gorilla/mux" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/templates/template_create.go b/api/http/handler/templates/template_create.go index f27cd494a..ef9c0c58f 100644 --- a/api/http/handler/templates/template_create.go +++ b/api/http/handler/templates/template_create.go @@ -4,11 +4,11 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" "github.com/portainer/portainer/filesystem" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type templateCreatePayload struct { diff --git a/api/http/handler/templates/template_delete.go b/api/http/handler/templates/template_delete.go index c23c2d237..f5793bb8c 100644 --- a/api/http/handler/templates/template_delete.go +++ b/api/http/handler/templates/template_delete.go @@ -3,10 +3,10 @@ package templates import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // DELETE request on /api/templates/:id diff --git a/api/http/handler/templates/template_inspect.go b/api/http/handler/templates/template_inspect.go index 6b1b4c6a1..70b6ada02 100644 --- a/api/http/handler/templates/template_inspect.go +++ b/api/http/handler/templates/template_inspect.go @@ -3,10 +3,10 @@ package templates import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // GET request on /api/templates/:id diff --git a/api/http/handler/templates/template_list.go b/api/http/handler/templates/template_list.go index cd312685d..24ca93bbd 100644 --- a/api/http/handler/templates/template_list.go +++ b/api/http/handler/templates/template_list.go @@ -4,10 +4,10 @@ import ( "encoding/json" "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" "github.com/portainer/portainer/http/client" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/templates/template_update.go b/api/http/handler/templates/template_update.go index 2eff9701f..123ea0f6a 100644 --- a/api/http/handler/templates/template_update.go +++ b/api/http/handler/templates/template_update.go @@ -3,10 +3,10 @@ package templates import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type templateUpdatePayload struct { diff --git a/api/http/handler/upload/handler.go b/api/http/handler/upload/handler.go index 6ce36df77..b0068979b 100644 --- a/api/http/handler/upload/handler.go +++ b/api/http/handler/upload/handler.go @@ -1,8 +1,8 @@ package upload import ( + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" "net/http" diff --git a/api/http/handler/upload/upload_tls.go b/api/http/handler/upload/upload_tls.go index aebab6813..964a7d29b 100644 --- a/api/http/handler/upload/upload_tls.go +++ b/api/http/handler/upload/upload_tls.go @@ -3,10 +3,10 @@ package upload import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // POST request on /api/upload/tls/{certificate:(?:ca|cert|key)}?folder= @@ -21,7 +21,7 @@ func (handler *Handler) uploadTLS(w http.ResponseWriter, r *http.Request) *httpe return &httperror.HandlerError{http.StatusBadRequest, "Invalid query parameter: folder", err} } - file, err := request.RetrieveMultiPartFormFile(r, "file") + file, _, err := request.RetrieveMultiPartFormFile(r, "file") if err != nil { return &httperror.HandlerError{http.StatusBadRequest, "Invalid certificate file. Ensure that the certificate file is uploaded correctly", err} } diff --git a/api/http/handler/users/admin_check.go b/api/http/handler/users/admin_check.go index 4d7ba233a..5fcd1d33d 100644 --- a/api/http/handler/users/admin_check.go +++ b/api/http/handler/users/admin_check.go @@ -3,9 +3,9 @@ package users import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" ) // GET request on /api/users/admin/check diff --git a/api/http/handler/users/admin_init.go b/api/http/handler/users/admin_init.go index f44eb43ca..fb2172686 100644 --- a/api/http/handler/users/admin_init.go +++ b/api/http/handler/users/admin_init.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type adminInitPayload struct { diff --git a/api/http/handler/users/handler.go b/api/http/handler/users/handler.go index 4a0dd2df2..ae43ef521 100644 --- a/api/http/handler/users/handler.go +++ b/api/http/handler/users/handler.go @@ -1,8 +1,8 @@ package users import ( + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" "net/http" diff --git a/api/http/handler/users/user_create.go b/api/http/handler/users/user_create.go index 9fb4cddda..7948ec2b6 100644 --- a/api/http/handler/users/user_create.go +++ b/api/http/handler/users/user_create.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/users/user_delete.go b/api/http/handler/users/user_delete.go index 90a5b52cc..1c500bfc1 100644 --- a/api/http/handler/users/user_delete.go +++ b/api/http/handler/users/user_delete.go @@ -3,10 +3,10 @@ package users import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/users/user_inspect.go b/api/http/handler/users/user_inspect.go index 9583c833c..a2e185bdf 100644 --- a/api/http/handler/users/user_inspect.go +++ b/api/http/handler/users/user_inspect.go @@ -3,10 +3,10 @@ package users import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // GET request on /api/users/:id diff --git a/api/http/handler/users/user_list.go b/api/http/handler/users/user_list.go index 945e85f10..9b46ff5eb 100644 --- a/api/http/handler/users/user_list.go +++ b/api/http/handler/users/user_list.go @@ -3,8 +3,8 @@ package users import ( "net/http" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/response" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/users/user_memberships.go b/api/http/handler/users/user_memberships.go index dfbb355ab..2ba837aec 100644 --- a/api/http/handler/users/user_memberships.go +++ b/api/http/handler/users/user_memberships.go @@ -3,10 +3,10 @@ package users import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/users/user_update.go b/api/http/handler/users/user_update.go index a8b6c8b1a..4ae5e50ab 100644 --- a/api/http/handler/users/user_update.go +++ b/api/http/handler/users/user_update.go @@ -3,10 +3,10 @@ package users import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/users/user_update_password.go b/api/http/handler/users/user_update_password.go index f810f0888..e5a65c8e3 100644 --- a/api/http/handler/users/user_update_password.go +++ b/api/http/handler/users/user_update_password.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/webhooks/handler.go b/api/http/handler/webhooks/handler.go index fe60f3fdb..d9b583535 100644 --- a/api/http/handler/webhooks/handler.go +++ b/api/http/handler/webhooks/handler.go @@ -4,9 +4,9 @@ import ( "net/http" "github.com/gorilla/mux" + httperror "github.com/portainer/libhttp/error" portainer "github.com/portainer/portainer" "github.com/portainer/portainer/docker" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/webhooks/webhook_create.go b/api/http/handler/webhooks/webhook_create.go index c74db0c6e..288435889 100644 --- a/api/http/handler/webhooks/webhook_create.go +++ b/api/http/handler/webhooks/webhook_create.go @@ -4,10 +4,10 @@ import ( "net/http" "github.com/asaskevich/govalidator" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" "github.com/satori/go.uuid" ) diff --git a/api/http/handler/webhooks/webhook_delete.go b/api/http/handler/webhooks/webhook_delete.go index b81a445e1..6df0e4156 100644 --- a/api/http/handler/webhooks/webhook_delete.go +++ b/api/http/handler/webhooks/webhook_delete.go @@ -3,10 +3,10 @@ package webhooks import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // DELETE request on /api/webhook/:serviceID diff --git a/api/http/handler/webhooks/webhook_execute.go b/api/http/handler/webhooks/webhook_execute.go index 395be9999..f43045899 100644 --- a/api/http/handler/webhooks/webhook_execute.go +++ b/api/http/handler/webhooks/webhook_execute.go @@ -6,10 +6,10 @@ import ( "strings" dockertypes "github.com/docker/docker/api/types" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) // Acts on a passed in token UUID to restart the docker service diff --git a/api/http/handler/webhooks/webhook_list.go b/api/http/handler/webhooks/webhook_list.go index 288bdcd65..7ed0df213 100644 --- a/api/http/handler/webhooks/webhook_list.go +++ b/api/http/handler/webhooks/webhook_list.go @@ -3,10 +3,10 @@ package webhooks import ( "net/http" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" + "github.com/portainer/libhttp/response" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" - "github.com/portainer/portainer/http/response" ) type webhookListOperationFilters struct { diff --git a/api/http/handler/websocket/handler.go b/api/http/handler/websocket/handler.go index 20364f52b..3de1cbc60 100644 --- a/api/http/handler/websocket/handler.go +++ b/api/http/handler/websocket/handler.go @@ -3,8 +3,8 @@ package websocket import ( "github.com/gorilla/mux" "github.com/gorilla/websocket" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "github.com/portainer/portainer/http/security" ) diff --git a/api/http/handler/websocket/websocket_exec.go b/api/http/handler/websocket/websocket_exec.go index 58d734072..d797e020a 100644 --- a/api/http/handler/websocket/websocket_exec.go +++ b/api/http/handler/websocket/websocket_exec.go @@ -15,10 +15,10 @@ import ( "github.com/asaskevich/govalidator" "github.com/gorilla/websocket" "github.com/koding/websocketproxy" + httperror "github.com/portainer/libhttp/error" + "github.com/portainer/libhttp/request" "github.com/portainer/portainer" "github.com/portainer/portainer/crypto" - httperror "github.com/portainer/portainer/http/error" - "github.com/portainer/portainer/http/request" ) type webSocketExecRequestParams struct { diff --git a/api/http/proxy/local.go b/api/http/proxy/local.go index 8a7f5842d..7686768ad 100644 --- a/api/http/proxy/local.go +++ b/api/http/proxy/local.go @@ -5,7 +5,7 @@ import ( "log" "net/http" - httperror "github.com/portainer/portainer/http/error" + httperror "github.com/portainer/libhttp/error" ) type localProxy struct { diff --git a/api/http/request/request.go b/api/http/request/request.go deleted file mode 100644 index ee56b0d05..000000000 --- a/api/http/request/request.go +++ /dev/null @@ -1,163 +0,0 @@ -package request - -import ( - "encoding/json" - "io/ioutil" - "net/http" - "strconv" - - "github.com/gorilla/mux" - "github.com/portainer/portainer" -) - -const ( - // ErrInvalidQueryParameter defines an error raised when a mandatory query parameter has an invalid value. - ErrInvalidQueryParameter = portainer.Error("Invalid query parameter") - // errInvalidRequestURL defines an error raised when the data sent in the query or the URL is invalid - errInvalidRequestURL = portainer.Error("Invalid request URL") - // errMissingQueryParameter defines an error raised when a mandatory query parameter is missing. - errMissingQueryParameter = portainer.Error("Missing query parameter") - // errMissingFormDataValue defines an error raised when a mandatory form data value is missing. - errMissingFormDataValue = portainer.Error("Missing form data value") -) - -// PayloadValidation is an interface used to validate the payload of a request. -type PayloadValidation interface { - Validate(request *http.Request) error -} - -// DecodeAndValidateJSONPayload decodes the body of the request into an object -// implementing the PayloadValidation interface. -// It also triggers a validation of object content. -func DecodeAndValidateJSONPayload(request *http.Request, v PayloadValidation) error { - if err := json.NewDecoder(request.Body).Decode(v); err != nil { - return err - } - return v.Validate(request) -} - -// RetrieveMultiPartFormFile returns the content of an uploaded file (form data) as bytes. -func RetrieveMultiPartFormFile(request *http.Request, requestParameter string) ([]byte, error) { - file, _, err := request.FormFile(requestParameter) - if err != nil { - return nil, err - } - defer file.Close() - - fileContent, err := ioutil.ReadAll(file) - if err != nil { - return nil, err - } - return fileContent, nil -} - -// RetrieveMultiPartFormJSONValue decodes the value of some form data as a JSON object into the target parameter. -// If optional is set to true, will not return an error when the form data value is not found. -func RetrieveMultiPartFormJSONValue(request *http.Request, name string, target interface{}, optional bool) error { - value, err := RetrieveMultiPartFormValue(request, name, optional) - if err != nil { - return err - } - if value == "" { - return nil - } - return json.Unmarshal([]byte(value), target) -} - -// RetrieveMultiPartFormValue returns the value of some form data as a string. -// If optional is set to true, will not return an error when the form data value is not found. -func RetrieveMultiPartFormValue(request *http.Request, name string, optional bool) (string, error) { - value := request.FormValue(name) - if value == "" && !optional { - return "", errMissingFormDataValue - } - return value, nil -} - -// RetrieveNumericMultiPartFormValue returns the value of some form data as an integer. -// If optional is set to true, will not return an error when the form data value is not found. -func RetrieveNumericMultiPartFormValue(request *http.Request, name string, optional bool) (int, error) { - value, err := RetrieveMultiPartFormValue(request, name, optional) - if err != nil { - return 0, err - } - return strconv.Atoi(value) -} - -// RetrieveBooleanMultiPartFormValue returns the value of some form data as a boolean. -// If optional is set to true, will not return an error when the form data value is not found. -func RetrieveBooleanMultiPartFormValue(request *http.Request, name string, optional bool) (bool, error) { - value, err := RetrieveMultiPartFormValue(request, name, optional) - if err != nil { - return false, err - } - return value == "true", nil -} - -// RetrieveRouteVariableValue returns the value of a route variable as a string. -func RetrieveRouteVariableValue(request *http.Request, name string) (string, error) { - routeVariables := mux.Vars(request) - if routeVariables == nil { - return "", errInvalidRequestURL - } - routeVar := routeVariables[name] - if routeVar == "" { - return "", errInvalidRequestURL - } - return routeVar, nil -} - -// RetrieveNumericRouteVariableValue returns the value of a route variable as an integer. -func RetrieveNumericRouteVariableValue(request *http.Request, name string) (int, error) { - routeVar, err := RetrieveRouteVariableValue(request, name) - if err != nil { - return 0, err - } - return strconv.Atoi(routeVar) -} - -// RetrieveQueryParameter returns the value of a query parameter as a string. -// If optional is set to true, will not return an error when the query parameter is not found. -func RetrieveQueryParameter(request *http.Request, name string, optional bool) (string, error) { - queryParameter := request.FormValue(name) - if queryParameter == "" && !optional { - return "", errMissingQueryParameter - } - return queryParameter, nil -} - -// RetrieveNumericQueryParameter returns the value of a query parameter as an integer. -// If optional is set to true, will not return an error when the query parameter is not found. -func RetrieveNumericQueryParameter(request *http.Request, name string, optional bool) (int, error) { - queryParameter, err := RetrieveQueryParameter(request, name, optional) - if err != nil { - return 0, err - } - if queryParameter == "" && optional { - return 0, nil - } - return strconv.Atoi(queryParameter) -} - -// RetrieveBooleanQueryParameter returns the value of a query parameter as a boolean. -// If optional is set to true, will not return an error when the query parameter is not found. -func RetrieveBooleanQueryParameter(request *http.Request, name string, optional bool) (bool, error) { - queryParameter, err := RetrieveQueryParameter(request, name, optional) - if err != nil { - return false, err - } - return queryParameter == "true", nil -} - -// RetrieveJSONQueryParameter decodes the value of a query paramater as a JSON object into the target parameter. -// If optional is set to true, will not return an error when the query parameter is not found. -func RetrieveJSONQueryParameter(request *http.Request, name string, target interface{}, optional bool) error { - queryParameter, err := RetrieveQueryParameter(request, name, optional) - if err != nil { - return err - } - if queryParameter == "" { - return nil - } - return json.Unmarshal([]byte(queryParameter), target) -} diff --git a/api/http/response/response.go b/api/http/response/response.go deleted file mode 100644 index 2451abd24..000000000 --- a/api/http/response/response.go +++ /dev/null @@ -1,25 +0,0 @@ -package response - -import ( - "encoding/json" - "net/http" - - httperror "github.com/portainer/portainer/http/error" -) - -// JSON encodes data to rw in JSON format. Returns a pointer to a -// HandlerError if encoding fails. -func JSON(rw http.ResponseWriter, data interface{}) *httperror.HandlerError { - rw.Header().Set("Content-Type", "application/json") - err := json.NewEncoder(rw).Encode(data) - if err != nil { - return &httperror.HandlerError{http.StatusInternalServerError, "Unable to write JSON response", err} - } - return nil -} - -// Empty merely sets the response code to NoContent (204). -func Empty(rw http.ResponseWriter) *httperror.HandlerError { - rw.WriteHeader(http.StatusNoContent) - return nil -} diff --git a/api/http/security/bouncer.go b/api/http/security/bouncer.go index 5aad463f1..0b25bd389 100644 --- a/api/http/security/bouncer.go +++ b/api/http/security/bouncer.go @@ -1,8 +1,8 @@ package security import ( + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" "net/http" "strings" diff --git a/api/http/security/rate_limiter.go b/api/http/security/rate_limiter.go index 27ab2523a..307329723 100644 --- a/api/http/security/rate_limiter.go +++ b/api/http/security/rate_limiter.go @@ -6,8 +6,8 @@ import ( "time" "github.com/g07cha/defender" + httperror "github.com/portainer/libhttp/error" "github.com/portainer/portainer" - httperror "github.com/portainer/portainer/http/error" ) // RateLimiter represents an entity that manages request rate limiting From 77913543b1b00e57878acf1aa01b734f5fb5414c Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Sat, 15 Sep 2018 09:53:35 +0800 Subject: [PATCH 19/32] feat(container-details): update container-restart-policy component (#2273) --- .../container-restart-policy-controller.js | 52 ++++++++----------- .../container-restart-policy.html | 27 ++-------- .../views/containers/edit/container.html | 2 +- .../containers/edit/containerController.js | 1 + 4 files changed, 27 insertions(+), 55 deletions(-) diff --git a/app/docker/components/container-restart-policy/container-restart-policy-controller.js b/app/docker/components/container-restart-policy/container-restart-policy-controller.js index c9ece16d4..fd96a1596 100644 --- a/app/docker/components/container-restart-policy/container-restart-policy-controller.js +++ b/app/docker/components/container-restart-policy/container-restart-policy-controller.js @@ -1,36 +1,26 @@ angular - .module('portainer.docker') - .controller('ContainerRestartPolicyController', [ - function ContainerRestartPolicyController() { - var ctrl = this; +.module('portainer.docker') +.controller('ContainerRestartPolicyController', [function ContainerRestartPolicyController() { + var ctrl = this; - this.state = { - editMode :false, - editModel :{} - }; - + this.state = { + editModel : {} + }; - ctrl.toggleEdit = toggleEdit; - ctrl.save = save; + ctrl.save = save; - function toggleEdit() { - ctrl.state.editMode = true; - ctrl.state.editModel = { - name: ctrl.name, - maximumRetryCount: ctrl.maximumRetryCount - }; - } - - function save() { - if (ctrl.state.editModel.name === ctrl.name && - ctrl.state.editModel.maximumRetryCount === ctrl.maximumRetryCount) { - ctrl.state.editMode = false; - return; - } - ctrl.updateRestartPolicy(ctrl.state.editModel) - .then(function onUpdateSucceed() { - ctrl.state.editMode = false; - }); - } + function save() { + if (ctrl.state.editModel.name === ctrl.name && ctrl.state.editModel.maximumRetryCount === ctrl.maximumRetryCount) { + return; } - ]); + ctrl.updateRestartPolicy(ctrl.state.editModel); + } + + this.$onInit = function() { + ctrl.state.editModel = { + name: ctrl.name, + maximumRetryCount: ctrl.maximumRetryCount + }; + }; +} +]); diff --git a/app/docker/components/container-restart-policy/container-restart-policy.html b/app/docker/components/container-restart-policy/container-restart-policy.html index c5352b6e4..41b87c2fc 100644 --- a/app/docker/components/container-restart-policy/container-restart-policy.html +++ b/app/docker/components/container-restart-policy/container-restart-policy.html @@ -1,23 +1,5 @@
- - - - - - - - - - -
- - - - Name - {{$ctrl.name }}
Maximum Retry Count - {{ $ctrl.maximumRetryCount }} -
- +
- -
Name @@ -31,15 +13,14 @@ - +
Maximum Retry Count +
-
\ No newline at end of file + diff --git a/app/docker/views/containers/edit/container.html b/app/docker/views/containers/edit/container.html index 92815f9c0..a251ae2d2 100644 --- a/app/docker/views/containers/edit/container.html +++ b/app/docker/views/containers/edit/container.html @@ -226,7 +226,7 @@
Restart policies - diff --git a/app/docker/views/containers/edit/containerController.js b/app/docker/views/containers/edit/containerController.js index e7b1a988b..f687b116c 100644 --- a/app/docker/views/containers/edit/containerController.js +++ b/app/docker/views/containers/edit/containerController.js @@ -323,6 +323,7 @@ function ($q, $scope, $state, $transition$, $filter, Commit, ContainerHelper, Co Name: restartPolicy, MaximumRetryCount: maximumRetryCount }; + Notifications.success('Restart policy updated'); } function notifyOnError(err) { From bab02f2b91b54b9b5651f2031a7e037e069dc872 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Sat, 15 Sep 2018 10:19:51 +0800 Subject: [PATCH 20/32] fix(container-details): update container restart policy init --- .../container-restart-policy-controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/docker/components/container-restart-policy/container-restart-policy-controller.js b/app/docker/components/container-restart-policy/container-restart-policy-controller.js index fd96a1596..64a8604fc 100644 --- a/app/docker/components/container-restart-policy/container-restart-policy-controller.js +++ b/app/docker/components/container-restart-policy/container-restart-policy-controller.js @@ -18,7 +18,7 @@ angular this.$onInit = function() { ctrl.state.editModel = { - name: ctrl.name, + name: ctrl.name ? ctrl.name : 'no', maximumRetryCount: ctrl.maximumRetryCount }; }; From e2258f98cc0f787a6d8cfd28c9129d7569f43beb Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Sat, 15 Sep 2018 10:33:33 +0800 Subject: [PATCH 21/32] fix(services): only display logs action when container has ID in agent proxy mode --- .../service-tasks-datatable/serviceTasksDatatable.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatable.html b/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatable.html index 433be02d8..cfba0524f 100644 --- a/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatable.html +++ b/app/docker/components/datatables/service-tasks-datatable/serviceTasksDatatable.html @@ -65,7 +65,7 @@
- +
From 57bd82ba8568166bf8eadfc06eeb8563ae96779c Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Sat, 15 Sep 2018 16:40:26 +0800 Subject: [PATCH 22/32] chore(version): bump version number --- api/bolt/migrator/migrator.go | 2 +- api/portainer.go | 2 +- api/swagger.yaml | 4 ++-- distribution/portainer.spec | 2 +- package.json | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/api/bolt/migrator/migrator.go b/api/bolt/migrator/migrator.go index b70172256..4d05820aa 100644 --- a/api/bolt/migrator/migrator.go +++ b/api/bolt/migrator/migrator.go @@ -178,7 +178,7 @@ func (m *Migrator) Migrate() error { } } - // 1.19.2-dev + // Portainer 1.19.2 if m.currentDBVersion < 14 { err := m.updateResourceControlsToDBVersion14() if err != nil { diff --git a/api/portainer.go b/api/portainer.go index 839abea7a..6367b14e0 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -639,7 +639,7 @@ type ( const ( // APIVersion is the version number of the Portainer API - APIVersion = "1.19.2-dev" + APIVersion = "1.19.2" // DBVersion is the version number of the Portainer database DBVersion = 14 // MessageOfTheDayURL represents the URL where Portainer MOTD message can be retrieved diff --git a/api/swagger.yaml b/api/swagger.yaml index 17785d43e..890c5fc2a 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -54,7 +54,7 @@ info: **NOTE**: You can find more information on how to query the Docker API in the [Docker official documentation](https://docs.docker.com/engine/api/v1.30/) as well as in [this Portainer example](https://gist.github.com/deviantony/77026d402366b4b43fa5918d41bc42f8). - version: "1.19.2-dev" + version: "1.19.2" title: "Portainer API" contact: email: "info@portainer.io" @@ -2816,7 +2816,7 @@ definitions: description: "Is analytics enabled" Version: type: "string" - example: "1.19.2-dev" + example: "1.19.2" description: "Portainer API version" PublicSettingsInspectResponse: type: "object" diff --git a/distribution/portainer.spec b/distribution/portainer.spec index c62ed0b72..af2337e91 100644 --- a/distribution/portainer.spec +++ b/distribution/portainer.spec @@ -1,5 +1,5 @@ Name: portainer -Version: 1.19.2-dev +Version: 1.19.2 Release: 0 License: Zlib Summary: A lightweight docker management UI diff --git a/package.json b/package.json index b908a30b3..ffe21637b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Portainer.io", "name": "portainer", "homepage": "http://portainer.io", - "version": "1.19.2-dev", + "version": "1.19.2", "repository": { "type": "git", "url": "git@github.com:portainer/portainer.git" From 313c8be997a4d000cb409557bfab0bea4ae26616 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Sat, 15 Sep 2018 19:26:03 +0800 Subject: [PATCH 23/32] chore(version): bump version number --- api/portainer.go | 2 +- api/swagger.yaml | 4 ++-- distribution/portainer.spec | 2 +- package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api/portainer.go b/api/portainer.go index 6367b14e0..2db839506 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -639,7 +639,7 @@ type ( const ( // APIVersion is the version number of the Portainer API - APIVersion = "1.19.2" + APIVersion = "1.20-dev" // DBVersion is the version number of the Portainer database DBVersion = 14 // MessageOfTheDayURL represents the URL where Portainer MOTD message can be retrieved diff --git a/api/swagger.yaml b/api/swagger.yaml index 890c5fc2a..1fda7d40f 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -54,7 +54,7 @@ info: **NOTE**: You can find more information on how to query the Docker API in the [Docker official documentation](https://docs.docker.com/engine/api/v1.30/) as well as in [this Portainer example](https://gist.github.com/deviantony/77026d402366b4b43fa5918d41bc42f8). - version: "1.19.2" + version: "1.20-dev" title: "Portainer API" contact: email: "info@portainer.io" @@ -2816,7 +2816,7 @@ definitions: description: "Is analytics enabled" Version: type: "string" - example: "1.19.2" + example: "1.20-dev" description: "Portainer API version" PublicSettingsInspectResponse: type: "object" diff --git a/distribution/portainer.spec b/distribution/portainer.spec index af2337e91..abbd4b371 100644 --- a/distribution/portainer.spec +++ b/distribution/portainer.spec @@ -1,5 +1,5 @@ Name: portainer -Version: 1.19.2 +Version: 1.20-dev Release: 0 License: Zlib Summary: A lightweight docker management UI diff --git a/package.json b/package.json index ffe21637b..2e60ee1ea 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Portainer.io", "name": "portainer", "homepage": "http://portainer.io", - "version": "1.19.2", + "version": "1.20-dev", "repository": { "type": "git", "url": "git@github.com:portainer/portainer.git" From 22450bbdebc47f98071c241a4c74842143683e4a Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Sun, 16 Sep 2018 10:34:46 +0800 Subject: [PATCH 24/32] chore(build): update build script and add grunt yarn script (#2276) --- build.sh | 2 +- package.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 36e86b8a9..c00f5dd0b 100755 --- a/build.sh +++ b/build.sh @@ -24,7 +24,7 @@ function build_archive() { function build_all() { mkdir -pv "${ARCHIVE_BUILD_FOLDER}" for tag in $@; do - grunt "release:`echo "$tag" | tr '-' ':'`" + yarn grunt "release:`echo "$tag" | tr '-' ':'`" name="portainer"; if [ "$(echo "$tag" | cut -c1)" = "w" ]; then name="${name}.exe"; fi mv dist/portainer-$tag* dist/$name if [ `echo $tag | cut -d \- -f 1` == 'linux' ]; then build_and_push_images "$tag"; fi diff --git a/package.json b/package.json index 2e60ee1ea..6d7486278 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ } ], "scripts": { + "grunt": "grunt", "dev": "yarn grunt run-dev", "clean-all": "yarn grunt clean:all", "build": "yarn grunt build", From b192b098ca0e6b9925f9ce6eb30e8b714961c6d1 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Mon, 17 Sep 2018 09:26:37 +0800 Subject: [PATCH 25/32] feat(build-system): update shippedDockerVersion to 18.06.1-ce (#2281) --- gruntfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gruntfile.js b/gruntfile.js index 79e05c95d..873d55473 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -80,7 +80,7 @@ module.exports = function (grunt) { grunt.initConfig({ root: 'dist', distdir: 'dist/public', - shippedDockerVersion: '18.03.1-ce', + shippedDockerVersion: '18.06.1-ce', shippedDockerVersionWindows: '17.09.0-ce', pkg: grunt.file.readJSON('package.json'), config: gruntfile_cfg.config, From c3d80a1b21b6c6b2f4f824069693bed645929717 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Wed, 19 Sep 2018 11:40:06 +0800 Subject: [PATCH 26/32] docs(project): update CONTRIBUTING.md --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3ddc75e8c..e26559a7e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -77,14 +77,14 @@ The subject contains succinct description of the change: ## Contribution process -Our contribution process is described below. Some of the steps can be visualized inside Github via specific `contrib/` labels, such as `contrib/func-review-in-progress` or `contrib/tech-review-approved`. +Our contribution process is described below. Some of the steps can be visualized inside Github via specific `status/` labels, such as `status/1-functional-review` or `status/2-technical-review`. ### Bug report -![portainer_bugreport_workflow](https://user-images.githubusercontent.com/5485061/43569306-5571b3a0-9637-11e8-8559-786cfc82a14f.png) +![portainer_bugreport_workflow](https://user-images.githubusercontent.com/5485061/45727219-50190a00-bbf5-11e8-9fe8-3a563bb8d5d7.png) ### Feature request -The feature request process is similar to the bug report process but has an extra functional validation before the technical validation. +The feature request process is similar to the bug report process but has an extra functional validation before the technical validation as well as a documentation validation before the testing phase. -![portainer_featurerequest_workflow](https://user-images.githubusercontent.com/5485061/43569315-5d30a308-9637-11e8-8292-3c62b5612925.png) +![portainer_featurerequest_workflow](https://user-images.githubusercontent.com/5485061/45727229-5ad39f00-bbf5-11e8-9550-16ba66c50615.png) From d5dd362d53ae60982b8ea5aa325d49d4f7f497c1 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Mon, 24 Sep 2018 12:09:12 +1200 Subject: [PATCH 27/32] =?UTF-8?q?feat(api):=20update=20client.Get=20with?= =?UTF-8?q?=20a=20new=20timeout=20parameter=20and=20default=E2=80=A6=20(#2?= =?UTF-8?q?297)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(api): update client.Get with a new timeout parameter and default to 5s * fix(api): fix invalid type --- api/http/client/client.go | 15 +++++++++++---- api/http/handler/motd/motd.go | 2 +- api/http/handler/templates/template_list.go | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/api/http/client/client.go b/api/http/client/client.go index 541ec8257..8892b6472 100644 --- a/api/http/client/client.go +++ b/api/http/client/client.go @@ -15,6 +15,7 @@ import ( const ( errInvalidResponseStatus = portainer.Error("Invalid response status (expecting 200)") + defaultHTTPTimeout = 5 ) // HTTPClient represents a client to send HTTP requests. @@ -26,7 +27,7 @@ type HTTPClient struct { func NewHTTPClient() *HTTPClient { return &HTTPClient{ &http.Client{ - Timeout: time.Second * 5, + Timeout: time.Second * time.Duration(defaultHTTPTimeout), }, } } @@ -67,10 +68,16 @@ func (client *HTTPClient) ExecuteAzureAuthenticationRequest(credentials *portain } // Get executes a simple HTTP GET to the specified URL and returns -// the content of the response body. -func Get(url string) ([]byte, error) { +// the content of the response body. Timeout can be specified via the timeout parameter, +// will default to defaultHTTPTimeout if set to 0. +func Get(url string, timeout int) ([]byte, error) { + + if timeout == 0 { + timeout = defaultHTTPTimeout + } + client := &http.Client{ - Timeout: time.Second * 3, + Timeout: time.Second * time.Duration(timeout), } response, err := client.Get(url) diff --git a/api/http/handler/motd/motd.go b/api/http/handler/motd/motd.go index fbe8b5acd..ca279d890 100644 --- a/api/http/handler/motd/motd.go +++ b/api/http/handler/motd/motd.go @@ -16,7 +16,7 @@ type motdResponse struct { func (handler *Handler) motd(w http.ResponseWriter, r *http.Request) { - motd, err := client.Get(portainer.MessageOfTheDayURL) + motd, err := client.Get(portainer.MessageOfTheDayURL, 0) if err != nil { w.WriteHeader(http.StatusInternalServerError) return diff --git a/api/http/handler/templates/template_list.go b/api/http/handler/templates/template_list.go index 24ca93bbd..7e802528f 100644 --- a/api/http/handler/templates/template_list.go +++ b/api/http/handler/templates/template_list.go @@ -26,7 +26,7 @@ func (handler *Handler) templateList(w http.ResponseWriter, r *http.Request) *ht } } else { var templateData []byte - templateData, err = client.Get(settings.TemplatesURL) + templateData, err = client.Get(settings.TemplatesURL, 0) if err != nil { return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve external templates", err} } From 94b202fedc3a2bd94a0dbc187f26dd9b5d4373da Mon Sep 17 00:00:00 2001 From: Lukas Joergensen Date: Tue, 25 Sep 2018 01:10:41 +0200 Subject: [PATCH 28/32] fix(authentication): escape LDAP filters (#2209) --- api/ldap/ldap.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/api/ldap/ldap.go b/api/ldap/ldap.go index 528a92e7f..05c9d55d7 100644 --- a/api/ldap/ldap.go +++ b/api/ldap/ldap.go @@ -22,11 +22,13 @@ type Service struct{} func searchUser(username string, conn *ldap.Conn, settings []portainer.LDAPSearchSettings) (string, error) { var userDN string found := false + usernameEscaped := ldap.EscapeFilter(username) + for _, searchSettings := range settings { searchRequest := ldap.NewSearchRequest( searchSettings.BaseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, - fmt.Sprintf("(&%s(%s=%s))", searchSettings.Filter, searchSettings.UserNameAttribute, username), + fmt.Sprintf("(&%s(%s=%s))", searchSettings.Filter, searchSettings.UserNameAttribute, usernameEscaped), []string{"dn"}, nil, ) @@ -134,12 +136,13 @@ func (*Service) GetUserGroups(username string, settings *portainer.LDAPSettings) // Get a list of group names for specified user from LDAP/AD func getGroups(userDN string, conn *ldap.Conn, settings []portainer.LDAPGroupSearchSettings) []string { groups := make([]string, 0) + userDNEscaped := ldap.EscapeFilter(userDN) for _, searchSettings := range settings { searchRequest := ldap.NewSearchRequest( searchSettings.GroupBaseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, - fmt.Sprintf("(&%s(%s=%s))", searchSettings.GroupFilter, searchSettings.GroupAttribute, userDN), + fmt.Sprintf("(&%s(%s=%s))", searchSettings.GroupFilter, searchSettings.GroupAttribute, userDNEscaped), []string{"cn"}, nil, ) From f0f01c33bd9df57de33cb2fc056c6b7cb367a821 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Wed, 26 Sep 2018 18:59:50 +1200 Subject: [PATCH 29/32] feat(endpoint-creation): add requirement message for agent endpoint (#2303) --- .../endpoints/create/createEndpointController.js | 10 ++++++++-- .../views/endpoints/create/createendpoint.html | 12 ++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/app/portainer/views/endpoints/create/createEndpointController.js b/app/portainer/views/endpoints/create/createEndpointController.js index 13fc1ad16..c682bee1b 100644 --- a/app/portainer/views/endpoints/create/createEndpointController.js +++ b/app/portainer/views/endpoints/create/createEndpointController.js @@ -1,6 +1,6 @@ angular.module('portainer.app') -.controller('CreateEndpointController', ['$q', '$scope', '$state', '$filter', 'EndpointService', 'GroupService', 'TagService', 'Notifications', -function ($q, $scope, $state, $filter, EndpointService, GroupService, TagService, Notifications) { +.controller('CreateEndpointController', ['$q', '$scope', '$state', '$filter', 'clipboard', 'EndpointService', 'GroupService', 'TagService', 'Notifications', +function ($q, $scope, $state, $filter, clipboard, EndpointService, GroupService, TagService, Notifications) { $scope.state = { EnvironmentType: 'docker', @@ -19,6 +19,12 @@ function ($q, $scope, $state, $filter, EndpointService, GroupService, TagService Tags: [] }; + $scope.copyAgentCommand = function() { + clipboard.copyText('curl -L https://portainer.io/download/agent-stack.yml -o agent-stack.yml && docker stack deploy --compose-file=agent-stack.yml portainer-agent'); + $('#copyNotification').show(); + $('#copyNotification').fadeOut(2000); + }; + $scope.addDockerEndpoint = function() { var name = $scope.formValues.Name; var URL = $filter('stripprotocol')($scope.formValues.URL); diff --git a/app/portainer/views/endpoints/create/createendpoint.html b/app/portainer/views/endpoints/create/createendpoint.html index ff8e7c232..4b7a762bd 100644 --- a/app/portainer/views/endpoints/create/createendpoint.html +++ b/app/portainer/views/endpoints/create/createendpoint.html @@ -64,8 +64,16 @@
- If you have started Portainer in the same overlay network as the agent, you can use tasks.AGENT_SERVICE_NAME:AGENT_SERVICE_PORT as the - endpoint URL format. + Ensure that you have deployed the Portainer agent in your cluster first. You can use execute the following command on any manager node to deploy it. +
+ + curl -L https://portainer.io/download/agent-stack.yml -o agent-stack.yml && docker stack deploy --compose-file=agent-stack.yml portainer-agent + + Copy + + + +
From 92b15523f07d85cd577ef7c09e19c496c07f3755 Mon Sep 17 00:00:00 2001 From: Angele Date: Fri, 28 Sep 2018 00:49:30 +0200 Subject: [PATCH 30/32] feat(containers): add container name in error notification * containersDatable: add containers name if error on executeActionOnContainerList * Update containersDatatableActionsController.js * Update containersDatatableActionsController.js --- .../actions/containersDatatableActionsController.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/docker/components/datatables/containers-datatable/actions/containersDatatableActionsController.js b/app/docker/components/datatables/containers-datatable/actions/containersDatatableActionsController.js index 88980f8f3..efacb89e7 100644 --- a/app/docker/components/datatables/containers-datatable/actions/containersDatatableActionsController.js +++ b/app/docker/components/datatables/containers-datatable/actions/containersDatatableActionsController.js @@ -72,6 +72,7 @@ function ($state, ContainerService, ModalService, Notifications, HttpRequestHelp Notifications.success(successMessage, container.Names[0]); }) .catch(function error(err) { + errorMessage = errorMessage + ':' + container.Names[0]; Notifications.error('Failure', err, errorMessage); }) .finally(function final() { From 226c45f0355f9897e5e4762db2851b1081a8c8ee Mon Sep 17 00:00:00 2001 From: Chaim Lev-Ari Date: Fri, 28 Sep 2018 06:06:47 +0300 Subject: [PATCH 31/32] fix(template-creation): fix an issue related to the network setting (#2312) * bug(template): pass network name on creation * bug(templates): choose network object on update * fix(templates): set network only when available --- app/portainer/models/template.js | 2 +- app/portainer/views/templates/edit/templateController.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/portainer/models/template.js b/app/portainer/models/template.js index 0218ce8a2..6b9509958 100644 --- a/app/portainer/models/template.js +++ b/app/portainer/models/template.js @@ -25,7 +25,7 @@ function TemplateCreateRequest(model) { this.Image = model.Image; this.Registry = model.Registry.URL; this.Command = model.Command; - this.Network = model.Network; + this.Network = model.Network && model.Network.Name; this.Privileged = model.Privileged; this.Interactive = model.Interactive; this.RestartPolicy = model.RestartPolicy; diff --git a/app/portainer/views/templates/edit/templateController.js b/app/portainer/views/templates/edit/templateController.js index ccf82d228..352764e43 100644 --- a/app/portainer/views/templates/edit/templateController.js +++ b/app/portainer/views/templates/edit/templateController.js @@ -38,6 +38,12 @@ function ($q, $scope, $state, $transition$, TemplateService, TemplateHelper, Net ) }) .then(function success(data) { + var template = data.template; + if (template.Network) { + template.Network = _.find(data.networks, function(o) { return o.Name === template.Network; }); + } else { + template.Network = _.find(data.networks, function(o) { return o.Name === 'bridge'; }); + } $scope.categories = TemplateHelper.getUniqueCategories(data.templates); $scope.template = data.template; $scope.networks = data.networks; From 5be2684442db3716a41067f2eb60a017ec8c5df5 Mon Sep 17 00:00:00 2001 From: Chaim Lev-Ari Date: Sun, 30 Sep 2018 01:20:10 +0300 Subject: [PATCH 32/32] feat(home): add the ability to edit an endpoint (#2305) * feat(home): add edit button * feat(home): style edit button * feat(home): make endpoint editable on admin only --- .../endpoint-item/endpoint-item-controller.js | 12 ++++++++++++ .../endpoint-list/endpoint-item/endpointItem.html | 12 ++++++++++-- .../endpoint-list/endpoint-item/endpointItem.js | 7 +++++-- .../components/endpoint-list/endpoint-list.js | 4 +++- .../components/endpoint-list/endpointList.html | 2 ++ app/portainer/views/home/home.html | 2 ++ app/portainer/views/home/homeController.js | 6 ++++++ 7 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 app/portainer/components/endpoint-list/endpoint-item/endpoint-item-controller.js diff --git a/app/portainer/components/endpoint-list/endpoint-item/endpoint-item-controller.js b/app/portainer/components/endpoint-list/endpoint-item/endpoint-item-controller.js new file mode 100644 index 000000000..62433ee25 --- /dev/null +++ b/app/portainer/components/endpoint-list/endpoint-item/endpoint-item-controller.js @@ -0,0 +1,12 @@ +angular.module('portainer.app').controller('EndpointItemController', [ + function EndpointItemController() { + var ctrl = this; + + ctrl.editEndpoint = editEndpoint; + + function editEndpoint(event) { + event.stopPropagation(); + ctrl.onEdit(ctrl.model.Id); + } + } +]); diff --git a/app/portainer/components/endpoint-list/endpoint-item/endpointItem.html b/app/portainer/components/endpoint-list/endpoint-item/endpointItem.html index 322ab9a90..6e643da5b 100644 --- a/app/portainer/components/endpoint-list/endpoint-item/endpointItem.html +++ b/app/portainer/components/endpoint-list/endpoint-item/endpointItem.html @@ -21,8 +21,16 @@ - - Group: {{ $ctrl.model.GroupName }} + + + + Group: {{ $ctrl.model.GroupName }} + + diff --git a/app/portainer/components/endpoint-list/endpoint-item/endpointItem.js b/app/portainer/components/endpoint-list/endpoint-item/endpointItem.js index d04fb25cf..450fa089d 100644 --- a/app/portainer/components/endpoint-list/endpoint-item/endpointItem.js +++ b/app/portainer/components/endpoint-list/endpoint-item/endpointItem.js @@ -2,6 +2,9 @@ angular.module('portainer.app').component('endpointItem', { templateUrl: 'app/portainer/components/endpoint-list/endpoint-item/endpointItem.html', bindings: { model: '<', - onSelect: '<' - } + onSelect: '<', + onEdit: '<', + isAdmin:'<' + }, + controller: 'EndpointItemController' }); diff --git a/app/portainer/components/endpoint-list/endpoint-list.js b/app/portainer/components/endpoint-list/endpoint-list.js index d11d7611d..d6a4bd33e 100644 --- a/app/portainer/components/endpoint-list/endpoint-list.js +++ b/app/portainer/components/endpoint-list/endpoint-list.js @@ -11,6 +11,8 @@ angular.module('portainer.app').component('endpointList', { endpoints: '<', dashboardAction: '<', snapshotAction: '<', - showSnapshotAction: '<' + showSnapshotAction: '<', + editAction: '<', + isAdmin:'<' } }); diff --git a/app/portainer/components/endpoint-list/endpointList.html b/app/portainer/components/endpoint-list/endpointList.html index 9110703f9..9b4850dd0 100644 --- a/app/portainer/components/endpoint-list/endpointList.html +++ b/app/portainer/components/endpoint-list/endpointList.html @@ -24,6 +24,8 @@ ng-repeat="endpoint in $ctrl.endpoints | filter:$ctrl.state.textFilter" model="endpoint" on-select="$ctrl.dashboardAction" + on-edit="$ctrl.editAction" + is-admin="$ctrl.isAdmin" >
Loading... diff --git a/app/portainer/views/home/home.html b/app/portainer/views/home/home.html index e9de46386..1ffaa88bd 100644 --- a/app/portainer/views/home/home.html +++ b/app/portainer/views/home/home.html @@ -44,6 +44,8 @@ dashboard-action="goToDashboard" show-snapshot-action="!applicationState.application.authentication || isAdmin" snapshot-action="triggerSnapshot" + edit-action="goToEdit" + is-admin="isAdmin" >
diff --git a/app/portainer/views/home/homeController.js b/app/portainer/views/home/homeController.js index 684c1ff7e..f666e49d7 100644 --- a/app/portainer/views/home/homeController.js +++ b/app/portainer/views/home/homeController.js @@ -62,6 +62,12 @@ function ($q, $scope, $state, Authentication, EndpointService, EndpointHelper, G }); } + $scope.goToEdit = goToEdit; + + function goToEdit(id) { + $state.go('portainer.endpoints.endpoint', { id: id }); + } + function initView() { $scope.isAdmin = Authentication.getUserDetails().role === 1;