Skip to content

Commit

Permalink
Merge pull request #126 from netdevopsbr/add-multi-cluster
Browse files Browse the repository at this point in the history
Closes #33 and #123 - Add multi cluster support.
Thanks to @devopstales!
  • Loading branch information
emersonfelipesp authored Jul 21, 2023
2 parents 68121fd + 965276c commit 3ff985a
Show file tree
Hide file tree
Showing 15 changed files with 761 additions and 543 deletions.
79 changes: 38 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,47 +152,43 @@ 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
},
{
'domain': 'proxbox2.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': '039ab154-23b2-4be0-8d40-b66abc8c4668'
},
'ssl': False
}
]
'netbox': {
'domain': 'localhost', # Ensure localhost is added to ALLOWED_HOSTS
'http_port': 8001, # Gunicorn port.
'token': '0dd7cddfaee3b38bbffbd2937d44c4a03f9c9d38',
'ssl': False, # There is no support to SSL on Netbox yet, so let it always False.
'settings': {
'virtualmachine_role_id' : 0,
'node_role_id' : 0,
'site_id': 0
}
},
'fastapi': {
'uvicorn_host' : '0.0.0.0',
'uvicorn_port' : '8002',
'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
},
# The following json is optional and applies only for multi-cluster use
{
'domain': 'proxbox2.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.
'token': '0dd7cddfaee3b38bbffbd2937d44c4a03f9c9d38',
'ssl': False, # There is no support to SSL on Netbox yet, so let it always False.
'settings': {
'virtualmachine_role_id' : 0,
'node_role_id' : 0,
'site_id': 0
}
}
}
}


Expand All @@ -211,6 +207,7 @@ PLUGINS_CONFIG = {
```
(venv) $ cd /opt/netbox/netbox/
(venv) $ python3 manage.py migrate
(venv) $ python3 manage.py collectstatic --no-input
```

---
Expand All @@ -228,7 +225,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.
Expand Down
5 changes: 5 additions & 0 deletions netbox_custom_fields.csv
Original file line number Diff line number Diff line change
@@ -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
24 changes: 13 additions & 11 deletions netbox_proxbox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
67 changes: 24 additions & 43 deletions netbox_proxbox/proxbox_api/create/dcim.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
# PLUGIN_CONFIG variables
import logging

from typing import Annotated
from fastapi import Depends, FastAPI
from ..plugins_config import (
NETBOX_SESSION as nb,
NETBOX_NODE_ROLE_ID,
NETBOX_SITE_ID,
)

from ..plugins_config import NETBOX_NODE_ROLE_ID
from ..plugins_config import NETBOX_SESSION as nb
from ..plugins_config import NETBOX_SITE_ID
from . import extras, virtualization
from . import (
extras,
virtualization,
)

import logging

#
# dcim.manufacturers
#
async def manufacturer():
def manufacturer():
proxbox_manufacturer_name = 'Proxbox Basic Manufacturer'
proxbox_manufacturer_slug = 'proxbox-manufacturer'
proxbox_manufacturer_desc = 'Manufacturer Proxbox will use if none is configured by user in PLUGINS_CONFIG'
Expand Down Expand Up @@ -44,10 +46,7 @@ async def manufacturer():
#
# dcim.device_types
#
async def device_type(
manufacturer = Annotated[any, Depends(manufacturer, use_cache=False)],
tags = Annotated[any, Depends(extras.tag, use_cache=False)]
):
def device_type():
proxbox_device_type_model = 'Proxbox Model'
proxbox_device_type_slug = 'proxbox-model'
proxbox_device_type_comments = "Device Type Proxbox will use when creating the Cluster's Nodes. When the Node is created, you can change the device type to the actual server model."
Expand All @@ -62,11 +61,11 @@ async def device_type(
try:
# If Proxbox manufacturer does not exist, create one.
device_type = nb.dcim.device_types.create(
manufacturer = manufacturer.id,
manufacturer = manufacturer().id,
model = proxbox_device_type_model,
slug = proxbox_device_type_slug,
comments = proxbox_device_type_comments,
tags = [tags.id]
tags = [extras.tag().id]
)
except:
log_message = f"Error creating the '{proxbox_device_type_model}' device type. Possible errors: the model '{proxbox_device_type_model}' or slug '{proxbox_device_type_slug}' is already used."
Expand All @@ -82,10 +81,7 @@ async def device_type(
#
# dcim.sites
#
async def site(
tags = Annotated[any, Depends(extras.tag, use_cache=False)],
**kwargs,
):
def site(**kwargs):
# If site_id equals to 0, consider it is not configured by user and must be created by Proxbox
site_id = kwargs.get('site_id', 0)

Expand Down Expand Up @@ -116,7 +112,7 @@ async def site(
name = site_proxbox_name,
slug = site_proxbox_slug,
status = 'active',
tags = [tags.id]
tags = [extras.tag().id]
)
except:
return f"Error creating the '{site_proxbox_name}' site. Possible errors: the name '{site_proxbox_name}' or slug '{site_proxbox_slug}' is already used."
Expand All @@ -134,35 +130,20 @@ async def site(
#
# dcim.devices (nodes)
#
async def node(
proxmox_node,
cluster = Annotated[any, Depends(virtualization.cluster, use_cache=False)],
):
def node(proxmox, proxmox_node):
# Create json with basic NODE information
node_json = {}
node_json["name"] = proxmox_node['name']

device_role = await extras.role(role_id = NETBOX_NODE_ROLE_ID)
node_json["device_role"] = device_role.id

device_type_id = await device_type()
node_json["device_type"] = device_type_id.id

site_id = await site(site_id = NETBOX_SITE_ID)
node_json["site"] = site_id.id

node_json["device_role"] = extras.role(role_id = NETBOX_NODE_ROLE_ID).id
node_json["device_type"] = device_type().id
node_json["site"] = site(site_id = NETBOX_SITE_ID).id
node_json["status"] = 'active'
node_json["tags"] = [extras.tag().id]

tags_id = await extras.tag()
tags_id = tags_id.id
node_json["tags"] = [tags_id]

cluster = virtualization.cluster(proxmox)
if cluster:
if isinstance(cluster, str):
print(cluster)
return

node_json["cluster"] = cluster.id
if cluster != None:
node_json["cluster"] = cluster.id

# If device already exists, append (2) to final of the name
check_duplicate = proxmox_node.get("duplicate", False)
Expand Down
Loading

0 comments on commit 3ff985a

Please sign in to comment.