mirror of
https://github.com/ansible/awx.git
synced 2026-01-18 13:11:19 -03:30
parent
8dbe24cb4f
commit
0971642d20
@ -99,7 +99,9 @@ a:focus {
|
||||
color: @blue-dark;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn{
|
||||
text-transform: uppercase;
|
||||
}
|
||||
/* Old style TB default button with grey background */
|
||||
.btn-grey {
|
||||
color: #333;
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2015 Ansible, Inc.
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
|
||||
|
||||
var urlPrefix;
|
||||
|
||||
if ($basePath) {
|
||||
@ -34,6 +32,7 @@ import managementJobs from './management-jobs/main';
|
||||
import jobDetail from './job-detail/main';
|
||||
|
||||
// modules
|
||||
import license from './license/main';
|
||||
import setupMenu from './setup-menu/main';
|
||||
import mainMenu from './main-menu/main';
|
||||
import breadCrumb from './bread-crumb/main';
|
||||
@ -46,7 +45,6 @@ import login from './login/main';
|
||||
import activityStream from './activity-stream/main';
|
||||
import standardOut from './standard-out/main';
|
||||
import {JobTemplatesList, JobTemplatesAdd, JobTemplatesEdit} from './controllers/JobTemplates';
|
||||
import {LicenseController} from './controllers/License';
|
||||
import {ScheduleEditController} from './controllers/Schedules';
|
||||
import {ProjectsList, ProjectsAdd, ProjectsEdit} from './controllers/Projects';
|
||||
import {OrganizationsList, OrganizationsAdd, OrganizationsEdit} from './controllers/Organizations';
|
||||
@ -79,6 +77,7 @@ var tower = angular.module('Tower', [
|
||||
// 'ngAnimate',
|
||||
'ngSanitize',
|
||||
'ngCookies',
|
||||
license.name,
|
||||
RestServices.name,
|
||||
browserData.name,
|
||||
systemTracking.name,
|
||||
@ -99,7 +98,6 @@ var tower = angular.module('Tower', [
|
||||
standardOut.name,
|
||||
'templates',
|
||||
'Utilities',
|
||||
'LicenseHelper',
|
||||
'OrganizationFormDefinition',
|
||||
'UserFormDefinition',
|
||||
'FormGenerator',
|
||||
@ -858,21 +856,6 @@ var tower = angular.module('Tower', [
|
||||
}
|
||||
}).
|
||||
|
||||
state('license', {
|
||||
url: '/license',
|
||||
templateUrl: urlPrefix + 'partials/license.html',
|
||||
controller: LicenseController,
|
||||
ncyBreadcrumb: {
|
||||
parent: 'setup',
|
||||
label: 'LICENSE'
|
||||
},
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
state('sockets', {
|
||||
url: '/sockets',
|
||||
templateUrl: urlPrefix + 'partials/sockets.html',
|
||||
@ -1042,7 +1025,6 @@ var tower = angular.module('Tower', [
|
||||
|
||||
|
||||
$rootScope.$on("$stateChangeStart", function (event, next, nextParams, prev) {
|
||||
|
||||
// this line removes the query params attached to a route
|
||||
if(prev && prev.$$route &&
|
||||
prev.$$route.name === 'systemTracking'){
|
||||
@ -1082,15 +1064,15 @@ var tower = angular.module('Tower', [
|
||||
if ($rootScope.current_user === undefined || $rootScope.current_user === null) {
|
||||
Authorization.restoreUserInfo(); //user must have hit browser refresh
|
||||
}
|
||||
if (next && next.$$route && (!/^\/(login|logout)/.test(next.$$route.originalPath))) {
|
||||
// if not headed to /login or /logout, then check the license
|
||||
CheckLicense.test();
|
||||
}
|
||||
}
|
||||
activateTab();
|
||||
});
|
||||
|
||||
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
|
||||
// catch license expiration notifications immediately after user logs in, redirect
|
||||
if (fromState.name == 'signIn'){
|
||||
CheckLicense.notify();
|
||||
}
|
||||
// broadcast event change if editing crud object
|
||||
if ($location.$$path && $location.$$path.split("/")[3] && $location.$$path.split("/")[3] === "schedules") {
|
||||
var list = $location.$$path.split("/")[3];
|
||||
|
||||
@ -1,189 +0,0 @@
|
||||
/************************************
|
||||
* Copyright (c) 2015 Ansible, Inc.
|
||||
*
|
||||
*
|
||||
* Organizations.js
|
||||
*
|
||||
* Controller functions for Organization model.
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name controllers.function:Organizations
|
||||
* @description This controller's for the Organizations page
|
||||
*/
|
||||
|
||||
|
||||
export function LicenseController(ClearScope, $location, $rootScope, $compile, $filter, GenerateForm, Rest, Alert,
|
||||
GetBasePath, ProcessErrors, FormatDate, Prompt, Empty, LicenseForm, IsAdmin, CreateDialog, CheckLicense,
|
||||
TextareaResize, $scope, Wait) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
$scope.getDefaultHTML = function(license_info) {
|
||||
var fld, html,
|
||||
self = this,
|
||||
generator = GenerateForm;
|
||||
|
||||
self.form = angular.copy(LicenseForm);
|
||||
|
||||
for (fld in self.form.fields) {
|
||||
if (fld !== 'time_remaining' && fld !== 'license_status' && fld !== 'tower_version') {
|
||||
if (Empty(license_info[fld])) {
|
||||
delete self.form.fields[fld];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsAdmin()) {
|
||||
delete self.form.fields.license_key;
|
||||
}
|
||||
|
||||
if (license_info.is_aws || Empty(license_info.license_date)) {
|
||||
delete self.form.fields.license_date;
|
||||
delete self.form.fields.time_remaining;
|
||||
}
|
||||
|
||||
html = generator.buildHTML(self.form, { mode: 'edit', showButtons: false });
|
||||
return html;
|
||||
};
|
||||
|
||||
$scope.loadDefaultScope = function(license_info, version) {
|
||||
var fld, dt, days, license,
|
||||
self = this;
|
||||
|
||||
for (fld in self.form.fields) {
|
||||
if (!Empty(license_info[fld])) {
|
||||
$scope[fld] = license_info[fld];
|
||||
}
|
||||
}
|
||||
|
||||
$scope.tower_version = version;
|
||||
|
||||
if ($scope.license_date) {
|
||||
dt = new Date(parseInt($scope.license_date, 10) * 1000); // expects license_date in seconds
|
||||
$scope.license_date = FormatDate(dt);
|
||||
$scope.time_remaining = parseInt($scope.time_remaining,10) * 1000;
|
||||
if ($scope.time_remaining < 0) {
|
||||
days = 0;
|
||||
} else {
|
||||
days = Math.floor($scope.time_remaining / 86400000);
|
||||
}
|
||||
$scope.time_remaining = (days!==1) ? $filter('number')(days, 0) + ' days' : $filter('number')(days, 0) + ' day'; // '1 day' and '0 days/2 days' or more
|
||||
}
|
||||
|
||||
if (parseInt($scope.free_instances) <= 0) {
|
||||
$scope.free_instances_class = 'field-failure';
|
||||
} else {
|
||||
$scope.free_instances_class = 'field-success';
|
||||
}
|
||||
|
||||
license = license_info;
|
||||
if (license.valid_key === undefined) {
|
||||
$scope.license_status = 'Missing License Key';
|
||||
$scope.status_color = 'license-invalid';
|
||||
} else if (!license.valid_key) {
|
||||
$scope.license_status = 'Invalid License Key';
|
||||
$scope.status_color = 'license-invalid';
|
||||
} else if (license.date_expired !== undefined && license.date_expired) {
|
||||
$scope.license_status = 'License Expired';
|
||||
$scope.status_color = 'license-expired';
|
||||
} else if (license.date_warning !== undefined && license.date_warning) {
|
||||
$scope.license_status = 'License Expiring Soon';
|
||||
$scope.status_color = 'license-warning';
|
||||
} else if (license.free_instances !== undefined && parseInt(license.free_instances) <= 0) {
|
||||
$scope.license_status = 'No Available Managed Hosts';
|
||||
$scope.status_color = 'license-invalid';
|
||||
} else {
|
||||
$scope.license_status = 'Valid License';
|
||||
$scope.status_color = 'license-valid';
|
||||
}
|
||||
};
|
||||
|
||||
$scope.setLicense = function(license_info, version) {
|
||||
this.license = license_info;
|
||||
this.version = version;
|
||||
};
|
||||
|
||||
$scope.getLicense = function(){
|
||||
return this.license;
|
||||
};
|
||||
|
||||
$scope.submitLicenseKey = function() {
|
||||
CheckLicense.postLicense($scope.license_json, $scope);
|
||||
};
|
||||
|
||||
if ($scope.removeLicenseDataReady) {
|
||||
$scope.removeLicenseDataReady();
|
||||
}
|
||||
$scope.removeLicenseDataReady = $scope.$on('LicenseDataReady', function(e, data) {
|
||||
var html, version, eula, h;
|
||||
version = data.version.replace(/-.*$/,'');
|
||||
$scope.setLicense(data.license_info, version);
|
||||
html = $scope.getDefaultHTML(data.license_info);
|
||||
$scope.loadDefaultScope(data.license_info, version);
|
||||
eula = (data.eula) ? data.eula : "" ;
|
||||
|
||||
e = angular.element(document.getElementById('license-modal-dialog'));
|
||||
e.empty().html(html);
|
||||
|
||||
$scope.parseType = 'json';
|
||||
$scope.license_json = JSON.stringify($scope.license, null, ' ');
|
||||
$scope.eula = eula;
|
||||
$scope.eula_agreement = false;
|
||||
|
||||
|
||||
h = CheckLicense.getHTML($scope.getLicense(),true).body;
|
||||
$('#license-modal-dialog #license_tabs').append("<li><a id=\"update_license_link\" ng-click=\"toggleTab($event, 'update_license_link', 'license_tabs')\" href=\"#update_license\" data-toggle=\"tab\">Update License</a></li>");
|
||||
$('#license-modal-dialog .tab-content').append("<div class=\"tab-pane\" id=\"update_license\"></div>");
|
||||
$('#license-modal-dialog #update_license').html(h);
|
||||
|
||||
if ($scope.license_status === 'Invalid License Key' || $scope.license_status === 'Missing License Key') {
|
||||
$('#license_tabs li:eq(1)').hide();
|
||||
$('#license_tabs li:eq(2) a').tab('show');
|
||||
}
|
||||
|
||||
$('#license_license_json').attr('ng-required' , 'true' );
|
||||
$('#license_eula_agreement_chbox').attr('ng-required' , 'true' );
|
||||
$('#license_form_submit_btn').attr('ng-disabled' , "license_form.$invalid" );
|
||||
e = angular.element(document.getElementById('license-modal-dialog'));
|
||||
$compile(e)($scope);
|
||||
|
||||
if (IsAdmin()) {
|
||||
setTimeout(function() {
|
||||
TextareaResize({
|
||||
scope: $scope,
|
||||
textareaId: 'license_license_json',
|
||||
modalId: 'license-modal-dialog',
|
||||
formId: 'license-notification-body',
|
||||
fld: 'license_json',
|
||||
parse: true,
|
||||
bottom_margin: 90,
|
||||
onChange: function() { $scope.license_json_api_error = ''; }
|
||||
});
|
||||
}, 300);
|
||||
}
|
||||
$('#license-ok-button').focus();
|
||||
$('#update_license_link').on('shown.bs.tab', function() {
|
||||
if (IsAdmin()) {
|
||||
TextareaResize({
|
||||
scope: $scope,
|
||||
textareaId: 'license_license_json',
|
||||
modalId: 'license-modal-dialog',
|
||||
formId: 'license-notification-body',
|
||||
fld: 'license_json',
|
||||
bottom_margin: 90,
|
||||
parse: true,
|
||||
onChange: function() { $scope.license_json_api_error = ''; }
|
||||
});
|
||||
}
|
||||
});
|
||||
Wait("stop");
|
||||
});
|
||||
CheckLicense.GetLicense('LicenseDataReady', $scope);
|
||||
|
||||
}
|
||||
|
||||
LicenseController.$inject = ['ClearScope', '$location', '$rootScope', '$compile', '$filter', 'GenerateForm', 'Rest', 'Alert',
|
||||
'GetBasePath', 'ProcessErrors', 'FormatDate', 'Prompt', 'Empty', 'LicenseForm', 'IsAdmin', 'CreateDialog',
|
||||
'CheckLicense', 'TextareaResize', '$scope', "Wait"];
|
||||
@ -19,7 +19,6 @@ import JobDetail from "./helpers/JobDetail";
|
||||
import JobSubmission from "./helpers/JobSubmission";
|
||||
import JobTemplates from "./helpers/JobTemplates";
|
||||
import Jobs from "./helpers/Jobs";
|
||||
import License from "./helpers/License";
|
||||
import LoadConfig from "./helpers/LoadConfig";
|
||||
import LogViewer from "./helpers/LogViewer";
|
||||
import Lookup from "./helpers/Lookup";
|
||||
@ -57,7 +56,6 @@ export
|
||||
JobSubmission,
|
||||
JobTemplates,
|
||||
Jobs,
|
||||
License,
|
||||
LoadConfig,
|
||||
LogViewer,
|
||||
Lookup,
|
||||
|
||||
@ -1,271 +0,0 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2015 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name helpers.function:License
|
||||
* @description Routines for checking and reporting license status
|
||||
* CheckLicense.test() is called in app.js, in line 532, which is when the license is checked. The license information is
|
||||
* stored in local storage using 'Store()'.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
import '../forms';
|
||||
|
||||
export default
|
||||
angular.module('LicenseHelper', ['RestServices', 'Utilities', 'LicenseUpdateFormDefinition',
|
||||
'FormGenerator', 'ParseHelper', 'ModalDialog', 'VariablesHelper', 'LicenseFormDefinition'])
|
||||
|
||||
|
||||
.factory('CheckLicense', ['$q', '$rootScope', '$compile', 'CreateDialog', 'Store',
|
||||
'LicenseUpdateForm', 'GenerateForm', 'TextareaResize', 'ToJSON', 'GetBasePath',
|
||||
'Rest', 'ProcessErrors', 'Alert', 'IsAdmin', '$location', 'pendoService',
|
||||
'Authorization', 'Wait',
|
||||
function($q, $rootScope, $compile, CreateDialog, Store, LicenseUpdateForm, GenerateForm,
|
||||
TextareaResize, ToJSON, GetBasePath, Rest, ProcessErrors, Alert, IsAdmin, $location,
|
||||
pendoService, Authorization, Wait) {
|
||||
return {
|
||||
getRemainingDays: function(time_remaining) {
|
||||
// assumes time_remaining will be in seconds
|
||||
var tr = parseInt(time_remaining, 10);
|
||||
return Math.floor(tr / 86400);
|
||||
},
|
||||
|
||||
shouldNotify: function(license) {
|
||||
if (license && typeof license === 'object' && Object.keys(license).length > 0) {
|
||||
// we have a license object
|
||||
if (!license.valid_key) {
|
||||
// missing valid key
|
||||
return true;
|
||||
}
|
||||
else if (license.free_instances <= 0) {
|
||||
// host count exceeded
|
||||
return true;
|
||||
}
|
||||
else if (this.getRemainingDays(license.time_remaining) < 15) {
|
||||
// below 15 days remaining on license
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
// missing license object
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
isAdmin: function() {
|
||||
return IsAdmin();
|
||||
},
|
||||
|
||||
getHTML: function(license, includeFormButton) {
|
||||
|
||||
var title, html,
|
||||
contact_us = "<a href=\"http://www.ansible.com/contact-us\" target=\"_black\">contact us <i class=\"fa fa-external-link\"></i></a>",
|
||||
renew = "<a href=\"http://www.ansible.com/renew\" target=\"_blank\">ansible.com/renew <i class=\"fa fa-external-link\"></i></a>",
|
||||
pricing = "<a href=\"http://www.ansible.com/pricing\" target=\"_blank\">ansible.com/pricing <i class=\"fa fa-external-link\"></i></a>",
|
||||
license_link = "<a href=\"http://www.ansible.com/license\" target=\"_blank\">click here</a>",
|
||||
result = {},
|
||||
license_is_valid=false;
|
||||
|
||||
if (license && typeof license === 'object' && Object.keys(license).length > 0 && license.valid_key !== undefined) {
|
||||
// we have a license
|
||||
if (!license.valid_key) {
|
||||
title = "Invalid License";
|
||||
html = "<div id=\"license-notification-body\"><div style=\"margin-top:5px; margin-bottom:25px;\"><p>The Ansible Tower license is invalid.</p>";
|
||||
}
|
||||
else if (this.getRemainingDays(license.time_remaining) <= 0) {
|
||||
title = "License Expired";
|
||||
html = "<div id=\"license-notification-body\"><div style=\"margin-top:5px; margin-bottom:25px;\">\n" +
|
||||
"<p>Thank you for using Ansible Tower. The Ansible Tower license has expired</p>";
|
||||
if (parseInt(license.grace_period_remaining,10) > 86400) {
|
||||
// trial licenses don't get a grace period
|
||||
if (license.trial) {
|
||||
html += "<p>Don't worry — your existing history and content has not been affected, but playbooks will no longer run and new hosts cannot be added. " +
|
||||
"If you are ready to upgrade, " + contact_us + " or visit " + pricing + " to see all of your license options. Thanks!</p>";
|
||||
} else {
|
||||
html += "<p>Don't worry — your existing history and content has not been affected, but in " + this.getRemainingDays(license.grace_period_remaining) + " days playbooks will no longer " +
|
||||
"run and new hosts cannot be added. If you are ready to upgrade, " + contact_us + " " +
|
||||
"or visit <a href=\"http://www.ansible.com/pricing\" target=\"_blank\">ansible.com/pricing <i class=\"fa fa-external-link\"></i></a> to see all of your license options. Thanks!</p>";
|
||||
}
|
||||
} else {
|
||||
html += "<p>Don’t worry — your existing history and content has not been affected, but playbooks will no longer run and new hosts cannot be added. If you are ready to renew or upgrade, contact us " +
|
||||
"at " + renew + ". Thanks!</p>";
|
||||
}
|
||||
}
|
||||
else if (this.getRemainingDays(license.time_remaining) < 15) {
|
||||
// Warning: license expiring in less than 15 days
|
||||
title = "License Warning";
|
||||
html = "<div id=\"license-notification-body\"><div style=\"margin-top:5px; margin-bottom:25px;\"><p>Thank you for using Ansible Tower. The Ansible Tower license " +
|
||||
"has " + this.getRemainingDays(license.time_remaining) + " days remaining.</p>";
|
||||
// trial licenses don't get a grace period
|
||||
if (license.trial) {
|
||||
html += "<p>After this license expires, playbooks will no longer run and hosts cannot be added. If you are ready to upgrade, " + contact_us + " or visit " + pricing + " to see all of your license options. Thanks!</p>";
|
||||
} else {
|
||||
html += "<p>After this license expires, playbooks will no longer run and hosts cannot be added. If you are ready to renew or upgrade, contact us at " + renew + ". Thanks!</p>";
|
||||
}
|
||||
|
||||
// If there is exactly one day remaining, change "days remaining"
|
||||
// to "day remaining".
|
||||
html = html.replace('has 1 days remaining', 'has 1 day remaining');
|
||||
}
|
||||
else if (license.free_instances <= 0) {
|
||||
title = "Host Count Exceeded";
|
||||
html = "<div id=\"license-notification-body\"><div style=\"margin-top:5px; margin-bottom:25px;\"><p>The Ansible Tower license has reached capacity for the number of managed hosts allowed. No new hosts can be added. Existing " +
|
||||
"playbooks can still be run against hosts already in inventory.</p>" +
|
||||
"<p>If you are ready to upgrade, contact us at " + renew + ". Thanks!</p>";
|
||||
|
||||
} else {
|
||||
// license is valid. the following text is displayed in the license viewer
|
||||
title = "Update License";
|
||||
html = "<div id=\"license-notification-body\"><div style=\"margin-top:5px; margin-bottom:25px;\"><p>The Ansible Tower license is valid.</p>" +
|
||||
"<p>If you are ready to upgrade, contact us at " + renew + ". Thanks!</p>";
|
||||
license_is_valid = true;
|
||||
}
|
||||
} else {
|
||||
// No license
|
||||
title = "Add Your License";
|
||||
html = "<div id=\"license-notification-body\"><div style=\"margin-top:5px; margin-bottom:25px;\"><p>Now that you’ve successfully installed or upgraded Ansible Tower, the next step is to add a license file. " +
|
||||
"If you don’t have a license file yet, " + license_link + " to see all of our free and paid license options.</p>" +
|
||||
"<p style=\"margin-top:15px; margin-bottom 15px; text-align:center;\"><a href=\"http://ansible.com/license\" target=\"_blank\" class=\"btn btn-danger free-button\">Get a Free Tower Trial License</a></p>";
|
||||
}
|
||||
|
||||
if (IsAdmin()) {
|
||||
html += "<p>Copy and paste the contents of your license in the field below, agree to the End User License Agreement, and click Submit.</p>";
|
||||
} else {
|
||||
html += "<p>A system administrator can install the new license by choosing View License on the Account Menu and clicking on the Update License tab.</p>";
|
||||
}
|
||||
|
||||
html += "</div>";
|
||||
|
||||
if (IsAdmin()) {
|
||||
html += GenerateForm.buildHTML(LicenseUpdateForm, { mode: 'edit', showButtons:((includeFormButton) ? true : false) });
|
||||
}
|
||||
|
||||
html += "</div>";
|
||||
|
||||
result.body = html;
|
||||
result.title = title;
|
||||
return result;
|
||||
},
|
||||
|
||||
postLicense: function(license_key, in_scope) {
|
||||
var url = GetBasePath('config'),
|
||||
self = this,
|
||||
json_data, scope;
|
||||
|
||||
scope = (in_scope) ? in_scope : self.scope;
|
||||
|
||||
json_data = ToJSON('json', license_key);
|
||||
json_data.eula_accepted = scope.eula_agreement;
|
||||
if (typeof json_data === 'object' && Object.keys(json_data).length > 0) {
|
||||
Rest.setUrl(url);
|
||||
Rest.post(json_data)
|
||||
.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;
|
||||
|
||||
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'));
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
})
|
||||
.catch(function (response) {
|
||||
scope.license_json_api_error = "A valid license key in JSON format is required";
|
||||
ProcessErrors(scope, response.data, response.status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to update license. POST returned: ' + response.status
|
||||
});
|
||||
});
|
||||
} else {
|
||||
scope.license_json_api_error = "A valid license key in JSON format is required";
|
||||
}
|
||||
},
|
||||
|
||||
test: function() {
|
||||
var license = Store('license'),
|
||||
self = this,
|
||||
scope;
|
||||
|
||||
var getLicense = function() {
|
||||
var deferred = $q.defer();
|
||||
|
||||
if (license === null) {
|
||||
Rest.setUrl(GetBasePath('config'));
|
||||
return Rest.get()
|
||||
.then(function (data) {
|
||||
license = data.data.license_info;
|
||||
deferred.resolve();
|
||||
return deferred.promise;
|
||||
}, function () {
|
||||
deferred.resolve();
|
||||
return deferred.promise;
|
||||
});
|
||||
} else {
|
||||
deferred.resolve(license);
|
||||
return deferred.promise;
|
||||
}
|
||||
}
|
||||
|
||||
var promise = getLicense();
|
||||
promise.then(function() {
|
||||
self.scope = $rootScope.$new();
|
||||
scope = self.scope;
|
||||
|
||||
if (license && typeof license === 'object' && Object.keys(license).length > 0) {
|
||||
if (license.tested) {
|
||||
return true;
|
||||
}
|
||||
license.tested = true;
|
||||
Store('license',license); //update with tested flag
|
||||
}
|
||||
|
||||
// Don't do anything when the license is valid
|
||||
if (!self.shouldNotify(license)) {
|
||||
return true; // if the license is valid it would exit 'test' here, otherwise it moves on to making the modal for the license
|
||||
}
|
||||
|
||||
$location.path('/license');
|
||||
});
|
||||
},
|
||||
|
||||
GetLicense: function(callback, inScope) {
|
||||
// Retrieve license detail
|
||||
var self = this,
|
||||
scope = (inScope) ? inScope : self.scope,
|
||||
url = GetBasePath('config');
|
||||
Rest.setUrl(url);
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
if (scope && callback) {
|
||||
scope.$emit(callback, data);
|
||||
}
|
||||
else if (scope) {
|
||||
scope.$emit('CheckLicenseReady', data);
|
||||
}
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($rootScope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Failed to retrieve license. GET status: ' + status
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
80
awx/ui/client/src/license/license.block.less
Normal file
80
awx/ui/client/src/license/license.block.less
Normal file
@ -0,0 +1,80 @@
|
||||
@import "awx/ui/client/src/shared/branding/colors.default.less";
|
||||
|
||||
.License-container{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.License-container label{
|
||||
text-transform: uppercase;
|
||||
color: @default-interface-txt;
|
||||
font-weight: 500;
|
||||
}
|
||||
.License-management .CodeMirror-scroll{
|
||||
min-height: 140px;
|
||||
}
|
||||
.License-file textarea{
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
.License-eula textarea{
|
||||
width: 100%;
|
||||
height: 140px;
|
||||
}
|
||||
.License-field label{
|
||||
width: 155px;
|
||||
}
|
||||
.License-field span{
|
||||
width: 255px;
|
||||
display: inline-block;
|
||||
}
|
||||
.License-field{
|
||||
word-wrap: break-word;
|
||||
width: 100%;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.License-greenText{
|
||||
color: @submit-button-bg;
|
||||
}
|
||||
.License-redText{
|
||||
color: #d9534f;
|
||||
}
|
||||
.License-fields{
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.License-details {
|
||||
height: 520px;
|
||||
width: 460px;
|
||||
flex-grow: 1;
|
||||
display: inline-block;
|
||||
background-color: @default-bg;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
border: @default-interface-txt;
|
||||
align-items: baseline;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.License-titleText {
|
||||
color: @default-interface-txt;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.License-management{
|
||||
height: 520px;
|
||||
flex-grow: 2;
|
||||
display: inline-block;
|
||||
background-color: @default-bg;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
border: @default-interface-txt;
|
||||
align-items: baseline;
|
||||
margin-top: 20px;
|
||||
}
|
||||
50
awx/ui/client/src/license/license.controller.js
Normal file
50
awx/ui/client/src/license/license.controller.js
Normal file
@ -0,0 +1,50 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default
|
||||
[ 'Wait', '$state', '$scope', '$location',
|
||||
'GetBasePath', 'Rest', 'ProcessErrors', 'CheckLicense', 'moment',
|
||||
function( Wait, $state, $scope, $location,
|
||||
GetBasePath, Rest, ProcessErrors, CheckLicense, moment){
|
||||
// codemirror
|
||||
var textArea = document.getElementById('License-codemirror');
|
||||
var editor = CodeMirror.fromTextArea(textArea, {
|
||||
lineNumbers: true,
|
||||
mode: 'json'
|
||||
});
|
||||
editor.on('blur', function(cm){
|
||||
$scope.newLicense.file = cm.getValue()
|
||||
});
|
||||
$scope.newLicense = {};
|
||||
$scope.submit = function(e){
|
||||
Wait('start')
|
||||
CheckLicense.post($scope.newLicense.file, $scope.newLicense.eula)
|
||||
.success(function(res){
|
||||
console.log(res)
|
||||
});
|
||||
}
|
||||
var calcDaysRemaining = function(ms){
|
||||
// calculate the number of days remaining on the license
|
||||
var duration = moment.duration(ms);
|
||||
return duration.days()
|
||||
}
|
||||
|
||||
var calcExpiresOn = function(days){
|
||||
// calculate the expiration date of the license
|
||||
return moment().add(days, 'days').calendar()
|
||||
}
|
||||
Wait('start');
|
||||
CheckLicense.get()
|
||||
.then(function(res){
|
||||
$scope.license = res.data;
|
||||
$scope.time = {};
|
||||
$scope.time.remaining = calcDaysRemaining($scope.license.license_info.time_remaining);
|
||||
$scope.time.expiresOn = calcExpiresOn($scope.time.remaining);
|
||||
$scope.valid = CheckLicense.valid($scope.license.license_info);
|
||||
Wait('stop');
|
||||
});
|
||||
}
|
||||
];
|
||||
72
awx/ui/client/src/license/license.partial.html
Normal file
72
awx/ui/client/src/license/license.partial.html
Normal file
@ -0,0 +1,72 @@
|
||||
<div class="License-container">
|
||||
<div class="License-details ng-cloak">
|
||||
<div class="License-titleText">Details</div>
|
||||
<div class="License-fields">
|
||||
<div class="License-field">
|
||||
<label>License</label>
|
||||
<span ng-show='valid'><i class="fa fa-circle License-greenText"></i> Valid</span>
|
||||
<span ng-show='invalid'><i class="fa fa-circle License-redText"></i> Invalid</span>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<label>Version</label>
|
||||
<span>{{license.version}}</span>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<label>License Type</label>
|
||||
<span>{{license.license_info.license_type}}</span>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<label>Subscription</label>
|
||||
<span>{{license.license_info.subscription_name}}</span>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<label>License Key</label>
|
||||
<span>{{license.license_info.license_key}}</span>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<label>Expires On</label>
|
||||
<span>{{time.expiresOn}}</span>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<label>Time Remaining</label>
|
||||
<span>{{time.remaining}} Days</span>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<label>Hosts Available</label>
|
||||
<span>{{license.license_info.available_instances}}</span>
|
||||
</div>
|
||||
<div class="License-field">
|
||||
<label>Hosts Used</label>
|
||||
<span>{{license.license_info.current_instances}}</span>
|
||||
</div>
|
||||
<div class="License-field License-greenText">
|
||||
<label>Hosts Remaining</label>
|
||||
<span>{{license.license_info.free_instances}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<p>If you are ready to upgrade, please contact us by clicking the button below</p>
|
||||
<button class="btn btn-default">Upgrade</button>
|
||||
</div>
|
||||
<div class="License-management">
|
||||
<div class="License-titleText">License Management</div>
|
||||
<p>Copy and paste the contents of your license in the field below, agree to the End User License Agreement, and click submit.</p>
|
||||
<form name="license">
|
||||
<div class="form-group License-file prepend-asterisk ">
|
||||
<label>License File</label>
|
||||
<textarea id="License-codemirror" placeholder="Please paste your license here"></textarea>
|
||||
</div>
|
||||
<div class="License-titleText prepend-asterisk"> End User License Agreement</div>
|
||||
<div class="form-group License-eula">
|
||||
<textarea class="form-control">{{license.eula}}
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<label><input type="checkbox" ng-model="newLicense.eula" required> I agree to the End User License Agreement</label>
|
||||
<button ng-click="submit()" class="btn btn-success pull-right" ng-disabled="newLicense.file == null || newLicense.eula == null">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
19
awx/ui/client/src/license/license.route.js
Normal file
19
awx/ui/client/src/license/license.route.js
Normal file
@ -0,0 +1,19 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import {templateUrl} from '../shared/template-url/template-url.factory';
|
||||
|
||||
export default {
|
||||
name: 'license',
|
||||
route: '/license',
|
||||
templateUrl: templateUrl('license/license'),
|
||||
controller: 'licenseController',
|
||||
data: {},
|
||||
ncyBreadcrumb: {
|
||||
parent: 'setup',
|
||||
label: 'LICENSE'
|
||||
}
|
||||
}
|
||||
71
awx/ui/client/src/license/main.js
Normal file
71
awx/ui/client/src/license/main.js
Normal file
@ -0,0 +1,71 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import route from './license.route';
|
||||
import controller from './license.controller';
|
||||
|
||||
export default
|
||||
angular.module('license', [])
|
||||
.controller('licenseController', controller)
|
||||
.factory('CheckLicense', ['$state', '$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', function($state, $rootScope, Rest, GetBasePath, ProcessErrors){
|
||||
return {
|
||||
get: function() {
|
||||
var defaultUrl = GetBasePath('config');
|
||||
Rest.setUrl(defaultUrl);
|
||||
return Rest.get()
|
||||
.success(function(res){
|
||||
return res
|
||||
})
|
||||
.error(function(res, status){
|
||||
ProcessErrors($rootScope, res, status, null, {hdr: 'Error!',
|
||||
msg: 'Call to '+ defaultUrl + ' failed. Return status: '+ status});
|
||||
});
|
||||
},
|
||||
post: function(license, eula){
|
||||
var defaultUrl = GetBasePath('config');
|
||||
Rest.setUrl(defaultUrl);
|
||||
var data = {
|
||||
eula_accepted: eula,
|
||||
license_key: license
|
||||
};
|
||||
console.log(data)
|
||||
return Rest.post(JSON.stringify(data))
|
||||
.success(function(res){
|
||||
return res
|
||||
})
|
||||
.error(function(res, status){
|
||||
ProcessErrors($rootScope, res, status, null, {hdr: 'Error!',
|
||||
msg: 'Call to '+ defaultUrl + ' failed. Return status: '+ status});
|
||||
});
|
||||
},
|
||||
// Checks current license validity
|
||||
// Intended to for runtime or pre-state checks
|
||||
// Returns false if invalid
|
||||
valid: function(license) {
|
||||
if (!license.valid_key){
|
||||
return false
|
||||
}
|
||||
else if (license.free_instances <= 0){
|
||||
return false
|
||||
}
|
||||
// notify if less than 15 days remaining
|
||||
else if (license.time_remaining / 1000 / 60 / 60 / 24 > 15){
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
notify: function(){
|
||||
this.get()
|
||||
.then(function(res){
|
||||
this.valid(res.license_info) ? null : $state.go('license');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}])
|
||||
.run(['$stateExtender', function($stateExtender) {
|
||||
$stateExtender.addState(route);
|
||||
}]);
|
||||
@ -1,4 +0,0 @@
|
||||
<div class="tab-pane" id="license-partial">
|
||||
<div ng-cloak id="htmlTemplate" class="Panel"></div>
|
||||
<div id="license-modal-dialog"></div>
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user