66import { Context , KubernetesObject } from '@kubernetes/client-node' ;
77import * as fs from 'fs' ;
88import * as path from 'path' ;
9+ import * as tmp from 'tmp' ;
910import {
11+ commands ,
1012 Disposable ,
1113 Event ,
1214 EventEmitter ,
15+ extensions ,
16+ TextDocumentShowOptions ,
1317 ThemeIcon ,
1418 TreeDataProvider ,
1519 TreeItem ,
1620 TreeItemCollapsibleState ,
1721 TreeView ,
1822 Uri ,
19- commands ,
20- extensions ,
2123 version ,
2224 window ,
2325 workspace
@@ -31,7 +33,7 @@ import { Oc } from './oc/ocWrapper';
3133import { Component } from './openshift/component' ;
3234import { getServiceKindStubs , getServices } from './openshift/serviceHelpers' ;
3335import { PortForward } from './port-forward' ;
34- import { KubeConfigUtils , getKubeConfigFiles , getNamespaceKind , isOpenShiftCluster } from './util/kubeUtils' ;
36+ import { getKubeConfigFiles , getNamespaceKind , isOpenShiftCluster , KubeConfigInfo } from './util/kubeUtils' ;
3537import { LoginUtil } from './util/loginUtil' ;
3638import { Platform } from './util/platform' ;
3739import { Progress } from './util/progress' ;
@@ -106,7 +108,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
106108
107109 private kubeConfigWatchers : FileContentChangeNotifier [ ] ;
108110 private kubeContext : Context ;
109- private kubeConfig : KubeConfigUtils ;
111+ private kubeConfigInfo : KubeConfigInfo ;
110112
111113 private executionContext : ExecutionContext = new ExecutionContext ( ) ;
112114
@@ -120,8 +122,8 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
120122
121123 private constructor ( ) {
122124 try {
123- this . kubeConfig = new KubeConfigUtils ( ) ;
124- this . kubeContext = this . kubeConfig . getContextObject ( this . kubeConfig . currentContext ) ;
125+ this . kubeConfigInfo = new KubeConfigInfo ( ) ;
126+ this . kubeContext = this . kubeConfigInfo . getEffectiveKubeConfig ( ) . getContextObject ( this . kubeConfigInfo . getEffectiveKubeConfig ( ) . currentContext ) ;
125127 } catch {
126128 // ignore config loading error and let odo report it on first call
127129 }
@@ -137,17 +139,18 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
137139 }
138140 for ( const fsw of this . kubeConfigWatchers ) {
139141 fsw . emitter ?. on ( 'file-changed' , ( ) => {
140- const ku2 = new KubeConfigUtils ( ) ;
141- const newCtx = ku2 . getContextObject ( ku2 . currentContext ) ;
142+ const kci2 = new KubeConfigInfo ( ) ;
143+ const kc2 = kci2 . getEffectiveKubeConfig ( ) ;
144+ const newCtx = kc2 . getContextObject ( kc2 . currentContext ) ;
142145 if ( Boolean ( this . kubeContext ) !== Boolean ( newCtx )
143- || ( this . kubeContext . cluster !== newCtx . cluster
144- || this . kubeContext . user !== newCtx . user
145- || this . kubeContext . namespace !== newCtx . namespace ) ) {
146+ || ( this . kubeContext ? .cluster !== newCtx ? .cluster
147+ || this . kubeContext ? .user !== newCtx ? .user
148+ || this . kubeContext ? .namespace !== newCtx ? .namespace ) ) {
146149 this . refresh ( ) ;
147150 this . onDidChangeContextEmitter . fire ( newCtx ?. name ) ; // newCtx can be 'null'
148151 }
149152 this . kubeContext = newCtx ;
150- this . kubeConfig = ku2 ;
153+ this . kubeConfigInfo = kci2 ;
151154 } ) ;
152155 }
153156 this . treeView = window . createTreeView < ExplorerItem > ( 'openshiftProjectExplorer' , {
@@ -202,7 +205,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
202205 void commands . executeCommand ( 'setContext' , 'isLoggedIn' , true ) ;
203206 return {
204207 contextValue : 'openshift.k8sContext' ,
205- label : this . kubeConfig . getCluster ( element . cluster ) ?. server ,
208+ label : this . kubeConfigInfo . getEffectiveKubeConfig ( ) . getCluster ( element . cluster ) ?. server ,
206209 collapsibleState : TreeItemCollapsibleState . Collapsed ,
207210 iconPath : imagePath ( 'context/cluster-node.png' )
208211 } ;
@@ -466,7 +469,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
466469 } catch {
467470 // ignore because ether server is not accessible or user is logged out
468471 }
469- OpenShiftExplorer . getInstance ( ) . onDidChangeContextEmitter . fire ( new KubeConfigUtils ( ) . currentContext ) ;
472+ OpenShiftExplorer . getInstance ( ) . onDidChangeContextEmitter . fire ( this . kubeConfigInfo . getEffectiveKubeConfig ( ) . currentContext ) ;
470473 } else if ( 'name' in element ) { // we are dealing with context here
471474 // user is logged into cluster from current context
472475 // and project should be shown as child node of current context
@@ -494,7 +497,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
494497 } ,
495498 } as KubernetesObject ]
496499 } else {
497- const projectName = this . kubeConfig . extractProjectNameFromCurrentContext ( ) || 'default' ;
500+ const projectName = this . kubeConfigInfo . extractProjectNameFromCurrentContext ( ) || 'default' ;
498501 result = [ await createOrSetProjectItem ( projectName , this . executionContext ) ] ;
499502 }
500503
@@ -544,7 +547,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
544547 try {
545548 return this . getPods ( element ) ;
546549 } catch {
547- return [ couldNotGetItem ( element . kind , this . kubeConfig . getCluster ( this . kubeContext . cluster ) ?. server ) ] ;
550+ return [ couldNotGetItem ( element . kind , this . kubeConfigInfo . getEffectiveKubeConfig ( ) . getCluster ( this . kubeContext . cluster ) ?. server ) ] ;
548551 }
549552 } else if ( 'kind' in element && element . kind === 'project' ) {
550553 const deployments = {
@@ -651,7 +654,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
651654 try {
652655 collections = await Oc . Instance . getKubernetesObjects ( element . kind , undefined , undefined , this . executionContext ) ;
653656 } catch {
654- collections = [ couldNotGetItem ( element . kind , this . kubeConfig . getCluster ( this . kubeContext . cluster ) ?. server ) ] ;
657+ collections = [ couldNotGetItem ( element . kind , this . kubeConfigInfo . getEffectiveKubeConfig ( ) . getCluster ( this . kubeContext . cluster ) ?. server ) ] ;
655658 }
656659 break ;
657660 }
@@ -872,4 +875,28 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
872875 ] . join ( '\n' ) ;
873876 return `${ packageJSON . bugs } /new?labels=kind/bug&title=&body=**Environment**\n${ body } \n**Description**` ;
874877 }
878+
879+ @vsCommand ( 'openshift.explorer.describe.kubeconfig' , true )
880+ static async describeEffectiveConfig ( ) : Promise < void > {
881+ const k8sConfig : string = new KubeConfigInfo ( ) . dumpEffectiveKubeConfig ( ) ;
882+ const tempK8sConfigFile = await new Promise < string > ( ( resolve , reject ) => {
883+ tmp . file ( { prefix : 'effective.config' , postfix : '.yaml' } , ( err , name ) => {
884+ if ( err ) {
885+ reject ( err ) ;
886+ }
887+ resolve ( name ) ;
888+ } ) ;
889+ } ) ;
890+ fs . writeFileSync ( tempK8sConfigFile , k8sConfig , 'utf-8' )
891+ fs . chmodSync ( tempK8sConfigFile , 0o400 ) ;
892+ const fileUri = Uri . parse ( tempK8sConfigFile ) ;
893+ window . showTextDocument ( fileUri , { preview : true , readOnly : true } as TextDocumentShowOptions ) ;
894+ const onCloseSubscription = workspace . onDidCloseTextDocument ( ( closedDoc ) => {
895+ if ( closedDoc . uri . toString ( ) === fileUri . toString ( ) ) {
896+ fs . chmodSync ( tempK8sConfigFile , 0o600 ) ;
897+ fs . unlinkSync ( tempK8sConfigFile ) ;
898+ onCloseSubscription . dispose ( ) ;
899+ }
900+ } ) ;
901+ }
875902}
0 commit comments