emasser 1.0.3 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.env-example +2 -0
  3. data/.github/workflows/gh-pages.yml +4 -5
  4. data/.github/workflows/release.yml +9 -9
  5. data/Dockerfile +6 -4
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +23 -30
  8. data/README.md +87 -78
  9. data/docs/features.md +343 -207
  10. data/docs/images/emasser_architecture.jpg +0 -0
  11. data/emasser.gemspec +5 -3
  12. data/images/emasser_architecture.jpg +0 -0
  13. data/images/emasser_diagram-Page-3.jpg +0 -0
  14. data/lib/emasser/cli.rb +2 -2
  15. data/lib/emasser/configuration.rb +1 -0
  16. data/lib/emasser/constants.rb +11 -3
  17. data/lib/emasser/delete.rb +9 -7
  18. data/lib/emasser/get.rb +43 -48
  19. data/lib/emasser/help/cloudresource_post_mapper.md +62 -0
  20. data/lib/emasser/help/container_post_mapper.md +44 -0
  21. data/lib/emasser/output_converters.rb +101 -4
  22. data/lib/emasser/post.rb +231 -38
  23. data/lib/emasser/put.rb +23 -16
  24. data/lib/emasser/version.rb +1 -1
  25. metadata +19 -25
  26. data/.github/workflows/generate_docs.yml +0 -33
  27. data/docs/developers.md +0 -115
  28. data/docs/swagger/dist/favicon-16x16.png +0 -0
  29. data/docs/swagger/dist/favicon-32x32.png +0 -0
  30. data/docs/swagger/dist/oauth2-redirect.html +0 -75
  31. data/docs/swagger/dist/swagger-ui-bundle.js +0 -3
  32. data/docs/swagger/dist/swagger-ui-bundle.js.map +0 -1
  33. data/docs/swagger/dist/swagger-ui-es-bundle-core.js +0 -3
  34. data/docs/swagger/dist/swagger-ui-es-bundle-core.js.map +0 -1
  35. data/docs/swagger/dist/swagger-ui-es-bundle.js +0 -3
  36. data/docs/swagger/dist/swagger-ui-es-bundle.js.map +0 -1
  37. data/docs/swagger/dist/swagger-ui-standalone-preset.js +0 -3
  38. data/docs/swagger/dist/swagger-ui-standalone-preset.js.map +0 -1
  39. data/docs/swagger/dist/swagger-ui.css +0 -4
  40. data/docs/swagger/dist/swagger-ui.css.map +0 -1
  41. data/docs/swagger/dist/swagger-ui.js +0 -3
  42. data/docs/swagger/dist/swagger-ui.js.map +0 -1
  43. data/docs/swagger/index.html +0 -60
data/emasser.gemspec CHANGED
@@ -6,11 +6,11 @@ Gem::Specification.new do |spec|
6
6
  spec.name = 'emasser'
7
7
  spec.version = Emasser::VERSION
8
8
  spec.authors = ['Amndeep Singh Mann', 'George Dias', 'Kyle Fagan', 'Robert Clark', 'Aaron Lippold']
9
- spec.email = ['saf@mitre.org']
9
+ spec.email = ['saf@groups.mitre.org']
10
10
  spec.licenses = ['Apache-2.0']
11
11
 
12
12
  spec.summary = 'Provide an automated capability for invoving eMASS API endpoints'
13
- spec.description = 'emasser can be used as a gem or used from the command line to access eMASS via thei API.'
13
+ spec.description = 'emasser can be used as a gem or used from the command line (CL) to access eMASS endpoints via their API.'
14
14
  spec.homepage = 'https://saf.mitre.org'
15
15
  spec.required_ruby_version = Gem::Requirement.new('~> 2.5')
16
16
 
@@ -21,13 +21,15 @@ Gem::Specification.new do |spec|
21
21
  end
22
22
  spec.bindir = 'exe'
23
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ # References: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-rubygems-registry
25
+ spec.metadata = { "github_repo" => "ssh://github.com/mitre/emasser" }
24
26
 
25
27
  spec.add_runtime_dependency 'activesupport', '~> 6.1.4'
26
28
  spec.add_runtime_dependency 'colorize', '~> 0.8.1'
27
29
  spec.add_runtime_dependency 'dotenv', '~> 2.7.6'
28
30
  spec.add_runtime_dependency 'rubyzip', '~> 2.3.2'
