mirror of
https://github.com/ansible/awx.git
synced 2026-01-21 06:28:01 -03:30
updates to getting host counts
This commit is contained in:
parent
e31bfa2f1c
commit
11592047d6
@ -4,90 +4,21 @@
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default [function(){
|
||||
export default ['jobResultsService', function(jobResultsService){
|
||||
var val = {};
|
||||
|
||||
// the playbook_on_stats event returns the count data in a weird format.
|
||||
// format to what we need!
|
||||
var getCountsFromStatsEvent = function(event_data) {
|
||||
var hosts = {},
|
||||
hostsArr;
|
||||
|
||||
// iterate over the event_data and populate an object with hosts
|
||||
// and their status data
|
||||
Object.keys(event_data).forEach(key => {
|
||||
// failed passes boolean not integer
|
||||
if (key === "failed") {
|
||||
// array of hosts from failed type
|
||||
hostsArr = Object.keys(event_data[key]);
|
||||
hostsArr.forEach(host => {
|
||||
if (!hosts[host]) {
|
||||
// host has not been added to hosts object
|
||||
// add now
|
||||
hosts[host] = {};
|
||||
}
|
||||
|
||||
hosts[host][key] = event_data[key][host];
|
||||
});
|
||||
} else {
|
||||
// array of hosts from each type ("changed", "dark", etc.)
|
||||
hostsArr = Object.keys(event_data[key]);
|
||||
hostsArr.forEach(host => {
|
||||
if (!hosts[host]) {
|
||||
// host has not been added to hosts object
|
||||
// add now
|
||||
hosts[host] = {};
|
||||
}
|
||||
|
||||
if (!hosts[host][key]) {
|
||||
// host doesn't have key
|
||||
hosts[host][key] = 0;
|
||||
}
|
||||
hosts[host][key] += event_data[key][host];
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// use the hosts data populate above to get the count
|
||||
var count = {
|
||||
ok : _.filter(hosts, function(o){
|
||||
return !o.failures && !o.changed && o.ok > 0;
|
||||
}),
|
||||
skipped : _.filter(hosts, function(o){
|
||||
return o.skipped > 0;
|
||||
}),
|
||||
unreachable : _.filter(hosts, function(o){
|
||||
return o.dark > 0;
|
||||
}),
|
||||
failures : _.filter(hosts, function(o){
|
||||
return o.failed === true;
|
||||
}),
|
||||
changed : _.filter(hosts, function(o){
|
||||
return o.changed > 0;
|
||||
})
|
||||
};
|
||||
|
||||
// turn the count into an actual count, rather than a list of host
|
||||
// names
|
||||
Object.keys(count).forEach(key => {
|
||||
count[key] = count[key].length;
|
||||
});
|
||||
|
||||
return count;
|
||||
};
|
||||
|
||||
// Get the count of the last event
|
||||
var getPreviousCount = function(id) {
|
||||
var getPreviousCount = function(counter) {
|
||||
// get the ids of all the queue
|
||||
var ids = Object.keys(val.queue).map(id => parseInt(id));
|
||||
var counters = Object.keys(val.queue).map(counter => parseInt(counter));
|
||||
|
||||
// iterate backwards to find the last count
|
||||
while(ids.indexOf(id - 1) > -1) {
|
||||
id = id - 1;
|
||||
if (val.queue[id].count) {
|
||||
while(counters.indexOf(counter - 1) > -1) {
|
||||
counter = counter - 1;
|
||||
if (val.queue[counter].count) {
|
||||
// need to create a new copy of count when returning
|
||||
// so that it is accurate for the particular event
|
||||
return _.clone(val.queue[id].count);
|
||||
return _.clone(val.queue[counter].count);
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,33 +35,39 @@ export default [function(){
|
||||
// munge the raw event from the backend into the event_queue's format
|
||||
var mungeEvent = function(event) {
|
||||
var mungedEvent = {
|
||||
counter: event.counter,
|
||||
id: event.id,
|
||||
processed: false,
|
||||
name: event.event_name,
|
||||
count: getPreviousCount(event.id)
|
||||
name: event.event_name
|
||||
};
|
||||
|
||||
if (event.event_name === 'playbook_on_start') {
|
||||
// sets count initially so this is a change
|
||||
mungedEvent.count = getPreviousCount(mungedEvent.counter);
|
||||
mungedEvent.changes = ['count'];
|
||||
} else if (event.event_name === 'runner_on_ok' ||
|
||||
event.event_name === 'runner_on_async_ok') {
|
||||
mungedEvent.count = getPreviousCount(mungedEvent.counter);
|
||||
mungedEvent.count.ok++;
|
||||
mungedEvent.changes = ['count'];
|
||||
} else if (event.event_name === 'runner_on_skipped') {
|
||||
mungedEvent.count = getPreviousCount(mungedEvent.counter);
|
||||
mungedEvent.count.skipped++;
|
||||
mungedEvent.changes = ['count'];
|
||||
} else if (event.event_name === 'runner_on_unreachable') {
|
||||
mungedEvent.count = getPreviousCount(mungedEvent.counter);
|
||||
mungedEvent.count.unreachable++;
|
||||
mungedEvent.changes = ['count'];
|
||||
} else if (event.event_name === 'runner_on_error' ||
|
||||
event.event_name === 'runner_on_async_failed') {
|
||||
mungedEvent.count = getPreviousCount(mungedEvent.counter);
|
||||
mungedEvent.count.failed++;
|
||||
mungedEvent.changes = ['count'];
|
||||
} else if (event.event_name === 'playbook_on_stats') {
|
||||
// get the data for populating the host status bar
|
||||
mungedEvent.count = getCountsFromStatsEvent(event.event_data);
|
||||
mungedEvent.changes = ['count'];
|
||||
mungedEvent.count = jobResultsService
|
||||
.getCountsFromStatsEvent(event.event_data);
|
||||
mungedEvent.changes = ['count', 'countFinished'];
|
||||
}
|
||||
return mungedEvent;
|
||||
};
|
||||
@ -143,15 +80,19 @@ export default [function(){
|
||||
},
|
||||
// populates the event queue
|
||||
populate: function(event) {
|
||||
var mungedEvent = mungeEvent(event);
|
||||
val.queue[event.id] = mungedEvent;
|
||||
// don't populate the event if it's already been added either
|
||||
// by rest or by websocket event
|
||||
if (!val.queue[event.counter]) {
|
||||
var mungedEvent = mungeEvent(event);
|
||||
val.queue[mungedEvent.counter] = mungedEvent;
|
||||
|
||||
return mungedEvent;
|
||||
return mungedEvent;
|
||||
}
|
||||
},
|
||||
// the event has been processed in the view and should be marked as
|
||||
// completed in the queue
|
||||
markProcessed: function(event) {
|
||||
val.queue[event.id].processed = true;
|
||||
val.queue[event.counter].processed = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -7,41 +7,46 @@
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.HostStatusBar-ok,
|
||||
.HostStatusBar-changed,
|
||||
.HostStatusBar-unreachable,
|
||||
.HostStatusBar-failures,
|
||||
.HostStatusBar-skipped,
|
||||
.HostStatusBar-noData {
|
||||
height: 15px;
|
||||
border-top: 5px solid @default-bg;
|
||||
border-bottom: 5px solid @default-bg;
|
||||
}
|
||||
|
||||
.HostStatusBar-ok {
|
||||
background-color: @default-succ;
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.HostStatusBar-changed {
|
||||
background-color: @default-warning;
|
||||
flex: 0 0 auto;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.HostStatusBar-unreachable {
|
||||
background-color: @default-unreachable;
|
||||
flex: 0 0 auto;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.HostStatusBar-failures {
|
||||
background-color: @default-err;
|
||||
flex: 0 0 auto;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.HostStatusBar-skipped {
|
||||
background-color: @default-link;
|
||||
flex: 0 0 auto;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.HostStatusBar-noData {
|
||||
background-color: @default-icon-hov;
|
||||
flex: 1 0 auto;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
.HostStatusBar-tooltipLabel {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export default ['jobData', 'jobDataOptions', 'jobLabels', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', '$rootScope', 'eventQueue', function(jobData, jobDataOptions, jobLabels, $scope, ParseTypeChange, ParseVariableString, jobResultsService, $rootScope, eventQueue) {
|
||||
export default ['jobData', 'jobDataOptions', 'jobLabels', 'count', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', '$rootScope', 'eventQueue', function(jobData, jobDataOptions, jobLabels, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, $rootScope, eventQueue) {
|
||||
var getTowerLinks = function() {
|
||||
var getTowerLink = function(key) {
|
||||
if ($scope.job.related[key]) {
|
||||
@ -34,6 +34,11 @@ export default ['jobData', 'jobDataOptions', 'jobLabels', '$scope', 'ParseTypeCh
|
||||
$scope.verbosity_label = getTowerLabel('verbosity');
|
||||
};
|
||||
|
||||
var getTotalHostCount = function(count) {
|
||||
return Object
|
||||
.keys(count).reduce((acc, i) => acc += count[i], 0);
|
||||
};
|
||||
|
||||
// put initially resolved request data on scope
|
||||
$scope.job = jobData;
|
||||
$scope.jobOptions = jobDataOptions.actions.GET;
|
||||
@ -66,6 +71,11 @@ export default ['jobData', 'jobDataOptions', 'jobLabels', '$scope', 'ParseTypeCh
|
||||
jobResultsService.cancelJob($scope.job);
|
||||
};
|
||||
|
||||
// get initial count from resolve
|
||||
$scope.count = count.val;
|
||||
$scope.hostCount = getTotalHostCount(count.val);
|
||||
$scope.countFinished = count.countFinished;
|
||||
|
||||
// EVENT STUFF BELOW
|
||||
|
||||
// just putting the event queue on scope so it can be inspected in the
|
||||
@ -79,8 +89,14 @@ export default ['jobData', 'jobDataOptions', 'jobLabels', '$scope', 'ParseTypeCh
|
||||
// make changes to ui based on the event returned from the queue
|
||||
if (mungedEvent.changes) {
|
||||
mungedEvent.changes.forEach(change => {
|
||||
if (change === 'count') {
|
||||
if (change === 'count' && !$scope.countFinished) {
|
||||
$scope.count = mungedEvent.count;
|
||||
$scope.hostCount = getTotalHostCount(mungedEvent
|
||||
.count);
|
||||
}
|
||||
|
||||
if (change === 'countFnished') {
|
||||
$scope.countFinished = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -90,15 +106,21 @@ export default ['jobData', 'jobDataOptions', 'jobLabels', '$scope', 'ParseTypeCh
|
||||
};
|
||||
|
||||
// grab completed event data and process each event
|
||||
jobResultsService.getEvents($scope.job)
|
||||
.then(events => {
|
||||
events.forEach(event => {
|
||||
// get the name in the same format as the data
|
||||
// coming over the websocket
|
||||
event.event_name = event.event;
|
||||
processEvent(event);
|
||||
var getEvents = function(url) {
|
||||
jobResultsService.getEvents(url)
|
||||
.then(events => {
|
||||
events.results.forEach(event => {
|
||||
// get the name in the same format as the data
|
||||
// coming over the websocket
|
||||
event.event_name = event.event;
|
||||
processEvent(event);
|
||||
});
|
||||
if (events.next) {
|
||||
getEvents(events.next);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
getEvents($scope.job.related.job_events);
|
||||
|
||||
// process incoming job events
|
||||
$rootScope.event_socket.on("job_events-" + $scope.job.id, function(data) {
|
||||
|
||||
@ -459,7 +459,7 @@
|
||||
Plays
|
||||
</div>
|
||||
<span class="badge List-titleBadge">
|
||||
{{jobData.playCount || 0}}
|
||||
{{ playCount || 0}}
|
||||
</span>
|
||||
|
||||
<!-- TASKS COUNT -->
|
||||
@ -467,7 +467,7 @@
|
||||
Tasks
|
||||
</div>
|
||||
<span class="badge List-titleBadge">
|
||||
{{jobData.taskCount || 0}}
|
||||
{{ taskCount || 0}}
|
||||
</span>
|
||||
|
||||
<!-- HOSTS COUNT -->
|
||||
@ -475,7 +475,7 @@
|
||||
Hosts
|
||||
</div>
|
||||
<span class="badge List-titleBadge">
|
||||
{{jobData.hostCount || 0}}
|
||||
{{ hostCount || 0}}
|
||||
</span>
|
||||
|
||||
<!-- ELAPSED TIME -->
|
||||
|
||||
@ -35,6 +35,43 @@ export default {
|
||||
});
|
||||
return val.promise;
|
||||
}],
|
||||
count: ['jobData', 'jobResultsService', 'Rest', '$q', function(jobData, jobResultsService, Rest, $q) {
|
||||
var defer = $q.defer();
|
||||
if (jobData.finished) {
|
||||
// if the job is finished, grab the playbook_on_stats
|
||||
// role to get the final count
|
||||
Rest.setUrl(jobData.related.job_events +
|
||||
"?event=playbook_on_stats");
|
||||
Rest.get()
|
||||
.success(function(data) {
|
||||
defer.resolve({
|
||||
val: jobResultsService
|
||||
.getCountsFromStatsEvent(data
|
||||
.results[0].event_data),
|
||||
countFinished: true});
|
||||
})
|
||||
.error(function() {
|
||||
defer.resolve({val: {
|
||||
ok: 0,
|
||||
skipped: 0,
|
||||
unreachable: 0,
|
||||
failures: 0,
|
||||
changed: 0
|
||||
}, countFinished: false});
|
||||
});
|
||||
} else {
|
||||
// job isn't finished so just send an empty count and read
|
||||
// from events
|
||||
defer.resolve({val: {
|
||||
ok: 0,
|
||||
skipped: 0,
|
||||
unreachable: 0,
|
||||
failures: 0,
|
||||
changed: 0
|
||||
}, countFinished: false});
|
||||
}
|
||||
return defer.promise;
|
||||
}],
|
||||
jobLabels: ['Rest', 'GetBasePath', '$stateParams', '$q', function(Rest, GetBasePath, $stateParams, $q) {
|
||||
var getNext = function(data, arr, resolve) {
|
||||
Rest.setUrl(data.next);
|
||||
|
||||
@ -7,13 +7,81 @@
|
||||
|
||||
export default ['$q', 'Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErrors', function ($q, Prompt, $filter, Wait, Rest, $state, ProcessErrors) {
|
||||
var val = {
|
||||
getEvents: function(job) {
|
||||
// the playbook_on_stats event returns the count data in a weird format.
|
||||
// format to what we need!
|
||||
getCountsFromStatsEvent: function(event_data) {
|
||||
var hosts = {},
|
||||
hostsArr;
|
||||
|
||||
// iterate over the event_data and populate an object with hosts
|
||||
// and their status data
|
||||
Object.keys(event_data).forEach(key => {
|
||||
// failed passes boolean not integer
|
||||
if (key === "failed") {
|
||||
// array of hosts from failed type
|
||||
hostsArr = Object.keys(event_data[key]);
|
||||
hostsArr.forEach(host => {
|
||||
if (!hosts[host]) {
|
||||
// host has not been added to hosts object
|
||||
// add now
|
||||
hosts[host] = {};
|
||||
}
|
||||
|
||||
hosts[host][key] = event_data[key][host];
|
||||
});
|
||||
} else {
|
||||
// array of hosts from each type ("changed", "dark", etc.)
|
||||
hostsArr = Object.keys(event_data[key]);
|
||||
hostsArr.forEach(host => {
|
||||
if (!hosts[host]) {
|
||||
// host has not been added to hosts object
|
||||
// add now
|
||||
hosts[host] = {};
|
||||
}
|
||||
|
||||
if (!hosts[host][key]) {
|
||||
// host doesn't have key
|
||||
hosts[host][key] = 0;
|
||||
}
|
||||
hosts[host][key] += event_data[key][host];
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// use the hosts data populate above to get the count
|
||||
var count = {
|
||||
ok : _.filter(hosts, function(o){
|
||||
return !o.failures && !o.changed && o.ok > 0;
|
||||
}),
|
||||
skipped : _.filter(hosts, function(o){
|
||||
return o.skipped > 0;
|
||||
}),
|
||||
unreachable : _.filter(hosts, function(o){
|
||||
return o.dark > 0;
|
||||
}),
|
||||
failures : _.filter(hosts, function(o){
|
||||
return o.failed === true;
|
||||
}),
|
||||
changed : _.filter(hosts, function(o){
|
||||
return o.changed > 0;
|
||||
})
|
||||
};
|
||||
|
||||
// turn the count into an actual count, rather than a list of host
|
||||
// names
|
||||
Object.keys(count).forEach(key => {
|
||||
count[key] = count[key].length;
|
||||
});
|
||||
|
||||
return count;
|
||||
},
|
||||
getEvents: function(url) {
|
||||
var val = $q.defer();
|
||||
|
||||
Rest.setUrl(job.related.job_events);
|
||||
Rest.setUrl(url);
|
||||
Rest.get()
|
||||
.success(function(data) {
|
||||
val.resolve(data.results);
|
||||
val.resolve({results: data.results, next: data.next});
|
||||
})
|
||||
.error(function(obj, status) {
|
||||
ProcessErrors(null, obj, status, null, {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user