Skip to content

Commit 0f20b9c

Browse files
authored
Merge pull request #101 from bharathGuntamadugu/feature/smus
Add SageMaker-UI env and DER creds endpoint patch
2 parents acba5c3 + c869500 commit 0f20b9c

File tree

8 files changed

+3853
-30
lines changed

8 files changed

+3853
-30
lines changed

patched-vscode/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
"update-build-ts-version": "yarn add typescript@next && tsc -p ./build/tsconfig.build.json"
6868
},
6969
"dependencies": {
70+
"@aws-sdk/credential-providers": "^3.388.0",
7071
"@microsoft/1ds-core-js": "^3.2.13",
7172
"@microsoft/1ds-post-js": "^3.2.13",
7273
"@parcel/watcher": "2.1.0",

patched-vscode/remote/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"version": "0.0.0",
44
"private": true,
55
"dependencies": {
6+
"@aws-sdk/credential-providers": "^3.388.0",
67
"@microsoft/1ds-core-js": "^3.2.13",
78
"@microsoft/1ds-post-js": "^3.2.13",
89
"@parcel/watcher": "2.1.0",

patched-vscode/remote/yarn.lock

Lines changed: 851 additions & 0 deletions
Large diffs are not rendered by default.

patched-vscode/src/vs/server/node/webClientServer.ts

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { createReadStream } from 'fs';
6+
import { createReadStream, existsSync, writeFileSync } from 'fs';
77
import {readFile } from 'fs/promises';
88
import { Promises } from 'vs/base/node/pfs';
99
import * as path from 'path';
@@ -30,6 +30,7 @@ import { IProductConfiguration } from 'vs/base/common/product';
3030
import { isString } from 'vs/base/common/types';
3131
import { CharCode } from 'vs/base/common/charCode';
3232
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
33+
import { fromIni } from "@aws-sdk/credential-providers"
3334

3435
const textMimeType: { [ext: string]: string | undefined } = {
3536
'.html': 'text/html',
@@ -102,6 +103,8 @@ export class WebClientServer {
102103
private readonly _callbackRoute: string;
103104
private readonly _webExtensionRoute: string;
104105
private readonly _idleRoute: string;
106+
private readonly _envMetadata: string;
107+
private readonly _derCreds: string;
105108

106109
constructor(
107110
private readonly _connectionToken: ServerConnectionToken,
@@ -118,6 +121,8 @@ export class WebClientServer {
118121
this._callbackRoute = `${serverRootPath}/callback`;
119122
this._webExtensionRoute = `${serverRootPath}/web-extension-resource`;
120123
this._idleRoute = '/api/idle';
124+
this._envMetadata = '/api/env';
125+
this._derCreds = '/api/creds';
121126
}
122127

123128
/**
@@ -146,6 +151,12 @@ export class WebClientServer {
146151
// extension resource support
147152
return this._handleWebExtensionResource(req, res, parsedUrl);
148153
}
154+
if (pathname === this._envMetadata) {
155+
return this._handleEnvMetadata(req, res);
156+
}
157+
if (pathname === this._derCreds) {
158+
return this._handleDERCreds(req, res);
159+
}
149160

150161
return serveError(req, res, 404, 'Not found.');
151162
} catch (error) {
@@ -459,12 +470,20 @@ export class WebClientServer {
459470
}
460471

461472
/**
462-
* Handles API requests to retrieve the last activity timestamp.
463-
*/
473+
* Handles API requests to retrieve the last activity timestamp.
474+
*/
464475
private async _handleIdle(req: http.IncomingMessage, res: http.ServerResponse): Promise<void> {
465476
try {
466477
const tmpDirectory = '/tmp/'
467478
const idleFilePath = path.join(tmpDirectory, '.sagemaker-last-active-timestamp');
479+
480+
// If idle shutdown file does not exist, this indicates the app UI may never been opened
481+
// Create the initial metadata file
482+
if (!existsSync(idleFilePath)) {
483+
const timestamp = new Date().toISOString();
484+
writeFileSync(idleFilePath, timestamp);
485+
}
486+
468487
const data = await readFile(idleFilePath, 'utf8');
469488

470489
res.statusCode = 200;
@@ -474,6 +493,49 @@ export class WebClientServer {
474493
serveError(req, res, 500, error.message)
475494
}
476495
}
496+
497+
/**
498+
* Handles API requests to retrieve the /opt/ml/metadata/resource-metadata.json file.
499+
*/
500+
private async _handleEnvMetadata(req: http.IncomingMessage, res: http.ServerResponse): Promise<void> {
501+
try {
502+
const envMetadataDirectory = '/opt/ml/metadata/';
503+
const envMetadataFilePath = path.join(envMetadataDirectory, 'resource-metadata.json');
504+
if (existsSync(envMetadataFilePath)) {
505+
const envMetadata = await readFile(envMetadataFilePath, 'utf8');
506+
res.statusCode = 200;
507+
res.setHeader('Content-Type', 'application/json');
508+
res.end(envMetadata);
509+
} else {
510+
serveError(req, res, 500, 'No metadata file at ' + envMetadataFilePath);
511+
}
512+
} catch (error) {
513+
serveError(req, res, 500, error.message);
514+
}
515+
}
516+
517+
/**
518+
* Handles API requests to retrieve the /opt/ml/metadata/resource-metadata.json file.
519+
*/
520+
private async _handleDERCreds(req: http.IncomingMessage, res: http.ServerResponse): Promise<void> {
521+
try {
522+
const derCreds = await fromIni({
523+
profile: "DomainExecutionRoleCreds"
524+
})();
525+
const creds = {
526+
access_key: derCreds.accessKeyId,
527+
secret_key: derCreds.secretAccessKey,
528+
session_token: derCreds.sessionToken
529+
};
530+
res.statusCode = 200;
531+
res.setHeader('Content-Type', 'application/json');
532+
res.setHeader('Cache-Control', 'no-store');
533+
res.setHeader('Expires', '0');
534+
res.end(JSON.stringify(creds));
535+
} catch (error) {
536+
serveError(req, res, 500, error.message);
537+
}
538+
}
477539
}
478540

479541
/**

0 commit comments

Comments
 (0)