Skip to content

docs: VM discovery design, tickets, deployment plan, and testbed results - #117

Open
mayankpande88 wants to merge 16 commits into
mainfrom
docs/vm-discovery-phase0
Open

docs: VM discovery design, tickets, deployment plan, and testbed results#117
mayankpande88 wants to merge 16 commits into
mainfrom
docs/vm-discovery-phase0

Conversation

@mayankpande88

@mayankpande88 mayankpande88 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Description

The design and planning record for VM discovery (epic nudgebee/nudgebee-enterprise#35404), including what the AWS testbed run actually found.

Six documents:

File What it is
vm-discovery-phase0.md The design: industry research, build-vs-fork, architecture, discovery sources, OS matrix, signed content packs, server side, coverage report
vm-discovery-phase0-tickets.md P1–P8 breakdown with acceptance criteria, open decisions, and the invariants that are not open
vm-discovery-phase0-epic.md Plain-language epic text
vm-discovery-deployment.md What can ship and the gaps blocking end-to-end discovery
vm-discovery-aws-testbed.md Runbook for the AWS testbed, with the results of actually running it
vm-discovery-next.md Where things stand and what is next, written after the testbed run

Data model and pack format are deliberately marked OPEN rather than settled — the storage question in particular may resolve toward reusing the existing resource model, and the docs say so instead of implying a decision that has not been made.

The finding worth reading if nothing else: /sys/class/dmi/id/product_uuid is root-only, so the unprivileged credential never reads an SMBIOS UUID. A hypervisor knows a VM by SMBIOS UUID and SSH inventory knows it by machine-id, so on-prem those two sources share no strong identifier — under the "only strong identifiers may merge" rule, the same VM lands in the asset list twice, permanently. Three options with their costs are written up in vm-discovery-next.md; it needs deciding before #115 or the #35405 schema hardens.

Type of change

  • Documentation

How Has This Been Tested?

  • Manual testing

Not code. The claims in the testbed document were produced by running the thing: a forager deployed on EC2 swept a /28 and inventoried Ubuntu 22.04 and Amazon Linux 2023 targets, and the numbers, collector names and identity findings recorded there are from those runs rather than from reading the source.

Checklist

  • CLA signed (the CLA bot will prompt on your first PR)
  • make validate passes (fmt + lint + test)
  • Docs updated if the wire shape, config surface, or proxy module behavior changed

Design for making VMs first-class Nudgebee resources: per-segment
forager discovery (sweep, hypervisor, LDAP, SSH inventory), signed
content packs, server-side reconciliation and coverage reporting.
Referenced by epic nudgebee/nudgebee-enterprise#35404 and tickets
#113-#116.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the design, epic, and ticket breakdown documents for Phase 0 of the VM Discovery & Package Inventory initiative, which aims to make VMs first-class resources in Nudgebee using an agentless, per-segment forager model. The review feedback highlights several critical technical issues in the design: the asset_packages primary key must include version and release to support co-installed packages like kernels; the asset_identities table is missing the tenant_id column required for its unique constraint; the virsh command specified for libvirt discovery is insufficient to retrieve all required VM metadata; collecting SMBIOS UUIDs requires root privileges which conflicts with the unprivileged SSH user; and ARP sweeps are Layer 2 only and cannot be routed across arbitrary CIDRs.

Comment on lines +353 to +355
asset_packages -- the package cache
asset_id, name, epoch, version, release, arch, pkg_type, repo, installed_at
pk (asset_id, name, arch)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Setting the primary key of asset_packages to pk (asset_id, name, arch) will cause primary key violations on systems that have multiple versions of the same package installed concurrently. For example, Linux kernels (e.g., kernel or linux-image-* packages) are routinely co-installed during updates. Additionally, RPM-based systems allow co-installation of different versions/releases of the same package (such as gpg-pubkey or dual-arch libraries).

To support multi-version co-installation, the primary key should include the version and release fields.

Suggested schema update:

asset_packages        -- the package cache
  asset_id, name, epoch, version, release, arch, pkg_type, repo, installed_at
  pk (asset_id, name, version, release, arch)


- `vcenter` (govmomi, read-only role)
- `proxmox` (REST `/cluster/resources`)
- `libvirt` (over SSH to the KVM host: `virsh list --all --uuid`)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The command virsh list --all --uuid only outputs a list of raw UUIDs. It does not provide the VM name, power state, guest OS, or IP addresses. Furthermore, virsh on its own does not natively know the guest OS or guest IP addresses unless the QEMU guest agent is installed and queried (e.g., via virsh domifaddr <dom> --source agent or virsh qemu-agent-command).

To satisfy the discovery_hypervisor return requirements (UUID, name, power state, guest OS, IPs), the libvirt connector will need to perform more complex queries, such as parsing virsh list --all for names/states, and inspecting domain XMLs (virsh dumpxml) or querying network DHCP leases/ARP tables to resolve IPs.

Comment on lines +249 to +252
- **Identity:** `/etc/machine-id`; SMBIOS UUID via
`/sys/class/dmi/id/product_uuid` (root) with `dmidecode -s
system-uuid` fallback if sudo-permitted — degrade gracefully to
machine-id only; hostname/FQDN; MACs (`ip -o link`).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Both /sys/class/dmi/id/product_uuid and dmidecode require root/sudo privileges on most standard Linux distributions (permissions on /sys/class/dmi/id/product_uuid are typically 0400 owned by root). Since the SSH user nudgebee-ro is unprivileged, reading the SMBIOS UUID via the primary path will fail without sudo. The design should explicitly note that the primary path also requires sudo/root, or accept that SMBIOS UUID collection will always fall back to machine-id for unprivileged SSH sessions.

Comment on lines +344 to +348
asset_identities -- merge keys; many per asset
asset_id, kind, value, source, observed_at
-- kinds: machine_id | smbios_uuid | instance_id | ad_objectguid (STRONG)
-- fqdn | ip | mac (WEAK)
-- unique (tenant_id, kind, value) enforced for STRONG kinds only

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The asset_identities table definition is missing the tenant_id column, but the unique constraint references it: unique (tenant_id, kind, value). To enforce this multi-column unique constraint, tenant_id must be added as a column to the asset_identities table.

Suggested schema update:

asset_identities      -- merge keys; many per asset
  asset_id, tenant_id, kind, value, source, observed_at
  -- kinds: machine_id | smbios_uuid | instance_id | ad_objectguid   (STRONG)
  --        fqdn | ip | mac                                          (WEAK)
  -- unique (tenant_id, kind, value) enforced for STRONG kinds only

Comment on lines +90 to +94
Tasks: (a) `discovery_sweep` — ARP local L2, ICMP, TCP 22/3389/5985
over configured CIDRs; opt-in per CIDR, exclusions, hard rate cap
(default ≤100 pps), well-formed packets, windows honored; decide
TCP-connect vs naabu inside the ticket; (b) `discovery_ldap` —
read-only AD bind (go-ldap), filter `lastLogonTimestamp` tombstones.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

ARP (Address Resolution Protocol) is a Layer 2 protocol and cannot be routed across subnets. Therefore, performing an ARP sweep over arbitrary "configured CIDRs" is technically impossible if those CIDRs belong to routed networks outside the forager's local broadcast domain.

The ticket description should clarify that ARP sweeps are strictly limited to the local subnet of the forager's active network interface, whereas ICMP and TCP port probes (22/3389/5985) are used for routed CIDRs.

…ckoff

Matches the issue restructure after #35406 was removed.
Covers what can ship now (an rc image) and the four gaps blocking
end-to-end discovery: local config cannot configure a discovery
datasource, a sweep-only datasource still demands SSH credentials, no
signed content pack exists (#116), and nothing triggers discovery yet.
product_uuid is root-only on stock Linux, so the unprivileged
nudgebee-ro credential never gets an SMBIOS UUID. That leaves a
hypervisor record and an SSH record for the same on-prem VM with no
strong identifier in common, which blocks the merge §8.2 depends on.
board_asset_tag is world-readable and carries the EC2 instance id, so
cloud VMs are unaffected.
Records the setup, what a correct sweep and inventory look like on
real hosts, and the three findings: SMBIOS UUID is root-only so
hypervisor-to-SSH merging has no shared strong identifier on-prem,
rpm reports a missing epoch as (none), and board_asset_tag gives cloud
VMs a strong identifier unprivileged.
The agent half is proven and does nothing, because everything
user-visible is behind the server side. Records the one design
decision the testbed forced — SMBIOS UUID is root-only, so on-prem a
hypervisor record and an SSH record share no strong identifier — with
three options and the tradeoff of each.
@mayankpande88 mayankpande88 changed the title docs: VM discovery phase 0 design, ticket plan, epic draft docs: VM discovery design, tickets, deployment plan, and testbed results Aug 3, 2026
Exact requests and verbatim responses for discovery_sweep and
discovery_inventory, plus parsing notes taken from real output rather
than from the collector definitions — rpm reports a missing epoch as
(none), smbios-uuid comes back empty under the unprivileged
credential.

Marks clearly which parts were exercised and which were not: the
actions ran against real hosts, the relay envelope around them has
never carried a discovery action.
Plain-language explanation of what discovery does, written for a
non-technical reader, with the joint-build split made explicit: what
we need answered, what only they can set up, and the identification
trade-off that is genuinely their call.

States current status honestly rather than as 'in progress' — what
works and was tested on real machines, what is not built, and the
limits we are not hiding (powered-off machines are invisible without
the hypervisor; no-SSH machines can be found but not inventoried).
Four points were each made three times: machines that are switched off
needing the hypervisor, old systems having no patches, nothing being
installed on customer machines, and machines that cannot be logged
into. Each now appears once, in the section that owns it, with
cross-references where another section needs to point at it.

Also drops the closing section that restated the questions and the
decision already asked for above.
The previous version read as generated: an em-dash in nearly every
paragraph, rule-of-three constructions, a rhetorical turn per section,
bold lead-ins on every bullet, and headings like 'Limits we are not
hiding' that perform honesty rather than being honest.

Same content, flatter voice. No em-dashes, no bold, no tables, and the
editorialising cut — the section on why per-machine agents are costly
was selling rather than explaining, and the customer did not ask to be
sold.
Asked 'do you use Active Directory?', which answers nothing — everyone
uses it for user authentication. The question that decides whether it
helps discovery is whether their Linux servers are domain-joined, and
most are not.

AD holds a computer object per domain-joined machine, which is what we
query (objectCategory=computer, not users). But domain-joining Linux is
a minority setup, so for a Linux-first scope AD will usually return
little. The doc now says so instead of listing it beside the hypervisor
as an equal source.
Reviewer asked whether machine ID and MAC address are the same thing,
which they are not, and the section did not say so. It now names all
three with real example values and states which side can see each.

Also corrects the second option. It said 'match on hostname and IP',
having overlooked that both the hypervisor and an SSH login can see MAC
addresses, which are more stable than IPs. That makes the no-setup
option meaningfully better than described, and the customer was being
asked to choose against a weaker version of it than actually exists.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant