Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
29b0296
fixes typos
bb-Ricardo Nov 20, 2024
08b244a
mitigates issue of pruning newly used tags #401
bb-Ricardo Nov 20, 2024
13685c5
adds config options vlan_group_relation_by_name and vlan_group_relati…
bb-Ricardo Nov 22, 2024
1a0c742
reduce docker file size
bb-Ricardo Nov 27, 2024
740f1e1
fixes issue with vlan filter #373
bb-Ricardo Nov 28, 2024
9d11567
fixes issue with redfish source and sorting resource with no names
bb-Ricardo Dec 12, 2024
26a2281
adds config option disable collection of ESXi serial #428
bb-Ricardo Dec 12, 2024
849bd27
add the 'serial' field to NetBox VirtualMachine and set it from VMWar…
joachimBurket Jan 23, 2025
2963de5
only set the 'serial' field for NetBox version >=4.1.0
joachimBurket Jan 23, 2025
5b54f04
Merge pull request #435 from joachimBurket/feat/set-vm-serial-number-…
bb-Ricardo Jan 30, 2025
9400b16
adds support for 'primary_mac_address' in NetBox 4.2 #436
bb-Ricardo Jan 31, 2025
80ac276
adds support for site scope on cluster object in NetBox 4.2.0 #436
bb-Ricardo Feb 19, 2025
13311ab
adds vm guest prettyName in order to extract correct VM platform #429
bb-Ricardo Feb 19, 2025
f88c5f7
adds possibility to match VM by serial for NetNox >= 4.1 instances
bb-Ricardo Feb 19, 2025
04cb13c
adds custom field for host power status and combines two others #379 …
bb-Ricardo Feb 20, 2025
c12cb81
improves the vlan group relation settings #373
bb-Ricardo Feb 21, 2025
c783da6
fixes issue with tagging of VLANs if VLAN sync is disabled #392
bb-Ricardo Feb 21, 2025
1117bf1
fixes issue with mac address wrongly tagged orphaned
bb-Ricardo Feb 21, 2025
e5619c3
better mitigates issue with assigning VLAN groups #373
bb-Ricardo Feb 22, 2025
ff49570
adds check if permitted subnet contains prefix length #441
bb-Ricardo Feb 24, 2025
6274052
skip IP address handling if no VMWare tools are installed or if VM is…
bb-Ricardo Feb 24, 2025
e798b30
fixes issue with reassigned IP addresses of subinterfaces within VM #302
bb-Ricardo Feb 24, 2025
758e864
ignore reassignment and deletion if IP has role anycast #344
bb-Ricardo Feb 24, 2025
eebede0
fixes implementation for guest tools prettyName #429
bb-Ricardo Feb 25, 2025
c47e4ae
bumps version to 1.8.0
bb-Ricardo Feb 26, 2025
d7ca5d3
adds config option 'vm_exclude_by_tag_filter' #393
bb-Ricardo Feb 26, 2025
8f9fa01
fixes issue with finding ip prefixx in NetBox 4.2 and reassignes VRFs…
bb-Ricardo Feb 26, 2025
64f1c3a
fixes issue with detection of running guest tools #326 #443
bb-Ricardo Feb 27, 2025
c6d617c
improves handling of object scopes
bb-Ricardo Feb 28, 2025
4a61095
adds CDP info to ESXi host nic description if available #350
bb-Ricardo Mar 3, 2025
ae5246f
fixes issue with properly assigned MAC addresses
bb-Ricardo Mar 3, 2025
341e6ec
bump version to 1.8.0 and current date
bb-Ricardo Mar 7, 2025
2e4c0f3
adds note about issue with VLAN group
bb-Ricardo Mar 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@ FROM python:3.11-slim-bookworm AS builder

COPY requirements.txt .

ARG VENV=/opt/netbox-sync/venv

