Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update version 1.0.2 #1

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Binary file added .DS_Store
Binary file not shown.
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
**/netbox
**/netbox-docker
**/*.pyc
**/__pycache__
**/.idea
.vscode/
dist/*
ci/docker-compose.override.yml
ci/reports
out/production
*.iml
build/*
netbox_excel.egg-info/*
7 changes: 7 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
include LICENSE
include README.md
include SECURITY.md
graft netbox_excel
prune netbox_excel/tests
global-exclude *.py[cod]
global-exclude __pycache__
63 changes: 63 additions & 0 deletions PKG-INFO
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
Metadata-Version: 2.1
Name: netbox-excel
Version: 1.0.0
Summary: Import device from file excel Netbox Plugin
Home-page: https://github.com/hocchudong/netbox-excel
Author-email: ducna <ducna@hcd@gmail.com.vn>
License: Apache-2.0
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Requires-Python: >=3.10.12
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: build
Requires-Dist: build==1.2.1; extra == "build"
Requires-Dist: setuptools==70.3.0; extra == "build"
Requires-Dist: twine==5.1.1; extra == "build"
Provides-Extra: tools
Requires-Dist: ruff==0.5.1; extra == "tools"


## Install Require

netbox version >= 4.0

## Known Issues

- WARNING: This plugin is only tested with a single NetBox version at this time.

## Installation Guide

### In mono service:

To install the plugin, first using pip and install netbox-excel:

```
cd /opt/netbox
source venv/bin/activate
pip install netbox-excel
```

Next, enable the plugin in /opt/netbox/netbox/netbox/configuration.py, or if you have a /configuration/plugins.py file, the plugins.py file will take precedence.

```
PLUGINS = [
'netbox_excel'
]
```
Then you may need to perform the final step of restarting the service to ensure that the changes take effect correctly:

```
python netbox/manage.py migrate netbox_excel
sudo systemctl restart netbox
```
Binary file added netbox_excel/.DS_Store
Binary file not shown.
16 changes: 16 additions & 0 deletions netbox_excel/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from netbox.plugins import PluginConfig

__version__ = "1.0.0"

class NetboxExcelConfig(PluginConfig):
name = "netbox_excel"
verbose_name = "Netbox excel"
description = "Import object from file excel"
version = __version__
author = "ducna"
author_email = "ducna@hcd.com.vn"
base_url = "netbox-excel"
required_settings = []
default_settings = {"version_info": False}

config = NetboxExcelConfig
Binary file added netbox_excel/__pycache__/__init__.cpython-310.pyc
Binary file not shown.
Binary file added netbox_excel/__pycache__/forms.cpython-310.pyc
Binary file not shown.
Binary file added netbox_excel/__pycache__/models.cpython-310.pyc
Binary file not shown.
Binary file added netbox_excel/__pycache__/navigation.cpython-310.pyc
Binary file not shown.
Binary file not shown.
Binary file added netbox_excel/__pycache__/urls.cpython-310.pyc
Binary file not shown.
Binary file added netbox_excel/__pycache__/views.cpython-310.pyc
Binary file not shown.
Empty file added netbox_excel/api/__init__.py
Empty file.
Binary file not shown.
Binary file not shown.
Binary file added netbox_excel/api/__pycache__/urls.cpython-310.pyc
Binary file not shown.
Binary file added netbox_excel/api/__pycache__/views.cpython-310.pyc
Binary file not shown.
24 changes: 24 additions & 0 deletions netbox_excel/api/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from rest_framework import serializers

from netbox.api.serializers import NetBoxModelSerializer
from netbox_excel.models import ImportExcel


class ImportExcelSerializer(NetBoxModelSerializer):
display = serializers.SerializerMethodField()

class Meta:
model = ImportExcel
fields = (
"id",
"name",
"description",
"tags",
"custom_field_data",
"created",
"last_updated",
)
brief_fields = ("id", "name", "description")

def get_display(self, obj):
return f"{obj}"
11 changes: 11 additions & 0 deletions netbox_excel/api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from netbox.api.routers import NetBoxRouter
from netbox_excel.api.views import (
NetboxExcelInfoRootView,
ImportExcelViewSet,
)

router = NetBoxRouter()
router.APIRootView = NetboxExcelInfoRootView

router.register("import_excel", ImportExcelViewSet)
urlpatterns = router.urls
20 changes: 20 additions & 0 deletions netbox_excel/api/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from rest_framework.routers import APIRootView

from netbox.api.viewsets import NetBoxModelViewSet
from netbox_excel.api.serializers import (
ImportExcelSerializer,
)
from netbox_excel.models import ImportExcel


class NetboxExcelInfoRootView(APIRootView):
"""
Netbox Excel API root view
"""

def get_view_name(self):
return "Netbox Excel"

class ImportExcelViewSet(NetBoxModelViewSet):
queryset = ImportExcel.objects.all()
serializer_class = ImportExcelSerializer
3 changes: 3 additions & 0 deletions netbox_excel/export/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .devices import get_device
from .export import export_all_view_rack , export_only_device
from .rack import get_rack_have_device
Binary file not shown.
Binary file not shown.
Binary file not shown.
6 changes: 6 additions & 0 deletions netbox_excel/export/devices.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from dcim.models import Device

def get_device():
devices = Device.objects.all()
devices = devices.order_by('rack', '-position')
return devices
201 changes: 201 additions & 0 deletions netbox_excel/export/export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
import openpyxl
from netbox_excel.models import ExportExcel
from .devices import get_device
from .rack import get_rack_have_device
import pandas as pd
# from io import StringIO
# import xlsxwriter
from django.http import HttpResponse , HttpResponseRedirect

def export_all_view_rack():
# Create a new workbook and select the active worksheet
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "Data Export"

# create the headers
headers = ['Rack', 'U/Rack','Tên Thiết bị', 'Chủng loại', 'Quản lý', 'Số HĐ', 'Model', 'SN', 'Thời gian lắp đặt', 'Ghi Chú']
sheet.append(headers)

try:
# get device
devices_list = get_device()
racks_list = [] # danh sách rack có thiết bị
item_sheet_list = [] # danh sách item device đã xử lý dữ liệu

# start loop for chuẩn bị dữ liệu export
for device in devices_list:
#Kiểm tra nếu thiết bị không nằm trong tủ rack hoặc không có position bỏ qua
if device.position is None:
continue
# get data custom feild
device_owner = ""
year_of_investment = ""
contract_number = ""
custom_fields = device.get_custom_fields_by_group()
for key, value in custom_fields[''].items():
if str(key) == 'Device owner' and value != None:
device_owner = value
elif str(key) == 'Year of investment' and value != None:
year_of_investment = value
elif str(key) == 'Contract number' and value != None:
contract_number = value

# create new item export
item_export = ExportExcel(
rack = str(device.rack),
device_role = str(device.role),
device_type = str(device.device_type),
device_name = str(device.name),
position = int(device.position), # U/Rack
serial_number = str(device.serial),
device_description = str(device.description),
owner_device = str(device_owner),
year_of_investment = str(year_of_investment),
contract_number = str(contract_number),
u_number = int(device.device_type.u_height),
)

# append data to item_sheet_list export
racks_list.append(str(device.rack))
item_sheet_list.append(item_export)
# end loop for chuẩn bị dữ liệu export

# lọc trùng rack
racks_list = sorted(list(set(racks_list)))
u_height_sheet = 2 # đếm dòng sheet dòng 1 là header nên bắt đầu từ 2
# start add item into sheet
for rack in racks_list:
u_height_rack = 42 # mỗi 1 rack có 42 lần add item ( 1 item = 1 U)
for i in range(42):
# kiểm tra trong list item export
device = find_device_item(item_sheet_list, rack, u_height_rack)
if device:
# add item into sheet
item = [
rack,
u_height_rack,
device.device_name,
device.device_role,
device.owner_device,
device.contract_number,
device.device_type,
device.serial_number,
device.year_of_investment,
device.device_description,
]
sheet.append(item)

# check height > 1 => merg cell
if device.u_number > 1:
# Từ cột thứ 3 đến cuối đều cần merg ô bằng chiều cao của thiết bị
height_device_in_sheet = u_height_sheet - device.u_number + 1
# copy data từ row position sang ô đầu tiên
for col in range(3, 11):
sheet.cell(row=height_device_in_sheet, column=col).value = sheet.cell(row=u_height_sheet, column=col).value

sheet.merge_cells(start_row=height_device_in_sheet, start_column=3, end_row=u_height_sheet, end_column=3)
sheet.merge_cells(start_row=height_device_in_sheet, start_column=4, end_row=u_height_sheet, end_column=4)
sheet.merge_cells(start_row=height_device_in_sheet, start_column=5, end_row=u_height_sheet, end_column=5)
sheet.merge_cells(start_row=height_device_in_sheet, start_column=6, end_row=u_height_sheet, end_column=6)
sheet.merge_cells(start_row=height_device_in_sheet, start_column=7, end_row=u_height_sheet, end_column=7)
sheet.merge_cells(start_row=height_device_in_sheet, start_column=8, end_row=u_height_sheet, end_column=8)
sheet.merge_cells(start_row=height_device_in_sheet, start_column=9, end_row=u_height_sheet, end_column=9)
sheet.merge_cells(start_row=height_device_in_sheet, start_column=10, end_row=u_height_sheet, end_column=10)
else:
# add item into sheet
empty_item = [rack,u_height_rack]
sheet.append(empty_item)
# print(f"add empty into rack {rack} and U{u_height_rack}")
# variable counter

u_height_rack-= 1
u_height_sheet+= 1

return workbook
except Exception as e:
print("error export all device")
return workbook

# Tìm device với rack name và position
def find_device_item(devices_list, rack_name, position):
for device in devices_list:
if device.rack == rack_name and device.position == position:
return device

return


def export_only_device():
# Create a new workbook and select the active worksheet
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "Data Export"

# create the headers
headers = ['Rack', 'Số U','Vị trí bắt đầu','Vị trí kế thúc', 'Tên Thiết bị', 'Chủng loại', 'Quản lý', 'Số HĐ', 'Model', 'SN', 'Thời gian lắp đặt', 'Ghi Chú']
sheet.append(headers)

try:

# check form data: 1. export all table
item_sheet_list = []
# get all device
devices_list = get_device()

# start loop for
for device in devices_list:
# get data custom feild
device_owner = ""
year_of_investment = ""
contract_number = ""
custom_fields = device.get_custom_fields_by_group()
for key, value in custom_fields[''].items():
if str(key) == 'Device owner' and value != None:
device_owner = value
elif str(key) == 'Year of investment' and value != None:
year_of_investment = value
elif str(key) == 'Contract number' and value != None:
contract_number = value
# Tính start U - end U
end_u = int(device.position) + int(device.device_type.u_height) - 1
# create new item export
item_export = ExportExcel(
rack = device.rack,
device_role = device.role,
device_type = device.device_type,
device_name = device.name,
position = int(device.position),
serial_number = device.serial,
device_description = device.description,
owner_device = device_owner,
year_of_investment = year_of_investment,
contract_number = contract_number,
u_number = int(device.device_type.u_height),
u_end = end_u,
)

# append data to item_sheet_list export
item_sheet_list.append(item_export)

# create item in sheet
item_sheet = [
str(item_export.rack),
str(item_export.u_number),
str(item_export.position), # U start
str(item_export.u_end), # U end
str(item_export.device_name),
str(item_export.device_role),
str(item_export.owner_device),
str(item_export.contract_number),
str(item_export.device_type),
str(item_export.serial_number),
str(item_export.year_of_investment),
str(item_export.device_description),
]
sheet.append(item_sheet)
# end loop for
return workbook
except Exception as e:
print("return empty excel")
return workbook
6 changes: 6 additions & 0 deletions netbox_excel/export/rack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from dcim.models import Rack

def get_rack_have_device():
racks = Rack.objects.all()
racks = racks.order_by('name')
return racks
Loading