cem_acpt 0.11.2 → 0.12.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +93 -0
  4. data/docs/ARCHITECTURE.md +10 -16
  5. data/exe/cem_acpt_scan +16 -0
  6. data/lib/cem_acpt/cli.rb +24 -0
  7. data/lib/cem_acpt/config/base.rb +10 -3
  8. data/lib/cem_acpt/config/cem_acpt_scan.rb +115 -0
  9. data/lib/cem_acpt/config.rb +1 -0
  10. data/lib/cem_acpt/platform/gcp.rb +6 -9
  11. data/lib/cem_acpt/provision/terraform/linux.rb +52 -6
  12. data/lib/cem_acpt/provision/terraform.rb +147 -10
  13. data/lib/cem_acpt/scan/daemon_client.rb +91 -0
  14. data/lib/cem_acpt/scan/errors.rb +53 -0
  15. data/lib/cem_acpt/scan/result.rb +89 -0
  16. data/lib/cem_acpt/scan.rb +17 -0
  17. data/lib/cem_acpt/test_data.rb +72 -3
  18. data/lib/cem_acpt/test_runner/log_formatter/scan_result_formatter.rb +72 -0
  19. data/lib/cem_acpt/test_runner/log_formatter.rb +4 -1
  20. data/lib/cem_acpt/test_runner.rb +103 -5
  21. data/lib/cem_acpt/version.rb +1 -1
  22. data/lib/cem_acpt.rb +18 -0
  23. data/lib/terraform/gcp/linux/main.tf +129 -1
  24. data/lib/terraform/gcp/linux/scan/scan_service.rb +148 -0
  25. data/lib/terraform/gcp/linux/scan/scan_service.service +12 -0
  26. data/lib/terraform/gcp/windows/main.tf +1 -1
  27. data/lib/terraform/image/gcp/linux/main.tf +1 -1
  28. data/specifications/CEM-6511.md +286 -0
  29. data/specifications/CEM-6720.md +187 -0
  30. data/specifications/CEM-6759.md +168 -0
  31. data/specifications/CEM-6760.md +120 -0
  32. data/specifications/CEM-6761.md +136 -0
  33. data/specifications/CEM-6762.md +163 -0
  34. data/specifications/CEM-6765.md +101 -0
  35. data/specifications/CEM-6798.md +170 -0
  36. metadata +24 -4
  37. data/lib/cem_acpt/provision.rb +0 -20
