report UI
Change-Id: Iccb042fb542d8dea2b1fe2826bc0bfbac77d83a7
This commit is contained in:
parent
0d41c806be
commit
f94c50c6d3
|
@ -1056,3 +1056,13 @@ h4.widget-title:hover {
|
|||
.loadingMask .mask{
|
||||
opacity: 0.5;
|
||||
}
|
||||
.centerLoading{
|
||||
padding-top: 20%;
|
||||
padding-left: 45%;
|
||||
}
|
||||
.popover-title{
|
||||
background: #F2DEDE;
|
||||
}
|
||||
.yellow{
|
||||
color: #FEE188 !important;
|
||||
}
|
|
@ -40,17 +40,16 @@ define([
|
|||
compassModule.stateProvider = $stateProvider;
|
||||
$urlRouterProvider.otherwise('/clusterlist');
|
||||
});
|
||||
compassModule.config(function($httpProvider){
|
||||
compassModule.config(function($httpProvider) {
|
||||
$httpProvider.interceptors.push('authenticationInterceptor');
|
||||
});
|
||||
compassModule.run(function($rootScope, $state, authService, rememberMe) {
|
||||
$rootScope.Object = Object; //Object can be used in anywhere. e.g. : Object.key({}).length == 0
|
||||
$rootScope.Object = Object; //Object can be used in anywhere. e.g. : Object.key({}).length == 0
|
||||
$rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
|
||||
if (toState.authenticate && !authService.isAuthenticated) {
|
||||
if (rememberMe.getCookie("isAuthenticated")) {
|
||||
authService.isAuthenticated = true
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// User isn't authenticated
|
||||
$state.transitionTo("login");
|
||||
event.preventDefault();
|
||||
|
@ -79,11 +78,11 @@ define([
|
|||
})
|
||||
}
|
||||
});
|
||||
compassModule.controller('errorHandlingModalController',function($scope,$modalInstance,message){
|
||||
compassModule.controller('errorHandlingModalController', function($scope, $modalInstance, message) {
|
||||
$scope.warning = message.data;
|
||||
$scope.status = message.status;
|
||||
|
||||
$scope.ok =function(){
|
||||
$scope.ok = function() {
|
||||
$modalInstance.close();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -24,6 +24,428 @@ compassAppDev.run(function($httpBackend, settings, $http) {
|
|||
return [200, message, {}];
|
||||
});
|
||||
|
||||
$httpBackend.whenPOST(/\.*\/clusters\/([0-9]|[1-9][0-9])\/action$/).respond(function(method, url, data) {
|
||||
console.log(method, url, data);
|
||||
var healthrequest = {
|
||||
"status": "start to check cluster health.",
|
||||
"cluster_id": 1
|
||||
};
|
||||
return [200, healthrequest, {}];
|
||||
});
|
||||
|
||||
$httpBackend.whenGET(/\.*\/clusters\/([0-9]|[1-9][0-9])*\/healthreports$/).respond(function(method, url, data) {
|
||||
console.log(method, url, data);
|
||||
var healthStates = ["verifying", "finished", "error", "success"];
|
||||
var reports = [{
|
||||
"name": "name1",
|
||||
"category": "neutron",
|
||||
"state": "verifying",
|
||||
"error_message": "GetResourceErrorStatus",
|
||||
"cluster_id": 1,
|
||||
"report": {
|
||||
"results": {
|
||||
"total_errors": 2,
|
||||
"actions": {
|
||||
"nova.boot_server": {
|
||||
"duration": {
|
||||
"data": [
|
||||
83.646584987640381,
|
||||
48.459306001663208
|
||||
],
|
||||
"summary": {
|
||||
"errors": 1,
|
||||
"success": "100.0%",
|
||||
"min (sec)": 48.459000000000003,
|
||||
"avg (sec)": 66.052999999999997,
|
||||
"max (sec)": 83.647000000000006,
|
||||
"total": 2,
|
||||
"errors_info": ["title", "error"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"nova.delete_server": {
|
||||
"duration": {
|
||||
"data": [
|
||||
2.3977420330047607,
|
||||
2.6214451789855957
|
||||
],
|
||||
"summary": {
|
||||
"errors": 0,
|
||||
"success": "100.0%",
|
||||
"min (sec)": 2.3980000000000001,
|
||||
"avg (sec)": 2.5099999999999998,
|
||||
"max (sec)": 2.621,
|
||||
"total": 2,
|
||||
"errors_info": ["title", "error"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"raw_output": "output1"
|
||||
}
|
||||
}, {
|
||||
"name": "name3",
|
||||
"category": "neutron",
|
||||
"state": "verifying",
|
||||
"error_message": "GetResourceErrorStatus",
|
||||
"cluster_id": 1,
|
||||
"report": {
|
||||
"results": {
|
||||
"total_errors": 2,
|
||||
"actions": {
|
||||
"nova.boot_server": {
|
||||
"duration": {
|
||||
"data": [
|
||||
83.646584987640381,
|
||||
48.459306001663208
|
||||
],
|
||||
"summary": {
|
||||
"errors": 1,
|
||||
"success": "100.0%",
|
||||
"min (sec)": 48.459000000000003,
|
||||
"avg (sec)": 66.052999999999997,
|
||||
"max (sec)": 83.647000000000006,
|
||||
"total": 2,
|
||||
"errors_info": ["title", "error"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"nova.delete_server": {
|
||||
"duration": {
|
||||
"data": [
|
||||
2.3977420330047607,
|
||||
2.6214451789855957
|
||||
],
|
||||
"summary": {
|
||||
"errors": 0,
|
||||
"success": "100.0%",
|
||||
"min (sec)": 2.3980000000000001,
|
||||
"avg (sec)": 2.5099999999999998,
|
||||
"max (sec)": 2.621,
|
||||
"total": 2,
|
||||
"errors_info": ["title", "error"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"raw_output": "output1"
|
||||
}
|
||||
}, {
|
||||
"name": "name2",
|
||||
"category": "nova",
|
||||
"state": "verifying",
|
||||
"error_message": "GetResourceErrorStatus",
|
||||
"cluster_id": 2,
|
||||
"report": {
|
||||
"results": {
|
||||
"total_errors": 2,
|
||||
"actions": {
|
||||
"neutron.create_network": {
|
||||
"duration": {
|
||||
"data": [
|
||||
0.87460207939147949,
|
||||
0.97025418281555176
|
||||
],
|
||||
"summary": {
|
||||
"errors": 1,
|
||||
"success": "100.0%",
|
||||
"min (sec)": 0.875,
|
||||
"avg (sec)": 0.92200000000000004,
|
||||
"max (sec)": 0.96999999999999997,
|
||||
"total": 2,
|
||||
"errors_info": ["title", "error"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"neutron.delete_network": {
|
||||
"duration": {
|
||||
"data": [
|
||||
0.58310413360595703,
|
||||
0.6661829948425293
|
||||
],
|
||||
"summary": {
|
||||
"errors": 0,
|
||||
"success": "100.0%",
|
||||
"min (sec)": 0.58299999999999996,
|
||||
"avg (sec)": 0.625,
|
||||
"max (sec)": 0.66600000000000004,
|
||||
"total": 2,
|
||||
"errors_info": []
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"raw_output": "output2"
|
||||
}
|
||||
}];
|
||||
return [200, reports, {}];
|
||||
|
||||
});
|
||||
|
||||
|
||||
$httpBackend.whenGET(/\.*\/clusters\/([0-9]|[1-9][0-9])\/healthreports\/.*/).respond(function(method, url, data){
|
||||
console.log(method, url, data);
|
||||
var healthStates = ["verifying","finished","error","success"];
|
||||
var indireports =
|
||||
{
|
||||
"name": "name1",
|
||||
"category": "neutron",
|
||||
"state": healthStates[Math.floor((Math.random()*4))],
|
||||
"error_message": "",
|
||||
"cluster_id": 1,
|
||||
"report": {
|
||||
"results": {
|
||||
"total_errors": 2,
|
||||
"actions": {
|
||||
"nova.boot_server": {
|
||||
"duration": {
|
||||
"data": [
|
||||
83.646584987640381,
|
||||
48.459306001663208
|
||||
],
|
||||
"summary": {
|
||||
"errors": {
|
||||
"count": 2,
|
||||
"details": [
|
||||
[
|
||||
"GetResourceErrorStatus",
|
||||
"Resource <Server: rally_novaserver_mmlywuugchuxrjth> has ERROR status: No valid host was found. ",
|
||||
"Traceback (most recent call last):\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/runners/base.py\", line 77, in _run_scenario_once\n method_name)(**kwargs) or scenario_output\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/scenarios/nova/servers.py\", line 104, in boot_and_delete_server\n self._generate_random_name(), image, flavor, **kwargs)\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/scenarios/base.py\", line 261, in func_atomic_actions\n f = func(self, *args, **kwargs)\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/scenarios/nova/utils.py\", line 126, in _boot_server\n check_interval=CONF.benchmark.nova_server_boot_poll_interval\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/utils.py\", line 104, in wait_for\n resource = update_resource(resource)\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/utils.py\", line 67, in _get_from_manager\n status=status, fault=msg)\nGetResourceErrorStatus: Resource <Server: rally_novaserver_mmlywuugchuxrjth> has ERROR status: No valid host was found. \n"
|
||||
],
|
||||
[
|
||||
"GetResourceErrorStatus",
|
||||
"Resource <Server: rally_novaserver_tydvigmxvdrwdgir> has ERROR status: No valid host was found. ",
|
||||
"Traceback (most recent call last):\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/runners/base.py\", line 77, in _run_scenario_once\n method_name)(**kwargs) or scenario_output\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/scenarios/nova/servers.py\", line 104, in boot_and_delete_server\n self._generate_random_name(), image, flavor, **kwargs)\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/scenarios/base.py\", line 261, in func_atomic_actions\n f = func(self, *args, **kwargs)\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/scenarios/nova/utils.py\", line 126, in _boot_server\n check_interval=CONF.benchmark.nova_server_boot_poll_interval\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/utils.py\", line 104, in wait_for\n resource = update_resource(resource)\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/utils.py\", line 67, in _get_from_manager\n status=status, fault=msg)\nGetResourceErrorStatus: Resource <Server: rally_novaserver_tydvigmxvdrwdgir> has ERROR status: No valid host was found. \n"
|
||||
]
|
||||
]
|
||||
},
|
||||
"success": "100.0%",
|
||||
"min (sec)": 48.459000000000003,
|
||||
"avg (sec)": 66.052999999999997,
|
||||
"max (sec)": 83.647000000000006,
|
||||
"total": 2,
|
||||
}
|
||||
}
|
||||
},
|
||||
"nova.delete_server": {
|
||||
"duration": {
|
||||
"data": [
|
||||
2.3977420330047607,
|
||||
2.6214451789855957
|
||||
],
|
||||
"summary": {
|
||||
"errors": 0,
|
||||
"success": "100.0%",
|
||||
"min (sec)": 2.3980000000000001,
|
||||
"avg (sec)": 2.5099999999999998,
|
||||
"max (sec)": 2.621,
|
||||
"total": 2,
|
||||
"errors": {
|
||||
"count": 0,
|
||||
"details": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"raw_output": {
|
||||
"result": [
|
||||
{
|
||||
"duration": 86.044774055480957,
|
||||
"scenario_output": {
|
||||
"errors": "",
|
||||
"data": {}
|
||||
},
|
||||
"idle_duration": 0.0,
|
||||
"atomic_actions": {
|
||||
"nova.boot_server": 83.646584987640381,
|
||||
"nova.delete_server": 2.3977420330047607
|
||||
},
|
||||
"error": []
|
||||
},
|
||||
{
|
||||
"duration": 51.081114053726196,
|
||||
"scenario_output": {
|
||||
"errors": "",
|
||||
"data": {}
|
||||
},
|
||||
"idle_duration": 0.0,
|
||||
"atomic_actions": {
|
||||
"nova.boot_server": 48.459306001663208,
|
||||
"nova.delete_server": 2.6214451789855957
|
||||
},
|
||||
"error": []
|
||||
}
|
||||
],
|
||||
"key": {
|
||||
"kw": {
|
||||
"runner": {
|
||||
"type": "constant",
|
||||
"concurrency": 2,
|
||||
"times": 2
|
||||
},
|
||||
"args": {
|
||||
"flavor": {
|
||||
"name": "m1.tiny"
|
||||
},
|
||||
"image": {
|
||||
"name": "cirros"
|
||||
}
|
||||
},
|
||||
"context": {
|
||||
"users": {
|
||||
"project_domain": "default",
|
||||
"users_per_tenant": 2,
|
||||
"tenants": 3,
|
||||
"resource_management_workers": 30,
|
||||
"user_domain": "default"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "NovaServers.boot_and_delete_server",
|
||||
"pos": 0
|
||||
},
|
||||
"sla": []
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
return [200, indireports, {}];
|
||||
|
||||
});
|
||||
|
||||
$httpBackend.whenGET(/\.*\/clusters\/([0-9]|[1-9][0-9])\/healthreports\/.*/).respond(function(method, url, data) {
|
||||
console.log(method, url, data);
|
||||
var healthStates = ["verifying", "finished", "error", "success"];
|
||||
var indireports = {
|
||||
"name": "name1",
|
||||
"category": "neutron",
|
||||
"state": healthStates[Math.floor((Math.random() * 4))],
|
||||
"error_message": "",
|
||||
"cluster_id": 1,
|
||||
"report": {
|
||||
"results": {
|
||||
"total_errors": 2,
|
||||
"actions": {
|
||||
"nova.boot_server": {
|
||||
"duration": {
|
||||
"data": [
|
||||
83.646584987640381,
|
||||
48.459306001663208
|
||||
],
|
||||
"summary": {
|
||||
"errors": {
|
||||
"count": 2,
|
||||
"details": [
|
||||
[
|
||||
"GetResourceErrorStatus",
|
||||
"Resource <Server: rally_novaserver_mmlywuugchuxrjth> has ERROR status: No valid host was found. ",
|
||||
"Traceback (most recent call last):\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/runners/base.py\", line 77, in _run_scenario_once\n method_name)(**kwargs) or scenario_output\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/scenarios/nova/servers.py\", line 104, in boot_and_delete_server\n self._generate_random_name(), image, flavor, **kwargs)\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/scenarios/base.py\", line 261, in func_atomic_actions\n f = func(self, *args, **kwargs)\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/scenarios/nova/utils.py\", line 126, in _boot_server\n check_interval=CONF.benchmark.nova_server_boot_poll_interval\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/utils.py\", line 104, in wait_for\n resource = update_resource(resource)\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/utils.py\", line 67, in _get_from_manager\n status=status, fault=msg)\nGetResourceErrorStatus: Resource <Server: rally_novaserver_mmlywuugchuxrjth> has ERROR status: No valid host was found. \n"
|
||||
],
|
||||
[
|
||||
"GetResourceErrorStatus",
|
||||
"Resource <Server: rally_novaserver_tydvigmxvdrwdgir> has ERROR status: No valid host was found. ",
|
||||
"Traceback (most recent call last):\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/runners/base.py\", line 77, in _run_scenario_once\n method_name)(**kwargs) or scenario_output\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/scenarios/nova/servers.py\", line 104, in boot_and_delete_server\n self._generate_random_name(), image, flavor, **kwargs)\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/scenarios/base.py\", line 261, in func_atomic_actions\n f = func(self, *args, **kwargs)\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/scenarios/nova/utils.py\", line 126, in _boot_server\n check_interval=CONF.benchmark.nova_server_boot_poll_interval\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/utils.py\", line 104, in wait_for\n resource = update_resource(resource)\n File \"/opt/rally/lib/python2.6/site-packages/rally/benchmark/utils.py\", line 67, in _get_from_manager\n status=status, fault=msg)\nGetResourceErrorStatus: Resource <Server: rally_novaserver_tydvigmxvdrwdgir> has ERROR status: No valid host was found. \n"
|
||||
]
|
||||
]
|
||||
},
|
||||
"success": "100.0%",
|
||||
"min (sec)": 48.459000000000003,
|
||||
"avg (sec)": 66.052999999999997,
|
||||
"max (sec)": 83.647000000000006,
|
||||
"total": 2,
|
||||
}
|
||||
}
|
||||
},
|
||||
"nova.delete_server": {
|
||||
"duration": {
|
||||
"data": [
|
||||
2.3977420330047607,
|
||||
2.6214451789855957
|
||||
],
|
||||
"summary": {
|
||||
"errors": 0,
|
||||
"success": "100.0%",
|
||||
"min (sec)": 2.3980000000000001,
|
||||
"avg (sec)": 2.5099999999999998,
|
||||
"max (sec)": 2.621,
|
||||
"total": 2,
|
||||
"errors": {
|
||||
"count": 0,
|
||||
"details": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"raw_output": {
|
||||
"result": [{
|
||||
"duration": 86.044774055480957,
|
||||
"scenario_output": {
|
||||
"errors": "",
|
||||
"data": {}
|
||||
},
|
||||
"idle_duration": 0.0,
|
||||
"atomic_actions": {
|
||||
"nova.boot_server": 83.646584987640381,
|
||||
"nova.delete_server": 2.3977420330047607
|
||||
},
|
||||
"error": []
|
||||
}, {
|
||||
"duration": 51.081114053726196,
|
||||
"scenario_output": {
|
||||
"errors": "",
|
||||
"data": {}
|
||||
},
|
||||
"idle_duration": 0.0,
|
||||
"atomic_actions": {
|
||||
"nova.boot_server": 48.459306001663208,
|
||||
"nova.delete_server": 2.6214451789855957
|
||||
},
|
||||
"error": []
|
||||
}],
|
||||
"key": {
|
||||
"kw": {
|
||||
"runner": {
|
||||
"type": "constant",
|
||||
"concurrency": 2,
|
||||
"times": 2
|
||||
},
|
||||
"args": {
|
||||
"flavor": {
|
||||
"name": "m1.tiny"
|
||||
},
|
||||
"image": {
|
||||
"name": "cirros"
|
||||
}
|
||||
},
|
||||
"context": {
|
||||
"users": {
|
||||
"project_domain": "default",
|
||||
"users_per_tenant": 2,
|
||||
"tenants": 3,
|
||||
"resource_management_workers": 30,
|
||||
"user_domain": "default"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "NovaServers.boot_and_delete_server",
|
||||
"pos": 0
|
||||
},
|
||||
"sla": []
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
return [200, indireports, {}];
|
||||
|
||||
});
|
||||
|
||||
$httpBackend.whenGET(settings.apiUrlBase + '/adapters').respond(function(method, url, data) {
|
||||
console.log(method, url);
|
||||
var adapters = [{
|
||||
|
@ -42,18 +464,8 @@ compassAppDev.run(function($httpBackend, settings, $http) {
|
|||
}],
|
||||
"id": 2
|
||||
}, {
|
||||
"flavors": [{
|
||||
"roles": [{
|
||||
"display_name": "Ceph Cluster (Firefly)",
|
||||
"description": "Ceph Cluster (Firefly)",
|
||||
"name": "ceph_firefly"
|
||||
}],
|
||||
"display_name": "Ceph Cluster (Firefly)",
|
||||
"id": 1,
|
||||
"template": "cephfirefly.tmpl",
|
||||
"name": "ceph_firefly"
|
||||
}],
|
||||
"name": "ceph_firefly",
|
||||
"flavors": [],
|
||||
"name": "ceph(chef)",
|
||||
"roles": [],
|
||||
"distributed_system_id": 2,
|
||||
"supported_oses": [{
|
||||
|
@ -66,7 +478,7 @@ compassAppDev.run(function($httpBackend, settings, $http) {
|
|||
"name": "Ubuntu-12.04-x86_64"
|
||||
}],
|
||||
"distributed_system_name": "ceph",
|
||||
"display_name": "ceph_firefly",
|
||||
"display_name": "ceph(chef)",
|
||||
"id": 4
|
||||
}, {
|
||||
"flavors": [{
|
||||
|
@ -719,8 +1131,8 @@ compassAppDev.run(function($httpBackend, settings, $http) {
|
|||
var config = {
|
||||
"os_config": {
|
||||
"server_credentials": {
|
||||
"username": "root",
|
||||
"password": "huawei"
|
||||
"username": "",
|
||||
"password": ""
|
||||
},
|
||||
"partition": {
|
||||
"/var": {
|
||||
|
|
|
@ -84,6 +84,13 @@
|
|||
</a>
|
||||
</li>
|
||||
|
||||
<li ng-class="{active:state.includes('cluster.report')}">
|
||||
<a ui-sref="cluster.report">
|
||||
<i class="menu-icon glyphicon glyphicon-list-alt glyphicon-list-alt"></i>
|
||||
<span class="menu-text">Report</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<div class="sidebar-toggle sidebar-collapse" ng-click="sidebarCollapse = !sidebarCollapse">
|
||||
|
|
|
@ -82,6 +82,10 @@
|
|||
</div>
|
||||
<div class="pull-right">
|
||||
<div class="btn-group" dropdown>
|
||||
<button type="button" class="btn btn-info" ng-click="startChecking()" ng-disabled="clusterProgress.state == 'INSTALLING'">
|
||||
Report
|
||||
</button>
|
||||
|
||||
<button type="button" class="btn btn-info dropdown-toggle" ng-disabled="clusterProgress.state == 'INSTALLING'">
|
||||
Actions
|
||||
<span class="ace-icon fa fa-caret-down icon-on-right"></span>
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
<div ng-if="!showData && !isTimeout" class="centerLoading">
|
||||
<i class='class="ace-icon fa fa-spinner fa-spin bigger-300 orange'></i>
|
||||
<span>loading...</span>
|
||||
</div>
|
||||
<div ng-if="isTimeout" class="centerLoading">
|
||||
<i class='class="ce-icon fa fa-times bigger-300 red'></i>
|
||||
<span>Timeout Error</span>
|
||||
</div>
|
||||
<div ng-if="showData && !isTimeout" class="widget-box transparent" style="border-radius: 7px;" ng-repeat="(categoryName, categoryValue) in categories">
|
||||
<div class="widget-header">
|
||||
<h4 class="widget-title">{{categoryName}}</h4>
|
||||
</div>
|
||||
<div class="widget-body">
|
||||
<div class="widget-main">
|
||||
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
|
||||
<span ng-if="showData && !isTimeout">
|
||||
<div class="panel panel-default" ng-repeat = "report in reports | FilterByCategory: categoryName">
|
||||
<div class="panel-heading" role="tab" id="headingOne">
|
||||
<h4 class="panel-title">
|
||||
<span>{{report.name}}</span>
|
||||
<span ng-if="reportStates[report.name] =='success'">
|
||||
<i class='class="ace-icon fa fa fa-check bigger-160 green'></i>
|
||||
</span>
|
||||
<span ng-if="reportStates[report.name] =='finished'">
|
||||
<i class='class="ace-icon fa fa-exclamation bigger-160 yellow'></i>
|
||||
</span>
|
||||
<span ng-if="reportStates[report.name] =='verifying'">
|
||||
<i class='class="ace-icon fa fa-spinner fa-spin bigger-160 orange'></i>
|
||||
</span>
|
||||
<span ng-if="reportStates[report.name] =='error'">
|
||||
<i class='class="ace-icon fa fa-times bigger-160 red'></i>
|
||||
</span>
|
||||
<button class="pull-right btn btn-default btn-xs" data-toggle="collapse" data-parent="#accordion" href="#{{report.name}}" aria-expanded="true" aria-controls="{{report.name}}" ng-disabled="reportStates[report.name] == 'verifying'" ng-style="{color: notFinished ? 'white' : 'grey'}">
|
||||
<i class="glyphicon glyphicon-chevron-down"></i>
|
||||
</button>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="{{report.name}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
|
||||
<div class="panel-body">
|
||||
<table class="table" style="font-size:13px">
|
||||
<thead>
|
||||
<tr class="info">
|
||||
<th>Actions</th>
|
||||
<th>Avg(sec)</th>
|
||||
<th>Max(sec)</th>
|
||||
<th>Min(sec)</th>
|
||||
<th>Errors</th>
|
||||
<th>Success</th>
|
||||
<th>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr ng-repeat="(key,detail) in details[report.name]">
|
||||
<td>{{key}}</td>
|
||||
<td>{{detail.duration.summary["avg (sec)"]}}</td>
|
||||
<td>{{detail.duration.summary["max (sec)"]}}</td>
|
||||
<td>{{detail.duration.summary["min (sec)"]}}</td>
|
||||
<td>
|
||||
<span ng-if="detail.duration.summary.errors.count == 0">{{detail.duration.summary.errors.count}}</span>
|
||||
<span ng-if="detail.duration.summary.errors.count!= 0">
|
||||
<button id="popover" data-trigger="hover" style = "border-radius:20px!important" class="btn btn-xs btn-danger popover-hide"
|
||||
title='{{detail.duration.summary.errors.details[0][0]}}'
|
||||
type="button"
|
||||
data-toggle="modal"
|
||||
data-placement="right"
|
||||
data-target="#{{createModalId(key,report.name)}}"
|
||||
data-content='{{detail.duration.summary.errors.details[0][1]}}'>
|
||||
{{detail.duration.summary.errors.count}}
|
||||
</button>
|
||||
<!-- Modal -->
|
||||
<div class="modal fade" id="{{createModalId(key,report.name)}}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header" style="background:#B74635">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<h4 class="modal-title" id="myModalLabel">Error Details</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td><strong>Exception Type</strong>
|
||||
</td>
|
||||
<td>{{detail.duration.summary.errors.details[0][0]}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Exception Message</strong>
|
||||
</td>
|
||||
<td>{{detail.duration.summary.errors.details[0][1]}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<p ng-bind-html="detail.duration.summary.errors.details[0][2] | nl2br"></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer" style="background:#F2DEDE">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(function() {
|
||||
$('.popover-show').popover('show');
|
||||
});
|
||||
$(function() {
|
||||
$('.popover-hide').popover('hide');
|
||||
});
|
||||
$(function() {
|
||||
$('.popover-destroy').popover('destroy');
|
||||
});
|
||||
$(function() {
|
||||
$('.popover-toggle').popover('toggle');
|
||||
});
|
||||
$(function() {
|
||||
$(".popover-options a").popover({
|
||||
html: true
|
||||
});
|
||||
});
|
||||
$("#popover").popover({
|
||||
trigger: "hover"
|
||||
});
|
||||
</script>
|
||||
</span>
|
||||
</td>
|
||||
<td>{{detail.duration.summary["success"]}}</td>
|
||||
<td>{{detail.duration.summary["total"]}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -62,8 +62,125 @@ define(['angular'], function() {
|
|||
controller: "clusterLogCtrl",
|
||||
templateUrl: 'src/app/cluster/cluster-log.tpl.html',
|
||||
authenticate: true
|
||||
})
|
||||
.state('cluster.report', {
|
||||
url: '/report',
|
||||
controller: "clusterReportCtrl",
|
||||
templateUrl: 'src/app/cluster/cluster-report.tpl.html',
|
||||
authenticate: true
|
||||
});
|
||||
});
|
||||
clusterModule.controller('clusterReportCtrl', function($scope, $state, dataService, $stateParams, $timeout, $modal) {
|
||||
$scope.details = {};
|
||||
$scope.modalId = {};
|
||||
$scope.errorActions = {};
|
||||
$scope.promise = $timeout(timeoutAlert, 1200000);
|
||||
var progressTimer;
|
||||
var fireTimer = true;
|
||||
$scope.notFinished = true;
|
||||
$scope.reportStates = {};
|
||||
var clusterId = $stateParams.id;
|
||||
$scope.showData = false;
|
||||
$scope.showDetails = false;
|
||||
$scope.isTimeout = false;
|
||||
$scope.categories = {};
|
||||
$scope.dtLength = 0;
|
||||
|
||||
function timeoutAlert() {
|
||||
$scope.isTimeout = true;
|
||||
}
|
||||
|
||||
function isEmpty(obj) {
|
||||
for (var prop in obj) {
|
||||
if (obj.hasOwnProperty(prop))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var getAllReports = function() {
|
||||
if (!$scope.isTimeout) {
|
||||
dataService.getHealthReports(clusterId).success(function(data) {
|
||||
|
||||
if (!isEmpty(data)) {
|
||||
|
||||
if (data.length != $scope.dtLength) {
|
||||
$scope.dtLength = data.length;
|
||||
$scope.reportsData = $timeout(getAllReports, 3000);
|
||||
} else {
|
||||
$scope.reports = data;
|
||||
$scope.showData = true;
|
||||
$timeout.cancel($scope.promise);
|
||||
angular.forEach(data, function(dt) {
|
||||
if (!isEmpty($scope.categories) && !isEmpty($scope.categories[dt.category])) {
|
||||
$scope.categories[dt.category].push(dt.name);
|
||||
} else {
|
||||
$scope.categories[dt.category] = [];
|
||||
$scope.categories[dt.category].push(dt.name);
|
||||
}
|
||||
});
|
||||
var getClusterReport = function() {
|
||||
angular.forEach($scope.reports, function(rd) {
|
||||
if (($scope.reportStates[rd.name] != "finished" && $scope.reportStates[rd.name] != "error" && $scope.reportStates[rd.name] != "success") || isEmpty($scope.reportStates[rd.name])) {
|
||||
var getResults = function() {
|
||||
dataService.getIndividualReports(rd.cluster_id, rd.name).success(function(dt) {
|
||||
if (!isEmpty(dt.report)) {
|
||||
$scope.details[rd.name] = dt.report.results.actions;
|
||||
for (var i in dt.report.results.actions) {
|
||||
var str = i + rd.name;
|
||||
$scope.modalId[i + rd.name] = str.replace(".", "-");
|
||||
$scope.createModalId = function(action, name) {
|
||||
return $scope.modalId[action + name];
|
||||
};
|
||||
}
|
||||
$scope.reportStates[rd.name] = dt.state;
|
||||
} else {
|
||||
$scope.reportStates[rd.name] = dt.state;
|
||||
$scope.showDetails = false;
|
||||
$timeout(getResults, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
getResults();
|
||||
}
|
||||
});
|
||||
if (fireTimer) {
|
||||
progressTimer = $timeout(getClusterReport, 3000);
|
||||
};
|
||||
}
|
||||
getClusterReport();
|
||||
$scope.$on('$destroy', function() {
|
||||
fireTimer = false;
|
||||
$timeout.cancel(progressTimer);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
$timeout(getAllReports, 2000);
|
||||
$scope.showData = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
getAllReports();
|
||||
|
||||
});
|
||||
clusterModule.filter('FilterByCategory', function() {
|
||||
return function(items, categoryName) {
|
||||
var filtered = [];
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
if (item.category == categoryName) {
|
||||
filtered.push(item);
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
});
|
||||
clusterModule.filter('nl2br', function($sce) {
|
||||
return function(text) {
|
||||
return text ? $sce.trustAsHtml(text.replace(/\n/g, '<br/>')) : '';
|
||||
};
|
||||
});
|
||||
|
||||
clusterModule.controller('clusterCtrl', function($scope, $state, dataService, $stateParams) {
|
||||
$scope.clusterId = $stateParams.id;
|
||||
|
@ -72,7 +189,6 @@ define(['angular'], function() {
|
|||
dataService.getClusterById($scope.clusterId).success(function(data) {
|
||||
$scope.clusterInfo = data;
|
||||
});
|
||||
|
||||
});
|
||||
clusterModule.directive('clusternav', function($timeout) {
|
||||
return {
|
||||
|
@ -98,11 +214,20 @@ define(['angular'], function() {
|
|||
|
||||
});
|
||||
|
||||
clusterModule.controller('clusterProgressCtrl', function($scope, dataService, $stateParams, $filter, ngTableParams, $timeout, $modal, clusterhostsData) {
|
||||
clusterModule.controller('clusterProgressCtrl', function($scope, dataService, $state, $stateParams, $filter, ngTableParams, $timeout, $modal, clusterhostsData, $rootScope) {
|
||||
var clusterId = $stateParams.id;
|
||||
var progressTimer;
|
||||
var fireTimer = true;
|
||||
$scope.hosts = clusterhostsData;
|
||||
var request = {
|
||||
"check_health": null
|
||||
}
|
||||
|
||||
$scope.startChecking = function() {
|
||||
dataService.startHealthCheck($scope.clusterId, request).success(function(data) {
|
||||
$state.go('cluster.report', data);
|
||||
});
|
||||
};
|
||||
|
||||
var getClusterProgress = function() {
|
||||
dataService.getClusterProgress(clusterId).success(function(data) {
|
||||
|
|
|
@ -126,6 +126,23 @@ define(['angular','uiBootstrap'], function(ng, uiBootstrap) {
|
|||
this.getUserLog = function() {
|
||||
return $http.get(settings.apiUrlBase + '/users/logs');
|
||||
}
|
||||
|
||||
this.getHealthReports = function(id){
|
||||
return $http.get(settings.apiUrlBase + '/clusters/' + id + '/healthreports');
|
||||
};
|
||||
|
||||
this.getIndividualReports = function(id, name){
|
||||
return $http.get(settings.apiUrlBase + '/clusters/' + id + '/healthreports/' + name);
|
||||
};
|
||||
|
||||
this.postHealthCheck = function(id, checkHealth){
|
||||
return $http.post(settings.apiUrlBase + '/clusters/' + id + '/action', angular.toJason(checkHealth));
|
||||
};
|
||||
|
||||
this.startHealthCheck = function(id, request){
|
||||
return $http.post(settings.apiUrlBase + '/clusters/' + id + '/action',angular.toJson(request));
|
||||
};
|
||||
|
||||
this.getClusters = function() {
|
||||
return $http.get(settings.apiUrlBase + '/clusters');
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue