Skip to content

Additional Source from Ovirt - #599

Open
ekrichbaum wants to merge 21 commits into
bb-Ricardo:mainfrom
ekrichbaum:Ovirt
Open

ekrichbaum wants to merge 21 commits into
bb-Ricardo:mainfrom
ekrichbaum:Ovirt

Conversation

@ekrichbaum

Copy link
Copy Markdown

Previous pull request wasn't adopted. Rebased against other changes and re-added source with doucmentation. Broke Ovirt and Openstack out to individual subs.

Added oVirt / Red Hat Virtualization as a source type and included relevant installation documentation.
Added a method to check if an object is synced by another source based on ownership and tags.
Added configuration options for oVirt integration.
This file defines the OVirtConfig class, which manages configuration options for connecting to the oVirt API, including authentication, TLS settings, and filtering options for syncing with NetBox.
Added support for optional oVirt installation in Dockerfile.
Removed the method object_synced_by_other_source from the connection.py file, which checked if a NetBox object was maintained by a different configured source.
@bb-Ricardo

Copy link
Copy Markdown
Owner

Hi @ekrichbaum,

thank you for not giving up and resubmitting your contributions.

With the Hetzner source we agreed that @SerhiiZahuba will take care of issues and feature requests. Same question would be here, if you would like to be code owner for the Ovirt and Openstack sources? Mostly due to the lack of a testing environment we are not able to easily reproduce errors and therefore would make debugging really difficult.

regarding the PR's:

  • not sure if we have it documented already: you can recreate the config by simply running rm settings-example.ini && ./netbox-sync.py -g -c settings-example.ini
  • it is fantastic that you added a docs document to this PR but not sure if intentional or not, it missing in the Openstack PR
  • are you aware of Ovirt or Openstack mockup services (similar to vcsim), which you could use to create integration tests? It would be fantastic to add these as well (if possible).

@ekrichbaum

Copy link
Copy Markdown
Author

I swore I put a response in. Absolutely on these sources. Once I finish my AWS source, I'll get it posted as well, before I go back to a Digital Ocean version. I split them to be a little more obvious but of course missed that documentation item. I'm not aware of a mockup environment. I'm running against dev/staging/prod versions of the platforms in general.

@semx semx mentioned this pull request Oct 26, 2026

@semx semx left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Tested against oVirt 4.5.7 (engine plus one host on CentOS Stream 9, NFS data domain) with ovirt-engine-sdk-python 4.6.3, syncing into NetBox 4.7.3. Test VMs:

  • one running VM with qemu-guest-agent and two NICs
  • one stopped VM with a data disk

1. A wrong password logs success, then crashes in apply()

sdk.Connection() does not authenticate, so create_ovirt_session logs success (L139) and the first API call raises:

INFO: Successfully connected to oVirt 'https://engine.nbtest.lan/ovirt-engine/api'
Traceback (most recent call last):
  File ".../module/sources/ovirt/connection.py", line 175, in apply
ovirtsdk4.AuthError: Error during SSO authentication access_denied : Cannot authenticate user 'admin@internal' ...

The exception is not caught, so netbox-sync exits with this traceback (exit 1) instead of skipping the source the way the openstack source does on a 401.

2. A host added by FQDN never gets a primary IP

The host was added as host1.nbtest.lan. nic.ip.address == obj.address (L1077, L1088) compares an IP with the FQDN, so it is never true. In NetBox, eth0 has 192.168.1.130/24, but primary_ip4 stays empty, even with a covering prefix present.

3. vm_interface_exclude_filter is not applied

The option exists in the config, but unlike the openstack and vmware sources, the oVirt add_device_vm_to_inventory does not filter discovered NICs. With vm_interface_exclude_filter = ^nic1$ on a VM that already had nic1 in NetBox, the run:

  • orphan-tagged the existing nic1
  • created a second MAC object for the same MAC
  • tried to create nic1 again, which NetBox rejected:
POST /api/virtualization/interfaces/ Bad Request
{'__all__': ['Interface with this Virtual machine and Name already exists.']}

4. The VM platform flips on every start/stop

For a running VM the platform comes from guest_operating_system. For a stopped VM, that field is None and the code falls back to os.type (L1149-1152). Every power state change updates the VM:

Updating NetBox 'virtual machine' object 'nbO-up' with data: {'status': 'offline', 'platform': 6}   # rhel_9x64
Updating NetBox 'virtual machine' object 'nbO-up' with data: {'status': 'active', 'platform': 5}    # CentOS Stream 9

5. Guest-agent IPs need a NetBox prefix

The engine returns netmask=None for reported_devices IPs. Without a covering prefix the bare address is dropped:

WARNING: No matching NetBox prefix for '192.168.1.81' found. Unable to add IP address to NetBox

After adding 192.168.1.0/24 they sync as /24. The openstack source keeps a host-length mask in the same situation. If this is intended, a note in docs/source_ovirt.md would help.

6. Smaller points

  • Host link: the VM is not linked to the host it runs on (device is empty). The vmware and openstack sources set it.
  • Removed settings: the block is copied from vmware. sync_tags etc. point to host_tag_source / vm_tag_source / cluster_tag_source, which this source doesn't have.
  • Base branch: the PR targets main; other changes go to development.
  • Conflicts: it conflicts with #600 in six files.
  • Version range: ovirt-engine-sdk-python>=4.6,<5 is a range, while requirements.txt pins exact versions.
  • Commit message: commit b134b87 is titled "Update fmt.Println message from 'Hello' to 'Goodbye'" but only changes uv.lock.

What worked

  • Lockfile and tests: uv.lock entries match PyPI sha256. pytest merged into development: 383 passed, 8 skipped (vcsim tests included).
  • IPs and disks: host NIC IPs given as address/255.255.255.0 are stored as /24. Disk sizes are correct (10 GiB → 10240, 1 GiB → 1024).
  • Stopped VMs: a stopped VM keeps its guest-reported interfaces and IPs (the engine still returns reported_devices after shutdown).
  • Idempotency: a rerun without changes writes nothing.
  • Shared code: moving object_synced_by_other_source into SourceBase keeps vmware behaviour identical. The vmware_object is not None guard fixes IP handling for non-vmware VM sources: on development, add_update_interface(nic, vm, ..., ["10.0.0.9/24"], vmware_object=None) returns no IPs; with the guard it returns 10.0.0.9/24.

@ekrichbaum

Copy link
Copy Markdown
Author

interesting and thanks for the run. I've been running that in production for years without hitting those situations. I had posted that base PR quite some time ago and didn't pay much attention beyond that when it just sat. I'll take a look at all of these and see what needs to change. I'm getting to a very difficult point keeping all of these separated and combined to my own use.

Clarify behavior of address importation regarding prefix matching and permitted subnets.
Added host_address parameter to populate function and updated its usage in tests. Implemented test for host primary IP matching FQDN and added tests for excluded VM interfaces.
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.

3 participants