cem_acpt 0.11.0 → 0.11.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.
- checksums.yaml +4 -4
- data/.gitignore +8 -0
- data/.worktreeinclude +1 -0
- data/CLAUDE.md +64 -25
- data/Gemfile.lock +1 -1
- data/README.md +20 -7
- data/docs/ARCHITECTURE.md +1042 -0
- data/docs/rfcs/0000-template.md +54 -0
- data/docs/rfcs/0001-fix-bolt-missing-skip-path.md +105 -0
- data/docs/rfcs/0002-fix-default-character-substitutions.md +119 -0
- data/docs/rfcs/0003-windows-image-builder-template.md +110 -0
- data/docs/rfcs/0004-image-name-truncation-off-by-one.md +108 -0
- data/docs/rfcs/0005-os-dispatch-replace-windows-heuristic.md +117 -0
- data/docs/rfcs/0006-configurable-windows-bucket.md +96 -0
- data/docs/rfcs/0007-logging-quiet-and-typos.md +121 -0
- data/docs/rfcs/0008-namespace-platform-classes.md +110 -0
- data/docs/rfcs/0009-bolt-log-formatter-cleanup.md +111 -0
- data/docs/rfcs/0010-dead-code-cleanup.md +83 -0
- data/docs/rfcs/0011-provisioner-factory-consistency.md +89 -0
- data/docs/rfcs/README.md +34 -0
- data/lib/cem_acpt/cli.rb +10 -1
- data/lib/cem_acpt/config/cem_acpt.rb +4 -1
- data/lib/cem_acpt/image_builder/errors.rb +24 -0
- data/lib/cem_acpt/image_builder.rb +28 -1
- data/lib/cem_acpt/image_name_builder.rb +8 -1
- data/lib/cem_acpt/platform/gcp.rb +112 -106
- data/lib/cem_acpt/platform.rb +21 -19
- data/lib/cem_acpt/provision/terraform/linux.rb +1 -1
- data/lib/cem_acpt/provision/terraform/os_data.rb +23 -0
- data/lib/cem_acpt/provision/terraform/windows.rb +7 -1
- data/lib/cem_acpt/provision/terraform.rb +20 -16
- data/lib/cem_acpt/test_runner/log_formatter/bolt_summary_results_formatter.rb +2 -1
- data/lib/cem_acpt/test_runner/log_formatter.rb +0 -1
- data/lib/cem_acpt/test_runner.rb +21 -8
- data/lib/cem_acpt/utils/winrm_runner.rb +4 -3
- data/lib/cem_acpt/utils.rb +0 -12
- data/lib/cem_acpt/version.rb +1 -1
- data/lib/cem_acpt.rb +19 -7
- data/specifications/CEM-6713.md +165 -0
- data/specifications/CEM-6714.md +271 -0
- data/specifications/CEM-6715.md +133 -0
- data/specifications/CEM-6716.md +160 -0
- data/specifications/CEM-6717.md +239 -0
- data/specifications/CEM-6718.md +120 -0
- data/specifications/CEM-6719.md +173 -0
- metadata +26 -11
- data/.claude/settings.local.json +0 -7
- data/lib/cem_acpt/action_result.rb +0 -91
- data/lib/cem_acpt/puppet_helpers.rb +0 -38
- data/lib/cem_acpt/test_runner/log_formatter/bolt_error_formatter.rb +0 -65
- data/lib/cem_acpt/test_runner/log_formatter/bolt_output_formatter.rb +0 -54
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: df61aa1c290a076e460b4c790babb19d0e0729e7d543feb96a9fb40e1589e50a
|
|
4
|
+
data.tar.gz: 800a652e59491e42f0e3fdd43db93e397956309e2b575d33e0f2c1497ebd8311
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a4a93419e474a066291ead08cbb28222f635f218b3df394b92f8c23d2fc1d63d55b9c5e240229c86db22a7b98e0e8673a5f13c7d02bd0d3633976942cc22be08
|
|
7
|
+
data.tar.gz: 614ecdad289b17a01ffcaea724aa928372cf578a4270f641e592549a6f2d017235646fe5ab8b3274e23801755935b6d7e17cdd39072aee28cbc7692b86e5b663
|
data/.gitignore
CHANGED
data/.worktreeinclude
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.env
|
data/CLAUDE.md
CHANGED
|
@@ -2,75 +2,113 @@
|
|
|
2
2
|
|
|
3
3
|
## What This Project Is
|
|
4
4
|
|
|
5
|
-
`cem_acpt` is a Ruby gem providing an acceptance testing CLI for Puppet SCE (Security Compliance Enforcement
|
|
5
|
+
`cem_acpt` is a Ruby gem providing an acceptance testing CLI for Puppet SCE (Security Compliance Enforcement, formerly Puppet CEM / Compliance Enforcement Modules). It provisions cloud nodes via Terraform, applies a Puppet manifest, runs infrastructure tests via Goss (and optionally Bolt task/plan tests), then tears everything down. Both Linux nodes (over SSH) and Windows nodes (over WinRM) are supported.
|
|
6
|
+
|
|
7
|
+
A second binary, `cem_acpt_image`, builds the base VM images used by the test runner.
|
|
8
|
+
|
|
9
|
+
The gem name is intentionally unchanged after the CEM → SCE rename. The consuming Puppet modules were renamed to `sce_linux` / `sce_windows`, but this gem stays `cem_acpt`.
|
|
10
|
+
|
|
11
|
+
## Where to Read More
|
|
12
|
+
|
|
13
|
+
Before diving into the summary below, skim:
|
|
14
|
+
- `docs/ARCHITECTURE.md` — fuller architecture writeup
|
|
15
|
+
- `docs/rfcs/` — design decisions (Windows image builder, OS dispatch, platform namespacing, logging behavior, etc.). Check here before proposing structural changes.
|
|
6
16
|
|
|
7
17
|
## Commands
|
|
8
18
|
|
|
9
19
|
```bash
|
|
10
20
|
bundle install # Install dependencies
|
|
11
21
|
|
|
12
|
-
bundle exec rake spec # Run all
|
|
22
|
+
bundle exec rake spec # Run all spec tests
|
|
13
23
|
bundle exec rake spec SPEC=spec/path/to/file_spec.rb # Run a single spec file
|
|
14
24
|
|
|
15
25
|
rubocop # Lint
|
|
16
26
|
rubocop -a # Auto-fix lint issues
|
|
17
27
|
|
|
18
28
|
bundle exec rake build # Build the gem (saves to pkg/cem_acpt-<semver>.gem)
|
|
19
|
-
bundle exec gem install pkg/cem_acpt-X.X.X.gem # Install
|
|
29
|
+
bundle exec gem install pkg/cem_acpt-X.X.X.gem # Install built gem
|
|
20
30
|
|
|
21
31
|
bundle exec exe/cem_acpt -h # CLI help
|
|
22
|
-
bundle exec exe/cem_acpt -Y # Print merged config
|
|
32
|
+
bundle exec exe/cem_acpt -Y # Print merged config as YAML
|
|
23
33
|
bundle exec exe/cem_acpt -X # Explain config merge sources
|
|
24
34
|
```
|
|
25
35
|
|
|
26
|
-
|
|
36
|
+
CI runs `bundle exec rake spec` on PRs against `main` (see `.github/workflows/spec.yml`). Lint is not currently gated in CI, but RuboCop should be clean before merging.
|
|
37
|
+
|
|
38
|
+
RuboCop targets Ruby 3.2 with a 200-char line limit. The config in `.rubocop.yml` is intentionally permissive — many cops (complexity, layout, style) are disabled. Check `.rubocop.yml` before assuming a rule is enforced.
|
|
27
39
|
|
|
28
40
|
## Architecture
|
|
29
41
|
|
|
30
42
|
### Entry Points
|
|
31
43
|
|
|
32
|
-
- `exe/cem_acpt`
|
|
33
|
-
-
|
|
34
|
-
-
|
|
44
|
+
- `exe/cem_acpt` and `exe/cem_acpt_image` both call into `CemAcpt.run` in `lib/cem_acpt.rb`, which dispatches on the command:
|
|
45
|
+
- `:cem_acpt` → `TestRunner::Runner`
|
|
46
|
+
- `:cem_acpt_image` → `ImageBuilder::TerraformBuilder`
|
|
47
|
+
- `:print_yaml_config` / `:print_explain_config` → handle the `-Y` / `-X` debugging flags
|
|
48
|
+
- `:version` → prints gem version
|
|
49
|
+
- CLI parsing lives in `lib/cem_acpt/cli.rb` (Ruby `OptionParser`).
|
|
35
50
|
|
|
36
51
|
### Configuration System (`lib/cem_acpt/config/`)
|
|
37
52
|
|
|
38
|
-
Config is
|
|
53
|
+
Config is built by merging four sources, with each later source overriding earlier ones:
|
|
54
|
+
|
|
39
55
|
1. Environment variables (`CEM_ACPT_` prefix; nested keys use `__`)
|
|
40
56
|
2. User config at `~/.cem_acpt/config.yaml`
|
|
41
57
|
3. `--config FILE` option
|
|
42
58
|
4. Other CLI flags
|
|
43
59
|
|
|
44
|
-
`Config::Base` handles the merge
|
|
60
|
+
`Config::Base` handles the merge via `deep_merge`. `Config::CemAcpt` and `Config::CemAcptImage` define the schema for each command. Use `-Y` to print the merged result and `-X` to see which source contributed each value.
|
|
45
61
|
|
|
46
62
|
### Test Runner Lifecycle (`lib/cem_acpt/test_runner.rb`)
|
|
47
63
|
|
|
48
|
-
1. **Pre-provision**
|
|
49
|
-
2. **Provision**
|
|
50
|
-
3. **Execute**
|
|
51
|
-
4. **Cleanup**
|
|
64
|
+
1. **Pre-provision** — Build the Puppet module tarball (`Utils::Puppet`).
|
|
65
|
+
2. **Provision** — Spin up nodes via the configured platform (currently only GCP) using Terraform (`Provision::Terraform`), generate ephemeral SSH keys (or set up WinRM for Windows), and install the module.
|
|
66
|
+
3. **Execute** — Run action groups: `:goss` (async, HTTP) and `:bolt` (sync, Puppet tasks). Filter with `--only-actions` / `--except-actions`.
|
|
67
|
+
4. **Cleanup** — `terraform destroy` unless `--no-destroy-nodes`.
|
|
52
68
|
|
|
53
69
|
### Platform Abstraction (`lib/cem_acpt/platform/`)
|
|
54
70
|
|
|
55
|
-
`Platform::Base` defines the interface; `Platform::
|
|
71
|
+
`Platform::Base` defines the interface; `Platform::TestBase` extends it for test-node platforms. `Platform::Gcp` is the only concrete implementation today, but platforms are loaded dynamically by name from config — so adding e.g. AWS means a new file here plus a Terraform tree under `lib/terraform/`.
|
|
56
72
|
|
|
57
73
|
### Actions (`lib/cem_acpt/actions.rb`)
|
|
58
74
|
|
|
59
|
-
The `Actions` class orchestrates test execution.
|
|
75
|
+
The `Actions` class orchestrates test execution. Actions register themselves via `register_action`/`register_group` and run in `order` order. Goss actions run asynchronously via `async-http`; Bolt actions run synchronously.
|
|
76
|
+
|
|
77
|
+
### Transports
|
|
78
|
+
|
|
79
|
+
- **SSH** (`lib/cem_acpt/utils/ssh.rb`) — Linux nodes
|
|
80
|
+
- **WinRM** (`lib/cem_acpt/utils/winrm_runner.rb`) — Windows nodes
|
|
81
|
+
- **Goss HTTP API** (`lib/cem_acpt/goss/api.rb`) — assertions, on a port exposed by the provisioned node
|
|
60
82
|
|
|
61
83
|
### Terraform Templates (`lib/terraform/`)
|
|
62
84
|
|
|
63
|
-
Terraform HCL
|
|
64
|
-
- `lib/terraform/gcp/linux/` and `lib/terraform/gcp/windows/`
|
|
65
|
-
- `lib/terraform/image/gcp/linux/`
|
|
85
|
+
Terraform HCL ships inside the gem:
|
|
86
|
+
- `lib/terraform/gcp/linux/` and `lib/terraform/gcp/windows/` — test-node provisioning
|
|
87
|
+
- `lib/terraform/image/gcp/linux/` and `lib/terraform/image/gcp/windows/` — image-building provisioning
|
|
66
88
|
|
|
67
89
|
### Logging (`lib/cem_acpt/logging/`)
|
|
68
90
|
|
|
69
|
-
Supports simultaneous STDOUT + file logging.
|
|
91
|
+
Supports simultaneous STDOUT + file logging. `-I` / `--CI` enables GitHub Actions–formatted output. `--trace` enables Ruby `TracePoint` debugging. Most subsystems include `CemAcpt::Logging` to get a `logger` method.
|
|
92
|
+
|
|
93
|
+
## Where to Add Things
|
|
94
|
+
|
|
95
|
+
| Adding… | Touch |
|
|
96
|
+
| ----------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
97
|
+
| A new platform (e.g. AWS) | `lib/cem_acpt/platform/<name>.rb` (subclass `Platform::TestBase`) + `lib/terraform/<name>/...` |
|
|
98
|
+
| A new action group | Register in `lib/cem_acpt/actions.rb`; add a subdir under `lib/cem_acpt/<group>/` |
|
|
99
|
+
| A new config option | Add to `lib/cem_acpt/config/cem_acpt.rb` (or `cem_acpt_image.rb`) and wire into `cli.rb` |
|
|
100
|
+
| A new Bolt helper | `lib/cem_acpt/bolt/` — see `inventory.rb`, `tasks.rb`, `tests.rb` for the existing pattern |
|
|
101
|
+
| A new utility (SSH/WinRM/etc) | `lib/cem_acpt/utils/` |
|
|
70
102
|
|
|
71
103
|
## Test Structure
|
|
72
104
|
|
|
73
|
-
|
|
105
|
+
### Unit tests (this repo)
|
|
106
|
+
|
|
107
|
+
Specs live under `spec/`, mirroring the layout of `lib/`. Fixtures live in `spec/fixtures/`. Run with `bundle exec rake spec`.
|
|
108
|
+
|
|
109
|
+
### Acceptance tests (consuming module)
|
|
110
|
+
|
|
111
|
+
Acceptance test cases live in the **consuming module** (e.g. `sce_linux`, `sce_windows`), not in this gem. They follow this layout:
|
|
74
112
|
|
|
75
113
|
```
|
|
76
114
|
spec/acceptance/<framework>_<os>-<version>_<firewall>_<profile>_<level>/
|
|
@@ -79,9 +117,10 @@ spec/acceptance/<framework>_<os>-<version>_<firewall>_<profile>_<level>/
|
|
|
79
117
|
bolt.yaml # (optional) Bolt task assertions
|
|
80
118
|
```
|
|
81
119
|
|
|
82
|
-
Unit tests mirror `lib/` under `spec/`. Fixtures are in `spec/fixtures/`.
|
|
83
|
-
|
|
84
120
|
## Conventions
|
|
85
121
|
|
|
86
|
-
- Document
|
|
87
|
-
- All changes should have tests
|
|
122
|
+
- Document Ruby code with YARD comments.
|
|
123
|
+
- All changes should have tests.
|
|
124
|
+
- Subsystem-specific error classes live alongside the subsystem (e.g. `lib/cem_acpt/bolt/errors.rb`); follow that pattern rather than reusing generic `StandardError`.
|
|
125
|
+
- Use `CemAcpt::Utils::FinalizerQueue` for ordered cleanup of provisioned resources rather than ad-hoc `ensure` blocks.
|
|
126
|
+
- Mix in `CemAcpt::Logging` to get a logger; don't instantiate one directly.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -16,7 +16,7 @@ gem install cem_acpt
|
|
|
16
16
|
|
|
17
17
|
### Quickstart
|
|
18
18
|
|
|
19
|
-
Make sure Terraform and the gcloud CLI are installed and in your PATH. Instructions for installing Terraform can be found [here](https://learn.hashicorp.com/tutorials/terraform/install-cli) and instructions for installing the gcloud CLI can be found [here](https://cloud.google.com/sdk/docs/install).Then, navigate to the root of the `
|
|
19
|
+
Make sure Terraform and the gcloud CLI are installed and in your PATH. Instructions for installing Terraform can be found [here](https://learn.hashicorp.com/tutorials/terraform/install-cli) and instructions for installing the gcloud CLI can be found [here](https://cloud.google.com/sdk/docs/install).Then, navigate to the root of the `sce_linux` module and run the following command:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
22
|
cem_acpt --config ./cem_acpt_config.yaml
|
|
@@ -140,7 +140,7 @@ All Bolt tasks are ran with the `--format json` flag, which returns a JSON docum
|
|
|
140
140
|
|
|
141
141
|
Example:
|
|
142
142
|
|
|
143
|
-
In this example, we will go over how a Bolt task's output would be evaluated by a Bolt test hash. This example assumes one Bolt task named `
|
|
143
|
+
In this example, we will go over how a Bolt task's output would be evaluated by a Bolt test hash. This example assumes one Bolt task named `sce_linux::audit_sssd_certmap` that takes no parameters was ran successfully against two nodes.
|
|
144
144
|
|
|
145
145
|
Bolt task JSON output:
|
|
146
146
|
|
|
@@ -150,7 +150,7 @@ Bolt task JSON output:
|
|
|
150
150
|
{
|
|
151
151
|
"target":"35.212.146.14",
|
|
152
152
|
"action":"task",
|
|
153
|
-
"object":"
|
|
153
|
+
"object":"sce_linux::audit_sssd_certmap",
|
|
154
154
|
"status":"success",
|
|
155
155
|
"value":{
|
|
156
156
|
"sssd_certmap_exists":false
|
|
@@ -159,7 +159,7 @@ Bolt task JSON output:
|
|
|
159
159
|
{
|
|
160
160
|
"target":"35.212.197.53",
|
|
161
161
|
"action":"task",
|
|
162
|
-
"object":"
|
|
162
|
+
"object":"sce_linux::audit_sssd_certmap",
|
|
163
163
|
"status":"success",
|
|
164
164
|
"value":{
|
|
165
165
|
"sssd_certmap_exists":false
|
|
@@ -174,7 +174,7 @@ Bolt task JSON output:
|
|
|
174
174
|
Bolt test hash in `bolt.yaml`:
|
|
175
175
|
|
|
176
176
|
```yaml
|
|
177
|
-
'
|
|
177
|
+
'sce_linux::audit_sssd_certmap':
|
|
178
178
|
status: 'success'
|
|
179
179
|
value:
|
|
180
180
|
match: 'false'
|
|
@@ -335,6 +335,19 @@ images:
|
|
|
335
335
|
|
|
336
336
|
See [sample_config.yaml](sample_config.yaml) for a more complete example.
|
|
337
337
|
|
|
338
|
-
### Testing with
|
|
338
|
+
### Testing with sce_windows
|
|
339
339
|
|
|
340
|
-
While testing with
|
|
340
|
+
While testing with sce_windows follows pretty much the same outline as sce_linux, there are a few extra step that we have to do when bootstrapping the generated node. Two of the most prominents steps are enabling long path and using NSSM to start the goss service. When we enable long path on Windows, it allows the command `puppet module install` to install dependencies correctly (specifically the dsc modules). As for [NSSM](https://nssm.cc/), stands for Non-sucking service manager, it is necessary for us to use this tool because without it, we will not be able to create services for Goss. Windows services cannot run from an executable but rather through a Windows service project that can be build with Visual Studio. NSSM allows us to bypass having to create Windows service project for Goss and create services directly from the Goss executable.
|
|
341
|
+
|
|
342
|
+
#### Configuring the GCS bucket
|
|
343
|
+
|
|
344
|
+
The Windows test path uploads the Puppet module tarball to a GCS bucket so the test instance can `gcloud storage cp` it back down. The bucket name is configurable via `platform.gcp.windows_bucket` (default: `win_cem_acpt`):
|
|
345
|
+
|
|
346
|
+
```yaml
|
|
347
|
+
platform:
|
|
348
|
+
name: gcp
|
|
349
|
+
gcp:
|
|
350
|
+
windows_bucket: my-org-cem-acpt
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Alternatively, pass `--windows-bucket BUCKET` on the CLI or set `CEM_ACPT_PLATFORM__GCP__WINDOWS_BUCKET` in the environment. The bucket must exist and be writable by the account running `cem_acpt`; it must also be readable by the service account attached to the Windows test instance.
|