Files
awx/awx/ui/client/src/adhoc/adhoc.controller.js
2015-09-09 13:08:16 -04:00

318 lines
11 KiB
JavaScript

/*************************************************
* Copyright (c) 2015 Ansible, Inc.
*
* All Rights Reserved
*************************************************/
/**
* @ngdoc function
* @name controllers.function:Adhoc
* @description This controller controls the adhoc form creation, command launching and navigating to standard out after command has been succesfully ran.
*/
function adhocController($q, $scope, $rootScope, $location, $routeParams,
CheckPasswords, PromptForPasswords, CreateLaunchDialog, adhocForm,
GenerateForm, Rest, ProcessErrors, ClearScope, GetBasePath, GetChoices,
KindChange, LookUpInit, CredentialList, Empty, Wait) {
ClearScope();
// this is done so that we can access private functions for testing, but
// we don't want to populate the "public" scope with these internal
// functions
var privateFn = {};
this.privateFn = privateFn;
// note: put any urls that the controller will use in here!!!!
privateFn.setAvailableUrls = function() {
return {
adhocUrl: GetBasePath('inventory') + id + '/ad_hoc_commands/',
inventoryUrl: GetBasePath('inventory') + id + '/',
machineCredentialUrl: GetBasePath('credentials') + '?kind=ssh'
};
};
var id = $routeParams.inventory_id,
urls = privateFn.setAvailableUrls(),
hostPattern = $rootScope.hostPatterns || "all";
// set the default options for the selects of the adhoc form
privateFn.setFieldDefaults = function(verbosity_options, forks_default) {
var verbosity;
for (verbosity in verbosity_options) {
if (verbosity_options[verbosity].isDefault) {
$scope.verbosity = verbosity_options[verbosity];
}
}
$("#forks-number").spinner("value", forks_default);
$scope.forks = forks_default;
};
// set when "working" starts and stops
privateFn.setLoadingStartStop = function() {
var asyncHelper = {},
formReadyPromise = 0;
Wait('start');
if (asyncHelper.removeChoicesReady) {
asyncHelper.removeChoicesReady();
}
asyncHelper.removeChoicesReady = $scope.$on('adhocFormReady',
isFormDone);
// check to see if all requests have completed
function isFormDone() {
formReadyPromise++;
if (formReadyPromise === 2) {
privateFn.setFieldDefaults($scope.adhoc_verbosity_options,
$scope.forks_field.default);
Wait('stop');
}
}
};
privateFn.getInventoryNameForBreadcrumbs = function(url) {
Rest.setUrl(url);
var promise = Rest.get();
promise.then(function (response) {
$scope.inv_name = response.data.name;
});
promise.catch(function (response) {
ProcessErrors($rootScope, response.data, response.status, null, {
hdr: 'Error!',
msg: 'Failed to get inventory name. GET returned status: ' +
response.status });
$location.path("/inventories/");
});
return promise;
};
// set the arguments help to watch on change of the module
privateFn.instantiateArgumentHelp = function() {
$scope.$watch('module_name', function(val) {
if (val) {
// give the docs for the selected module in the popover
$scope.argsPopOver = '<p>These arguments are used with the ' +
'specified module. You can find information about the ' +
val.value + ' module <a ' +
'id=\"adhoc_module_arguments_docs_link_for_module_' +
val.value + '\" href=\"http://docs.ansible.com/' +
val.value + '_module.html\" ' +
'target=\"_blank\">here</a>.</p>';
} else {
// no module selected
$scope.argsPopOver = "<p>These arguments are used with the" +
" specified module.</p>";
}
}, true);
// initially set to the same as no module selected
$scope.argsPopOver = "<p>These arguments are used with the " +
"specified module.</p>";
};
// pre-populate host patterns from the inventory page and
// delete the value off of rootScope
privateFn.instantiateHostPatterns = function(hostPattern) {
$scope.limit = hostPattern;
$scope.providedHostPatterns = $scope.limit;
delete $rootScope.hostPatterns;
};
// call helpers to initialize lookup and select fields through get
// requests
privateFn.initializeFields = function(machineCredentialUrl, adhocUrl) {
// setup machine credential lookup
LookUpInit({
url: machineCredentialUrl,
scope: $scope,
form: adhocForm,
current_item: (!Empty($scope.credential_id)) ?
$scope.credential_id : null,
list: CredentialList,
field: 'credential',
input_type: 'radio'
});
// setup module name select
GetChoices({
scope: $scope,
url: adhocUrl,
field: 'module_name',
variable: 'adhoc_module_options',
callback: 'adhocFormReady'
});
// setup verbosity options select
GetChoices({
scope: $scope,
url: adhocUrl,
field: 'verbosity',
variable: 'adhoc_verbosity_options',
callback: 'adhocFormReady'
});
};
// instantiate all variables on scope for display in the partial
privateFn.initializeForm = function(id, urls, hostPattern) {
// inject the adhoc command form
GenerateForm.inject(adhocForm,
{ mode: 'edit', related: true, scope: $scope });
// set when "working" starts and stops
privateFn.setLoadingStartStop();
// put the inventory id on scope for the partial to use
$scope.inv_id = id;
// get the inventory name
privateFn.getInventoryNameForBreadcrumbs(urls.inventoryUrl);
// set the arguments help to watch on change of the module
privateFn.instantiateArgumentHelp();
// pre-populate host patterns from the inventory page and
// delete the value off of rootScope
privateFn.instantiateHostPatterns(hostPattern);
privateFn.initializeFields(urls.machineCredentialUrl, urls.adhocUrl);
};
privateFn.initializeForm(id, urls, hostPattern);
// remove all data input into the form and reset the form back to defaults
$scope.formReset = function () {
GenerateForm.reset();
// pre-populate host patterns from the inventory page and
// delete the value off of rootScope
privateFn.instantiateHostPatterns($scope.providedHostPatterns);
KindChange({ scope: $scope, form: adhocForm, reset: false });
// set the default options for the selects of the adhoc form
privateFn.setFieldDefaults($scope.adhoc_verbosity_options,
$scope.forks_default);
};
// launch the job with the provided form data
$scope.launchJob = function () {
var adhocUrl = GetBasePath('inventory') + $routeParams.inventory_id +
'/ad_hoc_commands/', fld, data={}, html;
html = '<form class="ng-valid ng-valid-required" ' +
'name="job_launch_form" id="job_launch_form" autocomplete="off" ' +
'nonvalidate>';
// stub the payload with defaults from DRF
data = {
"job_type": "run",
"limit": "",
"credential": null,
"module_name": "command",
"module_args": "",
"forks": 0,
"verbosity": 0,
"privilege_escalation": ""
};
GenerateForm.clearApiErrors();
// populate data with the relevant form values
for (fld in adhocForm.fields) {
if (adhocForm.fields[fld].type === 'select') {
data[fld] = $scope[fld].value;
} else {
data[fld] = $scope[fld];
}
}
Wait('start');
if ($scope.removeStartAdhocRun) {
$scope.removeStartAdhocRun();
}
$scope.removeStartAdhocRun = $scope.$on('StartAdhocRun', function() {
var password;
for (password in $scope.passwords) {
data[$scope.passwords[password]] = $scope[
$scope.passwords[password]
];
}
// Launch the adhoc job
Rest.setUrl(GetBasePath('inventory') +
$routeParams.inventory_id + '/ad_hoc_commands/');
Rest.post(data)
.success(function (data) {
Wait('stop');
$location.path("/ad_hoc_commands/" + data.id);
})
.error(function (data, status) {
ProcessErrors($scope, data, status, adhocForm, {
hdr: 'Error!',
msg: 'Failed to launch adhoc command. POST ' +
'returned status: ' + status });
});
});
if ($scope.removeCreateLaunchDialog) {
$scope.removeCreateLaunchDialog();
}
$scope.removeCreateLaunchDialog = $scope.$on('CreateLaunchDialog',
function(e, html, url) {
CreateLaunchDialog({
scope: $scope,
html: html,
url: url,
callback: 'StartAdhocRun'
});
});
if ($scope.removePromptForPasswords) {
$scope.removePromptForPasswords();
}
$scope.removePromptForPasswords = $scope.$on('PromptForPasswords',
function(e, passwords_needed_to_start,html, url) {
PromptForPasswords({ scope: $scope,
passwords: passwords_needed_to_start,
callback: 'CreateLaunchDialog',
html: html,
url: url
});
});
if ($scope.removeContinueCred) {
$scope.removeContinueCred();
}
$scope.removeContinueCred = $scope.$on('ContinueCred', function(e,
passwords) {
if(passwords.length>0){
$scope.passwords_needed_to_start = passwords;
// only go through the password prompting steps if there are
// passwords to prompt for
$scope.$emit('PromptForPasswords', passwords, html, adhocUrl);
} else {
// if not, go straight to trying to run the job.
$scope.$emit('StartAdhocRun', adhocUrl);
}
});
// start adhoc launching routine
CheckPasswords({
scope: $scope,
credential: $scope.credential,
callback: 'ContinueCred'
});
};
}
export default ['$q', '$scope', '$rootScope', '$location', '$routeParams',
'CheckPasswords', 'PromptForPasswords', 'CreateLaunchDialog', 'adhocForm',
'GenerateForm', 'Rest', 'ProcessErrors', 'ClearScope', 'GetBasePath',
'GetChoices', 'KindChange', 'LookUpInit', 'CredentialList', 'Empty', 'Wait',
adhocController];