bulk_import.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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', 'comments')
  57. class VirtualMachineCSVForm(NetBoxModelCSVForm):
  58. status = CSVChoiceField(
  59. choices=VirtualMachineStatusChoices,
  60. help_text='Operational status'
  61. )
  62. cluster = CSVModelChoiceField(
  63. queryset=Cluster.objects.all(),
  64. to_field_name='name',
  65. help_text='Assigned cluster'
  66. )
  67. device = CSVModelChoiceField(
  68. queryset=Device.objects.all(),
  69. to_field_name='name',
  70. required=False,
  71. help_text='Assigned device within cluster'
  72. )
  73. role = CSVModelChoiceField(
  74. queryset=DeviceRole.objects.filter(
  75. vm_role=True
  76. ),
  77. required=False,
  78. to_field_name='name',
  79. help_text='Functional role'
  80. )
  81. tenant = CSVModelChoiceField(
  82. queryset=Tenant.objects.all(),
  83. required=False,
  84. to_field_name='name',
  85. help_text='Assigned tenant'
  86. )
  87. platform = CSVModelChoiceField(
  88. queryset=Platform.objects.all(),
  89. required=False,
  90. to_field_name='name',
  91. help_text='Assigned platform'
  92. )
  93. class Meta:
  94. model = VirtualMachine
  95. fields = (
  96. 'name', 'status', 'role', 'cluster', 'device', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments',
  97. )
  98. class VMInterfaceCSVForm(NetBoxModelCSVForm):
  99. virtual_machine = CSVModelChoiceField(
  100. queryset=VirtualMachine.objects.all(),
  101. to_field_name='name'
  102. )
  103. parent = CSVModelChoiceField(
  104. queryset=VMInterface.objects.all(),
  105. required=False,
  106. to_field_name='name',
  107. help_text='Parent interface'
  108. )
  109. bridge = CSVModelChoiceField(
  110. queryset=VMInterface.objects.all(),
  111. required=False,
  112. to_field_name='name',
  113. help_text='Bridged interface'
  114. )
  115. mode = CSVChoiceField(
  116. choices=InterfaceModeChoices,
  117. required=False,
  118. help_text='IEEE 802.1Q operational mode (for L2 interfaces)'
  119. )
  120. vrf = CSVModelChoiceField(
  121. queryset=VRF.objects.all(),
  122. required=False,
  123. to_field_name='rd',
  124. help_text='Assigned VRF'
  125. )
  126. class Meta:
  127. model = VMInterface
  128. fields = (
  129. 'virtual_machine', 'name', 'parent', 'bridge', 'enabled', 'mac_address', 'mtu', 'description', 'mode',
  130. 'vrf',
  131. )
  132. def __init__(self, data=None, *args, **kwargs):
  133. super().__init__(data, *args, **kwargs)
  134. if data:
  135. # Limit interface choices for parent & bridge interfaces to the assigned VM
  136. if virtual_machine := data.get('virtual_machine'):
  137. params = {
  138. f"virtual_machine__{self.fields['virtual_machine'].to_field_name}": virtual_machine
  139. }
  140. self.fields['parent'].queryset = self.fields['parent'].queryset.filter(**params)
  141. self.fields['bridge'].queryset = self.fields['bridge'].queryset.filter(**params)
  142. def clean_enabled(self):
  143. # Make sure enabled is True when it's not included in the uploaded data
  144. if 'enabled' not in self.data:
  145. return True
  146. else:
  147. return self.cleaned_data['enabled']