UNPKG

deep-package-manager

Version:
362 lines (285 loc) 9.03 kB
/** * Created by AlexanderC on 8/26/15. */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.SharedAwsConfig = undefined; var _awsSdk = require('aws-sdk'); var _awsSdk2 = _interopRequireDefault(_awsSdk); var _Exec = require('./Exec'); var _Env = require('./Env'); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _util = require('util'); var _Prompt = require('./Terminal/Prompt'); var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class SharedAwsConfig { constructor() { this._providers = SharedAwsConfig.DEFAULT_PROVIDERS; this._credentials = null; } /** * @returns {Object[]} */ get providers() { return this._providers; } /** * @param {Object} provider * @returns {SharedAwsConfig} */ addProvider(provider) { this._providers.push(provider); return this; } /** * @returns {*[]} */ static get ACCOUNT_ID_FROM_USER_ARN_EXTRACTOR_REGEX() { return [/^.*:(\d+):(root|(user\/.*))$/i, '$1']; } /** * @param {Object} config * @param {Function} cb */ refillPropertyConfigIfNeeded(config, cb) { if (!config.aws.accessKeyId || !config.aws.secretAccessKey || config.aws.accessKeyId === SharedAwsConfig.DEFAULT_ACCESS_KEY || config.aws.secretAccessKey === SharedAwsConfig.DEFAULT_SECRET_ACCESS_KEY) { console.warn('You should set real AWS keys in order to use it in production'); config.aws = this.choose(); this.guessAccountId(config.aws, (error, accountId) => { config.awsAccountId = accountId || config.awsAccountId; cb(true); }); } else { cb(false); } } /** * @param {Object} awsCredentials * @param {Function} cb */ guessAccountId(awsCredentials, cb) { try { let iam = new _awsSdk2.default.IAM(awsCredentials); iam.getUser({}, (error, data) => { if (error) { cb(error, null); return; } if (!data.User || !data.User.Arn) { cb(null, null); return; } cb(null, data.User.Arn.replace(...SharedAwsConfig.ACCOUNT_ID_FROM_USER_ARN_EXTRACTOR_REGEX)); }); } catch (error) { cb(error, null); } } /** * @param {Boolean} requestOnMissing * @returns {Object} */ choose(requestOnMissing = true) { let chosenCredentials = null; let guessedCredentials = this.guess(); let credentials = (0, _util._extend)({ 'default': this.guess() }, this._parseAwsCredentialsFile([guessedCredentials.accessKeyId])); let awsProfiles = Object.keys(credentials); if (awsProfiles.length === 1) { return requestOnMissing ? this.askForCredentialsIfMissing(guessedCredentials) : guessedCredentials; } let prompt = new _Prompt.Prompt('Choose the AWS profile to be used'); prompt.syncMode = true; // it is sync! prompt.readChoice(awsProfile => { chosenCredentials = credentials[awsProfile]; }, awsProfiles.sort()); return requestOnMissing ? this.askForCredentialsIfMissing(chosenCredentials) : chosenCredentials; } /** * @param {Object} credentials * @returns {Object} */ askForCredentialsIfMissing(credentials) { if (!credentials.accessKeyId) { let prompt = new _Prompt.Prompt('AWS access key'); prompt.syncMode = true; prompt.read(answer => { credentials.accessKeyId = answer || SharedAwsConfig.DEFAULT_ACCESS_KEY; }); } if (!credentials.secretAccessKey) { let prompt = new _Prompt.Prompt('AWS secret access key'); prompt.syncMode = true; prompt.readHidden(answer => { credentials.secretAccessKey = answer || SharedAwsConfig.DEFAULT_SECRET_ACCESS_KEY; }); } if (!credentials.region) { let prompt = new _Prompt.Prompt('AWS region'); prompt.syncMode = true; prompt.readWithDefaults(answer => { credentials.region = answer; }, SharedAwsConfig.DEFAULT_REGION); } return credentials; } /** * @param {String[]} filterAccessKeys * @returns {Object} * @private */ _parseAwsCredentialsFile(filterAccessKeys = []) { let resultCredentials = {}; let sifCredentials = new _awsSdk2.default.SharedIniFileCredentials(); sifCredentials.loadDefaultFilename = sifCredentials.loadDefaultFilename || function () { sifCredentials.filename = SharedAwsConfig.AWS_GLOB_CFG_FILE; }; sifCredentials.loadDefaultFilename(); let guessedIniFile = sifCredentials.filename; if (!_fs2.default.existsSync(guessedIniFile)) { return {}; } let credentials = _awsSdk2.default.util.ini.parse(_awsSdk2.default.util.readFileSync(guessedIniFile)); for (let profile in credentials) { if (!credentials.hasOwnProperty(profile)) { continue; } let credentialsObj = credentials[profile]; // @todo: remove this case? if (filterAccessKeys.indexOf(credentialsObj.aws_access_key_id) !== -1) { continue; } resultCredentials[profile] = { accessKeyId: credentialsObj.aws_access_key_id, secretAccessKey: credentialsObj.aws_secret_access_key, region: SharedAwsConfig.DEFAULT_REGION }; } return resultCredentials; } /** * @returns {Object} */ guess() { if (this._credentials) { return this._credentials; } for (let i in this._providers) { if (!this._providers.hasOwnProperty(i)) { continue; } let provider = this._providers[i]; try { provider.refresh(); } catch (e) { // do nothing... } } return this._chooseCredentials(this._providers); } /** * @param {Object[]} providers * @returns {Object} * @private */ _chooseCredentials(providers) { let maxWeight = 0; let credentials = { accessKeyId: null, secretAccessKey: null, region: null }; for (let i in providers) { if (!providers.hasOwnProperty(i)) { continue; } let provider = providers[i]; let weight = this._getWeight(provider); if (maxWeight < weight) { maxWeight = weight; credentials.accessKeyId = provider.accessKeyId; credentials.secretAccessKey = provider.secretAccessKey; credentials.region = provider.region || SharedAwsConfig.DEFAULT_REGION; } } this._credentials = credentials; return credentials; } /** * @param {Object} provider * @returns {number} * @private */ _getWeight(provider) { return (provider.accessKeyId ? 2 : 0) + (provider.secretAccessKey ? 2 : 0) + (provider.region ? 1 : 0); } /** * @returns {Function} * @constructor */ static get AwsCliConfig() { return function () { return { accessKeyId: null, secretAccessKey: null, region: null, refresh: function () { let cmdPipe = _Env.Env.isWin ? '2 > NUL' : '2>/dev/null'; let accessKeyIdConfigureCmd = `aws configure get aws_access_key_id ${cmdPipe}`; let secretAccessKeyConfigureCmd = `aws configure get aws_secret_access_key ${cmdPipe}`; let regionConfigureCmd = `aws configure get region ${cmdPipe}`; let accessKeyIdResult = new _Exec.Exec(accessKeyIdConfigureCmd).runSync(); let secretAccessKeyResult = new _Exec.Exec(secretAccessKeyConfigureCmd).runSync(); let regionResult = new _Exec.Exec(regionConfigureCmd).runSync(); this.accessKeyId = accessKeyIdResult.succeed ? accessKeyIdResult.result : null; this.secretAccessKey = secretAccessKeyResult.succeed ? secretAccessKeyResult.result : null; this.region = regionResult.succeed ? regionResult.result : null; } }; }; } /** * @returns {Object[]} */ static get DEFAULT_PROVIDERS() { return [new _awsSdk2.default.EnvironmentCredentials(), new _awsSdk2.default.SharedIniFileCredentials(), new _awsSdk2.default.FileSystemCredentials(SharedAwsConfig.AWS_GLOB_CFG_FILE), new SharedAwsConfig.AwsCliConfig()]; } /** * @returns {String} */ static get DEFAULT_REGION() { return 'us-west-2'; } /** * @returns {String} */ static get AWS_GLOB_CFG_FILE() { let env = process.env; let sharedCredentialsFile = env['AWS_SHARED_CREDENTIALS_FILE']; let home = env.HOME || env.USERPROFILE || (env.HOMEPATH ? (env.HOMEDRIVE || 'C:/') + env.HOMEPATH : null); if (!home) { home = '~/'; } return sharedCredentialsFile || _path2.default.join(home, '.aws', 'credentials'); } /** * @returns {String} */ static get DEFAULT_ACCESS_KEY() { return '[YOUR_AWS_ACCESS_KEY]'; } /** * @returns {String} */ static get DEFAULT_SECRET_ACCESS_KEY() { return '[YOUR_AWS_SECRET_ACCESS_KEY]'; } } exports.SharedAwsConfig = SharedAwsConfig;