Skip to content

Commit 698e4ea

Browse files
committed
Update to re-add files accidentally deleted
1 parent cab57be commit 698e4ea

File tree

11 files changed

+3791
-0
lines changed

11 files changed

+3791
-0
lines changed

deployment/manifest-generator/app.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*********************************************************************************************************************
2+
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. *
3+
* *
4+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance *
5+
* with the License. A copy of the License is located at *
6+
* *
7+
* http://www.apache.org/licenses/LICENSE-2.0 *
8+
* *
9+
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES *
10+
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions *
11+
* and limitations under the License. *
12+
*********************************************************************************************************************/
13+
14+
/**
15+
* @author Solution Builders
16+
*/
17+
18+
'use strict';
19+
20+
const fs = require('fs');
21+
const path = require('path');
22+
const args = require('minimist')(process.argv.slice(2));
23+
24+
// List all files in a directory in Node.js recursively in a synchronous fashion
25+
let walkSync = function(dir, filelist) {
26+
let files = fs.readdirSync(dir);
27+
filelist = filelist || [];
28+
files.forEach(function(file) {
29+
if (fs.statSync(path.join(dir, file)).isDirectory()) {
30+
filelist = walkSync(path.join(dir, file), filelist);
31+
} else {
32+
filelist.push(path.join(dir, file));
33+
}
34+
});
35+
36+
return filelist;
37+
};
38+
39+
let _filelist = [];
40+
let _manifest = {
41+
files: []
42+
};
43+
44+
if (!args.hasOwnProperty('target')) {
45+
console.log('--target parameter missing. This should be the target directory containing content for the manifest.');
46+
process.exit(1);
47+
}
48+
49+
if (!args.hasOwnProperty('output')) {
50+
console.log('--ouput parameter missing. This should be the out directory where the manifest file will be generated.');
51+
process.exit(1);
52+
}
53+
54+
console.log(`Generating a manifest file ${args.output} for directory ${args.target}`);
55+
56+
walkSync(args.target, _filelist);
57+
58+
for (let i = 0; i < _filelist.length; i++) {
59+
_manifest.files.push(_filelist[i].replace(`${args.target}/`, ''));
60+
}
61+
62+
fs.writeFileSync(args.output, JSON.stringify(_manifest, null, 4));
63+
console.log(`Manifest file ${args.output} generated.`);
Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
/*********************************************************************************************************************
2+
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. *
3+
* *
4+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance *
5+
* with the License. A copy of the License is located at *
6+
* *
7+
* http://www.apache.org/licenses/LICENSE-2.0 *
8+
* *
9+
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES *
10+
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions *
11+
* and limitations under the License. *
12+
*********************************************************************************************************************/
13+
14+
/**
15+
* @author Solution Builders
16+
*/
17+
18+
'use strict';
19+
20+
let AWS = require('aws-sdk');
21+
const fs = require('fs');
22+
23+
/**
24+
* Helper function to interact with AWS S3 for cfn custom resource.
25+
*
26+
* @class s3Helper
27+
*/
28+
class s3Helper {
29+
30+
/**
31+
* @class s3Helper
32+
* @constructor
33+
*/
34+
constructor() {
35+
this.creds = new AWS.EnvironmentCredentials('AWS'); // Lambda provided credentials
36+
this.downloadLocation = '/tmp/manifest.json';
37+
}
38+
39+
/**
40+
* validateBuckets
41+
* Cross-checks provided bucket names against existing bucket names in the account for
42+
* validation.
43+
* @param {String} strBuckets - String of bucket names from the template params.
44+
*/
45+
async validateBuckets(strBuckets) {
46+
const formatted = strBuckets.replace(/\s/g,'');
47+
console.log(`Attempting to check if the following buckets exist: ${formatted}`);
48+
const buckets = formatted.split(',');
49+
const errorBuckets = [];
50+
for (let i = 0; i < buckets.length; i++) {
51+
const s3 = new AWS.S3({ signatureVersion: 'v4' });
52+
const params = { Bucket: buckets[i] };
53+
try {
54+
await s3.headBucket(params).promise();
55+
console.log(`Found bucket: ${buckets[i]}`);
56+
} catch (err) {
57+
console.log(`Could not find bucket: ${buckets[i]}`);
58+
console.log(err);
59+
errorBuckets.push(buckets[i]);
60+
}
61+
}
62+
if (errorBuckets.length === 0) return Promise.resolve();
63+
else return Promise.reject(errorBuckets);
64+
}
65+
66+
/**
67+
* putConfigFile
68+
* Saves a JSON config file to S3 location.
69+
* @param {JSON} content - JSON object.
70+
* @param {JSON} destS3Bucket - S3 destination bucket.
71+
* @param {JSON} destS3key - S3 destination key.
72+
*/
73+
putConfigFile(content, destS3Bucket, destS3key) {
74+
console.log(`Attempting to save content blob destination location: ${destS3Bucket}/${destS3key}`);
75+
console.log(JSON.stringify(content));
76+
77+
return new Promise((resolve, reject) => {
78+
let _content = `'use strict';\n\nconst appVariables = {\n`;
79+
80+
let i = 0;
81+
for (let key in content) {
82+
if (i > 0) {
83+
_content += ', \n';
84+
}
85+
_content += `${key}: '${content[key]}'`;
86+
i++;
87+
}
88+
_content += '\n};';
89+
90+
let params = {
91+
Bucket: destS3Bucket,
92+
Key: destS3key,
93+
Body: _content
94+
};
95+
96+
let s3 = new AWS.S3({
97+
signatureVersion: 'v4'
98+
});
99+
s3.putObject(params, function(err, data) {
100+
if (err) {
101+
console.log(err);
102+
reject(`Error creating ${destS3Bucket}/${destS3key} content \n${err}`);
103+
} else {
104+
console.log(data);
105+
resolve(data);
106+
}
107+
});
108+
});
109+
}
110+
111+
copyAssets(manifestKey, sourceS3Bucket, sourceS3prefix, destS3Bucket) {
112+
console.log(`source bucket: ${sourceS3Bucket}`);
113+
console.log(`source prefix: ${sourceS3prefix}`);
114+
console.log(`destination bucket: ${destS3Bucket}`);
115+
116+
let _self = this;
117+
return new Promise((resolve, reject) => {
118+
119+
this._downloadManifest(sourceS3Bucket, manifestKey).then((data) => {
120+
121+
fs.readFile(_self.downloadLocation, 'utf8', function(err, data) {
122+
if (err) {
123+
console.log(err);
124+
reject(err);
125+
}
126+
127+
let _manifest = _self._validateJSON(data);
128+
129+
if (!_manifest) {
130+
reject('Unable to validate downloaded manifest file JSON');
131+
} else {
132+
_self._uploadFile(_manifest.files, 0, destS3Bucket, `${sourceS3Bucket}/${sourceS3prefix}`).then((resp) => {
133+
console.log(resp);
134+
resolve(resp)
135+
}).catch((err) => {
136+
console.log(err);
137+
reject(err);
138+
});
139+
}
140+
141+
});
142+
}).catch((err) => {
143+
console.log(err);
144+
reject(err);
145+
});
146+
147+
});
148+
};
149+
150+
/**
151+
* Helper function to validate the JSON structure of contents of an import manifest file.
152+
* @param {string} body - JSON object stringify-ed.
153+
* @returns {JSON} - The JSON parsed string or null if string parsing failed
154+
*/
155+
_validateJSON(body) {
156+
try {
157+
let data = JSON.parse(body);
158+
console.log(data);
159+
return data;
160+
} catch (e) {
161+
// failed to parse
162+
console.log('Manifest file contains invalid JSON.');
163+
return null;
164+
}
165+
};
166+
167+
_uploadFile(filelist, index, destS3Bucket, sourceS3prefix) {
168+
let _self = this;
169+
return new Promise((resolve, reject) => {
170+
171+
if (filelist.length > index) {
172+
let params = {
173+
Bucket: destS3Bucket,
174+
Key: filelist[index],
175+
CopySource: [sourceS3prefix, filelist[index]].join('/'),
176+
MetadataDirective: 'REPLACE'
177+
};
178+
179+
params.ContentType = this._setContentType(filelist[index]);
180+
params.Metadata = {
181+
'Content-Type': params.ContentType
182+
};
183+
console.log(params);
184+
let s3 = new AWS.S3({
185+
signatureVersion: 'v4'
186+
});
187+
s3.copyObject(params, function(err, data) {
188+
if (err) {
189+
console.log(err);
190+
reject(`error copying ${sourceS3prefix}/${filelist[index]}\n${err}`);
191+
} else {
192+
console.log(`${sourceS3prefix}/${filelist[index]} uploaded successfully`);
193+
let _next = index + 1;
194+
_self._uploadFile(filelist, _next, destS3Bucket, sourceS3prefix).then((resp) => {
195+
resolve(resp);
196+
}).catch((err2) => {
197+
reject(err2);
198+
});
199+
}
200+
});
201+
} else {
202+
resolve(`${index} files copied`);
203+
}
204+
205+
});
206+
207+
}
208+
209+
/**
210+
* Helper function to download a manifest to local storage for processing.
211+
* @param {string} s3Bucket - Amazon S3 bucket of the manifest to download.
212+
* @param {string} s3Key - Amazon S3 key of the manifest to download.
213+
* @param {string} downloadLocation - Local storage location to download the Amazon S3 object.
214+
*/
215+
_downloadManifest(s3Bucket, s3Key) {
216+
let _self = this;
217+
return new Promise((resolve, reject) => {
218+
219+
let params = {
220+
Bucket: s3Bucket,
221+
Key: s3Key
222+
};
223+
224+
console.log(`Attempting to download manifest: ${JSON.stringify(params)}`);
225+
226+
// check to see if the manifest file exists
227+
let s3 = new AWS.S3({
228+
signatureVersion: 'v4'
229+
});
230+
s3.headObject(params, function(err, metadata) {
231+
if (err) {
232+
console.log(err);
233+
}
234+
235+
if (err && err.code === 'NotFound') {
236+
// Handle no object on cloud here
237+
console.log('manifest file doesn\'t exist');
238+
reject('Manifest file was not found.');
239+
} else {
240+
console.log('manifest file exists');
241+
console.log(metadata);
242+
let file = require('fs').createWriteStream(_self.downloadLocation);
243+
244+
s3.getObject(params).
245+
on('httpData', function(chunk) {
246+
file.write(chunk);
247+
}).
248+
on('httpDone', function() {
249+
file.end();
250+
console.log('manifest downloaded for processing...');
251+
resolve('success');
252+
}).
253+
send();
254+
}
255+
});
256+
});
257+
}
258+
259+
_setContentType(file) {
260+
let _contentType = 'binary/octet-stream';
261+
if (file.endsWith('.html')) {
262+
_contentType = 'text/html';
263+
} else if (file.endsWith('.css')) {
264+
_contentType = 'text/css';
265+
} else if (file.endsWith('.png')) {
266+
_contentType = 'image/png';
267+
} else if (file.endsWith('.svg')) {
268+
_contentType = 'image/svg+xml';
269+
} else if (file.endsWith('.jpg')) {
270+
_contentType = 'image/jpeg';
271+
} else if (file.endsWith('.js')) {
272+
_contentType = 'application/javascript';
273+
}
274+
275+
return _contentType;
276+
}
277+
278+
279+
}
280+
281+
module.exports = s3Helper;

0 commit comments

Comments
 (0)