# Install dependencies
RUN apt-get update && apt-get install -y --no-install-recommends git && \
rm -rf /var/lib/apt/lists/* && \
python3 -m venv /opt/netbox-sync/venv && \
/opt/netbox-sync/venv/bin/python3 -m pip install --upgrade pip && \
/opt/netbox-sync/venv/bin/pip install -r requirements.txt && \
/opt/netbox-sync/venv/bin/pip install --upgrade git+https://github.com/vmware/vsphere-automation-sdk-python.git
python3 -m venv $VENV && \
$VENV/bin/python3 -m pip install --upgrade pip && \
$VENV/bin/pip install -r requirements.txt && \
$VENV/bin/pip install --upgrade git+https://github.com/vmware/vsphere-automation-sdk-python.git && \
find $VENV -type d -name "__pycache__" -print0 | xargs -0 -n1 rm -rf

FROM python:3.11-slim-bookworm AS netbox-sync

ARG VENV=/opt/netbox-sync/venv

# Copy installed packages
COPY --from=builder /opt/netbox-sync/venv /opt/netbox-sync/venv
COPY --from=builder $VENV $VENV

# Add netbox-sync user
RUN groupadd --gid 1000 netbox-sync && \
Expand All @@ -27,7 +32,7 @@ WORKDIR /app
COPY --chown=netbox-sync:netbox-sync . .

# Use virtual env packages and allow timezone setup
ENV PATH=/opt/netbox-sync/venv/bin:$PATH
ENV PATH=$VENV/bin:$PATH
ENV TZ=Europe/Berlin

ENTRYPOINT ["python3", "netbox-sync.py"]
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020 - 2021 Ricardo Bartels
Copyright (c) 2020 - 2025 Ricardo Bartels

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ usage: netbox-sync.py [-h] [-c settings.ini [settings.ini ...]] [-g]

Sync objects from various sources to NetBox

Version: 1.7.0 (2024-10-21)
Version: 1.8.0 (2025-03-07)
Project URL: https://github.com/bb-ricardo/netbox-sync

options:
Expand Down
4 changes: 2 additions & 2 deletions docs/source_vmware.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ IP addresses and interfaces will be added to NetBox.
Try to find object first based on the object data, interface MAC addresses and primary IPs.
1. try to find by name and cluster/site
2. try to find by mac addresses interfaces
3. try to find by serial number (1st) or asset tag (2nd) (ESXi host)
3. try to find by serial number (1st) or asset tag (2nd)
4. try to find by primary IP

### Finding hosts and VMs from discovered data
Expand All @@ -49,7 +49,7 @@ If two or more NetBox object (device, vm) with matching MACs were found, compare
NetBox object (device, vm) with the highest amount of matching interfaces. If the ratio of matching interface
MAC addresses exceeds 2.0 then the top matching NetBox object (device, vm) is chosen as desired object.

If the ratio is below 2.0 then None will be chosen. The probability is to low that
If the ratio is below 2.0 then None will be chosen. The probability is too low that
this one is the correct one.

#### 3. Try to find a NetBox object based on the primary IP (v4 or v6) address
Expand Down
6 changes: 3 additions & 3 deletions module/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
# This work is licensed under the terms of the MIT license.
# For a copy, see file LICENSE.txt included in this
# repository or visit: <https://opensource.org/licenses/MIT>.

__version__ = "1.7.0"
__version_date__ = "2024-10-21"
__version__ = "1.8.0"
__version_date__ = "2025-03-07"
__author__ = "Ricardo Bartels <ricardo.bartels@telekom.de>"
__description__ = "NetBox Sync"
__license__ = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion module/common/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down
4 changes: 2 additions & 2 deletions module/common/cli_parser.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand All @@ -23,7 +23,7 @@ def parse_command_line(self_description=None):
Parameters
----------
self_description: str
short self description of this program
short self-description of this program

Returns
-------
Expand Down
2 changes: 1 addition & 1 deletion module/common/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down
2 changes: 1 addition & 1 deletion module/common/logging.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down
6 changes: 3 additions & 3 deletions module/common/misc.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand All @@ -15,7 +15,7 @@ def grab(structure=None, path=None, separator=".", fallback=None):
"""
get data from a complex object/json structure with a
"." separated path information. If a part of a path
is not not present then this function returns the
is not present then this function returns the
value of fallback (default: "None").

example structure:
Expand All @@ -38,7 +38,7 @@ def grab(structure=None, path=None, separator=".", fallback=None):
Parameters
----------
structure: dict, list, object
object structure to extract data from
an object structure to extract data from
path: str
nested path to extract
separator: str
Expand Down
6 changes: 3 additions & 3 deletions module/common/support.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down Expand Up @@ -51,9 +51,9 @@ def perform_ptr_lookups(ips, dns_servers=None):
Parameters
----------
ips: list
list of IP addresses to look up
a list of IP addresses to look up
dns_servers: list
list of DNS servers to use to look up list of IP addresses
a list of DNS servers to use to look up list of IP addresses

Returns
-------
Expand Down
2 changes: 1 addition & 1 deletion module/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down
6 changes: 5 additions & 1 deletion module/config/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down Expand Up @@ -30,6 +30,10 @@ def __eq__(self, other):
def __contains__(self, key):
return key in self.__dict__

def __getattr__(self, item):
if item in self:
return getattr(self, item)
return None

class ConfigBase:
"""
Expand Down
2 changes: 1 addition & 1 deletion module/config/file_output.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down
2 changes: 1 addition & 1 deletion module/config/files.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down
2 changes: 1 addition & 1 deletion module/config/formatter.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down
2 changes: 1 addition & 1 deletion module/config/group.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down
2 changes: 1 addition & 1 deletion module/config/option.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down
2 changes: 1 addition & 1 deletion module/config/parser.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down
5 changes: 4 additions & 1 deletion module/netbox/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand All @@ -16,9 +16,11 @@
NBTagList,
NBTenant,
NBSite,
NBSiteGroup,
NBVRF,
NBVLAN,
NBVLANList,
NBVLANGroup,
NBPrefix,
NBManufacturer,
NBDeviceType,
Expand All @@ -33,6 +35,7 @@
NBVirtualDisk,
NBInterface,
NBIPAddress,
NBMACAddress,
NBFHRPGroupItem,
NBInventoryItem,
NBPowerPort
Expand Down
2 changes: 1 addition & 1 deletion module/netbox/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down
31 changes: 16 additions & 15 deletions module/netbox/connection.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2023 Ricardo Bartels. All rights reserved.
# Copyright (c) 2020 - 2025 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
Expand Down Expand Up @@ -217,20 +217,20 @@ def request(self, object_class, req_type="GET", data=None, params=None, nb_id=No

Parameters
----------
object_class: NetBoxObject sub class
object_class: NetBoxObject subclass
class definition of the desired NetBox object
req_type: str
GET, PATCH, PUT, DELETE
data: dict
data which shall be send to NetBox
data which shall be sent to NetBox
params: dict
dict of URL params which should be passed to NetBox
dictionary of URL params which should be passed to NetBox
nb_id: int
ID of the NetBox object which will be appended to the requested NetBox URL

Returns
-------
(dict, bool, None): of returned NetBox data. If object was requested to be deleted and it was
dict, bool, None: of returned NetBox data. If object was requested to be deleted, and it was
successful then True will be returned. None if request failed or was empty
"""

Expand Down Expand Up @@ -373,12 +373,12 @@ def query_current_data(self, netbox_objects_to_query=None):
"""
Request all current NetBox objects. Use caching whenever possible.
Objects must provide "last_updated" attribute to support caching for this object type.
Otherwise it's not possible to query only changed objects since last run. If attribute is
Otherwise, it's not possible to query only changed objects since last run. If attribute is
not present all objects will be requested (looking at you *Interfaces)

Parameters
----------
netbox_objects_to_query: list of NetBoxObject sub classes
netbox_objects_to_query: list of NetBoxObject subclasses
NetBox items to query

"""
Expand Down Expand Up @@ -585,14 +585,14 @@ def initialize_basic_data(self):

def update_object(self, nb_object_sub_class, unset=False, last_run=False):
"""
Iterate over all objects of a certain NetBoxObject sub class and add/update them.
Iterate over all objects of a certain NetBoxObject subclass and add/update them.
But first update objects which this object class depends on.
If some dependencies are unresolvable then these will be removed from the request
and re added later to the object to try update object in a third run.

Parameters
----------
nb_object_sub_class: NetBoxObject sub class
nb_object_sub_class: NetBoxObject subclass
NetBox objects to update
unset: bool
True if only unset items should be deleted
Expand Down Expand Up @@ -650,17 +650,18 @@ def update_object(self, nb_object_sub_class, unset=False, last_run=False):
# resolve dependency issues in last run
# primary IP always set in last run
if value.get_nb_reference() is None or \
(key.startswith("primary_ip") and last_run is False):
(key.startswith("primary_ip") and last_run is False) or \
(key.startswith("primary_mac_address") and last_run is False):
unresolved_dependency_data[key] = value
else:
data_to_patch[key] = value.get_nb_reference()

else:
data_to_patch[key] = value

# special case for IP address
if isinstance(this_object, NBIPAddress):
# if object is new and and has no id, then we need to remove assigned_object_type from data_to_patch
# special case for IP and MAC addresses
if isinstance(this_object, (NBIPAddress, NBMACAddress)):
# if object is new and has no id, then we need to remove assigned_object_type from data_to_patch
if "assigned_object_id" in unresolved_dependency_data.keys() and \
"assigned_object_type" in data_to_patch.keys():
del data_to_patch["assigned_object_type"]
Expand All @@ -674,7 +675,7 @@ def update_object(self, nb_object_sub_class, unset=False, last_run=False):
req_type = "POST"
action = "Creating new"

# if its not a new object then update it
# if it's not a new object then update it
if this_object.is_new is False:
nb_id = this_object.nb_id
req_type = "PATCH"
Expand Down Expand Up @@ -928,7 +929,7 @@ def delete_unused_tags(self):
if tag_description is None or not tag_description.startswith(self.primary_tag):
continue

if tag_tagged_items is None or tag_tagged_items != 0:
if tag_tagged_items is None or tag_tagged_items != 0 or this_tag.used is True:
continue

log.info(f"Deleting unused tag '{this_tag.get_display_name()}'")
Expand Down
Loading
Loading