1
0
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:
John Mitchell 2018-03-14 10:26:08 -04:00 committed by GitHub
commit ea5ab2df7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 200 additions and 134 deletions

View File

@ -139,3 +139,7 @@
.License-detailsGroup {
margin-bottom: 20px;
}
.License-detailsGroup--withSeparator {
border-top: 1px solid @default-icon-hov;
}

View File

@ -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);
}
});
});
};
}];

View File

@ -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>

View File

@ -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}"`);
}
}
};
}
];
}];