Compare commits
2 commits
20cdbfc499
...
eb663ee3c6
Author | SHA1 | Date | |
---|---|---|---|
eb663ee3c6 | |||
685e8ac589 |
4 changed files with 35 additions and 8 deletions
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.2.0] - 21/04/2025
|
||||||
|
|
||||||
|
### New
|
||||||
|
|
||||||
|
- Monitoring PVE HA/Replication.
|
||||||
|
|
||||||
## [0.1.1] - 19/02/2025
|
## [0.1.1] - 19/02/2025
|
||||||
|
|
||||||
### New
|
### New
|
||||||
|
|
14
README.md
14
README.md
|
@ -34,17 +34,19 @@ You'll also need to perform a minimal configuration on NetBox:
|
||||||
- Create the cluster.
|
- Create the cluster.
|
||||||
- Add the following Custom Fields:
|
- Add the following Custom Fields:
|
||||||
|
|
||||||
| Name | Object types | Label | Type |
|
| Name | Object types | Label | Type |
|
||||||
|-----------|-----------------|-----------|---------|
|
|------------|-----------------|------------|---------|
|
||||||
| autostart | Virtual Machine | Autostart | Boolean |
|
| autostart | Virtual Machine | Autostart | Boolean |
|
||||||
| backup | Virtual Disk | Backup | Boolean |
|
| replicated | Virtual Machine | Replicated | Boolean |
|
||||||
| dns_name | Prefix | DNS Name | Text |
|
| ha | Virtual Machine | Failover | Boolean |
|
||||||
|
| backup | Virtual Disk | Backup | Boolean |
|
||||||
|
| dns_name | Prefix | DNS Name | Text |
|
||||||
|
|
||||||
### On the PVE API
|
### On the PVE API
|
||||||
|
|
||||||
You'll need to create a dedicated user (ex: netsync) on your PVE cluster and then create an API token.
|
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:
|
The following env variables will need to be set:
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,9 @@ def _process_pve_virtual_machine(
|
||||||
_nb_objects: dict,
|
_nb_objects: dict,
|
||||||
_nb_device: any,
|
_nb_device: any,
|
||||||
_pve_tags: [str],
|
_pve_tags: [str],
|
||||||
_pve_virtual_machine: dict
|
_pve_virtual_machine: dict,
|
||||||
|
_is_replicated: bool,
|
||||||
|
_has_ha: bool,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
_pve_node_name = _nb_device.name.lower()
|
_pve_node_name = _nb_device.name.lower()
|
||||||
|
|
||||||
|
@ -133,6 +135,8 @@ def _process_pve_virtual_machine(
|
||||||
tags=list(map(lambda _pve_tag_name: _nb_objects['tags'][_pve_tag_name].id, _pve_tags)),
|
tags=list(map(lambda _pve_tag_name: _nb_objects['tags'][_pve_tag_name].id, _pve_tags)),
|
||||||
custom_fields={
|
custom_fields={
|
||||||
'autostart': pve_virtual_machine_config.get('onboot') == 1,
|
'autostart': pve_virtual_machine_config.get('onboot') == 1,
|
||||||
|
'replicated': _is_replicated,
|
||||||
|
'ha': _has_ha,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -145,6 +149,8 @@ def _process_pve_virtual_machine(
|
||||||
nb_virtual_machine.status = 'active' if _pve_virtual_machine['status'] == 'running' else 'offline'
|
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.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['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()
|
nb_virtual_machine.save()
|
||||||
|
|
||||||
# Handle the VM network interfaces
|
# Handle the VM network interfaces
|
||||||
|
@ -432,8 +438,19 @@ def main():
|
||||||
if 'tags' in pve_vm_resource:
|
if 'tags' in pve_vm_resource:
|
||||||
pass # TODO: pve_vm_tags[pve_vm_resource['vmid']].append(pve_vm_resource['tags'])
|
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
|
# Process Proxmox nodes
|
||||||
for pve_node in pve_api.nodes.get():
|
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.
|
# This script does not create the hardware devices.
|
||||||
nb_device = nb_objects['devices'].get(pve_node['node'].lower())
|
nb_device = nb_objects['devices'].get(pve_node['node'].lower())
|
||||||
if nb_device is None:
|
if nb_device is None:
|
||||||
|
@ -452,6 +469,8 @@ def main():
|
||||||
nb_device,
|
nb_device,
|
||||||
pve_vm_tags.get(pve_virtual_machine['vmid'], []),
|
pve_vm_tags.get(pve_virtual_machine['vmid'], []),
|
||||||
pve_virtual_machine,
|
pve_virtual_machine,
|
||||||
|
pve_virtual_machine['vmid'] in pve_replicated_virtual_machine_ids,
|
||||||
|
pve_virtual_machine['vmid'] in pve_ha_virtual_machine_ids,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "netbox-pve-sync"
|
name = "netbox-pve-sync"
|
||||||
version = "0.1.1"
|
version = "0.2.0"
|
||||||
authors = [
|
authors = [
|
||||||
{ name = "Aloïs Micard", email = "alois@micard.lu" },
|
{ name = "Aloïs Micard", email = "alois@micard.lu" },
|
||||||
]
|
]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue