@moonset/util
Version:
107 lines • 14.2 kB
JavaScript
;
// A factory pattern to fetch SDK module for different accounts e.g. working
// accont and references account.
//
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/index.html
Object.defineProperty(exports, "__esModule", { value: true });
exports.SDKProvider = exports.SDK = void 0;
const AWS = require("aws-sdk");
const credential_plugins_1 = require("aws-cdk/lib/api/aws-auth/credential-plugins");
const aws_cdk_1 = require("aws-cdk");
const log_1 = require("./log");
const config_1 = require("./config");
class SDK {
constructor(credentials, region) {
this.credentials = credentials;
/**
* Default retry options for SDK clients.
*/
this.retryOptions = {
maxRetries: 6,
retryDelayOptions: { base: 300 },
};
this.config = {
...this.retryOptions,
credentials,
region,
};
this.currentRegion = region;
}
s3() {
return new AWS.S3(this.config);
}
ec2() {
return new AWS.EC2(this.config);
}
emr() {
return new AWS.EMR(this.config);
}
iam() {
return new AWS.IAM(this.config);
}
stepfunctions() {
return new AWS.StepFunctions(this.config);
}
cfn() {
return new AWS.CloudFormation(this.config);
}
sts() {
return new AWS.STS(this.config);
}
tagApi() {
return new AWS.ResourceGroupsTaggingAPI(this.config);
}
async currentAccount() {
log_1.logger.info('Looking up default account ID from STS');
const result = await new AWS.STS(this.config)
.getCallerIdentity().promise();
const accountId = result.Account;
const partition = result.Arn.split(':')[1];
if (!accountId) {
throw new Error('STS didn\'t return an account ID');
}
log_1.logger.info('Default account ID:', accountId);
return { accountId, partition };
}
// It might be a user or a role.
async getSession() {
const sts = this.sts();
const currentUser = await sts.getCallerIdentity().promise();
const session = currentUser.Arn
.split('/')
.slice(-1)[0]
.replace(/[^A-Za-z0-9-]/g, '-');
log_1.logger.info(`Current user is ${JSON.stringify(currentUser)},` +
` the extract session id is ${session}.`);
return session;
}
}
exports.SDK = SDK;
class SDKProvider {
static async forWorkingAccount() {
if (!process.env[config_1.ConfigConstant.WORKING_ACCOUNT]) {
throw new Error('The working account is not specified.');
}
let credentials;
const region = process.env[config_1.ConfigConstant.WORKING_REGION];
if (config_1.Config.get(config_1.ConfigConstant.WORKING_ACCESS_KEY) &&
config_1.Config.get(config_1.ConfigConstant.WORKING_SECRET_KEY)) {
// Check config first.
log_1.logger.info(`Fetch Working account credentials from ${config_1.CONFIG_PATH}`);
credentials = new AWS.Credentials(config_1.Config.get(config_1.ConfigConstant.WORKING_ACCESS_KEY), config_1.Config.get(config_1.ConfigConstant.WORKING_SECRET_KEY));
}
else {
// Load from CDK Credentials plugins.
credentials = await new credential_plugins_1.CredentialPlugins().fetchCredentialsFor(process.env[config_1.ConfigConstant.WORKING_ACCOUNT], aws_cdk_1.Mode.ForWriting);
}
if (!credentials) {
throw new Error(`No credentials for account ${config_1.ConfigConstant.WORKING_ACCOUNT}`);
}
if (!region) {
throw new Error(`The working account region is not specified.`);
}
return new SDK(credentials, region);
}
}
exports.SDKProvider = SDKProvider;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2RrLXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic2RrLXV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw0RUFBNEU7QUFDNUUsaUNBQWlDO0FBQ2pDLEVBQUU7QUFDRixpRUFBaUU7OztBQUVqRSwrQkFBK0I7QUFHL0Isb0ZBQThFO0FBQzlFLHFDQUE2QjtBQUM3QiwrQkFBNkI7QUFDN0IscUNBQW1FO0FBbUJuRSxNQUFhLEdBQUc7SUFhWixZQUE2QixXQUE0QixFQUFFLE1BQWM7UUFBNUMsZ0JBQVcsR0FBWCxXQUFXLENBQWlCO1FBUnpEOztXQUVHO1FBQ2MsaUJBQVksR0FBRztZQUM5QixVQUFVLEVBQUUsQ0FBQztZQUNiLGlCQUFpQixFQUFFLEVBQUMsSUFBSSxFQUFFLEdBQUcsRUFBQztTQUMvQixDQUFDO1FBR0EsSUFBSSxDQUFDLE1BQU0sR0FBRztZQUNaLEdBQUcsSUFBSSxDQUFDLFlBQVk7WUFDcEIsV0FBVztZQUNYLE1BQU07U0FDUCxDQUFDO1FBQ0YsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUM7SUFDOUIsQ0FBQztJQUVNLEVBQUU7UUFDUCxPQUFPLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVNLEdBQUc7UUFDUixPQUFPLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVNLEdBQUc7UUFDUixPQUFPLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVNLEdBQUc7UUFDUixPQUFPLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVNLGFBQWE7UUFDbEIsT0FBTyxJQUFJLEdBQUcsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE1B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SSxzQ0FBaUIsRUFBRSxDQUFDLG1CQUFtQixDQUN6RCxPQUFPLENBQUMsR0FBRyxDQUFDLHVCQUFFLENBQUMsZUFBZSxDQUFFLEVBQ2hDLGNBQUksQ0FBQyxVQUFVLENBQ3BCLENBQUM7U0FDSDtRQUNELElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsdUJBQUUsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDO1NBQ3JFO1FBQ0QsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNYLE1BQU0sSUFBSSxLQUFLLENBQUMsOENBQThDLENBQUMsQ0FBQztTQUNqRTtRQUNELE9BQU8sSUFBSSxHQUFHLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3RDLENBQUM7Q0FDRjtBQS9CRCxrQ0ErQkMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBIGZhY3RvcnkgcGF0dGVybiB0byBmZXRjaCBTREsgbW9kdWxlIGZvciBkaWZmZXJlbnQgYWNjb3VudHMgZS5nLiB3b3JraW5nXG4vLyBhY2NvbnQgYW5kIHJlZmVyZW5jZXMgYWNjb3VudC5cbi8vXG4vLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTSmF2YVNjcmlwdFNESy9sYXRlc3QvaW5kZXguaHRtbFxuXG5pbXBvcnQgKiBhcyBBV1MgZnJvbSAnYXdzLXNkayc7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbmltcG9ydCB7Q29uZmlndXJhdGlvbk9wdGlvbnN9IGZyb20gJ2F3cy1zZGsvbGliL2NvbmZpZyc7XG5pbXBvcnQge0NyZWRlbnRpYWxQbHVnaW5zfSBmcm9tICdhd3MtY2RrL2xpYi9hcGkvYXdzLWF1dGgvY3JlZGVudGlhbC1wbHVnaW5zJztcbmltcG9ydCB7TW9kZX0gZnJvbSAnYXdzLWNkayc7XG5pbXBvcnQge2xvZ2dlcn0gZnJvbSAnLi9sb2cnO1xuaW1wb3J0IHtDb25maWcsIENvbmZpZ0NvbnN0YW50IGFzIENDLCBDT05GSUdfUEFUSH0gZnJvbSAnLi9jb25maWcnO1xuXG5leHBvcnQgaW50ZXJmYWNlIElTREsge1xuXG4gICAgcmVhZG9ubHkgY3VycmVudFJlZ2lvbjogc3RyaW5nO1xuXG4gICAgY3VycmVudEFjY291bnQoKTogUHJvbWlzZTxBY2NvdW50PjtcbiAgICBnZXRTZXNzaW9uKCk6IFByb21pc2U8c3RyaW5nPjtcblxuICAgIHMzKCk6IEFXUy5TMztcbiAgICBlYzIoKTogQVdTLkVDMjtcbiAgICBlbXIoKTogQVdTLkVNUjtcbiAgICBpYW0oKTogQVdTLklBTTtcbiAgICBzdGVwZnVuY3Rpb25zKCk6IEFXUy5TdGVwRnVuY3Rpb25zO1xuICAgIHN0cygpOiBBV1MuU1RTO1xuICAgIGNmbigpOiBBV1MuQ2xvdWRGb3JtYXRpb247XG4gICAgdGFnQXBpKCk6IEFXUy5SZXNvdXJjZUdyb3Vwc1RhZ2dpbmdBUEk7XG59XG5cbmV4cG9ydCBjbGFzcyBTREsgaW1wbGVtZW50cyBJU0RLIHtcbiAgICBwdWJsaWMgcmVhZG9ubHkgY3VycmVudFJlZ2lvbjogc3RyaW5nO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25maWc6IENvbmZpZ3VyYXRpb25PcHRpb25zO1xuXG4gICAgLyoqXG4gICAgICogRGVmYXVsdCByZXRyeSBvcHRpb25zIGZvciBTREsgY2xpZW50cy5cbiAgICAgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IHJldHJ5T3B0aW9ucyA9IHtcbiAgICAgIG1heFJldHJpZXM6IDYsXG4gICAgICByZXRyeURlbGF5T3B0aW9uczoge2Jhc2U6IDMwMH0sXG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgY3JlZGVudGlhbHM6IEFXUy5DcmVkZW50aWFscywgcmVnaW9uOiBzdHJpbmcpIHtcbiAgICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgICAuLi50aGlzLnJldHJ5T3B0aW9ucyxcbiAgICAgICAgY3JlZGVudGlhbHMsXG4gICAgICAgIHJlZ2lvbixcbiAgICAgIH07XG4gICAgICB0aGlzLmN1cnJlbnRSZWdpb24gPSByZWdpb247XG4gICAgfVxuXG4gICAgcHVibGljIHMzKCk6IEFXUy5TMyB7XG4gICAgICByZXR1cm4gbmV3IEFXUy5TMyh0aGlzLmNvbmZpZyk7XG4gICAgfVxuXG4gICAgcHVibGljIGVjMigpOiBBV1MuRUMyIHtcbiAgICAgIHJldHVybiBuZXcgQVdTLkVDMih0aGlzLmNvbmZpZyk7XG4gICAgfVxuXG4gICAgcHVibGljIGVtcigpOiBBV1MuRU1SIHtcbiAgICAgIHJldHVybiBuZXcgQVdTLkVNUih0aGlzLmNvbmZpZyk7XG4gICAgfVxuXG4gICAgcHVibGljIGlhbSgpOiBBV1MuSUFNIHtcbiAgICAgIHJldHVybiBuZXcgQVdTLklBTSh0aGlzLmNvbmZpZyk7XG4gICAgfVxuXG4gICAgcHVibGljIHN0ZXBmdW5jdGlvbnMoKTogQVdTLlN0ZXBGdW5jdGlvbnMge1xuICAgICAgcmV0dXJuIG5ldyBBV1MuU3RlcEZ1bmN0aW9ucyh0aGlzLmNvbmZpZyk7XG4gICAgfVxuXG4gICAgcHVibGljIGNmbigpOiBBV1MuQ2xvdWRGb3JtYXRpb24ge1xuICAgICAgcmV0dXJuIG5ldyBBV1MuQ2xvdWRGb3JtYXRpb24odGhpcy5jb25maWcpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdHMoKTogQVdTLlNUUyB7XG4gICAgICByZXR1cm4gbmV3IEFXUy5TVFModGhpcy5jb25maWcpO1xuICAgIH1cblxuICAgIHB1YmxpYyB0YWdBcGkoKTogQVdTLlJlc291cmNlR3JvdXBzVGFnZ2luZ0FQSSB7XG4gICAgICByZXR1cm4gbmV3IEFXUy5SZXNvdXJjZUdyb3Vwc1RhZ2dpbmdBUEkodGhpcy5jb25maWcpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBjdXJyZW50QWNjb3VudCgpOiBQcm9taXNlPEFjY291bnQ+IHtcbiAgICAgIGxvZ2dlci5pbmZvKCdMb29raW5nIHVwIGRlZmF1bHQgYWNjb3VudCBJRCBmcm9tIFNUUycpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbmV3IEFXUy5TVFModGhpcy5jb25maWcpXG4gICAgICAgICAgLmdldENhbGxlcklkZW50aXR5KCkucHJvbWlzZSgpO1xuICAgICAgY29uc3QgYWNjb3VudElkID0gcmVzdWx0LkFjY291bnQ7XG4gICAgICBjb25zdCBwYXJ0aXRpb24gPSByZXN1bHQuQXJuIS5zcGxpdCgnOicpWzFdO1xuICAgICAgaWYgKCFhY2NvdW50SWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTVFMgZGlkblxcJ3QgcmV0dXJuIGFuIGFjY291bnQgSUQnKTtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5pbmZvKCdEZWZhdWx0IGFjY291bnQgSUQ6JywgYWNjb3VudElkKTtcbiAgICAgIHJldHVybiB7YWNjb3VudElkLCBwYXJ0aXRpb259O1xuICAgIH1cblxuXG4gICAgLy8gSXQgbWlnaHQgYmUgYSB1c2VyIG9yIGEgcm9sZS5cbiAgICBwdWJsaWMgYXN5bmMgZ2V0U2Vzc2lvbigpIHtcbiAgICAgIGNvbnN0IHN0cyA9IHRoaXMuc3RzKCk7XG4gICAgICBjb25zdCBjdXJyZW50VXNlciA9IGF3YWl0IHN0cy5nZXRDYWxsZXJJZGVudGl0eSgpLnByb21pc2UoKTtcbiAgICAgIGNvbnN0IHNlc3Npb24gPSBjdXJyZW50VXNlci5Bcm4hXG4gICAgICAgICAgLnNwbGl0KCcvJylcbiAgICAgICAgICAuc2xpY2UoLTEpWzBdXG4gICAgICAgICAgLnJlcGxhY2UoL1teQS1aYS16MC05LV0vZywgJy0nKTtcbiAgICAgIGxvZ2dlci5pbmZvKGBDdXJyZW50IHVzZXIgaXMgJHtKU09OLnN0cmluZ2lmeShjdXJyZW50VXNlcil9LGAgK1xuICAgICAgICBgIHRoZSBleHRyYWN0IHNlc3Npb24gaWQgaXMgJHtzZXNzaW9ufS5gKTtcbiAgICAgIHJldHVybiBzZXNzaW9uO1xuICAgIH1cbn1cblxuXG5leHBvcnQgY2xhc3MgU0RLUHJvdmlkZXIge1xuICBwdWJsaWMgc3RhdGljIGFzeW5jIGZvcldvcmtpbmdBY2NvdW50KCk6IFByb21pc2U8SVNESz4ge1xuICAgIGlmICghcHJvY2Vzcy5lbnZbQ0MuV09SS0lOR19BQ0NPVU5UXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgd29ya2luZyBhY2NvdW50IGlzIG5vdCBzcGVjaWZpZWQuJyk7XG4gICAgfVxuICAgIGxldCBjcmVkZW50aWFsczogQVdTLkNyZWRlbnRpYWxzIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IHJlZ2lvbiA9IHByb2Nlc3MuZW52W0NDLldPUktJTkdfUkVHSU9OXTtcblxuICAgIGlmIChDb25maWcuZ2V0KENDLldPUktJTkdfQUNDRVNTX0tFWSkgJiZcbiAgICAgICAgQ29uZmlnLmdldChDQy5XT1JLSU5HX1NFQ1JFVF9LRVkpKSB7XG4gICAgICAvLyBDaGVjayBjb25maWcgZmlyc3QuXG4gICAgICBsb2dnZXIuaW5mbyhgRmV0Y2ggV29ya2luZyBhY2NvdW50IGNyZWRlbnRpYWxzIGZyb20gJHtDT05GSUdfUEFUSH1gKTtcbiAgICAgIGNyZWRlbnRpYWxzID0gbmV3IEFXUy5DcmVkZW50aWFscyhcbiAgICAgICAgICBDb25maWcuZ2V0KENDLldPUktJTkdfQUNDRVNTX0tFWSkhLFxuICAgICAgICAgIENvbmZpZy5nZXQoQ0MuV09SS0lOR19TRUNSRVRfS0VZKSEsXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBMb2FkIGZyb20gQ0RLIENyZWRlbnRpYWxzIHBsdWdpbnMuXG4gICAgICBjcmVkZW50aWFscyA9IGF3YWl0IG5ldyBDcmVkZW50aWFsUGx1Z2lucygpLmZldGNoQ3JlZGVudGlhbHNGb3IoXG4gICAgICAgICAgICBwcm9jZXNzLmVudltDQy5XT1JLSU5HX0FDQ09VTlRdISxcbiAgICAgICAgICAgIE1vZGUuRm9yV3JpdGluZyxcbiAgICAgICk7XG4gICAgfVxuICAgIGlmICghY3JlZGVudGlhbHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gY3JlZGVudGlhbHMgZm9yIGFjY291bnQgJHtDQy5XT1JLSU5HX0FDQ09VTlR9YCk7XG4gICAgfVxuICAgIGlmICghcmVnaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSB3b3JraW5nIGFjY291bnQgcmVnaW9uIGlzIG5vdCBzcGVjaWZpZWQuYCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgU0RLKGNyZWRlbnRpYWxzLCByZWdpb24pO1xuICB9XG59XG5cbi8qKlxuICogQW4gQVdTIGFjY291bnRcbiAqXG4gKiBBbiBBV1MgYWNjb3VudCBhbHdheXMgZXhpc3RzIGluIG9ubHkgb25lIHBhcnRpdGlvbi4gVXN1YWxseSB3ZSBkb24ndCBjYXJlXG4gKiBhYm91dCB0aGUgcGFydGl0aW9uLCBidXQgd2hlbiB3ZSBuZWVkIHRvIGZvcm0gQVJOcyB3ZSBkby5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBY2NvdW50IHtcbiAgICAvKipcbiAgICAgKiBUaGUgYWNjb3VudCBudW1iZXJcbiAgICAgKi9cbiAgICByZWFkb25seSBhY2NvdW50SWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBwYXJ0aXRpb24gKCdhd3MnIG9yICdhd3MtY24nIG9yIG90aGVyd2lzZSlcbiAgICAgKi9cbiAgICByZWFkb25seSBwYXJ0aXRpb246IHN0cmluZztcbn1cblxuIl19