29
31
  spec.add_runtime_dependency 'thor', '~> 1.1.0'
30
- spec.add_runtime_dependency 'emass_client', '~> 1.0'
32
+ spec.add_runtime_dependency 'emass_client', '~> 1.0', '!= 1.0.3'
31
33
 
32
34
  spec.add_development_dependency 'bundler', '~> 2.3'
33
35
  spec.add_development_dependency 'bundler-audit', '~> 0.7'
Binary file
Binary file
data/lib/emasser/cli.rb CHANGED
@@ -20,8 +20,8 @@ module Emasser
20
20
  puts "emasser version: #{Emasser::VERSION}".green
21
21
  exit
22
22
  elsif ARGV[0].to_s.include? 'hello'
23
- user_name = ENV['USERNAME'] || 'rookie'
24
- puts "Hello #{user_name} - enjoy using emasser!".cyan
23
+ user_name = ENV.fetch('USERNAME', 'rookie')
24
+ puts "Hello #{user_name} - enjoy using emasser version #{Emasser::VERSION}!".cyan
25
25
  exit
26
26
  end
27
27
 
@@ -33,6 +33,7 @@ module Emasser
33
33
  config.api_key['user-uid'] = raise_unless_present('EMASSER_API_KEY_USER_UID')
34
34
  config.scheme = 'https'
35
35
  config.base_path = '/'
36
+ config.server_index = nil
36
37
  config.host = raise_unless_present('EMASSER_HOST')
37
38
  config.key_file = raise_unless_present('EMASSER_KEY_FILE_PATH')
38
39
  config.cert_file = raise_unless_present('EMASSER_CERT_FILE_PATH')
@@ -5,14 +5,22 @@ module Emasser
5
5
  include_package: false,
6
6
  include_ditpr_metrics: false,
7
7
  include_decommissioned: false,
8
- return_type: 'SystemResponse' # This is used by swagger client only to format output
8
+ debug_return_type: 'SystemResponse' # This is used by swagger client only to format output
9
9
  }.freeze
10
10
 
11
11
  GET_SYSTEM_RETURN_TYPE = {
12
- return_type: 'SystemResponse'
12
+ debug_return_type: 'SystemResponse'
13
13
  }.freeze
14
14
 
15
15
  GET_ARTIFACTS_RETURN_TYPE = {
16
- return_type: 'String'
16
+ debug_return_type: 'String'
17
+ }.freeze
18
+
19
+ GET_WORKFLOWINSTANCES_RETURN_TYPE = {
20
+ debug_return_type: 'Object'
21
+ }.freeze
22
+
23
+ DEL_MILESTONES_RETURN_TYPE = {
24
+ debug_return_type: 'Object'
17
25
  }.freeze
18
26
  end
@@ -55,11 +55,11 @@ module Emasser
55
55
  option :poamId, type: :numeric, required: true, desc: 'A numeric value representing the poam identification'
56
56
 
57
57
  def remove
58
- body = EmassClient::DeletePoam.new
58
+ body = EmassClient::PoamGet.new
59
59
  body.poam_id = options[:poamId]
60
60
  body_array = Array.new(1, body)
61
61
 
62
- result = EmassClient::POAMApi.new.delete_poam(body_array, options[:systemId])
62
+ result = EmassClient::POAMApi.new.delete_poam(options[:systemId], body_array)
63
63
  puts to_output_hash(result).green
64
64
  rescue EmassClient::ApiError => e
65
65
  puts 'Exception when calling POAMApi->delete_poam'.red
@@ -88,16 +88,18 @@ module Emasser
88
88
  desc: 'A numeric value representing the milestone identification'
89
89
 
90
90
  def remove
91
- body = EmassClient::DeleteMilestone.new
91
+ body = EmassClient::MilestonesGet.new
92
92
  body.milestone_id = options[:milestoneId]
93
93
  body_array = Array.new(1, body)
94
94
 
95
- result = EmassClient::MilestonesApi.new.delete_milestone(body_array, options[:systemId], options[:poamId])
96
- # The server returns an empty object upon successfully deleting a milestone.
95
+ # Getting an empty return when utilizing the default return type - using 'Object' as return type
96
+ opts = Emasser::DEL_MILESTONES_RETURN_TYPE
97
+
98
+ result = EmassClient::MilestonesApi.new.delete_milestone(options[:systemId], options[:poamId], body_array, opts)
97
99
  puts to_output_hash(result).green
