diff --git a/netbox/templates/virtualization/virtualdisk.html b/netbox/templates/virtualization/virtualdisk.html
new file mode 100644
index 000000000..222e97146
--- /dev/null
+++ b/netbox/templates/virtualization/virtualdisk.html
@@ -0,0 +1,59 @@
+{% extends 'generic/object.html' %}
+{% load helpers %}
+{% load plugins %}
+{% load render_table from django_tables2 %}
+{% load i18n %}
+
+{% block breadcrumbs %}
+ {{ block.super }}
+
+ {% comment %}
+ {{ object.virtual_machine }}
+ {% endcomment %}
+
+{% endblock %}
+
+{% block content %}
+
+
+
+
+
+
+
+ {% trans "Virtual Machine" %} |
+ {{ object.virtual_machine|linkify }} |
+
+
+ {% trans "Name" %} |
+ {{ object.name }} |
+
+
+ {% trans "Disk Space" %} |
+
+ {% if object.size %}
+ {{ object.size }} {% trans "GB" context "Abbreviation for gigabyte" %}
+ {% else %}
+ {{ ''|placeholder }}
+ {% endif %}
+ |
+
+
+
+
+ {% include 'inc/panels/tags.html' %}
+ {% plugin_left_page object %}
+
+
+ {% include 'inc/panels/custom_fields.html' %}
+ {% plugin_right_page object %}
+
+
+
+
+ {% plugin_full_width_page object %}
+
+
+{% endblock %}
diff --git a/netbox/virtualization/api/serializers.py b/netbox/virtualization/api/serializers.py
index e3838594b..84dcd5407 100644
--- a/netbox/virtualization/api/serializers.py
+++ b/netbox/virtualization/api/serializers.py
@@ -84,6 +84,7 @@ class VirtualMachineSerializer(NetBoxModelSerializer):
# Counter fields
interface_count = serializers.IntegerField(read_only=True)
+ virtual_disk_count = serializers.IntegerField(read_only=True)
class Meta:
model = VirtualMachine
@@ -91,7 +92,7 @@ class VirtualMachineSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'name', 'status', 'site', 'cluster', 'device', 'role', 'tenant', 'platform',
'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description', 'comments',
'config_template', 'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated',
- 'interface_count',
+ 'interface_count', 'virtual_disk_count',
]
validators = []
@@ -104,7 +105,7 @@ class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer):
'id', 'url', 'display', 'name', 'status', 'site', 'cluster', 'device', 'role', 'tenant', 'platform',
'primary_ip', 'primary_ip4', 'primary_ip6', 'vcpus', 'memory', 'disk', 'description', 'comments',
'local_context_data', 'tags', 'custom_fields', 'config_context', 'created', 'last_updated',
- 'interface_count',
+ 'interface_count', 'virtual_disk_count',
]
@extend_schema_field(serializers.JSONField(allow_null=True))
diff --git a/netbox/virtualization/models/virtualmachines.py b/netbox/virtualization/models/virtualmachines.py
index 67638c38c..882f861f3 100644
--- a/netbox/virtualization/models/virtualmachines.py
+++ b/netbox/virtualization/models/virtualmachines.py
@@ -131,6 +131,10 @@ class VirtualMachine(ContactsMixin, RenderConfigMixin, ConfigContextModel, Prima
to_model='virtualization.VMInterface',
to_field='virtual_machine'
)
+ virtual_disk_count = CounterCacheField(
+ to_model='virtualization.VirtualDisk',
+ to_field='virtual_machine'
+ )
objects = ConfigContextModelQuerySet.as_manager()
diff --git a/netbox/virtualization/tables/virtualmachines.py b/netbox/virtualization/tables/virtualmachines.py
index abfbed6eb..4328c12e7 100644
--- a/netbox/virtualization/tables/virtualmachines.py
+++ b/netbox/virtualization/tables/virtualmachines.py
@@ -85,6 +85,9 @@ class VirtualMachineTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable)
interface_count = tables.Column(
verbose_name=_('Interfaces')
)
+ virtual_disk_count = tables.Column(
+ verbose_name=_('Virtual Disks')
+ )
config_template = tables.Column(
verbose_name=_('Config Template'),
linkify=True
diff --git a/netbox/virtualization/views.py b/netbox/virtualization/views.py
index ab14921ae..0dafb97a5 100644
--- a/netbox/virtualization/views.py
+++ b/netbox/virtualization/views.py
@@ -365,6 +365,12 @@ class VirtualMachineInterfacesView(generic.ObjectChildrenView):
permission='virtualization.view_vminterface',
weight=500
)
+ tab = ViewTab(
+ label=_('Disks'),
+ badge=lambda obj: obj.virtual_disk_count,
+ permission='virtualization.view_virtual_disk',
+ weight=500
+ )
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
action_perms = defaultdict(set, **{
'add': {'add'},