diff --git a/README.md b/README.md
index 67b6419..421e4e5 100755
--- a/README.md
+++ b/README.md
@@ -153,17 +153,19 @@ Replace the values with your own following the [Configuration Parameters](#2-con
```python
PLUGINS_CONFIG = {
'netbox_proxbox': {
- 'proxmox': {
- 'domain': 'proxbox.example.com', # May also be IP address
- 'http_port': 8006,
- 'user': 'root@pam', # always required
- 'password': 'Strong@P4ssword', # only required, if you don't want to use token based authentication
- 'token': {
- 'name': 'tokenID', # Only type the token name and not the 'user@pam:tokenID' format
- 'value': '039az154-23b2-4be0-8d20-b66abc8c4686'
- },
- 'ssl': False
- },
+ 'proxmox': [
+ {
+ 'domain': 'proxbox.example.com', # May also be IP address
+ 'http_port': 8006,
+ 'user': 'root@pam', # always required
+ 'password': 'Strong@P4ssword', # only required, if you don't want to use token based authentication
+ 'token': {
+ 'name': 'tokenID', # Only type the token name and not the 'user@pam:tokenID' format
+ 'value': '039az154-23b2-4be0-8d20-b66abc8c4686'
+ },
+ 'ssl': False
+ }
+ ],
'netbox': {
'domain': 'localhost', # Ensure localhost is added to ALLOWED_HOSTS
'http_port': 8001, # Gunicorn port.
@@ -194,6 +196,7 @@ PLUGINS_CONFIG = {
```
(venv) $ cd /opt/netbox/netbox/
(venv) $ python3 manage.py migrate
+(venv) $ python3 manage.py collectstatic --no-input
```
---
@@ -211,7 +214,7 @@ Restart the WSGI service to load the new plugin:
The following options are available:
-* `proxmox`: (Dict) Proxmox related configuration to use proxmoxer.
+* `proxmox`: (List) Proxmox related configuration to use proxmoxer.
* `proxmox.domain`: (String) Domain or IP address of Proxmox.
* `proxmox.http_port`: (Integer) Proxmox HTTP port (default: 8006).
* `proxmox.user`: (String) Proxmox Username.
diff --git a/netbox_custom_fields.csv b/netbox_custom_fields.csv
new file mode 100644
index 0000000..5d69a33
--- /dev/null
+++ b/netbox_custom_fields.csv
@@ -0,0 +1,5 @@
+Name,Content types,Label,Group name,Type,Required,Description,ID,Default,Search weight,Filter logic,UI visibility,Cloneable,Display weight,Choices,Created,Last updated
+proxmox_id,virtualization.virtualmachine,[Proxmox] ID,,Integer,False,Proxmox VM/CT ID,1,,1000,Loose,Read/Write,False,100,[],2023-07-06 12:49,2023-07-06 12:50
+proxmox_keep_interface,dcim.interface,,,Boolean (true/false),False,,4,,1000,Loose,Read/Write,False,100,[],2023-07-06 12:53,2023-07-06 12:53
+proxmox_node,virtualization.virtualmachine,[Proxmox] Node,,Text,False,Proxmox Node (Server),2,,1000,Loose,Read/Write,False,100,[],2023-07-06 12:51,2023-07-06 12:51
+proxmox_type,virtualization.virtualmachine,[Proxmox] Type,,Selection,False,Proxmox type (VM or CT),3,,1000,Loose,Read/Write,False,100,"['qemu', 'lxc']",2023-07-06 12:52,2023-07-06 12:52
diff --git a/netbox_proxbox/__init__.py b/netbox_proxbox/__init__.py
index 054f72f..bfb25f8 100755
--- a/netbox_proxbox/__init__.py
+++ b/netbox_proxbox/__init__.py
@@ -11,17 +11,19 @@ class ProxboxConfig(PluginConfig):
base_url = "proxbox"
required_settings = []
default_settings = {
- 'proxmox': {
- 'domain': 'proxbox.example.com', # May also be IP address
- 'http_port': 8006,
- 'user': 'root@pam',
- 'password': 'Strong@P4ssword',
- 'token': {
- 'name': 'tokenID',
- 'value': '039az154-23b2-4be0-8d20-b66abc8c4686'
- },
- 'ssl': False
- },
+ 'proxmox': [
+ {
+ 'domain': 'proxbox.example.com', # May also be IP address
+ 'http_port': 8006,
+ 'user': 'root@pam',
+ 'password': 'Strong@P4ssword',
+ 'token': {
+ 'name': 'proxbox',
+ 'value': '039az154-23b2-4be0-8d20-b66abc8c4686'
+ },
+ 'ssl': False
+ }
+ ],
'netbox': {
'domain': 'netbox.example.com', # May also be IP address
'http_port': 80,
diff --git a/netbox_proxbox/proxbox_api/create/dcim.py b/netbox_proxbox/proxbox_api/create/dcim.py
index 28cfc4a..a1f47c1 100755
--- a/netbox_proxbox/proxbox_api/create/dcim.py
+++ b/netbox_proxbox/proxbox_api/create/dcim.py
@@ -130,7 +130,7 @@ def site(**kwargs):
#
# dcim.devices (nodes)
#
-def node(proxmox_node):
+def node(proxmox, proxmox_node):
# Create json with basic NODE information
node_json = {}
node_json["name"] = proxmox_node['name']
@@ -140,7 +140,7 @@ def node(proxmox_node):
node_json["status"] = 'active'
node_json["tags"] = [extras.tag().id]
- cluster = virtualization.cluster()
+ cluster = virtualization.cluster(proxmox)
if cluster:
if cluster != None:
node_json["cluster"] = cluster.id
diff --git a/netbox_proxbox/proxbox_api/create/virtualization.py b/netbox_proxbox/proxbox_api/create/virtualization.py
index 56feaef..a092697 100755
--- a/netbox_proxbox/proxbox_api/create/virtualization.py
+++ b/netbox_proxbox/proxbox_api/create/virtualization.py
@@ -3,9 +3,7 @@
# PLUGIN_CONFIG variables
from ..plugins_config import (
NETBOX_SESSION as nb,
- PROXMOX_SESSION as proxmox,
NETBOX_VM_ROLE_ID,
-
)
from . import (
@@ -54,7 +52,7 @@ def cluster_type():
#
# virtualization.clusters
#
-def cluster():
+def cluster(proxmox):
#
# Cluster
#
@@ -135,19 +133,10 @@ def cluster():
except:
return f"Error creating the '{proxmox_cluster_name}' cluster. Possible errors: the name '{proxmox_cluster_name}' is already used."
-
-
-
-
-
-
-
-
-
#
# virtualization.virtual_machines
#
-def virtual_machine(proxmox_vm, duplicate):
+def virtual_machine(proxmox, proxmox_vm, duplicate):
# Create json with basic VM/CT information
vm_json = {}
netbox_obj = None
@@ -164,7 +153,7 @@ def virtual_machine(proxmox_vm, duplicate):
vm_json["name"] = proxmox_vm['name']
vm_json["status"] = 'active'
- vm_json["cluster"] = cluster().id
+ vm_json["cluster"] = cluster(proxmox).id
vm_json["role"] = extras.role(role_id = NETBOX_VM_ROLE_ID).id
vm_json["tags"] = [extras.tag().id]
diff --git a/netbox_proxbox/proxbox_api/plugins_config.py b/netbox_proxbox/proxbox_api/plugins_config.py
index 7b2f6f6..881f421 100755
--- a/netbox_proxbox/proxbox_api/plugins_config.py
+++ b/netbox_proxbox/proxbox_api/plugins_config.py
@@ -33,15 +33,15 @@
# Proxmox related settings
#
# API URI
-DEFAULT_PROXMOX = DEFAULT_PROXMOX_SETTING.get("domain")
-DEFAULT_PROXMOX_PORT = DEFAULT_PROXMOX_SETTING.get("http_port")
-DEFAULT_PROXMOX_SSL = DEFAULT_PROXMOX_SETTING.get("ssl")
+DEFAULT_PROXMOX = DEFAULT_PROXMOX_SETTING[0].get("domain")
+DEFAULT_PROXMOX_PORT = DEFAULT_PROXMOX_SETTING[0].get("http_port")
+DEFAULT_PROXMOX_SSL = DEFAULT_PROXMOX_SETTING[0].get("ssl")
# ACCESS
-DEFAULT_PROXMOX_USER = DEFAULT_PROXMOX_SETTING.get("user")
-DEFAULT_PROXMOX_PASSWORD = DEFAULT_PROXMOX_SETTING.get("password")
+DEFAULT_PROXMOX_USER = DEFAULT_PROXMOX_SETTING[0].get("user")
+DEFAULT_PROXMOX_PASSWORD = DEFAULT_PROXMOX_SETTING[0].get("password")
-DEFAULT_PROXMOX_TOKEN = DEFAULT_PROXMOX_SETTING.get("token")
+DEFAULT_PROXMOX_TOKEN = DEFAULT_PROXMOX_SETTING[0].get("token")
DEFAULT_PROXMOX_TOKEN_NAME = DEFAULT_PROXMOX_TOKEN.get("name", None)
DEFAULT_PROXMOX_TOKEN_VALUE = DEFAULT_PROXMOX_TOKEN.get("value", None)
@@ -74,23 +74,6 @@
PROXMOX_SETTING = USER_PLUGINS_CONFIG.get("proxmox", DEFAULT_PROXMOX_SETTING)
NETBOX_SETTING = USER_PLUGINS_CONFIG.get("netbox", DEFAULT_NETBOX_SETTING)
-#
-# Proxmox related settings
-#
-# API URI
-PROXMOX = PROXMOX_SETTING.get("domain", DEFAULT_PROXMOX)
-PROXMOX_PORT = PROXMOX_SETTING.get("http_port", DEFAULT_PROXMOX_PORT)
-PROXMOX_SSL = PROXMOX_SETTING.get("ssl", DEFAULT_PROXMOX_SSL)
-
-# ACCESS
-PROXMOX_USER = PROXMOX_SETTING.get("user", DEFAULT_PROXMOX_USER)
-PROXMOX_PASSWORD = PROXMOX_SETTING.get("password", DEFAULT_PROXMOX_PASSWORD)
-
-PROXMOX_TOKEN = PROXMOX_SETTING.get("token", DEFAULT_PROXMOX_TOKEN)
-if PROXMOX_TOKEN != None:
- PROXMOX_TOKEN_NAME = PROXMOX_TOKEN.get("name", DEFAULT_PROXMOX_TOKEN_NAME)
- PROXMOX_TOKEN_VALUE = PROXMOX_TOKEN.get("value", DEFAULT_PROXMOX_TOKEN_VALUE)
-
#
# NETBOX RELATED SETTINGS
#
@@ -111,49 +94,98 @@
NETBOX_NODE_ROLE_ID = NETBOX_SETTINGS.get("node_role_id", DEFAULT_NETBOX_NODE_ROLE_ID)
NETBOX_SITE_ID = NETBOX_SETTINGS.get("site_id", DEFAULT_NETBOX_SITE_ID)
-
-####################################################################################################
-# #
-# WITH PLUGIN CONFIGURED, STARTS BOTH PROXMOX AND NETBOX SESSION #
-# #
-####################################################################################################
-
-#
-# PROXMOX SESSION
-#
-# Check if token was provided
-if PROXMOX_TOKEN_VALUE != None and len(PROXMOX_TOKEN_VALUE) > 0:
- try:
- if PROXMOX_SSL == False:
- # DISABLE SSL WARNING
- import urllib3
- urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
-
- # Start PROXMOX session using TOKEN
- PROXMOX_SESSION = ProxmoxAPI(
- PROXMOX,
- port=PROXMOX_PORT,
- user=PROXMOX_USER,
- token_name=PROXMOX_TOKEN_NAME,
- token_value=PROXMOX_TOKEN_VALUE,
- verify_ssl=PROXMOX_SSL
- )
- except:
- raise RuntimeError(f'Error trying to initialize Proxmox Session using TOKEN (token_name: {PROXMOX_TOKEN_NAME} and token_value: {PROXMOX_TOKEN_VALUE} provided')
-
-# If token not provided, start session using user and passwd
-else:
- try:
- # Start PROXMOX session using USER CREDENTIALS
- PROXMOX_SESSION = ProxmoxAPI(
- PROXMOX,
- port=PROXMOX_PORT,
- user=PROXMOX_USER,
- password=PROXMOX_PASSWORD,
- verify_ssl=PROXMOX_SSL
- )
- except:
- raise RuntimeError(f'Error trying to initialize Proxmox Session using USER {PROXMOX_USER} and PASSWORD')
+PROXMOX_SESSIONS = {}
+
+def get_proxmox_session(PROXMOX_SETTING):
+ #
+ # Proxmox related settings
+ #
+ # API URI
+ PROXMOX = PROXMOX_SETTING.get("domain", DEFAULT_PROXMOX)
+ PROXMOX_PORT = PROXMOX_SETTING.get("http_port", DEFAULT_PROXMOX_PORT)
+ PROXMOX_SSL = PROXMOX_SETTING.get("ssl", DEFAULT_PROXMOX_SSL)
+
+ # ACCESS
+ PROXMOX_USER = PROXMOX_SETTING.get("user", DEFAULT_PROXMOX_USER)
+ PROXMOX_PASSWORD = PROXMOX_SETTING.get("password", DEFAULT_PROXMOX_PASSWORD)
+
+ output = {
+ 'PROXMOX': PROXMOX,
+ 'PROXMOX_PORT': PROXMOX_PORT,
+ 'PROXMOX_SSL': PROXMOX_SSL,
+ 'PROXMOX_TOKEN': None,
+ 'PROXMOX_TOKEN_NAME': None,
+ 'PROXMOX_TOKEN_VALUE': None
+ }
+
+ PROXMOX_TOKEN = PROXMOX_SETTING.get("token", DEFAULT_PROXMOX_TOKEN)
+ if PROXMOX_PASSWORD is None and PROXMOX_TOKEN is not None:
+ PROXMOX_TOKEN_NAME = PROXMOX_TOKEN.get("name", DEFAULT_PROXMOX_TOKEN_NAME)
+ PROXMOX_TOKEN_VALUE = PROXMOX_TOKEN.get("value", DEFAULT_PROXMOX_TOKEN_VALUE)
+ output["PROXMOX_TOKEN"] = PROXMOX_TOKEN
+ output["PROXMOX_TOKEN_NAME"] = PROXMOX_TOKEN_NAME
+ output["PROXMOX_TOKEN_VALUE"] = PROXMOX_TOKEN_VALUE
+ else:
+ PROXMOX_TOKEN_NAME = None
+ PROXMOX_TOKEN_VALUE = None
+
+ ####################################################################################################
+ # #
+ # WITH PLUGIN CONFIGURED, STARTS BOTH PROXMOX AND NETBOX SESSION #
+ # #
+ ####################################################################################################
+
+ #
+ # PROXMOX SESSION
+ #
+ # Check if token was provided
+ if PROXMOX_TOKEN_VALUE is not None and len(PROXMOX_TOKEN_VALUE) > 0:
+ try:
+ if PROXMOX_SSL == False:
+ # DISABLE SSL WARNING
+ import urllib3
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
+
+ # Start PROXMOX session using TOKEN
+ PROXMOX_SESSION = ProxmoxAPI(
+ PROXMOX,
+ port=PROXMOX_PORT,
+ user=PROXMOX_USER,
+ token_name=PROXMOX_TOKEN_NAME,
+ token_value=PROXMOX_TOKEN_VALUE,
+ verify_ssl=PROXMOX_SSL
+ )
+ output['PROXMOX_SESSION'] = PROXMOX_SESSION
+ return output
+ except:
+ raise RuntimeError(f'Error trying to initialize Proxmox Session using TOKEN (token_name: {PROXMOX_TOKEN_NAME} and token_value: {PROXMOX_TOKEN_VALUE} provided')
+
+ # If token not provided, start session using user and passwd
+ else:
+ try:
+ if PROXMOX_SSL == False:
+ # DISABLE SSL WARNING
+ import urllib3
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
+
+ # Start PROXMOX session using USER CREDENTIALS
+ PROXMOX_SESSION = ProxmoxAPI(
+ PROXMOX,
+ port=PROXMOX_PORT,
+ user=PROXMOX_USER,
+ password=PROXMOX_PASSWORD,
+ verify_ssl=PROXMOX_SSL
+ )
+ output['PROXMOX_SESSION'] = PROXMOX_SESSION
+ return output
+ except:
+ raise RuntimeError(f'Error trying to initialize Proxmox Session using USER {PROXMOX_USER} and PASSWORD')
+
+for s in PROXMOX_SETTING:
+ P_Setting = get_proxmox_session(s)
+ if P_Setting is not None:
+ v = P_Setting['PROXMOX']
+ PROXMOX_SESSIONS[v] = P_Setting
#
# NETBOX SESSION
diff --git a/netbox_proxbox/proxbox_api/remove.py b/netbox_proxbox/proxbox_api/remove.py
index 9556d4b..a87dca0 100755
--- a/netbox_proxbox/proxbox_api/remove.py
+++ b/netbox_proxbox/proxbox_api/remove.py
@@ -2,15 +2,18 @@
# PLUGIN_CONFIG variables
from .plugins_config import (
- PROXMOX_SESSION as proxmox,
NETBOX_SESSION as nb,
)
import logging
# Verify if VM/CT exists on Proxmox
-def is_vm_on_proxmox(netbox_vm):
+def is_vm_on_proxmox(proxmox_session, netbox_vm):
# Get json of all virtual machines from Proxmox
+ proxmox = proxmox_session.get('PROXMOX_SESSION')
+ PROXMOX = proxmox_session.get('PROXMOX')
+ PROXMOX_PORT = proxmox_session.get('PROXMOX_PORT')
+
all_proxmox_vms = proxmox.cluster.resources.get(type='vm')
# Netbox name
@@ -69,7 +72,7 @@ def is_vm_on_proxmox(netbox_vm):
# If 'local_context' is null, try updating it to be able to get ID from VM
if local_context == None:
- local_context_updated = updates.local_context_data(netbox_vm, all_proxmox_vms[name_index])
+ local_context_updated = updates.local_context_data(netbox_vm, all_proxmox_vms[name_index], PROXMOX, PROXMOX_PORT)
if local_context_updated == True:
local_context = netbox_vm.local_context_data
@@ -105,11 +108,11 @@ def is_vm_on_proxmox(netbox_vm):
# Comparison failed, not able to find VM on Proxmox
return False
-def all():
+def all(proxmox_session, cluster):
json_vm_all = []
- # Get all VM/CTs from Netbox
- netbox_all_vms = nb.virtualization.virtual_machines.all()
+ # Get VM/CTs of the specific cluster from Netbox
+ netbox_all_vms = nb.virtualization.virtual_machines.filter(cluster=cluster.name)
for nb_vm_each in netbox_all_vms:
json_vm = {}
@@ -120,7 +123,7 @@ def all():
json_vm["name"] = netbox_name
# Verify if VM exists on Proxmox
- vm_on_proxmox = is_vm_on_proxmox(nb_vm_each)
+ vm_on_proxmox = is_vm_on_proxmox(proxmox_session, nb_vm_each)
if vm_on_proxmox == True:
log_message = f'[OK] VM exists on both systems (Netbox and Proxmox) -> {netbox_name}'
diff --git a/netbox_proxbox/proxbox_api/update.py b/netbox_proxbox/proxbox_api/update.py
index 0b0b5b5..80139c8 100755
--- a/netbox_proxbox/proxbox_api/update.py
+++ b/netbox_proxbox/proxbox_api/update.py
@@ -1,13 +1,10 @@
+import time
+from threading import Thread
# PLUGIN_CONFIG variables
from .plugins_config import (
- PROXMOX,
- PROXMOX_PORT,
- PROXMOX_USER,
- PROXMOX_PASSWORD,
- PROXMOX_SSL,
NETBOX,
NETBOX_TOKEN,
- PROXMOX_SESSION as proxmox,
+ PROXMOX_SESSIONS as proxmox_sessions,
NETBOX_SESSION as nb,
)
@@ -22,7 +19,10 @@
import logging
# Call all functions to update Virtual Machine
-def vm_full_update(netbox_vm, proxmox_vm):
+def vm_full_update(proxmox_session, netbox_vm, proxmox_vm):
+ proxmox = proxmox_session.get('PROXMOX_SESSION')
+ PROXMOX = proxmox_session.get('PROXMOX')
+ PROXMOX_PORT = proxmox_session.get('PROXMOX_PORT')
changes = {}
# Update 'status' field, if necessary.
@@ -32,13 +32,13 @@ def vm_full_update(netbox_vm, proxmox_vm):
custom_fields_updated = updates.virtual_machine.custom_fields(netbox_vm, proxmox_vm)
# Update 'local_context_data' json, if necessary.
- local_context_updated = updates.virtual_machine.local_context_data(netbox_vm, proxmox_vm)
+ local_context_updated = updates.virtual_machine.local_context_data(netbox_vm, proxmox_vm, PROXMOX, PROXMOX_PORT)
# Update 'resources', like CPU, Memory and Disk, if necessary.
resources_updated = updates.virtual_machine.resources(netbox_vm, proxmox_vm)
- interfaces_updated = updates.virtual_machine.interfaces(netbox_vm, proxmox_vm)
- ips_updated = updates.virtual_machine.interfaces_ips(netbox_vm, proxmox_vm)
+ interfaces_updated = updates.virtual_machine.interfaces(proxmox, netbox_vm, proxmox_vm)
+ ips_updated = updates.virtual_machine.interfaces_ips(proxmox, netbox_vm, proxmox_vm)
tag_updated = updates.extras.tag(netbox_vm)
@@ -57,12 +57,12 @@ def vm_full_update(netbox_vm, proxmox_vm):
-def node_full_update(netbox_node, proxmox_json, proxmox_cluster):
+def node_full_update(proxmox, netbox_node, proxmox_json, proxmox_cluster):
changes = {}
status_updated = updates.node.status(netbox_node, proxmox_json)
- cluster_updated = updates.node.cluster(netbox_node, proxmox_json, proxmox_cluster)
- interfaces_updated = updates.node.interfaces(netbox_node, proxmox_json)
+ cluster_updated = updates.node.cluster(proxmox, netbox_node, proxmox_json, proxmox_cluster)
+ interfaces_updated = updates.node.interfaces(proxmox, netbox_node, proxmox_json)
changes = {
"status" : status_updated,
@@ -73,7 +73,7 @@ def node_full_update(netbox_node, proxmox_json, proxmox_cluster):
return changes
-def search_by_proxmox_id(proxmox_id):
+def search_by_proxmox_id(proxmox, proxmox_id):
all_proxmox_vms = proxmox.cluster.resources.get(type='vm')
for px_vm in all_proxmox_vms:
@@ -88,7 +88,7 @@ def search_by_proxmox_id(proxmox_id):
-def search_by_proxmox_name(proxmox_name):
+def search_by_proxmox_name(proxmox, proxmox_name):
all_proxmox_vms = proxmox.cluster.resources.get(type='vm')
for px_vm in all_proxmox_vms:
@@ -104,7 +104,7 @@ def search_by_proxmox_name(proxmox_name):
def search_by_id(id):
- # Save Netbox VirtualMachine object
+ # Get Netbox VirtualMachine object
netbox_obj = nb.virtualization.virtual_machines.get(id)
proxmox_name = netbox_obj.name
@@ -127,6 +127,9 @@ def search_by_id(id):
# Makes all necessary checks so that VM/CT exist on Netbox.
def virtual_machine(**kwargs):
+ print('[OK] STARTING PROCESS FOR VIRTUAL MACHINE')
+ proxmox_session = kwargs.get('proxmox_session')
+ proxmox = proxmox_session.get('PROXMOX_SESSION')
# JSON containing the result of the VM changes
json_vm = {}
@@ -203,7 +206,7 @@ def virtual_machine(**kwargs):
# Search using Proxmox ID
if 'int' in str(search_result_type):
- proxmox_json = search_by_proxmox_id(search_result)
+ proxmox_json = search_by_proxmox_id(proxmox, search_result)
# Analyze search result and returns error, if null value.
if proxmox_json == None:
@@ -215,7 +218,7 @@ def virtual_machine(**kwargs):
# Search using Proxmox NAME
elif 'str' in str(search_result_type):
- proxmox_json = search_by_proxmox_name(search_result)
+ proxmox_json = search_by_proxmox_name(proxmox, search_result)
# Analyze search result and returns error, if null value.
if proxmox_json == None:
@@ -228,7 +231,7 @@ def virtual_machine(**kwargs):
else:
# Search VM JSON of Proxmox using argument 'proxmox_id'
if proxmox_id != None:
- proxmox_json = search_by_proxmox_id(proxmox_id)
+ proxmox_json = search_by_proxmox_id(proxmox, proxmox_id)
# Analyze search result and returns error, if null value.
if proxmox_json == None:
@@ -241,7 +244,7 @@ def virtual_machine(**kwargs):
else:
# Search using Proxmox NAME
if name != None:
- proxmox_json = search_by_proxmox_name(name)
+ proxmox_json = search_by_proxmox_name(proxmox, name)
# Analyze search result and returns error, if null value.
if proxmox_json == None:
@@ -255,8 +258,30 @@ def virtual_machine(**kwargs):
return False
# Search Netbox object by name gotten from Proxmox
- netbox_vm = nb.virtualization.virtual_machines.get(name = proxmox_vm_name)
+ # netbox_vm = nb.virtualization.virtual_machines.get(name = proxmox_vm_name)
+ print('[OK] Getting node')
+ node = proxmox_json['node']
+ cluster = None
+ try:
+ cluster = kwargs.get('cluster')
+ print('[OK] Getting cluster')
+ except Exception as e:
+ cluster = None
+ if cluster is None:
+ cluster = create.virtualization.cluster(proxmox)
+
+ print('[OK] Getting vmid')
+ vmid = proxmox_json['vmid']
+ print('[OK] Getting getting vm from netbox for {} , {}, {}'.format(cluster.name, vmid, node))
+ netbox_vm_all = nb.virtualization.virtual_machines.filter(cluster=cluster.name, cf_proxmox_id=vmid,
+ cf_proxmox_node=node)
+
+ netbox_vm = None
+ for vm in netbox_vm_all:
+ netbox_vm = vm
+ break # ????
+
duplicate = False
try:
# Check if Proxbox tag exist.
@@ -270,7 +295,7 @@ def virtual_machine(**kwargs):
# VM Found:
if netbox_vm:
# Update Netbox information
- full_update = vm_full_update(netbox_vm, proxmox_json)
+ full_update = vm_full_update(proxmox_session, netbox_vm, proxmox_json)
# I made this way since dict.update didn't work
json_vm["vm_id"] = netbox_vm.id
@@ -298,12 +323,12 @@ def virtual_machine(**kwargs):
logging.info(f'[OK] VM does not exist on Netbox -> {proxmox_vm_name}')
# Analyze if VM was sucessfully created.
- netbox_vm = create.virtualization.virtual_machine(proxmox_json, duplicate)
+ netbox_vm = create.virtualization.virtual_machine(proxmox, proxmox_json, duplicate)
# VM created with basic information
if netbox_vm != None:
# Update rest of configuration
- full_update = vm_full_update(netbox_vm, proxmox_json)
+ full_update = vm_full_update(proxmox_session, netbox_vm, proxmox_json)
json_vm = full_update
json_vm["vm_id"] = netbox_vm.id
@@ -329,6 +354,7 @@ def virtual_machine(**kwargs):
# VM not created
json_vm["result"] = False
+ print('[OK] FINISH PROCESS FOR VIRTUAL MACHINE')
return json_vm
@@ -336,12 +362,13 @@ def virtual_machine(**kwargs):
def nodes(**kwargs):
proxmox_cluster = kwargs.get('proxmox_cluster')
proxmox_json = kwargs.get('proxmox_json')
+ proxmox = kwargs.get('proxmox')
proxmox_node_name = proxmox_json.get("name")
def create_node():
# If node does not exist, create it.
- netbox_node = create.dcim.node(proxmox_json)
+ netbox_node = create.dcim.node(proxmox, proxmox_json)
# Node created
if netbox_node != None:
@@ -367,6 +394,9 @@ def create_node():
else:
logging.error(f'[ERROR] Something went wrong when creating the node.-> {proxmox_node_name} (2)')
json_node = {}
+ json_node["status"] = None
+ json_node["cluster"] = None
+ json_node["interfaces"] = None
json_node["result"] = False
return json_node
@@ -398,7 +428,7 @@ def create_node():
netbox_node = netbox_search
# Update Netbox node information, if necessary.
- full_update = node_full_update(netbox_node, proxmox_json, proxmox_cluster)
+ full_update = node_full_update(proxmox, netbox_node, proxmox_json, proxmox_cluster)
json_node = full_update
full_update_list = list(full_update.values())
@@ -427,17 +457,91 @@ def create_node():
return json_node
-
+def run_process_in_thread(proxmox_session, key, result, index, **kwargs):
+ output = {}
+ try:
+ print("Processing data for: {0}".format(key))
+ output = process_all_in_session(proxmox_session, **kwargs)
+ result[index] = output
+ except Exception as e:
+ message = "OS error: {0}".format(e)
+ print(message)
+ result[index] = {
+ 'message': message
+ }
+ return output
# Makes everything needed so that VIRTUAL MACHINES / CONTAINERS, NODES and CLUSTER exists on Netbox
def all(**kwargs):
+ run_with_threads = kwargs.get("run_with_threads", True)
+ start_time = time.time()
+ results = []
+ if run_with_threads:
+ print("Start process with threading")
+ threads = [None] * len(proxmox_sessions)
+ results = [None] * len(proxmox_sessions)
+ i = 0
+ for key in proxmox_sessions:
+ proxmox_session = proxmox_sessions[key]
+ threads[i] = Thread(target=run_process_in_thread, args=(proxmox_session, key, results, i), kwargs=kwargs)
+ threads[i].start()
+ i = i + 1
+
+ p = len(threads)
+ r = range(p)
+ for i in r:
+ threads[(p - 1) - i].join()
+ else:
+ print("Start process Sequential")
+ for key in proxmox_sessions:
+ try:
+ session = proxmox_sessions[key]
+ print("Processing data for: {0}".format(key))
+ output = process_all_in_session(session, **kwargs)
+ results.append(output)
+ except Exception as e:
+ message = "OS error: {0}".format(e)
+ print(message)
+ output = {
+ 'message': message
+ }
+ results.append(output)
+
+ print("--- %s seconds ---" % (time.time() - start_time))
+ return results
+
+def single(**kwargs):
+ proxmox_domain = kwargs.get("proxmox_domain", False)
+ start_time = time.time()
+ results = []
+ for key in proxmox_sessions:
+ if key == proxmox_domain:
+ print("Start process Sequential")
+ try:
+ session = proxmox_sessions[key]
+ print("Processing data for: {0}".format(key))
+ output = process_all_in_session(session, **kwargs)
+ results.append(output)
+ except Exception as e:
+ message = "OS error: {0}".format(e)
+ print(message)
+ output = {
+ 'message': message
+ }
+ results.append(output)
+
+ print("--- %s seconds ---" % (time.time() - start_time))
+ return results
+
+def process_all_in_session(proxmox_session, **kwargs):
print("[Proxbox - Netbox plugin | Update All]")
+ proxmox = proxmox_session.get('PROXMOX_SESSION')
cluster_all = proxmox.cluster.status.get()
#
# CLUSTER
#
- cluster = create.virtualization.cluster()
+ cluster = create.virtualization.cluster(proxmox)
print('\n\n\nCLUSTER...')
try:
@@ -455,8 +559,7 @@ def all(**kwargs):
# Get all NODES from Proxmox
for px_node_each in proxmox_nodes:
- node_updated = nodes(proxmox_json = px_node_each, proxmox_cluster = proxmox_cluster)
-
+ node_updated = nodes(proxmox_json = px_node_each, proxmox_cluster = proxmox_cluster, proxmox = proxmox)
nodes_list.append(node_updated)
@@ -468,9 +571,9 @@ def all(**kwargs):
print('\nUPDATE ALL...')
# Get all VM/CTs from Proxmox
- for px_vm_each in proxmox.cluster.resources.get(type='vm'):
- vm_updated = virtual_machine(proxmox_json = px_vm_each)
-
+ node_vms_all = proxmox.cluster.resources.get(type='vm')
+ for px_vm_each in node_vms_all:
+ vm_updated = virtual_machine(proxmox_json = px_vm_each, proxmox_session = proxmox_session, cluster = cluster)
virtualmachines_list.append(vm_updated)
# Get "remove_unused" passed on function call
@@ -479,7 +582,7 @@ def all(**kwargs):
# Remove Netbox's old data
if remove_unused == True:
print('\nREMOVE UNUSED DATA...')
- remove_info = remove.all()
+ remove_info = remove.all(proxmox_session, cluster)
else:
remove_info = False
#
diff --git a/netbox_proxbox/proxbox_api/updates/node.py b/netbox_proxbox/proxbox_api/updates/node.py
index c8f5f8c..ca08318 100755
--- a/netbox_proxbox/proxbox_api/updates/node.py
+++ b/netbox_proxbox/proxbox_api/updates/node.py
@@ -1,12 +1,6 @@
from ..plugins_config import (
- PROXMOX,
- PROXMOX_PORT,
- PROXMOX_USER,
- PROXMOX_PASSWORD,
- PROXMOX_SSL,
NETBOX,
NETBOX_TOKEN,
- PROXMOX_SESSION as proxmox,
NETBOX_SESSION as nb,
)
@@ -57,7 +51,7 @@ def status(netbox_node, proxmox_node):
# Update CLUSTER field on /dcim/device/{id}
-def cluster(netbox_node, proxmox_node, proxmox_cluster):
+def cluster(proxmox, netbox_node, proxmox_node, proxmox_cluster):
#
# Compare CLUSTER
#
@@ -69,7 +63,7 @@ def cluster(netbox_node, proxmox_node, proxmox_cluster):
# If cluster is not filled or even filled, but different from actual cluster, update it.
if netbox_node.cluster.name != proxmox_cluster['name'] or netbox_node.cluster.name == None:
# Search for Proxmox Cluster using create.cluster() function
- cluster_id = create.virtualization.cluster().id
+ cluster_id = create.virtualization.cluster(proxmox).id
# Use Cluster ID to update NODE information
netbox_node.cluster.id = cluster_id
@@ -106,7 +100,7 @@ def cluster(netbox_node, proxmox_node, proxmox_cluster):
return cluster_updated
-def interfaces(netbox_node, proxmox_json):
+def interfaces(proxmox, netbox_node, proxmox_json):
updated = False
_int_port = ['OVSIntPort']
_lag_port = ['OVSBond']
@@ -118,6 +112,20 @@ def interfaces(netbox_node, proxmox_json):
_bond = [iface for iface in proxmox.nodes(proxmox_json['name']).network.get() if iface['type'] in _lag_port]
_bridge = [iface for iface in proxmox.nodes(proxmox_json['name']).network.get() if iface['type'] in _brg_port]
+ def get_or_create_vlan(vlan_id):
+ # FIXME: we may need to specify the datacenter
+ # since users may have same vlan id in multiple dc
+ vlan = nb.ipam.vlans.get(
+ vid=vlan_id,
+ )
+ if vlan is None:
+ vlan = nb.ipam.vlans.create(
+ name='VLAN {}'.format(vlan_id),
+ vid=vlan_id,
+ group=None,
+ )
+ return vlan
+
for iface in _eth:
ntb_iface = list(nb.dcim.interfaces.filter(device_id=netbox_node.id, name=iface['iface']))
if iface.get('ovs_tag') is not None:
@@ -128,7 +136,8 @@ def interfaces(netbox_node, proxmox_json):
pmx_if = next((_if for _if in _pmx_iface if _if['name'] == iface['iface']), None)
if not len(ntb_iface):
if len(_tagged_vlans):
- ntb_iface = nb.dcim.interfaces.create(device=netbox_node.id, name=pmx_if['name'], type='other', mtu=pmx_if['mtu'], mode='tagged', tagged_vlans=[nb.ipam.vlans.get(vid=_tagged_vlans[0]).id])
+ _nb_vlan = get_or_create_vlan(_tagged_vlans[0])
+ ntb_iface = nb.dcim.interfaces.create(device=netbox_node.id, name=pmx_if['name'], type='other', mtu=pmx_if['mtu'], mode='tagged', tagged_vlans=[_nb_vlan.id])
else:
ntb_iface = nb.dcim.interfaces.create(device=netbox_node.id, name=pmx_if['name'], type='other', mtu=pmx_if['mtu'])
updated = True
@@ -138,7 +147,8 @@ def interfaces(netbox_node, proxmox_json):
ntb_if = next((_if for _if in _ntb_iface if _if['name'] == iface['iface']), None)
if pmx_if != ntb_if:
if len(pmx_if['tagged_vlans']):
- nb.dcim.interfaces.update([{'id': ntb_iface.id, 'mtu': pmx_if['mtu'], 'mode': 'tagged', 'tagged_vlans': [nb.ipam.vlans.get(vid=_tagged_vlans[0]).id]}])
+ _nb_vlan = get_or_create_vlan(_tagged_vlans[0])
+ nb.dcim.interfaces.update([{'id': ntb_iface.id, 'mtu': pmx_if['mtu'], 'mode': 'tagged', 'tagged_vlans': [_nb_vlan.id]}])
else:
nb.dcim.interfaces.update([{'id': ntb_iface.id, 'mtu': pmx_if['mtu']}])
updated = True
@@ -152,7 +162,8 @@ def interfaces(netbox_node, proxmox_json):
_pmx_iface.append({'name': iface['iface'], 'mtu' : int(iface.get('mtu', 1500)), 'tagged_vlans': _tagged_vlans})
if not len(ntb_iface):
if len(_tagged_vlans):
- ntb_iface = nb.dcim.interfaces.create(device=netbox_node.id, name=iface['iface'], type='lag', mtu=int(iface.get('mtu', 1500)), mode='tagged', tagged_vlans=[nb.ipam.vlans.get(vid=_tagged_vlans[0]).id])
+ _nb_vlan = get_or_create_vlan(_tagged_vlans[0])
+ ntb_iface = nb.dcim.interfaces.create(device=netbox_node.id, name=iface['iface'], type='lag', mtu=int(iface.get('mtu', 1500)), mode='tagged', tagged_vlans=[_nb_vlan.id])
else:
ntb_iface = nb.dcim.interfaces.create(device=netbox_node.id, name=iface['iface'], type='lag', mtu=int(iface.get('mtu', 1500)))
else:
@@ -162,7 +173,8 @@ def interfaces(netbox_node, proxmox_json):
ntb_if = next((_if for _if in _ntb_iface if _if['name'] == iface['iface']), None)
if pmx_if != ntb_if:
if len(pmx_if['tagged_vlans']):
- nb.dcim.interfaces.update([{'id': ntb_iface.id, 'mtu': pmx_if['mtu'], 'mode': 'tagged', 'tagged_vlans': [nb.ipam.vlans.get(vid=_tagged_vlans[0]).id]}])
+ _nb_vlan = get_or_create_vlan(_tagged_vlans[0])
+ nb.dcim.interfaces.update([{'id': ntb_iface.id, 'mtu': pmx_if['mtu'], 'mode': 'tagged', 'tagged_vlans': [_nb_vlan.id]}])
else:
nb.dcim.interfaces.update([{'id': ntb_iface.id, 'mtu': pmx_if['mtu']}])
updated = True
@@ -181,7 +193,8 @@ def interfaces(netbox_node, proxmox_json):
_pmx_iface.append({'name': iface['iface'], 'mtu' : int(iface.get('mtu', 1500)), 'tagged_vlans': _tagged_vlans})
if not len(ntb_iface):
if len(_tagged_vlans):
- ntb_iface = nb.dcim.interfaces.create(device=netbox_node.id, name=iface['iface'], type='virtual', mtu=int(iface.get('mtu', 1500)), mode='tagged', tagged_vlans=[nb.ipam.vlans.get(vid=_tagged_vlans[0]).id])
+ _nb_vlan = get_or_create_vlan(_tagged_vlans[0])
+ ntb_iface = nb.dcim.interfaces.create(device=netbox_node.id, name=iface['iface'], type='virtual', mtu=int(iface.get('mtu', 1500)), mode='tagged', tagged_vlans=[_nb_vlan.id])
else:
ntb_iface = nb.dcim.interfaces.create(device=netbox_node.id, name=iface['iface'], type='virtual', mtu=int(iface.get('mtu', 1500)))
else:
@@ -191,7 +204,8 @@ def interfaces(netbox_node, proxmox_json):
ntb_if = next((_if for _if in _ntb_iface if _if['name'] == iface['iface']), None)
if pmx_if != ntb_if:
if len(pmx_if['tagged_vlans']):
- nb.dcim.interfaces.update([{'id': ntb_iface.id, 'mtu': pmx_if['mtu'], 'mode': 'tagged', 'tagged_vlans': [nb.ipam.vlans.get(vid=_tagged_vlans[0]).id]}])
+ _nb_vlan = get_or_create_vlan(_tagged_vlans[0])
+ nb.dcim.interfaces.update([{'id': ntb_iface.id, 'mtu': pmx_if['mtu'], 'mode': 'tagged', 'tagged_vlans': [_nb_vlan.id]}])
else:
nb.dcim.interfaces.update([{'id': ntb_iface.id, 'mtu': pmx_if['mtu']}])
updated = True
@@ -205,7 +219,8 @@ def interfaces(netbox_node, proxmox_json):
_pmx_iface.append({'name': iface['iface'], 'mtu' : int(iface.get('mtu', 1500)), 'tagged_vlans': _tagged_vlans})
if not len(ntb_iface):
if len(_tagged_vlans):
- ntb_iface = nb.dcim.interfaces.create(device=netbox_node.id, name=iface['iface'], type='bridge', mtu=int(iface.get('mtu', 1500)), mode='tagged', tagged_vlans=[nb.ipam.vlans.get(vid=_tagged_vlans[0]).id])
+ _nb_vlan = get_or_create_vlan(_tagged_vlans[0])
+ ntb_iface = nb.dcim.interfaces.create(device=netbox_node.id, name=iface['iface'], type='bridge', mtu=int(iface.get('mtu', 1500)), mode='tagged', tagged_vlans=[_nb_vlan.id])
else:
ntb_iface = nb.dcim.interfaces.create(device=netbox_node.id, name=iface['iface'], type='bridge', mtu=int(iface.get('mtu', 1500)))
else:
@@ -215,7 +230,8 @@ def interfaces(netbox_node, proxmox_json):
ntb_if = next((_if for _if in _ntb_iface if _if['name'] == iface['iface']), None)
if pmx_if != ntb_if:
if len(pmx_if['tagged_vlans']):
- nb.dcim.interfaces.update([{'id': ntb_iface.id, 'mtu': pmx_if['mtu'], 'mode': 'tagged', 'tagged_vlans': [nb.ipam.vlans.get(vid=_tagged_vlans[0]).id]}])
+ _nb_vlan = get_or_create_vlan(_tagged_vlans[0])
+ nb.dcim.interfaces.update([{'id': ntb_iface.id, 'mtu': pmx_if['mtu'], 'mode': 'tagged', 'tagged_vlans': [_nb_vlan.id]}])
else:
nb.dcim.interfaces.update([{'id': ntb_iface.id, 'mtu': pmx_if['mtu']}])
updated = True
diff --git a/netbox_proxbox/proxbox_api/updates/virtual_machine.py b/netbox_proxbox/proxbox_api/updates/virtual_machine.py
index c1dc232..575bdc0 100755
--- a/netbox_proxbox/proxbox_api/updates/virtual_machine.py
+++ b/netbox_proxbox/proxbox_api/updates/virtual_machine.py
@@ -4,14 +4,8 @@
# PLUGIN_CONFIG variables
from ..plugins_config import (
- PROXMOX,
- PROXMOX_PORT,
- PROXMOX_USER,
- PROXMOX_PASSWORD,
- PROXMOX_SSL,
NETBOX,
NETBOX_TOKEN,
- PROXMOX_SESSION as proxmox,
NETBOX_SESSION as nb,
)
@@ -84,7 +78,7 @@ def http_update_custom_fields(**kwargs):
# HTTP PATCH Request (partially update)
#
# URL
- url = '{}/api/virtualization/virtual-machines/{}/'.format(domain_with_http, vm_id)
+ url = '{}api/virtualization/virtual-machines/{}/'.format(domain_with_http, vm_id)
# HTTP Request Headers
headers = {
@@ -177,7 +171,7 @@ def custom_fields(netbox_vm, proxmox_vm):
# Update 'local_context_data' field on Netbox Virtual Machine based on Proxbox
-def local_context_data(netbox_vm, proxmox_vm):
+def local_context_data(netbox_vm, proxmox_vm, PROXMOX, PROXMOX_PORT):
current_local_context = netbox_vm.local_context_data
proxmox_values = {}
@@ -219,12 +213,6 @@ def local_context_data(netbox_vm, proxmox_vm):
return False
-
-
-
-
-
-
# Updates following fields based on Proxmox: "vcpus", "memory", "disk", if necessary.
def resources(netbox_vm, proxmox_vm):
# Save values from Proxmox
@@ -285,7 +273,7 @@ def resources(netbox_vm, proxmox_vm):
else:
return False
-def interfaces(netbox_vm, proxmox_vm):
+def interfaces(proxmox, netbox_vm, proxmox_vm):
updated = False
try:
if proxmox_vm['type'] == 'qemu':
@@ -369,7 +357,7 @@ def interfaces(netbox_vm, proxmox_vm):
return False
return updated
-def interfaces_ips(netbox_vm, proxmox_vm):
+def interfaces_ips(proxmox, netbox_vm, proxmox_vm):
updated = False
if proxmox_vm['status'] == 'running':
_pmx_ips = []
diff --git a/netbox_proxbox/templates/netbox_proxbox/home.html b/netbox_proxbox/templates/netbox_proxbox/home.html
index 8e95eb1..fd4afb6 100644
--- a/netbox_proxbox/templates/netbox_proxbox/home.html
+++ b/netbox_proxbox/templates/netbox_proxbox/home.html
@@ -19,11 +19,12 @@
+ {% for px in configuration.netbox_proxbox.proxmox %}
@@ -31,60 +32,77 @@
Domain / IP |
- {% if configuration.netbox_proxbox.proxmox.domain %}
- {{ configuration.netbox_proxbox.proxmox.domain }} |
+ {% if px.domain %}
+ {{ px.domain }} |
{% else %}
{{ default_config.proxmox.domain }} (default) |
{% endif %}
HTTP Port |
- {% if configuration.netbox_proxbox.proxmox.http_port %}
- {{ configuration.netbox_proxbox.proxmox.http_port }} |
+ {% if px.http_port %}
+ {{ px.http_port }} |
{% else %}
{{ default_config.proxmox.http_port }} (default) |
{% endif %}
Proxmox User |
- {% if configuration.netbox_proxbox.proxmox.user %}
- {{ configuration.netbox_proxbox.proxmox.user }} |
+ {% if px.user %}
+ {{ px.user }} |
{% else %}
{{ default_config.proxmox.user }} (default) |
{% endif %}
Proxmox Password |
- {% if configuration.netbox_proxbox.proxmox.password %}
+ {% if px.password %}
password defined in configuration.py |
{% else %}
{{ default_config.proxmox.password }} (default) |
{% endif %}
Token Name |
- {% if configuration.netbox_proxbox.proxmox.token.name %}
- {{ configuration.netbox_proxbox.proxmox.token.name }} |
+ {% if px.token.name %}
+ {{ px.token.name }} |
{% else %}
{{ default_config.proxmox.token.name }} (default) |
{% endif %}
Token Value |
- {% if configuration.netbox_proxbox.proxmox.token.value %}
- {{ configuration.netbox_proxbox.proxmox.token.value }} |
+ {% if px.token.value %}
+ {{ px.token.value }} |
{% else %}
{{ default_config.proxmox.token.value }} (default) |
{% endif %}
SSL |
- {% if configuration.netbox_proxbox.proxmox.ssl %}
- {{ configuration.netbox_proxbox.proxmox.ssl }} |
+ {% if px.ssl %}
+ {{ px.ssl }} |
{% else %}
{{ default_config.proxmox.ssl }} (default) |
{% endif %}
-
+ {% endfor %}
@@ -108,32 +127,32 @@
Domain / IP |
- {% if configuration.netbox_proxbox.netbox.domain %}
- {{ configuration.netbox_proxbox.netbox.domain }} |
+ {% if px.netbox.domain %}
+ {{ px.netbox.domain }} |
{% else %}
{{ default_config.netbox.domain }} (default) |
{% endif %}
HTTP Port |
- {% if configuration.netbox_proxbox.netbox.http_port %}
- {{ configuration.netbox_proxbox.netbox.http_port }} |
+ {% if px.netbox.http_port %}
+ {{ px.netbox.http_port }} |
{% else %}
{{ default_config.netbox.http_port }} (default) |
{% endif %}
Token |
- {% if configuration.netbox_proxbox.netbox.token %}
- {{ configuration.netbox_proxbox.netbox.token }} |
+ {% if px.netbox.token %}
+ {{ px.netbox.token }} |
{% else %}
{{ default_config.netbox.token }} (default) |
{% endif %}
SSL |
- {% if configuration.netbox_proxbox.netbox.ssl %}
- {{ configuration.netbox_proxbox.netbox.ssl }} |
+ {% if px.netbox.ssl %}
+ {{ px.netbox.ssl }} |
{% else %}
{{ default_config.netbox.ssl }} (default) |
{% endif %}
diff --git a/netbox_proxbox/templates/netbox_proxbox/proxmox_vm_full_update.html b/netbox_proxbox/templates/netbox_proxbox/proxmox_vm_full_update.html
index 21a8cb1..616073f 100755
--- a/netbox_proxbox/templates/netbox_proxbox/proxmox_vm_full_update.html
+++ b/netbox_proxbox/templates/netbox_proxbox/proxmox_vm_full_update.html
@@ -7,184 +7,186 @@ Virtual Machines and Containers
- {% if proxmox.nodes %}
-
Nodes
-
-
+ {% for px in proxmox %}
+ {% if px.nodes %}
+ Nodes
+
+
+
+ Node Name |
+ Node status changed |
+ Cluster changed |
+ Interface changed |
+ Update result |
+
+
+
+ {% for node in px.nodes %}
- Node Name |
- Node status changed |
- Cluster changed |
- Interface changed |
- Update result |
-
-
-
- {% for node in proxmox.nodes %}
-
-
-
- {% if node.node_id %}
-
+
+
+ {% if node.node_id %}
+
+ {{ node.name }}
+
+ {% else %}
{{ node.name }}
-
+ {% endif %}
+
+ |
+
+ {% if node.status %}
+
+ {{ node.status }}
+
{% else %}
- {{ node.name }}
+
+ {{ node.status }}
+
{% endif %}
-
- |
-
- {% if node.status %}
-
- {{ node.status }}
-
- {% else %}
-
- {{ node.status }}
-
- {% endif %}
- |
-
- {% if node.cluster %}
-
- {{ node.cluster }}
-
- {% else %}
-
- {{ node.cluster }}
-
- {% endif %}
- |
- {% if node.interfaces %}
-
- {{ node.interfaces }}
-
- {% else %}
-
- {{ node.interfaces }}
-
- {% endif %}
- |
-
- {% if node.result %}
-
- {{ node.result }}
-
- {% else %}
-
- {{ node.result }}
-
- {% endif %}
- |
- |
- {% endfor %}
-
-
-
-
- {% endif %}
- {% if proxmox.virtualmachines %}
- Virtual Machines and Containers
-
-
-
-
- VM/CT Name |
- Status changed |
- Custom Fields |
- Local context |
- Resources |
- Tag |
- Update result |
+
+
+ {% if node.cluster %}
+
+ {{ node.cluster }}
+
+ {% else %}
+
+ {{ node.cluster }}
+
+ {% endif %}
+ |
+ {% if node.interfaces %}
+
+ {{ node.interfaces }}
+
+ {% else %}
+
+ {{ node.interfaces }}
+
+ {% endif %}
+ |
+
+ {% if node.result %}
+
+ {{ node.result }}
+
+ {% else %}
+
+ {{ node.result }}
+
+ {% endif %}
+ |
-
-
- {% for virtualmachine in proxmox.virtualmachines %}
-
-
-
- {% if virtualmachine.vm_id %}
-
+ {% endfor %}
+ |
+
+
+
+ {% endif %}
+ {% if px.virtualmachines %}
+ Virtual Machines and Containers
+
+
+
+
+ VM/CT Name |
+ Status changed |
+ Custom Fields |
+ Local context |
+ Resources |
+ Tag |
+ Update result |
+
+
+
+ {% for virtualmachine in px.virtualmachines %}
+
+
+
+ {% if virtualmachine.vm_id %}
+
+ {{ virtualmachine.name }}
+
+ {% else %}
{{ virtualmachine.name }}
-
+ {% endif %}
+
+ |
+
+ {% if virtualmachine.status %}
+
+ {{ virtualmachine.status }}
+
{% else %}
- {{ virtualmachine.name }}
- {% endif %}
-
- |
-
- {% if virtualmachine.status %}
-
- {{ virtualmachine.status }}
-
- {% else %}
-
- {{ virtualmachine.status }}
-
- {% endif %}
- |
-
- {% if virtualmachine.custom_fields %}
-
- {{ virtualmachine.custom_fields }}
-
- {% else %}
-
- {{ virtualmachine.custom_fields }}
-
- {% endif %}
- |
-
- {% if virtualmachine.local_context %}
-
- {{ virtualmachine.local_context }}
-
- {% else %}
-
- {{ virtualmachine.local_context }}
-
- {% endif %}
- |
-
- {% if virtualmachine.resources %}
-
- {{ virtualmachine.resources }}
-
- {% else %}
-
- {{ virtualmachine.resources }}
-
- {% endif %}
- |
-
- {% if virtualmachine.tag %}
-
- {{ virtualmachine.tag }}
-
- {% else %}
-
- {{ virtualmachine.tag }}
-
- {% endif %}
- |
-
- {% if virtualmachine.result %}
-
- {{ virtualmachine.result }}
-
- {% else %}
-
- {{ virtualmachine.result }}
-
- {% endif %}
- |
-
- {% endfor %}
-
-
-
-
- {% endif %}
+
+ {{ virtualmachine.status }}
+
+ {% endif %}
+
+
+ {% if virtualmachine.custom_fields %}
+
+ {{ virtualmachine.custom_fields }}
+
+ {% else %}
+
+ {{ virtualmachine.custom_fields }}
+
+ {% endif %}
+ |
+
+ {% if virtualmachine.local_context %}
+
+ {{ virtualmachine.local_context }}
+
+ {% else %}
+
+ {{ virtualmachine.local_context }}
+
+ {% endif %}
+ |
+
+ {% if virtualmachine.resources %}
+
+ {{ virtualmachine.resources }}
+
+ {% else %}
+
+ {{ virtualmachine.resources }}
+
+ {% endif %}
+ |
+
+ {% if virtualmachine.tag %}
+
+ {{ virtualmachine.tag }}
+
+ {% else %}
+
+ {{ virtualmachine.tag }}
+
+ {% endif %}
+ |
+
+ {% if virtualmachine.result %}
+
+ {{ virtualmachine.result }}
+
+ {% else %}
+
+ {{ virtualmachine.result }}
+
+ {% endif %}
+ |
+
+ {% endfor %}
+
+
+
+
+ {% endif %}
+ {% endfor %}
diff --git a/netbox_proxbox/urls.py b/netbox_proxbox/urls.py
index dd9a86f..b78c378 100755
--- a/netbox_proxbox/urls.py
+++ b/netbox_proxbox/urls.py
@@ -28,9 +28,6 @@
path("/delete/", views.ProxmoxVMDeleteView.as_view(), name="proxmoxvm_delete"),
path("/edit/", views.ProxmoxVMEditView.as_view(), name="proxmoxvm_edit"),
-
-
# Proxbox API full update
- #path("full_update/", ProxmoxVMFullUpdate.as_view(), name="proxmoxvm_full_update")
- path("full_update/", views.ProxmoxFullUpdate.as_view(), name="proxmoxvm_full_update")
-]
+ path("full_update/", views.ProxmoxFullUpdate.as_view(), name="proxmoxvm_full_update"),
+ path("single_update/", views.ProxmoxSingleUpdate.as_view(), name="proxmoxvm_single_update"),
diff --git a/netbox_proxbox/views.py b/netbox_proxbox/views.py
index e4ee81a..59e6e76 100755
--- a/netbox_proxbox/views.py
+++ b/netbox_proxbox/views.py
@@ -135,6 +135,29 @@ def table_data():
return [virtualmachines_table, nodes_table]
'''
+class ProxmoxSingleUpdate(PermissionRequiredMixin, View):
+ """Update a single Proxmox information on Netbox."""
+
+ # Define permission
+ permission_required = "netbox_proxbox.view_proxmoxvm"
+
+ # service incoming POST HTTP requests
+ # 'proxmox_domain' value is passed to post()
+ def post(self, request):
+ """Post request."""
+
+ proxmox_domain = self.request.POST.get('proxmox_domain')
+ json_result = proxbox_api.update.single(remove_unused = True, proxmox_domain = proxmox_domain)
+
+ return render(
+ request,
+ "netbox_proxbox/proxmox_vm_full_update.html",
+ {
+ "proxmox": json_result,
+ "proxmox_json": json.dumps(json_result, indent=4)
+ },
+ )
+
class ProxmoxFullUpdate(PermissionRequiredMixin, View):
"""Full Update of Proxmox information on Netbox."""
@@ -142,9 +165,6 @@ class ProxmoxFullUpdate(PermissionRequiredMixin, View):
# Define permission
permission_required = "netbox_proxbox.view_proxmoxvm"
-
-
-
# service incoming GET HTTP requests
# 'pk' value is passed to get() via URL defined in urls.py
def get(self, request):
diff --git a/reinstall.sh b/reinstall.sh
new file mode 100755
index 0000000..9e51666
--- /dev/null
+++ b/reinstall.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+systemctl stop netbox.service
+
+pip3 uninstall netbox-proxbox -y
+
+python3 setup.py develop
+
+systemctl start netbox.service