mirror of
https://github.com/serverless/serverless.git
synced 2026-02-01 16:07:28 +00:00
ProjectInit is now working
This commit is contained in:
parent
a146ef6c76
commit
40423b3b97
@ -181,6 +181,7 @@ class Project extends SerializerFileSystem {
|
||||
this.resources[ resources.getName() ] = resources;
|
||||
}
|
||||
|
||||
|
||||
getResources(resourcesName) {
|
||||
if (this.resources[resourcesName]) return this.resources[resourcesName];
|
||||
else return this.resources[Object.keys(this.resources)[0]]; // This temporarily defaults to a single resource stack for backward compatibility
|
||||
|
||||
@ -258,7 +258,7 @@ class ServerlessProviderAws {
|
||||
Bucket: bucketName
|
||||
};
|
||||
|
||||
return this.request('S3', 'getBucketAclPromised', params, stage, region)
|
||||
return this.request('S3', 'getBucketAcl', params, stage, region)
|
||||
.then(function(response) {
|
||||
SUtils.sDebug(`Project bucket already exists: ${bucketName}`);
|
||||
})
|
||||
@ -269,7 +269,7 @@ class ServerlessProviderAws {
|
||||
} else if (err.code == 'NoSuchBucket') {
|
||||
SCli.log('Creating your project bucket on S3: ' + bucketName + '...');
|
||||
params.ACL = 'private';
|
||||
return _this.request('S3', 'createBucketPromised', params, stage, region);
|
||||
return _this.request('S3', 'createBucket', params, stage, region);
|
||||
} else {
|
||||
throw new SError(err);
|
||||
}
|
||||
@ -288,9 +288,9 @@ class ServerlessProviderAws {
|
||||
|
||||
let _this = this;
|
||||
|
||||
return _this.findOrCreateProjectBucket()
|
||||
return _this.findOrCreateProjectBucket(params.Bucket, stage, region)
|
||||
.then(function() {
|
||||
SUtils.sDebug(`Uploading to project bucket: ${key}...`);
|
||||
SUtils.sDebug(`Uploading to project bucket: ${params.Bucket}...`);
|
||||
return _this.request('S3', 'upload', params, stage);
|
||||
});
|
||||
}
|
||||
|
||||
@ -15,7 +15,70 @@ class Resources extends SerializerFileSystem {
|
||||
this._class = 'Resources';
|
||||
this._config = config;
|
||||
this._partials = [];
|
||||
this.name = 'resources-' + SUtils.generateShortId(4);
|
||||
|
||||
this.AWSTemplateFormatVersion = "2010-09-09";
|
||||
this.Description = "The AWS CloudFormation template for this Serverless application's resources outside of Lambdas and Api Gateway";
|
||||
this.Resources = {
|
||||
"IamRoleLambda": {
|
||||
"Type": "AWS::IAM::Role",
|
||||
"Properties": {
|
||||
"AssumeRolePolicyDocument": {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Service": [
|
||||
"lambda.amazonaws.com"
|
||||
]
|
||||
},
|
||||
"Action": [
|
||||
"sts:AssumeRole"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"Path": "/"
|
||||
}
|
||||
},
|
||||
"IamPolicyLambda": {
|
||||
"Type": "AWS::IAM::Policy",
|
||||
"Properties": {
|
||||
"PolicyName": "${stage}-${project}-lambda",
|
||||
"PolicyDocument": {
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"logs:CreateLogGroup",
|
||||
"logs:CreateLogStream",
|
||||
"logs:PutLogEvents"
|
||||
],
|
||||
"Resource": "arn:aws:logs:${region}:*:*"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Roles": [
|
||||
{
|
||||
"Ref": "IamRoleLambda"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Outputs = {
|
||||
"IamRoleArnLambda": {
|
||||
"Description": "ARN of the lambda IAM role",
|
||||
"Value": {
|
||||
"Fn::GetAtt": [
|
||||
"IamRoleLambda",
|
||||
"Arn"
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
updateConfig(config) {
|
||||
@ -49,10 +112,10 @@ class Resources extends SerializerFileSystem {
|
||||
if (!options.stage || !options.region) throw new SError('Both "stage" and "region" params are required');
|
||||
|
||||
// Validate: Check project path is set
|
||||
if (!this._S.hasProject()) throw new SError('Function could not be populated because no project path has been set on Serverless instance');
|
||||
if (!this._S.hasProject()) throw new SError('Resources could not be populated because no project path has been set on Serverless instance');
|
||||
|
||||
// Populate
|
||||
return SUtils.populate(this.getVariables(), this.getTemplates(), this.toObject(), options.stage, options.region);
|
||||
return SUtils.populate(this.getProject(), this.toObject(), options.stage, options.region);
|
||||
}
|
||||
|
||||
fromObject(data) {
|
||||
|
||||
@ -114,10 +114,11 @@ class SerializerFileSystem {
|
||||
})
|
||||
.then(function() {
|
||||
|
||||
|
||||
// Load Resources
|
||||
if (SUtils.fileExistsSync(path.join(_this._projectPath, 's-resources-cf.json'))) {
|
||||
let resources = new _this._S.classes.Resources(_this._S);
|
||||
return resources.load();
|
||||
return resources.load()
|
||||
}
|
||||
})
|
||||
.then(function () {
|
||||
@ -154,7 +155,7 @@ class SerializerFileSystem {
|
||||
.then(function() {
|
||||
|
||||
// Save Project Variables "s-variables-common.json"
|
||||
let variables = new _this._S.classes.Variables(_this._S);
|
||||
let variables = project.getVariables();
|
||||
let variablesPath = project.getFilePath('_meta', 'variables', 's-variables-common.json');
|
||||
SUtils.writeFileSync(variablesPath, variables.toObject());
|
||||
|
||||
@ -392,11 +393,12 @@ class SerializerFileSystem {
|
||||
if (!_this._S.hasProject()) throw new SError('Resources could not be loaded because no project path has been set on Serverless instance');
|
||||
|
||||
// Validate: Check resources exists
|
||||
if (!SUtils.fileExistsSync(resources.getProject().getFilePath())) return resources;
|
||||
//if (!SUtils.fileExistsSync(resources.getProject().getFilePath())) return resources;
|
||||
|
||||
// Set Data
|
||||
resources.fromObject(SUtils.readFileSync(resources.getProject().getFilePath('s-resources-cf.json')));
|
||||
|
||||
|
||||
})
|
||||
.then(function() {
|
||||
|
||||
|
||||
@ -250,17 +250,6 @@ module.exports = function(SPlugin, serverlessPath) {
|
||||
projectBucketRegion: _this.evt.options.region
|
||||
});
|
||||
|
||||
// Create s-resources-cf.json
|
||||
if (!_this.project.cloudFormation && // TODO: Remove Back-compat support - In case initializing older project w/ cloudFormation property
|
||||
!SUtils.fileExistsSync( _this.project.getFilePath( 's-resources-cf.json' ))) {
|
||||
files.push(
|
||||
SUtils.writeFile(
|
||||
_this.project.getFilePath( 's-resources-cf.json' ),
|
||||
JSON.stringify(
|
||||
SUtils.readFileSync(path.join(_this.S.getServerlessPath(), 'templates', 's-resources-cf.json')),
|
||||
null, 2)
|
||||
));
|
||||
}
|
||||
|
||||
// Save Project
|
||||
return _this.project.save()
|
||||
|
||||
@ -145,8 +145,14 @@ usage: serverless region create`,
|
||||
// Add region to stage
|
||||
_this.stage = _this.project.getStage(_this.evt.options.stage);
|
||||
_this.region = new _this.S.classes.Region(_this.S, _this.stage, _this.evt.options.region);
|
||||
|
||||
// Add default project variables
|
||||
_this.regionVariables = _this.region.getVariables();
|
||||
_this.regionVariables.fromObject({
|
||||
region: _this.evt.options.region
|
||||
});
|
||||
_this.stage.setRegion(_this.region);
|
||||
return _this.stage.save();
|
||||
return _this.region.save();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -155,16 +155,15 @@ usage: serverless resources deploy`,
|
||||
|
||||
_deployResources() {
|
||||
|
||||
let _this = this;
|
||||
let regionVars = _this.S.getProject().getRegion(_this.evt.options.stage, _this.evt.options.region)._variables
|
||||
let resourceVars = [ 'iamRoleArnLambda' ].concat( _this.S.getProject().resourceVars);
|
||||
let _this = this,
|
||||
region = _this.S.getProject().getRegion(_this.evt.options.stage, _this.evt.options.region),
|
||||
regionVariables = region.getVariables();
|
||||
|
||||
return BbPromise.try(function() {
|
||||
return _this.S.getProject().getResources({
|
||||
populate: true,
|
||||
stage: _this.evt.options.stage,
|
||||
region: _this.evt.options.region
|
||||
}).toObject();
|
||||
return _this.S.getProject().getResources().toObjectPopulated({
|
||||
stage: _this.evt.options.stage,
|
||||
region: _this.evt.options.region
|
||||
});
|
||||
})
|
||||
.then(function(resources) {
|
||||
|
||||
@ -221,23 +220,27 @@ usage: serverless resources deploy`,
|
||||
.then(cfStackData => {
|
||||
|
||||
// Save stack name
|
||||
regionVars.resourcesStackName = cfStackData.StackName;
|
||||
//regionVariables.resourcesStackName = cfStackData.StackName;
|
||||
|
||||
// Save allowed (exported) CF output variables for Project Lambdas
|
||||
regionVariables.fromObject({
|
||||
resourcesStackName: cfStackData.StackName
|
||||
});
|
||||
|
||||
// Save IAM Role ARN for Project Lambdas
|
||||
for (let i = 0; i < cfStackData.Outputs.length; i++) {
|
||||
let varName = _.lowerFirst(cfStackData.Outputs[i].OutputKey);
|
||||
if (resourceVars.indexOf(varName) !== -1) {
|
||||
regionVars[varName] = cfStackData.Outputs[i].OutputValue;
|
||||
}
|
||||
if (cfStackData.Outputs[i].OutputKey === 'IamRoleArnLambda') {
|
||||
//regionVariables.iamRoleArnLambda = cfStackData.Outputs[i].OutputValue;
|
||||
regionVariables.fromObject({
|
||||
iamRoleArnLambda: cfStackData.Outputs[i].OutputValue
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
// Stop Spinner
|
||||
_this._spinner.stop(true);
|
||||
|
||||
// Save State
|
||||
_this.S.state.save();
|
||||
region.save();
|
||||
|
||||
// Status
|
||||
SCli.log('Successfully deployed "' + _this.evt.options.stage + '" resources to "' + _this.evt.options.region + '"');
|
||||
@ -264,7 +267,7 @@ usage: serverless resources deploy`,
|
||||
stage = this.evt.options.stage,
|
||||
region = this.evt.options.region,
|
||||
aws = this.S.getProvider('aws'),
|
||||
stackName = this.S.getProject().getRegion(stage, region)._variables.resourcesStackName || aws.getLambdasStackName(stage, projectName);
|
||||
stackName = this.S.getProject().getRegion(stage, region).getVariables().resourcesStackName || aws.getResourcesStackName(stage, projectName);
|
||||
|
||||
// CF Params
|
||||
let params = {
|
||||
@ -283,7 +286,7 @@ usage: serverless resources deploy`,
|
||||
Value: stage
|
||||
}];
|
||||
|
||||
params.StackName = stackName
|
||||
params.StackName = stackName;
|
||||
params.OnFailure = 'DELETE';
|
||||
return aws.request('CloudFormation', 'createStack', params, stage, region);
|
||||
};
|
||||
|
||||
@ -161,7 +161,7 @@ usage: serverless stage create`,
|
||||
}
|
||||
];
|
||||
|
||||
return _this.cliPromptSelect(`For this stage, do you want to use an existing ${_this.provider.getProviderName()} profile or create a new one?`, choices, false)
|
||||
return _this.cliPromptSelect(`For the "${_this.evt.options.stage}" stage, do you want to use an existing ${_this.provider.getProviderName()} profile or create a new one?`, choices, false)
|
||||
.then(function(values) {
|
||||
|
||||
// If "Use Existing" is selected, skip
|
||||
@ -232,6 +232,8 @@ usage: serverless stage create`,
|
||||
return _this.cliPromptSelect('Select a profile for your project: ', choices, false)
|
||||
.then(function(results) {
|
||||
_this.evt.options.profile = results[0].value;
|
||||
_this.S.config.awsAdminKeyId = _this.S.getProvider('aws').getProfile(_this.evt.options.profile).aws_access_key_id;
|
||||
_this.S.config.awsAdminSecretKey = _this.S.getProvider('aws').getProfile(_this.evt.options.profile).aws_secret_access_key;
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -278,7 +280,14 @@ usage: serverless stage create`,
|
||||
*/
|
||||
|
||||
_createStage() {
|
||||
this.stage = new this.S.classes.Stage(this.S, this.project, this.evt.options.stage);
|
||||
this.stage = new this.S.classes.Stage(this.S, this.project, this.evt.options.stage);
|
||||
|
||||
// Add default project variables
|
||||
this.stageVariables = this.stage.getVariables();
|
||||
this.stageVariables.fromObject({
|
||||
stage: this.evt.options.stage
|
||||
});
|
||||
|
||||
this.project.setStage(this.stage);
|
||||
return this.stage.save();
|
||||
}
|
||||
|
||||
@ -408,12 +408,10 @@ exports.doesFunctionExist = function(functionName, componentName, projectRootPat
|
||||
* Example: {"variableSyntax": "<%([\\s\\S]+?)%>"}
|
||||
*/
|
||||
|
||||
exports.populate = function(meta, templates, data, stage, region) {
|
||||
|
||||
const project = meta._S.getProject()
|
||||
exports.populate = function(project, data, stage, region) {
|
||||
|
||||
// Validate required params
|
||||
if (!meta || !templates || !data || !stage || !region) throw new SError(`Missing required params: Serverless, project, stage, region`);
|
||||
if (!project || !data || !stage || !region) throw new SError(`Missing required params: project, data, stage, region`);
|
||||
|
||||
// Validate: Check stage exists
|
||||
if (typeof stage != 'undefined' && !project.validateStageExists(stage)) throw new SError(`Stage doesn't exist`);
|
||||
@ -421,15 +419,10 @@ exports.populate = function(meta, templates, data, stage, region) {
|
||||
// Validate: Check region exists in stage
|
||||
if (typeof region != 'undefined' && !project.validateRegionExists(stage, region)) throw new SError(`Region "${region}" doesn't exist in provided stage "${stage}"`);
|
||||
|
||||
// Sanitize: Remove nested properties. DO NOT populate these. Rely on calling those classes toObjectPopulated methods instead.
|
||||
|
||||
let _components = data.components;
|
||||
let _functions = data.functions;
|
||||
if (data.components) delete data.components;
|
||||
if (data.functions) delete data.functions;
|
||||
|
||||
let varTemplateSyntax = /\${([\s\S]+?)}/g,
|
||||
templateTemplateSyntax = /\$\${([\s\S]+?)}/g;
|
||||
templateTemplateSyntax = /\$\${([\s\S]+?)}/g,
|
||||
templates = project.getTemplates();
|
||||
|
||||
if (project.variableSyntax) {
|
||||
varTemplateSyntax = RegExp(project.variableSyntax,'g');
|
||||
@ -481,8 +474,8 @@ exports.populate = function(meta, templates, data, stage, region) {
|
||||
value = project.getRegion(stage, region).getVariables()[variableName]
|
||||
} else if (project.getStage(stage).getVariables()[variableName]) {
|
||||
value = project.getStage(stage).getVariables()[variableName];
|
||||
} else if (meta[variableName]) {
|
||||
value = meta[variableName];
|
||||
} else if (project.getVariables()[variableName]) {
|
||||
value = project.getVariables()[variableName];
|
||||
}
|
||||
|
||||
// Reserved Variables
|
||||
@ -501,10 +494,6 @@ exports.populate = function(meta, templates, data, stage, region) {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (_components) data.components = _.mapValues(_components, (c) => c.toObjectPopulated({stage, region}));
|
||||
if (_functions) data.functions = _.mapValues(_functions, (f) => f.toObjectPopulated({stage, region}));
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user