diff --git a/api/http/handler/endpoints/endpoint_inspect.go b/api/http/handler/endpoints/endpoint_inspect.go index 82d2cb7b9..e382b3f16 100644 --- a/api/http/handler/endpoints/endpoint_inspect.go +++ b/api/http/handler/endpoints/endpoint_inspect.go @@ -23,5 +23,12 @@ func (handler *Handler) endpointInspect(w http.ResponseWriter, r *http.Request) return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err} } + err = handler.requestBouncer.EndpointAccess(r, endpoint) + if err != nil { + return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access endpoint", portainer.ErrEndpointAccessDenied} + } + + hideFields(endpoint) + return response.JSON(w, endpoint) } diff --git a/api/http/handler/endpoints/handler.go b/api/http/handler/endpoints/handler.go index 69440037e..1c6e79cc4 100644 --- a/api/http/handler/endpoints/handler.go +++ b/api/http/handler/endpoints/handler.go @@ -25,6 +25,7 @@ func hideFields(endpoint *portainer.Endpoint) { type Handler struct { *mux.Router authorizeEndpointManagement bool + requestBouncer *security.RequestBouncer EndpointService portainer.EndpointService EndpointGroupService portainer.EndpointGroupService FileService portainer.FileService @@ -37,6 +38,7 @@ func NewHandler(bouncer *security.RequestBouncer, authorizeEndpointManagement bo h := &Handler{ Router: mux.NewRouter(), authorizeEndpointManagement: authorizeEndpointManagement, + requestBouncer: bouncer, } h.Handle("/endpoints", @@ -44,7 +46,7 @@ func NewHandler(bouncer *security.RequestBouncer, authorizeEndpointManagement bo h.Handle("/endpoints", bouncer.RestrictedAccess(httperror.LoggerHandler(h.endpointList))).Methods(http.MethodGet) h.Handle("/endpoints/{id}", - bouncer.AdministratorAccess(httperror.LoggerHandler(h.endpointInspect))).Methods(http.MethodGet) + bouncer.RestrictedAccess(httperror.LoggerHandler(h.endpointInspect))).Methods(http.MethodGet) h.Handle("/endpoints/{id}", bouncer.AdministratorAccess(httperror.LoggerHandler(h.endpointUpdate))).Methods(http.MethodPut) h.Handle("/endpoints/{id}/access", diff --git a/api/swagger.yaml b/api/swagger.yaml index 07c5a9f45..fec94d1dd 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -320,7 +320,7 @@ paths: summary: "Inspect an endpoint" description: | Retrieve details abount an endpoint. - **Access policy**: administrator + **Access policy**: restricted operationId: "EndpointInspect" produces: - "application/json" diff --git a/app/docker/filters/filters.js b/app/docker/filters/filters.js index 9b0ba8c0b..b6f9a71dd 100644 --- a/app/docker/filters/filters.js +++ b/app/docker/filters/filters.js @@ -218,6 +218,30 @@ angular.module('portainer.docker') return runningTasks; }; }) +.filter('containerswithstatus', function () { + 'use strict'; + return function (containers, status) { + var containersWithStatus = 0; + for (var i = 0; i < containers.length; i++) { + var container = containers[i]; + if (container.Status === status) { + containersWithStatus++; + } + } + return containersWithStatus; + }; +}) +.filter('imagestotalsize', function () { + 'use strict'; + return function (images) { + var totalImageSize = 0; + for (var i = 0; i < images.length; i++) { + var item = images[i]; + totalImageSize += item.VirtualSize; + } + return totalImageSize; + }; +}) .filter('tasknodename', function () { 'use strict'; return function (nodeId, nodes) { diff --git a/app/docker/views/dashboard/dashboard.html b/app/docker/views/dashboard/dashboard.html index 26c22be3c..86950c43e 100644 --- a/app/docker/views/dashboard/dashboard.html +++ b/app/docker/views/dashboard/dashboard.html @@ -34,32 +34,37 @@ -
Name | -{{ infoData.Name }} | +Endpoint | ++ {{ endpoint.Name }} + {{ info.NCPU }} {{ info.MemTotal | humansize }} + - {{ info.Swarm && info.Swarm.NodeID !== '' ? 'Swarm' : 'Standalone' }} {{ info.ServerVersion }} + Agent + |
Docker version | -{{ infoData.ServerVersion }} | +URL | +{{ endpoint.URL | stripprotocol }} |
CPU | -{{ infoData.NCPU }} | -||
Memory | -{{ infoData.MemTotal|humansize }} | -||
Node role | -{{ infoData.Swarm.ControlAvailable ? 'Manager' : 'Worker' }} | +Tags | ++ + - + + + + {{ tag }}{{ $last? '' : ', ' }} + + + |
@@ -102,7 +107,7 @@
-
+
-
-
- {{ containerData.running }} running
- {{ containerData.stopped }} stopped
+ {{ containers | containerswithstatus:'running' }} running
+ {{ containers | containerswithstatus:'stopped' }} stopped
{{ containerData.total }}
+ {{ containers.length }}
Containers
+
-
- {{ imageData.size|humansize }}
+ {{ images | imagestotalsize | humansize }}
{{ imageData.total }}
+ {{ images.length }}
Images
@@ -142,7 +147,7 @@
- {{ volumeData.total }}
+ {{ volumeCount }}
Volumes
@@ -155,7 +160,7 @@
- {{ networkData.total }}
+ {{ networkCount }}
Networks
diff --git a/app/docker/views/dashboard/dashboardController.js b/app/docker/views/dashboard/dashboardController.js
index 4f478bc60..d9bf1b2c4 100644
--- a/app/docker/views/dashboard/dashboardController.js
+++ b/app/docker/views/dashboard/dashboardController.js
@@ -1,95 +1,33 @@
angular.module('portainer.docker')
-.controller('DashboardController', ['$scope', '$q', 'Container', 'ContainerHelper', 'Image', 'Network', 'Volume', 'SystemService', 'ServiceService', 'StackService', 'Notifications', 'EndpointProvider',
-function ($scope, $q, Container, ContainerHelper, Image, Network, Volume, SystemService, ServiceService, StackService, Notifications, EndpointProvider) {
-
- $scope.containerData = {
- total: 0
- };
- $scope.imageData = {
- total: 0
- };
- $scope.networkData = {
- total: 0
- };
- $scope.volumeData = {
- total: 0
- };
-
- $scope.serviceCount = 0;
- $scope.stackCount = 0;
-
- function prepareContainerData(d) {
- var running = 0;
- var stopped = 0;
- var containers = d;
-
- for (var i = 0; i < containers.length; i++) {
- var item = containers[i];
- if (item.Status.indexOf('Up') !== -1) {
- running += 1;
- } else if (item.Status.indexOf('Exit') !== -1) {
- stopped += 1;
- }
- }
- $scope.containerData.running = running;
- $scope.containerData.stopped = stopped;
- $scope.containerData.total = containers.length;
- }
-
- function prepareImageData(d) {
- var images = d;
- var totalImageSize = 0;
- for (var i = 0; i < images.length; i++) {
- var item = images[i];
- totalImageSize += item.VirtualSize;
- }
- $scope.imageData.total = images.length;
- $scope.imageData.size = totalImageSize;
- }
-
- function prepareVolumeData(d) {
- var volumes = d.Volumes;
- if (volumes) {
- $scope.volumeData.total = volumes.length;
- }
- }
-
- function prepareNetworkData(d) {
- var networks = d;
- $scope.networkData.total = networks.length;
- }
-
- function prepareInfoData(d) {
- var info = d;
- $scope.infoData = info;
- }
+.controller('DashboardController', ['$scope', '$q', 'ContainerService', 'ImageService', 'NetworkService', 'VolumeService', 'SystemService', 'ServiceService', 'StackService', 'EndpointService', 'Notifications', 'EndpointProvider',
+function ($scope, $q, ContainerService, ImageService, NetworkService, VolumeService, SystemService, ServiceService, StackService, EndpointService, Notifications, EndpointProvider) {
function initView() {
var endpointMode = $scope.applicationState.endpoint.mode;
var endpointId = EndpointProvider.endpointID();
- $q.all([
- Container.query({all: 1}).$promise,
- Image.query({}).$promise,
- Volume.query({}).$promise,
- Network.query({}).$promise,
- SystemService.info(),
- endpointMode.provider === 'DOCKER_SWARM_MODE' && endpointMode.role === 'MANAGER' ? ServiceService.services() : [],
- StackService.stacks(
- true,
- endpointMode.provider === 'DOCKER_SWARM_MODE' && endpointMode.role === 'MANAGER',
- endpointId
- )
- ]).then(function (d) {
- prepareContainerData(d[0]);
- prepareImageData(d[1]);
- prepareVolumeData(d[2]);
- prepareNetworkData(d[3]);
- prepareInfoData(d[4]);
- $scope.serviceCount = d[5].length;
- $scope.stackCount = d[6].length;
- }, function(e) {
- Notifications.error('Failure', e, 'Unable to load dashboard data');
+ $q.all({
+ containers: ContainerService.containers(1),
+ images: ImageService.images(false),
+ volumes: VolumeService.volumes(),
+ networks: NetworkService.networks(true, true, true),
+ services: endpointMode.provider === 'DOCKER_SWARM_MODE' && endpointMode.role === 'MANAGER' ? ServiceService.services() : [],
+ stacks: StackService.stacks(true, endpointMode.provider === 'DOCKER_SWARM_MODE' && endpointMode.role === 'MANAGER', endpointId),
+ info: SystemService.info(),
+ endpoint: EndpointService.endpoint(endpointId)
+ })
+ .then(function success(data) {
+ $scope.containers = data.containers;
+ $scope.images = data.images;
+ $scope.volumeCount = data.volumes.length;
+ $scope.networkCount = data.networks.length;
+ $scope.serviceCount = data.services.length;
+ $scope.stackCount = data.stacks.length;
+ $scope.info = data.info;
+ $scope.endpoint = data.endpoint;
+ })
+ .catch(function error(err) {
+ Notifications.error('Failure', err, 'Unable to load dashboard data');
});
}
|