Skip to content

Commit

Permalink
feat(source-aws): add support for easily assuming roles
Browse files Browse the repository at this point in the history
  • Loading branch information
blacha committed Sep 15, 2021
1 parent 8a42472 commit 11d7a1c
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions packages/source-aws/src/s3.fs.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,64 @@
import { FileInfo, FileSystem, isRecord } from '@chunkd/core';
import S3 from 'aws-sdk/clients/s3.js';
import { Credentials } from 'aws-sdk/lib/credentials.js';
import { ChainableTemporaryCredentials } from 'aws-sdk/lib/credentials/chainable_temporary_credentials.js';
import { EC2MetadataCredentials } from 'aws-sdk/lib/credentials/ec2_metadata_credentials.js';
import { SharedIniFileCredentials } from 'aws-sdk/lib/credentials/shared_ini_file_credentials.js';
import type { Readable } from 'stream';
import { getCompositeError, SourceAwsS3 } from './s3.source.js';
import { ListRes, S3Like } from './type.js';

const Ec2 = Symbol();
const x: typeof Ec2 = Ec2;
console.log(x);

export class FsAwsS3 implements FileSystem<SourceAwsS3> {
static protocol = 's3';
protocol = FsAwsS3.protocol;
/** Max list requests to run before erroring */
static MaxListCount = 100;

static Ec2Credentials = Ec2;

static credentials: Map<string, Credentials> = new Map();
/**
* Create a aws credential instance from a role arn
*
* if the AWS profile is "FsAwsS3.Ec2Credentials" use EC2MetadataCredentials, otherwise load credentials from the shared ini file
*/
static getCredentials(roleArn: string, profile?: string | typeof Ec2, externalId?: string): Credentials {
const credKey = `${roleArn}::${roleArn}::${externalId}`;
let credentials = FsAwsS3.credentials.get(credKey);
if (credentials == null) {
const masterCredentials =
profile === Ec2 ? new EC2MetadataCredentials() : new SharedIniFileCredentials({ profile });
credentials = new ChainableTemporaryCredentials({
params: {
RoleArn: roleArn,
ExternalId: externalId,
RoleSessionName: 'fsa-' + Math.random().toString(32) + '-' + Date.now(),
},
masterCredentials,
});
FsAwsS3.credentials.set(credKey, credentials);
}
return credentials;
}

/**
* Create a FsS3 instance from a role arn
*
* if the AWS profile is "ec2" use EC2MetadataCredentials, otherwise load credentials from the shared ini file
*
* @example
* Fs3.fromRoleArn('arn:foo', 'ec2');
* FsS3.fromRoleArn('arn:bar', process.env.AWS_PROFILE);
*/
static fromRoleArn(roleArn: string, profile?: string | typeof Ec2, externalId?: string): FsAwsS3 {
const credentials = FsAwsS3.getCredentials(roleArn, profile, externalId);
return new FsAwsS3(new S3({ credentials }));
}

/** AWS-SDK s3 to use */
s3: S3Like;

Expand Down

0 comments on commit 11d7a1c

Please sign in to comment.