emasser 3.12.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 +2 -2
- data/.github/workflows/push-to-docker-mail.yml +1 -2
- data/.github/workflows/push-to-docker.yml +2 -2
- data/.github/workflows/rubocop.yml +1 -1
- data/.github/workflows/test-cli.yml +4 -4
- data/.mergify.yml +11 -11
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +6 -0
- data/Dockerfile +6 -4
- data/Gemfile.lock +108 -64
- data/README.md +7 -7
- data/docs/features.md +492 -524
- 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 -0
- data/lib/emasser/delete.rb +75 -7
- data/lib/emasser/errors.rb +9 -0
- data/lib/emasser/get.rb +610 -177
- 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 +50 -42
- 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/emasser.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.summary = 'Provide an automated capability for invoving eMASS API endpoints'
|
13
13
|
spec.description = 'The 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
|
-
spec.required_ruby_version = Gem::Requirement.new('~> 2
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('~> 3.2')
|
16
16
|
|
17
17
|
# Specify which files should be added to the gem when it is released.
|
18
18
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
@@ -24,21 +24,27 @@ Gem::Specification.new do |spec|
|
|
24
24
|
# References: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-rubygems-registry
|
25
25
|
spec.metadata = { "github_repo" => "ssh://github.com/mitre/emasser" }
|
26
26
|
|
27
|
+
# ---- Run Time Dependencies
|
27
28
|
spec.add_runtime_dependency 'activesupport', '>= 6.1.4', '< 7.1.0'
|
28
|
-
spec.add_runtime_dependency 'colorize', '~>
|
29
|
-
spec.add_runtime_dependency 'dotenv', '~>
|
29
|
+
spec.add_runtime_dependency 'colorize', '~> 1.1.0'
|
30
|
+
spec.add_runtime_dependency 'dotenv', '~> 3.1.2'
|
30
31
|
spec.add_runtime_dependency 'rubyzip', '~> 2.3.2'
|
31
|
-
spec.add_runtime_dependency 'thor', '~> 1.
|
32
|
-
spec.add_runtime_dependency 'emass_client', '~> 3.
|
32
|
+
spec.add_runtime_dependency 'thor', '~> 1.3.0'
|
33
|
+
spec.add_runtime_dependency 'emass_client', '~> 3.20'
|
33
34
|
|
34
|
-
|
35
|
-
spec.add_development_dependency 'bundler
|
35
|
+
# ---- Development Dependencies
|
36
|
+
spec.add_development_dependency 'bundler', '~> 2.5'
|
37
|
+
spec.add_development_dependency 'bundler-audit', '~> 0.9'
|
38
|
+
# byebug - does not work with ruby 3.3.3
|
36
39
|
spec.add_development_dependency 'byebug', '~> 11.1.3'
|
37
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
38
|
-
spec.add_development_dependency 'yaml', '~> 0.
|
39
|
-
spec.add_development_dependency 'rake', '~> 13.
|
40
|
+
spec.add_development_dependency 'rspec', '~> 3.13.0'
|
41
|
+
spec.add_development_dependency 'yaml', '~> 0.3.0'
|
42
|
+
spec.add_development_dependency 'rake', '~> 13.2.1'
|
40
43
|
spec.add_development_dependency 'rubocop', '~> 1.7'
|
41
|
-
spec.add_development_dependency 'rubocop
|
42
|
-
spec.add_development_dependency 'rubocop-
|
43
|
-
spec.add_development_dependency 'rubocop-
|
44
|
+
# spec.add_development_dependency 'rubocop', '~> 1.64'
|
45
|
+
spec.add_development_dependency 'rubocop-minitest', '~> 0.35'
|
46
|
+
spec.add_development_dependency 'rubocop-performance', '~> 1.21'
|
47
|
+
spec.add_development_dependency 'rubocop-rake', '~> 0.6'
|
48
|
+
# solargraph - does not work with ruby 3.3.3
|
49
|
+
spec.add_development_dependency 'solargraph', '~> 0.50'
|
44
50
|
end
|
Binary file
|
@@ -2,48 +2,149 @@
|
|
2
2
|
|
3
3
|
module Emasser
|
4
4
|
require 'emasser/errors'
|
5
|
+
require 'fileutils'
|
5
6
|
|
6
7
|
class Configuration
|
7
|
-
# rubocop: disable Style/
|
8
|
+
# rubocop: disable Style/GuardClause, Lint/NonAtomicFileOperation
|
9
|
+
# rubocop: disable Style/RescueStandardError, Lint/DuplicateBranch, Style/RedundantReturn
|
10
|
+
# rubocop: disable Style/RaiseArgs, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
8
11
|
def self.raise_unless_present(env)
|
9
|
-
ENV.fetch(env) { raise Emasser::ConfigurationMissingError.new(env) }
|
12
|
+
env_value = ENV.fetch(env) { raise Emasser::ConfigurationMissingError.new(env) }
|
13
|
+
if env_value.empty?
|
14
|
+
raise Emasser::ConfigurationEmptyValueError.new(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
return env_value
|
18
|
+
rescue Emasser::ConfigurationEmptyValueError => e
|
19
|
+
unless (ARGV[0].to_s.include? 'post') && (ARGV[1].to_s.include? 'register') && (env.include? 'EMASSER_API_KEY')
|
20
|
+
puts "\n", e.message.red
|
21
|
+
show = Configuration.new
|
22
|
+
show.emasser_env_msg
|
23
|
+
exit
|
24
|
+
end
|
10
25
|
rescue Emasser::ConfigurationMissingError => e
|
11
|
-
|
12
|
-
puts "eMASSer version: #{Emasser::VERSION}".green
|
13
|
-
else
|
26
|
+
unless (ARGV[0].to_s.include? 'post') && (ARGV[1].to_s.include? 'register') && (env.include? 'EMASSER_API_KEY')
|
14
27
|
puts "\n", e.message.red
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
puts ' export EMASSER_USER_UID=<unique identifier of the eMASS user EMASSER_API_KEY belongs to>'.green
|
19
|
-
puts ' export EMASSER_HOST_URL=<FQDN of the eMASS server>'.green
|
20
|
-
puts ' export EMASSER_KEY_FILE_PATH=<path to your eMASS key in PEM format>'.green
|
21
|
-
puts ' export EMASSER_CERT_FILE_PATH=<path to your eMASS certficate in PEM format>'.green
|
22
|
-
puts ' export EMASSER_KEY_FILE_PASSWORD=<password for the key given in EMASSER_KEY_FILE_PATH>'.green, "\n"
|
23
|
-
puts 'See eMASSer environment variables requirements in eMASSer CLI Features for more information (https://mitre.github.io/emasser/docs/features.html).', "\n"
|
28
|
+
show = Configuration.new
|
29
|
+
show.emasser_env_msg
|
30
|
+
exit
|
24
31
|
end
|
25
|
-
exit
|
26
32
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
#
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
33
|
+
|
34
|
+
def self.check_folder_exists(env)
|
35
|
+
folder_path = ENV.fetch(env) # raises error if EMASSER_DOWNLOAD_DIR is missing
|
36
|
+
if folder_path.empty?
|
37
|
+
# Create a default downloads folder
|
38
|
+
raise CreateDefaultDownloadDirectory
|
39
|
+
else
|
40
|
+
# Create the folder if does not exist
|
41
|
+
unless Dir.exist?(folder_path)
|
42
|
+
FileUtils.mkdir_p('eMASSerDownloads')
|
43
|
+
end
|
44
|
+
return folder_path
|
45
|
+
end
|
46
|
+
rescue # CreateDefaultDownloadDirectory
|
47
|
+
# Create the default folder if does not exist
|
48
|
+
unless Dir.exist?('eMASSerDownloads')
|
49
|
+
FileUtils.mkdir_p('eMASSerDownloads')
|
50
|
+
end
|
51
|
+
return 'eMASSerDownloads'
|
52
|
+
end
|
53
|
+
# rubocop: enable Style/GuardClause, Lint/NonAtomicFileOperation
|
54
|
+
# rubocop: enable Style/RescueStandardError, Lint/DuplicateBranch, Style/RedundantReturn
|
55
|
+
# rubocop: enable Style/RaiseArgs, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
56
|
+
|
57
|
+
def emasser_env_msg
|
58
|
+
puts 'Create (or update) the configuration (.env) file and place it in the root directory where the emasser command is executed'.yellow
|
59
|
+
puts 'Required environment variables:'.yellow
|
60
|
+
puts ' export EMASSER_API_KEY=<API key>'.green
|
61
|
+
puts ' export EMASSER_HOST_URL=<FQDN of the eMASS server>'.green
|
62
|
+
puts ' export EMASSER_KEY_FILE_PATH=<path to your eMASS key in PEM format>'.green
|
63
|
+
puts ' export EMASSER_CERT_FILE_PATH=<path to your eMASS certficate in PEM format>'.green
|
64
|
+
puts ' export EMASSER_KEY_FILE_PASSWORD=<password for the key given in EMASSER_KEY_FILE_PATH>'.green
|
65
|
+
puts 'Note: '.yellow + 'EMASSER_API_KEY is acquired by invoking the "emasser post register cert" API command'.cyan, "\n"
|
66
|
+
puts 'Actionable (POST,PUT,DELETE) variable required by some eMASS instances:'.yellow
|
67
|
+
puts ' export EMASSER_USER_UID=<unique identifier of the eMASS user EMASSER_API_KEY belongs to>'.green
|
68
|
+
puts "\n"
|
69
|
+
puts 'See eMASSer environment variables requirements in eMASSer CLI Features for more information (https://mitre.github.io/emasser/docs/features.html).'.yellow
|
70
|
+
end
|
71
|
+
|
72
|
+
def emasser_pki_help
|
73
|
+
puts 'eMASSer PKI Certificate Requirements:'.yellow
|
74
|
+
puts 'eMASSer uses a client (signed certificate) and key (private key to the certificate) certificate for authenticating to eMASS.'.cyan
|
75
|
+
puts 'Both files are pem (Privacy-Enhanced Mail) text-based containers using base-64 encoding. The key file requires a passphrase.'.cyan
|
76
|
+
puts "\n"
|
77
|
+
puts 'The following variables must be provided on the .env (configuration) file:'.yellow
|
78
|
+
puts ' EMASSER_HOST_URL - The eMASS host URL'.cyan
|
79
|
+
puts ' EMASSER_CERT_FILE_PATH - The client certificate (.pem) file (full path is required)'.cyan
|
80
|
+
puts ' EMASSER_KEY_FILE_PATH - The private key for the certificate (.pem) file (full path is required)'.cyan
|
81
|
+
puts ' EMASSER_KEY_FILE_PASSWORD - The key file passphrase value if the key file password has been set'.cyan
|
82
|
+
puts 'IMPORTANT: If using a self signed certificate in the certificate chain the optional "EMASSER_VERIFY_SSL" variable must be set to false.'.red
|
83
|
+
end
|
84
|
+
|
85
|
+
if (ARGV[0].to_s.downcase.include? '-v') || (ARGV[0].to_s.downcase.include? '--V')
|
86
|
+
puts "emasser version: #{Emasser::VERSION}".green
|
87
|
+
exit
|
88
|
+
elsif ARGV[0].to_s.downcase.include? 'hello'
|
89
|
+
user_name = ENV.fetch('USERNAME', 'rookie')
|
90
|
+
puts "Hello #{user_name} - enjoy using eMASSer version #{Emasser::VERSION}!".cyan
|
91
|
+
exit
|
92
|
+
elsif ARGV[0].to_s.downcase.include? 'auth'
|
93
|
+
puts 'eMASS Authentication/Authorization Requirements:'.yellow
|
94
|
+
puts 'Every call to the eMASS API (via eMASSer) requires the use of a client certificate and an API key.'.cyan
|
95
|
+
puts 'A PKI-valid/trusted client certificate must be obtained from the owning eMASS instances that eMASSer is connecting to.'.cyan
|
96
|
+
puts 'An API key is also required. To obtain the API key, after configuring the PKI certificate, than'.cyan
|
97
|
+
puts 'invoke the following API command to retrieve the API key: "emasser post register cert")'.cyan
|
98
|
+
puts "\n"
|
99
|
+
puts 'eMASS Authentication Errors:'.red
|
100
|
+
puts 'If the API receives an untrusted certificate, a 403 forbidden response code will be returned.'.cyan
|
101
|
+
puts 'If an invalid api-key or combination of client certificate and api-key (from the registered account) is received, a 401 unauthorized response code will be returned.'.cyan
|
102
|
+
puts "\n"
|
103
|
+
show = Configuration.new
|
104
|
+
show.emasser_pki_help
|
105
|
+
exit
|
106
|
+
elsif (ARGV[0].to_s.downcase.include? 'help') || (ARGV[0].to_s.include? '-')
|
107
|
+
puts 'eMASSer Help'.yellow
|
108
|
+
puts 'eMASSer makes use of an environment configuration (.env) file for required and optional variables.'.cyan
|
109
|
+
puts 'The configuration file containing required variables must be located in the root directory where the eMASSer command is executed.'.cyan
|
110
|
+
puts "\n"
|
111
|
+
show = Configuration.new
|
112
|
+
show.emasser_pki_help
|
113
|
+
puts "\n"
|
114
|
+
puts 'See eMASSer environment variables requirements in eMASSer CLI Features for more information (https://mitre.github.io/emasser/docs/features.html).'.yellow
|
115
|
+
puts 'For eMASS Authentication Requirements invoke the eMASSer API command with the [auth]entication parameter (emasser auth)'.green
|
116
|
+
exit
|
117
|
+
elsif ARGV.empty?
|
118
|
+
puts 'eMASSer commands:'.yellow
|
119
|
+
puts ' emasser [get, put, post, delet] or [-h, --h, -v, -V, --version, --Version] or [help, Authentication, Authorization] '.yellow
|
120
|
+
exit
|
121
|
+
else
|
122
|
+
# rubocop: disable Style/TernaryParentheses, Style/IfWithBooleanLiteralBranches, Style/RedundantCondition
|
123
|
+
EmassClient.configure do |config|
|
124
|
+
# -----------------------------------------------------------------------
|
125
|
+
# Required env variables
|
126
|
+
config.scheme = 'https'
|
127
|
+
config.base_path = '/'
|
128
|
+
config.server_index = nil
|
129
|
+
config.api_key['api-key'] = raise_unless_present('EMASSER_API_KEY')
|
130
|
+
config.host = raise_unless_present('EMASSER_HOST_URL')
|
131
|
+
config.key_file = raise_unless_present('EMASSER_KEY_FILE_PATH')
|
132
|
+
config.cert_file = raise_unless_present('EMASSER_CERT_FILE_PATH')
|
133
|
+
config.key_password = raise_unless_present('EMASSER_KEY_FILE_PASSWORD')
|
134
|
+
|
135
|
+
# Some eMASS instances may not require this variable, others
|
136
|
+
# may required for actionable (POST,PUT,DELETE) requests
|
137
|
+
config.api_key['user-uid'] = ENV.fetch('EMASSER_USER_UID', '')
|
138
|
+
|
139
|
+
# -----------------------------------------------------------------------
|
140
|
+
# Optional env variables
|
141
|
+
config.client_side_validation = (ENV.fetch('EMASSER_CLIENT_SIDE_VALIDATION', 'true').eql? 'true') ? true : false
|
142
|
+
config.verify_ssl = (ENV.fetch('EMASSER_VERIFY_SSL', 'true').eql? 'true') ? true : false
|
143
|
+
config.verify_ssl_host = (ENV.fetch('EMASSER_VERIFY_SSL_HOST', 'true').eql? 'true') ? true : false
|
144
|
+
config.debugging = (ENV.fetch('EMASSER_DEBUGGING', 'false') == 'false') ? false : true
|
145
|
+
config.temp_folder_path = check_folder_exists('EMASSER_DOWNLOAD_DIR')
|
146
|
+
end
|
147
|
+
# rubocop: enable Style/TernaryParentheses, Style/IfWithBooleanLiteralBranches, Style/RedundantCondition
|
46
148
|
end
|
47
|
-
# rubocop: enable Style/TernaryParentheses, Style/IfWithBooleanLiteralBranches
|
48
149
|
end
|
49
150
|
end
|
data/lib/emasser/constants.rb
CHANGED
data/lib/emasser/delete.rb
CHANGED
@@ -125,7 +125,7 @@ module Emasser
|
|
125
125
|
body_array << obj
|
126
126
|
end
|
127
127
|
|
128
|
-
result = EmassClient::ArtifactsApi.new.delete_artifact(
|
128
|
+
result = EmassClient::ArtifactsApi.new.delete_artifact(options[:systemId], body_array)
|
129
129
|
puts to_output_hash(result).green
|
130
130
|
rescue EmassClient::ApiError => e
|
131
131
|
puts 'Exception when calling ArtifactsApi->delete_artifact'.red
|
@@ -133,11 +133,73 @@ module Emasser
|
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
|
+
# Remove one or many hardware assets in a system
|
137
|
+
#
|
138
|
+
# Endpoint:
|
139
|
+
# /api/systems/{systemId}/hw-baseline
|
140
|
+
class Hardware < SubCommandBase
|
141
|
+
def self.exit_on_failure?
|
142
|
+
true
|
143
|
+
end
|
144
|
+
|
145
|
+
desc 'remove', 'Delete one or many hardware assets in a system'
|
146
|
+
|
147
|
+
# Required parameters/fields
|
148
|
+
option :systemId, aliases: '-s', type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
149
|
+
option :hardwareIds, aliases: '-w', type: :array, required: true, desc: 'GUID identifying the specific hardware asset'
|
150
|
+
|
151
|
+
def remove
|
152
|
+
body_array = []
|
153
|
+
options[:hardwareIds].each do |hardware|
|
154
|
+
obj = {}
|
155
|
+
obj[:hardwareId] = hardware
|
156
|
+
body_array << obj
|
157
|
+
end
|
158
|
+
|
159
|
+
result = EmassClient::HardwareBaselineApi.new.delete_hw_baseline_assets(options[:systemId], body_array)
|
160
|
+
puts to_output_hash(result).green
|
161
|
+
rescue EmassClient::ApiError => e
|
162
|
+
puts 'Exception when calling HardwareBaselineApi->delete_hw_baseline_assets'.red
|
163
|
+
puts to_output_hash(e)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Remove one or many software assets in a system
|
168
|
+
#
|
169
|
+
# Endpoint:
|
170
|
+
# /api/systems/{systemId}/sw-baseline
|
171
|
+
class Software < SubCommandBase
|
172
|
+
def self.exit_on_failure?
|
173
|
+
true
|
174
|
+
end
|
175
|
+
|
176
|
+
desc 'remove', 'Delete one or many software assets in a system'
|
177
|
+
|
178
|
+
# Required parameters/fields
|
179
|
+
option :systemId, aliases: '-s', type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
180
|
+
option :softwareIds, aliases: '-w', type: :array, required: true, desc: 'GUID identifying the specific software asset'
|
181
|
+
|
182
|
+
def remove
|
183
|
+
body_array = []
|
184
|
+
options[:softwareIds].each do |software|
|
185
|
+
obj = {}
|
186
|
+
obj[:softwareId] = software
|
187
|
+
body_array << obj
|
188
|
+
end
|
189
|
+
|
190
|
+
result = EmassClient::SoftwareBaselineApi.new.delete_sw_baseline_assets(options[:systemId], body_array)
|
191
|
+
puts to_output_hash(result).green
|
192
|
+
rescue EmassClient::ApiError => e
|
193
|
+
puts 'Exception when calling SoftwareBaselineApi->delete_sw_baseline_assets'.red
|
194
|
+
puts to_output_hash(e)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
136
198
|
# The Cloud Resource Results endpoint provides the ability to remove
|
137
199
|
# cloud resources and their scan results in the assets module for a system.
|
138
200
|
#
|
139
201
|
# Endpoint:
|
140
|
-
# /api/systems/{systemId}/cloud-resource-results
|
202
|
+
# /api/systems/{systemId}/cloud-resource-results
|
141
203
|
class CloudResource < SubCommandBase
|
142
204
|
def self.exit_on_failure?
|
143
205
|
true
|
@@ -147,7 +209,7 @@ module Emasser
|
|
147
209
|
|
148
210
|
# Required parameters/fields
|
149
211
|
option :systemId, aliases: '-s', type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
150
|
-
option :resourceId, aliases: '-
|
212
|
+
option :resourceId, aliases: '-r', type: :string, required: true, desc: 'Unique identifier/resource namespace for policy compliance result'
|
151
213
|
|
152
214
|
def remove
|
153
215
|
body = EmassClient::CloudResourcesDeleteBodyInner.new
|
@@ -157,7 +219,7 @@ module Emasser
|
|
157
219
|
result = EmassClient::CloudResourceResultsApi.new.delete_cloud_resources(options[:systemId], body_array)
|
158
220
|
puts to_output_hash(result).green
|
159
221
|
rescue EmassClient::ApiError => e
|
160
|
-
puts 'Exception when calling
|
222
|
+
puts 'Exception when calling CloudResourceResultsApi->delete_cloud_resources'.red
|
161
223
|
puts to_output_hash(e)
|
162
224
|
end
|
163
225
|
end
|
@@ -166,7 +228,7 @@ module Emasser
|
|
166
228
|
# containers and their scan results in the assets module for a system.
|
167
229
|
#
|
168
230
|
# Endpoint:
|
169
|
-
# /api/systems/{systemId}/container-scan-results
|
231
|
+
# /api/systems/{systemId}/container-scan-results
|
170
232
|
class Container < SubCommandBase
|
171
233
|
def self.exit_on_failure?
|
172
234
|
true
|
@@ -180,13 +242,13 @@ module Emasser
|
|
180
242
|
|
181
243
|
def remove
|
182
244
|
body = EmassClient::ContainerResourcesDeleteBodyInner.new
|
183
|
-
body.
|
245
|
+
body.container_id = options[:containerId]
|
184
246
|
body_array = Array.new(1, body)
|
185
247
|
|
186
248
|
result = EmassClient::ContainerScanResultsApi.new.delete_container_sans(options[:systemId], body_array)
|
187
249
|
puts to_output_hash(result).green
|
188
250
|
rescue EmassClient::ApiError => e
|
189
|
-
puts 'Exception when calling
|
251
|
+
puts 'Exception when calling ContainerScanResultsApi->delete_container_sans'.red
|
190
252
|
puts to_output_hash(e)
|
191
253
|
end
|
192
254
|
end
|
@@ -201,6 +263,12 @@ module Emasser
|
|
201
263
|
desc 'artifacts', 'Delete system Artifacts'
|
202
264
|
subcommand 'artifacts', Artifacts
|
203
265
|
|
266
|
+
desc 'hardware', 'Delete one or many hardware assets to a system'
|
267
|
+
subcommand 'hardware', Hardware
|
268
|
+
|
269
|
+
desc 'software', 'Delete one or many software assets to a system'
|
270
|
+
subcommand 'software', Software
|
271
|
+
|
204
272
|
desc 'cloud_resource', 'Delete cloud resource and their scan results'
|
205
273
|
subcommand 'cloud_resource', CloudResource
|
206
274
|
|
data/lib/emasser/errors.rb
CHANGED
@@ -11,4 +11,13 @@ module Emasser
|
|
11
11
|
super("#{message} #{@config}")
|
12
12
|
end
|
13
13
|
end
|
14
|
+
|
15
|
+
class ConfigurationEmptyValueError < Error
|
16
|
+
attr_reader :config
|
17
|
+
|
18
|
+
def initialize(config = 'an option', message = 'Environment variable cannot be an empty:')
|
19
|
+
@config = config
|
20
|
+
super("#{message} #{@config}")
|
21
|
+
end
|
22
|
+
end
|
14
23
|
end
|