From fef3a855657a7e5c2393dc469690d73bb249bd8f Mon Sep 17 00:00:00 2001 From: Parker Berberian Date: Tue, 29 Jan 2019 10:05:27 -0500 Subject: Allow Users to Delete objects and Cancel Bookings A user can now delete thier own resources, configs, and snapshots as well as cancelling bookings. Change-Id: Ic8e4751feeb0b8fa0d76816b8df2d16729ad2828 Signed-off-by: Parker Berberian --- .../migrations/0006_auto_20190124_1700.py | 76 ++++++++++++++++++++++ src/resource_inventory/models.py | 37 ++++++----- 2 files changed, 97 insertions(+), 16 deletions(-) create mode 100644 src/resource_inventory/migrations/0006_auto_20190124_1700.py (limited to 'src/resource_inventory') diff --git a/src/resource_inventory/migrations/0006_auto_20190124_1700.py b/src/resource_inventory/migrations/0006_auto_20190124_1700.py new file mode 100644 index 0000000..a5a972f --- /dev/null +++ b/src/resource_inventory/migrations/0006_auto_20190124_1700.py @@ -0,0 +1,76 @@ +# Generated by Django 2.1 on 2019-01-24 17:00 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import resource_inventory.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('resource_inventory', '0005_image_os'), + ] + + operations = [ + migrations.AlterField( + model_name='cpuprofile', + name='host', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cpuprofile', to='resource_inventory.HostProfile'), + ), + migrations.AlterField( + model_name='diskprofile', + name='host', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='storageprofile', to='resource_inventory.HostProfile'), + ), + migrations.AlterField( + model_name='generichost', + name='profile', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='resource_inventory.HostProfile'), + ), + migrations.AlterField( + model_name='generichost', + name='resource', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='generic_host', to='resource_inventory.GenericResource'), + ), + migrations.AlterField( + model_name='genericinterface', + name='host', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='generic_interfaces', to='resource_inventory.GenericHost'), + ), + migrations.AlterField( + model_name='genericresource', + name='bundle', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='generic_resources', to='resource_inventory.GenericResourceBundle'), + ), + migrations.AlterField( + model_name='genericresourcebundle', + name='lab', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='account.Lab'), + ), + migrations.AlterField( + model_name='genericresourcebundle', + name='owner', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='hostconfiguration', + name='opnfvRole', + field=models.ForeignKey(on_delete=models.SET(resource_inventory.models.get_sentinal_opnfv_role), to='resource_inventory.OPNFVRole'), + ), + migrations.AlterField( + model_name='interfaceprofile', + name='host', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interfaceprofile', to='resource_inventory.HostProfile'), + ), + migrations.AlterField( + model_name='ramprofile', + name='host', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ramprofile', to='resource_inventory.HostProfile'), + ), + migrations.AlterField( + model_name='resourcebundle', + name='template', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='resource_inventory.GenericResourceBundle'), + ), + ] diff --git a/src/resource_inventory/models.py b/src/resource_inventory/models.py index 5b07077..e1f2aa3 100644 --- a/src/resource_inventory/models.py +++ b/src/resource_inventory/models.py @@ -39,7 +39,7 @@ class InterfaceProfile(models.Model): id = models.AutoField(primary_key=True) speed = models.IntegerField() name = models.CharField(max_length=100) - host = models.ForeignKey(HostProfile, on_delete=models.DO_NOTHING, related_name='interfaceprofile') + host = models.ForeignKey(HostProfile, on_delete=models.CASCADE, related_name='interfaceprofile') nic_type = models.CharField( max_length=50, choices=[ @@ -61,7 +61,7 @@ class DiskProfile(models.Model): ("HDD", "HDD") ]) name = models.CharField(max_length=50) - host = models.ForeignKey(HostProfile, on_delete=models.DO_NOTHING, related_name='storageprofile') + host = models.ForeignKey(HostProfile, on_delete=models.CASCADE, related_name='storageprofile') rotation = models.IntegerField(default=0) interface = models.CharField( max_length=50, @@ -88,7 +88,7 @@ class CpuProfile(models.Model): ("aarch64", "aarch64") ]) cpus = models.IntegerField() - host = models.ForeignKey(HostProfile, on_delete=models.DO_NOTHING, related_name='cpuprofile') + host = models.ForeignKey(HostProfile, on_delete=models.CASCADE, related_name='cpuprofile') cflags = models.TextField(null=True) def __str__(self): @@ -99,7 +99,7 @@ class RamProfile(models.Model): id = models.AutoField(primary_key=True) amount = models.IntegerField() channels = models.IntegerField() - host = models.ForeignKey(HostProfile, on_delete=models.DO_NOTHING, related_name='ramprofile') + host = models.ForeignKey(HostProfile, on_delete=models.CASCADE, related_name='ramprofile') def __str__(self): return str(self.amount) + "G for " + str(self.host) @@ -130,8 +130,8 @@ class GenericResourceBundle(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=300, unique=True) xml = models.TextField() - owner = models.ForeignKey(User, null=True, on_delete=models.DO_NOTHING) - lab = models.ForeignKey(Lab, null=True, on_delete=models.DO_NOTHING) + owner = models.ForeignKey(User, null=True, on_delete=models.SET_NULL) + lab = models.ForeignKey(Lab, null=True, on_delete=models.SET_NULL) description = models.CharField(max_length=1000, default="") def getHosts(self): @@ -146,7 +146,7 @@ class GenericResourceBundle(models.Model): class GenericResource(models.Model): - bundle = models.ForeignKey(GenericResourceBundle, related_name='generic_resources', on_delete=models.DO_NOTHING) + bundle = models.ForeignKey(GenericResourceBundle, related_name='generic_resources', on_delete=models.CASCADE) hostname_validchars = RegexValidator(regex=r'(?=^.{1,253}$)(?=(^([A-Za-z0-9\-\_]{1,62}\.)*[A-Za-z0-9\-\_]{1,63}$))', message="Enter a valid hostname. Full domain name may be 1-253 characters, each hostname 1-63 characters (including suffixed dot), and valid characters for hostnames are A-Z, a-z, 0-9, hyphen (-), and underscore (_)") name = models.CharField(max_length=200, validators=[hostname_validchars]) @@ -167,8 +167,8 @@ class GenericResource(models.Model): # Host template class GenericHost(models.Model): id = models.AutoField(primary_key=True) - profile = models.ForeignKey(HostProfile, on_delete=models.DO_NOTHING) - resource = models.OneToOneField(GenericResource, related_name='generic_host', on_delete=models.DO_NOTHING) + profile = models.ForeignKey(HostProfile, on_delete=models.CASCADE) + resource = models.OneToOneField(GenericResource, related_name='generic_host', on_delete=models.CASCADE) def __str__(self): return self.resource.name @@ -177,9 +177,11 @@ class GenericHost(models.Model): # Physical, actual resources class ResourceBundle(models.Model): id = models.AutoField(primary_key=True) - template = models.ForeignKey(GenericResourceBundle, on_delete=models.DO_NOTHING) + template = models.ForeignKey(GenericResourceBundle, on_delete=models.SET_NULL, null=True) def __str__(self): + if self.template is None: + return "Resource bundle " + str(self.id) + " with no template" return "instance of " + str(self.template) @@ -189,8 +191,8 @@ class ResourceBundle(models.Model): class GenericInterface(models.Model): id = models.AutoField(primary_key=True) vlans = models.ManyToManyField(Vlan) - profile = models.ForeignKey(InterfaceProfile, on_delete=models.DO_NOTHING) - host = models.ForeignKey(GenericHost, on_delete=models.DO_NOTHING, related_name='generic_interfaces') + profile = models.ForeignKey(InterfaceProfile, on_delete=models.CASCADE) + host = models.ForeignKey(GenericHost, on_delete=models.CASCADE, related_name='generic_interfaces') def __str__(self): return "type " + str(self.profile) + " on host " + str(self.host) @@ -224,7 +226,7 @@ class Opsys(models.Model): class ConfigBundle(models.Model): id = models.AutoField(primary_key=True) - owner = models.ForeignKey(User, on_delete=models.CASCADE) # consider setting to root user? + owner = models.ForeignKey(User, on_delete=models.CASCADE) name = models.CharField(max_length=200, unique=True) description = models.CharField(max_length=1000, default="") bundle = models.ForeignKey(GenericResourceBundle, null=True, on_delete=models.CASCADE) @@ -262,15 +264,18 @@ class Image(models.Model): name = models.CharField(max_length=200) owner = models.ForeignKey(User, null=True, on_delete=models.SET_NULL) public = models.BooleanField(default=True) - # may need to change host_type.on_delete to models.SET() once images are transferrable between compatible host types host_type = models.ForeignKey(HostProfile, on_delete=models.CASCADE) description = models.TextField() - os = models.ForeignKey(Opsys, null=True, on_delete=models.CASCADE) + os = models.ForeignKey(Opsys, null=True, on_delete=models.CASCADE) #sentinal? def __str__(self): return self.name +def get_sentinal_opnfv_role(): + return OPNFVRole.objects.get_or_create(name="deleted", description="Role was deleted.") + + class HostConfiguration(models.Model): """ model to represent a complete configuration for a single @@ -280,7 +285,7 @@ class HostConfiguration(models.Model): host = models.ForeignKey(GenericHost, related_name="configuration", on_delete=models.CASCADE) image = models.ForeignKey(Image, on_delete=models.PROTECT) bundle = models.ForeignKey(ConfigBundle, related_name="hostConfigurations", null=True, on_delete=models.CASCADE) - opnfvRole = models.ForeignKey(OPNFVRole, on_delete=models.PROTECT) + opnfvRole = models.ForeignKey(OPNFVRole, on_delete=models.SET(get_sentinal_opnfv_role)) def __str__(self): return "config with " + str(self.host) + " and image " + str(self.image) -- cgit 1.2.3-korg