mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 09:51:22 -06:00
Merge branch 'develop' into feature
This commit is contained in:
commit
bd79a27e4d
14
.github/ISSUE_TEMPLATE/documentation_change.yaml
vendored
14
.github/ISSUE_TEMPLATE/documentation_change.yaml
vendored
@ -19,11 +19,15 @@ body:
|
|||||||
label: Area
|
label: Area
|
||||||
description: To what section of the documentation does this change primarily pertain?
|
description: To what section of the documentation does this change primarily pertain?
|
||||||
options:
|
options:
|
||||||
- Installation instructions
|
- Features
|
||||||
- Configuration parameters
|
- Installation/upgrade
|
||||||
- Functionality/features
|
- Getting started
|
||||||
- REST API
|
- Configuration
|
||||||
- Administration/development
|
- Customization
|
||||||
|
- Integrations/API
|
||||||
|
- Plugins
|
||||||
|
- Administration
|
||||||
|
- Development
|
||||||
- Other
|
- Other
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
@ -46,7 +46,7 @@ Next, create a file in the same directory as `configuration.py` (typically `/opt
|
|||||||
### General Server Configuration
|
### General Server Configuration
|
||||||
|
|
||||||
!!! info
|
!!! info
|
||||||
When using Windows Server 2012 you may need to specify a port on `AUTH_LDAP_SERVER_URI`. Use `3269` for secure, or `3268` for non-secure.
|
When using Active Directory you may need to specify a port on `AUTH_LDAP_SERVER_URI` to authenticate users from all domains in the forest. Use `3269` for secure, or `3268` for non-secure access to the GC (Global Catalog).
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import ldap
|
import ldap
|
||||||
@ -67,6 +67,16 @@ AUTH_LDAP_BIND_PASSWORD = "demo"
|
|||||||
# Note that this is a NetBox-specific setting which sets:
|
# Note that this is a NetBox-specific setting which sets:
|
||||||
# ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
|
# ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
|
||||||
LDAP_IGNORE_CERT_ERRORS = True
|
LDAP_IGNORE_CERT_ERRORS = True
|
||||||
|
|
||||||
|
# Include this setting if you want to validate the LDAP server certificates against a CA certificate directory on your server
|
||||||
|
# Note that this is a NetBox-specific setting which sets:
|
||||||
|
# ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, LDAP_CA_CERT_DIR)
|
||||||
|
LDAP_CA_CERT_DIR = '/etc/ssl/certs'
|
||||||
|
|
||||||
|
# Include this setting if you want to validate the LDAP server certificates against your own CA.
|
||||||
|
# Note that this is a NetBox-specific setting which sets:
|
||||||
|
# ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, LDAP_CA_CERT_FILE)
|
||||||
|
LDAP_CA_CERT_FILE = '/path/to/example-CA.crt'
|
||||||
```
|
```
|
||||||
|
|
||||||
STARTTLS can be configured by setting `AUTH_LDAP_START_TLS = True` and using the `ldap://` URI scheme.
|
STARTTLS can be configured by setting `AUTH_LDAP_START_TLS = True` and using the `ldap://` URI scheme.
|
||||||
|
@ -144,73 +144,73 @@ class MyModelFilterForm(NetBoxModelFilterSetForm):
|
|||||||
In addition to the [form fields provided by Django](https://docs.djangoproject.com/en/stable/ref/forms/fields/), NetBox provides several field classes for use within forms to handle specific types of data. These can be imported from `utilities.forms.fields` and are documented below.
|
In addition to the [form fields provided by Django](https://docs.djangoproject.com/en/stable/ref/forms/fields/), NetBox provides several field classes for use within forms to handle specific types of data. These can be imported from `utilities.forms.fields` and are documented below.
|
||||||
|
|
||||||
::: utilities.forms.ColorField
|
::: utilities.forms.ColorField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: utilities.forms.CommentField
|
::: utilities.forms.CommentField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: utilities.forms.JSONField
|
::: utilities.forms.JSONField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: utilities.forms.MACAddressField
|
::: utilities.forms.MACAddressField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: utilities.forms.SlugField
|
::: utilities.forms.SlugField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
## Choice Fields
|
## Choice Fields
|
||||||
|
|
||||||
::: utilities.forms.ChoiceField
|
::: utilities.forms.ChoiceField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: utilities.forms.MultipleChoiceField
|
::: utilities.forms.MultipleChoiceField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
## Dynamic Object Fields
|
## Dynamic Object Fields
|
||||||
|
|
||||||
::: utilities.forms.DynamicModelChoiceField
|
::: utilities.forms.DynamicModelChoiceField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: utilities.forms.DynamicModelMultipleChoiceField
|
::: utilities.forms.DynamicModelMultipleChoiceField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
## Content Type Fields
|
## Content Type Fields
|
||||||
|
|
||||||
::: utilities.forms.ContentTypeChoiceField
|
::: utilities.forms.ContentTypeChoiceField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: utilities.forms.ContentTypeMultipleChoiceField
|
::: utilities.forms.ContentTypeMultipleChoiceField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
## CSV Import Fields
|
## CSV Import Fields
|
||||||
|
|
||||||
::: utilities.forms.CSVChoiceField
|
::: utilities.forms.CSVChoiceField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: utilities.forms.CSVMultipleChoiceField
|
::: utilities.forms.CSVMultipleChoiceField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: utilities.forms.CSVModelChoiceField
|
::: utilities.forms.CSVModelChoiceField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: utilities.forms.CSVContentTypeField
|
::: utilities.forms.CSVContentTypeField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: utilities.forms.CSVMultipleContentTypeField
|
::: utilities.forms.CSVMultipleContentTypeField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
@ -32,11 +32,11 @@ schema = MyQuery
|
|||||||
NetBox provides two object type classes for use by plugins.
|
NetBox provides two object type classes for use by plugins.
|
||||||
|
|
||||||
::: netbox.graphql.types.BaseObjectType
|
::: netbox.graphql.types.BaseObjectType
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: netbox.graphql.types.NetBoxObjectType
|
::: netbox.graphql.types.NetBoxObjectType
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
## GraphQL Fields
|
## GraphQL Fields
|
||||||
@ -44,9 +44,9 @@ NetBox provides two object type classes for use by plugins.
|
|||||||
NetBox provides two field classes for use by plugins.
|
NetBox provides two field classes for use by plugins.
|
||||||
|
|
||||||
::: netbox.graphql.fields.ObjectField
|
::: netbox.graphql.fields.ObjectField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: netbox.graphql.fields.ObjectListField
|
::: netbox.graphql.fields.ObjectListField
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
@ -52,38 +52,38 @@ This will automatically apply any user-specific preferences for the table. (If u
|
|||||||
The table column classes listed below are supported for use in plugins. These classes can be imported from `netbox.tables.columns`.
|
The table column classes listed below are supported for use in plugins. These classes can be imported from `netbox.tables.columns`.
|
||||||
|
|
||||||
::: netbox.tables.BooleanColumn
|
::: netbox.tables.BooleanColumn
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: netbox.tables.ChoiceFieldColumn
|
::: netbox.tables.ChoiceFieldColumn
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: netbox.tables.ColorColumn
|
::: netbox.tables.ColorColumn
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: netbox.tables.ColoredLabelColumn
|
::: netbox.tables.ColoredLabelColumn
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: netbox.tables.ContentTypeColumn
|
::: netbox.tables.ContentTypeColumn
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: netbox.tables.ContentTypesColumn
|
::: netbox.tables.ContentTypesColumn
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: netbox.tables.MarkdownColumn
|
::: netbox.tables.MarkdownColumn
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: netbox.tables.TagColumn
|
::: netbox.tables.TagColumn
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: netbox.tables.TemplateColumn
|
::: netbox.tables.TemplateColumn
|
||||||
selection:
|
options:
|
||||||
members:
|
members:
|
||||||
- __init__
|
- __init__
|
||||||
|
@ -84,24 +84,24 @@ Below are the class definitions for NetBox's object views. These views handle CR
|
|||||||
::: netbox.views.generic.base.BaseObjectView
|
::: netbox.views.generic.base.BaseObjectView
|
||||||
|
|
||||||
::: netbox.views.generic.ObjectView
|
::: netbox.views.generic.ObjectView
|
||||||
selection:
|
options:
|
||||||
members:
|
members:
|
||||||
- get_object
|
- get_object
|
||||||
- get_template_name
|
- get_template_name
|
||||||
|
|
||||||
::: netbox.views.generic.ObjectEditView
|
::: netbox.views.generic.ObjectEditView
|
||||||
selection:
|
options:
|
||||||
members:
|
members:
|
||||||
- get_object
|
- get_object
|
||||||
- alter_object
|
- alter_object
|
||||||
|
|
||||||
::: netbox.views.generic.ObjectDeleteView
|
::: netbox.views.generic.ObjectDeleteView
|
||||||
selection:
|
options:
|
||||||
members:
|
members:
|
||||||
- get_object
|
- get_object
|
||||||
|
|
||||||
::: netbox.views.generic.ObjectChildrenView
|
::: netbox.views.generic.ObjectChildrenView
|
||||||
selection:
|
options:
|
||||||
members:
|
members:
|
||||||
- get_children
|
- get_children
|
||||||
- prep_table_data
|
- prep_table_data
|
||||||
@ -113,22 +113,22 @@ Below are the class definitions for NetBox's multi-object views. These views han
|
|||||||
::: netbox.views.generic.base.BaseMultiObjectView
|
::: netbox.views.generic.base.BaseMultiObjectView
|
||||||
|
|
||||||
::: netbox.views.generic.ObjectListView
|
::: netbox.views.generic.ObjectListView
|
||||||
selection:
|
options:
|
||||||
members:
|
members:
|
||||||
- get_table
|
- get_table
|
||||||
- export_table
|
- export_table
|
||||||
- export_template
|
- export_template
|
||||||
|
|
||||||
::: netbox.views.generic.BulkImportView
|
::: netbox.views.generic.BulkImportView
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: netbox.views.generic.BulkEditView
|
::: netbox.views.generic.BulkEditView
|
||||||
selection:
|
options:
|
||||||
members: false
|
members: false
|
||||||
|
|
||||||
::: netbox.views.generic.BulkDeleteView
|
::: netbox.views.generic.BulkDeleteView
|
||||||
selection:
|
options:
|
||||||
members:
|
members:
|
||||||
- get_form
|
- get_form
|
||||||
|
|
||||||
@ -137,12 +137,12 @@ Below are the class definitions for NetBox's multi-object views. These views han
|
|||||||
These views are provided to enable or enhance certain NetBox model features, such as change logging or journaling. These typically do not need to be subclassed: They can be used directly e.g. in a URL path.
|
These views are provided to enable or enhance certain NetBox model features, such as change logging or journaling. These typically do not need to be subclassed: They can be used directly e.g. in a URL path.
|
||||||
|
|
||||||
::: netbox.views.generic.ObjectChangeLogView
|
::: netbox.views.generic.ObjectChangeLogView
|
||||||
selection:
|
options:
|
||||||
members:
|
members:
|
||||||
- get_form
|
- get_form
|
||||||
|
|
||||||
::: netbox.views.generic.ObjectJournalView
|
::: netbox.views.generic.ObjectJournalView
|
||||||
selection:
|
options:
|
||||||
members:
|
members:
|
||||||
- get_form
|
- get_form
|
||||||
|
|
||||||
|
@ -2,6 +2,21 @@
|
|||||||
|
|
||||||
## v3.3.6 (FUTURE)
|
## v3.3.6 (FUTURE)
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
* [#9722](https://github.com/netbox-community/netbox/issues/9722) - Add LDAP configuration parameters to specify certificates
|
||||||
|
* [#10685](https://github.com/netbox-community/netbox/issues/10685) - Position A/Z termination cards above the fold under circuit view
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* [#9669](https://github.com/netbox-community/netbox/issues/9669) - Strip colons from usernames when using remote authentication
|
||||||
|
* [#10575](https://github.com/netbox-community/netbox/issues/10575) - Include OIDC dependencies for python-social-auth
|
||||||
|
* [#10584](https://github.com/netbox-community/netbox/issues/10584) - Fix service clone link
|
||||||
|
* [#10643](https://github.com/netbox-community/netbox/issues/10643) - Ensure consistent display of custom fields for all model forms
|
||||||
|
* [#10646](https://github.com/netbox-community/netbox/issues/10646) - Fix filtering of power feed by power panel when connecting a cable
|
||||||
|
* [#10655](https://github.com/netbox-community/netbox/issues/10655) - Correct display of assigned contacts in object tables
|
||||||
|
* [#10712](https://github.com/netbox-community/netbox/issues/10712) - Fix ModuleNotFoundError exception when generating API schema under Python 3.9+
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## v3.3.5 (2022-10-05)
|
## v3.3.5 (2022-10-05)
|
||||||
|
@ -30,7 +30,7 @@ plugins:
|
|||||||
- os.chdir('netbox/')
|
- os.chdir('netbox/')
|
||||||
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "netbox.settings")
|
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "netbox.settings")
|
||||||
- django.setup()
|
- django.setup()
|
||||||
rendering:
|
options:
|
||||||
heading_level: 3
|
heading_level: 3
|
||||||
members_order: source
|
members_order: source
|
||||||
show_root_heading: true
|
show_root_heading: true
|
||||||
|
@ -64,6 +64,12 @@ class ProviderNetworkForm(NetBoxModelForm):
|
|||||||
class CircuitTypeForm(NetBoxModelForm):
|
class CircuitTypeForm(NetBoxModelForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Circuit Type', (
|
||||||
|
'name', 'slug', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CircuitType
|
model = CircuitType
|
||||||
fields = [
|
fields = [
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
|
|
||||||
from circuits.models import *
|
from circuits.models import *
|
||||||
|
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
|
||||||
|
|
||||||
from netbox.tables import NetBoxTable, columns
|
from netbox.tables import NetBoxTable, columns
|
||||||
from tenancy.tables import TenancyColumnsMixin
|
|
||||||
from .columns import CommitRateColumn
|
from .columns import CommitRateColumn
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -39,7 +40,7 @@ class CircuitTypeTable(NetBoxTable):
|
|||||||
default_columns = ('pk', 'name', 'circuit_count', 'description', 'slug')
|
default_columns = ('pk', 'name', 'circuit_count', 'description', 'slug')
|
||||||
|
|
||||||
|
|
||||||
class CircuitTable(TenancyColumnsMixin, NetBoxTable):
|
class CircuitTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||||
cid = tables.Column(
|
cid = tables.Column(
|
||||||
linkify=True,
|
linkify=True,
|
||||||
verbose_name='Circuit ID'
|
verbose_name='Circuit ID'
|
||||||
@ -58,9 +59,6 @@ class CircuitTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
)
|
)
|
||||||
commit_rate = CommitRateColumn()
|
commit_rate = CommitRateColumn()
|
||||||
comments = columns.MarkdownColumn()
|
comments = columns.MarkdownColumn()
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='circuits:circuit_list'
|
url_name='circuits:circuit_list'
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
from django_tables2.utils import Accessor
|
|
||||||
|
|
||||||
from circuits.models import *
|
from circuits.models import *
|
||||||
|
from django_tables2.utils import Accessor
|
||||||
|
from tenancy.tables import ContactsColumnMixin
|
||||||
|
|
||||||
from netbox.tables import NetBoxTable, columns
|
from netbox.tables import NetBoxTable, columns
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -10,7 +11,7 @@ __all__ = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ProviderTable(NetBoxTable):
|
class ProviderTable(ContactsColumnMixin, NetBoxTable):
|
||||||
name = tables.Column(
|
name = tables.Column(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
@ -31,9 +32,6 @@ class ProviderTable(NetBoxTable):
|
|||||||
verbose_name='Circuits'
|
verbose_name='Circuits'
|
||||||
)
|
)
|
||||||
comments = columns.MarkdownColumn()
|
comments = columns.MarkdownColumn()
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='circuits:provider_list'
|
url_name='circuits:provider_list'
|
||||||
)
|
)
|
||||||
|
@ -108,7 +108,7 @@ def get_cable_form(a_type, b_type):
|
|||||||
label='Power Feed',
|
label='Power Feed',
|
||||||
disabled_indicator='_occupied',
|
disabled_indicator='_occupied',
|
||||||
query_params={
|
query_params={
|
||||||
'powerpanel_id': f'$termination_{cable_end}_powerpanel',
|
'power_panel_id': f'$termination_{cable_end}_powerpanel',
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -78,6 +78,12 @@ class RegionForm(NetBoxModelForm):
|
|||||||
)
|
)
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Region', (
|
||||||
|
'parent', 'name', 'slug', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Region
|
model = Region
|
||||||
fields = (
|
fields = (
|
||||||
@ -92,6 +98,12 @@ class SiteGroupForm(NetBoxModelForm):
|
|||||||
)
|
)
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Site Group', (
|
||||||
|
'parent', 'name', 'slug', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SiteGroup
|
model = SiteGroup
|
||||||
fields = (
|
fields = (
|
||||||
@ -213,6 +225,12 @@ class LocationForm(TenancyForm, NetBoxModelForm):
|
|||||||
class RackRoleForm(NetBoxModelForm):
|
class RackRoleForm(NetBoxModelForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Rack Role', (
|
||||||
|
'name', 'slug', 'color', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = RackRole
|
model = RackRole
|
||||||
fields = [
|
fields = [
|
||||||
@ -341,6 +359,12 @@ class RackReservationForm(TenancyForm, NetBoxModelForm):
|
|||||||
class ManufacturerForm(NetBoxModelForm):
|
class ManufacturerForm(NetBoxModelForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Manufacturer', (
|
||||||
|
'name', 'slug', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Manufacturer
|
model = Manufacturer
|
||||||
fields = [
|
fields = [
|
||||||
@ -413,6 +437,12 @@ class ModuleTypeForm(NetBoxModelForm):
|
|||||||
class DeviceRoleForm(NetBoxModelForm):
|
class DeviceRoleForm(NetBoxModelForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Device Role', (
|
||||||
|
'name', 'slug', 'color', 'vm_role', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = DeviceRole
|
model = DeviceRole
|
||||||
fields = [
|
fields = [
|
||||||
@ -429,6 +459,13 @@ class PlatformForm(NetBoxModelForm):
|
|||||||
max_length=64
|
max_length=64
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Platform', (
|
||||||
|
'name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_args', 'description', 'tags',
|
||||||
|
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Platform
|
model = Platform
|
||||||
fields = [
|
fields = [
|
||||||
@ -1584,6 +1621,12 @@ class InventoryItemForm(DeviceComponentForm):
|
|||||||
class InventoryItemRoleForm(NetBoxModelForm):
|
class InventoryItemRoleForm(NetBoxModelForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Inventory Item Role', (
|
||||||
|
'name', 'slug', 'color', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InventoryItemRole
|
model = InventoryItemRole
|
||||||
fields = [
|
fields = [
|
||||||
|
@ -1,12 +1,26 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
from django_tables2.utils import Accessor
|
|
||||||
|
|
||||||
from dcim.models import (
|
from dcim.models import (
|
||||||
ConsolePort, ConsoleServerPort, Device, DeviceBay, DeviceRole, FrontPort, Interface, InventoryItem,
|
ConsolePort,
|
||||||
InventoryItemRole, ModuleBay, Platform, PowerOutlet, PowerPort, RearPort, VirtualChassis,
|
ConsoleServerPort,
|
||||||
|
Device,
|
||||||
|
DeviceBay,
|
||||||
|
DeviceRole,
|
||||||
|
FrontPort,
|
||||||
|
Interface,
|
||||||
|
InventoryItem,
|
||||||
|
InventoryItemRole,
|
||||||
|
ModuleBay,
|
||||||
|
Platform,
|
||||||
|
PowerOutlet,
|
||||||
|
PowerPort,
|
||||||
|
RearPort,
|
||||||
|
VirtualChassis,
|
||||||
)
|
)
|
||||||
|
from django_tables2.utils import Accessor
|
||||||
|
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
|
||||||
|
|
||||||
from netbox.tables import NetBoxTable, columns
|
from netbox.tables import NetBoxTable, columns
|
||||||
from tenancy.tables import TenancyColumnsMixin
|
|
||||||
from .template_code import *
|
from .template_code import *
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -137,7 +151,7 @@ class PlatformTable(NetBoxTable):
|
|||||||
# Devices
|
# Devices
|
||||||
#
|
#
|
||||||
|
|
||||||
class DeviceTable(TenancyColumnsMixin, NetBoxTable):
|
class DeviceTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||||
name = tables.TemplateColumn(
|
name = tables.TemplateColumn(
|
||||||
order_by=('_name',),
|
order_by=('_name',),
|
||||||
template_code=DEVICE_LINK
|
template_code=DEVICE_LINK
|
||||||
@ -201,9 +215,6 @@ class DeviceTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
verbose_name='VC Priority'
|
verbose_name='VC Priority'
|
||||||
)
|
)
|
||||||
comments = columns.MarkdownColumn()
|
comments = columns.MarkdownColumn()
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='dcim:device_list'
|
url_name='dcim:device_list'
|
||||||
)
|
)
|
||||||
|
@ -1,10 +1,21 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
|
|
||||||
from dcim.models import (
|
from dcim.models import (
|
||||||
ConsolePortTemplate, ConsoleServerPortTemplate, DeviceBayTemplate, DeviceType, FrontPortTemplate, InterfaceTemplate,
|
ConsolePortTemplate,
|
||||||
InventoryItemTemplate, Manufacturer, ModuleBayTemplate, PowerOutletTemplate, PowerPortTemplate, RearPortTemplate,
|
ConsoleServerPortTemplate,
|
||||||
|
DeviceBayTemplate,
|
||||||
|
DeviceType,
|
||||||
|
FrontPortTemplate,
|
||||||
|
InterfaceTemplate,
|
||||||
|
InventoryItemTemplate,
|
||||||
|
Manufacturer,
|
||||||
|
ModuleBayTemplate,
|
||||||
|
PowerOutletTemplate,
|
||||||
|
PowerPortTemplate,
|
||||||
|
RearPortTemplate,
|
||||||
)
|
)
|
||||||
from netbox.tables import NetBoxTable, columns
|
from netbox.tables import NetBoxTable, columns
|
||||||
|
from tenancy.tables import ContactsColumnMixin
|
||||||
from .template_code import MODULAR_COMPONENT_TEMPLATE_BUTTONS, DEVICE_WEIGHT
|
from .template_code import MODULAR_COMPONENT_TEMPLATE_BUTTONS, DEVICE_WEIGHT
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -27,7 +38,7 @@ __all__ = (
|
|||||||
# Manufacturers
|
# Manufacturers
|
||||||
#
|
#
|
||||||
|
|
||||||
class ManufacturerTable(NetBoxTable):
|
class ManufacturerTable(ContactsColumnMixin, NetBoxTable):
|
||||||
name = tables.Column(
|
name = tables.Column(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
@ -43,9 +54,6 @@ class ManufacturerTable(NetBoxTable):
|
|||||||
verbose_name='Platforms'
|
verbose_name='Platforms'
|
||||||
)
|
)
|
||||||
slug = tables.Column()
|
slug = tables.Column()
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='dcim:manufacturer_list'
|
url_name='dcim:manufacturer_list'
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
|
|
||||||
from dcim.models import PowerFeed, PowerPanel
|
from dcim.models import PowerFeed, PowerPanel
|
||||||
|
from tenancy.tables import ContactsColumnMixin
|
||||||
|
|
||||||
from netbox.tables import NetBoxTable, columns
|
from netbox.tables import NetBoxTable, columns
|
||||||
|
|
||||||
from .devices import CableTerminationTable
|
from .devices import CableTerminationTable
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -14,7 +16,7 @@ __all__ = (
|
|||||||
# Power panels
|
# Power panels
|
||||||
#
|
#
|
||||||
|
|
||||||
class PowerPanelTable(NetBoxTable):
|
class PowerPanelTable(ContactsColumnMixin, NetBoxTable):
|
||||||
name = tables.Column(
|
name = tables.Column(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
@ -29,9 +31,6 @@ class PowerPanelTable(NetBoxTable):
|
|||||||
url_params={'power_panel_id': 'pk'},
|
url_params={'power_panel_id': 'pk'},
|
||||||
verbose_name='Feeds'
|
verbose_name='Feeds'
|
||||||
)
|
)
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='dcim:powerpanel_list'
|
url_name='dcim:powerpanel_list'
|
||||||
)
|
)
|
||||||
|
@ -3,7 +3,7 @@ from django_tables2.utils import Accessor
|
|||||||
|
|
||||||
from dcim.models import Rack, RackReservation, RackRole
|
from dcim.models import Rack, RackReservation, RackRole
|
||||||
from netbox.tables import NetBoxTable, columns
|
from netbox.tables import NetBoxTable, columns
|
||||||
from tenancy.tables import TenancyColumnsMixin
|
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
|
||||||
from .template_code import DEVICE_WEIGHT
|
from .template_code import DEVICE_WEIGHT
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -38,7 +38,7 @@ class RackRoleTable(NetBoxTable):
|
|||||||
# Racks
|
# Racks
|
||||||
#
|
#
|
||||||
|
|
||||||
class RackTable(TenancyColumnsMixin, NetBoxTable):
|
class RackTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||||
name = tables.Column(
|
name = tables.Column(
|
||||||
order_by=('_name',),
|
order_by=('_name',),
|
||||||
linkify=True
|
linkify=True
|
||||||
@ -69,9 +69,6 @@ class RackTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
orderable=False,
|
orderable=False,
|
||||||
verbose_name='Power'
|
verbose_name='Power'
|
||||||
)
|
)
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='dcim:rack_list'
|
url_name='dcim:rack_list'
|
||||||
)
|
)
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
|
|
||||||
from dcim.models import Location, Region, Site, SiteGroup
|
from dcim.models import Location, Region, Site, SiteGroup
|
||||||
|
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
|
||||||
|
|
||||||
from netbox.tables import NetBoxTable, columns
|
from netbox.tables import NetBoxTable, columns
|
||||||
from tenancy.tables import TenancyColumnsMixin
|
|
||||||
from .template_code import LOCATION_BUTTONS
|
from .template_code import LOCATION_BUTTONS
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -17,7 +18,7 @@ __all__ = (
|
|||||||
# Regions
|
# Regions
|
||||||
#
|
#
|
||||||
|
|
||||||
class RegionTable(NetBoxTable):
|
class RegionTable(ContactsColumnMixin, NetBoxTable):
|
||||||
name = columns.MPTTColumn(
|
name = columns.MPTTColumn(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
@ -26,9 +27,6 @@ class RegionTable(NetBoxTable):
|
|||||||
url_params={'region_id': 'pk'},
|
url_params={'region_id': 'pk'},
|
||||||
verbose_name='Sites'
|
verbose_name='Sites'
|
||||||
)
|
)
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='dcim:region_list'
|
url_name='dcim:region_list'
|
||||||
)
|
)
|
||||||
@ -46,7 +44,7 @@ class RegionTable(NetBoxTable):
|
|||||||
# Site groups
|
# Site groups
|
||||||
#
|
#
|
||||||
|
|
||||||
class SiteGroupTable(NetBoxTable):
|
class SiteGroupTable(ContactsColumnMixin, NetBoxTable):
|
||||||
name = columns.MPTTColumn(
|
name = columns.MPTTColumn(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
@ -55,9 +53,6 @@ class SiteGroupTable(NetBoxTable):
|
|||||||
url_params={'group_id': 'pk'},
|
url_params={'group_id': 'pk'},
|
||||||
verbose_name='Sites'
|
verbose_name='Sites'
|
||||||
)
|
)
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='dcim:sitegroup_list'
|
url_name='dcim:sitegroup_list'
|
||||||
)
|
)
|
||||||
@ -75,7 +70,7 @@ class SiteGroupTable(NetBoxTable):
|
|||||||
# Sites
|
# Sites
|
||||||
#
|
#
|
||||||
|
|
||||||
class SiteTable(TenancyColumnsMixin, NetBoxTable):
|
class SiteTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||||
name = tables.Column(
|
name = tables.Column(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
@ -97,9 +92,6 @@ class SiteTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
verbose_name='ASN Count'
|
verbose_name='ASN Count'
|
||||||
)
|
)
|
||||||
comments = columns.MarkdownColumn()
|
comments = columns.MarkdownColumn()
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='dcim:site_list'
|
url_name='dcim:site_list'
|
||||||
)
|
)
|
||||||
@ -118,7 +110,7 @@ class SiteTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
# Locations
|
# Locations
|
||||||
#
|
#
|
||||||
|
|
||||||
class LocationTable(TenancyColumnsMixin, NetBoxTable):
|
class LocationTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||||
name = columns.MPTTColumn(
|
name = columns.MPTTColumn(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
@ -136,9 +128,6 @@ class LocationTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
url_params={'location_id': 'pk'},
|
url_params={'location_id': 'pk'},
|
||||||
verbose_name='Devices'
|
verbose_name='Devices'
|
||||||
)
|
)
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='dcim:location_list'
|
url_name='dcim:location_list'
|
||||||
)
|
)
|
||||||
|
@ -88,6 +88,12 @@ class RouteTargetForm(TenancyForm, NetBoxModelForm):
|
|||||||
class RIRForm(NetBoxModelForm):
|
class RIRForm(NetBoxModelForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('RIR', (
|
||||||
|
'name', 'slug', 'is_private', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = RIR
|
model = RIR
|
||||||
fields = [
|
fields = [
|
||||||
@ -164,6 +170,12 @@ class ASNForm(TenancyForm, NetBoxModelForm):
|
|||||||
class RoleForm(NetBoxModelForm):
|
class RoleForm(NetBoxModelForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Role', (
|
||||||
|
'name', 'slug', 'weight', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Role
|
model = Role
|
||||||
fields = [
|
fields = [
|
||||||
@ -784,6 +796,12 @@ class ServiceTemplateForm(NetBoxModelForm):
|
|||||||
help_text="Comma-separated list of one or more port numbers. A range may be specified using a hyphen."
|
help_text="Comma-separated list of one or more port numbers. A range may be specified using a hyphen."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Service Template', (
|
||||||
|
'name', 'protocol', 'ports', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ServiceTemplate
|
model = ServiceTemplate
|
||||||
fields = ('name', 'protocol', 'ports', 'description', 'tags')
|
fields = ('name', 'protocol', 'ports', 'description', 'tags')
|
||||||
|
@ -92,6 +92,8 @@ class Service(ServiceBase, NetBoxModel):
|
|||||||
verbose_name='IP addresses'
|
verbose_name='IP addresses'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
clone_fields = ['protocol', 'ports', 'description', 'device', 'virtual_machine', 'ipaddresses', ]
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('protocol', 'ports', 'pk') # (protocol, port) may be non-unique
|
ordering = ('protocol', 'ports', 'pk') # (protocol, port) may be non-unique
|
||||||
|
|
||||||
|
@ -351,6 +351,14 @@ class LDAPBackend:
|
|||||||
if getattr(ldap_config, 'LDAP_IGNORE_CERT_ERRORS', False):
|
if getattr(ldap_config, 'LDAP_IGNORE_CERT_ERRORS', False):
|
||||||
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
|
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
|
||||||
|
|
||||||
|
# Optionally set CA cert directory
|
||||||
|
if ca_cert_dir := getattr(ldap_config, 'LDAP_CA_CERT_DIR', None):
|
||||||
|
ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, ca_cert_dir)
|
||||||
|
|
||||||
|
# Optionally set CA cert file
|
||||||
|
if ca_cert_file := getattr(ldap_config, 'LDAP_CA_CERT_FILE', None):
|
||||||
|
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, ca_cert_file)
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
@ -493,7 +493,7 @@ for param in dir(configuration):
|
|||||||
|
|
||||||
# Force usage of PostgreSQL's JSONB field for extra data
|
# Force usage of PostgreSQL's JSONB field for extra data
|
||||||
SOCIAL_AUTH_JSONFIELD_ENABLED = True
|
SOCIAL_AUTH_JSONFIELD_ENABLED = True
|
||||||
|
SOCIAL_AUTH_CLEAN_USERNAME_FUNCTION = 'netbox.users.utils.clean_username'
|
||||||
|
|
||||||
#
|
#
|
||||||
# Django Prometheus
|
# Django Prometheus
|
||||||
|
@ -31,8 +31,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"@typescript-eslint/no-unused-vars": "off",
|
"@typescript-eslint/no-unused-vars": "error",
|
||||||
"@typescript-eslint/no-unused-vars-experimental": "error",
|
|
||||||
"no-unused-vars": "off",
|
"no-unused-vars": "off",
|
||||||
"no-inner-declarations": "off",
|
"no-inner-declarations": "off",
|
||||||
"comma-dangle": ["error", "always-multiline"],
|
"comma-dangle": ["error", "always-multiline"],
|
||||||
|
BIN
netbox/project-static/dist/cable_trace.css
vendored
BIN
netbox/project-static/dist/cable_trace.css
vendored
Binary file not shown.
BIN
netbox/project-static/dist/config.js
vendored
BIN
netbox/project-static/dist/config.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/config.js.map
vendored
BIN
netbox/project-static/dist/config.js.map
vendored
Binary file not shown.
BIN
netbox/project-static/dist/graphiql.css
vendored
BIN
netbox/project-static/dist/graphiql.css
vendored
Binary file not shown.
BIN
netbox/project-static/dist/graphiql.js
vendored
BIN
netbox/project-static/dist/graphiql.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/graphiql.js.map
vendored
BIN
netbox/project-static/dist/graphiql.js.map
vendored
Binary file not shown.
BIN
netbox/project-static/dist/lldp.js
vendored
BIN
netbox/project-static/dist/lldp.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/lldp.js.map
vendored
BIN
netbox/project-static/dist/lldp.js.map
vendored
Binary file not shown.
BIN
netbox/project-static/dist/materialdesignicons-webfont-DWVXV5L5.woff
vendored
Normal file
BIN
netbox/project-static/dist/materialdesignicons-webfont-DWVXV5L5.woff
vendored
Normal file
Binary file not shown.
BIN
netbox/project-static/dist/materialdesignicons-webfont-ER2MFQKM.woff2
vendored
Normal file
BIN
netbox/project-static/dist/materialdesignicons-webfont-ER2MFQKM.woff2
vendored
Normal file
Binary file not shown.
BIN
netbox/project-static/dist/materialdesignicons-webfont-UHEFFMSX.eot
vendored
Normal file
BIN
netbox/project-static/dist/materialdesignicons-webfont-UHEFFMSX.eot
vendored
Normal file
Binary file not shown.
BIN
netbox/project-static/dist/materialdesignicons-webfont-WM6M6ZHQ.ttf
vendored
Normal file
BIN
netbox/project-static/dist/materialdesignicons-webfont-WM6M6ZHQ.ttf
vendored
Normal file
Binary file not shown.
BIN
netbox/project-static/dist/netbox-dark.css
vendored
BIN
netbox/project-static/dist/netbox-dark.css
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox-external.css
vendored
BIN
netbox/project-static/dist/netbox-external.css
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox-light.css
vendored
BIN
netbox/project-static/dist/netbox-light.css
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox-print.css
vendored
BIN
netbox/project-static/dist/netbox-print.css
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox.js
vendored
BIN
netbox/project-static/dist/netbox.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox.js.map
vendored
BIN
netbox/project-static/dist/netbox.js.map
vendored
Binary file not shown.
BIN
netbox/project-static/dist/rack_elevation.css
vendored
BIN
netbox/project-static/dist/rack_elevation.css
vendored
Binary file not shown.
BIN
netbox/project-static/dist/status.js
vendored
BIN
netbox/project-static/dist/status.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/status.js.map
vendored
BIN
netbox/project-static/dist/status.js.map
vendored
Binary file not shown.
@ -22,43 +22,38 @@
|
|||||||
"validate:formatting:scripts": "prettier -c src/**/*.ts"
|
"validate:formatting:scripts": "prettier -c src/**/*.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mdi/font": "^5.9.55",
|
"@mdi/font": "^7.0.96",
|
||||||
"@popperjs/core": "^2.9.2",
|
"@popperjs/core": "^2.11.6",
|
||||||
"bootstrap": "~5.0.2",
|
"bootstrap": "~5.0.2",
|
||||||
"clipboard": "^2.0.8",
|
"clipboard": "^2.0.11",
|
||||||
"color2k": "^1.2.4",
|
"color2k": "^2.0.0",
|
||||||
"dayjs": "^1.10.4",
|
"dayjs": "^1.11.5",
|
||||||
"flatpickr": "4.6.3",
|
"flatpickr": "4.6.13",
|
||||||
"htmx.org": "^1.6.1",
|
"htmx.org": "^1.8.0",
|
||||||
"just-debounce-it": "^1.4.0",
|
"just-debounce-it": "^3.1.1",
|
||||||
"masonry-layout": "^4.2.2",
|
"masonry-layout": "^4.2.2",
|
||||||
"query-string": "^6.14.1",
|
"query-string": "^7.1.1",
|
||||||
"sass": "^1.32.8",
|
"sass": "^1.55.0",
|
||||||
"simplebar": "^5.3.4",
|
"simplebar": "^5.3.9",
|
||||||
"slim-select": "^1.27.0"
|
"slim-select": "^1.27.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bootstrap": "^5.0.12",
|
"@types/bootstrap": "^5.0.17",
|
||||||
"@types/cookie": "^0.4.0",
|
"@types/cookie": "^0.5.1",
|
||||||
"@types/masonry-layout": "^4.2.2",
|
"@types/masonry-layout": "^4.2.5",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.29.3",
|
"@typescript-eslint/eslint-plugin": "^5.39.0",
|
||||||
"@typescript-eslint/parser": "^4.29.3",
|
"@typescript-eslint/parser": "^5.39.0",
|
||||||
"esbuild": "^0.12.24",
|
"esbuild": "^0.13.15",
|
||||||
"esbuild-sass-plugin": "^1.5.2",
|
"esbuild-sass-plugin": "^2.3.3",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^8.24.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"eslint-import-resolver-typescript": "^2.4.0",
|
"eslint-import-resolver-typescript": "^3.5.1",
|
||||||
"eslint-plugin-import": "^2.24.2",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
"eslint-plugin-prettier": "^3.4.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"prettier": "^2.3.2",
|
"prettier": "^2.7.1",
|
||||||
"typescript": "~4.3.5"
|
"typescript": "~4.8.4"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"eslint-import-resolver-typescript/**/path-parse": "^1.0.7",
|
"@types/bootstrap/**/@popperjs/core": "^2.11.6"
|
||||||
"slim-select/**/trim-newlines": "^3.0.1",
|
|
||||||
"eslint/glob-parent": "^5.1.2",
|
|
||||||
"esbuild-sass-plugin/**/glob-parent": "^5.1.2",
|
|
||||||
"@typescript-eslint/**/glob-parent": "^5.1.2",
|
|
||||||
"eslint-plugin-import/**/hosted-git-info": "^2.8.9"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -37,14 +37,12 @@ function initDocument(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function initWindow(): void {
|
function initWindow(): void {
|
||||||
|
const documentForms = document.forms;
|
||||||
const documentForms = document.forms
|
for (const documentForm of documentForms) {
|
||||||
for (var documentForm of documentForms) {
|
|
||||||
if (documentForm.method.toUpperCase() == 'GET') {
|
if (documentForm.method.toUpperCase() == 'GET') {
|
||||||
// @ts-ignore: Our version of typescript seems to be too old for FormDataEvent
|
|
||||||
documentForm.addEventListener('formdata', function (event: FormDataEvent) {
|
documentForm.addEventListener('formdata', function (event: FormDataEvent) {
|
||||||
let formData: FormData = event.formData;
|
const formData: FormData = event.formData;
|
||||||
for (let [name, value] of Array.from(formData.entries())) {
|
for (const [name, value] of Array.from(formData.entries())) {
|
||||||
if (value === '') formData.delete(name);
|
if (value === '') formData.delete(name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -32,7 +32,7 @@ $spacing-s: $input-padding-x;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@import './node_modules/slim-select/src/slim-select/slimselect';
|
@import '../node_modules/slim-select/src/slim-select/slimselect';
|
||||||
|
|
||||||
.ss-main {
|
.ss-main {
|
||||||
color: $form-select-color;
|
color: $form-select-color;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -60,23 +60,17 @@
|
|||||||
</div>
|
</div>
|
||||||
{% include 'inc/panels/custom_fields.html' %}
|
{% include 'inc/panels/custom_fields.html' %}
|
||||||
{% include 'inc/panels/tags.html' %}
|
{% include 'inc/panels/tags.html' %}
|
||||||
|
{% include 'inc/panels/comments.html' %}
|
||||||
{% plugin_left_page object %}
|
{% plugin_left_page object %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
{% include 'inc/panels/comments.html' %}
|
{% include 'circuits/inc/circuit_termination.html' with termination=object.termination_a side='A' %}
|
||||||
|
{% include 'circuits/inc/circuit_termination.html' with termination=object.termination_z side='Z' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
{% include 'inc/panels/contacts.html' %}
|
||||||
{% include 'inc/panels/image_attachments.html' %}
|
{% include 'inc/panels/image_attachments.html' %}
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
|
||||||
<div class="col col-md-6">
|
|
||||||
{% include 'circuits/inc/circuit_termination.html' with termination=object.termination_a side='A' %}
|
|
||||||
</div>
|
|
||||||
<div class="col col-md-6">
|
|
||||||
{% include 'circuits/inc/circuit_termination.html' with termination=object.termination_z side='Z' %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
{% plugin_full_width_page object %}
|
{% plugin_full_width_page object %}
|
||||||
|
@ -77,10 +77,10 @@
|
|||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu dropdown-menu-end">
|
<ul class="dropdown-menu dropdown-menu-end">
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.powerportport&a_terminations={{ object.pk }}&termination_b_type=dcim.poweroutlet&termination_b_site={{ object.device.site.pk }}&termination_b_rack={{ object.device.rack.pk }}&return_url={{ object.get_absolute_url }}" class="dropdown-link">Power Outlet</a>
|
<a href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.powerportport&a_terminations={{ object.pk }}&termination_b_type=dcim.poweroutlet&termination_b_site={{ object.device.site.pk }}&termination_b_rack={{ object.device.rack.pk }}&return_url={{ object.get_absolute_url }}" class="dropdown-item">Power Outlet</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.powerportport&a_terminations={{ object.pk }}&termination_b_type=dcim.powerfeed&termination_b_site={{ object.device.site.pk }}&termination_b_rack={{ object.device.rack.pk }}&return_url={{ object.get_absolute_url }}" class="dropdown-link">Power Feed</a>
|
<a href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.powerportport&a_terminations={{ object.pk }}&termination_b_type=dcim.powerfeed&termination_b_site={{ object.device.site.pk }}&termination_b_rack={{ object.device.rack.pk }}&return_url={{ object.get_absolute_url }}" class="dropdown-item">Power Feed</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</span>
|
</span>
|
||||||
|
@ -105,16 +105,16 @@
|
|||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu dropdown-menu-end">
|
<ul class="dropdown-menu dropdown-menu-end">
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-link" href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ object.pk }}&b_terminations_type=dcim.interface&termination_b_site={{ object.device.site.pk }}&termination_b_rack={{ object.device.rack.pk }}&return_url={{ object.get_absolute_url }}">Interface</a>
|
<a href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ object.pk }}&b_terminations_type=dcim.interface&termination_b_site={{ object.device.site.pk }}&termination_b_rack={{ object.device.rack.pk }}&return_url={{ object.get_absolute_url }}" class="dropdown-item">Interface</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-link" href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ object.pk }}&b_terminations_type=dcim.frontport&termination_b_site={{ object.device.site.pk }}&termination_b_rack={{ object.device.rack.pk }}&return_url={{ object.get_absolute_url }}">Front Port</a>
|
<a href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ object.pk }}&b_terminations_type=dcim.frontport&termination_b_site={{ object.device.site.pk }}&termination_b_rack={{ object.device.rack.pk }}&return_url={{ object.get_absolute_url }}" class="dropdown-item">Front Port</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-link" href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ object.pk }}&b_terminations_type=dcim.rearport&termination_b_site={{ object.device.site.pk }}&termination_b_rack={{ object.device.rack.pk }}&return_url={{ object.get_absolute_url }}">Rear Port</a>
|
<a href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ object.pk }}&b_terminations_type=dcim.rearport&termination_b_site={{ object.device.site.pk }}&termination_b_rack={{ object.device.rack.pk }}&return_url={{ object.get_absolute_url }}" class="dropdown-item">Rear Port</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-link" href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ object.pk }}&b_terminations_type=circuits.circuittermination&termination_b_site={{ object.device.site.pk }}&return_url={{ object.get_absolute_url }}">Circuit Termination</a>
|
<a href="{% url 'dcim:cable_add' %}?a_terminations_type=dcim.rearport&a_terminations={{ object.pk }}&b_terminations_type=circuits.circuittermination&termination_b_site={{ object.device.site.pk }}&return_url={{ object.get_absolute_url }}" class="dropdown-item">Circuit Termination</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</span>
|
</span>
|
||||||
|
@ -27,6 +27,12 @@ class TenantGroupForm(NetBoxModelForm):
|
|||||||
)
|
)
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Tenant Group', (
|
||||||
|
'parent', 'name', 'slug', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = TenantGroup
|
model = TenantGroup
|
||||||
fields = [
|
fields = [
|
||||||
@ -64,6 +70,12 @@ class ContactGroupForm(NetBoxModelForm):
|
|||||||
)
|
)
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Contact Group', (
|
||||||
|
'parent', 'name', 'slug', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ContactGroup
|
model = ContactGroup
|
||||||
fields = ('parent', 'name', 'slug', 'description', 'tags')
|
fields = ('parent', 'name', 'slug', 'description', 'tags')
|
||||||
@ -72,6 +84,12 @@ class ContactGroupForm(NetBoxModelForm):
|
|||||||
class ContactRoleForm(NetBoxModelForm):
|
class ContactRoleForm(NetBoxModelForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Contact Role', (
|
||||||
|
'name', 'slug', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ContactRole
|
model = ContactRole
|
||||||
fields = ('name', 'slug', 'description', 'tags')
|
fields = ('name', 'slug', 'description', 'tags')
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
|
|
||||||
|
from netbox.tables import columns
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
|
'ContactsColumnMixin',
|
||||||
'TenantColumn',
|
'TenantColumn',
|
||||||
'TenantGroupColumn',
|
'TenantGroupColumn',
|
||||||
'TenancyColumnsMixin',
|
'TenancyColumnsMixin',
|
||||||
@ -55,3 +58,10 @@ class TenantGroupColumn(tables.TemplateColumn):
|
|||||||
class TenancyColumnsMixin(tables.Table):
|
class TenancyColumnsMixin(tables.Table):
|
||||||
tenant_group = TenantGroupColumn()
|
tenant_group = TenantGroupColumn()
|
||||||
tenant = TenantColumn()
|
tenant = TenantColumn()
|
||||||
|
|
||||||
|
|
||||||
|
class ContactsColumnMixin(tables.Table):
|
||||||
|
contacts = columns.ManyToManyColumn(
|
||||||
|
linkify_item=True,
|
||||||
|
transform=lambda obj: obj.contact.name
|
||||||
|
)
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
|
from tenancy.models import *
|
||||||
|
from tenancy.tables import ContactsColumnMixin
|
||||||
|
|
||||||
from netbox.tables import NetBoxTable, columns
|
from netbox.tables import NetBoxTable, columns
|
||||||
from tenancy.models import *
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'TenantGroupTable',
|
'TenantGroupTable',
|
||||||
@ -30,7 +31,7 @@ class TenantGroupTable(NetBoxTable):
|
|||||||
default_columns = ('pk', 'name', 'tenant_count', 'description')
|
default_columns = ('pk', 'name', 'tenant_count', 'description')
|
||||||
|
|
||||||
|
|
||||||
class TenantTable(NetBoxTable):
|
class TenantTable(ContactsColumnMixin, NetBoxTable):
|
||||||
name = tables.Column(
|
name = tables.Column(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
@ -38,9 +39,6 @@ class TenantTable(NetBoxTable):
|
|||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
comments = columns.MarkdownColumn()
|
comments = columns.MarkdownColumn()
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='tenancy:contact_list'
|
url_name='tenancy:contact_list'
|
||||||
)
|
)
|
||||||
|
9
netbox/users/utils.py
Normal file
9
netbox/users/utils.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from social_core.storage import NO_ASCII_REGEX, NO_SPECIAL_REGEX
|
||||||
|
|
||||||
|
|
||||||
|
def clean_username(value):
|
||||||
|
"""Clean username removing any unsupported character"""
|
||||||
|
value = NO_ASCII_REGEX.sub('', value)
|
||||||
|
value = NO_SPECIAL_REGEX.sub('', value)
|
||||||
|
value = value.replace(':', '')
|
||||||
|
return value
|
@ -28,6 +28,12 @@ __all__ = (
|
|||||||
class ClusterTypeForm(NetBoxModelForm):
|
class ClusterTypeForm(NetBoxModelForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Cluster Type', (
|
||||||
|
'name', 'slug', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ClusterType
|
model = ClusterType
|
||||||
fields = (
|
fields = (
|
||||||
@ -38,6 +44,12 @@ class ClusterTypeForm(NetBoxModelForm):
|
|||||||
class ClusterGroupForm(NetBoxModelForm):
|
class ClusterGroupForm(NetBoxModelForm):
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Cluster Group', (
|
||||||
|
'name', 'slug', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ClusterGroup
|
model = ClusterGroup
|
||||||
fields = (
|
fields = (
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
|
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
|
||||||
|
from virtualization.models import Cluster, ClusterGroup, ClusterType
|
||||||
|
|
||||||
from netbox.tables import NetBoxTable, columns
|
from netbox.tables import NetBoxTable, columns
|
||||||
from tenancy.tables import TenancyColumnsMixin
|
|
||||||
from virtualization.models import Cluster, ClusterGroup, ClusterType
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ClusterTable',
|
'ClusterTable',
|
||||||
@ -32,7 +32,7 @@ class ClusterTypeTable(NetBoxTable):
|
|||||||
default_columns = ('pk', 'name', 'cluster_count', 'description')
|
default_columns = ('pk', 'name', 'cluster_count', 'description')
|
||||||
|
|
||||||
|
|
||||||
class ClusterGroupTable(NetBoxTable):
|
class ClusterGroupTable(ContactsColumnMixin, NetBoxTable):
|
||||||
name = tables.Column(
|
name = tables.Column(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
@ -41,9 +41,6 @@ class ClusterGroupTable(NetBoxTable):
|
|||||||
url_params={'group_id': 'pk'},
|
url_params={'group_id': 'pk'},
|
||||||
verbose_name='Clusters'
|
verbose_name='Clusters'
|
||||||
)
|
)
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='virtualization:clustergroup_list'
|
url_name='virtualization:clustergroup_list'
|
||||||
)
|
)
|
||||||
@ -57,7 +54,7 @@ class ClusterGroupTable(NetBoxTable):
|
|||||||
default_columns = ('pk', 'name', 'cluster_count', 'description')
|
default_columns = ('pk', 'name', 'cluster_count', 'description')
|
||||||
|
|
||||||
|
|
||||||
class ClusterTable(TenancyColumnsMixin, NetBoxTable):
|
class ClusterTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||||
name = tables.Column(
|
name = tables.Column(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
@ -81,9 +78,6 @@ class ClusterTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
verbose_name='VMs'
|
verbose_name='VMs'
|
||||||
)
|
)
|
||||||
comments = columns.MarkdownColumn()
|
comments = columns.MarkdownColumn()
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='virtualization:cluster_list'
|
url_name='virtualization:cluster_list'
|
||||||
)
|
)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
|
|
||||||
from dcim.tables.devices import BaseInterfaceTable
|
from dcim.tables.devices import BaseInterfaceTable
|
||||||
from netbox.tables import NetBoxTable, columns
|
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
|
||||||
from tenancy.tables import TenancyColumnsMixin
|
|
||||||
from virtualization.models import VirtualMachine, VMInterface
|
from virtualization.models import VirtualMachine, VMInterface
|
||||||
|
|
||||||
|
from netbox.tables import NetBoxTable, columns
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'VirtualMachineTable',
|
'VirtualMachineTable',
|
||||||
'VirtualMachineVMInterfaceTable',
|
'VirtualMachineVMInterfaceTable',
|
||||||
@ -37,7 +37,7 @@ VMINTERFACE_BUTTONS = """
|
|||||||
# Virtual machines
|
# Virtual machines
|
||||||
#
|
#
|
||||||
|
|
||||||
class VirtualMachineTable(TenancyColumnsMixin, NetBoxTable):
|
class VirtualMachineTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||||
name = tables.Column(
|
name = tables.Column(
|
||||||
order_by=('_name',),
|
order_by=('_name',),
|
||||||
linkify=True
|
linkify=True
|
||||||
@ -67,9 +67,6 @@ class VirtualMachineTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
order_by=('primary_ip4', 'primary_ip6'),
|
order_by=('primary_ip4', 'primary_ip6'),
|
||||||
verbose_name='IP Address'
|
verbose_name='IP Address'
|
||||||
)
|
)
|
||||||
contacts = columns.ManyToManyColumn(
|
|
||||||
linkify_item=True
|
|
||||||
)
|
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='virtualization:virtualmachine_list'
|
url_name='virtualization:virtualmachine_list'
|
||||||
)
|
)
|
||||||
|
@ -19,6 +19,12 @@ class WirelessLANGroupForm(NetBoxModelForm):
|
|||||||
)
|
)
|
||||||
slug = SlugField()
|
slug = SlugField()
|
||||||
|
|
||||||
|
fieldsets = (
|
||||||
|
('Wireless LAN Group', (
|
||||||
|
'parent', 'name', 'slug', 'description', 'tags',
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WirelessLANGroup
|
model = WirelessLANGroup
|
||||||
fields = [
|
fields = [
|
||||||
|
@ -27,10 +27,13 @@ psycopg2-binary==2.9.3
|
|||||||
PyYAML==6.0
|
PyYAML==6.0
|
||||||
sentry-sdk==1.9.10
|
sentry-sdk==1.9.10
|
||||||
social-auth-app-django==5.0.0
|
social-auth-app-django==5.0.0
|
||||||
social-auth-core==4.3.0
|
social-auth-core[openidconnect]==4.3.0
|
||||||
svgwrite==1.4.3
|
svgwrite==1.4.3
|
||||||
tablib==3.2.1
|
tablib==3.2.1
|
||||||
tzdata==2022.4
|
tzdata==2022.4
|
||||||
|
|
||||||
# Workaround for #7401
|
# Workaround for #7401
|
||||||
jsonschema==3.2.0
|
jsonschema==3.2.0
|
||||||
|
|
||||||
|
# Temporary fix for #10712
|
||||||
|
swagger-spec-validator==2.7.6
|
||||||
|
Loading…
Reference in New Issue
Block a user