From c7d489026ed3d286034bc9238b6888d0618ca087 Mon Sep 17 00:00:00 2001 From: Chris Houseknecht Date: Sun, 6 Apr 2014 03:51:17 -0400 Subject: [PATCH] AC-1083 more better handling of missing machine credentials when submitting a job. --- awx/ui/static/js/controllers/Credentials.js | 3 +- awx/ui/static/js/controllers/Organizations.js | 2 +- awx/ui/static/js/helpers/JobSubmission.js | 85 ++++++++++++++----- awx/ui/static/less/ansible-ui.less | 4 +- awx/ui/static/lib/ansible/Utilities.js | 6 +- awx/ui/static/lib/ansible/list-generator.js | 2 +- awx/ui/static/lib/ansible/prompt-dialog.js | 9 +- 7 files changed, 77 insertions(+), 34 deletions(-) diff --git a/awx/ui/static/js/controllers/Credentials.js b/awx/ui/static/js/controllers/Credentials.js index 075d770730..b164b82f29 100644 --- a/awx/ui/static/js/controllers/Credentials.js +++ b/awx/ui/static/js/controllers/Credentials.js @@ -101,7 +101,6 @@ function CredentialsList($scope, $rootScope, $location, $log, $routeParams, Rest }; $scope.deleteCredential = function (id, name) { - var action = function () { $('#prompt-modal').on('hidden.bs.modal', function () { Wait('start'); @@ -121,7 +120,7 @@ function CredentialsList($scope, $rootScope, $location, $log, $routeParams, Rest Prompt({ hdr: 'Delete', - body: 'Are you sure you want to delete ' + name + '?', + body: "
Delete credential " + name + "?
", action: action }); }; diff --git a/awx/ui/static/js/controllers/Organizations.js b/awx/ui/static/js/controllers/Organizations.js index 88122b212b..976d9ce72b 100644 --- a/awx/ui/static/js/controllers/Organizations.js +++ b/awx/ui/static/js/controllers/Organizations.js @@ -87,7 +87,7 @@ function OrganizationsList($routeParams, $scope, $rootScope, $location, $log, Re Prompt({ hdr: 'Delete', - body: 'Are you sure you want to delete ' + name + '?', + body: "
Delete organization " + name + "?
", action: action }); }; diff --git a/awx/ui/static/js/helpers/JobSubmission.js b/awx/ui/static/js/helpers/JobSubmission.js index 0a9b88d4a7..95ed9f1b4d 100644 --- a/awx/ui/static/js/helpers/JobSubmission.js +++ b/awx/ui/static/js/helpers/JobSubmission.js @@ -30,8 +30,8 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential }; }]) -.factory('PromptForCredential', ['Wait', 'GetBasePath', 'LookUpInit', 'JobTemplateForm', 'CredentialList', -function(Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialList) { +.factory('PromptForCredential', ['$location', 'Wait', 'GetBasePath', 'LookUpInit', 'JobTemplateForm', 'CredentialList', 'Rest', 'Prompt', 'ProcessErrors', +function($location, Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialList, Rest, Prompt, ProcessErrors) { return function(params) { var scope = params.scope, @@ -41,22 +41,59 @@ function(Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialList) { Wait('stop'); scope.credential = ''; - selectionMade = function () { - scope.$emit(callback, scope.credential); - }; - - LookUpInit({ - url: GetBasePath('credentials') + '?kind=ssh', - scope: scope, - form: JobTemplateForm(), - current_item: null, - list: CredentialList, - field: 'credential', - hdr: 'Credential Required', - instructions: "Launching this job requires a machine credential. Please select your machine credential now or Cancel to quit.", - postAction: selectionMade + if (scope.removeShowLookupDialog) { + scope.removeShowLookupDialog(); + } + scope.removeShowLookupDialog = scope.$on('ShowLookupDialog', function() { + selectionMade = function () { + scope.$emit(callback, scope.credential); + }; + + LookUpInit({ + url: GetBasePath('credentials') + '?kind=ssh', + scope: scope, + form: JobTemplateForm(), + current_item: null, + list: CredentialList, + field: 'credential', + hdr: 'Credential Required', + instructions: "Launching this job requires a machine credential. Please select your machine credential now or Cancel to quit.", + postAction: selectionMade + }); + scope.lookUpCredential(); }); - scope.lookUpCredential(); + + if (scope.removeAlertNoCredentials) { + scope.removeAlertNoCredentials(); + } + scope.removeAlertNoCredentials = scope.$on('AlertNoCredentials', function() { + var action = function () { + $('#prompt-modal').modal('hide'); + $location.url('/credentials/add'); + }; + + Prompt({ + hdr: 'Machine Credential Required', + body: "
There are no machine credentials defined in Tower. Launching this job requires a machine credential. " + + "Create one now?", + action: action + }); + }); + + Rest.setUrl(GetBasePath('credentials') + '?kind=ssh'); + Rest.get() + .success(function(data) { + if (data.results.length > 0) { + scope.$emit('ShowLookupDialog'); + } + else { + scope.$emit('AlertNoCredentials'); + } + }) + .error(function(data,status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Checking for machine credentials failed. GET returned: ' + status }); + }); }; }]) @@ -76,10 +113,11 @@ function(Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialList) { function promptPassword() { var e, fld, field; - + console.log(passwords); password = passwords.pop(); // Prompt for password + html = ""; html += "
\n"; field = form.fields[password]; fld = password; @@ -123,7 +161,7 @@ function(Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialList) { html += "
\n"; } html += "\n"; - $('#password-body').empty().html(html); + $('#password-body').html(html); e = angular.element(document.getElementById('password-modal')); $compile(e)(scope); $('#password-modal').modal(); @@ -134,9 +172,13 @@ function(Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialList) { scope.passwordAccept = function() { $('#password-modal').modal('hide'); + $('#password-modal').off('shown.bs.modal'); + $('#password-body').empty(); acceptedPasswords[password] = scope[password]; if (passwords.length > 0) { - promptPassword(); + setTimeout(function() { + promptPassword(); + }, 500); } else { parent_scope.$emit(callback, acceptedPasswords); @@ -146,11 +188,12 @@ function(Wait, GetBasePath, LookUpInit, JobTemplateForm, CredentialList) { scope.passwordCancel = function() { $('#password-modal').modal('hide'); + $('#password-modal').off('shown.bs.modal'); + $('#password-body').empty(); Alert('Missing Password', 'Required password(s) not provided. Your request will not be submitted.', 'alert-info'); parent_scope.$emit('PasswordsCanceled'); scope.$destroy(); }; - promptPassword(); }; }]) diff --git a/awx/ui/static/less/ansible-ui.less b/awx/ui/static/less/ansible-ui.less index 6a8974851f..00dbdd9d21 100644 --- a/awx/ui/static/less/ansible-ui.less +++ b/awx/ui/static/less/ansible-ui.less @@ -856,12 +856,12 @@ input[type="checkbox"].checkbox-no-label { .list-actions { margin: 0; } - .list-wrapper { + /*.list-wrapper { background-color: @well; padding: 10px; border-radius: 4px; border: 1px solid @well-border; - } + }*/ .ui-accordion-content { padding-left: 15px; padding-right: 15px; diff --git a/awx/ui/static/lib/ansible/Utilities.js b/awx/ui/static/lib/ansible/Utilities.js index 324f40afed..551ca686d8 100644 --- a/awx/ui/static/lib/ansible/Utilities.js +++ b/awx/ui/static/lib/ansible/Utilities.js @@ -75,14 +75,14 @@ angular.module('Utilities', ['RestServices', 'Utilities']) * alert-info...). Pass an optional function(){}, if you want a specific action to occur when user * clicks 'OK' button. Set secondAlert to true, when a second dialog is needed. */ -.factory('Alert', ['$rootScope', '$compile', function ($rootScope, $compile) { +.factory('Alert', ['$rootScope', '$compile', '$sce', function ($rootScope, $compile, $sce) { return function (hdr, msg, cls, action, secondAlert, disableButtons) { var scope = $rootScope.$new(), alertClass, e; if (secondAlert) { e = angular.element(document.getElementById('alert-modal2')); $compile(e)(scope); scope.alertHeader2 = hdr; - scope.alertBody2 = msg; + scope.alertBody2 = $sce.trustAsHtml(msg); alertClass = (cls) ? cls : 'alert-danger'; //default alert class is alert-danger $('#alert2-modal-msg').attr({ "class": "alert " + alertClass }); $('#alert-modal2').modal({ @@ -106,7 +106,7 @@ angular.module('Utilities', ['RestServices', 'Utilities']) e = angular.element(document.getElementById('alert-modal')); $compile(e)(scope); scope.alertHeader = hdr; - scope.alertBody = msg; + scope.alertBody = $sce.trustAsHtml(msg); alertClass = (cls) ? cls : 'alert-danger'; //default alert class is alert-danger $('#alert-modal-msg').attr({ "class": "alert " + alertClass }); $('#alert-modal').modal({ diff --git a/awx/ui/static/lib/ansible/list-generator.js b/awx/ui/static/lib/ansible/list-generator.js index e4a9e6e982..588cffa3f3 100644 --- a/awx/ui/static/lib/ansible/list-generator.js +++ b/awx/ui/static/lib/ansible/list-generator.js @@ -282,7 +282,7 @@ angular.module('ListGenerator', ['GeneratorHelpers']) // table header row html += "
\n"; html += "