mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
new awsm.json format, alias lambda, version lambda
This commit is contained in:
parent
806ced38a8
commit
bc072fb925
@ -6,3 +6,6 @@
|
||||
|
||||
## Running test cases
|
||||
|
||||
1. Set env vars defined in `tests/config.js`. By default if you do not set `TEST_JAWS_EXE_CF` no AWS resources will be created.
|
||||
1. Make sure you have run `npm install` from the jaws project root
|
||||
1. Run the mocha test from the CLI (`mocha tests/all.js`) or setup mocha test from your IDE. WebStorm allows you to run a debugger in the IDE for your test cases which is really handy to track down issues.
|
||||
16
lib/Jaws.js
16
lib/Jaws.js
@ -148,14 +148,14 @@ class Jaws {
|
||||
*/
|
||||
_executeQueue(queue) {
|
||||
return Promise.try(() => {
|
||||
return queue;
|
||||
})
|
||||
.each(function(p) {
|
||||
return p();
|
||||
})
|
||||
.catch(function(error) {
|
||||
throw new JawsError(error);
|
||||
});
|
||||
return queue;
|
||||
})
|
||||
.each(function(p) {
|
||||
return p();
|
||||
})
|
||||
.catch(function(error) {
|
||||
throw new JawsError(error);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -55,23 +55,23 @@ class ApiDeployer {
|
||||
let _this = this;
|
||||
|
||||
return this._findTaggedEndpoints()
|
||||
.bind(_this)
|
||||
.then(_this._validateAndSantizeTaggedEndpoints)
|
||||
.then(_this._fetchDeployedLambdas)
|
||||
.then(_this._findOrCreateApi)
|
||||
.then(_this._saveApiId)
|
||||
.then(_this._listApiResources)
|
||||
.then(_this._buildEndpoints)
|
||||
.then(_this._createDeployment)
|
||||
.then(function() {
|
||||
return 'https://'
|
||||
+ _this._restApiId
|
||||
+ '.execute-api.'
|
||||
+ _this._regionJson.region
|
||||
+ '.amazonaws.com/'
|
||||
+ _this._stage
|
||||
+ '/';
|
||||
});
|
||||
.bind(_this)
|
||||
.then(_this._validateAndSantizeTaggedEndpoints)
|
||||
.then(_this._fetchDeployedLambdas)
|
||||
.then(_this._findOrCreateApi)
|
||||
.then(_this._saveApiId)
|
||||
.then(_this._listApiResources)
|
||||
.then(_this._buildEndpoints)
|
||||
.then(_this._createDeployment)
|
||||
.then(function() {
|
||||
return 'https://'
|
||||
+ _this._restApiId
|
||||
+ '.execute-api.'
|
||||
+ _this._regionJson.region
|
||||
+ '.amazonaws.com/'
|
||||
+ _this._stage
|
||||
+ '/';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,26 +83,26 @@ class ApiDeployer {
|
||||
let _this = this;
|
||||
|
||||
return JawsUtils.findAllEndpoints(_this._prjRootPath)
|
||||
.each(function(endpoint) {
|
||||
.each(function(endpoint) {
|
||||
|
||||
let eJson = require(endpoint);
|
||||
if (eJson.apiGateway.deploy) _this._endpoints.push(eJson);
|
||||
let eJson = require(endpoint);
|
||||
if (eJson.apiGateway.deploy) _this._endpoints.push(eJson);
|
||||
|
||||
}).then(function() {
|
||||
}).then(function() {
|
||||
|
||||
if (!_this._endpoints.length) {
|
||||
throw new JawsError(
|
||||
'You have no tagged endpoints',
|
||||
JawsError.errorCodes.UNKNOWN);
|
||||
}
|
||||
if (!_this._endpoints.length) {
|
||||
throw new JawsError(
|
||||
'You have no tagged endpoints',
|
||||
JawsError.errorCodes.UNKNOWN);
|
||||
}
|
||||
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ '": found '
|
||||
+ _this._endpoints.length + ' endpoints to deploy');
|
||||
});
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ '": found '
|
||||
+ _this._endpoints.length + ' endpoints to deploy');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,14 +113,14 @@ class ApiDeployer {
|
||||
_fetchDeployedLambdas() {
|
||||
let _this = this;
|
||||
|
||||
return AWSUtils.cfGetLambdaNames(
|
||||
_this._JAWS._profile,
|
||||
_this._regionJson.region,
|
||||
_this._stage + '-' + _this._JAWS._projectJson.name + '-l'
|
||||
)
|
||||
.then(lambdas => {
|
||||
this._lambdas = lambdas;
|
||||
});
|
||||
return AWSUtils.cfGetLambdaResourceSummaries(
|
||||
_this._JAWS._profile,
|
||||
_this._regionJson.region,
|
||||
AWSUtils.cfGetLambdasStackName(_this._stage, _this._JAWS._projectJson.name)
|
||||
)
|
||||
.then(lambdas => {
|
||||
this._lambdas = lambdas;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,13 +140,13 @@ class ApiDeployer {
|
||||
|
||||
// Validate attributes
|
||||
if (!e.Type
|
||||
|| !e.Path
|
||||
|| !e.Method
|
||||
|| !e.AuthorizationType
|
||||
|| typeof e.ApiKeyRequired === 'undefined') {
|
||||
|| !e.Path
|
||||
|| !e.Method
|
||||
|| !e.AuthorizationType
|
||||
|| typeof e.ApiKeyRequired === 'undefined') {
|
||||
return Promise.reject(new JawsError(
|
||||
'Missing one of many required endpoint attributes: Type, Path, Method, AuthorizationType, ApiKeyRequired',
|
||||
JawsError.errorCodes.UNKNOWN));
|
||||
'Missing one of many required endpoint attributes: Type, Path, Method, AuthorizationType, ApiKeyRequired',
|
||||
JawsError.errorCodes.UNKNOWN));
|
||||
}
|
||||
|
||||
// Sanitize path
|
||||
@ -194,16 +194,16 @@ class ApiDeployer {
|
||||
|
||||
// Show existing REST API
|
||||
return this.ApiClient.showRestApi(_this._restApiId)
|
||||
.then(function(response) {
|
||||
.then(function(response) {
|
||||
|
||||
_this._restApiId = response.id;
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ '": found existing REST API on AWS API Gateway with ID: '
|
||||
+ response.id);
|
||||
});
|
||||
_this._restApiId = response.id;
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ '": found existing REST API on AWS API Gateway with ID: '
|
||||
+ response.id);
|
||||
});
|
||||
} else {
|
||||
|
||||
// Create REST API
|
||||
@ -218,11 +218,11 @@ class ApiDeployer {
|
||||
|
||||
_this._restApiId = response.id;
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ '": created a new REST API on AWS API Gateway with ID: '
|
||||
+ response.id);
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ '": created a new REST API on AWS API Gateway with ID: '
|
||||
+ response.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -238,27 +238,27 @@ class ApiDeployer {
|
||||
|
||||
// List all Resources for this REST API
|
||||
return this.ApiClient.listResources(_this._restApiId)
|
||||
.then(function(response) {
|
||||
.then(function(response) {
|
||||
|
||||
// Parse API Gateway's HAL response
|
||||
_this._resources = response._embedded.item;
|
||||
if (!Array.isArray(_this._resources)) _this._resources = [_this._resources];
|
||||
// Parse API Gateway's HAL response
|
||||
_this._resources = response._embedded.item;
|
||||
if (!Array.isArray(_this._resources)) _this._resources = [_this._resources];
|
||||
|
||||
// Get Parent Resource ID
|
||||
for (let i = 0; i < _this._resources.length; i++) {
|
||||
if (_this._resources[i].path === '/') {
|
||||
_this._parentResourceId = _this._resources[i].id;
|
||||
// Get Parent Resource ID
|
||||
for (let i = 0; i < _this._resources.length; i++) {
|
||||
if (_this._resources[i].path === '/') {
|
||||
_this._parentResourceId = _this._resources[i].id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ '": found '
|
||||
+ _this._resources.length
|
||||
+ ' existing resources on API Gateway');
|
||||
});
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ '": found '
|
||||
+ _this._resources.length
|
||||
+ ' existing resources on API Gateway');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -275,18 +275,18 @@ class ApiDeployer {
|
||||
}).each(function(endpoint) {
|
||||
|
||||
return _this._createEndpointResources(endpoint)
|
||||
.bind(_this)
|
||||
.then(_this._createEndpointMethod)
|
||||
.then(_this._createEndpointIntegration)
|
||||
.then(_this._manageLambdaAccessPolicy)
|
||||
.then(_this._createEndpointMethodResponses)
|
||||
.then(_this._createEndpointMethodIntegResponses)
|
||||
.then(function() {
|
||||
.bind(_this)
|
||||
.then(_this._createEndpointMethod)
|
||||
.then(_this._createEndpointIntegration)
|
||||
.then(_this._manageLambdaAccessPolicy)
|
||||
.then(_this._createEndpointMethodResponses)
|
||||
.then(_this._createEndpointMethodIntegResponses)
|
||||
.then(function() {
|
||||
|
||||
// Clean-up hack
|
||||
// TODO figure out how "apig" temp property is being written to the awsm's json and remove that
|
||||
if (endpoint.apiGateway.apig) delete endpoint.apiGateway.apig;
|
||||
});
|
||||
// Clean-up hack
|
||||
// TODO figure out how "apig" temp property is being written to the awsm's json and remove that
|
||||
if (endpoint.apiGateway.apig) delete endpoint.apiGateway.apig;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -358,21 +358,21 @@ class ApiDeployer {
|
||||
|
||||
// Create Resource
|
||||
return _this.ApiClient.createResource(
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.parentResourceId,
|
||||
eResource)
|
||||
.then(function(response) {
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.parentResourceId,
|
||||
eResource)
|
||||
.then(function(response) {
|
||||
|
||||
// Add resource to _this.resources and callback
|
||||
_this._resources.push(response);
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "' +
|
||||
_this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - ' + endpoint.apiGateway.cloudFormation.Path + '": '
|
||||
+ 'created resource: '
|
||||
+ response.pathPart);
|
||||
});
|
||||
// Add resource to _this.resources and callback
|
||||
_this._resources.push(response);
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "' +
|
||||
_this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - ' + endpoint.apiGateway.cloudFormation.Path + '": '
|
||||
+ 'created resource: '
|
||||
+ response.pathPart);
|
||||
});
|
||||
|
||||
}).then(function() {
|
||||
|
||||
@ -411,42 +411,42 @@ class ApiDeployer {
|
||||
}
|
||||
|
||||
return _this.ApiClient.showMethod(
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method)
|
||||
.then(function() {
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method)
|
||||
.then(function() {
|
||||
|
||||
return _this.ApiClient.deleteMethod(
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method)
|
||||
.then(function() {
|
||||
_this.ApiClient.putMethod(
|
||||
return _this.ApiClient.deleteMethod(
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method)
|
||||
.then(function() {
|
||||
_this.ApiClient.putMethod(
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method,
|
||||
methodBody);
|
||||
});
|
||||
}, function() {
|
||||
|
||||
return _this.ApiClient.putMethod(
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method,
|
||||
methodBody);
|
||||
});
|
||||
}, function() {
|
||||
})
|
||||
.delay(250) // API Gateway takes time to delete Methods. Might have to increase this.
|
||||
.then(function(response) {
|
||||
|
||||
return _this.ApiClient.putMethod(
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method,
|
||||
methodBody);
|
||||
})
|
||||
.delay(250) // API Gateway takes time to delete Methods. Might have to increase this.
|
||||
.then(function(response) {
|
||||
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - ' + endpoint.apiGateway.cloudFormation.Path + '": '
|
||||
+ 'created method: '
|
||||
+ endpoint.apiGateway.cloudFormation.Method);
|
||||
return endpoint;
|
||||
});
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - ' + endpoint.apiGateway.cloudFormation.Path + '": '
|
||||
+ 'created method: '
|
||||
+ endpoint.apiGateway.cloudFormation.Method);
|
||||
return endpoint;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -464,7 +464,7 @@ class ApiDeployer {
|
||||
if (endpoint.type === 'lambda' || typeof endpoint.lambda !== 'undefined') {
|
||||
|
||||
// Find Deployed Lambda and its function name
|
||||
let cfLogicalResourceId = JawsUtils.generateLambdaName(endpoint);
|
||||
let cfLogicalResourceId = JawsUtils.getLambdaName(endpoint);
|
||||
let lambda = null;
|
||||
|
||||
for (let i = 0; i < _this._lambdas.length; i++) {
|
||||
@ -476,7 +476,7 @@ class ApiDeployer {
|
||||
// If no deployed lambda found, throw error
|
||||
if (!lambda) {
|
||||
return Promise.reject(new JawsError('Could not find a lambda deployed in this stage/region with this function name: '
|
||||
+ cfLogicalResourceId));
|
||||
+ cfLogicalResourceId));
|
||||
}
|
||||
endpoint.apiGateway.apig.lambda = lambda;
|
||||
|
||||
@ -513,28 +513,28 @@ class ApiDeployer {
|
||||
|
||||
// Create Integration
|
||||
return _this.ApiClient.putIntegration(
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method,
|
||||
integrationBody)
|
||||
.then(function(response) {
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method,
|
||||
integrationBody)
|
||||
.then(function(response) {
|
||||
|
||||
// Save integration to apig property
|
||||
endpoint.apiGateway.apig.integration = response;
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - ' + endpoint.apiGateway.cloudFormation.Path + '": '
|
||||
+ 'created integration with the type: '
|
||||
+ endpoint.apiGateway.cloudFormation.Type);
|
||||
return endpoint;
|
||||
})
|
||||
.catch(function(error) {
|
||||
throw new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN);
|
||||
});
|
||||
// Save integration to apig property
|
||||
endpoint.apiGateway.apig.integration = response;
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage + ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - ' + endpoint.apiGateway.cloudFormation.Path + '": '
|
||||
+ 'created integration with the type: '
|
||||
+ endpoint.apiGateway.cloudFormation.Type);
|
||||
return endpoint;
|
||||
})
|
||||
.catch(function(error) {
|
||||
throw new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -549,65 +549,65 @@ class ApiDeployer {
|
||||
|
||||
return Promise.try(function() {
|
||||
|
||||
// Collect Response Keys
|
||||
if (endpoint.apiGateway.cloudFormation.Responses) return Object.keys(endpoint.apiGateway.cloudFormation.Responses);
|
||||
else return [];
|
||||
})
|
||||
.each(function(responseKey) {
|
||||
// Collect Response Keys
|
||||
if (endpoint.apiGateway.cloudFormation.Responses) return Object.keys(endpoint.apiGateway.cloudFormation.Responses);
|
||||
else return [];
|
||||
})
|
||||
.each(function(responseKey) {
|
||||
|
||||
let thisResponse = endpoint.apiGateway.cloudFormation.Responses[responseKey];
|
||||
let methodResponseBody = {};
|
||||
let thisResponse = endpoint.apiGateway.cloudFormation.Responses[responseKey];
|
||||
let methodResponseBody = {};
|
||||
|
||||
// If Request Params, add them
|
||||
if (thisResponse.responseParameters) {
|
||||
// If Request Params, add them
|
||||
if (thisResponse.responseParameters) {
|
||||
|
||||
methodResponseBody.responseParameters = {};
|
||||
methodResponseBody.responseParameters = {};
|
||||
|
||||
// Format Response Parameters per APIG API's Expectations
|
||||
for (let prop in thisResponse.responseParameters) {
|
||||
methodResponseBody.responseParameters[prop] = true;
|
||||
// Format Response Parameters per APIG API's Expectations
|
||||
for (let prop in thisResponse.responseParameters) {
|
||||
methodResponseBody.responseParameters[prop] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If Request models, add them
|
||||
if (thisResponse.responseModels) {
|
||||
// If Request models, add them
|
||||
if (thisResponse.responseModels) {
|
||||
|
||||
methodResponseBody.responseModels = {};
|
||||
methodResponseBody.responseModels = {};
|
||||
|
||||
// Format Response Models per APIG API's Expectations
|
||||
for (let name in thisResponse.responseModels) {
|
||||
let value = thisResponse.responseModels[name];
|
||||
methodResponseBody.responseModels[name] = value;
|
||||
// Format Response Models per APIG API's Expectations
|
||||
for (let name in thisResponse.responseModels) {
|
||||
let value = thisResponse.responseModels[name];
|
||||
methodResponseBody.responseModels[name] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create Method Response
|
||||
return _this.ApiClient.putMethodResponse(
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method,
|
||||
thisResponse.statusCode,
|
||||
methodResponseBody)
|
||||
.then(function() {
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage
|
||||
+ ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - '
|
||||
+ endpoint.apiGateway.cloudFormation.Path
|
||||
+ '": '
|
||||
+ 'created method response');
|
||||
})
|
||||
.catch(function(error) {
|
||||
throw new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN);
|
||||
});
|
||||
})
|
||||
.then(function() {
|
||||
return endpoint;
|
||||
});
|
||||
// Create Method Response
|
||||
return _this.ApiClient.putMethodResponse(
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method,
|
||||
thisResponse.statusCode,
|
||||
methodResponseBody)
|
||||
.then(function() {
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage
|
||||
+ ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - '
|
||||
+ endpoint.apiGateway.cloudFormation.Path
|
||||
+ '": '
|
||||
+ 'created method response');
|
||||
})
|
||||
.catch(function(error) {
|
||||
throw new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN);
|
||||
});
|
||||
})
|
||||
.then(function() {
|
||||
return endpoint;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -622,47 +622,47 @@ class ApiDeployer {
|
||||
|
||||
return Promise.try(function() {
|
||||
|
||||
// Collect Response Keys
|
||||
if (endpoint.apiGateway.cloudFormation.Responses) return Object.keys(endpoint.apiGateway.cloudFormation.Responses);
|
||||
else return [];
|
||||
})
|
||||
.each(function(responseKey) {
|
||||
// Collect Response Keys
|
||||
if (endpoint.apiGateway.cloudFormation.Responses) return Object.keys(endpoint.apiGateway.cloudFormation.Responses);
|
||||
else return [];
|
||||
})
|
||||
.each(function(responseKey) {
|
||||
|
||||
let thisResponse = endpoint.apiGateway.cloudFormation.Responses[responseKey];
|
||||
let integrationResponseBody = {};
|
||||
let thisResponse = endpoint.apiGateway.cloudFormation.Responses[responseKey];
|
||||
let integrationResponseBody = {};
|
||||
|
||||
// Add Response Parameters
|
||||
integrationResponseBody.responseParameters = thisResponse.responseParameters || {};
|
||||
// Add Response Parameters
|
||||
integrationResponseBody.responseParameters = thisResponse.responseParameters || {};
|
||||
|
||||
// Add Response Templates
|
||||
integrationResponseBody.responseTemplates = thisResponse.responseTemplates || {};
|
||||
// Add Response Templates
|
||||
integrationResponseBody.responseTemplates = thisResponse.responseTemplates || {};
|
||||
|
||||
// Add SelectionPattern
|
||||
integrationResponseBody.selectionPattern = thisResponse.selectionPattern || (responseKey === 'default' ? null : responseKey);
|
||||
// Add SelectionPattern
|
||||
integrationResponseBody.selectionPattern = thisResponse.selectionPattern || (responseKey === 'default' ? null : responseKey);
|
||||
|
||||
// Create Integration Response
|
||||
return _this.ApiClient.putIntegrationResponse(
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method,
|
||||
thisResponse.statusCode,
|
||||
integrationResponseBody)
|
||||
.then(function() {
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage
|
||||
+ ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - '
|
||||
+ endpoint.apiGateway.cloudFormation.Path
|
||||
+ '": '
|
||||
+ 'created method integration response');
|
||||
}).catch(function(error) {
|
||||
throw new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN);
|
||||
});
|
||||
});
|
||||
// Create Integration Response
|
||||
return _this.ApiClient.putIntegrationResponse(
|
||||
_this._restApiId,
|
||||
endpoint.apiGateway.apig.resource.id,
|
||||
endpoint.apiGateway.cloudFormation.Method,
|
||||
thisResponse.statusCode,
|
||||
integrationResponseBody)
|
||||
.then(function() {
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage
|
||||
+ ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - '
|
||||
+ endpoint.apiGateway.cloudFormation.Path
|
||||
+ '": '
|
||||
+ 'created method integration response');
|
||||
}).catch(function(error) {
|
||||
throw new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -679,9 +679,9 @@ class ApiDeployer {
|
||||
if (!endpoint.apiGateway.apig.lambda) return Promise.resolve(endpoint);
|
||||
|
||||
return this._getLambdaAccessPolicy(endpoint)
|
||||
.bind(_this)
|
||||
.then(_this._removeLambdaAccessPolicy)
|
||||
.then(_this._updateLambdaAccessPolicy);
|
||||
.bind(_this)
|
||||
.then(_this._removeLambdaAccessPolicy)
|
||||
.then(_this._updateLambdaAccessPolicy);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -701,16 +701,16 @@ class ApiDeployer {
|
||||
let _this = this;
|
||||
|
||||
return AWSUtils.lambdaGetPolicy(
|
||||
_this._JAWS._meta.profile,
|
||||
_this._regionJson.region,
|
||||
endpoint.apiGateway.apig.lambda.PhysicalResourceId)
|
||||
.then(function(data) {
|
||||
endpoint.apiGateway.apig.lambda.Policy = JSON.parse(data.Policy);
|
||||
return endpoint;
|
||||
})
|
||||
.catch(function(error) {
|
||||
return endpoint;
|
||||
});
|
||||
_this._JAWS._meta.profile,
|
||||
_this._regionJson.region,
|
||||
endpoint.apiGateway.apig.lambda.PhysicalResourceId)
|
||||
.then(function(data) {
|
||||
endpoint.apiGateway.apig.lambda.Policy = JSON.parse(data.Policy);
|
||||
return endpoint;
|
||||
})
|
||||
.catch(function(error) {
|
||||
return endpoint;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -737,27 +737,27 @@ class ApiDeployer {
|
||||
if (!statement) return Promise.resolve(endpoint);
|
||||
|
||||
return AWSUtils.lambdaRemovePermission(
|
||||
_this._JAWS._meta.profile,
|
||||
_this._regionJson.region,
|
||||
endpoint.apiGateway.apig.lambda.PhysicalResourceId,
|
||||
'jaws-apigateway-access')
|
||||
.then(function(data) {
|
||||
_this._JAWS._meta.profile,
|
||||
_this._regionJson.region,
|
||||
endpoint.apiGateway.apig.lambda.PhysicalResourceId,
|
||||
'jaws-apigateway-access')
|
||||
.then(function(data) {
|
||||
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage
|
||||
+ ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - '
|
||||
+ endpoint.apiGateway.cloudFormation.Path
|
||||
+ '": removed existing lambda access policy statement');
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage
|
||||
+ ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - '
|
||||
+ endpoint.apiGateway.cloudFormation.Path
|
||||
+ '": removed existing lambda access policy statement');
|
||||
|
||||
return endpoint;
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.log(error);
|
||||
return endpoint;
|
||||
});
|
||||
return endpoint;
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.log(error);
|
||||
return endpoint;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -781,35 +781,35 @@ class ApiDeployer {
|
||||
statement.Principal = 'apigateway.amazonaws.com';
|
||||
statement.StatementId = 'jaws-apigateway-access';
|
||||
statement.SourceArn = 'arn:aws:execute-api:'
|
||||
+ _this._regionJson.region
|
||||
+ ':'
|
||||
+ _this._awsAccountNumber
|
||||
+ ':'
|
||||
+ _this._restApiId
|
||||
+ '/*/'
|
||||
+ endpoint.apiGateway.cloudFormation.Method
|
||||
+ '/'
|
||||
+ endpoint.apiGateway.cloudFormation.Path;
|
||||
+ _this._regionJson.region
|
||||
+ ':'
|
||||
+ _this._awsAccountNumber
|
||||
+ ':'
|
||||
+ _this._restApiId
|
||||
+ '/*/'
|
||||
+ endpoint.apiGateway.cloudFormation.Method
|
||||
+ '/'
|
||||
+ endpoint.apiGateway.cloudFormation.Path;
|
||||
|
||||
return AWSUtils.lambdaAddPermission(
|
||||
_this._JAWS._meta.profile,
|
||||
_this._regionJson.region,
|
||||
statement)
|
||||
.then(function(data) {
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage
|
||||
+ ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - '
|
||||
+ endpoint.apiGateway.cloudFormation.Path
|
||||
+ '": created new lambda access policy statement');
|
||||
return endpoint;
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.log(error);
|
||||
return endpoint;
|
||||
});
|
||||
_this._JAWS._meta.profile,
|
||||
_this._regionJson.region,
|
||||
statement)
|
||||
.then(function(data) {
|
||||
JawsCli.log(
|
||||
'Endpoint Deployer: "'
|
||||
+ _this._stage
|
||||
+ ' - '
|
||||
+ _this._regionJson.region
|
||||
+ ' - '
|
||||
+ endpoint.apiGateway.cloudFormation.Path
|
||||
+ '": created new lambda access policy statement');
|
||||
return endpoint;
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.log(error);
|
||||
return endpoint;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -828,14 +828,14 @@ class ApiDeployer {
|
||||
};
|
||||
|
||||
return _this.ApiClient.createDeployment(_this._restApiId, deployment)
|
||||
.then(function(response) {
|
||||
return response;
|
||||
})
|
||||
.catch(function(error) {
|
||||
throw new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN);
|
||||
});
|
||||
.then(function(response) {
|
||||
return response;
|
||||
})
|
||||
.catch(function(error) {
|
||||
throw new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -863,46 +863,46 @@ const CMD = class DeployEndpoint extends ProjectCmd {
|
||||
let _this = this;
|
||||
|
||||
return this._JAWS.validateProject()
|
||||
.bind(_this)
|
||||
.then(function() {
|
||||
// If !allTagged, tag current directory
|
||||
if (!_this._allTagged) {
|
||||
return Tag.tag('endpoint', null, false);
|
||||
}
|
||||
})
|
||||
.then(_this._promptStage)
|
||||
.then(_this._promptRegions)
|
||||
.then(function() {
|
||||
return _this._regions;
|
||||
})
|
||||
.each(function(regionJson) {
|
||||
.bind(_this)
|
||||
.then(function() {
|
||||
// If !allTagged, tag current directory
|
||||
if (!_this._allTagged) {
|
||||
return Tag.tag('endpoint', null, false);
|
||||
}
|
||||
})
|
||||
.then(_this._promptStage)
|
||||
.then(_this._promptRegions)
|
||||
.then(function() {
|
||||
return _this._regions;
|
||||
})
|
||||
.each(function(regionJson) {
|
||||
|
||||
JawsCli.log(`Endpoint Deployer: Deploying endpoint(s) to region "${regionJson.region}"...`);
|
||||
JawsCli.log(`Endpoint Deployer: Deploying endpoint(s) to region "${regionJson.region}"...`);
|
||||
|
||||
let deployer = new ApiDeployer(
|
||||
_this._JAWS,
|
||||
_this._stage,
|
||||
regionJson,
|
||||
_this._prjRootPath,
|
||||
_this._prjJson,
|
||||
_this._prjCreds
|
||||
);
|
||||
let deployer = new ApiDeployer(
|
||||
_this._JAWS,
|
||||
_this._stage,
|
||||
regionJson,
|
||||
_this._prjRootPath,
|
||||
_this._prjJson,
|
||||
_this._prjCreds
|
||||
);
|
||||
|
||||
return deployer.deploy()
|
||||
.then(function(url) {
|
||||
JawsCli.log('Endpoint Deployer: Endpoints for stage "'
|
||||
+ _this._stage
|
||||
+ '" successfully deployed to API Gateway in the region "'
|
||||
+ regionJson.region
|
||||
+ '". Access them @ '
|
||||
+ url);
|
||||
});
|
||||
})
|
||||
.then(function() {
|
||||
// Untag All tagged endpoints
|
||||
let CmdTag = new Tag(_this._JAWS, 'endpoint');
|
||||
return _this._allTagged ? CmdTag.tagAll(true) : Tag.tag('endpoint', null, true);
|
||||
});
|
||||
return deployer.deploy()
|
||||
.then(function(url) {
|
||||
JawsCli.log('Endpoint Deployer: Endpoints for stage "'
|
||||
+ _this._stage
|
||||
+ '" successfully deployed to API Gateway in the region "'
|
||||
+ regionJson.region
|
||||
+ '". Access them @ '
|
||||
+ url);
|
||||
});
|
||||
})
|
||||
.then(function() {
|
||||
// Untag All tagged endpoints
|
||||
let CmdTag = new Tag(_this._JAWS, 'endpoint');
|
||||
return _this._allTagged ? CmdTag.tagAll(true) : Tag.tag('endpoint', null, true);
|
||||
});
|
||||
}
|
||||
|
||||
_promptStage() {
|
||||
@ -933,11 +933,11 @@ const CMD = class DeployEndpoint extends ProjectCmd {
|
||||
}
|
||||
|
||||
return JawsCli.select('Select a stage to deploy to: ', choices, false)
|
||||
.then(function(selectedStages) {
|
||||
if (selectedStages && (selectedStages.length > 0)) {
|
||||
_this._stage = selectedStages[0].value;
|
||||
}
|
||||
});
|
||||
.then(function(selectedStages) {
|
||||
if (selectedStages && (selectedStages.length > 0)) {
|
||||
_this._stage = selectedStages[0].value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_promptRegions() {
|
||||
|
||||
@ -15,7 +15,7 @@ const GlobalCmd = require('./GlobalCmd'),
|
||||
|
||||
function simulateNodeJs(awsmJson, handler, event) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
let lambdaName = utils.generateLambdaName(awsmJson);
|
||||
let lambdaName = utils.getLambdaName(awsmJson);
|
||||
|
||||
utils.jawsDebug('Testing', lambdaName);
|
||||
handler(event, context(lambdaName, function(err, result) {
|
||||
|
||||
@ -1,24 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
//TODO: make this extend GlobalCmd but it will require some decent sized refactoring in bin/jaws
|
||||
//plus need to handle if CWD is in a jaws project, to intelligently create it in aws_modules
|
||||
//TODO: account for changes in new awsm.json structure
|
||||
|
||||
/**
|
||||
* Create jaws module
|
||||
*
|
||||
*/
|
||||
const ProjectCmd = require('./ProjectCmd.js'),
|
||||
JawsError = require('../jaws-error'),
|
||||
JawsCLI = require('../utils/cli'),
|
||||
Promise = require('bluebird'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
utils = require('../utils');
|
||||
JawsError = require('../jaws-error'),
|
||||
JawsCLI = require('../utils/cli'),
|
||||
Promise = require('bluebird'),
|
||||
fs = require('fs'),
|
||||
path = require('path'),
|
||||
utils = require('../utils');
|
||||
|
||||
let supportedRuntimes = {
|
||||
nodejs: {
|
||||
defaultPkgMgr: 'npm',
|
||||
validPkgMgrs: ['npm']
|
||||
validPkgMgrs: ['npm']
|
||||
}
|
||||
};
|
||||
|
||||
@ -38,20 +37,20 @@ const CMD = class ModuleCreate extends ProjectCmd {
|
||||
throw new JawsError(`Unsupported runtime "${runtime}"`, JawsError.errorCodes.UNKNOWN);
|
||||
}
|
||||
|
||||
let _this = this,
|
||||
let _this = this,
|
||||
supportedRuntimeObj = supportedRuntimes[runtime];
|
||||
|
||||
this._module = {
|
||||
name: name,
|
||||
this._module = {
|
||||
name: name,
|
||||
runtime: runtime,
|
||||
action: action,
|
||||
pkgMgr: pkgMgr,
|
||||
action: action,
|
||||
pkgMgr: pkgMgr,
|
||||
modType: modType,
|
||||
};
|
||||
this._prompts = {
|
||||
this._prompts = {
|
||||
properties: {},
|
||||
};
|
||||
this.Prompter = JawsCLI.prompt();
|
||||
this.Prompter = JawsCLI.prompt();
|
||||
this.Prompter.override = {};
|
||||
|
||||
if (pkgMgr && supportedRuntimeObj.validPkgMgrs.indexOf(_this._module.pkgMgr) == -1) {
|
||||
@ -81,14 +80,14 @@ const CMD = class ModuleCreate extends ProjectCmd {
|
||||
* @private
|
||||
*/
|
||||
_createPackageMgrSkeleton() {
|
||||
let _this = this,
|
||||
let _this = this,
|
||||
deferredWrites = [];
|
||||
|
||||
switch (_this._module.runtime) {
|
||||
case 'nodejs':
|
||||
if (_this._module.pkgMgr == 'npm') {
|
||||
|
||||
let modulePath = path.join(
|
||||
let modulePath = path.join(
|
||||
_this._JAWS._meta.projectRootPath, //TOOD: make this CWD if not in a JAWS project
|
||||
'node_modules',
|
||||
_this._module.name);
|
||||
@ -101,9 +100,9 @@ const CMD = class ModuleCreate extends ProjectCmd {
|
||||
|
||||
// Create module package.json if DNE in node_module
|
||||
if (!utils.fileExistsSync(path.join(modulePath, 'package.json'))) {
|
||||
let packageJsonTemplate = utils.readAndParseJsonSync(path.join(templatesPath, 'nodejs', 'package.json'));
|
||||
packageJsonTemplate.name = _this._name;
|
||||
packageJsonTemplate.description = 'An aws-module';
|
||||
let packageJsonTemplate = utils.readAndParseJsonSync(path.join(templatesPath, 'nodejs', 'package.json'));
|
||||
packageJsonTemplate.name = _this._name;
|
||||
packageJsonTemplate.description = 'An aws-module';
|
||||
packageJsonTemplate.dependencies = {};
|
||||
if (packageJsonTemplate.private) delete packageJsonTemplate.private;
|
||||
deferredWrites.push(
|
||||
@ -116,7 +115,7 @@ const CMD = class ModuleCreate extends ProjectCmd {
|
||||
|
||||
// Create module awsm.json if DNE in node_module
|
||||
if (!utils.fileExistsSync(path.join(modulePath, 'awsm.json'))) {
|
||||
let moduleTemplateJson = utils.readAndParseJsonSync(path.join(templatesPath, 'module.awsm.json'));
|
||||
let moduleTemplateJson = utils.readAndParseJsonSync(path.join(templatesPath, 'module.awsm.json'));
|
||||
moduleTemplateJson.name = _this._module.name;
|
||||
deferredWrites.push(
|
||||
utils.writeFile(
|
||||
@ -145,11 +144,11 @@ const CMD = class ModuleCreate extends ProjectCmd {
|
||||
'action.awsm.json'));
|
||||
|
||||
// Create action awsm.json
|
||||
actionTemplateJson.apiGateway.cloudFormation.Path = _this._module.name + '/' + _this._module.action;
|
||||
actionTemplateJson.apiGateway.cloudFormation.Path = _this._module.name + '/' + _this._module.action;
|
||||
actionTemplateJson.apiGateway.cloudFormation.Method = 'GET';
|
||||
actionTemplateJson.apiGateway.cloudFormation.Type = 'AWS';
|
||||
actionTemplateJson.lambda.cloudFormation.Runtime = 'nodejs';
|
||||
actionTemplateJson.lambda.cloudFormation.Handler = path.join(
|
||||
actionTemplateJson.apiGateway.cloudFormation.Type = 'AWS';
|
||||
actionTemplateJson.lambda.cloudFormation.Runtime = 'nodejs';
|
||||
actionTemplateJson.lambda.cloudFormation.Handler = path.join(
|
||||
'aws_modules',
|
||||
_this._module.name,
|
||||
_this._module.action,
|
||||
@ -157,7 +156,7 @@ const CMD = class ModuleCreate extends ProjectCmd {
|
||||
|
||||
// Create handler.js, index.js, event.json, package.json
|
||||
let handlerJs = fs.readFileSync(path.join(templatesPath, 'nodejs', 'handler.js'));
|
||||
let indexJs = fs.readFileSync(path.join(templatesPath, 'nodejs', 'index.js'));
|
||||
let indexJs = fs.readFileSync(path.join(templatesPath, 'nodejs', 'index.js'));
|
||||
|
||||
deferredWrites.push(
|
||||
utils.writeFile(
|
||||
@ -201,17 +200,17 @@ const CMD = class ModuleCreate extends ProjectCmd {
|
||||
* @private
|
||||
*/
|
||||
_createSkeleton() {
|
||||
let _this = this,
|
||||
let _this = this,
|
||||
writeFilesDeferred = [];
|
||||
|
||||
// Fetch skeleton resources
|
||||
let templatesPath = path.join(__dirname, '..', 'templates');
|
||||
let templatesPath = path.join(__dirname, '..', 'templates');
|
||||
let actionTemplateJson = utils.readAndParseJsonSync(path.join(templatesPath, 'action.awsm.json'));
|
||||
let modulePath = path.join(
|
||||
let modulePath = path.join(
|
||||
_this._JAWS._meta.projectRootPath, //TOOD: make this CWD if not in a JAWS project
|
||||
'aws_modules',
|
||||
_this._module.name);
|
||||
let actionPath = path.join(modulePath, _this._module.action);
|
||||
let actionPath = path.join(modulePath, _this._module.action);
|
||||
|
||||
// If module/action already exists, throw error
|
||||
if (utils.dirExistsSync(actionPath)) {
|
||||
@ -225,7 +224,7 @@ const CMD = class ModuleCreate extends ProjectCmd {
|
||||
|
||||
// If module awsm.json doesn't exist, create it
|
||||
if (!utils.fileExistsSync(path.join(modulePath, 'awsm.json'))) {
|
||||
let moduleTemplateJson = utils.readAndParseJsonSync(path.join(templatesPath, 'module.awsm.json'));
|
||||
let moduleTemplateJson = utils.readAndParseJsonSync(path.join(templatesPath, 'module.awsm.json'));
|
||||
moduleTemplateJson.name = _this._module.name;
|
||||
writeFilesDeferred.push(
|
||||
utils.writeFile(
|
||||
@ -237,11 +236,17 @@ const CMD = class ModuleCreate extends ProjectCmd {
|
||||
writeFilesDeferred.push(actionPath);
|
||||
|
||||
// Create action awsm.json
|
||||
actionTemplateJson.apiGateway.cloudFormation.Path = _this._module.name + '/' + _this._module.action;
|
||||
actionTemplateJson.apiGateway.cloudFormation.Path = _this._module.name + '/' + _this._module.action;
|
||||
actionTemplateJson.apiGateway.cloudFormation.Method = 'GET';
|
||||
actionTemplateJson.apiGateway.cloudFormation.Type = 'AWS';
|
||||
actionTemplateJson.apiGateway.cloudFormation.Type = 'AWS';
|
||||
|
||||
if (['lambda', 'both'].indexOf(_this._module.modType) != -1) {
|
||||
//We prefix with an l to make sure the CloudFormation resource map index is unique
|
||||
//we will probably have API gateway resources in their own CF JSON but we dont want to
|
||||
//make that decsision until CF has API gateway support
|
||||
actionTemplateJson.lambda.name = 'l' + _this._module.name.charAt(0).toUpperCase() + _this._module.name.slice(1) + _this._module.action.charAt(0).toUpperCase() + _this._module.action.slice(1);
|
||||
actionTemplateJson.lambda.cloudFormation.Runtime = _this._module.runtime;
|
||||
|
||||
// Create files for lambda actions
|
||||
switch (_this._module.runtime) {
|
||||
case 'nodejs':
|
||||
@ -256,7 +261,7 @@ const CMD = class ModuleCreate extends ProjectCmd {
|
||||
|
||||
// Create handler.js, index.js, event.json, package.json
|
||||
let handlerJs = fs.readFileSync(path.join(templatesPath, 'nodejs', 'handler.js'));
|
||||
let indexJs = fs.readFileSync(path.join(templatesPath, 'nodejs', 'index.js'));
|
||||
let indexJs = fs.readFileSync(path.join(templatesPath, 'nodejs', 'index.js'));
|
||||
|
||||
writeFilesDeferred.push(
|
||||
utils.writeFile(path.join(actionPath, 'handler.js'), handlerJs),
|
||||
|
||||
@ -164,7 +164,7 @@ CMD.prototype._prepareResources = Promise.method(function() {
|
||||
key: ' L) ',
|
||||
value: jsonPaths[i],
|
||||
type: 'lambda',
|
||||
label: JawsUtils.generateLambdaName(json),
|
||||
label: JawsUtils.getLambdaName(json),
|
||||
};
|
||||
|
||||
// Create path
|
||||
|
||||
196
lib/defaults/actions/AliasLambda.js
Normal file
196
lib/defaults/actions/AliasLambda.js
Normal file
@ -0,0 +1,196 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Action: AliasLambda
|
||||
*/
|
||||
|
||||
const JawsPlugin = require('../../JawsPlugin'),
|
||||
JawsError = require('../../jaws-error'),
|
||||
JawsCLI = require('../../utils/cli'),
|
||||
BbPromise = require('bluebird'),
|
||||
path = require('path'),
|
||||
os = require('os'),
|
||||
AWSUtils = require('../../utils/aws'),
|
||||
JawsUtils = require('../../utils/index');
|
||||
|
||||
let fs = require('fs');
|
||||
BbPromise.promisifyAll(fs);
|
||||
|
||||
class AliasLambda extends JawsPlugin {
|
||||
|
||||
/**
|
||||
* @param Jaws class object
|
||||
* @param config object
|
||||
*/
|
||||
|
||||
constructor(Jaws, config) {
|
||||
super(Jaws, config);
|
||||
this._stage = null;
|
||||
this._region = null;
|
||||
this._lambdaLogicalIdsToAlias = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Define your plugins name
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
static getName() {
|
||||
return 'jaws.core.' + AliasLambda.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise} upon completion of all registrations
|
||||
*/
|
||||
|
||||
registerActions() {
|
||||
this.Jaws.action(this.lambdaCreateAlias.bind(this), {
|
||||
handler: 'lambdaCreateAlias',
|
||||
description: `Version lambda at CWD
|
||||
usage: jaws lambda alias <version> <aliasName>`,
|
||||
context: 'lambda',
|
||||
contextAction: 'alias',
|
||||
options: [
|
||||
{
|
||||
option: 'stage',
|
||||
shortcut: 's',
|
||||
description: 'Optional if only one stage is defined in project'
|
||||
}, {
|
||||
option: 'region',
|
||||
shortcut: 'r',
|
||||
description: 'Optional. Default is to version lambda in all regions defined in stage'
|
||||
}
|
||||
],
|
||||
});
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param stage Optional if only one stage is defined in project
|
||||
* @param region Optional. Default is to version lambda in all regions defined in stage
|
||||
* @param verAndAliasName <Array> version, aliasName
|
||||
* @returns {Promise.<Array>}
|
||||
*/
|
||||
lambdaCreateAlias(stage, region) {
|
||||
let _this = this,
|
||||
verAliasName = Array.prototype.slice.call(arguments, 3);
|
||||
|
||||
if (!verAliasNameAndPaths || verAliasName.length !== 2) {
|
||||
return Promise.reject(new JawsError('Must specify a lambda version and alias name'));
|
||||
}
|
||||
|
||||
this._stage = stage;
|
||||
this._region = region; //may not be set
|
||||
|
||||
return this._JAWS.validateProject()
|
||||
.bind(_this)
|
||||
.then(_this._promptStage)
|
||||
.then(() => {
|
||||
JawsUtils.jawsDebug('publishing version for stage:', _this._stage);
|
||||
return _this._setLambdaLogicalIds(lambdaPaths);
|
||||
})
|
||||
.then(_this._getRegions)
|
||||
.each(region => {
|
||||
//1) For each region, get all the lambdas for stack
|
||||
let lStackName = AWSUtils.cfGetLambdasStackName(_this._stage, _this._JAWS._projectJson.name);
|
||||
return AWSUtils.cfGetLambdaResourceSummaries(_this.Jaws._profile, region, lStackName)
|
||||
.then(lambdaSummaries => {
|
||||
//2) identify physical function names from logical
|
||||
return AWSUtils.cfGetLambdaPhysicalsFromLogicals(_this._lambdaLogicalIdsToAlias, lambdaSummaries);
|
||||
})
|
||||
.then(lambdaNamesToVersion => {
|
||||
//3) publishVersions
|
||||
return AWSUtils.lambdaCreateAliass(_this.Jaws._profile, region, lambdaNamesToVersion);
|
||||
});
|
||||
})
|
||||
.then(versionedLambdas => {
|
||||
JawsCLI.log('Lambda AliasLambda: Successfully published following lambda versions to the requested regions:');
|
||||
JawsCLI.log(versionedLambdas);
|
||||
return versionedLambdas;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {Promise}
|
||||
* @private
|
||||
*/
|
||||
_promptStage() {
|
||||
let stages = [],
|
||||
_this = this;
|
||||
|
||||
// If stage exists, skip
|
||||
if (!this._stage) {
|
||||
stages = Object.keys(_this.JAWS._projectJson.stages);
|
||||
|
||||
// If project only has 1 stage, skip prompt
|
||||
if (stages.length === 1) {
|
||||
this._stage = stages[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (this._stage) { //User specified stage or only one stage
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Create Choices
|
||||
let choices = [];
|
||||
for (let i = 0; i < stages.length; i++) {
|
||||
choices.push({
|
||||
key: '',
|
||||
value: stages[i],
|
||||
label: stages[i],
|
||||
});
|
||||
}
|
||||
|
||||
return this.selectInput('AliasLambda: Choose a stage: ', choices, false)
|
||||
.then(results => {
|
||||
_this._stage = results[0].value;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* this._stage must be set before calling this method
|
||||
* @returns {Promise} list of regions
|
||||
* @private
|
||||
*/
|
||||
_getRegions() {
|
||||
if (this._region) { //user specified specific region to deploy to
|
||||
JawsUtils.jawsDebug('Deploying to region: ' + this._region);
|
||||
return BbPromise.resolve([region]);
|
||||
}
|
||||
|
||||
//Deploy to all regions in stage
|
||||
|
||||
let stage = this._stage,
|
||||
projJson = this.JAWS._projectJson;
|
||||
|
||||
let regionConfigs = projJson.stages[stage],
|
||||
regions = regionConfigs.map(rCfg => {
|
||||
return rCfg.region;
|
||||
});
|
||||
|
||||
JawsUtils.jawsDebug('Publishing version to regions:', regions);
|
||||
return BbPromise.resolve(regions);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param lambdaPaths [] optional abs or rel (to cwd) paths to lambda dirs. If ommitted deploys lambda @ cwd
|
||||
* @return {Promise}
|
||||
* @private
|
||||
*/
|
||||
_setLambdaLogicalIds(lambdaPaths) {
|
||||
let _this = this;
|
||||
return JawsUtils.getFullLambdaPaths(process.cwd(), lambdaPaths)
|
||||
.then(fullAwsmJsonPaths => {
|
||||
_this._lambdaLogicalIdsToAlias = fullAwsmJsonPaths.map(alp => {
|
||||
let awsmJson = JawsUtils.readAndParseJsonSync(alp);
|
||||
return JawsUtils.getLambdaName(awsmJson);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AliasLambda;
|
||||
@ -41,91 +41,91 @@ class Deployer {
|
||||
awsmLambdas = [];
|
||||
|
||||
return BbPromise.try(function() {
|
||||
})
|
||||
.bind(_this)
|
||||
.then(function() {
|
||||
return _this._lambdaAwsmPaths;
|
||||
})
|
||||
.each(function(lambdaAwsmPath) {
|
||||
let packager = new Packager(
|
||||
_this._JAWS,
|
||||
_this._stage,
|
||||
_this._region,
|
||||
lambdaAwsmPath
|
||||
);
|
||||
|
||||
return BbPromise.try(function() {
|
||||
})
|
||||
.bind(_this)
|
||||
.then(function() {
|
||||
return packager.run();
|
||||
})
|
||||
.then(function(packagedLambda) {
|
||||
let jawsBucket = _this._JAWS.getJawsBucket(_this._region, _this._stage);
|
||||
JawsCLI.log('Lambda Deployer: Uploading ' + packagedLambda.lambdaName + ` to ${jawsBucket}`);
|
||||
|
||||
return AWSUtils.putLambdaZip(
|
||||
_this._JAWS._profile,
|
||||
_this._region,
|
||||
jawsBucket,
|
||||
projName,
|
||||
})
|
||||
.bind(_this)
|
||||
.then(function() {
|
||||
return _this._lambdaAwsmPaths;
|
||||
})
|
||||
.each(function(lambdaAwsmPath) {
|
||||
let packager = new Packager(
|
||||
_this._JAWS,
|
||||
_this._stage,
|
||||
packagedLambda.lambdaName,
|
||||
packagedLambda.zipBuffer
|
||||
)
|
||||
.then(function(s3Key) {
|
||||
awsmLambdas.push({
|
||||
awsmPath: lambdaAwsmPath,
|
||||
Code: {
|
||||
S3Bucket: jawsBucket,
|
||||
S3Key: s3Key,
|
||||
},
|
||||
lambdaName: packagedLambda.lambdaName,
|
||||
});
|
||||
_this._region,
|
||||
lambdaAwsmPath
|
||||
);
|
||||
|
||||
return BbPromise.try(function() {
|
||||
})
|
||||
.bind(_this)
|
||||
.then(function() {
|
||||
return packager.run();
|
||||
})
|
||||
.then(function(packagedLambda) {
|
||||
let jawsBucket = _this._JAWS.getJawsBucket(_this._region, _this._stage);
|
||||
JawsCLI.log('Lambda Deployer: Uploading ' + packagedLambda.lambdaName + ` to ${jawsBucket}`);
|
||||
|
||||
return AWSUtils.putLambdaZip(
|
||||
_this._JAWS._profile,
|
||||
_this._region,
|
||||
jawsBucket,
|
||||
projName,
|
||||
_this._stage,
|
||||
packagedLambda.lambdaName,
|
||||
packagedLambda.zipBuffer
|
||||
)
|
||||
.then(function(s3Key) {
|
||||
awsmLambdas.push({
|
||||
awsmPath: lambdaAwsmPath,
|
||||
Code: {
|
||||
S3Bucket: jawsBucket,
|
||||
S3Key: s3Key,
|
||||
},
|
||||
lambdaName: packagedLambda.lambdaName,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(function() {
|
||||
//At this point all packages have been created and uploaded to s3
|
||||
let lambdaRoleArn = JawsUtils
|
||||
.getProjRegionConfigForStage(_this._JAWS._projectJson, _this._stage, _this._region).iamRoleArnLambda;
|
||||
return [lambdaRoleArn, _this._generateLambdaCf(awsmLambdas, lambdaRoleArn)];
|
||||
})
|
||||
.spread(function(lambdaRoleArn, existingStack) {
|
||||
if (_this._noExeCf) {
|
||||
JawsCLI.log(`Lambda Deployer: not executing CloudFormation. Remember to set aaLambdaRoleArn parameter to ${lambdaRoleArn}`);
|
||||
return false;
|
||||
} else {
|
||||
let createOrUpdate,
|
||||
cfDeferred;
|
||||
|
||||
JawsUtils.jawsDebug(`Deploying with lambda role arn ${lambdaRoleArn}`);
|
||||
|
||||
if (existingStack) {
|
||||
cfDeferred = AWSUtils.cfUpdateLambdasStack(_this._JAWS, _this._stage, _this._region, lambdaRoleArn);
|
||||
createOrUpdate = 'update';
|
||||
})
|
||||
.then(function() {
|
||||
//At this point all packages have been created and uploaded to s3
|
||||
let lambdaRoleArn = JawsUtils
|
||||
.getProjRegionConfigForStage(_this._JAWS._projectJson, _this._stage, _this._region).iamRoleArnLambda;
|
||||
return [lambdaRoleArn, _this._generateLambdaCf(awsmLambdas, lambdaRoleArn)];
|
||||
})
|
||||
.spread(function(lambdaRoleArn, existingStack) {
|
||||
if (_this._noExeCf) {
|
||||
JawsCLI.log(`Lambda Deployer: not executing CloudFormation. Remember to set aaLambdaRoleArn parameter to ${lambdaRoleArn}`);
|
||||
return false;
|
||||
} else {
|
||||
cfDeferred = AWSUtils.cfCreateLambdasStack(_this._JAWS, _this._stage, _this._region, lambdaRoleArn);
|
||||
createOrUpdate = 'create';
|
||||
let createOrUpdate,
|
||||
cfDeferred;
|
||||
|
||||
JawsUtils.jawsDebug(`Deploying with lambda role arn ${lambdaRoleArn}`);
|
||||
|
||||
if (existingStack) {
|
||||
cfDeferred = AWSUtils.cfUpdateLambdasStack(_this._JAWS, _this._stage, _this._region, lambdaRoleArn);
|
||||
createOrUpdate = 'update';
|
||||
} else {
|
||||
cfDeferred = AWSUtils.cfCreateLambdasStack(_this._JAWS, _this._stage, _this._region, lambdaRoleArn);
|
||||
createOrUpdate = 'create';
|
||||
}
|
||||
|
||||
JawsCLI.log('Running CloudFormation lambda deploy...');
|
||||
let spinner = JawsCLI.spinner();
|
||||
spinner.start();
|
||||
|
||||
return cfDeferred
|
||||
.then(function(cfData) {
|
||||
return AWSUtils.monitorCf(cfData, _this._JAWS._profile, _this._region, createOrUpdate);
|
||||
})
|
||||
.then(function() {
|
||||
spinner.stop(true);
|
||||
});
|
||||
}
|
||||
|
||||
JawsCLI.log('Running CloudFormation lambda deploy...');
|
||||
let spinner = JawsCLI.spinner();
|
||||
spinner.start();
|
||||
|
||||
return cfDeferred
|
||||
.then(function(cfData) {
|
||||
return AWSUtils.monitorCf(cfData, _this._JAWS._profile, _this._region, createOrUpdate);
|
||||
})
|
||||
.then(function() {
|
||||
spinner.stop(true);
|
||||
});
|
||||
}
|
||||
})
|
||||
.then(function() {
|
||||
JawsCLI.log('Lambda Deployer: Done deploying lambdas in ' + _this._region);
|
||||
}
|
||||
);
|
||||
})
|
||||
.then(function() {
|
||||
JawsCLI.log('Lambda Deployer: Done deploying lambdas in ' + _this._region);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,83 +151,83 @@ class Deployer {
|
||||
projName = this._JAWS._projectJson.name;
|
||||
|
||||
return AWSUtils.cfGetLambdasStackTemplate(_this._JAWS._profile, _this._region, _this._stage, projName)
|
||||
.error(e => {
|
||||
if (e && ['ValidationError', 'ResourceNotFoundException'].indexOf(e.code) == -1) { //ValidationError if DNE
|
||||
console.error(
|
||||
'Error trying to fetch existing lambda cf stack for region', _this._region, 'stage', _this._stage, e
|
||||
.error(e => {
|
||||
if (e && ['ValidationError', 'ResourceNotFoundException'].indexOf(e.code) == -1) { //ValidationError if DNE
|
||||
console.error(
|
||||
'Error trying to fetch existing lambda cf stack for region', _this._region, 'stage', _this._stage, e
|
||||
);
|
||||
throw new JawsError(e.message, JawsError.errorCodes.UNKNOWN);
|
||||
}
|
||||
|
||||
JawsUtils.jawsDebug('no exsting lambda stack');
|
||||
existingStack = false;
|
||||
return false;
|
||||
})
|
||||
.then(cfTemplateBody => {
|
||||
let templatesPath = path.join(__dirname, '..', 'templates'),
|
||||
lambdaCf = JawsUtils.readAndParseJsonSync(path.join(templatesPath, 'lambdas-cf.json'));
|
||||
|
||||
delete lambdaCf.Resources.lTemplate;
|
||||
lambdaCf.Description = projName + " lambdas";
|
||||
lambdaCf.Parameters.aaLambdaRoleArn.Default = lambdaRoleArn;
|
||||
|
||||
//Always add lambdas tagged for deployment
|
||||
taggedLambdaPkgs.forEach(function(pkg) {
|
||||
let lResource = {
|
||||
Type: "AWS::Lambda::Function",
|
||||
Properties: {}
|
||||
},
|
||||
awsm = JawsUtils.readAndParseJsonSync(pkg.awsmPath);
|
||||
|
||||
lResource.Properties = awsm.lambda.cloudFormation;
|
||||
lResource.Properties.Code = pkg.Code;
|
||||
lResource.Properties.Role = {
|
||||
Ref: "aaLambdaRoleArn"
|
||||
};
|
||||
|
||||
JawsUtils.jawsDebug('adding Resource ' + pkg.lambdaName + ': ');
|
||||
JawsUtils.jawsDebug(lResource);
|
||||
|
||||
lambdaCf.Resources[pkg.lambdaName] = lResource;
|
||||
});
|
||||
|
||||
// If existing lambdas CF template
|
||||
if (cfTemplateBody) {
|
||||
JawsUtils.jawsDebug('existing stack detected');
|
||||
|
||||
// Find all lambdas in project, and copy ones that are in existing lambda-cf
|
||||
let existingTemplate = JSON.parse(cfTemplateBody);
|
||||
|
||||
return JawsUtils.getAllLambdaNames(_this._JAWS._projectRootPath)
|
||||
.then(allLambdaNames => {
|
||||
Object.keys(existingTemplate.Resources).forEach(resource => {
|
||||
|
||||
if (!lambdaCf.Resources[resource] && allLambdaNames.indexOf(resource) != -1) {
|
||||
JawsUtils.jawsDebug(`Adding exsiting lambda ${resource}`);
|
||||
lambdaCf.Resources[resource] = existingTemplate.Resources[resource];
|
||||
}
|
||||
});
|
||||
|
||||
return lambdaCf;
|
||||
});
|
||||
} else {
|
||||
return lambdaCf;
|
||||
}
|
||||
})
|
||||
.then(lambdaCfTemplate => {
|
||||
let lambdasCfPath = path.join(
|
||||
_this._JAWS._projectRootPath,
|
||||
'cloudformation',
|
||||
_this._stage,
|
||||
_this._region,
|
||||
'lambdas-cf.json'
|
||||
);
|
||||
throw new JawsError(e.message, JawsError.errorCodes.UNKNOWN);
|
||||
}
|
||||
|
||||
JawsUtils.jawsDebug('no exsting lambda stack');
|
||||
existingStack = false;
|
||||
return false;
|
||||
})
|
||||
.then(cfTemplateBody => {
|
||||
let templatesPath = path.join(__dirname, '..', 'templates'),
|
||||
lambdaCf = JawsUtils.readAndParseJsonSync(path.join(templatesPath, 'lambdas-cf.json'));
|
||||
JawsUtils.jawsDebug(`Wrting to ${lambdasCfPath}`);
|
||||
|
||||
delete lambdaCf.Resources.lTemplate;
|
||||
lambdaCf.Description = projName + " lambdas";
|
||||
lambdaCf.Parameters.aaLambdaRoleArn.Default = lambdaRoleArn;
|
||||
|
||||
//Always add lambdas tagged for deployment
|
||||
taggedLambdaPkgs.forEach(function(pkg) {
|
||||
let lResource = {
|
||||
Type: "AWS::Lambda::Function",
|
||||
Properties: {}
|
||||
},
|
||||
awsm = JawsUtils.readAndParseJsonSync(pkg.awsmPath);
|
||||
|
||||
lResource.Properties = awsm.lambda.cloudFormation;
|
||||
lResource.Properties.Code = pkg.Code;
|
||||
lResource.Properties.Role = {
|
||||
Ref: "aaLambdaRoleArn"
|
||||
};
|
||||
|
||||
JawsUtils.jawsDebug('adding Resource ' + pkg.lambdaName + ': ');
|
||||
JawsUtils.jawsDebug(lResource);
|
||||
|
||||
lambdaCf.Resources[pkg.lambdaName] = lResource;
|
||||
return JawsUtils.writeFile(lambdasCfPath, JSON.stringify(lambdaCfTemplate, null, 2))
|
||||
.then(() => existingStack);
|
||||
});
|
||||
|
||||
// If existing lambdas CF template
|
||||
if (cfTemplateBody) {
|
||||
JawsUtils.jawsDebug('existing stack detected');
|
||||
|
||||
// Find all lambdas in project, and copy ones that are in existing lambda-cf
|
||||
let existingTemplate = JSON.parse(cfTemplateBody);
|
||||
|
||||
return JawsUtils.getAllLambdaNames(_this._JAWS._projectRootPath)
|
||||
.then(allLambdaNames => {
|
||||
Object.keys(existingTemplate.Resources).forEach(resource => {
|
||||
|
||||
if (!lambdaCf.Resources[resource] && allLambdaNames.indexOf(resource) != -1) {
|
||||
JawsUtils.jawsDebug(`Adding exsiting lambda ${resource}`);
|
||||
lambdaCf.Resources[resource] = existingTemplate.Resources[resource];
|
||||
}
|
||||
});
|
||||
|
||||
return lambdaCf;
|
||||
});
|
||||
} else {
|
||||
return lambdaCf;
|
||||
}
|
||||
})
|
||||
.then(lambdaCfTemplate => {
|
||||
let lambdasCfPath = path.join(
|
||||
_this._JAWS._projectRootPath,
|
||||
'cloudformation',
|
||||
_this._stage,
|
||||
_this._region,
|
||||
'lambdas-cf.json'
|
||||
);
|
||||
|
||||
JawsUtils.jawsDebug(`Wrting to ${lambdasCfPath}`);
|
||||
|
||||
return JawsUtils.writeFile(lambdasCfPath, JSON.stringify(lambdaCfTemplate, null, 2))
|
||||
.then(() => existingStack);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,22 +251,22 @@ class Packager {
|
||||
this._lambdaName = this.createLambdaName();
|
||||
|
||||
return this._createDistFolder()
|
||||
.then(function() {
|
||||
.then(function() {
|
||||
|
||||
// Package by runtime
|
||||
switch (_this._awsmJson.lambda.cloudFormation.Runtime) {
|
||||
case 'nodejs':
|
||||
return _this._packageNodeJs()
|
||||
.then(function(packageData) {
|
||||
packageData.lambdaName = _this._lambdaName;
|
||||
return packageData;
|
||||
});
|
||||
break;
|
||||
default:
|
||||
return Promise.reject(new JawsError('Unsupported lambda runtime ' + _this._awsmJson.lambda.cloudFormation.Runtime));
|
||||
break;
|
||||
}
|
||||
});
|
||||
// Package by runtime
|
||||
switch (_this._awsmJson.lambda.cloudFormation.Runtime) {
|
||||
case 'nodejs':
|
||||
return _this._packageNodeJs()
|
||||
.then(function(packageData) {
|
||||
packageData.lambdaName = _this._lambdaName;
|
||||
return packageData;
|
||||
});
|
||||
break;
|
||||
default:
|
||||
return Promise.reject(new JawsError('Unsupported lambda runtime ' + _this._awsmJson.lambda.cloudFormation.Runtime));
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -277,7 +277,7 @@ class Packager {
|
||||
*/
|
||||
createLambdaName() {
|
||||
let _this = this,
|
||||
name = JawsUtils.generateLambdaName(_this._awsmJson);
|
||||
name = JawsUtils.getLambdaName(_this._awsmJson);
|
||||
|
||||
JawsUtils.jawsDebug(`computed lambdaName: ${name}`);
|
||||
return name;
|
||||
@ -306,42 +306,42 @@ class Packager {
|
||||
// Copy entire test project to temp folder
|
||||
_this._excludePatterns = _this._awsmJson.lambda.package.excludePatterns || [];
|
||||
wrench.copyDirSyncRecursive(
|
||||
_this._JAWS._projectRootPath,
|
||||
_this._distDir,
|
||||
{
|
||||
exclude: function(name, prefix) {
|
||||
if (!_this._excludePatterns.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let relPath = path.join(
|
||||
prefix.replace(_this._distDir, ''), name);
|
||||
|
||||
return _this._excludePatterns.some(sRegex => {
|
||||
relPath = (relPath.charAt(0) == path.sep) ? relPath.substr(1) : relPath;
|
||||
|
||||
let re = new RegExp(sRegex),
|
||||
matches = re.exec(relPath);
|
||||
|
||||
let willExclude = (matches && matches.length > 0);
|
||||
|
||||
if (willExclude) {
|
||||
JawsCLI.log(`Lambda Deployer: Excluding ${relPath}`);
|
||||
_this._JAWS._projectRootPath,
|
||||
_this._distDir,
|
||||
{
|
||||
exclude: function(name, prefix) {
|
||||
if (!_this._excludePatterns.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return willExclude;
|
||||
});
|
||||
},
|
||||
}
|
||||
let relPath = path.join(
|
||||
prefix.replace(_this._distDir, ''), name);
|
||||
|
||||
return _this._excludePatterns.some(sRegex => {
|
||||
relPath = (relPath.charAt(0) == path.sep) ? relPath.substr(1) : relPath;
|
||||
|
||||
let re = new RegExp(sRegex),
|
||||
matches = re.exec(relPath);
|
||||
|
||||
let willExclude = (matches && matches.length > 0);
|
||||
|
||||
if (willExclude) {
|
||||
JawsCLI.log(`Lambda Deployer: Excluding ${relPath}`);
|
||||
}
|
||||
|
||||
return willExclude;
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
JawsUtils.jawsDebug('Packaging stage & region:', _this._stage, _this._region);
|
||||
|
||||
// Get ENV file from S3
|
||||
return _this._JAWS.getEnvFile(_this._region, _this._stage)
|
||||
.then(function(s3ObjData) {
|
||||
fs.writeFileSync(path.join(_this._distDir, '.env'), s3ObjData.Body);
|
||||
});
|
||||
.then(function(s3ObjData) {
|
||||
fs.writeFileSync(path.join(_this._distDir, '.env'), s3ObjData.Body);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -355,30 +355,30 @@ class Packager {
|
||||
deferred = null;
|
||||
|
||||
if (_this._awsmJson.lambda.package
|
||||
&& _this._awsmJson.lambda.package.optimize
|
||||
&& _this._awsmJson.lambda.package.optimize.builder) {
|
||||
&& _this._awsmJson.lambda.package.optimize
|
||||
&& _this._awsmJson.lambda.package.optimize.builder) {
|
||||
|
||||
deferred = _this._optimizeNodeJs()
|
||||
.then(optimizedCodeBuffer => {
|
||||
.then(optimizedCodeBuffer => {
|
||||
|
||||
// Lambda freaks out if code doesnt end in newline
|
||||
let ocbWithNewline = optimizedCodeBuffer.concat(new Buffer('\n'));
|
||||
let envData = fs.readFileSync(path.join(_this._distDir, '.env'));
|
||||
// Lambda freaks out if code doesnt end in newline
|
||||
let ocbWithNewline = optimizedCodeBuffer.concat(new Buffer('\n'));
|
||||
let envData = fs.readFileSync(path.join(_this._distDir, '.env'));
|
||||
|
||||
let handlerFileName = _this._awsmJson.lambda.cloudFormation.Handler.split('.')[0],
|
||||
compressPaths = [
|
||||
let handlerFileName = _this._awsmJson.lambda.cloudFormation.Handler.split('.')[0],
|
||||
compressPaths = [
|
||||
|
||||
// handlerFileName is the full path lambda file including dir rel to back
|
||||
{fileName: handlerFileName + '.js', data: ocbWithNewline},
|
||||
{fileName: '.env', data: envData},
|
||||
];
|
||||
// handlerFileName is the full path lambda file including dir rel to back
|
||||
{fileName: handlerFileName + '.js', data: ocbWithNewline},
|
||||
{fileName: '.env', data: envData},
|
||||
];
|
||||
|
||||
if (_this._awsmJson.lambda.package.optimize.includePaths.length) {
|
||||
compressPaths = compressPaths.concat(_this._generateIncludePaths());
|
||||
}
|
||||
if (_this._awsmJson.lambda.package.optimize.includePaths.length) {
|
||||
compressPaths = compressPaths.concat(_this._generateIncludePaths());
|
||||
}
|
||||
|
||||
return _this._compressCode(compressPaths);
|
||||
});
|
||||
return _this._compressCode(compressPaths);
|
||||
});
|
||||
} else {
|
||||
// User chose not to optimize, zip up whatever is in back
|
||||
_this._awsmJson.lambda.package.optimize.includePaths = ['.'];
|
||||
@ -387,14 +387,14 @@ class Packager {
|
||||
}
|
||||
|
||||
return deferred
|
||||
.then(function(compressedCodeBuffer) {
|
||||
let zippedFilePath = path.join(_this._distDir, 'package.zip'); // Save for auditing;
|
||||
fs.writeFileSync(zippedFilePath, compressedCodeBuffer);
|
||||
.then(function(compressedCodeBuffer) {
|
||||
let zippedFilePath = path.join(_this._distDir, 'package.zip'); // Save for auditing;
|
||||
fs.writeFileSync(zippedFilePath, compressedCodeBuffer);
|
||||
|
||||
JawsCLI.log(`Lambda Deployer: Compressed lambda written to ${zippedFilePath}`);
|
||||
JawsCLI.log(`Lambda Deployer: Compressed lambda written to ${zippedFilePath}`);
|
||||
|
||||
return Promise.resolve({awsmFilePath: _this._lambdaPath, zipBuffer: compressedCodeBuffer});
|
||||
});
|
||||
return Promise.resolve({awsmFilePath: _this._lambdaPath, zipBuffer: compressedCodeBuffer});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -407,7 +407,7 @@ class Packager {
|
||||
let _this = this;
|
||||
|
||||
if (!_this._awsmJson.lambda.package.optimize
|
||||
|| !_this._awsmJson.lambda.package.optimize.builder) {
|
||||
|| !_this._awsmJson.lambda.package.optimize.builder) {
|
||||
return Promise.reject(new JawsError('Cant optimize for nodejs. lambda jaws.json does not have optimize.builder set'));
|
||||
}
|
||||
|
||||
@ -524,20 +524,20 @@ class Packager {
|
||||
let dirname = path.basename(p);
|
||||
|
||||
wrench
|
||||
.readdirSyncRecursive(fullPath)
|
||||
.forEach(file => {
|
||||
// Ignore certain files
|
||||
for (let i = 0; i < ignore.length; i++) {
|
||||
if (file.toLowerCase().indexOf(ignore[i]) > -1) return;
|
||||
}
|
||||
.readdirSyncRecursive(fullPath)
|
||||
.forEach(file => {
|
||||
// Ignore certain files
|
||||
for (let i = 0; i < ignore.length; i++) {
|
||||
if (file.toLowerCase().indexOf(ignore[i]) > -1) return;
|
||||
}
|
||||
|
||||
let filePath = [fullPath, file].join('/');
|
||||
if (fs.lstatSync(filePath).isFile()) {
|
||||
let pathInZip = path.join(dirname, file);
|
||||
JawsUtils.jawsDebug('Adding', pathInZip);
|
||||
compressPaths.push({fileName: pathInZip, data: fs.readFileSync(filePath)});
|
||||
}
|
||||
});
|
||||
let filePath = [fullPath, file].join('/');
|
||||
if (fs.lstatSync(filePath).isFile()) {
|
||||
let pathInZip = path.join(dirname, file);
|
||||
JawsUtils.jawsDebug('Adding', pathInZip);
|
||||
compressPaths.push({fileName: pathInZip, data: fs.readFileSync(filePath)});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -564,8 +564,8 @@ class Packager {
|
||||
|
||||
if (zippedData.length > 52428800) {
|
||||
Promise.reject(new JawsError(
|
||||
'Zip file is > the 50MB Lambda deploy limit (' + zippedData.length + ' bytes)',
|
||||
JawsError.errorCodes.ZIP_TOO_BIG)
|
||||
'Zip file is > the 50MB Lambda deploy limit (' + zippedData.length + ' bytes)',
|
||||
JawsError.errorCodes.ZIP_TOO_BIG)
|
||||
);
|
||||
}
|
||||
|
||||
@ -604,7 +604,8 @@ class DeployLambda extends JawsPlugin {
|
||||
registerActions() {
|
||||
this.Jaws.action(this.deployLambda.bind(this), {
|
||||
handler: 'lambdaDeploy',
|
||||
description: 'Deploy lambda at CWD or lambdas at specified paths',
|
||||
description: `Deploy lambda at CWD or lambdas at specified paths
|
||||
usage: jaws lambda deploy [rel or abs path to lambda dirs. default is cwd]`,
|
||||
context: 'lambda',
|
||||
contextAction: 'deploy',
|
||||
options: [
|
||||
@ -643,22 +644,22 @@ class DeployLambda extends JawsPlugin {
|
||||
this._noExeCf = (noExeCf == true || noExeCf == 'true');
|
||||
|
||||
return this._JAWS.validateProject()
|
||||
.bind(_this)
|
||||
.then(_this._promptStage)
|
||||
.then(_this._validate)
|
||||
.then(() => {
|
||||
JawsUtils.jawsDebug('Deploying to stage:', _this._stage);
|
||||
return _this._setLambdaAwsmPaths(lambdaPaths);
|
||||
})
|
||||
.then(_this._getRegions)
|
||||
.each(region => {
|
||||
let d = new Deployer(_this.JAWS, _this._lambdaAwsmPathsToDeploy, _this._stage, region, _this._noExeCf);
|
||||
return d.run();
|
||||
})
|
||||
.then(lambdaAwsmPkgs => {
|
||||
JawsCLI.log('Lambda Deployer: Successfully deployed lambdas to the requested regions!');
|
||||
return lambdaAwsmPkgs;
|
||||
});
|
||||
.bind(_this)
|
||||
.then(_this._promptStage)
|
||||
.then(_this._validate)
|
||||
.then(() => {
|
||||
JawsUtils.jawsDebug('Deploying to stage:', _this._stage);
|
||||
return _this._setLambdaAwsmPaths(lambdaPaths);
|
||||
})
|
||||
.then(_this._getRegions)
|
||||
.each(region => {
|
||||
let d = new Deployer(_this.JAWS, _this._lambdaAwsmPathsToDeploy, _this._stage, region, _this._noExeCf);
|
||||
return d.run();
|
||||
})
|
||||
.then(lambdaAwsmPkgs => {
|
||||
JawsCLI.log('Lambda Deployer: Successfully deployed lambdas to the requested regions!');
|
||||
return lambdaAwsmPkgs;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -695,9 +696,9 @@ class DeployLambda extends JawsPlugin {
|
||||
}
|
||||
|
||||
return this.selectInput('Lambda Deployer: Choose a stage: ', choices, false)
|
||||
.then(results => {
|
||||
_this._stage = results[0].value;
|
||||
});
|
||||
.then(results => {
|
||||
_this._stage = results[0].value;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -749,9 +750,9 @@ class DeployLambda extends JawsPlugin {
|
||||
_setLambdaAwsmPaths(lambdaPaths) {
|
||||
let _this = this;
|
||||
return JawsUtils.getFullLambdaPaths(process.cwd(), lambdaPaths)
|
||||
.then(fullAwsmJsonPaths => {
|
||||
_this._lambdaAwsmPathsToDeploy = fullAwsmJsonPaths;
|
||||
});
|
||||
.then(fullAwsmJsonPaths => {
|
||||
_this._lambdaAwsmPathsToDeploy = fullAwsmJsonPaths;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@ const JawsPlugin = require('../../JawsPlugin'),
|
||||
BbPromise = require('bluebird'),
|
||||
path = require('path'),
|
||||
os = require('os'),
|
||||
AWS = require('aws-sdk'),
|
||||
AWSUtils = require('../../utils/aws'),
|
||||
JawsUtils = require('../../utils/index');
|
||||
|
||||
@ -26,10 +25,9 @@ class VersionLambda extends JawsPlugin {
|
||||
|
||||
constructor(Jaws, config) {
|
||||
super(Jaws, config);
|
||||
this._stage = null;
|
||||
this._region = null;
|
||||
this._noExeCf = false;
|
||||
this._lambdaAwsmPathsToVersion = [];
|
||||
this._stage = null;
|
||||
this._region = null;
|
||||
this._lambdaLogicalIdsToVersion = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,7 +69,7 @@ class VersionLambda extends JawsPlugin {
|
||||
* @param stage Optional if only one stage is defined in project
|
||||
* @param region Optional. Default is to version lambda in all regions defined in stage
|
||||
* @param lambdaPaths [] optional abs or rel (to cwd) paths to lambda dirs. If ommitted versions lambda @ cwd
|
||||
* @returns {Promise.<T>}
|
||||
* @returns {Promise.<Array>}
|
||||
*/
|
||||
lambdaPublishVersion(stage, region) {
|
||||
let _this = this,
|
||||
@ -81,21 +79,31 @@ class VersionLambda extends JawsPlugin {
|
||||
this._region = region; //may not be set
|
||||
|
||||
return this._JAWS.validateProject()
|
||||
.bind(_this)
|
||||
.then(_this._promptStage)
|
||||
.then(() => {
|
||||
JawsUtils.jawsDebug('publishing version for stage:', _this._stage);
|
||||
return _this._setLambdaAwsmPaths(lambdaPaths);
|
||||
})
|
||||
.then(_this._getRegions)
|
||||
.each(region => {
|
||||
|
||||
})
|
||||
.then(versionedLambdas => {
|
||||
JawsCLI.log('Lambda Deployer: Successfully published lambda versions to the requested regions!');
|
||||
JawsCLI.log(versionedLambdas);
|
||||
return versionedLambdas;
|
||||
});
|
||||
.bind(_this)
|
||||
.then(_this._promptStage)
|
||||
.then(() => {
|
||||
JawsUtils.jawsDebug('publishing version for stage:', _this._stage);
|
||||
return _this._setLambdaLogicalIds(lambdaPaths);
|
||||
})
|
||||
.then(_this._getRegions)
|
||||
.each(region => {
|
||||
//1) For each region, get all the lambdas for stack
|
||||
let lStackName = AWSUtils.cfGetLambdasStackName(_this._stage, _this._JAWS._projectJson.name);
|
||||
return AWSUtils.cfGetLambdaResourceSummaries(_this.Jaws._profile, region, lStackName)
|
||||
.then(lambdaSummaries => {
|
||||
//2) identify physical function names from logical
|
||||
return AWSUtils.cfGetLambdaPhysicalsFromLogicals(_this._lambdaLogicalIdsToVersion, lambdaSummaries);
|
||||
})
|
||||
.then(lambdaNamesToVersion => {
|
||||
//3) publishVersions
|
||||
return AWSUtils.lambdaPublishVersions(_this.Jaws._profile, region, lambdaNamesToVersion);
|
||||
});
|
||||
})
|
||||
.then(versionedLambdas => {
|
||||
JawsCLI.log('Lambda VersionLambda: Successfully published following lambda versions to the requested regions:');
|
||||
JawsCLI.log(versionedLambdas);
|
||||
return versionedLambdas;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,9 +140,9 @@ class VersionLambda extends JawsPlugin {
|
||||
}
|
||||
|
||||
return this.selectInput('VersionLambda: Choose a stage: ', choices, false)
|
||||
.then(results => {
|
||||
_this._stage = results[0].value;
|
||||
});
|
||||
.then(results => {
|
||||
_this._stage = results[0].value;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -168,12 +176,15 @@ class VersionLambda extends JawsPlugin {
|
||||
* @return {Promise}
|
||||
* @private
|
||||
*/
|
||||
_setLambdaAwsmPaths(lambdaPaths) {
|
||||
_setLambdaLogicalIds(lambdaPaths) {
|
||||
let _this = this;
|
||||
return JawsUtils.getFullLambdaPaths(process.cwd(), lambdaPaths)
|
||||
.then(fullAwsmJsonPaths => {
|
||||
_this._lambdaAwsmPathsToVersion = fullAwsmJsonPaths;
|
||||
});
|
||||
.then(fullAwsmJsonPaths => {
|
||||
_this._lambdaLogicalIdsToVersion = fullAwsmJsonPaths.map(alp => {
|
||||
let awsmJson = JawsUtils.readAndParseJsonSync(alp);
|
||||
return JawsUtils.getLambdaName(awsmJson);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,31 +1,55 @@
|
||||
{
|
||||
"lambda": {
|
||||
"envVars": [],
|
||||
"deploy": false,
|
||||
"package": {
|
||||
"optimize": {
|
||||
"builder": "browserify",
|
||||
"minify": true,
|
||||
"ignore": [],
|
||||
"exclude": [
|
||||
"aws-sdk"
|
||||
],
|
||||
"includePaths": []
|
||||
},
|
||||
"excludePatterns": []
|
||||
"name": "",
|
||||
"envVars": [],
|
||||
"package": {
|
||||
"optimize": {
|
||||
"builder": "browserify",
|
||||
"minify": true,
|
||||
"ignore": [],
|
||||
"exclude": [
|
||||
"aws-sdk"
|
||||
],
|
||||
"includePaths": []
|
||||
},
|
||||
"cloudFormation": {
|
||||
"Description": "",
|
||||
"Handler": "",
|
||||
"MemorySize": 1024,
|
||||
"Runtime": "nodejs",
|
||||
"Timeout": 6
|
||||
}
|
||||
"excludePatterns": []
|
||||
},
|
||||
"apiGateway": {
|
||||
"deploy": false,
|
||||
"cloudFormation": {
|
||||
"Type": "",
|
||||
"plugins": [],
|
||||
"cloudFormation": {
|
||||
"Lambda": {
|
||||
"Type": "AWS::Lambda::Function",
|
||||
"Properties": {
|
||||
"Handler": "",
|
||||
"Role": {
|
||||
"Ref": "aaLambdaRoleArn"
|
||||
},
|
||||
"Code": {
|
||||
"S3Bucket": "",
|
||||
"S3Key": ""
|
||||
},
|
||||
"Runtime": "nodejs",
|
||||
"Timeout": 6,
|
||||
"MemorySize": 1024
|
||||
}
|
||||
},
|
||||
"LambdaEventSourceMapping": {
|
||||
"Type": "AWS::Lambda::EventSourceMapping",
|
||||
"Properties": {
|
||||
"EventSourceArn": {},
|
||||
"FunctionName": "",
|
||||
"StartingPosition": ""
|
||||
}
|
||||
},
|
||||
"LambdaAccessPolicyX": {
|
||||
"Type": "AWS::Lambda::Permission",
|
||||
"Properties": {
|
||||
"FunctionName": "",
|
||||
"Action": "",
|
||||
"Principal": "",
|
||||
"SourceAccount": ""
|
||||
}
|
||||
},
|
||||
"APIGatewayEndpoint": {
|
||||
"Type": "AWS::ApiGateway::Endpoint",
|
||||
"Path": "",
|
||||
"Method": "GET",
|
||||
"AuthorizationType": "none",
|
||||
@ -33,16 +57,15 @@
|
||||
"RequestTemplates": {},
|
||||
"RequestParameters": {},
|
||||
"Responses": {
|
||||
"400": {
|
||||
"statusCode": "400"
|
||||
},
|
||||
"default": {
|
||||
"statusCode": "200",
|
||||
"responseParameters": {},
|
||||
"responseModels": {},
|
||||
"responseTemplates": {
|
||||
"application/json": ""
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"statusCode": "400"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
301
lib/utils/aws.js
301
lib/utils/aws.js
@ -53,8 +53,8 @@ module.exports.getConfigDir = function() {
|
||||
|
||||
let env = process.env;
|
||||
let home = env.HOME ||
|
||||
env.USERPROFILE ||
|
||||
(env.HOMEPATH ? ((env.HOMEDRIVE || 'C:/') + env.HOMEPATH) : null);
|
||||
env.USERPROFILE ||
|
||||
(env.HOMEPATH ? ((env.HOMEDRIVE || 'C:/') + env.HOMEPATH) : null);
|
||||
|
||||
if (!home) {
|
||||
throw new JawsError('Cant find homedir', JawsError.errorCodes.MISSING_HOMEDIR);
|
||||
@ -94,16 +94,16 @@ module.exports.profilesSet = function(awsProfile, awsRegion, accessKeyId, secret
|
||||
}
|
||||
|
||||
fs.appendFileSync(
|
||||
credsPath,
|
||||
`[${awsProfile}]
|
||||
credsPath,
|
||||
`[${awsProfile}]
|
||||
aws_access_key_id = ${accessKeyId.trim()}
|
||||
aws_secret_access_key = ${secretKey.trim()}\n`);
|
||||
|
||||
let profileNameForConfig = (awsProfile == 'default') ? 'default' : 'profile ' + awsProfile;
|
||||
|
||||
fs.appendFileSync(
|
||||
configPath,
|
||||
`[${profileNameForConfig}]
|
||||
configPath,
|
||||
`[${profileNameForConfig}]
|
||||
region = ${awsRegion}\n`);
|
||||
};
|
||||
|
||||
@ -152,8 +152,8 @@ exports.iamGetRole = function(awsProfile, awsRegion, roleName) {
|
||||
|
||||
if (error) {
|
||||
return reject(new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN));
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN));
|
||||
} else {
|
||||
return resolve(data);
|
||||
}
|
||||
@ -190,8 +190,8 @@ exports.cfDescribeStacks = function(awsProfile, awsRegion, stackName) {
|
||||
|
||||
if (error) {
|
||||
return reject(new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN));
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN));
|
||||
} else {
|
||||
return resolve(data);
|
||||
}
|
||||
@ -231,8 +231,8 @@ exports.cfDescribeStackResource = function(awsProfile, awsRegion, stackId, cfRes
|
||||
|
||||
if (error) {
|
||||
return reject(new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN));
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN));
|
||||
} else {
|
||||
return resolve(data);
|
||||
}
|
||||
@ -264,48 +264,131 @@ exports.cfListStackResources = function(awsProfile, awsRegion, stackName, nextTo
|
||||
return CF.listStackResourcesAsync(params);
|
||||
};
|
||||
|
||||
exports.cfGetLambdaNames = function(awsProfile, awsRegion, stackName) {
|
||||
/**
|
||||
* Returns data like:
|
||||
* [
|
||||
{
|
||||
"LogicalResourceId": "lChannelWxLatlng",
|
||||
"PhysicalResourceId": "prod-pushChannelSearch-l-lChannelWxLatlng-AS845QCZ8J1L",
|
||||
"ResourceType": "AWS::Lambda::Function",
|
||||
"LastUpdatedTimestamp": "2015-10-15T19:06:55.134Z",
|
||||
"ResourceStatus": "UPDATE_COMPLETE"
|
||||
},
|
||||
{
|
||||
"LogicalResourceId": "lChannelWxTypeahead",
|
||||
"PhysicalResourceId": "prod-pushChannelSearch-l-lChannelWxTypeahead-15NUNJF0O22HA",
|
||||
"ResourceType": "AWS::Lambda::Function",
|
||||
"LastUpdatedTimestamp": "2015-10-19T21:35:24.357Z",
|
||||
"ResourceStatus": "UPDATE_COMPLETE"
|
||||
}
|
||||
]
|
||||
|
||||
* @param awsProfile
|
||||
* @param awsRegion
|
||||
* @param stackName
|
||||
* @returns {Promise.<array>}
|
||||
*/
|
||||
exports.cfGetLambdaResourceSummaries = function(awsProfile, awsRegion, stackName) {
|
||||
let _this = this,
|
||||
moreResources = true,
|
||||
nextStackToken,
|
||||
lambdas = [];
|
||||
|
||||
async.whilst(
|
||||
function() {
|
||||
return moreResources === true;
|
||||
},
|
||||
function(callback) {
|
||||
_this.cfListStackResources(awsProfile, awsRegion, stackName, nextStackToken)
|
||||
.then(function(lambdaCfResources) {
|
||||
if (lambdaCfResources.StackResourceSummaries) {
|
||||
lambdas = lambdas.concat(lambdaCfResources.StackResourceSummaries);
|
||||
}
|
||||
return new Promise((resolve, reject)=> {
|
||||
async.whilst(
|
||||
function() {
|
||||
return moreResources === true;
|
||||
},
|
||||
function(callback) {
|
||||
_this.cfListStackResources(awsProfile, awsRegion, stackName, nextStackToken)
|
||||
.then(function(lambdaCfResources) {
|
||||
if (lambdaCfResources.StackResourceSummaries) {
|
||||
lambdas = lambdas.concat(lambdaCfResources.StackResourceSummaries);
|
||||
}
|
||||
|
||||
// Check if more resources are available
|
||||
if (!lambdaCfResources.NextToken) {
|
||||
moreResources = false;
|
||||
// Check if more resources are available
|
||||
if (!lambdaCfResources.NextToken) {
|
||||
moreResources = false;
|
||||
} else {
|
||||
nextStackToken = lambdaCfResources.NextToken;
|
||||
}
|
||||
|
||||
callback();
|
||||
})
|
||||
.catch(function(error) {
|
||||
JawsCli.log('Warning: JAWS could not find a deployed Cloudformation '
|
||||
+ 'template containing lambda functions.');
|
||||
console.log(error);
|
||||
moreResources = false;
|
||||
callback(error);
|
||||
});
|
||||
},
|
||||
function(err) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
nextStackToken = lambdaCfResources.NextToken;
|
||||
resolve(lambdas);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
callback();
|
||||
})
|
||||
.catch(function(error) {
|
||||
JawsCli.log('Warning: JAWS could not find a deployed Cloudformation '
|
||||
+ 'template containing lambda functions.');
|
||||
console.log(error);
|
||||
moreResources = false;
|
||||
callback(error);
|
||||
});
|
||||
},
|
||||
function(err) {
|
||||
if (err) {
|
||||
return Promise.reject(err);
|
||||
} else {
|
||||
return Promise.resolve(lambdas);
|
||||
}
|
||||
/**
|
||||
* Given a list of lambda LogicalResourceId's and a list of lambdaResourceSummaries
|
||||
* return a corresponding list of lambda PhysicalResourceId's
|
||||
*
|
||||
* @param logicalIds
|
||||
* @param lambdaResourceSummaries
|
||||
*/
|
||||
exports.cfGetLambdaPhysicalsFromLogicals = function(logicalIds, lambdaResourceSummaries) {
|
||||
let lambdaPhysicalIds = [];
|
||||
for (let lid of logicalIds) {
|
||||
let foundLambda = lambdaResourceSummaries.find(element=> {
|
||||
return element.LogicalResourceId == lid;
|
||||
});
|
||||
|
||||
if (!foundLambda) {
|
||||
throw new JawsError(`unable to find lambda with logical id ${lid}`, JawsError.errorCodes.UNKNOWN);
|
||||
}
|
||||
);
|
||||
|
||||
lambdaPhysicalIds.push(foundLambda.PhysicalResourceId);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrns [{FunctionName: d.FunctionName, Version: d.Version},...]
|
||||
* @param awsProfile
|
||||
* @param awsRegion
|
||||
* @param functionNames
|
||||
* @returns {Promise.<Array>}
|
||||
*/
|
||||
exports.lambdaPublishVersions = function(awsProfile, awsRegion, functionNames) {
|
||||
this.configAWS(awsProfile, awsRegion);
|
||||
|
||||
let L = Promise.promisifyAll(new AWS.Lambda({
|
||||
apiVersion: '2015-03-31',
|
||||
}));
|
||||
|
||||
let d = new Date(),
|
||||
ds = `versioned at ${d}`,
|
||||
deferreds = [];
|
||||
|
||||
functionNames.forEach(fn => {
|
||||
let params = {
|
||||
FunctionName: stackName,
|
||||
Description: ds
|
||||
};
|
||||
|
||||
deferreds.push(L.publishVersionAsync(params));
|
||||
});
|
||||
|
||||
return Promise.all(deferreds)
|
||||
.then(data => {
|
||||
return data.map(d => {
|
||||
return {FunctionName: d.FunctionName, Version: d.Version};
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -350,11 +433,11 @@ exports.cfGetLambdasStackTemplate = function(awsProfile, awsRegion, stage, projN
|
||||
}));
|
||||
|
||||
return CF.getTemplateAsync({
|
||||
StackName: _this.cfGetLambdasStackName(stage, projName)
|
||||
})
|
||||
.then(function(data) {
|
||||
return data.TemplateBody;
|
||||
});
|
||||
StackName: _this.cfGetLambdasStackName(stage, projName)
|
||||
})
|
||||
.then(function(data) {
|
||||
return data.TemplateBody;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -386,13 +469,13 @@ exports.putCfFile = function(awsProfile, projRootPath, awsRegion, bucketName, pr
|
||||
};
|
||||
|
||||
return this.putS3Object(awsProfile, awsRegion, params)
|
||||
.then(function() {
|
||||
//Really AWS - TemplateURL is an https:// URL. You force us to lookup endpt vs bucket/key attrs!?!? wtf not cool
|
||||
let s3 = new AWS.S3();
|
||||
.then(function() {
|
||||
//Really AWS - TemplateURL is an https:// URL. You force us to lookup endpt vs bucket/key attrs!?!? wtf not cool
|
||||
let s3 = new AWS.S3();
|
||||
|
||||
//Seriously, not cool...
|
||||
return 'https://' + s3.endpoint.hostname + `/${bucketName}/${key}`;
|
||||
})
|
||||
//Seriously, not cool...
|
||||
return 'https://' + s3.endpoint.hostname + `/${bucketName}/${key}`;
|
||||
})
|
||||
};
|
||||
|
||||
/**
|
||||
@ -434,10 +517,10 @@ exports.cfCreateLambdasStack = function(JAWS, stage, region, lambdaRoleArn) {
|
||||
};
|
||||
|
||||
return _this.putCfFile(awsProfile, projRootPath, region, bucketName, projName, stage, 'lambdas')
|
||||
.then(function(templateUrl) {
|
||||
params.TemplateURL = templateUrl;
|
||||
return CF.createStackAsync(params);
|
||||
});
|
||||
.then(function(templateUrl) {
|
||||
params.TemplateURL = templateUrl;
|
||||
return CF.createStackAsync(params);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -475,10 +558,10 @@ exports.cfUpdateLambdasStack = function(JAWS, stage, region, lambdaRoleArn) {
|
||||
};
|
||||
|
||||
return _this.putCfFile(awsProfile, projRootPath, region, bucketName, projName, stage, 'lambdas')
|
||||
.then(function(templateUrl) {
|
||||
params.TemplateURL = templateUrl;
|
||||
return CF.updateStackAsync(params);
|
||||
});
|
||||
.then(function(templateUrl) {
|
||||
params.TemplateURL = templateUrl;
|
||||
return CF.updateStackAsync(params);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -591,10 +674,10 @@ exports.cfUpdateResourcesStack = function(JAWS, stage, region) {
|
||||
};
|
||||
|
||||
return _this.putCfFile(awsProfile, projRootPath, region, bucketName, projName, stage, 'resources')
|
||||
.then(function(templateUrl) {
|
||||
params.TemplateURL = templateUrl;
|
||||
return CF.updateStackAsync(params);
|
||||
});
|
||||
.then(function(templateUrl) {
|
||||
params.TemplateURL = templateUrl;
|
||||
return CF.updateStackAsync(params);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -630,31 +713,31 @@ exports.monitorCf = function(cfData, awsProfile, region, createOrUpdate, checkFr
|
||||
stackData = null;
|
||||
|
||||
async.whilst(
|
||||
function() {
|
||||
return stackStatus !== stackStatusComplete;
|
||||
},
|
||||
function() {
|
||||
return stackStatus !== stackStatusComplete;
|
||||
},
|
||||
|
||||
function(callback) {
|
||||
setTimeout(function() {
|
||||
_this.cfDescribeStacks(awsProfile, region, cfData.StackId)
|
||||
.then(function(data) {
|
||||
stackData = data;
|
||||
stackStatus = stackData.Stacks[0].StackStatus;
|
||||
function(callback) {
|
||||
setTimeout(function() {
|
||||
_this.cfDescribeStacks(awsProfile, region, cfData.StackId)
|
||||
.then(function(data) {
|
||||
stackData = data;
|
||||
stackStatus = stackData.Stacks[0].StackStatus;
|
||||
|
||||
if (!stackStatus || validStatuses.indexOf(stackStatus) === -1) {
|
||||
console.log((data.Stacks && data.Stacks.length ? data.Stacks[0] : data));
|
||||
return reject(new JawsError(
|
||||
`Something went wrong while ${createOrUpdate}ing your cloudformation`));
|
||||
} else {
|
||||
return callback();
|
||||
}
|
||||
});
|
||||
}, checkFreq);
|
||||
},
|
||||
if (!stackStatus || validStatuses.indexOf(stackStatus) === -1) {
|
||||
console.log((data.Stacks && data.Stacks.length ? data.Stacks[0] : data));
|
||||
return reject(new JawsError(
|
||||
`Something went wrong while ${createOrUpdate}ing your cloudformation`));
|
||||
} else {
|
||||
return callback();
|
||||
}
|
||||
});
|
||||
}, checkFreq);
|
||||
},
|
||||
|
||||
function() {
|
||||
return resolve(stackData.Stacks[0]);
|
||||
}
|
||||
function() {
|
||||
return resolve(stackData.Stacks[0]);
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
@ -673,21 +756,21 @@ exports.createBucket = function(awsProfile, awsRegion, bucketName) {
|
||||
let s3 = Promise.promisifyAll(new AWS.S3());
|
||||
|
||||
return s3.getBucketAclAsync({Bucket: bucketName})
|
||||
.then(function() {
|
||||
})
|
||||
.error(function(err) {
|
||||
if (err.code == 'AccessDenied') {
|
||||
throw new JawsError(
|
||||
`Bucket ${bucketName} already exists and you do not have permissions to use it`,
|
||||
JawsError.errorCodes.ACCESS_DENIED
|
||||
);
|
||||
}
|
||||
.then(function() {
|
||||
})
|
||||
.error(function(err) {
|
||||
if (err.code == 'AccessDenied') {
|
||||
throw new JawsError(
|
||||
`Bucket ${bucketName} already exists and you do not have permissions to use it`,
|
||||
JawsError.errorCodes.ACCESS_DENIED
|
||||
);
|
||||
}
|
||||
|
||||
return s3.createBucketAsync({
|
||||
Bucket: bucketName,
|
||||
ACL: 'private',
|
||||
return s3.createBucketAsync({
|
||||
Bucket: bucketName,
|
||||
ACL: 'private',
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -784,9 +867,9 @@ exports.putLambdaZip = function(awsProfile, awsRegion, bucketName, projectName,
|
||||
utils.jawsDebug(`lambda zip s3 key: ${key}`);
|
||||
|
||||
return this.putS3Object(awsProfile, awsRegion, params)
|
||||
.then(function() {
|
||||
return key;
|
||||
});
|
||||
.then(function() {
|
||||
return key;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -815,8 +898,8 @@ exports.cwGetLogStreams = function(logGroupName, limit) {
|
||||
|
||||
if (error) {
|
||||
return reject(new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN));
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN));
|
||||
} else {
|
||||
return resolve(data);
|
||||
}
|
||||
@ -847,8 +930,8 @@ exports.cwGetStreamEvents = function(logGroupName, logStreamName) {
|
||||
cwLogs.getLogEvents(params, function(err, data) {
|
||||
if (error) {
|
||||
return reject(new JawsError(
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN));
|
||||
error.message,
|
||||
JawsError.errorCodes.UNKNOWN));
|
||||
} else {
|
||||
return resolve(data);
|
||||
}
|
||||
|
||||
@ -37,26 +37,26 @@ exports.findAllAwsmPathsOfType = function(startPath, type) {
|
||||
}
|
||||
|
||||
return _this.readRecursively(startPath, '*awsm.json')
|
||||
.then(function(jsonPaths) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
.then(function(jsonPaths) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
|
||||
let jawsPathsOfType = [];
|
||||
let jawsPathsOfType = [];
|
||||
|
||||
// Check each file to ensure it is a lambda
|
||||
async.eachLimit(jsonPaths, 10, function(jsonPath, cb) {
|
||||
let lambdaJawsPath = path.join(startPath, jsonPath),
|
||||
json = require(lambdaJawsPath);
|
||||
// Check each file to ensure it is a lambda
|
||||
async.eachLimit(jsonPaths, 10, function(jsonPath, cb) {
|
||||
let lambdaJawsPath = path.join(startPath, jsonPath),
|
||||
json = require(lambdaJawsPath);
|
||||
|
||||
if (typeof json[jawsJsonAttr] !== 'undefined') jawsPathsOfType.push(lambdaJawsPath);
|
||||
return cb();
|
||||
},
|
||||
if (typeof json[jawsJsonAttr] !== 'undefined') jawsPathsOfType.push(lambdaJawsPath);
|
||||
return cb();
|
||||
},
|
||||
|
||||
function(error) {
|
||||
if (error) reject(error);
|
||||
resolve(jawsPathsOfType);
|
||||
});
|
||||
function(error) {
|
||||
if (error) reject(error);
|
||||
resolve(jawsPathsOfType);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -102,15 +102,15 @@ exports.findProjectRootPath = function(startDir) {
|
||||
|
||||
exports.execute = function(promise) {
|
||||
promise
|
||||
.catch(JawsError, function(e) {
|
||||
console.error(e);
|
||||
process.exit(e.messageId);
|
||||
})
|
||||
.error(function(e) {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.done();
|
||||
.catch(JawsError, function(e) {
|
||||
console.error(e);
|
||||
process.exit(e.messageId);
|
||||
})
|
||||
.error(function(e) {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.done();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -128,15 +128,15 @@ exports.readRecursively = function(path, filter) {
|
||||
root: path,
|
||||
fileFilter: filter,
|
||||
})
|
||||
.on('data', function(entry) {
|
||||
files.push(entry.path);
|
||||
})
|
||||
.on('error', function(error) {
|
||||
reject(error);
|
||||
})
|
||||
.on('end', function() {
|
||||
resolve(files);
|
||||
});
|
||||
.on('data', function(entry) {
|
||||
files.push(entry.path);
|
||||
})
|
||||
.on('error', function(error) {
|
||||
reject(error);
|
||||
})
|
||||
.on('end', function() {
|
||||
resolve(files);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@ -171,24 +171,24 @@ exports.findAllEnvletsForAwsm = function(projectRootPath, modName) {
|
||||
let _this = this;
|
||||
|
||||
return this.findAllAwsmPathsOfType(path.join(projectRootPath, 'aws_modules', modName), 'lambda')
|
||||
.then(function(awsmJsonPaths) {
|
||||
let envletKeys = [];
|
||||
.then(function(awsmJsonPaths) {
|
||||
let envletKeys = [];
|
||||
|
||||
awsmJsonPaths.forEach(function(awsmJsonPath) {
|
||||
let awsmJson = _this.readAndParseJsonSync(awsmJsonPath);
|
||||
awsmJsonPaths.forEach(function(awsmJsonPath) {
|
||||
let awsmJson = _this.readAndParseJsonSync(awsmJsonPath);
|
||||
|
||||
//TODO: change to es6 set...
|
||||
if (awsmJson.lambda && awsmJson.lambda.envlets) {
|
||||
awsmJson.lambda.envlets.forEach(function(envlet) {
|
||||
if (envletKeys.indexOf(envlet) == -1) {
|
||||
envletKeys.push(envlet);
|
||||
}
|
||||
});
|
||||
}
|
||||
//TODO: change to es6 set...
|
||||
if (awsmJson.lambda && awsmJson.lambda.envlets) {
|
||||
awsmJson.lambda.envlets.forEach(function(envlet) {
|
||||
if (envletKeys.indexOf(envlet) == -1) {
|
||||
envletKeys.push(envlet);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return envletKeys;
|
||||
});
|
||||
|
||||
return envletKeys;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -199,11 +199,11 @@ exports.findAllEnvletsForAwsm = function(projectRootPath, modName) {
|
||||
*/
|
||||
exports.findAllAwsmJsons = function(startPath) {
|
||||
return this.readRecursively(startPath, '*awsm.json')
|
||||
.then(function(jsonPaths) {
|
||||
return jsonPaths.map(function(jsonPath) {
|
||||
return path.resolve(path.join(startPath, jsonPath));
|
||||
.then(function(jsonPaths) {
|
||||
return jsonPaths.map(function(jsonPath) {
|
||||
return path.resolve(path.join(startPath, jsonPath));
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -250,27 +250,19 @@ exports.writeFile = function(filePath, contents) {
|
||||
}
|
||||
|
||||
return mkdirpAsync(path.dirname(filePath))
|
||||
.then(function() {
|
||||
return fs.writeFileAsync(filePath, contents);
|
||||
});
|
||||
.then(function() {
|
||||
return fs.writeFileAsync(filePath, contents);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate Lambda Name
|
||||
* Get Lambda Name
|
||||
* @param awsmJson
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
exports.generateLambdaName = function(awsmJson) {
|
||||
let handlerName = awsmJson.lambda.cloudFormation.Handler.replace('aws_modules', ''),
|
||||
resourceAction = handlerName.substr(0, handlerName.lastIndexOf('/'));
|
||||
|
||||
//We prefix with an l to make sure the CloudFormation resource map index is unique
|
||||
//we will probably have API gateway resources in their own CF JSON but we dont want to
|
||||
//make that decsision until CF has API gateway support
|
||||
return 'l' + resourceAction.replace(/(\/|-|_)([a-z])/g, function(g) {
|
||||
return g[1].toUpperCase();
|
||||
});
|
||||
exports.getLambdaName = function(awsmJson) {
|
||||
return awsmJson.name;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -302,16 +294,16 @@ exports.getAllLambdaNames = function(projectRootPath) {
|
||||
lambdaNames = [];
|
||||
|
||||
return this.findAllLambdas(projectRootPath)
|
||||
.then(function(lambdaAwsmPaths) {
|
||||
lambdaAwsmPaths.forEach(function(ljp) {
|
||||
let awsm = _this.readAndParseJsonSync(ljp),
|
||||
lambdaName = _this.generateLambdaName(awsm);
|
||||
.then(function(lambdaAwsmPaths) {
|
||||
lambdaAwsmPaths.forEach(function(ljp) {
|
||||
let awsm = _this.readAndParseJsonSync(ljp),
|
||||
lambdaName = _this.getLambdaName(awsm);
|
||||
|
||||
lambdaNames.push(lambdaName);
|
||||
lambdaNames.push(lambdaName);
|
||||
});
|
||||
|
||||
return lambdaNames;
|
||||
});
|
||||
|
||||
return lambdaNames;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -392,8 +384,8 @@ exports.generateResourcesCf = function(projRootPath, projName, projDomain, stage
|
||||
cfTemplate.Description = projName + " resources";
|
||||
|
||||
return this.writeFile(
|
||||
path.join(projRootPath, 'cloudformation', stage, region, 'resources-cf.json'),
|
||||
JSON.stringify(cfTemplate, null, 2)
|
||||
path.join(projRootPath, 'cloudformation', stage, region, 'resources-cf.json'),
|
||||
JSON.stringify(cfTemplate, null, 2)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
17
tests/all.js
17
tests/all.js
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
//TODO: doc on needing to set env vars
|
||||
//TODO: must setup an env var file for unittest
|
||||
require('./config'); //init config
|
||||
|
||||
describe('All Tests', function() {
|
||||
@ -15,7 +13,7 @@ describe('All Tests', function() {
|
||||
});
|
||||
|
||||
//require tests vs inline so we can run sequentially
|
||||
require('./tests/TestPluginCustom');
|
||||
//require('./tests/TestPluginCustom');
|
||||
//require('./cli/tag');
|
||||
//require('./cli/env');
|
||||
//require('./cli/module_create');
|
||||
@ -24,10 +22,11 @@ describe('All Tests', function() {
|
||||
/**
|
||||
* Tests below create AWS Resources
|
||||
*/
|
||||
//require('./cli/dash');
|
||||
//require('./cli/deploy_lambda');
|
||||
//require('./cli/deploy_resources');
|
||||
//require('./cli/deploy_endpoint');
|
||||
//require('./cli/new_stage_region');
|
||||
require('./tests/TestActionProjectCreate');
|
||||
//require('./cli/dash');
|
||||
//require('./cli/deploy_lambda');
|
||||
//require('./cli/deploy_resources');
|
||||
//require('./cli/deploy_endpoint');
|
||||
//require('./cli/new_stage_region');
|
||||
//require('./tests/actions/ProjectCreate');
|
||||
require('./tests/actions/VersionLambda');
|
||||
});
|
||||
@ -1,25 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path'),
|
||||
AWS = require('aws-sdk');
|
||||
AWS = require('aws-sdk');
|
||||
|
||||
// Require ENV lets, can also set ENV lets in your IDE
|
||||
require('dotenv').config({path: path.join(__dirname, '.env'), silent: true});
|
||||
|
||||
process.env.JAWS_VERBOSE = true;
|
||||
process.env.DEBUG = '*';
|
||||
|
||||
let config = {
|
||||
name: 'test-prj',
|
||||
domain: 'test-prj.com',
|
||||
notifyEmail: 'tester@jawsstack.com',
|
||||
stage: 'unittest',
|
||||
region: 'us-east-1',
|
||||
stage2: 'unittest2',
|
||||
region2: 'us-west-2',
|
||||
name: 'test-prj',
|
||||
domain: process.env.TEST_JAWS_DOMAIN,
|
||||
notifyEmail: 'tester@jawsstack.com',
|
||||
stage: 'unittest',
|
||||
region: 'us-east-1',
|
||||
stage2: 'unittest2',
|
||||
region2: 'us-west-2',
|
||||
iamRoleArnApiGateway: process.env.TEST_JAWS_APIGATEWAY_ROLE,
|
||||
iamRoleArnLambda: process.env.TEST_JAWS_LAMBDA_ROLE,
|
||||
profile: process.env.TEST_JAWS_PROFILE,
|
||||
noExecuteCf: (process.env.TEST_JAWS_NO_EXE_CF != "false"),
|
||||
iamRoleArnLambda: process.env.TEST_JAWS_LAMBDA_ROLE,
|
||||
profile: process.env.TEST_JAWS_AWS_PROFILE,
|
||||
noExecuteCf: process.env.TEST_JAWS_EXE_CF != "true",
|
||||
};
|
||||
|
||||
AWS.config.credentials = new AWS.SharedIniFileCredentials({
|
||||
|
||||
@ -6,20 +6,20 @@
|
||||
* - Deletes the CF stack created by the project
|
||||
*/
|
||||
|
||||
let JAWS = require('../../lib/jaws.js'),
|
||||
JawsError = require('../../lib/jaws-error'),
|
||||
let JAWS = require('../../../lib/Jaws.js'),
|
||||
JawsError = require('../../../lib/jaws-error/index'),
|
||||
path = require('path'),
|
||||
os = require('os'),
|
||||
utils = require('../../lib/utils'),
|
||||
utils = require('../../../lib/utils/index'),
|
||||
assert = require('chai').assert,
|
||||
shortid = require('shortid'),
|
||||
config = require('../config');
|
||||
config = require('../../config');
|
||||
|
||||
// Instantiate JAWS
|
||||
let Jaws = new JAWS({
|
||||
awsAdminKeyId: '123',
|
||||
awsAdminKeyId: '123',
|
||||
awsAdminSecretKey: '123',
|
||||
interactive: false,
|
||||
interactive: false,
|
||||
});
|
||||
|
||||
describe('Test Plugin: Project Create', function() {
|
||||
@ -38,17 +38,17 @@ describe('Test Plugin: Project Create', function() {
|
||||
|
||||
this.timeout(0);
|
||||
|
||||
let name = 'jaws-test-' + shortid.generate().replace('_', '');
|
||||
let name = config.name + shortid.generate().replace('_', '');
|
||||
|
||||
Jaws.actions.projectCreate(
|
||||
name,
|
||||
name + '.com',
|
||||
'test',
|
||||
'us-east-1',
|
||||
'test@test.com',
|
||||
config.domain,
|
||||
config.stage,
|
||||
config.region,
|
||||
config.notifyEmail,
|
||||
'nodejs',
|
||||
true
|
||||
)
|
||||
config.noExecuteCf
|
||||
)
|
||||
.then(function() {
|
||||
let jawsJson = utils.readAndParseJsonSync(path.join(os.tmpdir(), name, 'jaws.json'));
|
||||
|
||||
79
tests/tests/actions/VersionLambda.js
Normal file
79
tests/tests/actions/VersionLambda.js
Normal file
@ -0,0 +1,79 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Test: Project Create Action
|
||||
* - Creates a new project in your system's temp directory
|
||||
* - Deletes the CF stack created by the project
|
||||
*/
|
||||
|
||||
//let JAWS = require('../../../lib/Jaws.js'),
|
||||
// JawsError = require('../../../lib/jaws-error/index'),
|
||||
// path = require('path'),
|
||||
// os = require('os'),
|
||||
// utils = require('../../../lib/utils/index'),
|
||||
// assert = require('chai').assert,
|
||||
// shortid = require('shortid'),
|
||||
// config = require('../../config');
|
||||
|
||||
//let Jaws = new JAWS();
|
||||
|
||||
let AwsUtils = require('../../../lib/utils/aws');
|
||||
|
||||
describe('Test Plugin: Version Lambda', function() {
|
||||
|
||||
before(function(done) {
|
||||
this.timeout(0);
|
||||
done();
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
done();
|
||||
});
|
||||
|
||||
describe('Test Plugin: Version lambda', function() {
|
||||
it('should create a new project in temp directory', function(done) {
|
||||
this.timeout(0);
|
||||
|
||||
//let name = config.name + shortid.generate().replace('_', '');
|
||||
//
|
||||
//Jaws.actions.projectCreate(
|
||||
// name,
|
||||
// config.domain,
|
||||
// config.stage,
|
||||
// config.region,
|
||||
// config.notifyEmail,
|
||||
// 'nodejs',
|
||||
// config.noExecuteCf
|
||||
// )
|
||||
// .then(function() {
|
||||
// let jawsJson = utils.readAndParseJsonSync(path.join(os.tmpdir(), name, 'jaws.json'));
|
||||
//
|
||||
// let region = false;
|
||||
//
|
||||
// for (let i = 0; i < jawsJson.stages[config.stage].length; i++) {
|
||||
// let stage = jawsJson.stages[config.stage][i];
|
||||
// if (stage.region === config.region) {
|
||||
// region = stage.region;
|
||||
// }
|
||||
// }
|
||||
// assert.isTrue(region !== false);
|
||||
// done();
|
||||
// })
|
||||
// .catch(JawsError, function(e) {
|
||||
// done(e);
|
||||
// })
|
||||
// .error(function(e) {
|
||||
// done(e);
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
//it('Delete Cloudformation stack from new project', function(done) {
|
||||
// this.timeout(0);
|
||||
// let CF = new config.AWS.CloudFormation();
|
||||
// CF.deleteStack({ StackName: config.stage + '-' + config.name }, function(err, data) {
|
||||
// if (err) console.log(err, err.stack);
|
||||
// done();
|
||||
// });
|
||||
//});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user