mirror of
https://github.com/ansible/awx.git
synced 2026-05-08 01:47:35 -02:30
wip - integrate adhoc and workflow
This commit is contained in:
@@ -12,6 +12,8 @@ let resource;
|
|||||||
let strings;
|
let strings;
|
||||||
let wait;
|
let wait;
|
||||||
|
|
||||||
|
let vm;
|
||||||
|
|
||||||
function mapChoices (choices) {
|
function mapChoices (choices) {
|
||||||
if (!choices) return {};
|
if (!choices) return {};
|
||||||
return Object.assign(...choices.map(([k, v]) => ({ [k]: v })));
|
return Object.assign(...choices.map(([k, v]) => ({ [k]: v })));
|
||||||
@@ -33,7 +35,7 @@ function getStatusDetails (status) {
|
|||||||
return { label, icon, value };
|
return { label, icon, value };
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStartTimeDetails (started) {
|
function getStartDetails (started) {
|
||||||
const unfiltered = started || resource.model.get('started');
|
const unfiltered = started || resource.model.get('started');
|
||||||
|
|
||||||
const label = 'Started';
|
const label = 'Started';
|
||||||
@@ -49,7 +51,7 @@ function getStartTimeDetails (started) {
|
|||||||
return { label, value };
|
return { label, value };
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFinishTimeDetails (finished) {
|
function getFinishDetails (finished) {
|
||||||
const unfiltered = finished || resource.model.get('finished');
|
const unfiltered = finished || resource.model.get('finished');
|
||||||
|
|
||||||
const label = 'Finished';
|
const label = 'Finished';
|
||||||
@@ -416,6 +418,17 @@ function cancelJob () {
|
|||||||
|
|
||||||
function deleteJob () {}
|
function deleteJob () {}
|
||||||
|
|
||||||
|
function handleSocketEvent (data) {
|
||||||
|
const project = resource.model.get('project');
|
||||||
|
|
||||||
|
if (resource.model.get('id') === data.unified_job_id) {
|
||||||
|
vm.status = getStatusDetails(data.status);
|
||||||
|
} else if (project && (project === data.project_id)) {
|
||||||
|
vm.project.update = vm.project.update || {};
|
||||||
|
vm.project.update.status = data.status;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function AtDetailsController (
|
function AtDetailsController (
|
||||||
_$http_,
|
_$http_,
|
||||||
_$filter_,
|
_$filter_,
|
||||||
@@ -427,7 +440,7 @@ function AtDetailsController (
|
|||||||
ParseTypeChange,
|
ParseTypeChange,
|
||||||
ParseVariableString,
|
ParseVariableString,
|
||||||
) {
|
) {
|
||||||
const vm = this || {};
|
vm = this || {};
|
||||||
|
|
||||||
$http = _$http_;
|
$http = _$http_;
|
||||||
$filter = _$filter_;
|
$filter = _$filter_;
|
||||||
@@ -444,8 +457,8 @@ function AtDetailsController (
|
|||||||
resource = $scope.resource; // eslint-disable-line prefer-destructuring
|
resource = $scope.resource; // eslint-disable-line prefer-destructuring
|
||||||
|
|
||||||
vm.status = getStatusDetails();
|
vm.status = getStatusDetails();
|
||||||
vm.started = getStartTimeDetails();
|
vm.started = getStartDetails();
|
||||||
vm.finished = getFinishTimeDetails();
|
vm.finished = getFinishDetails();
|
||||||
vm.jobType = getJobTypeDetails();
|
vm.jobType = getJobTypeDetails();
|
||||||
vm.jobTemplate = getJobTemplateDetails();
|
vm.jobTemplate = getJobTemplateDetails();
|
||||||
vm.sourceWorkflowJob = getSourceWorkflowJobDetails();
|
vm.sourceWorkflowJob = getSourceWorkflowJobDetails();
|
||||||
@@ -488,13 +501,10 @@ function AtDetailsController (
|
|||||||
vm.deleteJob = deleteJob;
|
vm.deleteJob = deleteJob;
|
||||||
vm.toggleLabels = toggleLabels;
|
vm.toggleLabels = toggleLabels;
|
||||||
|
|
||||||
const observe = (key, transform) => {
|
$scope.$watch('started', value => { vm.started = getStartDetails(value); });
|
||||||
$scope.$watch(key, value => { vm[key] = transform(value); });
|
$scope.$watch('finished', value => { vm.finished = getFinishDetails(value); });
|
||||||
};
|
|
||||||
|
|
||||||
observe('finished', getFinishTimeDetails);
|
$scope.$on(resource.ws.status, (e, data) => handleSocketEvent(data));
|
||||||
observe('status', getStatusDetails);
|
|
||||||
observe('started', getStartTimeDetails);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,10 +535,9 @@ function atDetails () {
|
|||||||
link: atDetailsLink,
|
link: atDetailsLink,
|
||||||
controller: AtDetailsController,
|
controller: AtDetailsController,
|
||||||
scope: {
|
scope: {
|
||||||
resource: '=',
|
|
||||||
status: '=',
|
|
||||||
started: '=',
|
|
||||||
finished: '=',
|
finished: '=',
|
||||||
|
started: '=',
|
||||||
|
resource: '=',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,12 +84,14 @@ function JobsIndexController (
|
|||||||
eventCounter = null;
|
eventCounter = null;
|
||||||
statsEvent = resource.stats;
|
statsEvent = resource.stats;
|
||||||
|
|
||||||
|
// Panel Title
|
||||||
|
vm.title = resource.model.get('name');
|
||||||
|
|
||||||
// Status Bar
|
// Status Bar
|
||||||
vm.status = {
|
vm.status = {
|
||||||
stats: statsEvent,
|
stats: statsEvent,
|
||||||
elapsed: resource.model.get('elapsed'),
|
elapsed: resource.model.get('elapsed'),
|
||||||
running: Boolean(resource.model.get('started')) && !resource.model.get('finished'),
|
running: Boolean(resource.model.get('started')) && !resource.model.get('finished'),
|
||||||
title: resource.model.get('name'),
|
|
||||||
plays: null,
|
plays: null,
|
||||||
tasks: null,
|
tasks: null,
|
||||||
};
|
};
|
||||||
@@ -99,7 +101,6 @@ function JobsIndexController (
|
|||||||
resource,
|
resource,
|
||||||
started: resource.model.get('started'),
|
started: resource.model.get('started'),
|
||||||
finished: resource.model.get('finished'),
|
finished: resource.model.get('finished'),
|
||||||
status: resource.model.get('status'),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render.requestAnimationFrame(() => init(!vm.status.running));
|
render.requestAnimationFrame(() => init(!vm.status.running));
|
||||||
@@ -143,7 +144,7 @@ function init (pageMode) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.$on(resource.ws.namespace, handleSocketEvent);
|
$scope.$on(resource.ws.events, handleSocketEvent);
|
||||||
|
|
||||||
if (pageMode) {
|
if (pageMode) {
|
||||||
next();
|
next();
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ function resolveResource (
|
|||||||
Wait
|
Wait
|
||||||
) {
|
) {
|
||||||
const { id, type, job_event_search } = $stateParams; // eslint-disable-line camelcase
|
const { id, type, job_event_search } = $stateParams; // eslint-disable-line camelcase
|
||||||
|
const { name, key } = getWebSocketResource(type);
|
||||||
|
|
||||||
let Resource;
|
let Resource;
|
||||||
let related = 'events';
|
let related = 'events';
|
||||||
@@ -50,9 +51,9 @@ function resolveResource (
|
|||||||
case 'system':
|
case 'system':
|
||||||
Resource = SystemJob;
|
Resource = SystemJob;
|
||||||
break;
|
break;
|
||||||
case 'workflow':
|
// case 'workflow':
|
||||||
Resource = WorkflowJob;
|
// todo: integrate workflow chart components into this view
|
||||||
break;
|
// break;
|
||||||
default:
|
default:
|
||||||
// Redirect
|
// Redirect
|
||||||
return null;
|
return null;
|
||||||
@@ -87,7 +88,8 @@ function resolveResource (
|
|||||||
model,
|
model,
|
||||||
related,
|
related,
|
||||||
ws: {
|
ws: {
|
||||||
namespace: `${WS_PREFIX}-${getWebSocketResource(type).key}-${id}`
|
events: `${WS_PREFIX}-${key}-${id}`,
|
||||||
|
status: `${WS_PREFIX}-${name}`,
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
cache: PAGE_CACHE,
|
cache: PAGE_CACHE,
|
||||||
@@ -99,22 +101,23 @@ function resolveResource (
|
|||||||
.finally(() => Wait('stop'));
|
.finally(() => Wait('stop'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveWebSocketConnection (SocketService, $stateParams) {
|
function resolveWebSocketConnection ($stateParams, SocketService) {
|
||||||
const { type, id } = $stateParams;
|
const { type, id } = $stateParams;
|
||||||
const resource = getWebSocketResource(type);
|
const { name, key } = getWebSocketResource(type);
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
data: {
|
data: {
|
||||||
socket: {
|
socket: {
|
||||||
groups: {
|
groups: {
|
||||||
[resource.name]: ['status_changed', 'summary'],
|
[name]: ['status_changed', 'summary'],
|
||||||
[resource.key]: []
|
[key]: []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketService.addStateResolve(state, id);
|
return SocketService.addStateResolve(state, id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveBreadcrumb (strings) {
|
function resolveBreadcrumb (strings) {
|
||||||
@@ -129,19 +132,19 @@ function getWebSocketResource (type) {
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'system':
|
case 'system':
|
||||||
name = 'system_jobs';
|
name = 'jobs';
|
||||||
key = 'system_job_events';
|
key = 'system_job_events';
|
||||||
break;
|
break;
|
||||||
case 'project':
|
case 'project':
|
||||||
name = 'project_updates';
|
name = 'jobs';
|
||||||
key = 'project_update_events';
|
key = 'project_update_events';
|
||||||
break;
|
break;
|
||||||
case 'command':
|
case 'command':
|
||||||
name = 'ad_hoc_commands';
|
name = 'jobs';
|
||||||
key = 'ad_hoc_command_events';
|
key = 'ad_hoc_command_events';
|
||||||
break;
|
break;
|
||||||
case 'inventory':
|
case 'inventory':
|
||||||
name = 'inventory_updates';
|
name = 'jobs';
|
||||||
key = 'inventory_update_events';
|
key = 'inventory_update_events';
|
||||||
break;
|
break;
|
||||||
case 'playbook':
|
case 'playbook':
|
||||||
@@ -188,10 +191,10 @@ function JobsRun ($stateRegistry) {
|
|||||||
resolveBreadcrumb
|
resolveBreadcrumb
|
||||||
],
|
],
|
||||||
webSocketConnection: [
|
webSocketConnection: [
|
||||||
'SocketService',
|
|
||||||
'$stateParams',
|
'$stateParams',
|
||||||
|
'SocketService',
|
||||||
resolveWebSocketConnection
|
resolveWebSocketConnection
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -208,6 +211,7 @@ angular
|
|||||||
.service('JobStrings', Strings)
|
.service('JobStrings', Strings)
|
||||||
.service('JobPageService', PageService)
|
.service('JobPageService', PageService)
|
||||||
.service('JobScrollService', ScrollService)
|
.service('JobScrollService', ScrollService)
|
||||||
|
.service('JobRenderService', RenderService)
|
||||||
.service('JobEventEngine', EngineService)
|
.service('JobEventEngine', EngineService)
|
||||||
.directive('atDetails', DetailsDirective)
|
.directive('atDetails', DetailsDirective)
|
||||||
.directive('atSearchKey', SearchKeyDirective)
|
.directive('atSearchKey', SearchKeyDirective)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
<at-panel>
|
<at-panel>
|
||||||
<at-details
|
<at-details
|
||||||
resource="vm.details.resource"
|
resource="vm.details.resource"
|
||||||
status="vm.details.status"
|
|
||||||
started="vm.details.started"
|
started="vm.details.started"
|
||||||
finished="vm.details.finished">
|
finished="vm.details.finished">
|
||||||
</at-details>
|
</at-details>
|
||||||
@@ -13,6 +12,7 @@
|
|||||||
|
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<at-panel class="at-Stdout">
|
<at-panel class="at-Stdout">
|
||||||
|
<div class="at-Panel-headingTitle">{{ vm.title }}</div>
|
||||||
<at-stats
|
<at-stats
|
||||||
elapsed="vm.status.elapsed"
|
elapsed="vm.status.elapsed"
|
||||||
running="vm.status.running"
|
running="vm.status.running"
|
||||||
|
|||||||
@@ -48,9 +48,7 @@ function AtStatsController (strings) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
vm.init = scope => {
|
vm.init = scope => {
|
||||||
const { elapsed, running, stats, title, plays, tasks } = scope;
|
const { elapsed, running, stats, plays, tasks } = scope;
|
||||||
|
|
||||||
vm.title = title;
|
|
||||||
|
|
||||||
vm.plays = plays;
|
vm.plays = plays;
|
||||||
vm.tasks = tasks;
|
vm.tasks = tasks;
|
||||||
@@ -99,7 +97,6 @@ function atStats () {
|
|||||||
elapsed: '=',
|
elapsed: '=',
|
||||||
running: '=',
|
running: '=',
|
||||||
stats: '=',
|
stats: '=',
|
||||||
title: '=',
|
|
||||||
plays: '=',
|
plays: '=',
|
||||||
tasks: '=',
|
tasks: '=',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +1,42 @@
|
|||||||
|
<!-- todo: styling, css etc. - disposition according to project lib conventions -->
|
||||||
|
<div class="at-u-floatRight">
|
||||||
|
<span class="at-Panel-label">plays</span>
|
||||||
|
<span ng-show="!vm.plays" class="at-Panel-headingTitleBadge">...</span>
|
||||||
|
<span ng-show="vm.plays" class="at-Panel-headingTitleBadge">{{ vm.plays }}</span>
|
||||||
|
|
||||||
|
<span class="at-Panel-label">tasks</span>
|
||||||
|
<span ng-show="!vm.tasks" class="at-Panel-headingTitleBadge">...</span>
|
||||||
|
<span ng-show="vm.tasks" class="at-Panel-headingTitleBadge">{{ vm.tasks }}</span>
|
||||||
|
|
||||||
|
<span class="at-Panel-label">hosts</span>
|
||||||
|
<span ng-show="!vm.hosts" class="at-Panel-headingTitleBadge">...</span>
|
||||||
|
<span ng-show="vm.hosts" class="at-Panel-headingTitleBadge">{{ vm.hosts }}</span>
|
||||||
|
|
||||||
|
<span class="at-Panel-label">elapsed</span>
|
||||||
|
<span ng-show="!vm.elapsed" class="at-Panel-headingTitleBadge">...</span>
|
||||||
|
<span ng-show="vm.elapsed" class="at-Panel-headingTitleBadge">
|
||||||
|
{{ vm.elapsed * 1000 | duration: "hh:mm:ss" }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<button class="btn at-Input-button at-u-noBorder"
|
||||||
|
aw-tool-tip="{{ toggleStdoutFullscreenTooltip }}"
|
||||||
|
data-tip-watch="toggleStdoutFullscreenTooltip"
|
||||||
|
data-placement="top"
|
||||||
|
ng-class="{'StandardOut-actionButton--active': stdoutFullScreen}"
|
||||||
|
ng-click="toggleStdoutFullscreen()">
|
||||||
|
<i class="fa fa-arrows-alt"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a ng-show="true" href="/api/v2/jobs/{{ job.id }}/stdout?format=txt_download">
|
||||||
|
<button class="btn at-Input-button at-u-noBorder"
|
||||||
|
aw-tool-tip="{{ standardOutTooltip }}"
|
||||||
|
data-tip-watch="standardOutTooltip"
|
||||||
|
data-placement="top">
|
||||||
|
<i class="fa fa-download"></i>
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="HostStatusBar">
|
<div class="HostStatusBar">
|
||||||
<div class="HostStatusBar-ok"
|
<div class="HostStatusBar-ok"
|
||||||
data-placement="top"
|
data-placement="top"
|
||||||
@@ -19,10 +58,10 @@
|
|||||||
aw-tool-tip="{{ vm.tooltips.failures }}"
|
aw-tool-tip="{{ vm.tooltips.failures }}"
|
||||||
data-tip-watch="vm.tooltips.failures">
|
data-tip-watch="vm.tooltips.failures">
|
||||||
</div>
|
</div>
|
||||||
<div class="HostStatusBar-unreachable"
|
<div class="HostStatusBar-dark"
|
||||||
data-placement="top"
|
data-placement="top"
|
||||||
aw-tool-tip="{{ vm.tooltips.unreachable }}"
|
aw-tool-tip="{{ vm.tooltips.dark }}"
|
||||||
data-tip-watch="vm.tooltips.unreachable">
|
data-tip-watch="vm.tooltips.dark">
|
||||||
</div>
|
</div>
|
||||||
<div class="HostStatusBar-noData"
|
<div class="HostStatusBar-noData"
|
||||||
ng-show="vm.running"
|
ng-show="vm.running"
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ function atRelaunchCtrl (
|
|||||||
const jobObj = new Job();
|
const jobObj = new Job();
|
||||||
const jobTemplate = new JobTemplate();
|
const jobTemplate = new JobTemplate();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const checkRelaunchPlaybook = (option) => {
|
const checkRelaunchPlaybook = (option) => {
|
||||||
jobObj.getRelaunch({
|
jobObj.getRelaunch({
|
||||||
id: vm.job.id
|
id: vm.job.id
|
||||||
@@ -182,7 +184,7 @@ function atRelaunchCtrl (
|
|||||||
project.postUpdate(vm.job.project)
|
project.postUpdate(vm.job.project)
|
||||||
.then((postUpdateRes) => {
|
.then((postUpdateRes) => {
|
||||||
if (!$state.includes('jobs')) {
|
if (!$state.includes('jobs')) {
|
||||||
$state.go('scmUpdateStdout', { id: postUpdateRes.data.id }, { reload: true });
|
$state.go('jobz', { id: postUpdateRes.data.id, type: 'project' }, { reload: true });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -218,7 +220,7 @@ function atRelaunchCtrl (
|
|||||||
id: vm.job.id
|
id: vm.job.id
|
||||||
}).then((launchRes) => {
|
}).then((launchRes) => {
|
||||||
if (!$state.includes('jobs')) {
|
if (!$state.includes('jobs')) {
|
||||||
$state.go('adHocJobStdout', { id: launchRes.data.id }, { reload: true });
|
$state.go('jobz', { id: launchRes.data.id, type: 'command' }, { reload: true });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,12 +19,17 @@ function postRelaunch (params) {
|
|||||||
return $http(req);
|
return $http(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getStats () {
|
||||||
|
return Promise.resolve(null);
|
||||||
|
}
|
||||||
|
|
||||||
function AdHocCommandModel (method, resource, config) {
|
function AdHocCommandModel (method, resource, config) {
|
||||||
BaseModel.call(this, 'ad_hoc_commands');
|
BaseModel.call(this, 'ad_hoc_commands');
|
||||||
|
|
||||||
this.Constructor = AdHocCommandModel;
|
this.Constructor = AdHocCommandModel;
|
||||||
this.postRelaunch = postRelaunch.bind(this);
|
this.postRelaunch = postRelaunch.bind(this);
|
||||||
this.getRelaunch = getRelaunch.bind(this);
|
this.getRelaunch = getRelaunch.bind(this);
|
||||||
|
this.getStats = getStats.bind(this);
|
||||||
|
|
||||||
return this.create(method, resource, config);
|
return this.create(method, resource, config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ export default
|
|||||||
// socket-enabled AND socket-disabled, and whether the $state
|
// socket-enabled AND socket-disabled, and whether the $state
|
||||||
// requires a subscribe or an unsubscribe
|
// requires a subscribe or an unsubscribe
|
||||||
var self = this;
|
var self = this;
|
||||||
socketPromise.promise.then(function(){
|
return socketPromise.promise.then(function(){
|
||||||
if(!state.data || !state.data.socket){
|
if(!state.data || !state.data.socket){
|
||||||
_.merge(state.data, {socket: {groups: {}}});
|
_.merge(state.data, {socket: {groups: {}}});
|
||||||
self.unsubscribe(state);
|
self.unsubscribe(state);
|
||||||
|
|||||||
@@ -898,13 +898,13 @@ export default ['$state','moment', '$timeout', '$window', '$filter', 'Rest', 'Ge
|
|||||||
|
|
||||||
let goToJobResults = function(job_type) {
|
let goToJobResults = function(job_type) {
|
||||||
if(job_type === 'job') {
|
if(job_type === 'job') {
|
||||||
$state.go('jobResult', {id: d.job.id});
|
$state.go('jobz', {id: d.job.id, type: 'playbook'});
|
||||||
}
|
}
|
||||||
else if(job_type === 'inventory_update') {
|
else if(job_type === 'inventory_update') {
|
||||||
$state.go('inventorySyncStdout', {id: d.job.id});
|
$state.go('jobz', {id: d.job.id, type: 'inventory'});
|
||||||
}
|
}
|
||||||
else if(job_type === 'project_update') {
|
else if(job_type === 'project_update') {
|
||||||
$state.go('scmUpdateStdout', {id: d.job.id});
|
$state.go('jobz', {id: d.job.id, type: 'project'});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user