UNPKG

8.64 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.toLowerCase() in envFiles ) {
105 return envFiles[ env.toLowerCase() ];
106 } else {
107 console.log( "no env value defined" );
108 throw new Error("`--env` parameter value has no matching colly file");
109 }
110}
111
112function getLambdaConfigFilePath () {
113 return `${process.env.COLLY__PROJECT_DIR}/${process.env.COLLY__LAMBDA_NAME}/function.json`;
114}
115
116function getLambdaConfigFile () {
117 return JSON.parse( fs.readFileSync( getLambdaConfigFilePath() ) );
118}
119
120function getLambdaHandlerName () {
121 const config = getLambdaConfigFile();
122 return everythingAfterTheLastDot( config.handler );
123}
124
125function listEnvFiles () {
126
127 const path = `${process.env.COLLY__PROJECT_DIR}/colly*.json`;
128 let opts = {
129 "dot": true
130 };
131 if ( path.substring(0,1) === "/" ) {
132 opts.cwd = "/";
133 }
134 const relativePaths = globby.sync( path );
135 let envFiles = {};
136 relativePaths.forEach( ( relativePath ) => {
137
138 const fileName = relativePath.split( "/" ).pop();
139 const fileNameParts = fileName.split(".");
140 let envName;
141 if ( fileName === "colly.json" ) {
142 envName = "live";
143 }
144
145 if ( fileNameParts.length > 2 ) {
146 envName = fileNameParts[ 1 ];
147 }
148
149 envFiles[ envName ] = fileName;
150
151 });
152 return envFiles;
153}
154
155function getProjectConfigFilePath () {
156 return `${process.env.COLLY__PROJECT_DIR}/${ chooseProjectFile( listEnvFiles(), process.env.ENV ) }`;
157}
158
159function getProjectConfig() {
160 return JSON.parse( fs.readFileSync( getProjectConfigFilePath() ) );
161}
162
163function getLambdaFilePath( altStartOfPath ) {
164
165 const startOfPath = altStartOfPath || process.env.COLLY__PROJECT_DIR;
166
167 const config = getLambdaConfigFile( process.env.COLLY__LAMBDA_NAME );
168
169 const relativePathToLambdaFile = config.handler.split( "." ).slice( 0, -1 ).join( "." ) + ".js";
170
171 return startOfPath + "/" + relativePathToLambdaFile;
172
173}
174
175function copyAllFilesToDistDir () {
176 return new Promise( ( resolve, reject ) => {
177 const webpack = require( "webpack" );
178 const config = getLambdaConfigFile( process.env.COLLY__LAMBDA_NAME );
179 const webpackOutput = getLambdaFilePath( "./dist" );
180 webpack({
181 "context": process.env.COLLY__PROJECT_DIR,
182 "entry": getLambdaFilePath(),
183 "output": {
184 "filename": webpackOutput,
185 "libraryTarget": "commonjs"
186 },
187 "target": "node",
188 "externals": [ "aws-sdk" ]
189 }, ( err, stats ) => {
190 if ( err || stats.hasErrors() ) {
191 reject( err );
192 }
193 console.log( stats.toString( {
194 colors: true
195 } ) );
196 resolve( `./dist/${process.env.COLLY__LAMBDA_NAME}` );
197 });
198 });
199}
200
201function setOptions ( cliOptions ) {
202
203 if ( cliOptions.env ) {
204 process.env.ENV = cliOptions.env;
205 }
206
207 if ( cliOptions.name ) {
208 process.env.COLLY__LAMBDA_NAME = cliOptions.name;
209 }
210
211 if ( cliOptions.event ) {
212 process.env.COLLY__LAMBDA_EVENT_FILE = cliOptions.event;
213 }
214
215 if ( typeof cliOptions.local === "boolean" ) {
216 process.env.COLLY__RUN_LAMBDA_LOCAL = cliOptions.local;
217 }
218
219 if ( cliOptions.use_bastion ) {
220 process.env.COLLY__USE_BASTION = cliOptions.use_bastion;
221 }
222
223 if ( cliOptions.aws_profile ) {
224 process.env.AWS_PROFILE = cliOptions.aws_profile;
225 }
226
227 if ( !process.env.COLLY__PROJECT_DIR ) {
228 process.env.COLLY__PROJECT_DIR = process.cwd();
229 }
230
231}
232
233function setAwsRegion () {
234 const projectConfig = getProjectConfig();
235 AWS.config.region = projectConfig.region;
236}
237
238function lastItemInArray ( item, arr ) {
239 return _.last( arr ) === item;
240}
241
242function addValueToLambdaConfig ( DotDelimitedProperty, value ) {
243
244 let config = getLambdaConfigFile( process.env.LAMBDA_NAME );
245
246 const propertyChain = DotDelimitedProperty.split( "." );
247
248 let referencedPropertyToEdit = config;
249
250 propertyChain.forEach( ( property, i, a ) => {
251
252 if ( !( property in referencedPropertyToEdit ) ) {
253 referencedPropertyToEdit[ property ] = {};
254 }
255
256 if ( lastItemInArray( property, propertyChain ) ) {
257 referencedPropertyToEdit[ property ] = value;
258 } else {
259 referencedPropertyToEdit = referencedPropertyToEdit[ property ];
260 }
261
262 });
263
264 fs.writeFileSync( getLambdaConfigFilePath( process.env.LAMBDA_NAME ), JSON.stringify( config, null, " " ) );
265
266}
267
268function zipFile ( package ) {
269
270 return new Promise( ( resolve, reject ) => {
271
272 console.log( "Zipping the webpack output... " );
273
274 cmd.get( `cd dist && zip -9 -r ${process.env.COLLY__LAMBDA_NAME}.zip ${process.env.COLLY__LAMBDA_NAME}`, ( err, stdout ) => {
275
276 console.log( stdout );
277
278 resolve( `${package}.zip` );
279
280 });
281
282 });
283
284}
285
286module.exports = {
287 "addLambdaEnvironmentVariablesToProcess": addLambdaEnvironmentVariablesToProcess,
288 "addValueToLambdaConfig": addValueToLambdaConfig,
289 "anyEnvButLive": anyEnvButLive,
290 "authenticate": authenticate,
291 "chooseProjectFile": chooseProjectFile,
292 "copyAllFilesToDistDir": copyAllFilesToDistDir,
293 "everythingAfterTheLastDot": everythingAfterTheLastDot,
294 "getLambdaConfigFile": getLambdaConfigFile,
295 "getLambdaConfigFilePath": getLambdaConfigFilePath,
296 "getLambdaFilePath": getLambdaFilePath,
297 "getLambdaHandlerName": getLambdaHandlerName,
298 "getLambdaName": getLambdaName,
299 "getProjectConfig": getProjectConfig,
300 "listEnvFiles": listEnvFiles,
301 "setAwsRegion": setAwsRegion,
302 "setOptions": setOptions,
303 "zipFile": zipFile
304}
\No newline at end of file