Compare commits

...

15 commits
0.1.0 ... main

Author SHA1 Message Date
1a0107381b Update run instructions
All checks were successful
CI / ci (push) Successful in 39s
2025-06-03 16:36:12 +02:00
e0a94e68d9 Release 0.2.2
All checks were successful
CD / ci (push) Successful in 59s
CI / ci (push) Successful in 51s
2025-05-07 09:10:07 +02:00
c0d2c62bbb Use NB_CLUSTER_ID even for VM update
All checks were successful
CI / ci (push) Successful in 49s
2025-05-02 08:20:54 +02:00
e0c732043c Documentation updated to mention NB_CLUSTER_ID
All checks were successful
CI / ci (push) Successful in 46s
2025-05-01 09:16:44 +02:00
e7d5f5dd26 Release 0.2.1
All checks were successful
CD / ci (push) Successful in 1m32s
CI / ci (push) Successful in 1m24s
2025-05-01 08:50:40 +02:00
c892d596f4 [#7] Improve tag handling
All checks were successful
CI / ci (push) Successful in 1m16s
Closes: #7
2025-05-01 08:49:38 +02:00
eb663ee3c6 Release 0.2.0
All checks were successful
CD / ci (push) Successful in 1m37s
CI / ci (push) Successful in 1m35s
2025-04-21 15:56:17 +02:00
685e8ac589 Monitoring PVE ha/replication 2025-04-21 15:54:59 +02:00
20cdbfc499 Add PyPi installation instruction
All checks were successful
CI / ci (push) Successful in 28s
2025-02-24 12:10:30 +01:00
f1b37a1e32 Add dates to changelog
All checks were successful
CI / ci (push) Successful in 31s
2025-02-19 22:29:49 +01:00
2f17021e5d Release 0.1.1
All checks were successful
CD / ci (push) Successful in 34s
CI / ci (push) Successful in 29s
2025-02-19 22:29:18 +01:00
d11c1677e2 Add eth0 as raw_interface_name
All checks were successful
CI / ci (push) Successful in 29s
2025-02-19 22:28:53 +01:00
2870560577 Update pyproject.toml
All checks were successful
CI / ci (push) Successful in 27s
2025-02-19 17:51:49 +01:00
7943a36b0a Add Changelog.md
All checks were successful
CI / ci (push) Successful in 26s
2025-02-19 17:49:31 +01:00
0c82c4ecf8 Allow to configure NetBox cluster ID
All checks were successful
CI / ci (push) Successful in 33s
Closes: #5
2025-02-19 17:42:02 +01:00
4 changed files with 82 additions and 14 deletions

35
Changelog.md Normal file
View file

@ -0,0 +1,35 @@
# netbox-pve-sync
## [Unreleased]
## [0.2.2] - 07/05/2025
### Fixed
- Use `NB_CLUSTER_ID` even for VM update.
## [0.2.1] - 01/05/2025
### Fixed
- [#7] Improve tag handling.
## [0.2.0] - 21/04/2025
### New
- Monitoring PVE HA/Replication.
## [0.1.1] - 19/02/2025
### New
- [#5] Allow to configure cluster ID.
### Changed
- Add eth0 as raw_interface_name.
## [0.1.0] - 19/02/2025
- Initial release.

View file

@ -9,6 +9,12 @@ This script work by pulling VMs information from the PVE API and create/update/d
## Installation
This package is available on PyPi. You can install it using pip.
```
$ pip install netbox-pve-sync
```
## Configuration
### On NetBox
@ -21,6 +27,9 @@ The following env variables will need to be set:
- **NB_API_URL**: The URL to your NetBox instance. (ex: https://netbox.example.org)
- **NB_API_TOKEN**: The token created previously. (ex: f74cb99cf552b7005fd1a616b53efba2ce0c9656)
You can also set the `NB_CLUSTER_ID` env variable in order to indicate the ID of the cluster that will be used in
NetBox.
You'll also need to perform a minimal configuration on NetBox:
- Create the physical nodes hosting the cluster. (The name should match the one on Proxmox, so that the script can
@ -28,17 +37,19 @@ You'll also need to perform a minimal configuration on NetBox:
- Create the cluster.
- Add the following Custom Fields:
| Name | Object types | Label | Type |
|-----------|-----------------|-----------|---------|
| autostart | Virtual Machine | Autostart | Boolean |
| backup | Virtual Disk | Backup | Boolean |
| dns_name | Prefix | DNS Name | Text |
| Name | Object types | Label | Type |
|------------|-----------------|------------|---------|
| autostart | Virtual Machine | Autostart | Boolean |
| replicated | Virtual Machine | Replicated | Boolean |
| ha | Virtual Machine | Failover | Boolean |
| backup | Virtual Disk | Backup | Boolean |
| dns_name | Prefix | DNS Name | Text |
### On the PVE API
You'll need to create a dedicated user (ex: netsync) on your PVE cluster and then create an API token.
The user needs to have access to the VM.Monitor, Pool.Audit, VM.Audit permissions.
The user needs to have access to the VM.Monitor, Pool.Audit, VM.Audit, Sys.Audit permissions.
The following env variables will need to be set:
@ -52,5 +63,5 @@ The following env variables will need to be set:
You can then execute the script using the following command:
```
PVE_API_HOST=xx PVE_API_USER=xx PVE_API_TOKEN=xx PVE_API_SECRET=xx NB_API_URL=xx NB_API_TOKEN=xx python3 -m netbox_pve_sync
```
PVE_API_HOST=xx PVE_API_USER=xx PVE_API_TOKEN=xx PVE_API_SECRET=xx NB_API_URL=xx NB_API_TOKEN=xx nbpxsync
```

View file

@ -88,6 +88,7 @@ def _process_pve_tags(
slug=f'pool-{_pve_pool["poolid"]}'.lower(),
description=f'Proxmox pool {_pve_pool["poolid"]}',
)
_nb_objects['tags'][_nb_tag.name] = _nb_tag
return _nb_objects
@ -98,7 +99,9 @@ def _process_pve_virtual_machine(
_nb_objects: dict,
_nb_device: any,
_pve_tags: [str],
_pve_virtual_machine: dict
_pve_virtual_machine: dict,
_is_replicated: bool,
_has_ha: bool,
) -> dict:
_pve_node_name = _nb_device.name.lower()
@ -125,7 +128,7 @@ def _process_pve_virtual_machine(
serial=_pve_virtual_machine['vmid'],
name=_pve_virtual_machine['name'],
site=_nb_device.site.id,
cluster=1, # TODO
cluster=os.environ.get('NB_CLUSTER_ID', 1),
device=_nb_device.id,
vcpus=pve_virtual_machine_config['cores'],
memory=int(pve_virtual_machine_config['memory']),
@ -133,18 +136,22 @@ def _process_pve_virtual_machine(
tags=list(map(lambda _pve_tag_name: _nb_objects['tags'][_pve_tag_name].id, _pve_tags)),
custom_fields={
'autostart': pve_virtual_machine_config.get('onboot') == 1,
'replicated': _is_replicated,
'ha': _has_ha,
}
)
else:
nb_virtual_machine.name = _pve_virtual_machine['name']
nb_virtual_machine.site = _nb_device.site.id
nb_virtual_machine.cluster = 1
nb_virtual_machine.cluster = os.environ.get('NB_CLUSTER_ID', 1)
nb_virtual_machine.device = _nb_device.id
nb_virtual_machine.vcpus = pve_virtual_machine_config['cores']
nb_virtual_machine.memory = int(pve_virtual_machine_config['memory'])
nb_virtual_machine.status = 'active' if _pve_virtual_machine['status'] == 'running' else 'offline'
nb_virtual_machine.tags = list(map(lambda _pve_tag_name: _nb_objects['tags'][_pve_tag_name].id, _pve_tags))
nb_virtual_machine.custom_fields['autostart'] = pve_virtual_machine_config.get('onboot') == 1
nb_virtual_machine.custom_fields['replicated'] = _is_replicated
nb_virtual_machine.custom_fields['ha'] = _has_ha
nb_virtual_machine.save()
# Handle the VM network interfaces
@ -246,7 +253,7 @@ def _process_pve_virtual_machine_network_interface(
# TODO: Improve Multiple IP address handling
_pve_virtual_machine_ip_address = None
for raw_interface_name in ['ens18', 'ens19']:
for raw_interface_name in ['eth0', 'ens18', 'ens19']:
if raw_interface_name in _pve_virtual_machine_ip_addresses:
_pve_virtual_machine_ip_address = _pve_virtual_machine_ip_addresses[raw_interface_name][0]
break
@ -427,13 +434,25 @@ def main():
for pve_vm_resource in pve_api.cluster.resources.get(type='vm'):
pve_vm_tags[pve_vm_resource['vmid']] = []
pve_vm_tags[pve_vm_resource['vmid']].append(f'Pool/{pve_vm_resource["pool"]}')
if 'pool' in pve_vm_resource:
pve_vm_tags[pve_vm_resource['vmid']].append(f'Pool/{pve_vm_resource["pool"]}')
if 'tags' in pve_vm_resource:
pass # TODO: pve_vm_tags[pve_vm_resource['vmid']].append(pve_vm_resource['tags'])
pve_ha_virtual_machine_ids = list(
map(
lambda r: int(r['sid'].split(':')[1]),
filter(lambda r: r['type'] == 'service', pve_api.cluster.ha.status.current.get())
)
)
# Process Proxmox nodes
for pve_node in pve_api.nodes.get():
pve_replicated_virtual_machine_ids = list(
map(lambda r: r['guest'], pve_api.nodes(pve_node['node']).replication.get())
)
# This script does not create the hardware devices.
nb_device = nb_objects['devices'].get(pve_node['node'].lower())
if nb_device is None:
@ -452,6 +471,8 @@ def main():
nb_device,
pve_vm_tags.get(pve_virtual_machine['vmid'], []),
pve_virtual_machine,
pve_virtual_machine['vmid'] in pve_replicated_virtual_machine_ids,
pve_virtual_machine['vmid'] in pve_ha_virtual_machine_ids,
)

View file

@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "netbox-pve-sync"
version = "0.1.0"
version = "0.2.2"
authors = [
{ name = "Aloïs Micard", email = "alois@micard.lu" },
]
@ -26,6 +26,7 @@ dependencies = [
[project.urls]
Homepage = "https://git.creekorful.cloud/creekorful/netbox-pve-sync"
Issues = "https://git.creekorful.cloud/creekorful/netbox-pve-sync/issues"
Changelog = "https://git.creekorful.cloud/creekorful/netbox-pve-sync/src/branch/main/Changelog.md"
[project.scripts]
nbpxsync = "netbox_pve_sync:main"