Skip to content

Commit d5d6142

Browse files
authored
fix(ec2): instance may not have a name (#3639)
Problem Currently the toolkit is unable to load EC2 instances that are not assigned a name. It causes it to fail to load all of the instances associated with a specific region. Solution displayed as (no name) in QuickPick. displayed with instanceId in explorer. behavior above captured in test suite.
1 parent 2f46e3c commit d5d6142

File tree

4 files changed

+78
-8
lines changed

4 files changed

+78
-8
lines changed

src/ec2/explorer/ec2InstanceNode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export class Ec2InstanceNode extends AWSTreeNodeBase implements AWSResourceNode
4040
}
4141

4242
public get name(): string {
43-
return getNameOfInstance(this.instance) ?? 'Unnamed instance'
43+
return getNameOfInstance(this.instance) ?? `${this.InstanceId} (no name)`
4444
}
4545

4646
public get InstanceId(): string {

src/ec2/explorer/ec2ParentNode.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ export class Ec2ParentNode extends AWSTreeNodeBase {
3939
}
4040

4141
public async updateChildren(): Promise<void> {
42-
const ec2Instances = await (await this.ec2Client.getInstances()).toMap(instance => getNameOfInstance(instance))
43-
42+
const ec2Instances = await (
43+
await this.ec2Client.getInstances()
44+
).toMap(instance => getNameOfInstance(instance) ?? instance.InstanceId)
4445
updateInPlace(
4546
this.ec2InstanceNodes,
4647
ec2Instances.keys(),

src/shared/clients/ec2Client.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ export class Ec2Client {
4343
.flatten()
4444
.filter(instance => instance!.InstanceId !== undefined)
4545
.map(instance => {
46-
return instance!.Tags ? { ...instance, name: lookupTagKey(instance!.Tags!, 'Name') } : instance!
46+
return instanceHasName(instance!)
47+
? { ...instance, name: lookupTagKey(instance!.Tags!, 'Name') }
48+
: instance!
4749
})
4850
}
4951

@@ -109,9 +111,13 @@ export class Ec2Client {
109111
}
110112

111113
export function getNameOfInstance(instance: EC2.Instance): string | undefined {
112-
return instance.Tags ? lookupTagKey(instance.Tags, 'Name') : undefined
114+
return instanceHasName(instance) ? lookupTagKey(instance.Tags!, 'Name')! : undefined
115+
}
116+
117+
export function instanceHasName(instance: EC2.Instance): boolean {
118+
return instance.Tags !== undefined && instance.Tags.filter(tag => tag.Key === 'Name').length != 0
113119
}
114120

115121
function lookupTagKey(tags: EC2.Tag[], targetKey: string) {
116-
return tags.filter(tag => tag.Key == targetKey)[0].Value
122+
return tags.filter(tag => tag.Key === targetKey)[0].Value
117123
}

src/test/shared/clients/defaultEc2Client.test.ts

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as assert from 'assert'
77
import { AsyncCollection } from '../../../shared/utilities/asyncCollection'
88
import { toCollection } from '../../../shared/utilities/asyncCollection'
99
import { intoCollection } from '../../../shared/utilities/collectionUtils'
10-
import { Ec2Client } from '../../../shared/clients/ec2Client'
10+
import { Ec2Client, instanceHasName } from '../../../shared/clients/ec2Client'
1111
import { EC2 } from 'aws-sdk'
1212

1313
describe('extractInstancesFromReservations', function () {
@@ -93,9 +93,49 @@ describe('extractInstancesFromReservations', function () {
9393
actualResult
9494
)
9595
})
96+
97+
it('can process results without complete Tag field.', async function () {
98+
const testReservationsList: EC2.ReservationList = [
99+
{
100+
Instances: [
101+
{
102+
InstanceId: 'id1',
103+
Tags: [{ Key: 'Name', Value: 'name1' }],
104+
},
105+
{
106+
InstanceId: 'id2',
107+
},
108+
],
109+
},
110+
{
111+
Instances: [
112+
{
113+
InstanceId: 'id3',
114+
Tags: [{ Key: 'Name', Value: 'name3' }],
115+
},
116+
{
117+
InstanceId: 'id4',
118+
Tags: [],
119+
},
120+
],
121+
},
122+
]
123+
124+
const actualResult = await client.getInstancesFromReservations(intoCollection([testReservationsList])).promise()
125+
126+
assert.deepStrictEqual(
127+
[
128+
{ InstanceId: 'id1', name: 'name1', Tags: [{ Key: 'Name', Value: 'name1' }] },
129+
{ InstanceId: 'id2' },
130+
{ InstanceId: 'id3', name: 'name3', Tags: [{ Key: 'Name', Value: 'name3' }] },
131+
{ InstanceId: 'id4', Tags: [] },
132+
],
133+
actualResult
134+
)
135+
})
96136
})
97137

98-
describe('getSingleInstanceFilter', function () {
138+
describe('getInstancesFilter', function () {
99139
const client = new Ec2Client('')
100140

101141
it('returns proper filter when given instanceId', function () {
@@ -122,3 +162,26 @@ describe('getSingleInstanceFilter', function () {
122162
assert.deepStrictEqual(expectedFilters2, actualFilters2)
123163
})
124164
})
165+
166+
describe('instanceHasName', function () {
167+
it('returns whether or not there is name attached to instance', function () {
168+
const instances = [
169+
{ InstanceId: 'id1', Tags: [] },
170+
{ InstanceId: 'id2', name: 'name2', Tags: [{ Key: 'Name', Value: 'name2' }] },
171+
{ InstanceId: 'id3', Tags: [{ Key: 'NotName', Value: 'notAName' }] },
172+
{
173+
InstanceId: 'id4',
174+
name: 'name4',
175+
Tags: [
176+
{ Key: 'Name', Value: 'name4' },
177+
{ Key: 'anotherKey', Value: 'Another Key' },
178+
],
179+
},
180+
]
181+
182+
assert.deepStrictEqual(false, instanceHasName(instances[0]))
183+
assert.deepStrictEqual(true, instanceHasName(instances[1]))
184+
assert.deepStrictEqual(false, instanceHasName(instances[2]))
185+
assert.deepStrictEqual(true, instanceHasName(instances[3]))
186+
})
187+
})

0 commit comments

Comments
 (0)