mirror of
https://github.com/ZwareBear/awx.git
synced 2026-04-15 20:41:49 -05:00
Merge branch 'modularize-helpers-utilities' of https://github.com/mabashian/ansible-tower into mabashian-modularize-helpers-utilities
# Conflicts: # awx/ui/client/src/activity-stream/main.js # awx/ui/client/src/app.js # awx/ui/client/src/helpers.js # awx/ui/client/src/helpers/Credentials.js # awx/ui/client/src/helpers/Groups.js # awx/ui/client/src/helpers/Hosts.js # awx/ui/client/src/helpers/teams.js
This commit is contained in:
@@ -7,11 +7,11 @@
|
||||
export default ['$scope', '$rootScope', '$compile', '$location',
|
||||
'$log', '$stateParams', 'CredentialForm', 'GenerateForm', 'Rest', 'Alert',
|
||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'GetChoices', 'Empty', 'KindChange', 'BecomeMethodChange',
|
||||
'OwnerChange', 'FormSave', '$state', 'CreateSelect2', 'i18n',
|
||||
'OwnerChange', 'CredentialFormSave', '$state', 'CreateSelect2', 'i18n',
|
||||
function($scope, $rootScope, $compile, $location, $log,
|
||||
$stateParams, CredentialForm, GenerateForm, Rest, Alert, ProcessErrors,
|
||||
ClearScope, GetBasePath, GetChoices, Empty, KindChange, BecomeMethodChange,
|
||||
OwnerChange, FormSave, $state, CreateSelect2, i18n) {
|
||||
OwnerChange, CredentialFormSave, $state, CreateSelect2, i18n) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
@@ -126,7 +126,7 @@ export default ['$scope', '$rootScope', '$compile', '$location',
|
||||
// Save
|
||||
$scope.formSave = function() {
|
||||
if ($scope[form.name + '_form'].$valid) {
|
||||
FormSave({ scope: $scope, mode: 'add' });
|
||||
CredentialFormSave({ scope: $scope, mode: 'add' });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@ export default ['$scope', '$rootScope', '$compile', '$location',
|
||||
'$log', '$stateParams', 'CredentialForm', 'Rest', 'Alert',
|
||||
'ProcessErrors', 'ClearScope', 'Prompt', 'GetBasePath', 'GetChoices',
|
||||
'KindChange', 'BecomeMethodChange', 'Empty', 'OwnerChange',
|
||||
'FormSave', 'Wait', '$state', 'CreateSelect2', 'Authorization', 'i18n',
|
||||
'CredentialFormSave', 'Wait', '$state', 'CreateSelect2', 'Authorization', 'i18n',
|
||||
function($scope, $rootScope, $compile, $location, $log,
|
||||
$stateParams, CredentialForm, Rest, Alert, ProcessErrors, ClearScope, Prompt,
|
||||
GetBasePath, GetChoices, KindChange, BecomeMethodChange, Empty, OwnerChange, FormSave, Wait,
|
||||
GetBasePath, GetChoices, KindChange, BecomeMethodChange, Empty, OwnerChange, CredentialFormSave, Wait,
|
||||
$state, CreateSelect2, Authorization, i18n) {
|
||||
|
||||
ClearScope();
|
||||
@@ -236,7 +236,7 @@ export default ['$scope', '$rootScope', '$compile', '$location',
|
||||
// Save changes to the parent
|
||||
$scope.formSave = function() {
|
||||
if ($scope[form.name + '_form'].$valid) {
|
||||
FormSave({ scope: $scope, mode: 'edit' });
|
||||
CredentialFormSave({ scope: $scope, mode: 'edit' });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
export default
|
||||
function BecomeMethodChange(Empty, i18n) {
|
||||
return function(params) {
|
||||
var scope = params.scope;
|
||||
|
||||
if (!Empty(scope.kind)) {
|
||||
// Apply kind specific settings
|
||||
switch (scope.kind.value) {
|
||||
case 'aws':
|
||||
scope.aws_required = true;
|
||||
break;
|
||||
case 'rax':
|
||||
scope.rackspace_required = true;
|
||||
scope.username_required = true;
|
||||
break;
|
||||
case 'ssh':
|
||||
scope.usernameLabel = i18n._('Username'); //formally 'SSH Username'
|
||||
scope.becomeUsernameLabel = i18n._('Privilege Escalation Username');
|
||||
scope.becomePasswordLabel = i18n._('Privilege Escalation Password');
|
||||
break;
|
||||
case 'scm':
|
||||
scope.sshKeyDataLabel = i18n._('SCM Private Key');
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
break;
|
||||
case 'gce':
|
||||
scope.usernameLabel = i18n._('Service Account Email Address');
|
||||
scope.sshKeyDataLabel = i18n._('RSA Private Key');
|
||||
scope.email_required = true;
|
||||
scope.key_required = true;
|
||||
scope.project_required = true;
|
||||
scope.key_description = i18n._('Paste the contents of the PEM file associated with the service account email.');
|
||||
scope.projectLabel = i18n._("Project");
|
||||
scope.project_required = false;
|
||||
scope.projectPopOver = "<p>" + i18n._("The Project ID is the " +
|
||||
"GCE assigned identification. It is constructed as " +
|
||||
"two words followed by a three digit number. Such " +
|
||||
"as: ") + "</p><p>adjective-noun-000</p>";
|
||||
break;
|
||||
case 'azure':
|
||||
scope.sshKeyDataLabel = i18n._('Management Certificate');
|
||||
scope.subscription_required = true;
|
||||
scope.key_required = true;
|
||||
scope.key_description = i18n._("Paste the contents of the PEM file that corresponds to the certificate you uploaded in the Microsoft Azure console.");
|
||||
break;
|
||||
case 'azure_rm':
|
||||
scope.usernameLabel = i18n._("Username");
|
||||
scope.subscription_required = true;
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.azure_rm_required = true;
|
||||
break;
|
||||
case 'vmware':
|
||||
scope.username_required = true;
|
||||
scope.host_required = true;
|
||||
scope.password_required = true;
|
||||
scope.hostLabel = "vCenter Host";
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.hostPopOver = i18n._("Enter the hostname or IP address which corresponds to your VMware vCenter.");
|
||||
break;
|
||||
case 'openstack':
|
||||
scope.hostLabel = i18n._("Host (Authentication URL)");
|
||||
scope.projectLabel = i18n._("Project (Tenant Name)");
|
||||
scope.domainLabel = i18n._("Domain Name");
|
||||
scope.password_required = true;
|
||||
scope.project_required = true;
|
||||
scope.host_required = true;
|
||||
scope.username_required = true;
|
||||
scope.projectPopOver = "<p>" + i18n._("This is the tenant name. " +
|
||||
" This value is usually the same " +
|
||||
" as the username.") + "</p>";
|
||||
scope.hostPopOver = "<p>" + i18n._("The host to authenticate with.") +
|
||||
"<br />" + i18n.sprintf(i18n._("For example, %s"), "https://openstack.business.com/v2.0/");
|
||||
break;
|
||||
case 'satellite6':
|
||||
scope.username_required = true;
|
||||
scope.password_required = true;
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.host_required = true;
|
||||
scope.hostLabel = i18n._("Satellite 6 URL");
|
||||
scope.hostPopOver = i18n.sprintf(i18n._("Enter the URL which corresponds to your %s" +
|
||||
"Red Hat Satellite 6 server. %s" +
|
||||
"For example, %s"), "<br />", "<br />", "https://satellite.example.org");
|
||||
break;
|
||||
case 'cloudforms':
|
||||
scope.username_required = true;
|
||||
scope.password_required = true;
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.host_required = true;
|
||||
scope.hostLabel = i18n._("CloudForms URL");
|
||||
scope.hostPopOver = i18n.sprintf(i18n._("Enter the URL for the virtual machine which %s" +
|
||||
"corresponds to your CloudForm instance. %s" +
|
||||
"For example, %s"), "<br />", "<br />", "https://cloudforms.example.org");
|
||||
break;
|
||||
case 'net':
|
||||
scope.username_required = true;
|
||||
scope.password_required = false;
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.sshKeyDataLabel = i18n._('SSH Key');
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
BecomeMethodChange.$inject =
|
||||
[ 'Empty', 'i18n' ];
|
||||
@@ -0,0 +1,105 @@
|
||||
export default
|
||||
function CredentialFormSave($rootScope, $location, Alert, Rest, ProcessErrors, Empty, GetBasePath, CredentialForm, ReturnToCaller, Wait, $state, i18n) {
|
||||
return function(params) {
|
||||
var scope = params.scope,
|
||||
mode = params.mode,
|
||||
form = CredentialForm,
|
||||
data = {}, fld, url;
|
||||
|
||||
for (fld in form.fields) {
|
||||
if (fld !== 'access_key' && fld !== 'secret_key' && fld !== 'ssh_username' &&
|
||||
fld !== 'ssh_password') {
|
||||
if (fld === "organization" && !scope[fld]) {
|
||||
data.user = $rootScope.current_user.id;
|
||||
} else if (scope[fld] === null) {
|
||||
data[fld] = "";
|
||||
} else {
|
||||
data[fld] = scope[fld];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data.kind = scope.kind.value;
|
||||
if (scope.become_method === null || typeof scope.become_method === 'undefined') {
|
||||
data.become_method = "";
|
||||
data.become_username = "";
|
||||
data.become_password = "";
|
||||
} else {
|
||||
data.become_method = (scope.become_method.value) ? scope.become_method.value : "";
|
||||
}
|
||||
switch (data.kind) {
|
||||
case 'ssh':
|
||||
data.password = scope.ssh_password;
|
||||
break;
|
||||
case 'aws':
|
||||
data.username = scope.access_key;
|
||||
data.password = scope.secret_key;
|
||||
break;
|
||||
case 'rax':
|
||||
data.password = scope.api_key;
|
||||
break;
|
||||
case 'gce':
|
||||
data.username = scope.email_address;
|
||||
data.project = scope.project;
|
||||
break;
|
||||
case 'azure':
|
||||
data.username = scope.subscription;
|
||||
}
|
||||
|
||||
Wait('start');
|
||||
if (mode === 'add') {
|
||||
url = GetBasePath("credentials");
|
||||
Rest.setUrl(url);
|
||||
Rest.post(data)
|
||||
.success(function (data) {
|
||||
scope.addedItem = data.id;
|
||||
|
||||
Wait('stop');
|
||||
var base = $location.path().replace(/^\//, '').split('/')[0];
|
||||
if (base === 'credentials') {
|
||||
$state.go('credentials.edit', {credential_id: data.id}, {reload: true});
|
||||
}
|
||||
else {
|
||||
ReturnToCaller(1);
|
||||
}
|
||||
})
|
||||
.error(function (data, status) {
|
||||
Wait('stop');
|
||||
// TODO: hopefully this conditional error handling will to away in a future version of tower. The reason why we cannot
|
||||
// simply pass this error to ProcessErrors is because it will actually match the form element 'ssh_key_unlock' and show
|
||||
// the error there. The ssh_key_unlock field is not shown when the kind of credential is gce/azure and as a result the
|
||||
// error is never shown. In the future, the API will hopefully either behave or respond differently.
|
||||
if(status && status === 400 && data && data.ssh_key_unlock && (scope.kind.value === 'gce' || scope.kind.value === 'azure')) {
|
||||
scope.ssh_key_data_api_error = i18n._("Encrypted credentials are not supported.");
|
||||
}
|
||||
else {
|
||||
ProcessErrors(scope, data, status, form, {
|
||||
hdr: i18n._('Error!'),
|
||||
msg: i18n._('Failed to create new Credential. POST status: ') + status
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
url = GetBasePath('credentials') + scope.id + '/';
|
||||
Rest.setUrl(url);
|
||||
Rest.put(data)
|
||||
.success(function () {
|
||||
Wait('stop');
|
||||
$state.go($state.current, {}, {reload: true});
|
||||
})
|
||||
.error(function (data, status) {
|
||||
Wait('stop');
|
||||
ProcessErrors(scope, data, status, form, {
|
||||
hdr: i18n._('Error!'),
|
||||
msg: i18n._('Failed to update Credential. PUT status: ') + status
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CredentialFormSave.$inject =
|
||||
[ '$rootScope', '$location', 'Alert', 'Rest',
|
||||
'ProcessErrors', 'Empty', 'GetBasePath', 'CredentialForm',
|
||||
'ReturnToCaller', 'Wait', '$state', 'i18n'
|
||||
];
|
||||
192
awx/ui/client/src/credentials/factories/kind-change.factory.js
Normal file
192
awx/ui/client/src/credentials/factories/kind-change.factory.js
Normal file
@@ -0,0 +1,192 @@
|
||||
export default
|
||||
function KindChange(Empty, i18n) {
|
||||
return function(params) {
|
||||
var scope = params.scope,
|
||||
reset = params.reset,
|
||||
collapse, id;
|
||||
|
||||
$('.popover').each(function() {
|
||||
// remove lingering popover <div>. Seems to be a bug in TB3 RC1
|
||||
$(this).remove();
|
||||
});
|
||||
$('.tooltip').each( function() {
|
||||
// close any lingering tool tipss
|
||||
$(this).hide();
|
||||
});
|
||||
// Put things in a default state
|
||||
scope.usernameLabel = i18n._('Username');
|
||||
scope.aws_required = false;
|
||||
scope.email_required = false;
|
||||
scope.rackspace_required = false;
|
||||
scope.sshKeyDataLabel = i18n._('Private Key');
|
||||
scope.username_required = false; // JT-- added username_required b/c mutliple 'kinds' need username to be required (GCE)
|
||||
scope.key_required = false; // JT -- doing the same for key and project
|
||||
scope.project_required = false;
|
||||
scope.subscription_required = false;
|
||||
scope.key_description = i18n.sprintf(i18n._("Paste the contents of the SSH private key file.%s or click to close%s"), "<div class=\"popover-footer\"><span class=\"key\">Esc</span>", "</div>");
|
||||
scope.host_required = false;
|
||||
scope.password_required = false;
|
||||
scope.hostLabel = '';
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
|
||||
$('.popover').each(function() {
|
||||
// remove lingering popover <div>. Seems to be a bug in TB3 RC1
|
||||
$(this).remove();
|
||||
});
|
||||
$('.tooltip').each( function() {
|
||||
// close any lingering tool tipss
|
||||
$(this).hide();
|
||||
});
|
||||
// Put things in a default state
|
||||
scope.usernameLabel = i18n._('Username');
|
||||
scope.aws_required = false;
|
||||
scope.email_required = false;
|
||||
scope.rackspace_required = false;
|
||||
scope.sshKeyDataLabel = i18n._('Private Key');
|
||||
scope.username_required = false; // JT-- added username_required b/c mutliple 'kinds' need username to be required (GCE)
|
||||
scope.key_required = false; // JT -- doing the same for key and project
|
||||
scope.project_required = false;
|
||||
scope.domain_required = false;
|
||||
scope.subscription_required = false;
|
||||
scope.key_description = i18n._("Paste the contents of the SSH private key file.");
|
||||
scope.host_required = false;
|
||||
scope.password_required = false;
|
||||
scope.hostLabel = '';
|
||||
scope.projectLabel = '';
|
||||
scope.domainLabel = '';
|
||||
scope.project_required = false;
|
||||
scope.passwordLabel = i18n._('Password (API Key)');
|
||||
scope.projectPopOver = "<p>" + i18n._("The project value") + "</p>";
|
||||
scope.hostPopOver = "<p>" + i18n._("The host value") + "</p>";
|
||||
scope.ssh_key_data_api_error = '';
|
||||
|
||||
if (!Empty(scope.kind)) {
|
||||
// Apply kind specific settings
|
||||
switch (scope.kind.value) {
|
||||
case 'aws':
|
||||
scope.aws_required = true;
|
||||
break;
|
||||
case 'rax':
|
||||
scope.rackspace_required = true;
|
||||
scope.username_required = true;
|
||||
break;
|
||||
case 'ssh':
|
||||
scope.usernameLabel = i18n._('Username'); //formally 'SSH Username'
|
||||
scope.becomeUsernameLabel = i18n._('Privilege Escalation Username');
|
||||
scope.becomePasswordLabel = i18n._('Privilege Escalation Password');
|
||||
break;
|
||||
case 'scm':
|
||||
scope.sshKeyDataLabel = i18n._('SCM Private Key');
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
break;
|
||||
case 'gce':
|
||||
scope.usernameLabel = i18n._('Service Account Email Address');
|
||||
scope.sshKeyDataLabel = i18n._('RSA Private Key');
|
||||
scope.email_required = true;
|
||||
scope.key_required = true;
|
||||
scope.project_required = true;
|
||||
scope.key_description = i18n._('Paste the contents of the PEM file associated with the service account email.');
|
||||
scope.projectLabel = i18n._("Project");
|
||||
scope.project_required = false;
|
||||
scope.projectPopOver = "<p>" + i18n._("The Project ID is the " +
|
||||
"GCE assigned identification. It is constructed as " +
|
||||
"two words followed by a three digit number. Such " +
|
||||
"as: ") + "</p><p>adjective-noun-000</p>";
|
||||
break;
|
||||
case 'azure':
|
||||
scope.sshKeyDataLabel = i18n._('Management Certificate');
|
||||
scope.subscription_required = true;
|
||||
scope.key_required = true;
|
||||
scope.key_description = i18n._("Paste the contents of the PEM file that corresponds to the certificate you uploaded in the Microsoft Azure console.");
|
||||
break;
|
||||
case 'azure_rm':
|
||||
scope.usernameLabel = i18n._("Username");
|
||||
scope.subscription_required = true;
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.azure_rm_required = true;
|
||||
break;
|
||||
case 'vmware':
|
||||
scope.username_required = true;
|
||||
scope.host_required = true;
|
||||
scope.password_required = true;
|
||||
scope.hostLabel = "vCenter Host";
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.hostPopOver = i18n._("Enter the hostname or IP address which corresponds to your VMware vCenter.");
|
||||
break;
|
||||
case 'openstack':
|
||||
scope.hostLabel = i18n._("Host (Authentication URL)");
|
||||
scope.projectLabel = i18n._("Project (Tenant Name)");
|
||||
scope.domainLabel = i18n._("Domain Name");
|
||||
scope.password_required = true;
|
||||
scope.project_required = true;
|
||||
scope.host_required = true;
|
||||
scope.username_required = true;
|
||||
scope.projectPopOver = "<p>" + i18n._("This is the tenant name. " +
|
||||
" This value is usually the same " +
|
||||
" as the username.") + "</p>";
|
||||
scope.hostPopOver = "<p>" + i18n._("The host to authenticate with.") +
|
||||
"<br />" + i18n.sprintf(i18n._("For example, %s"), "https://openstack.business.com/v2.0/");
|
||||
break;
|
||||
case 'satellite6':
|
||||
scope.username_required = true;
|
||||
scope.password_required = true;
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.host_required = true;
|
||||
scope.hostLabel = i18n._("Satellite 6 URL");
|
||||
scope.hostPopOver = i18n.sprintf(i18n._("Enter the URL which corresponds to your %s" +
|
||||
"Red Hat Satellite 6 server. %s" +
|
||||
"For example, %s"), "<br />", "<br />", "https://satellite.example.org");
|
||||
break;
|
||||
case 'cloudforms':
|
||||
scope.username_required = true;
|
||||
scope.password_required = true;
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.host_required = true;
|
||||
scope.hostLabel = i18n._("CloudForms URL");
|
||||
scope.hostPopOver = i18n.sprintf(i18n._("Enter the URL for the virtual machine which %s" +
|
||||
"corresponds to your CloudForm instance. %s" +
|
||||
"For example, %s"), "<br />", "<br />", "https://cloudforms.example.org");
|
||||
break;
|
||||
case 'net':
|
||||
scope.username_required = true;
|
||||
scope.password_required = false;
|
||||
scope.passwordLabel = i18n._('Password');
|
||||
scope.sshKeyDataLabel = i18n._('SSH Key');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset all the field values related to Kind.
|
||||
if (reset) {
|
||||
scope.access_key = null;
|
||||
scope.secret_key = null;
|
||||
scope.api_key = null;
|
||||
scope.username = null;
|
||||
scope.password = null;
|
||||
scope.password_confirm = null;
|
||||
scope.ssh_key_data = null;
|
||||
scope.ssh_key_unlock = null;
|
||||
scope.ssh_key_unlock_confirm = null;
|
||||
scope.become_username = null;
|
||||
scope.become_password = null;
|
||||
scope.authorize = false;
|
||||
scope.authorize_password = null;
|
||||
}
|
||||
|
||||
// Collapse or open help widget based on whether scm value is selected
|
||||
collapse = $('#credential_kind').parent().find('.panel-collapse').first();
|
||||
id = collapse.attr('id');
|
||||
if (!Empty(scope.kind) && scope.kind.value !== '') {
|
||||
if ($('#' + id + '-icon').hasClass('icon-minus')) {
|
||||
scope.accordionToggle('#' + id);
|
||||
}
|
||||
} else {
|
||||
if ($('#' + id + '-icon').hasClass('icon-plus')) {
|
||||
scope.accordionToggle('#' + id);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
KindChange.$inject =
|
||||
[ 'Empty', 'i18n' ];
|
||||
@@ -0,0 +1,18 @@
|
||||
export default
|
||||
function OwnerChange() {
|
||||
return function(params) {
|
||||
var scope = params.scope,
|
||||
owner = scope.owner;
|
||||
if (owner === 'team') {
|
||||
scope.team_required = true;
|
||||
scope.user_required = false;
|
||||
scope.user = null;
|
||||
scope.user_username = null;
|
||||
} else {
|
||||
scope.team_required = false;
|
||||
scope.user_required = true;
|
||||
scope.team = null;
|
||||
scope.team_name = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -8,11 +8,19 @@ import ownerList from './ownerList.directive';
|
||||
import CredentialsList from './list/credentials-list.controller';
|
||||
import CredentialsAdd from './add/credentials-add.controller';
|
||||
import CredentialsEdit from './edit/credentials-edit.controller';
|
||||
import BecomeMethodChange from './factories/become-method-change.factory';
|
||||
import CredentialFormSave from './factories/credential-form-save.factory';
|
||||
import KindChange from './factories/kind-change.factory';
|
||||
import OwnerChange from './factories/owner-change.factory';
|
||||
import { N_ } from '../i18n';
|
||||
|
||||
export default
|
||||
angular.module('credentials', [])
|
||||
.directive('ownerList', ownerList)
|
||||
.factory('BecomeMethodChange', BecomeMethodChange)
|
||||
.factory('CredentialFormSave', CredentialFormSave)
|
||||
.factory('KindChange', KindChange)
|
||||
.factory('OwnerChange', OwnerChange)
|
||||
.controller('CredentialsList', CredentialsList)
|
||||
.controller('CredentialsAdd', CredentialsAdd)
|
||||
.controller('CredentialsEdit', CredentialsEdit)
|
||||
|
||||
Reference in New Issue
Block a user