models.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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. comments = models.TextField(
  76. blank=True
  77. )
  78. custom_field_values = GenericRelation(
  79. to=CustomFieldValue,
  80. content_type_field='obj_type',
  81. object_id_field='obj_id'
  82. )
  83. class Meta:
  84. ordering = ['name']
  85. def __str__(self):
  86. return self.name
  87. def get_absolute_url(self):
  88. return reverse('virtualization:cluster', args=[self.pk])
  89. #
  90. # Virtual machines
  91. #
  92. @python_2_unicode_compatible
  93. class VirtualMachine(CreatedUpdatedModel, CustomFieldModel):
  94. """
  95. A virtual machine which runs inside a Cluster.
  96. """
  97. cluster = models.ForeignKey(
  98. to=Cluster,
  99. on_delete=models.PROTECT,
  100. related_name='virtual_machines'
  101. )
  102. tenant = models.ForeignKey(
  103. to='tenancy.Tenant',
  104. on_delete=models.PROTECT,
  105. related_name='virtual_machines',
  106. blank=True,
  107. null=True
  108. )
  109. platform = models.ForeignKey(
  110. to='dcim.Platform',
  111. on_delete=models.SET_NULL,
  112. related_name='virtual_machines',
  113. blank=True,
  114. null=True
  115. )
  116. name = models.CharField(
  117. max_length=64,
  118. unique=True
  119. )
  120. primary_ip4 = models.OneToOneField(
  121. to='ipam.IPAddress',
  122. on_delete=models.SET_NULL,
  123. related_name='+',
  124. blank=True,
  125. null=True,
  126. verbose_name='Primary IPv4'
  127. )
  128. primary_ip6 = models.OneToOneField(
  129. to='ipam.IPAddress',
  130. on_delete=models.SET_NULL,
  131. related_name='+',
  132. blank=True,
  133. null=True,
  134. verbose_name='Primary IPv6'
  135. )
  136. vcpus = models.PositiveSmallIntegerField(
  137. blank=True,
  138. null=True,
  139. verbose_name='vCPUs'
  140. )
  141. memory = models.PositiveIntegerField(
  142. blank=True,
  143. null=True,
  144. verbose_name='Memory (MB)'
  145. )
  146. disk = models.PositiveIntegerField(
  147. blank=True,
  148. null=True,
  149. verbose_name='Disk (GB)'
  150. )
  151. comments = models.TextField(
  152. blank=True
  153. )
  154. custom_field_values = GenericRelation(
  155. to=CustomFieldValue,
  156. content_type_field='obj_type',
  157. object_id_field='obj_id'
  158. )
  159. class Meta:
  160. ordering = ['name']
  161. def __str__(self):
  162. return self.name
  163. def get_absolute_url(self):
  164. return reverse('virtualization:virtualmachine', args=[self.pk])
  165. @python_2_unicode_compatible
  166. class VMInterface(models.Model):
  167. """
  168. A virtual interface which belongs to a VirtualMachine. Like the dcim.Interface model, IPAddresses can be assigned to
  169. VMInterfaces.
  170. """
  171. virtual_machine = models.ForeignKey(
  172. to=VirtualMachine,
  173. on_delete=models.CASCADE,
  174. related_name='interfaces'
  175. )
  176. name = models.CharField(
  177. max_length=30
  178. )
  179. enabled = models.BooleanField(
  180. default=True
  181. )
  182. mac_address = MACAddressField(
  183. blank=True,
  184. null=True,
  185. verbose_name='MAC Address'
  186. )
  187. mtu = models.PositiveSmallIntegerField(
  188. blank=True,
  189. null=True,
  190. verbose_name='MTU'
  191. )
  192. description = models.CharField(
  193. max_length=100,
  194. blank=True
  195. )
  196. ip_addresses = GenericRelation(
  197. to='ipam.IPAddress',
  198. content_type_field='interface_type',
  199. object_id_field='interface_id'
  200. )
  201. class Meta:
  202. ordering = ['virtual_machine', 'name']
  203. unique_together = ['virtual_machine', 'name']
  204. verbose_name = 'VM interface'
  205. def __str__(self):
  206. return self.name