@@ -0,0 +1,170 @@
1
+ # CEM-6798 — Per-OS OpenSCAP datastream config (required, with DatastreamNotFoundError)
2
+
3
+ ## Summary
4
+
5
+ `scan_post_processing!` in `lib/cem_acpt/test_data.rb` never populates a `datastream` key in
6
+ the `:scan` hash it builds for each OpenSCAP test case. The on-node scan daemon's
7
+ `perform_scan` in `lib/terraform/gcp/linux/scan/scan_service.rb` fills the gap with a
8
+ hardcoded `|| '/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml'` fallback, which silently
9
+ uses the wrong datastream on every non-RHEL 8 OS — confirmed when RHEL 9 provisioning failed
10
+ because `ssg-rhel8-ds.xml` does not exist on that OS.
11
+
12
+ Remove the hardcoded fallback. Add a `cem_acpt_scan.datastreams.openscap` config map (keyed
13
+ by test-case name, same pattern as `cem_acpt_scan.profiles.openscap`) and raise a new
14
+ `DatastreamNotFoundError` in `scan_post_processing!` when an OpenSCAP test case has no
15
+ datastream configured. CIS-CAT test cases are unaffected; their `datastream` key remains
16
+ `nil`.
17
+
18
+ ## Goals
19
+
20
+ - OpenSCAP scans receive the correct per-OS datastream file path from operator-supplied config.
21
+ - Misconfiguration is caught before any node is provisioned (early error in `scan_post_processing!`).
22
+ - The `ssg-rhel8-ds.xml` fallback is removed so it can never silently produce wrong scan results on non-RHEL 8 nodes.
23
+
24
+ ## Non-goals
25
+
26
+ - Automatic discovery or lookup of datastream paths by OS family or version at runtime.
27
+ - Changing the on-node `run_openscap` invocation or any OpenSCAP flags.
28
+ - Any changes to the CIS-CAT scan path.
29
+ - Removing the `level` key from `test_data[:scan]` or `scan_config.json`.
30
+
31
+ ## Proposed Design
32
+
33
+ ### `lib/cem_acpt/config/cem_acpt_scan.rb`
34
+
35
+ Add `datastreams: { openscap: {} }` alongside the existing `benchmarks` entry in `defaults`:
36
+
37
+ ```ruby
38
+ # before
39
+ benchmarks: {
40
+ cis_cat: {},
41
+ },
42
+
43
+ # after
44
+ benchmarks: {
45
+ cis_cat: {},
46
+ },
47
+ datastreams: {
48
+ openscap: {},
49
+ },
50
+ ```
51
+
52
+ ### `lib/cem_acpt/scan/errors.rb`
53
+
54
+ Add `DatastreamNotFoundError` following the same shape as `BenchmarkNotFoundError`:
55
+
56
+ ```ruby
57
+ # Raised when a test case has no entry in `cem_acpt_scan.datastreams.openscap`
58
+ # and so no datastream path can be resolved. The message carries the missing
59
+ # config key so the operator can fix it without re-running.
60
+ class DatastreamNotFoundError < StandardError
61
+ def initialize(test_case, scanner, config_key)
62
+ super("No datastream configured for test case '#{test_case}' (scanner: #{scanner}). Set '#{config_key}' in cem_acpt config.")
63
+ end
64
+ end
65
+ ```
66
+
67
+ ### `lib/cem_acpt/test_data.rb` — `scan_post_processing!`
68
+
69
+ After the `benchmark` lookup block (which is already gated to `scanner == :ciscat`), add a
70
+ symmetric `datastream` lookup gated to `scanner == :openscap`. Raise `DatastreamNotFoundError`
71
+ when the mapping is missing or empty. Pass `datastream` as a new key in `test_data[:scan]`.
72
+
73
+ ```ruby
74
+ datastream = nil
75
+ if scanner == :openscap
76
+ datastreams = @config.get('cem_acpt_scan.datastreams.openscap') || {}
77
+ datastream = datastreams[test_data[:test_name]] || datastreams[test_data[:test_name].to_sym]
78
+ if datastream.nil? || datastream.to_s.empty?
79
+ raise CemAcpt::Scan::DatastreamNotFoundError.new(
80
+ test_data[:test_name], scanner,
81
+ "cem_acpt_scan.datastreams.openscap.#{test_data[:test_name]}"
82
+ )
83
+ end
84
+ end
85
+
86
+ test_data[:scan] = {
87
+ scanner: scanner,
88
+ profile: profile,
89
+ level: test_data[:level] || test_data['level'],
90
+ benchmark: benchmark,
91
+ datastream: datastream,
92
+ }
93
+ ```
94
+
95
+ ### `lib/terraform/gcp/linux/scan/scan_service.rb` — `perform_scan`
96
+
97
+ Remove the hardcoded `|| '/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml'` fallback:
98
+
99
+ ```ruby
100
+ # before
101
+ run_openscap(cfg['profile'], cfg['datastream'] || '/usr/share/xml/scap/ssg/content/ssg-rhel8-ds.xml')
102
+
103
+ # after
104
+ run_openscap(cfg['profile'], cfg['datastream'])
105
+ ```
106
+
107
+ The fixture mirror at `spec/fixtures/config_testing/user_config_dir/terraform/gcp/linux/scan/scan_service.rb`
108
+ is updated identically. `spec/fixtures/config_testing/user_config_dir/terraform_checksum.txt`
109
+ is regenerated.
110
+
111
+ ## Edge Cases
112
+
113
+ - **`datastream` is `nil` for CIS-CAT test cases** — `run_ciscat` does not receive a datastream argument; the `nil` assignment is harmless.
114
+ - **`datastream` key present but empty string** — treated as missing; `DatastreamNotFoundError` is raised.
115
+ - **`cem_acpt_scan.datastreams.openscap` key absent from config** — `@config.get(...)` returns `nil`; the `|| {}` guard prevents a `NoMethodError` on the subsequent lookup.
116
+
117
+ ## Constraints / Invariants
118
+
119
+ - `test_data[:scan]` hash shape gains one key (`datastream`) but is otherwise unchanged. All
120
+ existing callers that read `scanner`, `profile`, `level`, `benchmark` are unaffected.
121
+ - `DatastreamNotFoundError` is raised in `scan_post_processing!`, before any Terraform
122
+ provisioning begins — same as `ProfileNotFoundError` and `BenchmarkNotFoundError`.
123
+ - The on-node `scan_config.json` payload already passes `cfg['datastream']` through to
124
+ `run_openscap`; no change to `lib/cem_acpt/provision/terraform.rb` or the scan-config
125
+ serialization is needed.
126
+
127
+ ## Test Plan
128
+
129
+ ### `spec/cem_acpt/scan/errors_spec.rb`
130
+
131
+ Add a `DatastreamNotFoundError` describe block mirroring the existing `BenchmarkNotFoundError`
132
+ block: assert the message includes the test-case name and the config key path.
133
+
134
+ ### `spec/cem_acpt/scan/test_data_scan_spec.rb`
135
+
136
+ 1. Update the existing "does not require a benchmark for openscap test cases" example to
137
+ also supply a `datastreams` map and assert `scan[:datastream]` equals the configured value.
138
+ 2. Add a test that `DatastreamNotFoundError` is raised when the datastream mapping is absent
139
+ for an OpenSCAP test case, and that the error message includes the missing config key path.
140
+ 3. Add a test that CIS-CAT test cases still have `scan[:datastream]` set to `nil`.
141
+
142
+ ### `spec/terraform/gcp/linux/scan/scan_service_spec.rb`
143
+
144
+ Add a text-grep assertion that the hardcoded `ssg-rhel8-ds.xml` fallback string is absent
145
+ from `scan_service.rb` (mirrors the `-l` absence test added for CEM-6765).
146
+
147
+ ## Acceptance Criteria
148
+
149
+ - [ ] `cem_acpt_scan.datastreams.openscap` is a recognized config key with a default of `{}`.
150
+ - [ ] `DatastreamNotFoundError` is defined in `lib/cem_acpt/scan/errors.rb`; its message includes the test-case name and the missing config key path.
151
+ - [ ] `scan_post_processing!` populates `test_data[:scan][:datastream]` from the config map for OpenSCAP test cases.
152
+ - [ ] `scan_post_processing!` raises `DatastreamNotFoundError` when the datastream mapping is missing or empty for an OpenSCAP test case.
153
+ - [ ] `test_data[:scan][:datastream]` is `nil` for CIS-CAT test cases.
154
+ - [ ] The hardcoded `ssg-rhel8-ds.xml` fallback is removed from `perform_scan` in `scan_service.rb` and its fixture mirror.
155
+ - [ ] `spec/fixtures/config_testing/user_config_dir/terraform_checksum.txt` is updated.
156
+ - [ ] All existing specs pass.
157
+ - [ ] New unit tests for `DatastreamNotFoundError` and datastream lookup in `scan_post_processing!` pass.
158
+
159
+ ## Files Touched
160
+
161
+ - `lib/cem_acpt/config/cem_acpt_scan.rb` — add `datastreams: { openscap: {} }` default.
162
+ - `lib/cem_acpt/scan/errors.rb` — add `DatastreamNotFoundError`.
163
+ - `lib/cem_acpt/test_data.rb` — add datastream lookup and error raise in `scan_post_processing!`.
164
+ - `lib/terraform/gcp/linux/scan/scan_service.rb` — remove hardcoded fallback from `perform_scan`.
165
+ - `spec/fixtures/config_testing/user_config_dir/terraform/gcp/linux/scan/scan_service.rb` — mirror update.
166
+ - `spec/fixtures/config_testing/user_config_dir/terraform_checksum.txt` — checksum update.
167
+ - `spec/cem_acpt/scan/errors_spec.rb` — add `DatastreamNotFoundError` describe block.
168
+ - `spec/cem_acpt/scan/test_data_scan_spec.rb` — datastream lookup and error raise tests.
169
+ - `spec/terraform/gcp/linux/scan/scan_service_spec.rb` — absence of hardcoded fallback text-grep.
170
+ - `specifications/CEM-6798.md` — this file.
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cem_acpt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.2
4
+ version: 0.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - puppetlabs
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-06-10 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: async-http
@@ -219,6 +220,7 @@ email:
219
220
  executables:
