Skip to content

Commit

Permalink
lungroups -> datastores, vmdk object type added
Browse files Browse the repository at this point in the history
  • Loading branch information
viroge committed Feb 8, 2023
1 parent 8449a85 commit 609a176
Show file tree
Hide file tree
Showing 21 changed files with 413 additions and 139 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ THIS PLUGIN IS UNDER DEVELOPMENT AND MAY CHANGE.

A [Netbox](https://github.com/netbox-community/netbox) plugin for storage related documentation where virtualization is used.

4 new object types are introduced:
5 new object types are introduced:
- Storage Pools: a pool that is created on a storage. Currently this storage has to be a Netbox Device.
- LUN: tied to a Storage Pool
- LUN Groups: a collection of LUNs for easier management of Storage Sessions.
- Datastores: created on LUN(s)
- Storage Sessions: the "source" of a session is a Netbox Virtualization Cluster, the "destination" is the LUN Group
- VMDK: can be assigned to a VM and a datastore
2 changes: 1 addition & 1 deletion netbox_storage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class NetBoxStorageConfig(PluginConfig):
name = 'netbox_storage'
verbose_name = ' NetBox Storage'
description = 'Netbox Storage Administration Plugin'
version = '0.1'
version = '0.2'
base_url = 'storage'


Expand Down
56 changes: 40 additions & 16 deletions netbox_storage/api/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from rest_framework import serializers

from ..models import StoragePool, StorageLUN, StorageSession, StorageLUNGroup
from ..models import StoragePool, LUN, StorageSession, Datastore, VMDK
from virtualization.api.serializers import NestedClusterSerializer
from netbox.api.serializers import NetBoxModelSerializer, WritableNestedSerializer

Expand All @@ -19,13 +19,23 @@ class Meta:
fields = ('id', 'url', 'display', 'name')


class NestedStorageLUNSerializer(WritableNestedSerializer):
class NestedLUNSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_storage-api:storagelun-detail'
view_name='plugins-api:netbox_storage-api:lun-detail'
)

class Meta:
model = StorageLUN
model = LUN
fields = ('id', 'url', 'display', 'name')


class NestedDatastoreSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_storage-api:datastore-detail'
)

class Meta:
model = Datastore
fields = ('id', 'url', 'display', 'name')


Expand All @@ -39,13 +49,13 @@ class Meta:
fields = ('id', 'url', 'display', 'name')


class NestedStorageLUNGroupSerializer(WritableNestedSerializer):
class NestedVMDKSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_storage-api:storagelungroup-detail'
view_name='plugins-api:netbox_storage-api:vmdk-detail'
)

class Meta:
model = StorageLUNGroup
model = VMDK
fields = ('id', 'url', 'display', 'name')


Expand All @@ -66,21 +76,34 @@ class Meta:
)


class StorageLUNSerializer(NetBoxModelSerializer):
class LUNSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_storage-api:storagelun-detail'
view_name='plugins-api:netbox_storage-api:lun-detail'
)
storage_pool = NestedStoragePoolSerializer()

class Meta:
model = StorageLUN
model = LUN
fields = (
'id', 'url', 'display', 'name', 'size', 'storage_pool',
'description', 'tags', 'custom_fields',
'created', 'last_updated',
)


class DatastoreSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_storage-api:datastore-detail'
)

class Meta:
model = Datastore
fields = (
'id', 'url', 'display', 'name', 'lun',
'description', 'tags', 'custom_fields', 'created', 'last_updated',
)


class StorageSessionSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_storage-api:storagesession-detail'
Expand All @@ -90,19 +113,20 @@ class StorageSessionSerializer(NetBoxModelSerializer):
class Meta:
model = StorageSession
fields = (
'id', 'url', 'display', 'name', 'cluster', 'storage_lun_groups',
'id', 'url', 'display', 'name', 'cluster', 'datastores',
'description', 'tags', 'custom_fields', 'created', 'last_updated',
)


class StorageLUNGroupSerializer(NetBoxModelSerializer):
class VMDKSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='plugins-api:netbox_storage-api:storagelungroup-detail'
view_name='plugins-api:netbox_storage-api:vmdk-detail'
)
datastore = NestedDatastoreSerializer()

class Meta:
model = StorageLUNGroup
model = VMDK
fields = (
'id', 'url', 'display', 'name', 'storage_lun',
'description', 'tags', 'custom_fields', 'created', 'last_updated',
'id', 'url', 'display', 'vm', 'name', 'datastore',
'size', 'tags', 'custom_fields', 'created', 'last_updated',
)
5 changes: 3 additions & 2 deletions netbox_storage/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

router = NetBoxRouter()
router.register('storagepool', views.StoragePoolViewSet)
router.register('storagelun', views.StorageLUNViewSet)
router.register('lun', views.LUNViewSet)
router.register('datastore', views.DatastoreViewSet)
router.register('storagesession', views.StorageSessionViewSet)
router.register('storagelungroup', views.StorageLUNGroupViewSet)
router.register('vmdk', views.VMDKViewSet)

urlpatterns = router.urls
25 changes: 16 additions & 9 deletions netbox_storage/api/views.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,37 @@
from netbox.api.viewsets import NetBoxModelViewSet

from .. import filtersets, models
from .serializers import StoragePoolSerializer, StorageLUNSerializer, StorageSessionSerializer, StorageLUNGroupSerializer
from .serializers import StoragePoolSerializer, LUNSerializer, StorageSessionSerializer, DatastoreSerializer, VMDKSerializer


class StoragePoolViewSet(NetBoxModelViewSet):
queryset = models.StoragePool.objects.prefetch_related('device', 'tags')
serializer_class = StoragePoolSerializer


class StorageLUNViewSet(NetBoxModelViewSet):
queryset = models.StorageLUN.objects.prefetch_related(
class LUNViewSet(NetBoxModelViewSet):
queryset = models.LUN.objects.prefetch_related(
'storage_pool', 'tags'
)
serializer_class = StorageLUNSerializer
serializer_class = LUNSerializer


class StorageLUNGroupViewSet(NetBoxModelViewSet):
queryset = models.StorageLUNGroup.objects.prefetch_related(
'storage_lun', 'tags'
class DatastoreViewSet(NetBoxModelViewSet):
queryset = models.Datastore.objects.prefetch_related(
'lun', 'tags'
)
serializer_class = StorageLUNGroupSerializer
serializer_class = DatastoreSerializer


class StorageSessionViewSet(NetBoxModelViewSet):
queryset = models.StorageSession.objects.prefetch_related(
'cluster', 'storage_lun_groups', 'tags'
'cluster', 'datastores', 'tags'
)
serializer_class = StorageSessionSerializer


class VMDKViewSet(NetBoxModelViewSet):
queryset = models.VMDK.objects.prefetch_related(
'datastore', 'vm', 'tags'
)
serializer_class = VMDKSerializer
2 changes: 1 addition & 1 deletion netbox_storage/filtersets.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from netbox.filtersets import NetBoxModelFilterSet
from .models import StorageLUN, StorageSession, StorageLUNGroup
from .models import LUN, StorageSession, Datastore


# class StorageLUNFilterSet(NetBoxModelFilterSet):
Expand Down
43 changes: 30 additions & 13 deletions netbox_storage/forms.py
Original file line number Diff line number Diff line change
@@ -1,54 +1,71 @@
from django import forms
from netbox.forms import NetBoxModelForm, NetBoxModelFilterSetForm, NetBoxModelCSVForm
from utilities.forms.fields import DynamicModelChoiceField, CSVModelChoiceField, DynamicModelMultipleChoiceField
from ipam.models import IPAddress
from dcim.models import Device
from virtualization.models import Cluster
from .models import StoragePool, StorageSession, StorageLUN, StorageLUNGroup
from virtualization.models import Cluster, VirtualMachine
from .models import StoragePool, StorageSession, LUN, Datastore, VMDK


#
# Regular forms
#
class StoragePoolForm(NetBoxModelForm):
device = DynamicModelChoiceField(
queryset=Device.objects.all()
)

class Meta:
model = StoragePool
fields = ('name', 'size', 'device', 'description', 'tags')


class StorageLUNForm(NetBoxModelForm):
class LUNForm(NetBoxModelForm):
storage_pool = DynamicModelChoiceField(
queryset=StoragePool.objects.all()
)

class Meta:
model = StorageLUN
model = LUN
fields = ('storage_pool', 'name', 'size', 'description')


class StorageLUNGroupForm(NetBoxModelForm):
storage_lun = DynamicModelMultipleChoiceField(
queryset=StorageLUN.objects.all()
class DatastoreForm(NetBoxModelForm):
lun = DynamicModelMultipleChoiceField(
queryset=LUN.objects.all()
)

class Meta:
model = StorageLUN
fields = ('storage_lun', 'name', 'description')
model = LUN
fields = ('lun', 'name', 'description')


class StorageSessionForm(NetBoxModelForm):
cluster = DynamicModelChoiceField(
queryset=Cluster.objects.all(),
)
storage_lun_groups = DynamicModelMultipleChoiceField(
queryset=StorageLUNGroup.objects.all()
datastores = DynamicModelMultipleChoiceField(
queryset=Datastore.objects.all()
)

class Meta:
model = StorageSession
fields = (
'name', 'cluster', 'storage_lun_groups', 'description'
'name', 'cluster', 'datastores', 'description'
)


class VMDKForm(NetBoxModelForm):
datastore = DynamicModelChoiceField(
queryset=Datastore.objects.all(),
)
vm = DynamicModelChoiceField(
queryset=VirtualMachine.objects.all(),
)

class Meta:
model = VMDK
fields = (
'vm', 'datastore', 'name', 'size',
)


Expand Down
48 changes: 31 additions & 17 deletions netbox_storage/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 4.1.6 on 2023-02-06 11:00
# Generated by Django 4.1.6 on 2023-02-08 16:56

from django.db import migrations, models
import django.db.models.deletion
Expand All @@ -11,41 +11,41 @@ class Migration(migrations.Migration):
initial = True

dependencies = [
('dcim', '0167_module_status'),
('virtualization', '0034_standardize_description_comments'),
('extras', '0084_staging'),
('dcim', '0167_module_status'),
]

operations = [
migrations.CreateModel(
name='StorageLUN',
name='Datastore',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
('created', models.DateTimeField(auto_now_add=True, null=True)),
('last_updated', models.DateTimeField(auto_now=True, null=True)),
('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
('name', models.CharField(max_length=100)),
('size', models.PositiveIntegerField()),
('description', models.TextField(blank=True)),
],
options={
'ordering': ('name',),
},
),
migrations.CreateModel(
name='StorageLUNGroup',
name='VMDK',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
('created', models.DateTimeField(auto_now_add=True, null=True)),
('last_updated', models.DateTimeField(auto_now=True, null=True)),
('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
('name', models.CharField(max_length=100)),
('description', models.TextField(blank=True)),
('storage_lun', models.ManyToManyField(related_name='lun_groups', to='netbox_storage.storagelun')),
('size', models.PositiveIntegerField()),
('datastore', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='vmdks', to='netbox_storage.datastore')),
('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
('vm', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='vmdks', to='virtualization.virtualmachine')),
],
options={
'ordering': ('name',),
'ordering': ('datastore', 'name'),
},
),
migrations.CreateModel(
Expand All @@ -58,7 +58,7 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=100)),
('description', models.TextField(blank=True)),
('cluster', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='storage_sessions', to='virtualization.cluster')),
('storage_lun_groups', models.ManyToManyField(related_name='storage_sessions', to='netbox_storage.storagelungroup')),
('datastores', models.ManyToManyField(related_name='storage_sessions', to='netbox_storage.datastore')),
('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
],
options={
Expand All @@ -82,18 +82,32 @@ class Migration(migrations.Migration):
'ordering': ('name',),
},
),
migrations.CreateModel(
name='LUN',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
('created', models.DateTimeField(auto_now_add=True, null=True)),
('last_updated', models.DateTimeField(auto_now=True, null=True)),
('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
('name', models.CharField(max_length=100)),
('size', models.PositiveIntegerField()),
('description', models.TextField(blank=True)),
('storage_pool', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='luns', to='netbox_storage.storagepool')),
('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
],
options={
'ordering': ('name',),
'unique_together': {('storage_pool', 'name')},
},
),
migrations.AddField(
model_name='storagelun',
name='storage_pool',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='luns', to='netbox_storage.storagepool'),
model_name='datastore',
name='lun',
field=models.ManyToManyField(related_name='lun_groups', to='netbox_storage.lun'),
),
migrations.AddField(
model_name='storagelun',
model_name='datastore',
name='tags',
field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
),
migrations.AlterUniqueTogether(
name='storagelun',
unique_together={('storage_pool', 'name')},
),
]
Loading

0 comments on commit 609a176

Please sign in to comment.