44 */
55import * as vscode from 'vscode'
66import { Session } from 'aws-sdk/clients/ssm'
7- import { IAM , SSM } from 'aws-sdk'
7+ import { EC2 , IAM , SSM } from 'aws-sdk'
88import { Ec2Selection } from './prompter'
99import { getOrInstallCli } from '../../shared/utilities/cliUtils'
1010import { isCloud9 } from '../../shared/extensionUtilities'
@@ -25,20 +25,24 @@ import { createBoundProcess } from '../../codecatalyst/model'
2525import { getLogger } from '../../shared/logger/logger'
2626import { CancellationError , Timeout } from '../../shared/utilities/timeoutUtils'
2727import { showMessageWithCancel } from '../../shared/utilities/messages'
28- import { SshConfig , sshLogFileLocation } from '../../shared/sshConfig'
28+ import { SshConfig } from '../../shared/sshConfig'
2929import { SshKeyPair } from './sshKeyPair'
30+ import { Ec2SessionTracker } from './remoteSessionManager'
31+ import { getEc2SsmEnv } from './utils'
3032
3133export type Ec2ConnectErrorCode = 'EC2SSMStatus' | 'EC2SSMPermission' | 'EC2SSMConnect' | 'EC2SSMAgentStatus'
3234
33- interface Ec2RemoteEnv extends VscodeRemoteConnection {
35+ export interface Ec2RemoteEnv extends VscodeRemoteConnection {
3436 selection : Ec2Selection
3537 keyPair : SshKeyPair
38+ ssmSession : SSM . StartSessionResponse
3639}
3740
38- export class Ec2ConnectionManager {
41+ export class Ec2Connecter implements vscode . Disposable {
3942 protected ssmClient : SsmClient
4043 protected ec2Client : Ec2Client
4144 protected iamClient : DefaultIamClient
45+ protected sessionManager : Ec2SessionTracker
4246
4347 private policyDocumentationUri = vscode . Uri . parse (
4448 'https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started-instance-profile.html'
@@ -52,6 +56,7 @@ export class Ec2ConnectionManager {
5256 this . ssmClient = this . createSsmSdkClient ( )
5357 this . ec2Client = this . createEc2SdkClient ( )
5458 this . iamClient = this . createIamSdkClient ( )
59+ this . sessionManager = new Ec2SessionTracker ( regionCode , this . ssmClient )
5560 }
5661
5762 protected createSsmSdkClient ( ) : SsmClient {
@@ -66,6 +71,18 @@ export class Ec2ConnectionManager {
6671 return new DefaultIamClient ( this . regionCode )
6772 }
6873
74+ public async addActiveSession ( sessionId : SSM . SessionId , instanceId : EC2 . InstanceId ) : Promise < void > {
75+ await this . sessionManager . addSession ( instanceId , sessionId )
76+ }
77+
78+ public async dispose ( ) : Promise < void > {
79+ await this . sessionManager . dispose ( )
80+ }
81+
82+ public isConnectedTo ( instanceId : string ) : boolean {
83+ return this . sessionManager . isConnectedTo ( instanceId )
84+ }
85+
6986 public async getAttachedIamRole ( instanceId : string ) : Promise < IAM . Role | undefined > {
7087 const IamInstanceProfile = await this . ec2Client . getAttachedIamInstanceProfile ( instanceId )
7188 if ( IamInstanceProfile && IamInstanceProfile . Arn ) {
@@ -183,6 +200,7 @@ export class Ec2ConnectionManager {
183200 this . throwGeneralConnectionError ( selection , err as Error )
184201 }
185202 }
203+
186204 public async prepareEc2RemoteEnvWithProgress ( selection : Ec2Selection , remoteUser : string ) : Promise < Ec2RemoteEnv > {
187205 const timeout = new Timeout ( 60000 )
188206 await showMessageWithCancel ( 'AWS: Opening remote connection...' , timeout )
@@ -204,8 +222,10 @@ export class Ec2ConnectionManager {
204222
205223 throw err
206224 }
207- const session = await this . ssmClient . startSession ( selection . instanceId , 'AWS-StartSSHSession' )
208- const vars = getEc2SsmEnv ( selection , ssm , session )
225+ const ssmSession = await this . ssmClient . startSession ( selection . instanceId , 'AWS-StartSSHSession' )
226+ await this . addActiveSession ( selection . instanceId , ssmSession . SessionId ! )
227+
228+ const vars = getEc2SsmEnv ( selection , ssm , ssmSession )
209229 const envProvider = async ( ) => {
210230 return { [ sshAgentSocketVariable ] : await startSshAgent ( ) , ...vars }
211231 }
@@ -223,6 +243,7 @@ export class Ec2ConnectionManager {
223243 SessionProcess,
224244 selection,
225245 keyPair,
246+ ssmSession,
226247 }
227248 }
228249
@@ -267,17 +288,3 @@ export class Ec2ConnectionManager {
267288 throw new ToolkitError ( `Unrecognized OS name ${ osName } on instance ${ instanceId } ` , { code : 'UnknownEc2OS' } )
268289 }
269290}
270-
271- function getEc2SsmEnv ( selection : Ec2Selection , ssmPath : string , session : SSM . StartSessionResponse ) : NodeJS . ProcessEnv {
272- return Object . assign (
273- {
274- AWS_REGION : selection . region ,
275- AWS_SSM_CLI : ssmPath ,
276- LOG_FILE_LOCATION : sshLogFileLocation ( 'ec2' , selection . instanceId ) ,
277- STREAM_URL : session . StreamUrl ,
278- SESSION_ID : session . SessionId ,
279- TOKEN : session . TokenValue ,
280- } ,
281- process . env
282- )
283- }
0 commit comments