From 365432142c0a54cafe9087a2a8396641c3281121 Mon Sep 17 00:00:00 2001 From: Gavin Didrichsen Date: Tue, 28 Jul 2026 18:28:43 +0100 Subject: [PATCH 1/2] Sort inventory targets and groups alphabetically binvv listed VMs in whatever order they came back from the provider API, making a long inventory hard to scan. Sort by name in both providers so targets, windows/linux/unavailable groups, and regex-matched groups all come back alphabetized. Co-Authored-By: Claude Sonnet 5 --- .rubocop_todo.yml | 2 +- docs/README.md | 31 ------------------- docs/howto_how_to_use_as_a_gem.md | 8 ++--- .../provider/orbstack/inventory.rb | 5 +-- .../provider/vmpooler/inventory.rb | 11 +++++-- spec/bolt_dynamic_inventory_spec.rb | 20 ++++++++++-- 6 files changed, 33 insertions(+), 44 deletions(-) delete mode 100644 docs/README.md diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 8d148b0..e908daa 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -22,7 +22,7 @@ Metrics/AbcSize: # Offense count: 1 # Configuration parameters: CountComments, CountAsOne. Metrics/ClassLength: - Max: 195 + Max: 198 # Offense count: 2 # Configuration parameters: AllowedMethods, AllowedPatterns. diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 2b1253f..0000000 --- a/docs/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# bolt_dynamic_inventory - -## Description - -### Design Decisions - - -* [ADR-0001](adr/0001-extend-this-gem-to-be-a-bolt-inventory-dynamic-plugin-also.md) - Extend this gem to be a bolt inventory dynamic plugin also -* [ADR-0002](adr/0002-configure-bolt-inventory-with-native-ssh-to-keep-things-simple.md) - Configure bolt inventory with native ssh to keep things simple -* [ADR-0003](adr/0003-gather-inventory-metadata-via-the-cli-to-keep-things-simple.md) - Gather inventory metadata via the cli to keep things simple -* [ADR-0004](adr/0004-create-dynamic-inventory-groups-based-on-hostname-regex-patterns.md) - Create dynamic inventory groups based on hostname regex patterns -* [ADR-0005](adr/0005-add-role-fact-that-matches-the-group-name-making-puppet-switching-easier.md) - Add 'role' fact that matches the group name making puppet switching easier -* [ADR-0006](adr/0006-extend-the-plugin-to-handle-not-only-orbstack-but-vmpooler-as-well.md) - Extend the plugin to handle not only orbstack but vmpooler as well -* [ADR-0007](adr/0007-use-nmap-ssh-port-scan-for-vmpooler-vm-connectivity-filtering.md) - Use nmap SSH port scan for VMPooler VM connectivity filtering -* [ADR-0008](adr/0008-query-both-abs-and-vmpooler-services-to-find-all-active-vms.md) - Query both ABS and vmpooler services to find all active VMs -* [ADR-0009](adr/0009-cache-vm-data-with-smart-ttl-based-invalidation.md) - Cache VM data with smart TTL-based invalidation -* [ADR-0010](adr/0010-surface-unavailable-vms-in-a-dedicated-group-instead-of-silently-dropping.md) - Surface unavailable VMs in a dedicated group instead of silently dropping - - -### How-To Guides - - -* [How to create a basic dynamic inventory plugin](howto_how_to_create_a_basic_dynamic_inventory_plugin.md) -* [How to create and remove orbstack VMs from the command-line](howto_how_to_create_and_remove_orbstack_vms_from_the_command_line.md) -* [How to setup the environment](howto_how_to_setup_the_environment.md) -* [How to setup windows credentials for vmpooler](howto_how_to_setup_windows_credentials_for_vmpooler.md) -* [How to Test VMPooler Inventory Features](howto_how_to_test_vmpooler_inventory_features.md) -* [How to use as a bolt dynamic plugin](howto_how_to_use_as_a_bolt_dynamic_plugin.md) -* [How to use as a gem](howto_how_to_use_as_a_gem.md) -* [How to use the `role` fact](howto_how_to_use_the_role_fact.md) - diff --git a/docs/howto_how_to_use_as_a_gem.md b/docs/howto_how_to_use_as_a_gem.md index 63988a4..1fe6268 100644 --- a/docs/howto_how_to_use_as_a_gem.md +++ b/docs/howto_how_to_use_as_a_gem.md @@ -161,14 +161,14 @@ Vmpooler output: ➜ bolt_dynamic_inventory git:(development) ✗ bundle exec binv --provider=vmpooler --groups "agent:tender|normal" --- targets: +- name: normal-meddling + uri: normal-meddling.delivery.puppetlabs.net - name: onetime-algebra uri: onetime-algebra.delivery.puppetlabs.net - name: stiff-boulevard uri: stiff-boulevard.delivery.puppetlabs.net - name: tender-punditry uri: tender-punditry.delivery.puppetlabs.net -- name: normal-meddling - uri: normal-meddling.delivery.puppetlabs.net - name: unimposing-poll uri: unimposing-poll.delivery.puppetlabs.net groups: @@ -201,13 +201,13 @@ groups: facts: role: linux targets: - - tender-punditry - normal-meddling + - tender-punditry - name: agent facts: role: agent targets: - - tender-punditry - normal-meddling + - tender-punditry ➜ bolt_dynamic_inventory git:(development) ✗ ``` diff --git a/lib/bolt_dynamic_inventory/provider/orbstack/inventory.rb b/lib/bolt_dynamic_inventory/provider/orbstack/inventory.rb index 6e0a31e..f5fa721 100644 --- a/lib/bolt_dynamic_inventory/provider/orbstack/inventory.rb +++ b/lib/bolt_dynamic_inventory/provider/orbstack/inventory.rb @@ -64,18 +64,19 @@ def parse_group_patterns(patterns) end def generate_targets(orbs) - orbs.map do |orb| + targets = orbs.map do |orb| { 'name' => orb['name'], 'uri' => "#{orb['name']}@orb" } end + targets.sort_by { |t| t['name'] } end def generate_groups(orbs) return [] if @group_patterns.empty? - target_names = orbs.map { |orb| orb['name'] } + target_names = orbs.map { |orb| orb['name'] }.sort @group_patterns.each_with_object([]) do |pattern, groups| matching_targets = target_names.grep(pattern[:regex]) diff --git a/lib/bolt_dynamic_inventory/provider/vmpooler/inventory.rb b/lib/bolt_dynamic_inventory/provider/vmpooler/inventory.rb index 99a461a..8217a32 100644 --- a/lib/bolt_dynamic_inventory/provider/vmpooler/inventory.rb +++ b/lib/bolt_dynamic_inventory/provider/vmpooler/inventory.rb @@ -158,8 +158,8 @@ def merge_vm_lists(abs_vms, vmpooler_vms) def generate_inventory(alive_vms, unavailable_vms) targets = extract_targets(alive_vms + unavailable_vms) - alive_names = alive_vms.map { |vm| vm['hostname'].split('.').first } - unavailable_names = unavailable_vms.map { |vm| vm['hostname'].split('.').first } + alive_names = sorted_hostnames(alive_vms) + unavailable_names = sorted_hostnames(unavailable_vms) alive_targets = targets.select { |t| alive_names.include?(t['name']) } windows_targets, linux_targets = partition_targets_by_type(alive_targets) @@ -174,8 +174,12 @@ def generate_inventory(alive_vms, unavailable_vms) } end + def sorted_hostnames(vms) + vms.map { |vm| vm['hostname'].split('.').first }.sort + end + def extract_targets(vms) - vms.map do |vm| + targets = vms.map do |vm| vars = { 'type' => vm['type'] } vars['ttl'] = vm['ttl'] if vm['ttl'] { @@ -184,6 +188,7 @@ def extract_targets(vms) 'vars' => vars } end + targets.sort_by { |t| t['name'] } end def partition_targets_by_type(targets_with_type) diff --git a/spec/bolt_dynamic_inventory_spec.rb b/spec/bolt_dynamic_inventory_spec.rb index b69f98a..b3bf6c7 100644 --- a/spec/bolt_dynamic_inventory_spec.rb +++ b/spec/bolt_dynamic_inventory_spec.rb @@ -24,10 +24,10 @@ describe BoltDynamicInventory::Provider::Orbstack::Inventory do let(:mock_orbs) do [ - { 'name' => 'agent01', 'status' => 'running' }, - { 'name' => 'agent02', 'status' => 'running' }, + { 'name' => 'webserver01', 'status' => 'running' }, { 'name' => 'compiler01', 'status' => 'running' }, - { 'name' => 'webserver01', 'status' => 'running' } + { 'name' => 'agent02', 'status' => 'running' }, + { 'name' => 'agent01', 'status' => 'running' } ] end @@ -66,6 +66,14 @@ 'port' => 32_222 ) end + + it 'sorts targets alphabetically by name' do + result = inventory.generate + + expect(result['targets'].map { |t| t['name'] }).to eq( + %w[agent01 agent02 compiler01 webserver01] + ) + end end context 'with group patterns' do @@ -296,6 +304,12 @@ def stub_vmpooler_service_response(json_str) ) end + it 'sorts targets alphabetically by name' do + expect(result['targets'].map { |t| t['name'] }).to eq( + %w[normal-meddling onetime-algebra tender-punditry] + ) + end + it 'includes vars with type and ttl for each target' do targets = result['targets'] From 3d4b01807c8d8173058b145d686c155d9460522e Mon Sep 17 00:00:00 2001 From: Gavin Didrichsen Date: Tue, 28 Jul 2026 18:29:13 +0100 Subject: [PATCH 2/2] Consolidate README to repo root; tag narrow ADRs instead of a separate IDR type .diataxis now points readme generation at the top-level README.md (docs/README.md was a stale duplicate, already removed in the prior commit). Also drops the short-lived separate IDR document type: five ADRs that were briefly migrated to docs/idr/ are back at their original path/number, tagged -scope/implementation instead. A tag is cheap to revise later; a directory/numbering split isn't. Co-Authored-By: Claude Sonnet 5 --- .diataxis | 3 +- README.md | 28 +++++++++++++++++++ ...adata-via-the-cli-to-keep-things-simple.md | 5 ++++ ...oup-name-making-puppet-switching-easier.md | 5 ++++ ...-for-vmpooler-vm-connectivity-filtering.md | 5 ++++ ...mpooler-services-to-find-all-active-vms.md | 5 ++++ ...ated-group-instead-of-silently-dropping.md | 5 ++++ 7 files changed, 55 insertions(+), 1 deletion(-) diff --git a/.diataxis b/.diataxis index f32050d..d0f8d46 100644 --- a/.diataxis +++ b/.diataxis @@ -1,6 +1,7 @@ { "default": "docs", - "readme": "docs/README.md", + "readme": "README.md", "adr": "docs/adr", + "wow": "docs/wow", "projects": "docs/_gtd" } diff --git a/README.md b/README.md index 295749b..8c5907f 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,31 @@ For a complete listing of various how-to guides and design decisions, see the [d - [How to create and remove orbstack VMs from the command-line](howto_how_to_create_and_remove_orbstack_vms_from_the_command_line.md) - [How to setup windows credentials for vmpooler](howto_how_to_setup_windows_credentials_for_vmpooler.md) - [How to Test VMPooler Inventory Features](howto_how_to_test_vmpooler_inventory_features.md) + +### Design Decisions + + +* [ADR-0001](docs/adr/0001-extend-this-gem-to-be-a-bolt-inventory-dynamic-plugin-also.md) - Extend this gem to be a bolt inventory dynamic plugin also +* [ADR-0002](docs/adr/0002-configure-bolt-inventory-with-native-ssh-to-keep-things-simple.md) - Configure bolt inventory with native ssh to keep things simple +* [ADR-0003](docs/adr/0003-gather-inventory-metadata-via-the-cli-to-keep-things-simple.md) - Gather inventory metadata via the cli to keep things simple +* [ADR-0004](docs/adr/0004-create-dynamic-inventory-groups-based-on-hostname-regex-patterns.md) - Create dynamic inventory groups based on hostname regex patterns +* [ADR-0005](docs/adr/0005-add-role-fact-that-matches-the-group-name-making-puppet-switching-easier.md) - Add 'role' fact that matches the group name making puppet switching easier +* [ADR-0006](docs/adr/0006-extend-the-plugin-to-handle-not-only-orbstack-but-vmpooler-as-well.md) - Extend the plugin to handle not only orbstack but vmpooler as well +* [ADR-0007](docs/adr/0007-use-nmap-ssh-port-scan-for-vmpooler-vm-connectivity-filtering.md) - Use nmap SSH port scan for VMPooler VM connectivity filtering +* [ADR-0008](docs/adr/0008-query-both-abs-and-vmpooler-services-to-find-all-active-vms.md) - Query both ABS and vmpooler services to find all active VMs +* [ADR-0009](docs/adr/0009-cache-vm-data-with-smart-ttl-based-invalidation.md) - Cache VM data with smart TTL-based invalidation +* [ADR-0010](docs/adr/0010-surface-unavailable-vms-in-a-dedicated-group-instead-of-silently-dropping.md) - Surface unavailable VMs in a dedicated group instead of silently dropping + + +### How-To Guides + + +* [How to create a basic dynamic inventory plugin](docs/howto_how_to_create_a_basic_dynamic_inventory_plugin.md) +* [How to create and remove orbstack VMs from the command-line](docs/howto_how_to_create_and_remove_orbstack_vms_from_the_command_line.md) +* [How to setup the environment](docs/howto_how_to_setup_the_environment.md) +* [How to setup windows credentials for vmpooler](docs/howto_how_to_setup_windows_credentials_for_vmpooler.md) +* [How to Test VMPooler Inventory Features](docs/howto_how_to_test_vmpooler_inventory_features.md) +* [How to use as a bolt dynamic plugin](docs/howto_how_to_use_as_a_bolt_dynamic_plugin.md) +* [How to use as a gem](docs/howto_how_to_use_as_a_gem.md) +* [How to use the `role` fact](docs/howto_how_to_use_the_role_fact.md) + diff --git a/docs/adr/0003-gather-inventory-metadata-via-the-cli-to-keep-things-simple.md b/docs/adr/0003-gather-inventory-metadata-via-the-cli-to-keep-things-simple.md index 187d939..37807dc 100644 --- a/docs/adr/0003-gather-inventory-metadata-via-the-cli-to-keep-things-simple.md +++ b/docs/adr/0003-gather-inventory-metadata-via-the-cli-to-keep-things-simple.md @@ -1,3 +1,8 @@ +--- +tags: + - -scope/implementation +--- + # 3. Gather inventory metadata via the cli to keep things simple Date: 2025-01-10 diff --git a/docs/adr/0005-add-role-fact-that-matches-the-group-name-making-puppet-switching-easier.md b/docs/adr/0005-add-role-fact-that-matches-the-group-name-making-puppet-switching-easier.md index 68ade0b..caaf5af 100644 --- a/docs/adr/0005-add-role-fact-that-matches-the-group-name-making-puppet-switching-easier.md +++ b/docs/adr/0005-add-role-fact-that-matches-the-group-name-making-puppet-switching-easier.md @@ -1,3 +1,8 @@ +--- +tags: + - -scope/implementation +--- + # 5. Add 'role' fact that matches the group name making puppet switching easier Date: 2025-02-02 diff --git a/docs/adr/0007-use-nmap-ssh-port-scan-for-vmpooler-vm-connectivity-filtering.md b/docs/adr/0007-use-nmap-ssh-port-scan-for-vmpooler-vm-connectivity-filtering.md index 98d146c..d4f4d06 100644 --- a/docs/adr/0007-use-nmap-ssh-port-scan-for-vmpooler-vm-connectivity-filtering.md +++ b/docs/adr/0007-use-nmap-ssh-port-scan-for-vmpooler-vm-connectivity-filtering.md @@ -1,3 +1,8 @@ +--- +tags: + - -scope/implementation +--- + # 7. Use nmap SSH port scan for VMPooler VM connectivity filtering Date: 2025-10-28 diff --git a/docs/adr/0008-query-both-abs-and-vmpooler-services-to-find-all-active-vms.md b/docs/adr/0008-query-both-abs-and-vmpooler-services-to-find-all-active-vms.md index d56fc85..b37f779 100644 --- a/docs/adr/0008-query-both-abs-and-vmpooler-services-to-find-all-active-vms.md +++ b/docs/adr/0008-query-both-abs-and-vmpooler-services-to-find-all-active-vms.md @@ -1,3 +1,8 @@ +--- +tags: + - -scope/implementation +--- +