UNPKG

11.1 kBJavaScriptView Raw
1const globby = require( "globby" );
2const fs = require( "fs" );
3const request = require( "request" );
4const path = require( "path" );
5const AWS = require( "aws-sdk" );
6const _ = require( "lodash" );
7const cmd = require( "node-cmd" );
8
9function addLambdaEnvironmentVariablesToProcess ( environmentVariables ) {
10 if ( environmentVariables ) {
11 Object.keys( environmentVariables ).forEach( ( key ) => {
12 process.env[ key ] = environmentVariables[ key ];
13 });
14 }
15}
16
17function authenticate () {
18
19 return new Promise( ( resolve, reject ) => {
20
21 if ( process.env.COLLY__USE_BASTION ) {
22
23 console.log( "Authenticating via bastion servers..." );
24
25 authenticateAgainstBastionService()
26 .then( resolve );
27 return;
28
29 }
30
31 if ( process.env.AWS_PROFILE ) {
32
33 console.log( "Authenticating via local AWS profile..." );
34 resolve();
35 return;
36
37 }
38
39 reject( "No login credentials supplied" );
40
41 });
42
43}
44
45function authenticateAgainstBastionService() {
46
47 return new Promise( ( resolve, reject ) => {
48
49 const projectConfig = getProjectConfig();
50 const certPath = path.resolve( projectConfig.bastionService.certPath );
51 const requestOptions = {
52 url: projectConfig.bastionService.endpoint,
53 agentOptions: {
54 cert: fs.readFileSync( certPath ),
55 key: fs.readFileSync( certPath ),
56 ca: fs.readFileSync( projectConfig.bastionService.cloudServicesRoot )
57 }
58 };
59
60 request.get( requestOptions, function ( error, response, body ) {
61
62 if ( error || ( response && response.statusCode !== 200 ) ) {
63
64 const statusCode = ( response && response.statusCode ) ? response.statusCode : 'no code';
65 const errorMessage = `Unable to authenticate to AWS using the wormhole (Code: ${statusCode})`;
66
67 reject( errorMessage );
68
69 } else {
70
71 const credentials = JSON.parse(body);
72
73 process.env.AWS_ACCESS_KEY_ID = credentials.accessKeyId;
74 process.env.AWS_SECRET_ACCESS_KEY = credentials.secretAccessKey;
75 process.env.AWS_SESSION_TOKEN = credentials.sessionToken;
76
77 resolve();
78
79 }
80
81 });
82
83 });
84
85}
86
87function everythingAfterTheLastDot( dotDelimitedString ) {
88 return dotDelimitedString.split(".").pop();
89}
90
91function getLambdaName ( nameOverride ) {
92
93 const appendedToName = anyEnvButLive();
94
95 return ( nameOverride || getLambdaConfigFile().name ) + appendedToName;
96
97}
98
99function anyEnvButLive () {
100 return ( process.env.ENV !== "live" ) ? process.env.ENV.toUpperCase() : "";
101}
102
103function chooseProjectFile( envFiles, env ) {
104 if ( env.trim() === "" ) {
105 env = "live";
106 }
107 if ( env.toLowerCase() in envFiles ) {
108 return envFiles[ env.toLowerCase() ];
109 } else {
110 console.log( "no env value defined" );
111 throw new Error("`--env` parameter value has no matching colly file");
112 }
113}
114
115function getLambdaConfigFilePath () {
116 return `${process.env.COLLY__PROJECT_DIR}/${process.env.COLLY__LAMBDA_NAME}/function.json`;
117}
118
119function getLambdaConfigFile () {
120 return JSON.parse( fs.readFileSync( getLambdaConfigFilePath() ) );
121}
122
123function getLambdaHandlerName () {
124 const config = getLambdaConfigFile();
125 return everythingAfterTheLastDot( config.handler );
126}
127
128function listEnvFiles () {
129
130 const path = `${process.env.COLLY__PROJECT_DIR}/colly*.json`;
131 let opts = {
132 "dot": true
133 };
134 if ( path.substring(0,1) === "/" ) {
135 opts.cwd = "/";
136 }
137 const relativePaths = globby.sync( path );
138 let envFiles = {};
139 relativePaths.forEach( ( relativePath ) => {
140
141 const fileName = relativePath.split( "/" ).pop();
142 const fileNameParts = fileName.split(".");
143 let envName;
144 if ( fileName === "colly.json" ) {
145 envName = "live";
146 }
147
148 if ( fileNameParts.length > 2 ) {
149 envName = fileNameParts[ 1 ];
150 }
151
152 envFiles[ envName ] = fileName;
153
154 });
155 return envFiles;
156}
157
158function getProjectConfigFilePath () {
159 return `${process.env.COLLY__PROJECT_DIR}/${ chooseProjectFile( listEnvFiles(), process.env.ENV ) }`;
160}
161
162function getProjectConfig() {
163 return JSON.parse( fs.readFileSync( getProjectConfigFilePath() ) );
164}
165
166function getLambdaFilePath( altStartOfPath ) {
167
168 const startOfPath = altStartOfPath || process.env.COLLY__PROJECT_DIR;
169
170 const config = getLambdaConfigFile( process.env.COLLY__LAMBDA_NAME );
171
172 const relativePathToLambdaFile = config.handler.split( "." ).slice( 0, -1 ).join( "." ) + ".js";
173
174 return startOfPath + "/" + relativePathToLambdaFile;
175
176}
177
178function copyAllFilesToDistDir () {
179 return new Promise( ( resolve, reject ) => {
180 const webpack = require( "webpack" );
181 const config = getLambdaConfigFile( process.env.COLLY__LAMBDA_NAME );
182 const webpackOutput = getLambdaFilePath( "./dist" );
183 webpack({
184 "context": process.env.COLLY__PROJECT_DIR,
185 "entry": getLambdaFilePath(),
186 "output": {
187 "filename": webpackOutput,
188 "libraryTarget": "commonjs"
189 },
190 "target": "node",
191 "externals": [ "aws-sdk" ]
192 }, ( err, stats ) => {
193 if ( err || stats.hasErrors() ) {
194 reject( err );
195 }
196 console.log( stats.toString( {
197 colors: true
198 } ) );
199 resolve( `./dist/${process.env.COLLY__LAMBDA_NAME}` );
200 });
201 });
202}
203
204function optionsCustomiser ( objVal, srcVal, propName ) {
205 const validOptionNames = [
206 "env",
207 "name",
208 "event",
209 "local",
210 "use_bastion",
211 "aws_profile"
212 ];
213 console.log( propName );
214 if ( validOptionNames.indexOf( propName ) > -1 ) {
215 if ( srcVal ) {
216 return srcVal;
217 } else {
218 return objVal;
219 }
220 } else {
221
222 }
223}
224
225function formatConfigFile( configFile ) {
226 const propertyNameMap = {
227 "useBastion": "use_bastion",
228 "awsProfile": "aws_profile"
229 }
230 let formattedConfigFile = {};
231 Object.keys( configFile ).forEach( propName => {
232 if ( propName in propertyNameMap ) {
233 formattedConfigFile[ propertyNameMap[ propName ] ] = configFile[ propName ];
234 }
235 });
236 return formattedConfigFile;
237}
238
239function filterOptions( options ) {
240 const validOptionNames = [
241 "env",
242 "name",
243 "event",
244 "local",
245 "use_bastion",
246 "aws_profile",
247 "context",
248 "search",
249 "start_time",
250 "tail"
251 ];
252 return _.pickBy( options, ( val, name ) => {
253 return ( validOptionNames.indexOf( name ) > -1 );
254 })
255}
256
257function setOptions ( cliOptions ) {
258
259 if ( cliOptions.env ) {
260 process.env.ENV = cliOptions.env;
261 } else {
262 process.env.ENV = "live";
263 }
264
265 if ( !process.env.COLLY__PROJECT_DIR ) {
266 process.env.COLLY__PROJECT_DIR = process.cwd();
267 }
268
269 projectConfig = getProjectConfig();
270
271 const options = filterOptions( _.defaults( formatConfigFile( projectConfig ), cliOptions ) );
272
273 if ( options.name ) {
274 process.env.COLLY__LAMBDA_NAME = options.name;
275 }
276
277 if ( options.event ) {
278 process.env.COLLY__LAMBDA_EVENT_FILE = options.event;
279 }
280
281 if ( options.context ) {
282 process.env.COLLY__LAMBDA_CONTEXT_FILE = options.context;
283 }
284
285 if ( typeof options.local === "boolean" ) {
286 process.env.COLLY__RUN_LAMBDA_LOCAL = options.local;
287 }
288
289 if ( options.use_bastion ) {
290 process.env.COLLY__USE_BASTION = options.use_bastion;
291 }
292
293 if ( options.aws_profile ) {
294 process.env.AWS_PROFILE = options.aws_profile;
295 }
296
297 if ( !process.env.COLLY__PROJECT_DIR ) {
298 process.env.COLLY__PROJECT_DIR = process.cwd();
299 }
300
301 if ( options.search ) {
302 process.env.COLLY__SEARCH = options.search;
303 }
304
305 if ( options.start_time ) {
306 process.env.COLLY__START_TIME = options.start_time;
307 }
308
309 if ( typeof options.tail === "boolean" ) {
310 process.env.COLLY__TAIL = options.tail;
311 }
312}
313
314function setAwsRegion () {
315 const projectConfig = getProjectConfig();
316 AWS.config.region = projectConfig.region;
317}
318
319function lastItemInArray ( item, arr ) {
320 return _.last( arr ) === item;
321}
322
323function addValueToLambdaConfig ( DotDelimitedProperty, value ) {
324
325 let config = getLambdaConfigFile( process.env.LAMBDA_NAME );
326
327 const propertyChain = DotDelimitedProperty.split( "." );
328
329 let referencedPropertyToEdit = config;
330
331 propertyChain.forEach( ( property, i, a ) => {
332
333 if ( !( property in referencedPropertyToEdit ) ) {
334 referencedPropertyToEdit[ property ] = {};
335 }
336
337 if ( lastItemInArray( property, propertyChain ) ) {
338 referencedPropertyToEdit[ property ] = value;
339 } else {
340 referencedPropertyToEdit = referencedPropertyToEdit[ property ];
341 }
342
343 });
344
345 fs.writeFileSync( getLambdaConfigFilePath( process.env.LAMBDA_NAME ), JSON.stringify( config, null, " " ) );
346
347}
348
349function zipFile ( package ) {
350
351 return new Promise( ( resolve, reject ) => {
352
353 console.log( "Zipping the webpack output... " );
354
355 cmd.get( `cd dist && zip -9 -r ${process.env.COLLY__LAMBDA_NAME}.zip ${process.env.COLLY__LAMBDA_NAME}`, ( err, stdout ) => {
356
357 console.log( stdout );
358
359 resolve( `${package}.zip` );
360
361 });
362
363 });
364
365}
366
367function addEnvVarToProjectConfig ( name, value ) {
368
369 let projectConfig = getProjectConfig();
370 if ( !( "environmentVariables" in projectConfig ) ) {
371 projectConfig.environmentVariables = {};
372 }
373 projectConfig.environmentVariables[ name ] = value;
374 fs.writeFileSync( getProjectConfigFilePath(), JSON.stringify( projectConfig, null, " " ) );
375
376}
377
378module.exports = {
379 "addEnvVarToProjectConfig": addEnvVarToProjectConfig,
380 "addLambdaEnvironmentVariablesToProcess": addLambdaEnvironmentVariablesToProcess,
381 "addValueToLambdaConfig": addValueToLambdaConfig,
382 "anyEnvButLive": anyEnvButLive,
383 "authenticate": authenticate,
384 "chooseProjectFile": chooseProjectFile,
385 "copyAllFilesToDistDir": copyAllFilesToDistDir,
386 "everythingAfterTheLastDot": everythingAfterTheLastDot,
387 "formatConfigFile": formatConfigFile,
388 "getLambdaConfigFile": getLambdaConfigFile,
389 "getLambdaConfigFilePath": getLambdaConfigFilePath,
390 "getLambdaFilePath": getLambdaFilePath,
391 "getLambdaHandlerName": getLambdaHandlerName,
392 "getLambdaName": getLambdaName,
393 "getProjectConfig": getProjectConfig,
394 "getProjectConfigFilePath": getProjectConfigFilePath,
395 "listEnvFiles": listEnvFiles,
396 "setAwsRegion": setAwsRegion,
397 "setOptions": setOptions,
398 "zipFile": zipFile
399}
\No newline at end of file