inspec-reporter-json-hdf 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a6c20b0715afb937bf44526ca1d45e7644c594fd8fe2749baaca84da1efbbcee
4
+ data.tar.gz: a1cacadb0ec44285a0f506e876efe175dbe8e074608aaa66296485354a35be61
5
+ SHA512:
6
+ metadata.gz: 615fbd5bda9c8018b2e01dc6fe7801289b05cc6eb7b0077234f518c9e8f23a52aa738d153dc3bf4d74ecf74a232fd1bf5a6cc692c7dc004513a5ce4ba0f28faa
7
+ data.tar.gz: 1bdf1a54c466a3d150522aa5546729e5d0616d68fef645b57e3a01b0ee4f73d5f5e4bf0b5c9d229f7bddb00f256a6dcfe4c8088eb9ebc61a820312701d84206f
@@ -0,0 +1,30 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'inspec-reporter-json-hdf/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'inspec-reporter-json-hdf'
8
+ spec.version = InspecPlugins::HdfReporter::VERSION
9
+ spec.authors = ['Rony Xavier']
10
+ spec.email = ['rxavier@mitre.org']
11
+ spec.summary = 'InSpec Reporter plugin for Heimdall'
12
+ spec.description = 'InSpec Reporter plugin to report HDF formated JSON to be used with Heimdall.'
13
+ spec.homepage = 'https://github.com/mitre/inspec-reporter-json-hdf'
14
+ spec.license = 'Apache-2.0'
15
+ spec.require_paths = ['lib']
16
+ spec.files = Dir.glob('{{lib}/**/*,inspec-reporter-json-hdf.gemspec}').reject { |f| File.directory?(f) }
17
+
18
+ spec.required_ruby_version = '~> 2.5'
19
+
20
+ spec.add_runtime_dependency 'git-lite-version-bump', '~> 0.17', '>= 0.17.3'
21
+ spec.add_development_dependency 'bundler'
22
+ spec.add_development_dependency 'bundler-audit'
23
+ spec.add_development_dependency 'codeclimate-test-reporter'
24
+ spec.add_development_dependency 'minitest'
25
+ spec.add_development_dependency 'minitest-reporters'
26
+ spec.add_development_dependency 'pry'
27
+ spec.add_development_dependency 'rake'
28
+ spec.add_development_dependency 'simplecov'
29
+ spec.add_development_dependency 'inspec'
30
+ end
@@ -0,0 +1 @@
1
+ require_relative 'inspec-reporter-json-hdf/plugin'
@@ -0,0 +1,14 @@
1
+ require 'inspec/plugin/v2'
2
+
3
+ module InspecPlugins
4
+ module HdfReporter
5
+ class Plugin < Inspec.plugin(2)
6
+ plugin_name :'inspec-reporter-json-hdf'
7
+
8
+ reporter :hdf do
9
+ require_relative 'reporter.rb'
10
+ InspecPlugins::HdfReporter::Reporter
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,163 @@
1
+
2
+ require 'inspec/plugin/v2'
3
+ require 'json'
4
+
5
+ VALID_FREQUENCY = %w[annually semiannually quarterly monthly every2weeks weekly every3days daily].freeze
6
+
7
+ VALID_STATUSES = %w[passed failed].freeze
8
+
9
+ DATE_FORMAT = '%Y-%m-%d'.freeze
10
+
11
+ module InspecPlugins::HdfReporter
12
+ # Reporter Plugin Class
13
+ class Reporter < Inspec.plugin(2, :reporter)
14
+ def render
15
+ output(report.to_json, false)
16
+ end
17
+
18
+ def self.run_data_schema_constraints
19
+ '~> 0.0' # Accept any non-breaking change
20
+ end
21
+
22
+ def report
23
+ report = Inspec::Reporters::Json.new(@config).report
24
+ attestations = collect_attestations
25
+
26
+ report[:profiles].each do |profile|
27
+ profile[:controls].each do |control|
28
+ attestation = attestations.detect { |x| x['control_id'].eql?(control[:id]) }
29
+
30
+ next if attestation.nil?
31
+
32
+ control[:attestation] = attestation
33
+ unless attestation_expired?(attestation['updated'], attestation['frequency'])
34
+ control[:results] = apply_attestation(control[:results], attestation)
35
+ end
36
+ end
37
+ end
38
+ report
39
+ end
40
+
41
+ private
42
+
43
+ def apply_attestation(results, attestation)
44
+ if results.empty?
45
+ results = [{
46
+ "code_desc": 'Manually verified Status provided through attestation',
47
+ "run_time": 0.0,
48
+ "start_time": DateTime.now.to_s,
49
+ "status": attestation['status'],
50
+ "message": attestation_message(attestation)
51
+ }]
52
+ else
53
+ results.each do |result|
54
+ result[:message] = 'Automated test returned as passed.' if result[:status].eql?('passed')
55
+ result[:message] = result[:skip_message] if result[:status].eql?('skipped')
56
+
57
+ result[:status] = attestation['status']
58
+ result[:message] = result[:message] + attestation_message(attestation)
59
+
60
+ if result[:backtrace]
61
+ result[:message] = result[:message] + "\nbacktrace: #{result[:backtrace]}"
62
+ result[:backtrace] = nil
63
+ end
64
+ end
65
+ end
66
+ results
67
+ end
68
+
69
+ def attestation_message(attestation)
70
+ "
71
+ Attestation:
72
+ Status: #{attestation['status']}
73
+ Explanation: #{attestation['explanation']}
74
+ Updated: #{attestation['updated']}
75
+ Updated By: #{attestation['updated_by']}
76
+ Frequency: #{attestation['frequency']}
77
+ "
78
+ end
79
+
80
+ def attestation_expired?(date, frequency)
81
+ advanced_date(date, frequency) < DateTime.now
82
+ end
83
+
84
+ def advanced_date(date, frequency)
85
+ parsed_date = DateTime.strptime(date, DATE_FORMAT)
86
+
87
+ case frequency.downcase
88
+ when 'annually'
89
+ parsed_date.next_year(1)
90
+ when 'semiannually'
91
+ parsed_date.next_year(0.5)
92
+ when 'quarterly'
93
+ parsed_date.next_year(0.25)
94
+ when 'monthly'
95
+ parsed_date.next_month(1)
96
+ when 'every2weeks'
97
+ parsed_date.next_day(14)
98
+ when 'weekly'
99
+ parsed_date.next_day(7)
100
+ when 'every3days'
101
+ parsed_date.next_day(3)
102
+ when 'daily'
103
+ parsed_date.next_day(1)
104
+ else
105
+ parsed_date
106
+ end
107
+ end
108
+
109
+ # Check if its a valid Date and Date not in future.
110
+ def valid_date?(date)
111
+ DateTime.strptime(date, DATE_FORMAT) < DateTime.now
112
+ rescue ArgumentError
113
+ false
114
+ end
115
+
116
+ def valid_frequency?(frequency)
117
+ frequency.is_a?(String) && VALID_FREQUENCY.include?(frequency.downcase)
118
+ end
119
+
120
+ def valid_status?(status)
121
+ status.is_a?(String) && VALID_STATUSES.include?(status.downcase)
122
+ end
123
+
124
+ def collect_attestations
125
+ plugin_config = Inspec::Config.cached.fetch_plugin_config('inspec-reporter-json-hdf')
126
+ attestations = plugin_config['attestations'] || []
127
+
128
+ if attestations.empty?
129
+ puts 'Warning: Attestations not provided; HDF will be generated without attestations.'
130
+ else
131
+ validate_attestation(attestations)
132
+ end
133
+ attestations
134
+ end
135
+
136
+ def validate_attestation(attestations)
137
+ attestations.each do |attestation|
138
+ unless attestation['control_id'].is_a?(String)
139
+ raise "Error: Invalid `control_id` field at attestation: #{attestation}."
140
+ end
141
+ unless valid_status?(attestation['status'])
142
+ raise "Error: Invalid `status` field at attestation: #{attestation}."
143
+ end
144
+ unless attestation['updated_by'].is_a?(String)
145
+ raise "Error: Invalid `updated_by` field at attestation: #{attestation}."
146
+ end
147
+ unless attestation['explanation'].is_a?(String)
148
+ raise "Error: Invalid `explanation` field at attestation: #{attestation}."
149
+ end
150
+ unless valid_frequency?(attestation['frequency'])
151
+ raise "Error: Invalid `frequency` field at attestation: #{attestation}."
152
+ end
153
+ unless valid_date?(attestation['updated'])
154
+ raise "Error: Invalid `updated` field at attestation: #{attestation}."
155
+ end
156
+
157
+ if attestation_expired?(attestation['updated'], attestation['frequency'])
158
+ puts "Warning: Attestation Expired : #{attestation}"
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,8 @@
1
+ # provide the version for the plugin
2
+ require 'git-version-bump'
3
+
4
+ module InspecPlugins
5
+ module HdfReporter
6
+ VERSION = GVB.version(false, true)
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,194 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inspec-reporter-json-hdf
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Rony Xavier
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-01-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: git-lite-version-bump
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.17'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.17.3
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.17'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.17.3
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler-audit
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: codeclimate-test-reporter
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: minitest
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: minitest-reporters
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: pry
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rake
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: simplecov
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ - !ruby/object:Gem::Dependency
146
+ name: inspec
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ description: InSpec Reporter plugin to report HDF formated JSON to be used with Heimdall.
160
+ email:
161
+ - rxavier@mitre.org
162
+ executables: []
163
+ extensions: []
164
+ extra_rdoc_files: []
165
+ files:
166
+ - inspec-reporter-json-hdf.gemspec
167
+ - lib/inspec-reporter-json-hdf.rb
168
+ - lib/inspec-reporter-json-hdf/plugin.rb
169
+ - lib/inspec-reporter-json-hdf/reporter.rb
170
+ - lib/inspec-reporter-json-hdf/version.rb
171
+ homepage: https://github.com/mitre/inspec-reporter-json-hdf
172
+ licenses:
173
+ - Apache-2.0
174
+ metadata: {}
175
+ post_install_message:
176
+ rdoc_options: []
177
+ require_paths:
178
+ - lib
179
+ required_ruby_version: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - "~>"
182
+ - !ruby/object:Gem::Version
183
+ version: '2.5'
184
+ required_rubygems_version: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ requirements: []
190
+ rubygems_version: 3.2.3
191
+ signing_key:
192
+ specification_version: 4
193
+ summary: InSpec Reporter plugin for Heimdall
194
+ test_files: []