models.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. from __future__ import unicode_literals
  2. from django.contrib.contenttypes.fields import GenericRelation
  3. from django.db import models
  4. from django.urls import reverse
  5. from django.utils.encoding import python_2_unicode_compatible
  6. from dcim.fields import MACAddressField
  7. from extras.models import CustomFieldModel, CustomFieldValue
  8. from utilities.models import CreatedUpdatedModel
  9. #
  10. # Cluster types
  11. #
  12. @python_2_unicode_compatible
  13. class ClusterType(models.Model):
  14. """
  15. A type of Cluster.
  16. """
  17. name = models.CharField(
  18. max_length=50,
  19. unique=True
  20. )
  21. slug = models.SlugField(
  22. unique=True
  23. )
  24. class Meta:
  25. ordering = ['name']
  26. def __str__(self):
  27. return self.name
  28. def get_absolute_url(self):
  29. return "{}?type={}".format(reverse('virtualization:cluster_list'), self.slug)
  30. #
  31. # Cluster groups
  32. #
  33. @python_2_unicode_compatible
  34. class ClusterGroup(models.Model):
  35. """
  36. An organizational group of Clusters.
  37. """
  38. name = models.CharField(
  39. max_length=50,
  40. unique=True
  41. )
  42. slug = models.SlugField(
  43. unique=True
  44. )
  45. class Meta:
  46. ordering = ['name']
  47. def __str__(self):
  48. return self.name
  49. def get_absolute_url(self):
  50. return "{}?group={}".format(reverse('virtualization:cluster_list'), self.slug)
  51. #
  52. # Clusters
  53. #
  54. @python_2_unicode_compatible
  55. class Cluster(CreatedUpdatedModel, CustomFieldModel):
  56. """
  57. A cluster of VirtualMachines. Each Cluster may optionally be associated with one or more Devices.
  58. """
  59. name = models.CharField(
  60. max_length=100,
  61. unique=True
  62. )
  63. type = models.ForeignKey(
  64. to=ClusterType,
  65. on_delete=models.PROTECT,
  66. related_name='clusters'
  67. )
  68. group = models.ForeignKey(
  69. to=ClusterGroup,
  70. on_delete=models.PROTECT,
  71. related_name='clusters',
  72. blank=True,
  73. null=True
  74. )
  75. devices = models.ManyToManyField(
  76. to='dcim.Device'
  77. )
  78. comments = models.TextField(
  79. blank=True
  80. )
  81. custom_field_values = GenericRelation(
  82. to=CustomFieldValue,
  83. content_type_field='obj_type',
  84. object_id_field='obj_id'
  85. )
  86. class Meta:
  87. ordering = ['name']
  88. def __str__(self):
  89. return self.name
  90. def get_absolute_url(self):
  91. return reverse('virtualization:cluster', args=[self.pk])
  92. #
  93. # Virtual machines
  94. #
  95. @python_2_unicode_compatible
  96. class VirtualMachine(CreatedUpdatedModel, CustomFieldModel):
  97. """
  98. A virtual machine which runs inside a Cluster.
  99. """
  100. cluster = models.ForeignKey(
  101. to=Cluster,
  102. on_delete=models.PROTECT,
  103. related_name='virtual_machines'
  104. )
  105. tenant = models.ForeignKey(
  106. to='tenancy.Tenant',
  107. on_delete=models.PROTECT,
  108. related_name='virtual_machines',
  109. blank=True,
  110. null=True
  111. )
  112. platform = models.ForeignKey(
  113. to='dcim.Platform',
  114. on_delete=models.SET_NULL,
  115. related_name='virtual_machines',
  116. blank=True,
  117. null=True
  118. )
  119. name = models.CharField(
  120. max_length=64,
  121. unique=True
  122. )
  123. primary_ip4 = models.OneToOneField(
  124. to='ipam.IPAddress',
  125. on_delete=models.SET_NULL,
  126. related_name='+',
  127. blank=True,
  128. null=True,
  129. verbose_name='Primary IPv4'
  130. )
  131. primary_ip6 = models.OneToOneField(
  132. to='ipam.IPAddress',
  133. on_delete=models.SET_NULL,
  134. related_name='+',
  135. blank=True,
  136. null=True,
  137. verbose_name='Primary IPv6'
  138. )
  139. comments = models.TextField(
  140. blank=True
  141. )
  142. custom_field_values = GenericRelation(
  143. to=CustomFieldValue,
  144. content_type_field='obj_type',
  145. object_id_field='obj_id'
  146. )
  147. class Meta:
  148. ordering = ['name']
  149. def __str__(self):
  150. return self.name
  151. def get_absolute_url(self):
  152. return reverse('virtualization:virtualmachine', args=[self.pk])
  153. @python_2_unicode_compatible
  154. class VMInterface(models.Model):
  155. """
  156. A virtual interface which belongs to a VirtualMachine. Like the dcim.Interface model, IPAddresses can be assigned to
  157. VMInterfaces.
  158. """
  159. virtual_machine = models.ForeignKey(
  160. to=VirtualMachine,
  161. on_delete=models.CASCADE,
  162. related_name='interfaces'
  163. )
  164. name = models.CharField(
  165. max_length=30
  166. )
  167. enabled = models.BooleanField(
  168. default=True
  169. )
  170. mac_address = MACAddressField(
  171. blank=True,
  172. null=True,
  173. verbose_name='MAC Address'
  174. )
  175. mtu = models.PositiveSmallIntegerField(
  176. blank=True,
  177. null=True,
  178. verbose_name='MTU'
  179. )
  180. description = models.CharField(
  181. max_length=100,
  182. blank=True
  183. )
  184. class Meta:
  185. ordering = ['virtual_machine', 'name']
  186. unique_together = ['virtual_machine', 'name']
  187. def __str__(self):
  188. return self.name