Skip to content

Commit 6b853ff

Browse files
authored
refactor(sdkv3): migrate ec2 to sdkv3 (#6672)
## Problem EC2 currently uses the old sdkv2, we can start the migration to v3. ## Solution - migrate existing use cases and provide small clean ups along the way. - Re-work pagination to use `AsyncCollection` abstraction. ## Testing - Manually tested Ec2Connect, Explorer (polling functionality), Command Palette, and some edge cases including instances missing a name, duplicate names, and windows instance (for remote terminal). ## Future Work - Allow quickpicks to support `AsyncIterator` of individual items, to avoid loading entire collection. Alternatively, add a `batchIterator` to `AsyncCollection` that returns an `AsyncIterator` with batches of size `k`. - built-in explorer support for pagination. - automated E2E testing for EC2? --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 7bc1d42 commit 6b853ff

23 files changed

+991
-464
lines changed

package-lock.json

Lines changed: 599 additions & 57 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@
505505
"@aws-sdk/client-sso": "<3.696.0",
506506
"@aws-sdk/client-sso-oidc": "<3.696.0",
507507
"@aws-sdk/client-ssm": "<3.696.0",
508+
"@aws-sdk/client-ec2": "<3.696.0",
508509
"@aws-sdk/credential-provider-env": "<3.696.0",
509510
"@aws-sdk/credential-provider-process": "<3.696.0",
510511
"@aws-sdk/credential-provider-sso": "<3.696.0",

packages/core/src/awsService/ec2/commands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55
import { Ec2InstanceNode } from './explorer/ec2InstanceNode'
66
import { Ec2Node } from './explorer/ec2ParentNode'
7-
import { SafeEc2Instance, Ec2Client } from '../../shared/clients/ec2Client'
7+
import { SafeEc2Instance, Ec2Client } from '../../shared/clients/ec2'
88
import { copyToClipboard } from '../../shared/utilities/messages'
99
import { ec2LogSchema } from './ec2LogDocumentProvider'
1010
import { getAwsConsoleUrl } from '../../shared/awsConsole'

packages/core/src/awsService/ec2/ec2LogDocumentProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55
import * as vscode from 'vscode'
66
import { Ec2Selection } from './prompter'
7-
import { Ec2Client } from '../../shared/clients/ec2Client'
7+
import { Ec2Client } from '../../shared/clients/ec2'
88
import { ec2LogsScheme } from '../../shared/constants'
99
import { UriSchema } from '../../shared/utilities/uriUtils'
1010

packages/core/src/awsService/ec2/explorer/ec2InstanceNode.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55
import * as vscode from 'vscode'
6-
import { Ec2Client, getNameOfInstance } from '../../../shared/clients/ec2Client'
6+
import { Ec2Client, getNameOfInstance } from '../../../shared/clients/ec2'
77
import { AWSResourceNode } from '../../../shared/treeview/nodes/awsResourceNode'
88
import { AWSTreeNodeBase } from '../../../shared/treeview/nodes/awsTreeNodeBase'
9-
import { SafeEc2Instance } from '../../../shared/clients/ec2Client'
9+
import { SafeEc2Instance } from '../../../shared/clients/ec2'
1010
import globals from '../../../shared/extensionGlobals'
1111
import { getIconCode } from '../utils'
1212
import { Ec2Selection } from '../prompter'
1313
import { Ec2Node, Ec2ParentNode } from './ec2ParentNode'
14-
import { EC2 } from 'aws-sdk'
1514
import { getLogger } from '../../../shared/logger/logger'
15+
import { InstanceStateName } from '@aws-sdk/client-ec2'
1616

1717
export const Ec2InstanceRunningContext = 'awsEc2RunningNode'
1818
export const Ec2InstanceStoppedContext = 'awsEc2StoppedNode'
@@ -68,7 +68,7 @@ export class Ec2InstanceNode extends AWSTreeNodeBase implements AWSResourceNode
6868
return Ec2InstancePendingContext
6969
}
7070

