From 0a59d25158b87690ed016f05561432c846dee8e4 Mon Sep 17 00:00:00 2001 From: Emerson Felipe Date: Mon, 14 Oct 2024 14:50:20 +0000 Subject: [PATCH] Add scrollable div sticking to bottom log messsages --- .../backend/routes/netbox/generic.py | 87 +-- .../templates/netbox_proxbox/home.html | 531 +++++++++--------- 2 files changed, 287 insertions(+), 331 deletions(-) diff --git a/netbox_proxbox/backend/routes/netbox/generic.py b/netbox_proxbox/backend/routes/netbox/generic.py index 8252027..4aaf76b 100755 --- a/netbox_proxbox/backend/routes/netbox/generic.py +++ b/netbox_proxbox/backend/routes/netbox/generic.py @@ -580,16 +580,16 @@ async def _check_duplicate(self, search_params: dict = None, object: dict = None return None - await log(self.websocket, " (1) First attempt: Checking object making EXACT MATCH with the Payload provided...") + await log(self.websocket, " (1) First attempt: Checking object making EXACT MATCH with the Payload provided...") result = await asyncio.to_thread(self.pynetbox_path.get, dict(object)) if result: - await log(self.websocket, f" Object found on Netbox. Returning it.") + await log(self.websocket, f" Object found on Netbox. Returning it.") return result else: - await log(self.websocket, " (1.5) Checking object using NAME and DEVICE provided by the Payload and also the PROXBOX TAG. If found, return it.") + await log(self.websocket, " (1.5) Checking object using NAME and DEVICE provided by the Payload and also the PROXBOX TAG. If found, return it.") result_by_device = None @@ -598,7 +598,7 @@ async def _check_duplicate(self, search_params: dict = None, object: dict = None print(f"object: {object}") device_obj = None try: - await log(self.websocket, " (1.5.1) Checking duplicate using Device Object as parameter.") + await log(self.websocket, " (1.5.1) Checking duplicate using Device Object as parameter.") device_obj = self.nb.session.dcim.devices.get(int(device_id)) print(f"device_obj: {device_obj}") @@ -616,7 +616,7 @@ async def _check_duplicate(self, search_params: dict = None, object: dict = None except: - await log(self.websocket, " (1.5.1) Device Object NOT found when checking for duplicated using Device as parameter.") + await log(self.websocket, " (1.5.1) Device Object NOT found when checking for duplicated using Device as parameter.") if result_by_device: @@ -633,16 +633,16 @@ async def _check_duplicate(self, search_params: dict = None, object: dict = None if int(object.get("device")) != int(result_by_device.device.id): return None - await log(self.websocket, " (1.5.1) Object found on Netbox. Returning it.") + await log(self.websocket, " (1.5.1) Object found on Netbox. Returning it.") return result_by_device - await log(self.websocket, " (2) Checking object using only NAME and SLUG provided by the Payload and also the PROXBOX TAG. If found, return it.") + await log(self.websocket, " (2) Checking object using only NAME and SLUG provided by the Payload and also the PROXBOX TAG. If found, return it.") result_by_tag = None try: - await log(self.websocket, " (2.1) Searching object using 'get' method") + await log(self.websocket, " (2.1) Searching object using GET method") result_by_tag = await asyncio.to_thread(self.pynetbox_path.get, name=object.get("name"), slug=object.get("slug"), @@ -660,13 +660,13 @@ async def _check_duplicate(self, search_params: dict = None, object: dict = None ) if result_by_tag: - await log(self.websocket, " (2) More than one object found.") + await log(self.websocket, " (2) More than one object found.") for obj in result_by_tag: print(f"obj.id: {obj.device.id} / device_obj.id: {device_obj.id}") if int(obj.device.id) == int(device_obj.id): - await log(self.websocket, " (2) More than one object found, but returning with the same ID.") + await log(self.websocket, " (2) More than one object found, but returning with the same ID.") return obj return None print(f"filter: {result_by_tag}") @@ -676,11 +676,11 @@ async def _check_duplicate(self, search_params: dict = None, object: dict = None if result_by_tag: - await log(self.websocket, f" Object found on Netbox. Returning it.") + await log(self.websocket, f" Object found on Netbox. Returning it.") return result_by_tag - await log(self.websocket, f" (3) Checking duplicate object using only NAME and SLUG") + await log(self.websocket, f" (3) Checking duplicate object using only NAME and SLUG") result_by_name_and_slug = await asyncio.to_thread(self.pynetbox_path.get, name=object.get("name"), slug=object.get("slug"), @@ -688,71 +688,12 @@ async def _check_duplicate(self, search_params: dict = None, object: dict = None if result_by_name_and_slug: raise ProxboxException( - message=f" {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.", + message=f" {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 except ProxboxException as error: raise error - - #except Exception as error: - # raise ProxboxException( - # message=f" Error trying to create {self.object_name} on Netbox.", - # detail=f"Payload provided: {object}", - # python_exception=f"{error}" - # ) - return None - # name = search_params.get("name") - # slug = search_params.get("slug") - - # await log(self.websocket, f"Checking if {name} exists on Netbox.") - # """ - # Check if object exists on Netbox based on the dict provided. - # The fields used to distinguish duplicates are: - # - name - # - slug - # - tags - # """ - - # try: - # print(f"search_params: {search_params}") - # # Check if default object exists. - # search_result = self.pynetbox_path.get(name = name, slug = slug) - - # print(f"[get] search_result: {search_result}") - - # if search_result: - # return search_result - - # except ValueError as error: - # logger.warning(f"Mutiple objects by get() returned. Proxbox will use filter(), delete duplicate objects and return only the first one.\n > {error}") - # try: - - # search_result = self.pynetbox_path.filter(name = name, slug = slug) - - # # Create list of all objects returned by filter. - # delete_list = [item for item in search_result] - - # # Removes the first object from the list to return it. - # single_default = delete_list.pop(0) - - # # Delete all other objects from the list. - # self.pynetbox_path.delete(delete_list) - - # # Returns first element of the list. - # print(f"[get] search_result: {search_result}") - # return single_default - - # except ProxboxException as error: raise error - - # except Exception as error: - # raise ProxboxException( - - # message=f"Error trying to create default {self.object_name} on Netbox.", - # python_exception=f"{error}", - # detail=f"Multiple objects returned by filter. Please delete all objects with name '{self.default_dict.get('name')}' and slug '{self.default_dict.get('slug')}' and try again." - # ) - - # return None \ No newline at end of file + return None \ No newline at end of file diff --git a/netbox_proxbox/templates/netbox_proxbox/home.html b/netbox_proxbox/templates/netbox_proxbox/home.html index 7b5d4c8..8ce1063 100755 --- a/netbox_proxbox/templates/netbox_proxbox/home.html +++ b/netbox_proxbox/templates/netbox_proxbox/home.html @@ -9,287 +9,302 @@

Log Messages

--> -
    -
- + message.style.lineHeight = '170%' + //var breakLine = document.createElement('br') + + message.innerHTML = event.data -
- - + // var content = document.createTextNode(event.data) + // message.appendChild(content) + messages.appendChild(message) -
- {# Full Update Button#} -
- {% if perms.netbox_proxbox.add_proxmoxvm %} - Proxmox Full Update (probably not working on v4.0) - {% endif %} -
-
- {% if perms.netbox_proxbox.add_proxmoxvm %} - Proxmox Nodes Update - {% endif %} -
-
- {% if perms.netbox_proxbox.add_proxmoxvm %} - Proxmox Virtual Machines Update - {% endif %} -
-
- + var test = document.getElementById('scrollable-div') + test.scrollTop = test.scrollHeight + + messages.appendChild(breakLine) + + }; + function sendMessage(event) { + var input = document.getElementById("messageText") + ws.send(input.value) + input.value = '' + event.preventDefault() + } + + +
+ + +
+ {# Full Update Button#} +
+ {% if perms.netbox_proxbox.add_proxmoxvm %} + Proxmox Full Update (probably not working on v4.0) + {% endif %} +
+
+ {% if perms.netbox_proxbox.add_proxmoxvm %} + Proxmox Nodes Update + {% endif %} +
+
+ {% if perms.netbox_proxbox.add_proxmoxvm %} + Proxmox Virtual Machines Update + {% endif %} +
-
-

- Proxbox Configuration -

-
+
+
+ +
+

+ Proxbox Configuration +

+
- {% for px in configuration.netbox_proxbox.proxmox %} -
-
-
-
- - Proxmox Logo - -
-
- - - + {% for px in configuration.netbox_proxbox.proxmox %} +
+
+
+
+ + Proxmox Logo + +
+
+
Domain / IP
+ + + {% if px.domain %} + + {% else %} + + {% endif %} + + + + {% if px.http_port %} + + {% else %} + + {% endif %} + + + + {% if px.user %} + + {% else %} + + {% endif %} + + + + {% if px.password %} + + {% else %} + + {% endif %} + + + {% if px.token.name %} + + {% else %} + + {% endif %} + + + + + + + {% if px.ssl %} + + {% else %} + + {% endif %} + +
Domain / IP{{ px.domain }}{{ default_config.proxmox.domain }} (default)
HTTP Port{{ px.http_port }}{{ default_config.proxmox.http_port }} (default)
Proxmox User{{ px.user }}{{ default_config.proxmox.user }} (default)
Proxmox Passwordpassword defined in configuration.py(secret) (default)
Token Name{{ px.token.name }}{{ default_config.proxmox.token.name }} (default)
Token Value(secret)
SSL{{ px.ssl }}{{ default_config.proxmox.ssl }} (default)
+
{% if px.domain %} - {{ px.domain }} - {% else %} - {{ default_config.proxmox.domain }} (default) - {% endif %} - - - HTTP Port - {% if px.http_port %} - {{ px.http_port }} - {% else %} - {{ default_config.proxmox.http_port }} (default) - {% endif %} - - - Proxmox User - {% if px.user %} - {{ px.user }} - {% else %} - {{ default_config.proxmox.user }} (default) - {% endif %} - - - Proxmox Password - {% if px.password %} - password defined in configuration.py - {% else %} - (secret) (default) - {% endif %} - - Token Name - {% if px.token.name %} - {{ px.token.name }} +
+ + + Proxmox Update +
{% else %} - {{ default_config.proxmox.token.name }} (default) - {% endif %} - - Token Value - (secret) - - - SSL - {% if px.ssl %} - {{ px.ssl }} - {% else %} - {{ default_config.proxmox.ssl }} (default) - {% endif %} - - -
- {% if px.domain %} -
- - Proxmox Update -
- {% else %} - Proxmox Update - {% endif %} - + {% endif %} + +
-
- {% endfor %} -
-
-
-
- - Netbox Logo - -
-
- - - - {% if px.netbox.domain %} - - {% else %} - - {% endif %} - - - - {% if px.netbox.http_port %} - - {% else %} - - {% endif %} - - - - {% if px.netbox.token %} - - {% else %} - - {% endif %} - - - - {% if px.netbox.ssl %} - - {% else %} - - {% endif %} - -
Domain / IP{{ px.netbox.domain }}{{ default_config.netbox.domain }} (default)
HTTP Port{{ px.netbox.http_port }}{{ default_config.netbox.http_port }} (default)
Token{{ px.netbox.token }}{{ default_config.netbox.token }} (default)
SSL{{ px.netbox.ssl }}{{ default_config.netbox.ssl }} (default)
-
- + {% endfor %} +
+
+
+
+ + Netbox Logo + +
+
+ + + + {% if px.netbox.domain %} + + {% else %} + + {% endif %} + + + + {% if px.netbox.http_port %} + + {% else %} + + {% endif %} + + + + {% if px.netbox.token %} + + {% else %} + + {% endif %} + + + + {% if px.netbox.ssl %} + + {% else %} + + {% endif %} + +
Domain / IP{{ px.netbox.domain }}{{ default_config.netbox.domain }} (default)
HTTP Port{{ px.netbox.http_port }}{{ default_config.netbox.http_port }} (default)
Token{{ px.netbox.token }}{{ default_config.netbox.token }} (default)
SSL{{ px.netbox.ssl }}{{ default_config.netbox.ssl }} (default)
+
+ +
-
-
-
-
-
- - Netbox Logo - -
-
- - - - {% if configuration.netbox_proxbox.fastapi.uvicorn_host %} - - {% else %} - - {% endif %} - - - - {% if configuration.netbox_proxbox.fastapi.uvicorn_port %} - - {% else %} - - {% endif %} - -
Uvicorn Host{{ configuration.netbox_proxbox.fastapi.uvicorn_host }}{{ default_config.fastapi.uvicorn_host }} (default)
Uvicorn Port{{ configuration.netbox_proxbox.fastapi.uvicorn_port }}{{ default_config.fastapi.uvicorn_port }} (default)
-
- +
+
+
+
+ + Netbox Logo + +
+
+ + + + {% if configuration.netbox_proxbox.fastapi.uvicorn_host %} + + {% else %} + + {% endif %} + + + + {% if configuration.netbox_proxbox.fastapi.uvicorn_port %} + + {% else %} + + {% endif %} + +
Uvicorn Host{{ configuration.netbox_proxbox.fastapi.uvicorn_host }}{{ default_config.fastapi.uvicorn_host }} (default)
Uvicorn Port{{ configuration.netbox_proxbox.fastapi.uvicorn_port }}{{ default_config.fastapi.uvicorn_port }} (default)
+
+ +
-
- -

- -

-
-
-
-
-
- -

Configuration (PLUGINS_CONFIG)

-
- -
-
{{ configuration_json }}
+ +

+ +

+
+
+
+
+
+ +

Configuration (PLUGINS_CONFIG)

+
+ +
+
{{ configuration_json }}
+
-
- -
-
-
- -

Default Config

-
- -
-
{{ default_config_json }}
+ +
+
+
+ +

Default Config

+
+ +
+
{{ default_config_json }}
+