emasser 3.4.0 → 3.4.1
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.
- 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 -1436
- 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 -949
- 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 +8 -8
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
|