mirror of
https://github.com/ansible/awx.git
synced 2026-09-12 23:05:00 -02:30
Merge branch 'release_2.4.0' into devel
* release_2.4.0: (70 commits) Disallow changing a users password for social auth bump django-radius to include new license Change Jenkins server references from IP to DNS name Social auth and SSO updates: allow multi-org expired licenses to delete orgs Add social log messages to tower's log on error Update default scopes requested for github social auth. Switch to matburt's fork for python social auth Emit a warning for unmapped SAML paramters Fix up some SAML issues Remove `environment` play stmt Use correct aw_repo_url when building packer Add missing libxmlsec1 openssl dependency for ubuntu adds socket tests added git pre commit hook to run flake8 fixes remove_instance error null pointer exception Resolve issue on precise keeping old debs around Attach handlers to django_auth_ldap Attach handlers to django_auth_ldap ...
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
|
||||
<div id="about-dialog-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-5">
|
||||
<div class="col-xs-12 col-sm-5 About-cowsay">
|
||||
<div style="width: 340px; margin: 0 auto;">
|
||||
<pre id="cowsay">
|
||||
________________
|
||||
@@ -19,10 +19,11 @@
|
||||
<div class="col-xs-12 col-sm-7 text-center">
|
||||
<img id="about-modal-titlelogo" src="/static/assets/ansible_tower_logo_minimalc.png"><br>
|
||||
<p>Copyright 2015. All rights reserved.</p>
|
||||
<p>Ansible and Ansible Tower are registered trademarks of Ansible, Inc.</p>
|
||||
<p>Ansible and Ansible Tower are registered trademarks of Red Hat, Inc.</p>
|
||||
<br>
|
||||
<img class="About-redhat" src="/static/assets/redhat_ansible_lockup.png">
|
||||
<br>
|
||||
<p>Visit <a href="http://www.ansible.com" target="_blank">Ansible.com</a> for more information.</p>
|
||||
<br>
|
||||
<p><span id='about-modal-subscription'></span></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
14
awx/ui/client/src/about/about.block.less
Normal file
14
awx/ui/client/src/about/about.block.less
Normal file
@@ -0,0 +1,14 @@
|
||||
/** @define About */
|
||||
.About {
|
||||
height: 309px !important;
|
||||
}
|
||||
|
||||
.About-cowsay {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.About-redhat {
|
||||
max-width: 100%;
|
||||
margin-top: -61px;
|
||||
margin-bottom: -33px;
|
||||
}
|
||||
@@ -837,9 +837,9 @@ var tower = angular.module('Tower', [
|
||||
}]);
|
||||
}])
|
||||
|
||||
.run(['$compile', '$cookieStore', '$rootScope', '$log', 'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer', 'ClearScope', 'HideStream', 'Socket',
|
||||
.run(['$q', '$compile', '$cookieStore', '$rootScope', '$log', 'CheckLicense', '$location', 'Authorization', 'LoadBasePaths', 'Timer', 'ClearScope', 'HideStream', 'Socket',
|
||||
'LoadConfig', 'Store', 'ShowSocketHelp', 'AboutAnsibleHelp', 'pendoService',
|
||||
function ($compile, $cookieStore, $rootScope, $log, CheckLicense, $location, Authorization, LoadBasePaths, Timer, ClearScope, HideStream, Socket,
|
||||
function ($q, $compile, $cookieStore, $rootScope, $log, CheckLicense, $location, Authorization, LoadBasePaths, Timer, ClearScope, HideStream, Socket,
|
||||
LoadConfig, Store, ShowSocketHelp, AboutAnsibleHelp, pendoService) {
|
||||
|
||||
|
||||
@@ -950,7 +950,8 @@ var tower = angular.module('Tower', [
|
||||
control_socket.init();
|
||||
control_socket.on("limit_reached", function(data) {
|
||||
$log.debug(data.reason);
|
||||
Timer.expireSession('session_limit');
|
||||
$rootScope.sessionTimer.expireSession('session_limit');
|
||||
$location.url('/login');
|
||||
});
|
||||
}
|
||||
openSocket();
|
||||
@@ -999,7 +1000,7 @@ var tower = angular.module('Tower', [
|
||||
// gets here on timeout
|
||||
if (next.templateUrl !== (urlPrefix + 'login/loginBackDrop.partial.html')) {
|
||||
$rootScope.sessionTimer.expireSession('idle');
|
||||
if (sock) {
|
||||
if (sock&& sock.socket && sock.socket.socket) {
|
||||
sock.socket.socket.disconnect();
|
||||
}
|
||||
$location.path('/login');
|
||||
@@ -1026,9 +1027,11 @@ var tower = angular.module('Tower', [
|
||||
$rootScope.user_is_superuser = Authorization.getUserInfo('is_superuser');
|
||||
// when the user refreshes we want to open the socket, except if the user is on the login page, which should happen after the user logs in (see the AuthService module for that call to OpenSocket)
|
||||
if(!_.contains($location.$$url, '/login')){
|
||||
$rootScope.sessionTimer = Timer.init();
|
||||
$rootScope.$emit('OpenSocket');
|
||||
pendoService.issuePendoIdentity();
|
||||
Timer.init().then(function(timer){
|
||||
$rootScope.sessionTimer = timer;
|
||||
$rootScope.$emit('OpenSocket');
|
||||
pendoService.issuePendoIdentity();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1063,8 +1066,8 @@ var tower = angular.module('Tower', [
|
||||
|
||||
|
||||
if (!$AnsibleConfig) {
|
||||
// there may be time lag when loading the config file, so temporarily use what's in local storage
|
||||
$AnsibleConfig = Store('AnsibleConfig');
|
||||
// create a promise that will resolve when $AnsibleConfig is loaded
|
||||
$rootScope.loginConfig = $q.defer();
|
||||
}
|
||||
|
||||
//the authorization controller redirects to the home page automatcially if there is no last path defined. in order to override
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
export function JobDetailController ($location, $rootScope, $filter, $scope, $compile, $routeParams, $log, ClearScope, Breadcrumbs, LoadBreadCrumbs, GetBasePath, Wait, Rest,
|
||||
ProcessErrors, SelectPlay, SelectTask, Socket, GetElapsed, DrawGraph, LoadHostSummary, ReloadHostSummaryList, JobIsFinished, SetTaskStyles, DigestEvent,
|
||||
UpdateDOM, EventViewer, DeleteJob, PlaybookRun, HostEventsViewer, LoadPlays, LoadTasks, LoadHosts, HostsEdit, ParseVariableString, GetChoices) {
|
||||
UpdateDOM, EventViewer, DeleteJob, PlaybookRun, HostEventsViewer, LoadPlays, LoadTasks, LoadHosts, HostsEdit, ParseVariableString, GetChoices, fieldChoices, fieldLabels) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
@@ -27,11 +27,33 @@ export function JobDetailController ($location, $rootScope, $filter, $scope, $co
|
||||
|
||||
scope.plays = [];
|
||||
|
||||
scope.previousTaskFailed = false;
|
||||
|
||||
scope.$watch('job_status', function(job_status) {
|
||||
if (job_status && job_status.explanation && job_status.explanation.split(":")[0] === "Previous Task Failed") {
|
||||
scope.previousTaskFailed = true;
|
||||
var taskObj = JSON.parse(job_status.explanation.substring(job_status.explanation.split(":")[0].length + 1));
|
||||
job_status.explanation = job_status.explanation.split(":")[0] + ". ";
|
||||
job_status.explanation += "<code>" + taskObj.task_type + "-" + taskObj.task_id + " failed for " + taskObj.task_name + "</code>"
|
||||
// return a promise from the options request with the permission type choices (including adhoc) as a param
|
||||
var fieldChoice = fieldChoices({
|
||||
scope: $scope,
|
||||
url: 'api/v1/unified_jobs/',
|
||||
field: 'type'
|
||||
});
|
||||
|
||||
// manipulate the choices from the options request to be set on
|
||||
// scope and be usable by the list form
|
||||
fieldChoice.then(function (choices) {
|
||||
choices =
|
||||
fieldLabels({
|
||||
choices: choices
|
||||
});
|
||||
scope.explanation_fail_type = choices[taskObj.job_type];
|
||||
scope.explanation_fail_name = taskObj.job_name;
|
||||
scope.explanation_fail_id = taskObj.job_id;
|
||||
scope.task_detail = scope.explanation_fail_type + " failed for " + scope.explanation_fail_name + " with ID " + scope.explanation_fail_id + ".";
|
||||
});
|
||||
} else {
|
||||
scope.previousTaskFailed = false;
|
||||
}
|
||||
}, true);
|
||||
|
||||
@@ -649,61 +671,6 @@ export function JobDetailController ($location, $rootScope, $filter, $scope, $co
|
||||
});
|
||||
|
||||
|
||||
if (scope.removeGetCredentialNames) {
|
||||
scope.removeGetCredentialNames();
|
||||
}
|
||||
scope.removeGetCredentialNames = scope.$on('GetCredentialNames', function(e, data) {
|
||||
var url;
|
||||
if (data.credential) {
|
||||
url = GetBasePath('credentials') + data.credential + '/';
|
||||
Rest.setUrl(url);
|
||||
Rest.get()
|
||||
.success( function(data) {
|
||||
scope.credential_name = data.name;
|
||||
})
|
||||
.error( function(data, status) {
|
||||
scope.credential_name = '';
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to ' + url + '. GET returned: ' + status });
|
||||
});
|
||||
}
|
||||
if (data.cloud_credential) {
|
||||
url = GetBasePath('credentials') + data.cloud_credential + '/';
|
||||
Rest.setUrl(url);
|
||||
Rest.get()
|
||||
.success( function(data) {
|
||||
scope.cloud_credential_name = data.name;
|
||||
})
|
||||
.error( function(data, status) {
|
||||
scope.credential_name = '';
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to ' + url + '. GET returned: ' + status });
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (scope.removeGetCreatedByNames) {
|
||||
scope.removeGetCreatedByNames();
|
||||
}
|
||||
scope.removeGetCreatedByNames = scope.$on('GetCreatedByNames', function(e, data) {
|
||||
var url;
|
||||
data = data.slice(0, data.length-1);
|
||||
data = data.slice(data.lastIndexOf('/')+1, data.length);
|
||||
url = GetBasePath('users') + data + '/';
|
||||
scope.users_url = '/#/users/' + data;
|
||||
Rest.setUrl(url);
|
||||
Rest.get()
|
||||
.success( function(data) {
|
||||
scope.created_by = data.username;
|
||||
})
|
||||
.error( function(data, status) {
|
||||
scope.credential_name = '';
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to ' + url + '. GET returned: ' + status });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
if (scope.removeLoadJob) {
|
||||
scope.removeLoadJob();
|
||||
}
|
||||
@@ -738,6 +705,24 @@ export function JobDetailController ($location, $rootScope, $filter, $scope, $co
|
||||
scope.verbosity = data.verbosity;
|
||||
scope.job_tags = data.job_tags;
|
||||
scope.variables = ParseVariableString(data.extra_vars);
|
||||
scope.users_url = (data.summary_fields.created_by) ? '/#/users/' + data.summary_fields.created_by.id : '';
|
||||
scope.created_by = (data.summary_fields.created_by) ? data.summary_fields.created_by.username : '';
|
||||
|
||||
if (data.summary_fields.credential) {
|
||||
scope.credential_name = data.summary_fields.credential.name;
|
||||
scope.credential_url = data.related.credential
|
||||
.replace('api/v1', '#');
|
||||
} else {
|
||||
scope.credential_name = "";
|
||||
}
|
||||
|
||||
if (data.summary_fields.cloud_credential) {
|
||||
scope.cloud_credential_name = data.summary_fields.cloud_credential.name;
|
||||
scope.cloud_credential_url = data.related.cloud_credential
|
||||
.replace('api/v1', '#');
|
||||
} else {
|
||||
scope.cloud_credential_name = "";
|
||||
}
|
||||
|
||||
for (i=0; i < verbosity_options.length; i++) {
|
||||
if (verbosity_options[i].value === data.verbosity) {
|
||||
@@ -792,10 +777,6 @@ export function JobDetailController ($location, $rootScope, $filter, $scope, $co
|
||||
});
|
||||
//scope.setSearchAll('host');
|
||||
scope.$emit('LoadPlays', data.related.job_events);
|
||||
scope.$emit('GetCreatedByNames', data.related.created_by);
|
||||
if (!scope.credential_name) {
|
||||
scope.$emit('GetCredentialNames', data);
|
||||
}
|
||||
})
|
||||
.error(function(data, status) {
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
@@ -1415,5 +1396,5 @@ export function JobDetailController ($location, $rootScope, $filter, $scope, $co
|
||||
JobDetailController.$inject = [ '$location', '$rootScope', '$filter', '$scope', '$compile', '$routeParams', '$log', 'ClearScope', 'Breadcrumbs', 'LoadBreadCrumbs', 'GetBasePath',
|
||||
'Wait', 'Rest', 'ProcessErrors', 'SelectPlay', 'SelectTask', 'Socket', 'GetElapsed', 'DrawGraph', 'LoadHostSummary', 'ReloadHostSummaryList',
|
||||
'JobIsFinished', 'SetTaskStyles', 'DigestEvent', 'UpdateDOM', 'EventViewer', 'DeleteJob', 'PlaybookRun', 'HostEventsViewer', 'LoadPlays', 'LoadTasks',
|
||||
'LoadHosts', 'HostsEdit', 'ParseVariableString', 'GetChoices'
|
||||
'LoadHosts', 'HostsEdit', 'ParseVariableString', 'GetChoices', 'fieldChoices', 'fieldLabels'
|
||||
];
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
export function ProjectsList ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, ProjectList, GenerateList, LoadBreadCrumbs,
|
||||
Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, SelectionInit, ProjectUpdate,
|
||||
Refresh, Wait, Stream, GetChoices, Empty, Find, LogViewer, GetProjectIcon, GetProjectToolTip) {
|
||||
Refresh, Wait, Stream, GetChoices, Empty, Find, LogViewer, GetProjectIcon, GetProjectToolTip, $filter) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
@@ -309,29 +309,37 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $routeParams,
|
||||
});
|
||||
|
||||
$scope.cancelUpdate = function (id, name) {
|
||||
// Start the cancel process
|
||||
var i, project, found = false;
|
||||
for (i = 0; i < $scope.projects.length; i++) {
|
||||
if ($scope.projects[i].id === id) {
|
||||
project = $scope.projects[i];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found && project.related.current_update) {
|
||||
Rest.setUrl(project.related.current_update);
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
$scope.$emit('Check_Cancel', data);
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to ' + project.related.current_update + ' failed. GET status: ' + status });
|
||||
});
|
||||
} else {
|
||||
Alert('Update Not Found', 'An SCM update does not appear to be running for project: ' + name + '. Click the <em>Refresh</em> ' +
|
||||
'button to view the latet status.', 'alert-info');
|
||||
}
|
||||
// // Start the cancel process
|
||||
// var i, project, found = false;
|
||||
// for (i = 0; i < $scope.projects.length; i++) {
|
||||
// if ($scope.projects[i].id === id) {
|
||||
// project = $scope.projects[i];
|
||||
// found = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
Rest.setUrl(GetBasePath("projects") + id);
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
if (data.related.current_update) {
|
||||
Rest.setUrl(data.related.current_update);
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
$scope.$emit('Check_Cancel', data);
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to ' + data.related.current_update + ' failed. GET status: ' + status });
|
||||
});
|
||||
} else {
|
||||
Alert('Update Not Found', 'An SCM update does not appear to be running for project: ' + $filter('sanitize')(name) + '. Click the <em>Refresh</em> ' +
|
||||
'button to view the latest status.', 'alert-info',undefined,undefined,undefined,undefined,true);
|
||||
}
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to get project failed. GET status: ' + status });
|
||||
})
|
||||
};
|
||||
|
||||
$scope.refresh = function () {
|
||||
@@ -384,7 +392,7 @@ export function ProjectsList ($scope, $rootScope, $location, $log, $routeParams,
|
||||
ProjectsList.$inject = ['$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'ProjectList', 'generateList',
|
||||
'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', 'GetBasePath',
|
||||
'SelectionInit', 'ProjectUpdate', 'Refresh', 'Wait', 'Stream', 'GetChoices', 'Empty', 'Find',
|
||||
'LogViewer', 'GetProjectIcon', 'GetProjectToolTip'
|
||||
'LogViewer', 'GetProjectIcon', 'GetProjectToolTip', '$filter'
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ TeamsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$r
|
||||
|
||||
export function TeamsEdit($scope, $rootScope, $compile, $location, $log, $routeParams, TeamForm, GenerateForm, Rest, Alert, ProcessErrors,
|
||||
LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, LookUpInit, Prompt, GetBasePath, CheckAccess,
|
||||
OrganizationList, Wait, Stream, permissionsChoices, permissionsLabel, permissionsSearchSelect) {
|
||||
OrganizationList, Wait, Stream, fieldChoices, fieldLabels, permissionsSearchSelect) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
@@ -192,16 +192,17 @@ export function TeamsEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
$scope.permission_search_select = [];
|
||||
|
||||
// return a promise from the options request with the permission type choices (including adhoc) as a param
|
||||
var permissionsChoice = permissionsChoices({
|
||||
var permissionsChoice = fieldChoices({
|
||||
scope: $scope,
|
||||
url: 'api/v1/' + base + '/' + id + '/permissions/'
|
||||
url: 'api/v1/' + base + '/' + id + '/permissions/',
|
||||
field: 'permission_type'
|
||||
});
|
||||
|
||||
// manipulate the choices from the options request to be set on
|
||||
// scope and be usable by the list form
|
||||
permissionsChoice.then(function (choices) {
|
||||
choices =
|
||||
permissionsLabel({
|
||||
fieldLabels({
|
||||
choices: choices
|
||||
});
|
||||
_.map(choices, function(n, key) {
|
||||
@@ -209,8 +210,6 @@ export function TeamsEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
});
|
||||
});
|
||||
|
||||
$scope.team_id = id;
|
||||
|
||||
// manipulate the choices from the options request to be usable
|
||||
// by the search option for permission_type, you can't inject the
|
||||
// list until this is done!
|
||||
@@ -221,8 +220,11 @@ export function TeamsEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
});
|
||||
generator.inject(form, { mode: 'edit', related: true, scope: $scope });
|
||||
generator.reset();
|
||||
$scope.$emit('loadTeam');
|
||||
});
|
||||
|
||||
$scope.team_id = id;
|
||||
|
||||
$scope.PermissionAddAllowed = false;
|
||||
|
||||
// Retrieve each related set and any lookups
|
||||
@@ -253,59 +255,65 @@ export function TeamsEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
}
|
||||
});
|
||||
|
||||
// Retrieve detail record and prepopulate the form
|
||||
Wait('start');
|
||||
Rest.setUrl(defaultUrl + ':id/');
|
||||
Rest.get({
|
||||
params: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
.success(function (data) {
|
||||
var fld, related, set;
|
||||
$scope.team_name = data.name;
|
||||
for (fld in form.fields) {
|
||||
if (data[fld]) {
|
||||
$scope[fld] = data[fld];
|
||||
master[fld] = $scope[fld];
|
||||
}
|
||||
// Retrieve each related set and any lookups
|
||||
if ($scope.loadTeamRemove) {
|
||||
$scope.loadTeamRemove();
|
||||
}
|
||||
$scope.loadTeamRemove = $scope.$on('loadTeam', function () {
|
||||
// Retrieve detail record and prepopulate the form
|
||||
Wait('start');
|
||||
Rest.setUrl(defaultUrl + ':id/');
|
||||
Rest.get({
|
||||
params: {
|
||||
id: id
|
||||
}
|
||||
related = data.related;
|
||||
for (set in form.related) {
|
||||
if (related[set]) {
|
||||
relatedSets[set] = {
|
||||
url: related[set],
|
||||
iterator: form.related[set].iterator
|
||||
};
|
||||
}
|
||||
}
|
||||
// Initialize related search functions. Doing it here to make sure relatedSets object is populated.
|
||||
RelatedSearchInit({
|
||||
scope: $scope,
|
||||
form: form,
|
||||
relatedSets: relatedSets
|
||||
});
|
||||
RelatedPaginateInit({
|
||||
scope: $scope,
|
||||
relatedSets: relatedSets
|
||||
});
|
||||
|
||||
LookUpInit({
|
||||
scope: $scope,
|
||||
form: form,
|
||||
current_item: data.organization,
|
||||
list: OrganizationList,
|
||||
field: 'organization',
|
||||
input_type: 'radio'
|
||||
});
|
||||
|
||||
$scope.organization_url = data.related.organization;
|
||||
$scope.$emit('teamLoaded');
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, form, { hdr: 'Error!', msg: 'Failed to retrieve team: ' + $routeParams.team_id +
|
||||
'. GET status: ' + status });
|
||||
});
|
||||
.success(function (data) {
|
||||
var fld, related, set;
|
||||
$scope.team_name = data.name;
|
||||
for (fld in form.fields) {
|
||||
if (data[fld]) {
|
||||
$scope[fld] = data[fld];
|
||||
master[fld] = $scope[fld];
|
||||
}
|
||||
}
|
||||
related = data.related;
|
||||
for (set in form.related) {
|
||||
if (related[set]) {
|
||||
relatedSets[set] = {
|
||||
url: related[set],
|
||||
iterator: form.related[set].iterator
|
||||
};
|
||||
}
|
||||
}
|
||||
// Initialize related search functions. Doing it here to make sure relatedSets object is populated.
|
||||
RelatedSearchInit({
|
||||
scope: $scope,
|
||||
form: form,
|
||||
relatedSets: relatedSets
|
||||
});
|
||||
RelatedPaginateInit({
|
||||
scope: $scope,
|
||||
relatedSets: relatedSets
|
||||
});
|
||||
|
||||
LookUpInit({
|
||||
scope: $scope,
|
||||
form: form,
|
||||
current_item: data.organization,
|
||||
list: OrganizationList,
|
||||
field: 'organization',
|
||||
input_type: 'radio'
|
||||
});
|
||||
|
||||
$scope.organization_url = data.related.organization;
|
||||
$scope.$emit('teamLoaded');
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, form, { hdr: 'Error!', msg: 'Failed to retrieve team: ' + $routeParams.team_id +
|
||||
'. GET status: ' + status });
|
||||
});
|
||||
});
|
||||
|
||||
$scope.getPermissionText = function () {
|
||||
if (this.permission.permission_type !== "admin" && this.permission.run_ad_hoc_commands) {
|
||||
@@ -431,5 +439,5 @@ export function TeamsEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
|
||||
TeamsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'TeamForm',
|
||||
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit',
|
||||
'ReturnToCaller', 'ClearScope', 'LookUpInit', 'Prompt', 'GetBasePath', 'CheckAccess', 'OrganizationList', 'Wait', 'Stream', 'permissionsChoices', 'permissionsLabel', 'permissionsSearchSelect'
|
||||
'ReturnToCaller', 'ClearScope', 'LookUpInit', 'Prompt', 'GetBasePath', 'CheckAccess', 'OrganizationList', 'Wait', 'Stream', 'fieldChoices', 'fieldLabels', 'permissionsSearchSelect'
|
||||
];
|
||||
|
||||
@@ -208,7 +208,7 @@ UsersAdd.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$r
|
||||
|
||||
export function UsersEdit($scope, $rootScope, $compile, $location, $log, $routeParams, UserForm, GenerateForm, Rest, Alert,
|
||||
ProcessErrors, LoadBreadCrumbs, RelatedSearchInit, RelatedPaginateInit, ReturnToCaller, ClearScope, GetBasePath,
|
||||
Prompt, CheckAccess, ResetForm, Wait, Stream, permissionsChoices, permissionsLabel, permissionsSearchSelect) {
|
||||
Prompt, CheckAccess, ResetForm, Wait, Stream, fieldChoices, fieldLabels, permissionsSearchSelect) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
@@ -224,16 +224,17 @@ export function UsersEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
$scope.permission_search_select = [];
|
||||
|
||||
// return a promise from the options request with the permission type choices (including adhoc) as a param
|
||||
var permissionsChoice = permissionsChoices({
|
||||
var permissionsChoice = fieldChoices({
|
||||
scope: $scope,
|
||||
url: 'api/v1/' + base + '/' + id + '/permissions/'
|
||||
url: 'api/v1/' + base + '/' + id + '/permissions/',
|
||||
field: 'permission_type'
|
||||
});
|
||||
|
||||
// manipulate the choices from the options request to be set on
|
||||
// scope and be usable by the list form
|
||||
permissionsChoice.then(function (choices) {
|
||||
choices =
|
||||
permissionsLabel({
|
||||
fieldLabels({
|
||||
choices: choices
|
||||
});
|
||||
_.map(choices, function(n, key) {
|
||||
@@ -241,22 +242,23 @@ export function UsersEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
});
|
||||
});
|
||||
|
||||
// manipulate the choices from the options request to be usable
|
||||
// by the search option for permission_type, you can't inject the
|
||||
// list until this is done!
|
||||
permissionsChoice.then(function (choices) {
|
||||
form.related.permissions.fields.permission_type.searchOptions =
|
||||
permissionsSearchSelect({
|
||||
choices: choices
|
||||
});
|
||||
generator.inject(form, { mode: 'edit', related: true, scope: $scope });
|
||||
generator.reset();
|
||||
$scope.$emit("loadForm");
|
||||
});
|
||||
|
||||
if ($scope.removeFormReady) {
|
||||
$scope.removeFormReady();
|
||||
}
|
||||
$scope.removeFormReady = $scope.$on('formReady', function () {
|
||||
// manipulate the choices from the options request to be usable
|
||||
// by the search option for permission_type, you can't inject the
|
||||
// list until this is done!
|
||||
permissionsChoice.then(function (choices) {
|
||||
form.related.permissions.fields.permission_type.searchOptions =
|
||||
permissionsSearchSelect({
|
||||
choices: choices
|
||||
});
|
||||
generator.inject(form, { mode: 'edit', related: true, scope: $scope });
|
||||
generator.reset();
|
||||
});
|
||||
|
||||
if ($scope.removePostRefresh) {
|
||||
$scope.removePostRefresh();
|
||||
}
|
||||
@@ -470,54 +472,60 @@ export function UsersEdit($scope, $rootScope, $compile, $location, $log, $routeP
|
||||
// Put form back to its original state
|
||||
ResetForm();
|
||||
|
||||
|
||||
if ($scope.removeModifyForm) {
|
||||
$scope.removeModifyForm();
|
||||
if ($scope.removeLoadForm) {
|
||||
$scope.removeLoadForm();
|
||||
}
|
||||
$scope.removeModifyForm = $scope.$on('modifyForm', function () {
|
||||
// Modify form based on LDAP settings
|
||||
Rest.setUrl(GetBasePath('config'));
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
var i, fld;
|
||||
if (data.user_ldap_fields) {
|
||||
for (i = 0; i < data.user_ldap_fields.length; i++) {
|
||||
fld = data.user_ldap_fields[i];
|
||||
if (form.fields[fld]) {
|
||||
form.fields[fld].readonly = true;
|
||||
form.fields[fld].editRequired = false;
|
||||
if (form.fields[fld].awRequiredWhen) {
|
||||
delete form.fields[fld].awRequiredWhen;
|
||||
$scope.removeLoadForm = $scope.$on('loadForm', function () {
|
||||
|
||||
|
||||
if ($scope.removeModifyForm) {
|
||||
$scope.removeModifyForm();
|
||||
}
|
||||
$scope.removeModifyForm = $scope.$on('modifyForm', function () {
|
||||
// Modify form based on LDAP settings
|
||||
Rest.setUrl(GetBasePath('config'));
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
var i, fld;
|
||||
if (data.user_ldap_fields) {
|
||||
for (i = 0; i < data.user_ldap_fields.length; i++) {
|
||||
fld = data.user_ldap_fields[i];
|
||||
if (form.fields[fld]) {
|
||||
form.fields[fld].readonly = true;
|
||||
form.fields[fld].editRequired = false;
|
||||
if (form.fields[fld].awRequiredWhen) {
|
||||
delete form.fields[fld].awRequiredWhen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$scope.$emit('formReady');
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to retrieve application config. GET status: ' + status });
|
||||
});
|
||||
});
|
||||
|
||||
Wait('start');
|
||||
Rest.setUrl(defaultUrl + id + '/');
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
if (data.ldap_dn !== null && data.ldap_dn !== undefined && data.ldap_dn !== '') {
|
||||
//this is an LDAP user
|
||||
$scope.$emit('modifyForm');
|
||||
} else {
|
||||
$scope.$emit('formReady');
|
||||
}
|
||||
$scope.$emit('formReady');
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to retrieve application config. GET status: ' + status });
|
||||
msg: 'Failed to retrieve user: ' + id + '. GET status: ' + status });
|
||||
});
|
||||
});
|
||||
|
||||
Wait('start');
|
||||
Rest.setUrl(defaultUrl + id + '/');
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
if (data.ldap_dn !== null && data.ldap_dn !== undefined && data.ldap_dn !== '') {
|
||||
//this is an LDAP user
|
||||
$scope.$emit('modifyForm');
|
||||
} else {
|
||||
$scope.$emit('formReady');
|
||||
}
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to retrieve user: ' + id + '. GET status: ' + status });
|
||||
});
|
||||
}
|
||||
|
||||
UsersEdit.$inject = ['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'UserForm', 'GenerateForm',
|
||||
'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit', 'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope',
|
||||
'GetBasePath', 'Prompt', 'CheckAccess', 'ResetForm', 'Wait', 'Stream', 'permissionsChoices', 'permissionsLabel', 'permissionsSearchSelect'
|
||||
'GetBasePath', 'Prompt', 'CheckAccess', 'ResetForm', 'Wait', 'Stream', 'fieldChoices', 'fieldLabels', 'permissionsSearchSelect'
|
||||
];
|
||||
|
||||
@@ -118,8 +118,8 @@ export default
|
||||
sourceModel: 'inventory_script',
|
||||
sourceField: 'name',
|
||||
ngClick: 'lookUpInventory_script()' ,
|
||||
addRequired: false,
|
||||
editRequired: false,
|
||||
addRequired: true,
|
||||
editRequired: true,
|
||||
ngRequired: "source && source.value === 'custom'",
|
||||
},
|
||||
extra_vars: {
|
||||
|
||||
@@ -75,7 +75,7 @@ export default
|
||||
scope: scope,
|
||||
// buttons: [],
|
||||
width: 710,
|
||||
height: 400,
|
||||
height: 450,
|
||||
minWidth: 300,
|
||||
resizable: false,
|
||||
callback: 'DialogReady',
|
||||
|
||||
@@ -751,9 +751,9 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', listGenerator.name
|
||||
$compile(elem)(modal_scope);
|
||||
|
||||
var form_scope =
|
||||
generator.inject(GroupForm, { mode: 'edit', id: 'properties-tab', breadCrumbs: false, related: false, scope: properties_scope });
|
||||
generator.inject(GroupForm, { mode: mode, id: 'properties-tab', breadCrumbs: false, related: false, scope: properties_scope });
|
||||
var source_form_scope =
|
||||
generator.inject(SourceForm, { mode: 'edit', id: 'sources-tab', breadCrumbs: false, related: false, scope: sources_scope });
|
||||
generator.inject(SourceForm, { mode: mode, id: 'sources-tab', breadCrumbs: false, related: false, scope: sources_scope });
|
||||
|
||||
//generator.reset();
|
||||
|
||||
@@ -1465,6 +1465,11 @@ angular.module('GroupsHelper', [ 'RestServices', 'Utilities', listGenerator.name
|
||||
|
||||
// Change the lookup and regions when the source changes
|
||||
sources_scope.sourceChange = function () {
|
||||
sources_scope.credential_name = "";
|
||||
sources_scope.credential = "";
|
||||
if (sources_scope.credential_name_api_error) {
|
||||
delete sources_scope.credential_name_api_error;
|
||||
}
|
||||
parent_scope.showSchedulesTab = (mode === 'edit' && sources_scope.source && sources_scope.source.value!=="manual") ? true : false;
|
||||
SourceChange({ scope: sources_scope, form: SourceForm });
|
||||
};
|
||||
|
||||
@@ -25,9 +25,11 @@ export default
|
||||
|
||||
.factory('CheckLicense', ['$rootScope', '$compile', 'CreateDialog', 'Store',
|
||||
'LicenseUpdateForm', 'GenerateForm', 'TextareaResize', 'ToJSON', 'GetBasePath',
|
||||
'Rest', 'ProcessErrors', 'Alert', 'IsAdmin', '$location',
|
||||
'Rest', 'ProcessErrors', 'Alert', 'IsAdmin', '$location', 'pendoService',
|
||||
'Authorization', 'Wait',
|
||||
function($rootScope, $compile, CreateDialog, Store, LicenseUpdateForm, GenerateForm,
|
||||
TextareaResize, ToJSON, GetBasePath, Rest, ProcessErrors, Alert, IsAdmin, $location) {
|
||||
TextareaResize, ToJSON, GetBasePath, Rest, ProcessErrors, Alert, IsAdmin, $location,
|
||||
pendoService, Authorization, Wait) {
|
||||
return {
|
||||
getRemainingDays: function(time_remaining) {
|
||||
// assumes time_remaining will be in seconds
|
||||
@@ -164,21 +166,32 @@ export default
|
||||
if (typeof json_data === 'object' && Object.keys(json_data).length > 0) {
|
||||
Rest.setUrl(url);
|
||||
Rest.post(json_data)
|
||||
.success(function () {
|
||||
try {
|
||||
$('#license-modal-dialog').dialog('close');
|
||||
}
|
||||
catch(e) {
|
||||
// ignore
|
||||
}
|
||||
.success(function (response) {
|
||||
response.license_info = response;
|
||||
Alert('License Accepted', 'The Ansible Tower license was updated. To review or update the license, choose View License from the Setup menu.','alert-info');
|
||||
$rootScope.features = undefined;
|
||||
$location.path('/home');
|
||||
|
||||
Authorization.getLicense()
|
||||
.success(function (data) {
|
||||
Authorization.setLicense(data);
|
||||
pendoService.issuePendoIdentity();
|
||||
Wait("stop");
|
||||
$location.path('/home');
|
||||
})
|
||||
.error(function () {
|
||||
Wait('stop');
|
||||
Alert('Error', 'Failed to access license information. GET returned status: ' + status, 'alert-danger',
|
||||
$location.path('/logout'));
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
})
|
||||
.error(function (data, status) {
|
||||
.catch(function (response) {
|
||||
scope.license_json_api_error = "A valid license key in JSON format is required";
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to update license. POST returned: ' + status
|
||||
ProcessErrors(scope, response.data, response.status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to update license. POST returned: ' + response.status
|
||||
});
|
||||
});
|
||||
} else {
|
||||
|
||||
@@ -39,16 +39,25 @@ angular.module('LoadConfigHelper', ['Utilities'])
|
||||
if(angular.isObject(response.data)){
|
||||
$AnsibleConfig = _.extend($AnsibleConfig, response.data);
|
||||
Store('AnsibleConfig', $AnsibleConfig);
|
||||
if ($rootScope.loginConfig) {
|
||||
$rootScope.loginConfig.resolve('config loaded');
|
||||
}
|
||||
$rootScope.$emit('ConfigReady');
|
||||
}
|
||||
else {
|
||||
$log.info('local_settings.json is not a valid object');
|
||||
if ($rootScope.loginConfig) {
|
||||
$rootScope.loginConfig.resolve('config loaded');
|
||||
}
|
||||
$rootScope.$emit('ConfigReady');
|
||||
}
|
||||
|
||||
}, function() {
|
||||
//local_settings.json not found
|
||||
$log.info('local_settings.json not found');
|
||||
if ($rootScope.loginConfig) {
|
||||
$rootScope.loginConfig.resolve('config loaded');
|
||||
}
|
||||
$rootScope.$emit('ConfigReady');
|
||||
});
|
||||
});
|
||||
@@ -57,15 +66,16 @@ angular.module('LoadConfigHelper', ['Utilities'])
|
||||
// load config.js
|
||||
$log.info('attempting to load config.js');
|
||||
$http({ method:'GET', url: $basePath + 'config.js' })
|
||||
.success(function(data) {
|
||||
.then(function(response) {
|
||||
$log.info('loaded config.js');
|
||||
$AnsibleConfig = eval(data);
|
||||
$AnsibleConfig = eval(response.data);
|
||||
Store('AnsibleConfig', $AnsibleConfig);
|
||||
$rootScope.$emit('LoadConfig');
|
||||
})
|
||||
.error(function(data, status) {
|
||||
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to load ' + $basePath + '/config.js. GET status: ' + status
|
||||
.catch(function(response) {
|
||||
response.data = 'Failed to load ' + $basePath + '/config.js';
|
||||
ProcessErrors($rootScope, response, response.status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to load ' + $basePath + '/config.js.'
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -60,7 +60,8 @@ export default
|
||||
logout: function () {
|
||||
// the following puts our primary scope up for garbage collection, which
|
||||
// should prevent content flash from the prior user.
|
||||
var scope = angular.element(document.getElementById('main-view')).scope();
|
||||
|
||||
var x, scope = angular.element(document.getElementById('main-view')).scope();
|
||||
scope.$destroy();
|
||||
//$rootScope.$destroy();
|
||||
|
||||
@@ -78,6 +79,9 @@ export default
|
||||
$cookieStore.remove('lastPath');
|
||||
$rootScope.lastPath = '/home';
|
||||
}
|
||||
x = Store('sessionTime');
|
||||
x[$rootScope.current_user.id].loggedIn = false;
|
||||
Store('sessionTime', x);
|
||||
|
||||
$rootScope.lastUser = $cookieStore.get('current_user').id;
|
||||
$cookieStore.remove('token_expires');
|
||||
@@ -94,7 +98,7 @@ export default
|
||||
$rootScope.token_expires = null;
|
||||
$rootScope.login_username = null;
|
||||
$rootScope.login_password = null;
|
||||
$rootScope.sessionTimer.expireSession();
|
||||
$rootScope.sessionTimer.clearTimers();
|
||||
},
|
||||
|
||||
getLicense: function () {
|
||||
@@ -112,6 +116,7 @@ export default
|
||||
var license = data.license_info;
|
||||
license.analytics_status = data.analytics_status;
|
||||
license.version = data.version;
|
||||
license.ansible_version = data.ansible_version;
|
||||
license.tested = false;
|
||||
Store('license', license);
|
||||
$rootScope.features = Store('license').features;
|
||||
@@ -149,7 +154,6 @@ export default
|
||||
// store the response values in $rootScope so we can get to them later
|
||||
$rootScope.current_user = response.results[0];
|
||||
$cookieStore.put('current_user', response.results[0]); //keep in session cookie in the event of browser refresh
|
||||
$rootScope.$emit('OpenSocket');
|
||||
},
|
||||
|
||||
restoreUserInfo: function () {
|
||||
|
||||
@@ -12,7 +12,8 @@ export default
|
||||
Store, $log) {
|
||||
return {
|
||||
setPendoOptions: function (config) {
|
||||
var options = {
|
||||
var tower_version = config.version.split('-')[0],
|
||||
options = {
|
||||
visitor: {
|
||||
id: null,
|
||||
role: null,
|
||||
@@ -23,7 +24,9 @@ export default
|
||||
planLevel: config.license_type,
|
||||
planPrice: config.instance_count,
|
||||
creationDate: config.license_date,
|
||||
trial: config.trial
|
||||
trial: config.trial,
|
||||
tower_version: tower_version,
|
||||
ansible_version: config.ansible_version
|
||||
}
|
||||
};
|
||||
if(config.analytics_status === 'detailed'){
|
||||
|
||||
@@ -23,22 +23,21 @@
|
||||
*/
|
||||
export default
|
||||
['$rootScope', '$cookieStore', 'transitionTo', 'CreateDialog', 'Authorization',
|
||||
'Store', '$interval',
|
||||
'Store', '$interval', '$location', '$q',
|
||||
function ($rootScope, $cookieStore, transitionTo, CreateDialog, Authorization,
|
||||
Store, $interval) {
|
||||
Store, $interval, $location, $q) {
|
||||
return {
|
||||
|
||||
sessionTime: null,
|
||||
timeout: null,
|
||||
|
||||
getSessionTime: function () {
|
||||
if(Store('sessionTime_'+$rootScope.current_user.id)){
|
||||
return Store('sessionTime_'+$rootScope.current_user.id);
|
||||
if(Store('sessionTime')){
|
||||
return Store('sessionTime')[$rootScope.current_user.id].time;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
isExpired: function (increase) {
|
||||
@@ -83,14 +82,24 @@ export default
|
||||
this.sessionTime = 0;
|
||||
this.clearTimers();
|
||||
$cookieStore.put('sessionExpired', true);
|
||||
transitionTo('signOut');
|
||||
},
|
||||
|
||||
moveForward: function () {
|
||||
var tm, t;
|
||||
var tm, t, x, y;
|
||||
tm = ($AnsibleConfig.session_timeout) ? $AnsibleConfig.session_timeout : 1800;
|
||||
t = new Date().getTime() + (tm * 1000);
|
||||
Store('sessionTime_'+$rootScope.current_user.id, t);
|
||||
x = {
|
||||
time: t,
|
||||
loggedIn: true
|
||||
};
|
||||
if(Store('sessionTime')){
|
||||
y = Store('sessionTime');
|
||||
}
|
||||
else {
|
||||
y = {};
|
||||
}
|
||||
y[$rootScope.current_user.id] = x;
|
||||
Store('sessionTime' , y);
|
||||
$rootScope.sessionExpired = false;
|
||||
$cookieStore.put('sessionExpired', false);
|
||||
this.startTimers();
|
||||
@@ -148,6 +157,14 @@ export default
|
||||
$('#idle-modal').dialog('close');
|
||||
}
|
||||
that.expireSession('idle');
|
||||
$location.url('/login');
|
||||
}
|
||||
if(Store('sessionTime') &&
|
||||
Store('sessionTime')[$rootScope.current_user.id] &&
|
||||
Store('sessionTime')[$rootScope.current_user.id].loggedIn === false){
|
||||
that.expireSession();
|
||||
$location.url('/login');
|
||||
|
||||
}
|
||||
|
||||
}, 1000);
|
||||
@@ -156,11 +173,15 @@ export default
|
||||
|
||||
clearTimers: function(){
|
||||
$interval.cancel($rootScope.expireTimer);
|
||||
delete $rootScope.expireTimer;
|
||||
},
|
||||
|
||||
init: function () {
|
||||
var deferred = $q.defer();
|
||||
this.moveForward();
|
||||
return this;
|
||||
deferred.resolve(this);
|
||||
return deferred.promise;
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -110,17 +110,11 @@ export default ['$log', '$cookieStore', '$compile', '$window', '$rootScope', '$l
|
||||
setLoginFocus();
|
||||
});
|
||||
|
||||
|
||||
if ($AnsibleConfig.custom_logo) {
|
||||
scope.customLogo = "custom_console_logo.png"
|
||||
scope.customLogoPresent = true;
|
||||
} else {
|
||||
scope.customLogo = "login_modal_logo.png";
|
||||
scope.customLogoPresent = false;
|
||||
}
|
||||
|
||||
scope.customLoginInfo = $AnsibleConfig.custom_login_info;
|
||||
scope.customLoginInfoPresent = (scope.customLoginInfo) ? true : false;
|
||||
$rootScope.loginConfig.promise.then(function () {
|
||||
scope.customLogo = ($AnsibleConfig.custom_logo) ? "custom_console_logo.png" : "tower_console_logo.png";
|
||||
scope.customLoginInfo = $AnsibleConfig.custom_login_info;
|
||||
scope.customLoginInfoPresent = ($AnsibleConfig.customLoginInfo) ? true : false;
|
||||
});
|
||||
|
||||
// Reset the login form
|
||||
//scope.loginForm.login_username.$setPristine();
|
||||
@@ -171,9 +165,12 @@ export default ['$log', '$cookieStore', '$compile', '$window', '$rootScope', '$l
|
||||
Authorization.getUser()
|
||||
.success(function (data) {
|
||||
Authorization.setUserInfo(data);
|
||||
$rootScope.sessionTimer = Timer.init();
|
||||
$rootScope.user_is_superuser = data.results[0].is_superuser;
|
||||
scope.$emit('AuthorizationGetLicense');
|
||||
Timer.init().then(function(timer){
|
||||
$rootScope.sessionTimer = timer;
|
||||
$rootScope.$emit('OpenSocket');
|
||||
$rootScope.user_is_superuser = data.results[0].is_superuser;
|
||||
scope.$emit('AuthorizationGetLicense');
|
||||
});
|
||||
})
|
||||
.error(function (data, status) {
|
||||
Authorization.logout();
|
||||
@@ -200,7 +197,7 @@ export default ['$log', '$cookieStore', '$compile', '$window', '$rootScope', '$l
|
||||
function (data) {
|
||||
var key;
|
||||
Wait('stop');
|
||||
if (data.data.non_field_errors && data.data.non_field_errors.length === 0) {
|
||||
if (data && data.data && data.data.non_field_errors && data.data.non_field_errors.length === 0) {
|
||||
// show field specific errors returned by the API
|
||||
for (key in data.data) {
|
||||
scope[key + 'Error'] = data.data[key][0];
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
var options = [],
|
||||
error = "";
|
||||
|
||||
function parseGoogle(option, key) {
|
||||
function parseGoogle(option) {
|
||||
var newOption = {};
|
||||
|
||||
newOption.type = "google";
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<div class="row">
|
||||
<div class="left-side col-sm-4 col-xs-12">
|
||||
<img id="about-modal-logo" src="static/assets/tower_console_bug.png">
|
||||
|
||||
</div>
|
||||
<div class="right-side col-sm-8 col-xs-12">
|
||||
<img id="about-modal-titlelogo" src="static/assets/tower_login_logo.png"><br>
|
||||
<p>Tower Version <span id='about-modal-version'></span></p>
|
||||
<textarea class="form-control" rows="2" readonly>Copyright 2015. All rights reserved.
Ansible and Ansible Tower are registered trademarks of Ansible, Inc.
</textarea>
|
||||
<br>
|
||||
<p>Visit <a href="http://www.ansible.com" target="_blank">Ansible.com</a> for more information!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -33,8 +33,24 @@
|
||||
<div class="form-horizontal" role="form" id="job-status-form">
|
||||
|
||||
<div class="form-group" ng-show="job_status.explanation">
|
||||
<label class="col-lg-2 col-md-12 col-sm-12 col-xs-12">Explanation</label>
|
||||
<div class="col-lg-10 col-md-12 col-sm-12 col-xs-12 job_status_explanation" ng-bind-html="job_status.explanation"></div>
|
||||
<label class="col-lg-2 col-md-2 col-sm-2 col-xs-3 col-xs-12">Explanation</label>
|
||||
<div class="col-lg-10 col-md-10 col-sm-10 col-xs-9 job_status_explanation"
|
||||
ng-show="!previousTaskFailed" ng-bind-html="job_status.explanation"></div>
|
||||
<div class="col-lg-10 col-md-10 col-sm-10 col-xs-9 job_status_explanation"
|
||||
ng-show="previousTaskFailed">Previous Task Failed
|
||||
<a
|
||||
href=""
|
||||
id="explanation_help"
|
||||
aw-pop-over="{{ task_detail }}"
|
||||
aw-pop-over-watch="task_detail"
|
||||
data-placement="bottom"
|
||||
data-container="body" class="help-link" over-title="Failure Detail"
|
||||
title=""
|
||||
tabindex="-1">
|
||||
<i class="fa fa-question-circle">
|
||||
</i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-show="job_status.traceback">
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
* @description This controller for permissions add
|
||||
*/
|
||||
export default
|
||||
['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'permissionsForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', 'ReturnToCaller', 'InventoryList', 'ProjectList', 'LookUpInit', 'CheckAccess', 'Wait', 'permissionsCategoryChange', 'permissionsChoices', 'permissionsLabel',
|
||||
function($scope, $rootScope, $compile, $location, $log, $routeParams, permissionsForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath, ReturnToCaller, InventoryList, ProjectList, LookUpInit, CheckAccess, Wait, permissionsCategoryChange, permissionsChoices, permissionsLabel) {
|
||||
['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'permissionsForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ClearScope', 'GetBasePath', 'ReturnToCaller', 'InventoryList', 'ProjectList', 'LookUpInit', 'CheckAccess', 'Wait', 'permissionsCategoryChange', 'fieldChoices', 'fieldLabels',
|
||||
function($scope, $rootScope, $compile, $location, $log, $routeParams, permissionsForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ClearScope, GetBasePath, ReturnToCaller, InventoryList, ProjectList, LookUpInit, CheckAccess, Wait, permissionsCategoryChange, fieldChoices, fieldLabels) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
@@ -22,13 +22,14 @@ export default
|
||||
base = $location.path().replace(/^\//, '').split('/')[0],
|
||||
master = {};
|
||||
|
||||
var permissionsChoice = permissionsChoices({
|
||||
var permissionsChoice = fieldChoices({
|
||||
scope: $scope,
|
||||
url: 'api/v1/' + base + '/' + id + '/permissions/'
|
||||
url: 'api/v1/' + base + '/' + id + '/permissions/',
|
||||
field: 'permission_type'
|
||||
});
|
||||
|
||||
permissionsChoice.then(function (choices) {
|
||||
return permissionsLabel({
|
||||
return fieldLabels({
|
||||
choices: choices
|
||||
});
|
||||
}).then(function (choices) {
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
* @description This controller for permissions edit
|
||||
*/
|
||||
export default
|
||||
['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'permissionsForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'Prompt', 'GetBasePath', 'InventoryList', 'ProjectList', 'LookUpInit', 'CheckAccess', 'Wait', 'permissionsCategoryChange', 'permissionsChoices', 'permissionsLabel',
|
||||
function($scope, $rootScope, $compile, $location, $log, $routeParams, permissionsForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, Prompt, GetBasePath, InventoryList, ProjectList, LookUpInit, CheckAccess, Wait, permissionsCategoryChange, permissionsChoices, permissionsLabel) {
|
||||
['$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'permissionsForm', 'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'ReturnToCaller', 'ClearScope', 'Prompt', 'GetBasePath', 'InventoryList', 'ProjectList', 'LookUpInit', 'CheckAccess', 'Wait', 'permissionsCategoryChange', 'fieldChoices', 'fieldLabels',
|
||||
function($scope, $rootScope, $compile, $location, $log, $routeParams, permissionsForm, GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, ReturnToCaller, ClearScope, Prompt, GetBasePath, InventoryList, ProjectList, LookUpInit, CheckAccess, Wait, permissionsCategoryChange, fieldChoices, fieldLabels) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
@@ -25,13 +25,14 @@ export default
|
||||
|
||||
$scope.permission_label = {};
|
||||
|
||||
var permissionsChoice = permissionsChoices({
|
||||
var permissionsChoice = fieldChoices({
|
||||
scope: $scope,
|
||||
url: 'api/v1/' + base + '/' + base_id + '/permissions/'
|
||||
url: 'api/v1/' + base + '/' + base_id + '/permissions/',
|
||||
field: 'permission_type'
|
||||
});
|
||||
|
||||
permissionsChoice.then(function (choices) {
|
||||
return permissionsLabel({
|
||||
return fieldLabels({
|
||||
choices: choices
|
||||
});
|
||||
}).then(function (choices) {
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
|
||||
export default
|
||||
['$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'permissionsList', 'generateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', 'GetBasePath', 'CheckAccess', 'Wait', 'permissionsChoices', 'permissionsLabel', 'permissionsSearchSelect',
|
||||
function ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, permissionsList, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, CheckAccess, Wait, permissionsChoices, permissionsLabel, permissionsSearchSelect) {
|
||||
['$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'permissionsList', 'generateList', 'LoadBreadCrumbs', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope', 'ProcessErrors', 'GetBasePath', 'CheckAccess', 'Wait', 'fieldChoices', 'fieldLabels', 'permissionsSearchSelect',
|
||||
function ($scope, $rootScope, $location, $log, $routeParams, Rest, Alert, permissionsList, GenerateList, LoadBreadCrumbs, Prompt, SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath, CheckAccess, Wait, fieldChoices, fieldLabels, permissionsSearchSelect) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
@@ -27,16 +27,17 @@ export default
|
||||
$scope.permission_search_select = [];
|
||||
|
||||
// return a promise from the options request with the permission type choices (including adhoc) as a param
|
||||
var permissionsChoice = permissionsChoices({
|
||||
var permissionsChoice = fieldChoices({
|
||||
scope: $scope,
|
||||
url: 'api/v1/' + base + '/' + base_id + '/permissions/'
|
||||
url: 'api/v1/' + base + '/' + base_id + '/permissions/',
|
||||
field: 'permission_type'
|
||||
});
|
||||
|
||||
// manipulate the choices from the options request to be set on
|
||||
// scope and be usable by the list form
|
||||
permissionsChoice.then(function (choices) {
|
||||
choices =
|
||||
permissionsLabel({
|
||||
fieldLabels({
|
||||
choices: choices
|
||||
});
|
||||
_.map(choices, function(n, key) {
|
||||
|
||||
@@ -12,8 +12,6 @@ import list from './shared/permissions.list';
|
||||
import form from './shared/permissions.form';
|
||||
|
||||
import permissionsCategoryChange from './shared/category-change.factory';
|
||||
import permissionsChoices from './shared/get-choices.factory';
|
||||
import permissionsLabel from './shared/get-labels.factory';
|
||||
import permissionsSearchSelect from './shared/get-search-select.factory';
|
||||
|
||||
export default
|
||||
@@ -25,6 +23,4 @@ export default
|
||||
.factory('permissionsList', list)
|
||||
.factory('permissionsForm', form)
|
||||
.factory('permissionsCategoryChange', permissionsCategoryChange)
|
||||
.factory('permissionsChoices', permissionsChoices)
|
||||
.factory('permissionsLabel', permissionsLabel)
|
||||
.factory('permissionsSearchSelect', permissionsSearchSelect);
|
||||
|
||||
@@ -16,24 +16,28 @@
|
||||
['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
|
||||
return function (params) {
|
||||
var scope = params.scope,
|
||||
url = params.url;
|
||||
url = params.url,
|
||||
field = params.field;
|
||||
|
||||
// Auto populate the field if there is only one result
|
||||
Rest.setUrl(url);
|
||||
return Rest.options()
|
||||
.then(function (data) {
|
||||
data = data.data;
|
||||
var choices = data.actions.GET.permission_type.choices;
|
||||
var choices = data.actions.GET[field].choices;
|
||||
|
||||
// manually add the adhoc label to the choices object
|
||||
choices.push(["adhoc",
|
||||
data.actions.GET.run_ad_hoc_commands.help_text]);
|
||||
// manually add the adhoc label to the choices object if
|
||||
// the permission_type field
|
||||
if (field === "permission_type") {
|
||||
choices.push(["adhoc",
|
||||
data.actions.GET.run_ad_hoc_commands.help_text]);
|
||||
}
|
||||
|
||||
return choices;
|
||||
})
|
||||
.catch(function (data, status) {
|
||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to get permission type labels. Options requrest returned status: ' + status });
|
||||
msg: 'Failed to get ' + field + ' labels. Options requrest returned status: ' + status });
|
||||
});
|
||||
};
|
||||
}];
|
||||
@@ -11,8 +11,8 @@
|
||||
*************************************************/
|
||||
|
||||
export default
|
||||
[ '$rootScope', '$q',
|
||||
function ($rootScope, $q) {
|
||||
[ '$rootScope', '$q', '$injector',
|
||||
function ($rootScope, $q, $injector) {
|
||||
return {
|
||||
response: function(config) {
|
||||
if(config.headers('auth-token-timeout') !== null){
|
||||
@@ -21,8 +21,10 @@
|
||||
return config;
|
||||
},
|
||||
responseError: function(rejection){
|
||||
if( rejection.data && !_.isEmpty(rejection.data.detail) && rejection.data.detail === "Maximum per-user sessions reached"){
|
||||
if(rejection && rejection.data && rejection.data.detail && rejection.data.detail === "Maximum per-user sessions reached"){
|
||||
$rootScope.sessionTimer.expireSession('session_limit');
|
||||
var location = $injector.get('$location');
|
||||
location.url('/login');
|
||||
return $q.reject(rejection);
|
||||
}
|
||||
return $q.reject(rejection);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
import restServicesFactory from './restServices.factory';
|
||||
import interceptors from './interceptors.service';
|
||||
import fieldChoices from './get-choices.factory';
|
||||
import fieldLabels from './get-labels.factory';
|
||||
|
||||
export default
|
||||
angular.module('RestServices', [])
|
||||
@@ -13,4 +15,6 @@ export default
|
||||
$httpProvider.interceptors.push('RestInterceptor');
|
||||
}])
|
||||
.factory('Rest', restServicesFactory)
|
||||
.service('RestInterceptor', interceptors);
|
||||
.service('RestInterceptor', interceptors)
|
||||
.factory('fieldChoices', fieldChoices)
|
||||
.factory('fieldLabels', fieldLabels);
|
||||
|
||||
@@ -53,8 +53,8 @@
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
<a link-to="managementJobsList" class="SetupItem SetupItem--aside HoverIcon Media">
|
||||
<i class="HoverIcon-icon HoverIcon-icon--opacity HoverIcon-icon--color Media-figure SetupItem-icon SetupItem-icon--aside" ng-if="user_is_superuser">
|
||||
<a link-to="managementJobsList" class="SetupItem SetupItem--aside HoverIcon Media" ng-if="user_is_superuser">
|
||||
<i class="HoverIcon-icon HoverIcon-icon--opacity HoverIcon-icon--color Media-figure SetupItem-icon SetupItem-icon--aside">
|
||||
<aw-icon name="ManagementJobs"></aw-icon>
|
||||
</i>
|
||||
<div class="Media-block">
|
||||
|
||||
@@ -252,15 +252,20 @@ angular.module('Utilities', ['RestServices', 'Utilities', 'sanitizeFilter'])
|
||||
if ((!fieldErrors) && defaultMsg) {
|
||||
Alert(defaultMsg.hdr, defaultMsg.msg);
|
||||
}
|
||||
} else if (typeof data === 'object' && Object.keys(data).length > 0) {
|
||||
keys = Object.keys(data);
|
||||
if (Array.isArray(data[keys[0]])) {
|
||||
msg = data[keys[0]][0];
|
||||
} else if (typeof data === 'object' && data !== null){
|
||||
if(Object.keys(data).length > 0) {
|
||||
keys = Object.keys(data);
|
||||
if (Array.isArray(data[keys[0]])) {
|
||||
msg = data[keys[0]][0];
|
||||
}
|
||||
else {
|
||||
msg = data[keys[0]];
|
||||
}
|
||||
Alert(defaultMsg.hdr, msg);
|
||||
}
|
||||
else {
|
||||
msg = data[keys[0]];
|
||||
Alert(defaultMsg.hdr, defaultMsg.msg);
|
||||
}
|
||||
Alert(defaultMsg.hdr, msg);
|
||||
} else {
|
||||
Alert(defaultMsg.hdr, defaultMsg.msg);
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'JobsHelper'])
|
||||
if (/^\-?\d*$/.test(viewValue)) {
|
||||
// it is valid
|
||||
ctrl.$setValidity('integer', true);
|
||||
if ( viewValue === '-' || viewValue === '-0' || viewValue === '' || viewValue === null) {
|
||||
if ( viewValue === '-' || viewValue === '-0' || viewValue === null) {
|
||||
ctrl.$setValidity('integer', false);
|
||||
return viewValue;
|
||||
}
|
||||
|
||||
@@ -221,15 +221,68 @@ angular.module('StreamWidget', ['RestServices', 'Utilities', 'StreamListDefiniti
|
||||
if (obj2_obj && obj2_obj.name && !/^_delete/.test(obj2_obj.name)) {
|
||||
obj2_obj.base = obj2;
|
||||
obj2_obj.name = $filter('sanitize')(obj2_obj.name);
|
||||
descr += obj2 + " <a href=\"" + BuildUrl(obj2_obj) + "\">" + obj2_obj.name + '</a>' + ((activity.operation === 'disassociate') ? ' from ' : ' to ');
|
||||
descr_nolink += obj2 + ' ' + obj2_obj.name + ((activity.operation === 'disassociate') ? ' from ' : ' to ');
|
||||
descr += obj2 +
|
||||
" <a href=\"" + BuildUrl(obj2_obj) + "\">" +
|
||||
obj2_obj.name + '</a>';
|
||||
if (activity.object_association === 'admins') {
|
||||
if (activity.operation === 'disassociate') {
|
||||
descr += ' from being an admin of ';
|
||||
} else {
|
||||
descr += ' as an admin of ';
|
||||
}
|
||||
} else {
|
||||
if (activity.operation === 'disassociate') {
|
||||
descr += ' from ';
|
||||
} else {
|
||||
descr += ' to ';
|
||||
}
|
||||
}
|
||||
descr_nolink += obj2 + ' ' + obj2_obj.name;
|
||||
if (activity.object_association === 'admins') {
|
||||
if (activity.operation === 'disassociate') {
|
||||
descr_nolink += ' from being an admin of ';
|
||||
} else {
|
||||
descr_nolink += ' as an admin of ';
|
||||
}
|
||||
} else {
|
||||
if (activity.operation === 'disassociate') {
|
||||
descr_nolink += ' from ';
|
||||
} else {
|
||||
descr_nolink += ' to ';
|
||||
}
|
||||
}
|
||||
} else if (obj2) {
|
||||
name = '';
|
||||
if (obj2_obj && obj2_obj.name) {
|
||||
name = ' ' + stripDeleted(obj2_obj.name);
|
||||
}
|
||||
descr += obj2 + name + ((activity.operation === 'disassociate') ? ' from ' : ' to ');
|
||||
descr_nolink += obj2 + name + ((activity.operation === 'disassociate') ? ' from ' : ' to ');
|
||||
if (activity.object_association === 'admins') {
|
||||
if (activity.operation === 'disassociate') {
|
||||
descr += ' from being an admin of ';
|
||||
} else {
|
||||
descr += ' as an admin of ';
|
||||
}
|
||||
} else {
|
||||
if (activity.operation === 'disassociate') {
|
||||
descr += ' from ';
|
||||
} else {
|
||||
descr += ' to ';
|
||||
}
|
||||
}
|
||||
descr_nolink += obj2 + ' ' + obj2_obj.name;
|
||||
if (activity.object_association === 'admins') {
|
||||
if (activity.operation === 'disassociate') {
|
||||
descr_nolink += ' from being an admin of ';
|
||||
} else {
|
||||
descr_nolink += ' as an admin of ';
|
||||
}
|
||||
} else {
|
||||
if (activity.operation === 'disassociate') {
|
||||
descr_nolink += ' from ';
|
||||
} else {
|
||||
descr_nolink += ' to ';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obj1_obj && obj1_obj.name && !/^\_delete/.test(obj1_obj.name)) {
|
||||
obj1_obj.base = obj1;
|
||||
|
||||
Reference in New Issue
Block a user