98
100
  rescue EmassClient::ApiError => e
99
101
  puts 'Exception when calling MilestonesApi->delete_milestone'.red
100
- puts to_output_hash(e)
102
+ puts to_output_hash(e).yellow
101
103
  end
102
104
  end
103
105
 
@@ -125,7 +127,7 @@ module Emasser
125
127
  body_array << obj
126
128
  end
127
129
 
128
- result = EmassClient::ArtifactsApi.new.delete_artifact(body_array, options[:systemId])
130
+ result = EmassClient::ArtifactsApi.new.delete_artifact(options[:systemId], body_array)
129
131
  puts to_output_hash(result).green
130
132
  rescue EmassClient::ApiError => e
131
133
  puts 'Exception when calling ArtifactsApi->delete_artifact'.red
data/lib/emasser/get.rb CHANGED
@@ -58,9 +58,8 @@ module Emasser
58
58
  true
59
59
  end
60
60
 
61
- desc 'id [--system-name [SYSTEM_NAME]] [--system-owner [SYSTEM_OWNER]]',
61
+ desc 'id [--system_name [SYSTEM_NAME]] [--system_owner [SYSTEM_OWNER]]',
62
62
  'Attempts to provide system ID of a system with name [NAME] and owner [SYSTEM_OWNER]'
63
- # desc 'id', 'Get a system ID given "name" or "owner"'
64
63
 
65
64
  # Required parameters/fields
66
65
  option :system_name
@@ -73,26 +72,29 @@ module Emasser
73
72
  end
74
73
 
75
74
  begin
76
- results = EmassClient::SystemsApi.new.get_systems.data
75
+ results = EmassClient::SystemsApi.new.get_systems
77
76
  results = filter_systems(results, options[:system_name], options[:system_owner])
78
77
  results.each { |result| puts "#{result[:systemId]} - #{result[:systemOwner]} - #{result[:name]}" }
79
78
  rescue EmassClient::ApiError => e
80
79
  puts 'Exception when calling SystemsApi->get_systems'
81
- puts to_output_hash(e)
80
+ puts to_output_hash(e).yellow
82
81
  end
83
82
  end
84
83
 
84
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
85
85
  no_commands do
86
86
  def filter_systems(results, system_name = nil, system_owner = nil)
87
+ results = results.to_body if results.respond_to?(:to_body)
87
88
  if system_owner.nil?
88
- results.filter { |result| result[:name].eql?(system_name) }
89
+ results[:data].filter { |result| result[:name].eql?(system_name) }
89
90
  elsif system_name.nil?
90
- results.filter { |result| result[:systemOwner].eql?(system_owner) }
91
+ results[:data].filter { |result| result[:systemOwner].eql?(system_owner) }
91
92
  else
92
- results.filter { |result| result[:name].eql?(system_name) && result[:systemOwner].eql?(system_owner) }
93
+ results[:data].filter { |result| result[:name].eql?(system_name) && result[:systemOwner].eql?(system_owner) }
93
94
  end
94
95
  end
95
96
  end
97
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
96
98
 
97
99
  desc "byId \[options\]", 'Retrieve a system - filtered by [options] params'
98
100
  option :systemId, type: :numeric, required: true,
@@ -110,8 +112,8 @@ module Emasser
110
112
  result = EmassClient::SystemsApi.new.get_system(options[:systemId], optional_options)
111
113
  puts to_output_hash(result).green
112
114
  rescue EmassClient::ApiError => e
113
- puts 'Exception when calling SystemsApi->get_systems'.red
114
- puts to_output_hash(e)
115
+ puts 'Exception when calling SystemsApi->get_system'.red
116
+ puts to_output_hash(e).yellow
115
117
  end
116
118
  end
117
119
  end
@@ -148,7 +150,7 @@ module Emasser
148
150
  puts to_output_hash(result).green
149
151
  rescue EmassClient::ApiError => e
150
152
  puts 'Exception when calling SystemsApi->get_systems'.red
151
- puts to_output_hash(e)
153
+ puts to_output_hash(e).yellow
152
154
  end
153
155
  end
154
156
  end
@@ -174,7 +176,7 @@ module Emasser
174
176
  puts to_output_hash(result).green
175
177
  rescue EmassClient::ApiError => e
176
178
  puts 'Exception when calling SystemRolesApi->get_system_roles'.red