220
221
  - cem_acpt
221
222
  - cem_acpt_image
223
+ - cem_acpt_scan
222
224
  extensions: []
223
225
  extra_rdoc_files: []
224
226
  files:
@@ -252,6 +254,7 @@ files:
252
254
  - docs/rfcs/README.md
253
255
  - exe/cem_acpt
254
256
  - exe/cem_acpt_image
257
+ - exe/cem_acpt_scan
255
258
  - lib/cem_acpt.rb
256
259
  - lib/cem_acpt/actions.rb
257
260
  - lib/cem_acpt/bolt.rb
@@ -272,6 +275,7 @@ files:
272
275
  - lib/cem_acpt/config/base.rb
273
276
  - lib/cem_acpt/config/cem_acpt.rb
274
277
  - lib/cem_acpt/config/cem_acpt_image.rb
278
+ - lib/cem_acpt/config/cem_acpt_scan.rb
275
279
  - lib/cem_acpt/core_ext.rb
276
280
  - lib/cem_acpt/goss.rb
277
281
  - lib/cem_acpt/goss/api.rb
@@ -286,12 +290,15 @@ files:
286
290
  - lib/cem_acpt/platform.rb
287
291
  - lib/cem_acpt/platform/base.rb
288
292
  - lib/cem_acpt/platform/gcp.rb
