mirror of
https://github.com/ansible/awx.git
synced 2026-03-10 14:09:28 -02:30
Merge pull request #3165 from mabashian/2630-become-plugins
Makes priv escalation method a dynamic select element Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
This commit is contained in:
@@ -1,4 +1,11 @@
|
|||||||
function AddCredentialsController (models, $state, $scope, strings, componentsStrings) {
|
function AddCredentialsController (
|
||||||
|
models,
|
||||||
|
$state,
|
||||||
|
$scope,
|
||||||
|
strings,
|
||||||
|
componentsStrings,
|
||||||
|
ConfigService
|
||||||
|
) {
|
||||||
const vm = this || {};
|
const vm = this || {};
|
||||||
|
|
||||||
const { me, credential, credentialType, organization } = models;
|
const { me, credential, credentialType, organization } = models;
|
||||||
@@ -48,6 +55,11 @@ function AddCredentialsController (models, $state, $scope, strings, componentsSt
|
|||||||
if (credentialType.get('name') === 'Google Compute Engine') {
|
if (credentialType.get('name') === 'Google Compute Engine') {
|
||||||
fields.splice(2, 0, gceFileInputSchema);
|
fields.splice(2, 0, gceFileInputSchema);
|
||||||
$scope.$watch(`vm.form.${gceFileInputSchema.id}._value`, vm.gceOnFileInputChanged);
|
$scope.$watch(`vm.form.${gceFileInputSchema.id}._value`, vm.gceOnFileInputChanged);
|
||||||
|
} else if (credentialType.get('name') === 'Machine') {
|
||||||
|
const apiConfig = ConfigService.get();
|
||||||
|
const become = fields.find((field) => field.id === 'become_method');
|
||||||
|
become._isDynamic = true;
|
||||||
|
become._choices = Array.from(apiConfig.become_methods, method => method[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
@@ -136,7 +148,8 @@ AddCredentialsController.$inject = [
|
|||||||
'$state',
|
'$state',
|
||||||
'$scope',
|
'$scope',
|
||||||
'CredentialsStrings',
|
'CredentialsStrings',
|
||||||
'ComponentsStrings'
|
'ComponentsStrings',
|
||||||
|
'ConfigService'
|
||||||
];
|
];
|
||||||
|
|
||||||
export default AddCredentialsController;
|
export default AddCredentialsController;
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
function EditCredentialsController (models, $state, $scope, strings, componentsStrings) {
|
function EditCredentialsController (
|
||||||
|
models,
|
||||||
|
$state,
|
||||||
|
$scope,
|
||||||
|
strings,
|
||||||
|
componentsStrings,
|
||||||
|
ConfigService
|
||||||
|
) {
|
||||||
const vm = this || {};
|
const vm = this || {};
|
||||||
|
|
||||||
const { me, credential, credentialType, organization, isOrgCredAdmin } = models;
|
const { me, credential, credentialType, organization, isOrgCredAdmin } = models;
|
||||||
@@ -103,6 +110,19 @@ function EditCredentialsController (models, $state, $scope, strings, componentsS
|
|||||||
|
|
||||||
$scope.$watch(`vm.form.${gceFileInputSchema.id}._value`, vm.gceOnFileInputChanged);
|
$scope.$watch(`vm.form.${gceFileInputSchema.id}._value`, vm.gceOnFileInputChanged);
|
||||||
$scope.$watch('vm.form.ssh_key_data._isBeingReplaced', vm.gceOnReplaceKeyChanged);
|
$scope.$watch('vm.form.ssh_key_data._isBeingReplaced', vm.gceOnReplaceKeyChanged);
|
||||||
|
} else if (credentialType.get('name') === 'Machine') {
|
||||||
|
const apiConfig = ConfigService.get();
|
||||||
|
const become = fields.find((field) => field.id === 'become_method');
|
||||||
|
become._isDynamic = true;
|
||||||
|
become._choices = Array.from(apiConfig.become_methods, method => method[0]);
|
||||||
|
// Add the value to the choices if it doesn't exist in the preset list
|
||||||
|
if (become._value && become._value !== '') {
|
||||||
|
const optionMatches = become._choices
|
||||||
|
.findIndex((option) => option === become._value);
|
||||||
|
if (optionMatches === -1) {
|
||||||
|
become._choices.push(become._value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
@@ -189,7 +209,8 @@ EditCredentialsController.$inject = [
|
|||||||
'$state',
|
'$state',
|
||||||
'$scope',
|
'$scope',
|
||||||
'CredentialsStrings',
|
'CredentialsStrings',
|
||||||
'ComponentsStrings'
|
'ComponentsStrings',
|
||||||
|
'ConfigService'
|
||||||
];
|
];
|
||||||
|
|
||||||
export default EditCredentialsController;
|
export default EditCredentialsController;
|
||||||
|
|||||||
@@ -377,6 +377,7 @@
|
|||||||
|
|
||||||
.select2-results__option {
|
.select2-results__option {
|
||||||
color: @field-label !important;
|
color: @field-label !important;
|
||||||
|
min-height: 33px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select2-container--default .select2-results__option--highlighted[aria-selected] {
|
.select2-container--default .select2-results__option--highlighted[aria-selected] {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import atLibServices from '~services';
|
|||||||
|
|
||||||
import actionGroup from '~components/action/action-group.directive';
|
import actionGroup from '~components/action/action-group.directive';
|
||||||
import divider from '~components/utility/divider.directive';
|
import divider from '~components/utility/divider.directive';
|
||||||
|
import dynamicSelect from '~components/input/dynamic-select.directive';
|
||||||
import form from '~components/form/form.directive';
|
import form from '~components/form/form.directive';
|
||||||
import formAction from '~components/form/action.directive';
|
import formAction from '~components/form/action.directive';
|
||||||
import inputCheckbox from '~components/input/checkbox.directive';
|
import inputCheckbox from '~components/input/checkbox.directive';
|
||||||
@@ -53,6 +54,7 @@ angular
|
|||||||
])
|
])
|
||||||
.directive('atActionGroup', actionGroup)
|
.directive('atActionGroup', actionGroup)
|
||||||
.directive('atDivider', divider)
|
.directive('atDivider', divider)
|
||||||
|
.directive('atDynamicSelect', dynamicSelect)
|
||||||
.directive('atForm', form)
|
.directive('atForm', form)
|
||||||
.directive('atFormAction', formAction)
|
.directive('atFormAction', formAction)
|
||||||
.directive('atInputCheckbox', inputCheckbox)
|
.directive('atInputCheckbox', inputCheckbox)
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
const templateUrl = require('~components/input/dynamic-select.partial.html');
|
||||||
|
|
||||||
|
function atDynamicSelectLink (scope, element, attrs, controllers) {
|
||||||
|
const [formController, inputController] = controllers;
|
||||||
|
|
||||||
|
inputController.init(scope, element, formController);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AtDynamicSelectController (baseInputController, CreateSelect2) {
|
||||||
|
const vm = this || {};
|
||||||
|
|
||||||
|
let scope;
|
||||||
|
|
||||||
|
vm.init = (_scope_, _element_, form) => {
|
||||||
|
baseInputController.call(vm, 'input', _scope_, _element_, form);
|
||||||
|
scope = _scope_;
|
||||||
|
CreateSelect2({
|
||||||
|
element: `#${scope.state._formId}_${scope.state.id}_dynamic_select`,
|
||||||
|
model: 'state._value',
|
||||||
|
multiple: false,
|
||||||
|
addNew: true,
|
||||||
|
scope,
|
||||||
|
options: 'state._data'
|
||||||
|
});
|
||||||
|
vm.check();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
AtDynamicSelectController.$inject = ['BaseInputController', 'CreateSelect2'];
|
||||||
|
|
||||||
|
function atDynamicSelect () {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
transclude: true,
|
||||||
|
replace: true,
|
||||||
|
require: ['^^at-form', 'atDynamicSelect'],
|
||||||
|
templateUrl,
|
||||||
|
controller: AtDynamicSelectController,
|
||||||
|
controllerAs: 'vm',
|
||||||
|
link: atDynamicSelectLink,
|
||||||
|
scope: {
|
||||||
|
state: '=',
|
||||||
|
col: '@',
|
||||||
|
tab: '@'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default atDynamicSelect;
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<div class="col-sm-{{::col}} at-InputContainer">
|
||||||
|
<div class="form-group at-u-flat">
|
||||||
|
<at-input-label></at-input-label>
|
||||||
|
<div class="at-InputSelect">
|
||||||
|
<select class="form-control at-InputSelect-select"
|
||||||
|
ng-model="state._value"
|
||||||
|
ng-attr-tabindex="{{ tab || undefined }}"
|
||||||
|
ng-disabled="state._disabled || form.disabled"
|
||||||
|
id="{{ state._formId }}_{{ state.id }}_dynamic_select">
|
||||||
|
<option value=""></option>
|
||||||
|
<option ng-repeat="option in state._data" label="{{option}}" value="{{option}}">{{option}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<at-input-message></at-input-message>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -75,10 +75,18 @@ function AtInputGroupController ($scope, $compile) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
vm.getComponentType = input => {
|
vm.getComponentType = input => {
|
||||||
const config = {};
|
const config = {
|
||||||
|
_formId: formId
|
||||||
|
};
|
||||||
|
|
||||||
if (input.type === 'string') {
|
if (input.type === 'string') {
|
||||||
if (!input.multiline) {
|
if (input._isDynamic) {
|
||||||
|
config._component = 'at-dynamic-select';
|
||||||
|
config._format = 'array';
|
||||||
|
config._data = input._choices;
|
||||||
|
config._exp = 'choice for (index, choice) in state._data';
|
||||||
|
config._isDynamic = true;
|
||||||
|
} else if (!input.multiline) {
|
||||||
if (input.secret) {
|
if (input.secret) {
|
||||||
config._component = 'at-input-secret';
|
config._component = 'at-input-secret';
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -596,7 +596,7 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
|||||||
minimumResultsForSearch = params.minimumResultsForSearch ? params.minimumResultsForSearch : Infinity;
|
minimumResultsForSearch = params.minimumResultsForSearch ? params.minimumResultsForSearch : Infinity;
|
||||||
|
|
||||||
if (scope && selectOptions) {
|
if (scope && selectOptions) {
|
||||||
original_options = _.cloneDeep(scope[selectOptions]);
|
original_options = _.get(scope, selectOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
$.fn.select2.amd.require([
|
$.fn.select2.amd.require([
|
||||||
@@ -675,13 +675,16 @@ angular.module('Utilities', ['RestServices', 'Utilities'])
|
|||||||
|
|
||||||
if (addNew && !multiple) {
|
if (addNew && !multiple) {
|
||||||
$(element).on('select2:select', (e) => {
|
$(element).on('select2:select', (e) => {
|
||||||
scope[model] = e.params.data.text;
|
_.set(scope, model, e.params.data.text);
|
||||||
scope[selectOptions] = _.cloneDeep(original_options);
|
const optionsClone = _.clone(original_options);
|
||||||
|
_.set(scope, selectOptions, optionsClone);
|
||||||
if (e.params.data.id === "") {
|
if (e.params.data.id === "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (scope[selectOptions].indexOf(e.params.data.text) === -1) {
|
const optionMatches = original_options.findIndex((option) => option === e.params.data.text);
|
||||||
scope[selectOptions].push(e.params.data.text);
|
if (optionMatches === -1) {
|
||||||
|
optionsClone.push(e.params.data.text);
|
||||||
|
_.set(scope, selectOptions, optionsClone);
|
||||||
}
|
}
|
||||||
$(element).select2(config);
|
$(element).select2(config);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user