UNPKG

deep-package-manager

Version:
569 lines (454 loc) 13.8 kB
/** * Created by AlexanderC on 5/27/15. */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.Instance = undefined; var _deepCore = require('deep-core'); var _deepCore2 = _interopRequireDefault(_deepCore); var _InvalidArgumentException = require('../Exception/InvalidArgumentException'); var _AbstractService = require('./Service/AbstractService'); var _S3Service = require('./Service/S3Service'); var _CognitoIdentityService = require('./Service/CognitoIdentityService'); var _CognitoIdentityProviderService = require('./Service/CognitoIdentityProviderService'); var _IAMService = require('./Service/IAMService'); var _CloudFrontService = require('./Service/CloudFrontService'); var _ACMService = require('./Service/ACMService.js'); var _SNSService = require('./Service/SNSService'); var _LambdaService = require('./Service/LambdaService'); var _KinesisService = require('./Service/KinesisService'); var _DynamoDBService = require('./Service/DynamoDBService'); var _ElasticacheService = require('./Service/ElasticacheService'); var _APIGatewayService = require('./Service/APIGatewayService'); var _SQSService = require('./Service/SQSService'); var _CloudWatchLogsService = require('./Service/CloudWatchLogsService'); var _CloudWatchEventsService = require('./Service/CloudWatchEventsService'); var _ESService = require('./Service/ESService'); var _Instance = require('../Property/Instance'); var _WaitFor = require('../Helpers/WaitFor'); var _Tagging = require('./ResourceTagging/Tagging'); var _SESService = require('./Service/SESService'); var _objectMerge = require('object-merge'); var _objectMerge2 = _interopRequireDefault(_objectMerge); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Provisioning instance */ class Instance { /** * @param {PropertyInstance|*} property */ constructor(property) { if (!(property instanceof _Instance.Instance)) { throw new _InvalidArgumentException.InvalidArgumentException(property, _Instance.Instance); } this._property = property; // deep-db instance this._db = null; this._ec2 = new property.AWS.EC2(); // used for security groups retrieval this._sns = new property.AWS.SNS(); this._cloudFront = new property.AWS.CloudFront(); this._iam = new property.AWS.IAM(); // set appropriate region for services that are not available on all regions this._dynamoDb = new property.AWS.DynamoDB({ region: this.getAwsServiceRegion(_DynamoDBService.DynamoDBService, property.config.awsRegion) }); this._kinesis = new property.AWS.Kinesis({ region: this.getAwsServiceRegion(_KinesisService.KinesisService, property.config.awsRegion) }); this._lambda = new property.AWS.Lambda({ region: this.getAwsServiceRegion(_LambdaService.LambdaService, property.config.awsRegion) }); this._cognitoIdentity = new property.AWS.CognitoIdentity({ region: this.getAwsServiceRegion(_CognitoIdentityService.CognitoIdentityService, property.config.awsRegion) }); this._cognitoIdentityServiceProvider = new property.AWS.CognitoIdentityServiceProvider({ region: this.getAwsServiceRegion(_CognitoIdentityProviderService.CognitoIdentityProviderService, property.config.awsRegion) }); this._apiGateway = new property.AWS.APIGateway({ region: this.getAwsServiceRegion(_APIGatewayService.APIGatewayService, property.config.awsRegion) }); this._sqs = new property.AWS.SQS({ region: this.getAwsServiceRegion(_SQSService.SQSService, property.config.awsRegion) }); this._acm = new property.AWS.ACM({ region: this.getAwsServiceRegion(_ACMService.ACMService, property.config.awsRegion) }); this._elasticsearch = new property.AWS.ES({ region: this.getAwsServiceRegion(_ESService.ESService, property.config.awsRegion) }); this._ses = new property.AWS.SES({ region: this.getAwsServiceRegion(_SESService.SESService, property.config.awsRegion) }); // set region for services that depend on other services region this._elasticache = new property.AWS.ElastiCache({ region: this._lambda.config.region }); this._s3 = new property.AWS.S3({ region: this._lambda.config.region }); this._cloudWatchLogs = new property.AWS.CloudWatchLogs({ region: this._lambda.config.region }); this._cloudWatchEvents = new property.AWS.CloudWatchEvents({ region: this._lambda.config.region }); this._cloudWatch = new property.AWS.CloudWatch({ region: this._lambda.config.region }); this._config = {}; this._services = null; this._tagging = null; } /** * @param {Function} awsService * @param {string} defaultRegion * @returns {string} */ getAwsServiceRegion(awsService, defaultRegion) { return _deepCore2.default.AWS.Region.getAppropriateAwsRegion(defaultRegion, awsService.AVAILABLE_REGIONS); } /** * @returns {DB} */ get db() { return this._db; } /** * In order to make possible DB manipulations * in post provision hook * * @param {DB} instance */ set db(instance) { this._db = instance; } /** * @returns {Object} */ get config() { return this._config; } /** * @param {Object} cfg */ set config(cfg) { this._config = cfg; } /** * @returns {PropertyInstance} */ get property() { return this._property; } /** * @returns {AWS.CloudWatchEvents|*} */ get cloudWatchEvents() { return this._cloudWatchEvents; } /** * @returns {AWS.CloudWatch|*} */ get cloudWatch() { return this._cloudWatch; } /** * @returns {AWS.EC2|*} */ get ec2() { return this._ec2; } /** * @returns {AWS.ACM|*} */ get acm() { return this._acm; } /** * @returns {AWS.CloudWatchLogs|*} */ get cloudWatchLogs() { return this._cloudWatchLogs; } /** * @returns {AWS.S3|*} */ get s3() { return this._s3; } /** * @returns {AWS.DynamoDB|*} */ get dynamoDB() { return this._dynamoDb; } /** * @returns {AWS.ElastiCache|*} */ get elasticCache() { return this._elasticache; } /** * @returns {AWS.Kinesis|*} */ get kinesis() { return this._kinesis; } /** * @returns {AWS.SNS|*} */ get sns() { return this._sns; } /** * @returns {AWS.Lambda|*} */ get lambda() { return this._lambda; } /** * @returns {AWS.IAM|*} */ get iam() { return this._iam; } /** * @returns {AWS.CognitoIdentity|*} */ get cognitoIdentity() { return this._cognitoIdentity; } /** * @returns {AWS.CognitoIdentityServiceProvider|*} */ get cognitoIdentityServiceProvider() { return this._cognitoIdentityServiceProvider; } /** * @returns {AWS.CloudFront|*} */ get cloudFront() { return this._cloudFront; } /** * @returns {AWS.APIGateway|*} */ get apiGateway() { return this._apiGateway; } /** * @returns {AWS.SQS|*} */ get sqs() { return this._sqs; } /** * @returns {AWS.SES|*} */ get ses() { return this._ses; } /** * @returns {AWS.ES|*} */ get elasticSearch() { return this._elasticsearch; } /** * @param {String} name * @returns {Object} */ getAwsServiceByName(name) { switch (name) { case 'IAM': case 'SNS': case 'SQS': case 'ACM': name = name.toLowerCase(); break; case 'APIGateway': case 'APIGatewayPlan': case 'APIGatewayKey': name = 'apiGateway'; break; case 'ElastiCache': name = 'elasticCache'; break; case 'ES': name = 'elasticSearch'; break; case 'CognitoIdentityProvider': name = 'cognitoIdentityServiceProvider'; break; default: name = _AbstractService.AbstractService.lowerCaseFirst(name); } return this[name]; } /** * @returns {Core.Generic.ObjectStorage} */ get services() { if (this._services === null) { // @todo - add only required services that are configured in appConfig file this._services = new _deepCore2.default.Generic.ObjectStorage([new _ElasticacheService.ElasticacheService(this), new _S3Service.S3Service(this), new _DynamoDBService.DynamoDBService(this), new _KinesisService.KinesisService(this), new _SNSService.SNSService(this), new _SESService.SESService(this), new _IAMService.IAMService(this), new _CognitoIdentityService.CognitoIdentityService(this), new _CognitoIdentityProviderService.CognitoIdentityProviderService(this), new _ACMService.ACMService(this), new _CloudFrontService.CloudFrontService(this), new _LambdaService.LambdaService(this), new _APIGatewayService.APIGatewayService(this), new _SQSService.SQSService(this), new _CloudWatchLogsService.CloudWatchLogsService(this), new _CloudWatchEventsService.CloudWatchEventsService(this), new _ESService.ESService(this)]); } return this._services; } /** * @todo: split update into a separate method * * @param {Function} callback * @param {Boolean} isUpdate */ create(callback, isUpdate = false) { if (!(callback instanceof Function)) { throw new _InvalidArgumentException.InvalidArgumentException(callback, 'Function'); } let services = this.services; let wait = new _WaitFor.WaitFor(); let servicesVector = services.iterator; let remaining = servicesVector.length; if (isUpdate) { this.isUpdate(); } for (let i in servicesVector) { if (!servicesVector.hasOwnProperty(i)) { continue; } let service = servicesVector[i]; console.debug(`Start provisioning "${service.name()}" service.`); service.setup(services).ready(() => { console.debug(`Service "${service.name()}" provisioned.`); this._config[service.name()] = service.config(); remaining--; }); } wait.push(() => { return remaining <= 0; }); wait.ready(() => { let subWait = new _WaitFor.WaitFor(); let subRemaining = servicesVector.length; for (let i in servicesVector) { if (!servicesVector.hasOwnProperty(i)) { continue; } let service = servicesVector[i]; console.debug(`Start post-provisioning for "${service.name()}" service.`); service.postProvision(services).ready(() => { console.debug(`Post-provisioning done for "${service.name()}" service.`); this._config[service.name()] = this._mergeConfigs(this._config[service.name()], service.config()); subRemaining--; }); } subWait.push(() => { return subRemaining <= 0; }); subWait.ready(() => { if (isUpdate) { callback(this._config); } else { console.debug('Start tagging resources'); this.tagging.tag(() => { callback(this._config); }); } }); }); } /** * @returns {Tagging} */ get tagging() { if (!this._tagging) { this._tagging = _Tagging.Tagging.create(this._property); } return this._tagging; } /** * * @param {Object} oldConfig * @param {Object} newConfig * @returns {Object} */ _mergeConfigs(oldConfig, newConfig) { // use this hook to avoid circular reference error return (0, _objectMerge2.default)(JSON.parse(JSON.stringify(oldConfig)), JSON.parse(JSON.stringify(newConfig))); } /** * @param {Object|null} config * @returns {Instance} */ injectConfig(config = null) { if (config) { this._config = config; } let services = this.services; let servicesVector = services.iterator; let propertyProvisioning = this.property.config.provisioning; for (let i in servicesVector) { if (!servicesVector.hasOwnProperty(i)) { continue; } let service = servicesVector[i]; service.injectConfig(propertyProvisioning[service.name()]); } return this; } /** * @param {Boolean} value */ isUpdate(value = true) { let services = this.services; let servicesVector = services.iterator; for (let i in servicesVector) { if (!servicesVector.hasOwnProperty(i)) { continue; } let service = servicesVector[i]; service.isUpdate = value; } } /** * @param {Function} callback * @param {Boolean} isUpdate */ postDeployProvision(callback, isUpdate = false) { if (!(callback instanceof Function)) { throw new _InvalidArgumentException.InvalidArgumentException(callback, 'Function'); } let services = this.services; let wait = new _WaitFor.WaitFor(); let servicesVector = services.iterator; let remaining = servicesVector.length; if (isUpdate) { this.isUpdate(); } for (let i in servicesVector) { if (!servicesVector.hasOwnProperty(i)) { continue; } let service = servicesVector[i]; console.debug(`Start post-deploy-provisioning for "${service.name()}" service.`); service.postDeployProvision(services).ready(() => { console.debug(`Post-deploy-provisioning done for "${service.name()}" service.`); this._config[service.name()] = this._mergeConfigs(this._config[service.name()], service.config()); remaining--; }); } wait.push(() => { return remaining <= 0; }); wait.ready(() => { console.debug('Start tagging resources post deploy'); this.tagging.tag(() => { callback(this._config); }, _Tagging.Tagging.POST_DEPLOY_STEP); }); } } exports.Instance = Instance;