deep-package-manager
Version:
DEEP Package Manager
569 lines (454 loc) • 13.8 kB
JavaScript
/**
* 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;