labs = models.ManyToManyField(Lab, related_name="hostprofiles")
def validate(self):
- validname = re.compile("^[A-Za-z0-9\-\_\.\/\, ]+$")
+ validname = re.compile(r"^[A-Za-z0-9\-\_\.\/\, ]+$")
if not validname.match(self.name):
return "Invalid host profile name given. Name must only use A-Z, a-z, 0-9, hyphens, underscores, dots, commas, or spaces."
else:
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')
- nic_type = models.CharField(max_length=50, choices=[
- ("onboard", "onboard"),
- ("pcie", "pcie")
- ], default="onboard")
+ host = models.ForeignKey(HostProfile, on_delete=models.CASCADE, related_name='interfaceprofile')
+ nic_type = models.CharField(
+ max_length=50,
+ choices=[
+ ("onboard", "onboard"),
+ ("pcie", "pcie")
+ ],
+ default="onboard"
+ )
def __str__(self):
return self.name + " for " + str(self.host)
("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, choices=[
+ interface = models.CharField(
+ max_length=50,
+ choices=[
("sata", "sata"),
("sas", "sas"),
("ssd", "ssd"),
("nvme", "nvme"),
("scsi", "scsi"),
("iscsi", "iscsi"),
- ], default="sata")
+ ],
+ default="sata"
+ )
def __str__(self):
return self.name + " for " + str(self.host)
("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):
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)
-##Networking -- located here due to import order requirements
+# Networking -- located here due to import order requirements
class Network(models.Model):
id = models.AutoField(primary_key=True)
vlan_id = models.IntegerField()
def __str__(self):
return self.name
+
class Vlan(models.Model):
id = models.AutoField(primary_key=True)
vlan_id = models.IntegerField()
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):
class GenericResource(models.Model):
- bundle = models.ForeignKey(GenericResourceBundle, related_name='generic_resources', on_delete=models.DO_NOTHING)
- hostname_validchars = RegexValidator(regex='(?=^.{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 (_)")
+ 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])
def getHost(self):
return self.name
def validate(self):
- validname = re.compile('(?=^.{1,253}$)(?=(^([A-Za-z0-9\-\_]{1,62}\.)*[A-Za-z0-9\-\_]{1,63}$))')
+ validname = re.compile(r'(?=^.{1,253}$)(?=(^([A-Za-z0-9\-\_]{1,62}\.)*[A-Za-z0-9\-\_]{1,63}$))')
if not validname.match(self.name):
return "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 (_)"
else:
# 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
# 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)
+ def get_host(self, role="Jumphost"):
+ return Host.objects.filter(bundle=self, config__opnfvRole__name=role).first()
+
# Networking
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)
def __str__(self):
return self.name
+
class Installer(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
def __str__(self):
return self.name
+
class Opsys(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100)
def __str__(self):
return self.name
+
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)
def __str__(self):
return self.name
+
class OPNFVConfig(models.Model):
id = models.AutoField(primary_key=True)
installer = models.ForeignKey(Installer, on_delete=models.CASCADE)
def __str__(self):
return "OPNFV job with " + str(self.installer) + " and " + str(self.scenario)
+
class OPNFVRole(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
def __str__(self):
return self.name
+
class Image(models.Model):
"""
model for representing OS images / snapshots of hosts
name = models.CharField(max_length=200)
owner = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
public = models.BooleanField(default=True)
- host_type = models.ForeignKey(HostProfile, on_delete=models.CASCADE) #may need to change 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)
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
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) #need protocol for phasing out a role if we are going to allow that to happen
+ 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)
+class RemoteInfo(models.Model):
+ address = models.CharField(max_length=15)
+ mac_address = models.CharField(max_length=17)
+ password = models.CharField(max_length=100)
+ user = models.CharField(max_length=100)
+ management_type = models.CharField(max_length=50, default="ipmi")
+ versions = models.CharField(max_length=100) # json serialized list of floats
+
+
+def get_default_remote_info():
+ return RemoteInfo.objects.get_or_create(
+ address="default",
+ mac_address="default",
+ password="default",
+ user="default",
+ management_type="default",
+ versions="[default]"
+ )[0].pk
+
+
# Concrete host, actual machine in a lab
class Host(models.Model):
id = models.AutoField(primary_key=True)
working = models.BooleanField(default=True)
vendor = models.CharField(max_length=100, default="unknown")
model = models.CharField(max_length=150, default="unknown")
+ remote_management = models.ForeignKey(RemoteInfo, default=get_default_remote_info, on_delete=models.SET(get_default_remote_info))
def __str__(self):
return self.name