UNPKG

8.99 kBPlain TextView Raw
1#!/usr/bin/env node
2
3const os = require('os')
4const packageJson = require('../package.json')
5const slsArt = require('../lib/')
6
7/**
8 * Determine whether any of the given flags exists in the given argv (object representation)
9 * @param flags The set flags to look for
10 * @param argv The object containing the processed CLI arguments
11 * @returns boolean Whether one of the given flags was a truthy value within the given argv object.
12 */
13const hasFlag = (flags, argv) => flags.some(
14 (flag) => {
15 const f = flag.split('-').join('') // remove '-' or '--'
16 return f in argv && argv[f] // flag is defined in argv object (argv name is misleading) and has a truthy value
17 } // eslint-disable-line comma-dangle
18)
19
20const yargs = require('yargs')
21 .help()
22 .version(packageJson.version)
23 .options({
24 D: {
25 alias: 'debug',
26 description: 'Execute the command in debug mode. It will be chatty about what it is happening in the code.',
27 requiresArg: false,
28 },
29 V: {
30 alias: 'verbose',
31 description: 'Execute the command in verbose mode. It will be chatty about what it is attempting to accomplish.',
32 requiresArg: false,
33 },
34 })
35 .global(['D', 'V'])
36 .command('deploy', 'Deploy a default version of the function that will execute your Artillery scripts. See ' +
37 'https://serverless.com/framework/docs/providers/aws/cli-reference/deploy/ for reference.', {})
38 .command(
39 'invoke',
40 'Invoke your function with your Artillery script. Will prefer a script given by `-d`, `--data`, `-p`, or ' +
41 '`--path` over a `script.[yml|json]` file in the current directory over the default script. Invocation mode ' +
42 'will default to "performance" but adding the `-a` flag will run the script in "acceptance" mode. ' +
43 'See https://serverless.com/framework/docs/providers/aws/cli-reference/invoke/ for reference.',
44 {
45 a: {
46 alias: 'acceptance',
47 description: 'Execute the script in acceptance mode. It will execute each flow once, reporting failures.',
48 requiresArg: false,
49 },
50 m: {
51 alias: 'monitoring',
52 description: 'Execute the script in monitoring mode. It will execute each flow a multiple of times, alerting ' +
53 'if the number of errors exceeds the configured threshold.',
54 requiresArg: false,
55 },
56 d: {
57 alias: 'data',
58 description: 'A stringified script to execute',
59 requiresArg: true,
60 },
61 p: {
62 alias: 'path',
63 description: 'A path to the file containing the script to execute',
64 requiresArg: true,
65 },
66 si: {
67 alias: 'stdIn',
68 description: 'Have serverless read the event to invoke the remote function with from the "standard in" stream',
69 requiresArg: false,
70 },
71 jo: {
72 alias: 'jsonOnly',
73 description: 'Only write JSON to console.log to facilitate piping the invocation result into a tool such as jq',
74 requiresArg: false,
75 },
76 },
77 /**
78 * Custom argument rejection logic, to deal with legacy, argument conflicts (between slsart and sls), and
79 * unsupported flags.
80 * @param argv The array of arguments that were provided to the CLI
81 */
82 (argv) => {
83 const breakingFlags = [
84 '-s', '--script',
85 ]
86 const reservedFlags = [
87 '-t', '--type',
88 '-f', '--function',
89 ]
90 const unsupportedFlags = [
91 '--raw',
92 ]
93 // ##!! LEGACY MANAGEMENT BEGIN !!##
94 // TODO Delete this block once transition is satisfactory (previously we accepted -s and --script to provide the
95 // TODO artillery script. This conflicts with the -s and --stage flags of the serverless framework. As such,
96 // TODO while we transition our users away from providing the script via -s/--script, we reject those flags and
97 // TODO redirect them.
98 // TODO Transition start date:
99 if (hasFlag(breakingFlags, argv)) {
100 console.error([
101 os.EOL,
102 `DDOS Off!${os.EOL}${os.EOL}`,
103 `TL;DR: use -p/--path to supply a script, use --stage to supply a stage.${os.EOL}${os.EOL}`,
104 `**BREAKING CHANGE**${os.EOL}`,
105 'In order to facilitate the richer and more sustainable use of `serverless-artillery`, we have made a ',
106 `'breaking change during this 0.x.x formation period.${os.EOL}`,
107 'The `-s` flag you provided is no longer supported. Instead, use the `-p` flag (still supplying the path ',
108 'to your script. The `-p` flag is the standard Serverless Framework flag for supplying a "path" to the ',
109 `"event" file that is to be used to invoke the function.${os.EOL}`,
110 'We apologize for not forseeing the consequence of our previous choice. On the positive side, the feature ',
111 'enabled by this change allows you to use any valid command line flag of the serverless framework with ',
112 `\`slsart\` in order to facilitate your workflow, whatever is involved.${os.EOL}`,
113 `Notable exceptions include: "${reservedFlags.join('", "')}" `,
114 `flags which are reserved due to assumptions of \`serverless-artillery\`${os.EOL}`,
115 `**BREAKING CHANGE**${os.EOL}${os.EOL}`,
116 'NOTE: if you have intended to supply the "STAGE" of the service, please use the long form of that flag ' +
117 `(\`--stage\`) to specify that setting. This constraint will eventually be removed.${os.EOL}${os.EOL}`,
118 `DDOS On!${os.EOL}${os.EOL}`,
119 ].join(''))
120 process.exit(1)
121 }
122 // ##!! LEGACY MANAGEMENT END !!##
123 if (hasFlag(reservedFlags, argv)) {
124 console.error([
125 os.EOL,
126 `!ERROR!${os.EOL}`,
127 'One of the `serverless` flags you provided is reserved for exclusive `serverless-artillery` use, ',
128 `reserved flags include: "${
129 Object.keys(reservedFlags).map(key => reservedFlags[key]).join('", "')
130 }".${os.EOL}`,
131 'Please see the "reserved flags" documentation in the README ',
132 `(https://www.npmjs.com/package/serverless-artillery#reserved-flags).${os.EOL}`,
133 ].join(''))
134 process.exit(1)
135 } else if (hasFlag(unsupportedFlags, argv)) {
136 console.error([
137 os.EOL,
138 `!ERROR!${os.EOL}`,
139 `One of the flags you provided is unsupported by \`serverless-artillery\`. Unsupported flags include: "${
140 Object.keys(unsupportedFlags).map(key => unsupportedFlags[key]).join('", "')}"${os.EOL}`,
141 'Please see the "unsupported flags" documentation in the README ',
142 `(https://www.npmjs.com/package/serverless-artillery#unsupported-flags).${os.EOL}`,
143 ].join(''))
144 process.exit(1)
145 }
146 } // eslint-disable-line comma-dangle
147 )
148 .command('kill', 'Stop a currently running load test and remove the function.', {})
149 .command('remove', 'Remove the function and the associated resources created for or by it. See ' +
150 'https://serverless.com/framework/docs/providers/aws/cli-reference/remove/ for reference.', {})
151 .command(
152 'script',
153 'Create a local Artillery script so that you can customize it for your specific load requirements. ' +
154 'See https://artillery.io for documentation.',
155 {
156 e: {
157 alias: 'endpoint',
158 description: 'The endpoint to load with traffic.',
159 requiresArg: true,
160 type: 'string',
161 },
162 d: {
163 alias: 'duration',
164 description: 'The duration, in seconds, to load the given endpoint.',
165 requiresArg: true,
166 type: 'number',
167 },
168 r: {
169 alias: 'rate',
170 description: 'The rate, in requests per second, at which to load the given endpoint.',
171 requiresArg: true,
172 type: 'number',
173 },
174 t: {
175 alias: 'rampTo',
176 description: 'The rate to ramp up to from the given (starting) rate, in requests per second at which to load ' +
177 'the given endpoint.',
178 requiresArg: true,
179 type: 'number',
180 },
181 o: {
182 alias: 'out',
183 description: 'The file to output the generated script in to.',
184 requiresArg: true,
185 type: 'string',
186 },
187 } // eslint-disable-line comma-dangle
188 )
189 .command('configure', 'Create a local copy of the deployment assets for modification and deployment. See ' +
190 'https://serverless.com/framework/docs/ for documentation.', {})
191 .command('upgrade', 'Upgrade local assets to latest version.', {})
192 .demand(1)
193
194const command = yargs.argv._[0]
195
196if (yargs.argv.debug) {
197 console.log(`options were:${os.EOL}${JSON.stringify(yargs.argv, null, 2)}`)
198 console.log(`command that will be executed: slsArt[${command}](${yargs.argv})`)
199}
200
201if (!(command in slsArt)) {
202 yargs.showHelp()
203 process.exit(1)
204}
205
206slsArt[command](yargs.argv)
207 .catch((ex) => {
208 console.error(ex.message)
209 if (yargs.argv.verbose) {
210 console.error(ex.stack)
211 }
212 process.exit(1)
213 })