mirror of https://github.com/rancher/dashboard.git
220 lines
6.4 KiB
TypeScript
220 lines
6.4 KiB
TypeScript
/**
|
|
* Helper for collecting system information and formatting into to a query string
|
|
*/
|
|
|
|
import { sha256 } from '@shell/utils/crypto';
|
|
import {
|
|
COUNT,
|
|
MANAGEMENT,
|
|
} from '@shell/config/types';
|
|
import { SETTING } from '@shell/config/settings';
|
|
import { getVersionData } from '@shell/config/version';
|
|
import { SettingsInfo } from '@shell/utils/dynamic-content/types';
|
|
|
|
const QS_VERSION = 'v1'; // Include a version number in the query string in case we want to version the set of params we are sending
|
|
const UNKNOWN = 'unknown';
|
|
|
|
// List of known UI extensions from SUSE
|
|
const SUSE_EXTENSIONS = [
|
|
'capi',
|
|
'elemental',
|
|
'harvester',
|
|
'kubewarden',
|
|
'neuvector-ui-ext',
|
|
'observability',
|
|
'supportability-review-app',
|
|
'virtual-clusters'
|
|
];
|
|
|
|
/**
|
|
* System information that is collected and which can then be encoded into a query string in the dyanmic content request
|
|
*/
|
|
type SystemInfo = {
|
|
systemUUID: string;
|
|
systemHash: string;
|
|
serverVersionType: string;
|
|
userHash: string;
|
|
version: string;
|
|
isDeveloperVersion: boolean;
|
|
isPrime: boolean;
|
|
isLTS: boolean;
|
|
clusterCount: number;
|
|
localCluster: any;
|
|
extensions?: {
|
|
knownInstalled: string[];
|
|
customCount: number;
|
|
};
|
|
browserSize: string;
|
|
screenSize: string;
|
|
language: string;
|
|
};
|
|
|
|
/**
|
|
* Helper that will gather system information and provided the `buildQueryString` method to format as a query string
|
|
*/
|
|
export class SystemInfoProvider {
|
|
private info: SystemInfo;
|
|
|
|
constructor(getters: any, settings: Partial<SettingsInfo>) {
|
|
this.info = this.getSystemData(getters, settings);
|
|
}
|
|
|
|
/**
|
|
* Get the data that we need from the system
|
|
* @param getters Store getters to access the store
|
|
* @returns System data
|
|
*/
|
|
private getSystemData(getters: any, settingsInfo: Partial<SettingsInfo>): SystemInfo {
|
|
let url;
|
|
let systemUUID = UNKNOWN;
|
|
let serverVersionType = UNKNOWN;
|
|
|
|
const serverUrlSetting = getters['management/byId'](MANAGEMENT.SETTING, SETTING.SERVER_URL);
|
|
|
|
// Server URL
|
|
if (serverUrlSetting) {
|
|
url = serverUrlSetting.value || UNKNOWN;
|
|
}
|
|
|
|
// UUID
|
|
const uuidSetting = getters['management/byId'](MANAGEMENT.SETTING, 'install-uuid');
|
|
|
|
if (uuidSetting) {
|
|
systemUUID = uuidSetting.value || UNKNOWN;
|
|
}
|
|
|
|
// Server Version Type
|
|
const serverVersionTypeSetting = getters['management/byId'](MANAGEMENT.SETTING, 'server-version-type');
|
|
|
|
if (serverVersionTypeSetting) {
|
|
serverVersionType = serverVersionTypeSetting.value || UNKNOWN;
|
|
}
|
|
|
|
// Otherwise, use the window location's host
|
|
url = url || window.location?.host;
|
|
|
|
// System and User hashes
|
|
const systemHash = (sha256(url, 'hex') as string).substring(0, 32);
|
|
const currentPrincipal = getters['auth/principalId'] || UNKNOWN;
|
|
const userHash = (sha256(currentPrincipal, 'hex') as string).substring(0, 32);
|
|
|
|
// Version info
|
|
const versionData = getVersionData();
|
|
const vers = versionData.Version.split('-');
|
|
|
|
// General stats that can help us shape content delivery
|
|
|
|
// High-level information from clusters
|
|
const counts = this.getAll(getters, COUNT)?.[0]?.counts || {};
|
|
const clusterCount = counts[MANAGEMENT.CLUSTER] || {};
|
|
const all = this.getAll(getters, MANAGEMENT.CLUSTER);
|
|
const localCluster = all ? all.find((c: any) => c.isLocal) : undefined;
|
|
|
|
// Stats for installed extensions
|
|
const uiExtensionList = getters['uiplugins/plugins'];
|
|
let extensions;
|
|
|
|
if (uiExtensionList) {
|
|
const suseExtensions = [
|
|
...SUSE_EXTENSIONS,
|
|
...settingsInfo?.suseExtensions || []
|
|
];
|
|
const notBuiltIn = uiExtensionList.filter((e: any) => !e.builtin);
|
|
const suseNames = notBuiltIn.filter((e: any) => suseExtensions.includes(e.name)).map((e: any) => e.name);
|
|
const customCount = notBuiltIn.length - suseNames.length;
|
|
|
|
extensions = {
|
|
knownInstalled: suseNames,
|
|
customCount,
|
|
};
|
|
}
|
|
|
|
const screenSize = `${ window.screen?.width || '?' }x${ window.screen?.height || '?' }`;
|
|
const browserSize = `${ window.innerWidth }x${ window.innerHeight }`;
|
|
|
|
return {
|
|
systemUUID,
|
|
userHash,
|
|
systemHash,
|
|
serverVersionType,
|
|
version: vers[0],
|
|
isDeveloperVersion: vers.length > 1,
|
|
isPrime: versionData.RancherPrime === 'true',
|
|
isLTS: false,
|
|
clusterCount: clusterCount?.summary?.count,
|
|
localCluster,
|
|
extensions,
|
|
screenSize,
|
|
browserSize,
|
|
language: window.navigator?.language,
|
|
};
|
|
}
|
|
|
|
// Helper to get all resources of a type only if they are available
|
|
private getAll(getters: any, typeName: string): any {
|
|
if (getters['management/typeRegistered'](typeName)) {
|
|
return getters['management/all'](typeName);
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
/**
|
|
* Build query string of params to send so that we can deliver better content
|
|
*/
|
|
public buildQueryString(): string {
|
|
const systemData = this.info;
|
|
const params = [`dcv=${ QS_VERSION }`];
|
|
|
|
// System and User
|
|
params.push(`s=${ systemData.systemHash }`);
|
|
params.push(`u=${ systemData.userHash }`);
|
|
|
|
// Install UUID
|
|
if (systemData.systemUUID !== UNKNOWN) {
|
|
params.push(`uuid=${ systemData.systemUUID }`);
|
|
}
|
|
|
|
// Server Version Type
|
|
if (systemData.serverVersionType !== UNKNOWN) {
|
|
params.push(`svt=${ systemData.serverVersionType }`);
|
|
}
|
|
|
|
// Version info
|
|
params.push(`v=${ systemData.version }`);
|
|
params.push(`dev=${ systemData.isDeveloperVersion }`);
|
|
params.push(`p=${ systemData.isPrime }`);
|
|
|
|
// Remove LTS for now, until we can determine LTS status
|
|
// params.push(`lts=${ systemData.isLTS }`);
|
|
|
|
// Clusters
|
|
params.push(`cc=${ systemData.clusterCount }`);
|
|
|
|
if (systemData.localCluster) {
|
|
params.push(`lkv=${ systemData.localCluster.kubernetesVersionBase || UNKNOWN }`);
|
|
params.push(`lcp=${ systemData.localCluster.provisioner || UNKNOWN }`);
|
|
params.push(`lnc=${ systemData.localCluster.status.nodeCount || 0 }`);
|
|
}
|
|
|
|
// Extensions
|
|
if (systemData.extensions) {
|
|
params.push(`xkn=${ systemData.extensions.knownInstalled.join(',') }`);
|
|
params.push(`xcc=${ systemData.extensions.customCount }`);
|
|
}
|
|
|
|
// Browser Language
|
|
params.push(`bl=${ systemData.language }`);
|
|
|
|
// Browser size
|
|
params.push(`bs=${ systemData.browserSize }`);
|
|
|
|
// Screen size
|
|
if (systemData.screenSize !== '?x?') {
|
|
params.push(`ss=${ systemData.screenSize }`);
|
|
}
|
|
|
|
return params.join('&');
|
|
}
|
|
}
|