diff --git a/awx/ui/client/src/organizations/add/organizations-add.controller.js b/awx/ui/client/src/organizations/add/organizations-add.controller.js
index 009f9240e6..4b6e4a5e66 100644
--- a/awx/ui/client/src/organizations/add/organizations-add.controller.js
+++ b/awx/ui/client/src/organizations/add/organizations-add.controller.js
@@ -6,26 +6,32 @@
export default ['$scope', '$rootScope', '$location', '$stateParams',
'OrganizationForm', 'GenerateForm', 'Rest', 'Alert',
- 'ProcessErrors', 'GetBasePath', 'Wait', 'CreateSelect2', '$state','InstanceGroupsService',
+ 'ProcessErrors', 'GetBasePath', 'Wait', 'CreateSelect2', '$state','InstanceGroupsService', 'ConfigData',
function($scope, $rootScope, $location, $stateParams, OrganizationForm,
- GenerateForm, Rest, Alert, ProcessErrors, GetBasePath, Wait, CreateSelect2, $state, InstanceGroupsService) {
+ GenerateForm, Rest, Alert, ProcessErrors, GetBasePath, Wait, CreateSelect2, $state, InstanceGroupsService, ConfigData) {
Rest.setUrl(GetBasePath('organizations'));
Rest.options()
- .then(({data}) => {
- if (!data.actions.POST) {
- $state.go("^");
- Alert('Permission Error', 'You do not have permission to add an organization.', 'alert-info');
- }
- });
+ .then(({data}) => {
+ if (!data.actions.POST) {
+ $state.go("^");
+ Alert('Permission Error', 'You do not have permission to add an organization.', 'alert-info');
+ }
+ });
var form = OrganizationForm(),
- base = $location.path().replace(/^\//, '').split('/')[0];
+ base = $location.path().replace(/^\//, '').split('/')[0];
init();
function init(){
// @issue What is this doing, why
$scope.$emit("HideOrgListHeader");
+ $scope.custom_virtualenvs_options = ConfigData.custom_virtualenvs;
+ CreateSelect2({
+ element: '#organization_custom_virtualenv',
+ multiple: false,
+ opts: $scope.custom_virtualenvs_options
+ });
// apply form definition's default field values
GenerateForm.applyDefaults(form, $scope);
@@ -39,7 +45,8 @@ export default ['$scope', '$rootScope', '$location', '$stateParams',
Rest.setUrl(url);
Rest.post({
name: $scope.name,
- description: $scope.description
+ description: $scope.description,
+ custom_virtualenv: $scope.custom_virtualenv
})
.then(({data}) => {
const organization_id = data.id,
diff --git a/awx/ui/client/src/organizations/edit/organizations-edit.controller.js b/awx/ui/client/src/organizations/edit/organizations-edit.controller.js
index 3cf0c5fc5f..d44ee45746 100644
--- a/awx/ui/client/src/organizations/edit/organizations-edit.controller.js
+++ b/awx/ui/client/src/organizations/edit/organizations-edit.controller.js
@@ -6,10 +6,10 @@
export default ['$scope', '$location', '$stateParams',
'OrganizationForm', 'Rest', 'ProcessErrors', 'Prompt',
- 'GetBasePath', 'Wait', '$state', 'ToggleNotification', 'CreateSelect2', 'InstanceGroupsService', 'InstanceGroupsData',
+ 'GetBasePath', 'Wait', '$state', 'ToggleNotification', 'CreateSelect2', 'InstanceGroupsService', 'InstanceGroupsData', 'ConfigData',
function($scope, $location, $stateParams,
OrganizationForm, Rest, ProcessErrors, Prompt,
- GetBasePath, Wait, $state, ToggleNotification, CreateSelect2, InstanceGroupsService, InstanceGroupsData) {
+ GetBasePath, Wait, $state, ToggleNotification, CreateSelect2, InstanceGroupsService, InstanceGroupsData, ConfigData) {
let form = OrganizationForm(),
defaultUrl = GetBasePath('organizations'),
@@ -29,6 +29,7 @@ export default ['$scope', '$location', '$stateParams',
$scope.$emit("HideOrgListHeader");
$scope.instance_groups = InstanceGroupsData;
+ $scope.custom_virtualenvs_options = ConfigData.custom_virtualenvs;
}
@@ -36,20 +37,26 @@ export default ['$scope', '$location', '$stateParams',
Wait('start');
Rest.setUrl(defaultUrl + id + '/');
Rest.get()
- .then(({data}) => {
- let fld;
+ .then(({data}) => {
+ let fld;
- $scope.organization_name = data.name;
- for (fld in form.fields) {
- if (data[fld]) {
- $scope[fld] = data[fld];
- master[fld] = data[fld];
- }
+ $scope.organization_name = data.name;
+ for (fld in form.fields) {
+ if (data[fld]) {
+ $scope[fld] = data[fld];
+ master[fld] = data[fld];
}
+ }
- $scope.organization_obj = data;
- $scope.$emit('organizationLoaded');
- Wait('stop');
+ CreateSelect2({
+ element: '#organization_custom_virtualenv',
+ multiple: false,
+ opts: $scope.custom_virtualenvs_options
+ });
+
+ $scope.organization_obj = data;
+ $scope.$emit('organizationLoaded');
+ Wait('stop');
});
$scope.toggleNotification = function(event, id, column) {
diff --git a/awx/ui/client/src/organizations/main.js b/awx/ui/client/src/organizations/main.js
index 128676263d..bb21bfb6c0 100644
--- a/awx/ui/client/src/organizations/main.js
+++ b/awx/ui/client/src/organizations/main.js
@@ -55,7 +55,15 @@ angular.module('Organizations', [
activityStreamTarget: 'organization'
},
resolve: {
+ add: {
+ ConfigData: ['ConfigService', (ConfigService) => {
+ return ConfigService.getConfig().then(response => response);
+ }]
+ },
edit: {
+ ConfigData: ['ConfigService', (ConfigService) => {
+ return ConfigService.getConfig().then(response => response);
+ }],
InstanceGroupsData: ['$stateParams', 'Rest', 'GetBasePath', 'ProcessErrors',
function($stateParams, Rest, GetBasePath, ProcessErrors){
let path = `${GetBasePath('organizations')}${$stateParams.organization_id}/instance_groups/`;
diff --git a/awx/ui/client/src/organizations/organizations.form.js b/awx/ui/client/src/organizations/organizations.form.js
index 2a79118d70..14883a3428 100644
--- a/awx/ui/client/src/organizations/organizations.form.js
+++ b/awx/ui/client/src/organizations/organizations.form.js
@@ -42,6 +42,17 @@ export default ['NotificationsList', 'i18n',
dataContainer: 'body',
dataPlacement: 'right',
control: '
" + i18n._("Select the custom Python virtual environment for this organization to run on.") + "
", + dataTitle: i18n._('Ansible Environment'), + dataContainer: 'body', + dataPlacement: 'right', + ngDisabled: '!(organization_obj.summary_fields.user_capabilities.edit || canAdd)' } }, diff --git a/awx/ui/client/src/projects/add/projects-add.controller.js b/awx/ui/client/src/projects/add/projects-add.controller.js index e4304ccb32..a5ccdbdbf2 100644 --- a/awx/ui/client/src/projects/add/projects-add.controller.js +++ b/awx/ui/client/src/projects/add/projects-add.controller.js @@ -7,12 +7,12 @@ export default ['$scope', '$location', '$stateParams', 'GenerateForm', 'ProjectsForm', 'Rest', 'Alert', 'ProcessErrors', 'GetBasePath', 'GetProjectPath', 'GetChoices', 'Wait', '$state', 'CreateSelect2', 'i18n', - 'CredentialTypes', + 'CredentialTypes', 'ConfigData', function($scope, $location, $stateParams, GenerateForm, ProjectsForm, Rest, Alert, ProcessErrors, GetBasePath, GetProjectPath, GetChoices, Wait, $state, - CreateSelect2, i18n, CredentialTypes) { + CreateSelect2, i18n, CredentialTypes, ConfigData) { - var form = ProjectsForm(), + let form = ProjectsForm(), base = $location.path().replace(/^\//, '').split('/')[0], defaultUrl = GetBasePath('projects'), master = {}; @@ -21,13 +21,21 @@ export default ['$scope', '$location', '$stateParams', 'GenerateForm', function init() { $scope.canEditOrg = true; + $scope.custom_virtualenvs_options = ConfigData.custom_virtualenvs; + Rest.setUrl(GetBasePath('projects')); Rest.options() - .then(({data}) => { - if (!data.actions.POST) { - $state.go("^"); - Alert(i18n._('Permission Error'), i18n._('You do not have permission to add a project.'), 'alert-info'); - } + .then(({data}) => { + if (!data.actions.POST) { + $state.go("^"); + Alert(i18n._('Permission Error'), i18n._('You do not have permission to add a project.'), 'alert-info'); + } + }); + + CreateSelect2({ + element: '#project_custom_virtualenv', + multiple: false, + opts: $scope.custom_virtualenvs_options }); // apply form definition's default field values diff --git a/awx/ui/client/src/projects/edit/projects-edit.controller.js b/awx/ui/client/src/projects/edit/projects-edit.controller.js index 7d1acb1bc1..457a21545a 100644 --- a/awx/ui/client/src/projects/edit/projects-edit.controller.js +++ b/awx/ui/client/src/projects/edit/projects-edit.controller.js @@ -8,14 +8,14 @@ export default ['$scope', '$rootScope', '$stateParams', 'ProjectsForm', 'Rest', 'Alert', 'ProcessErrors', 'GenerateForm', 'Prompt', 'GetBasePath', 'GetProjectPath', 'Authorization', 'GetChoices', 'Empty', 'Wait', 'ProjectUpdate', '$state', 'CreateSelect2', 'ToggleNotification', - 'i18n', 'CredentialTypes', 'OrgAdminLookup', + 'i18n', 'CredentialTypes', 'OrgAdminLookup', 'ConfigData', function($scope, $rootScope, $stateParams, ProjectsForm, Rest, Alert, ProcessErrors, GenerateForm, Prompt, GetBasePath, GetProjectPath, Authorization, GetChoices, Empty, Wait, ProjectUpdate, $state, CreateSelect2, ToggleNotification, i18n, CredentialTypes, - OrgAdminLookup) { + OrgAdminLookup, ConfigData) { - var form = ProjectsForm(), + let form = ProjectsForm(), defaultUrl = GetBasePath('projects') + $stateParams.project_id + '/', master = {}, id = $stateParams.project_id; @@ -25,6 +25,7 @@ export default ['$scope', '$rootScope', '$stateParams', 'ProjectsForm', 'Rest', function init() { $scope.project_local_paths = []; $scope.base_dir = ''; + $scope.custom_virtualenvs_options = ConfigData.custom_virtualenvs; } $scope.$watch('project_obj.summary_fields.user_capabilities.edit', function(val) { @@ -147,6 +148,12 @@ export default ['$scope', '$rootScope', '$stateParams', 'ProjectsForm', 'Rest', $scope.canEditOrg = canEditOrg; }); + CreateSelect2({ + element: '#project_custom_virtualenv', + multiple: false, + opts: $scope.custom_virtualenvs_options + }); + $scope.project_obj = data; $scope.name = data.name; $scope.$emit('projectLoaded'); diff --git a/awx/ui/client/src/projects/main.js b/awx/ui/client/src/projects/main.js index 7bd3616c23..c997f2a5c0 100644 --- a/awx/ui/client/src/projects/main.js +++ b/awx/ui/client/src/projects/main.js @@ -32,7 +32,7 @@ angular.module('Projects', []) let stateDefinitions = stateDefinitionsProvider.$get(); let stateExtender = $stateExtenderProvider.$get(); var projectResolve = { - CredentialTypes: ['Rest', '$stateParams', 'GetBasePath', 'ProcessErrors', + CredentialTypes: ['Rest', '$stateParams', 'GetBasePath', 'ProcessErrors', (Rest, $stateParams, GetBasePath, ProcessErrors) => { var path = GetBasePath('credential_types'); Rest.setUrl(path); @@ -47,7 +47,10 @@ angular.module('Projects', []) }); }); } - ] + ], + ConfigData: ['ConfigService', (ConfigService) => { + return ConfigService.getConfig().then(response => response); + }] }; function generateStateTree() { diff --git a/awx/ui/client/src/projects/projects.form.js b/awx/ui/client/src/projects/projects.form.js index a9d6762860..7982175d78 100644 --- a/awx/ui/client/src/projects/projects.form.js +++ b/awx/ui/client/src/projects/projects.form.js @@ -52,6 +52,17 @@ export default ['i18n', 'NotificationsList', 'TemplateList', ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd) || !canEditOrg', awLookupWhen: '(project_obj.summary_fields.user_capabilities.edit || canAdd) && canEditOrg' }, + custom_virtualenv: { + label: i18n._('Ansible Environment'), + type: 'select', + defaultText: i18n._('Select Ansible Environment'), + ngOptions: 'venv for venv in custom_virtualenvs_options track by venv', + awPopOver: "" + i18n._("Select the custom Python virtual environment for this project to run on.") + "
", + dataTitle: i18n._('Ansible Environment'), + dataContainer: 'body', + dataPlacement: 'right', + ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)' + }, scm_type: { label: i18n._('SCM Type'), type: 'select', diff --git a/awx/ui/client/src/templates/job_templates/add-job-template/job-template-add.controller.js b/awx/ui/client/src/templates/job_templates/add-job-template/job-template-add.controller.js index b213d3d498..10754cb0e7 100644 --- a/awx/ui/client/src/templates/job_templates/add-job-template/job-template-add.controller.js +++ b/awx/ui/client/src/templates/job_templates/add-job-template/job-template-add.controller.js @@ -9,13 +9,15 @@ '$stateParams', 'JobTemplateForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'GetBasePath', 'md5Setup', 'ParseTypeChange', 'Wait', 'Empty', 'ToJSON', 'CallbackHelpInit', 'GetChoices', '$state', 'availableLabels', - 'CreateSelect2', '$q', 'i18n', 'Inventory', 'Project', 'InstanceGroupsService', 'MultiCredentialService', + 'CreateSelect2', '$q', 'i18n', 'Inventory', 'Project', 'InstanceGroupsService', + 'MultiCredentialService', 'ConfigData', function( $filter, $scope, $stateParams, JobTemplateForm, GenerateForm, Rest, Alert, ProcessErrors, GetBasePath, md5Setup, ParseTypeChange, Wait, Empty, ToJSON, CallbackHelpInit, GetChoices, - $state, availableLabels, CreateSelect2, $q, i18n, Inventory, Project, InstanceGroupsService, MultiCredentialService + $state, availableLabels, CreateSelect2, $q, i18n, Inventory, Project, InstanceGroupsService, + MultiCredentialService, ConfigData ) { // Inject dynamic view @@ -50,12 +52,12 @@ $scope.surveyTooltip = i18n._('Please save before adding a survey to this job template.'); MultiCredentialService.getCredentialTypes() - .then(({ data }) => { - $scope.multiCredential = { - credentialTypes: data.results, - selectedCredentials: [] - }; - }); + .then(({ data }) => { + $scope.multiCredential = { + credentialTypes: data.results, + selectedCredentials: [] + }; + }); } callback = function() { @@ -80,6 +82,7 @@ } } $scope.job_type = $scope.job_type_options[form.fields.job_type.default]; + $scope.custom_virtualenvs_options = ConfigData.custom_virtualenvs; CreateSelect2({ element:'#job_template_job_type', @@ -109,6 +112,12 @@ multiple: true, addNew: true }); + + CreateSelect2({ + element: '#job_template_custom_virtualenv', + multiple: false, + opts: $scope.custom_virtualenvs_options + }); } }); @@ -259,7 +268,7 @@ try { for (fld in form.fields) { if (form.fields[fld].type === 'select' && - fld !== 'playbook' && $scope[fld]) { + fld !== 'playbook' && fld !== 'custom_virtualenv' && $scope[fld]) { data[fld] = $scope[fld].value; } else if(form.fields[fld].type === 'checkbox_group') { diff --git a/awx/ui/client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js b/awx/ui/client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js index c7cc71ce4b..38b32b2942 100644 --- a/awx/ui/client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js +++ b/awx/ui/client/src/templates/job_templates/edit-job-template/job-template-edit.controller.js @@ -17,16 +17,19 @@ export default 'ParseTypeChange', 'Wait', 'selectedLabels', 'i18n', 'Empty', 'Prompt', 'ToJSON', 'GetChoices', 'CallbackHelpInit', 'InitiatePlaybookRun' , 'initSurvey', '$state', 'CreateSelect2', - 'ToggleNotification','$q', 'InstanceGroupsService', 'InstanceGroupsData', 'MultiCredentialService', 'availableLabels', - 'projectGetPermissionDenied', 'inventoryGetPermissionDenied', 'jobTemplateData', 'ParseVariableString', + 'ToggleNotification','$q', 'InstanceGroupsService', 'InstanceGroupsData', + 'MultiCredentialService', 'availableLabels', 'projectGetPermissionDenied', + 'inventoryGetPermissionDenied', 'jobTemplateData', 'ParseVariableString', 'ConfigData', function( $filter, $scope, $rootScope, $location, $stateParams, JobTemplateForm, GenerateForm, Rest, Alert, ProcessErrors, GetBasePath, md5Setup, ParseTypeChange, Wait, selectedLabels, i18n, - Empty, Prompt, ToJSON, GetChoices, CallbackHelpInit, InitiatePlaybookRun, SurveyControllerInit, $state, - CreateSelect2, ToggleNotification, $q, InstanceGroupsService, InstanceGroupsData, MultiCredentialService, availableLabels, - projectGetPermissionDenied, inventoryGetPermissionDenied, jobTemplateData, ParseVariableString + Empty, Prompt, ToJSON, GetChoices, CallbackHelpInit, + InitiatePlaybookRun, SurveyControllerInit, $state, CreateSelect2, + ToggleNotification, $q, InstanceGroupsService, InstanceGroupsData, + MultiCredentialService, availableLabels, projectGetPermissionDenied, + inventoryGetPermissionDenied, jobTemplateData, ParseVariableString, ConfigData ) { $scope.$watch('job_template_obj.summary_fields.user_capabilities.edit', function(val) { @@ -60,6 +63,7 @@ export default $scope.surveyTooltip = i18n._('Surveys allow users to be prompted at job launch with a series of questions related to the job. This allows for variables to be defined that affect the playbook run at time of launch.'); $scope.job_tag_options = []; $scope.skip_tag_options = []; + $scope.custom_virtualenvs_options = ConfigData.custom_virtualenvs; SurveyControllerInit({ scope: $scope, @@ -198,6 +202,12 @@ export default multiple: true, addNew: true }); + + CreateSelect2({ + element: '#job_template_custom_virtualenv', + multiple: false, + opts: $scope.custom_virtualenvs_options + }); } $scope.toggleForm = function(key) { @@ -598,7 +608,7 @@ export default try { for (fld in form.fields) { if (form.fields[fld].type === 'select' && - fld !== 'playbook' && $scope[fld]) { + fld !== 'playbook' && fld !== 'custom_virtualenv' && $scope[fld]) { data[fld] = $scope[fld].value; } else if(form.fields[fld].type === 'checkbox_group') { diff --git a/awx/ui/client/src/templates/job_templates/job-template.form.js b/awx/ui/client/src/templates/job_templates/job-template.form.js index 02eaeff943..bb9d57467b 100644 --- a/awx/ui/client/src/templates/job_templates/job-template.form.js +++ b/awx/ui/client/src/templates/job_templates/job-template.form.js @@ -103,6 +103,17 @@ function(NotificationsList, CompletedJobsList, i18n) { ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAddJobTemplate) || !canGetAllRelatedResources', awLookupWhen: 'canGetAllRelatedResources' }, + custom_virtualenv: { + label: i18n._('Ansible Environment'), + type: 'select', + defaultText: i18n._('Select Ansible Environment'), + ngOptions: 'venv for venv in custom_virtualenvs_options track by venv', + awPopOver: "" + i18n._("Select the custom Python virtual environment for this job template to run on.") + "
", + dataTitle: i18n._('Ansible Environment'), + dataContainer: 'body', + dataPlacement: 'right', + ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)' + }, playbook: { label: i18n._('Playbook'), type:'select', diff --git a/awx/ui/client/src/templates/main.js b/awx/ui/client/src/templates/main.js index 5d1eee77d8..21ec6ce323 100644 --- a/awx/ui/client/src/templates/main.js +++ b/awx/ui/client/src/templates/main.js @@ -129,7 +129,10 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p response.status }); }); - }] + }], + ConfigData: ['ConfigService', (ConfigService) => { + return ConfigService.getConfig().then(response => response); + }] } } }); @@ -260,6 +263,9 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p response.status }); }); + }], + ConfigData: ['ConfigService', (ConfigService) => { + return ConfigService.getConfig().then(response => response); }] } }