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 2d8ad53545..4ba5a4c13f 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 @@ -281,6 +281,12 @@ } else { data.credential = null; } + if ($scope.selectedCredentials && $scope.selectedCredentials + .vault && $scope.selectedCredentials + .vault.id) { + data.vault_credential = $scope.selectedCredentials + .vault.id; + } data.extra_vars = ToJSON($scope.parseType, $scope.variables, true); 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 a357ae9c19..e16a8fb57f 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 @@ -487,13 +487,18 @@ export default data.skip_tags = (Array.isArray($scope.skip_tags)) ? $scope.skip_tags.join() : ""; if ($scope.selectedCredentials && $scope.selectedCredentials .machine && $scope.selectedCredentials - .machine) { + .machine.id) { data.credential = $scope.selectedCredentials .machine.id; } else { data.credential = null; } - + if ($scope.selectedCredentials && $scope.selectedCredentials + .vault && $scope.selectedCredentials + .vault.id) { + data.vault_credential = $scope.selectedCredentials + .vault.id; + } data.extra_vars = ToJSON($scope.parseType, $scope.variables, true); diff --git a/awx/ui/client/src/templates/job_templates/multi-credential/multi-credential-modal.directive.js b/awx/ui/client/src/templates/job_templates/multi-credential/multi-credential-modal.directive.js index de26d37d96..64822702d6 100644 --- a/awx/ui/client/src/templates/job_templates/multi-credential/multi-credential-modal.directive.js +++ b/awx/ui/client/src/templates/job_templates/multi-credential/multi-credential-modal.directive.js @@ -83,6 +83,21 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile' $scope.credentialTypeOptions); }; + let updateVaultCredentialList = function() { + $scope.credentials.forEach(cred => { + if (cred.credential_type === 3) { + cred.checked = ($scope.selectedCredentials + .vault !== null && + cred.id === $scope.selectedCredentials + .vault.id) ? 1 : 0; + } + }); + + $scope.credTags = MultiCredentialService + .updateCredentialTags($scope.selectedCredentials, + $scope.credentialTypeOptions); + }; + let uncheckAllCredentials = function() { $scope.credentials.forEach(cred => { cred.checked = 0; @@ -156,6 +171,16 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile' } }); + $scope.$watch('selectedCredentials.vault', () => { + if($scope.selectedCredentials && + $scope.selectedCredentials.vault && + parseInt($scope.credentialKind) === 3) { + updateVaultCredentialList(); + } else { + uncheckAllCredentials(); + } + }); + $scope.$watchGroup(['credentials', 'selectedCredentials.machine'], () => { if($scope.credentials && @@ -164,6 +189,10 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile' $scope.selectedCredentials.machine && parseInt($scope.credentialKind) === 1) { updateMachineCredentialList(); + } else if($scope.selectedCredentials && + $scope.selectedCredentials.vault && + parseInt($scope.credentialKind) === 3) { + updateVaultCredentialList(); } else if($scope.selectedCredentials && $scope.selectedCredentials.extra && $scope.selectedCredentials.extra.length > 0 && @@ -189,6 +218,14 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile' } else { $scope.selectedCredentials.machine = _.cloneDeep(selectedRow); } + }else if(parseInt($scope.credentialKind) === 3) { + if($scope.selectedCredentials && + $scope.selectedCredentials.vault && + $scope.selectedCredentials.vault.id === selectedRow.id) { + $scope.selectedCredentials.vault = null; + } else { + $scope.selectedCredentials.vault = _.cloneDeep(selectedRow); + } } else { let rowDeselected = false; for (let i = $scope.selectedCredentials.extra.length - 1; i >= 0; i--) { @@ -211,6 +248,7 @@ export default ['templateUrl', 'Rest', 'GetBasePath', 'generateList', '$compile' $scope.selectedCredentialsDirty = function() { if ($scope.originalSelectedCredentials) { return !($scope.originalSelectedCredentials.machine === null && + $scope.originalSelectedCredentials.vault === null && $scope.originalSelectedCredentials.extra.length === 0) && !_.isEqual($scope.selectedCredentials, $scope.originalSelectedCredentials); diff --git a/awx/ui/client/src/templates/job_templates/multi-credential/multi-credential.service.js b/awx/ui/client/src/templates/job_templates/multi-credential/multi-credential.service.js index 33d5f7ffba..e114b92050 100644 --- a/awx/ui/client/src/templates/job_templates/multi-credential/multi-credential.service.js +++ b/awx/ui/client/src/templates/job_templates/multi-credential/multi-credential.service.js @@ -84,7 +84,7 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro data.results.forEach((credentialType => { credential_types[credentialType.id] = credentialType; if(credentialType.kind - .match(/^(machine|cloud|net|ssh)$/)) { + .match(/^(machine|cloud|net|ssh|vault)$/)) { credentialTypeOptions.push({ name: credentialType.name, value: credentialType.id @@ -111,6 +111,7 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro val.updateCredentialTags = (creds, typeOpts) => { let machineCred = []; let extraCreds = []; + let vaultCred = []; if (creds.machine) { let mach = creds.machine; @@ -118,6 +119,12 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro machineCred = [mach]; } + if (creds.vault) { + let vault = creds.vault; + vault.postType = "vault"; + vaultCred = [vault]; + } + if (creds.extra) { extraCreds = creds.extra .map((cred) => { @@ -127,7 +134,7 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro }); } - return machineCred.concat(extraCreds).map(cred => ({ + return machineCred.concat(extraCreds).concat(vaultCred).map(cred => ({ name: cred.name, id: cred.id, postType: cred.postType, @@ -145,6 +152,8 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro if (credToRemove === cred.id) { if (cred.postType === 'machine') { structuredObj[cred.postType] = null; + } else if (cred.postType === 'vault') { + structuredObj[cred.postType] = null; } else { structuredObj[cred.postType] = structuredObj[cred.postType] .filter(cred => cred @@ -163,6 +172,7 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro val.loadCredentials = (data) => { let selectedCredentials = { machine: null, + vault: null, extra: [] }, credTypes, credTypeOptions, credTags; @@ -187,6 +197,24 @@ export default ['Rest', 'ProcessErrors', '$q', 'GetBasePath', function(Rest, Pro })); } + if (data.related.vault_credential) { + Rest.setUrl(data.related.vault_credential); + credDefers.push(Rest.get() + .then(({data}) => { + selectedCredentials.vault = data; + }) + .catch(({data, status}) => { + ProcessErrors( + null, data, status, null, + { + hdr: 'Error!', + msg: 'Failed to get machine credential. ' + + 'Get returned status: ' + + status + }); + })); + } + // get extra credentials if (data.related.extra_credentials) { Rest.setUrl(data.related.extra_credentials);