From 66f93364b12d53dd75c3f48f4d516b079fba86d2 Mon Sep 17 00:00:00 2001 From: chouseknecht Date: Fri, 17 May 2013 00:17:11 -0400 Subject: [PATCH] No longer create\/execute job when template is saved. Execute job from list view by clicking 'play' button. Prompts for missing credential and all required password. --- lib/ui/static/js/controllers/JobTemplates.js | 118 +++++++++++++------ lib/ui/static/js/helpers/JobTemplate.js | 25 ++++ lib/ui/static/js/helpers/Lookup.js | 11 +- lib/ui/static/js/lists/JobTemplates.js | 8 +- 4 files changed, 121 insertions(+), 41 deletions(-) diff --git a/lib/ui/static/js/controllers/JobTemplates.js b/lib/ui/static/js/controllers/JobTemplates.js index 272e9b3964..0b13b71feb 100644 --- a/lib/ui/static/js/controllers/JobTemplates.js +++ b/lib/ui/static/js/controllers/JobTemplates.js @@ -12,7 +12,8 @@ function JobTemplatesList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, JobTemplateList, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, - ClearScope, ProcessErrors, GetBasePath) + ClearScope, ProcessErrors, GetBasePath, PromptPasswords, JobTemplateForm, CredentialList, + LookUpInit) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -20,8 +21,8 @@ function JobTemplatesList ($scope, $rootScope, $location, $log, $routeParams, Re var defaultUrl = GetBasePath('job_templates'); var view = GenerateList; var base = $location.path().replace(/^\//,'').split('/')[0]; - var mode = (base == 'job_templates') ? 'edit' : 'select'; // if base path 'credentials', we're here to add/edit - var scope = view.inject(list, { mode: mode }); // Inject our view + var mode = (base == 'job_templates') ? 'edit' : 'select'; + var scope = view.inject(list, { mode: mode }); scope.selected = []; SearchInit({ scope: scope, set: 'job_templates', list: list, url: defaultUrl }); @@ -39,7 +40,6 @@ function JobTemplatesList ($scope, $rootScope, $location, $log, $routeParams, Re } scope.deleteJobTemplate = function(id, name) { - var action = function() { var url = defaultUrl + id + '/'; Rest.setUrl(url); @@ -124,15 +124,87 @@ function JobTemplatesList ($scope, $rootScope, $location, $log, $routeParams, Re scope.selected.push(idx); } } + + function postJob(data) { + // Once we have a credential and all required passwords, use this + // to create and start a job + var dt = new Date().toISOString(); + Rest.setUrl(data.related.jobs); + Rest.post({ + name: data.name + ' ' + dt, // job name required and unique + description: data.description, + job_template: data.id, + inventory: data.inventory, + project: data.project, + playbook: data.playbook, + credential: data.credential, + forks: data.forks, + limit: data.limit, + verbosity: data.verbosity, + extra_vars: data.extra_vars + }) + .success( function(data, status, headers, config) { + // Prompt for passwords and start the job + PromptPasswords({ + scope: scope, + passwords: data.passwords_needed_to_start, + start_url: data.related.start + }); + }) + .error( function(data, status, headers, config) { + ProcessErrors(scope, data, status, null, + { hdr: 'Error!', msg: 'Failed to create job. POST returned status: ' + status }); + }); + }; + + scope.submitJob = function(id) { + // Get the job details + Rest.setUrl(defaultUrl + id + '/'); + Rest.get() + .success( function(data, status, headers, config) { + // Create a job record + if (data.credential == '' || data.credential == null) { + // Template does not have credential, prompt for one + scope.$watch('credential', function(newVal, oldVal) { + if (newVal !== oldVal) { + console.log('credential is: ' + scope.credential); + // After user selects a credential from the modal, + // submit the job + data.credential = scope.credential; + postJob(data); + } + }); + LookUpInit({ + scope: scope, + form: JobTemplateForm, + current_item: null, + list: CredentialList, + field: 'credential', + hdr: 'Credential Required' + }); + scope.lookUpCredential(); + } + else { + // We have what we need, submit the job + postJob(data); + } + }) + .error( function(data, status, headers, config) { + ProcessErrors(scope, data, status, null, + { hdr: 'Error!', msg: 'Failed to get job template details. GET returned status: ' + status }); + }); + }; + } JobTemplatesList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'JobTemplateList', 'GenerateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', - 'ProcessErrors','GetBasePath' ]; + 'ProcessErrors','GetBasePath', 'PromptPasswords', 'JobTemplateForm', 'CredentialList', 'LookUpInit' + ]; function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, - GetBasePath, InventoryList, CredentialList, ProjectList, LookUpInit, PromptPasswords) + GetBasePath, InventoryList, CredentialList, ProjectList, LookUpInit) { ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior //scope. @@ -211,37 +283,11 @@ function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeP else { data[fld] = scope[fld]; } - } + } Rest.post(data) .success( function(data, status, headers, config) { - // Template saved. Now create a new job - Rest.setUrl(data.related.jobs); - Rest.post({ - name: data.name, - description: data.description, - job_template: data.job_template, - job_type: data.job_type, - inventory: data.inventory, - project: data.project, - playbook: data.playbook, - credential: data.credential, - forks: data.forks, - limit: data.limit, - verbosity: data.verbosity, - extra_vars: data.extra_vars}) - .success( function(data, status, headers, config) { - console.log('Job posted!'); - console.log(data); - PromptPasswords({ - scope: scope, - passwords: data.passwords_needed_to_start, - start_url: data.related.start - }); - }) - .error( function(data, status, headers, config) { - ProcessErrors(scope, data, status, form, - { hdr: 'Error!', msg: 'Failed to post job. POST returned status: ' + status }); - }); + var base = $location.path().replace(/^\//,'').split('/')[0]; + (base == 'job_templates') ? ReturnToCaller() : ReturnToCaller(1); }) .error( function(data, status, headers, config) { ProcessErrors(scope, data, status, form, @@ -259,7 +305,7 @@ function JobTemplatesAdd ($scope, $rootScope, $compile, $location, $log, $routeP JobTemplatesAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'JobTemplateForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', - 'GetBasePath', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit', 'PromptPasswords' ]; + 'GetBasePath', 'InventoryList', 'CredentialList', 'ProjectList', 'LookUpInit' ]; function JobTemplatesEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, JobTemplateForm, diff --git a/lib/ui/static/js/helpers/JobTemplate.js b/lib/ui/static/js/helpers/JobTemplate.js index 3444c12c20..0c8c05aa30 100644 --- a/lib/ui/static/js/helpers/JobTemplate.js +++ b/lib/ui/static/js/helpers/JobTemplate.js @@ -82,3 +82,28 @@ angular.module('JobTemplateHelper', [ 'RestServices', 'Utilities', 'CredentialFo $('#password-modal').modal(); } }]); + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/ui/static/js/helpers/Lookup.js b/lib/ui/static/js/helpers/Lookup.js index 2b04138324..4ab1600b5e 100644 --- a/lib/ui/static/js/helpers/Lookup.js +++ b/lib/ui/static/js/helpers/Lookup.js @@ -9,7 +9,8 @@ * form:
, * current_item: , * list: , - * field: + * field: , + * hdr: * }) */ @@ -25,18 +26,20 @@ angular.module('LookUpHelper', [ 'RestServices', 'Utilities', 'SearchHelper', 'P var list = params.list; // list object var field = params.field; // form field var postAction = params.postAction //action to perform post user selection + // Show pop-up to select user var name = list.iterator.charAt(0).toUpperCase() + list.iterator.substring(1); var defaultUrl = (list.name == 'inventories') ? GetBasePath('inventory') : GetBasePath(list.name); - + var hdr = (params.hdr) ? params.hdr : 'Select ' + name; + $('input[name="' + form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '"]').attr('data-url',defaultUrl + '?' + form.fields[field].sourceField + '__' + 'iexact=:value'); $('input[name="' + form.fields[field].sourceModel + '_' + form.fields[field].sourceField + '"]').attr('data-source',field); scope['lookUp' + name] = function() { var listGenerator = GenerateList; - var listScope = listGenerator.inject(list, { mode: 'lookup', hdr: 'Select ' + name }); + var listScope = listGenerator.inject(list, { mode: 'lookup', hdr: hdr }); listScope.selectAction = function() { var found = false; var name; @@ -44,7 +47,7 @@ angular.module('LookUpHelper', [ 'RestServices', 'Utilities', 'SearchHelper', 'P if (listScope[list.iterator + "_" + listScope[list.name][i].id + "_class"] == "success") { found = true; scope[field] = listScope[list.name][i].id; - if (form.fields[field] && form.fields[field].sourceModel) { + if (scope[form.name + '_form'] && form.fields[field] && form.fields[field].sourceModel) { scope[form.fields[field].sourceModel + '_' + form.fields[field].sourceField] = listScope[list.name][i][form.fields[field].sourceField]; scope[form.name + '_form'][form.fields[field].sourceModel + '_' + form.fields[field].sourceField] diff --git a/lib/ui/static/js/lists/JobTemplates.js b/lib/ui/static/js/lists/JobTemplates.js index f1f451c1b4..70c50c612d 100644 --- a/lib/ui/static/js/lists/JobTemplates.js +++ b/lib/ui/static/js/lists/JobTemplates.js @@ -38,12 +38,18 @@ angular.module('JobTemplatesListDefinition', []) }, fieldActions: { + submit: { + icon: 'icon-play', + mode: 'all', + ngClick: 'submitJob(\{\{ job_template.id \}\})', + class: 'btn btn-mini', + awToolTip: 'Create and run a job using this template' + }, edit: { ngClick: "editJobTemplate(\{\{ job_template.id \}\})", icon: 'icon-edit', awToolTip: 'Edit template' }, - delete: { ngClick: "deleteJobTemplate(\{\{ job_template.id \}\},'\{\{ job_template.name \}\}')", icon: 'icon-remove',