bulk_import.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. from django.utils.translation import gettext as _
  2. from dcim.choices import InterfaceModeChoices
  3. from dcim.models import Device, DeviceRole, Platform, Site
  4. from ipam.models import VRF
  5. from netbox.forms import NetBoxModelImportForm
  6. from tenancy.models import Tenant
  7. from utilities.forms.fields import CSVChoiceField, CSVModelChoiceField, SlugField
  8. from virtualization.choices import *
  9. from virtualization.models import *
  10. __all__ = (
  11. 'ClusterImportForm',
  12. 'ClusterGroupImportForm',
  13. 'ClusterTypeImportForm',
  14. 'VirtualMachineImportForm',
  15. 'VMInterfaceImportForm',
  16. )
  17. class ClusterTypeImportForm(NetBoxModelImportForm):
  18. slug = SlugField()
  19. class Meta:
  20. model = ClusterType
  21. fields = ('name', 'slug', 'description', 'tags')
  22. class ClusterGroupImportForm(NetBoxModelImportForm):
  23. slug = SlugField()
  24. class Meta:
  25. model = ClusterGroup
  26. fields = ('name', 'slug', 'description', 'tags')
  27. class ClusterImportForm(NetBoxModelImportForm):
  28. type = CSVModelChoiceField(
  29. queryset=ClusterType.objects.all(),
  30. to_field_name='name',
  31. help_text=_('Type of cluster')
  32. )
  33. group = CSVModelChoiceField(
  34. queryset=ClusterGroup.objects.all(),
  35. to_field_name='name',
  36. required=False,
  37. help_text=_('Assigned cluster group')
  38. )
  39. status = CSVChoiceField(
  40. choices=ClusterStatusChoices,
  41. help_text=_('Operational status')
  42. )
  43. site = CSVModelChoiceField(
  44. queryset=Site.objects.all(),
  45. to_field_name='name',
  46. required=False,
  47. help_text=_('Assigned site')
  48. )
  49. tenant = CSVModelChoiceField(
  50. queryset=Tenant.objects.all(),
  51. to_field_name='name',
  52. required=False,
  53. help_text=_('Assigned tenant')
  54. )
  55. class Meta:
  56. model = Cluster
  57. fields = ('name', 'type', 'group', 'status', 'site', 'tenant', 'description', 'comments', 'tags')
  58. class VirtualMachineImportForm(NetBoxModelImportForm):
  59. status = CSVChoiceField(
  60. choices=VirtualMachineStatusChoices,
  61. help_text=_('Operational status')
  62. )
  63. site = CSVModelChoiceField(
  64. queryset=Site.objects.all(),
  65. to_field_name='name',
  66. required=False,
  67. help_text=_('Assigned site')
  68. )
  69. cluster = CSVModelChoiceField(
  70. queryset=Cluster.objects.all(),
  71. to_field_name='name',
  72. required=False,
  73. help_text=_('Assigned cluster')
  74. )
  75. device = CSVModelChoiceField(
  76. queryset=Device.objects.all(),
  77. to_field_name='name',
  78. required=False,
  79. help_text=_('Assigned device within cluster')
  80. )
  81. role = CSVModelChoiceField(
  82. queryset=DeviceRole.objects.filter(
  83. vm_role=True
  84. ),
  85. required=False,
  86. to_field_name='name',
  87. help_text=_('Functional role')
  88. )
  89. tenant = CSVModelChoiceField(
  90. queryset=Tenant.objects.all(),
  91. required=False,
  92. to_field_name='name',
  93. help_text=_('Assigned tenant')
  94. )
  95. platform = CSVModelChoiceField(
  96. queryset=Platform.objects.all(),
  97. required=False,
  98. to_field_name='name',
  99. help_text=_('Assigned platform')
  100. )
  101. class Meta:
  102. model = VirtualMachine
  103. fields = (
  104. 'name', 'status', 'role', 'site', 'cluster', 'device', 'tenant', 'platform', 'vcpus', 'memory', 'disk',
  105. 'description', 'comments', 'tags',
  106. )
  107. class VMInterfaceImportForm(NetBoxModelImportForm):
  108. virtual_machine = CSVModelChoiceField(
  109. queryset=VirtualMachine.objects.all(),
  110. to_field_name='name'
  111. )
  112. parent = CSVModelChoiceField(
  113. queryset=VMInterface.objects.all(),
  114. required=False,
  115. to_field_name='name',
  116. help_text=_('Parent interface')
  117. )
  118. bridge = CSVModelChoiceField(
  119. queryset=VMInterface.objects.all(),
  120. required=False,
  121. to_field_name='name',
  122. help_text=_('Bridged interface')
  123. )
  124. mode = CSVChoiceField(
  125. choices=InterfaceModeChoices,
  126. required=False,
  127. help_text=_('IEEE 802.1Q operational mode (for L2 interfaces)')
  128. )
  129. vrf = CSVModelChoiceField(
  130. queryset=VRF.objects.all(),
  131. required=False,
  132. to_field_name='rd',
  133. help_text=_('Assigned VRF')
  134. )
  135. class Meta:
  136. model = VMInterface
  137. fields = (
  138. 'virtual_machine', 'name', 'parent', 'bridge', 'enabled', 'mac_address', 'mtu', 'description', 'mode',
  139. 'vrf', 'tags'
  140. )
  141. def __init__(self, data=None, *args, **kwargs):
  142. super().__init__(data, *args, **kwargs)
  143. if data:
  144. # Limit interface choices for parent & bridge interfaces to the assigned VM
  145. if virtual_machine := data.get('virtual_machine'):
  146. params = {
  147. f"virtual_machine__{self.fields['virtual_machine'].to_field_name}": virtual_machine
  148. }
  149. self.fields['parent'].queryset = self.fields['parent'].queryset.filter(**params)
  150. self.fields['bridge'].queryset = self.fields['bridge'].queryset.filter(**params)
  151. def clean_enabled(self):
  152. # Make sure enabled is True when it's not included in the uploaded data
  153. if 'enabled' not in self.data:
  154. return True
  155. else:
  156. return self.cleaned_data['enabled']