177
- puts to_output_hash(e)
179
+ puts to_output_hash(e).yellow
178
180
  end
179
181
 
180
182
  desc "byCategory \[options\]", 'Retrieves role(s) - filtered by [options] params'
@@ -184,7 +186,7 @@ module Emasser
184
186
  enum: ['AO', 'Auditor', 'Artifact Manager', 'C&A Team', 'IAO',
185
187
  'ISSO', 'PM/IAM', 'SCA', 'User Rep', 'Validator']
186
188
  # Optional parameters/fields
187
- option :policy, type: :string, required: false, enum: %w[diacap rmf reporting]
189
+ option :policy, type: :string, required: false, default: 'rmf', enum: %w[diacap rmf reporting]
188
190
  option :includeDecommissioned, type: :boolean, required: false, desc: 'BOOLEAN - true or false.'
189
191
 
190
192
  def byCategory
@@ -197,7 +199,7 @@ module Emasser
197
199
  puts to_output_hash(result).green
198
200
  rescue EmassClient::ApiError => e
199
201
  puts 'Exception when calling SystemRolesApi->get_system_by_role_category_id'.red
200
- puts to_output_hash(e)
202
+ puts to_output_hash(e).yellow
201
203
  end
202
204
  end
203
205
  end
@@ -230,7 +232,7 @@ module Emasser
230
232
  puts to_output_hash(result).green
231
233
  rescue EmassClient::ApiError => e
232
234
  puts 'Exception when calling ControlsApi->get_system_controls'.red
233
- puts to_output_hash(e)
235
+ puts to_output_hash(e).yellow
234
236
  end
235
237
  end
236
238
  end
@@ -263,7 +265,7 @@ module Emasser
263
265
  puts to_output_hash(result).green
264
266
  rescue EmassClient::ApiError => e
265
267
  puts 'Exception when calling TestResultsApi->get_system_test_results'.red
266
- puts to_output_hash(e)
268
+ puts to_output_hash(e).yellow
267
269
  end
268
270
  end
269
271
  end
@@ -289,8 +291,8 @@ module Emasser
289
291
  desc: 'The schedule completion start date - Unix time format.'
290
292
  option :scheduledCompletionDateEnd, type: :numeric, required: false,
291
293
  desc: 'The scheduled completion end date - Unix time format.'
292
- option :controlAcronyms, type: :string, required: false, desc: 'The system acronym(s) e.g "AC-1, AC-2"'
293
- option :ccis, type: :string, required: false, desc: 'The system CCIS string numerical value'
294
+ option :controlAcronyms, type: :string, required: false, desc: 'The system acronym(s) e.g "AC-1" or "AC-1, AC-2"'
295
+ option :ccis, type: :string, required: false, desc: 'The system CCIS string numerical value e.g "000123" or "000123,000069"'
294
296
  option :systemOnly, type: :boolean, required: false, default: false, desc: 'BOOLEAN - true or false.'
295
297
 
296
298
  def forSystem
@@ -302,7 +304,7 @@ module Emasser
302
304
  puts to_output_hash(result).green
303
305
  rescue EmassClient::ApiError => e
304
306
  puts 'Exception when calling POAMApi->get_system_poams'.red
305
- puts to_output_hash(e)
307
+ puts to_output_hash(e).yellow
306
308
  end
307
309
  end
308
310
 
@@ -319,7 +321,7 @@ module Emasser
319
321
  puts to_output_hash(result).green
320
322
  rescue EmassClient::ApiError => e
321
323
  puts 'Exception when calling POAMApi->get_system_poams_by_poam_id'.red
322
- puts to_output_hash(e)
324
+ puts to_output_hash(e).yellow
323
325
  end
324
326
  end
325
327
 
@@ -356,7 +358,7 @@ module Emasser
356
358
  puts to_output_hash(result).green
357
359
  rescue EmassClient::ApiError => e
358
360
  puts 'Exception when calling MilestonesApi->get_system_milestones_by_poam_id'.red
359
- puts to_output_hash(e)
361
+ puts to_output_hash(e).yellow
360
362
  end
361
363
  end
362
364
 
@@ -377,7 +379,7 @@ module Emasser
377
379
  puts to_output_hash(result).green
378
380
  rescue EmassClient::ApiError => e
379
381
  puts 'Exception when calling MilestonesApi->get_system_milestones_by_poam_id_and_milestone_id'.red
