From ab77f149fa27cf03a8cf91bc87992c3149216a63 Mon Sep 17 00:00:00 2001 From: Anthony Lapenna Date: Wed, 25 Jul 2018 21:52:17 +0200 Subject: [PATCH] feat(home): add the ability to refresh endpoint information (#2080) * feat(home): add the ability to refresh endpoint information * style(home): update refresh confirmation message --- .../handler/endpoints/endpoint_snapshot.go | 42 +++++++++++++++++++ api/http/handler/endpoints/handler.go | 2 + .../components/endpoint-list/endpoint-list.js | 4 +- .../endpoint-list/endpointList.html | 6 +++ app/portainer/rest/endpoint.js | 3 +- app/portainer/services/api/endpointService.js | 4 ++ app/portainer/services/modalService.js | 8 ++-- app/portainer/views/home/home.html | 2 + app/portainer/views/home/homeController.js | 22 +++++++++- 9 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 api/http/handler/endpoints/endpoint_snapshot.go diff --git a/api/http/handler/endpoints/endpoint_snapshot.go b/api/http/handler/endpoints/endpoint_snapshot.go new file mode 100644 index 000000000..51a18293e --- /dev/null +++ b/api/http/handler/endpoints/endpoint_snapshot.go @@ -0,0 +1,42 @@ +package endpoints + +import ( + "log" + "net/http" + + "github.com/portainer/portainer" + httperror "github.com/portainer/portainer/http/error" + "github.com/portainer/portainer/http/response" +) + +// POST request on /api/endpoints/snapshot +func (handler *Handler) endpointSnapshot(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { + endpoints, err := handler.EndpointService.Endpoints() + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve endpoints from the database", err} + } + + for _, endpoint := range endpoints { + if endpoint.Type == portainer.AzureEnvironment { + continue + } + + snapshot, err := handler.Snapshotter.CreateSnapshot(&endpoint) + endpoint.Status = portainer.EndpointStatusUp + if err != nil { + log.Printf("http error: endpoint snapshot error (endpoint=%s, URL=%s) (err=%s)\n", endpoint.Name, endpoint.URL, err) + endpoint.Status = portainer.EndpointStatusDown + } + + if snapshot != nil { + endpoint.Snapshots = []portainer.Snapshot{*snapshot} + } + + err = handler.EndpointService.UpdateEndpoint(endpoint.ID, &endpoint) + if err != nil { + return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist endpoint changes inside the database", err} + } + } + + return response.Empty(w) +} diff --git a/api/http/handler/endpoints/handler.go b/api/http/handler/endpoints/handler.go index 1c6e79cc4..fc1bc1e6c 100644 --- a/api/http/handler/endpoints/handler.go +++ b/api/http/handler/endpoints/handler.go @@ -43,6 +43,8 @@ func NewHandler(bouncer *security.RequestBouncer, authorizeEndpointManagement bo h.Handle("/endpoints", bouncer.AdministratorAccess(httperror.LoggerHandler(h.endpointCreate))).Methods(http.MethodPost) + h.Handle("/endpoints/snapshot", + bouncer.AdministratorAccess(httperror.LoggerHandler(h.endpointSnapshot))).Methods(http.MethodPost) h.Handle("/endpoints", bouncer.RestrictedAccess(httperror.LoggerHandler(h.endpointList))).Methods(http.MethodGet) h.Handle("/endpoints/{id}", diff --git a/app/portainer/components/endpoint-list/endpoint-list.js b/app/portainer/components/endpoint-list/endpoint-list.js index 9d551591f..319d6ef08 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', { titleText: '@', titleIcon: '@', endpoints: '<', - dashboardAction: '<' + dashboardAction: '<', + snapshotAction: '<', + showSnapshotAction: '<' } }); diff --git a/app/portainer/components/endpoint-list/endpointList.html b/app/portainer/components/endpoint-list/endpointList.html index f6b904408..9110703f9 100644 --- a/app/portainer/components/endpoint-list/endpointList.html +++ b/app/portainer/components/endpoint-list/endpointList.html @@ -8,6 +8,12 @@ +
+ +
+ diff --git a/app/portainer/views/home/homeController.js b/app/portainer/views/home/homeController.js index f9d3bfe5f..88bee800b 100644 --- a/app/portainer/views/home/homeController.js +++ b/app/portainer/views/home/homeController.js @@ -1,6 +1,6 @@ angular.module('portainer.app') -.controller('HomeController', ['$q', '$scope', '$state', 'Authentication', 'EndpointService', 'EndpointHelper', 'GroupService', 'Notifications', 'EndpointProvider', 'StateManager', 'ExtensionManager', -function ($q, $scope, $state, Authentication, EndpointService, EndpointHelper, GroupService, Notifications, EndpointProvider, StateManager, ExtensionManager) { +.controller('HomeController', ['$q', '$scope', '$state', 'Authentication', 'EndpointService', 'EndpointHelper', 'GroupService', 'Notifications', 'EndpointProvider', 'StateManager', 'ExtensionManager', 'ModalService', +function ($q, $scope, $state, Authentication, EndpointService, EndpointHelper, GroupService, Notifications, EndpointProvider, StateManager, ExtensionManager, ModalService) { $scope.goToDashboard = function(endpoint) { EndpointProvider.setEndpointID(endpoint.Id); @@ -12,6 +12,24 @@ function ($q, $scope, $state, Authentication, EndpointService, EndpointHelper, G } }; + function triggerSnapshot() { + EndpointService.snapshot() + .then(function success(data) { + Notifications.success('Success', 'Endpoints updated'); + $state.reload(); + }) + .catch(function error(err) { + Notifications.error('Failure', err, 'An error occured during endpoint snapshot'); + }); + } + + $scope.triggerSnapshot = function() { + ModalService.confirmEndpointSnapshot(function (result) { + if(!result) { return; } + triggerSnapshot(); + }); + }; + function switchToAzureEndpoint(endpoint) { StateManager.updateEndpointState(endpoint.Name, endpoint.Type, []) .then(function success() {