Merge pull request #111 from ryanmerolle/dev

1.2.0 release
This commit is contained in:
Ryan Merolle 2023-01-23 08:33:31 -05:00 committed by GitHub
commit c95587fc7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
71 changed files with 388 additions and 1281 deletions

View File

@ -1,8 +1,8 @@
ARG NETBOX_VARIANT=v3.3 ARG NETBOX_VARIANT=v3.4
FROM netboxcommunity/netbox:${NETBOX_VARIANT} FROM netboxcommunity/netbox:${NETBOX_VARIANT}
ARG NETBOX_INITIALIZERS_VARIANT=3.3.* ARG NETBOX_INITIALIZERS_VARIANT=3.4.*
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive

View File

@ -10,37 +10,53 @@ services:
#- netbox-worker #- netbox-worker
env_file: env/netbox.env env_file: env/netbox.env
user: 'unit:root' user: 'unit:root'
healthcheck:
start_period: 60s
timeout: 3s
interval: 15s
test: "curl -f http://localhost:8080/api/ || exit 1"
volumes: volumes:
- ./initializers:/opt/netbox/initializers:z,ro
- ./configuration:/etc/netbox/config:z,ro - ./configuration:/etc/netbox/config:z,ro
#- ./reports:/etc/netbox/reports:z,ro
#- ./scripts:/etc/netbox/scripts:z,ro
#- netbox-media-files:/opt/netbox/netbox/media:z #- netbox-media-files:/opt/netbox/netbox/media:z
#netbox-worker: #netbox-worker:
# <<: *netbox # <<: *netbox
# depends_on: # depends_on:
# - redis # netbox:
# - postgres # condition: service_healthy
# command: # command:
# - /opt/netbox/venv/bin/python # - /opt/netbox/venv/bin/python
# - /opt/netbox/netbox/manage.py # - /opt/netbox/netbox/manage.py
# - rqworker # - rqworker
# healthcheck:
# start_period: 20s
# timeout: 3s
# interval: 15s
# test: "ps -aux | grep -v grep | grep -q rqworker || exit 1"
#netbox-housekeeping: #netbox-housekeeping:
# <<: *netbox # <<: *netbox
# depends_on: # depends_on:
# - redis # netbox:
# - postgres # condition: service_healthy
# command: # command:
# - /opt/netbox/housekeeping.sh # - /opt/netbox/housekeeping.sh
# healthcheck:
# start_period: 20s
# timeout: 3s
# interval: 15s
# test: "ps -aux | grep -v grep | grep -q housekeeping || exit 1"
# postgres # postgres
postgres: postgres:
image: postgres:14-alpine image: postgres:15-alpine
env_file: env/postgres.env env_file: env/postgres.env
volumes: volumes:
- netbox-postgres-data:/var/lib/postgresql/data - netbox-postgres-data:/var/lib/postgresql/data
# redis # redis
redis: redis:
image: redis:6-alpine image: redis:7-alpine
command: command:
- sh - sh
- -c # this is to evaluate the $REDIS_PASSWORD from the env - -c # this is to evaluate the $REDIS_PASSWORD from the env
@ -49,12 +65,14 @@ services:
#volumes: #volumes:
# - netbox-redis-data:/data # - netbox-redis-data:/data
#redis-cache: #redis-cache:
# image: redis:6-alpine # image: redis:7-alpine
# command: # command:
# - sh # - sh
# - -c # this is to evaluate the $REDIS_PASSWORD from the env # - -c # this is to evaluate the $REDIS_PASSWORD from the env
# - redis-server --requirepass $$REDIS_PASSWORD ## $$ because of docker-compose # - redis-server --requirepass $$REDIS_PASSWORD ## $$ because of docker-compose
# env_file: env/redis-cache.env # env_file: env/redis-cache.env
# volumes:
# - netbox-redis-cache-data:/data
volumes: volumes:
#netbox-media-files: #netbox-media-files:
@ -63,3 +81,5 @@ volumes:
driver: local driver: local
#netbox-redis-data: #netbox-redis-data:
# driver: local # driver: local
#netbox-redis-cache-data:
# driver: local

View File

@ -1,8 +0,0 @@
---
- prefix: 10.0.0.0/16
rir: RFC1918
tenant: tenant1
- prefix: fd00:ccdd::/32
rir: RFC4193 ULA
- prefix: 2001:db8::/32
rir: RFC3849

View File

@ -1,8 +0,0 @@
---
- asn: 1
rir: RFC1918
tenant: tenant1
- asn: 2
rir: RFC4193 ULA
- asn: 3
rir: RFC3849

View File

@ -1,72 +0,0 @@
---
# Required parameters for termination X ('a' or 'b'):
#
# ```
# termination_x_name -> name of interface
# termination_x_device -> name of the device interface belongs to
# termination_x_class -> required if different from 'Interface' which is the default
# ```
#
# Supported termination classes: Interface, ConsolePort, ConsoleServerPort, FrontPort, RearPort, PowerPort, PowerOutlet
#
#
# If a termination is a circuit then the required parameter is termination_x_circuit.
# Required parameters for a circuit termination:
#
# ```
# termination_x_circuit:
# term_side -> termination side of a circuit. Must be A or B
# cid -> circuit ID value
# site OR provider_network -> name of Site or ProviderNetwork respectively. If both provided, Site takes precedence
# ```
#
# If a termination is a power feed then the required parameter is termination_x_feed.
#
# ```
# termination_x_feed:
# name -> name of the PowerFeed object
# power_panel:
# name -> name of the PowerPanel the PowerFeed is attached to
# site -> name of the Site in which the PowerPanel is present
# ```
#
# Any other Cable parameters supported by Netbox are supported as the top level keys, e.g. 'type', 'status', etc.
#
# - termination_a_name: console
# termination_a_device: spine
# termination_a_class: ConsolePort
# termination_b_name: tty9
# termination_b_device: console-server
# termination_b_class: ConsoleServerPort
# type: cat6
#
- termination_a_name: to-server02
termination_a_device: server01
termination_b_name: to-server01
termination_b_device: server02
status: planned
type: mmf
- termination_a_name: eth0
termination_a_device: server02
termination_b_circuit:
term_side: A
cid: Circuit_ID-1
site: AMS 1
type: cat6
- termination_a_name: psu0
termination_a_device: server04
termination_a_class: PowerPort
termination_b_feed:
name: power feed 1
power_panel:
name: power panel AMS 1
site: AMS 1
- termination_a_name: outlet1
termination_a_device: server04
termination_a_class: PowerOutlet
termination_b_name: psu1
termination_b_device: server04
termination_b_class: PowerPort

View File

@ -1,7 +0,0 @@
---
- name: VPLS
slug: vpls
- name: MPLS
slug: mpls
- name: Internet
slug: internet

View File

@ -1,8 +0,0 @@
---
- cid: Circuit_ID-1
provider: Provider1
type: Internet
tenant: tenant1
- cid: Circuit_ID-2
provider: Provider2
type: MPLS

View File

@ -1,5 +0,0 @@
---
- name: Group 1
slug: group-1
- name: Group 2
slug: group-2

View File

@ -1,3 +0,0 @@
---
- name: Hyper-V
slug: hyper-v

View File

@ -1,8 +0,0 @@
---
- name: cluster1
type: Hyper-V
group: Group 1
tenant: tenant1
- name: cluster2
type: Hyper-V
site: SING 1

View File

@ -1,8 +0,0 @@
---
- name: Network-Team
slug: network-team
description: This is a new contact group for the Network-Team
- name: New Contact Group
slug: new-contact-group
description: This is a new contact group sub under of Network-Team
parent: Network-Team

View File

@ -1,4 +0,0 @@
---
- name: New Contact Role
slug: new-contact-role
description: This is a new contact role description

View File

@ -1,21 +0,0 @@
---
- name: Lee Widget
title: CEO of Widget Corp
phone: 221-555-1212
email: widgetCEO@widgetcorp.com
address: 1200 Nowhere Blvd, Scranton NJ, 555111
comments: This is a very important contact
- name: Ali Gator
group: Network-Team
title: Consultant for Widget Corp
phone: 221-555-1213
email: Consultant@widgetcorp.com
address: 1200 Nowhere Blvd, Scranton NJ, 555111
comments: This is a very important contact
- name: Karlchen Maier
group: New Contact Group
title: COO of Widget Corp
phone: 221-555-1214
email: Karlchen@widgetcorp.com
address: 1200 Nowhere Blvd, Scranton NJ, 555111
comments: This is a very important contact

View File

@ -1,118 +0,0 @@
---
## Possible Choices:
## type:
## - text
## - integer
## - boolean
## - date
## - url
## - select
## - multiselect
## - object
## - multiobject
## filter_logic:
## - disabled
## - loose
## - exact
##
## Examples:
text_field:
type: text
label: Custom Text
description: Enter text in a text field.
required: false
weight: 0
on_objects:
- dcim.models.Device
- dcim.models.Rack
- dcim.models.Site
- dcim.models.DeviceType
- ipam.models.IPAddress
- ipam.models.Prefix
- tenancy.models.Tenant
- virtualization.models.VirtualMachine
integer_field:
type: integer
label: Custom Number
description: Enter numbers into an integer field.
required: true
filter_logic: loose
validation_minimum: 0
validation_maximum: 255
weight: 10
on_objects:
- tenancy.models.Tenant
select_field:
type: select
label: Choose between items
required: false
filter_logic: exact
weight: 30
default: First Item
on_objects:
- dcim.models.Device
choices:
- First Item
- Second Item
- Third Item
- Fifth Item
- Fourth Item
select_field_legacy_format:
type: select
label: Choose between items
required: false
filter_logic: loose
weight: 30
on_objects:
- dcim.models.Device
choices:
- value: A # this is the deprecated format.
- value: B # we only use it for the tests.
- value: C # please see above for the new format.
- value: "D like deprecated"
weight: 999
- value: E
boolean_field:
type: boolean
label: Yes Or No?
required: true
filter_logic: loose
default: "false" # important: put "false" in quotes!
weight: 90
on_objects:
- dcim.models.Device
url_field:
type: url
label: Hyperlink
description: Link to something nice.
required: true
filter_logic: disabled
validation_regex: ^https://
on_objects:
- tenancy.models.Tenant
date_field:
type: date
label: Important Date
required: false
filter_logic: disabled
on_objects:
- dcim.models.Device
multiobject_field:
type: multiobject
label: Related Objects
description: IP addresses that belong to this location
required: true
filter_logic: loose
on_objects:
- dcim.models.Location
object_type: ipam.models.IPAddress
object_field:
type: object
label: ASN
description: This device has an ASN now
required: false
filter_logic: loose
on_objects:
- dcim.models.Device
object_type: ipam.models.ASN

View File

@ -1,22 +0,0 @@
---
## Possible Choices:
## new_window:
## - True
## - False
## content_type:
## - device
## - site
## - any-other-content-type
##
## Examples:
- name: link_to_repo
link_text: 'Link to Netbox Docker'
link_url: 'https://github.com/netbox-community/netbox-docker'
new_window: False
content_type: device
- name: link_to_localhost
link_text: 'Link to localhost'
link_url: 'http://localhost'
new_window: True
content_type: device

View File

@ -1,16 +0,0 @@
---
- name: switch
slug: switch
color: Grey
- name: router
slug: router
color: Cyan
- name: load-balancer
slug: load-balancer
color: Red
- name: server
slug: server
color: Blue
- name: patchpanel
slug: patchpanel
color: Black

View File

@ -1,58 +0,0 @@
---
- model: Model 1
manufacturer: Manufacturer 1
slug: model-1
u_height: 2
custom_field_data:
text_field: Description
- model: Model 2
manufacturer: Manufacturer 1
slug: model-2
custom_field_data:
text_field: Description
- model: Model 3
manufacturer: Manufacturer 1
slug: model-3
is_full_depth: false
u_height: 0
custom_field_data:
text_field: Description
- model: Other
manufacturer: No Name
slug: other
custom_field_data:
text_field: Description
interfaces:
- name: eth0
type: 1000base-t
mgmt_only: True
- name: eth1
type: 1000base-t
console_server_ports:
- name_template: ttyS[1-48]
type: rj-45
power_ports:
- name_template: psu[0,1]
type: iec-60320-c14
maximum_draw: 35
allocated_draw: 35
front_ports:
- name_template: front[1,2]
type: 8p8c
rear_port_template: rear[0,1]
rear_port_position_template: "[1,2]"
rear_ports:
- name_template: rear[0,1]
type: 8p8c
positions_template: "[3,2]"
device_bays:
- name: bay0 # both non-template and template field specified; non-template field takes precedence
name_template: bay[0-9]
label: test0
label_template: test[0-5,9,6-8]
description: Test description
power_outlets:
- name_template: outlet[0,1]
type: iec-60320-c5
power_port: psu0
feed_leg: B

View File

@ -1,54 +0,0 @@
---
## Possible Choices:
## face:
## - front
## - rear
## status:
## - offline
## - active
## - planned
## - staged
## - failed
## - inventory
## - decommissioning
##
## Examples:
- name: server01
device_role: server
device_type: Other
site: AMS 1
rack: rack-01
face: front
position: 1
custom_field_data:
text_field: Description
- name: server02
device_role: server
device_type: Other
site: AMS 2
rack: rack-02
face: front
position: 2
primary_ip4: 10.1.1.2/24
primary_ip6: 2001:db8:a000:1::2/64
custom_field_data:
text_field: Description
- name: server03
device_role: server
device_type: Other
site: SING 1
rack: rack-03
face: front
position: 3
custom_field_data:
text_field: Description
- name: server04
device_role: server
device_type: Other
site: SING 1
location: cage 101
face: front
position: 3
custom_field_data:
text_field: Description

View File

@ -1,10 +0,0 @@
---
applications:
users:
- technical_user
readers:
users:
- reader
writers:
users:
- writer

View File

@ -1,36 +0,0 @@
---
## Possible Choices:
## type:
## - virtual
## - lag
## - 1000base-t
## - ... and many more. See for yourself:
## https://github.com/netbox-community/netbox/blob/295d4f0394b431351c0cb2c3ecc791df68c6c2fb/netbox/dcim/choices.py#L510
##
## Examples:
- device: server01
name: ath0
type: 1000base-t
lag: ae0
bridge: br0
- device: server01
name: ath1
type: 1000base-t
parent: ath0
- device: server01
enabled: true
type: 1000base-x-sfp
name: to-server02
- device: server02
enabled: true
type: 1000base-x-sfp
name: to-server01
- device: server02
enabled: true
type: 1000base-t
name: eth0
- device: server02
enabled: true
type: virtual
name: loopback

View File

@ -1,45 +0,0 @@
---
## Possible Choices:
## status:
## - active
## - reserved
## - deprecated
## - dhcp
## role:
## - loopback
## - secondary
## - anycast
## - vip
## - vrrp
## - hsrp
## - glbp
## - carp
##
## Examples:
- address: 10.1.1.1/24
device: server01
interface: to-server02
status: active
vrf: vrf1
- address: 2001:db8:a000:1::1/64
device: server01
interface: to-server02
status: active
vrf: vrf1
- address: 10.1.1.2/24
device: server02
interface: to-server01
status: active
- address: 2001:db8:a000:1::2/64
device: server02
interface: to-server01
status: active
- address: 10.1.1.10/24
description: reserved IP
status: reserved
tenant: tenant1
- address: 2001:db8:a000:1::10/64
description: reserved IP
status: reserved
tenant: tenant1

View File

@ -1,4 +0,0 @@
---
- name: cage 101
slug: cage-101
site: SING 1

View File

@ -1,7 +0,0 @@
---
- name: Manufacturer 1
slug: manufacturer-1
- name: Manufacturer 2
slug: manufacturer-2
- name: No Name
slug: no-name

View File

@ -1,61 +0,0 @@
---
all.ro:
actions:
- view
description: 'Read Only for All Objects'
enabled: true
groups:
- applications
- readers
object_types: all
users:
- jdoe
all.rw:
actions:
- add
- change
- delete
- view
description: 'Read/Write for All Objects'
enabled: true
groups:
- writers
object_types: all
network_team.rw:
actions:
- add
- change
- delete
- view
description: "Network Team Permissions"
enabled: true
object_types:
circuits:
- circuit
- circuittermination
- circuittype
- provider
dcim: all
ipam:
- aggregate
- ipaddress
- prefix
- rir
- role
- routetarget
- service
- vlan
- vlangroup
- vrf
vips.change:
actions:
- change
description: "Update VIP object permission"
enabled: true
object_types:
ipam:
- ipaddress
groups:
- devops
constraints:
role: vip

View File

@ -1,16 +0,0 @@
---
- name: Platform 1
slug: platform-1
manufacturer: Manufacturer 1
napalm_driver: driver1
napalm_args: "{'arg1': 'value1', 'arg2': 'value2'}"
- name: Platform 2
slug: platform-2
manufacturer: Manufacturer 2
napalm_driver: driver2
napalm_args: "{'arg1': 'value1', 'arg2': 'value2'}"
- name: Platform 3
slug: platform-3
manufacturer: No Name
napalm_driver: driver3
napalm_args: "{'arg1': 'value1', 'arg2': 'value2'}"

View File

@ -1,15 +0,0 @@
---
- name: power feed 1
power_panel: power panel AMS 1
voltage: 208
amperage: 50
max_utilization: 80
phase: Single phase
rack: rack-01
- name: power feed 2
power_panel: power panel SING 1
voltage: 208
amperage: 50
max_utilization: 80
phase: Three-phase
rack: rack-03

View File

@ -1,6 +0,0 @@
---
- name: power panel AMS 1
site: AMS 1
- name: power panel SING 1
site: SING 1
location: cage 101

View File

@ -1,3 +0,0 @@
---
- name: Main Management
slug: main-management

View File

@ -1,30 +0,0 @@
---
## Possible Choices:
## status:
## - container
## - active
## - reserved
## - deprecated
##
## Examples:
- description: prefix1
prefix: 10.1.1.0/24
site: AMS 1
status: active
tenant: tenant1
vlan: vlan1
- description: prefix2
prefix: 10.1.2.0/24
site: AMS 2
status: active
tenant: tenant2
vlan: vlan2
is_pool: true
vrf: vrf2
- description: ipv6 prefix1
prefix: 2001:db8:a000:1::/64
site: AMS 2
status: active
tenant: tenant2
vlan: vlan2

View File

@ -1,7 +0,0 @@
---
- name: Provider1
slug: provider1
asn: 121
- name: Provider2
slug: provider2
asn: 122

View File

@ -1,13 +0,0 @@
---
- name: Role 1
slug: role-1
color: Pink
- name: Role 2
slug: role-2
color: Cyan
- name: Role 3
slug: role-3
color: Grey
- name: Role 4
slug: role-4
color: Teal

View File

@ -1,42 +0,0 @@
---
## Possible Choices:
## width:
## - 19
## - 23
## types:
## - 2-post-frame
## - 4-post-frame
## - 4-post-cabinet
## - wall-frame
## - wall-cabinet
## outer_unit:
## - mm
## - in
##
## Examples:
- site: AMS 1
name: rack-01
role: Role 1
type: 4-post-cabinet
width: 19
u_height: 47
custom_field_data:
text_field: Description
- site: AMS 2
name: rack-02
role: Role 2
type: 4-post-cabinet
width: 19
u_height: 47
custom_field_data:
text_field: Description
- site: SING 1
name: rack-03
location: cage 101
role: Role 3
type: 4-post-cabinet
width: 19
u_height: 47
custom_field_data:
text_field: Description

View File

@ -1,11 +0,0 @@
---
- name: Singapore
slug: singapore
- name: Amsterdam
slug: amsterdam
- name: Downtown
slug: downtown
parent: Amsterdam
- name: Suburbs
slug: suburbs
parent: Amsterdam

View File

@ -1,10 +0,0 @@
---
- is_private: true
name: RFC1918
slug: rfc1918
- is_private: true
name: RFC4193 ULA
slug: rfc4193-ula
- is_private: true
name: RFC3849
slug: rfc3849

View File

@ -1,4 +0,0 @@
---
- name: 65000:1001
tenant: tenant1
- name: 65000:1002

View File

@ -1,16 +0,0 @@
---
- name: DNS
protocol: TCP
ports:
- 53
virtual_machine: virtual machine 1
- name: DNS
protocol: UDP
ports:
- 53
virtual_machine: virtual machine 1
- name: MISC
protocol: UDP
ports:
- 4000
device: server01

View File

@ -1,31 +0,0 @@
---
- name: AMS 1
slug: ams1
region: Downtown
status: active
facility: Amsterdam 1
custom_field_data:
text_field: Description for AMS1
- name: AMS 2
slug: ams2
region: Downtown
status: active
facility: Amsterdam 2
custom_field_data:
text_field: Description for AMS2
- name: AMS 3
slug: ams3
region: Suburbs
status: active
facility: Amsterdam 3
tenant: tenant1
custom_field_data:
text_field: Description for AMS3
- name: SING 1
slug: sing1
region: Singapore
status: active
facility: Singapore 1
tenant: tenant2
custom_field_data:
text_field: Description for SING1

View File

@ -1,13 +0,0 @@
---
- name: Tag 1
slug: tag-1
color: Pink
- name: Tag 2
slug: tag-2
color: Cyan
- name: Tag 3
slug: tag-3
color: Grey
- name: Tag 4
slug: tag-4
color: Teal

View File

@ -1,5 +0,0 @@
---
- name: Tenant Group 1
slug: tenant-group-1
- name: Tenant Group 2
slug: tenant-group-2

View File

@ -1,6 +0,0 @@
---
- name: tenant1
slug: tenant1
- name: tenant2
slug: tenant2
group: Tenant Group 2

View File

@ -1,13 +0,0 @@
---
technical_user:
api_token: "" # a token is generated automatically unless the value is explicity set to empty
reader:
api_token: "" # a token is generated automatically unless the value is explicity set to empty
writer:
api_token: "" # a token is generated automatically unless the value is explicity set to empty
jdoe:
first_name: John
last_name: Doe
is_active: True
is_superuser: False
is_staff: False

View File

@ -1,29 +0,0 @@
---
## Possible Choices:
## status:
## - active
## - offline
## - staged
##
## Examples:
- cluster: cluster1
comments: VM1
disk: 200
memory: 4096
name: virtual machine 1
platform: Platform 2
status: active
tenant: tenant1
vcpus: 8
- cluster: cluster1
comments: VM2
disk: 100
memory: 2048
name: virtual machine 2
platform: Platform 2
primary_ip4: 10.1.1.10/24
primary_ip6: 2001:db8:a000:1::10/64
status: active
tenant: tenant1
vcpus: 8

View File

@ -1,13 +0,0 @@
---
- description: Network Interface 1
enabled: true
mac_address: 00:77:77:77:77:77
mtu: 1500
name: Network Interface 1
virtual_machine: virtual machine 1
- description: Network Interface 2
enabled: true
mac_address: 00:55:55:55:55:55
mtu: 1500
name: Network Interface 2
virtual_machine: virtual machine 1

View File

@ -1,25 +0,0 @@
---
- name: VLAN group 1
scope_type: dcim.region
scope: Amsterdam
slug: vlan-group-1
- name: VLAN group 2
scope_type: dcim.site
scope: AMS 1
slug: vlan-group-2
- name: VLAN group 3
scope_type: dcim.location
scope: cage 101
slug: vlan-group-3
- name: VLAN group 4
scope_type: dcim.rack
scope: rack-01
slug: vlan-group-4
- name: VLAN group 5
scope_type: virtualization.cluster
scope: cluster1
slug: vlan-group-5
- name: VLAN group 6
scope_type: virtualization.clustergroup
scope: Group 1
slug: vlan-group-6

View File

@ -1,20 +0,0 @@
---
## Possible Choices:
## status:
## - active
## - reserved
## - deprecated
##
## Examples:
- name: vlan1
site: AMS 1
status: active
vid: 5
role: Main Management
description: VLAN 5 for MGMT
- group: VLAN group 2
name: vlan2
site: AMS 1
status: active
vid: 1300

View File

@ -1,9 +0,0 @@
---
- enforce_unique: true
name: vrf1
tenant: tenant1
description: main VRF
- enforce_unique: true
name: vrf2
rd: "6500:6500"
tenant: tenant2

View File

@ -1,28 +0,0 @@
---
## Possible Choices:
## object_types:
## - device
## - site
## - any-other-content-type
## types:
## - type_create
## - type_update
## - type_delete
## Examples:
- name: device_creation
payload_url: 'http://localhost:8080'
object_types:
- device
- cable
type_create: True
- name: device_update
payload_url: 'http://localhost:8080'
object_types:
- device
type_update: True
- name: device_delete
payload_url: 'http://localhost:8080'
object_types:
- device
type_delete: True

View File

@ -23,14 +23,14 @@ body:
attributes: attributes:
label: NetBox access-list plugin version label: NetBox access-list plugin version
description: What version of the NetBox access-list plugin are you currently running? description: What version of the NetBox access-list plugin are you currently running?
placeholder: v0.1 placeholder: v1.2.0
validations: validations:
required: true required: true
- type: input - type: input
attributes: attributes:
label: NetBox version label: NetBox version
description: What version of NetBox are you currently running? description: What version of NetBox are you currently running?
placeholder: v3.2.7 placeholder: v3.4.3
validations: validations:
required: true required: true
- type: textarea - type: textarea

View File

@ -15,7 +15,7 @@ body:
attributes: attributes:
label: NetBox version label: NetBox version
description: What version of NetBox are you currently running? description: What version of NetBox are you currently running?
placeholder: v3.2.5 placeholder: v3.4.3
validations: validations:
required: true required: true
- type: dropdown - type: dropdown

View File

@ -1,7 +1,8 @@
PLUGIN_NAME=netbox_acls PLUGIN_NAME=netbox_acls
REPO_PATH=/opt/netbox/netbox/netbox-acls REPO_PATH=/opt/netbox/netbox/netbox-acls
VENV_PY_PATH=/opt/netbox/venv/bin/python3 VENV_PY_PATH=/opt/netbox/venv/bin/python3
NETBOX_MANAGE_PATH=/opt/netbox/netbox/manage.py NETBOX_MANAGE_PATH=/opt/netbox/netbox
NETBOX_INITIALIZER_PATH=${NETBOX_MANAGE_PATH}/netbox_initializers/
VERFILE=./version.py VERFILE=./version.py
.PHONY: help ## Display help message .PHONY: help ## Display help message
@ -26,7 +27,7 @@ help:
.PHONY: nbshell ## Run nbshell .PHONY: nbshell ## Run nbshell
nbshell: nbshell:
${VENV_PY_PATH} ${NETBOX_MANAGE_PATH} nbshell ${VENV_PY_PATH} ${NETBOX_MANAGE_PATH}/manage.py nbshell
from netbox_acls.models import * from netbox_acls.models import *
.PHONY: setup ## Copy plugin settings. Setup NetBox plugin. .PHONY: setup ## Copy plugin settings. Setup NetBox plugin.
@ -36,27 +37,31 @@ setup:
.PHONY: example_initializers ## Run initializers .PHONY: example_initializers ## Run initializers
example_initializers: example_initializers:
-${VENV_PY_PATH} ${NETBOX_MANAGE_PATH} copy_initializers_examples --path /opt/netbox/netbox/netbox-acls/.devcontainer/initializers -${VENV_PY_PATH} ${NETBOX_MANAGE_PATH}/manage.py copy_initializers_examples --path /opt/netbox/netbox/netbox-acls/.devcontainer/initializers
.PHONY: load_initializers ## Run initializers .PHONY: load_initializers ## Run initializers
load_initializers: load_initializers:
-${VENV_PY_PATH} ${NETBOX_MANAGE_PATH} load_initializer_data --path /opt/netbox/netbox/netbox-acls/.devcontainer/initializers -${VENV_PY_PATH} ${NETBOX_MANAGE_PATH}/manage.py load_initializer_data --path /opt/netbox/netbox/netbox-acls/.devcontainer/initializers
.PHONY: makemigrations ## Run makemigrations .PHONY: makemigrations ## Run makemigrations
makemigrations: makemigrations:
-${VENV_PY_PATH} ${NETBOX_MANAGE_PATH} makemigrations --name ${PLUGIN_NAME} -${VENV_PY_PATH} ${NETBOX_MANAGE_PATH}/manage.py makemigrations --name ${PLUGIN_NAME}
.PHONY: migrate ## Run migrate .PHONY: migrate ## Run migrate
migrate: migrate:
-${VENV_PY_PATH} ${NETBOX_MANAGE_PATH} migrate -${VENV_PY_PATH} ${NETBOX_MANAGE_PATH}/manage.py migrate
.PHONY: collectstatic .PHONY: collectstatic
collectstatic: collectstatic:
-${VENV_PY_PATH} ${NETBOX_MANAGE_PATH} collectstatic --no-input -${VENV_PY_PATH} ${NETBOX_MANAGE_PATH}/manage.py collectstatic --no-input
.PHONY: initializers .PHONY: initializers
initializers: initializers:
-${VENV_PY_PATH} ${NETBOX_MANAGE_PATH} load_initializer_data --path /opt/netbox/netbox/netbox-acls/.devcontainer/initializers -rm -rf ${NETBOX_INITIALIZER_PATH}
-mkdir ${NETBOX_INITIALIZER_PATH}
-${VENV_PY_PATH} ${NETBOX_MANAGE_PATH}/manage.py copy_initializers_examples --path ${NETBOX_INITIALIZER_PATH}
-for file in ${NETBOX_INITIALIZER_PATH}/*.yml; do sed -i "s/^# //g" "$$file"; done
-${VENV_PY_PATH} ${NETBOX_MANAGE_PATH}/manage.py load_initializer_data --path ${NETBOX_INITIALIZER_PATH}
.PHONY: start ## Start NetBox .PHONY: start ## Start NetBox
start: start:

View File

@ -37,10 +37,10 @@ See the [CONTRIBUTING](CONTRIBUTING.md) for more information.
Each Plugin Version listed below has been tested with its corresponding NetBox Version. Each Plugin Version listed below has been tested with its corresponding NetBox Version.
| NetBox Version | Plugin Version | | NetBox Version | Plugin Version |
|----------------|----------------| |:--------------:|:--------------:|
| 3.2 | 1.0.1 | | 3.2 | 1.0.1 |
| 3.3 | 1.1.1 | | 3.3 | 1.1.0 |
| 3.4 | 1.2.0(coming) | | 3.4 | 1.2.0 |
## Installing ## Installing
@ -81,8 +81,8 @@ To develop this plugin further one can use the included .devcontainer configurat
1. In the WSL terminal, enter `code` to run Visual studio code. 1. In the WSL terminal, enter `code` to run Visual studio code.
2. Install the devcontainer extension "ms-vscode-remote.remote-containers" 2. Install the devcontainer extension "ms-vscode-remote.remote-containers"
3. Press Ctrl+Shift+P and use the "Dev Container: Clone Repository in Container Volume" function to clone this repository. This will take a while depending on your computer 3. Press Ctrl+Shift+P and use the "Dev Container: Clone Repository in Container Volume" function to clone this repository. This will take a while depending on your computer
4. If you'd like the netbox instance to be prepopulated run `make Makefile example_initializers` and `make Makefile load_initializers` 4. If you'd like the netbox instance to be prepopulated with example data from [netbox-initializers](https://github.com/tobiasge/netbox-initializers) run `make initializers`
5. Start the netbox instance using `make Makefile all` 5. Start the netbox instance using `make all`
Your netbox instance will be served under 0.0.0.0:8000, so it should now be available under localhost:8000. Your netbox instance will be served under 0.0.0.0:8000, so it should now be available under localhost:8000.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 363 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 360 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 437 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 386 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 330 KiB

View File

@ -17,9 +17,8 @@ class NetBoxACLsConfig(PluginConfig):
version = __version__ version = __version__
description = "Manage simple ACLs in NetBox" description = "Manage simple ACLs in NetBox"
base_url = "access-lists" base_url = "access-lists"
min_version = "3.3.0" min_version = "3.4.0"
max_version = "3.3.99" max_version = "3.4.99"
# default_settings = {}
config = NetBoxACLsConfig config = NetBoxACLsConfig

View File

@ -28,8 +28,12 @@ class AccessListViewSet(NetBoxModelViewSet):
Defines the view set for the django AccessList model & associates it to a view. Defines the view set for the django AccessList model & associates it to a view.
""" """
queryset = models.AccessList.objects.prefetch_related("tags").annotate( queryset = (
rule_count=Count("aclextendedrules") + Count("aclstandardrules"), models.AccessList.objects.prefetch_related("tags")
.annotate(
rule_count=Count("aclextendedrules") + Count("aclstandardrules"),
)
.prefetch_related("tags")
) )
serializer_class = AccessListSerializer serializer_class = AccessListSerializer
filterset_class = filtersets.AccessListFilterSet filterset_class = filtersets.AccessListFilterSet

View File

@ -2,82 +2,77 @@
Define the plugin menu buttons & the plugin navigation bar enteries. Define the plugin menu buttons & the plugin navigation bar enteries.
""" """
from extras.plugins import PluginMenuButton, PluginMenuItem from extras.plugins import PluginMenu, PluginMenuButton, PluginMenuItem
from utilities.choices import ButtonColorChoices from utilities.choices import ButtonColorChoices
# #
# Define plugin menu buttons # Define plugin menu buttons
# #
accesslist_buttons = [ menu = PluginMenu(
PluginMenuButton( label="Access Lists",
link="plugins:netbox_acls:accesslist_add", groups=(
title="Add", (
icon_class="mdi mdi-plus-thick", "ACLs",
color=ButtonColorChoices.GREEN, (
permissions=["netbox_acls.add_accesslist"], PluginMenuItem(
), link="plugins:netbox_acls:accesslist_list",
] link_text="Access Lists",
permissions=["netbox_acls.view_accesslist"],
aclstandardrule_butons = [ buttons=(
PluginMenuButton( PluginMenuButton(
link="plugins:netbox_acls:aclstandardrule_add", link="plugins:netbox_acls:accesslist_add",
title="Add", title="Add",
icon_class="mdi mdi-plus-thick", icon_class="mdi mdi-plus-thick",
color=ButtonColorChoices.GREEN, color=ButtonColorChoices.GREEN,
permissions=["netbox_acls.add_aclstandardrule"], permissions=["netbox_acls.add_accesslist"],
), ),
] ),
),
aclextendedrule_butons = [ PluginMenuItem(
PluginMenuButton( link="plugins:netbox_acls:aclstandardrule_list",
link="plugins:netbox_acls:aclextendedrule_add", link_text="Standard Rules",
title="Add", permissions=["netbox_acls.view_aclstandardrule"],
icon_class="mdi mdi-plus-thick", buttons=(
color=ButtonColorChoices.GREEN, PluginMenuButton(
permissions=["netbox_acls.add_aclextendedrule"], link="plugins:netbox_acls:aclstandardrule_add",
), title="Add",
] icon_class="mdi mdi-plus-thick",
color=ButtonColorChoices.GREEN,
accesslistassignment_buttons = [ permissions=["netbox_acls.add_aclstandardrule"],
PluginMenuButton( ),
link="plugins:netbox_acls:aclinterfaceassignment_add", ),
title="Add", ),
icon_class="mdi mdi-plus-thick", PluginMenuItem(
color=ButtonColorChoices.GREEN, link="plugins:netbox_acls:aclextendedrule_list",
permissions=["netbox_acls.add_aclinterfaceassignment"], link_text="Extended Rules",
), permissions=["netbox_acls.view_aclextendedrule"],
] buttons=(
PluginMenuButton(
# link="plugins:netbox_acls:aclextendedrule_add",
# Define navigation bar links including the above buttons defined. title="Add",
# icon_class="mdi mdi-plus-thick",
color=ButtonColorChoices.GREEN,
menu_items = ( permissions=["netbox_acls.add_aclextendedrule"],
PluginMenuItem( ),
link="plugins:netbox_acls:accesslist_list", ),
link_text="Access Lists", ),
buttons=accesslist_buttons, PluginMenuItem(
permissions=["netbox_acls.view_accesslist"], link="plugins:netbox_acls:aclinterfaceassignment_list",
), link_text="Interface Assignments",
# Comment out Standard Access List rule to force creation in the ACL view permissions=["netbox_acls.view_aclinterfaceassignment"],
PluginMenuItem( buttons=(
link="plugins:netbox_acls:aclstandardrule_list", PluginMenuButton(
link_text="ACL Standard Rules", link="plugins:netbox_acls:aclinterfaceassignment_add",
buttons=aclstandardrule_butons, title="Add",
permissions=["netbox_acls.view_aclstandardrule"], icon_class="mdi mdi-plus-thick",
), color=ButtonColorChoices.GREEN,
# Comment out Extended Access List rule to force creation in the ACL view permissions=["netbox_acls.add_aclinterfaceassignment"],
PluginMenuItem( ),
link="plugins:netbox_acls:aclextendedrule_list", ),
link_text="ACL Extended Rules", ),
buttons=aclextendedrule_butons, ),
permissions=["netbox_acls.view_aclextendedrule"], ),
),
PluginMenuItem(
link="plugins:netbox_acls:aclinterfaceassignment_list",
link_text="ACL Interface Assignments",
buttons=accesslistassignment_buttons,
permissions=["netbox_acls.view_aclinterfaceassignment"],
), ),
icon_class="mdi mdi-lock",
) )

View File

@ -1,98 +0,0 @@
from django.contrib.contenttypes.models import ContentType
from extras.plugins import PluginTemplateExtension
from .models import AccessList, ACLInterfaceAssignment
__all__ = (
"AccessLists",
"ACLInterfaceAssignments",
"DeviceAccessLists",
"VirtualChassisAccessLists",
"VMAccessLists",
"DeviceACLInterfaceAssignments",
"VMAACLInterfaceAssignments",
)
class ACLInterfaceAssignments(PluginTemplateExtension):
def right_page(self):
obj = self.context["object"]
acl_interface_assignments = None
ctype = ContentType.objects.get_for_model(obj)
if ctype.model in ["interface", "vminterface"]:
acl_interface_assignments = ACLInterfaceAssignment.objects.filter(
assigned_object_id=obj.pk,
assigned_object_type=ctype,
)
if ctype.model == "interface":
parent_type = "device"
parent_id = obj.device.pk
elif ctype.model == "vminterface":
parent_type = "virtual_machine"
parent_id = obj.virtual_machine.pk
else:
parent_type = None
parent_id = None
return self.render(
"inc/assigned_interface/access_lists.html",
extra_context={
"acl_interface_assignments": acl_interface_assignments,
"type": ctype.model,
"parent_type": parent_type,
"parent_id": parent_id,
},
)
class AccessLists(PluginTemplateExtension):
def right_page(self):
obj = self.context["object"]
access_lists = None
ctype = ContentType.objects.get_for_model(obj)
if ctype.model in ["device", "virtualchassis", "virtualmachine"]:
access_lists = AccessList.objects.filter(
assigned_object_id=obj.pk,
assigned_object_type=ctype,
)
return self.render(
"inc/assigned_host/access_lists.html",
extra_context={
"access_lists": access_lists,
"type": ctype.model
if ctype.model == "device"
else ctype.name.replace(" ", "_"),
},
)
class DeviceAccessLists(AccessLists):
model = "dcim.device"
class VirtualChassisAccessLists(AccessLists):
model = "dcim.virtualchassis"
class VMAccessLists(AccessLists):
model = "virtualization.virtualmachine"
class DeviceACLInterfaceAssignments(ACLInterfaceAssignments):
model = "dcim.interface"
class VMAACLInterfaceAssignments(ACLInterfaceAssignments):
model = "virtualization.vminterface"
template_extensions = [
DeviceAccessLists,
VirtualChassisAccessLists,
VMAccessLists,
DeviceACLInterfaceAssignments,
VMAACLInterfaceAssignments,
]

View File

@ -1,13 +0,0 @@
<div class="card">
<h5 class="card-header">
Access Lists
</h5>
<div class="card-body">
{% include 'inc/assigned_host/assigned_access_lists.html' %}
</div>
<div class="card-footer text-end noprint">
<a href="{% url 'plugins:netbox_acls:accesslist_add' %}?{{ type }}={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-primary">
<i class="mdi mdi-plus-thick"></i> Add Access List
</a>
</div>
</div>

View File

@ -1,27 +0,0 @@
{% if access_lists %}
<table class="table table-hover">
<tr>
<th>Name</th>
<th>Type</th>
<th>Default Action</th>
<th>Rule Count</th>
</tr>
{% for object in access_lists %}
<tr>
<td>{{ object|linkify }}</td>
<td>{{ object.type|title }}</td>
<td>{{ object.default_action|title }}</td>
{% if object.type == 'standard' %}
<td>{{ object.aclstandardrules.count|placeholder }}</td>
{% elif object.type == 'extended' %}
<td>{{ object.aclextendedrules.count|placeholder }}</td>
{% endif %}
</tr>
{% endfor %}
</table>
{% else %}
<div class="text-muted">
None found
</div>
{% endif %}

View File

@ -1,13 +0,0 @@
<div class="card">
<h5 class="card-header">
Access Lists
</h5>
<div class="card-body">
{% include 'inc/assigned_interface/assigned_access_lists.html' %}
</div>
<div class="card-footer text-end noprint">
<a href="{% url 'plugins:netbox_acls:aclinterfaceassignment_add' %}?{{ parent_type }}={{ parent_id }}&{{ type }}={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-primary">
<i class="mdi mdi-plus-thick"></i> Assign Access List
</a>
</div>
</div>

View File

@ -1,29 +0,0 @@
{% if acl_interface_assignments %}
<table class="table table-hover">
<tr>
<th>Name</th>
<th>Type</th>
<th>Default Action</th>
<th>Rule Count</th>
<th>Direction</th>
</tr>
{% for object in acl_interface_assignments %}
<tr>
<td>{{ object.access_list|linkify }}</td>
<td>{{ object.access_list.type|title }}</td>
<td>{{ object.access_list.default_action|title }}</td>
{% if object.access_list.type == 'standard' %}
<td>{{ object.access_list.aclstandardrules.count|placeholder }}</td>
{% elif object.access_list.type == 'extended' %}
<td>{{ object.access_list.aclextendedrules.count|placeholder }}</td>
{% endif %}
<td>{{ object.direction|title }}</td>
</tr>
{% endfor %}
</table>
{% else %}
<div class="text-muted">
None
</div>
{% endif %}

View File

@ -0,0 +1,31 @@
{% extends 'generic/object.html' %}
{% load buttons %}
{% load helpers %}
{% load plugins %}
{% load render_table from django_tables2 %}
{% block extra_controls %}
{% if perms.netbox_todo.add_accesslist %}
<a href="{% url add_url %}?{{ model_type }}={{ object.pk }}&return_url={{ object.get_absolute_url }}"
class="btn btn-sm btn-primary">
<i class="mdi mdi-plus-thick"></i> Add Access List
</a>
{% endif %}
{% endblock extra_controls %}
{% block content %}
{% include 'inc/table_controls_htmx.html' with table_modal=table_config %}
<form method="post">
{% csrf_token %}
<div class="card">
<div class="card-body" id="object_list">
{% include 'htmx/table.html' %}
</div>
</div>
</form>
{% endblock content %}
{% block modals %}
{{ block.super }}
{% table_config_form table %}
{% endblock modals %}

View File

@ -2,8 +2,8 @@
Map Views to URLs. Map Views to URLs.
""" """
from django.urls import path from django.urls import include, path
from netbox.views.generic import ObjectChangeLogView from utilities.urls import get_model_urls
from . import models, views from . import models, views
@ -33,12 +33,8 @@ urlpatterns = (
name="accesslist_delete", name="accesslist_delete",
), ),
path( path(
"access-lists/<int:pk>/changelog/", "access-lists/<int:pk>/",
ObjectChangeLogView.as_view(), include(get_model_urls("netbox_acls", "accesslist")),
name="accesslist_changelog",
kwargs={
"model": models.AccessList,
},
), ),
# Access List Interface Assignments # Access List Interface Assignments
path( path(
@ -73,12 +69,8 @@ urlpatterns = (
name="aclinterfaceassignment_delete", name="aclinterfaceassignment_delete",
), ),
path( path(
"interface-assignments/<int:pk>/changelog/", "interface-assignments/<int:pk>/",
ObjectChangeLogView.as_view(), include(get_model_urls("netbox_acls", "aclinterfaceassignment")),
name="aclinterfaceassignment_changelog",
kwargs={
"model": models.ACLInterfaceAssignment,
},
), ),
# Standard Access List Rules # Standard Access List Rules
path( path(
@ -112,12 +104,8 @@ urlpatterns = (
name="aclstandardrule_delete", name="aclstandardrule_delete",
), ),
path( path(
"standard-rules/<int:pk>/changelog/", "standard-rules/<int:pk>/",
ObjectChangeLogView.as_view(), include(get_model_urls("netbox_acls", "aclstandardrule")),
name="aclstandardrule_changelog",
kwargs={
"model": models.ACLStandardRule,
},
), ),
# Extended Access List Rules # Extended Access List Rules
path( path(
@ -151,11 +139,7 @@ urlpatterns = (
name="aclextendedrule_delete", name="aclextendedrule_delete",
), ),
path( path(
"extended-rules/<int:pk>/changelog/", "extended-rules/<int:pk>/",
ObjectChangeLogView.as_view(), include(get_model_urls("netbox_acls", "aclextendedrule")),
name="aclextendedrule_changelog",
kwargs={
"model": models.ACLExtendedRule,
},
), ),
) )

View File

@ -1 +1 @@
__version__ = "1.1.1" __version__ = "1.2.0"

View File

@ -3,8 +3,11 @@ Defines the business logic for the plugin.
Specifically, all the various interactions with a client. Specifically, all the various interactions with a client.
""" """
from dcim.models import Device, Interface, VirtualChassis
from django.db.models import Count from django.db.models import Count
from netbox.views import generic from netbox.views import generic
from utilities.views import ViewTab, register_model_view
from virtualization.models import VirtualMachine, VMInterface
from . import choices, filtersets, forms, models, tables from . import choices, filtersets, forms, models, tables
@ -37,12 +40,13 @@ __all__ = (
# #
@register_model_view(models.AccessList)
class AccessListView(generic.ObjectView): class AccessListView(generic.ObjectView):
""" """
Defines the view for the AccessLists django model. Defines the view for the AccessLists django model.
""" """
queryset = models.AccessList.objects.all() queryset = models.AccessList.objects.prefetch_related("tags")
def get_extra_context(self, request, instance): def get_extra_context(self, request, instance):
""" """
@ -73,47 +77,121 @@ class AccessListListView(generic.ObjectListView):
queryset = models.AccessList.objects.annotate( queryset = models.AccessList.objects.annotate(
rule_count=Count("aclextendedrules") + Count("aclstandardrules"), rule_count=Count("aclextendedrules") + Count("aclstandardrules"),
) ).prefetch_related("tags")
table = tables.AccessListTable table = tables.AccessListTable
filterset = filtersets.AccessListFilterSet filterset = filtersets.AccessListFilterSet
filterset_form = forms.AccessListFilterForm filterset_form = forms.AccessListFilterForm
@register_model_view(models.AccessList, "edit")
class AccessListEditView(generic.ObjectEditView): class AccessListEditView(generic.ObjectEditView):
""" """
Defines the edit view for the AccessLists django model. Defines the edit view for the AccessLists django model.
""" """
queryset = models.AccessList.objects.all() queryset = models.AccessList.objects.prefetch_related("tags")
form = forms.AccessListForm form = forms.AccessListForm
template_name = "netbox_acls/accesslist_edit.html" template_name = "netbox_acls/accesslist_edit.html"
@register_model_view(models.AccessList, "delete")
class AccessListDeleteView(generic.ObjectDeleteView): class AccessListDeleteView(generic.ObjectDeleteView):
""" """
Defines delete view for the AccessLists django model. Defines delete view for the AccessLists django model.
""" """
queryset = models.AccessList.objects.all() queryset = models.AccessList.objects.prefetch_related("tags")
class AccessListBulkDeleteView(generic.BulkDeleteView): class AccessListBulkDeleteView(generic.BulkDeleteView):
queryset = models.AccessList.objects.all() queryset = models.AccessList.objects.prefetch_related("tags")
filterset = filtersets.AccessListFilterSet filterset = filtersets.AccessListFilterSet
table = tables.AccessListTable table = tables.AccessListTable
class AccessListChildView(generic.ObjectChildrenView):
"""
Defines the child view for the AccessLists model.
"""
child_model = models.AccessList
table = tables.AccessListTable
filterset = filtersets.AccessListFilterSet
template_name = "inc/view_tab.html"
def get_extra_context(self, request, instance):
return {
"table_config": self.table.__name__,
"model_type": self.queryset.model._meta.verbose_name.replace(" ", "_"),
"add_url": "plugins:netbox_acls:accesslist_add",
}
def prep_table_data(self, request, queryset, parent):
return queryset.annotate(
rule_count=Count("aclextendedrules") + Count("aclstandardrules"),
)
@register_model_view(Device, "access_lists")
class DeviceAccessListView(AccessListChildView):
queryset = Device.objects.prefetch_related("tags")
tab = ViewTab(
label="Access Lists",
badge=lambda obj: models.AccessList.objects.filter(device=obj).count(),
permission="netbox_acls.view_accesslist",
)
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, "view").filter(
device=parent,
)
@register_model_view(VirtualChassis, "access_lists")
class VirtualChassisAccessListView(AccessListChildView):
queryset = VirtualChassis.objects.prefetch_related("tags")
tab = ViewTab(
label="Access Lists",
badge=lambda obj: models.AccessList.objects.filter(virtual_chassis=obj).count(),
permission="netbox_acls.view_accesslist",
)
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, "view").filter(
virtual_chassis=parent,
)
@register_model_view(VirtualMachine, "access_lists")
class VirtualMachineAccessListView(AccessListChildView):
queryset = VirtualMachine.objects.prefetch_related("tags")
tab = ViewTab(
label="Access Lists",
badge=lambda obj: models.AccessList.objects.filter(virtual_machine=obj).count(),
permission="netbox_acls.view_accesslist",
)
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, "view").filter(
virtual_machine=parent,
)
# #
# ACLInterfaceAssignment views # ACLInterfaceAssignment views
# #
@register_model_view(models.ACLInterfaceAssignment)
class ACLInterfaceAssignmentView(generic.ObjectView): class ACLInterfaceAssignmentView(generic.ObjectView):
""" """
Defines the view for the ACLInterfaceAssignments django model. Defines the view for the ACLInterfaceAssignments django model.
""" """
queryset = models.ACLInterfaceAssignment.objects.all() queryset = models.ACLInterfaceAssignment.objects.prefetch_related(
"access_list",
"tags",
)
class ACLInterfaceAssignmentListView(generic.ObjectListView): class ACLInterfaceAssignmentListView(generic.ObjectListView):
@ -121,18 +199,25 @@ class ACLInterfaceAssignmentListView(generic.ObjectListView):
Defines the list view for the ACLInterfaceAssignments django model. Defines the list view for the ACLInterfaceAssignments django model.
""" """
queryset = models.ACLInterfaceAssignment.objects.all() queryset = models.ACLInterfaceAssignment.objects.prefetch_related(
"access_list",
"tags",
)
table = tables.ACLInterfaceAssignmentTable table = tables.ACLInterfaceAssignmentTable
filterset = filtersets.ACLInterfaceAssignmentFilterSet filterset = filtersets.ACLInterfaceAssignmentFilterSet
filterset_form = forms.ACLInterfaceAssignmentFilterForm filterset_form = forms.ACLInterfaceAssignmentFilterForm
@register_model_view(models.ACLInterfaceAssignment, "edit")
class ACLInterfaceAssignmentEditView(generic.ObjectEditView): class ACLInterfaceAssignmentEditView(generic.ObjectEditView):
""" """
Defines the edit view for the ACLInterfaceAssignments django model. Defines the edit view for the ACLInterfaceAssignments django model.
""" """
queryset = models.ACLInterfaceAssignment.objects.all() queryset = models.ACLInterfaceAssignment.objects.prefetch_related(
"access_list",
"tags",
)
form = forms.ACLInterfaceAssignmentForm form = forms.ACLInterfaceAssignmentForm
template_name = "netbox_acls/aclinterfaceassignment_edit.html" template_name = "netbox_acls/aclinterfaceassignment_edit.html"
@ -148,31 +233,97 @@ class ACLInterfaceAssignmentEditView(generic.ObjectEditView):
} }
@register_model_view(models.ACLInterfaceAssignment, "delete")
class ACLInterfaceAssignmentDeleteView(generic.ObjectDeleteView): class ACLInterfaceAssignmentDeleteView(generic.ObjectDeleteView):
""" """
Defines delete view for the ACLInterfaceAssignments django model. Defines delete view for the ACLInterfaceAssignments django model.
""" """
queryset = models.ACLInterfaceAssignment.objects.all() queryset = models.ACLInterfaceAssignment.objects.prefetch_related(
"access_list",
"tags",
)
class ACLInterfaceAssignmentBulkDeleteView(generic.BulkDeleteView): class ACLInterfaceAssignmentBulkDeleteView(generic.BulkDeleteView):
queryset = models.ACLInterfaceAssignment.objects.all() queryset = models.ACLInterfaceAssignment.objects.prefetch_related(
"access_list",
"tags",
)
filterset = filtersets.ACLInterfaceAssignmentFilterSet filterset = filtersets.ACLInterfaceAssignmentFilterSet
table = tables.ACLInterfaceAssignmentTable table = tables.ACLInterfaceAssignmentTable
class ACLInterfaceAssignmentChildView(generic.ObjectChildrenView):
"""
Defines the child view for the ACLInterfaceAssignments model.
"""
child_model = models.ACLInterfaceAssignment
table = tables.ACLInterfaceAssignmentTable
filterset = filtersets.ACLInterfaceAssignmentFilterSet
template_name = "inc/view_tab.html"
def get_extra_context(self, request, instance):
return {
"table_config": self.table.__name__,
"model_type": self.queryset.model._meta.verbose_name.replace(" ", "_"),
"add_url": "plugins:netbox_acls:aclinterfaceassignment_add",
}
@register_model_view(Interface, "acl_interface_assignments")
class InterfaceACLInterfaceAssignmentView(ACLInterfaceAssignmentChildView):
queryset = Interface.objects.prefetch_related("device", "tags")
tab = ViewTab(
label="ACL Interface Assignments",
badge=lambda obj: models.ACLInterfaceAssignment.objects.filter(
interface=obj,
).count(),
permission="netbox_acls.view_aclinterfaceassignment",
)
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, "view").filter(
interface=parent,
)
@register_model_view(VMInterface, "acl_interface_assignments")
class VirtualMachineInterfaceACLInterfaceAssignmentView(
ACLInterfaceAssignmentChildView,
):
queryset = VMInterface.objects.prefetch_related("virtual_machine", "tags")
tab = ViewTab(
label="ACL Interface Assignments",
badge=lambda obj: models.ACLInterfaceAssignment.objects.filter(
vminterface=obj,
).count(),
permission="netbox_acls.view_aclinterfaceassignment",
)
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, "view").filter(
vminterface=parent,
)
# #
# ACLStandardRule views # ACLStandardRule views
# #
@register_model_view(models.ACLStandardRule)
class ACLStandardRuleView(generic.ObjectView): class ACLStandardRuleView(generic.ObjectView):
""" """
Defines the view for the ACLStandardRule django model. Defines the view for the ACLStandardRule django model.
""" """
queryset = models.ACLStandardRule.objects.all() queryset = models.ACLStandardRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
)
class ACLStandardRuleListView(generic.ObjectListView): class ACLStandardRuleListView(generic.ObjectListView):
@ -180,18 +331,27 @@ class ACLStandardRuleListView(generic.ObjectListView):
Defines the list view for the ACLStandardRule django model. Defines the list view for the ACLStandardRule django model.
""" """
queryset = models.ACLStandardRule.objects.all() queryset = models.ACLStandardRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
)
table = tables.ACLStandardRuleTable table = tables.ACLStandardRuleTable
filterset = filtersets.ACLStandardRuleFilterSet filterset = filtersets.ACLStandardRuleFilterSet
filterset_form = forms.ACLStandardRuleFilterForm filterset_form = forms.ACLStandardRuleFilterForm
@register_model_view(models.ACLStandardRule, "edit")
class ACLStandardRuleEditView(generic.ObjectEditView): class ACLStandardRuleEditView(generic.ObjectEditView):
""" """
Defines the edit view for the ACLStandardRule django model. Defines the edit view for the ACLStandardRule django model.
""" """
queryset = models.ACLStandardRule.objects.all() queryset = models.ACLStandardRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
)
form = forms.ACLStandardRuleForm form = forms.ACLStandardRuleForm
def get_extra_addanother_params(self, request): def get_extra_addanother_params(self, request):
@ -205,16 +365,25 @@ class ACLStandardRuleEditView(generic.ObjectEditView):
} }
@register_model_view(models.ACLStandardRule, "delete")
class ACLStandardRuleDeleteView(generic.ObjectDeleteView): class ACLStandardRuleDeleteView(generic.ObjectDeleteView):
""" """
Defines delete view for the ACLStandardRules django model. Defines delete view for the ACLStandardRules django model.
""" """
queryset = models.ACLStandardRule.objects.all() queryset = models.ACLStandardRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
)
class ACLStandardRuleBulkDeleteView(generic.BulkDeleteView): class ACLStandardRuleBulkDeleteView(generic.BulkDeleteView):
queryset = models.ACLStandardRule.objects.all() queryset = models.ACLStandardRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
)
filterset = filtersets.ACLStandardRuleFilterSet filterset = filtersets.ACLStandardRuleFilterSet
table = tables.ACLStandardRuleTable table = tables.ACLStandardRuleTable
@ -224,12 +393,18 @@ class ACLStandardRuleBulkDeleteView(generic.BulkDeleteView):
# #
@register_model_view(models.ACLExtendedRule)
class ACLExtendedRuleView(generic.ObjectView): class ACLExtendedRuleView(generic.ObjectView):
""" """
Defines the view for the ACLExtendedRule django model. Defines the view for the ACLExtendedRule django model.
""" """
queryset = models.ACLExtendedRule.objects.all() queryset = models.ACLExtendedRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
"destination_prefix",
)
class ACLExtendedRuleListView(generic.ObjectListView): class ACLExtendedRuleListView(generic.ObjectListView):
@ -237,18 +412,29 @@ class ACLExtendedRuleListView(generic.ObjectListView):
Defines the list view for the ACLExtendedRule django model. Defines the list view for the ACLExtendedRule django model.
""" """
queryset = models.ACLExtendedRule.objects.all() queryset = models.ACLExtendedRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
"destination_prefix",
)
table = tables.ACLExtendedRuleTable table = tables.ACLExtendedRuleTable
filterset = filtersets.ACLExtendedRuleFilterSet filterset = filtersets.ACLExtendedRuleFilterSet
filterset_form = forms.ACLExtendedRuleFilterForm filterset_form = forms.ACLExtendedRuleFilterForm
@register_model_view(models.ACLExtendedRule, "edit")
class ACLExtendedRuleEditView(generic.ObjectEditView): class ACLExtendedRuleEditView(generic.ObjectEditView):
""" """
Defines the edit view for the ACLExtendedRule django model. Defines the edit view for the ACLExtendedRule django model.
""" """
queryset = models.ACLExtendedRule.objects.all() queryset = models.ACLExtendedRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
"destination_prefix",
)
form = forms.ACLExtendedRuleForm form = forms.ACLExtendedRuleForm
def get_extra_addanother_params(self, request): def get_extra_addanother_params(self, request):
@ -262,15 +448,26 @@ class ACLExtendedRuleEditView(generic.ObjectEditView):
} }
@register_model_view(models.ACLExtendedRule, "delete")
class ACLExtendedRuleDeleteView(generic.ObjectDeleteView): class ACLExtendedRuleDeleteView(generic.ObjectDeleteView):
""" """
Defines delete view for the ACLExtendedRules django model. Defines delete view for the ACLExtendedRules django model.
""" """
queryset = models.ACLExtendedRule.objects.all() queryset = models.ACLExtendedRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
"destination_prefix",
)
class ACLExtendedRuleBulkDeleteView(generic.BulkDeleteView): class ACLExtendedRuleBulkDeleteView(generic.BulkDeleteView):
queryset = models.ACLExtendedRule.objects.all() queryset = models.ACLExtendedRule.objects.prefetch_related(
"access_list",
"tags",
"source_prefix",
"destination_prefix",
)
filterset = filtersets.ACLExtendedRuleFilterSet filterset = filtersets.ACLExtendedRuleFilterSet
table = tables.ACLExtendedRuleTable table = tables.ACLExtendedRuleTable