380
- puts to_output_hash(e)
382
+ puts to_output_hash(e).yellow
381
383
  end
382
384
  end
383
385
 
@@ -393,7 +395,7 @@ module Emasser
393
395
  true
394
396
  end
395
397
 
396
- desc 'system', 'Get all system artifacts for a system Id'
398
+ desc 'forSystem', 'Get all system artifacts for a system Id'
397
399
  # Required parameters/fields
398
400
  option :systemId, type: :numeric, required: true,
399
401
  desc: 'A numeric value representing the system identification'
@@ -414,7 +416,7 @@ module Emasser
414
416
  puts to_output_hash(result).green
415
417
  rescue EmassClient::ApiError => e
416
418
  puts 'Exception when calling ArtifactsApi->get_system_artifacts'.red
417
- puts to_output_hash(e)
419
+ puts to_output_hash(e).yellow
418
420
  end
419
421
  end
420
422
 
@@ -437,7 +439,7 @@ module Emasser
437
439
  options[:systemId], options[:filename], optional_options
438
440
  )
439
441
  if options[:compress]
440
- p result.green
442
+ pp result
441
443
  else
442
444
  begin
443
445
  puts JSON.pretty_generate(JSON.parse(result)).green
@@ -447,7 +449,7 @@ module Emasser
447
449
  end
448
450
  rescue EmassClient::ApiError => e
449
451
  puts 'Exception when calling ArtifactsApi->get_system_artifacts_export'.red
450
- puts to_output_hash(e)
452
+ puts to_output_hash(e).yellow
451
453
  end
452
454
  end
453
455
 
@@ -483,7 +485,7 @@ module Emasser
483
485
  puts to_output_hash(result).green
484
486
  rescue EmassClient::ApiError => e
485
487
  puts 'Exception when calling ApprovalChainApi->get_system_cac'.red
486
- puts to_output_hash(e)
488
+ puts to_output_hash(e).yellow
487
489
  end
488
490
  end
489
491
  end
@@ -514,7 +516,7 @@ module Emasser
514
516
  puts to_output_hash(result).green
515
517
  rescue EmassClient::ApiError => e
516
518
  puts 'Exception when calling ApprovalChainApi->get_system_'.red
517
- puts to_output_hash(e)
519
+ puts to_output_hash(e).yellow
518
520
  end
519
521
  end
520
522
 
@@ -539,7 +541,7 @@ module Emasser
539
541
  puts to_output_hash(result).green
540
542
  rescue EmassClient::ApiError => e
541
543
  puts 'Exception when calling ApprovalChainApi->get_cmmc_assessments'.red
542
- puts to_output_hash(e)
544
+ puts to_output_hash(e).yellow
543
545
  end
544
546
  end
545
547
 
@@ -569,7 +571,7 @@ module Emasser
569
571
  puts to_output_hash(result).green
570
572
  rescue EmassClient::ApiError => e
571
573
  puts 'Exception when calling ApprovalChainApi->get_workflow_definitions'.red
572
- puts to_output_hash(e)
574
+ puts to_output_hash(e).yellow
573
575
  end
574
576
  end
575
577
 
@@ -577,17 +579,14 @@ module Emasser
577
579
  # active and historical workflows for a system.
578
580
  #
579
581
  # Endpoints:
580
- # /api/systems/{systemId}/workflow-instances - Get workflow instances in a system
581
- # /api/systems/{systemId}/workflow-instances/{workflowInstanceId} - Get workflow instance by ID in a system
582
+ # /api/workflows/instances - Get workflow instances in a site
583
+ # /api/workflows/instances/{workflowInstanceId} - Get workflow instance by ID
582
584
  class WorkflowInstances < SubCommandBase
583
585
  def self.exit_on_failure?
584
586
  true
585
587
  end
586
588
 
587
- desc 'forSystem', 'Get workflow instances in a system'
588
- # Required parameters/fields
589
- option :systemId, type: :numeric, required: true,
590
- desc: 'A numeric value representing the system identification'
589
+ desc 'all', 'Get workflow instances in a site'
591
590
 
592
591
  # Optional parameters/fields
593
592
  option :includeComments, type: :boolean, required: false, default: false, desc: 'BOOLEAN - true or false.'
@@ -595,36 +594,32 @@ module Emasser
595
594
  option :sinceDate, type: :string, required: false, desc: 'The workflow instance date. Unix date format'