71-
public setInstanceStatus(instanceStatus: string) {
71+
public setInstanceStatus(instanceStatus: InstanceStateName) {
7272
this.instance.LastSeenStatus = instanceStatus
7373
}
7474

@@ -79,12 +79,12 @@ export class Ec2InstanceNode extends AWSTreeNodeBase implements AWSResourceNode
7979
}
8080
}
8181

82-
public getStatus(): EC2.InstanceStateName {
82+
public getStatus(): InstanceStateName {
8383
return this.instance.LastSeenStatus
8484
}
8585

8686
public get name(): string {
87-
return getNameOfInstance(this.instance) ?? `(no name)`
87+
return this.instance.Name ?? getNameOfInstance(this.instance) ?? `(no name)`
8888
}
8989

9090
public get InstanceId(): string {

packages/core/src/awsService/ec2/explorer/ec2ParentNode.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { AWSTreeNodeBase } from '../../../shared/treeview/nodes/awsTreeNodeBase'
77
import { makeChildrenNodes } from '../../../shared/treeview/utils'
88
import { PlaceholderNode } from '../../../shared/treeview/nodes/placeholderNode'
99
import { Ec2InstanceNode } from './ec2InstanceNode'
10-
import { Ec2Client } from '../../../shared/clients/ec2Client'
10+
import { Ec2Client } from '../../../shared/clients/ec2'
1111
import { updateInPlace } from '../../../shared/utilities/collectionUtils'
1212
import { PollingSet } from '../../../shared/utilities/pollingSet'
1313

@@ -30,7 +30,7 @@ export class Ec2ParentNode extends AWSTreeNodeBase {
3030
}
3131

3232
public override async getChildren(): Promise<AWSTreeNodeBase[]> {
33-
return await makeChildrenNodes({
33+
const result = await makeChildrenNodes({
3434
getChildNodes: async () => {
3535
await this.updateChildren()
3636

@@ -39,6 +39,7 @@ export class Ec2ParentNode extends AWSTreeNodeBase {
3939
getNoChildrenPlaceholderNode: async () => new PlaceholderNode(this, this.placeHolderMessage),
4040
sort: (nodeA, nodeB) => nodeA.name.localeCompare(nodeB.name),
4141
})
42+
return result
4243
}
4344

4445
public trackPendingNode(instanceId: string) {

packages/core/src/awsService/ec2/model.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55
import * as vscode from 'vscode'
6-
import { EC2, IAM } from 'aws-sdk'
6+
import { IAM } from 'aws-sdk'
77
import { Ec2Selection } from './prompter'
88
import { getOrInstallCli } from '../../shared/utilities/cliUtils'
99
import { isCloud9 } from '../../shared/extensionUtilities'
1010
import { ToolkitError } from '../../shared/errors'
1111
import { SsmClient } from '../../shared/clients/ssm'
12-
import { Ec2Client } from '../../shared/clients/ec2Client'
12+
import { Ec2Client } from '../../shared/clients/ec2'
1313
import {
1414
VscodeRemoteConnection,
1515
createBoundProcess,
@@ -83,7 +83,7 @@ export class Ec2Connecter implements vscode.Disposable {
8383
return new DefaultIamClient(this.regionCode)
8484
}
8585

86-
public async addActiveSession(sessionId: string, instanceId: EC2.InstanceId): Promise<void> {
86+
public async addActiveSession(sessionId: string, instanceId: string): Promise<void> {
8787
await this.sessionManager.addSession(instanceId, sessionId)
8888
}
8989

packages/core/src/awsService/ec2/prompter.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55

66
import { RegionSubmenu, RegionSubmenuResponse } from '../../shared/ui/common/regionSubmenu'
77
import { DataQuickPickItem } from '../../shared/ui/pickerPrompter'
8-
import { Ec2Client, SafeEc2Instance } from '../../shared/clients/ec2Client'
8+
import { Ec2Client, SafeEc2Instance } from '../../shared/clients/ec2'
99
import { isValidResponse } from '../../shared/wizards/wizard'
1010
import { CancellationError } from '../../shared/utilities/timeoutUtils'
11-
import { AsyncCollection } from '../../shared/utilities/asyncCollection'
1211
import { getIconCode } from './utils'
1312
import { Ec2Node } from './explorer/ec2ParentNode'
1413
import { Ec2InstanceNode } from './explorer/ec2InstanceNode'
14+
import { AsyncCollection } from '../../shared/utilities/asyncCollection'
1515

1616
export type instanceFilter = (instance: SafeEc2Instance) => boolean
1717
export interface Ec2Selection {
@@ -58,16 +58,19 @@ export class Ec2Prompter {
5858
return await client.getInstances()
5959
}
6060

61+
// TODO: implement a batched generator to avoid loading all instances into UI.
6162
protected async getInstancesAsQuickPickItems(region: string): Promise<DataQuickPickItem<string>[]> {
62-
return (await this.getInstancesFromRegion(region))
63+
return await (
64+
await this.getInstancesFromRegion(region)
65+
)
6366
.filter(this.filter ? (instance) => this.filter!(instance) : (instance) => true)
6467
.map((instance) => Ec2Prompter.asQuickPickItem(instance))
6568
.promise()
6669
}
6770

6871
private createEc2ConnectPrompter(): RegionSubmenu<string> {
6972
return new RegionSubmenu(
70-
async (region) => this.getInstancesAsQuickPickItems(region),
73+
async (region) => await this.getInstancesAsQuickPickItems(region),
7174
{ title: 'Select EC2 Instance', matchOnDetail: true },
7275
{ title: 'Select Region for EC2 Instance' },
7376
'Instances'

packages/core/src/awsService/ec2/remoteSessionManager.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,18 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
import { EC2 } from 'aws-sdk'
76
import { SsmClient } from '../../shared/clients/ssm'
87
import { Disposable } from 'vscode'
98

10-
export class Ec2SessionTracker extends Map<EC2.InstanceId, string> implements Disposable {
9+
export class Ec2SessionTracker extends Map<string, string> implements Disposable {
1110
public constructor(
1211
readonly regionCode: string,
1312
protected ssm: SsmClient
1413
) {
1514
super()
1615
}
1716

18-
public async addSession(instanceId: EC2.InstanceId, sessionId: string): Promise<void> {
17+
public async addSession(instanceId: string, sessionId: string): Promise<void> {
1918
if (this.isConnectedTo(instanceId)) {
2019
const existingSessionId = this.get(instanceId)!
2120
await this.ssm.terminateSessionFromId(existingSessionId)
@@ -25,7 +24,7 @@ export class Ec2SessionTracker extends Map<EC2.InstanceId, string> implements Di
2524
}
2625
}
2726

28-
private async disconnectEnv(instanceId: EC2.InstanceId): Promise<void> {
27+
private async disconnectEnv(instanceId: string): Promise<void> {
2928
await this.ssm.terminateSessionFromId(this.get(instanceId)!)
3029
this.delete(instanceId)
3130
}
@@ -35,7 +34,7 @@ export class Ec2SessionTracker extends Map<EC2.InstanceId, string> implements Di
3534
this.forEach(async (_sessionId, instanceId) => await this.disconnectEnv(instanceId))
3635
}
3736

38-
public isConnectedTo(instanceId: EC2.InstanceId): boolean {
37+
public isConnectedTo(instanceId: string): boolean {
3938
return this.has(instanceId)
4039
}
4140
}

packages/core/src/awsService/ec2/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
import { SafeEc2Instance } from '../../shared/clients/ec2Client'
6+
import { SafeEc2Instance } from '../../shared/clients/ec2'
77
import { copyToClipboard } from '../../shared/utilities/messages'
88
import { Ec2Selection } from './prompter'
99
import { sshLogFileLocation } from '../../shared/sshConfig'

0 commit comments

Comments
 (0)