@govuk-pay/cli 0.0.7 → 0.0.9
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/package.json +1 -1
- package/resources/legacy-ruby-cli/Gemfile.lock +2 -2
- package/resources/legacy-ruby-cli/config/secrets.yml +81 -9
- package/resources/legacy-ruby-cli/config/service_secrets.yml +25 -9
- package/resources/legacy-ruby-cli/lib/pay_cli/commands/local/config.yaml +3 -0
- package/resources/legacy-ruby-cli/lib/pay_cli/commands/local/files/all.yaml +760 -0
- package/resources/legacy-ruby-cli/lib/pay_cli/commands/local/files/card.yaml +508 -0
- package/resources/legacy-ruby-cli/lib/pay_cli/commands/local/files/custom.yaml +71 -0
- package/resources/legacy-ruby-cli/lib/pay_cli/commands/local/files/java.yaml +456 -0
- package/resources/legacy-ruby-cli/lib/pay_cli/commands/local/files/services/ssl/certs/publicapi-proxy.crt +18 -0
- package/resources/legacy-ruby-cli/lib/pay_cli/commands/local/files/services/ssl/keys/publicapi-proxy.key +28 -0
- package/resources/legacy-ruby-cli/lib/pay_cli/commands/local/files/toolbox.yaml +473 -0
- package/resources/legacy-ruby-cli/lib/pay_cli/commands/local.rb +3 -2
- package/resources/legacy-ruby-cli/rds_access/connect.sh +30 -4
- package/resources/legacy-ruby-cli/vulnerability_scan/generate_vulnerability_report.js +52 -55
- package/resources/legacy-ruby-cli/vulnerability_scan/package.json +15 -0
- package/resources/legacy-ruby-cli/vulnerability_scan/scan.sh +56 -25
- package/resources/legacy-ruby-cli/vulnerability_scan/reports/.gitkeep +0 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
version: '2.1'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
|
|
5
|
+
adminusers_db:
|
|
6
|
+
image: postgres:11.1
|
|
7
|
+
environment:
|
|
8
|
+
- POSTGRES_PASSWORD=mysecretpassword
|
|
9
|
+
mem_limit: 250M
|
|
10
|
+
logging:
|
|
11
|
+
driver: "json-file"
|
|
12
|
+
container_name: adminusers_db
|
|
13
|
+
healthcheck:
|
|
14
|
+
test: ["CMD-SHELL", "pg_isready"]
|
|
15
|
+
interval: 10s
|
|
16
|
+
timeout: 5s
|
|
17
|
+
retries: 5
|
|
18
|
+
volumes:
|
|
19
|
+
- ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
|
|
20
|
+
ports:
|
|
21
|
+
- "19700:5432"
|
|
22
|
+
|
|
23
|
+
connector_db:
|
|
24
|
+
image: postgres:11.1
|
|
25
|
+
environment:
|
|
26
|
+
- POSTGRES_PASSWORD=mysecretpassword
|
|
27
|
+
mem_limit: 250M
|
|
28
|
+
logging:
|
|
29
|
+
driver: "json-file"
|
|
30
|
+
container_name: connector_db
|
|
31
|
+
healthcheck:
|
|
32
|
+
test: ["CMD-SHELL", "pg_isready"]
|
|
33
|
+
interval: 10s
|
|
34
|
+
timeout: 5s
|
|
35
|
+
retries: 5
|
|
36
|
+
volumes:
|
|
37
|
+
- ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
|
|
38
|
+
ports:
|
|
39
|
+
- "19300:5432"
|
|
40
|
+
|
|
41
|
+
publicauth_db:
|
|
42
|
+
image: postgres:11.1
|
|
43
|
+
environment:
|
|
44
|
+
- POSTGRES_PASSWORD=mysecretpassword
|
|
45
|
+
mem_limit: 250M
|
|
46
|
+
logging:
|
|
47
|
+
driver: "json-file"
|
|
48
|
+
container_name: publicauth_db
|
|
49
|
+
healthcheck:
|
|
50
|
+
test: ["CMD-SHELL", "pg_isready"]
|
|
51
|
+
interval: 10s
|
|
52
|
+
timeout: 5s
|
|
53
|
+
retries: 5
|
|
54
|
+
volumes:
|
|
55
|
+
- ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
|
|
56
|
+
ports:
|
|
57
|
+
- "19600:5432"
|
|
58
|
+
|
|
59
|
+
products_db:
|
|
60
|
+
image: postgres:11.1
|
|
61
|
+
environment:
|
|
62
|
+
- POSTGRES_PASSWORD=mysecretpassword
|
|
63
|
+
mem_limit: 250M
|
|
64
|
+
logging:
|
|
65
|
+
driver: "json-file"
|
|
66
|
+
container_name: products_db
|
|
67
|
+
healthcheck:
|
|
68
|
+
test: ["CMD-SHELL", "pg_isready"]
|
|
69
|
+
interval: 10s
|
|
70
|
+
timeout: 5s
|
|
71
|
+
retries: 5
|
|
72
|
+
volumes:
|
|
73
|
+
- ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
|
|
74
|
+
ports:
|
|
75
|
+
- "19800:5432"
|
|
76
|
+
|
|
77
|
+
ledger_db:
|
|
78
|
+
image: postgres:11.1
|
|
79
|
+
environment:
|
|
80
|
+
- POSTGRES_PASSWORD=mysecretpassword
|
|
81
|
+
mem_limit: 250M
|
|
82
|
+
logging:
|
|
83
|
+
driver: "json-file"
|
|
84
|
+
container_name: ledger_db
|
|
85
|
+
healthcheck:
|
|
86
|
+
test: ["CMD-SHELL", "pg_isready"]
|
|
87
|
+
interval: 10s
|
|
88
|
+
timeout: 5s
|
|
89
|
+
retries: 5
|
|
90
|
+
volumes:
|
|
91
|
+
- ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
|
|
92
|
+
ports:
|
|
93
|
+
- "20700:5432"
|
|
94
|
+
|
|
95
|
+
webhooks_db:
|
|
96
|
+
image: postgres:11.1
|
|
97
|
+
environment:
|
|
98
|
+
- POSTGRES_PASSWORD=mysecretpassword
|
|
99
|
+
mem_limit: 250M
|
|
100
|
+
logging:
|
|
101
|
+
driver: "json-file"
|
|
102
|
+
container_name: webhooks_db
|
|
103
|
+
healthcheck:
|
|
104
|
+
test: ["CMD-SHELL", "pg_isready"]
|
|
105
|
+
interval: 10s
|
|
106
|
+
timeout: 5s
|
|
107
|
+
retries: 5
|
|
108
|
+
volumes:
|
|
109
|
+
- ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
|
|
110
|
+
ports:
|
|
111
|
+
- "20800:5432"
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
adminusers:
|
|
116
|
+
image: governmentdigitalservice/pay-adminusers:local
|
|
117
|
+
|
|
118
|
+
depends_on:
|
|
119
|
+
adminusers_db:
|
|
120
|
+
condition: service_healthy
|
|
121
|
+
|
|
122
|
+
env_file:
|
|
123
|
+
- services/java_app.env
|
|
124
|
+
- services/adminusers.env
|
|
125
|
+
environment:
|
|
126
|
+
- RUN_MIGRATION=true
|
|
127
|
+
- RUN_APP=true
|
|
128
|
+
- PORT=9700
|
|
129
|
+
- DISABLE_INTERNAL_HTTPS=true
|
|
130
|
+
|
|
131
|
+
- DB_HOST=adminusers_db
|
|
132
|
+
- DB_USER=adminusers
|
|
133
|
+
- DB_PASSWORD=mysecretpassword
|
|
134
|
+
- DB_SSL_OPTION=ssl=none
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
- ADMINUSERS_URL=http://adminusers:9700
|
|
144
|
+
- CONNECTOR_URL=http://connector:9300
|
|
145
|
+
- PUBLICAUTH_URL=http://publicauth:9600
|
|
146
|
+
- PRODUCTS_URL=http://products:18000
|
|
147
|
+
- LEDGER_URL=http://ledger:10700
|
|
148
|
+
- WEBHOOKS_URL=http://webhooks:10800
|
|
149
|
+
- TOOLBOX_URL=http://localhost:3040
|
|
150
|
+
working_dir: '/app'
|
|
151
|
+
mem_limit: 2G
|
|
152
|
+
user: root
|
|
153
|
+
logging:
|
|
154
|
+
driver: "json-file"
|
|
155
|
+
ports:
|
|
156
|
+
- "9700:9700"
|
|
157
|
+
|
|
158
|
+
container_name: adminusers
|
|
159
|
+
|
|
160
|
+
connector:
|
|
161
|
+
image: governmentdigitalservice/pay-connector:local
|
|
162
|
+
|
|
163
|
+
depends_on:
|
|
164
|
+
connector_db:
|
|
165
|
+
condition: service_healthy
|
|
166
|
+
|
|
167
|
+
env_file:
|
|
168
|
+
- services/java_app.env
|
|
169
|
+
- services/connector.env
|
|
170
|
+
environment:
|
|
171
|
+
- RUN_MIGRATION=true
|
|
172
|
+
- RUN_APP=true
|
|
173
|
+
- PORT=9300
|
|
174
|
+
- DISABLE_INTERNAL_HTTPS=true
|
|
175
|
+
|
|
176
|
+
- DB_HOST=connector_db
|
|
177
|
+
- DB_USER=connector
|
|
178
|
+
- DB_PASSWORD=mysecretpassword
|
|
179
|
+
- DB_SSL_OPTION=ssl=none
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
- AWS_ACCESS_KEY=mockAccessKey
|
|
184
|
+
- AWS_SECRET_ACCESS_KEY=mockSecretAccessKey
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
- AWS_SQS_REGION=eu-west-1
|
|
189
|
+
- AWS_SQS_MESSAGE_MAXIMUM_WAIT_TIME_IN_SECONDS=20
|
|
190
|
+
- AWS_SQS_NON_STANDARD_SERVICE_ENDPOINT=true
|
|
191
|
+
- AWS_SQS_ENDPOINT=http://localstack:4566
|
|
192
|
+
- AWS_SQS_CAPTURE_QUEUE_URL=http://localstack:4566/000000000000/pay_capture_queue
|
|
193
|
+
- AWS_SQS_PAYMENT_EVENT_QUEUE_URL=http://localstack:4566/000000000000/pay_event_queue
|
|
194
|
+
- AWS_SQS_PAYOUT_RECONCILE_QUEUE_URL=http://localstack:4566/000000000000/payout_reconcile_queue
|
|
195
|
+
- AWS_SQS_CONNECTOR_TASKS_QUEUE_URL=http://localstack:4566/000000000000/connector_tasks_queue
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
- ADMINUSERS_URL=http://adminusers:9700
|
|
201
|
+
- CONNECTOR_URL=http://connector:9300
|
|
202
|
+
- PUBLICAUTH_URL=http://publicauth:9600
|
|
203
|
+
- PRODUCTS_URL=http://products:18000
|
|
204
|
+
- LEDGER_URL=http://ledger:10700
|
|
205
|
+
- WEBHOOKS_URL=http://webhooks:10800
|
|
206
|
+
- TOOLBOX_URL=http://localhost:3040
|
|
207
|
+
working_dir: '/app'
|
|
208
|
+
mem_limit: 2G
|
|
209
|
+
user: root
|
|
210
|
+
logging:
|
|
211
|
+
driver: "json-file"
|
|
212
|
+
ports:
|
|
213
|
+
- "9300:9300"
|
|
214
|
+
- "9301:9301"
|
|
215
|
+
container_name: connector
|
|
216
|
+
|
|
217
|
+
publicauth:
|
|
218
|
+
image: governmentdigitalservice/pay-publicauth:local
|
|
219
|
+
|
|
220
|
+
depends_on:
|
|
221
|
+
publicauth_db:
|
|
222
|
+
condition: service_healthy
|
|
223
|
+
|
|
224
|
+
env_file:
|
|
225
|
+
- services/java_app.env
|
|
226
|
+
- services/publicauth.env
|
|
227
|
+
environment:
|
|
228
|
+
- RUN_MIGRATION=true
|
|
229
|
+
- RUN_APP=true
|
|
230
|
+
- PORT=9600
|
|
231
|
+
- DISABLE_INTERNAL_HTTPS=true
|
|
232
|
+
|
|
233
|
+
- DB_HOST=publicauth_db
|
|
234
|
+
- DB_USER=publicauth
|
|
235
|
+
- DB_PASSWORD=mysecretpassword
|
|
236
|
+
- DB_SSL_OPTION=ssl=none
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
- ADMINUSERS_URL=http://adminusers:9700
|
|
246
|
+
- CONNECTOR_URL=http://connector:9300
|
|
247
|
+
- PUBLICAUTH_URL=http://publicauth:9600
|
|
248
|
+
- PRODUCTS_URL=http://products:18000
|
|
249
|
+
- LEDGER_URL=http://ledger:10700
|
|
250
|
+
- WEBHOOKS_URL=http://webhooks:10800
|
|
251
|
+
- TOOLBOX_URL=http://localhost:3040
|
|
252
|
+
working_dir: '/app'
|
|
253
|
+
mem_limit: 2G
|
|
254
|
+
user: root
|
|
255
|
+
logging:
|
|
256
|
+
driver: "json-file"
|
|
257
|
+
ports:
|
|
258
|
+
- "9600:9600"
|
|
259
|
+
|
|
260
|
+
container_name: publicauth
|
|
261
|
+
|
|
262
|
+
products:
|
|
263
|
+
image: governmentdigitalservice/pay-products:local
|
|
264
|
+
|
|
265
|
+
depends_on:
|
|
266
|
+
products_db:
|
|
267
|
+
condition: service_healthy
|
|
268
|
+
|
|
269
|
+
env_file:
|
|
270
|
+
- services/java_app.env
|
|
271
|
+
- services/products.env
|
|
272
|
+
environment:
|
|
273
|
+
- RUN_MIGRATION=true
|
|
274
|
+
- RUN_APP=true
|
|
275
|
+
- PORT=18000
|
|
276
|
+
- DISABLE_INTERNAL_HTTPS=true
|
|
277
|
+
|
|
278
|
+
- DB_HOST=products_db
|
|
279
|
+
- DB_USER=products
|
|
280
|
+
- DB_PASSWORD=mysecretpassword
|
|
281
|
+
- DB_SSL_OPTION=ssl=none
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
- ADMINUSERS_URL=http://adminusers:9700
|
|
291
|
+
- CONNECTOR_URL=http://connector:9300
|
|
292
|
+
- PUBLICAUTH_URL=http://publicauth:9600
|
|
293
|
+
- PRODUCTS_URL=http://products:18000
|
|
294
|
+
- LEDGER_URL=http://ledger:10700
|
|
295
|
+
- WEBHOOKS_URL=http://webhooks:10800
|
|
296
|
+
- TOOLBOX_URL=http://localhost:3040
|
|
297
|
+
working_dir: '/app'
|
|
298
|
+
mem_limit: 2G
|
|
299
|
+
user: root
|
|
300
|
+
logging:
|
|
301
|
+
driver: "json-file"
|
|
302
|
+
ports:
|
|
303
|
+
- "18000:18000"
|
|
304
|
+
|
|
305
|
+
container_name: products
|
|
306
|
+
|
|
307
|
+
ledger:
|
|
308
|
+
image: governmentdigitalservice/pay-ledger:local
|
|
309
|
+
|
|
310
|
+
depends_on:
|
|
311
|
+
ledger_db:
|
|
312
|
+
condition: service_healthy
|
|
313
|
+
|
|
314
|
+
env_file:
|
|
315
|
+
- services/java_app.env
|
|
316
|
+
- services/ledger.env
|
|
317
|
+
environment:
|
|
318
|
+
- RUN_MIGRATION=true
|
|
319
|
+
- RUN_APP=true
|
|
320
|
+
- PORT=10700
|
|
321
|
+
- DISABLE_INTERNAL_HTTPS=true
|
|
322
|
+
|
|
323
|
+
- DB_HOST=ledger_db
|
|
324
|
+
- DB_USER=ledger
|
|
325
|
+
- DB_PASSWORD=mysecretpassword
|
|
326
|
+
- DB_SSL_OPTION=ssl=none
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
- AWS_ACCESS_KEY=mockAccessKey
|
|
331
|
+
- AWS_SECRET_ACCESS_KEY=mockSecretAccessKey
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
- AWS_SQS_REGION=eu-west-1
|
|
336
|
+
- AWS_SQS_MESSAGE_MAXIMUM_WAIT_TIME_IN_SECONDS=20
|
|
337
|
+
- AWS_SQS_NON_STANDARD_SERVICE_ENDPOINT=true
|
|
338
|
+
- AWS_SQS_ENDPOINT=http://localstack:4566
|
|
339
|
+
- AWS_SQS_PAYMENT_EVENT_QUEUE_URL=http://localstack:4566/000000000000/pay_event_queue
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
- AWS_SNS_NON_STANDARD_SERVICE_ENDPOINT=true
|
|
344
|
+
- AWS_SNS_ENDPOINT=http://localstack:4566
|
|
345
|
+
- AWS_SNS_REGION=eu-west-1
|
|
346
|
+
- SNS_TOPIC_CARD_PAYMENT_EVENTS_ARN=arn:aws:sns:eu-west-1:000000000000:card-payment-events-topic
|
|
347
|
+
- SNS_TOPIC_CARD_PAYMENT_DISPUTE_EVENTS_ARN=arn:aws:sns:eu-west-1:000000000000:card-payment-dispute-events-topic
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
- ADMINUSERS_URL=http://adminusers:9700
|
|
351
|
+
- CONNECTOR_URL=http://connector:9300
|
|
352
|
+
- PUBLICAUTH_URL=http://publicauth:9600
|
|
353
|
+
- PRODUCTS_URL=http://products:18000
|
|
354
|
+
- LEDGER_URL=http://ledger:10700
|
|
355
|
+
- WEBHOOKS_URL=http://webhooks:10800
|
|
356
|
+
- TOOLBOX_URL=http://localhost:3040
|
|
357
|
+
- SNS_ENABLED=true
|
|
358
|
+
- PUBLISH_CARD_PAYMENT_EVENTS_TO_SNS=true
|
|
359
|
+
- PUBLISH_CARD_PAYMENT_DISPUTE_EVENTS_TO_SNS=true
|
|
360
|
+
working_dir: '/app'
|
|
361
|
+
mem_limit: 2G
|
|
362
|
+
user: root
|
|
363
|
+
logging:
|
|
364
|
+
driver: "json-file"
|
|
365
|
+
ports:
|
|
366
|
+
- "10700:10700"
|
|
367
|
+
|
|
368
|
+
container_name: ledger
|
|
369
|
+
|
|
370
|
+
webhooks:
|
|
371
|
+
image: governmentdigitalservice/pay-webhooks:local
|
|
372
|
+
|
|
373
|
+
depends_on:
|
|
374
|
+
webhooks_db:
|
|
375
|
+
condition: service_healthy
|
|
376
|
+
|
|
377
|
+
env_file:
|
|
378
|
+
- services/java_app.env
|
|
379
|
+
- services/webhooks.env
|
|
380
|
+
environment:
|
|
381
|
+
- RUN_MIGRATION=true
|
|
382
|
+
- RUN_APP=true
|
|
383
|
+
- PORT=10800
|
|
384
|
+
- DISABLE_INTERNAL_HTTPS=true
|
|
385
|
+
|
|
386
|
+
- DB_HOST=webhooks_db
|
|
387
|
+
- DB_USER=webhooks
|
|
388
|
+
- DB_PASSWORD=mysecretpassword
|
|
389
|
+
- DB_SSL_OPTION=ssl=none
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
- AWS_ACCESS_KEY=mockAccessKey
|
|
394
|
+
- AWS_SECRET_ACCESS_KEY=mockSecretAccessKey
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
- AWS_SQS_REGION=eu-west-1
|
|
399
|
+
- AWS_SQS_MESSAGE_MAXIMUM_WAIT_TIME_IN_SECONDS=20
|
|
400
|
+
- AWS_SQS_NON_STANDARD_SERVICE_ENDPOINT=true
|
|
401
|
+
- AWS_SQS_ENDPOINT=http://localstack:4566
|
|
402
|
+
- AWS_SQS_PAYMENT_EVENT_QUEUE_URL=http://localstack:4566/000000000000/webhooks-events-subscriber-queue
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
- ADMINUSERS_URL=http://adminusers:9700
|
|
408
|
+
- CONNECTOR_URL=http://connector:9300
|
|
409
|
+
- PUBLICAUTH_URL=http://publicauth:9600
|
|
410
|
+
- PRODUCTS_URL=http://products:18000
|
|
411
|
+
- LEDGER_URL=http://ledger:10700
|
|
412
|
+
- WEBHOOKS_URL=http://webhooks:10800
|
|
413
|
+
- TOOLBOX_URL=http://localhost:3040
|
|
414
|
+
working_dir: '/app'
|
|
415
|
+
mem_limit: 2G
|
|
416
|
+
user: root
|
|
417
|
+
logging:
|
|
418
|
+
driver: "json-file"
|
|
419
|
+
ports:
|
|
420
|
+
- "10800:10800"
|
|
421
|
+
|
|
422
|
+
container_name: webhooks
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
toolbox:
|
|
427
|
+
image: node:16.20.0-alpine3.17
|
|
428
|
+
|
|
429
|
+
env_file: services/toolbox.env
|
|
430
|
+
environment:
|
|
431
|
+
- SECURE_COOKIE_OFF=true
|
|
432
|
+
- RUN_APP=true
|
|
433
|
+
- DISABLE_APPMETRICS=true
|
|
434
|
+
- DISABLE_INTERNAL_HTTPS=true
|
|
435
|
+
- PORT=3040
|
|
436
|
+
|
|
437
|
+
- ADMINUSERS_URL=http://adminusers:9700
|
|
438
|
+
|
|
439
|
+
- CONNECTOR_URL=http://connector:9300
|
|
440
|
+
|
|
441
|
+
- PUBLIC_AUTH_URL=http://publicauth:9600
|
|
442
|
+
|
|
443
|
+
- PRODUCTS_URL=http://products:18000
|
|
444
|
+
|
|
445
|
+
- LEDGER_URL=http://ledger:10700
|
|
446
|
+
|
|
447
|
+
- WEBHOOKS_URL=http://webhooks:10800
|
|
448
|
+
- TOOLBOX_URL=http://localhost:3040
|
|
449
|
+
volumes:
|
|
450
|
+
- "$WORKSPACE/pay-toolbox:/app"
|
|
451
|
+
mem_limit: 1G
|
|
452
|
+
working_dir: '/app'
|
|
453
|
+
entrypoint: sh -c "npm run build:copy && npm --inspect=0.0.0.0:3041 start"
|
|
454
|
+
ports:
|
|
455
|
+
- "3040:3040"
|
|
456
|
+
- "3041:3041"
|
|
457
|
+
logging:
|
|
458
|
+
driver: "json-file"
|
|
459
|
+
container_name: toolbox
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
localstack:
|
|
464
|
+
image: localstack/localstack:3
|
|
465
|
+
container_name: localstack
|
|
466
|
+
environment:
|
|
467
|
+
- EAGER_SERVICE_LOADING=1
|
|
468
|
+
- SERVICES=sns,sqs
|
|
469
|
+
ports:
|
|
470
|
+
- "4566:4566" # All AWS services exposed on this port
|
|
471
|
+
volumes:
|
|
472
|
+
- /Users/jonathan.harden/gitdevel/github.com/alphagov/pay-infra/cli/lib/pay_cli/commands/local/files/localstack/init-aws.sh:/etc/localstack/init/ready.d/init-aws.sh
|
|
473
|
+
|
|
@@ -14,6 +14,7 @@ require 'pathname'
|
|
|
14
14
|
REQUIRES_COMPILATION = %w[frontend products-ui selfservice toolbox].freeze
|
|
15
15
|
|
|
16
16
|
class PayCLI::Commands::Local < Thor
|
|
17
|
+
warn "🏠 Local Pay for local people\n\n"
|
|
17
18
|
map "up" => :launch
|
|
18
19
|
desc 'launch | up [--cluster <cluster>] [--local <app>] [--proxy] [--apps] [--rebuild]',
|
|
19
20
|
'Launch a predefined cluster, or a user specified list of apps.' \
|
|
@@ -171,7 +172,7 @@ class PayCLI::Commands::Local < Thor
|
|
|
171
172
|
def user
|
|
172
173
|
warn '🏗️🏗 Constructing useful things for you...'
|
|
173
174
|
gateway_account_ids = []
|
|
174
|
-
|
|
175
|
+
|
|
175
176
|
service = AppClient::create_service()
|
|
176
177
|
service_id = service.fetch('external_id')
|
|
177
178
|
|
|
@@ -189,7 +190,7 @@ class PayCLI::Commands::Local < Thor
|
|
|
189
190
|
end
|
|
190
191
|
end
|
|
191
192
|
end
|
|
192
|
-
|
|
193
|
+
|
|
193
194
|
warn '🤓 Creating admin user for service'
|
|
194
195
|
user = AppClient::create_user(gateway_account_ids: gateway_account_ids)
|
|
195
196
|
warn '😎 Creating read only user for service'
|
|
@@ -41,6 +41,7 @@ do
|
|
|
41
41
|
done
|
|
42
42
|
|
|
43
43
|
ACCOUNT="${ENVIRONMENT%%-*}"
|
|
44
|
+
PAY_ENV_NAME=$(sed -E 's/-[0-9]+$//' <<<"$ENVIRONMENT")
|
|
44
45
|
KEY_LOCATION="${TMPDIR}rds_tunnel_temp_key"
|
|
45
46
|
|
|
46
47
|
function cleanup() {
|
|
@@ -54,6 +55,22 @@ function cleanup() {
|
|
|
54
55
|
|
|
55
56
|
trap cleanup EXIT
|
|
56
57
|
|
|
58
|
+
PROMPT_TEXT="Do you require read-only access, or write-access to the database? [R/w]: "
|
|
59
|
+
read -r -p "$PROMPT_TEXT" READONLY_INPUT
|
|
60
|
+
while [ "$READONLY_INPUT" != "R" ] && [ "$READONLY_INPUT" != "r" ] && [ "$READONLY_INPUT" != "W" ] && [ "$READONLY_INPUT" != "w" ] && [ "$READONLY_INPUT" != "" ]; do
|
|
61
|
+
echo
|
|
62
|
+
read -r -p "$PROMPT_TEXT" READONLY_INPUT
|
|
63
|
+
done
|
|
64
|
+
echo
|
|
65
|
+
|
|
66
|
+
if [ "$READONLY_INPUT" == "w" ] || [ "$READONLY_INPUT" == "W" ]; then
|
|
67
|
+
echo "Database write access requested"
|
|
68
|
+
READONLY=0
|
|
69
|
+
else
|
|
70
|
+
echo "Database read-only access requested"
|
|
71
|
+
READONLY=1
|
|
72
|
+
fi
|
|
73
|
+
|
|
57
74
|
echo "Finding bastion host"
|
|
58
75
|
read -r bastion_instance_id availability_zone <<< "$(aws-vault exec "$ACCOUNT" -- \
|
|
59
76
|
aws autoscaling describe-auto-scaling-groups | \
|
|
@@ -132,18 +149,27 @@ if ! aws-vault exec "$ACCOUNT" -- \
|
|
|
132
149
|
fi
|
|
133
150
|
|
|
134
151
|
SOURCE_DIRECTORY=$(dirname "$BASH_SOURCE")
|
|
135
|
-
|
|
152
|
+
|
|
153
|
+
if [ "$READONLY" -eq 1 ]; then
|
|
154
|
+
DB_USER=$(yq eval ".value.$ENVIRONMENT.$APP.DB_SUPPORT_USER_READONLY" < "${SOURCE_DIRECTORY}/../config/secrets.yml")
|
|
155
|
+
DB_USER_SECRET_NAME="aws/rds/support_readonly_users/${PAY_ENV_NAME}/${DB_USER}" # pragma: allowlist secret
|
|
156
|
+
PAY_SECRETS_PASSWORD_NAME="DB_SUPPORT_PASSWORD_READONLY" # pragma: allowlist secret
|
|
157
|
+
else
|
|
158
|
+
DB_USER=$(yq eval ".value.$ENVIRONMENT.$APP.DB_USER" < "${SOURCE_DIRECTORY}/../config/secrets.yml")
|
|
159
|
+
DB_USER_SECRET_NAME="aws/rds/application_users/${ACCOUNT}/${DB_USER}" # pragma: allowlist secret
|
|
160
|
+
PAY_SECRETS_PASSWORD_NAME="DB_PASSWORD" # pragma: allowlist secret
|
|
161
|
+
fi
|
|
136
162
|
|
|
137
163
|
echo -e "Connected tunnel to $APP RDS database in $ENVIRONMENT on port 65432\n"
|
|
138
164
|
echo "Copy DB credentials to clipboard (in another window) using pay-low-pass:"
|
|
139
|
-
echo -e " pay-low-pass
|
|
165
|
+
echo -e " pay-low-pass $DB_USER_SECRET_NAME | pbcopy\n" # pragma: allowlist secret
|
|
140
166
|
echo "Alternatively, fetch credentials from pay secrets:"
|
|
141
|
-
echo -e " pay secrets fetch $ENVIRONMENT $APP
|
|
167
|
+
echo -e " pay secrets fetch $ENVIRONMENT $APP $PAY_SECRETS_PASSWORD_NAME | pbcopy\n" # pragma: allowlist secret
|
|
142
168
|
echo "Open psql with:"
|
|
143
169
|
echo -e " psql -h localhost -p 65432 -U $DB_USER -d $APP\n"
|
|
144
170
|
echo "Alternatively connect using docker instead of needing psql installed locally and set the password automatically using pay-low-pass:"
|
|
145
171
|
echo -e " docker run --rm -ti postgres:${engine_version}-alpine psql --host docker.for.mac.localhost --port 65432 --user $DB_USER --dbname $APP\n"
|
|
146
172
|
echo "Or even more conveniently connect using a docker container and set the password automatically using pay-low-pass:"
|
|
147
|
-
echo -e " docker run -e \"PGPASSWORD=\$(pay-low-pass
|
|
173
|
+
echo -e " docker run -e \"PGPASSWORD=\$(pay-low-pass ${DB_USER_SECRET_NAME})\" --rm -ti postgres:${engine_version}-alpine psql --host docker.for.mac.localhost --port 65432 --user $DB_USER --dbname $APP\n"
|
|
148
174
|
read -rsn1 -p "Press any key to close session."; echo
|
|
149
175
|
ssh -O exit -S temp-ssh.sock '*'
|
|
@@ -1,91 +1,88 @@
|
|
|
1
1
|
const fs = require('fs')
|
|
2
2
|
const path = require('path')
|
|
3
|
+
const stringify = require('csv-stringify/sync').stringify
|
|
3
4
|
|
|
4
|
-
const INPUT_PATH = `${path.dirname(__filename)}/reports`
|
|
5
|
-
const OUTPUT_PATH = `${path.dirname(__filename)}/reports`
|
|
6
|
-
|
|
5
|
+
const INPUT_PATH = `${path.resolve(path.dirname(__filename))}/reports`
|
|
6
|
+
const OUTPUT_PATH = `${path.resolve(path.dirname(__filename))}/reports`
|
|
7
|
+
|
|
8
|
+
const HEADERS = ["App name", "Release", "Vulnerability", "Severity", "Status", "Package", "Fixed version"]
|
|
7
9
|
const NODE_MAJOR_VERSION = process.versions.node.split('.')[0];
|
|
8
10
|
|
|
9
11
|
if (NODE_MAJOR_VERSION < 16) {
|
|
10
12
|
console.warn('⛔️ requires >= Node 16')
|
|
13
|
+
process.exit(1)
|
|
11
14
|
} else {
|
|
12
15
|
generate()
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
function generate() {
|
|
16
|
-
const jsonData = []
|
|
17
19
|
const date = new Date().toJSON().slice(0, 10);
|
|
18
20
|
const jsonFiles = fs.readdirSync(INPUT_PATH).filter(file => path.extname(file) === '.json')
|
|
19
21
|
const reportFilePath = `${OUTPUT_PATH}/vulnerability_scan_report-${date}.csv`
|
|
22
|
+
const violatedRules = new Map()
|
|
20
23
|
let parseCount = 0
|
|
21
24
|
let rowCount = 0
|
|
22
25
|
try {
|
|
23
26
|
jsonFiles.forEach(file => {
|
|
24
|
-
const
|
|
27
|
+
const appInfo = extractAppAndReleaseFromFilename(file)
|
|
25
28
|
const filePath = path.join(INPUT_PATH, file)
|
|
26
29
|
const data = fs.readFileSync(filePath, 'utf8')
|
|
27
30
|
const parsedData = JSON.parse(data)
|
|
28
|
-
const cveObjects = extractCVEObjects(parsedData["runs"][0]["results"], appAndRelease)
|
|
29
|
-
jsonData.push({
|
|
30
|
-
"CVEs": cveObjects
|
|
31
|
-
})
|
|
32
|
-
})
|
|
33
31
|
|
|
34
|
-
|
|
32
|
+
const appViolations = [];
|
|
33
|
+
violatedRules.set(`${appInfo.name}:${appInfo.release}`, appViolations)
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
parsedData["runs"][0]["tool"]["driver"]["rules"].forEach(
|
|
36
|
+
(violatedRule) => appViolations.push({
|
|
37
|
+
"App name": appInfo.name,
|
|
38
|
+
"Release": appInfo.release,
|
|
39
|
+
"Vulnerability": violatedRule.id,
|
|
40
|
+
"Severity": violatedRule.properties.cvssV3_severity,
|
|
41
|
+
"Status": "",
|
|
42
|
+
"Package": violatedRule.properties.purls.join("\n"),
|
|
43
|
+
"Fixed version": violatedRule.properties.fixed_version,
|
|
44
|
+
})
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
parseCount++
|
|
48
|
+
})
|
|
49
|
+
} catch (err) {
|
|
50
|
+
console.error(`Error: Failed parsing source json after successfully parsing ${parseCount} of ${jsonFiles.length} source files: `, err)
|
|
51
|
+
process.exit(1)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const csv_rows = [HEADERS];
|
|
55
|
+
try {
|
|
56
|
+
violatedRules.forEach((violations) => {
|
|
57
|
+
violations.forEach((violation) => {
|
|
58
|
+
const row = HEADERS.map(key => violation[key])
|
|
59
|
+
csv_rows.push(row)
|
|
40
60
|
rowCount++
|
|
41
61
|
})
|
|
42
|
-
parseCount++
|
|
43
62
|
})
|
|
44
63
|
} catch (err) {
|
|
45
|
-
console.error("
|
|
46
|
-
|
|
47
|
-
|
|
64
|
+
console.error("Error collating results for writing to CSV: ", err)
|
|
65
|
+
process.exit(1)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
fs.writeFileSync(reportFilePath, stringify(csv_rows))
|
|
70
|
+
} catch (err) {
|
|
71
|
+
console.error("Error writing CSV file: ", err.message)
|
|
72
|
+
process.exit(1)
|
|
48
73
|
}
|
|
49
|
-
}
|
|
50
74
|
|
|
75
|
+
console.log(`Parsed ${parseCount} of ${jsonFiles.length} JSON files, wrote ${rowCount} row(s) to ${reportFilePath}`)
|
|
76
|
+
}
|
|
51
77
|
|
|
52
|
-
function
|
|
78
|
+
function extractAppAndReleaseFromFilename(fileName) {
|
|
53
79
|
const regex = /^.*?(?=-\d+)/ // matches any characters at the beginning of the string that are followed by a dash and one or more digits
|
|
54
|
-
const match =
|
|
80
|
+
const match = fileName.match(regex)
|
|
55
81
|
if (match && match[0]) {
|
|
56
|
-
const release =
|
|
57
|
-
return
|
|
82
|
+
const release = fileName.replace(`${match[0]}-`, "").replace(".json", "")
|
|
83
|
+
return { name: match[0], release }
|
|
58
84
|
} else {
|
|
59
|
-
const fallback =
|
|
60
|
-
return
|
|
85
|
+
const fallback = fileName.replace(".json", "")
|
|
86
|
+
return { name: fallback, release: fallback}
|
|
61
87
|
}
|
|
62
88
|
}
|
|
63
|
-
|
|
64
|
-
function extractCVEObjects(results, appAndRelease) {
|
|
65
|
-
let cveObjects = []
|
|
66
|
-
results.forEach(result => {
|
|
67
|
-
const stringArr = result["message"]["text"].split("\n").reduce((stringArr, string) => {
|
|
68
|
-
if (string !== "") {
|
|
69
|
-
stringArr.push(string
|
|
70
|
-
.split(", ")
|
|
71
|
-
.join(" ")
|
|
72
|
-
.trim()
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
return stringArr
|
|
76
|
-
}, [])
|
|
77
|
-
stringArr.push(`App name: ${appAndRelease[0]}`)
|
|
78
|
-
stringArr.push(`Release: ${appAndRelease[1]}`)
|
|
79
|
-
cveObjects.push(convertStringArrayToCVEObj(stringArr))
|
|
80
|
-
})
|
|
81
|
-
return cveObjects
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function convertStringArrayToCVEObj(stringArr) {
|
|
85
|
-
const cveObj = {}
|
|
86
|
-
stringArr.forEach(s => {
|
|
87
|
-
const parts = s.split(':');
|
|
88
|
-
cveObj[parts[0].trim()] = parts[1].trim()
|
|
89
|
-
})
|
|
90
|
-
return cveObj
|
|
91
|
-
}
|