Skip to content

Commit

Permalink
Update AWS cloud detector to check multiple uuid paths.
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeelmers committed Mar 31, 2021
1 parent a0aa72a commit 8adf9eb
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import { AWS, AWSCloudService, AWSResponse } from './aws';
type Callback = (err: unknown, res: unknown) => void;

describe('AWS', () => {
const expectedFilename = '/sys/hypervisor/uuid';
const expectedFilenames = ['/sys/hypervisor/uuid', '/sys/devices/virtual/dmi/id/product_uuid'];
const expectedEncoding = 'utf8';
// mixed case to ensure we check for ec2 after lowercasing
const ec2Uuid = 'eC2abcdef-ghijk\n';
const ec2FileSystem = {
readFile: (filename: string, encoding: string, callback: Callback) => {
expect(filename).toEqual(expectedFilename);
expect(expectedFilenames).toContain(filename);
expect(encoding).toEqual(expectedEncoding);

callback(null, ec2Uuid);
Expand Down Expand Up @@ -177,29 +177,64 @@ describe('AWS', () => {
});

describe('_tryToDetectUuid', () => {
it('checks the file system for UUID if not Windows', async () => {
const awsCheckedFileSystem = new AWSCloudService({
_fs: ec2FileSystem,
_isWindows: false,
describe('checks the file system for UUID if not Windows', () => {
it('checks /sys/hypervisor/uuid', async () => {
const awsCheckedFileSystem = new AWSCloudService({
_fs: {
readFile: (filename: string, encoding: string, callback: Callback) => {
expect(expectedFilenames).toContain(filename);
expect(encoding).toEqual(expectedEncoding);

callback(null, ec2Uuid);
},
} as typeof fs,
_isWindows: false,
});

const response = await awsCheckedFileSystem._tryToDetectUuid();

expect(response.isConfirmed()).toEqual(true);
expect(response.toJSON()).toEqual({
name: AWS.getName(),
id: ec2Uuid.trim().toLowerCase(),
region: undefined,
zone: undefined,
vm_type: undefined,
metadata: undefined,
});
});

const response = await awsCheckedFileSystem._tryToDetectUuid();

expect(response.isConfirmed()).toEqual(true);
expect(response.toJSON()).toEqual({
name: AWS.getName(),
id: ec2Uuid.trim().toLowerCase(),
region: undefined,
zone: undefined,
vm_type: undefined,
metadata: undefined,
it('checks /sys/devices/virtual/dmi/id/product_uuid', async () => {
const awsCheckedFileSystem = new AWSCloudService({
_fs: {
readFile: (filename: string, encoding: string, callback: Callback) => {
expect(expectedFilenames).toContain(filename);
expect(encoding).toEqual(expectedEncoding);

callback(null, ec2Uuid);
},
} as typeof fs,
_isWindows: false,
});

const response = await awsCheckedFileSystem._tryToDetectUuid();

expect(response.isConfirmed()).toEqual(true);
expect(response.toJSON()).toEqual({
name: AWS.getName(),
id: ec2Uuid.trim().toLowerCase(),
region: undefined,
zone: undefined,
vm_type: undefined,
metadata: undefined,
});
});
});

it('ignores UUID if it does not start with ec2', async () => {
const notEC2FileSystem = {
readFile: (filename: string, encoding: string, callback: Callback) => {
expect(filename).toEqual(expectedFilename);
expect(expectedFilenames).toContain(filename);
expect(encoding).toEqual(expectedEncoding);

callback(null, 'notEC2');
Expand Down Expand Up @@ -240,7 +275,7 @@ describe('AWS', () => {

expect(async () => {
await awsFailedFileSystem._tryToDetectUuid();
}).rejects.toThrowError(fileDNE);
}).rejects.toThrow(fileDNE);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,20 @@ export class AWSCloudService extends CloudService {
_tryToDetectUuid() {
// Windows does not have an easy way to check
if (!this._isWindows) {
return promisify(this._fs.readFile)('/sys/hypervisor/uuid', 'utf8').then((uuid) => {
if (isString(uuid)) {
// Some AWS APIs return it lowercase (like the file did in testing), while others return it uppercase
uuid = uuid.trim().toLowerCase();

if (uuid.startsWith('ec2')) {
return new CloudServiceResponse(this._name, true, { id: uuid });
const pathsToCheck = ['/sys/hypervisor/uuid', '/sys/devices/virtual/dmi/id/product_uuid'];
const promises = pathsToCheck.map((path) => promisify(this._fs.readFile)(path, 'utf8'));

return Promise.all(promises).then((uuids) => {
for (let uuid of uuids) {
if (isString(uuid)) {
// Some AWS APIs return it lowercase (like the file did in testing), while others return it uppercase
uuid = uuid.trim().toLowerCase();

// There is a small chance of a false positive here in the unlikely event that a uuid which doesn't
// belong to ec2 happens to be generated with `ec2` as the first three characters.
if (uuid.startsWith('ec2')) {
return new CloudServiceResponse(this._name, true, { id: uuid });
}
}
}

Expand Down

0 comments on commit 8adf9eb

Please sign in to comment.