bulk_import.py 5.0 KB

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