@@ -31,12 +31,20 @@ import { Progress } from './util/progress';
3131import { FileContentChangeNotifier , WatchUtil } from './util/watch' ;
3232import { vsCommand } from './vscommand' ;
3333import { CustomResourceDefinitionStub } from './webview/common/createServiceTypes' ;
34+ import { HelmRepo } from './helm/helmChartType' ;
3435
35- type ExplorerItem = KubernetesObject | Helm . HelmRelease | Context | TreeItem ;
36+ type ExplorerItem = KubernetesObject | Helm . HelmRelease | Context | TreeItem | OpenShiftObject | HelmRepo ;
37+
38+ export type OpenShiftObject = {
39+ kind : string ,
40+ metadata : {
41+ name : string
42+ } ,
43+ }
3644
3745type PackageJSON = {
38- version : string ;
39- bugs : string ;
46+ version : string ;
47+ bugs : string ;
4048} ;
4149
4250const CREATE_OR_SET_PROJECT_ITEM = {
@@ -108,8 +116,8 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
108116 return element ;
109117 }
110118
111- if ( 'label' in element ) {
112- return {
119+ if ( 'label' in element ) {
120+ return {
113121 contextValue : 'openshift.openConfigFile' ,
114122 label : element . label ,
115123 collapsibleState : TreeItemCollapsibleState . None ,
@@ -122,14 +130,24 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
122130 // check if element is Context instance
123131 if ( 'name' in element && 'cluster' in element && 'user' in element ) { // Context instance could be without namespace
124132 void commands . executeCommand ( 'setContext' , 'isLoggedIn' , true ) ;
125- return {
133+ return {
126134 contextValue : 'openshift.k8sContext' ,
127135 label : this . kubeConfig . getCluster ( element . cluster ) . server ,
128136 collapsibleState : TreeItemCollapsibleState . Collapsed ,
129137 iconPath : path . resolve ( __dirname , '../../images/context/cluster-node.png' )
130138 } ;
131139 }
132140
141+ if ( 'name' in element && 'url' in element ) {
142+ return {
143+ contextValue : 'openshift.helm.repo' ,
144+ label : element . name ,
145+ tooltip : element . url ,
146+ collapsibleState : TreeItemCollapsibleState . None ,
147+ iconPath : new ThemeIcon ( 'repo' )
148+ } ;
149+ }
150+
133151 // It's a Helm installation
134152 if ( 'chart' in element ) {
135153 return {
@@ -150,6 +168,14 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
150168 collapsibleState : TreeItemCollapsibleState . Collapsed ,
151169 iconPath : path . resolve ( __dirname , '../../images/context/project-node.png' )
152170 }
171+ } else if ( element . kind === 'helm' ) {
172+ return {
173+ contextValue : 'openshift.helm.repos' ,
174+ label : element . metadata . name ,
175+ collapsibleState : TreeItemCollapsibleState . Collapsed ,
176+ description : 'Repositories' ,
177+ iconPath : path . resolve ( __dirname , '../../images/context/helm.png' )
178+ }
153179 }
154180 return {
155181 contextValue : 'openshift.k8sObject' ,
@@ -181,7 +207,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
181207 const config = getKubeConfigFiles ( ) ;
182208 const canCreateNamespace = await Oc . Instance . canCreateNamespace ( ) ;
183209 void commands . executeCommand ( 'setContext' , 'canCreateNamespace' , canCreateNamespace ) ;
184- result . unshift ( { label : process . env . KUBECONFIG ? 'Custom KubeConfig' : 'Default KubeConfig' , description : config . join ( ':' ) } )
210+ result . unshift ( { label : process . env . KUBECONFIG ? 'Custom KubeConfig' : 'Default KubeConfig' , description : config . join ( ':' ) } )
185211 }
186212 } catch ( err ) {
187213 // ignore because ether server is not accessible or user is logged out
@@ -198,6 +224,12 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
198224 // (3) there is namespace set in context and namespace exists in the cluster
199225 // (4) there is namespace set in context and namespace does not exist in the cluster
200226 const namespaces = await Odo . Instance . getProjects ( ) ;
227+ const helmContext = {
228+ kind : 'helm' ,
229+ metadata : {
230+ name : 'Helm'
231+ } ,
232+ } as OpenShiftObject
201233 if ( this . kubeContext . namespace ) {
202234 if ( namespaces . find ( item => item . name === this . kubeContext . namespace ) ) {
203235 result = [ {
@@ -226,8 +258,16 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
226258 result = [ CREATE_OR_SET_PROJECT_ITEM ]
227259 }
228260 }
261+ result . push ( helmContext ) ;
262+ } else if ( 'kind' in element && element . kind === 'helm' ) {
263+ const cliData = await Helm . getHelmRepos ( ) ;
264+ if ( ! cliData . error && ! cliData . stderr ) {
265+ const helmRepos = JSON . parse ( cliData . stdout ) as HelmRepo [ ] ;
266+ if ( helmRepos ?. length > 0 ) {
267+ result = [ ...helmRepos . sort ( Helm . ascRepoName ) ] ;
268+ }
269+ }
229270 } else {
230-
231271 let serviceKinds : CustomResourceDefinitionStub [ ] = [ ] ;
232272 try {
233273 serviceKinds = await getServiceKindStubs ( ) ;
@@ -249,6 +289,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
249289 result = await Promise . all ( toCollect ) . then ( listOfLists => listOfLists . flatMap ( a => a as ExplorerItem [ ] ) ) ;
250290
251291 }
292+
252293 // don't show Open In Developer Dashboard if not openshift cluster
253294 const isOpenshiftCluster = await Oc . Instance . isOpenShiftCluster ( ) ;
254295 void commands . executeCommand ( 'setContext' , 'isOpenshiftCluster' , isOpenshiftCluster ) ;
@@ -272,7 +313,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
272313
273314 @vsCommand ( 'openshift.resource.load' )
274315 public static loadResource ( component : KubernetesObject ) {
275- void commands . executeCommand ( 'extension.vsKubernetesLoad' , { namespace : component . metadata . namespace , kindName : `${ component . kind } /${ component . metadata . name } ` } ) ;
316+ void commands . executeCommand ( 'extension.vsKubernetesLoad' , { namespace : component . metadata . namespace , kindName : `${ component . kind } /${ component . metadata . name } ` } ) ;
276317 }
277318
278319 @vsCommand ( 'openshift.resource.unInstall' )
@@ -285,13 +326,13 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
285326
286327 @vsCommand ( 'openshift.resource.openInConsole' )
287328 public static openInConsole ( component : KubernetesObject ) {
288- void commands . executeCommand ( 'extension.vsKubernetesLoad' , { namespace : component . metadata . namespace , kindName : `${ component . kind } /${ component . metadata . name } ` } ) ;
329+ void commands . executeCommand ( 'extension.vsKubernetesLoad' , { namespace : component . metadata . namespace , kindName : `${ component . kind } /${ component . metadata . name } ` } ) ;
289330 }
290331
291332 @vsCommand ( 'openshift.explorer.reportIssue' )
292333 static async reportIssue ( ) : Promise < unknown > {
293334 const extensionPath = path . resolve ( __dirname , '..' , '..' ) ;
294- const templatePath = path . join ( extensionPath , 'resources' , 'issueReport.md' ) ;
335+ const templatePath = path . join ( extensionPath , 'resources' , 'issueReport.md' ) ;
295336 const template = fs . readFileSync ( templatePath , 'utf-8' ) ;
296337 return commands . executeCommand ( 'workbench.action.openIssueReporter' , {
297338 extensionId : 'redhat.vscode-openshift-connector' ,
@@ -301,7 +342,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
301342
302343 @vsCommand ( 'openshift.open.configFile' )
303344 async openConfigFile ( context : TreeItem ) : Promise < void > {
304- if ( context . description && typeof context . description === 'string' ) {
345+ if ( context . description && typeof context . description === 'string' ) {
305346 await commands . executeCommand ( 'vscode.open' , Uri . file ( context . description ) ) ;
306347 }
307348 }
0 commit comments