596
595
  option :status, type: :string, required: false, enum: %w[active inactive all]
597
596
 
598
- def forSystem
597
+ def all
599
598
  optional_options_keys = optional_options(@_initializer).keys
600
599
  optional_options = to_input_hash(optional_options_keys, options)
601
600
 
602
- result = EmassClient::WorkflowInstancesApi.new.get_system_workflow_instances(
603
- options[:systemId], optional_options
604
- )
601
+ result = EmassClient::WorkflowInstancesApi.new.get_system_workflow_instances(optional_options)
605
602
  puts to_output_hash(result).green
606
603
  rescue EmassClient::ApiError => e
607
604
  puts 'Exception when calling ApprovalChainApi->get_system_workflow_instances'.red
608
- puts to_output_hash(e)
605
+ puts to_output_hash(e).yellow
609
606
  end
610
607
 
611
608
  # Workflow by workflowInstanceId ---------------------------------------------------------
612
- desc 'byWorkflowInstanceId', 'Get workflow instance by ID in a system'
609
+ desc 'byInstanceId', 'Get workflow instance by ID'
613
610
 
614
611
  # Required parameters/fields
615
- option :systemId, type: :numeric, required: true,
616
- desc: 'A numeric value representing the system identification'
617
612
  option :workflowInstanceId, type: :numeric, required: true,
618
613
  desc: 'A numeric value representing the workflowInstance identification'
619
614
 
620
- def byWorkflowInstanceId
621
- result = EmassClient::WorkflowInstancesApi.new.get_system_workflow_instances_by_workflow_instance_id(
622
- options[:systemId], options[:workflowInstanceId]
623
- )
615
+ def byInstanceId
616
+ opts = Emasser::GET_WORKFLOWINSTANCES_RETURN_TYPE
617
+ result = EmassClient::WorkflowInstancesApi.new
618
+ .get_system_workflow_instances_by_workflow_instance_id(options[:workflowInstanceId], opts)
624
619
  puts to_output_hash(result).green
625
620
  rescue EmassClient::ApiError => e
626
621
  puts 'Exception when calling ApprovalChainApi->get_system_workflow_instances_by_workflow_instance_id'.red
627
- puts to_output_hash(e)
622
+ puts to_output_hash(e).yellow
628
623
  end
629
624
  end
630
625
 
