Skip to content

Commit

Permalink
Save changes
Browse files Browse the repository at this point in the history
  • Loading branch information
emersonfelipesp committed Aug 15, 2024
1 parent 4ef2675 commit c3ac6d8
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 43 deletions.
3 changes: 2 additions & 1 deletion netbox_proxbox/backend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
from netbox_proxbox.backend.routes.netbox.dcim.device_roles import DeviceRole
from netbox_proxbox.backend.routes.netbox.dcim.device_types import DeviceType
from netbox_proxbox.backend.routes.netbox.dcim.devices import Device
from netbox_proxbox.backend.routes.netbox.dcim.interfaces import Interface
from netbox_proxbox.backend.routes.netbox.dcim.interfaces import Interface
from netbox_proxbox.backend.routes.netbox.ipam.ip_addresses import IPAddress
2 changes: 1 addition & 1 deletion netbox_proxbox/backend/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def setup_logger():
console_handler = logging.StreamHandler()

# Log all messages in the console
console_handler.setLevel(logging.ERROR)
console_handler.setLevel(logging.DEBUG)

# Create a formatter with colors
formatter = ColorizedFormatter('%(name)s [%(asctime)s] [%(levelname)-8s] %(module)s: %(message)s')
Expand Down
2 changes: 1 addition & 1 deletion netbox_proxbox/backend/routes/netbox/dcim/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ async def get_base_dict(self):
"device_type": device_type.id,
"status": "active",
"cluster": cluster.id
}
}
2 changes: 1 addition & 1 deletion netbox_proxbox/backend/routes/netbox/dcim/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Interface(NetboxBase):

app = "dcim"
endpoint = "interfaces"
object_name = "Device"
object_name = "Interface"

async def get_base_dict(self):
device = await Device(nb = self.nb).get()
Expand Down
98 changes: 74 additions & 24 deletions netbox_proxbox/backend/routes/netbox/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,16 @@ def __init__(
),
Doc(
"Ignore Proxbox tag filter when searching for objects in Netbox. This will return all Netbox objects, not only Proxbox related ones."
)

),
] = False,
primary_field_value: str = None,
):
self.nb = nb
self.id = id
self.all = all
self.default = default
self.ignore_tag = ignore_tag
self.primary_field_value = primary_field_value
#self.default_extra_fields = default_extra_fields

self.pynetbox_path = getattr(getattr(self.nb.session, self.app), self.endpoint)
Expand Down Expand Up @@ -98,7 +99,7 @@ async def get_base_dict(self):
app = None
endpoint = None
object_name = None

primary_field = None

