4
4
*-----------------------------------------------------------------------------------------------*/
5
5
6
6
import { KubernetesObject } from '@kubernetes/client-node' ;
7
+ import { Cluster as KcuCluster , Context as KcuContext } from '@kubernetes/client-node/dist/config_types' ;
8
+ import * as fs from 'fs/promises' ;
9
+ import * as YAML from 'js-yaml' ;
10
+ import { homedir } from 'os' ;
11
+ import * as path from 'path' ;
7
12
import { ExtensionContext , QuickInputButtons , QuickPickItem , QuickPickItemButtonEvent , ThemeIcon , Uri , commands , env , window , workspace } from 'vscode' ;
8
13
import { CommandText } from '../base/command' ;
9
14
import { CliChannel } from '../cli' ;
@@ -23,7 +28,6 @@ import { VsCommandError, vsCommand } from '../vscommand';
23
28
import { OpenShiftTerminalManager } from '../webview/openshift-terminal/openShiftTerminal' ;
24
29
import OpenShiftItem , { clusterRequired } from './openshiftItem' ;
25
30
import fetch = require( 'make-fetch-happen' ) ;
26
- import { Cluster as KcuCluster , Context as KcuContext } from '@kubernetes/client-node/dist/config_types' ;
27
31
28
32
export interface QuickPickItemExt extends QuickPickItem {
29
33
name : string ,
@@ -837,20 +841,22 @@ export class Cluster extends OpenShiftItem {
837
841
} else {
838
842
ocToken = userToken ;
839
843
}
840
- return Progress . execFunctionWithProgress ( `Login to the cluster: ${ clusterURL } ` , ( ) =>
841
- Oc . Instance . loginWithToken ( clusterURL , ocToken )
842
- . then ( ( ) => Cluster . loginMessage ( clusterURL ) )
843
- . catch ( ( error ) =>
844
- Promise . reject (
845
- new VsCommandError (
846
- `Failed to login to cluster '${ clusterURL } ' with '${ Filters . filterToken (
847
- error . message ,
848
- ) } '!`,
849
- 'Failed to login to cluster' ,
850
- ) ,
851
- ) ,
852
- ) ,
853
- ) ;
844
+ return Progress . execFunctionWithProgress ( `Login to the cluster: ${ clusterURL } ` , async ( ) => {
845
+ try {
846
+ await Oc . Instance . loginWithToken ( clusterURL , ocToken ) ;
847
+ if ( Cluster . isOpenShiftSandbox ( clusterURL ) ) {
848
+ await Cluster . installPipelineUserContext ( ) ;
849
+ }
850
+ return Cluster . loginMessage ( clusterURL ) ;
851
+ } catch ( error ) {
852
+ throw new VsCommandError (
853
+ `Failed to login to cluster '${ clusterURL } ' with '${ Filters . filterToken (
854
+ error . message ,
855
+ ) } '!`,
856
+ 'Failed to login to cluster' ,
857
+ ) ;
858
+ }
859
+ } ) ;
854
860
}
855
861
856
862
static validateLoginToken ( token : string ) : boolean {
@@ -877,6 +883,53 @@ export class Cluster extends OpenShiftItem {
877
883
return Cluster . tokenLogin ( apiEndpointUrl , true , clipboard ) ;
878
884
}
879
885
886
+ static async installPipelineUserContext ( ) : Promise < void > {
887
+ const SANDBOX_PIPELINE_USER_CTX = 'sandbox-pipeline-user' ;
888
+ const SANDBOX_PIPELINE_USERNAME = 'pipeline' ;
889
+ const kcu = new KubeConfigUtils ( ) ;
890
+ const kcPath = path . join ( homedir ( ) , '.kube' , 'config' ) ;
891
+ const kcActual = YAML . load ( ( await fs . readFile ( kcPath ) ) . toString ( 'utf-8' ) ) as {
892
+ users : { name : string , user : { token : string } } [ ] ;
893
+ contexts : object [ ] ;
894
+ 'current-context' : string ;
895
+ clusters : object [ ] ;
896
+ } ;
897
+
898
+ const secrets = await Oc . Instance . getKubernetesObjects ( 'Secret' )
899
+ const pipelineTokenSecret = secrets . find ( ( secret ) => secret . metadata . name . startsWith ( 'pipeline-token' ) ) as any ;
900
+ const pipelineToken = Buffer . from ( pipelineTokenSecret . data . token , 'base64' ) . toString ( )
901
+
902
+ if ( ! kcu . contexts . find ( ctx => ctx . name === SANDBOX_PIPELINE_USER_CTX ) ) {
903
+ const currentCtx = kcu . getCurrentContext ( ) ;
904
+ const currentCtxObj = kcu . contexts . find ( ctx => ctx . name === currentCtx ) ;
905
+
906
+ const newContextEntry = {
907
+ context : {
908
+ user : SANDBOX_PIPELINE_USERNAME ,
909
+ cluster : currentCtxObj . cluster ,
910
+ namespace : currentCtxObj . namespace
911
+ } ,
912
+ name : SANDBOX_PIPELINE_USER_CTX ,
913
+ } ;
914
+
915
+ const newUserEntry = {
916
+ user : {
917
+ token : pipelineToken
918
+ } ,
919
+ name : SANDBOX_PIPELINE_USERNAME ,
920
+ } ;
921
+
922
+ kcActual . users . push ( newUserEntry ) ;
923
+ kcActual . contexts . push ( newContextEntry ) ;
924
+ } else {
925
+ const pipelineUser = kcActual . users . find ( user => user . name === SANDBOX_PIPELINE_USERNAME ) ;
926
+ pipelineUser . user . token = pipelineToken ;
927
+ }
928
+
929
+ kcActual [ 'current-context' ] = SANDBOX_PIPELINE_USER_CTX ;
930
+ await fs . writeFile ( kcPath , YAML . dump ( kcActual ) ) ;
931
+ }
932
+
880
933
static async loginUsingClipboardInfo ( dashboardUrl : string ) : Promise < string | null > {
881
934
const clipboard = await Cluster . readFromClipboard ( ) ;
882
935
if ( ! NameValidator . ocLoginCommandMatches ( clipboard ) ) {
@@ -898,4 +951,9 @@ export class Cluster extends OpenShiftItem {
898
951
await commands . executeCommand ( 'setContext' , 'isLoggedIn' , true ) ;
899
952
return `Successfully logged in to '${ clusterURL } '` ;
900
953
}
954
+
955
+ static isOpenShiftSandbox ( url :string ) : boolean {
956
+ const asUrl = new URL ( url ) ;
957
+ return asUrl . hostname . endsWith ( 'openshiftapps.com' ) ;
958
+ }
901
959
}
0 commit comments