mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add a few missing folders to be linted.
Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com>
This commit is contained in:
1 parent
1477bb8274
commit
0b182ccf6f
29 files changed
+376
-374
No files matched your search
@@ -1,10 +1,10 @@
|
||||
import { LensRendererExtension, Component } from "@k8slens/extensions";
|
||||
import { CoffeeDoodle } from "react-open-doodles";
|
||||
import path from "path";
|
||||
import React from "react"
|
||||
import React from "react";
|
||||
|
||||
export function ExampleIcon(props: Component.IconProps) {
|
||||
return <Component.Icon {...props} material="pages" tooltip={path.basename(__filename)}/>
|
||||
return <Component.Icon {...props} material="pages" tooltip={path.basename(__filename)}/>;
|
||||
}
|
||||
|
||||
export class ExamplePage extends React.Component<{ extension: LensRendererExtension }> {
|
||||
@@ -16,7 +16,7 @@ export class ExamplePage extends React.Component<{ extension: LensRendererExtens
|
||||
render() {
|
||||
const doodleStyle = {
|
||||
width: "200px"
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="flex column gaps align-flex-start">
|
||||
<div style={doodleStyle}><CoffeeDoodle accent="#3d90ce" /></div>
|
||||
@@ -24,6 +24,6 @@ export class ExamplePage extends React.Component<{ extension: LensRendererExtens
|
||||
<p>File: <i>{__filename}</i></p>
|
||||
<Component.Button accent label="Deactivate" onClick={this.deactivate}/>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { LensRendererExtension } from "@k8slens/extensions";
|
||||
import { ExampleIcon, ExamplePage } from "./page"
|
||||
import React from "react"
|
||||
import { ExampleIcon, ExamplePage } from "./page";
|
||||
import React from "react";
|
||||
|
||||
export default class ExampleExtension extends LensRendererExtension {
|
||||
clusterPages = [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { LensRendererExtension, K8sApi } from "@k8slens/extensions";
|
||||
import { resolveStatus, resolveStatusForCronJobs, resolveStatusForPods } from "./src/resolver"
|
||||
import { resolveStatus, resolveStatusForCronJobs, resolveStatusForPods } from "./src/resolver";
|
||||
|
||||
export default class EventResourceStatusRendererExtension extends LensRendererExtension {
|
||||
kubeObjectStatusTexts = [
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { K8sApi } from "@k8slens/extensions";
|
||||
|
||||
export function resolveStatus(object: K8sApi.KubeObject): K8sApi.KubeObjectStatus {
|
||||
const eventStore = K8sApi.apiManager.getStore(K8sApi.eventApi)
|
||||
const eventStore = K8sApi.apiManager.getStore(K8sApi.eventApi);
|
||||
const events = (eventStore as K8sApi.EventStore).getEventsByObject(object);
|
||||
let warnings = events.filter(evt => evt.isWarning());
|
||||
const warnings = events.filter(evt => evt.isWarning());
|
||||
if (!events.length || !warnings.length) {
|
||||
return null;
|
||||
}
|
||||
@@ -12,16 +12,16 @@ export function resolveStatus(object: K8sApi.KubeObject): K8sApi.KubeObjectStatu
|
||||
level: K8sApi.KubeObjectStatusLevel.WARNING,
|
||||
text: `${event.message}`,
|
||||
timestamp: event.metadata.creationTimestamp
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveStatusForPods(pod: K8sApi.Pod): K8sApi.KubeObjectStatus {
|
||||
if (!pod.hasIssues()) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
const eventStore = K8sApi.apiManager.getStore(K8sApi.eventApi)
|
||||
const eventStore = K8sApi.apiManager.getStore(K8sApi.eventApi);
|
||||
const events = (eventStore as K8sApi.EventStore).getEventsByObject(pod);
|
||||
let warnings = events.filter(evt => evt.isWarning());
|
||||
const warnings = events.filter(evt => evt.isWarning());
|
||||
if (!events.length || !warnings.length) {
|
||||
return null;
|
||||
}
|
||||
@@ -30,13 +30,13 @@ export function resolveStatusForPods(pod: K8sApi.Pod): K8sApi.KubeObjectStatus {
|
||||
level: K8sApi.KubeObjectStatusLevel.WARNING,
|
||||
text: `${event.message}`,
|
||||
timestamp: event.metadata.creationTimestamp
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveStatusForCronJobs(cronJob: K8sApi.CronJob): K8sApi.KubeObjectStatus {
|
||||
const eventStore = K8sApi.apiManager.getStore(K8sApi.eventApi)
|
||||
const eventStore = K8sApi.apiManager.getStore(K8sApi.eventApi);
|
||||
let events = (eventStore as K8sApi.EventStore).getEventsByObject(cronJob);
|
||||
let warnings = events.filter(evt => evt.isWarning());
|
||||
const warnings = events.filter(evt => evt.isWarning());
|
||||
if (cronJob.isNeverRun()) {
|
||||
events = events.filter(event => event.reason != "FailedNeedsStart");
|
||||
}
|
||||
@@ -48,5 +48,5 @@ export function resolveStatusForCronJobs(cronJob: K8sApi.CronJob): K8sApi.KubeOb
|
||||
level: K8sApi.KubeObjectStatusLevel.WARNING,
|
||||
text: `${event.message}`,
|
||||
timestamp: event.metadata.creationTimestamp
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -6,7 +6,7 @@ export default class LicenseLensMainExtension extends LensMainExtension {
|
||||
parentId: "help",
|
||||
label: "License",
|
||||
async click() {
|
||||
Util.openExternal("https://k8slens.dev/licenses/eula.md")
|
||||
Util.openExternal("https://k8slens.dev/licenses/eula.md");
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import path from "path"
|
||||
import path from "path";
|
||||
|
||||
const outputPath = path.resolve(__dirname, 'dist');
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { LensRendererExtension } from "@k8slens/extensions"
|
||||
import { MetricsFeature } from "./src/metrics-feature"
|
||||
import React from "react"
|
||||
import { LensRendererExtension } from "@k8slens/extensions";
|
||||
import { MetricsFeature } from "./src/metrics-feature";
|
||||
import React from "react";
|
||||
|
||||
export default class ClusterMetricsFeatureExtension extends LensRendererExtension {
|
||||
clusterFeatures = [
|
||||
@@ -13,8 +13,8 @@ export default class ClusterMetricsFeatureExtension extends LensRendererExtensio
|
||||
Enable timeseries data visualization (Prometheus stack) for your cluster.
|
||||
Install this only if you don't have existing Prometheus stack installed.
|
||||
You can see preview of manifests <a href="https://github.com/lensapp/lens/tree/master/extensions/lens-metrics/resources" target="_blank">here</a>.
|
||||
</span>
|
||||
)
|
||||
</span>
|
||||
);
|
||||
}
|
||||
},
|
||||
feature: new MetricsFeature()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ClusterFeature, Store, K8sApi } from "@k8slens/extensions"
|
||||
import semver from "semver"
|
||||
import * as path from "path"
|
||||
import { ClusterFeature, Store, K8sApi } from "@k8slens/extensions";
|
||||
import semver from "semver";
|
||||
import * as path from "path";
|
||||
|
||||
export interface MetricsConfiguration {
|
||||
// Placeholder for Metrics config structure
|
||||
@@ -51,46 +51,46 @@ export class MetricsFeature extends ClusterFeature.Feature {
|
||||
|
||||
async install(cluster: Store.Cluster): Promise<void> {
|
||||
// Check if there are storageclasses
|
||||
const storageClassApi = K8sApi.forCluster(cluster, K8sApi.StorageClass)
|
||||
const scs = await storageClassApi.list()
|
||||
const storageClassApi = K8sApi.forCluster(cluster, K8sApi.StorageClass);
|
||||
const scs = await storageClassApi.list();
|
||||
this.config.persistence.enabled = scs.some(sc => (
|
||||
sc.metadata?.annotations?.['storageclass.kubernetes.io/is-default-class'] === 'true' ||
|
||||
sc.metadata?.annotations?.['storageclass.beta.kubernetes.io/is-default-class'] === 'true'
|
||||
));
|
||||
|
||||
super.applyResources(cluster, super.renderTemplates(path.join(__dirname, "../resources/")))
|
||||
super.applyResources(cluster, super.renderTemplates(path.join(__dirname, "../resources/")));
|
||||
}
|
||||
|
||||
async upgrade(cluster: Store.Cluster): Promise<void> {
|
||||
return this.install(cluster)
|
||||
return this.install(cluster);
|
||||
}
|
||||
|
||||
async updateStatus(cluster: Store.Cluster): Promise<ClusterFeature.FeatureStatus> {
|
||||
try {
|
||||
const statefulSet = K8sApi.forCluster(cluster, K8sApi.StatefulSet)
|
||||
const prometheus = await statefulSet.get({name: "prometheus", namespace: "lens-metrics"})
|
||||
const statefulSet = K8sApi.forCluster(cluster, K8sApi.StatefulSet);
|
||||
const prometheus = await statefulSet.get({name: "prometheus", namespace: "lens-metrics"});
|
||||
if (prometheus?.kind) {
|
||||
this.status.installed = true;
|
||||
this.status.currentVersion = prometheus.spec.template.spec.containers[0].image.split(":")[1];
|
||||
this.status.canUpgrade = semver.lt(this.status.currentVersion, this.latestVersion, true);
|
||||
} else {
|
||||
this.status.installed = false
|
||||
this.status.installed = false;
|
||||
}
|
||||
} catch(e) {
|
||||
if (e?.error?.code === 404) {
|
||||
this.status.installed = false
|
||||
this.status.installed = false;
|
||||
}
|
||||
}
|
||||
|
||||
return this.status
|
||||
return this.status;
|
||||
}
|
||||
|
||||
async uninstall(cluster: Store.Cluster): Promise<void> {
|
||||
const namespaceApi = K8sApi.forCluster(cluster, K8sApi.Namespace)
|
||||
const clusterRoleBindingApi = K8sApi.forCluster(cluster, K8sApi.ClusterRoleBinding)
|
||||
const clusterRoleApi = K8sApi.forCluster(cluster, K8sApi.ClusterRole)
|
||||
const namespaceApi = K8sApi.forCluster(cluster, K8sApi.Namespace);
|
||||
const clusterRoleBindingApi = K8sApi.forCluster(cluster, K8sApi.ClusterRoleBinding);
|
||||
const clusterRoleApi = K8sApi.forCluster(cluster, K8sApi.ClusterRole);
|
||||
|
||||
await namespaceApi.delete({name: "lens-metrics"})
|
||||
await clusterRoleBindingApi.delete({name: "lens-prometheus"})
|
||||
await clusterRoleApi.delete({name: "lens-prometheus"}) }
|
||||
await namespaceApi.delete({name: "lens-metrics"});
|
||||
await clusterRoleBindingApi.delete({name: "lens-prometheus"});
|
||||
await clusterRoleApi.delete({name: "lens-prometheus"}); }
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { LensRendererExtension } from "@k8slens/extensions";
|
||||
import React from "react"
|
||||
import { NodeMenu, NodeMenuProps } from "./src/node-menu"
|
||||
import React from "react";
|
||||
import { NodeMenu, NodeMenuProps } from "./src/node-menu";
|
||||
|
||||
export default class NodeMenuRendererExtension extends LensRendererExtension {
|
||||
kubeObjectMenuItems = [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { Component, K8sApi, Navigation} from "@k8slens/extensions"
|
||||
import { Component, K8sApi, Navigation} from "@k8slens/extensions";
|
||||
|
||||
export interface NodeMenuProps extends Component.KubeObjectMenuProps<K8sApi.Node> {
|
||||
}
|
||||
@@ -15,7 +15,7 @@ export function NodeMenu(props: NodeMenuProps) {
|
||||
newTab: true,
|
||||
});
|
||||
Navigation.hideDetails();
|
||||
}
|
||||
};
|
||||
|
||||
const shell = () => {
|
||||
Component.createTerminalTab({
|
||||
@@ -23,15 +23,15 @@ export function NodeMenu(props: NodeMenuProps) {
|
||||
node: nodeName,
|
||||
});
|
||||
Navigation.hideDetails();
|
||||
}
|
||||
};
|
||||
|
||||
const cordon = () => {
|
||||
sendToTerminal(`kubectl cordon ${nodeName}`);
|
||||
}
|
||||
};
|
||||
|
||||
const unCordon = () => {
|
||||
sendToTerminal(`kubectl uncordon ${nodeName}`)
|
||||
}
|
||||
sendToTerminal(`kubectl uncordon ${nodeName}`);
|
||||
};
|
||||
|
||||
const drain = () => {
|
||||
const command = `kubectl drain ${nodeName} --delete-local-data --ignore-daemonsets --force`;
|
||||
@@ -43,8 +43,8 @@ export function NodeMenu(props: NodeMenuProps) {
|
||||
Are you sure you want to drain <b>{nodeName}</b>?
|
||||
</p>
|
||||
),
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { LensRendererExtension } from "@k8slens/extensions";
|
||||
import { PodShellMenu, PodShellMenuProps } from "./src/shell-menu"
|
||||
import { PodLogsMenu, PodLogsMenuProps } from "./src/logs-menu"
|
||||
import React from "react"
|
||||
import { PodShellMenu, PodShellMenuProps } from "./src/shell-menu";
|
||||
import { PodLogsMenu, PodLogsMenuProps } from "./src/logs-menu";
|
||||
import React from "react";
|
||||
|
||||
export default class PodMenuRendererExtension extends LensRendererExtension {
|
||||
kubeObjectMenuItems = [
|
||||
|
||||
@@ -19,7 +19,7 @@ export class PodLogsMenu extends React.Component<PodLogsMenuProps> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { object: pod, toolbar } = this.props
|
||||
const { object: pod, toolbar } = this.props;
|
||||
const containers = pod.getAllContainers();
|
||||
const statuses = pod.getContainerStatuses();
|
||||
if (!containers.length) return null;
|
||||
@@ -33,25 +33,25 @@ export class PodLogsMenu extends React.Component<PodLogsMenuProps> {
|
||||
<Component.SubMenu>
|
||||
{
|
||||
containers.map(container => {
|
||||
const { name } = container
|
||||
const { name } = container;
|
||||
const status = statuses.find(status => status.name === name);
|
||||
const brick = status ? (
|
||||
<Component.StatusBrick
|
||||
className={Util.cssNames(Object.keys(status.state)[0], { ready: status.ready })}
|
||||
/>
|
||||
) : null
|
||||
) : null;
|
||||
return (
|
||||
<Component.MenuItem key={name} onClick={Util.prevDefault(() => this.showLogs(container))} className="flex align-center">
|
||||
{brick}
|
||||
{name}
|
||||
</Component.MenuItem>
|
||||
)
|
||||
);
|
||||
})
|
||||
}
|
||||
</Component.SubMenu>
|
||||
</>
|
||||
)}
|
||||
</Component.MenuItem>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -9,16 +9,16 @@ export interface PodShellMenuProps extends Component.KubeObjectMenuProps<K8sApi.
|
||||
export class PodShellMenu extends React.Component<PodShellMenuProps> {
|
||||
async execShell(container?: string) {
|
||||
Navigation.hideDetails();
|
||||
const { object: pod } = this.props
|
||||
const containerParam = container ? `-c ${container}` : ""
|
||||
let command = `kubectl exec -i -t -n ${pod.getNs()} ${pod.getName()} ${containerParam} "--"`
|
||||
const { object: pod } = this.props;
|
||||
const containerParam = container ? `-c ${container}` : "";
|
||||
let command = `kubectl exec -i -t -n ${pod.getNs()} ${pod.getName()} ${containerParam} "--"`;
|
||||
if (window.navigator.platform !== "Win32") {
|
||||
command = `exec ${command}`
|
||||
command = `exec ${command}`;
|
||||
}
|
||||
if (pod.getSelectedNodeOs() === "windows") {
|
||||
command = `${command} powershell`
|
||||
command = `${command} powershell`;
|
||||
} else {
|
||||
command = `${command} sh -c "clear; (bash || ash || sh)"`
|
||||
command = `${command} sh -c "clear; (bash || ash || sh)"`;
|
||||
}
|
||||
|
||||
const shell = Component.createTerminalTab({
|
||||
@@ -32,7 +32,7 @@ export class PodShellMenu extends React.Component<PodShellMenuProps> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { object, toolbar } = this.props
|
||||
const { object, toolbar } = this.props;
|
||||
const containers = object.getRunningContainers();
|
||||
if (!containers.length) return null;
|
||||
return (
|
||||
@@ -51,13 +51,13 @@ export class PodShellMenu extends React.Component<PodShellMenuProps> {
|
||||
<Component.StatusBrick/>
|
||||
{name}
|
||||
</Component.MenuItem>
|
||||
)
|
||||
);
|
||||
})
|
||||
}
|
||||
</Component.SubMenu>
|
||||
</>
|
||||
)}
|
||||
</Component.MenuItem>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
// TODO: support localization / figure out how to extract / consume i18n strings
|
||||
|
||||
import "./support.scss"
|
||||
import React from "react"
|
||||
import { observer } from "mobx-react"
|
||||
import "./support.scss";
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { App, Component } from "@k8slens/extensions";
|
||||
|
||||
@observer
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import path from "path"
|
||||
import path from "path";
|
||||
|
||||
const outputPath = path.resolve(__dirname, 'dist');
|
||||
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { LensMainExtension } from "@k8slens/extensions";
|
||||
import { telemetryPreferencesStore } from "./src/telemetry-preferences-store"
|
||||
import { telemetryPreferencesStore } from "./src/telemetry-preferences-store";
|
||||
import { tracker } from "./src/tracker";
|
||||
|
||||
export default class TelemetryMainExtension extends LensMainExtension {
|
||||
|
||||
async onActivate() {
|
||||
console.log("telemetry main extension activated")
|
||||
tracker.start()
|
||||
tracker.reportPeriodically()
|
||||
await telemetryPreferencesStore.loadExtension(this)
|
||||
console.log("telemetry main extension activated");
|
||||
tracker.start();
|
||||
tracker.reportPeriodically();
|
||||
await telemetryPreferencesStore.loadExtension(this);
|
||||
}
|
||||
|
||||
onDeactivate() {
|
||||
tracker.stop()
|
||||
console.log("telemetry main extension deactivated")
|
||||
tracker.stop();
|
||||
console.log("telemetry main extension deactivated");
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { LensRendererExtension } from "@k8slens/extensions";
|
||||
import { telemetryPreferencesStore } from "./src/telemetry-preferences-store"
|
||||
import { TelemetryPreferenceHint, TelemetryPreferenceInput } from "./src/telemetry-preference"
|
||||
import { tracker } from "./src/tracker"
|
||||
import React from "react"
|
||||
import { telemetryPreferencesStore } from "./src/telemetry-preferences-store";
|
||||
import { TelemetryPreferenceHint, TelemetryPreferenceInput } from "./src/telemetry-preference";
|
||||
import { tracker } from "./src/tracker";
|
||||
import React from "react";
|
||||
|
||||
export default class TelemetryRendererExtension extends LensRendererExtension {
|
||||
appPreferences = [
|
||||
@@ -16,8 +16,8 @@ export default class TelemetryRendererExtension extends LensRendererExtension {
|
||||
];
|
||||
|
||||
async onActivate() {
|
||||
console.log("telemetry extension activated")
|
||||
tracker.start()
|
||||
await telemetryPreferencesStore.loadExtension(this)
|
||||
console.log("telemetry extension activated");
|
||||
tracker.start();
|
||||
await telemetryPreferencesStore.loadExtension(this);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
import { Component } from "@k8slens/extensions"
|
||||
import React from "react"
|
||||
import { Component } from "@k8slens/extensions";
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { TelemetryPreferencesStore } from "./telemetry-preferences-store"
|
||||
import { TelemetryPreferencesStore } from "./telemetry-preferences-store";
|
||||
|
||||
@observer
|
||||
export class TelemetryPreferenceInput extends React.Component<{telemetry: TelemetryPreferencesStore}, {}> {
|
||||
render() {
|
||||
const { telemetry } = this.props
|
||||
const { telemetry } = this.props;
|
||||
return (
|
||||
<Component.Checkbox
|
||||
label="Allow telemetry & usage tracking"
|
||||
value={telemetry.enabled}
|
||||
onChange={v => { telemetry.enabled = v; }}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,6 @@ export class TelemetryPreferenceHint extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<span>Telemetry & usage data is collected to continuously improve the Lens experience.</span>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Store } from "@k8slens/extensions";
|
||||
import { toJS } from "mobx"
|
||||
import { toJS } from "mobx";
|
||||
|
||||
export type TelemetryPreferencesModel = {
|
||||
enabled: boolean;
|
||||
@@ -14,11 +14,11 @@ export class TelemetryPreferencesStore extends Store.ExtensionStore<TelemetryPre
|
||||
defaults: {
|
||||
enabled: true
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
protected fromStore({ enabled }: TelemetryPreferencesModel): void {
|
||||
this.enabled = enabled
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
toJSON(): TelemetryPreferencesModel {
|
||||
@@ -26,8 +26,8 @@ export class TelemetryPreferencesStore extends Store.ExtensionStore<TelemetryPre
|
||||
enabled: this.enabled
|
||||
}, {
|
||||
recurseEverything: true
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const telemetryPreferencesStore = TelemetryPreferencesStore.getInstance<TelemetryPreferencesStore>()
|
||||
export const telemetryPreferencesStore = TelemetryPreferencesStore.getInstance<TelemetryPreferencesStore>();
|
||||
@@ -1,8 +1,8 @@
|
||||
import { EventBus, Util, Store, App } from "@k8slens/extensions"
|
||||
import ua from "universal-analytics"
|
||||
import Analytics from "analytics-node"
|
||||
import { machineIdSync } from "node-machine-id"
|
||||
import { telemetryPreferencesStore } from "./telemetry-preferences-store"
|
||||
import { EventBus, Util, Store, App } from "@k8slens/extensions";
|
||||
import ua from "universal-analytics";
|
||||
import Analytics from "analytics-node";
|
||||
import { machineIdSync } from "node-machine-id";
|
||||
import { telemetryPreferencesStore } from "./telemetry-preferences-store";
|
||||
|
||||
export class Tracker extends Util.Singleton {
|
||||
static readonly GA_ID = "UA-159377374-1"
|
||||
@@ -23,69 +23,69 @@ export class Tracker extends Util.Singleton {
|
||||
|
||||
private constructor() {
|
||||
super();
|
||||
this.anonymousId = machineIdSync()
|
||||
this.os = this.resolveOS()
|
||||
this.userAgent = `Lens ${App.version} (${this.os})`
|
||||
this.anonymousId = machineIdSync();
|
||||
this.os = this.resolveOS();
|
||||
this.userAgent = `Lens ${App.version} (${this.os})`;
|
||||
try {
|
||||
this.visitor = ua(Tracker.GA_ID, this.anonymousId, { strictCidFormat: false })
|
||||
this.visitor = ua(Tracker.GA_ID, this.anonymousId, { strictCidFormat: false });
|
||||
} catch (error) {
|
||||
this.visitor = ua(Tracker.GA_ID)
|
||||
this.visitor = ua(Tracker.GA_ID);
|
||||
}
|
||||
|
||||
this.analytics = new Analytics(Tracker.SEGMENT_KEY, { flushAt: 1 })
|
||||
this.visitor.set("dl", "https://telemetry.k8slens.dev")
|
||||
this.visitor.set("ua", this.userAgent)
|
||||
this.analytics = new Analytics(Tracker.SEGMENT_KEY, { flushAt: 1 });
|
||||
this.visitor.set("dl", "https://telemetry.k8slens.dev");
|
||||
this.visitor.set("ua", this.userAgent);
|
||||
}
|
||||
|
||||
start() {
|
||||
if (this.started === true) { return }
|
||||
if (this.started === true) { return; }
|
||||
|
||||
this.started = true
|
||||
this.started = true;
|
||||
|
||||
const handler = (ev: EventBus.AppEvent) => {
|
||||
this.event(ev.name, ev.action, ev.params)
|
||||
}
|
||||
this.eventHandlers.push(handler)
|
||||
EventBus.appEventBus.addListener(handler)
|
||||
this.event(ev.name, ev.action, ev.params);
|
||||
};
|
||||
this.eventHandlers.push(handler);
|
||||
EventBus.appEventBus.addListener(handler);
|
||||
}
|
||||
|
||||
reportPeriodically() {
|
||||
this.reportInterval = setInterval(() => {
|
||||
this.reportData()
|
||||
}, 60 * 60 * 1000) // report every 1h
|
||||
this.reportData();
|
||||
}, 60 * 60 * 1000); // report every 1h
|
||||
}
|
||||
|
||||
stop() {
|
||||
if (!this.started) { return }
|
||||
if (!this.started) { return; }
|
||||
|
||||
this.started = false
|
||||
this.started = false;
|
||||
|
||||
for (const handler of this.eventHandlers) {
|
||||
EventBus.appEventBus.removeListener(handler)
|
||||
EventBus.appEventBus.removeListener(handler);
|
||||
}
|
||||
if (this.reportInterval) {
|
||||
clearInterval(this.reportInterval)
|
||||
clearInterval(this.reportInterval);
|
||||
}
|
||||
}
|
||||
|
||||
protected async isTelemetryAllowed(): Promise<boolean> {
|
||||
return telemetryPreferencesStore.enabled
|
||||
return telemetryPreferencesStore.enabled;
|
||||
}
|
||||
|
||||
protected reportData() {
|
||||
const clustersList = Store.clusterStore.enabledClustersList
|
||||
const clustersList = Store.clusterStore.enabledClustersList;
|
||||
|
||||
this.event("generic-data", "report", {
|
||||
appVersion: App.version,
|
||||
os: this.os,
|
||||
clustersCount: clustersList.length,
|
||||
workspacesCount: Store.workspaceStore.enabledWorkspacesList.length
|
||||
})
|
||||
});
|
||||
|
||||
clustersList.forEach((cluster) => {
|
||||
if (!cluster?.metadata.lastSeen) { return }
|
||||
this.reportClusterData(cluster)
|
||||
})
|
||||
if (!cluster?.metadata.lastSeen) { return; }
|
||||
this.reportClusterData(cluster);
|
||||
});
|
||||
}
|
||||
|
||||
protected reportClusterData(cluster: Store.ClusterModel) {
|
||||
@@ -96,26 +96,26 @@ export class Tracker extends Util.Singleton {
|
||||
distribution: cluster.metadata.distribution,
|
||||
nodesCount: cluster.metadata.nodes,
|
||||
lastSeen: cluster.metadata.lastSeen
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
protected resolveOS() {
|
||||
let os = ""
|
||||
let os = "";
|
||||
if (App.isMac) {
|
||||
os = "MacOS"
|
||||
os = "MacOS";
|
||||
} else if(App.isWindows) {
|
||||
os = "Windows"
|
||||
os = "Windows";
|
||||
} else if (App.isLinux) {
|
||||
os = "Linux"
|
||||
os = "Linux";
|
||||
if (App.isSnap) {
|
||||
os += "; Snap"
|
||||
os += "; Snap";
|
||||
} else {
|
||||
os += "; AppImage"
|
||||
os += "; AppImage";
|
||||
}
|
||||
} else {
|
||||
os = "Unknown"
|
||||
os = "Unknown";
|
||||
}
|
||||
return os
|
||||
return os;
|
||||
}
|
||||
|
||||
protected async event(eventCategory: string, eventAction: string, otherParams = {}) {
|
||||
@@ -128,7 +128,7 @@ export class Tracker extends Util.Singleton {
|
||||
ec: eventCategory,
|
||||
ea: eventAction,
|
||||
...otherParams,
|
||||
}).send()
|
||||
}).send();
|
||||
|
||||
this.analytics.track({
|
||||
anonymousId: this.anonymousId,
|
||||
@@ -141,9 +141,9 @@ export class Tracker extends Util.Singleton {
|
||||
...otherParams,
|
||||
},
|
||||
|
||||
})
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(`Failed to track "${eventCategory}:${eventAction}"`, err)
|
||||
console.error(`Failed to track "${eventCategory}:${eventAction}"`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user