mirror of https://github.com/portainer/portainer
style(dashboard): update dashboard information (#2079)
* style(dashboard): update dashboard information * docs(swagger): update swagger.ymlpull/2080/head
parent
3306cbaa27
commit
134a38a566
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -34,32 +34,37 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" ng-if="!applicationState.endpoint.mode.agentProxy || applicationState.endpoint.mode.provider !== 'DOCKER_SWARM_MODE'">
|
||||
<div class="row" ng-if="(!applicationState.endpoint.mode.agentProxy || applicationState.endpoint.mode.provider !== 'DOCKER_SWARM_MODE') && info && endpoint">
|
||||
<div class="col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-tachometer-alt" title-text="Node info"></rd-widget-header>
|
||||
<rd-widget-header icon="fa-tachometer-alt" title-text="Endpoint info"></rd-widget-header>
|
||||
<rd-widget-body classes="no-padding">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
<td>{{ infoData.Name }}</td>
|
||||
<td>Endpoint</td>
|
||||
<td>
|
||||
{{ endpoint.Name }}
|
||||
<span class="small text-muted space-left"><i class="fa fa-microchip"></i> {{ info.NCPU }}<i class="fa fa-memory space-left"></i> {{ info.MemTotal | humansize }}</span>
|
||||
<span class="small text-muted"> - {{ info.Swarm && info.Swarm.NodeID !== '' ? 'Swarm' : 'Standalone' }} {{ info.ServerVersion }} <span ng-if="endpoint.Type === 2">+ <i class="fa fa-bolt" aria-hidden="true"></i> Agent</span></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Docker version</td>
|
||||
<td>{{ infoData.ServerVersion }}</td>
|
||||
<td>URL</td>
|
||||
<td>{{ endpoint.URL | stripprotocol }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CPU</td>
|
||||
<td>{{ infoData.NCPU }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Memory</td>
|
||||
<td>{{ infoData.MemTotal|humansize }}</td>
|
||||
</tr>
|
||||
<tr ng-if="applicationState.endpoint.mode.provider === 'DOCKER_SWARM_MODE'">
|
||||
<td>Node role</td>
|
||||
<td>{{ infoData.Swarm.ControlAvailable ? 'Manager' : 'Worker' }}</td>
|
||||
<td>Tags</td>
|
||||
<td>
|
||||
<span ng-if="endpoint.Tags.length === 0">
|
||||
-
|
||||
</span>
|
||||
<span ng-if="endpoint.Tags.length > 0">
|
||||
<span ng-repeat="tag in endpoint.Tags">
|
||||
{{ tag }}{{ $last? '' : ', ' }}
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="applicationState.endpoint.mode.provider === 'DOCKER_SWARM_MODE' && applicationState.endpoint.mode.role === 'MANAGER'">
|
||||
<td colspan="2">
|
||||
|
@ -102,7 +107,7 @@
|
|||
</rd-widget>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<div class="col-xs-12 col-md-6" ng-if="containers">
|
||||
<a ui-sref="docker.containers">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
|
@ -110,16 +115,16 @@
|
|||
<i class="fa fa-server"></i>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<div><i class="fa fa-heartbeat space-right green-icon"></i>{{ containerData.running }} running</div>
|
||||
<div><i class="fa fa-heartbeat space-right red-icon"></i>{{ containerData.stopped }} stopped</div>
|
||||
<div><i class="fa fa-heartbeat space-right green-icon"></i>{{ containers | containerswithstatus:'running' }} running</div>
|
||||
<div><i class="fa fa-heartbeat space-right red-icon"></i>{{ containers | containerswithstatus:'stopped' }} stopped</div>
|
||||
</div>
|
||||
<div class="title">{{ containerData.total }}</div>
|
||||
<div class="title">{{ containers.length }}</div>
|
||||
<div class="comment">Containers</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<div class="col-xs-12 col-md-6" ng-if="images">
|
||||
<a ui-sref="docker.images">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
|
@ -127,9 +132,9 @@
|
|||
<i class="fa fa-clone"></i>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<div><i class="fa fa-chart-pie space-right"></i>{{ imageData.size|humansize }}</div>
|
||||
<div><i class="fa fa-chart-pie space-right"></i>{{ images | imagestotalsize | humansize }}</div>
|
||||
</div>
|
||||
<div class="title">{{ imageData.total }}</div>
|
||||
<div class="title">{{ images.length }}</div>
|
||||
<div class="comment">Images</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
|
@ -142,7 +147,7 @@
|
|||
<div class="widget-icon blue pull-left">
|
||||
<i class="fa fa-cubes"></i>
|
||||
</div>
|
||||
<div class="title">{{ volumeData.total }}</div>
|
||||
<div class="title">{{ volumeCount }}</div>
|
||||
<div class="comment">Volumes</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
|
@ -155,7 +160,7 @@
|
|||
<div class="widget-icon blue pull-left">
|
||||
<i class="fa fa-sitemap"></i>
|
||||
</div>
|
||||
<div class="title">{{ networkData.total }}</div>
|
||||
<div class="title">{{ networkCount }}</div>
|
||||
<div class="comment">Networks</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue