NetBox 是用于建模和记录现代网络的领先解决方案。由 结合 IP 地址管理 (IPAM) 的传统学科和 具有强大 API 和扩展的数据中心基础架构管理 (DCIM), NetBox 为推动网络自动化提供了理想的“事实来源”。 NetBox 在 Apache 2.0 许可下作为开源软件提供 作为数千个组织中网络自动化的基石。

  • 物理基础设施:

    准确模拟物理世界,从全球区域到单个机柜。然后连接一切 - 网络、Console和电源!

  • 现代的IPAM:

    您期望的所有标准 IPAM 功能,IP地址自动层级以及 VRF 导入/导出跟踪、VLAN 管理和Overlay网络支持。

  • 传输线路:

    自信地管理来自不同服务提供商的关键电路的交付,并与您自己的基础设施无缝建模。

  • 电力跟踪:

    将上游电源的配电映射到单个电源线和插座。

  • 组织:

    以本机方式管理租户和联系人分配。

  • 强大的搜索功能:

    使用单个全局搜索功能轻松找到您需要的任何内容。

  • 综合日志记录:

    利用自动更改日志记录和用户提交的日志条目来跟踪Netbox随时间的增长。

  • 无限制的定制:

    自定义字段、自定义链接、标签、导出模板、自定义验证、报告、脚本等!

  • 灵活的权限:

    高级权限系统可实现非常灵活的权限委派。

  • 集成:

    通过其 REST 和 GraphQL API 轻松将 NetBox 连接到您的其他工具。

  • 插件:

    在核心应用程序中找不到您需要的内容?尝试众多社区插件之一 - 或构建自己的插件!

  • 认证

    :支持域控AD、LDAP、SSO、Azure AD、Okta等

NetBox 最初由DigitalOcean的网络工程团队构思,专为满足网络和基础设施工程师的需求而开发。

设计理念:

  • 复制真实世界(Replicate the Real World)
  • 充当“真理之源(Serve as a “Source of Truth”)
  • 保持简单(Keep it Simple)
  • 应用程序堆栈(Application Stack)

架构图

示例图

专为网络打造

与通用CMDB不同,NetBox策划了一个专门满足网络工程师和运营商需求的数据模型。它提供了精心设计的各种对象类型,以最好地满足基础架构设计和文档的需求。这些涵盖了网络技术的所有方面,从 IP 地址管理到布线再到覆盖层等等:

  • 分层地区、数据中心和物理位置
  • 机架、设备和设备组件
  • 线路连接和无线连接管理
  • 供电跟踪
  • 虚拟线路和提供商
  • 虚拟机和群集
  • IP 网段、汇聚和地址
  • VRF 和 RT
  • FHRP组(VRRP,HSRP等)
  • AS 编号
  • VLAN 和作用域 VLAN 组
  • L2VPN 虚拟网络
  • 租户分配
  • 联系人管理

安装环境介绍

使用Rocky Linux 9.2 (关闭SE Linux和防火墙)

使用Python 3.9

使用PostgreSQL 15

使用Redis 6

NetBox版本:3.5.6

硬件配置:建议4C8G以上,100G存储空间。

PS:没有使用Docker安装是为了方便修改代码。用Docker会更简单些。

安装和配置 PostgreSQL 数据库

关闭SE Linux和防火墙

1
2
3
4
5
6
7
systemctl disable --now firewalld
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config && setenforce 0

dnf install tree vim bash-completion -y

# 安装一些工具

安装数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
dnf module install postgresql:15 -y


# 指定安装15版本

postgresql-setup --initdb

# 初始化数据库


vim /var/lib/pgsql/data/pg_hba.conf

# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 scram-sha-256
# IPv6 local connections:
host all all ::1/128 scram-sha-256

# 将主机连接的加密方式将ident改为scram-sha-256即可。

systemctl enable --now postgresql

# 启动并设置开机启动

systemctl status postgresql
ss -an | grep 5432

# 查看是否正常启动

修改密码和创建数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo -u postgres psql

# 登录到PostgreSQL shell

ALTER USER postgres WITH PASSWORD 'Songxwn.com';

# 运行查询,为默认的PostgreSQL用户“postgres”设置新密码。

CREATE DATABASE netboxdb;

# 创建数据库

quit

# 退出

PS: 优化配置生成器:https://pgtune.leopard.in.ua/

安装和配置 Redis

深入配置可以参考:https://songxwn.com/redis-sentinel/

1
2
dnf install redis -y

配置访问密码

1
2
3
4
5
6
vim /etc/redis/redis.conf

requirepass Songxwn.com

# 打开配置文件,找到被注释的requirepass行,修改密码为Songxwn.com。保存文件并退出

配置启动并验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
systemctl enable --now redis

# 配置启动并开机启动

systemctl status redis
ss -an | grep 6379

# 验证启动

edis-cli
127.0.0.1:6379> AUTH songxwn.com
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> exit

# 输入密码登录验证是否正常

安装 Netbox

环境准备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
dnf install gcc libxml2-devel libxslt-devel libffi-devel libpq-devel openssl-devel redhat-rpm-config git -y

# 安装环境,系统默认有Python3.9


useradd -r -d /opt/netbox -s /usr/sbin/nologin netbox

# 创建netbox用户

mkdir -p /opt/netbox; cd /opt/netbox

# 创建netbox所属权限的文件,作为安装主文件夹。并CD过去。

git clone -b master --depth 1 https://github.com/netbox-community/netbox.git .

# 下载最新源代码,如果网络不允许,可以手动下载,上传到服务器。

chown -R netbox:netbox /opt/netbox

cd /opt/netbox/netbox/netbox

# 配置netbox文件夹权限所属。

tree -L 3 /opt/
/opt/
└── netbox
├── base_requirements.txt
├── CHANGELOG.md
├── contrib
│ ├── apache.conf
│ ├── gunicorn.py
│ ├── netbox-housekeeping.service
│ ├── netbox-housekeeping.sh
│ ├── netbox-housekeeping.timer
│ ├── netbox-rq.service
│ ├── netbox.service
│ ├── nginx.conf
│ ├── openapi2.json
│ └── openapi2.yaml
├── CONTRIBUTING.md
├── docs
│ ├── administration
│ ├── configuration
│ ├── customization
│ ├── development
│ ├── extra.css
│ ├── features
│ ├── getting-started
│ ├── index.md
│ ├── installation
│ ├── integrations
│ ├── introduction.md
│ ├── media
│ ├── models
│ ├── netbox_logo.png
│ ├── netbox_logo.svg
│ ├── plugins
│ ├── reference
│ ├── release-notes
│ └── _theme
├── LICENSE.txt
├── mkdocs.yml
├── netbox
│ ├── circuits
│ ├── core
│ ├── dcim
│ ├── extras
│ ├── generate_secret_key.py
│ ├── ipam
│ ├── manage.py
│ ├── media
│ ├── netbox
│ ├── project-static
│ ├── reports
│ ├── scripts
│ ├── templates
│ ├── tenancy
│ ├── users
│ ├── utilities
│ ├── virtualization
│ └── wireless
├── NOTICE
├── pyproject.toml
├── README.md
├── requirements.txt
├── scripts
│ ├── git-hooks
│ └── verify-bundles.sh
├── SECURITY.md
└── upgrade.sh

# 查看当前目录结构

生成并配置加密密钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cd /opt/netbox/netbox/netbox

# 确保进入到此目录

sudo -u netbox cp configuration_example.py configuration.py

# 创建配置文件,指定用户权限

sudo -u netbox python3 ../generate_secret_key.py

# 生成密钥,生成的密钥示例:SOGo0)YKa^RMGs&b=4p1AtnB-5nZq(!N#2-cah$q972DPCf&%F

sudo -u netbox vim configuration.py

SECRET_KEY = 'SOGo0)YKa^RMGs&b=4p1AtnB-5nZq(!N#2-cah$q972DPCf&%F'

# 打开配置文件,将生成的密钥写入进去。

配置数据库连接等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
cd /opt/netbox/netbox/netbox

sudo -u netbox vim configuration.py

ALLOWED_HOSTS = ["*"]

# 代表可以通过任意域名访问Netbox

DATABASE = {
'ENGINE': 'django.db.backends.postgresql', # Database engine
'NAME': 'netboxdb', # 配置数据库名字
'USER': 'postgres', # 数据库用户
'PASSWORD': 'Songxwn.com', # 数据库用户密码
'HOST': 'localhost', # Database server
'PORT': '', # Database port (leave blank for default)
'CONN_MAX_AGE': 300, # Max database connection age
}


REDIS = {
'tasks': {
'HOST': 'localhost',
'PORT': 6379,
'USERNAME': '',
'PASSWORD': 'Songxwn.com', #配置数据库密码
'DATABASE': 0,
'SSL': False,
},
'caching': {
'HOST': 'localhost',
'PORT': 6379,
'USERNAME': '',
'PASSWORD': 'Songxwn.com', #配置数据库密码
'DATABASE': 1,
'SSL': False,

}
}


SECRET_KEY = 'SOGo0)YKa^RMGs&b=4p1AtnB-5nZq(!N#2-cah$q972DPCf&%F'

# 加密密钥

ENABLE_LOCALIZATION = True

# 开启本地化,让一些选项中文。

TIME_ZONE = 'Asia/Shanghai'

# 配置时区

PAGINATE_COUNT = 60

# 配置查看的时候默认分页数量

初始化python虚拟环境,初始化数据库,生成静态Web。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sed -i 'pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple' /opt/netbox/upgrade.sh

# 配置安装环境的时候,使用清华源的pypi。(可不配置)

sudo -u netbox /opt/netbox/upgrade.sh

# 执行安装,需要较久时间。

Completed.
Removing expired user sessions (python3 netbox/manage.py clearsessions)...
Clearing the cache (python3 netbox/manage.py clearcache)...
Cache has been cleared.
Upgrade complete! Don't forget to restart the NetBox services:
> sudo systemctl restart netbox netbox-rq

# 出现以上字符代表成功。

创建管理员账号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
source /opt/netbox/venv/bin/activate

# 进入虚拟环境

cd /opt/netbox/netbox
python3 manage.py createsuperuser


Username (leave blank to use 'root'): admin
Email address: [emailprotected]
Password:
Password (again):
Superuser created successfully.

# 创建管理员 admin,输入邮箱和两遍密码。

配置每天定时清理任务

1
2
sudo ln -s /opt/netbox/contrib/netbox-housekeeping.sh /etc/cron.daily/netbox-housekeeping

配置Gunicorn WSGI

Gunicorn 是一个 Python 的 WSGI HTTP 服务器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
sudo -u netbox cp /opt/netbox/contrib/gunicorn.py /opt/netbox/gunicorn.py

# 复制创建配置文件

sudo -u netbox vim /opt/netbox/gunicorn.py

# 可修改配置文件,更改监听端口,默认8001