async def get(
self,
Expand Down Expand Up @@ -302,17 +303,18 @@ async def post(

# If no explicit slug was provided by the payload, create one based on the name.
if data.get("slug") == None:
logger.info("[POST] SLUG field not provided on the payload. Creating one based on the NAME or MODEL field.")
try:
data["slug"] = data.get("name").replace(" ", "-").lower()
except AttributeError:

if not self.primary_field:
logger.info("[POST] SLUG field not provided on the payload. Creating one based on the NAME or MODEL field.")
try:
data["slug"] = data.get("model").replace(" ", "-").lower()
data["slug"] = data.get("name").replace(" ", "-").lower()
except AttributeError:
raise ProxboxException(
message=f"[POST] No 'name' or 'model' field provided on the payload. Please provide one of them.",
)

try:
data["slug"] = data.get("model").replace(" ", "-").lower()
except AttributeError:
raise ProxboxException(
message=f"[POST] No 'name' or 'model' field provided on the payload. Please provide one of them.",
)

if self.default or data == None:
logger.info(f"[POST] Creating DEFAULT '{self.object_name}' object on Netbox.")
Expand Down Expand Up @@ -413,15 +415,62 @@ async def _check_duplicate(self, search_params: dict = None, object: dict = None

if object:
try:
if (self.primary_field):
logger.info("[CHECK DUPLICATE] (0.5) Checking object using only custom PRIMARY FIELD and Proxbox TAG provided by the class attribute.")
print(f"primary field: {self.primary_field} - primary_field_value: {self.primary_field_value}")

if self.primary_field == "address":
result_by_primary = await asyncio.to_thread(self.pynetbox_path.get, address=self.primary_field_value)
else:
result_by_primary = await asyncio.to_thread(self.pynetbox_path.get,
{
f"{self.primary_field}": self.primary_field_value,
}
)

print(f"result_by_primary: {result_by_primary}")
if result_by_primary:
logger.info(f"[CHECK_DUPLICATE] Object found on Netbox. Returning it.")
print(f'result_by_primary: {result_by_primary}')
return result_by_primary

return None

logger.info("[CHECK DUPLICATE] (1) First attempt: Checking object making EXACT MATCH with the Payload provided...")
result = await asyncio.to_thread(self.pynetbox_path.get, object)
result = await asyncio.to_thread(self.pynetbox_path.get, dict(object))

if result:
logger.info(f"[CHECK DUPLICATE] Object found on Netbox. Returning it.")
return result

else:
logger.info("[CHECK DUPLICATE] (2) Checking object using only NAME and SLUG provided by the Payload and also the PROXBOX TAG). If found, return it.")

logger.info("[CHECK DUPLICATE] (1.5) Checking object using NAME and DEVICE provided by the Payload and also the PROXBOX TAG. If found, return it.")

device_id = object.get("device")
device_obj = None
try:
device_obj = self.nb.dcim.devices.get(id=device_id)
print(device_obj)
except:
logger.info("[CHECK DUPLICATE] (1.5.1) Device Object not found when checking for duplicated using Device as parameter.")

if device_obj != None:
print(f"device_obj.name: {device_obj.name}")
result_by_device = await asyncio.to_thread(self.pynetbox_path.get,
name=object.get("name"),
#device__id=object.get("device"),
device=device_obj.name,
tag=[self.nb.tag.slug]
)

if result_by_device:
logger.info("[CHECK DUPLICATE] Object found on Netbox. Returning it.")
return result_by_device



logger.info("[CHECK DUPLICATE] (2) Checking object using only NAME and SLUG provided by the Payload and also the PROXBOX TAG. If found, return it.")
result_by_tag = await asyncio.to_thread(self.pynetbox_path.get,
name=object.get("name"),
slug=object.get("slug"),
Expand All @@ -432,17 +481,18 @@ async def _check_duplicate(self, search_params: dict = None, object: dict = None
logger.info(f"[CHECK DUPLICATE] Object found on Netbox. Returning it.")
return result_by_tag

else:
result_by_name_and_slug = await asyncio.to_thread(self.pynetbox_path.get,
name=object.get("name"),
slug=object.get("slug"),


result_by_name_and_slug = await asyncio.to_thread(self.pynetbox_path.get,
name=object.get("name"),
slug=object.get("slug"),
)

if result_by_name_and_slug:
raise ProxboxException(
message=f"[CHECK DUPLICATE] '{self.object_name}' with ID '{result_by_name_and_slug.id}' found on Netbox, but without Proxbox tag. Please delete it (or add the tag) and try again.",
detail="Netbox does not allow duplicated names and/or slugs."
)

if result_by_name_and_slug:
raise ProxboxException(
message=f"[CHECK DUPLICATE] '{self.object_name}' with ID '{result_by_name_and_slug.id}' found on Netbox, but without Proxbox tag. Please delete it (or add the tag) and try again.",
detail="Netbox does not allow duplicated names and/or slugs."
)

return None

Expand Down
Empty file.
16 changes: 16 additions & 0 deletions netbox_proxbox/backend/routes/netbox/ipam/ip_addresses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from netbox_proxbox.backend.routes.netbox.generic import NetboxBase

class IPAddress(NetboxBase):
# Default IP Address Params
default_description: str = "Proxbox Basic IP Address"

app: str = "ipam"
endpoint: str = "ip_addresses"
object_name: str = "IP Address"
primary_field: str = "address"

async def get_base_dict(self):
return {
"description": self.default_description,
"status": "active"
}
125 changes: 110 additions & 15 deletions netbox_proxbox/backend/routes/proxbox/clusters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
Device,
VirtualMachine,
Interface,
IPAddress,
)

router = APIRouter()
Expand Down Expand Up @@ -89,6 +90,24 @@ async def proxbox_get_clusters(

return result


def find_interface_type(
proxmox_int_type: str,
proxmox_int_name: str
):
if proxmox_int_type == "eth":

if 'eno' in proxmox_int_name: interface_type = '1000base-t'
elif 'en' in proxmox_int_name: interface_type = '10gbase-t'

elif proxmox_int_type == "bridge": interface_type = proxmox_int_type
elif proxmox_int_type == "bond": interface_type = 'lag'
else: interface_type = 'other'

print(f'interface_type: {interface_type} / {type(interface_type)}')
return str(interface_type)


@router.get("/nodes")
async def get_nodes(
nb: NetboxSessionDep,
Expand Down Expand Up @@ -131,26 +150,21 @@ async def get_nodes(
print("\n")

for interface in node_interfaces:
interface_type = None
interface_type = find_interface_type(
interface.get("type"),
interface.get("iface")
)
print(f'[0] interface: {interface}')
print(f'interface_type: {interface_type}')
interface_name = interface.get("iface")
interface_px_type = interface.get("type")

if interface.get("active") == 1:
enabled = True
else: enabled = False

if interface_px_type == "eth":

if 'eno' in interface_name: interface_type = '1000base-t'
elif 'en' in interface_name: interface_type = '10gbase-t'

else: interface_name = 'other'

elif interface_px_type == "bridge": interface_type = 'bridge'

elif interface_px_type == "bond": interface_type = 'lag'
if interface.get("active") == 1:
enabled = True
else: enabled = False

else: interface_type = 'other'

create_interface = await Interface(nb=nb).post(data={
"device": current_node.id,
Expand All @@ -160,8 +174,89 @@ async def get_nodes(
"mtu": interface.get("mtu", None),
"description": interface.get("comments", "")
})

print(f'create_interface: {create_interface}')
print(interface)

print(f"interface value type: {type(interface)}")

cidr = interface.get("cidr")
print(f"cidr: {cidr}")

if create_interface and cidr:
logger.info("Interface with CIDR/Network. Creating the IP Address object on Netbox...")
# If interface with network configured, create IP Address and attach interface to it.
create_ipaddress = await IPAddress(nb=nb, primary_field_value=cidr).post(data={
"address": cidr,
"assigned_object_id": create_interface.id,
"assigned_object_type": "dcim.interface"
})
print(f'create_ipaddress: {create_ipaddress}')



if interface_type == "bridge":

bridge_ports = interface.get("bridge_ports")
print(f'bridge_ports: {bridge_ports}')
if bridge_ports:
bridge_ports = bridge_ports.split(" ")


for port in bridge_ports:
print(f'current_node: {current_node}')

netbox_port = await Interface(nb=nb).get(
device=current_node.name,
name=port
)
print(f"port: {port}")
print(f"netbox_port: {netbox_port}")
if not netbox_port:

proxmox_port = px.session.nodes(node.get("node")).network(port).get()

print(f"proxmox_port: {proxmox_port}")

if proxmox_port.get("active") == 1:
enabled = True
else: enabled = False

# Interface and Bridge Interface must belong to the same Device
if create_interface.device == current_node.id:
print("Creating interface...")
new_netbox_port = await Interface(nb=nb).post(data={
"device": current_node.id,
"name": port,
"enabled": enabled,
"type": interface_type,
"mtu": proxmox_port.get("mtu", None),
"description": proxmox_port.get("comments", ""),
"bridge": create_interface.id
})

cidr = proxmox_port.get("cidr")
print(f"[2] cidr: {cidr}")

if cidr:
# If interface with network configured, create IP Address and attach interface to it.
create_ipaddress = await IPAddress(nb=nb, primary_field_value=cidr).post(data={
"address": cidr,
"assigned_object_id": new_netbox_port.id,
"assigned_object_type": "dcim.interface"
})



else:
print("Interface already exists. Attaching Bridge to Interface")
print(f'create_interface: {create_interface}')
# Interface and Bridge Interface must belong to the same Device
if create_interface.device == current_node.id:
netbox_port.bridge = create_interface.id
netbox_port.device = current_node.id
netbox_port.save()

print(f'interface: {interface}')

print("\n")

Expand Down

0 comments on commit c3ac6d8

Please sign in to comment.