@@ -0,0 +1,62 @@
1
+ Add cloud resource and scan results in the assets module for a system
2
+
3
+ Endpoint request parameters/fields
4
+
5
+ Field Data Type Details
6
+ -------------------------------------------------------------------------------------------------
7
+ systemId Integer [Required] Unique eMASS identifier. Will need to provide correct number.
8
+ provider String [Required] Cloud service provider name.
9
+ resourceId String [Required] Unique identifier/resource namespace for policy compliance result.
10
+ resourceName String [Required] Friendly name of Cloud resource.
11
+ resourceType String [Required] Type of Cloud resource.
12
+
13
+ initiatedBy String [Optional] Email of POC.
14
+ cspAccountId String [Optional] System/owner's CSP account ID/number.
15
+ cspRegion String [Optional] CSP region of system.
16
+ isBaseline Boolean [Optional] True/false flag for providing results as baseline.
17
+ If true, all existing compliance results for the resourceId will be replaced by results in the current call.
18
+
19
+ tags Object [Optional] Informational tags associated to results for other metadata
20
+ text String [Optional] Tag metadata information
21
+
22
+ complianceResults Object [Required] Compliance result information
23
+ cspPolicyDefinitionId String [Required] Unique identifier/compliance namespace for CSP/Resource’s
24
+ policy definition/compliance check.
25
+ policyDefinitionTitle String [Required] Friendly policy/compliance check title. Recommend short title
26
+ isCompliant Boolean [Required] Compliance status of the policy for the identified cloud resource.
27
+
28
+ complianceCheckTimestamp Date [Optional] Unix date format
29
+ control String [Optional] Comma separated correlation to Security Control
30
+ (e.g. exact NIST Control acronym).
31
+ assessmentProcedure String [Optional] Comma separated correlation to Assessment Procedure
32
+ (i.e. CCI number for DoD Control Set).
33
+ complianceReason String [Optional] Reason/comments for compliance result
34
+ policyDeploymentName String [Optional] Name of policy deployment
35
+ policyDeploymentVersion String [Optional] Version of policy deployment.
36
+ severity String [Optional] Values include the following: (Low, Medium, High, Critical)
37
+
38
+
39
+ The following Cloud Resource parameters/fields have the following character limitations:
40
+ - Fields that can not exceed 50 characters:
41
+ - Policy Deployment Version (`policyDeploymentVersion`)
42
+ - Fields that can not exceed 100 characters:
43
+ - Assessment Procedure (`assessmentProcedure`)
44
+ - Security Control Acronym (`control`)
45
+ - CSP Account ID (`cspAccountId`)
46
+ - CSP Region (`cspRegion`)
47
+ - Email of POC (`initiatedBy`)
48
+ - Cloud Service Provider (`provider`)
49
+ - Type of Cloud resource (`resourceType`)
50
+ - Fields that can not exceed 500 characters:
51
+ - CSP/Resource’s Policy ID (`cspPolicyDefinitionId`)
52
+ - Policy Deployment Name (`policyDeploymentName`)
53
+ - Policy Compliance ID (`resourceId`)
54
+ - Cloud Resource Name (`resourceName`)
55
+ - Fields that can not exceed 1000 characters:
56
+ - Reason for Compliance (`complianceReason`)
57
+ - Fields that can not exceed 2000 characters:
58
+ - Policy Short Title (`policyDefinitionTitle`)
59
+
60
+ Example:
61
+
62
+ bundle exec exe/emasser post cloud_resource add --systemId [value] --provider [value] --resourceId [value] --resourceName [value] --resourceType [value] --cspPolicyDefinitionId [value] --isCompliant or --is-not-Compliant --policyDefinitionTitle [value] --test [value]
@@ -0,0 +1,44 @@
1
+ Add cloud resource and scan results in the assets module for a system
2
+
3
+ Endpoint request parameters/fields
4
+
5
+ Field Data Type Details
6
+ -------------------------------------------------------------------------------------------------
7
+ systemId Integer [Required] Unique eMASS identifier. Will need to provide correct number.
8
+ containerId String [Required] Unique identifier of the container.
9
+ containerName String [Required] Friendly name of the container.
10
+ time Date [Required] Datetime of scan/result. Unix date format.
11
+
12
+ podName String [Optional] Name of pod (e.g. Kubernetes pod).
13
+ podIp String [Optional] IP address of pod.
14
+ namespace String [Optional] Namespace of container in container orchestration (e.g. Kubernetes namespace).
15
+
16
+ tags Object [Optional] Informational tags associated to results for other metadata.
17
+ text String [Optional] Tag metadata information.
18
+
19
+ benchmarks Object
20
+ benchmark String [Required] Identifier of the benchmark/grouping of compliance results.
21
+ (e.g. for STIG results, provide the benchmark id for the STIG technology).
22
+ isBaseline Boolean [Optional] True/false flag for providing results as baseline. If true, all existing
23
+ compliance results for the provided benchmark within the container will be replaced
24
+ by results in the current call.
25
+ results Object
26
+ ruleId String [Required] Identifier for the compliance result, vulnerability, etc.
27
+ status String [Required] Benchmark result status
28
+ lastSeen Date [Required] Date last seen, Unix date format
29
+ message String [Optional] Comments for the result
30
+
31
+ The following Container parameters/fields have the following character limitations:
32
+ - Fields that can not exceed 100 characters:
33
+ - STIG Benchmark ID (`benchmark`)
34
+ - Container Namespace (`namespace`)
35
+ - Kubernetes assigned IP (`podIp`)
36
+ - Kubernetes Pod Name) (`podName`)
37
+ - Fields that can not exceed 500 characters:
38
+ - Container ID (`containerId`)
39
+ - Friendly Container Name (`containerName`)
40
+ - Fields that can not exceed 1000 characters:
41
+ - Result Comments (`message`)
42
+
43
+ Example:
44
+ bundle exec ruby exe/emasser post container add --systemId [value] --containerId [value] --containerName [value] --time [value] --benchmark [value] --lastSeen [value] --ruleId [value] --status [value]
@@ -1,14 +1,111 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OutputConverters
4
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Style/TernaryParentheses
5
+ # rubocop:disable Style/IfWithBooleanLiteralBranches, Style/RescueStandardError, Metrics/BlockNesting
4
6
  def to_output_hash(obj)
