bulk_import.py 6.5 KB

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