mirror of
https://github.com/ansible/awx.git
synced 2026-03-10 22:19:28 -02:30
AC-1014 fixed issued related to deleted templates and templates containing quotes in the name. De-linted job templates and the jobs controller.
This commit is contained in:
@@ -8,79 +8,81 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* global jsyaml:false */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function JobsListCtrl ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobList,
|
function JobsListCtrl ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobList, GenerateList, LoadBreadCrumbs, Prompt,
|
||||||
GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller,
|
SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, LookUpInit, SubmitJob, FormatDate, Refresh,
|
||||||
ClearScope, ProcessErrors, GetBasePath, LookUpInit, SubmitJob, FormatDate, Refresh,
|
JobStatusToolTip, Empty, Wait) {
|
||||||
JobStatusToolTip, Empty, Wait)
|
|
||||||
{
|
|
||||||
ClearScope('htmlTemplate');
|
ClearScope('htmlTemplate');
|
||||||
var list = JobList;
|
|
||||||
var defaultUrl = GetBasePath('jobs');
|
var list = JobList,
|
||||||
var view = GenerateList;
|
defaultUrl = GetBasePath('jobs'),
|
||||||
var base = $location.path().replace(/^\//,'').split('/')[0];
|
view = GenerateList,
|
||||||
var scope = view.inject(list, { mode: 'edit' });
|
scope = view.inject(list, { mode: 'edit' }),
|
||||||
|
opt;
|
||||||
|
|
||||||
$rootScope.flashMessage = null;
|
$rootScope.flashMessage = null;
|
||||||
scope.selected = [];
|
scope.selected = [];
|
||||||
|
|
||||||
if (scope.removePostRefresh) {
|
if (scope.removePostRefresh) {
|
||||||
scope.removePostRefresh();
|
scope.removePostRefresh();
|
||||||
}
|
}
|
||||||
scope.removePostRefresh = scope.$on('PostRefresh', function() {
|
scope.removePostRefresh = scope.$on('PostRefresh', function() {
|
||||||
$("tr.success").each(function(index) {
|
var i,cDate;
|
||||||
|
$("tr.success").each(function() {
|
||||||
// Make sure no rows have a green background
|
// Make sure no rows have a green background
|
||||||
var ngc = $(this).attr('ng-class');
|
var ngc = $(this).attr('ng-class');
|
||||||
scope[ngc] = "";
|
scope[ngc] = "";
|
||||||
});
|
|
||||||
|
|
||||||
if (scope['jobs'] && scope['jobs'].length) {
|
|
||||||
var cDate;
|
|
||||||
for (var i=0; i < scope['jobs'].length; i++) {
|
|
||||||
// Convert created date to local time zone
|
|
||||||
cDate = new Date(scope['jobs'][i].created);
|
|
||||||
scope['jobs'][i].created = FormatDate(cDate);
|
|
||||||
// Set tooltip and link
|
|
||||||
scope.jobs[i].statusBadgeToolTip = JobStatusToolTip(scope.jobs[i].status) +
|
|
||||||
" Click to view status details.";
|
|
||||||
scope.jobs[i].statusLinkTo = '/#/jobs/' + scope.jobs[i].id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
if (scope.jobs && scope.jobs.length) {
|
||||||
|
for (i=0; i < scope.jobs.length; i++) {
|
||||||
|
// Convert created date to local time zone
|
||||||
|
cDate = new Date(scope.jobs[i].created);
|
||||||
|
scope.jobs[i].created = FormatDate(cDate);
|
||||||
|
// Set tooltip and link
|
||||||
|
scope.jobs[i].statusBadgeToolTip = JobStatusToolTip(scope.jobs[i].status) +
|
||||||
|
" Click to view status details.";
|
||||||
|
scope.jobs[i].statusLinkTo = '/#/jobs/' + scope.jobs[i].id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
if ($routeParams['job_host_summaries__host']) {
|
if ($routeParams.job_host_summaries__host) {
|
||||||
defaultUrl += '?job_host_summaries__host=' + $routeParams['job_host_summaries__host'];
|
defaultUrl += '?job_host_summaries__host=' + $routeParams.job_host_summaries__host;
|
||||||
}
|
}
|
||||||
else if ($routeParams['inventory__int'] && $routeParams['status']) {
|
else if ($routeParams.inventory__int && $routeParams.status) {
|
||||||
defaultUrl += '?inventory__int=' + $routeParams['inventory__int'] + '&status=' +
|
defaultUrl += '?inventory__int=' + $routeParams.inventory__int + '&status=' +
|
||||||
$routeParams['status'];
|
$routeParams.status;
|
||||||
}
|
}
|
||||||
SearchInit({ scope: scope, set: 'jobs', list: list, url: defaultUrl });
|
SearchInit({ scope: scope, set: 'jobs', list: list, url: defaultUrl });
|
||||||
PaginateInit({ scope: scope, list: list, url: defaultUrl });
|
PaginateInit({ scope: scope, list: list, url: defaultUrl });
|
||||||
|
|
||||||
// Called from Inventories page, failed jobs link. Find jobs for selected inventory.
|
// Called from Inventories page, failed jobs link. Find jobs for selected inventory.
|
||||||
if ($routeParams['inventory__int']) {
|
if ($routeParams.inventory__int) {
|
||||||
scope[list.iterator + 'SearchField'] = 'inventory';
|
scope[list.iterator + 'SearchField'] = 'inventory';
|
||||||
scope[list.iterator + 'SearchValue'] = $routeParams['inventory__int'];
|
scope[list.iterator + 'SearchValue'] = $routeParams.inventory__int;
|
||||||
scope[list.iterator + 'SearchFieldLabel'] = 'Inventory ID';
|
scope[list.iterator + 'SearchFieldLabel'] = 'Inventory ID';
|
||||||
}
|
}
|
||||||
if ($routeParams['id__int']) {
|
if ($routeParams.id__int) {
|
||||||
scope[list.iterator + 'SearchField'] = 'id';
|
scope[list.iterator + 'SearchField'] = 'id';
|
||||||
scope[list.iterator + 'SearchValue'] = $routeParams['id__int'];
|
scope[list.iterator + 'SearchValue'] = $routeParams.id__int;
|
||||||
scope[list.iterator + 'SearchFieldLabel'] = 'Job ID';
|
scope[list.iterator + 'SearchFieldLabel'] = 'Job ID';
|
||||||
}
|
}
|
||||||
if ($routeParams['status']) {
|
if ($routeParams.status) {
|
||||||
scope[list.iterator + 'SearchField'] = 'status';
|
scope[list.iterator + 'SearchField'] = 'status';
|
||||||
scope[list.iterator + 'SelectShow'] = true;
|
scope[list.iterator + 'SelectShow'] = true;
|
||||||
scope[list.iterator + 'SearchSelectOpts'] = list.fields['status'].searchOptions;
|
scope[list.iterator + 'SearchSelectOpts'] = list.fields.status.searchOptions;
|
||||||
scope[list.iterator + 'SearchFieldLabel'] = list.fields['status'].label.replace(/\<br\>/g,' ');
|
scope[list.iterator + 'SearchFieldLabel'] = list.fields.status.label.replace(/<br>/g,' ');
|
||||||
for (var opt in list.fields['status'].searchOptions) {
|
for (opt in list.fields.status.searchOptions) {
|
||||||
if (list.fields['status'].searchOptions[opt].value == $routeParams['status']) {
|
if (list.fields.status.searchOptions[opt].value === $routeParams.status) {
|
||||||
scope[list.iterator + 'SearchSelectValue'] = list.fields['status'].searchOptions[opt];
|
scope[list.iterator + 'SearchSelectValue'] = list.fields.status.searchOptions[opt];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.search(list.iterator);
|
scope.search(list.iterator);
|
||||||
@@ -88,88 +90,89 @@ function JobsListCtrl ($scope, $rootScope, $location, $log, $routeParams, Rest,
|
|||||||
LoadBreadCrumbs();
|
LoadBreadCrumbs();
|
||||||
|
|
||||||
scope.refresh = function() {
|
scope.refresh = function() {
|
||||||
Wait('start');
|
Wait('start');
|
||||||
scope['jobLoading'] = false;
|
scope.jobLoading = false;
|
||||||
Refresh({ scope: scope, set: 'jobs', iterator: 'job', url: scope['current_url'] });
|
Refresh({ scope: scope, set: 'jobs', iterator: 'job', url: scope.current_url });
|
||||||
}
|
};
|
||||||
|
|
||||||
scope.refreshJob = scope.refresh;
|
scope.refreshJob = scope.refresh;
|
||||||
|
|
||||||
scope.editJob = function(id, name) {
|
scope.editJob = function(id, name) {
|
||||||
LoadBreadCrumbs({ path: '/jobs/' + id, title: id + ' - ' + name });
|
LoadBreadCrumbs({ path: '/jobs/' + id, title: id + ' - ' + name });
|
||||||
$location.path($location.path() + '/' + id);
|
$location.path($location.path() + '/' + id);
|
||||||
}
|
};
|
||||||
|
|
||||||
scope.viewEvents = function(id, name) {
|
scope.viewEvents = function(id, name) {
|
||||||
LoadBreadCrumbs({ path: '/jobs/' + id, title: id + ' - ' + name });
|
LoadBreadCrumbs({ path: '/jobs/' + id, title: id + ' - ' + name });
|
||||||
$location.path($location.path() + '/' + id + '/job_events');
|
$location.path($location.path() + '/' + id + '/job_events');
|
||||||
}
|
};
|
||||||
|
|
||||||
scope.viewSummary = function(id, name) {
|
scope.viewSummary = function(id, name) {
|
||||||
LoadBreadCrumbs({ path: '/jobs/' + id, title: id + ' - ' + name });
|
LoadBreadCrumbs({ path: '/jobs/' + id, title: id + ' - ' + name });
|
||||||
$location.path($location.path() + '/' + id + '/job_host_summaries');
|
$location.path($location.path() + '/' + id + '/job_host_summaries');
|
||||||
}
|
};
|
||||||
|
|
||||||
scope.deleteJob = function(id, name) {
|
scope.deleteJob = function(id) {
|
||||||
Rest.setUrl(defaultUrl + id + '/');
|
Rest.setUrl(defaultUrl + id + '/');
|
||||||
Rest.get()
|
Rest.get()
|
||||||
.success( function(data, status, headers, config) {
|
.success( function(data) {
|
||||||
var url, action_label, restcall, hdr;
|
|
||||||
if (data.status == 'pending' || data.status == 'running' || data.status == 'waiting') {
|
var action, url, action_label, hdr;
|
||||||
url = data.related.cancel;
|
|
||||||
action_label = 'cancel';
|
if (data.status === 'pending' || data.status === 'running' || data.status === 'waiting') {
|
||||||
hdr = 'Cancel Job';
|
url = data.related.cancel;
|
||||||
}
|
action_label = 'cancel';
|
||||||
else {
|
hdr = 'Cancel Job';
|
||||||
url = defaultUrl + id + '/';
|
}
|
||||||
action_label = 'delete';
|
else {
|
||||||
hdr = 'Delete Job';
|
url = defaultUrl + id + '/';
|
||||||
}
|
action_label = 'delete';
|
||||||
|
hdr = 'Delete Job';
|
||||||
|
}
|
||||||
|
|
||||||
var action = function() {
|
action = function() {
|
||||||
Rest.setUrl(url);
|
Rest.setUrl(url);
|
||||||
if (action_label == 'cancel') {
|
if (action_label === 'cancel') {
|
||||||
Rest.post()
|
Rest.post()
|
||||||
.success( function(data, status, headers, config) {
|
.success( function() {
|
||||||
$('#prompt-modal').modal('hide');
|
$('#prompt-modal').modal('hide');
|
||||||
scope.search(list.iterator);
|
scope.search(list.iterator);
|
||||||
})
|
})
|
||||||
.error( function(data, status, headers, config) {
|
.error( function(data, status) {
|
||||||
$('#prompt-modal').modal('hide');
|
$('#prompt-modal').modal('hide');
|
||||||
ProcessErrors(scope, data, status, null,
|
ProcessErrors(scope, data, status, null,
|
||||||
{ hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status });
|
{ hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST returned status: ' + status });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Rest.destroy()
|
Rest.destroy()
|
||||||
.success( function(data, status, headers, config) {
|
.success( function() {
|
||||||
$('#prompt-modal').modal('hide');
|
$('#prompt-modal').modal('hide');
|
||||||
scope.search(list.iterator);
|
scope.search(list.iterator);
|
||||||
})
|
})
|
||||||
.error( function(data, status, headers, config) {
|
.error( function(data, status) {
|
||||||
$('#prompt-modal').modal('hide');
|
$('#prompt-modal').modal('hide');
|
||||||
ProcessErrors(scope, data, status, null,
|
ProcessErrors(scope, data, status, null,
|
||||||
{ hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status });
|
{ hdr: 'Error!', msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Prompt({
|
Prompt({
|
||||||
hdr: hdr,
|
hdr: hdr,
|
||||||
body: 'Are you sure you want to ' + action_label + ' job ' + id + '?',
|
body: 'Are you sure you want to ' + action_label + ' job ' + id + '?',
|
||||||
action: action
|
action: action
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.error( function(data, status, headers, config) {
|
.error( function(data, status) {
|
||||||
ProcessErrors(scope, data, status, null,
|
ProcessErrors(scope, data, status, null,
|
||||||
{ hdr: 'Error!', msg: 'Failed to get job details. GET returned status: ' + status });
|
{ hdr: 'Error!', msg: 'Failed to get job details. GET returned status: ' + status });
|
||||||
});
|
});
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|
||||||
scope.submitJob = function(id, template) {
|
scope.submitJob = function(id, template) {
|
||||||
SubmitJob({ scope: scope, id: id, template: template });
|
SubmitJob({ scope: scope, id: id, template: template });
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
JobsListCtrl.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobList',
|
JobsListCtrl.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobList',
|
||||||
@@ -179,294 +182,282 @@ JobsListCtrl.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routePar
|
|||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, JobForm,
|
function JobsEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, JobForm, GenerateForm, Rest, Alert, ProcessErrors,
|
||||||
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit,
|
LoadBreadCrumbs, RelatedSearchInit,RelatedPaginateInit, ReturnToCaller, ClearScope, InventoryList, CredentialList,
|
||||||
RelatedPaginateInit, ReturnToCaller, ClearScope, InventoryList, CredentialList,
|
ProjectList, LookUpInit, PromptPasswords, GetBasePath, md5Setup, FormatDate, JobStatusToolTip, Wait) {
|
||||||
ProjectList, LookUpInit, PromptPasswords, GetBasePath, md5Setup, FormatDate,
|
|
||||||
JobStatusToolTip, Wait)
|
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||||
{
|
|
||||||
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
|
||||||
//scope.
|
//scope.
|
||||||
|
|
||||||
var defaultUrl= GetBasePath('jobs');
|
var defaultUrl= GetBasePath('jobs'),
|
||||||
var generator = GenerateForm;
|
generator = GenerateForm,
|
||||||
var form = JobForm;
|
form = JobForm,
|
||||||
|
scope = generator.inject(form, {mode: 'edit', related: true}),
|
||||||
|
master = {},
|
||||||
|
id = $routeParams.id,
|
||||||
|
relatedSets = {},
|
||||||
|
loadingFinishedCount = 0;
|
||||||
|
|
||||||
|
generator.reset();
|
||||||
|
|
||||||
var scope = generator.inject(form, {mode: 'edit', related: true});
|
scope.job_id = id;
|
||||||
generator.reset();
|
scope.parseType = 'yaml';
|
||||||
var base = $location.path().replace(/^\//,'').split('/')[0];
|
scope.statusSearchSpin = false;
|
||||||
var master = {};
|
|
||||||
var id = $routeParams.id;
|
|
||||||
var relatedSets = {};
|
|
||||||
var loadingFinishedCount = 0;
|
|
||||||
|
|
||||||
scope.job_id = id;
|
|
||||||
scope.parseType = 'yaml';
|
|
||||||
scope.statusSearchSpin = false;
|
|
||||||
|
|
||||||
function getPlaybooks(project) {
|
function getPlaybooks(project) {
|
||||||
if (project !== null && project !== '' && project !== undefined) {
|
if (project !== null && project !== '' && project !== undefined) {
|
||||||
var url = GetBasePath('projects') + project + '/playbooks/';
|
var url = GetBasePath('projects') + project + '/playbooks/';
|
||||||
Rest.setUrl(url);
|
Rest.setUrl(url);
|
||||||
Rest.get()
|
Rest.get()
|
||||||
.success( function(data, status, headers, config) {
|
.success( function(data) {
|
||||||
scope.playbook_options = [];
|
scope.playbook_options = [];
|
||||||
for (var i=0; i < data.length; i++) {
|
for (var i=0; i < data.length; i++) {
|
||||||
scope.playbook_options.push(data[i]);
|
scope.playbook_options.push(data[i]);
|
||||||
}
|
}
|
||||||
scope.$emit('jobTemplateLoadFinished');
|
scope.$emit('jobTemplateLoadFinished');
|
||||||
})
|
})
|
||||||
.error( function(data, status, headers, config) {
|
.error( function() {
|
||||||
scope.$emit('jobTemplateLoadFinished');
|
scope.$emit('jobTemplateLoadFinished');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
scope.$emit('jobTemplateLoadFinished');
|
scope.$emit('jobTemplateLoadFinished');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Retrieve each related set and populate the playbook list
|
// Retrieve each related set and populate the playbook list
|
||||||
if (scope.jobLoadedRemove) {
|
if (scope.jobLoadedRemove) {
|
||||||
scope.jobLoadedRemove();
|
scope.jobLoadedRemove();
|
||||||
}
|
}
|
||||||
scope.jobLoadedRemove = scope.$on('jobLoaded', function(e, related_cloud_credential) {
|
scope.jobLoadedRemove = scope.$on('jobLoaded', function(e, related_cloud_credential) {
|
||||||
|
|
||||||
getPlaybooks(scope.project);
|
getPlaybooks(scope.project);
|
||||||
|
|
||||||
scope[form.name + 'ReadOnly'] = (scope.status == 'new') ? false : true;
|
scope[form.name + 'ReadOnly'] = (scope.status === 'new') ? false : true;
|
||||||
|
|
||||||
$('#forks-slider').slider("option", "value", scope.forks);
|
$('#forks-slider').slider("option", "value", scope.forks);
|
||||||
$('#forks-slider').slider("disable");
|
$('#forks-slider').slider("disable");
|
||||||
$('input[type="checkbox"]').attr('disabled','disabled');
|
$('input[type="checkbox"]').attr('disabled','disabled');
|
||||||
$('input[type="radio"]').attr('disabled','disabled');
|
$('input[type="radio"]').attr('disabled','disabled');
|
||||||
$('#host_config_key-gen-btn').attr('disabled','disabled');
|
$('#host_config_key-gen-btn').attr('disabled','disabled');
|
||||||
$('textarea').attr('readonly','readonly');
|
$('textarea').attr('readonly','readonly');
|
||||||
|
|
||||||
// Get job template and display/hide host callback fields
|
// Get job template and display/hide host callback fields
|
||||||
Rest.setUrl(scope.template_url);
|
Rest.setUrl(scope.template_url);
|
||||||
Rest.get()
|
Rest.get()
|
||||||
.success( function(data, status, headers, config) {
|
.success( function(data) {
|
||||||
var dft = (data['host_config_key']) ? 'true' : 'false';
|
var dft = (data.host_config_key) ? 'true' : 'false';
|
||||||
scope['host_config_key'] = data['host_config_key'];
|
scope.host_config_key = data.host_config_key;
|
||||||
md5Setup({
|
md5Setup({
|
||||||
scope: scope,
|
scope: scope,
|
||||||
master: master,
|
master: master,
|
||||||
check_field: 'allow_callbacks',
|
check_field: 'allow_callbacks',
|
||||||
default_val: dft
|
default_val: dft
|
||||||
});
|
});
|
||||||
scope['callback_url'] = data.related['callback'];
|
scope.callback_url = data.related.callback;
|
||||||
scope.$emit('jobTemplateLoadFinished');
|
scope.$emit('jobTemplateLoadFinished');
|
||||||
})
|
})
|
||||||
.error( function(data, status, headers, config) {
|
.error( function() {
|
||||||
scope['callback_url'] = '<< Job template not found >>';
|
Wait('stop');
|
||||||
});
|
scope.callback_url = '<< Job template not found >>';
|
||||||
|
});
|
||||||
|
|
||||||
if (related_cloud_credential) {
|
if (related_cloud_credential) {
|
||||||
//Get the name of the cloud credential
|
//Get the name of the cloud credential
|
||||||
Rest.setUrl(related_cloud_credential);
|
Rest.setUrl(related_cloud_credential);
|
||||||
Rest.get()
|
Rest.get()
|
||||||
.success( function(data, status, headers, config) {
|
.success( function(data) {
|
||||||
scope['cloud_credential_name'] = data.name;
|
scope.cloud_credential_name = data.name;
|
||||||
scope.$emit('jobTemplateLoadFinished');
|
scope.$emit('jobTemplateLoadFinished');
|
||||||
})
|
})
|
||||||
.error( function(data, status, headers, config) {
|
.error( function(data, status) {
|
||||||
ProcessErrors(scope, data, status, null,
|
ProcessErrors(scope, data, status, null,
|
||||||
{ hdr: 'Error!', msg: 'Failed to related cloud credential. GET returned status: ' + status });
|
{ hdr: 'Error!', msg: 'Failed to related cloud credential. GET returned status: ' + status });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
scope.$emit('jobTemplateLoadFinished');
|
scope.$emit('jobTemplateLoadFinished');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Turn off 'Wait' after both cloud credential and playbook list come back
|
// Turn off 'Wait' after both cloud credential and playbook list come back
|
||||||
if (scope.removeJobTemplateLoadFinished) {
|
if (scope.removeJobTemplateLoadFinished) {
|
||||||
scope.removeJobTemplateLoadFinished();
|
scope.removeJobTemplateLoadFinished();
|
||||||
}
|
}
|
||||||
scope.removeJobTemplateLoadFinished = scope.$on('jobTemplateLoadFinished', function() {
|
scope.removeJobTemplateLoadFinished = scope.$on('jobTemplateLoadFinished', function() {
|
||||||
loadingFinishedCount++;
|
loadingFinishedCount++;
|
||||||
if (loadingFinishedCount >= 3) {
|
if (loadingFinishedCount >= 3) {
|
||||||
// The initial template load finished. Now load related jobs, which
|
// The initial template load finished. Now load related jobs, which
|
||||||
// will turn off the 'working' spinner.
|
// will turn off the 'working' spinner.
|
||||||
Wait('stop');
|
Wait('stop');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Our job type options
|
// Our job type options
|
||||||
scope.job_type_options = [{ value: 'run', label: 'Run' }, { value: 'check', label: 'Check' }];
|
scope.job_type_options = [{ value: 'run', label: 'Run' }, { value: 'check', label: 'Check' }];
|
||||||
scope.verbosity_options = [
|
scope.verbosity_options = [
|
||||||
{ value: '0', label: 'Default' },
|
{ value: '0', label: 'Default' },
|
||||||
{ value: '1', label: 'Verbose' },
|
{ value: '1', label: 'Verbose' },
|
||||||
{ value: '3', label: 'Debug' }];
|
{ value: '3', label: 'Debug' }
|
||||||
scope.playbook_options = null;
|
];
|
||||||
scope.playbook = null;
|
scope.playbook_options = null;
|
||||||
|
scope.playbook = null;
|
||||||
|
|
||||||
function calcRows (content) {
|
function calcRows (content) {
|
||||||
var n = content.match(/\n/g);
|
var n = content.match(/\n/g),
|
||||||
var rows = (n) ? n.length : 1;
|
rows = (n) ? n.length : 1;
|
||||||
return (rows > 15) ? 15 : rows;
|
return (rows > 15) ? 15 : rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve detail record and prepopulate the form
|
// Retrieve detail record and prepopulate the form
|
||||||
Wait('start');
|
Wait('start');
|
||||||
Rest.setUrl(defaultUrl + ':id/');
|
Rest.setUrl(defaultUrl + ':id/');
|
||||||
Rest.get({ params: {id: id} })
|
Rest.get({ params: {id: id} })
|
||||||
.success( function(data, status, headers, config) {
|
.success( function(data) {
|
||||||
|
//LoadBreadCrumbs({ path: '/jobs/' + id, title: data.id + ' - ' + data.summary_fields.job_template.name });
|
||||||
|
var i, cDate, fld, json_obj, related, set;
|
||||||
|
LoadBreadCrumbs();
|
||||||
|
for (fld in form.fields) {
|
||||||
|
if (fld !== 'variables' && data[fld] !== null && data[fld] !== undefined) {
|
||||||
|
if (form.fields[fld].type === 'select') {
|
||||||
|
if (scope[fld + '_options'] && scope[fld + '_options'].length > 0) {
|
||||||
|
for (i=0; i < scope[fld + '_options'].length; i++) {
|
||||||
|
if (data[fld] === scope[fld + '_options'][i].value) {
|
||||||
|
scope[fld] = scope[fld + '_options'][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scope[fld] = data[fld];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scope[fld] = data[fld];
|
||||||
|
}
|
||||||
|
master[fld] = scope[fld];
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.id = data.id;
|
||||||
|
scope.name = data.summary_fields.job_template.name;
|
||||||
|
|
||||||
|
if (fld === 'variables') {
|
||||||
|
// Parse extra_vars, converting to YAML.
|
||||||
|
if ($.isEmptyObject(data.extra_vars) || data.extra_vars === "{}" || data.extra_vars === "null" ||
|
||||||
|
data.extra_vars === "" || data.extra_vars === null) {
|
||||||
|
scope.variables = "---";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
json_obj = JSON.parse(data.extra_vars);
|
||||||
|
scope.variables = jsyaml.safeDump(json_obj);
|
||||||
|
}
|
||||||
|
master.variables = scope.variables;
|
||||||
|
}
|
||||||
|
if (form.fields[fld].type === 'lookup' && data.summary_fields[form.fields[fld].sourceModel]) {
|
||||||
|
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
|
||||||
|
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
|
||||||
|
master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
|
||||||
|
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField];
|
||||||
|
}
|
||||||
|
|
||||||
//LoadBreadCrumbs({ path: '/jobs/' + id, title: data.id + ' - ' + data.summary_fields.job_template.name });
|
for (fld in form.statusFields) {
|
||||||
LoadBreadCrumbs();
|
if (data[fld] !== null && data[fld] !== undefined) {
|
||||||
|
if (fld === 'created') {
|
||||||
for (var fld in form.fields) {
|
// Convert created date to local time zone
|
||||||
if (fld != 'variables' && data[fld] !== null && data[fld] !== undefined) {
|
cDate = new Date(data.created);
|
||||||
if (form.fields[fld].type == 'select') {
|
scope.created = FormatDate(cDate);
|
||||||
if (scope[fld + '_options'] && scope[fld + '_options'].length > 0) {
|
|
||||||
for (var i=0; i < scope[fld + '_options'].length; i++) {
|
|
||||||
if (data[fld] == scope[fld + '_options'][i].value) {
|
|
||||||
scope[fld] = scope[fld + '_options'][i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
scope[fld] = data[fld];
|
scope[fld] = data[fld];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
scope[fld] = data[fld];
|
|
||||||
}
|
|
||||||
master[fld] = scope[fld];
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.id = data.id;
|
|
||||||
scope.name = data.summary_fields.job_template.name;
|
|
||||||
|
|
||||||
if (fld == 'variables') {
|
scope.statusToolTip = JobStatusToolTip(data.status);
|
||||||
// Parse extra_vars, converting to YAML.
|
|
||||||
if ($.isEmptyObject(data.extra_vars) || data.extra_vars == "\{\}" || data.extra_vars == "null"
|
|
||||||
|| data.extra_vars == "" || data.extra_vars == null) {
|
|
||||||
scope.variables = "---";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var json_obj = JSON.parse(data.extra_vars);
|
|
||||||
scope.variables = jsyaml.safeDump(json_obj);
|
|
||||||
}
|
|
||||||
master.variables = scope.variables;
|
|
||||||
}
|
|
||||||
if (form.fields[fld].type == 'lookup' && data.summary_fields[form.fields[fld].sourceModel]) {
|
|
||||||
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
|
|
||||||
data.summary_fields[form.fields[fld].sourceModel][form.fields[fld].sourceField];
|
|
||||||
master[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField] =
|
|
||||||
scope[form.fields[fld].sourceModel + '_' + form.fields[fld].sourceField];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var fld in form.statusFields) {
|
|
||||||
if (data[fld] !== null && data[fld] !== undefined) {
|
|
||||||
if (fld == 'created') {
|
|
||||||
// Convert created date to local time zone
|
|
||||||
var cDate = new Date(data.created);
|
|
||||||
scope.created = FormatDate(cDate);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
scope[fld] = data[fld];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.statusToolTip = JobStatusToolTip(data.status);
|
|
||||||
|
|
||||||
$('form[name="jobs_form"] input[type="text"], form[name="jobs_form"] jobs_form textarea').attr('readonly','readonly');
|
$('form[name="jobs_form"] input[type="text"], form[name="jobs_form"] jobs_form textarea').attr('readonly','readonly');
|
||||||
$('form[name="jobs_form"] select').prop('disabled', 'disabled');
|
$('form[name="jobs_form"] select').prop('disabled', 'disabled');
|
||||||
$('form[name="jobs_form"] .lookup-btn').prop('disabled', 'disabled');
|
$('form[name="jobs_form"] .lookup-btn').prop('disabled', 'disabled');
|
||||||
$('form[name="jobs_form"] .buttons, form[name="jobs_form"] hr').hide();
|
$('form[name="jobs_form"] .buttons, form[name="jobs_form"] hr').hide();
|
||||||
|
|
||||||
scope.url = data.url;
|
scope.url = data.url;
|
||||||
var related = data.related;
|
related = data.related;
|
||||||
for (var set in form.related) {
|
for (set in form.related) {
|
||||||
if (related[set]) {
|
if (related[set]) {
|
||||||
relatedSets[set] = { url: related[set], iterator: form.related[set].iterator };
|
relatedSets[set] = { url: related[set], iterator: form.related[set].iterator };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calc row size of stdout and traceback textarea fields
|
|
||||||
//var n = scope['result_stdout'].match(/\n/g);
|
|
||||||
//var rows = (n) ? n.length : 1;
|
|
||||||
//rows = (rows > 15) ? 15 : rows;
|
|
||||||
//rows;
|
|
||||||
|
|
||||||
scope['stdout_rows'] = calcRows(scope['result_stdout']);
|
scope.stdout_rows = calcRows(scope.result_stdout);
|
||||||
|
|
||||||
|
scope.traceback_rows = calcRows(scope.result_traceback);
|
||||||
|
|
||||||
//n = scope['result_traceback'].match(/\n/g);
|
LookUpInit({
|
||||||
//var rows = (n) ? n.length : 1;
|
scope: scope,
|
||||||
//rows = (rows > 15) ? 15 : rows;
|
form: form,
|
||||||
|
current_item: data.inventory,
|
||||||
|
list: InventoryList,
|
||||||
|
field: 'inventory'
|
||||||
|
});
|
||||||
|
|
||||||
scope['traceback_rows'] = calcRows(scope['result_traceback']);
|
LookUpInit({
|
||||||
|
scope: scope,
|
||||||
|
form: form,
|
||||||
|
current_item: data.credential,
|
||||||
|
list: CredentialList,
|
||||||
|
field: 'credential'
|
||||||
|
});
|
||||||
|
|
||||||
LookUpInit({
|
LookUpInit({
|
||||||
scope: scope,
|
scope: scope,
|
||||||
form: form,
|
form: form,
|
||||||
current_item: data.inventory,
|
current_item: data.project,
|
||||||
list: InventoryList,
|
list: ProjectList,
|
||||||
field: 'inventory'
|
field: 'project'
|
||||||
});
|
});
|
||||||
|
|
||||||
LookUpInit({
|
// Initialize related search functions. Doing it here to make sure relatedSets object is populated.
|
||||||
scope: scope,
|
RelatedSearchInit({ scope: scope, form: form, relatedSets: relatedSets });
|
||||||
form: form,
|
RelatedPaginateInit({ scope: scope, relatedSets: relatedSets });
|
||||||
current_item: data.credential,
|
scope.template_url = data.related.job_template;
|
||||||
list: CredentialList,
|
scope.$emit('jobLoaded', data.related.cloud_credential);
|
||||||
field: 'credential'
|
})
|
||||||
});
|
.error( function(data, status) {
|
||||||
|
ProcessErrors(scope, data, status, form,
|
||||||
|
{ hdr: 'Error!', msg: 'Failed to retrieve job: ' + $routeParams.id + '. GET status: ' + status });
|
||||||
|
});
|
||||||
|
|
||||||
LookUpInit({
|
scope.refresh = function() {
|
||||||
scope: scope,
|
Wait('start');
|
||||||
form: form,
|
Rest.setUrl(defaultUrl + id + '/');
|
||||||
current_item: data.project,
|
Rest.get()
|
||||||
list: ProjectList,
|
.success( function(data) {
|
||||||
field: 'project'
|
scope.status = data.status;
|
||||||
});
|
scope.result_stdout = data.result_stdout;
|
||||||
|
scope.result_traceback = data.result_traceback;
|
||||||
|
scope.stdout_rows = calcRows(scope.result_stdout);
|
||||||
|
scope.traceback_rows = calcRows(scope.result_traceback);
|
||||||
|
Wait('stop');
|
||||||
|
})
|
||||||
|
.error( function(data, status) {
|
||||||
|
Wait('stop');
|
||||||
|
ProcessErrors(scope, data, status, null,
|
||||||
|
{ hdr: 'Error!', msg: 'Attempt to load job failed. GET returned status: ' + status });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Initialize related search functions. Doing it here to make sure relatedSets object is populated.
|
scope.jobSummary = function() {
|
||||||
RelatedSearchInit({ scope: scope, form: form, relatedSets: relatedSets });
|
$location.path('/jobs/' + id + '/job_host_summaries');
|
||||||
RelatedPaginateInit({ scope: scope, relatedSets: relatedSets });
|
};
|
||||||
scope.template_url = data.related.job_template;
|
|
||||||
scope.$emit('jobLoaded', data.related.cloud_credential);
|
|
||||||
})
|
|
||||||
.error( function(data, status, headers, config) {
|
|
||||||
ProcessErrors(scope, data, status, form,
|
|
||||||
{ hdr: 'Error!', msg: 'Failed to retrieve job: ' + $routeParams.id + '. GET status: ' + status });
|
|
||||||
});
|
|
||||||
|
|
||||||
scope.refresh = function() {
|
scope.jobEvents = function() {
|
||||||
Wait('start');
|
$location.path('/jobs/' + id + '/job_events');
|
||||||
Rest.setUrl(defaultUrl + id + '/');
|
};
|
||||||
Rest.get()
|
|
||||||
.success( function(data, status, headers, config) {
|
|
||||||
scope.status = data.status;
|
|
||||||
scope.result_stdout = data.result_stdout;
|
|
||||||
scope.result_traceback = data.result_traceback;
|
|
||||||
scope['stdout_rows'] = calcRows(scope['result_stdout']);
|
|
||||||
scope['traceback_rows'] = calcRows(scope['result_traceback']);
|
|
||||||
Wait('stop');
|
|
||||||
})
|
|
||||||
.error( function(data, status, headers, config) {
|
|
||||||
Wait('stop');
|
|
||||||
ProcessErrors(scope, data, status, null,
|
|
||||||
{ hdr: 'Error!', msg: 'Attempt to load job failed. GET returned status: ' + status });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.jobSummary = function() {
|
|
||||||
$location.path('/jobs/' + id + '/job_host_summaries');
|
|
||||||
}
|
|
||||||
|
|
||||||
scope.jobEvents = function() {
|
|
||||||
$location.path('/jobs/' + id + '/job_events');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JobsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobForm',
|
JobsEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobForm',
|
||||||
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit',
|
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit',
|
||||||
'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'InventoryList', 'CredentialList',
|
'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'InventoryList', 'CredentialList',
|
||||||
'ProjectList', 'LookUpInit', 'PromptPasswords', 'GetBasePath', 'md5Setup', 'FormatDate',
|
'ProjectList', 'LookUpInit', 'PromptPasswords', 'GetBasePath', 'md5Setup', 'FormatDate',
|
||||||
'JobStatusToolTip', 'Wait'
|
'JobStatusToolTip', 'Wait'
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ angular.module('JobEventsListDefinition', [])
|
|||||||
event_display: {
|
event_display: {
|
||||||
label: 'Event',
|
label: 'Event',
|
||||||
hasChildren: true,
|
hasChildren: true,
|
||||||
ngClick: 'toggleChildren({{ jobevent.id }}, \'{{ jobevent.related.children }}\')',
|
ngClick: 'toggleChildren(jobevent.id, jobevent.related.children)',
|
||||||
nosort: true,
|
nosort: true,
|
||||||
searchable: false,
|
searchable: false,
|
||||||
ngClass: '{{ jobevent.class }}',
|
ngClass: '{{ jobevent.class }}',
|
||||||
@@ -101,7 +101,7 @@ angular.module('JobEventsListDefinition', [])
|
|||||||
|
|
||||||
view: {
|
view: {
|
||||||
label: 'View',
|
label: 'View',
|
||||||
ngClick: 'viewJobEvent({{ jobevent.id }})',
|
ngClick: 'viewJobEvent(jobevent.id)',
|
||||||
awToolTip: 'View event details',
|
awToolTip: 'View event details',
|
||||||
dataPlacement: 'top'
|
dataPlacement: 'top'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
angular.module('JobHostDefinition', [])
|
angular.module('JobHostDefinition', [])
|
||||||
.value(
|
.value('JobHostList', {
|
||||||
'JobHostList', {
|
|
||||||
|
|
||||||
name: 'jobhosts',
|
name: 'jobhosts',
|
||||||
iterator: 'jobhost',
|
iterator: 'jobhost',
|
||||||
@@ -23,50 +22,50 @@ angular.module('JobHostDefinition', [])
|
|||||||
label: 'Status',
|
label: 'Status',
|
||||||
icon: 'icon-zoom-in',
|
icon: 'icon-zoom-in',
|
||||||
ngShow: "job_id !== null"
|
ngShow: "job_id !== null"
|
||||||
},
|
},
|
||||||
events: {
|
events: {
|
||||||
href: "/#/jobs/{{ job_id }}/job_events",
|
href: "/#/jobs/{{ job_id }}/job_events",
|
||||||
label: 'Events',
|
label: 'Events',
|
||||||
icon: 'icon-list-ul'
|
icon: 'icon-list-ul'
|
||||||
},
|
},
|
||||||
hosts: {
|
hosts: {
|
||||||
href: "/#/jobs/{{ job_id }}/job_host_summaries",
|
href: "/#/jobs/{{ job_id }}/job_host_summaries",
|
||||||
label: 'Host Summary',
|
label: 'Host Summary',
|
||||||
active: true,
|
active: true,
|
||||||
icon: 'icon-laptop'
|
icon: 'icon-laptop'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
fields: {
|
fields: {
|
||||||
job: {
|
job: {
|
||||||
label: 'Job ID',
|
label: 'Job ID',
|
||||||
ngClick: "showJob(\{\{ jobhost.job \}\})",
|
ngClick: "showJob(jobhost.job)",
|
||||||
columnShow: 'host_id !== null',
|
columnShow: 'host_id !== null',
|
||||||
key: true,
|
key: true,
|
||||||
desc: true
|
desc: true
|
||||||
},
|
},
|
||||||
host: {
|
host: {
|
||||||
label: 'Host',
|
label: 'Host',
|
||||||
key: true,
|
key: true,
|
||||||
sourceModel: 'host',
|
sourceModel: 'host',
|
||||||
sourceField: 'name',
|
sourceField: 'name',
|
||||||
ngBind: 'jobhost.host_name',
|
ngBind: 'jobhost.host_name',
|
||||||
ngHref: "\{\{ jobhost.hostLinkTo \}\}"
|
ngHref: "jobhost.hostLinkTo"
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
label: 'Status',
|
label: 'Status',
|
||||||
badgeNgHref: "\{\{ jobhost.statusLinkTo \}\}",
|
badgeNgHref: "{{ jobhost.statusLinkTo }}",
|
||||||
badgeIcon: 'fa icon-job-\{\{ jobhost.status \}\}',
|
badgeIcon: 'fa icon-job-{{ jobhost.status }}',
|
||||||
badgePlacement: 'left',
|
badgePlacement: 'left',
|
||||||
badgeToolTip: "\{\{ jobhost.statusBadgeToolTip \}\}",
|
badgeToolTip: "{{ jobhost.statusBadgeToolTip }}",
|
||||||
badgeTipPlacement: 'top',
|
badgeTipPlacement: 'top',
|
||||||
ngHref: "\{\{ jobhost.statusLinkTo \}\}",
|
ngHref: "{{ jobhost.statusLinkTo }}",
|
||||||
awToolTip: "\{\{ jobhost.statusBadgeToolTip \}\}",
|
awToolTip: "{{ jobhost.statusBadgeToolTip }}",
|
||||||
dataPlacement: 'top',
|
dataPlacement: 'top',
|
||||||
searchField: 'failed',
|
searchField: 'failed',
|
||||||
searchType: 'boolean',
|
searchType: 'boolean',
|
||||||
searchOptions: [{ name: "success", value: 0 }, { name: "error", value: 1 }]
|
searchOptions: [{ name: "success", value: 0 }, { name: "error", value: 1 }]
|
||||||
},
|
},
|
||||||
failed: {
|
failed: {
|
||||||
label: 'Job failed?',
|
label: 'Job failed?',
|
||||||
searchSingleValue: true,
|
searchSingleValue: true,
|
||||||
@@ -74,32 +73,32 @@ angular.module('JobHostDefinition', [])
|
|||||||
searchValue: 'true',
|
searchValue: 'true',
|
||||||
searchOnly: true,
|
searchOnly: true,
|
||||||
nosort: true
|
nosort: true
|
||||||
},
|
},
|
||||||
ok: {
|
ok: {
|
||||||
label: 'Success',
|
label: 'Success',
|
||||||
searchable: false
|
searchable: false
|
||||||
},
|
},
|
||||||
changed: {
|
changed: {
|
||||||
label: 'Changed',
|
label: 'Changed',
|
||||||
searchable: false
|
searchable: false
|
||||||
},
|
},
|
||||||
failures: {
|
failures: {
|
||||||
label: 'Failure',
|
label: 'Failure',
|
||||||
searchable: true,
|
searchable: true,
|
||||||
searchLabel: 'Contains failed events?',
|
searchLabel: 'Contains failed events?',
|
||||||
searchType: 'gtzero'
|
searchType: 'gtzero'
|
||||||
},
|
},
|
||||||
dark: {
|
dark: {
|
||||||
label: 'Unreachable',
|
label: 'Unreachable',
|
||||||
searchable: true,
|
searchable: true,
|
||||||
searchType: 'gtzero',
|
searchType: 'gtzero',
|
||||||
searchLabel: 'Contains unreachable hosts?'
|
searchLabel: 'Contains unreachable hosts?'
|
||||||
},
|
},
|
||||||
skipped: {
|
skipped: {
|
||||||
label: 'Skipped',
|
label: 'Skipped',
|
||||||
searchable: false
|
searchable: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
help: {
|
help: {
|
||||||
@@ -116,17 +115,16 @@ angular.module('JobHostDefinition', [])
|
|||||||
awToolTip: 'Click for help',
|
awToolTip: 'Click for help',
|
||||||
dataTitle: 'Job Host Summary',
|
dataTitle: 'Job Host Summary',
|
||||||
id: 'jobhost-help-button'
|
id: 'jobhost-help-button'
|
||||||
},
|
},
|
||||||
refresh: {
|
refresh: {
|
||||||
mode: 'all',
|
mode: 'all',
|
||||||
'class': 'btn-xs',
|
'class': 'btn-xs',
|
||||||
awToolTip: "Refresh the page",
|
awToolTip: "Refresh the page",
|
||||||
ngClick: "refresh()",
|
ngClick: "refresh()",
|
||||||
ngShow: "host_id == null" //don't show when viewing from inventory->hosts
|
ngShow: "host_id == null" //don't show when viewing from inventory->hosts
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
fieldActions: {
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
});
|
fieldActions: {}
|
||||||
|
|
||||||
|
});
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
angular.module('JobsListDefinition', [])
|
angular.module('JobsListDefinition', [])
|
||||||
.value(
|
.value( 'JobList', {
|
||||||
'JobList', {
|
|
||||||
|
|
||||||
name: 'jobs',
|
name: 'jobs',
|
||||||
iterator: 'job',
|
iterator: 'job',
|
||||||
@@ -22,26 +21,26 @@ angular.module('JobsListDefinition', [])
|
|||||||
label: 'Job ID',
|
label: 'Job ID',
|
||||||
key: true,
|
key: true,
|
||||||
desc: true,
|
desc: true,
|
||||||
searchType: 'int'
|
searchType: 'int'
|
||||||
},
|
},
|
||||||
inventory: {
|
inventory: {
|
||||||
label: 'Inventory ID',
|
label: 'Inventory ID',
|
||||||
searchType: 'int',
|
searchType: 'int',
|
||||||
searchOnly: true
|
searchOnly: true
|
||||||
},
|
},
|
||||||
created: {
|
created: {
|
||||||
label: 'Create On',
|
label: 'Create On',
|
||||||
link: false,
|
link: false,
|
||||||
searchable: false
|
searchable: false
|
||||||
},
|
},
|
||||||
job_template: {
|
job_template: {
|
||||||
label: 'Job Template',
|
label: 'Job Template',
|
||||||
ngBind: 'job.summary_fields.job_template.name',
|
ngBind: 'job.summary_fields.job_template.name',
|
||||||
//ngHref: "\{\{ '/#/job_templates/?name=' + job.summary_fields.job_template.name \}\}",
|
//ngHref: "{{ '/#/job_templates/?name=' + job.summary_fields.job_template.name }}",
|
||||||
ngHref:"\{\{ '/#/job_templates/' + job.job_template \}\}",
|
ngHref:"{{ '/#/job_templates/' + job.job_template }}",
|
||||||
sourceModel: 'job_template',
|
sourceModel: 'job_template',
|
||||||
sourceField: 'name'
|
sourceField: 'name'
|
||||||
},
|
},
|
||||||
failed: {
|
failed: {
|
||||||
label: 'Job failed?',
|
label: 'Job failed?',
|
||||||
searchSingleValue: true,
|
searchSingleValue: true,
|
||||||
@@ -49,76 +48,77 @@ angular.module('JobsListDefinition', [])
|
|||||||
searchValue: 'true',
|
searchValue: 'true',
|
||||||
searchOnly: true,
|
searchOnly: true,
|
||||||
nosort: true
|
nosort: true
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
label: 'Status',
|
label: 'Status',
|
||||||
"class": 'job-\{\{ job.status \}\}',
|
"class": 'job-{{ job.status }}',
|
||||||
searchType: 'select',
|
searchType: 'select',
|
||||||
linkTo: "\{\{ job.statusLinkTo \}\}",
|
linkTo: "{{ job.statusLinkTo }}",
|
||||||
searchOptions: [
|
searchOptions: [
|
||||||
{ name: "new", value: "new" },
|
{ name: "new", value: "new" },
|
||||||
{ name: "waiting", value: "waiting" },
|
{ name: "waiting", value: "waiting" },
|
||||||
{ name: "pending", value: "pending" },
|
{ name: "pending", value: "pending" },
|
||||||
{ name: "running", value: "running" },
|
{ name: "running", value: "running" },
|
||||||
{ name: "successful", value: "successful" },
|
{ name: "successful", value: "successful" },
|
||||||
{ name: "error", value: "error" },
|
{ name: "error", value: "error" },
|
||||||
{ name: "failed", value: "failed" },
|
{ name: "failed", value: "failed" },
|
||||||
{ name: "canceled", value: "canceled" } ],
|
{ name: "canceled", value: "canceled" }
|
||||||
badgeIcon: 'fa icon-job-\{\{ job.status \}\}',
|
],
|
||||||
|
badgeIcon: 'fa icon-job-{{ job.status }}',
|
||||||
badgePlacement: 'left',
|
badgePlacement: 'left',
|
||||||
badgeToolTip: "\{\{ job.statusBadgeToolTip \}\}",
|
badgeToolTip: "{{ job.statusBadgeToolTip }}",
|
||||||
badgeTipPlacement: 'top',
|
badgeTipPlacement: 'top',
|
||||||
badgeNgHref: "\{\{ job.statusLinkTo \}\}",
|
badgeNgHref: "{{ job.statusLinkTo }}",
|
||||||
awToolTip: "\{\{ job.statusBadgeToolTip \}\}",
|
awToolTip: "{{ job.statusBadgeToolTip }}",
|
||||||
dataPlacement: 'top'
|
dataPlacement: 'top'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
refresh: {
|
refresh: {
|
||||||
mode: 'all',
|
mode: 'all',
|
||||||
awToolTip: "Refresh the page",
|
awToolTip: "Refresh the page",
|
||||||
ngClick: "refresh()"
|
ngClick: "refresh()"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
fieldActions: {
|
fieldActions: {
|
||||||
submit: {
|
submit: {
|
||||||
label: 'Relaunch',
|
label: 'Relaunch',
|
||||||
icon: 'icon-rocket',
|
icon: 'icon-rocket',
|
||||||
mode: 'all',
|
mode: 'all',
|
||||||
ngClick: "submitJob(\{\{ job.id \}\}, '\{\{ job.summary_fields.job_template.name \}\}' )",
|
ngClick: 'submitJob(job.id, job.summary_fields.job_template.name)',
|
||||||
awToolTip: 'Start the job',
|
awToolTip: 'Start the job',
|
||||||
dataPlacement: 'top'
|
dataPlacement: 'top'
|
||||||
},
|
},
|
||||||
cancel: {
|
cancel: {
|
||||||
label: 'Stop',
|
label: 'Stop',
|
||||||
mode: 'all',
|
mode: 'all',
|
||||||
ngClick: 'deleteJob(\{\{ job.id \}\})',
|
ngClick: 'deleteJob(job.id)',
|
||||||
awToolTip: 'Cancel a running or pending job',
|
awToolTip: 'Cancel a running or pending job',
|
||||||
ngShow: "job.status == 'pending' || job.status == 'running' || job.status == 'waiting'",
|
ngShow: "job.status == 'pending' || job.status == 'running' || job.status == 'waiting'",
|
||||||
dataPlacement: 'top'
|
dataPlacement: 'top'
|
||||||
},
|
},
|
||||||
"delete": {
|
"delete": {
|
||||||
label: 'Delete',
|
label: 'Delete',
|
||||||
mode: 'all',
|
mode: 'all',
|
||||||
ngClick: 'deleteJob(\{\{ job.id \}\})',
|
ngClick: 'deleteJob(job.id)',
|
||||||
awToolTip: 'Delete the job',
|
awToolTip: 'Delete the job',
|
||||||
ngShow: "job.status != 'pending' && job.status != 'running' && job.status != 'waiting'",
|
ngShow: "job.status != 'pending' && job.status != 'running' && job.status != 'waiting'",
|
||||||
dataPlacement: 'top'
|
dataPlacement: 'top'
|
||||||
},
|
},
|
||||||
dropdown: {
|
dropdown: {
|
||||||
type: 'DropDown',
|
type: 'DropDown',
|
||||||
label: 'View',
|
label: 'View',
|
||||||
icon: 'fa-search-plus',
|
icon: 'fa-search-plus',
|
||||||
'class': 'btn-default btn-xs',
|
'class': 'btn-default btn-xs',
|
||||||
options: [
|
options: [
|
||||||
{ ngClick: "editJob(\{\{ job.id \}\}, '\{\{ job.summary_fields.job_template.name \}\}')", label: 'Status' },
|
{ ngClick: 'editJob(job.id, job.summary_fields.job_template.name)', label: 'Status' },
|
||||||
{ ngClick: "viewEvents(\{{ job.id \}\}, '\{\{ job.summary_fields.job_template.name \}\}')", label: 'Events',
|
{ ngClick: 'viewEvents(job.id, job.summary_fields.job_template.name)', label: 'Events',
|
||||||
ngHide: "job.status == 'new'" },
|
ngHide: "job.status == 'new'" },
|
||||||
{ ngClick: "viewSummary(\{{ job.id \}\}, '\{\{ job.summary_fields.job_template.name \}\}')", label: 'Host Summary',
|
{ ngClick: 'viewSummary(job.id, job.summary_fields.job_template.name)', label: 'Host Summary',
|
||||||
ngHide: "job.status == 'new'" }
|
ngHide: "job.status == 'new'" }
|
||||||
]
|
]
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -9,51 +9,49 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('ApiLoader', ['ngCookies'])
|
angular.module('ApiLoader', ['Utilities'])
|
||||||
.factory('LoadBasePaths', ['$http', '$rootScope', '$cookieStore', 'ProcessErrors',
|
|
||||||
function($http, $rootScope, $cookieStore, ProcessErrors) {
|
.factory('LoadBasePaths', ['$http', '$rootScope', 'Store', 'ProcessErrors',
|
||||||
return function() {
|
function($http, $rootScope, Store, ProcessErrors) {
|
||||||
$http.get('/api/')
|
return function() {
|
||||||
.success( function(data, status, headers, config) {
|
$http.get('/api/')
|
||||||
var base = data.current_version;
|
.success( function(data) {
|
||||||
$http.get(base)
|
var base = data.current_version;
|
||||||
.success( function(data, status, headers, config) {
|
$http.get(base)
|
||||||
data['base'] = base;
|
.success( function(data) {
|
||||||
$rootScope['defaultUrls'] = data;
|
data.base = base;
|
||||||
$cookieStore.remove('api');
|
$rootScope.defaultUrls = data;
|
||||||
$cookieStore.put('api',data); //Preserve in cookie to prevent against
|
Store('api', data);
|
||||||
//loss during browser refresh
|
})
|
||||||
})
|
.error ( function(data, status) {
|
||||||
.error ( function(data, status, headers, config) {
|
$rootScope.defaultUrls = { status: 'error' };
|
||||||
$rootScope['defaultUrls'] = { status: 'error' };
|
ProcessErrors(null, data, status, null,
|
||||||
ProcessErrors(null, data, status, null,
|
{ hdr: 'Error', msg: 'Failed to read ' + base + '. GET status: ' + status });
|
||||||
{ hdr: 'Error', msg: 'Failed to read ' + base + '. GET status: ' + status });
|
});
|
||||||
});
|
})
|
||||||
})
|
.error( function(data, status) {
|
||||||
.error( function(data, status, headers, config) {
|
$rootScope.defaultUrls = { status: 'error' };
|
||||||
$rootScope['defaultUrls'] = { status: 'error' };
|
ProcessErrors(null, data, status, null,
|
||||||
ProcessErrors(null, data, status, null,
|
{ hdr: 'Error', msg: 'Failed to read /api. GET status: ' + status });
|
||||||
{ hdr: 'Error', msg: 'Failed to read /api. GET status: ' + status });
|
});
|
||||||
});
|
};
|
||||||
}
|
}])
|
||||||
}])
|
|
||||||
|
.factory('GetBasePath', ['$rootScope', 'Store', 'LoadBasePaths', 'Empty',
|
||||||
|
function($rootScope, Store, LoadBasePaths, Empty) {
|
||||||
|
return function(set) {
|
||||||
|
// use /api/v1/ results to construct API URLs.
|
||||||
|
if (Empty($rootScope.defaultUrls)) {
|
||||||
|
// browser refresh must have occurred. load from local storage
|
||||||
|
if (Store('api')) {
|
||||||
|
$rootScope.defaultUrls = Store('api');
|
||||||
|
return $rootScope.defaultUrls[set];
|
||||||
|
}
|
||||||
|
return ''; //we should never get here
|
||||||
|
}
|
||||||
|
return $rootScope.defaultUrls[set];
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
|
||||||
.factory('GetBasePath', ['$rootScope', '$cookieStore', 'LoadBasePaths',
|
|
||||||
function($rootScope, $cookieStore, LoadBasePaths) {
|
|
||||||
return function(set) {
|
|
||||||
// use /api/v1/ results to construct API URLs.
|
|
||||||
var answer;
|
|
||||||
if ($rootScope['defaultUrls'] == null || $rootScope['defaultUrls'] == undefined) {
|
|
||||||
// browser refresh must have occurred. use what's in session cookie and refresh
|
|
||||||
answer = $cookieStore.get('api')[set];
|
|
||||||
LoadBasePaths();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
answer = $rootScope['defaultUrls'][set];
|
|
||||||
}
|
|
||||||
return answer;
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -12,14 +12,15 @@ angular.module('AWFilters', [])
|
|||||||
// capitalize -capitalize the first letter of each word
|
// capitalize -capitalize the first letter of each word
|
||||||
//
|
//
|
||||||
.filter('capitalize', [ function() {
|
.filter('capitalize', [ function() {
|
||||||
return function(input) {
|
return function(input) {
|
||||||
if (input) {
|
var values, result, i;
|
||||||
var values = input.replace(/\_/g,' ').split(" ");
|
if (input) {
|
||||||
var result = "";
|
values = input.replace(/\_/g,' ').split(" ");
|
||||||
for (var i = 0; i < values.length; i++){
|
result = "";
|
||||||
result += values[i].charAt(0).toUpperCase() + values[i].substr(1) + ' ';
|
for (i = 0; i < values.length; i++){
|
||||||
|
result += values[i].charAt(0).toUpperCase() + values[i].substr(1) + ' ';
|
||||||
|
}
|
||||||
|
return result.trim();
|
||||||
}
|
}
|
||||||
return result.trim();
|
};
|
||||||
}
|
}]);
|
||||||
}
|
|
||||||
}]);
|
|
||||||
Reference in New Issue
Block a user