mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 16:51:11 +03:00
Merge pull request #1453 from jlmitch5/licenseInSettingsUi
[Tower only] Make pendo license settings opt out whenever license is added
This commit is contained in:
commit
ea5ab2df7f
@ -139,3 +139,7 @@
|
||||
.License-detailsGroup {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.License-detailsGroup--withSeparator {
|
||||
border-top: 1px solid @default-icon-hov;
|
||||
}
|
||||
|
@ -9,35 +9,43 @@ import {N_} from "../i18n";
|
||||
export default
|
||||
['Wait', '$state', '$scope', '$rootScope',
|
||||
'ProcessErrors', 'CheckLicense', 'moment','$window',
|
||||
'ConfigService', 'FeaturesService', 'pendoService', 'i18n', 'config',
|
||||
function( Wait, $state, $scope, $rootScope,
|
||||
ProcessErrors, CheckLicense, moment, $window, ConfigService,
|
||||
FeaturesService, pendoService, i18n, config){
|
||||
'ConfigService', 'FeaturesService', 'pendoService', 'i18n', 'config', 'Rest', 'GetBasePath',
|
||||
function(Wait, $state, $scope, $rootScope, ProcessErrors, CheckLicense, moment,
|
||||
$window, ConfigService, FeaturesService, pendoService, i18n, config, Rest, GetBasePath) {
|
||||
|
||||
var calcDaysRemaining = function(seconds){
|
||||
// calculate the number of days remaining on the license
|
||||
var duration = moment.duration(seconds, 'seconds').asDays();
|
||||
duration = Math.floor(duration);
|
||||
if(duration < 0 ){
|
||||
duration = 0;
|
||||
}
|
||||
duration = (duration!==1) ? `${duration} Days` : `${duration} Day`;
|
||||
return duration;
|
||||
};
|
||||
const calcDaysRemaining = function(seconds) {
|
||||
// calculate the number of days remaining on the license
|
||||
let duration = moment.duration(seconds, 'seconds').asDays();
|
||||
|
||||
var calcExpiresOn = function(seconds){
|
||||
duration = Math.floor(duration);
|
||||
if(duration < 0){
|
||||
duration = 0;
|
||||
}
|
||||
|
||||
duration = (duration!==1) ? `${duration} Days` : `${duration} Day`;
|
||||
|
||||
return duration;
|
||||
};
|
||||
|
||||
const calcExpiresOn = function(seconds) {
|
||||
// calculate the expiration date of the license
|
||||
return moment.unix(seconds).calendar();
|
||||
};
|
||||
|
||||
var reset = function(){
|
||||
const reset = function() {
|
||||
document.getElementById('License-form').reset();
|
||||
};
|
||||
|
||||
var init = function(config){
|
||||
const init = function(config) {
|
||||
// license/license.partial.html compares fileName
|
||||
$scope.fileName = N_("No file selected.");
|
||||
$scope.title = $rootScope.licenseMissing ? ($rootScope.BRAND_NAME + i18n._(" License")) : i18n._("License Management");
|
||||
|
||||
if ($rootScope.licenseMissing) {
|
||||
$scope.title = $rootScope.BRAND_NAME + i18n._(" License");
|
||||
} else {
|
||||
$scope.title = i18n._("License Management");
|
||||
}
|
||||
|
||||
$scope.license = config;
|
||||
$scope.license.version = config.version.split('-')[0];
|
||||
$scope.time = {};
|
||||
@ -45,71 +53,94 @@ export default
|
||||
$scope.time.expiresOn = calcExpiresOn($scope.license.license_info.license_date);
|
||||
$scope.valid = CheckLicense.valid($scope.license.license_info);
|
||||
$scope.compliant = $scope.license.license_info.compliant;
|
||||
$scope.newLicense = {};
|
||||
|
||||
Rest.setUrl(`${GetBasePath('settings')}ui`);
|
||||
Rest.get()
|
||||
.then(({data}) => {
|
||||
if (data.PENDO_TRACKING_STATE === 'off' && !$rootScope.licenseMissing) {
|
||||
$scope.newLicense.pendo = false;
|
||||
} else {
|
||||
$scope.newLicense.pendo = true;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// default pendo tracking to true when settings is not accessible
|
||||
$scope.newLicense.pendo = true;
|
||||
});
|
||||
};
|
||||
|
||||
init(config);
|
||||
|
||||
$scope.getKey = function(event){
|
||||
$scope.getKey = function(event) {
|
||||
// Mimic HTML5 spec, show filename
|
||||
$scope.fileName = event.target.files[0].name;
|
||||
// Grab the key from the raw license file
|
||||
var raw = new FileReader();
|
||||
const raw = new FileReader();
|
||||
// readAsFoo runs async
|
||||
raw.onload = function(){
|
||||
raw.onload = function() {
|
||||
try {
|
||||
$scope.newLicense.file = JSON.parse(raw.result);
|
||||
}
|
||||
catch(err) {
|
||||
ProcessErrors($rootScope, null, null, null, {msg: i18n._('Invalid file format. Please upload valid JSON.')});
|
||||
} catch(err) {
|
||||
ProcessErrors($rootScope, null, null, null,
|
||||
{msg: i18n._('Invalid file format. Please upload valid JSON.')});
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
raw.readAsText(event.target.files[0]);
|
||||
}
|
||||
catch(err) {
|
||||
ProcessErrors($rootScope, null, null, null, {msg: i18n._('Invalid file format. Please upload valid JSON.')});
|
||||
} catch(err) {
|
||||
ProcessErrors($rootScope, null, null, null,
|
||||
{msg: i18n._('Invalid file format. Please upload valid JSON.')});
|
||||
}
|
||||
};
|
||||
|
||||
// HTML5 spec doesn't provide a way to customize file input css
|
||||
// So we hide the default input, show our own, and simulate clicks to the hidden input
|
||||
$scope.fakeClick = function(){
|
||||
$scope.fakeClick = function() {
|
||||
if($scope.user_is_superuser) {
|
||||
$('#License-file').click();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.downloadLicense = function(){
|
||||
$scope.downloadLicense = function() {
|
||||
$window.open('https://www.ansible.com/license', '_blank');
|
||||
};
|
||||
|
||||
$scope.newLicense = {};
|
||||
$scope.submit = function(){
|
||||
Wait('start');
|
||||
CheckLicense.post($scope.newLicense.file, $scope.newLicense.eula)
|
||||
.then(() => {
|
||||
reset();
|
||||
$scope.submit = function() {
|
||||
Wait('start');
|
||||
CheckLicense.post($scope.newLicense.file, $scope.newLicense.eula)
|
||||
.then(() => {
|
||||
reset();
|
||||
|
||||
ConfigService.delete();
|
||||
ConfigService.getConfig().then(function(config){
|
||||
delete($rootScope.features);
|
||||
FeaturesService.get();
|
||||
pendoService.issuePendoIdentity();
|
||||
if($rootScope.licenseMissing === true){
|
||||
$state.go('dashboard', {
|
||||
licenseMissing: false
|
||||
});
|
||||
}
|
||||
else{
|
||||
init(config);
|
||||
$scope.success = true;
|
||||
$rootScope.licenseMissing = false;
|
||||
// for animation purposes
|
||||
var successTimeout = setTimeout(function(){
|
||||
$scope.success = false;
|
||||
clearTimeout(successTimeout);
|
||||
}, 4000);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
];
|
||||
ConfigService.getConfig()
|
||||
.then(function(config) {
|
||||
delete($rootScope.features);
|
||||
FeaturesService.get();
|
||||
|
||||
if ($scope.newLicense.pendo) {
|
||||
pendoService.updatePendoTrackingState('detailed');
|
||||
pendoService.issuePendoIdentity();
|
||||
} else {
|
||||
pendoService.updatePendoTrackingState('off');
|
||||
}
|
||||
|
||||
if ($rootScope.licenseMissing === true) {
|
||||
$state.go('dashboard', {
|
||||
licenseMissing: false
|
||||
});
|
||||
} else {
|
||||
init(config);
|
||||
$scope.success = true;
|
||||
$rootScope.licenseMissing = false;
|
||||
// for animation purposes
|
||||
const successTimeout = setTimeout(function() {
|
||||
$scope.success = false;
|
||||
clearTimeout(successTimeout);
|
||||
}, 4000);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
}];
|
||||
|
@ -122,6 +122,19 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group License-detailsGroup License-detailsGroup--withSeparator">
|
||||
<div class="checkbox">
|
||||
<label class="License-details--label">
|
||||
<input type="checkbox" ng-model="newLicense.pendo" ng-disabled="!user_is_superuser" required>
|
||||
<translate>By default, Tower collects and transmits analytics data on Tower usage to Red Hat. This data is used to enhance future releases of the Tower Software and help streamline customer experience and success. For more information, see
|
||||
<a target="_blank"
|
||||
href="http://docs.ansible.com/ansible-tower/latest/html/installandreference/user-data.html#index-0">
|
||||
this Tower documentation page
|
||||
</a>. Uncheck this box to disable this feature.
|
||||
</translate>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button ng-click="submit()" class="btn btn-success pull-right" ng-disabled="newLicense.file.license_key == null || newLicense.eula == null || !user_is_superuser" translate>Submit</button>
|
||||
<span ng-show="success == true" class="License-greenText License-submit--success pull-right" translate>Save successful!</span>
|
||||
|
@ -5,87 +5,84 @@
|
||||
*************************************************/
|
||||
|
||||
|
||||
export default
|
||||
[ '$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', '$q',
|
||||
'ConfigService', '$log', 'AppStrings',
|
||||
function ($rootScope, Rest, GetBasePath, ProcessErrors, $q,
|
||||
ConfigService, $log, AppStrings) {
|
||||
return {
|
||||
export default ['$rootScope', 'Rest', 'GetBasePath', 'ProcessErrors', '$q', 'ConfigService', '$log',
|
||||
'AppStrings',
|
||||
function ($rootScope, Rest, GetBasePath, ProcessErrors, $q, ConfigService, $log, AppStrings) {
|
||||
return {
|
||||
setPendoOptions: function (config) {
|
||||
var tower_version = config.version.split('-')[0],
|
||||
trial = (config.trial) ? config.trial : false,
|
||||
options = {
|
||||
const tower_version = config.version.split('-')[0];
|
||||
const trial = (config.trial) ? config.trial : false;
|
||||
let options = {
|
||||
apiKey: AppStrings.get('PENDO_API_KEY'),
|
||||
visitor: {
|
||||
id: null,
|
||||
role: null,
|
||||
id: null,
|
||||
role: null,
|
||||
},
|
||||
account: {
|
||||
id: null,
|
||||
planLevel: config.license_type,
|
||||
planPrice: config.instance_count,
|
||||
creationDate: config.license_date,
|
||||
trial: trial,
|
||||
tower_version: tower_version,
|
||||
ansible_version: config.ansible_version
|
||||
id: null,
|
||||
planLevel: config.license_type,
|
||||
planPrice: config.instance_count,
|
||||
creationDate: config.license_date,
|
||||
trial: trial,
|
||||
tower_version: tower_version,
|
||||
ansible_version: config.ansible_version
|
||||
}
|
||||
};
|
||||
if(config.analytics_status === 'detailed'){
|
||||
|
||||
if (config.analytics_status === 'detailed') {
|
||||
this.setDetailed(options, config);
|
||||
}
|
||||
else if(config.analytics_status === 'anonymous'){
|
||||
} else if (config.analytics_status === 'anonymous') {
|
||||
this.setAnonymous(options);
|
||||
}
|
||||
return options;
|
||||
|
||||
return options;
|
||||
},
|
||||
|
||||
// Detailed mode sends:
|
||||
// VisitorId: userid+hash of license_key
|
||||
// AccountId: hash of license_key from license
|
||||
setDetailed: function(options, config) {
|
||||
// Detailed mode
|
||||
// VisitorId: userid+hash of license_key
|
||||
// AccountId: hash of license_key from license
|
||||
|
||||
// config.deployment_id is a hash of the tower license_key
|
||||
options.visitor.id = $rootScope.current_user.id + '@' + config.deployment_id;
|
||||
options.account.id = config.deployment_id;
|
||||
},
|
||||
|
||||
// Anonymous mode sends:
|
||||
// VisitorId: <hardcoded id that is the same across all anonymous>
|
||||
// AccountId: <hardcoded id that is the same across all anonymous>
|
||||
setAnonymous: function (options) {
|
||||
//Anonymous mode
|
||||
// VisitorId: <some hardcoded id that is the same across all anonymous>
|
||||
// AccountId: <some hardcoded id that is the same across all anonymous>
|
||||
|
||||
options.visitor.id = 0;
|
||||
options.account.id = "tower.ansible.com";
|
||||
},
|
||||
|
||||
setRole: function(options) {
|
||||
var deferred = $q.defer();
|
||||
if($rootScope.current_user.is_superuser === true){
|
||||
const deferred = $q.defer();
|
||||
|
||||
if ($rootScope.current_user.is_superuser === true) {
|
||||
options.visitor.role = 'admin';
|
||||
deferred.resolve(options);
|
||||
} else {
|
||||
Rest.setUrl(GetBasePath('users') + $rootScope.current_user.id +
|
||||
'/admin_of_organizations/');
|
||||
Rest.get()
|
||||
.then(function (response) {
|
||||
if (response.data.count > 0) {
|
||||
options.visitor.role = "orgadmin";
|
||||
deferred.resolve(options);
|
||||
} else {
|
||||
options.visitor.role = "user";
|
||||
deferred.resolve(options);
|
||||
}
|
||||
})
|
||||
.catch(function (response) {
|
||||
ProcessErrors($rootScope, response.data, response.status, null, {
|
||||
hdr: 'Error!',
|
||||
msg: 'Failed to get admin of org user list. GET returned status: ' +
|
||||
response.status });
|
||||
deferred.reject('Could not resolve pendo role.');
|
||||
});
|
||||
}
|
||||
else{
|
||||
var url = GetBasePath('users') + $rootScope.current_user.id + '/admin_of_organizations/';
|
||||
Rest.setUrl(url);
|
||||
var promise = Rest.get();
|
||||
promise.then(function (response) {
|
||||
if(response.data.count > 0 ) {
|
||||
options.visitor.role = "orgadmin";
|
||||
deferred.resolve(options);
|
||||
}
|
||||
else {
|
||||
options.visitor.role = "user";
|
||||
deferred.resolve(options);
|
||||
}
|
||||
});
|
||||
promise.catch(function (response) {
|
||||
ProcessErrors($rootScope, response.data, response.status, null, {
|
||||
hdr: 'Error!',
|
||||
msg: 'Failed to get inventory name. GET returned status: ' +
|
||||
response.status });
|
||||
deferred.reject('Could not resolve pendo role.');
|
||||
});
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
@ -100,31 +97,52 @@ export default
|
||||
},
|
||||
|
||||
issuePendoIdentity: function () {
|
||||
var options,
|
||||
c = ConfigService.get(),
|
||||
config = c.license_info;
|
||||
const c = ConfigService.get();
|
||||
|
||||
let options;
|
||||
let config = c.license_info;
|
||||
|
||||
config.analytics_status = c.analytics_status;
|
||||
config.version = c.version;
|
||||
config.ansible_version = c.ansible_version;
|
||||
if(config.analytics_status === 'detailed' || config.analytics_status === 'anonymous'){
|
||||
this.bootstrap();
|
||||
options = this.setPendoOptions(config);
|
||||
this.setRole(options).then(function(options){
|
||||
$log.debug('Pendo status is '+ config.analytics_status + '. Object below:');
|
||||
$log.debug(options);
|
||||
/* jshint ignore:start */
|
||||
pendo.initialize(options);
|
||||
/* jshint ignore:end */
|
||||
}, function(reason){
|
||||
// reject function for setRole
|
||||
$log.debug(reason);
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
||||
if (config.analytics_status === 'detailed' ||
|
||||
config.analytics_status === 'anonymous') {
|
||||
this.bootstrap();
|
||||
options = this.setPendoOptions(config);
|
||||
this.setRole(options)
|
||||
.then(function(options){
|
||||
$log.debug('Pendo status is '+ config.analytics_status +
|
||||
'. Object below:');
|
||||
$log.debug(options);
|
||||
|
||||
/* jshint ignore:start */
|
||||
pendo.initialize(options);
|
||||
/* jshint ignore:end */
|
||||
}, function(reason){
|
||||
// reject function for setRole
|
||||
$log.debug(reason);
|
||||
});
|
||||
} else {
|
||||
$log.debug('Pendo is turned off.');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updatePendoTrackingState: function(tracking_type) {
|
||||
if (tracking_type === 'off' || tracking_type === 'anonymous' ||
|
||||
tracking_type === 'detailed') {
|
||||
Rest.setUrl(`${GetBasePath('settings')}ui`);
|
||||
Rest.patch({ PENDO_TRACKING_STATE: tracking_type })
|
||||
.catch(function ({data, status}) {
|
||||
ProcessErrors($rootScope, data, status, null, {
|
||||
hdr: 'Error!',
|
||||
msg: 'Failed to patch PENDO_TRACKING_STATE in settings: ' +
|
||||
status });
|
||||
});
|
||||
} else {
|
||||
throw new Error(`Can't update pendo tracking state in settings to
|
||||
"${tracking_type}"`);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
];
|
||||
}];
|
||||
|
Loading…
Reference in New Issue
Block a user