@@ -7,27 +7,58 @@ import { Context, KubernetesObject } from '@kubernetes/client-node';
77import * as fs from 'fs' ;
88import * as path from 'path' ;
99import {
10- commands , Disposable ,
10+ Disposable ,
1111 Event ,
12- EventEmitter , extensions , ThemeIcon ,
12+ EventEmitter ,
13+ ThemeIcon ,
1314 TreeDataProvider ,
1415 TreeItem ,
1516 TreeItemCollapsibleState ,
1617 TreeView ,
17- Uri , version ,
18+ Uri ,
19+ commands ,
20+ extensions ,
21+ version ,
1822 window
1923} from 'vscode' ;
2024import { CliChannel } from './cli' ;
2125import * as Helm from './helm/helm' ;
2226import { Command } from './odo/command' ;
23- import { newInstance , Odo3 } from './odo3' ;
27+ import { Odo3 , newInstance } from './odo3' ;
2428import { KubeConfigUtils } from './util/kubeUtils' ;
2529import { Platform } from './util/platform' ;
2630import { Progress } from './util/progress' ;
2731import { FileContentChangeNotifier , WatchUtil } from './util/watch' ;
2832import { vsCommand } from './vscommand' ;
2933
30- const kubeConfigFolder : string = path . join ( Platform . getUserHomePath ( ) , '.kube' ) ;
34+ /**
35+ * Returns the list of kube config files:
36+ * - If KUBECONFIG is not set, just ~/.kube/config
37+ * - If KUBECONFIG is set, follows the semantics for specifying multiple config files described here:
38+ * https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/#append-home-kube-config-to-your-kubeconfig-environment-variable
39+ * BUT: it shows an error if multiple configs are specified, since the Kubernetes client we are using doesn't support this use case.
40+ */
41+ function getKubeConfigFiles ( ) : string [ ] {
42+ if ( process . env . KUBECONFIG ) {
43+ let configuredFiles : string [ ] = [ ] ;
44+ if ( process . platform === 'win32' ) {
45+ configuredFiles = process . env . KUBECONFIG . split ( ';' ) ;
46+ } else {
47+ configuredFiles = process . env . KUBECONFIG . split ( ':' ) ;
48+ }
49+ if ( configuredFiles . length > 1 ) {
50+ void window . showWarningMessage ( 'KUBECONFIG specifies multiple files. Unfortunately, the extension doesn\'t work properly with this setup. Expect things to break.' ) ;
51+ }
52+ const filesThatExist : string [ ] = [ ] ;
53+ for ( const configFile of configuredFiles ) {
54+ if ( fs . existsSync ( configFile ) ) {
55+ filesThatExist . push ( configFile ) ;
56+ }
57+ }
58+ return filesThatExist ;
59+ }
60+ return [ path . join ( Platform . getUserHomePath ( ) , '.kube' , 'config' ) ] ;
61+ }
3162
3263type ExplorerItem = KubernetesObject | Helm . HelmRelease | Context | TreeItem ;
3364
@@ -39,7 +70,7 @@ type PackageJSON = {
3970const CREATE_OR_SET_PROJECT_ITEM = {
4071 label : 'Create new or set active Project' ,
4172 command : {
42- title : 'Create new or ser active Project' ,
73+ title : 'Create new or set active Project' ,
4374 command : 'openshift.project.set'
4475 }
4576} ;
@@ -49,7 +80,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
4980
5081 private treeView : TreeView < ExplorerItem > ;
5182
52- private fsw : FileContentChangeNotifier ;
83+ private kubeConfigWatchers : FileContentChangeNotifier [ ] ;
5384 private kubeContext : Context ;
5485 private kubeConfig : KubeConfigUtils ;
5586
@@ -69,22 +100,25 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
69100 // ignore config loading error and let odo report it on first call
70101 }
71102 try {
72- this . fsw = WatchUtil . watchFileForContextChange ( kubeConfigFolder , 'config' ) ;
103+ const kubeconfigFiles = getKubeConfigFiles ( ) ;
104+ this . kubeConfigWatchers = kubeconfigFiles . map ( kubeconfigFile => WatchUtil . watchFileForContextChange ( path . dirname ( kubeconfigFile ) , path . basename ( kubeconfigFile ) ) ) ;
73105 } catch ( err ) {
74106 void window . showWarningMessage ( 'Couldn\'t install watcher for Kubernetes configuration file. OpenShift Application Explorer view won\'t be updated automatically.' ) ;
75107 }
76- this . fsw ?. emitter ?. on ( 'file-changed' , ( ) => {
77- const ku2 = new KubeConfigUtils ( ) ;
78- const newCtx = ku2 . getContextObject ( ku2 . currentContext ) ;
79- if ( ! this . kubeContext
80- || ( this . kubeContext . cluster !== newCtx . cluster
81- || this . kubeContext . user !== newCtx . user
82- || this . kubeContext . namespace !== newCtx . namespace ) ) {
83- this . refresh ( ) ;
84- }
85- this . kubeContext = newCtx ;
86- this . kubeConfig = ku2 ;
87- } ) ;
108+ for ( const fsw of this . kubeConfigWatchers ) {
109+ fsw . emitter ?. on ( 'file-changed' , ( ) => {
110+ const ku2 = new KubeConfigUtils ( ) ;
111+ const newCtx = ku2 . getContextObject ( ku2 . currentContext ) ;
112+ if ( Boolean ( this . kubeContext ) !== Boolean ( newCtx )
113+ || ( this . kubeContext . cluster !== newCtx . cluster
114+ || this . kubeContext . user !== newCtx . user
115+ || this . kubeContext . namespace !== newCtx . namespace ) ) {
116+ this . refresh ( ) ;
117+ }
118+ this . kubeContext = newCtx ;
119+ this . kubeConfig = ku2 ;
120+ } ) ;
121+ }
88122 this . treeView = window . createTreeView < ExplorerItem > ( 'openshiftProjectExplorer' , {
89123 treeDataProvider : this ,
90124 } ) ;
@@ -256,7 +290,9 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
256290 }
257291
258292 dispose ( ) : void {
259- this . fsw ?. watcher ?. close ( ) ;
293+ for ( const fsw of this . kubeConfigWatchers ) {
294+ fsw ?. watcher ?. close ( ) ;
295+ }
260296 this . treeView . dispose ( ) ;
261297 }
262298
0 commit comments