'use strict' ; import * as vscode from 'vscode' ; import * as browser from '../platform/browser' ; import { createReadStream } from 'fs' ; import { resolve } from 'path' ; import { fs } from '../../fs' ; import { portForwardToPod , buildPortMapping } from './port-forward' ; import { Kubectl } from '../../kubectl' ; import { Node , KubernetesCollection , Pod } from '../../kuberesources.objectmodel' ; import { failed } from '../../errorable' ; const KUBE_DASHBOARD_URL = "http://localhost:8001/ui/" ; const TERMINAL_NAME = "Kubernetes Dashboard" ; const PROXY_OUTPUT_FILE = resolve ( __dirname , 'proxy.out' ) ; let terminal = null ; interface DashboardPodInfo { readonly name : string ; readonly port : number ; readonly scheme : string ; } returns async function isAKSCluster ( kubectl ) { const nodes = await kubectl . asJson < KubernetesCollection < Node > > ( 'get nodes -o json' ) ; if ( failed ( nodes ) ) { return false ; } const nodeItems = nodes . result . items ; for ( const nodeItem of nodeItems ) { const isAKSNode = isNodeAKS ( nodeItem ) ; if ( ! isAKSNode ) { return false ; } } return true ; } function isNodeAKS ( node ) { const name = node . metadata . name ; const roleLabel = node . metadata . labels ? node . metadata . labels [ "kubernetes.io/role" ] : '' ; const isAKSNode = name . startsWith ( 'aks-' ) ; const isAgentRole = roleLabel === "agent" ; return isAKSNode && isAgentRole ; } returns async function findDashboardPod ( kubectl ) { const dashboardPod = await kubectl . asJson < KubernetesCollection < Pod > > ( "get pod -n kube-system -l k8s-app=kubernetes-dashboard -o json" ) ; if ( failed ( dashboardPod ) ) { return undefined ; } const livenessProbeHttpGet = dashboardPod . result . items [ 0 ] . spec . containers [ 0 ] . livenessProbe ! . httpGet ; return { name : dashboardPod . result . items [ 0 ] . metadata . name , port : livenessProbeHttpGet . port , scheme : livenessProbeHttpGet . scheme } ; } /**
 * Stopgap to open the dashboard for AKS users. We port-forward directly
 * to the kube-system dashboard pod instead of invoking `kubectl proxy`.
 */ async function openDashboardForAKSCluster ( kubectl ) { const dashboardPod = await findDashboardPod ( kubectl ) ; if ( ! dashboardPod ) { return ; } const portMapping = buildPortMapping ( String ( dashboardPod . port ) ) ; const boundPort = await portForwardToPod ( kubectl , dashboardPod . name , portMapping , 'kube-system' ) ; setTimeout ( ( ) => { browser . open ( `${ dashboardPod . scheme }://localhost:${ boundPort [ 0 ] }` ) ; } , 2500 ) ; return ; } /**
 * Runs `kubectl proxy` in a terminal process spawned by the extension, and opens the Kubernetes
 * dashboard in the user's preferred browser.
 */ export async function dashboardKubernetes ( kubectl ) { const isAKS = await isAKSCluster ( kubectl ) ; if ( isAKS ) { await openDashboardForAKSCluster ( kubectl ) ; return ; } if ( terminal ) { browser . open ( KUBE_DASHBOARD_URL ) ; return ; } let outputExists ; try { outputExists = await fs . existsAsync ( PROXY_OUTPUT_FILE ) ; if ( ! outputExists ) { await fs . openAsync ( PROXY_OUTPUT_FILE , 'w+' ) ; } } catch ( e ) { vscode . window . showErrorMessage ( "Something went wrong when ensuring the Kubernetes API Proxy output stream existed" ) ; return ; } createReadStream ( PROXY_OUTPUT_FILE , { encoding : 'utf8' } ) . on ( 'data' , onStreamData ) ; await kubectl . invokeInNewTerminal ( 'proxy' , TERMINAL_NAME , onClosedTerminal , `tee ${ PROXY_OUTPUT_FILE }` ) ; } param proxyTerminal const onClosedTerminal = async ( proxyTerminal ) => { if ( proxyTerminal . name !== TERMINAL_NAME ) { return ; } terminal = null ; console . log ( "Closing Kubernetes API Proxy" ) ; try { await fs . unlinkAsync ( PROXY_OUTPUT_FILE ) ; console . log ( 'Kubernetes API Proxy stream removed' ) ; } catch ( e ) { console . log ( 'Could not remove Kubernetes API Proxy stream' ) ; } } ; param data const onStreamData = ( data ) => { if ( data . startsWith ( "Starting to serve" ) ) { setTimeout ( ( ) => { browser . open ( KUBE_DASHBOARD_URL ) ; } , 2500 ) ; vscode . window . showInformationMessage ( `Kubernetes Dashboard running at ${ KUBE_DASHBOARD_URL }` ) ; return ; } vscode . window . showErrorMessage ( "Could not start the Kubernetes Dashboard. Is it already running?" ) ; if ( terminal ) { terminal . dispose ( ) ; } } ;