abide_dev_utils 0.18.5 → 0.18.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ae80024cc846f0a782c4336172a7c5c342ef332f0a3c09f63821e1dd975c3c4
4
- data.tar.gz: 5bfed1ba02c4aa3e09faeca535ced3a04a21e8ba8711e3a17e0b248a98a81e38
3
+ metadata.gz: 6b8b0cc560c6c4d0c1ce9648d10771fe9001708a9b4555884795f3cc7477b53e
4
+ data.tar.gz: a94aaf5a979f3b9c7175f4836071991af2c3b4450c50dd5a74ea06038372dd3b
5
5
  SHA512:
6
- metadata.gz: 310142e8b42dd096631b83604fd7cac7f3a0376abde7ef285f194d8f493998efd27197247416be01d71ce41ec1ab9c4e9200a0b67f76ad5967873d673edda31f
7
- data.tar.gz: bf9d42fbd2c937d70fe72e41417c81afad8d241b20cc48e5309ca5fcb3e709e586087478516a07c884e39ca2fd15f017e108b35d54be04c4556cb9d1e7a20c1b
6
+ metadata.gz: a8638fe3b8be214509f569907592c4ef95e071b1720c6fb31bc15a0cf6490dbbc71c7b43089c8ff0bf42e961bbfa98d9ae6cfccdee40816b5c96f67b699bfdb7
7
+ data.tar.gz: 5b0b7bfa433656a7ee7f95f5443928e2dd8397c3f04fd2a13cd57d3c87ea65be723edf0a850ab3f66e3b73a9d659a939bf9870532fadd4c3e77fe112b629d9ca
data/CLAUDE.md ADDED
@@ -0,0 +1,45 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project overview
6
+
7
+ `abide_dev_utils` is a Ruby gem that ships an `abide` CLI used by the Abide / Puppet SCE (Security Compliance Enforcement) team to develop compliance Puppet modules (CIS, STIG). The CLI converts XCCDF benchmarks into Hiera, generates mappings, builds coverage and reference reports against SCE modules, integrates with Jira, and (legacy) scrapes Puppet Comply.
8
+
9
+ The gem requires Ruby >= 2.7.0; CI runs on 3.2. The gem `puppet` is only installed when `PUPPET_AUTH_TOKEN` is set (it pulls from `rubygems-puppetcore.puppet.com`) — see `Gemfile`.
10
+
11
+ ## Common commands
12
+
13
+ ```sh
14
+ bin/setup # bundle install + initial setup
15
+ bundle exec rake # default: spec + rubocop
16
+ bundle exec rake spec # run all RSpec tests
17
+ bundle exec rspec spec/abide_dev_utils/sce/benchmark_spec.rb # single file
18
+ bundle exec rspec spec/path/to_spec.rb:42 # single example by line
19
+ bundle exec rubocop # lint
20
+ bundle exec rake build # build gem into pkg/
21
+ bundle exec rake install # build + install locally
22
+ bin/console # IRB with the gem preloaded
23
+ bundle exec exe/abide -h # run the CLI from a checkout
24
+ ```
25
+
26
+ ### SCE fixture modules (required for many specs)
27
+
28
+ Several specs and the coverage/reference generators load real Puppet modules from `spec/fixtures/`. Fetch them with:
29
+
30
+ ```sh
31
+ bundle exec rake sce:fixtures # clone all available fixture modules
32
+ bundle exec rake 'sce:fixture[linux]' # clone a single fixture by partial name
33
+ ```
34
+
35
+ The fixtures are cloned over SSH from `git@github.com:puppetlabs/<module>.git` (`puppetlabs-cem_linux`, `puppetlabs-sce_linux`, `puppetlabs-cem_windows`, `puppetlabs-sce_windows`). CI uses `webfactory/ssh-agent` with deploy keys; locally you need SSH access to those repos. Specs that require a fixture will fail if you skipped the clone.
36
+
37
+ `spec_helper.rb` exposes `sce_linux_fixture` / `sce_windows_fixture` helpers that prefer the `sce_*` repo and fall back to the older `cem_*` name.
38
+
39
+ ## Architecture
40
+
41
+ See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for a full breakdown of the file layout and architectural conventions.
42
+
43
+ ## Release flow
44
+
45
+ `bundle exec rake release` builds the gem, tags the version in git, pushes, and pushes to rubygems.org. Bump `lib/abide_dev_utils/version.rb` first.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abide_dev_utils (0.18.5)
4
+ abide_dev_utils (0.18.6)
5
5
  cmdparse (~> 3.0)
6
6
  facterdb (~> 4.1.0)
7
7
  google-cloud-storage (~> 1.34)
