mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Cleanup for #7854
This commit is contained in:
@ -37,7 +37,7 @@ router.register('inventory-item-templates', views.InventoryItemTemplateViewSet)
|
|||||||
router.register('device-roles', views.DeviceRoleViewSet)
|
router.register('device-roles', views.DeviceRoleViewSet)
|
||||||
router.register('platforms', views.PlatformViewSet)
|
router.register('platforms', views.PlatformViewSet)
|
||||||
router.register('devices', views.DeviceViewSet)
|
router.register('devices', views.DeviceViewSet)
|
||||||
router.register('vdcs', views.VirtualDeviceContextViewSet)
|
router.register('virtual-device-contexts', views.VirtualDeviceContextViewSet)
|
||||||
router.register('modules', views.ModuleViewSet)
|
router.register('modules', views.ModuleViewSet)
|
||||||
|
|
||||||
# Device components
|
# Device components
|
||||||
|
@ -1407,12 +1407,12 @@ class PowerFeedPhaseChoices(ChoiceSet):
|
|||||||
class VirtualDeviceContextStatusChoices(ChoiceSet):
|
class VirtualDeviceContextStatusChoices(ChoiceSet):
|
||||||
key = 'VirtualDeviceContext.status'
|
key = 'VirtualDeviceContext.status'
|
||||||
|
|
||||||
STATUS_PLANNED = 'planned'
|
|
||||||
STATUS_ACTIVE = 'active'
|
STATUS_ACTIVE = 'active'
|
||||||
|
STATUS_PLANNED = 'planned'
|
||||||
STATUS_OFFLINE = 'offline'
|
STATUS_OFFLINE = 'offline'
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
(STATUS_PLANNED, 'Planned', 'cyan'),
|
|
||||||
(STATUS_ACTIVE, 'Active', 'green'),
|
(STATUS_ACTIVE, 'Active', 'green'),
|
||||||
|
(STATUS_PLANNED, 'Planned', 'cyan'),
|
||||||
(STATUS_OFFLINE, 'Offline', 'red'),
|
(STATUS_OFFLINE, 'Offline', 'red'),
|
||||||
]
|
]
|
||||||
|
@ -1032,7 +1032,7 @@ class VirtualDeviceContextFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = VirtualDeviceContext
|
model = VirtualDeviceContext
|
||||||
fields = ['id', 'device', 'name', ]
|
fields = ['id', 'device', 'name']
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
if not value.strip():
|
if not value.strip():
|
||||||
|
@ -736,9 +736,8 @@ class VirtualDeviceContextFilterForm(
|
|||||||
model = VirtualDeviceContext
|
model = VirtualDeviceContext
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, ('q', 'filter_id', 'tag')),
|
(None, ('q', 'filter_id', 'tag')),
|
||||||
('Hardware', ('device', 'status', )),
|
('Attributes', ('device', 'status', 'has_primary_ip')),
|
||||||
('Tenant', ('tenant_group_id', 'tenant_id')),
|
('Tenant', ('tenant_group_id', 'tenant_id')),
|
||||||
('Miscellaneous', ('has_primary_ip',))
|
|
||||||
)
|
)
|
||||||
device = DynamicModelMultipleChoiceField(
|
device = DynamicModelMultipleChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
|
@ -1698,21 +1698,19 @@ class VirtualDeviceContextForm(TenancyForm, NetBoxModelForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
('Device', ('region', 'site_group', 'site', 'location', 'rack', 'device')),
|
('Assigned Device', ('region', 'site_group', 'site', 'location', 'rack', 'device')),
|
||||||
('Virtual Device Context', ('name', 'status', 'identifier', 'primary_ip4', 'primary_ip6', 'tenant_group',
|
('Virtual Device Context', ('name', 'status', 'identifier', 'primary_ip4', 'primary_ip6', 'tags')),
|
||||||
'tenant')),
|
('Tenancy', ('tenant_group', 'tenant'))
|
||||||
(None, ('tags', ))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = VirtualDeviceContext
|
model = VirtualDeviceContext
|
||||||
fields = [
|
fields = [
|
||||||
'region', 'site_group', 'site', 'location', 'rack',
|
'region', 'site_group', 'site', 'location', 'rack', 'device', 'name', 'status', 'identifier',
|
||||||
'device', 'name', 'status', 'identifier', 'primary_ip4', 'primary_ip6', 'tenant_group', 'tenant',
|
'primary_ip4', 'primary_ip6', 'tenant_group', 'tenant', 'comments', 'tags'
|
||||||
'comments', 'tags'
|
|
||||||
]
|
]
|
||||||
help_texts = {}
|
|
||||||
widgets = {
|
widgets = {
|
||||||
|
'status': StaticSelect(),
|
||||||
'primary_ip4': StaticSelect(),
|
'primary_ip4': StaticSelect(),
|
||||||
'primary_ip6': StaticSelect(),
|
'primary_ip6': StaticSelect(),
|
||||||
}
|
}
|
||||||
|
@ -1113,7 +1113,7 @@ class VirtualDeviceContext(PrimaryModel):
|
|||||||
choices=VirtualDeviceContextStatusChoices,
|
choices=VirtualDeviceContextStatusChoices,
|
||||||
)
|
)
|
||||||
identifier = models.PositiveSmallIntegerField(
|
identifier = models.PositiveSmallIntegerField(
|
||||||
help_text='Unique identifier provided by the platform being virtualized (Example: Nexus VDC Identifier)',
|
help_text='Numeric identifier unique to the parent device',
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
)
|
)
|
||||||
@ -1163,6 +1163,9 @@ class VirtualDeviceContext(PrimaryModel):
|
|||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('dcim:virtualdevicecontext', kwargs={'pk': self.pk})
|
return reverse('dcim:virtualdevicecontext', kwargs={'pk': self.pk})
|
||||||
|
|
||||||
|
def get_status_color(self):
|
||||||
|
return VirtualDeviceContextStatusChoices.colors.get(self.status)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def primary_ip(self):
|
def primary_ip(self):
|
||||||
if ConfigItem('PREFER_IPV4')() and self.primary_ip4:
|
if ConfigItem('PREFER_IPV4')() and self.primary_ip4:
|
||||||
|
@ -184,12 +184,12 @@ urlpatterns = [
|
|||||||
path('devices/<int:pk>/', include(get_model_urls('dcim', 'device'))),
|
path('devices/<int:pk>/', include(get_model_urls('dcim', 'device'))),
|
||||||
|
|
||||||
# Virtual Device Context
|
# Virtual Device Context
|
||||||
path('vdcs/', views.VirtualDeviceContextListView.as_view(), name='virtualdevicecontext_list'),
|
path('virtual-device-contexts/', views.VirtualDeviceContextListView.as_view(), name='virtualdevicecontext_list'),
|
||||||
path('vdcs/add/', views.VirtualDeviceContextEditView.as_view(), name='virtualdevicecontext_add'),
|
path('virtual-device-contexts/add/', views.VirtualDeviceContextEditView.as_view(), name='virtualdevicecontext_add'),
|
||||||
path('vdcs/import/', views.VirtualDeviceContextBulkImportView.as_view(), name='virtualdevicecontext_import'),
|
path('virtual-device-contexts/import/', views.VirtualDeviceContextBulkImportView.as_view(), name='virtualdevicecontext_import'),
|
||||||
path('vdcs/edit/', views.VirtualDeviceContextBulkEditView.as_view(), name='virtualdevicecontext_bulk_edit'),
|
path('virtual-device-contexts/edit/', views.VirtualDeviceContextBulkEditView.as_view(), name='virtualdevicecontext_bulk_edit'),
|
||||||
path('vdcs/delete/', views.VirtualDeviceContextBulkDeleteView.as_view(), name='virtualdevicecontext_bulk_delete'),
|
path('virtual-device-contexts/delete/', views.VirtualDeviceContextBulkDeleteView.as_view(), name='virtualdevicecontext_bulk_delete'),
|
||||||
path('vdcs/<int:pk>/', include(get_model_urls('dcim', 'virtualdevicecontext'))),
|
path('virtual-device-contexts/<int:pk>/', include(get_model_urls('dcim', 'virtualdevicecontext'))),
|
||||||
|
|
||||||
# Modules
|
# Modules
|
||||||
path('modules/', views.ModuleListView.as_view(), name='module_list'),
|
path('modules/', views.ModuleListView.as_view(), name='module_list'),
|
||||||
|
@ -1837,11 +1837,14 @@ class DeviceView(generic.ObjectView):
|
|||||||
else:
|
else:
|
||||||
vc_members = []
|
vc_members = []
|
||||||
|
|
||||||
# Services
|
|
||||||
services = Service.objects.restrict(request.user, 'view').filter(device=instance)
|
services = Service.objects.restrict(request.user, 'view').filter(device=instance)
|
||||||
|
vdcs = VirtualDeviceContext.objects.restrict(request.user, 'view').filter(device=instance).prefetch_related(
|
||||||
|
'tenant'
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'services': services,
|
'services': services,
|
||||||
|
'vdcs': vdcs,
|
||||||
'vc_members': vc_members,
|
'vc_members': vc_members,
|
||||||
'svg_extra': f'highlight=id:{instance.pk}'
|
'svg_extra': f'highlight=id:{instance.pk}'
|
||||||
}
|
}
|
||||||
|
@ -155,6 +155,38 @@
|
|||||||
{% 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' %}
|
{% include 'inc/panels/comments.html' %}
|
||||||
|
<div class="card">
|
||||||
|
<h5 class="card-header">Virtual Device Contexts</h5>
|
||||||
|
<div class="card-body">
|
||||||
|
{% if vdcs %}
|
||||||
|
<table class="table table-hover">
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Identifier</th>
|
||||||
|
<th>Tenant</th>
|
||||||
|
</tr>
|
||||||
|
{% for vdc in vdcs %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ vdc|linkify }}</td>
|
||||||
|
<td>{% badge vdc.get_status_display bg_color=vdc.get_status_color %}</td>
|
||||||
|
<td>{{ vdc.identifier|placeholder }}</td>
|
||||||
|
<td>{{ vdc.tenant|linkify|placeholder }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<div class="text-muted">None</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% if perms.dcim.add_virtualdevicecontext %}
|
||||||
|
<div class="card-footer text-end noprint">
|
||||||
|
<a href="{% url 'dcim:virtualdevicecontext_add' %}?device={{ object.pk }}" class="btn btn-sm btn-primary">
|
||||||
|
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Create VDC
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% plugin_left_page object %}
|
{% plugin_left_page object %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-12 col-xl-6">
|
<div class="col col-12 col-xl-6">
|
||||||
@ -264,34 +296,30 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h5 class="card-header">
|
<h5 class="card-header">Services</h5>
|
||||||
Services
|
<div class="card-body">
|
||||||
</h5>
|
|
||||||
<div class="card-body">
|
|
||||||
{% if services %}
|
{% if services %}
|
||||||
<table class="table table-hover">
|
<table class="table table-hover">
|
||||||
{% for service in services %}
|
{% for service in services %}
|
||||||
{% include 'ipam/inc/service.html' %}
|
{% include 'ipam/inc/service.html' %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-muted">
|
<div class="text-muted">None</div>
|
||||||
None
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if perms.ipam.add_service %}
|
{% if perms.ipam.add_service %}
|
||||||
<div class="card-footer text-end noprint">
|
<div class="card-footer text-end noprint">
|
||||||
<a href="{% url 'ipam:service_add' %}?device={{ object.pk }}" class="btn btn-sm btn-primary">
|
<a href="{% url 'ipam:service_add' %}?device={{ object.pk }}" class="btn btn-sm btn-primary">
|
||||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Assign Service
|
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Assign Service
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% include 'inc/panels/contacts.html' %}
|
{% include 'inc/panels/contacts.html' %}
|
||||||
{% include 'inc/panels/image_attachments.html' %}
|
{% include 'inc/panels/image_attachments.html' %}
|
||||||
{% if object.rack and object.position %}
|
{% if object.rack and object.position %}
|
||||||
<div class="row" style="margin-bottom: 20px">
|
<div class="row" style="margin-bottom: 20px">
|
||||||
<div class="col col-md-6 col-sm-6 col-xs-12 text-center">
|
<div class="col col-md-6 col-sm-6 col-xs-12 text-center">
|
||||||
<div style="margin-left: 30px">
|
<div style="margin-left: 30px">
|
||||||
<h4>Front</h4>
|
<h4>Front</h4>
|
||||||
@ -304,7 +332,7 @@
|
|||||||
{% include 'dcim/inc/rack_elevation.html' with object=object.rack face='rear' extra_params=svg_extra %}
|
{% include 'dcim/inc/rack_elevation.html' with object=object.rack face='rear' extra_params=svg_extra %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
<th scope="row">Identifier</th>
|
<th scope="row">Identifier</th>
|
||||||
<td>{{ object.identifier|placeholder }}</td>
|
<td>{{ object.identifier|placeholder }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Primary IPv4</th>
|
<th scope="row">Primary IPv4</th>
|
||||||
<td>
|
<td>
|
||||||
@ -41,6 +40,15 @@
|
|||||||
{{ object.primary_ip6|placeholder }}
|
{{ object.primary_ip6|placeholder }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">Tenant</th>
|
||||||
|
<td>
|
||||||
|
{% if object.tenant.group %}
|
||||||
|
{{ object.tenant.group|linkify }} /
|
||||||
|
{% endif %}
|
||||||
|
{{ object.tenant|linkify|placeholder }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user