7
+ diplay_nulls = (ENV.fetch('EMASSER_CLI_DISPLAY_NULL', 'true').eql? 'true') ? true : false
8
+ diplay_datetime = (ENV.fetch('EMASSER_EPOCH_TO_DATETIME', 'false').eql? 'true') ? true : false
9
+
5
10
  if obj.to_s.include? 'Error message'
6
- obj
11
+ begin
12
+ index = obj.to_s.index('Response body')+14
13
+ arr_obj = obj.to_s[index, obj.to_s.size - index]
14
+ JSON.pretty_generate(JSON.parse(arr_obj))
15
+ rescue
16
+ obj
17
+ end
7
18
  else
8
- hash = obj.instance_variables.each_with_object({}) do |var, h|
9
- h[var.to_s.delete('@')] = obj.instance_variable_get(var)
19
+ obj = obj.to_body if obj.respond_to?(:to_body)
20
+ if !diplay_nulls
21
+ clean_obj = {}
22
+ data_obj = {}
23
+ obj.each do |key, value|
24
+ if key.to_s.include?('meta')
25
+ obj_entry = {}
26
+ obj_entry[:meta] = value
27
+ clean_obj.merge!(obj_entry)
28
+ elsif key.to_s.include?('data')
29
+ if value.is_a?(Array)
30
+ hash_array = []
31
+ value.each do |elements|
32
+ hash_array << elements.compact
33
+ end
34
+ data_obj['data'] = hash_array
35
+ else
36
+ data_obj['data'] = value.nil? ? value : value.compact
37
+ end
38
+ elsif key.to_s.include?('pagination')
39
+ pg_obj = {}
40
+ pg_obj[:pagination] = value
41
+ data_obj.merge!(pg_obj)
42
+ end
43
+ clean_obj.merge!(data_obj)
44
+ end
45
+ obj = clean_obj
46
+ end
47
+
48
+ if diplay_datetime
49
+ clean_obj = {}
50
+ data_obj = {}
51
+ obj.each do |key, value|
52
+ if key.to_s.include?('meta')
53
+ obj_entry = {}
54
+ obj_entry[:meta] = value
55
+ clean_obj.merge!(obj_entry)
56
+ elsif key.to_s.include?('data')
57
+ if value.is_a?(Array)
58
+ hash_array = []
59
+ value.each do |element|
60
+ datetime_obj = change_to_datetime(element)
61
+ hash_array << datetime_obj
62
+ end
63
+ data_obj['data'] = hash_array
64
+ else
65
+ data_obj['data'] = change_to_datetime(value)
66
+ end
67
+ elsif key.to_s.include?('pagination')
68
+ pg_obj = {}
69
+ pg_obj[:pagination] = value
70
+ data_obj.merge!(pg_obj)
71
+ end
72
+ clean_obj.merge!(data_obj)
73
+ end
74
+ obj = clean_obj
75
+ end
76
+ JSON.pretty_generate(obj)
77
+ end
78
+ end
79
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Style/TernaryParentheses
80
+ # rubocop:enable Style/IfWithBooleanLiteralBranches, Style/RescueStandardError, Metrics/BlockNesting
81
+
82
+ # rubocop:disable Style/IdenticalConditionalBranches, Performance/RedundantMatch, Performance/RegexpMatch
83
+ def change_to_datetime(obj)
84
+ if obj.nil?
85
+ return obj
86
+ end
87
+
88
+ data_obj = {}
89
+ obj.each do |key, value|
90
+ obj_entry = {}
91
+ if value.is_a?(Array)
92
+ hash_array = []
93
+ value.each do |element|
94
+ hash_array << change_to_datetime(element)
95
+ end
96
+ obj_entry[key] = hash_array
97
+ data_obj.merge!(obj_entry)
98
+ else
99
+ if /\w(date|Date)/.match(key.to_s)
100
+ value = value.nil? ? value : Time.at(value)
101
+ end
102
+ obj_entry[key] = value
103
+ data_obj.merge!(obj_entry)
10
104
  end
11
- JSON.pretty_generate(hash)
12
105
  end
106
+ # rubocop:disable Style/RedundantReturn
107
+ return data_obj
108
+ # rubocop:enable Style/RedundantReturn
13
109
  end
110
+ # rubocop:enable Style/IdenticalConditionalBranches, Performance/RedundantMatch, Performance/RegexpMatch
14
111
  end