Add details view for hosts panel
This patch adds host details view for admin. Change-Id: I99a7429f226bf62edea2f745e844c963099a48e8 Implements: blueprint add-host-panel
This commit is contained in:
parent
7ebff515a7
commit
ddb31065ab
@ -1,4 +1,5 @@
|
||||
@import "containers/containers";
|
||||
@import "hosts/hosts";
|
||||
|
||||
.batch-action {
|
||||
float: right;
|
||||
|
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @ngname horizon.dashboard.container.hosts.details
|
||||
*
|
||||
* @description
|
||||
* Provides details for host.
|
||||
*/
|
||||
angular.module('horizon.dashboard.container.hosts.details',
|
||||
['horizon.framework.conf', 'horizon.app.core'])
|
||||
.run(registerDetails);
|
||||
|
||||
registerDetails.$inject = [
|
||||
'horizon.dashboard.container.hosts.basePath',
|
||||
'horizon.dashboard.container.hosts.resourceType',
|
||||
'horizon.dashboard.container.hosts.service',
|
||||
'horizon.framework.conf.resource-type-registry.service'
|
||||
];
|
||||
|
||||
function registerDetails(
|
||||
basePath,
|
||||
resourceType,
|
||||
hostService,
|
||||
registry
|
||||
) {
|
||||
registry.getResourceType(resourceType)
|
||||
.setLoadFunction(hostService.getHostPromise)
|
||||
.detailsViews
|
||||
.append({
|
||||
id: 'hostDetailsOverview',
|
||||
name: gettext('Overview'),
|
||||
template: basePath + 'details/overview.html'
|
||||
});
|
||||
}
|
||||
})();
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
angular
|
||||
.module('horizon.dashboard.container.hosts')
|
||||
.controller('horizon.dashboard.container.hosts.OverviewController', controller);
|
||||
|
||||
controller.$inject = [
|
||||
'$scope'
|
||||
];
|
||||
|
||||
function controller(
|
||||
$scope
|
||||
) {
|
||||
var ctrl = this;
|
||||
ctrl.chartSettings = {
|
||||
innerRadius: 24,
|
||||
outerRadius: 48,
|
||||
titleClass: "pie-chart-title-medium",
|
||||
showTitle: false,
|
||||
showLabel: true,
|
||||
showLegend: false,
|
||||
tooltipIcon: 'fa-square'
|
||||
};
|
||||
// Chart data is watched by pie-chart directive.
|
||||
// So to refresh chart after retrieving data, update whole of 'data' array.
|
||||
ctrl.chartDataMem = {
|
||||
maxLimit: 10,
|
||||
data: []
|
||||
};
|
||||
ctrl.chartDataCpu = {
|
||||
maxLimit: 10,
|
||||
data: []
|
||||
};
|
||||
ctrl.chartDataDisk = {
|
||||
maxLimit: 10,
|
||||
data: []
|
||||
};
|
||||
// container for temporal chart data
|
||||
var dataMem = [];
|
||||
var dataCpu = [];
|
||||
var dataDisk = [];
|
||||
|
||||
$scope.context.loadPromise.then(onGetHost);
|
||||
|
||||
function onGetHost(host) {
|
||||
ctrl.host = host.data;
|
||||
|
||||
// set data for memory chart
|
||||
dataMem = [
|
||||
{label: gettext("Used"), value: host.data.mem_used, colorClass: "exists"},
|
||||
{label: gettext("Margin"), value: host.data.mem_total - host.data.mem_used,
|
||||
colorClass: "margin"}
|
||||
];
|
||||
ctrl.chartDataMem = generateChartData(dataMem, gettext("Memory"));
|
||||
|
||||
// set data for CPU chart
|
||||
dataCpu = [
|
||||
{label: gettext("Used"), value: host.data.cpu_used, colorClass: "exists"},
|
||||
{label: gettext("Margin"), value: host.data.cpus - host.data.cpu_used,
|
||||
colorClass: "margin"}
|
||||
];
|
||||
ctrl.chartDataCpu = generateChartData(dataCpu, gettext("CPU"));
|
||||
|
||||
// set data for disk chart
|
||||
dataDisk = [
|
||||
{label: gettext("Used"), value: host.data.disk_used, colorClass: "exists"},
|
||||
{label: gettext("Margin"), value: host.data.disk_total - host.data.disk_used,
|
||||
colorClass: "margin"}
|
||||
];
|
||||
ctrl.chartDataDisk = generateChartData(dataDisk, gettext("Disk"));
|
||||
}
|
||||
|
||||
function generateChartData(data, title) {
|
||||
var sum = data[0].value;
|
||||
var max = data[0].value + data[1].value;
|
||||
var percent = Math.round(sum / max * 100);
|
||||
var overMax = percent > 100;
|
||||
var result = {
|
||||
title: title,
|
||||
label: percent + '%',
|
||||
maxLimit: max,
|
||||
overMax: overMax,
|
||||
data: data
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
})();
|
@ -0,0 +1,60 @@
|
||||
<div ng-controller="horizon.dashboard.container.hosts.OverviewController as ctrl">
|
||||
<div class="row">
|
||||
<div class="col-md-12 detail">
|
||||
<h3 translate>Usage</h3>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h4 translate>Memory</h4>
|
||||
<hr>
|
||||
<pie-chart chart-data="ctrl.chartDataMem"
|
||||
chart-settings="ctrl.chartSettings"></pie-chart>
|
||||
<dl class="dl-horizontal">
|
||||
<dd translate>Used {$ ctrl.host.mem_used | mb $} of {$ ctrl.host.mem_total | mb $}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h4 translate>CPU</h4>
|
||||
<hr>
|
||||
<pie-chart chart-data="ctrl.chartDataCpu"
|
||||
chart-settings="ctrl.chartSettings"></pie-chart>
|
||||
<dl class="dl-horizontal">
|
||||
<dd translate>Used {$ ctrl.host.cpu_used $} of {$ ctrl.host.cpus $}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h4 translate>Disk</h4>
|
||||
<hr>
|
||||
<pie-chart chart-data="ctrl.chartDataDisk"
|
||||
chart-settings="ctrl.chartSettings"></pie-chart>
|
||||
<dl class="dl-horizontal">
|
||||
<dd translate>Used {$ ctrl.host.disk_used | gb $} of {$ ctrl.host.disk_total | gb $}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 detail">
|
||||
<h3 translate>Info</h3>
|
||||
<hr>
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Zun::Host"
|
||||
cls="dl-horizontal"
|
||||
item="ctrl.host"
|
||||
property-groups="[['id', 'hostname', 'architecture', 'os', 'os_type',
|
||||
'kernel_version', 'runtimes', 'total_containers', 'disk_quota_supported']]">
|
||||
</hz-resource-property-list>
|
||||
</div>
|
||||
<div class="col-md-6 detail">
|
||||
<h3 translate>Miscellaneous</h3>
|
||||
<hr>
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Zun::Host"
|
||||
cls="dl-horizontal"
|
||||
item="ctrl.host"
|
||||
property-groups="[['labels', 'links']]">
|
||||
</hz-resource-property-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -25,7 +25,8 @@
|
||||
*/
|
||||
angular
|
||||
.module('horizon.dashboard.container.hosts', [
|
||||
'ngRoute'
|
||||
'ngRoute',
|
||||
'horizon.dashboard.container.hosts.details'
|
||||
])
|
||||
.constant('horizon.dashboard.container.hosts.resourceType', 'OS::Zun::Host')
|
||||
.run(run)
|
||||
@ -45,6 +46,7 @@
|
||||
// for detail summary view on table row.
|
||||
.setSummaryTemplateUrl(basePath + 'drawer.html')
|
||||
// for table row items and detail summary view.
|
||||
.setDefaultIndexUrl('/admin/container/hosts/')
|
||||
.setProperties(hostProperties())
|
||||
.setListFunction(hostService.getHostsPromise)
|
||||
.tableColumns
|
||||
@ -55,7 +57,8 @@
|
||||
.append({
|
||||
id: 'hostname',
|
||||
priority: 1,
|
||||
sortDefault: true
|
||||
sortDefault: true,
|
||||
urlFunction: hostService.getDetailsPath
|
||||
})
|
||||
.append({
|
||||
id: 'mem_total',
|
||||
@ -95,13 +98,14 @@
|
||||
'disk_used': { label: gettext('Disk Used'), filters: ['noValue', 'gb'] },
|
||||
'disk_quota_supported': { label: gettext('Disk Quota Supported'),
|
||||
filters: ['noValue', 'yesno'] },
|
||||
'total_containers': { label: gettext('Disk Used'), filters: ['noValue'] },
|
||||
'total_containers': { label: gettext('Total Containers'), filters: ['noValue'] },
|
||||
'os': { label: gettext('OS'), filters: ['noValue'] },
|
||||
'os_type': { label: gettext('OS Type'), filters: ['noValue'] },
|
||||
'architecture': { label: gettext('Architecture'), filters: ['noValue'] },
|
||||
'kernel_version': { label: gettext('Kernel Version'), filters: ['noValue'] },
|
||||
'runtimes': { label: gettext('Runtimes'), filters: ['noValue'] },
|
||||
'labels': { label: gettext('Labels'), filters: ['noValue'] }
|
||||
'runtimes': { label: gettext('Runtimes'), filters: ['noValue', 'json'] },
|
||||
'labels': { label: gettext('Labels'), filters: ['noValue', 'json'] },
|
||||
'links': { label: gettext('Links'), filters: ['noValue', 'json'] }
|
||||
};
|
||||
}
|
||||
|
||||
|
45
zun_ui/static/dashboard/container/hosts/hosts.scss
Normal file
45
zun_ui/static/dashboard/container/hosts/hosts.scss
Normal file
@ -0,0 +1,45 @@
|
||||
.pie-chart {
|
||||
display: block;
|
||||
.svg-pie-chart {
|
||||
.slice {
|
||||
&.exists {
|
||||
fill: lighten(blue, 20%);
|
||||
}
|
||||
&.margin {
|
||||
fill: $gray-lighter;
|
||||
}
|
||||
}
|
||||
}
|
||||
.pie-chart-legend {
|
||||
display: inline-block;
|
||||
margin-left: 20px;
|
||||
.slice-legend {
|
||||
.slice-key {
|
||||
&.exists {
|
||||
background-color: lighten(blue, 20%);
|
||||
}
|
||||
&.margin {
|
||||
background-color: $gray-lighter;
|
||||
}
|
||||
}
|
||||
.chartless {
|
||||
&.exists {
|
||||
color: lighten(blue, 20%);
|
||||
}
|
||||
&.margin {
|
||||
color: $gray-lighter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.chart-tooltip {
|
||||
span.fa {
|
||||
&.exists {
|
||||
color: lighten(blue, 20%);
|
||||
}
|
||||
&.margin {
|
||||
color: $gray-lighter;
|
||||
}
|
||||
}
|
||||
}
|
@ -33,9 +33,36 @@
|
||||
*/
|
||||
function hostsService(detailRoute, zun) {
|
||||
return {
|
||||
getHostsPromise: getHostsPromise
|
||||
getDetailsPath: getDetailsPath,
|
||||
getHostsPromise: getHostsPromise,
|
||||
getHostPromise: getHostPromise
|
||||
};
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name getDetailsPath
|
||||
* @param item {Object} - The host object
|
||||
* @description
|
||||
* Returns the relative path to the details view.
|
||||
*/
|
||||
function getDetailsPath(item) {
|
||||
return detailRoute + 'OS::Zun::Host/' + item.id;
|
||||
}
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name getHostPromise
|
||||
* @description
|
||||
* Given an id, returns a promise for the host data.
|
||||
*/
|
||||
function getHostPromise(identifier) {
|
||||
return zun.getHost(identifier).then(modifyDetails);
|
||||
}
|
||||
|
||||
function modifyDetails(response) {
|
||||
return {data: modifyItem(response.data)};
|
||||
}
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name getHostsPromise
|
||||
@ -49,12 +76,12 @@
|
||||
|
||||
function modifyResponse(response) {
|
||||
return {data: {items: response.data.items.map(modifyItem)}};
|
||||
}
|
||||
|
||||
function modifyItem(item) {
|
||||
var timestamp = new Date();
|
||||
item.trackBy = item.id.concat(timestamp.getTime());
|
||||
return item;
|
||||
}
|
||||
function modifyItem(item) {
|
||||
var timestamp = new Date();
|
||||
item.trackBy = item.id.concat(timestamp.getTime());
|
||||
return item;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user