aws-architect 6.6.26 → 6.6.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +3 -3
- package/lib/BucketManager.js +32 -11
- package/lib/CloudFormationDeployer.js +37 -26
- package/package.json +3 -3
package/index.js
CHANGED
|
@@ -4,7 +4,7 @@ let exec = require('child_process').exec;
|
|
|
4
4
|
let fs = require('fs-extra');
|
|
5
5
|
let path = require('path');
|
|
6
6
|
let os = require('os');
|
|
7
|
-
|
|
7
|
+
const shortUuid = require('short-uuid');
|
|
8
8
|
|
|
9
9
|
let Server = require('./lib/server');
|
|
10
10
|
let ApiGatewayManager = require('./lib/ApiGatewayManager');
|
|
@@ -47,7 +47,7 @@ AwsArchitect.prototype.publishZipArchive = async function(options = {}) {
|
|
|
47
47
|
if (!options.zipFileName || !this.deploymentBucket || !options.sourceDirectory) {
|
|
48
48
|
throw Error('The zipFileName, sourceDirectory, api options deploymentBucket must be specified.');
|
|
49
49
|
}
|
|
50
|
-
let tmpDir = path.join(os.tmpdir(), `zipDirectory-${
|
|
50
|
+
let tmpDir = path.join(os.tmpdir(), `zipDirectory-${shortUuid.generate()}`);
|
|
51
51
|
await new Promise((resolve, reject) => { fs.stat(options.sourceDirectory, (error, stats) => error || !stats.isDirectory ? reject(error || 'NotDirectoryError') : resolve()); });
|
|
52
52
|
await fs.copy(options.sourceDirectory, tmpDir);
|
|
53
53
|
let zipArchivePath = path.join(tmpDir, options.zipFileName);
|
|
@@ -67,7 +67,7 @@ AwsArchitect.prototype.publishZipArchive = async function(options = {}) {
|
|
|
67
67
|
|
|
68
68
|
AwsArchitect.prototype.publishLambdaArtifactPromise = AwsArchitect.prototype.PublishLambdaArtifactPromise = async function(options = {}) {
|
|
69
69
|
let lambdaZip = options && options.zipFileName || 'lambda.zip';
|
|
70
|
-
let tmpDir = path.join(os.tmpdir(), `lambda-${
|
|
70
|
+
let tmpDir = path.join(os.tmpdir(), `lambda-${shortUuid.generate()}`);
|
|
71
71
|
|
|
72
72
|
await new Promise((resolve, reject) => {
|
|
73
73
|
fs.stat(this.SourceDirectory, (error, stats) => {
|
package/lib/BucketManager.js
CHANGED
|
@@ -41,6 +41,9 @@ class BucketManager {
|
|
|
41
41
|
let cacheControl = matchingCacheMap && matchingCacheMap.value || cacheControlRegexMap[relativePathUnixFormat] || cacheControlRegexMap.default || 600;
|
|
42
42
|
const fileUrl = this.unixify(path.join(version, relativePath));
|
|
43
43
|
const fileData = await fs.readFile(file);
|
|
44
|
+
|
|
45
|
+
await this.ensureBucketExists(this.Bucket);
|
|
46
|
+
|
|
44
47
|
const putObjectParams = {
|
|
45
48
|
Bucket: this.Bucket,
|
|
46
49
|
Key: fileUrl,
|
|
@@ -112,18 +115,21 @@ class BucketManager {
|
|
|
112
115
|
await this.S3Manager.putObject(params).promise();
|
|
113
116
|
}
|
|
114
117
|
|
|
115
|
-
DeployLambdaPromise(bucket, localPath, remotePath) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
118
|
+
async DeployLambdaPromise(bucket, localPath, remotePath) {
|
|
119
|
+
await this.ensureBucketExists(bucket || this.Bucket);
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
await this.S3Manager.upload({
|
|
123
|
+
Bucket: bucket || this.Bucket,
|
|
124
|
+
Key: this.unixify(remotePath),
|
|
125
|
+
Body: fs.createReadStream(localPath),
|
|
126
|
+
ContentType: contentTypeMappingConst[path.extname(remotePath)] || lookup(remotePath) || contentTypeMappingConst.default || 'text/plain',
|
|
127
|
+
CacheControl: 'public, max-age=10'
|
|
128
|
+
}).promise();
|
|
129
|
+
console.log(`====> ${remotePath}`);
|
|
130
|
+
} catch (failure) {
|
|
125
131
|
throw { File: localPath, Detail: failure };
|
|
126
|
-
}
|
|
132
|
+
}
|
|
127
133
|
}
|
|
128
134
|
|
|
129
135
|
CopyBucket(source, target) {
|
|
@@ -153,6 +159,21 @@ class BucketManager {
|
|
|
153
159
|
});
|
|
154
160
|
}
|
|
155
161
|
|
|
162
|
+
async ensureBucketExists(bucket) {
|
|
163
|
+
try {
|
|
164
|
+
await this.S3Manager.headBucket({ Bucket: bucket }).promise();
|
|
165
|
+
} catch (error) {
|
|
166
|
+
if (error.code !== 'NotFound') {
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
await this.S3Manager.createBucket({ Bucket: bucket, ObjectOwnership: 'BucketOwnerEnforced', CreateBucketConfiguration: { LocationConstraint: this.S3Manager.config.region } }).promise();
|
|
171
|
+
await this.S3Manager.putPublicAccessBlock({
|
|
172
|
+
Bucket: bucket, PublicAccessBlockConfiguration: { BlockPublicAcls: true, BlockPublicPolicy: true, IgnorePublicAcls: true, RestrictPublicBuckets: true }
|
|
173
|
+
}).promise();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
156
177
|
// ensures a path will be in unix format (that is, forward slash), also on Windows systems.
|
|
157
178
|
unixify(fullPath) {
|
|
158
179
|
return fullPath.replace(/\\/g, '/');
|
|
@@ -54,35 +54,46 @@ class CloudFormationDeployer {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
stackExists(stackName) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
57
|
+
async stackExists(stackName) {
|
|
58
|
+
let data;
|
|
59
|
+
try {
|
|
60
|
+
data = await this.cloudFormationClient.describeStacks({ StackName: stackName }).promise();
|
|
61
|
+
} catch (error) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
if (!data.Stacks[0]) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
let stackStatus = data.Stacks[0].StackStatus;
|
|
68
|
+
let stackExistsDict = {
|
|
69
|
+
CREATE_COMPLETE: true,
|
|
70
|
+
UPDATE_COMPLETE: true,
|
|
71
|
+
UPDATE_ROLLBACK_COMPLETE: true
|
|
72
|
+
};
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
if (stackExistsDict[stackStatus]) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
if (stackStatus === 'REVIEW_IN_PROGRESS') {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
if (stackStatus === 'ROLLBACK_COMPLETE') {
|
|
81
|
+
console.log('Current status of stack is ROLLBACK_COMPLETE, deleting before generating a new stack.');
|
|
82
|
+
await this.cloudFormationClient.deleteStack({ StackName: stackName }).promise();
|
|
83
|
+
for (let checkIteration = 0; checkIteration < 120; checkIteration++) {
|
|
84
|
+
try {
|
|
85
|
+
await this.cloudFormationClient.describeStacks({ StackName: stackName }).promise();
|
|
86
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
87
|
+
} catch (error) {
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
80
90
|
}
|
|
81
|
-
|
|
82
|
-
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
throw { error: 'Current status of stack prevents creation or update.', status: stackStatus };
|
|
83
94
|
}
|
|
84
95
|
|
|
85
|
-
async waitForCompletion(stackName,
|
|
96
|
+
async waitForCompletion(stackName, allowUpdateRollback) {
|
|
86
97
|
let timeout = new Date();
|
|
87
98
|
let timeoutLength = 60 * 60 * 1000;
|
|
88
99
|
timeout.setTime(timeout.getTime() + timeoutLength);
|
|
@@ -110,7 +121,7 @@ class CloudFormationDeployer {
|
|
|
110
121
|
throw { error: 'Current status of the stack has failed', status: stackStatus };
|
|
111
122
|
}
|
|
112
123
|
|
|
113
|
-
if (!
|
|
124
|
+
if (!allowUpdateRollback && stackStatus === 'UPDATE_ROLLBACK_COMPLETE') {
|
|
114
125
|
throw { title: 'Current stack status is failure', status: stackStatus };
|
|
115
126
|
}
|
|
116
127
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aws-architect",
|
|
3
|
-
"version": "6.6.
|
|
3
|
+
"version": "6.6.31",
|
|
4
4
|
"description": "AWS Architect is a node based tool to configure and deploy AWS-based microservices.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"lodash.isequal": "^4.5.0",
|
|
32
32
|
"mime-types": "^2.1.27",
|
|
33
33
|
"morgan": "^1.9.1",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
34
|
+
"short-uuid": "^4.2.0",
|
|
35
|
+
"tmp": "^0.0.33"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"aws-sdk": ">=2.877.0"
|