mirror of
https://github.com/ansible/awx.git
synced 2026-03-09 05:29:26 -02:30
modularize host-summary and use socket.io/jobs/ endpoint
This commit is contained in:
@@ -930,7 +930,7 @@ export default
|
|||||||
}])
|
}])
|
||||||
|
|
||||||
// Call when the selected task needs to change
|
// Call when the selected task needs to change
|
||||||
.factory('SelectTask', ['LoadHosts', 'JobDetailService', function(LoadHosts, JobDetailService) {
|
.factory('SelectTask', ['JobDetailService', function(JobDetailService) {
|
||||||
return function(params) {
|
return function(params) {
|
||||||
var scope = params.scope,
|
var scope = params.scope,
|
||||||
id = params.id,
|
id = params.id,
|
||||||
@@ -953,111 +953,12 @@ export default
|
|||||||
order: 'host_name,counter',
|
order: 'host_name,counter',
|
||||||
};
|
};
|
||||||
JobDetailService.getRelatedJobEvents(scope.job.id, params).success(function(res){
|
JobDetailService.getRelatedJobEvents(scope.job.id, params).success(function(res){
|
||||||
scope.hostResults = JobDetailService.processHostResults(res.results)
|
scope.hostResults = JobDetailService.processHostEvents(res.results)
|
||||||
scope.hostResultsLoading = false;
|
scope.hostResultsLoading = false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}])
|
}])
|
||||||
|
|
||||||
// Refresh the list of hosts
|
|
||||||
.factory('LoadHosts', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
|
|
||||||
return function(params) {
|
|
||||||
var scope = params.scope,
|
|
||||||
callback = params.callback,
|
|
||||||
url;
|
|
||||||
scope.hostResults = [];
|
|
||||||
|
|
||||||
if (scope.selectedTask) {
|
|
||||||
// If we have a selected task, then get the list of hosts
|
|
||||||
url = scope.job.related.job_events + '?parent=' + scope.selectedTask + '&';
|
|
||||||
url += (scope.search_host_name) ? 'host__name__icontains=' + scope.search_host_name + '&' : '';
|
|
||||||
url += (scope.search_host_status === 'failed') ? 'failed=true&' : '';
|
|
||||||
url += 'event__startswith=runner&page_size=' + scope.hostResultsMaxRows + '&order=host_name,counter';
|
|
||||||
console.log(url)
|
|
||||||
scope.hostResultsLoading = true;
|
|
||||||
Rest.setUrl(url);
|
|
||||||
Rest.get()
|
|
||||||
.success(function(data) {
|
|
||||||
scope.next_host_results = data.next;
|
|
||||||
scope.hostResults = [];
|
|
||||||
data.results.forEach(function(event) {
|
|
||||||
var status, status_text, item, msg;
|
|
||||||
if (event.event === "runner_on_skipped") {
|
|
||||||
status = 'skipped';
|
|
||||||
}
|
|
||||||
else if (event.event === "runner_on_unreachable") {
|
|
||||||
status = 'unreachable';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
status = (event.failed) ? 'failed' : (event.changed) ? 'changed' : 'successful';
|
|
||||||
}
|
|
||||||
switch(status) {
|
|
||||||
case "successful":
|
|
||||||
status_text = 'OK';
|
|
||||||
break;
|
|
||||||
case "changed":
|
|
||||||
status_text = "Changed";
|
|
||||||
break;
|
|
||||||
case "failed":
|
|
||||||
status_text = "Failed";
|
|
||||||
break;
|
|
||||||
case "unreachable":
|
|
||||||
status_text = "Unreachable";
|
|
||||||
break;
|
|
||||||
case "skipped":
|
|
||||||
status_text = "Skipped";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.event_data && event.event_data.res) {
|
|
||||||
item = event.event_data.res.item;
|
|
||||||
if (typeof item === "object") {
|
|
||||||
item = JSON.stringify(item);
|
|
||||||
item = item.replace(/\"/g,'').replace(/:/g,': ').replace(/,/g,', ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = '';
|
|
||||||
if (event.event_data && event.event_data.res) {
|
|
||||||
if (typeof event.event_data.res === 'object') {
|
|
||||||
msg = event.event_data.res.msg;
|
|
||||||
} else {
|
|
||||||
msg = event.event_data.res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (event.event !== "runner_on_no_hosts") {
|
|
||||||
scope.hostResults.push({
|
|
||||||
id: event.id,
|
|
||||||
status: status,
|
|
||||||
status_text: status_text,
|
|
||||||
host_id: event.host,
|
|
||||||
task_id: event.parent,
|
|
||||||
name: event.event_data.host,
|
|
||||||
created: event.created,
|
|
||||||
msg: msg,
|
|
||||||
item: item
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
scope.hostResultsLoading = false;
|
|
||||||
if (callback) {
|
|
||||||
scope.$emit(callback);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.error(function(data, status) {
|
|
||||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
|
||||||
msg: 'Call to ' + url + '. GET returned: ' + status });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (callback) {
|
|
||||||
scope.$emit(callback);
|
|
||||||
}
|
|
||||||
//$('#hosts-table-detail').mCustomScrollbar("update");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}])
|
|
||||||
|
|
||||||
// Refresh the list of hosts in the hosts summary section
|
// Refresh the list of hosts in the hosts summary section
|
||||||
.factory('ReloadHostSummaryList', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
|
.factory('ReloadHostSummaryList', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
|
||||||
return function(params) {
|
return function(params) {
|
||||||
@@ -1069,7 +970,6 @@ export default
|
|||||||
url += (scope.search_host_summary_name) ? 'host_name__icontains=' + scope.search_host_summary_name + '&': '';
|
url += (scope.search_host_summary_name) ? 'host_name__icontains=' + scope.search_host_summary_name + '&': '';
|
||||||
url += (scope.search_host_summary_status === 'failed') ? 'failed=true&' : '';
|
url += (scope.search_host_summary_status === 'failed') ? 'failed=true&' : '';
|
||||||
url += '&page_size=' + scope.hostSummariesMaxRows + '&order=host_name';
|
url += '&page_size=' + scope.hostSummariesMaxRows + '&order=host_name';
|
||||||
|
|
||||||
scope.hosts = [];
|
scope.hosts = [];
|
||||||
scope.hostSummariesLoading = true;
|
scope.hostSummariesLoading = true;
|
||||||
|
|
||||||
@@ -1098,7 +998,6 @@ export default
|
|||||||
});
|
});
|
||||||
|
|
||||||
scope.hostSummariesLoading = false;
|
scope.hostSummariesLoading = false;
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
scope.$emit(callback);
|
scope.$emit(callback);
|
||||||
}
|
}
|
||||||
@@ -1564,7 +1463,6 @@ export default
|
|||||||
function(DrawPlays, DrawTasks, DrawHostResults, DrawHostSummaries, DrawGraph) {
|
function(DrawPlays, DrawTasks, DrawHostResults, DrawHostSummaries, DrawGraph) {
|
||||||
return function(params) {
|
return function(params) {
|
||||||
var scope = params.scope;
|
var scope = params.scope;
|
||||||
|
|
||||||
if (!scope.pauseLiveEvents) {
|
if (!scope.pauseLiveEvents) {
|
||||||
DrawPlays({ scope: scope });
|
DrawPlays({ scope: scope });
|
||||||
DrawTasks({ scope: scope });
|
DrawTasks({ scope: scope });
|
||||||
|
|||||||
@@ -804,6 +804,7 @@ function($compile, Rest, GetBasePath, TextareaResize,CreateDialog, GenerateForm,
|
|||||||
if((scope.portalMode===false || scope.$parent.portalMode===false ) && Empty(data.system_job) ||
|
if((scope.portalMode===false || scope.$parent.portalMode===false ) && Empty(data.system_job) ||
|
||||||
(base === 'home')){
|
(base === 'home')){
|
||||||
$location.path('/jobs/' + job);
|
$location.path('/jobs/' + job);
|
||||||
|
// use $state.go with reload: true option to re-instantiate sockets in
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -35,19 +35,14 @@ var hostEventModal = {
|
|||||||
$('.modal-backdrop').remove();
|
$('.modal-backdrop').remove();
|
||||||
$('body').removeClass('modal-open');
|
$('body').removeClass('modal-open');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
var hostEventDetails = {
|
var hostEventDetails = {
|
||||||
name: 'jobDetail.host-event.details',
|
name: 'jobDetail.host-event.details',
|
||||||
url: '/details',
|
url: '/details',
|
||||||
controller: 'HostEventController',
|
controller: 'HostEventController',
|
||||||
templateUrl: templateUrl('job-detail/host-event/host-event-details'),
|
templateUrl: templateUrl('job-detail/host-event/host-event-details'),
|
||||||
resolve: {
|
};
|
||||||
features: ['FeaturesService', function(FeaturesService){
|
|
||||||
return FeaturesService.get();
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var hostEventJson = {
|
var hostEventJson = {
|
||||||
name: 'jobDetail.host-event.json',
|
name: 'jobDetail.host-event.json',
|
||||||
@@ -60,27 +55,12 @@ var hostEventModal = {
|
|||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var hostEventTiming = {
|
|
||||||
name: 'jobDetail.host-event.timing',
|
|
||||||
url: '/timing',
|
|
||||||
controller: 'HostEventController',
|
|
||||||
templateUrl: templateUrl('job-detail/host-event/host-event-timing'),
|
|
||||||
resolve: {
|
|
||||||
features: ['FeaturesService', function(FeaturesService){
|
|
||||||
return FeaturesService.get();
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var hostEventStdout = {
|
var hostEventStdout = {
|
||||||
name: 'jobDetail.host-event.stdout',
|
name: 'jobDetail.host-event.stdout',
|
||||||
url: '/stdout',
|
url: '/stdout',
|
||||||
controller: 'HostEventController',
|
controller: 'HostEventController',
|
||||||
templateUrl: templateUrl('job-detail/host-event/host-event-stdout'),
|
templateUrl: templateUrl('job-detail/host-event/host-event-stdout')
|
||||||
resolve: {
|
|
||||||
features: ['FeaturesService', function(FeaturesService){
|
|
||||||
return FeaturesService.get();
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export {hostEventDetails, hostEventJson, hostEventTiming, hostEventStdout, hostEventModal}
|
export {hostEventDetails, hostEventJson, hostEventStdout, hostEventModal}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
import {hostEventModal, hostEventDetails, hostEventTiming,
|
import {hostEventModal, hostEventDetails,
|
||||||
hostEventJson, hostEventStdout} from './host-event.route';
|
hostEventJson, hostEventStdout} from './host-event.route';
|
||||||
import controller from './host-event.controller';
|
import controller from './host-event.controller';
|
||||||
|
|
||||||
@@ -15,7 +15,6 @@
|
|||||||
.run(['$stateExtender', function($stateExtender){
|
.run(['$stateExtender', function($stateExtender){
|
||||||
$stateExtender.addState(hostEventModal);
|
$stateExtender.addState(hostEventModal);
|
||||||
$stateExtender.addState(hostEventDetails);
|
$stateExtender.addState(hostEventDetails);
|
||||||
$stateExtender.addState(hostEventTiming);
|
|
||||||
$stateExtender.addState(hostEventJson);
|
$stateExtender.addState(hostEventJson);
|
||||||
$stateExtender.addState(hostEventStdout);
|
$stateExtender.addState(hostEventStdout);
|
||||||
}]);
|
}]);
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2016 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
export default
|
||||||
|
['$scope', '$rootScope', '$stateParams', 'JobDetailService', 'jobSocket', function($scope, $rootScope, $stateParams, JobDetailService, jobSocket){
|
||||||
|
|
||||||
|
// the job_events socket should be substituted for a job_host_summary socket post 3.0
|
||||||
|
var page_size = 200;
|
||||||
|
var socketListener = function(){
|
||||||
|
console.log(jobSocket)
|
||||||
|
jobSocket.on('summary_complete', function(data) {
|
||||||
|
JobDetailService.getJob($stateParams.id).success(function(res){
|
||||||
|
console.log('job at summary_complete.', res)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
jobSocket.on('status_changed', function(data) {
|
||||||
|
JobDetailService.getJob($stateParams.id).success(function(res){
|
||||||
|
console.log('job at data.stats.', data.status, res)
|
||||||
|
});
|
||||||
|
JobDetailService.getJobHostSummaries($stateParams.id, {}).success(function(res){
|
||||||
|
console.log('jobhostSummaries at summary_complete.', data.status, res)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$scope.loading = $scope.hosts.length > 0 ? false : true;
|
||||||
|
$scope.done = true;
|
||||||
|
$scope.events = [];
|
||||||
|
$scope.$watchCollection('events', function(c){
|
||||||
|
var filtered = $scope.events.filter(function(event){
|
||||||
|
return ((event.failed || event.changed ||
|
||||||
|
'runner_on_ok' || 'runner_on_async_ok' ||
|
||||||
|
'runner_on_unreachable' || 'runner_on_skipped')
|
||||||
|
&& event.host_name != '');
|
||||||
|
});
|
||||||
|
var grouped = _.groupBy(filtered, 'host_name');
|
||||||
|
//$scope.hosts =
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$scope.search = function(host_name){};
|
||||||
|
$scope.filter = function(filter){};
|
||||||
|
|
||||||
|
var init = function(){
|
||||||
|
socketListener();
|
||||||
|
JobDetailService.getJobHostSummaries($stateParams.id, {}).success(function(res){
|
||||||
|
console.log('jobhostSummaries at init.', res)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
init();
|
||||||
|
}];
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
<div id="hosts-summary-section" class="section">
|
||||||
|
|
||||||
|
<div class="JobDetail-searchHeaderRow">
|
||||||
|
<div class="JobDetail-searchContainer form-group">
|
||||||
|
<div class="search-name">
|
||||||
|
<input type="text" class="JobDetail-searchInput form-control List-searchInput" id="search_host_summary_name" ng-model="search_host_summary_name" placeholder="Host Name" ng-keypress="searchHostSummaryKeyPress($event)" >
|
||||||
|
<a class="List-searchInputIcon search-icon" ng-show="searchHostSummaryEnabled" ng-click="searchHostSummary()"><i class="fa fa-search"></i></a>
|
||||||
|
<a class="List-searchInputIcon search-icon" ng-show="!searchHostSummaryEnabled" ng-click="search_host_summary_name=''; searchHostSummary()"><i class="fa fa-times"></i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="JobDetail-tableToggleContainer form-group">
|
||||||
|
<div class="btn-group" aw-toggle-button data-after-toggle="filterHostSummaryStatus">
|
||||||
|
<button class="JobDetail-tableToggle btn btn-xs btn-primary active">All</button>
|
||||||
|
<button class="JobDetail-tableToggle btn btn-xs btn-default">Failed</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-header">
|
||||||
|
<table class="table table-condensed">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="List-tableHeader col-lg-6 col-md-6 col-sm-6 col-xs-6">Hosts</th>
|
||||||
|
<th class="List-tableHeader JobDetail-tableHeader col-lg-6 col-md-5 col-sm-5 col-xs-5">Completed Tasks</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="hosts-summary-table" class="table-detail" lr-infinite-scroll="hostSummariesScrollDown" scroll-threshold="10" time-threshold="500">
|
||||||
|
<table class="table">
|
||||||
|
<tbody>
|
||||||
|
<tr class="List-tableRow" ng-repeat="host in summaryList = (hosts) track by $index" id="{{ host.id }}" ng-class-even="'List-tableRow--evenRow'" ng-class-odd="'List-tableRow--oddRow'">
|
||||||
|
<td class="List-tableCell name col-lg-6 col-md-6 col-sm-6 col-xs-6">
|
||||||
|
<a ui-sref="jobDetail.host-events({hostName: host.name})" aw-tool-tip="View events" data-placement="top">{{ host.name }}</a>
|
||||||
|
</td>
|
||||||
|
<td class="List-tableCell col-lg-6 col-md-5 col-sm-5 col-xs-5 badge-column">
|
||||||
|
<a ui-sref="jobDetail.host-events({hostName: host.name, filter: 'ok'})" aw-tool-tip="{{ host.okTip }}" data-tip-watch="host.okTip" data-placement="top" ng-hide="host.ok == 0"><span class="badge successful-hosts">{{ host.ok }}</span></a>
|
||||||
|
<a ui-sref="jobDetail.host-events({hostName: host.name, filter: 'changed'})" aw-tool-tip="{{ host.changedTip }}" data-tip-watch="host.changedTip" data-placement="top" ng-hide="host.changed == 0"><span class="badge changed-hosts">{{ host.changed }}</span></a>
|
||||||
|
<a ui-sref="jobDetail.host-events({hostName: host.name, filter: 'unreachable'})" aw-tool-tip="{{ host.unreachableTip }}" data-tip-watch="host.unreachableTip" data-placement="top" ng-hide="host.unreachable == 0"><span class="badge unreachable-hosts">{{ host.unreachable }}</span></a>
|
||||||
|
<a ui-sref="jobDetail.host-events({hostName: host.name, filter: 'failed'})" aw-tool-tip="{{ host.failedTip }}" data-tip-watch="host.failedTip" data-placement="top" ng-hide="host.failed == 0"><span class="badge failed-hosts">{{ host.failed }}</span></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr ng-show="summaryList.length === 0 && waiting">
|
||||||
|
<td colspan="5" class="col-lg-12 loading-info">Waiting...</td>
|
||||||
|
</tr>
|
||||||
|
<tr ng-show="summaryList.length === 0 && hostSummariesLoading && !waiting">
|
||||||
|
<td colspan="5" class="col-lg-12 loading-info">Loading...</td>
|
||||||
|
</tr>
|
||||||
|
<tr ng-show="summaryList.length === 0 && !hostSummariesLoading && !waiting">
|
||||||
|
<td colspan="2" class="col-lg-12 loading-info">No matching hosts</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="scroll-spinner" id="hostSummariesMoreRows">
|
||||||
|
<i class="fa fa-cog fa-spin"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div><!-- section -->
|
||||||
|
|
||||||
|
<div id="graph-section" class="JobDetail-graphSection">
|
||||||
|
<svg width="100%" height="100%"></svg>
|
||||||
|
</div>
|
||||||
@@ -277,7 +277,6 @@ export default
|
|||||||
scope.$emit('LoadHostSummaries');
|
scope.$emit('LoadHostSummaries');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (scope.removeInitialLoadComplete) {
|
if (scope.removeInitialLoadComplete) {
|
||||||
scope.removeInitialLoadComplete();
|
scope.removeInitialLoadComplete();
|
||||||
}
|
}
|
||||||
@@ -292,12 +291,10 @@ export default
|
|||||||
};
|
};
|
||||||
JobDetailService.getRelatedJobEvents(scope.job.id, params)
|
JobDetailService.getRelatedJobEvents(scope.job.id, params)
|
||||||
.success(function(data) {
|
.success(function(data) {
|
||||||
if (data.results.length > 0) {
|
|
||||||
LoadHostSummary({
|
LoadHostSummary({
|
||||||
scope: scope,
|
scope: scope,
|
||||||
data: data.results[0].event_data
|
data: data.results[0].event_data
|
||||||
});
|
});
|
||||||
}
|
|
||||||
UpdateDOM({ scope: scope });
|
UpdateDOM({ scope: scope });
|
||||||
})
|
})
|
||||||
.error(function(data, status) {
|
.error(function(data, status) {
|
||||||
@@ -379,33 +376,12 @@ export default
|
|||||||
};
|
};
|
||||||
JobDetailService.getRelatedJobEvents(scope.job.id, params)
|
JobDetailService.getRelatedJobEvents(scope.job.id, params)
|
||||||
.success(function(data) {
|
.success(function(data) {
|
||||||
console.log(data)
|
|
||||||
var idx, event, status, status_text, item, msg;
|
var idx, event, status, status_text, item, msg;
|
||||||
if (data.results.length > 0) {$
|
if (data.results.length > 0) {$
|
||||||
lastEventId = data.results[0].id;
|
lastEventId = data.results[0].id;
|
||||||
}
|
}
|
||||||
scope.next_host_results = data.next;
|
scope.next_host_results = data.next;
|
||||||
for (idx=data.results.length - 1; idx >= 0; idx--) {
|
task.hostResults = JobDetailService.processHostEvents(data.results);
|
||||||
event = data.results[idx];
|
|
||||||
event.status = JobDetailService.processEventStatus(event).status;
|
|
||||||
msg = JobDetailService.processEventMsg(event);
|
|
||||||
item = JobDetailService.processEventItem(event);
|
|
||||||
|
|
||||||
if (event.event !== "runner_on$_no_hosts") {
|
|
||||||
task.hostResults[event.id] = {
|
|
||||||
id: event.id,
|
|
||||||
status: event.status,
|
|
||||||
status_text: event.status.toUpperCase(),
|
|
||||||
host_id: event.host,
|
|
||||||
task_id: event.parent,
|
|
||||||
name: event.event_data.host,
|
|
||||||
created: event.created,
|
|
||||||
msg: msg,
|
|
||||||
counter: event.counter,
|
|
||||||
item: item
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scope.$emit('LoadHostSummaries');
|
scope.$emit('LoadHostSummaries');
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -999,13 +975,6 @@ export default
|
|||||||
scope.searchTasksEnabled = true;
|
scope.searchTasksEnabled = true;
|
||||||
}
|
}
|
||||||
if (!scope.liveEventProcessing || scope.pauseLiveEvents) {
|
if (!scope.liveEventProcessing || scope.pauseLiveEvents) {
|
||||||
// /api/v1/jobs/15/job_tasks/?event_id=762&task__icontains=create&page_size=200&order=id
|
|
||||||
var params = {
|
|
||||||
event_id: scope.selectedPlay,
|
|
||||||
task__icontains: scope.search_task_name,
|
|
||||||
page_size: scope.tasksMaxRows,
|
|
||||||
|
|
||||||
};
|
|
||||||
if (scope.search_task_status === 'failed'){
|
if (scope.search_task_status === 'failed'){
|
||||||
params.failed = true;
|
params.failed = true;
|
||||||
}
|
}
|
||||||
@@ -1042,7 +1011,7 @@ export default
|
|||||||
params.failed = true;
|
params.failed = true;
|
||||||
}
|
}
|
||||||
JobDetailService.getRelatedJobEvents(scope.job.id, params).success(function(res){
|
JobDetailService.getRelatedJobEvents(scope.job.id, params).success(function(res){
|
||||||
scope.hostResults = JobDetailService.processHostResults(res.results)
|
scope.hostResults = JobDetailService.processHostEvents(res.results)
|
||||||
scope.hostResultsLoading = false;
|
scope.hostResultsLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1088,7 +1057,6 @@ export default
|
|||||||
scope.filterHostStatus = function() {
|
scope.filterHostStatus = function() {
|
||||||
scope.search_host_status = (scope.search_host_status === 'all') ? 'failed' : 'all';
|
scope.search_host_status = (scope.search_host_status === 'all') ? 'failed' : 'all';
|
||||||
if (!scope.liveEventProcessing || scope.pauseLiveEvents) {
|
if (!scope.liveEventProcessing || scope.pauseLiveEvents) {
|
||||||
console.log('filterHostStattus', scope)
|
|
||||||
var params = {
|
var params = {
|
||||||
parent: scope.selectedTask,
|
parent: scope.selectedTask,
|
||||||
event__startswith: 'runner',
|
event__startswith: 'runner',
|
||||||
@@ -1100,7 +1068,7 @@ export default
|
|||||||
}
|
}
|
||||||
scope.hostResultsLoading = true;
|
scope.hostResultsLoading = true;
|
||||||
JobDetailService.getRelatedJobEvents(scope.job.id, params).success(function(res){
|
JobDetailService.getRelatedJobEvents(scope.job.id, params).success(function(res){
|
||||||
scope.hostResults = JobDetailService.processHostResults(res.results)
|
scope.hostResults = JobDetailService.processHostEvents(res.results)
|
||||||
scope.hostResultsLoading = false;
|
scope.hostResultsLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1109,6 +1077,21 @@ export default
|
|||||||
scope.filterHostSummaryStatus = function() {
|
scope.filterHostSummaryStatus = function() {
|
||||||
scope.search_host_summary_status = (scope.search_host_summary_status === 'all') ? 'failed' : 'all';
|
scope.search_host_summary_status = (scope.search_host_summary_status === 'all') ? 'failed' : 'all';
|
||||||
if (!scope.liveEventProcessing || scope.pauseLiveEvents) {
|
if (!scope.liveEventProcessing || scope.pauseLiveEvents) {
|
||||||
|
// /api/v1/jobs/11/job_host_summaries/?failed=true&&page_size=200&order=host_name
|
||||||
|
var params = {
|
||||||
|
page_size: scope.hostSummariesMaxRows,
|
||||||
|
order: 'host_name'
|
||||||
|
}
|
||||||
|
if (scope.search_host_summary_status === 'failed'){
|
||||||
|
params.failed = true;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
JobDetailService.getJobHostSummaries(scope.job.id, params).success(function(res){
|
||||||
|
scope.next_host_summaries = res.next;
|
||||||
|
scope.hosts = res.results;
|
||||||
|
console.log(res.results)
|
||||||
|
});
|
||||||
|
*/
|
||||||
ReloadHostSummaryList({
|
ReloadHostSummaryList({
|
||||||
scope: scope
|
scope: scope
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -388,75 +388,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="events-summary" style="display:none">
|
<!-- Host Summary view -->
|
||||||
|
<div id="events-summary" style="display:none">
|
||||||
<div id="hosts-summary-section" class="section">
|
<div ui-view="host-summary@jobDetail"></div>
|
||||||
|
</div>
|
||||||
<div class="JobDetail-searchHeaderRow">
|
|
||||||
<div class="JobDetail-searchContainer form-group">
|
|
||||||
<div class="search-name">
|
|
||||||
<input type="text" class="JobDetail-searchInput form-control List-searchInput" id="search_host_summary_name" ng-model="search_host_summary_name" placeholder="Host Name" ng-keypress="searchHostSummaryKeyPress($event)" >
|
|
||||||
<a class="List-searchInputIcon search-icon" ng-show="searchHostSummaryEnabled" ng-click="searchHostSummary()"><i class="fa fa-search"></i></a>
|
|
||||||
<a class="List-searchInputIcon search-icon" ng-show="!searchHostSummaryEnabled" ng-click="search_host_summary_name=''; searchHostSummary()"><i class="fa fa-times"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="JobDetail-tableToggleContainer form-group">
|
|
||||||
<div class="btn-group" aw-toggle-button data-after-toggle="filterHostSummaryStatus">
|
|
||||||
<button class="JobDetail-tableToggle btn btn-xs btn-primary active">All</button>
|
|
||||||
<button class="JobDetail-tableToggle btn btn-xs btn-default">Failed</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="table-header">
|
|
||||||
<table class="table table-condensed">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="List-tableHeader col-lg-6 col-md-6 col-sm-6 col-xs-6">Hosts</th>
|
|
||||||
<th class="List-tableHeader JobDetail-tableHeader col-lg-6 col-md-5 col-sm-5 col-xs-5">Completed Tasks</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="hosts-summary-table" class="table-detail" lr-infinite-scroll="hostSummariesScrollDown" scroll-threshold="10" time-threshold="500">
|
|
||||||
<table class="table">
|
|
||||||
<tbody>
|
|
||||||
<tr class="List-tableRow" ng-repeat="host in summaryList = (hosts) track by $index" id="{{ host.id }}" ng-class-even="'List-tableRow--evenRow'" ng-class-odd="'List-tableRow--oddRow'">
|
|
||||||
<td class="List-tableCell name col-lg-6 col-md-6 col-sm-6 col-xs-6">
|
|
||||||
<a ui-sref="jobDetail.host-events({hostName: host.name})" aw-tool-tip="View events" data-placement="top">{{ host.name }}</a>
|
|
||||||
</td>
|
|
||||||
<td class="List-tableCell col-lg-6 col-md-5 col-sm-5 col-xs-5 badge-column">
|
|
||||||
<a ui-sref="jobDetail.host-events({hostName: host.name, hostId: host.id, filter: 'ok'})" aw-tool-tip="{{ host.okTip }}" data-tip-watch="host.okTip" data-placement="top" ng-hide="host.ok == 0"><span class="badge successful-hosts">{{ host.ok }}</span></a>
|
|
||||||
<a ui-sref="jobDetail.host-events({hostName: host.name, hostId: host.id, filter: 'changed'})" aw-tool-tip="{{ host.changedTip }}" data-tip-watch="host.changedTip" data-placement="top" ng-hide="host.changed == 0"><span class="badge changed-hosts">{{ host.changed }}</span></a>
|
|
||||||
<a ui-sref="jobDetail.host-events({hostName: host.name, hostId: host.id, filter: 'unreachable'})" aw-tool-tip="{{ host.unreachableTip }}" data-tip-watch="host.unreachableTip" data-placement="top" ng-hide="host.unreachable == 0"><span class="badge unreachable-hosts">{{ host.unreachable }}</span></a>
|
|
||||||
<a ui-sref="jobDetail.host-events({hostName: host.name, hostId: host.id, filter: 'failed'})" aw-tool-tip="{{ host.failedTip }}" data-tip-watch="host.failedTip" data-placement="top" ng-hide="host.failed == 0"><span class="badge failed-hosts">{{ host.failed }}</span></a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr ng-show="summaryList.length === 0 && waiting">
|
|
||||||
<td colspan="5" class="col-lg-12 loading-info">Waiting...</td>
|
|
||||||
</tr>
|
|
||||||
<tr ng-show="summaryList.length === 0 && hostSummariesLoading && !waiting">
|
|
||||||
<td colspan="5" class="col-lg-12 loading-info">Loading...</td>
|
|
||||||
</tr>
|
|
||||||
<tr ng-show="summaryList.length === 0 && !hostSummariesLoading && !waiting">
|
|
||||||
<td colspan="2" class="col-lg-12 loading-info">No matching hosts</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="scroll-spinner" id="hostSummariesMoreRows">
|
|
||||||
<i class="fa fa-cog fa-spin"></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div><!-- section -->
|
|
||||||
|
|
||||||
<div id="graph-section" class="JobDetail-graphSection">
|
|
||||||
<svg width="100%" height="100%"></svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--end of events summary-->
|
|
||||||
</div>
|
</div>
|
||||||
<!-- end of events summary-->
|
<!-- end of events summary-->
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,11 @@
|
|||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
import {templateUrl} from '../shared/template-url/template-url.factory';
|
import {templateUrl} from '../shared/template-url/template-url.factory';
|
||||||
|
import HostSummaryController from './host-summary/host-summary.controller';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'jobDetail',
|
name: 'jobDetail',
|
||||||
url: '/jobs/:id',
|
url: '/jobs/:id',
|
||||||
templateUrl: templateUrl('job-detail/job-detail'),
|
|
||||||
controller: 'JobDetailController',
|
|
||||||
ncyBreadcrumb: {
|
ncyBreadcrumb: {
|
||||||
parent: 'jobs',
|
parent: 'jobs',
|
||||||
label: "{{ job.id }} - {{ job.name }}"
|
label: "{{ job.id }} - {{ job.name }}"
|
||||||
@@ -26,10 +25,32 @@ export default {
|
|||||||
endpoint: "job_events"
|
endpoint: "job_events"
|
||||||
});
|
});
|
||||||
$rootScope.event_socket.init();
|
$rootScope.event_socket.init();
|
||||||
|
// returns should really be providing $rootScope.event_socket
|
||||||
|
// otherwise, we have to inject the entire $rootScope into the controller
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}],
|
||||||
|
jobSocket: ['Socket', '$rootScope', function(Socket, $rootScope) {
|
||||||
|
var job_socket = Socket({
|
||||||
|
scope: $rootScope,
|
||||||
|
endpoint: "jobs"
|
||||||
|
});
|
||||||
|
job_socket.init();
|
||||||
|
// returns should really be providing $rootScope.job_socket
|
||||||
|
// otherwise, we have to inject the entire $rootScope into the controller
|
||||||
|
return job_socket;
|
||||||
}]
|
}]
|
||||||
|
},
|
||||||
|
views: {
|
||||||
|
'': {
|
||||||
|
templateUrl: templateUrl('job-detail/job-detail'),
|
||||||
|
controller: 'JobDetailController',
|
||||||
|
},
|
||||||
|
'host-summary@jobDetail': {
|
||||||
|
templateUrl: templateUrl('job-detail/host-summary/host-summary'),
|
||||||
|
controller: HostSummaryController
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -63,52 +63,47 @@ export default
|
|||||||
// the stack for which status to display is
|
// the stack for which status to display is
|
||||||
// unreachable > failed > changed > ok
|
// unreachable > failed > changed > ok
|
||||||
// uses the API's runner events and convenience properties .failed .changed to determine status.
|
// uses the API's runner events and convenience properties .failed .changed to determine status.
|
||||||
// see: job_event_callback.py
|
// see: job_event_callback.py for more filters to support
|
||||||
processEventStatus: function(event){
|
processEventStatus: function(event){
|
||||||
if (event.event == 'runner_on_unreachable'){
|
if (event.event == 'runner_on_unreachable'){
|
||||||
return {
|
return {
|
||||||
class: 'HostEvents-status--unreachable',
|
class: 'HostEvents-status--unreachable',
|
||||||
status: 'unreachable'
|
status: 'unreachable'
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// equiv to 'runner_on_error' && 'runner on failed'
|
}
|
||||||
if (event.failed){
|
// equiv to 'runner_on_error' && 'runner on failed'
|
||||||
return {
|
if (event.failed){
|
||||||
class: 'HostEvents-status--failed',
|
return {
|
||||||
status: 'failed'
|
class: 'HostEvents-status--failed',
|
||||||
}
|
status: 'failed'
|
||||||
}
|
}
|
||||||
// catch the changed case before ok, because both can be true
|
}
|
||||||
if (event.changed){
|
// catch the changed case before ok, because both can be true
|
||||||
return {
|
if (event.changed){
|
||||||
class: 'HostEvents-status--changed',
|
return {
|
||||||
status: 'changed'
|
class: 'HostEvents-status--changed',
|
||||||
}
|
status: 'changed'
|
||||||
}
|
}
|
||||||
if (event.event == 'runner_on_ok'){
|
}
|
||||||
return {
|
if (event.event == 'runner_on_ok' || event.event == 'runner_on_async_ok'){
|
||||||
class: 'HostEvents-status--ok',
|
return {
|
||||||
status: 'ok'
|
class: 'HostEvents-status--ok',
|
||||||
}
|
status: 'ok'
|
||||||
}
|
}
|
||||||
if (event.event == 'runner_on_skipped'){
|
}
|
||||||
return {
|
if (event.event == 'runner_on_skipped'){
|
||||||
class: 'HostEvents-status--skipped',
|
return {
|
||||||
status: 'skipped'
|
class: 'HostEvents-status--skipped',
|
||||||
}
|
status: 'skipped'
|
||||||
}
|
|
||||||
else{
|
|
||||||
// study a case where none of these apply
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
// Consumes a response from this.getRelatedJobEvents(id, params)
|
||||||
// Consumes a response from this.getRelatedJobEvents
|
|
||||||
// returns an array for view logic to iterate over to build host result rows
|
// returns an array for view logic to iterate over to build host result rows
|
||||||
processHostResults: function(data){
|
processHostEvents: function(data){
|
||||||
var self = this;
|
var self = this;
|
||||||
var results = [];
|
var results = [];
|
||||||
data.forEach(function(element, index, array){
|
data.forEach(function(event){
|
||||||
var event = element;
|
|
||||||
if (event.event !== 'runner_on_no_hosts'){
|
if (event.event !== 'runner_on_no_hosts'){
|
||||||
var status = self.processEventStatus(event);
|
var status = self.processEventStatus(event);
|
||||||
var msg = self.processEventMsg(event);
|
var msg = self.processEventMsg(event);
|
||||||
@@ -116,7 +111,7 @@ export default
|
|||||||
results.push({
|
results.push({
|
||||||
id: event.id,
|
id: event.id,
|
||||||
status: status.status,
|
status: status.status,
|
||||||
status_text: status.status.charAt(0).toUpperCase() + status.status.slice(1),
|
status_text: _.head(status.status).toUpperCase() + _.tail(status.status),
|
||||||
host_id: event.host,
|
host_id: event.host,
|
||||||
task_id: event.parent,
|
task_id: event.parent,
|
||||||
name: event.event_data.host,
|
name: event.event_data.host,
|
||||||
@@ -128,7 +123,6 @@ export default
|
|||||||
});
|
});
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
|
|
||||||
// GET events related to a job run
|
// GET events related to a job run
|
||||||
// e.g.
|
// e.g.
|
||||||
// ?event=playbook_on_stats
|
// ?event=playbook_on_stats
|
||||||
|
|||||||
Reference in New Issue
Block a user