emasser 3.10.0 → 3.22.0
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/.env-example +18 -12
- data/.github/workflows/anchore-syft.yml +38 -0
- data/.github/workflows/codeql-analysis.yml +4 -4
- data/.github/workflows/gh-pages.yml +1 -1
- data/.github/workflows/push-to-docker-mail.yml +6 -7
- data/.github/workflows/push-to-docker.yml +6 -6
- data/.github/workflows/release.yml +1 -1
- data/.github/workflows/rubocop.yml +2 -2
- data/.github/workflows/test-cli.yml +5 -5
- data/.mergify.yml +11 -11
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +58 -2
- data/Dockerfile +6 -4
- data/Gemfile.lock +108 -64
- data/README.md +23 -22
- data/docs/features.md +682 -539
- data/emasser.gemspec +19 -13
- data/images/emasser_architecture.png +0 -0
- data/lib/emasser/configuration.rb +136 -35
- data/lib/emasser/constants.rb +4 -4
- data/lib/emasser/delete.rb +145 -15
- data/lib/emasser/errors.rb +9 -0
- data/lib/emasser/get.rb +891 -251
- data/lib/emasser/help/approvalCac_post_mapper.md +6 -5
- data/lib/emasser/help/approvalPac_post_mapper.md +1 -5
- data/lib/emasser/help/artifacts_del_mapper.md +2 -2
- data/lib/emasser/help/artifacts_post_mapper.md +23 -34
- data/lib/emasser/help/artifacts_put_mapper.md +28 -9
- data/lib/emasser/help/cloudresource_post_mapper.md +4 -3
- data/lib/emasser/help/controls_put_mapper.md +24 -16
- data/lib/emasser/help/hardware_post_mapper.md +41 -0
- data/lib/emasser/help/hardware_put_mapper.md +42 -0
- data/lib/emasser/help/milestone_del_mapper.md +1 -1
- data/lib/emasser/help/milestone_post_mapper.md +3 -1
- data/lib/emasser/help/milestone_put_mapper.md +1 -8
- data/lib/emasser/help/poam_del_mapper.md +1 -1
- data/lib/emasser/help/poam_post_mapper.md +40 -14
- data/lib/emasser/help/poam_put_mapper.md +43 -18
- data/lib/emasser/help/software_post_mapper.md +59 -0
- data/lib/emasser/help/software_put_mapper.md +60 -0
- data/lib/emasser/help/staticcode_post_mapper.md +0 -4
- data/lib/emasser/help/testresults_post_mapper.md +8 -11
- data/lib/emasser/output_converters.rb +64 -46
- data/lib/emasser/post.rb +603 -231
- data/lib/emasser/put.rb +453 -193
- data/lib/emasser/version.rb +1 -1
- metadata +51 -33
- data/images/emasser_architecture.jpg +0 -0
- data/images/emasser_diagram-Page-3.jpg +0 -0
data/lib/emasser/put.rb
CHANGED
@@ -22,7 +22,7 @@ class SubCommandBase < Thor
|
|
22
22
|
# rubocop:enable Style/OptionalBooleanParameter
|
23
23
|
end
|
24
24
|
|
25
|
-
# Override thor's long_desc
|
25
|
+
# Override thor's long_desc indentation behavior
|
26
26
|
class Thor
|
27
27
|
module Shell
|
28
28
|
class Basic
|
@@ -47,108 +47,118 @@ module Emasser
|
|
47
47
|
true
|
48
48
|
end
|
49
49
|
|
50
|
-
desc 'update', '
|
50
|
+
desc 'update', 'Update control information in a system for one or many controls (acronym)'
|
51
51
|
long_desc Help.text(:controls_put_mapper)
|
52
52
|
|
53
53
|
# Required parameters/fields
|
54
54
|
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
55
55
|
option :acronym, type: :string, required: true, desc: 'The system acronym(s) e.g "AC-1, AC-2"'
|
56
56
|
option :responsibleEntities, type: :string, required: true,
|
57
|
-
|
57
|
+
desc: 'Description of the responsible entities for the Security Control'
|
58
58
|
option :controlDesignation, type: :string, required: true,
|
59
|
-
|
60
|
-
desc: 'The Security Control Designation'
|
59
|
+
enum: ['Common', 'System-Specific', 'Hybrid'], desc: 'The Security Control Designation'
|
61
60
|
option :estimatedCompletionDate, type: :numeric, required: true, desc: 'Estimated completion date, Unix time format'
|
62
61
|
option :implementationNarrative, type: :string, required: true, desc: 'Security control comments'
|
63
62
|
|
64
63
|
# Conditional parameters/fields
|
65
64
|
option :commonControlProvider,
|
66
|
-
type: :string,
|
67
|
-
required: false,
|
68
|
-
enum: ['DoD', 'Component', 'Enclave'],
|
65
|
+
type: :string, required: false, enum: ['DoD', 'Component', 'Enclave'],
|
69
66
|
desc: 'Indicate the type of Common Control Provider for an "Inherited" Security Control'
|
70
67
|
option :naJustification,
|
71
68
|
type: :string, required: false,
|
72
69
|
desc: 'Provide justification for Security Controls deemed Not Applicable to the system'
|
73
|
-
option :slcmCriticality,
|
74
|
-
|
75
|
-
desc: 'Criticality of Security Control regarding SLCM'
|
76
|
-
option :slcmFrequency,
|
77
|
-
type: :string, required: false,
|
70
|
+
option :slcmCriticality, type: :string, required: false, desc: 'Criticality of Security Control regarding SLCM'
|
71
|
+
option :slcmFrequency, type: :string, required: false,
|
78
72
|
enum: ['Constantly', 'Daily', 'Weekly', 'Monthly', 'Quarterly', 'Semi-Annually',
|
79
73
|
'Annually', 'Every Two Years', 'Every Three Years', 'Undetermined'],
|
80
74
|
desc: 'The System-Level Continuous Monitoring frequency'
|
81
|
-
option :slcmMethod,
|
82
|
-
type: :string, required: false,
|
75
|
+
option :slcmMethod, type: :string, required: false,
|
83
76
|
enum: ['Automated', 'Semi-Automated', 'Manual', 'Undetermined'],
|
84
77
|
desc: 'The System-Level Continuous Monitoring method'
|
85
|
-
option :slcmReporting,
|
86
|
-
type: :string, required: false,
|
78
|
+
option :slcmReporting, type: :string, required: false,
|
87
79
|
desc: 'The System-Level Continuous Monitoring reporting'
|
88
|
-
option :slcmTracking,
|
89
|
-
type: :string, required: false,
|
80
|
+
option :slcmTracking, type: :string, required: false,
|
90
81
|
desc: 'The System-Level Continuous Monitoring tracking'
|
91
|
-
option :slcmComments,
|
92
|
-
type: :string, required: false,
|
82
|
+
option :slcmComments, type: :string, required: false,
|
93
83
|
desc: 'Additional comments for Security Control regarding SLCM'
|
94
84
|
|
95
85
|
# Optional parameters/fields
|
96
|
-
option :implementationStatus,
|
97
|
-
type: :string, required: false,
|
86
|
+
option :implementationStatus, type: :string, required: false,
|
98
87
|
enum: ['Planned', 'Implemented', 'Inherited', 'Not Applicable', 'Manually Inherited'],
|
99
88
|
desc: 'Implementation status of the security control for the information system'
|
100
|
-
option :severity,
|
101
|
-
type: :string, required: false,
|
89
|
+
option :severity, type: :string, required: false,
|
102
90
|
enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High'],
|
103
91
|
desc: 'The security control severity, required for approved items'
|
104
92
|
option :vulnerabiltySummary, type: :string, required: false, desc: 'The security control vulnerability summary'
|
105
93
|
option :recommendations, type: :string, required: false, desc: 'The security control vulnerability recommendation'
|
106
|
-
option :relevanceOfThreat,
|
107
|
-
type: :string, required: false,
|
94
|
+
option :relevanceOfThreat, type: :string, required: false,
|
108
95
|
enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High'],
|
109
96
|
desc: 'The security control vulnerability of threat'
|
110
|
-
option :likelihood,
|
111
|
-
type: :string, required: false,
|
97
|
+
option :likelihood, type: :string, required: false,
|
112
98
|
enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High'],
|
113
99
|
desc: 'The security control likelihood of vulnerability to threats'
|
114
|
-
option :impact,
|
115
|
-
type: :string, required: false,
|
100
|
+
option :impact, type: :string, required: false,
|
116
101
|
enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High'],
|
117
102
|
desc: 'The security control vulnerability impact'
|
118
103
|
option :impactDescription, type: :string, required: false, desc: 'Description of the security control impact'
|
119
|
-
option :residualRiskLevel,
|
120
|
-
type: :string, required: false,
|
104
|
+
option :residualRiskLevel, type: :string, required: false,
|
121
105
|
enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High'],
|
122
106
|
desc: 'The security control risk level'
|
123
|
-
option :testMethod,
|
124
|
-
type: :string, required: false,
|
107
|
+
option :testMethod, type: :string, required: false,
|
125
108
|
enum: ['Test', 'Interview', 'Examine', 'Test, Interview', 'Test, Examine',
|
126
109
|
'Interview, Examine', 'Test, Interview, Examine'],
|
127
110
|
desc: 'Assessment method/combination that determines if the security requirements are implemented correctly'
|
111
|
+
option :mitigations, type: :string, required: false,
|
112
|
+
desc: 'Identify any mitigations in place for the Non-Compliant Security Control\'s vulnerabilities.'
|
128
113
|
|
129
114
|
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
130
115
|
def update
|
131
|
-
#
|
132
|
-
|
133
|
-
body.acronym = options[:acronym]
|
134
|
-
body.responsible_entities = options[:responsibleEntities]
|
135
|
-
body.control_designation = options[:controlDesignation]
|
136
|
-
body.estimated_completion_date = options[:estimatedCompletionDate]
|
137
|
-
body.implementation_narrative = options[:implementationNarrative]
|
116
|
+
# Check if business logic is satisfied
|
117
|
+
process_business_logic
|
138
118
|
|
139
|
-
|
119
|
+
# Required fields
|
120
|
+
required = EmassClient::ControlsRequiredFields.new
|
121
|
+
required.acronym = options[:acronym]
|
122
|
+
required.responsible_entities = options[:responsibleEntities]
|
123
|
+
required.control_designation = options[:controlDesignation]
|
124
|
+
required.estimated_completion_date = options[:estimatedCompletionDate]
|
125
|
+
required.implementation_narrative = options[:implementationNarrative]
|
140
126
|
|
141
127
|
# Add optional fields
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
128
|
+
optional = EmassClient::ControlsOptionalFields.new
|
129
|
+
optional.implementation_status = options[:implementationStatus] if options[:implementationStatus]
|
130
|
+
optional.severity = options[:severity] if options[:severity]
|
131
|
+
optional.vulnerabilty_summary = options[:vulnerabiltySummary] if options[:vulnerabiltySummary]
|
132
|
+
optional.recommendations = options[:recommendations] if options[:recommendations]
|
133
|
+
optional.relevance_of_threat = options[:relevanceOfThreat] if options[:relevanceOfThreat]
|
134
|
+
optional.likelihood = options[:likelihood] if options[:likelihood]
|
135
|
+
optional.impact = options[:impact] if options[:impact]
|
136
|
+
optional.impact_description = options[:impactDescription] if options[:impactDescription]
|
137
|
+
optional.residual_risk_level = options[:residualRiskLevel] if options[:residualRiskLevel]
|
138
|
+
optional.test_method = options[:testMethod] if options[:testMethod]
|
139
|
+
optional.mitigations = options[:mitigations] if options[:mitigations]
|
140
|
+
optional.application_layer = options[:applicationLayer] if options[:applicationLayer]
|
141
|
+
optional.database_layer = options[:databaseLayer] if options[:databaseLayer]
|
142
|
+
optional.operating_system_layer = options[:operatingSystemLayer] if options[:operatingSystemLayer]
|
151
143
|
|
144
|
+
# Add conditional fields
|
145
|
+
conditional = EmassClient::ControlsConditionalFields.new
|
146
|
+
conditional.common_control_provider = options[:commonControlProvider] if options[:commonControlProvider]
|
147
|
+
conditional.na_justification = options[:naJustification] if options[:naJustification]
|
148
|
+
conditional.slcm_criticality = options[:slcmCriticality] if options[:slcmCriticality]
|
149
|
+
conditional.slcm_frequency = options[:slcmFrequency] if options[:slcmFrequency]
|
150
|
+
conditional.slcm_method = options[:slcmMethod] if options[:slcmMethod]
|
151
|
+
conditional.slcm_reporting = options[:slcmReporting] if options[:slcmReporting]
|
152
|
+
conditional.slcm_tracking = options[:slcmTracking] if options[:slcmTracking]
|
153
|
+
conditional.slcm_comments = options[:slcmComments] if options[:slcmComments]
|
154
|
+
|
155
|
+
# Build the request body
|
156
|
+
body = {}
|
157
|
+
body = body.merge(required)
|
158
|
+
body = body.merge(optional)
|
159
|
+
body = body.merge(conditional)
|
160
|
+
|
161
|
+
# All good, wrap object into an array
|
152
162
|
body_array = Array.new(1, body)
|
153
163
|
|
154
164
|
begin
|
@@ -163,13 +173,11 @@ module Emasser
|
|
163
173
|
|
164
174
|
# rubocop:disable Style/CaseLikeIf, Style/StringLiterals, Metrics/BlockLength, Metrics/CyclomaticComplexity
|
165
175
|
no_commands do
|
166
|
-
# rubocop:disable Metrics/PerceivedComplexity, Style/
|
167
|
-
def process_business_logic
|
176
|
+
# rubocop:disable Metrics/PerceivedComplexity, Style/MultipleComparison
|
177
|
+
def process_business_logic
|
168
178
|
# Conditional fields based on implementationStatus content
|
169
179
|
# unless executes code if conditional is false
|
170
180
|
unless options[:implementationStatus].nil?
|
171
|
-
body.implementation_status = options[:implementationStatus]
|
172
|
-
|
173
181
|
if options[:implementationStatus] == "Planned" || options[:implementationStatus] == "Implemented"
|
174
182
|
if options[:responsibleEntities].nil? || options[:slcmCriticality].nil? ||
|
175
183
|
options[:slcmFrequency].nil? || options[:slcmMethod].nil? ||
|
@@ -179,14 +187,6 @@ module Emasser
|
|
179
187
|
puts ' slcmMethod,slcmReporting, slcmTracking, slcmComments'.red
|
180
188
|
puts CONTROLS_PUT_HELP_MESSAGE.yellow
|
181
189
|
exit
|
182
|
-
else
|
183
|
-
body.responsible_entities = options[:responsibleEntities]
|
184
|
-
body.slcm_criticality = options[:slcmCriticality]
|
185
|
-
body.slcm_frequency = options[:slcmFrequency]
|
186
|
-
body.slcm_method = options[:slcmMethod]
|
187
|
-
body.slcm_reporting = options[:slcmReporting]
|
188
|
-
body.slcm_tracking = options[:slcmTracking]
|
189
|
-
body.slcm_comments = options[:slcmComments]
|
190
190
|
end
|
191
191
|
elsif options[:implementationStatus] == 'Not Applicable'
|
192
192
|
if options[:naJustification].nil? || options[:responsibleEntities].nil?
|
@@ -194,9 +194,6 @@ module Emasser
|
|
194
194
|
puts ' naJustification, responsibleEntities'.red
|
195
195
|
puts CONTROLS_PUT_HELP_MESSAGE.yellow
|
196
196
|
exit
|
197
|
-
else
|
198
|
-
body.slcm_reporting = options[:naJustification]
|
199
|
-
body.responsible_entities = options[:responsibleEntities]
|
200
197
|
end
|
201
198
|
elsif options[:implementationStatus] == 'Manually Inherited'
|
202
199
|
if options[:commonControlProvider].nil? || options[:responsibleEntities].nil? ||
|
@@ -207,15 +204,6 @@ module Emasser
|
|
207
204
|
puts ' slcmFrequency, slcmMethod, slcmReporting, slcmTracking, slcmComments'.red
|
208
205
|
puts CONTROLS_PUT_HELP_MESSAGE.yellow
|
209
206
|
exit
|
210
|
-
else
|
211
|
-
body.common_control_provider = options[:commonControlProvider]
|
212
|
-
body.responsible_entities = options[:responsibleEntities]
|
213
|
-
body.slcm_criticality = options[:slcmCriticality]
|
214
|
-
body.slcm_frequency = options[:slcmFrequency]
|
215
|
-
body.slcm_method = options[:slcmMethod]
|
216
|
-
body.slcm_reporting = options[:slcmReporting]
|
217
|
-
body.slcm_tracking = options[:slcmTracking]
|
218
|
-
body.slcm_comments = options[:slcmComments]
|
219
207
|
end
|
220
208
|
elsif options[:implementationStatus] == 'Inherited'
|
221
209
|
if options[:commonControlProvider].nil?
|
@@ -224,13 +212,15 @@ module Emasser
|
|
224
212
|
puts 'Missing the commonControlProvider field'.red
|
225
213
|
puts CONTROLS_PUT_HELP_MESSAGE.yellow
|
226
214
|
exit
|
227
|
-
else
|
228
|
-
body.common_control_provider = options[:commonControlProvider]
|
229
215
|
end
|
230
216
|
end
|
217
|
+
else
|
218
|
+
puts 'The "--implementationStatus" parameter is required when updating a Security Control.'.red
|
219
|
+
puts 'Values include the following: (Planned, Implemented, Inherited, Not Applicable, Manually Inherited)'.red
|
220
|
+
exit
|
231
221
|
end
|
232
222
|
end
|
233
|
-
# rubocop:enable Metrics/PerceivedComplexity, Style/
|
223
|
+
# rubocop:enable Metrics/PerceivedComplexity, Style/MultipleComparison
|
234
224
|
end
|
235
225
|
# rubocop:enable Style/CaseLikeIf, Style/StringLiterals, Metrics/BlockLength, Metrics/CyclomaticComplexity
|
236
226
|
end
|
@@ -239,7 +229,7 @@ module Emasser
|
|
239
229
|
# Update Plan of Action (POA&M) items to a system.
|
240
230
|
#
|
241
231
|
# Endpoint:
|
242
|
-
# /api/systems/{systemId}/poams
|
232
|
+
# /api/systems/{systemId}/poams
|
243
233
|
class Poams < SubCommandBase
|
244
234
|
def self.exit_on_failure?
|
245
235
|
true
|
@@ -256,7 +246,6 @@ module Emasser
|
|
256
246
|
# completionDate, milestones (at least 1)
|
257
247
|
# Not Applicable POAM can not be created
|
258
248
|
#--------------------------------------------------------------------------
|
259
|
-
#
|
260
249
|
# If a POC email is supplied, the application will attempt to locate a user
|
261
250
|
# already registered within the application and pre-populate any information
|
262
251
|
# not explicitly supplied in the request. If no such user is found, these
|
@@ -267,83 +256,147 @@ module Emasser
|
|
267
256
|
long_desc Help.text(:poam_put_mapper)
|
268
257
|
|
269
258
|
# Required parameters/fields
|
270
|
-
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
271
|
-
option :poamId, type: :numeric, required: true, desc: 'A numeric value representing the poam identification'
|
272
|
-
# option :displayPoamId,
|
273
|
-
# type: :numeric, required: true,
|
259
|
+
option :systemId, aliases: '-s', type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
260
|
+
option :poamId, aliases: '-p', type: :numeric, required: true, desc: 'A numeric value representing the poam identification'
|
261
|
+
# option :displayPoamId, type: :numeric, required: true,
|
274
262
|
# desc: 'Globally unique identifier for individual POA&M Items, seen on the front-end as "ID"'
|
275
263
|
option :status, type: :string, required: true, enum: ['Ongoing', 'Risk Accepted', 'Completed', 'Not Applicable']
|
276
264
|
option :vulnerabilityDescription, type: :string, required: true, desc: 'POA&M vulnerability description'
|
277
|
-
option :
|
278
|
-
type: :string, required: true, desc: 'Source that identifies the vulnerability'
|
265
|
+
option :sourceIdentifyingVulnerability, type: :string, required: true, desc: 'Source that identifies the vulnerability'
|
279
266
|
option :pocOrganization, type: :string, required: true, desc: 'Organization/Office represented'
|
280
267
|
option :resources, type: :string, required: true, desc: 'List of resources used'
|
281
268
|
|
269
|
+
# Some eMASS instances also require the Risk Analysis fields
|
270
|
+
# Note: These are grouped here for identification only, they are not marked as required.
|
271
|
+
option :severity, type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
272
|
+
option :relevanceOfThreat, type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
273
|
+
option :likelihood, type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
274
|
+
option :impact, type: :string, required: false, desc: 'Description of Security Control’s impact'
|
275
|
+
option :residualRiskLevel, type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
276
|
+
option :mitigations, type: :string, required: false, desc: 'Mitigations explanation'
|
277
|
+
|
282
278
|
# Conditional parameters/fields
|
283
|
-
option :milestone,
|
284
|
-
type: :hash, required: false, desc: 'key:values are: milestoneId, description and scheduledCompletionDate'
|
279
|
+
option :milestone, type: :hash, required: false, desc: 'key:values are: milestoneId, description and scheduledCompletionDate'
|
285
280
|
option :pocFirstName, type: :string, required: false, desc: 'First name of POC'
|
286
281
|
option :pocLastName, type: :string, required: false, desc: 'Last name of POC.'
|
287
282
|
option :pocEmail, type: :string, required: false, desc: 'Email address of POC'
|
288
283
|
option :pocPhoneNumber, type: :string, required: false, desc: 'Phone number of POC (area code) ***-**** format'
|
289
|
-
option :severity, type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
284
|
+
# option :severity, type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
290
285
|
option :scheduledCompletionDate,
|
291
286
|
type: :numeric, required: false, desc: 'The scheduled completion date - Unix time format'
|
292
287
|
option :completionDate,
|
293
288
|
type: :numeric, required: false, desc: 'The schedule completion date - Unix time format'
|
294
289
|
option :comments, type: :string, required: false, desc: 'Comments for completed and risk accepted POA&M items'
|
295
|
-
|
290
|
+
# The next fields are Required for VA. Optional for Army and USCG.
|
291
|
+
option :personnelResourcesFundedBaseHours, type: :numeric, required: false, desc: 'Funded based hours (125.34)'
|
292
|
+
option :personnelResourcesCostCode, type: :string, required: false, desc: 'Values are specific per eMASS instance'
|
293
|
+
option :personnelResourcesUnfundedBaseHours, type: :numeric, required: false, desc: 'Funded based hours (100.00)'
|
294
|
+
option :personnelResourcesNonfundingObstacle, type: :string, required: false, desc: 'Values are specific per eMASS instance'
|
295
|
+
option :personnelResourcesNonfundingObstacleOtherReason, type: :string, required: false, desc: 'Reason (text 2,000 char)'
|
296
|
+
option :nonPersonnelResourcesFundedAmount, type: :numeric, required: false, desc: 'Funded based hours (100.00)'
|
297
|
+
option :nonPersonnelResourcesCostCode, type: :string, required: false, desc: 'Values are specific per eMASS instance'
|
298
|
+
option :nonPersonnelResourcesUnfundedAmount, type: :numeric, required: false, desc: 'Funded based hours (100.00)'
|
299
|
+
option :nonPersonnelResourcesNonfundingObstacle, type: :string, required: false, desc: 'Values are specific per eMASS instance'
|
300
|
+
option :nonPersonnelResourcesNonfundingObstacleOtherReason, type: :string, required: false, desc: 'Reason (text 2,000 char)'
|
296
301
|
|
297
302
|
# Optional parameters/fields
|
303
|
+
# API spec states that the displayPoamId is a required field, by backend does not require it
|
304
|
+
option :displayPoamId, type: :numeric, required: false,
|
305
|
+
desc: 'Globally unique identifier for individual POA&M Items, seen on the front-end as "ID"'
|
298
306
|
option :externalUid, type: :string, required: false, desc: 'External ID associated with the POA&M'
|
299
307
|
option :controlAcronym, type: :string, required: false, desc: 'The system acronym(s) e.g "AC-1, AC-2"'
|
300
|
-
option :
|
308
|
+
option :assessmentProcedure, type: :string, required: false, desc: 'The system CCIS string numerical value'
|
301
309
|
option :securityChecks, type: :string, required: false, desc: 'Security Checks that are associated with the POA&M'
|
302
310
|
option :rawSeverity, type: :string, required: false, enum: %w[I II III]
|
303
|
-
option :relevanceOfThreat,
|
304
|
-
|
305
|
-
option :
|
306
|
-
option :impact, type: :string, required: false, desc: 'Description of Security Control’s impact'
|
311
|
+
# option :relevanceOfThreat, type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
312
|
+
# option :likelihood, type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
313
|
+
# option :impact, type: :string, required: false, desc: 'Description of Security Control’s impact'
|
307
314
|
option :impactDescription, type: :string, required: false, desc: 'Description of the security control impact'
|
308
|
-
option :residualRiskLevel,
|
309
|
-
|
310
|
-
option :
|
311
|
-
|
312
|
-
|
313
|
-
#
|
315
|
+
# option :residualRiskLevel, type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
316
|
+
option :recommendations, type: :string, required: false, desc: 'Recommendations'
|
317
|
+
# option :mitigations, type: :string, required: false, desc: 'Mitigations explanation'
|
318
|
+
# The next field is Required for VA. Optional for Army and USCG.
|
319
|
+
option :identifiedInCFOAuditOrOtherReview, type: :boolean, required: false, default: false, desc: 'BOOLEAN - true or false.'
|
320
|
+
# The next fields are for Navy Only
|
321
|
+
option :resultingResidualRiskLevelAfterProposedMitigations, type: :string, required: false, enum: ['Very Low', 'Low', 'Moderate', 'High', 'Very High']
|
322
|
+
option :predisposingConditions, type: :string, required: false, desc: 'Conditions (text 2,000 char)'
|
323
|
+
option :threatDescription, type: :string, required: false, desc: 'Threat description (text 2,000 char)'
|
324
|
+
option :devicesAffected, type: :string, required: false, desc: 'Devices Affected (text 2,000 char)'
|
325
|
+
|
326
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
|
314
327
|
def update
|
315
|
-
#
|
316
|
-
|
317
|
-
body.poam_id = options[:poamId]
|
318
|
-
body.status = options[:status]
|
319
|
-
body.vulnerability_description = options[:vulnerabilityDescription]
|
320
|
-
body.source_ident_vuln = options[:sourceIdentVuln]
|
321
|
-
body.poc_organization = options[:pocOrganization]
|
322
|
-
body.resources = options[:resources]
|
328
|
+
# Check if business logic is satisfied
|
329
|
+
process_business_logic
|
323
330
|
|
324
|
-
|
331
|
+
# Required fields
|
332
|
+
require_id_fields = EmassClient::PoamIds.new
|
333
|
+
require_id_fields.poam_id = options[:poamId]
|
334
|
+
# API spec states that the displayPoamId is a required field, by backend does not require it
|
335
|
+
require_id_fields.display_poam_id = options[:displayPoamId] if options[:displayPoamId]
|
336
|
+
|
337
|
+
require_fields = EmassClient::PoamRequiredFields.new
|
338
|
+
require_fields.status = options[:status]
|
339
|
+
require_fields.vulnerability_description = options[:vulnerabilityDescription]
|
340
|
+
require_fields.source_identifying_vulnerability = options[:sourceIdentifyingVulnerability]
|
341
|
+
require_fields.poc_organization = options[:pocOrganization]
|
342
|
+
require_fields.resources = options[:resources]
|
343
|
+
# Required for VA, optional for Army and USCG. - defaults to false
|
344
|
+
require_fields.identified_in_cfo_audit_or_other_review = options[:identifiedInCFOAuditOrOtherReview] if options[:identifiedInCFOAuditOrOtherReview]
|
325
345
|
|
326
346
|
# Add conditional fields
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
347
|
+
conditional_fields = EmassClient::PoamConditionalFields.new
|
348
|
+
conditional_fields.poc_first_name = options[:pocFirstName] if options[:pocFirstName]
|
349
|
+
conditional_fields.poc_last_name = options[:pocLastName] if options[:pocLastName]
|
350
|
+
conditional_fields.poc_email = options[:pocEmail] if options[:pocEmail]
|
351
|
+
conditional_fields.poc_phone_number = options[:pocPhoneNumber] if options[:pocPhoneNumber]
|
352
|
+
conditional_fields.severity = options[:severity] if options[:severity]
|
353
|
+
conditional_fields.scheduled_completion_date = options[:scheduledCompletionDate] if options[:scheduledCompletionDate]
|
354
|
+
conditional_fields.completion_date = options[:completionDate] if options[:completionDate]
|
355
|
+
conditional_fields.comments = options[:comments] if options[:comments]
|
356
|
+
conditional_fields.personnel_resources_funded_base_hours = options[:personnelResourcesFundedBaseHours] if options[:personnelResourcesFundedBaseHours]
|
357
|
+
conditional_fields.personnel_resources_cost_code = options[:personnelResourcesCostCode] if options[:personnelResourcesCostCode]
|
358
|
+
conditional_fields.personnel_resources_unfunded_base_hours = options[:personnelResourcesUnfundedBaseHours] if options[:personnelResourcesUnfundedBaseHours]
|
359
|
+
conditional_fields.personnel_resources_nonfunding_obstacle = options[:personnelResourcesNonfundingObstacle] if options[:personnelResourcesNonfundingObstacle]
|
360
|
+
conditional_fields.personnel_resources_nonfunding_obstacle_other_reason = options[:personnelResourcesNonfundingObstacleOtherReason] if options[:personnelResourcesNonfundingObstacleOtherReason]
|
361
|
+
conditional_fields.non_personnel_resources_funded_amount = options[:nonPersonnelResourcesFundedAmount] if options[:nonPersonnelResourcesFundedAmount]
|
362
|
+
conditional_fields.non_personnel_resources_cost_code = options[:nonPersonnelResourcesCostCode] if options[:nonPersonnelResourcesCostCode]
|
363
|
+
conditional_fields.non_personnel_resources_unfunded_amount = options[:nonPersonnelResourcesUnfundedAmount] if options[:nonPersonnelResourcesUnfundedAmount]
|
364
|
+
conditional_fields.non_personnel_resources_nonfunding_obstacle = options[:nonPersonnelResourcesNonfundingObstacle] if options[:nonPersonnelResourcesNonfundingObstacle]
|
365
|
+
conditional_fields.non_personnel_resources_nonfunding_obstacle_other_reason = options[:nonPersonnelResourcesNonfundingObstacleOtherReason] if options[:nonPersonnelResourcesNonfundingObstacleOtherReason]
|
332
366
|
|
333
367
|
# Add optional fields
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
368
|
+
optional_fields = EmassClient::PoamOptionalFields.new
|
369
|
+
optional_fields.external_uid = options[:externalUid] if options[:externalUid]
|
370
|
+
optional_fields.control_acronym = options[:controlAcronym] if options[:controlAcronym]
|
371
|
+
optional_fields.assessment_procedure = options[:assessmentProcedure] if options[:assessmentProcedure]
|
372
|
+
optional_fields.security_checks = options[:securityChecks] if options[:securityChecks]
|
373
|
+
optional_fields.raw_severity = options[:rawSeverity] if options[:rawSeverity]
|
374
|
+
optional_fields.relevance_of_threat = options[:relevanceOfThreat] if options[:relevanceOfThreat]
|
375
|
+
optional_fields.likelihood = options[:likelihood] if options[:likelihood]
|
376
|
+
optional_fields.impact = options[:impact] if options[:impact]
|
377
|
+
optional_fields.impact_description = options[:impactDescription] if options[:impactDescription]
|
378
|
+
optional_fields.residual_risk_level = options[:residualRiskLevel] if options[:residualRiskLevel]
|
379
|
+
optional_fields.recommendations = options[:recommendations] if options[:recommendations]
|
380
|
+
optional_fields.mitigations = options[:mitigations] if options[:mitigations]
|
381
|
+
optional_fields.resulting_residual_risk_level_after_proposed_mitigations = options[:resultingResidualRiskLevelAfterProposedMitigations] if options[:resultingResidualRiskLevelAfterProposedMitigations]
|
382
|
+
optional_fields.predisposing_conditions = options[:predisposingConditions] if options[:predisposingConditions]
|
383
|
+
optional_fields.threat_description = options[:threatDescription] if options[:threatDescription]
|
384
|
+
optional_fields.devices_affected = options[:devicesAffected] if options[:devicesAffected]
|
385
|
+
|
386
|
+
# Build the milestones object array
|
387
|
+
milestone = {}
|
388
|
+
milestone['milestoneId'] = options[:milestone]['milestoneId'].to_i if options[:milestone]['milestoneId']
|
389
|
+
milestone['description'] = options[:milestone]['description'] if options[:milestone]['description']
|
390
|
+
milestone['scheduledCompletionDate'] = options[:milestone]['scheduledCompletionDate'].to_f if options[:milestone]['scheduledCompletionDate']
|
391
|
+
milestone_array = Array.new(1, milestone)
|
392
|
+
|
393
|
+
# Build the request body
|
394
|
+
body = {}
|
395
|
+
body = body.merge(require_id_fields)
|
396
|
+
body = body.merge(require_fields)
|
397
|
+
body = body.merge(optional_fields)
|
398
|
+
body = body.merge(conditional_fields)
|
399
|
+
body = body.merge({ milestones: milestone_array })
|
347
400
|
body_array = Array.new(1, body)
|
348
401
|
|
349
402
|
begin
|
@@ -354,11 +407,11 @@ module Emasser
|
|
354
407
|
puts to_output_hash(e)
|
355
408
|
end
|
356
409
|
end
|
357
|
-
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
410
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/AbcSize
|
358
411
|
|
359
|
-
# rubocop:disable Metrics/
|
412
|
+
# rubocop:disable Metrics/BlockLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
360
413
|
no_commands do
|
361
|
-
def process_business_logic
|
414
|
+
def process_business_logic
|
362
415
|
#-----------------------------------------------------------------------------
|
363
416
|
# Conditional fields based on the status field values
|
364
417
|
# "Risk Accepted" comments, resources
|
@@ -393,15 +446,6 @@ module Emasser
|
|
393
446
|
puts 'Missing milstone parameters/fields'.red
|
394
447
|
print_milestone_help
|
395
448
|
exit
|
396
|
-
else
|
397
|
-
body.scheduled_completion_date = options[:scheduledCompletionDate]
|
398
|
-
|
399
|
-
milestone = EmassClient::MilestonesRequiredPut.new
|
400
|
-
milestone.milestone_id = options[:milestone]["milestoneId"] if options[:milestone]["milestoneId"]
|
401
|
-
milestone.description = options[:milestone]["description"]
|
402
|
-
milestone.scheduled_completion_date = options[:milestone]["scheduledCompletionDate"]
|
403
|
-
milestone_array = Array.new(1, milestone)
|
404
|
-
body.milestones = milestone_array
|
405
449
|
end
|
406
450
|
elsif options[:status] == "Completed"
|
407
451
|
if options[:scheduledCompletionDate].nil? || options[:comments].nil? ||
|
@@ -411,17 +455,6 @@ module Emasser
|
|
411
455
|
print_milestone_help
|
412
456
|
puts POAMS_PUT_HELP_MESSAGE.yellow
|
413
457
|
exit
|
414
|
-
else
|
415
|
-
body.scheduled_completion_date = options[:scheduledCompletionDate]
|
416
|
-
body.comments = options[:comments]
|
417
|
-
body.completion_date = options[:completionDate]
|
418
|
-
|
419
|
-
milestone = EmassClient::MilestonesRequiredPut.new
|
420
|
-
milestone.milestone_id = options[:milestone]["milestoneId"] if options[:milestone]["milestoneId"]
|
421
|
-
milestone.description = options[:milestone]["description"]
|
422
|
-
milestone.scheduled_completion_date = options[:milestone]["scheduledCompletionDate"]
|
423
|
-
milestone_array = Array.new(1, milestone)
|
424
|
-
body.milestones = milestone_array
|
425
458
|
end
|
426
459
|
end
|
427
460
|
|
@@ -464,13 +497,13 @@ module Emasser
|
|
464
497
|
puts 'The milestoneId:[value] is optional, if not provided a new milestone is created'.yellow
|
465
498
|
end
|
466
499
|
end
|
467
|
-
# rubocop:enable Metrics/
|
500
|
+
# rubocop:enable Metrics/BlockLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
468
501
|
end
|
469
502
|
|
470
503
|
# Update Milestones items to a system.
|
471
504
|
#
|
472
505
|
# Endpoint:
|
473
|
-
# /api/systems/{systemId}/poams/{poamId}/milestones
|
506
|
+
# /api/systems/{systemId}/poams/{poamId}/milestones
|
474
507
|
class Milestones < SubCommandBase
|
475
508
|
def self.exit_on_failure?
|
476
509
|
true
|
@@ -480,12 +513,12 @@ module Emasser
|
|
480
513
|
long_desc Help.text(:milestone_put_mapper)
|
481
514
|
|
482
515
|
# Required parameters/fields
|
483
|
-
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
484
|
-
option :poamId, type: :numeric, required: true, desc: 'A numeric value representing the poam identification'
|
485
|
-
option :milestoneId,
|
516
|
+
option :systemId, aliases: '-s', type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
517
|
+
option :poamId, aliases: '-p', type: :numeric, required: true, desc: 'A numeric value representing the poam identification'
|
518
|
+
option :milestoneId, aliases: '-m',
|
486
519
|
type: :numeric, required: true, desc: 'A numeric value representing the milestone identification'
|
487
|
-
option :description, type: :string, required: true, desc: 'The milestone description'
|
488
|
-
option :scheduledCompletionDate,
|
520
|
+
option :description, aliases: '-d', type: :string, required: true, desc: 'The milestone description'
|
521
|
+
option :scheduledCompletionDate, aliases: '-c',
|
489
522
|
type: :numeric, required: false, desc: 'The scheduled completion date - Unix time format'
|
490
523
|
|
491
524
|
def update
|
@@ -508,10 +541,11 @@ module Emasser
|
|
508
541
|
end
|
509
542
|
end
|
510
543
|
|
511
|
-
# Update one or many artifacts for a system
|
544
|
+
# Update one or many artifacts for a system
|
545
|
+
# (only one artifact per each execution)
|
512
546
|
#
|
513
547
|
# Endpoint:
|
514
|
-
# /api/systems/{systemId}/artifacts
|
548
|
+
# /api/systems/{systemId}/artifacts
|
515
549
|
class Artifacts < SubCommandBase
|
516
550
|
def self.exit_on_failure?
|
517
551
|
true
|
@@ -521,44 +555,50 @@ module Emasser
|
|
521
555
|
long_desc Help.text(:artifacts_put_mapper)
|
522
556
|
|
523
557
|
# Required parameters/fields
|
524
|
-
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
525
|
-
option :filename, type: :string, required: true, desc: 'Artifact file name to be updated'
|
526
|
-
option :type,
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
option :isTemplate, type: :boolean, required: false, default: false, desc: 'BOOLEAN - true or false.'
|
532
|
-
# NOTE: compress is a required parameter, however Thor does not allow a boolean type to be required because it
|
558
|
+
option :systemId, aliases: '-s', type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
559
|
+
option :filename, aliases: '-f', type: :string, required: true, desc: 'Artifact file name to be updated'
|
560
|
+
option :type, aliases: '-t', type: :string, required: true, default: 'Other',
|
561
|
+
desc: 'The type of artifact. Possible values are: Procedure, Diagram, Policy, Labor, Document, Image, Other, Scan Result, Auditor Report. May also accept other values set by system administrators.'
|
562
|
+
option :category, aliases: '-c', type: :string, required: true, default: 'Evidence',
|
563
|
+
desc: 'The category of artifact. Possible values are: Implementation Guidance, Evidence. May also accept other values set by system administrators.'
|
564
|
+
# NOTE: isTemplate is a required parameter, however Thor does not allow a boolean type to be required because it
|
533
565
|
# automatically creates a --no-isTemplate option for isTemplate=false
|
566
|
+
option :isTemplate, aliases: '-T', type: :boolean, required: false, default: false, desc: 'BOOLEAN - true or false.'
|
534
567
|
|
535
568
|
# Optional fields
|
569
|
+
option :name, type: :string, required: false, desc: 'Artifact name'
|
536
570
|
option :description, type: :string, required: false, desc: 'Artifact description'
|
537
|
-
option :
|
538
|
-
option :
|
539
|
-
option :controls,
|
540
|
-
type: :string, required: false,
|
571
|
+
option :referencePageNumber, type: :string, required: false, desc: 'Artifact reference page number'
|
572
|
+
option :controls, type: :string, required: false,
|
541
573
|
desc: 'Control acronym associated with the artifact. NIST SP 800-53 Revision 4 defined'
|
542
|
-
option :
|
543
|
-
|
544
|
-
option :lastReviewedDate,
|
545
|
-
|
574
|
+
option :assessmentProcedures, type: :string, required: false, desc: 'The Security Control Assessment Procedure being associated with the artifact'
|
575
|
+
option :expirationDate, type: :numeric, required: false, desc: 'Date Artifact expires and requires review - Unix time format'
|
576
|
+
option :lastReviewedDate, type: :numeric, required: false, desc: 'Date Artifact was last reviewed - Unix time format'
|
577
|
+
option :signedDate, type: :numeric, required: false, desc: 'Date Artifact was signed - Unix time format'
|
546
578
|
|
547
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
579
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
548
580
|
def update
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
# Optional fields
|
555
|
-
body.description = options[:description] if options[:description]
|
556
|
-
body.ref_page_number = options[:refPageNumber] if options[:refPageNumber]
|
557
|
-
body.ccis = options[:ccis] if options[:ccis]
|
558
|
-
body.controls = options[:controls] if options[:controls]
|
559
|
-
body.artifact_expiration_date = options[:artifactExpirationDate] if options[:artifactExpirationDate]
|
560
|
-
body.last_reviewed_date = options[:lastReviewedDate] if options[:lastReviewedDate]
|
581
|
+
require_fields = EmassClient::ArtifactsRequiredFields.new
|
582
|
+
require_fields.filename = options[:filename]
|
583
|
+
require_fields.type = options[:type]
|
584
|
+
require_fields.category = options[:category]
|
585
|
+
require_fields.is_template = options[:isTemplate]
|
561
586
|
|
587
|
+
# Optional fields
|
588
|
+
optional_fields = EmassClient::ArtifactsOptionalFields.new
|
589
|
+
optional_fields.name = options[:name] if options[:name]
|
590
|
+
optional_fields.description = options[:description] if options[:description]
|
591
|
+
optional_fields.reference_page_number = options[:referencePageNumber] if options[:referencePageNumber]
|
592
|
+
optional_fields.controls = options[:controls] if options[:controls]
|
593
|
+
optional_fields.assessment_procedures = options[:assessmentProcedures] if options[:assessmentProcedures]
|
594
|
+
optional_fields.expiration_date = options[:expirationDate] if options[:expirationDate]
|
595
|
+
optional_fields.last_reviewed_date = options[:lastReviewedDate] if options[:lastReviewedDate]
|
596
|
+
optional_fields.signed_date = options[:signedDate] if options[:signedDate]
|
597
|
+
|
598
|
+
# Build the request body
|
599
|
+
body = {}
|
600
|
+
body = body.merge(require_fields)
|
601
|
+
body = body.merge(optional_fields)
|
562
602
|
body_array = Array.new(1, body)
|
563
603
|
|
564
604
|
begin
|
@@ -569,7 +609,221 @@ module Emasser
|
|
569
609
|
puts to_output_hash(e)
|
570
610
|
end
|
571
611
|
end
|
572
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
612
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
613
|
+
end
|
614
|
+
|
615
|
+
# Update Hardware Baseline assets for a system
|
616
|
+
# (only one hardware per each execution)
|
617
|
+
#
|
618
|
+
# Endpoints:
|
619
|
+
# /api/systems/{systemId}/hw-baseline
|
620
|
+
class Hardware < SubCommandBase
|
621
|
+
def self.exit_on_failure?
|
622
|
+
true
|
623
|
+
end
|
624
|
+
|
625
|
+
desc 'update', 'Update one hardware assets in a system per execution'
|
626
|
+
long_desc Help.text(:hardware_put_mapper)
|
627
|
+
|
628
|
+
# Required parameters/fields
|
629
|
+
option :systemId, aliases: '-s', type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
630
|
+
option :hardwareId, aliases: '-h', type: :string, required: true, desc: 'GUID identifying the specific hardware asset'
|
631
|
+
option :assetName, aliases: '-a', type: :string, required: true, desc: 'Name of the hardware asset'
|
632
|
+
|
633
|
+
# Conditional fields
|
634
|
+
option :publicFacingFqdn, type: :string, required: false, desc: 'Public facing FQDN. Only applicable if Public Facing is set to true'
|
635
|
+
option :publicFacingIpAddress, type: :string, required: false, desc: 'Public facing IP address. Only applicable if Public Facing is set to true'
|
636
|
+
option :publicFacingUrls, type: :string, required: false, desc: 'Public facing URL(s). Only applicable if Public Facing is set to true'
|
637
|
+
|
638
|
+
# Optional fields
|
639
|
+
option :componentType, type: :string, required: false, desc: 'Component type of the hardware asset'
|
640
|
+
option :nickname, type: :string, required: false, desc: 'Nickname of the hardware asset'
|
641
|
+
option :assetIpAddress, type: :string, required: false, desc: 'IP address of the hardware asset'
|
642
|
+
option :publicFacing, type: :boolean, required: false, desc: 'Public facing is defined as any asset that is accessible from a commercial connection'
|
643
|
+
option :virtualAsset, type: :boolean, required: false, default: false, desc: 'Determine if this is a virtual hardware asset'
|
644
|
+
option :manufacturer, type: :string, required: false, desc: 'Manufacturer of the hardware asset. Populated with “Virtual” by default if Virtual Asset is true'
|
645
|
+
option :modelNumber, type: :string, required: false, desc: 'Model number of the hardware asset. Populated with “Virtual” by default if Virtual Asset is true'
|
646
|
+
option :serialNumber, type: :string, required: false, desc: 'Serial number of the hardware asset. Populated with “Virtual” by default if Virtual Asset is true'
|
647
|
+
option :OsIosFwVersion, type: :string, required: false, desc: 'OS/iOS/FW version of the hardware asset'
|
648
|
+
option :memorySizeType, type: :string, required: false, desc: 'Memory size / type of the hardware asset'
|
649
|
+
option :location, type: :string, required: false, desc: 'Location of the hardware asset'
|
650
|
+
option :approvalStatus, type: :string, required: false, desc: 'Approval status of the hardware asset'
|
651
|
+
option :criticalAsset, type: :boolean, required: false, default: false, desc: 'Indicates whether the asset is a critical information system asset'
|
652
|
+
|
653
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
654
|
+
def update
|
655
|
+
# Required fields
|
656
|
+
require_field = EmassClient::HwBaselineRequiredFields.new
|
657
|
+
require_field.asset_name = options[:assetName]
|
658
|
+
read_only_field = EmassClient::HwBaselineReadOnlyFields.new
|
659
|
+
read_only_field.hardware_id = options[:hardwareId] if options[:hardwareId]
|
660
|
+
|
661
|
+
# Conditional fields
|
662
|
+
conditional_fields = EmassClient::HwBaselineConditionalFields.new
|
663
|
+
conditional_fields.public_facing_fqdn = options[:publicFacingFqdn] if options[:publicFacingFqdn]
|
664
|
+
conditional_fields.public_facing_ip_address = options[:publicFacingIpAddress] if options[:publicFacingIpAddress]
|
665
|
+
conditional_fields.public_facing_urls = options[:publicFacingUrls] if options[:publicFacingUrls]
|
666
|
+
|
667
|
+
# Optional fields
|
668
|
+
optional_fields = EmassClient::HwBaselineOptionalFields.new
|
669
|
+
optional_fields.component_type = options[:componentType] if options[:componentType]
|
670
|
+
optional_fields.nickname = options[:nickname] if options[:nickname]
|
671
|
+
optional_fields.asset_ip_address = options[:assetIpAddress] if options[:assetIpAddress]
|
672
|
+
optional_fields.public_facing = options[:publicFacing] if options[:publicFacing]
|
673
|
+
optional_fields.virtual_asset = options[:virtualAsset] if options[:virtualAsset]
|
674
|
+
optional_fields.manufacturer = options[:manufacturer] if options[:manufacturer]
|
675
|
+
optional_fields.model_number = options[:modelNumber] if options[:modelNumber]
|
676
|
+
optional_fields.serial_number = options[:serialNumber] if options[:serialNumber]
|
677
|
+
optional_fields.os_ios_fw_version = options[:OsIosFwVersion] if options[:OsIosFwVersion]
|
678
|
+
optional_fields.memory_size_type = options[:memorySizeType] if options[:memorySizeType]
|
679
|
+
optional_fields.location = options[:location] if options[:location]
|
680
|
+
optional_fields.approval_status = options[:approvalStatus] if options[:approvalStatus]
|
681
|
+
optional_fields.critical_asset = options[:criticalAsset] if options[:criticalAsset]
|
682
|
+
|
683
|
+
# Build the body array
|
684
|
+
body = {}
|
685
|
+
body = body.merge(require_field)
|
686
|
+
body = body.merge(read_only_field)
|
687
|
+
body = body.merge(conditional_fields)
|
688
|
+
body = body.merge(optional_fields)
|
689
|
+
body_array = Array.new(1, body)
|
690
|
+
|
691
|
+
# Call the API
|
692
|
+
result = EmassClient::HardwareBaselineApi.new.update_hw_baseline_assets(options[:systemId], body_array)
|
693
|
+
puts to_output_hash(result).green
|
694
|
+
rescue EmassClient::ApiError => e
|
695
|
+
puts 'Exception when calling HardwareBaselineApi->update_hw_baseline_assets'.red
|
696
|
+
puts to_output_hash(e)
|
697
|
+
end
|
698
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
699
|
+
end
|
700
|
+
|
701
|
+
# Add Software Baseline assets for a system
|
702
|
+
# (only one software per each execution)
|
703
|
+
#
|
704
|
+
# Endpoints:
|
705
|
+
# /api/systems/{systemId}/sw-baseline
|
706
|
+
class Software < SubCommandBase
|
707
|
+
def self.exit_on_failure?
|
708
|
+
true
|
709
|
+
end
|
710
|
+
|
711
|
+
desc 'update', 'update one software assets into a system per execution'
|
712
|
+
long_desc Help.text(:software_put_mapper)
|
713
|
+
|
714
|
+
# Required parameters/fields
|
715
|
+
option :systemId, aliases: '-s', type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
716
|
+
option :softwareId, aliases: '-S', type: :string, required: true, desc: 'GUID identifying the specific software asset'
|
717
|
+
option :softwareVendor, aliases: '-V', type: :string, required: true, desc: 'Vendor of the software asset'
|
718
|
+
option :softwareName, aliases: '-N', type: :string, required: true, desc: 'Name of the software asset'
|
719
|
+
option :version, aliases: '-v', type: :string, required: true, desc: 'Version of the software asset'
|
720
|
+
|
721
|
+
# Conditional field
|
722
|
+
# If Approval Status is set to “Unapproved” or “In Progress”, Approval Date will be set to null.
|
723
|
+
option :approvalDate, type: :numeric, required: false, desc: 'Approval date of the software asset.'
|
724
|
+
|
725
|
+
# Optional fields
|
726
|
+
option :softwareType, type: :string, required: false, desc: 'Type of the software asset'
|
727
|
+
option :parentSystem, type: :string, required: false, desc: 'Parent system of the software asset'
|
728
|
+
option :subsystem, type: :string, required: false, desc: 'Subsystem of the software asset'
|
729
|
+
option :network, type: :string, required: false, desc: 'Network of the software asset'
|
730
|
+
option :hostingEnvironment, type: :string, required: false, desc: 'Hosting environment of the software asset'
|
731
|
+
option :softwareDependencies, type: :string, required: false, desc: 'Dependencies for the software asset'
|
732
|
+
option :cryptographicHash, type: :string, required: false, desc: 'Cryptographic hash for the software asset'
|
733
|
+
option :inServiceData, type: :string, required: false, desc: 'In service data for the software asset'
|
734
|
+
option :itBudgetUii, type: :string, required: false, desc: 'IT budget UII for the software asset'
|
735
|
+
option :fiscalYear, type: :string, required: false, desc: 'Fiscal year (FY) for the software asset'
|
736
|
+
option :popEndDate, type: :numeric, required: false, desc: 'Period of performance (POP) end date for the software asset'
|
737
|
+
option :licenseOrContract, type: :string, required: false, desc: 'License or contract for the software asset'
|
738
|
+
option :licenseTerm, type: :string, required: false, desc: 'License term for the software asset'
|
739
|
+
option :costPerLicense, type: :numeric, required: false, desc: 'Cost per license for the software asset'
|
740
|
+
option :totalLicenses, type: :numeric, required: false, desc: 'Number of total licenses for the software asset'
|
741
|
+
option :totalLicenseCost, type: :numeric, required: false, desc: 'Total cost of the licenses for the software asset'
|
742
|
+
option :licensesUsed, type: :numeric, required: false, desc: 'Number of licenses used for the software asset'
|
743
|
+
option :licensePoc, type: :string, required: false, desc: 'Point of contact (POC) for the software asset'
|
744
|
+
option :licenseRenewalDate, type: :numeric, required: false, desc: 'License renewal date for the software asset'
|
745
|
+
option :licenseExpirationDate, type: :numeric, required: false, desc: 'TLicense expiration date for the software asset'
|
746
|
+
option :approvalStatus, type: :string, required: false, desc: 'Approval status of the software asset'
|
747
|
+
option :releaseDate, type: :numeric, required: false, desc: 'Release date of the software asset'
|
748
|
+
option :maintenanceDate, type: :numeric, required: false, desc: 'Maintenance date of the software asset'
|
749
|
+
option :retirementDate, type: :numeric, required: false, desc: 'Retirement date of the software asset'
|
750
|
+
option :endOfLifeSupportDate, type: :numeric, required: false, desc: 'End of life/support date of the software asset'
|
751
|
+
option :extendedEndOfLifeSupportDate, type: :numeric, required: false, desc: 'Extended End of Life/Support Date cannot occur prior to the End of Life/Support Date'
|
752
|
+
option :criticalAsset, type: :boolean, required: false, default: false, desc: 'Indicates whether the asset is a critical information system asset'
|
753
|
+
option :location, type: :string, required: false, desc: 'Location of the software asset'
|
754
|
+
option :purpose, type: :string, required: false, desc: 'Purpose of the software asset'
|
755
|
+
# VA only
|
756
|
+
option :unsupportedOperatingSystem, type: :boolean, required: false, default: false, desc: 'Unsupported operating system'
|
757
|
+
option :unapprovedSoftwareFromTrm, type: :boolean, required: false, default: false, desc: 'Unapproved software from TRM'
|
758
|
+
option :approvedWaiver, type: :boolean, required: false, default: false, desc: 'Approved waiver'
|
759
|
+
|
760
|
+
# rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
761
|
+
def update
|
762
|
+
# Required fields
|
763
|
+
require_field = EmassClient::SwBaselineRequiredFields.new
|
764
|
+
require_field.software_vendor = options[:softwareVendor]
|
765
|
+
require_field.software_name = options[:softwareName]
|
766
|
+
require_field.version = options[:version]
|
767
|
+
read_only_field = EmassClient::SwBaselineReadOnlyFields.new
|
768
|
+
read_only_field.software_id = options[:softwareId] if options[:softwareId]
|
769
|
+
|
770
|
+
# Conditional fields
|
771
|
+
conditional_fields = EmassClient::SwBaselineConditionalFields.new
|
772
|
+
conditional_fields.approval_date = options[:approvalDate] if options[:approvalDate]
|
773
|
+
|
774
|
+
# Optional fields
|
775
|
+
optional_fields = EmassClient::SwBaselineOptionalFields.new
|
776
|
+
optional_fields.software_type = options[:softwareType] if options[:softwareType]
|
777
|
+
optional_fields.parent_system = options[:parentSystem] if options[:parentSystem]
|
778
|
+
optional_fields.subsystem = options[:subsystem] if options[:subsystem]
|
779
|
+
optional_fields.network = options[:network] if options[:network]
|
780
|
+
optional_fields.hosting_environment = options[:hostingEnvironment] if options[:hostingEnvironment]
|
781
|
+
optional_fields.software_dependencies = options[:softwareDependencies] if options[:softwareDependencies]
|
782
|
+
optional_fields.cryptographic_hash = options[:cryptographicHash] if options[:cryptographicHash]
|
783
|
+
optional_fields.in_service_data = options[:inServiceData] if options[:inServiceData]
|
784
|
+
optional_fields.it_budget_uii = options[:itBudgetUii] if options[:itBudgetUii]
|
785
|
+
optional_fields.fiscal_year = options[:fiscalYear] if options[:fiscalYear]
|
786
|
+
optional_fields.pop_end_date = options[:popEndDate] if options[:popEndDate]
|
787
|
+
optional_fields.license_or_contract = options[:licenseOrContract] if options[:licenseOrContract]
|
788
|
+
optional_fields.license_term = options[:licenseTerm] if options[:licenseTerm]
|
789
|
+
optional_fields.cost_per_license = options[:costPerLicense] if options[:costPerLicense]
|
790
|
+
optional_fields.total_licenses = options[:totalLicenses] if options[:totalLicenses]
|
791
|
+
optional_fields.total_license_cost = options[:totalLicenseCost] if options[:totalLicenseCost]
|
792
|
+
optional_fields.licenses_used = options[:licensesUsed] if options[:licensesUsed]
|
793
|
+
optional_fields.license_poc = options[:licensePoc] if options[:licensePoc]
|
794
|
+
optional_fields.license_renewal_date = options[:licenseRenewalDate] if options[:licenseRenewalDate]
|
795
|
+
optional_fields.license_expiration_date = options[:licenseExpirationDate] if options[:licenseExpirationDate]
|
796
|
+
optional_fields.approval_status = options[:approvalStatus] if options[:approvalStatus]
|
797
|
+
optional_fields.approval_date = options[:approvalDate] if options[:approvalDate]
|
798
|
+
optional_fields.release_date = options[:releaseDate] if options[:releaseDate]
|
799
|
+
optional_fields.maintenance_date = options[:maintenanceDate] if options[:maintenanceDate]
|
800
|
+
optional_fields.retirement_date = options[:retirementDate] if options[:retirementDate]
|
801
|
+
optional_fields.end_of_life_support_date = options[:endOfLifeSupportDate] if options[:endOfLifeSupportDate]
|
802
|
+
optional_fields.extended_end_of_life_support_date = options[:extendedEndOfLifeSupportDate] if options[:extendedEndOfLifeSupportDate]
|
803
|
+
optional_fields.critical_asset = options[:criticalAsset] if options[:criticalAsset]
|
804
|
+
optional_fields.location = options[:location] if options[:location]
|
805
|
+
optional_fields.purpose = options[:purpose] if options[:purpose]
|
806
|
+
# VA only.
|
807
|
+
optional_fields.unsupported_operating_system = options[:unsupportedOperatingSystem] if options[:unsupportedOperatingSystem]
|
808
|
+
optional_fields.unapproved_software_from_trm = options[:unapprovedSoftwareFromTrm] if options[:unapprovedSoftwareFromTrm]
|
809
|
+
optional_fields.approved_waiver = options[:approvedWaiver] if options[:approvedWaiver]
|
810
|
+
|
811
|
+
# Build the body array
|
812
|
+
body = {}
|
813
|
+
body = body.merge(require_field)
|
814
|
+
body = body.merge(read_only_field)
|
815
|
+
body = body.merge(conditional_fields)
|
816
|
+
body = body.merge(optional_fields)
|
817
|
+
body_array = Array.new(1, body)
|
818
|
+
|
819
|
+
# Call the API
|
820
|
+
result = EmassClient::SoftwareBaselineApi.new.update_sw_baseline_assets(options[:systemId], body_array)
|
821
|
+
puts to_output_hash(result).green
|
822
|
+
rescue EmassClient::ApiError => e
|
823
|
+
puts 'Exception when calling SoftwareBaselineApi->update_sw_baseline_assets'.red
|
824
|
+
puts to_output_hash(e)
|
825
|
+
end
|
826
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
573
827
|
end
|
574
828
|
|
575
829
|
class Put < SubCommandBase
|
@@ -582,7 +836,13 @@ module Emasser
|
|
582
836
|
desc 'milestones', 'Update Milestones items for a system'
|
583
837
|
subcommand 'milestones', Milestones
|
584
838
|
|
585
|
-
desc 'artifacts', '
|
839
|
+
desc 'artifacts', 'Update system Artifacts'
|
586
840
|
subcommand 'artifacts', Artifacts
|
841
|
+
|
842
|
+
desc 'hardware', 'Update one or many hardware assets to a system'
|
843
|
+
subcommand 'hardware', Hardware
|
844
|
+
|
845
|
+
desc 'software', 'Update one or many software assets to a system'
|
846
|
+
subcommand 'software', Software
|
587
847
|
end
|
588
848
|
end
|