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/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
@@ -1,6 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Emasser
|
4
|
+
GET_REGISTER_RETURN_TYPE = {
|
5
|
+
debug_return_type: 'Object'
|
6
|
+
}.freeze
|
7
|
+
|
4
8
|
GET_SYSTEM_ID_QUERY_PARAMS = {
|
5
9
|
include_package: false,
|
6
10
|
include_ditpr_metrics: false,
|
@@ -19,8 +23,4 @@ module Emasser
|
|
19
23
|
GET_WORKFLOWINSTANCES_RETURN_TYPE = {
|
20
24
|
debug_return_type: 'Object'
|
21
25
|
}.freeze
|
22
|
-
|
23
|
-
DEL_MILESTONES_RETURN_TYPE = {
|
24
|
-
debug_return_type: 'Object'
|
25
|
-
}.freeze
|
26
26
|
end
|
data/lib/emasser/delete.rb
CHANGED
@@ -51,11 +51,11 @@ module Emasser
|
|
51
51
|
long_desc Help.text(:poam_del_mapper)
|
52
52
|
|
53
53
|
# Required parameters/fields
|
54
|
-
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
55
|
-
option :poamId,
|
54
|
+
option :systemId, aliases: '-s', type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
55
|
+
option :poamId, aliases: '-p', type: :numeric, required: true, desc: 'A numeric value representing the poam identification'
|
56
56
|
|
57
57
|
def remove
|
58
|
-
body = EmassClient::
|
58
|
+
body = EmassClient::PoamRequestDeleteBodyInner.new
|
59
59
|
body.poam_id = options[:poamId]
|
60
60
|
body_array = Array.new(1, body)
|
61
61
|
|
@@ -80,26 +80,24 @@ module Emasser
|
|
80
80
|
long_desc Help.text(:milestone_del_mapper)
|
81
81
|
|
82
82
|
# Required parameters/fields
|
83
|
-
option :systemId,
|
83
|
+
option :systemId, aliases: '-s', type: :numeric, required: true,
|
84
84
|
desc: 'A numeric value representing the system identification'
|
85
|
-
option :poamId,
|
85
|
+
option :poamId, aliases: '-p', type: :numeric, required: true,
|
86
86
|
desc: 'A numeric value representing the poam identification'
|
87
|
-
option :milestoneId, type: :numeric, required: true,
|
87
|
+
option :milestoneId, aliases: '-m', type: :numeric, required: true,
|
88
88
|
desc: 'A numeric value representing the milestone identification'
|
89
89
|
|
90
90
|
def remove
|
91
|
-
body = EmassClient::
|
91
|
+
body = EmassClient::MilestonesRequestDeleteBodyInner.new
|
92
92
|
body.milestone_id = options[:milestoneId]
|
93
93
|
body_array = Array.new(1, body)
|
94
94
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
result = EmassClient::MilestonesApi.new.delete_milestone(options[:systemId], options[:poamId], body_array, opts)
|
95
|
+
result = EmassClient::MilestonesApi.new.delete_milestone(options[:systemId], options[:poamId], body_array)
|
96
|
+
# The server returns an empty object upon successfully deleting a milestone.
|
99
97
|
puts to_output_hash(result).green
|
100
98
|
rescue EmassClient::ApiError => e
|
101
99
|
puts 'Exception when calling MilestonesApi->delete_milestone'.red
|
102
|
-
puts to_output_hash(e)
|
100
|
+
puts to_output_hash(e)
|
103
101
|
end
|
104
102
|
end
|
105
103
|
|
@@ -113,11 +111,11 @@ module Emasser
|
|
113
111
|
end
|
114
112
|
|
115
113
|
desc 'remove', 'Delete one or many artifacts in a system'
|
116
|
-
long_desc Help.text(:
|
114
|
+
long_desc Help.text(:artifacts_del_mapper)
|
117
115
|
|
118
116
|
# Required parameters/fields
|
119
|
-
option :systemId, type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
120
|
-
option :files, type: :array, required: true, desc: 'Artifact file(s) to remove from the given system'
|
117
|
+
option :systemId, aliases: '-s', type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
118
|
+
option :files, aliases: '-f', type: :array, required: true, desc: 'Artifact file(s) to remove from the given system'
|
121
119
|
|
122
120
|
def remove
|
123
121
|
body_array = []
|
@@ -135,6 +133,126 @@ module Emasser
|
|
135
133
|
end
|
136
134
|
end
|
137
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
|
+
|
198
|
+
# The Cloud Resource Results endpoint provides the ability to remove
|
199
|
+
# cloud resources and their scan results in the assets module for a system.
|
200
|
+
#
|
201
|
+
# Endpoint:
|
202
|
+
# /api/systems/{systemId}/cloud-resource-results
|
203
|
+
class CloudResource < SubCommandBase
|
204
|
+
def self.exit_on_failure?
|
205
|
+
true
|
206
|
+
end
|
207
|
+
|
208
|
+
desc 'remove', 'Delete one or many Cloud Resources and their scan results in the assets module for a system'
|
209
|
+
|
210
|
+
# Required parameters/fields
|
211
|
+
option :systemId, aliases: '-s', type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
212
|
+
option :resourceId, aliases: '-r', type: :string, required: true, desc: 'Unique identifier/resource namespace for policy compliance result'
|
213
|
+
|
214
|
+
def remove
|
215
|
+
body = EmassClient::CloudResourcesDeleteBodyInner.new
|
216
|
+
body.resource_id = options[:resourceId]
|
217
|
+
body_array = Array.new(1, body)
|
218
|
+
|
219
|
+
result = EmassClient::CloudResourceResultsApi.new.delete_cloud_resources(options[:systemId], body_array)
|
220
|
+
puts to_output_hash(result).green
|
221
|
+
rescue EmassClient::ApiError => e
|
222
|
+
puts 'Exception when calling CloudResourceResultsApi->delete_cloud_resources'.red
|
223
|
+
puts to_output_hash(e)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
# The Container Scan Results endpoint provides the ability to remove
|
228
|
+
# containers and their scan results in the assets module for a system.
|
229
|
+
#
|
230
|
+
# Endpoint:
|
231
|
+
# /api/systems/{systemId}/container-scan-results
|
232
|
+
class Container < SubCommandBase
|
233
|
+
def self.exit_on_failure?
|
234
|
+
true
|
235
|
+
end
|
236
|
+
|
237
|
+
desc 'remove', 'Delete one or many containers scan results in the assets module for a system'
|
238
|
+
|
239
|
+
# Required parameters/fields
|
240
|
+
option :systemId, aliases: '-s', type: :numeric, required: true, desc: 'A numeric value representing the system identification'
|
241
|
+
option :containerId, aliases: '-c', type: :string, required: true, desc: 'Unique identifier of the container'
|
242
|
+
|
243
|
+
def remove
|
244
|
+
body = EmassClient::ContainerResourcesDeleteBodyInner.new
|
245
|
+
body.container_id = options[:containerId]
|
246
|
+
body_array = Array.new(1, body)
|
247
|
+
|
248
|
+
result = EmassClient::ContainerScanResultsApi.new.delete_container_sans(options[:systemId], body_array)
|
249
|
+
puts to_output_hash(result).green
|
250
|
+
rescue EmassClient::ApiError => e
|
251
|
+
puts 'Exception when calling ContainerScanResultsApi->delete_container_sans'.red
|
252
|
+
puts to_output_hash(e)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
138
256
|
class Delete < SubCommandBase
|
139
257
|
desc 'poams', 'Delete Plan of Action and Milestones (POA&M) items for a system'
|
140
258
|
subcommand 'poams', Poams
|
@@ -144,5 +262,17 @@ module Emasser
|
|
144
262
|
|
145
263
|
desc 'artifacts', 'Delete system Artifacts'
|
146
264
|
subcommand 'artifacts', Artifacts
|
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
|
+
|
272
|
+
desc 'cloud_resource', 'Delete cloud resource and their scan results'
|
273
|
+
subcommand 'cloud_resource', CloudResource
|
274
|
+
|
275
|
+
desc 'container', 'Delete container and their scan results'
|
276
|
+
subcommand 'container', Container
|
147
277
|
end
|
148
278
|
end
|
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
|