@@ -0,0 +1,264 @@
1
+ # Architecture
2
+
3
+ This document describes the file/directory layout of `abide_dev_utils` so contributors and AI assistants can find the right place to make a change. For build/test commands, see `CLAUDE.md` and `README.md`.
4
+
5
+ `abide_dev_utils` is a developer helper for the **`puppetlabs-sce_linux`** and **`puppetlabs-sce_windows`** Puppet SCE modules. Most of the design choices in this repo (the `sce/` subsystem, the fixture-cloning rake task, the local fact sets in `files/`) exist to support those two modules, so when something in the architecture seems oddly specific, it's almost always because one of those modules needed it.
6
+
7
+ ## Top-level layout
8
+
9
+ ```
10
+ abide_dev_utils/
11
+ ├── exe/ ← gem-installed CLI binary
12
+ ├── bin/ ← in-repo dev binaries + setup script
13
+ ├── lib/ ← all library + CLI code (see lib/ section below)
14
+ ├── spec/ ← RSpec tests, mirroring lib/ layout
15
+ ├── files/ ← static resources shipped with the gem
16
+ ├── docs/ ← contributor-facing docs (this file lives here)
17
+ ├── pkg/ ← rake build output (.gem files); not committed source
18
+ ├── Gemfile / .gemspec ← dependency + gem metadata
19
+ ├── Rakefile ← spec/rubocop/build tasks + sce:fixtures clone task
20
+ ├── new_diff.rb ← ad-hoc one-off script (not wired into the CLI)
21
+ └── README.md / CHANGELOG.md / LICENSE.txt / CODEOWNERS
22
+ ```
23
+
24
+ The unusual ones:
25
+
26
+ - **`exe/abide`** is the Bundler-recommended location for installed binaries; `spec.executables = ['abide']` in the gemspec wires it up.
27
+ - **`bin/abide.rb`** is a duplicate entry point used during development so you can `ruby bin/abide.rb ...` without installing the gem. `bin/console` is an IRB session with the gem preloaded; `bin/setup` is the `bundle install` bootstrap.
28
+ - **`new_diff.rb`** is a developer scratch script that exercises the XCCDF diff code; it's not part of the public CLI surface.
29
+ - **`pkg/`** is rake build output. Don't edit anything in there.
30
+ - **`files/fact_sets/`** holds locally-stored fact sets used as a FacterDB fallback. `abide sce generate reference` (the `REFERENCE.md` generator) relies on the `facterdb` gem to look up facts for every OS that `sce_linux` / `sce_windows` declare in their `metadata.json`. When one of those modules adds support for a brand-new OS release, FacterDB doesn't always have a matching fact set yet — in that case we drop a `<os>-<version>-<arch>.facts` file (e.g. `windows-2025-x86_64.facts`) into `files/fact_sets/` and `ppt/facter_utils.rb` loads it instead. Once FacterDB ships the fact set upstream, the file here can be removed.
31
+
32
+ ## `lib/abide_dev_utils/` — library + CLI
33
+
34
+ The whole gem lives under one namespace. `lib/abide_dev_utils.rb` is the require-everything entry point; the rest of the structure pairs each top-level CLI namespace with a sibling library directory.
35
+
36
+ ```
37
+ lib/abide_dev_utils.rb ← top-level require: pulls in every domain
38
+ lib/abide_dev_utils/
39
+ ├── cli.rb ← cmdparse setup; registers the 6 top-level commands
40
+ ├── cli/ ← one file per top-level CLI namespace
41
+
42
+ ├── sce.rb sce/ ← `abide sce ...` library
43
+ ├── xccdf.rb xccdf/ ← `abide xccdf ...` library
44
+ ├── ppt.rb ppt/ ← `abide puppet ...` library + shared Puppet helpers
45
+ ├── jira.rb jira/ ← `abide jira ...` library
46
+ ├── comply.rb ← `abide comply ...` library (deprecated, no subdir)
47
+
48
+ ├── config.rb ← reads ~/.abide_dev.yaml
49
+ ├── files.rb ← Reader/Writer dispatching on extension
50
+ ├── output.rb ← simple/text/json/yaml/progress writers
51
+ ├── validate.rb ← file/directory/hashable/puppet_module_directory checks
52
+ ├── prompt.rb ← interactive y/n prompt used by jira flows
53
+ ├── markdown.rb ← tiny Markdown builder used by sce reference generator
54
+ ├── gcloud.rb ← google-cloud-storage wrapper (loaded but unused by CLI)
55
+ ├── puppet_strings.rb ← shared puppet-strings helpers
56
+ ├── mixins.rb ← misc reusable mixins
57
+ ├── dot_number_comparable.rb ← <=> for dotted CIS ids ("1.2.10" > "1.2.2")
58
+ ├── constants.rb ← CliConstants
59
+ ├── version.rb ← VERSION string (bump before `rake release`)
60
+
61
+ ├── errors.rb errors/ ← typed exception classes, namespaced per domain
62
+ └── resources/ ← ERB templates shipped with the gem (e.g. generic_spec.erb)
63
+ ```
64
+
65
+ ### `cli/` — CLI command classes
66
+
67
+ One file per top-level `abide <namespace>` command. Each file defines a `*Command` class plus its subcommands.
68
+
69
+ ```
70
+ cli/
71
+ ├── abstract.rb ← AbideCommand base class (handles [DEPRECATED] tagging, mixes in Config)
72
+ ├── sce.rb ← `abide sce {generate,update-config,validate} ...`
73
+ ├── xccdf.rb ← `abide xccdf {to_hiera,diff,gen-map}`
74
+ ├── puppet.rb ← `abide puppet {coverage,new,...}`
75
+ ├── jira.rb ← `abide jira {auth,from_coverage,from_xccdf,new_issue,get_issue}`
76
+ ├── comply.rb ← `abide comply report` (DEPRECATED)
77
+ └── test.rb ← `abide test` (DEPRECATED, currently broken)
78
+ ```
79
+
80
+ All command classes inherit from `Abide::CLI::AbideCommand` (defined in `cli/abstract.rb`), which wraps `CmdParse::Command`, mixes in `AbideDevUtils::Config`, and prefixes short/long descriptions with `[DEPRECATED]` when `deprecated: true` is passed. Don't subclass `CmdParse::Command` directly when adding new commands.
81
+
82
+ ### `sce/` — Security Compliance Enforcement domain
83
+
84
+ The largest subsystem. Operates on Puppet SCE modules on disk (`puppetlabs-sce_linux`, `puppetlabs-sce_windows`, etc.) and produces coverage reports, reference docs, and validation output.
85
+
86
+ ```
87
+ sce.rb ← top-level entry; defines update_legacy_config_from_diff
88
+ sce/
89
+ ├── benchmark_loader.rb ← walks a Puppet module's supported_os × frameworks
90
+ │ and constructs Benchmark objects (errors are
91
+ │ collected, not raised)
92
+ ├── benchmark.rb ← Benchmark / Resource / Control domain model
93
+ │ (Control mixes in DotNumberComparable)
94
+
95
+ ├── generate.rb generate/ ← `abide sce generate ...`
96
+ │ ├── coverage_report.rb ← coverage-report subcommand
97
+ │ └── reference.rb ← reference (REFERENCE.md) subcommand
98
+
99
+ ├── validate.rb validate/ ← `abide sce validate ...`
100
+ │ ├── resource_data.rb ← validates data/resource_data/*.yaml
101
+ │ ├── strings.rb ← runs puppet-strings over the module
102
+ │ └── strings/ ← per-Puppet-type validators
103
+ │ ├── base_validator.rb
104
+ │ ├── puppet_class_validator.rb
105
+ │ ├── puppet_defined_type_validator.rb
106
+ │ └── validation_finding.rb
107
+
108
+ ├── mapping/ ← id ↔ id mapping (control numbers, hiera titles, ...)
109
+ │ └── mapper.rb ← Mapper, MapData, ALL_TYPES / FRAMEWORK_TYPES enums
110
+
111
+ └── hiera_data.rb hiera_data/ ← parsing the SCE module's data/ directory
112
+ ├── mapping_data.rb ← entry point for data/mapping/*.yaml
113
+ ├── mapping_data/
114
+ │ ├── map_data.rb ← parses one mapping YAML file
115
+ │ └── mixins.rb ← MixinCIS / MixinSTIG (per-framework lookup logic)
116
+ └── resource_data/ ← (placeholder; reserved for resource_data parsers)
117
+ ```
118
+
119
+ `sce.rb` plus everything in `sce/` is what powers the `abide sce` CLI. The pattern of *"top-level `.rb` requires the subdirectory"* is consistent across the codebase — `sce/generate.rb` requires `sce/generate/*.rb`, and so on.
120
+
121
+ ### `xccdf/` — XCCDF parsing and conversion
122
+
123
+ ```
124
+ xccdf.rb ← entry points (gen_map, to_hiera, diff) +
125
+ │ XCCDF::Common (CIS/STIG regex constants) +
126
+ │ XCCDF::Benchmark
127
+ xccdf/
128
+ ├── parser.rb parser/ ← Nokogiri-based parser
129
+ │ ├── helpers.rb
130
+ │ └── objects.rb objects/
131
+ │ ├── numbered_object.rb ← controls/profiles with dotted numbers
132
+ │ └── diffable_object.rb ← objects participating in benchmark diffing
133
+
134
+ ├── diff.rb ← BenchmarkDiff (used by `abide xccdf diff` and the
135
+ │ currently-disabled `sce update-config from-diff`)
136
+ └── utils.rb ← shared XCCDF helpers
137
+ ```
138
+
139
+ `XCCDF::Common` (in `xccdf.rb`) is the **single source of truth** for CIS vs STIG conventions: control-id regexes, profile-level codes, the `normalize_string` / `normalize_control_name` / `normalize_profile_name` helpers that the README documents. Touching the constants in `Common` affects mapping generation, Hiera key naming, and diffing simultaneously.
140
+
141
+ ### `ppt/` — Puppet-module utilities
142
+
143
+ Used both by the `sce/` subsystem (to read manifests off disk) and directly by the `abide puppet ...` commands.
144
+
145
+ ```
146
+ ppt.rb ← top-level helpers: rename_puppet_class, build_new_object,
147
+ │ audit/fix_class_names, add_cis_comment, score_module
148
+ ppt/
149
+ ├── puppet_module.rb ← PuppetModule class: reads metadata.json, hiera.yaml;
150
+ │ exposes supported_os used by BenchmarkLoader
151
+ ├── class_utils.rb ← Puppet class name ↔ on-disk path conversions
152
+ ├── code_introspection.rb ← parses Puppet manifests (used by Resource.manifest)
153
+ ├── hiera.rb ← Hiera::Config wrapper for a module's hiera.yaml
154
+ ├── facter_utils.rb ← FacterDB integration; can also load files/fact_sets/*.facts
155
+ ├── strings.rb ← puppet-strings helpers
156
+ ├── api.rb ← misc Puppet API glue
157
+ ├── new_obj.rb ← `abide puppet new` ERB-based generator
158
+ │ (honours c-/d- filename prefixes for spec dir routing)
159
+ ├── score_module.rb ← stub; Ppt.score_module currently prints "not implemented"
160
+
161
+ └── code_gen.rb code_gen/ ← AST-style wrappers for code generation
162
+ ├── generate.rb
163
+ ├── data_types.rb
164
+ ├── resource.rb
165
+ ├── resource_types.rb
166
+ └── resource_types/
167
+ ├── base.rb
168
+ ├── class.rb
169
+ ├── manifest.rb
170
+ ├── parameter.rb
171
+ └── strings.rb
172
+ ```
173
+
174
+ ### `jira/` — Jira integration
175
+
176
+ ```
177
+ jira.rb ← top-level flows: new_issues_from_coverage,
178
+ │ new_issues_from_xccdf, summary helpers.
179
+ │ Defines summary prefixes (COV_PARENT_SUMMARY_PREFIX,
180
+ │ COV_CHILD_SUMMARY_PREFIX, UPD_EPIC_SUMMARY_PREFIX)
181
+ │ used to recognise issues this tool created.
182
+ jira/
183
+ ├── client.rb ← jira-ruby client wrapper
184
+ ├── client_builder.rb ← builds a client from ~/.abide_dev.yaml's jira section
185
+ ├── dry_run.rb ← drop-in replacement returned when --dry-run is set
186
+ ├── finder.rb ← search existing issues
187
+ ├── issue_builder.rb ← payload construction for create/update
188
+ └── helper.rb ← project-level convenience (all_project_issues_attrs, etc.)
189
+ ```
190
+
191
+ ### `errors/` — typed exceptions
192
+
193
+ ```
194
+ errors.rb ← requires the per-domain files
195
+ errors/
196
+ ├── base.rb ← AbideDevUtils::Errors::* base class
197
+ ├── general.rb ← cross-cutting errors (FileNotFoundError, etc.)
198
+ ├── sce.rb ← BenchmarkLoadError (carries osname, major_version,
199
+ │ framework, module_name, original_error fields that
200
+ │ cli/sce.rb pretty-prints via respond_to?)
201
+ ├── xccdf.rb ← UnsupportedXCCDFError, ProfilePartsError, ControlPartsError
202
+ ├── ppt.rb ← Puppet-module errors (ClassFileNotFoundError, ...)
203
+ ├── jira.rb ← Jira-specific errors
204
+ ├── comply.rb ← Comply scraper errors (deprecated)
205
+ └── gcloud.rb ← GCS errors
206
+ ```
207
+
208
+ When introducing a new "soft" error that the CLI should pretty-print rather than raise, follow the `BenchmarkLoadError` pattern: subclass the matching domain error and expose extra metadata as accessors. The CLI uses `respond_to?` to decide which fields to render.
209
+
210
+ ### `comply.rb` — deprecated Selenium scraper
211
+
212
+ A single file (no `comply/` subdirectory) that drives `selenium-webdriver` against the Puppet Comply UI. It's deprecated and still loaded mostly so the deprecation message stays visible. Don't extend it.
213
+
214
+ ## `spec/` — tests
215
+
216
+ The spec layout mirrors `lib/abide_dev_utils/`:
217
+
218
+ ```
219
+ spec/
220
+ ├── spec_helper.rb ← requires every file under lib/ (catches load-order
221
+ │ regressions); exposes TestResources / OutputHelpers
222
+ ├── abide_dev_utils_spec.rb ← top-level smoke tests
223
+ ├── abide_dev_utils/ ← mirrors lib/abide_dev_utils/ one-to-one
224
+ │ ├── cli_spec.rb
225
+ │ ├── xccdf_spec.rb
226
+ │ ├── xccdf/
227
+ │ │ ├── parser_spec.rb
228
+ │ │ ├── parser/objects_spec.rb
229
+ │ │ └── diff/benchmark_spec.rb
230
+ │ ├── sce/benchmark_spec.rb
231
+ │ └── ppt/
232
+ │ ├── facter_utils_spec.rb
233
+ │ └── new_obj_spec.rb
234
+
235
+ ├── resources/ ← committed test inputs (work without network)
236
+ │ ├── cis/ ← real CIS XCCDF files for parser tests
237
+ │ │ ├── CIS_CentOS_Linux_7_Benchmark_v3.0.0-xccdf.xml
238
+ │ │ └── CIS_Microsoft_Windows_Server_2016_..._v1.2.0-xccdf.xml
239
+ │ └── test_files/ ← small synthetic XCCDFs for diff/version tests
240
+ │ ├── Test_XCCDF-v1.0.0-xccdf.xml
241
+ │ └── Test_XCCDF-v1.1.0-xccdf.xml
242
+
243
+ └── fixtures/ ← real Puppet SCE modules cloned at test time by
244
+ `rake sce:fixtures`. Not committed; required by
245
+ any spec that exercises BenchmarkLoader.
246
+ ├── puppetlabs-sce_linux/ ← clone of git@github.com:puppetlabs/puppetlabs-sce_linux
247
+ └── puppetlabs-sce_windows/ ← clone of git@github.com:puppetlabs/puppetlabs-sce_windows
248
+ ```
249
+
250
+ `spec_helper.rb` exposes helpers via mixins: `sce_linux_fixture` / `sce_windows_fixture` (prefer the `sce_*` clone, fall back to `cem_*`), `test_xccdf_files`, `capture_stdout`, `capture_stderr`. RSpec is configured with `disable_monkey_patching!`, `verify_partial_doubles = true`, and `fail_fast = false` — keep partial doubles realistic.
251
+
252
+ ## How a request flows through the codebase
253
+
254
+ Tracing `abide sce generate coverage-report` end-to-end is a good way to internalise the layout:
255
+
256
+ 1. **`exe/abide`** loads `lib/abide_dev_utils/cli.rb` and calls `Abide::CLI.execute`.
257
+ 2. **`cli.rb`** registers `SceCommand` (from `cli/sce.rb`) on the cmdparse parser.
258
+ 3. **`cli/sce.rb`** routes `generate coverage-report` to `SceGenerateCoverageReport#execute`, which collects flags into `@data` and calls `AbideDevUtils::Sce::Generate::CoverageReport.generate(...)`.
259
+ 4. **`sce/generate/coverage_report.rb`** asks `BenchmarkLoader::PupMod` (in `sce/benchmark_loader.rb`) to load benchmarks from the current directory.
260
+ 5. **`benchmark_loader.rb`** instantiates a `Ppt::PuppetModule` (from `ppt/puppet_module.rb`), reads `metadata.json` for `supported_os`, and constructs one `Sce::Benchmark` per (OS, version, framework) cell.
261
+ 6. Each **`Sce::Benchmark`** (in `sce/benchmark.rb`) builds a `Mapping::Mapper` (from `sce/mapping/mapper.rb`) over the module's `data/mapping/*.yaml` files, and a list of `Resource` objects whose manifests are parsed by `Ppt::CodeIntrospection::Manifest` (from `ppt/code_introspection.rb`).
262
+ 7. The coverage report is serialised through **`output.rb`** as YAML/JSON/text, optionally written to a file via **`files.rb`**'s `Writer`.
263
+
264
+ Every other command follows the same shape: `cli/<name>.rb` parses options → top-level domain module orchestrates → domain classes do the work → `Output` writes the result.
@@ -0,0 +1,606 @@
1
+ {
2
+ "aio_agent_version": "8.23.1",
3
+ "augeas": {
4
+ "version": "1.14.1"
5
+ },
6
+ "disks": {
7
+ "sda": {
8
+ "model": "VBOX HARDDISK",
9
+ "serial": "VB693833ed-482419db",
10
+ "size": "10.00 GiB",
11
+ "size_bytes": 10737418240,
12
+ "type": "hdd",
13
+ "vendor": "ATA"
14
+ }
15
+ },
16
+ "dmi": {
17
+ "bios": {
18
+ "release_date": "12/01/2006",
19
+ "vendor": "innotek GmbH",
20
+ "version": "VirtualBox"
21
+ },
22
+ "board": {
23
+ "manufacturer": "Oracle Corporation",
24
+ "product": "VirtualBox",
25
+ "serial_number": "0"
26
+ },
27
+ "chassis": {
28
+ "type": "Other"
29
+ },
30
+ "manufacturer": "innotek GmbH",
31
+ "product": {
32
+ "name": "VirtualBox",
33
+ "serial_number": "VirtualBox-b9cf1f28-4fba-4577-95b3-97983aacb94e",
34
+ "uuid": "281fcfb9-ba4f-7745-95b3-97983aacb94e",
35
+ "version": "1.2"
36
+ }
37
+ },
38
+ "facterversion": "5.1.0",
39
+ "filesystems": "vfat,xfs",
40
+ "fips_enabled": false,
41
+ "hypervisors": {
42
+ "virtualbox": {
43
+ "revision": "169651",
44
+ "version": "7.1.12"
45
+ }
46
+ },
47
+ "identity": {
48
+ "gid": 0,
49
+ "group": "root",
50
+ "privileged": true,
51
+ "uid": 0,
52
+ "user": "root"
53
+ },
54
+ "is_virtual": true,
55
+ "kernel": "Linux",
56
+ "kernelmajversion": "6.12",
57
+ "kernelrelease": "6.12.0-55.29.1.el10_0.x86_64",
58
+ "kernelversion": "6.12.0",
59
+ "load_averages": {
60
+ "15m": 0.04,
61
+ "1m": 0.43,
62
+ "5m": 0.11
63
+ },
64
+ "memory": {
65
+ "system": {
66
+ "available": "553.72 MiB",
67
+ "available_bytes": 580620288,
68
+ "capacity": "42.02%",
69
+ "total": "955.06 MiB",
70
+ "total_bytes": 1001451520,
71
+ "used": "401.34 MiB",
72
+ "used_bytes": 420831232
73
+ }
74
+ },
75
+ "mountpoints": {
76
+ "/": {
77
+ "available": "4.62 GiB",
78
+ "available_bytes": 4962111488,
79
+ "capacity": "44.88%",
80
+ "device": "/dev/sda4",
81
+ "filesystem": "xfs",
82
+ "options": [
83
+ "rw",
84
+ "seclabel",
85
+ "relatime",
86
+ "attr2",
87
+ "inode64",
88
+ "logbufs=8",
89
+ "logbsize=32k",
90
+ "noquota"
91
+ ],
92
+ "size": "8.38 GiB",
93
+ "size_bytes": 9003180032,
94
+ "used": "3.76 GiB",
95
+ "used_bytes": 4041068544
96
+ },
97
+ "/boot": {
98
+ "available": "743.04 MiB",
99
+ "available_bytes": 779128832,
100
+ "capacity": "20.62%",
101
+ "device": "/dev/sda3",
102
+ "filesystem": "xfs",
103
+ "options": [
104
+ "rw",
105
+ "seclabel",
106
+ "relatime",
107
+ "attr2",
108
+ "inode64",
109
+ "logbufs=8",
110
+ "logbsize=32k",
111
+ "noquota"
112
+ ],
113
+ "size": "936.00 MiB",
114
+ "size_bytes": 981467136,
115
+ "used": "192.96 MiB",
116
+ "used_bytes": 202338304
117
+ },
118
+ "/boot/efi": {
119
+ "available": "186.83 MiB",
120
+ "available_bytes": 195907584,
121
+ "capacity": "6.47%",
122
+ "device": "/dev/sda2",
123
+ "filesystem": "vfat",
124
+ "options": [
125
+ "rw",
126
+ "relatime",
127
+ "fmask=0077",
128
+ "dmask=0077",
129
+ "codepage=437",
130
+ "iocharset=ascii",
131
+ "shortname=winnt",
132
+ "errors=remount-ro"
133
+ ],
134
+ "size": "199.77 MiB",
135
+ "size_bytes": 209469440,
136
+ "used": "12.93 MiB",
137
+ "used_bytes": 13561856
138
+ },
139
+ "/dev": {
140
+ "available": "4.00 MiB",
141
+ "available_bytes": 4194304,
142
+ "capacity": "0%",
143
+ "device": "devtmpfs",
144
+ "filesystem": "devtmpfs",
145
+ "options": [
146
+ "rw",
147
+ "seclabel",
148
+ "nosuid",
149
+ "size=4096k",
150
+ "nr_inodes=117901",
151
+ "mode=755",
152
+ "inode64"
153
+ ],
154
+ "size": "4.00 MiB",
155
+ "size_bytes": 4194304,
156
+ "used": "0 bytes",
157
+ "used_bytes": 0
158
+ },
159
+ "/dev/hugepages": {
160
+ "available": "0 bytes",
161
+ "available_bytes": 0,
162
+ "capacity": "100%",
163
+ "device": "hugetlbfs",
164
+ "filesystem": "hugetlbfs",
165
+ "options": [
166
+ "rw",
167
+ "seclabel",
168
+ "nosuid",
169
+ "nodev",
170
+ "relatime",
171
+ "pagesize=2M"
172
+ ],
173
+ "size": "0 bytes",
174
+ "size_bytes": 0,
175
+ "used": "0 bytes",
176
+ "used_bytes": 0
177
+ },
178
+ "/dev/mqueue": {
179
+ "available": "0 bytes",
180
+ "available_bytes": 0,
181
+ "capacity": "100%",
182
+ "device": "mqueue",
183
+ "filesystem": "mqueue",
184
+ "options": [
185
+ "rw",
186
+ "seclabel",
187
+ "nosuid",
188
+ "nodev",
189
+ "noexec",
190
+ "relatime"
191
+ ],
192
+ "size": "0 bytes",
193
+ "size_bytes": 0,
194
+ "used": "0 bytes",
195
+ "used_bytes": 0
196
+ },
197
+ "/dev/pts": {
198
+ "available": "0 bytes",
199
+ "available_bytes": 0,
200
+ "capacity": "100%",
201
+ "device": "devpts",
202
+ "filesystem": "devpts",
203
+ "options": [
204
+ "rw",
205
+ "seclabel",
206
+ "nosuid",
207
+ "noexec",
208
+ "relatime",
209
+ "gid=5",
210
+ "mode=620",
211
+ "ptmxmode=000"
212
+ ],
213
+ "size": "0 bytes",
214
+ "size_bytes": 0,
215
+ "used": "0 bytes",
216
+ "used_bytes": 0
217
+ },
218
+ "/dev/shm": {
219
+ "available": "477.53 MiB",
220
+ "available_bytes": 500723712,
221
+ "capacity": "0%",
222
+ "device": "tmpfs",
223
+ "filesystem": "tmpfs",
224
+ "options": [
225
+ "rw",
226
+ "seclabel",
227
+ "nosuid",
228
+ "nodev",
229
+ "inode64"
230
+ ],
231
+ "size": "477.53 MiB",
232
+ "size_bytes": 500723712,
233
+ "used": "0 bytes",
234
+ "used_bytes": 0
235
+ },
236
+ "/run": {
237
+ "available": "187.44 MiB",
238
+ "available_bytes": 196546560,
239
+ "capacity": "1.87%",
240
+ "device": "tmpfs",
241
+ "filesystem": "tmpfs",
242
+ "options": [
243
+ "rw",
244
+ "seclabel",
245
+ "nosuid",
246
+ "nodev",
247
+ "size=195596k",
248
+ "nr_inodes=819200",
249
+ "mode=755",
250
+ "inode64"
251
+ ],
252
+ "size": "191.01 MiB",
253
+ "size_bytes": 200290304,
254
+ "used": "3.57 MiB",
255
+ "used_bytes": 3743744
256
+ },
257
+ "/run/credentials/getty@tty1.service": {
258
+ "available": "1.00 MiB",
259
+ "available_bytes": 1048576,
260
+ "capacity": "0%",
261
+ "device": "tmpfs",
262
+ "filesystem": "tmpfs",
263
+ "options": [
264
+ "ro",
265
+ "seclabel",
266
+ "nosuid",
267
+ "nodev",
268
+ "noexec",
269
+ "relatime",
270
+ "nosymfollow",
271
+ "size=1024k",
272
+ "nr_inodes=1024",
273
+ "mode=700",
274
+ "inode64",
275
+ "noswap"
276
+ ],
277
+ "size": "1.00 MiB",
278
+ "size_bytes": 1048576,
279
+ "used": "0 bytes",
280
+ "used_bytes": 0
281
+ },
282
+ "/run/credentials/serial-getty@ttyS0.service": {
283
+ "available": "1.00 MiB",
284
+ "available_bytes": 1048576,
285
+ "capacity": "0%",
286
+ "device": "tmpfs",
287
+ "filesystem": "tmpfs",
288
+ "options": [
289
+ "ro",
290
+ "seclabel",
291
+ "nosuid",
292
+ "nodev",
293
+ "noexec",
294
+ "relatime",
295
+ "nosymfollow",
296
+ "size=1024k",
297
+ "nr_inodes=1024",
298
+ "mode=700",
299
+ "inode64",
300
+ "noswap"
301
+ ],
302
+ "size": "1.00 MiB",
303
+ "size_bytes": 1048576,
304
+ "used": "0 bytes",
305
+ "used_bytes": 0
306
+ },
307
+ "/run/credentials/systemd-journald.service": {
308
+ "available": "1.00 MiB",
309
+ "available_bytes": 1048576,
310
+ "capacity": "0%",
311
+ "device": "tmpfs",
312
+ "filesystem": "tmpfs",
313
+ "options": [
314
+ "ro",
315
+ "seclabel",
316
+ "nosuid",
317
+ "nodev",
318
+ "noexec",
319
+ "relatime",
320
+ "nosymfollow",
321
+ "size=1024k",
322
+ "nr_inodes=1024",
323
+ "mode=700",
324
+ "inode64",
325
+ "noswap"
326
+ ],
327
+ "size": "1.00 MiB",
328
+ "size_bytes": 1048576,
329
+ "used": "0 bytes",
330
+ "used_bytes": 0
331
+ },
332
+ "/run/user/1000": {
333
+ "available": "95.50 MiB",
334
+ "available_bytes": 100134912,
335
+ "capacity": "0.01%",
336
+ "device": "tmpfs",
337
+ "filesystem": "tmpfs",
338
+ "options": [
339
+ "rw",
340
+ "seclabel",
341
+ "nosuid",
342
+ "nodev",
343
+ "relatime",
344
+ "size=97796k",
345
+ "nr_inodes=24449",
346
+ "mode=700",
347
+ "uid=1000",
348
+ "gid=1000",
349
+ "inode64"
350
+ ],
351
+ "size": "95.50 MiB",
352
+ "size_bytes": 100143104,
353
+ "used": "8.00 KiB",
354
+ "used_bytes": 8192
355
+ },
356
+ "/vagrant": {
357
+ "available": "318.33 GiB",
358
+ "available_bytes": 341807607808,
359
+ "capacity": "65.00%",
360
+ "device": "vagrant",
361
+ "filesystem": "vboxsf",
362
+ "options": [
363
+ "rw",
364
+ "nodev",
365
+ "relatime",
366
+ "iocharset=utf8",
367
+ "uid=1000",
368
+ "gid=1000"
369
+ ],
370
+ "size": "909.41 GiB",
371
+ "size_bytes": 976476184576,
372
+ "used": "591.08 GiB",
373
+ "used_bytes": 634668576768
374
+ },
375
+ "/var/lib/nfs/rpc_pipefs": {
376
+ "available": "0 bytes",
377
+ "available_bytes": 0,
378
+ "capacity": "100%",
379
+ "device": "sunrpc",
380
+ "filesystem": "rpc_pipefs",
381
+ "options": [
382
+ "rw",
383
+ "relatime"
384
+ ],
385
+ "size": "0 bytes",
386
+ "size_bytes": 0,
387
+ "used": "0 bytes",
388
+ "used_bytes": 0
389
+ }
390
+ },
391
+ "networking": {
392
+ "domain": "example.com",
393
+ "fqdn": "foo.example.com",
394
+ "hostname": "foo",
395
+ "interfaces": {
396
+ "enp0s3": {
397
+ "bindings": [
398
+ {
399
+ "address": "10.0.2.15",
400
+ "netmask": "255.255.255.0",
401
+ "network": "10.0.2.0"
402
+ }
403
+ ],
404
+ "bindings6": [
405
+ {
406
+ "address": "fd17:625c:f037:2:68ae:6fd4:3d05:c6f0",
407
+ "netmask": "ffff:ffff:ffff:ffff::",
408
+ "network": "fd17:625c:f037:2::",
409
+ "scope6": "global",
410
+ "flags": [
411
+
412
+ ]
413
+ },
414
+ {
415
+ "address": "fe80::34f1:2a32:96df:f711",
416
+ "netmask": "ffff:ffff:ffff:ffff::",
417
+ "network": "fe80::",
418
+ "scope6": "link",
419
+ "flags": [
420
+ "permanent"
421
+ ]
422
+ }
423
+ ],
424
+ "duplex": "full",
425
+ "ip": "10.0.2.15",
426
+ "ip6": "fd17:625c:f037:2:68ae:6fd4:3d05:c6f0",
427
+ "mac": "00:16:3e:55:3b:5a",
428
+ "mtu": 1500,
429
+ "netmask": "255.255.255.0",
430
+ "netmask6": "ffff:ffff:ffff:ffff::",
431
+ "network": "10.0.2.0",
432
+ "network6": "fd17:625c:f037:2::",
433
+ "operational_state": "up",
434
+ "physical": true,
435
+ "scope6": "global",
436
+ "speed": 1000
437
+ },
438
+ "lo": {
439
+ "bindings": [
440
+ {
441
+ "address": "127.0.0.1",
442
+ "netmask": "255.0.0.0",
443
+ "network": "127.0.0.0"
444
+ }
445
+ ],
446
+ "bindings6": [
447
+ {
448
+ "address": "::1",
449
+ "netmask": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
450
+ "network": "::1",
451
+ "scope6": "host",
452
+ "flags": [
453
+ "permanent"
454
+ ]
455
+ }
456
+ ],
457
+ "ip": "127.0.0.1",
458
+ "ip6": "::1",
459
+ "mtu": 65536,
460
+ "netmask": "255.0.0.0",
461
+ "netmask6": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
462
+ "network": "127.0.0.0",
463
+ "network6": "::1",
464
+ "operational_state": "unknown",
465
+ "physical": false,
466
+ "scope6": "host"
467
+ }
468
+ },
469
+ "ip": "10.0.2.15",
470
+ "ip6": "fd17:625c:f037:2:68ae:6fd4:3d05:c6f0",
471
+ "mac": "00:16:3e:55:3b:5a",
472
+ "mtu": 1500,
473
+ "netmask": "255.255.255.0",
474
+ "netmask6": "ffff:ffff:ffff:ffff::",
475
+ "network": "10.0.2.0",
476
+ "network6": "fd17:625c:f037:2::",
477
+ "primary": "enp0s3",
478
+ "scope6": "global"
479
+ },
480
+ "os": {
481
+ "architecture": "x86_64",
482
+ "distro": {
483
+ "codename": "Coughlan",
484
+ "description": "Red Hat Enterprise Linux release 10.0 (Coughlan)",
485
+ "id": "RedHatEnterprise",
486
+ "release": {
487
+ "full": "10.0",
488
+ "major": "10",
489
+ "minor": "0"
490
+ }
491
+ },
492
+ "family": "RedHat",
493
+ "hardware": "x86_64",
494
+ "name": "RedHat",
495
+ "release": {
496
+ "full": "10.0",
497
+ "major": "10",
498
+ "minor": "0"
499
+ },
500
+ "selinux": {
501
+ "config_mode": "enforcing",
502
+ "config_policy": "targeted",
503
+ "current_mode": "enforcing",
504
+ "enabled": true,
505
+ "enforced": true,
506
+ "policy_version": "33"
507
+ }
508
+ },
509
+ "partitions": {
510
+ "/dev/sda1": {
511
+ "partlabel": "p.legacy",
512
+ "parttype": "21686148-6449-6e6f-744e-656564454649",
513
+ "partuuid": "6daa36a1-8e8e-4d75-949d-f0eb8de6bf26",
514
+ "size": "2.00 MiB",
515
+ "size_bytes": 2097152
516
+ },
517
+ "/dev/sda2": {
518
+ "filesystem": "vfat",
519
+ "label": "EFI",
520
+ "mount": "/boot/efi",
521
+ "partlabel": "p.UEFI",
522
+ "parttype": "c12a7328-f81f-11d2-ba4b-00a0c93ec93b",
523
+ "partuuid": "e8295f80-98ea-49d6-9777-a68d641dbeff",
524
+ "size": "200.00 MiB",
525
+ "size_bytes": 209715200,
526
+ "uuid": "2748-9ED0"
527
+ },
528
+ "/dev/sda3": {
529
+ "filesystem": "xfs",
530
+ "label": "BOOT",
531
+ "mount": "/boot",
532
+ "partlabel": "p.lxboot",
533
+ "parttype": "bc13c2ff-59e6-4262-a352-b275fd6f7172",
534
+ "partuuid": "bb59c910-6af4-4d1f-9411-1ef9cb28a84e",
535
+ "size": "1000.00 MiB",
536
+ "size_bytes": 1048576000,
537
+ "uuid": "2bc41119-4269-48e3-9bd2-16691e849bf9"
538
+ },
539
+ "/dev/sda4": {
540
+ "filesystem": "xfs",
541
+ "label": "rhel",
542
+ "mount": "/",
543
+ "partlabel": "p.lxroot",
544
+ "parttype": "4f68bce3-e8cd-4db1-96e7-fbcaf984b709",
545
+ "partuuid": "0e5893ab-d171-4b09-80d2-fe6c3cb4e0d2",
546
+ "size": "8.83 GiB",
547
+ "size_bytes": 9475964416,
548
+ "uuid": "466e59b7-363a-4ff4-bfbb-24b064cd1e7b"
549
+ }
550
+ },
551
+ "path": "/opt/puppetlabs/bin:/root/.local/bin:/root/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin",
552
+ "processors": {
553
+ "cores": 1,
554
+ "count": 1,
555
+ "extensions": [
556
+ "unknown"
557
+ ],
558
+ "isa": "unknown",
559
+ "models": [
560
+ "AMD Ryzen 9 7940HS w/ Radeon 780M Graphics"
561
+ ],
562
+ "physicalcount": 1,
563
+ "speed": "3.99 GHz",
564
+ "threads": 1
565
+ },
566
+ "puppetversion": "8.23.1",
567
+ "ruby": {
568
+ "platform": "x86_64-linux",
569
+ "sitedir": "/opt/puppetlabs/puppet/lib/ruby/site_ruby/3.2.0",
570
+ "version": "3.2.9"
571
+ },
572
+ "ssh": {
573
+ "ecdsa": {
574
+ "fingerprints": {
575
+ "sha1": "SSHFP 3 1 d876cad40cad612e5110ee5e09f0cfa45dca6dee",
576
+ "sha256": "SSHFP 3 2 a139a8e35be9e248595764658aeb000e6761f75942f72664f944ce4456dd1ab3"
577
+ },
578
+ "key": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBG7KnRbJzAjTi2yJmIs8x0Lt+7/F4gi1RcsbkVDHoG5sb7jgT/NhATgv6HRgBhEd7kl9QUkMZ3u4KRuNwJJLx4Q=",
579
+ "type": "ecdsa-sha2-nistp256"
580
+ },
581
+ "ed25519": {
582
+ "fingerprints": {
583
+ "sha1": "SSHFP 4 1 f4b0b6869f7aaa161aa3d7980db2b773202ebdcb",
584
+ "sha256": "SSHFP 4 2 47f4663ac537f71bbe31cdd4d43072e444b749664a98c32e2c5884603c4e4a29"
585
+ },
586
+ "key": "AAAAC3NzaC1lZDI1NTE5AAAAIDkV+opGDVkLHDcbeamC3MSRKCzaMg2PB23xpaQo1uxp",
587
+ "type": "ssh-ed25519"
588
+ },
589
+ "rsa": {
590
+ "fingerprints": {
591
+ "sha1": "SSHFP 1 1 a823d0b44a22648b46e83fd42c6028ae8cba9a0d",
592
+ "sha256": "SSHFP 1 2 ac233a0b7a14c3938c971633706b42db2da05390356113fdfcc202f5fde21dc5"
593
+ },
594
+ "key": "AAAAB3NzaC1yc2EAAAADAQABAAABgQCPeaGa+8SwdHEF+VOFfTs8JdaSrmpTdjsOL5N7di3WxzA5XkPYDpPzCZi5RlhWNIjaXT9XaNUK+O2sjLWA67Gp+POKnkroauLbv7w31zjcxp9/BmolIyFe0WDIn+e3kx6CLZXOhtPbNIfzCb/jkW9piwDAO8NexnG1bXEYcRf65R0qvuk8sztxq3mUICaquFisuC62wYQGcqf+GzGv7bnX5oszjSxCZtPQIYuxQn0AczBKZW4+ZIiSlHhXqP8AY3hMkuXYXWaNGagWJw5/Yh1Ls95G4nkMQJZlvLERQj/rea2KXTGibL2DnwW2s+FdR5i/iLRgM0FzmbxQnR/qXpZzchrhXrhkRBDWyC+AfS2Fue1DXPTEvQUZUK6x//BNZgiIn09E4myKnsFsIybCW0pK/tL3v97SMEv0s0YL53QLIeqr8gaRbeqbSl82dJ2RiA5Og40D9Ccq/F40cHlnf1TeBCryLHDElW80NfJY1qmJfTJWg27StVjdk2ShgqBo0c0=",
595
+ "type": "ssh-rsa"
596
+ }
597
+ },
598
+ "system_uptime": {
599
+ "days": 0,
600
+ "hours": 0,
601
+ "seconds": 29,
602
+ "uptime": "0:00 hours"
603
+ },
604
+ "timezone": "UTC",
605
+ "virtual": "virtualbox"
606
+ }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbideDevUtils
4
- VERSION = "0.18.5"
4
+ VERSION = "0.18.6"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abide_dev_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.5
4
+ version: 0.18.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - abide-team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-02-23 00:00:00.000000000 Z
11
+ date: 2026-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -362,6 +362,7 @@ files:
362
362
  - ".rubocop.yml"
363
363
  - ".rubocop_todo.yml"
364
364
  - CHANGELOG.md
365
+ - CLAUDE.md
365
366
  - CODEOWNERS
366
367
  - Gemfile
367
368
  - Gemfile.lock
@@ -372,7 +373,9 @@ files:
372
373
  - bin/abide.rb
373
374
  - bin/console
374
375
  - bin/setup
376
+ - docs/ARCHITECTURE.md
375
377
  - exe/abide
378
+ - files/fact_sets/redhat-10-x86_64.facts
376
379
  - files/fact_sets/windows-2025-x86_64.facts
377
380
  - lib/abide_dev_utils.rb
378
381
  - lib/abide_dev_utils/cli.rb