diff --git a/awx/ui/client/features/credentials/add-credentials.controller.js b/awx/ui/client/features/credentials/add-credentials.controller.js
index f0e4445669..5c9abcfbba 100644
--- a/awx/ui/client/features/credentials/add-credentials.controller.js
+++ b/awx/ui/client/features/credentials/add-credentials.controller.js
@@ -1,4 +1,4 @@
-function AddCredentialsController (models, $state, strings) {
+function AddCredentialsController (models, $state, $scope, strings, componentsStrings) {
const vm = this || {};
const { me, credential, credentialType, organization } = models;
@@ -28,11 +28,27 @@ function AddCredentialsController (models, $state, strings) {
vm.form.credential_type._model = credentialType;
vm.form.credential_type._placeholder = strings.get('inputs.CREDENTIAL_TYPE_PLACEHOLDER');
+ const gceFileInputSchema = {
+ id: 'gce_service_account_key',
+ type: 'file',
+ label: strings.get('inputs.GCE_FILE_INPUT_LABEL'),
+ help_text: strings.get('inputs.GCE_FILE_INPUT_HELP_TEXT'),
+ };
+
+ let gceFileInputPreEditValues;
+
vm.form.inputs = {
_get: () => {
credentialType.mergeInputProperties();
- return credentialType.get('inputs.fields');
+ const fields = credentialType.get('inputs.fields');
+
+ if (credentialType.get('name') === 'Google Compute Engine') {
+ fields.splice(2, 0, gceFileInputSchema);
+ $scope.$watch(`vm.form.${gceFileInputSchema.id}._value`, vm.gceOnFileInputChanged);
+ }
+
+ return fields;
},
_source: vm.form.credential_type,
_reference: 'vm.form.inputs',
@@ -42,18 +58,66 @@ function AddCredentialsController (models, $state, strings) {
vm.form.save = data => {
data.user = me.get('id');
+ delete data.inputs[gceFileInputSchema.id];
+
return credential.request('post', { data });
};
vm.form.onSaveSuccess = res => {
$state.go('credentials.edit', { credential_id: res.data.id }, { reload: true });
};
+
+ vm.gceOnFileInputChanged = (value, oldValue) => {
+ if (value === oldValue) return;
+
+ const gceFileIsLoaded = !!value;
+ const gceFileInputState = vm.form[gceFileInputSchema.id];
+ const { obj, error } = vm.gceParseFileInput(value);
+
+ gceFileInputState._isValid = !error;
+ gceFileInputState._message = error ? componentsStrings.get('message.INVALID_INPUT') : '';
+
+ vm.form.project._disabled = gceFileIsLoaded;
+ vm.form.username._disabled = gceFileIsLoaded;
+ vm.form.ssh_key_data._disabled = gceFileIsLoaded;
+ vm.form.ssh_key_data._displayHint = !vm.form.ssh_key_data._disabled;
+
+ if (gceFileIsLoaded) {
+ gceFileInputPreEditValues = Object.assign({}, {
+ project: vm.form.project._value,
+ ssh_key_data: vm.form.ssh_key_data._value,
+ username: vm.form.username._value
+ });
+ vm.form.project._value = _.get(obj, 'project_id', '');
+ vm.form.ssh_key_data._value = _.get(obj, 'private_key', '');
+ vm.form.username._value = _.get(obj, 'client_email', '');
+ } else {
+ vm.form.project._value = gceFileInputPreEditValues.project;
+ vm.form.ssh_key_data._value = gceFileInputPreEditValues.ssh_key_data;
+ vm.form.username._value = gceFileInputPreEditValues.username;
+ }
+ };
+
+ vm.gceParseFileInput = value => {
+ let obj;
+ let error;
+
+ try {
+ obj = angular.fromJson(value);
+ } catch (err) {
+ error = err;
+ }
+
+ return { obj, error };
+ };
}
AddCredentialsController.$inject = [
'resolvedModels',
'$state',
- 'CredentialsStrings'
+ '$scope',
+ 'CredentialsStrings',
+ 'ComponentsStrings'
];
export default AddCredentialsController;
diff --git a/awx/ui/client/features/credentials/add-edit-credentials.view.html b/awx/ui/client/features/credentials/add-edit-credentials.view.html
index 39a4a1b20e..2019f403f1 100644
--- a/awx/ui/client/features/credentials/add-edit-credentials.view.html
+++ b/awx/ui/client/features/credentials/add-edit-credentials.view.html
@@ -14,9 +14,9 @@
-
+
-
+
{{:: vm.strings.get('inputs.GROUP_TITLE') }}
diff --git a/awx/ui/client/features/credentials/credentials.strings.js b/awx/ui/client/features/credentials/credentials.strings.js
index 958282aa09..cb6260ce55 100644
--- a/awx/ui/client/features/credentials/credentials.strings.js
+++ b/awx/ui/client/features/credentials/credentials.strings.js
@@ -17,7 +17,9 @@ function CredentialsStrings (BaseString) {
ns.inputs = {
GROUP_TITLE: t.s('Type Details'),
ORGANIZATION_PLACEHOLDER: t.s('SELECT AN ORGANIZATION'),
- CREDENTIAL_TYPE_PLACEHOLDER: t.s('SELECT A CREDENTIAL TYPE')
+ CREDENTIAL_TYPE_PLACEHOLDER: t.s('SELECT A CREDENTIAL TYPE'),
+ GCE_FILE_INPUT_LABEL: t.s('Service Account JSON File'),
+ GCE_FILE_INPUT_HELP_TEXT: t.s('Provide account information using Google Compute Engine JSON credentials file.')
};
ns.add = {
diff --git a/awx/ui/client/features/credentials/edit-credentials.controller.js b/awx/ui/client/features/credentials/edit-credentials.controller.js
index e0a36c106f..a7629a68e1 100644
--- a/awx/ui/client/features/credentials/edit-credentials.controller.js
+++ b/awx/ui/client/features/credentials/edit-credentials.controller.js
@@ -1,4 +1,4 @@
-function EditCredentialsController (models, $state, $scope, strings) {
+function EditCredentialsController (models, $state, $scope, strings, componentsStrings) {
const vm = this || {};
const { me, credential, credentialType, organization } = models;
@@ -64,15 +64,35 @@ function EditCredentialsController (models, $state, $scope, strings) {
vm.form.credential_type._displayValue = credentialType.get('name');
vm.form.credential_type._placeholder = strings.get('inputs.CREDENTIAL_TYPE_PLACEHOLDER');
+ const gceFileInputSchema = {
+ id: 'gce_service_account_key',
+ type: 'file',
+ label: strings.get('inputs.GCE_FILE_INPUT_LABEL'),
+ help_text: strings.get('inputs.GCE_FILE_INPUT_HELP_TEXT'),
+ };
+
+ let gceFileInputPreEditValues;
+
vm.form.inputs = {
_get () {
+ let fields;
+
credentialType.mergeInputProperties();
if (credentialType.get('id') === credential.get('credential_type')) {
- return credential.assignInputGroupValues(credentialType.get('inputs.fields'));
+ fields = credential.assignInputGroupValues(credentialType.get('inputs.fields'));
+ } else {
+ fields = credentialType.get('inputs.fields');
}
- return credentialType.get('inputs.fields');
+ if (credentialType.get('name') === 'Google Compute Engine') {
+ fields.splice(2, 0, gceFileInputSchema);
+
+ $scope.$watch(`vm.form.${gceFileInputSchema.id}._value`, vm.gceOnFileInputChanged);
+ $scope.$watch('vm.form.ssh_key_data._isBeingReplaced', vm.gceOnReplaceKeyChanged);
+ }
+
+ return fields;
},
_source: vm.form.credential_type,
_reference: 'vm.form.inputs',
@@ -88,19 +108,70 @@ function EditCredentialsController (models, $state, $scope, strings) {
data.user = me.get('id');
credential.unset('inputs');
+ delete data.inputs[gceFileInputSchema.id];
+
return credential.request('put', { data });
};
vm.form.onSaveSuccess = () => {
$state.go('credentials.edit', { credential_id: credential.get('id') }, { reload: true });
};
+
+ vm.gceOnReplaceKeyChanged = value => {
+ vm.form[gceFileInputSchema.id]._disabled = !value;
+ };
+
+ vm.gceOnFileInputChanged = (value, oldValue) => {
+ if (value === oldValue) return;
+
+ const gceFileIsLoaded = !!value;
+ const gceFileInputState = vm.form[gceFileInputSchema.id];
+ const { obj, error } = vm.gceParseFileInput(value);
+
+ gceFileInputState._isValid = !error;
+ gceFileInputState._message = error ? componentsStrings.get('message.INVALID_INPUT') : '';
+
+ vm.form.project._disabled = gceFileIsLoaded;
+ vm.form.username._disabled = gceFileIsLoaded;
+ vm.form.ssh_key_data._disabled = gceFileIsLoaded;
+ vm.form.ssh_key_data._displayHint = !vm.form.ssh_key_data._disabled;
+
+ if (gceFileIsLoaded) {
+ gceFileInputPreEditValues = Object.assign({}, {
+ project: vm.form.project._value,
+ ssh_key_data: vm.form.ssh_key_data._value,
+ username: vm.form.username._value
+ });
+ vm.form.project._value = _.get(obj, 'project_id', '');
+ vm.form.ssh_key_data._value = _.get(obj, 'private_key', '');
+ vm.form.username._value = _.get(obj, 'client_email', '');
+ } else {
+ vm.form.project._value = gceFileInputPreEditValues.project;
+ vm.form.ssh_key_data._value = gceFileInputPreEditValues.ssh_key_data;
+ vm.form.username._value = gceFileInputPreEditValues.username;
+ }
+ };
+
+ vm.gceParseFileInput = value => {
+ let obj;
+ let error;
+
+ try {
+ obj = angular.fromJson(value);
+ } catch (err) {
+ error = err;
+ }
+
+ return { obj, error };
+ };
}
EditCredentialsController.$inject = [
'resolvedModels',
'$state',
'$scope',
- 'CredentialsStrings'
+ 'CredentialsStrings',
+ 'ComponentsStrings'
];
export default EditCredentialsController;