Skip to content

platform detection issue #495

@berlikm

Description

@berlikm

Hey I run netbox-sync from development branch and I have this as a platform

2026-02-19 11:22:02,558 - INFO: Created new platform object: Usage: lsb_release [-a|--all] [-i|--id] [-d|--description] [-r|--release] [-c|-codename] [-s] [-b|-
2026-02-19 11:22:02,558 - INFO: Virtual machine 'xxxxxx' attribute 'platform' changed from 'Other 5.x or later Linux (64-bit)' to 'Usage: lsb_release [-a|--all] [-i|--id] [-d|--description] [-r|--release] [-c|-codename] [-s] [-b|-'
2

vmware shows i as

Guest OS | Other 5.x or later Linux (64-bit)

VMware Tools | Running, version:2147483647 (Guest Managed

I did a research about that you can check if that's accurate

The platform detection code in module/sources/vmware/connection.py add_virtual_machine() method (around line 2178-2189) follows this flow:

# Step 1: Get correct VMware guest OS name ✅
platform = get_string_or_none(grab(obj, "config.guestFullName"))
# e.g., "Other 5.x or later Linux (64-bit)"

# Step 2: Override with guest tools name (usually also correct) ✅
platform = get_string_or_none(grab(obj, "guest.guestFullName", fallback=platform))

# Step 3: Extract prettyName from extraConfig - THIS OVERRIDES WITH GARBAGE ❌
extra_config = [x.value for x in grab(obj, "config.extraConfig", fallback=[])
                if x.key == "guestOS.detailed.data"]
if len(extra_config) > 0:
    pretty_name = [x for x in quoted_split(extra_config[0].replace("' ", "', "))
                   if x.startswith("prettyName")]
    if len(pretty_name) > 0:
        platform = pretty_name[0].replace("prettyName='","")
        # platform is now "Usage: lsb_release [-a|--all] ..."

# Step 4: Apply user mapping
platform = self.get_object_relation(platform, "vm_platform_relation", fallback=platform)

What happens: VMware guest tools (open-vm-tools) internally run lsb_release to populate the guestOS.detailed.data extraConfig key. When lsb_release is not installed or misconfigured on the guest VM, instead of returning the OS pretty name, it returns its usage/help text. This gets stored by VMware as the prettyName in guestOS.detailed.data, and netbox-sync blindly uses it as the platform name, overriding the correct guestFullName from steps 1-2.

Environment

  • netbox-sync version: v1.8.0-22-gbb61e32 (development branch, commit bb61e32)
  • NetBox version: 4.x
  • VMware vCenter: 7.x/8.x
  • Guest OS: Ubuntu 24.04 with open-vm-tools (Guest Managed)
  • Guest VM lsb_release: not installed or broken

Suggested Fix

Add validation to the prettyName extraction to ensure the value looks like a reasonable OS name before using it. If validation fails, fall back to the previously determined config.guestFullName / guest.guestFullName value.

Option A: Basic sanity check (minimal change)

extra_config = [x.value for x in grab(obj, "config.extraConfig", fallback=[])
                if x.key == "guestOS.detailed.data"]
if len(extra_config) > 0:
    pretty_name = [x for x in quoted_split(extra_config[0].replace("' ", "', "))
                   if x.startswith("prettyName")]
    if len(pretty_name) > 0:
        extracted_name = pretty_name[0].replace("prettyName='", "")
        # Validate prettyName - reject values that look like command output/error text
        if extracted_name and not extracted_name.startswith("Usage:") and len(extracted_name) < 100:
            platform = extracted_name
        else:
            log.debug(f"Ignoring invalid prettyName from guestOS.detailed.data: '{extracted_name}'")

**Option B: More robust validation **

extra_config = [x.value for x in grab(obj, "config.extraConfig", fallback=[])
                if x.key == "guestOS.detailed.data"]
if len(extra_config) > 0:
    pretty_name = [x for x in quoted_split(extra_config[0].replace("' ", "', "))
                   if x.startswith("prettyName")]
    if len(pretty_name) > 0:
        extracted_name = pretty_name[0].replace("prettyName='", "").rstrip("'")
        # Validate: reject empty values, command output, or obviously invalid names
        invalid_patterns = ["Usage:", "Error:", "command not found", "No such file"]
        if extracted_name and not any(extracted_name.startswith(p) for p in invalid_patterns):
            platform = extracted_name
        else:
            log.warning(f"VM '{name}': Ignoring invalid prettyName from guest tools: "
                        f"'{extracted_name}'. Using fallback: '{platform}'")

thank you

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions