mirror of
https://github.com/ansible/awx.git
synced 2026-01-14 19:30:39 -03:30
Implemented the ability to specify credentials when creating a scheduled job run. Added validation for removing but not replacing default credentials.
This commit is contained in:
parent
61a48996ee
commit
a5043029c1
@ -118,5 +118,5 @@
|
||||
query-set="querySet">
|
||||
</paginate>
|
||||
</at-panel-body>
|
||||
<prompt prompt-data="promptData" open-modal="openModal" on-finish="launchJob()"></launch>
|
||||
<prompt prompt-data="promptData" on-finish="launchJob()"></launch>
|
||||
</at-panel>
|
||||
|
||||
@ -55,7 +55,8 @@ function TemplatesStrings (BaseString) {
|
||||
VALID_DECIMAL: t.s('Please enter an answer that is a decimal number.'),
|
||||
PLAYBOOK_RUN: t.s('Playbook Run'),
|
||||
CHECK: t.s('Check'),
|
||||
NO_CREDS_MATCHING_TYPE: t.s('No Credentials Matching This Type Have Been Created'),
|
||||
NO_CREDS_MATCHING_TYPE: t.s('No Credentials Matching This Type Have Been Created'),
|
||||
CREDENTIAL_TYPE_MISSING: typeLabel => t.s('This job template has a default {{typeLabel}} credential which must be included or replaced before proceeding.', { typeLabel })
|
||||
};
|
||||
|
||||
ns.alert = {
|
||||
@ -85,7 +86,7 @@ function TemplatesStrings (BaseString) {
|
||||
|
||||
ns.warnings = {
|
||||
WORKFLOW_RESTRICTED_COPY: t.s('You do not have access to all resources used by this workflow. Resources that you don\'t have access to will not be copied and will result in an incomplete workflow.')
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TemplatesStrings.$inject = ['BaseStringService'];
|
||||
|
||||
38
awx/ui/client/lib/models/Schedule.js
Normal file
38
awx/ui/client/lib/models/Schedule.js
Normal file
@ -0,0 +1,38 @@
|
||||
let Base;
|
||||
let $http;
|
||||
|
||||
function postCredential (params) {
|
||||
const req = {
|
||||
method: 'POST',
|
||||
url: `${this.path}${params.id}/credentials/`
|
||||
};
|
||||
|
||||
if (params.data) {
|
||||
req.data = params.data;
|
||||
}
|
||||
|
||||
return $http(req);
|
||||
}
|
||||
|
||||
function ScheduleModel (method, resource, config) {
|
||||
Base.call(this, 'schedules');
|
||||
|
||||
this.Constructor = ScheduleModel;
|
||||
this.postCredential = postCredential.bind(this);
|
||||
|
||||
return this.create(method, resource, config);
|
||||
}
|
||||
|
||||
function ScheduleModelLoader (BaseModel, _$http_) {
|
||||
Base = BaseModel;
|
||||
$http = _$http_;
|
||||
|
||||
return ScheduleModel;
|
||||
}
|
||||
|
||||
ScheduleModelLoader.$inject = [
|
||||
'BaseModel',
|
||||
'$http'
|
||||
];
|
||||
|
||||
export default ScheduleModelLoader;
|
||||
@ -16,6 +16,7 @@ import ModelsStrings from '~models/models.strings';
|
||||
import NotificationTemplate from '~models/NotificationTemplate';
|
||||
import Organization from '~models/Organization';
|
||||
import Project from '~models/Project';
|
||||
import Schedule from '~models/Schedule';
|
||||
import UnifiedJobTemplate from '~models/UnifiedJobTemplate';
|
||||
import WorkflowJob from '~models/WorkflowJob';
|
||||
import WorkflowJobTemplate from '~models/WorkflowJobTemplate';
|
||||
@ -43,6 +44,7 @@ angular
|
||||
.service('NotificationTemplate', NotificationTemplate)
|
||||
.service('OrganizationModel', Organization)
|
||||
.service('ProjectModel', Project)
|
||||
.service('ScheduleModel', Schedule)
|
||||
.service('UnifiedJobTemplateModel', UnifiedJobTemplate)
|
||||
.service('WorkflowJobModel', WorkflowJob)
|
||||
.service('WorkflowJobTemplateModel', WorkflowJobTemplate)
|
||||
|
||||
@ -1,36 +1,37 @@
|
||||
export default
|
||||
function SchedulePost(Rest, ProcessErrors, RRuleToAPI, Wait, $q) {
|
||||
function SchedulePost(Rest, ProcessErrors, RRuleToAPI, Wait, $q, Schedule) {
|
||||
return function(params) {
|
||||
var scope = params.scope,
|
||||
url = params.url,
|
||||
scheduler = params.scheduler,
|
||||
mode = params.mode,
|
||||
schedule = (params.schedule) ? params.schedule : {},
|
||||
scheduleData = (params.schedule) ? params.schedule : {},
|
||||
promptData = params.promptData,
|
||||
priorCredentials = params.priorCredentials ? params.priorCredentials : [],
|
||||
newSchedule, rrule, extra_vars;
|
||||
let deferred = $q.defer();
|
||||
if (scheduler.isValid()) {
|
||||
Wait('start');
|
||||
newSchedule = scheduler.getValue();
|
||||
rrule = scheduler.getRRule();
|
||||
schedule.name = newSchedule.name;
|
||||
schedule.rrule = RRuleToAPI(rrule.toString(), scope);
|
||||
schedule.description = (/error/.test(rrule.toText())) ? '' : rrule.toText();
|
||||
scheduleData.name = newSchedule.name;
|
||||
scheduleData.rrule = RRuleToAPI(rrule.toString(), scope);
|
||||
scheduleData.description = (/error/.test(rrule.toText())) ? '' : rrule.toText();
|
||||
|
||||
if (scope.isFactCleanup) {
|
||||
extra_vars = {
|
||||
"older_than": scope.scheduler_form.keep_amount.$viewValue + scope.scheduler_form.keep_unit.$viewValue.value,
|
||||
"granularity": scope.scheduler_form.granularity_keep_amount.$viewValue + scope.scheduler_form.granularity_keep_unit.$viewValue.value
|
||||
};
|
||||
schedule.extra_data = JSON.stringify(extra_vars);
|
||||
scheduleData.extra_data = JSON.stringify(extra_vars);
|
||||
} else if (scope.cleanupJob) {
|
||||
extra_vars = {
|
||||
"days" : scope.scheduler_form.schedulerPurgeDays.$viewValue
|
||||
};
|
||||
schedule.extra_data = JSON.stringify(extra_vars);
|
||||
scheduleData.extra_data = JSON.stringify(extra_vars);
|
||||
}
|
||||
else if(scope.extraVars){
|
||||
schedule.extra_data = scope.parseType === 'yaml' ?
|
||||
scheduleData.extra_data = scope.parseType === 'yaml' ?
|
||||
(scope.extraVars === '---' ? "" : jsyaml.safeLoad(scope.extraVars)) : scope.extraVars;
|
||||
}
|
||||
|
||||
@ -40,10 +41,10 @@ export default
|
||||
var fld = promptData.surveyQuestions[i].variable;
|
||||
// grab all survey questions that have answers
|
||||
if(promptData.surveyQuestions[i].required || (promptData.surveyQuestions[i].required === false && promptData.surveyQuestions[i].model.toString()!=="")) {
|
||||
if(!schedule.extra_data) {
|
||||
schedule.extra_data = {};
|
||||
if(!scheduleData.extra_data) {
|
||||
scheduleData.extra_data = {};
|
||||
}
|
||||
schedule.extra_data[fld] = promptData.surveyQuestions[i].model;
|
||||
scheduleData.extra_data[fld] = promptData.surveyQuestions[i].model;
|
||||
}
|
||||
|
||||
if(promptData.surveyQuestions[i].required === false && _.isEmpty(promptData.surveyQuestions[i].model)) {
|
||||
@ -55,7 +56,7 @@ export default
|
||||
case "text":
|
||||
case "textarea":
|
||||
if (promptData.surveyQuestions[i].min === 0) {
|
||||
schedule.extra_data[fld] = "";
|
||||
scheduleData.extra_data[fld] = "";
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -64,43 +65,65 @@ export default
|
||||
}
|
||||
|
||||
if(_.has(promptData, 'prompts.jobType.value.value') && _.get(promptData, 'launchConf.ask_job_type_on_launch')) {
|
||||
schedule.job_type = promptData.prompts.jobType.templateDefault === promptData.prompts.jobType.value.value ? null : promptData.prompts.jobType.value.value;
|
||||
scheduleData.job_type = promptData.launchConf.defaults.job_type && promptData.launchConf.defaults.job_type === promptData.prompts.jobType.value.value ? null : promptData.prompts.jobType.value.value;
|
||||
}
|
||||
if(_.has(promptData, 'prompts.tags.value') && _.get(promptData, 'launchConf.ask_tags_on_launch')){
|
||||
let templateDefaultJobTags = promptData.prompts.tags.templateDefault.split(',');
|
||||
schedule.job_tags = (_.isEqual(templateDefaultJobTags.sort(), promptData.prompts.tags.value.map(a => a.value).sort())) ? null : promptData.prompts.tags.value.map(a => a.value).join();
|
||||
let templateDefaultJobTags = promptData.launchConf.defaults.job_tags.split(',');
|
||||
scheduleData.job_tags = (_.isEqual(templateDefaultJobTags.sort(), promptData.prompts.tags.value.map(a => a.value).sort())) ? null : promptData.prompts.tags.value.map(a => a.value).join();
|
||||
}
|
||||
if(_.has(promptData, 'prompts.skipTags.value') && _.get(promptData, 'launchConf.ask_skip_tags_on_launch')){
|
||||
let templateDefaultSkipTags = promptData.prompts.skipTags.templateDefault.split(',');
|
||||
schedule.skip_tags = (_.isEqual(templateDefaultSkipTags.sort(), promptData.prompts.skipTags.value.map(a => a.value).sort())) ? null : promptData.prompts.skipTags.value.map(a => a.value).join();
|
||||
let templateDefaultSkipTags = promptData.launchConf.defaults.skip_tags.split(',');
|
||||
scheduleData.skip_tags = (_.isEqual(templateDefaultSkipTags.sort(), promptData.prompts.skipTags.value.map(a => a.value).sort())) ? null : promptData.prompts.skipTags.value.map(a => a.value).join();
|
||||
}
|
||||
if(_.has(promptData, 'prompts.limit.value') && _.get(promptData, 'launchConf.ask_limit_on_launch')){
|
||||
schedule.limit = promptData.prompts.limit.templateDefault === promptData.prompts.limit.value ? null : promptData.prompts.limit.value;
|
||||
scheduleData.limit = promptData.launchConf.defaults.limit && promptData.launchConf.defaults.limit === promptData.prompts.limit.value ? null : promptData.prompts.limit.value;
|
||||
}
|
||||
if(_.has(promptData, 'prompts.verbosity.value.value') && _.get(promptData, 'launchConf.ask_verbosity_on_launch')){
|
||||
schedule.verbosity = promptData.prompts.verbosity.templateDefault === promptData.prompts.verbosity.value.value ? null : promptData.prompts.verbosity.value.value;
|
||||
scheduleData.verbosity = promptData.launchConf.defaults.verbosity && promptData.launchConf.defaults.verbosity === promptData.prompts.verbosity.value.value ? null : promptData.prompts.verbosity.value.value;
|
||||
}
|
||||
if(_.has(promptData, 'prompts.inventory.value') && _.get(promptData, 'launchConf.ask_inventory_on_launch')){
|
||||
schedule.inventory = promptData.prompts.inventory.templateDefault.id === promptData.prompts.inventory.value.id ? null : promptData.prompts.inventory.value.id;
|
||||
scheduleData.inventory = promptData.launchConf.defaults.inventory && promptData.launchConf.defaults.inventory.id === promptData.prompts.inventory.value.id ? null : promptData.prompts.inventory.value.id;
|
||||
}
|
||||
if(_.has(promptData, 'prompts.diffMode.value') && _.get(promptData, 'launchConf.ask_diff_mode_on_launch')){
|
||||
schedule.diff_mode = promptData.prompts.diffMode.templateDefault === promptData.prompts.diffMode.value ? null : promptData.prompts.diffMode.value;
|
||||
scheduleData.diff_mode = promptData.launchConf.defaults.diff_mode && promptData.launchConf.defaults.diff_mode === promptData.prompts.diffMode.value ? null : promptData.prompts.diffMode.value;
|
||||
}
|
||||
// Credentials gets POST'd to a separate endpoint
|
||||
// if($scope.promptData.launchConf.ask_credential_on_launch){
|
||||
// jobLaunchData.credentials = [];
|
||||
// promptData.credentials.value.forEach((credential) => {
|
||||
// jobLaunchData.credentials.push(credential.id);
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
Rest.setUrl(url);
|
||||
if (mode === 'add') {
|
||||
Rest.post(schedule)
|
||||
.then(() => {
|
||||
Wait('stop');
|
||||
deferred.resolve();
|
||||
Rest.post(scheduleData)
|
||||
.then(({data}) => {
|
||||
if(_.get(promptData, 'launchConf.ask_credential_on_launch')){
|
||||
// This finds the credentials that were selected in the prompt but don't occur
|
||||
// in the template defaults
|
||||
let credentialsToPost = promptData.prompts.credentials.value.filter(function(credFromPrompt) {
|
||||
let defaultCreds = promptData.launchConf.defaults.credentials ? promptData.launchConf.defaults.credentials : [];
|
||||
return !defaultCreds.some(function(defaultCred) {
|
||||
return credFromPrompt.id === defaultCred.id;
|
||||
});
|
||||
});
|
||||
|
||||
let promises = [];
|
||||
let schedule = new Schedule();
|
||||
|
||||
credentialsToPost.forEach((credentialToPost) => {
|
||||
promises.push(schedule.postCredential({
|
||||
id: data.id,
|
||||
data: {
|
||||
id: credentialToPost.id
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
$q.all(promises)
|
||||
.then(() => {
|
||||
Wait('stop');
|
||||
deferred.resolve();
|
||||
});
|
||||
} else {
|
||||
Wait('stop');
|
||||
deferred.resolve();
|
||||
}
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
@ -110,10 +133,62 @@ export default
|
||||
});
|
||||
}
|
||||
else {
|
||||
Rest.put(schedule)
|
||||
.then(() => {
|
||||
Rest.put(scheduleData)
|
||||
.then(({data}) => {
|
||||
if(_.get(promptData, 'launchConf.ask_credential_on_launch')){
|
||||
let credentialsNotInPriorCredentials = promptData.prompts.credentials.value.filter(function(credFromPrompt) {
|
||||
let defaultCreds = promptData.launchConf.defaults.credentials ? promptData.launchConf.defaults.credentials : [];
|
||||
return !defaultCreds.some(function(defaultCred) {
|
||||
return credFromPrompt.id === defaultCred.id;
|
||||
});
|
||||
});
|
||||
|
||||
let credentialsToAdd = credentialsNotInPriorCredentials.filter(function(credNotInPrior) {
|
||||
return !priorCredentials.some(function(priorCred) {
|
||||
return credNotInPrior.id === priorCred.id;
|
||||
});
|
||||
});
|
||||
|
||||
let credentialsToRemove = priorCredentials.filter(function(priorCred) {
|
||||
return !credentialsNotInPriorCredentials.some(function(credNotInPrior) {
|
||||
return priorCred.id === credNotInPrior.id;
|
||||
});
|
||||
});
|
||||
|
||||
let promises = [];
|
||||
let schedule = new Schedule();
|
||||
|
||||
credentialsToAdd.forEach((credentialToAdd) => {
|
||||
promises.push(schedule.postCredential({
|
||||
id: data.id,
|
||||
data: {
|
||||
id: credentialToAdd.id
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
credentialsToRemove.forEach((credentialToRemove) => {
|
||||
promises.push(schedule.postCredential({
|
||||
id: data.id,
|
||||
data: {
|
||||
id: credentialToRemove.id,
|
||||
disassociate: true
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
$q.all(promises)
|
||||
.then(() => {
|
||||
Wait('stop');
|
||||
deferred.resolve();
|
||||
});
|
||||
} else {
|
||||
Wait('stop');
|
||||
deferred.resolve();
|
||||
}
|
||||
|
||||
Wait('stop');
|
||||
deferred.resolve(schedule);
|
||||
deferred.resolve(scheduleData);
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
@ -136,5 +211,6 @@ SchedulePost.$inject =
|
||||
'ProcessErrors',
|
||||
'RRuleToAPI',
|
||||
'Wait',
|
||||
'$q'
|
||||
'$q',
|
||||
'ScheduleModel'
|
||||
];
|
||||
|
||||
@ -104,6 +104,7 @@ export default ['$filter', '$state', '$stateParams', '$http', 'Wait',
|
||||
let watchForPromptChanges = () => {
|
||||
let promptValuesToWatch = [
|
||||
'promptData.prompts.inventory.value',
|
||||
'promptData.prompts.jobType.value',
|
||||
'promptData.prompts.verbosity.value',
|
||||
'missingSurveyValue'
|
||||
];
|
||||
|
||||
@ -5,7 +5,7 @@ function($filter, $state, $stateParams, Wait, $scope, moment,
|
||||
$rootScope, $http, CreateSelect2, ParseTypeChange, ParentObject, ProcessErrors, Rest,
|
||||
GetBasePath, SchedulerInit, SchedulePost, JobTemplate, $q, Empty, PromptService, RRuleToAPI) {
|
||||
|
||||
let schedule, scheduler;
|
||||
let schedule, scheduler, scheduleCredentials = [];
|
||||
|
||||
// initial end @ midnight values
|
||||
$scope.schedulerEndHour = "00";
|
||||
@ -63,7 +63,8 @@ function($filter, $state, $stateParams, Wait, $scope, moment,
|
||||
scheduler: scheduler,
|
||||
mode: 'edit',
|
||||
schedule: schedule,
|
||||
promptData: $scope.promptData
|
||||
promptData: $scope.promptData,
|
||||
priorCredentials: scheduleCredentials
|
||||
}).then(() => {
|
||||
Wait('stop');
|
||||
$state.go("^", null, {reload: true});
|
||||
@ -254,14 +255,14 @@ function($filter, $state, $stateParams, Wait, $scope, moment,
|
||||
$q.all([jobTemplate.optionsLaunch(ParentObject.id), jobTemplate.getLaunch(ParentObject.id), Rest.get()])
|
||||
.then((responses) => {
|
||||
let launchOptions = responses[0].data,
|
||||
launchConf = responses[1].data,
|
||||
scheduleCredentials = responses[2].data;
|
||||
launchConf = responses[1].data;
|
||||
|
||||
scheduleCredentials = responses[2].data.results;
|
||||
|
||||
let watchForPromptChanges = () => {
|
||||
let promptValuesToWatch = [
|
||||
// credential passwords...?
|
||||
'promptData.prompts.inventory.value',
|
||||
'promptData.prompts.jobType.value',
|
||||
'promptData.prompts.verbosity.value',
|
||||
'missingSurveyValue'
|
||||
];
|
||||
@ -283,7 +284,23 @@ function($filter, $state, $stateParams, Wait, $scope, moment,
|
||||
currentValues: data
|
||||
});
|
||||
|
||||
prompts.credentials.value = scheduleCredentials.results.length > 0 ? scheduleCredentials.results : prompts.credentials.value;
|
||||
let defaultCredsWithoutOverrides = [];
|
||||
|
||||
prompts.credentials.value.forEach((defaultCred) => {
|
||||
let typeMatches = false;
|
||||
scheduleCredentials.forEach((scheduleCred) => {
|
||||
if(defaultCred.credential_type === scheduleCred.credential_type) {
|
||||
if((!defaultCred.vault_id && !scheduleCred.inputs.vault_id) || (defaultCred.vault_id && scheduleCred.inputs.vault_id && defaultCred.vault_id === scheduleCred.inputs.vault_id)) {
|
||||
typeMatches = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
if(!typeMatches) {
|
||||
defaultCredsWithoutOverrides.push(defaultCred);
|
||||
}
|
||||
});
|
||||
|
||||
prompts.credentials.value = scheduleCredentials.concat(defaultCredsWithoutOverrides);
|
||||
|
||||
if(!launchConf.ask_variables_on_launch) {
|
||||
$scope.noVars = true;
|
||||
|
||||
@ -560,7 +560,13 @@ angular.module('GeneratorHelpers', [systemStatus.name])
|
||||
}
|
||||
html += "\" ";
|
||||
html += field.columnNgClass ? " ng-class=\"" + field.columnNgClass + "\"": "";
|
||||
html += (options.mode === 'lookup' || options.mode === 'select') ? " ng-click=\"toggle_row(" + list.iterator + ")\"" : "";
|
||||
if(options.mode === 'lookup' || options.mode === 'select') {
|
||||
if (options.input_type === "radio") {
|
||||
html += " ng-click=\"toggle_row(" + list.iterator + ")\"";
|
||||
} else {
|
||||
html += " ng-click=\"toggle_" + list.iterator + "(" + list.iterator + ", true)\"";
|
||||
}
|
||||
}
|
||||
html += (field.columnShow) ? Attr(field, 'columnShow') : "";
|
||||
html += (field.ngBindHtml) ? "ng-bind-html=\"" + field.ngBindHtml + "\" " : "";
|
||||
html += (field.columnClick) ? "ng-click=\"" + field.columnClick + "\" " : "";
|
||||
|
||||
@ -165,3 +165,7 @@
|
||||
.Prompt-credentialSubSection .select2 {
|
||||
width: 50% !important;
|
||||
}
|
||||
.Prompt-credentialTypeMissing {
|
||||
margin-bottom: 20px;
|
||||
color: @default-err;
|
||||
}
|
||||
|
||||
@ -65,8 +65,6 @@ export default [ 'Rest', 'GetBasePath', 'ProcessErrors', 'CredentialTypeModel',
|
||||
}
|
||||
}));
|
||||
|
||||
vm.promptData.prompts.inventory.templateDefault = _.has(vm, 'promptData.launchConf.defaults.inventory') ? vm.promptData.launchConf.defaults.inventory : null;
|
||||
vm.promptData.prompts.credentials.templateDefault = _.has(vm, 'promptData.launchConf.defaults.credentials') ? angular.copy(vm.promptData.launchConf.defaults.credentials) : [];
|
||||
vm.promptData.prompts.credentials.passwordsNeededToStart = vm.promptData.launchConf.passwords_needed_to_start;
|
||||
vm.promptData.prompts.credentials.passwords = {};
|
||||
|
||||
@ -99,17 +97,12 @@ export default [ 'Rest', 'GetBasePath', 'ProcessErrors', 'CredentialTypeModel',
|
||||
vm.promptData.prompts.credentials.passwords.vault.push(credPassObj);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
vm.promptData.credentialTypeMissing = [];
|
||||
|
||||
vm.promptData.prompts.variables.ignore = vm.promptData.launchConf.ignore_ask_variables;
|
||||
vm.promptData.prompts.verbosity.templateDefault = vm.promptData.launchConf.defaults.verbosity;
|
||||
vm.promptData.prompts.jobType.templateDefault = vm.promptData.launchConf.defaults.job_type;
|
||||
vm.promptData.prompts.limit.templateDefault = vm.promptData.launchConf.defaults.limit;
|
||||
vm.promptData.prompts.tags.templateDefault = vm.promptData.launchConf.defaults.job_tags;
|
||||
vm.promptData.prompts.skipTags.templateDefault = vm.promptData.launchConf.defaults.skip_tags;
|
||||
vm.promptData.prompts.diffMode.templateDefault = vm.promptData.launchConf.defaults.diff_mode;
|
||||
|
||||
if(vm.promptData.launchConf.ask_inventory_on_launch) {
|
||||
vm.steps.inventory.includeStep = true;
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
<div class="Prompt-footer">
|
||||
<button class="Prompt-defaultButton" ng-click="vm.cancel()">{{:: vm.strings.get('CANCEL') }}</button>
|
||||
<button class="Prompt-actionButton" ng-show="vm.steps.inventory.tab._active" ng-click="vm.next(vm.steps.inventory.tab)" ng-disabled="!vm.promptData.prompts.inventory.value.id">{{:: vm.strings.get('NEXT') }}</button>
|
||||
<button class="Prompt-actionButton" ng-show="vm.steps.credential.tab._active" ng-click="vm.next(vm.steps.credential.tab)" ng-disabled="!vm.forms.credentialPasswords.$valid">{{:: vm.strings.get('NEXT') }}</button>
|
||||
<button class="Prompt-actionButton" ng-show="vm.steps.credential.tab._active" ng-click="vm.next(vm.steps.credential.tab)" ng-disabled="!vm.forms.credentialPasswords.$valid || (vm.promptData.credentialTypeMissing && vm.promptData.credentialTypeMissing.length > 0)">{{:: vm.strings.get('NEXT') }}</button>
|
||||
<button class="Prompt-actionButton" ng-show="vm.steps.other_prompts.tab._active" ng-click="vm.next(vm.steps.other_prompts.tab)" ng-disabled="!vm.forms.otherPrompts.$valid">{{:: vm.strings.get('NEXT') }}</button>
|
||||
<button class="Prompt-actionButton" ng-show="vm.steps.survey.tab._active" ng-click="vm.next(vm.steps.survey.tab)" ng-disabled="!vm.forms.survey.$valid">{{:: vm.strings.get('NEXT') }}</button>
|
||||
<button class="Prompt-actionButton" ng-show="vm.steps.preview.tab._active" ng-click="vm.finish()" ng-bind="vm.actionText"></button>
|
||||
|
||||
@ -13,7 +13,7 @@ function PromptService (Empty, $filter) {
|
||||
diffMode: {}
|
||||
};
|
||||
|
||||
prompts.credentials.value = _.has(params, 'launchConf.defaults.credentials') ? params.launchConf.defaults.credentials : [];
|
||||
prompts.credentials.value = _.has(params, 'launchConf.defaults.credentials') ? _.cloneDeep(params.launchConf.defaults.credentials) : [];
|
||||
prompts.inventory.value = _.has(params, 'currentValues.summary_fields.inventory') ? params.currentValues.summary_fields.inventory : (_.has(params, 'launchConf.defaults.inventory') ? params.launchConf.defaults.inventory : null);
|
||||
|
||||
let skipTags = _.has(params, 'currentValues.skip_tags') && params.currentValues.skip_tags ? params.currentValues.skip_tags : (_.has(params, 'launchConf.defaults.skip_tags') ? params.launchConf.defaults.skip_tags : "");
|
||||
|
||||
@ -88,11 +88,41 @@ export default
|
||||
}
|
||||
};
|
||||
|
||||
let checkMissingCredType = (cred) => {
|
||||
scope.promptData.launchConf.defaults.credentials.forEach((defaultCred) => {
|
||||
if(cred.credential_type === defaultCred.credential_type) {
|
||||
let credTypeLabel = "";
|
||||
scope.promptData.prompts.credentials.credentialTypeOptions.forEach((credTypeOption) => {
|
||||
if(credTypeOption.value === defaultCred.credential_type) {
|
||||
credTypeLabel = credTypeOption.name;
|
||||
}
|
||||
});
|
||||
|
||||
if(scope.promptData.prompts.credentials.credentialTypes[cred.credential_type] === "vault") {
|
||||
if((_.get(cred, 'inputs.vault_id') ? _.get(cred, 'inputs.vault_id') : _.get(cred, 'vault_id')) === _.get(defaultCred, 'vault_id')) {
|
||||
scope.promptData.credentialTypeMissing.push({
|
||||
credential_type: defaultCred.credential_type,
|
||||
vault_id: defaultCred.vault_id,
|
||||
label: defaultCred.vault_id ? `${credTypeLabel} (id: ${defaultCred.vault_id})` : credTypeLabel
|
||||
});
|
||||
}
|
||||
} else {
|
||||
scope.promptData.credentialTypeMissing.push({
|
||||
credential_type: defaultCred.credential_type,
|
||||
label: credTypeLabel
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
vm.init = (_scope_, _launch_) => {
|
||||
scope = _scope_;
|
||||
launch = _launch_;
|
||||
|
||||
scope.toggle_row = (selectedRow) => {
|
||||
let selectedCred = _.cloneDeep(selectedRow);
|
||||
|
||||
for (let i = scope.promptData.prompts.credentials.value.length - 1; i >= 0; i--) {
|
||||
if(scope.promptData.prompts.credentials.value[i].credential_type === parseInt(scope.promptData.prompts.credentials.credentialKind)) {
|
||||
wipePasswords(scope.promptData.prompts.credentials.value[i]);
|
||||
@ -100,8 +130,15 @@ export default
|
||||
}
|
||||
}
|
||||
|
||||
scope.promptData.prompts.credentials.value.push(_.cloneDeep(selectedRow));
|
||||
scope.promptData.prompts.credentials.value.push(selectedCred);
|
||||
updateNeededPasswords(selectedRow);
|
||||
|
||||
for (let i = scope.promptData.credentialTypeMissing.length - 1; i >= 0; i--) {
|
||||
if(scope.promptData.credentialTypeMissing[i].credential_type === selectedRow.credential_type) {
|
||||
scope.promptData.credentialTypeMissing.splice(i,1);
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
scope.toggle_credential = (cred) => {
|
||||
@ -146,6 +183,18 @@ export default
|
||||
if(!uncheck) {
|
||||
scope.promptData.prompts.credentials.value.push(cred);
|
||||
updateNeededPasswords(cred);
|
||||
for (let i = scope.promptData.credentialTypeMissing.length - 1; i >= 0; i--) {
|
||||
if(scope.promptData.credentialTypeMissing[i].credential_type === cred.credential_type) {
|
||||
if(_.get(cred, 'inputs.vault_id') === _.get(scope.promptData.credentialTypeMissing[i], 'vault_id')) {
|
||||
scope.promptData.credentialTypeMissing.splice(i,1);
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(scope.promptData.launchConf.defaults.credentials && scope.promptData.launchConf.defaults.credentials.length > 0) {
|
||||
checkMissingCredType(cred);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -200,6 +249,9 @@ export default
|
||||
vm.deleteSelectedCredential = (credentialToDelete) => {
|
||||
for (let i = scope.promptData.prompts.credentials.value.length - 1; i >= 0; i--) {
|
||||
if(scope.promptData.prompts.credentials.value[i].id === credentialToDelete.id) {
|
||||
if(scope.promptData.launchConf.defaults.credentials && scope.promptData.launchConf.defaults.credentials.length > 0) {
|
||||
checkMissingCredType(credentialToDelete);
|
||||
}
|
||||
wipePasswords(credentialToDelete);
|
||||
scope.promptData.prompts.credentials.value.splice(i, 1);
|
||||
}
|
||||
@ -213,7 +265,7 @@ export default
|
||||
};
|
||||
|
||||
vm.revert = () => {
|
||||
scope.promptData.prompts.credentials.value = scope.promptData.prompts.credentials.templateDefault;
|
||||
scope.promptData.prompts.credentials.value = _.has(scope, 'promptData.launchConf.defaults.credentials') ? _.cloneDeep(scope.promptData.launchConf.defaults.credentials) : [];
|
||||
scope.promptData.prompts.credentials.passwords = {
|
||||
vault: []
|
||||
};
|
||||
@ -242,13 +294,15 @@ export default
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
scope.promptData.credentialTypeMissing = [];
|
||||
};
|
||||
|
||||
vm.showRevertCredentials = () => {
|
||||
if(scope.promptData.launchConf.ask_credential_on_launch) {
|
||||
if(scope.promptData.prompts.credentials.value && scope.promptData.prompts.credentials.templateDefault && (scope.promptData.prompts.credentials.value.length === scope.promptData.prompts.credentials.templateDefault.length)) {
|
||||
if(scope.promptData.prompts.credentials.value && _.has(scope, 'promptData.launchConf.defaults.credentials') && (scope.promptData.prompts.credentials.value.length === scope.promptData.launchConf.defaults.credentials.length)) {
|
||||
let selectedIds = scope.promptData.prompts.credentials.value.map((x) => { return x.id; }).sort();
|
||||
let defaultIds = scope.promptData.prompts.credentials.templateDefault.map((x) => { return x.id; }).sort();
|
||||
let defaultIds = _.has(scope, 'promptData.launchConf.defaults.credentials') ? scope.promptData.launchConf.defaults.credentials.map((x) => { return x.id; }).sort() : [];
|
||||
return !selectedIds.every((e, i) => { return defaultIds.indexOf(e) === i; });
|
||||
} else {
|
||||
return true;
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
<div>
|
||||
<div class="Prompt-selectedItem">
|
||||
<div class="Prompt-selectedItemInfo" ng-hide="promptData.prompts.credentials.templateDefault.length === 0 && promptData.prompts.credentials.value.length === 0">
|
||||
<div class="Prompt-selectedItemInfo" ng-hide="(!promptData.launchConf.defaults.credentials || promptData.launchConf.defaults.credentials.length === 0) && promptData.prompts.credentials.value.length === 0">
|
||||
<div class="Prompt-selectedItemLabel">
|
||||
<span>{{:: vm.strings.get('prompt.SELECTED') }}</span>
|
||||
</div>
|
||||
<div class="Prompt-previewTags--outer">
|
||||
<div ng-show="promptData.prompts.credentials.templateDefault.length > 0 && promptData.prompts.credentials.value.length === 0" class="Prompt-noSelectedItem">{{:: vm.strings.get('prompt.NO_CREDENTIALS_SELECTED') }}</div>
|
||||
<div ng-show="promptData.launchConf.defaults.credentials && promptData.launchConf.defaults.credentials.length > 0 && promptData.prompts.credentials.value.length === 0" class="Prompt-noSelectedItem">{{:: vm.strings.get('prompt.NO_CREDENTIALS_SELECTED') }}</div>
|
||||
<div class="Prompt-previewTags--inner">
|
||||
<div class="MultiCredential-tagContainer"
|
||||
ng-class="{'MultiCredential-tagContainer--disabled': !promptData.launchConf.ask_credential_on_launch}"
|
||||
@ -39,6 +39,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="promptData.credentialTypeMissing && promptData.credentialTypeMissing.length > 0" class="Prompt-credentialTypeMissing">
|
||||
<div ng-repeat="missingCred in promptData.credentialTypeMissing">
|
||||
<span class="fa fa-warning"></span> {{:: vm.strings.get('prompt.CREDENTIAL_TYPE_MISSING', missingCred.label) }}
|
||||
</div>
|
||||
</div>
|
||||
<span ng-show="promptData.launchConf.ask_credential_on_launch">
|
||||
<div class="Prompt-credentialSubSection">
|
||||
<span class="Prompt-label">{{:: vm.strings.get('prompt.CREDENTIAL_TYPE') }}:</span>
|
||||
|
||||
@ -31,7 +31,7 @@ export default
|
||||
};
|
||||
|
||||
vm.revert = () => {
|
||||
scope.promptData.prompts.inventory.value = scope.promptData.prompts.inventory.templateDefault;
|
||||
scope.promptData.prompts.inventory.value = scope.promptData.launchConf.defaults.inventory;
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
<div>
|
||||
<div class="Prompt-selectedItem">
|
||||
<div class="Prompt-selectedItemInfo" ng-hide="!promptData.prompts.inventory.value.id && !promptData.prompts.inventory.templateDefault.id">
|
||||
<div class="Prompt-selectedItemInfo" ng-hide="!promptData.prompts.inventory.value.id && !promptData.launchConf.defaults.inventory.id">
|
||||
<div class="Prompt-selectedItemLabel">
|
||||
<span>{{:: vm.strings.get('prompt.SELECTED') }}</span>
|
||||
</div>
|
||||
<div class="Prompt-previewTags--outer">
|
||||
<div ng-show="promptData.prompts.inventory.templateDefault.id && !promptData.prompts.inventory.value.id" class="Prompt-noSelectedItem">{{:: vm.strings.get('prompt.NO_INVENTORY_SELECTED') }}</div>
|
||||
<div ng-show="promptData.launchConf.defaults.inventory.id && !promptData.prompts.inventory.value.id" class="Prompt-noSelectedItem">{{:: vm.strings.get('prompt.NO_INVENTORY_SELECTED') }}</div>
|
||||
<div class="Prompt-previewTags--inner" ng-hide="!promptData.prompts.inventory.value.id">
|
||||
<div class="Prompt-previewTagContainer">
|
||||
<div class="Prompt-previewTag Prompt-previewTag--deletable">
|
||||
@ -18,7 +18,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="Prompt-previewTagRevert">
|
||||
<a class="Prompt-revertLink" href="" ng-hide="promptData.prompts.inventory.value.id === promptData.prompts.inventory.templateDefault.id" ng-click="vm.revert()">{{:: vm.strings.get('prompt.REVERT') }}</a>
|
||||
<a class="Prompt-revertLink" href="" ng-hide="promptData.prompts.inventory.value.id === promptData.launchConf.defaults.inventory.id" ng-click="vm.revert()">{{:: vm.strings.get('prompt.REVERT') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user