Skip to content

Add LLDP port discovery to PAN-OS inspect interface - #2564

Draft
khackworth wants to merge 13 commits into
mainfrom
panos-inspect-lldp-ports
Draft

khackworth wants to merge 13 commits into
mainfrom
panos-inspect-lldp-ports

Conversation

@khackworth

Copy link
Copy Markdown
Contributor

Summary

Implements automatic LLDP neighbor discovery during PAN-OS device inspection to populate port MAC addresses and local_link_connection data.

Changes

  • panos_inspect.py: Add _discover_and_update_ports() to enable LLDP, wait for neighbor discovery, and update ports
  • panos_api.py: Add API methods for config management, commit operations, and LLDP neighbor retrieval

Testing

Draft PR to build container image for testing in dev environment with device PaloAlto-026701009584.

Status

🚧 DO NOT MERGE - Testing in progress

- Implement _discover_and_update_ports() to collect LLDP neighbors
- Add config(), commit(), check_job(), wait_for_commit() to PanosClient
- Add get_interface_macs() and get_lldp_neighbors() to PanosClient
- Temporarily enable LLDP on unconfigured interfaces during inspection
- Create/update Ironic ports with LLDP neighbor data and real MAC addresses
- Restore original configuration after discovery
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Python test results

805 tests   805 ✅  11s ⏱️
  1 suites    0 💤
  1 files      0 ❌

Results for commit c1fc47f.

♻️ This comment has been updated with latest results.

Factory-fresh PAN-OS devices include default zones, security rules,
and virtual-wire configurations that block interface configuration.

Remove these factory defaults before enabling LLDP:
1. Delete entire vsys1 (zones, security rules, etc.)
2. Delete virtual-wire configurations
3. Commit the cleanup

This allows LLDP configuration to proceed without validation errors.

Fixes commit failures when inspecting factory-default devices.
The XML parsing for LLDP neighbors was looking for the wrong structure.
PAN-OS returns: <entry><local><port-id>X</port-id></local><neighbors><entry>...</entry></neighbors></entry>

Updated parser to:
- Find each entry's local/port-id correctly
- Navigate to neighbors/entry (not neighbors/entry via findall)
- Extract text from each element explicitly with .text.strip()
- Handle missing elements gracefully

This matches the working panos.py script parser logic.
The ElementTree XML parsing wasn't handling the PAN-OS LLDP response
correctly. Switch to the same approach used in the working panos.py
script:

1. Convert XML to nested dicts/lists using _xml_to_dict() helper
2. Parse the dict structure (handles empty neighbors gracefully)
3. Skip entries with no neighbor data

This matches the proven panos.py implementation that successfully
discovers LLDP neighbors.
PAN-OS config API calls were using POST with data= which PAN-OS was
accepting but not staging to candidate config. This caused all commits
to return code 19 (no changes). Changed to use GET with params= like
the working panos.py script, matching PAN-OS API documentation.
The commit() method was using POST with data/headers, but PAN-OS API
expects GET with params (including the API key). This was causing
commits to return 'code 19 (no changes)' because the configuration
changes weren't being properly associated with the session.

Changed to match the working panos.py implementation which uses
session.get() with params for all API calls including commit.
The commit was returning None on code 19, causing the code to skip
waiting for the commit job. But code 19 doesn't always mean 'no changes' -
need to check the message text. This matches the working panos.py behavior.

Also added detailed XML response logging to help debug API interactions.
The vlan_group_name_convention module provides vlan_group_names() which
takes a list of InspectedPort objects and returns a mapping, not a
derive_vlan_group_name() function for individual switches.

Updated to:
1. Create InspectedPort objects from LLDP neighbors
2. Call vlan_group_names() to get the physical_network mapping
3. Use that mapping when creating/updating Ironic ports
4. Handle errors gracefully by creating ports without physical_network

This completes the LLDP discovery flow.
…nspect

- Fix config reference from CONF.switch_name_vlan_group_mapping to
  CONF.ironic_understack.switch_name_vlan_group_mapping to match the
  actual config group definition
- Update port existence check to look for both MAC address and port
  name to handle re-inspection scenarios where ports already exist
- Update existing port MAC address when found by name to handle cases
  where the port exists but with different MAC

This branch has not been deployed

No deployments
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