cp -v /opt/netbox/contrib/*.service /etc/systemd/system/

# 复制到系统服务

systemctl daemon-reload

# 重新加载系统服务

systemctl enable --now netbox netbox-rq

# 配置启动并开机启动



systemctl status netbox
systemctl status netbox-rq

# 查看状态

配置Nginx 作为反向代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
dnf install nginx -y

# 安装Nginx

vim /etc/nginx/conf.d/netbox.conf

# 创建配置文件,注意修改netbox.songxwn.com 为自己的域名。反向代理到8001端口

server {
listen 80;
# CHANGE THIS TO YOUR SERVER'S NAME
server_name netbox.songxwn.com;
client_max_body_size 25m;
fastcgi_connect_timeout 1200s;
fastcgi_send_timeout 1200s;
fastcgi_read_timeout 1200s;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 256k;

location /static/ {
alias /opt/netbox/netbox/static/;
}

location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;

}

}

systemctl enable --now nginx

# 配置启动并开机启动

systemctl status nginx

# 查看状态

至此安装完成,可以打开你的域名,输入管理员账号登录。

菜单汉化

文件路径

1
2
vim /opt/netbox/netbox/netbox/navigation/menu.py

个人示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
from django.utils.translation import gettext as _

from netbox.registry import registry
from . import *

#
# Nav menus
#

ORGANIZATION_MENU = Menu(
label=_('组织机构'),
icon_class='mdi mdi-domain',
groups=(
MenuGroup(
label=_('机房'),
items=(
get_model_item('dcim', 'site', _('数据中心')),
get_model_item('dcim', 'region', _('地区')),
get_model_item('dcim', 'sitegroup', _('数据中心组')),
get_model_item('dcim', 'location', _('具体地点')),
),
),
MenuGroup(
label=_('机架'),
items=(
get_model_item('dcim', 'rack', _('机柜')),
get_model_item('dcim', 'rackrole', _('机柜角色')),
get_model_item('dcim', 'rackreservation', _('预留')),
MenuItem(
link='dcim:rack_elevation_list',
link_text=_('立面图'),
permissions=['dcim.view_rack']
),
),
),
MenuGroup(
label=_('租凭'),
items=(
get_model_item('tenancy', 'tenant', _('租户')),
get_model_item('tenancy', 'tenantgroup', _('租户组')),
),
),
MenuGroup(
label=_('联系方式'),
items=(
get_model_item('tenancy', 'contact', _('联系人')),
get_model_item('tenancy', 'contactgroup', _('联系人组')),
get_model_item('tenancy', 'contactrole', _('联系人角色')),
get_model_item('tenancy', 'contactassignment', _('联系方式分配'), actions=[]),
),
),
),
)

DEVICES_MENU = Menu(
label=_('设备'),
icon_class='mdi mdi-server',
groups=(
MenuGroup(
label=_('Devices'),
items=(
get_model_item('dcim', 'device', _('设备')),
get_model_item('dcim', 'module', _('模块组件')),
get_model_item('dcim', 'devicerole', _('设备角色')),
get_model_item('dcim', 'platform', _('平台')),
get_model_item('dcim', 'virtualchassis', _('虚拟机箱')),
get_model_item('dcim', 'virtualdevicecontext', _('Virtual Device Contexts')),
),
),
MenuGroup(
label=_('类型'),
items=(
get_model_item('dcim', 'devicetype', _('设备型号')),
get_model_item('dcim', 'moduletype', _('模块类型')),
get_model_item('dcim', 'manufacturer', _('制造商')),
),
),
MenuGroup(
label=_('设备组件'),
items=(
get_model_item('dcim', 'interface', _('接口')),
get_model_item('dcim', 'frontport', _('前端口')),
get_model_item('dcim', 'rearport', _('后端口')),
get_model_item('dcim', 'consoleport', _('Console 端口')),
get_model_item('dcim', 'consoleserverport', _('Console 服务器端口')),
get_model_item('dcim', 'powerport', _('电力接口')),
get_model_item('dcim', 'poweroutlet', _('电源插座PDU')),
get_model_item('dcim', 'modulebay', _('模块组件托架')),
get_model_item('dcim', 'devicebay', _('设备托架')),
get_model_item('dcim', 'inventoryitem', _('库存物品')),
get_model_item('dcim', 'inventoryitemrole', _('库存项目角色')),
),
),
),
)

CONNECTIONS_MENU = Menu(
label=_('连接'),
icon_class='mdi mdi-connection',
groups=(
MenuGroup(
label=_('Connections'),
items=(
get_model_item('dcim', 'cable', _('线缆'), actions=['import']),
get_model_item('wireless', 'wirelesslink', _('无线连接')),
MenuItem(
link='dcim:interface_connections_list',
link_text=_('接口连接'),
permissions=['dcim.view_interface']
),
MenuItem(
link='dcim:console_connections_list',
link_text=_('Console 连接'),
permissions=['dcim.view_consoleport']
),
MenuItem(
link='dcim:power_connections_list',
link_text=_('电源连接'),
permissions=['dcim.view_powerport']
),
),
),
),
)

WIRELESS_MENU = Menu(
label=_('无线'),
icon_class='mdi mdi-wifi',
groups=(
MenuGroup(
label=_('Wireless'),
items=(
get_model_item('wireless', 'wirelesslan', _('无线局域网')),
get_model_item('wireless', 'wirelesslangroup', _('无线局域网组')),
),
),
),
)

IPAM_MENU = Menu(
label=_('IP地址管理'),
icon_class='mdi mdi-counter',
groups=(
MenuGroup(
label=_('IP Addresses'),
items=(
get_model_item('ipam', 'ipaddress', _('IP 地址')),
get_model_item('ipam', 'iprange', _('IP 范围')),
),
),
MenuGroup(
label=_('Prefixes'),
items=(
get_model_item('ipam', 'prefix', _('IP网段')),
get_model_item('ipam', 'role', _('网段和VLAN 角色')),
),
),
MenuGroup(
label=_('ASNs'),
items=(
get_model_item('ipam', 'asnrange', _('ASN Ranges')),
get_model_item('ipam', 'asn', _('ASNs')),
),
),
MenuGroup(
label=_('Aggregates'),
items=(
get_model_item('ipam', 'aggregate', _('Aggregates')),
get_model_item('ipam', 'rir', _('RIRs')),
),
),
MenuGroup(
label=_('VRFs'),
items=(
get_model_item('ipam', 'vrf', _('VRFs')),
get_model_item('ipam', 'routetarget', _('Route Targets')),
),
),
MenuGroup(
label=_('VLANs'),
items=(
get_model_item('ipam', 'vlan', _('VLANs')),
get_model_item('ipam', 'vlangroup', _('VLAN Groups')),
),
),
MenuGroup(
label=_('Other'),
items=(
get_model_item('ipam', 'fhrpgroup', _('FHRP Groups')),
get_model_item('ipam', 'servicetemplate', _('Service Templates')),
get_model_item('ipam', 'service', _('Services')),
),
),
),
)

OVERLAY_MENU = Menu(
label=_('网络虚拟化Overlay'),
icon_class='mdi mdi-graph-outline',
groups=(
MenuGroup(
label='L2VPNs',
items=(
get_model_item('ipam', 'l2vpn', _('L2VPNs')),
get_model_item('ipam', 'l2vpntermination', _('Terminations')),
),
),
),
)

VIRTUALIZATION_MENU = Menu(
label=_('裸金属虚拟化'),
icon_class='mdi mdi-monitor',
groups=(
MenuGroup(
label=_('Virtual Machines'),
items=(
get_model_item('virtualization', 'virtualmachine', _('虚拟机')),
get_model_item('virtualization', 'vminterface', _('虚拟机接口')),
),
),
MenuGroup(
label=_('Clusters'),
items=(
get_model_item('virtualization', 'cluster', _('虚拟化集群')),
get_model_item('virtualization', 'clustertype', _('虚拟化集群类型')),
get_model_item('virtualization', 'clustergroup', _('集群组')),
),
),
),
)

CIRCUITS_MENU = Menu(
label=_('线路'),
icon_class='mdi mdi-transit-connection-variant',
groups=(
MenuGroup(
label=_('Circuits'),
items=(
get_model_item('circuits', 'circuit', _('线路')),
get_model_item('circuits', 'circuittype', _('线路类型')),
),
),
MenuGroup(
label=_('Providers'),
items=(
get_model_item('circuits', 'provider', _('供应商')),
get_model_item('circuits', 'provideraccount', _('供应商账号')),
get_model_item('circuits', 'providernetwork', _('供应商网络')),
),
),
),
)

POWER_MENU = Menu(
label=_('电力'),
icon_class='mdi mdi-flash',
groups=(
MenuGroup(
label=_('Power'),
items=(
get_model_item('dcim', 'powerfeed', _('电源线')),
get_model_item('dcim', 'powerpanel', _('电源插座')),
),
),
),
)

PROVISIONING_MENU = Menu(
label=_('设备配置'),
icon_class='mdi mdi-file-document-multiple-outline',
groups=(
MenuGroup(
label=_('Configurations'),
items=(
get_model_item('extras', 'configcontext', _('Config Contexts'), actions=['add']),
get_model_item('extras', 'configtemplate', _('Config Templates'), actions=['add']),
),
),
),
)

CUSTOMIZATION_MENU = Menu(
label=_('自定义'),
icon_class='mdi mdi-toolbox-outline',
groups=(
MenuGroup(
label=_('Customization'),
items=(
get_model_item('extras', 'customfield', _('自定义字段')),
get_model_item('extras', 'customlink', _('自定义链接')),
get_model_item('extras', 'exporttemplate', _('自定义验证')),
get_model_item('extras', 'savedfilter', _('已保存的筛选条件')),
get_model_item('extras', 'tag', 'Tags'),
get_model_item('extras', 'imageattachment', _('图片附件'), actions=()),
),
),
MenuGroup(
label=_('Reports & Scripts'),
items=(
MenuItem(
link='extras:report_list',
link_text=_('报告'),
permissions=['extras.view_report'],
buttons=get_model_buttons('extras', "reportmodule", actions=['add'])
),
MenuItem(
link='extras:script_list',
link_text=_('脚本'),
permissions=['extras.view_script'],
buttons=get_model_buttons('extras', "scriptmodule", actions=['add'])
),
),
),
),
)

OPERATIONS_MENU = Menu(
label=_('运营'),
icon_class='mdi mdi-cogs',
groups=(
MenuGroup(
label=_('Integrations'),
items=(
get_model_item('core', 'datasource', _('Data Sources')),
get_model_item('extras', 'webhook', _('Webhooks')),
),
),
MenuGroup(
label=_('Jobs'),
items=(
MenuItem(
link='core:job_list',
link_text=_('Jobs'),
permissions=['core.view_job'],
),
),
),
MenuGroup(
label=_('Logging'),
items=(
get_model_item('extras', 'journalentry', _('日记列表'), actions=['import']),
get_model_item('extras', 'objectchange', _('操作日志'), actions=[]),
),
),
),
)


MENUS = [
ORGANIZATION_MENU,
DEVICES_MENU,
CONNECTIONS_MENU,
WIRELESS_MENU,
IPAM_MENU,
OVERLAY_MENU,
VIRTUALIZATION_MENU,
CIRCUITS_MENU,
POWER_MENU,
PROVISIONING_MENU,
CUSTOMIZATION_MENU,
OPERATIONS_MENU,
]

#
# Add plugin menus
#

for menu in registry['plugins']['menus']:
MENUS.append(menu)

if registry['plugins']['menu_items']:

# Build the default plugins menu
groups = [
MenuGroup(label=label, items=items)
for label, items in registry['plugins']['menu_items'].items()
]
plugins_menu = Menu(
label=_("Plugins"),
icon_class="mdi mdi-puzzle",
groups=groups
)
MENUS.append(plugins_menu)

注意

git下载和pip安装的时候受网络环境影响。

参考

https://docs.netbox.dev/en/stable/

https://www.howtoforge.com/how-to-install-netbox-on-rocky-linux-9/