From c686e0a847f0a516764d7e2f4cd13bda322c6491 Mon Sep 17 00:00:00 2001 From: Ivan Towlson Date: Thu, 6 Sep 2018 16:06:36 +1200 Subject: [PATCH] Transfer commit: include Azure and Minikube target in command telemetry --- src/extension.ts | 3 +- src/telemetry-helper.ts | 84 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index f489fab20..8c68b3b85 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -342,7 +342,7 @@ export async function activate(context): Promise { export const deactivate = () => { }; function registerCommand(command: string, callback: (...args: any[]) => any): vscode.Disposable { - const wrappedCallback = telemetry.telemetrise(command, callback); + const wrappedCallback = telemetry.telemetrise(command, kubectl, callback); return vscode.commands.registerCommand(command, wrappedCallback); } @@ -1708,6 +1708,7 @@ async function useContextKubernetes(explorerNode: explorer.KubernetesObject) { const shellResult = await kubectl.invokeAsync(`config use-context ${targetContext}`); if (shellResult.code === 0) { refreshExplorer(); + telemetry.invalidateClusterType(targetContext); } else { vscode.window.showErrorMessage(`Failed to set '${targetContext}' as current cluster: ${shellResult.stderr}`); } diff --git a/src/telemetry-helper.ts b/src/telemetry-helper.ts index 8b63ddbaa..ecdcdda1c 100644 --- a/src/telemetry-helper.ts +++ b/src/telemetry-helper.ts @@ -1,8 +1,86 @@ import { reporter } from './telemetry'; +import { Kubectl } from './kubectl'; -export function telemetrise(command: string, callback: (...args: any[]) => any): (...args: any[]) => any { - return (a) => { - reporter.sendTelemetryEvent("command", { command: command }); +export function telemetrise(command: string, kubectl: Kubectl, callback: (...args: any[]) => any): (...args: any[]) => any { + return async (a) => { + reporter.sendTelemetryEvent("command", { command: command, clusterType: await clusterType(kubectl) }); return callback(a); }; } + +export enum ClusterType { + Azure, + Minikube, + Other +} + +let latestContextName: string | null; +let cachedClusterType: ClusterType | null = null; +const knownClusters: any = {}; + +export function invalidateClusterType(newContext: string): void { + latestContextName = newContext || null; + cachedClusterType = null; +} + +async function clusterType(kubectl: Kubectl): Promise { + if (latestContextName && knownClusters[latestContextName]) { + cachedClusterType = knownClusters[latestContextName]; + } + if (!cachedClusterType) { + cachedClusterType = await inferCurrentClusterType(kubectl, latestContextName); + if (latestContextName) { + knownClusters[latestContextName] = cachedClusterType; + } + } + switch (cachedClusterType) { + case ClusterType.Azure: + return 'azure'; + case ClusterType.Minikube: + return 'minikube'; + case ClusterType.Other: + return 'other'; + } +} + +async function inferCurrentClusterType(kubectl: Kubectl, contextNameHint: string | null): Promise { + if (!latestContextName) { + const ctxsr = await kubectl.invokeAsync('config current-context'); + if (ctxsr.code === 0) { + latestContextName = ctxsr.stdout.trim(); + } else { + return ClusterType.Other; // something is terribly wrong; we don't want to retry + } + } + + if (latestContextName === 'minikube') { + return ClusterType.Minikube; + } + + const cisr = await kubectl.invokeAsync('cluster-info'); + if (cisr.code !== 0) { + return null; + } + const masterInfos = cisr.stdout.split('\n') + .filter((s) => s.indexOf('master is running at') >= 0); + + if (masterInfos.length === 0) { + return ClusterType.Other; // something is terribly wrong; we don't want to retry + } + + const masterInfo = masterInfos[0]; + if (masterInfo.indexOf('azure.com') >= 0) { + return ClusterType.Azure; + } + + if (latestContextName) { + const gcsr = await kubectl.invokeAsync(`config get-contexts ${latestContextName}`); + if (gcsr.code === 0) { + if (gcsr.stdout.indexOf('minikube') >= 0) { + return ClusterType.Minikube; // It's pretty heuristic, so don't spend time parsing the table + } + } + } + + return ClusterType.Other; +}