emasser 1.0.6 → 3.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.dockerignore +8 -8
- data/.env-example +12 -12
- data/.github/release-drafter.yml +15 -15
- data/.github/workflows/codeql-analysis.yml +70 -70
- data/.github/workflows/draft-release.yml +15 -15
- data/.github/workflows/gh-pages.yml +32 -32
- data/.github/workflows/push-to-docker-mail.yml +28 -28
- data/.github/workflows/push-to-docker.yml +35 -35
- data/.github/workflows/release.yml +42 -42
- data/.github/workflows/rubocop.yml +23 -23
- data/.github/workflows/test-cli.yml +72 -72
- data/.gitignore +19 -19
- data/.mergify.yml +25 -25
- data/.rubocop.yml +80 -80
- data/.rubocop_todo.yml +27 -27
- data/CHANGELOG.md +16 -16
- data/Dockerfile +44 -44
- data/Gemfile +8 -8
- data/Gemfile.lock +104 -104
- data/LICENSE.md +15 -15
- data/README.md +178 -178
- data/Rakefile +18 -18
- data/_config.yml +1 -1
- data/docs/features.md +1436 -1330
- data/docs/redoc/index.html +1230 -1230
- data/emasser.gemspec +44 -44
- data/exe/emasser +5 -5
- data/lib/emasser/cli.rb +37 -37
- data/lib/emasser/configuration.rb +49 -49
- data/lib/emasser/constants.rb +26 -26
- data/lib/emasser/delete.rb +148 -148
- data/lib/emasser/errors.rb +14 -14
- data/lib/emasser/get.rb +949 -670
- data/lib/emasser/help/approvalCac_post_mapper.md +20 -20
- data/lib/emasser/help/approvalPac_post_mapper.md +20 -20
- data/lib/emasser/help/artifacts_del_mapper.md +9 -9
- data/lib/emasser/help/artifacts_post_mapper.md +59 -59
- data/lib/emasser/help/artifacts_put_mapper.md +34 -34
- data/lib/emasser/help/cloudresource_post_mapper.md +62 -62
- data/lib/emasser/help/cmmc_get_mapper.md +4 -4
- data/lib/emasser/help/container_post_mapper.md +44 -44
- data/lib/emasser/help/controls_put_mapper.md +74 -74
- data/lib/emasser/help/milestone_del_mapper.md +11 -11
- data/lib/emasser/help/milestone_post_mapper.md +14 -14
- data/lib/emasser/help/milestone_put_mapper.md +23 -23
- data/lib/emasser/help/poam_del_mapper.md +5 -5
- data/lib/emasser/help/poam_post_mapper.md +93 -93
- data/lib/emasser/help/poam_put_mapper.md +107 -107
- data/lib/emasser/help/staticcode_clear_mapper.md +16 -16
- data/lib/emasser/help/staticcode_post_mapper.md +21 -21
- data/lib/emasser/help/testresults_post_mapper.md +21 -21
- data/lib/emasser/help.rb +11 -11
- data/lib/emasser/input_converters.rb +21 -21
- data/lib/emasser/options_parser.rb +20 -20
- data/lib/emasser/output_converters.rb +111 -111
- data/lib/emasser/post.rb +830 -802
- data/lib/emasser/put.rb +588 -588
- data/lib/emasser/version.rb +5 -5
- data/lib/emasser.rb +19 -19
- metadata +10 -16
data/lib/emasser/post.rb
CHANGED
@@ -1,802 +1,830 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Hack class that properly formats the CLI help
|
4
|
-
class SubCommandBase < Thor
|
5
|
-
include OptionsParser
|
6
|
-
include InputConverters
|
7
|
-
include OutputConverters
|
8
|
-
|
9
|
-
# We do not control the method declaration for the banner
|
10
|
-
|
11
|
-
# rubocop:disable Style/OptionalBooleanParameter
|
12
|
-
def self.banner(command, _namespace = nil, subcommand = false)
|
13
|
-
# Use the $thor_runner (declared by the Thor CLI framework)
|
14
|
-
# to properly format the help text of sub-sub-commands.
|
15
|
-
|
16
|
-
# rubocop:disable Style/GlobalVars
|
17
|
-
if ancestors[0].to_s.include? '::Post'
|
18
|
-
"#{basename} #{command.formatted_usage(self, $thor_runner, subcommand)}"
|
19
|
-
else
|
20
|
-
"#{basename} post #{command.formatted_usage(self, $thor_runner, subcommand)}"
|
21
|
-
end
|
22
|
-
# rubocop:enable Style/GlobalVars
|
23
|
-
end
|
24
|
-
# rubocop:enable Style/OptionalBooleanParameter
|
25
|
-
end
|
26
|
-
|
27
|
-
# Override thor's long_desc identation behavior
|
28
|
-
class Thor
|
29
|
-
module Shell
|
30
|
-
class Basic
|
31
|
-
def print_wrapped(message, _options = {})
|
32
|
-
message = "\n#{message}\n" unless message[0] == "\n"
|
33
|
-
stdout.puts message
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
module Emasser
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
#
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
option :
|
143
|
-
option :
|
144
|
-
option :
|
145
|
-
|
146
|
-
|
147
|
-
option :
|
148
|
-
option :
|
149
|
-
|
150
|
-
|
151
|
-
option :
|
152
|
-
option :
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
body
|
183
|
-
body.
|
184
|
-
body.
|
185
|
-
body.
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
body.
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
puts
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
puts '
|
589
|
-
puts
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
body[:
|
670
|
-
body[:
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
body[:
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Hack class that properly formats the CLI help
|
4
|
+
class SubCommandBase < Thor
|
5
|
+
include OptionsParser
|
6
|
+
include InputConverters
|
7
|
+
include OutputConverters
|
8
|
+
|
9
|
+
# We do not control the method declaration for the banner
|
10
|
+
|
11
|
+
# rubocop:disable Style/OptionalBooleanParameter
|
12
|
+
def self.banner(command, _namespace = nil, subcommand = false)
|
13
|
+
# Use the $thor_runner (declared by the Thor CLI framework)
|
14
|
+
# to properly format the help text of sub-sub-commands.
|
15
|
+
|
16
|
+
# rubocop:disable Style/GlobalVars
|
17
|
+
if ancestors[0].to_s.include? '::Post'
|
18
|
+
"#{basename} #{command.formatted_usage(self, $thor_runner, subcommand)}"
|
19
|
+
else
|
20
|
+
"#{basename} post #{command.formatted_usage(self, $thor_runner, subcommand)}"
|
21
|
+
end
|
22
|
+
# rubocop:enable Style/GlobalVars
|
23
|
+
end
|
24
|
+
# rubocop:enable Style/OptionalBooleanParameter
|
25
|
+
end
|
26
|
+
|
27
|
+
# Override thor's long_desc identation behavior
|
28
|
+
class Thor
|
29
|
+
module Shell
|
30
|
+
class Basic
|
31
|
+
def print_wrapped(message, _options = {})
|
32
|
+
message = "\n#{message}\n" unless message[0] == "\n"
|
33
|
+
stdout.puts message
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module Emasser
|
40
|
+
# Common static messages
|
41
|
+
POAMS_POST_HELP_MESSAGE = "\nInvoke \"emasser post poams help add\" for additional help"
|
42
|
+
SCAN_POST_HELP_MESSAGE = "\nInvoke \"emasser post scan_findings help clear\" for additional help"
|
43
|
+
|
44
|
+
# The Registration endpoint provides the ability to register a certificate & obtain an API-key.
|
45
|
+
#
|
46
|
+
# Endpoint:
|
47
|
+
# /api/api-key - Register certificate and obtain API key
|
48
|
+
class Register < SubCommandBase
|
49
|
+
def self.exit_on_failure?
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
desc 'cert', 'Register a certificate & obtain an API-key'
|
54
|
+
# rubocop:disable Style/RedundantBegin
|
55
|
+
def cert
|
56
|
+
begin
|
57
|
+
result = EmassClient::RegistrationApi.new.register_user({})
|
58
|
+
puts to_output_hash(result).green
|
59
|
+
rescue EmassClient::ApiError => e
|
60
|
+
puts 'Exception when calling RegistrationApi->register_user'.red
|
61
|
+
puts to_output_hash(e)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
# rubocop:enable Style/RedundantBegin
|
65
|
+
end
|
66
|
+
|
67
|
+
# The Test Results endpoints provide the ability to add test results for a
|
68
|
+
# system's Assessment Procedures (CCIs) which determine Security Control compliance.
|
69
|
+
#
|
70
|
+
# Endpoint:
|
71
|
+
# /api/systems/{systemId}/test-results - Add one or many test results for a system
|
72
|
+
class TestResults < SubCommandBase
|
73
|
+
def self.exit_on_failure?
|
74
|
+
true
|
75
|
+
end
|
76
|
+
|
77
|
+
desc 'add', 'Post a test result for a system'
|
78
|
+
long_desc Help.text(:testresults_post_mapper)
|
79
|
+
|
80
|
+
# Required fields
|
81
|
+
option :systemId, type: :numeric, required: true,
|
82
|
+
desc: 'A numeric value representing the system identification'
|
83
|
+
option :cci, type: :string, required: true, desc: 'The system CCI string numerical value'
|
84
|
+
option :testedBy, type: :string, required: true, desc: 'The person that conducted the test (Last Name, First)'
|
85
|
+
option :testDate, type: :numeric, required: true, desc: 'The date test was conducted, Unix time format.'
|
86
|
+
option :description, type: :string, required: true, desc: 'The description of test result. 4000 Characters.'
|
87
|
+
option :complianceStatus, type: :string, required: true, enum: ['Compliant', 'Non-Compliant', 'Not Applicable']
|
88
|
+
|
89
|
+
def add
|
90
|
+
body = EmassClient::TestResultsGet.new
|
91
|
+
body.cci = options[:cci]
|
92
|
+
body.tested_by = options[:testedBy]
|
93
|
+
body.test_date = options[:testDate]
|
94
|
+
body.description = options[:description]
|
95
|
+
body.compliance_status = options[:complianceStatus]
|
96
|
+
|
97
|
+
body_array = Array.new(1, body)
|
98
|
+
|
99
|
+
begin
|
100
|
+
result = EmassClient::TestResultsApi
|
101
|
+
.new.add_test_results_by_system_id(options[:systemId], body_array)
|
102
|
+
puts to_output_hash(result).green
|
103
|
+
rescue EmassClient::ApiError => e
|
104
|
+
puts 'Exception when calling TestResultsApi->add_test_results_by_system_id'.red
|
105
|
+
puts to_output_hash(e)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# The POA&M endpoints provide the ability to add Plan of Action and Milestones (POA&M)
|
111
|
+
# items to a system.
|
112
|
+
#
|
113
|
+
# Endpoint:
|
114
|
+
# /api/systems/{systemId}/poams - Add one or many poa&m items in a system
|
115
|
+
class Poams < SubCommandBase
|
116
|
+
def self.exit_on_failure?
|
117
|
+
true
|
118
|
+
end
|
119
|
+
|
120
|
+
# POAM --------------------------------------------------------------------
|
121
|
+
#
|
122
|
+
# The following fields are required based on the contents of the status field
|
123
|
+
# status Required Fields
|
124
|
+
# -------------------------------------------------------------------------
|
125
|
+
# Risk Accepted comments, resources
|
126
|
+
# Ongoing scheduledCompletionDate, resources, milestones (at least 1)
|
127
|
+
# Completed scheduledCompletionDate, comments, resources,
|
128
|
+
# completionDate, milestones (at least 1)
|
129
|
+
# Not Applicable POAM can not be created
|
130
|
+
#--------------------------------------------------------------------------
|
131
|
+
#
|
132
|
+
# If a POC email is supplied, the application will attempt to locate a user
|
133
|
+
# already registered within the application and pre-populate any information
|
134
|
+
# not explicitly supplied in the request. If no such user is found, these
|
135
|
+
# fields are required within the request:
|
136
|
+
# pocFirstName, pocLastName, pocPhoneNumber
|
137
|
+
|
138
|
+
desc 'add', 'Add one or many POA&M items in a system'
|
139
|
+
long_desc Help.text(:poam_post_mapper)
|
140
|
+
|
141
|
+
# Required parameters/fields (the poamId and displayPoamId are generated by the PUT call)
|
142
|
+
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
143
|
+
option :status, type: :string, required: true, enum: ['Ongoing', 'Risk Accepted', 'Completed', 'Not Applicable']
|
144
|
+
option :vulnerabilityDescription, type: :string, required: true, desc: 'POA&M vulnerability description'
|
145
|
+
option :sourceIdentVuln,
|
146
|
+
type: :string, required: true, desc: 'Source that identifies the vulnerability'
|
147
|
+
option :pocOrganization, type: :string, required: true, desc: 'Organization/Office represented'
|
148
|
+
option :resources, type: :string, required: true, desc: 'List of resources used'
|
149
|
+
|
150
|
+
# Conditional parameters/fields
|
151
|
+
option :milestone, type: :hash, required: false, desc: 'key:values are: description and scheduledCompletionDate'
|
152
|
+
option :pocFirstName, type: :string, required: false, desc: 'First name of POC'
|
153
|
+
option :pocLastName, type: :string, required: false, desc: 'Last name of POC.'
|
154
|
+
option :pocEmail, type: :string, required: false, desc: 'Email address of POC'
|
155
|
+
option :pocPhoneNumber, type: :string, required: false, desc: 'Phone number of POC (area code) ***-**** format'
|
156
|
+
option :severity, type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
157
|
+
option :scheduledCompletionDate,
|
158
|
+
type: :numeric, required: false, desc: 'The scheduled completion date - Unix time format'
|
159
|
+
option :completionDate,
|
160
|
+
type: :numeric, required: false, desc: 'The schedule completion date - Unix time format'
|
161
|
+
option :comments, type: :string, required: false, desc: 'Comments for completed and risk accepted POA&M items'
|
162
|
+
|
163
|
+
# Optional parameters/fields
|
164
|
+
option :externalUid, type: :string, required: false, desc: 'External ID associated with the POA&M'
|
165
|
+
option :controlAcronym, type: :string, required: false, desc: 'The system acronym(s) e.g "AC-1, AC-2"'
|
166
|
+
option :cci, type: :string, required: false, desc: 'The system CCIS string numerical value'
|
167
|
+
option :securityChecks, type: :string, required: false, desc: 'Security Checks that are associated with the POA&M'
|
168
|
+
option :rawSeverity, type: :string, required: false, enum: %w[I II III]
|
169
|
+
option :relevanceOfThreat,
|
170
|
+
type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
171
|
+
option :likelihood, type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
172
|
+
option :impact, type: :string, required: false, desc: 'Description of Security Control’s impact'
|
173
|
+
option :impactDescription, type: :string, required: false, desc: 'Description of the security control impact'
|
174
|
+
option :residualRiskLevel,
|
175
|
+
type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
176
|
+
option :recommendations, type: :string, required: false, desc: 'Recomendations'
|
177
|
+
option :mitigation, type: :string, required: false, desc: 'Mitigation explanation'
|
178
|
+
|
179
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
180
|
+
def add
|
181
|
+
# Required fields
|
182
|
+
body = EmassClient::PoamGet.new
|
183
|
+
body.status = options[:status]
|
184
|
+
body.vulnerability_description = options[:vulnerabilityDescription]
|
185
|
+
body.source_ident_vuln = options[:sourceIdentVuln]
|
186
|
+
body.poc_organization = options[:pocOrganization]
|
187
|
+
body.resources = options[:resources]
|
188
|
+
|
189
|
+
process_business_logic(body)
|
190
|
+
|
191
|
+
# Add conditional fields
|
192
|
+
body.poc_first_name = options[:pocFirstName] if options[:pocFirstName]
|
193
|
+
body.poc_last_name = options[:pocLastName] if options[:pocLastName]
|
194
|
+
body.poc_email = options[:pocEmail] if options[:pocEmail]
|
195
|
+
body.poc_phone_number = options[:pocPhoneNumber] if options[:pocPhoneNumber]
|
196
|
+
body.severity = options[:severity] if options[:severity]
|
197
|
+
|
198
|
+
# Add optional fields
|
199
|
+
body.external_uid = options[:externalUid] if options[:externalUid]
|
200
|
+
body.control_acronyms = options[:controlAcronym] if options[:controlAcronym]
|
201
|
+
body.cci = options[:cci] if options[:cci]
|
202
|
+
body.security_checks = options[:securityChecks] if options[:securityChecks]
|
203
|
+
body.raw_severity = options[:rawSeverity] if options[:rawSeverity]
|
204
|
+
body.relevance_of_threat = options[:relevanceOfThreat] if options[:relevanceOfThreat]
|
205
|
+
body.likelihood = options[:likelihood] if options[:likelihood]
|
206
|
+
body.impact = options[:impact] if options[:impact]
|
207
|
+
body.impact_description = options[:impactDescription] if options[:impactDescription]
|
208
|
+
body.residual_risk_level = options[:residualRiskLevel] if options[:residualRiskLevel]
|
209
|
+
body.recommendations = options[:recommendations] if options[:recommendations]
|
210
|
+
body.mitigation = options[:mitigation] if options[:mitigation]
|
211
|
+
|
212
|
+
body_array = Array.new(1, body)
|
213
|
+
|
214
|
+
begin
|
215
|
+
result = EmassClient::POAMApi.new.add_poam_by_system_id(options[:systemId], body_array)
|
216
|
+
puts to_output_hash(result).green
|
217
|
+
rescue EmassClient::ApiError => e
|
218
|
+
puts 'Exception when calling POAMApi->add_poam_by_system_id'.red
|
219
|
+
puts to_output_hash(e)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
223
|
+
|
224
|
+
# rubocop:disable Metrics/BlockLength, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
225
|
+
no_commands do
|
226
|
+
def process_business_logic(body)
|
227
|
+
#-----------------------------------------------------------------------------
|
228
|
+
# Conditional fields based on the status field values
|
229
|
+
# "Risk Accepted" comments, resources
|
230
|
+
# "Ongoing" scheduledCompletionDate, resources, milestones (at least 1)
|
231
|
+
# "Completed" scheduledCompletionDate, comments, resources,
|
232
|
+
# completionDate, milestones (at least 1)
|
233
|
+
# "Not Applicable" POAM can not be created
|
234
|
+
#-----------------------------------------------------------------------------
|
235
|
+
# rubocop:disable Style/CaseLikeIf, Style/StringLiterals
|
236
|
+
if options[:status] == "Risk Accepted"
|
237
|
+
if options[:comments].nil?
|
238
|
+
puts 'When status = "Risk Accepted" the following parameters/fields are required:'.red
|
239
|
+
puts ' comments'.red
|
240
|
+
puts POAMS_POST_HELP_MESSAGE.yellow
|
241
|
+
exit
|
242
|
+
elsif !(options[:scheduledCompletionDate].nil? && options[:milestone].nil?)
|
243
|
+
puts 'When status = "Risk Accepted" POA&M Item CAN NOT be saved with the following parameters/fields:'.red
|
244
|
+
puts ' scheduledCompletionDate, or milestone'.red
|
245
|
+
puts POAMS_PUT_HELP_MESSAGE.yellow
|
246
|
+
exit
|
247
|
+
else
|
248
|
+
body.comments = options[:comments]
|
249
|
+
end
|
250
|
+
elsif options[:status] == "Ongoing"
|
251
|
+
if options[:scheduledCompletionDate].nil? || options[:milestone].nil?
|
252
|
+
puts 'When status = "Ongoing" the following parameters/fields are required:'.red
|
253
|
+
puts ' scheduledCompletionDate, milestone'.red
|
254
|
+
print_milestone_help
|
255
|
+
puts POAMS_POST_HELP_MESSAGE.yellow
|
256
|
+
exit
|
257
|
+
elsif options[:milestone]["description"].nil? || options[:milestone]["scheduledCompletionDate"].nil?
|
258
|
+
puts 'Missing milstone parameters/fields'.red
|
259
|
+
print_milestone_help
|
260
|
+
exit
|
261
|
+
else
|
262
|
+
body.scheduled_completion_date = options[:scheduledCompletionDate]
|
263
|
+
|
264
|
+
milestone = EmassClient::MilestonesRequiredPost.new
|
265
|
+
milestone.description = options[:milestone]["description"]
|
266
|
+
milestone.scheduled_completion_date = options[:milestone]["scheduledCompletionDate"]
|
267
|
+
milestone_array = Array.new(1, milestone)
|
268
|
+
body.milestones = milestone_array
|
269
|
+
end
|
270
|
+
elsif options[:status] == "Completed"
|
271
|
+
if options[:scheduledCompletionDate].nil? || options[:comments].nil? ||
|
272
|
+
options[:completionDate].nil? || options[:milestone].nil?
|
273
|
+
puts 'When status = "Completed" the following parameters/fields are required:'.red
|
274
|
+
puts ' scheduledCompletionDate, comments, completionDate, or milestone'.red
|
275
|
+
print_milestone_help
|
276
|
+
puts POAMS_POST_HELP_MESSAGE.yellow
|
277
|
+
exit
|
278
|
+
else
|
279
|
+
body.scheduled_completion_date = options[:scheduledCompletionDate]
|
280
|
+
body.comments = options[:comments]
|
281
|
+
body.completion_date = options[:completionDate]
|
282
|
+
|
283
|
+
milestone = EmassClient::MilestonesRequiredPost.new
|
284
|
+
milestone.description = options[:milestone]["description"]
|
285
|
+
milestone.scheduled_completion_date = options[:milestone]["scheduledCompletionDate"]
|
286
|
+
milestone_array = Array.new(1, milestone)
|
287
|
+
body.milestones = milestone_array
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
# POC checks: If any poc information is provided all POC fields are required
|
292
|
+
if options[:pocFirstName]
|
293
|
+
if options[:pocLastName].nil? || options[:pocEmail].nil? || options[:pocPhoneNumber].nil?
|
294
|
+
puts 'If a POC first name is given, then all POC information must be entered:'.red
|
295
|
+
puts ' pocLastName, pocEmail, pocPhoneNumber'.red
|
296
|
+
puts POAMS_POST_HELP_MESSAGE.yellow
|
297
|
+
exit
|
298
|
+
end
|
299
|
+
elsif options[:pocLastName]
|
300
|
+
if options[:pocFirstName].nil? || options[:pocEmail].nil? || options[:pocPhoneNumber].nil?
|
301
|
+
puts 'If a POC last name is given, then all POC information must be entered:'.red
|
302
|
+
puts ' pocFirstName, pocEmail, pocPhoneNumber'.red
|
303
|
+
puts POAMS_POST_HELP_MESSAGE.yellow
|
304
|
+
exit
|
305
|
+
end
|
306
|
+
elsif options[:pocEmail]
|
307
|
+
if options[:pocFirstName].nil? || options[:pocLastName].nil? || options[:pocPhoneNumber].nil?
|
308
|
+
puts 'If a POC email is given, then all POC information must be entered:'.red
|
309
|
+
puts ' pocFirstName, pocLastName, pocPhoneNumber'.red
|
310
|
+
puts POAMS_POST_HELP_MESSAGE.yellow
|
311
|
+
exit
|
312
|
+
end
|
313
|
+
elsif options[:pocPhoneNumber]
|
314
|
+
if options[:pocFirstName].nil? || options[:pocLastName].nil? || options[:pocEmail].nil?
|
315
|
+
puts 'If a POC phone number is given, then all POC information must be entered:'.red
|
316
|
+
puts ' pocFirstName, pocLastName, pocEmail'.red
|
317
|
+
puts POAMS_POST_HELP_MESSAGE.yellow
|
318
|
+
exit
|
319
|
+
end
|
320
|
+
end
|
321
|
+
# rubocop:enable Style/CaseLikeIf, Style/StringLiterals
|
322
|
+
end
|
323
|
+
|
324
|
+
def print_milestone_help
|
325
|
+
puts 'Milestone format is:'.yellow
|
326
|
+
puts ' --milestone description:"[value]" scheduledCompletionDate:"[value]"'.yellow
|
327
|
+
end
|
328
|
+
end
|
329
|
+
# rubocop:enable Metrics/BlockLength, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
330
|
+
end
|
331
|
+
|
332
|
+
# The Milestones endpoints provide the ability add milestones that are associated with
|
333
|
+
# Plan of Action and Milestones (POA&M) items for a system.
|
334
|
+
#
|
335
|
+
# Endpoint:
|
336
|
+
# /api/systems/{systemId}/poams/{poamId}/milestones - Add milestones in one or many poa&m items in a system
|
337
|
+
class Milestones < SubCommandBase
|
338
|
+
def self.exit_on_failure?
|
339
|
+
true
|
340
|
+
end
|
341
|
+
|
342
|
+
desc 'add', 'Add milestones to one or many POA&M items in a system'
|
343
|
+
long_desc Help.text(:milestone_post_mapper)
|
344
|
+
|
345
|
+
# Required parameters/fields
|
346
|
+
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
347
|
+
option :poamId, type: :numeric, required: true, desc: 'A numeric value representing the poam identification'
|
348
|
+
option :description, type: :string, required: true, desc: 'The milestone description'
|
349
|
+
option :scheduledCompletionDate,
|
350
|
+
type: :numeric, required: true, desc: 'The scheduled completion date - Unix time format'
|
351
|
+
|
352
|
+
def add
|
353
|
+
body = EmassClient::MilestonesGet.new
|
354
|
+
body.description = options[:description]
|
355
|
+
body.scheduled_completion_date = options[:scheduledCompletionDate]
|
356
|
+
body_array = Array.new(1, body)
|
357
|
+
|
358
|
+
begin
|
359
|
+
result = EmassClient::MilestonesApi
|
360
|
+
.new.add_milestone_by_system_id_and_poam_id(options[:systemId], options[:poamId], body_array)
|
361
|
+
puts to_output_hash(result).green
|
362
|
+
rescue EmassClient::ApiError => e
|
363
|
+
puts 'Exception when calling MilestonesApi->add_milestone_by_system_id_and_poam_id'.red
|
364
|
+
puts to_output_hash(e)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
# Add one or many artifacts for a system (delivery method must be a zip file)
|
370
|
+
#
|
371
|
+
# Endpoints:
|
372
|
+
# /api/systems/{systemId}/artifacts - Post one or many artifacts to a system
|
373
|
+
class Artifacts < SubCommandBase
|
374
|
+
def self.exit_on_failure?
|
375
|
+
true
|
376
|
+
end
|
377
|
+
|
378
|
+
desc 'upload SYSTEM_ID FILE [FILE ...]', 'Uploads [FILES] to the given [SYSTEM_ID] as artifacts'
|
379
|
+
long_desc Help.text(:artifacts_post_mapper)
|
380
|
+
|
381
|
+
# Required parameters/fields
|
382
|
+
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
383
|
+
option :files, type: :array, required: true, desc: 'Artifact file(s) to post to the given system'
|
384
|
+
option :type,
|
385
|
+
type: :string, required: true,
|
386
|
+
enum: ['Procedure', 'Diagram', 'Policy', 'Labor', 'Document',
|
387
|
+
'Image', 'Other', 'Scan Result', 'Auditor Report']
|
388
|
+
option :category, type: :string, required: true, enum: ['Implementation Guidance', 'Evidence']
|
389
|
+
option :isTemplate, type: :boolean, required: false, default: false, desc: 'BOOLEAN - true or false.'
|
390
|
+
|
391
|
+
# Optional parameters/fields
|
392
|
+
option :description, type: :string, required: false, desc: 'Artifact description'
|
393
|
+
option :refPageNumber, type: :string, required: false, desc: 'Artifact reference page number'
|
394
|
+
option :ccis, type: :string, required: false, desc: 'The system CCIs string numerical value'
|
395
|
+
option :controls,
|
396
|
+
type: :string, required: false,
|
397
|
+
desc: 'Control acronym associated with the artifact. NIST SP 800-53 Revision 4 defined'
|
398
|
+
option :artifactExpirationDate,
|
399
|
+
type: :numeric, required: false, desc: 'Date Artifact expires and requires review - Unix time format'
|
400
|
+
option :lastReviewedDate,
|
401
|
+
type: :numeric, required: false, desc: 'Date Artifact was last reviewed - Unix time format'
|
402
|
+
|
403
|
+
def upload
|
404
|
+
optional_options_keys = optional_options(@_initializer).keys
|
405
|
+
optional_options = to_input_hash(optional_options_keys, options)
|
406
|
+
# Remove the isTemplate as we can't use the required = true.
|
407
|
+
optional_options.delete(:is_template)
|
408
|
+
|
409
|
+
opts = {}
|
410
|
+
opts[:type] = options[:type]
|
411
|
+
opts[:category] = options[:category]
|
412
|
+
opts[:is_template] = options[:is_template]
|
413
|
+
opts[:form_params] = optional_options
|
414
|
+
|
415
|
+
tempfile = Tempfile.create(['artifacts', '.zip'])
|
416
|
+
|
417
|
+
Zip::OutputStream.open(tempfile.path) do |z|
|
418
|
+
options[:files].each do |file|
|
419
|
+
# Add file name to the archive: Don't use the full path
|
420
|
+
z.put_next_entry(File.basename(file))
|
421
|
+
# Add the file to the archive
|
422
|
+
z.print File.read(file)
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
begin
|
427
|
+
result = EmassClient::ArtifactsApi
|
428
|
+
.new
|
429
|
+
.add_artifacts_by_system_id(options[:systemId], tempfile, opts)
|
430
|
+
puts to_output_hash(result).green
|
431
|
+
rescue EmassClient::ApiError => e
|
432
|
+
puts 'Exception when calling ArtifactsApi->add_artifacts_by_system_id'.red
|
433
|
+
puts to_output_hash(e)
|
434
|
+
ensure
|
435
|
+
# Delete the temp file
|
436
|
+
unless File.exist? tempfile
|
437
|
+
tempfile.close
|
438
|
+
FileUtils.remove_file(tempfile, true)
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
# Add a Control Approval Chain (CAC)
|
445
|
+
#
|
446
|
+
# Endpoints:
|
447
|
+
# /api/systems/{systemId}/approval/cac - Submit control to second stage of CAC
|
448
|
+
class CAC < SubCommandBase
|
449
|
+
def self.exit_on_failure?
|
450
|
+
true
|
451
|
+
end
|
452
|
+
|
453
|
+
desc 'add', 'Submit control to second stage of CAC'
|
454
|
+
long_desc Help.text(:approvalCac_post_mapper)
|
455
|
+
|
456
|
+
# Required parameters/fields
|
457
|
+
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
458
|
+
option :controlAcronym, type: :string, required: true, desc: 'The system acronym "AC-1, AC-2"'
|
459
|
+
|
460
|
+
# Conditional parameters/fields
|
461
|
+
option :comments, type: :string, required: false, desc: 'The control approval chain comments'
|
462
|
+
|
463
|
+
def add
|
464
|
+
body = EmassClient::CacGet.new
|
465
|
+
body.control_acronym = options[:controlAcronym]
|
466
|
+
body.comments = options[:comments]
|
467
|
+
|
468
|
+
body_array = Array.new(1, body)
|
469
|
+
|
470
|
+
begin
|
471
|
+
# Get location of one or many controls in CAC
|
472
|
+
result = EmassClient::CACApi.new.add_system_cac(options[:systemId], body_array)
|
473
|
+
puts to_output_hash(result).green
|
474
|
+
rescue EmassClient::ApiError => e
|
475
|
+
puts 'Exception when calling ApprovalChainApi->add_system_cac'.red
|
476
|
+
puts to_output_hash(e)
|
477
|
+
end
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
# Add a Package Approval Chain (PAC)
|
482
|
+
#
|
483
|
+
# Endpoints:
|
484
|
+
# /api/systems/{systemId}/approval/pac - Initiate system workflow for review
|
485
|
+
class PAC < SubCommandBase
|
486
|
+
def self.exit_on_failure?
|
487
|
+
true
|
488
|
+
end
|
489
|
+
|
490
|
+
desc 'add', 'Initiate system workflow for review'
|
491
|
+
long_desc Help.text(:approvalPac_post_mapper)
|
492
|
+
|
493
|
+
# Required parameters/fields
|
494
|
+
option :systemId, type: :numeric, required: true,
|
495
|
+
desc: 'A numeric value representing the system identification'
|
496
|
+
option :workflow, type: :string, required: true,
|
497
|
+
enum: ['Assess and Authorize', 'Assess Only', 'Security Plan Approval']
|
498
|
+
option :name, type: :string, required: true, desc: 'The control package name'
|
499
|
+
option :comments, type: :string, required: true,
|
500
|
+
desc: 'Comments submitted upon initiation of the indicated workflow'
|
501
|
+
|
502
|
+
def add
|
503
|
+
body = EmassClient::PacGet.new
|
504
|
+
body.name = options[:name]
|
505
|
+
body.workflow = options[:workflow]
|
506
|
+
body.comments = options[:comments]
|
507
|
+
|
508
|
+
body_array = Array.new(1, body)
|
509
|
+
|
510
|
+
result = EmassClient::PACApi.new.add_system_pac(options[:systemId], body_array)
|
511
|
+
puts to_output_hash(result).green
|
512
|
+
rescue EmassClient::ApiError => e
|
513
|
+
puts 'Exception when calling ApprovalChainApi->add_system_pac'.red
|
514
|
+
puts to_output_hash(e)
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
# The Static Code Scans endpoint provides the ability to upload application
|
519
|
+
# scan findings into a system's assets module.
|
520
|
+
#
|
521
|
+
# Application findings can also be cleared from the system.
|
522
|
+
#
|
523
|
+
# Endpoint:
|
524
|
+
# /api/systems/{systemId}/static-code-scans - Upload static code scans
|
525
|
+
class ScanFindings < SubCommandBase
|
526
|
+
def self.exit_on_failure?
|
527
|
+
true
|
528
|
+
end
|
529
|
+
|
530
|
+
desc 'add', 'Upload static code scans'
|
531
|
+
long_desc Help.text(:staticcode_post_mapper)
|
532
|
+
|
533
|
+
# Required parameters/fields
|
534
|
+
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
535
|
+
option :applicationName, type: :string, required: true, desc: 'Name of the software application that was assessed'
|
536
|
+
option :version, type: :string, required: true, desc: 'The version of the application'
|
537
|
+
option :codeCheckName, type: :string, required: true, desc: 'Name of the software vulnerability or weakness'
|
538
|
+
option :scanDate, type: :numeric, required: true, desc: 'The findings scan date - Unix time format'
|
539
|
+
option :cweId, type: :string, required: true, desc: 'The Common Weakness Enumerator (CWE) identifier'
|
540
|
+
option :count, type: :numeric, required: true, desc: 'Number of instances observed for a specified finding'
|
541
|
+
# Optional parameter/fields
|
542
|
+
option :rawSeverity, type: :string, required: false, enum: %w[Low Medium Moderate High Critical]
|
543
|
+
|
544
|
+
def add
|
545
|
+
application = EmassClient::StaticCodeRequestPostBodyApplication.new
|
546
|
+
application.application_name = options[:applicationName]
|
547
|
+
application.version = options[:version]
|
548
|
+
|
549
|
+
application_findings = EmassClient::StaticCodeApplication.new
|
550
|
+
application_findings.code_check_name = options[:codeCheckName]
|
551
|
+
application_findings.scan_date = options[:scanDate]
|
552
|
+
application_findings.cwe_id = options[:cweId]
|
553
|
+
application_findings.count = options[:count]
|
554
|
+
application_findings.raw_severity = options[:rawSeverity] if options[:rawSeverity]
|
555
|
+
|
556
|
+
app_findings_array = Array.new(1, application_findings)
|
557
|
+
|
558
|
+
body = EmassClient::StaticCodeRequestPostBody.new
|
559
|
+
body.application = application
|
560
|
+
body.application_findings = app_findings_array
|
561
|
+
|
562
|
+
body_array = Array.new(1, body)
|
563
|
+
|
564
|
+
begin
|
565
|
+
result = EmassClient::StaticCodeScansApi
|
566
|
+
.new.add_static_code_scans_by_system_id(options[:systemId], body_array)
|
567
|
+
puts to_output_hash(result).green
|
568
|
+
rescue EmassClient::ApiError => e
|
569
|
+
puts 'Exception when calling StaticCodeScansApi->add_static_code_scans_by_system_id'.red
|
570
|
+
puts to_output_hash(e)
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
# CLEAR ------------------------------------------------------------------------------------
|
575
|
+
desc 'clear', 'Clear an application findings'
|
576
|
+
long_desc Help.text(:staticcode_clear_mapper)
|
577
|
+
|
578
|
+
# Required parameters/fields
|
579
|
+
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
580
|
+
option :applicationName, type: :string, required: true, desc: 'Name of the software application that was assessed'
|
581
|
+
option :version, type: :string, required: true, desc: 'The version of the application'
|
582
|
+
option :clearFindings, type: :boolean, required: false, default: false, desc: 'BOOLEAN - true or false'
|
583
|
+
# NOTE: clearFindings is a required parameter to clear an application's findings, however Thor does not allow
|
584
|
+
# a boolean type to be required because it automatically creates a --no-clearFindings option for clearFindings=false
|
585
|
+
|
586
|
+
def clear
|
587
|
+
unless options[:clearFindings]
|
588
|
+
puts 'To clear an application findings, the field clearFindings (--clearFindings) is required'.red
|
589
|
+
puts SCAN_POST_HELP_MESSAGE.yellow
|
590
|
+
exit
|
591
|
+
end
|
592
|
+
|
593
|
+
application = EmassClient::StaticCodeRequestPostBodyApplication.new
|
594
|
+
application.application_name = options[:applicationName]
|
595
|
+
application.version = options[:version]
|
596
|
+
|
597
|
+
application_findings = EmassClient::StaticCodeApplication.new
|
598
|
+
application_findings.clear_findings = options[:clearFindings]
|
599
|
+
|
600
|
+
app_findings_array = Array.new(1, application_findings)
|
601
|
+
|
602
|
+
body = EmassClient::StaticCodeRequestPostBody.new
|
603
|
+
body.application = application
|
604
|
+
body.application_findings = app_findings_array
|
605
|
+
|
606
|
+
body_array = Array.new(1, body)
|
607
|
+
|
608
|
+
begin
|
609
|
+
result = EmassClient::StaticCodeScansApi
|
610
|
+
.new.add_static_code_scans_by_system_id(options[:systemId], body_array)
|
611
|
+
puts to_output_hash(result).green
|
612
|
+
rescue EmassClient::ApiError => e
|
613
|
+
puts 'Exception when calling StaticCodeScansApi->add_static_code_scans_by_system_id'.red
|
614
|
+
puts to_output_hash(e)
|
615
|
+
end
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
619
|
+
# The Cloud Resources endpoint provides the ability to upload (add)
|
620
|
+
# cloud resources and their scan results in the assets module for a system.
|
621
|
+
#
|
622
|
+
#
|
623
|
+
# Endpoint:
|
624
|
+
# /api/systems/{systemId}/cloud-resources-results - Upload cloud resources and their scan results
|
625
|
+
class CloudResource < SubCommandBase
|
626
|
+
def self.exit_on_failure?
|
627
|
+
true
|
628
|
+
end
|
629
|
+
|
630
|
+
desc 'add', 'Upload cloud resources and their scan results'
|
631
|
+
long_desc Help.text(:cloudresource_post_mapper)
|
632
|
+
|
633
|
+
# Required parameters/fields
|
634
|
+
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
635
|
+
option :provider, type: :string, required: true, desc: 'Cloud service provider name'
|
636
|
+
option :resourceId, type: :string, required: true, desc: 'Unique identifier/resource namespace for policy compliance result'
|
637
|
+
option :resourceName, type: :string, required: true, desc: 'Friendly name of Cloud resource'
|
638
|
+
option :resourceType, type: :string, required: true, desc: 'Type of Cloud resource'
|
639
|
+
# ComplianceResults Array Objects
|
640
|
+
option :cspPolicyDefinitionId, type: :string, required: true, desc: 'Unique identifier/compliance namespace for CSP/Resource\'s policy definition/compliance check'
|
641
|
+
option :isCompliant, type: :boolean, required: false, default: false, desc: 'BOOLEAN - true or false'
|
642
|
+
option :policyDefinitionTitle, type: :string, required: true, desc: 'Friendly policy/compliance check title. Recommend short title'
|
643
|
+
|
644
|
+
# Optional parameter/fields
|
645
|
+
option :initiatedBy, type: :string, required: false, desc: 'Email of POC'
|
646
|
+
option :cspAccountId, type: :string, required: false, desc: 'System/owner\'s CSP account ID/number'
|
647
|
+
option :cspRegion, type: :string, required: false, desc: 'CSP region of system'
|
648
|
+
option :isBaseline, type: :boolean, required: false, default: true, desc: 'BOOLEAN - true or false'
|
649
|
+
# Tags Object
|
650
|
+
option :test, type: :string, required: false, desc: 'The test tag'
|
651
|
+
# ComplianceResults Array Objects
|
652
|
+
option :assessmentProcedure, type: :string, required: false, desc: 'Comma separated correlation to Assessment Procedure (i.e. CCI number for DoD Control Set)'
|
653
|
+
option :complianceCheckTimestamp, type: :numeric, required: false, desc: 'The compliance timestamp Unix date format.'
|
654
|
+
option :complianceReason, type: :string, required: false, desc: 'Reason/comments for compliance result'
|
655
|
+
option :control, type: :string, required: false, desc: 'Comma separated correlation to Security Control (e.g. exact NIST Control acronym)'
|
656
|
+
option :policyDeploymentName, type: :string, required: false, desc: 'Name of policy deployment'
|
657
|
+
option :policyDeploymentVersion, type: :string, required: false, desc: 'policyDeploymentVersion'
|
658
|
+
option :severity, type: :string, required: false, enum: %w[Low Medium Moderate High Critical]
|
659
|
+
|
660
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
661
|
+
def add
|
662
|
+
# Required and Optional main fields
|
663
|
+
body = {}
|
664
|
+
body[:provider] = options[:provider]
|
665
|
+
body[:resourceId] = options[:resourceId]
|
666
|
+
body[:resourceName] = options[:resourceName]
|
667
|
+
body[:resourceType] = options[:resourceType]
|
668
|
+
|
669
|
+
body[:initiatedBy] = options[:initiatedBy] if options[:initiatedBy]
|
670
|
+
body[:cspAccountId] = options[:cspAccountId] if options[:cspAccountId]
|
671
|
+
body[:cspRegion] = options[:cspRegion] if options[:cspRegion]
|
672
|
+
body[:isBaseline] = options[:isBaseline] if options[:isBaseline]
|
673
|
+
|
674
|
+
# Optional tags field
|
675
|
+
tags = {}
|
676
|
+
tags[:test] = options[:test] if options[:test]
|
677
|
+
|
678
|
+
# Required and Optional compliances results fields
|
679
|
+
compliance_results = {}
|
680
|
+
compliance_results[:cspPolicyDefinitionId] = options[:cspPolicyDefinitionId]
|
681
|
+
compliance_results[:isCompliant] = options[:isCompliant]
|
682
|
+
compliance_results[:policyDefinitionTitle] = options[:policyDefinitionTitle]
|
683
|
+
# Optional fields
|
684
|
+
compliance_results[:assessmentProcedure] = options[:assessmentProcedure] if options[:assessmentProcedure]
|
685
|
+
compliance_results[:complianceCheckTimestamp] = options[:complianceCheckTimestamp] if options[:complianceCheckTimestamp]
|
686
|
+
compliance_results[:complianceReason] = options[:complianceReason] if options[:complianceReason]
|
687
|
+
compliance_results[:control] = options[:control] if options[:control]
|
688
|
+
compliance_results[:policyDeploymentName] = options[:policyDeploymentName] if options[:policyDeploymentName]
|
689
|
+
compliance_results[:policyDeploymentVersion] = options[:policyDeploymentVersion] if options[:policyDeploymentVersion]
|
690
|
+
compliance_results[:severity] = options[:severity] if options[:severity]
|
691
|
+
|
692
|
+
compliance_results_array = Array.new(1, compliance_results)
|
693
|
+
|
694
|
+
body[:tags] = tags
|
695
|
+
body[:complianceResults] = compliance_results_array
|
696
|
+
|
697
|
+
body_array = Array.new(1, body)
|
698
|
+
|
699
|
+
begin
|
700
|
+
result = EmassClient::CloudResourcesApi
|
701
|
+
.new.add_cloud_resources_by_system_id(options[:systemId], body_array)
|
702
|
+
puts to_output_hash(result).green
|
703
|
+
rescue EmassClient::ApiError => e
|
704
|
+
puts 'Exception when calling StaticCodeScansApi->add_cloud_resources_by_system_id'.red
|
705
|
+
puts to_output_hash(e)
|
706
|
+
end
|
707
|
+
end
|
708
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
709
|
+
end
|
710
|
+
|
711
|
+
# The Containers endpoint provides the ability to upload (add)
|
712
|
+
# containers and their scan results in the assets module for a system.
|
713
|
+
#
|
714
|
+
#
|
715
|
+
# Endpoint:
|
716
|
+
# /api/systems/{systemId}/container-scan-results - Upload containers and their scan results
|
717
|
+
class Container < SubCommandBase
|
718
|
+
def self.exit_on_failure?
|
719
|
+
true
|
720
|
+
end
|
721
|
+
|
722
|
+
desc 'add', 'Upload containers and their scan results'
|
723
|
+
long_desc Help.text(:container_post_mapper)
|
724
|
+
|
725
|
+
# Required parameters/fields
|
726
|
+
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
727
|
+
option :containerId, type: :string, required: true, desc: 'Unique identifier of the container'
|
728
|
+
option :containerName, type: :string, required: true, desc: 'Friendly name of the container'
|
729
|
+
option :time, type: :numeric, required: true, desc: 'Datetime of scan/result. Unix date format'
|
730
|
+
# Benchmarks Array Objects
|
731
|
+
option :benchmark, type: :string, required: true, desc: 'Identifier of the benchmark/grouping of compliance results'
|
732
|
+
# Benchmarks.Results Array Objects
|
733
|
+
option :lastSeen, type: :numeric, required: true, desc: 'Date last seen, Unix date format'
|
734
|
+
option :ruleId, type: :string, required: true, desc: 'Identifier for the compliance result, vulnerability, etc. the result is for'
|
735
|
+
option :status, type: :string, required: true, enum: ['Pass', 'Fail', 'Other', 'Not Reviewed', 'Not Checked', 'Not Applicable']
|
736
|
+
|
737
|
+
# Optional parameter/fields
|
738
|
+
option :namespace, type: :string, required: false, desc: 'Namespace of container in container orchestration'
|
739
|
+
option :podIp, type: :string, required: false, desc: 'IP address of the pod'
|
740
|
+
option :podName, type: :string, required: false, desc: 'Name of pod (e.g. Kubernetes pod)'
|
741
|
+
# Tags Object
|
742
|
+
option :test, type: :string, required: false, desc: 'The test tag'
|
743
|
+
# Benchmarks Array Objects
|
744
|
+
option :isBaseline, type: :boolean, required: false, default: true, desc: 'BOOLEAN - true or false'
|
745
|
+
# Benchmarks.Results Array Objects
|
746
|
+
option :message, type: :string, required: false, desc: 'Benchmark result comments'
|
747
|
+
|
748
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
749
|
+
def add
|
750
|
+
# Required and Optional main fields
|
751
|
+
body = {}
|
752
|
+
body[:containerId] = options[:containerId]
|
753
|
+
body[:containerName] = options[:containerName]
|
754
|
+
body[:time] = options[:time]
|
755
|
+
body[:namespace] = options[:namespace] if options[:namespace]
|
756
|
+
body[:podIp] = options[:podIp] if options[:podIp]
|
757
|
+
body[:podName] = options[:podName] if options[:podName]
|
758
|
+
|
759
|
+
# Optional tags field
|
760
|
+
tags = {}
|
761
|
+
tags[:test] = options[:test] if options[:test]
|
762
|
+
|
763
|
+
# Required and Optional Benchmarks fields
|
764
|
+
benchmarks = {}
|
765
|
+
benchmarks[:benchmark] = options[:benchmark]
|
766
|
+
# Optional fields
|
767
|
+
benchmarks[:isBaseline] = options[:isBaseline] if options[:isBaseline]
|
768
|
+
|
769
|
+
# Required and Optional Benchmarks.Results
|
770
|
+
benchmarks_results = {}
|
771
|
+
benchmarks_results[:lastSeen] = options[:lastSeen]
|
772
|
+
benchmarks_results[:ruleId] = options[:ruleId]
|
773
|
+
benchmarks_results[:status] = options[:status]
|
774
|
+
benchmarks_results[:message] = options[:message] if options[:message]
|
775
|
+
|
776
|
+
# Add Benchmark results to an array and add array to benchmarks object
|
777
|
+
benchmarks_results_array = Array.new(1, benchmarks_results)
|
778
|
+
benchmarks[:results] = benchmarks_results_array # = Array.new(1, benchmarks_results)
|
779
|
+
# Add benchmarks object to an array
|
780
|
+
benchmarks_array = Array.new(1, benchmarks)
|
781
|
+
# Add tags and benchmark ojects to body object
|
782
|
+
body[:tags] = tags
|
783
|
+
body[:benchmarks] = benchmarks_array
|
784
|
+
|
785
|
+
body_array = Array.new(1, body)
|
786
|
+
|
787
|
+
begin
|
788
|
+
result = EmassClient::ContainersApi
|
789
|
+
.new.add_container_sans_by_system_id(options[:systemId], body_array)
|
790
|
+
puts to_output_hash(result).green
|
791
|
+
rescue EmassClient::ApiError => e
|
792
|
+
puts 'Exception when calling StaticCodeScansApi->add_container_sans_by_system_id'.red
|
793
|
+
puts to_output_hash(e)
|
794
|
+
end
|
795
|
+
end
|
796
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
797
|
+
end
|
798
|
+
|
799
|
+
class Post < SubCommandBase
|
800
|
+
desc 'register', 'Register a certificate & obtain an API-key'
|
801
|
+
subcommand 'register', Register
|
802
|
+
|
803
|
+
desc 'test_results', 'Add system Test Results'
|
804
|
+
subcommand 'test_results', TestResults
|
805
|
+
|
806
|
+
desc 'poams', 'Add Plan of Action and Milestones (POA&M) items to a system'
|
807
|
+
subcommand 'poams', Poams
|
808
|
+
|
809
|
+
desc 'milestones', 'Add milestone(s) to one or many POA&M items in a system'
|
810
|
+
subcommand 'milestones', Milestones
|
811
|
+
|
812
|
+
desc 'artifacts', 'Add system Artifacts'
|
813
|
+
subcommand 'artifacts', Artifacts
|
814
|
+
|
815
|
+
desc 'cac', 'Add Control Approval Chain (CAC) security content'
|
816
|
+
subcommand 'cac', CAC
|
817
|
+
|
818
|
+
desc 'pac', 'Add Package Approval Chain (PAC) security content'
|
819
|
+
subcommand 'pac', PAC
|
820
|
+
|
821
|
+
desc 'scan_findings', 'Upload static code scans'
|
822
|
+
subcommand 'scan_findings', ScanFindings
|
823
|
+
|
824
|
+
desc 'cloud_resource', 'Upload cloud resource and their scan results'
|
825
|
+
subcommand 'cloud_resource', CloudResource
|
826
|
+
|
827
|
+
desc 'container', 'Upload container and their scan results'
|
828
|
+
subcommand 'container', Container
|
829
|
+
end
|
830
|
+
end
|