289
- - lib/cem_acpt/provision.rb
290
293
  - lib/cem_acpt/provision/terraform.rb
291
294
  - lib/cem_acpt/provision/terraform/linux.rb
292
295
  - lib/cem_acpt/provision/terraform/os_data.rb
293
296
  - lib/cem_acpt/provision/terraform/terraform_cmd.rb
294
297
  - lib/cem_acpt/provision/terraform/windows.rb
298
+ - lib/cem_acpt/scan.rb
299
+ - lib/cem_acpt/scan/daemon_client.rb
300
+ - lib/cem_acpt/scan/errors.rb
301
+ - lib/cem_acpt/scan/result.rb
295
302
  - lib/cem_acpt/test_data.rb
296
303
  - lib/cem_acpt/test_runner.rb
297
304
  - lib/cem_acpt/test_runner/log_formatter.rb
@@ -299,6 +306,7 @@ files:
299
306
  - lib/cem_acpt/test_runner/log_formatter/bolt_summary_results_formatter.rb
300
307
  - lib/cem_acpt/test_runner/log_formatter/goss_action_response.rb
301
308
  - lib/cem_acpt/test_runner/log_formatter/goss_error_formatter.rb
309
+ - lib/cem_acpt/test_runner/log_formatter/scan_result_formatter.rb
302
310
  - lib/cem_acpt/test_runner/log_formatter/standard_error_formatter.rb
303
311
  - lib/cem_acpt/test_runner/test_results.rb
304
312
  - lib/cem_acpt/utils.rb
@@ -314,6 +322,8 @@ files:
314
322
  - lib/terraform/gcp/linux/goss/puppet_noop.yaml
315
323
  - lib/terraform/gcp/linux/log_service/log_service.rb
316
324
  - lib/terraform/gcp/linux/main.tf
325
+ - lib/terraform/gcp/linux/scan/scan_service.rb
326
+ - lib/terraform/gcp/linux/scan/scan_service.service
317
327
  - lib/terraform/gcp/linux/systemd/goss-acpt.service
318
328
  - lib/terraform/gcp/linux/systemd/goss-idempotent.service
319
329
  - lib/terraform/gcp/linux/systemd/goss-noop.service
@@ -324,6 +334,7 @@ files:
324
334
  - lib/terraform/image/gcp/linux/main.tf
325
335
  - lib/terraform/image/gcp/windows/.keep
326
336
  - sample_config.yaml
337
+ - specifications/CEM-6511.md
327
338
  - specifications/CEM-6713.md
328
339
  - specifications/CEM-6714.md
329
340
  - specifications/CEM-6715.md
@@ -331,6 +342,13 @@ files:
331
342
  - specifications/CEM-6717.md
332
343
  - specifications/CEM-6718.md
333
344
  - specifications/CEM-6719.md
345
+ - specifications/CEM-6720.md
346
+ - specifications/CEM-6759.md
347
+ - specifications/CEM-6760.md
348
+ - specifications/CEM-6761.md
349
+ - specifications/CEM-6762.md
350
+ - specifications/CEM-6765.md
351
+ - specifications/CEM-6798.md
334
352
  homepage: https://github.com/puppetlabs/cem_acpt
335
353
  licenses:
336
354
  - proprietary
@@ -338,6 +356,7 @@ metadata:
338
356
  homepage_uri: https://github.com/puppetlabs/cem_acpt
339
357
  source_code_uri: https://github.com/puppetlabs/cem_acpt
340
358
  changelog_uri: https://github.com/puppetlabs/cem_acpt
359
+ post_install_message:
341
360
  rdoc_options: []
342
361
  require_paths:
343
362
  - lib
@@ -352,7 +371,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
352
371
  - !ruby/object:Gem::Version
353
372
  version: '0'
354
373
  requirements: []
355
- rubygems_version: 3.6.9
374
+ rubygems_version: 3.5.22
375
+ signing_key:
356
376
  specification_version: 4
357
377
  summary: CEM Acceptance Tests
358
378
  test_files: []
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'logging'
4
- require_relative 'provision/terraform'
5
-
6
- module CemAcpt
7
- module Provision
8
- include CemAcpt::Logging
9
-
10
- def self.new_provisioner(config, provision_data)
11
- case config.get('provisioner')
12
- when 'terraform'
13
- logger.debug('CemAcpt::Provision') { 'Using Terraform provisioner' }
14
- CemAcpt::Provision::Terraform.new(config, provision_data)
15
- else
16
- raise ArgumentError, "Unknown provisioner #{config.get('provisioner')}"
17
- end
18
- end
19
- end
20
- end