bulk_edit.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. from django import forms
  2. from django.contrib.contenttypes.models import ContentType
  3. from django.core.exceptions import ObjectDoesNotExist
  4. from django.utils.translation import gettext_lazy as _
  5. from circuits.choices import (
  6. CircuitCommitRateChoices, CircuitPriorityChoices, CircuitStatusChoices, VirtualCircuitTerminationRoleChoices,
  7. )
  8. from circuits.constants import CIRCUIT_TERMINATION_TERMINATION_TYPES
  9. from circuits.models import *
  10. from dcim.models import Site
  11. from ipam.models import ASN
  12. from netbox.choices import DistanceUnitChoices
  13. from netbox.forms import NetBoxModelBulkEditForm
  14. from tenancy.models import Tenant
  15. from utilities.forms import add_blank_choice, get_field_value
  16. from utilities.forms.fields import (
  17. ColorField, CommentField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
  18. )
  19. from utilities.forms.rendering import FieldSet
  20. from utilities.forms.widgets import BulkEditNullBooleanSelect, DatePicker, HTMXSelect, NumberWithOptions
  21. from utilities.templatetags.builtins.filters import bettertitle
  22. __all__ = (
  23. 'CircuitBulkEditForm',
  24. 'CircuitGroupAssignmentBulkEditForm',
  25. 'CircuitGroupBulkEditForm',
  26. 'CircuitTerminationBulkEditForm',
  27. 'CircuitTypeBulkEditForm',
  28. 'ProviderBulkEditForm',
  29. 'ProviderAccountBulkEditForm',
  30. 'ProviderNetworkBulkEditForm',
  31. 'VirtualCircuitBulkEditForm',
  32. 'VirtualCircuitTerminationBulkEditForm',
  33. 'VirtualCircuitTypeBulkEditForm',
  34. )
  35. class ProviderBulkEditForm(NetBoxModelBulkEditForm):
  36. asns = DynamicModelMultipleChoiceField(
  37. queryset=ASN.objects.all(),
  38. label=_('ASNs'),
  39. required=False
  40. )
  41. description = forms.CharField(
  42. label=_('Description'),
  43. max_length=200,
  44. required=False
  45. )
  46. comments = CommentField()
  47. model = Provider
  48. fieldsets = (
  49. FieldSet('asns', 'description'),
  50. )
  51. nullable_fields = (
  52. 'asns', 'description', 'comments',
  53. )
  54. class ProviderAccountBulkEditForm(NetBoxModelBulkEditForm):
  55. provider = DynamicModelChoiceField(
  56. label=_('Provider'),
  57. queryset=Provider.objects.all(),
  58. required=False
  59. )
  60. description = forms.CharField(
  61. label=_('Description'),
  62. max_length=200,
  63. required=False
  64. )
  65. comments = CommentField()
  66. model = ProviderAccount
  67. fieldsets = (
  68. FieldSet('provider', 'description'),
  69. )
  70. nullable_fields = (
  71. 'description', 'comments',
  72. )
  73. class ProviderNetworkBulkEditForm(NetBoxModelBulkEditForm):
  74. provider = DynamicModelChoiceField(
  75. label=_('Provider'),
  76. queryset=Provider.objects.all(),
  77. required=False
  78. )
  79. service_id = forms.CharField(
  80. max_length=100,
  81. required=False,
  82. label=_('Service ID')
  83. )
  84. description = forms.CharField(
  85. label=_('Description'),
  86. max_length=200,
  87. required=False
  88. )
  89. comments = CommentField()
  90. model = ProviderNetwork
  91. fieldsets = (
  92. FieldSet('provider', 'service_id', 'description'),
  93. )
  94. nullable_fields = (
  95. 'service_id', 'description', 'comments',
  96. )
  97. class CircuitTypeBulkEditForm(NetBoxModelBulkEditForm):
  98. color = ColorField(
  99. label=_('Color'),
  100. required=False
  101. )
  102. description = forms.CharField(
  103. label=_('Description'),
  104. max_length=200,
  105. required=False
  106. )
  107. model = CircuitType
  108. fieldsets = (
  109. FieldSet('color', 'description'),
  110. )
  111. nullable_fields = ('color', 'description')
  112. class CircuitBulkEditForm(NetBoxModelBulkEditForm):
  113. type = DynamicModelChoiceField(
  114. label=_('Type'),
  115. queryset=CircuitType.objects.all(),
  116. required=False
  117. )
  118. provider = DynamicModelChoiceField(
  119. label=_('Provider'),
  120. queryset=Provider.objects.all(),
  121. required=False
  122. )
  123. provider_account = DynamicModelChoiceField(
  124. label=_('Provider account'),
  125. queryset=ProviderAccount.objects.all(),
  126. required=False,
  127. query_params={
  128. 'provider': '$provider'
  129. }
  130. )
  131. status = forms.ChoiceField(
  132. label=_('Status'),
  133. choices=add_blank_choice(CircuitStatusChoices),
  134. required=False,
  135. initial=''
  136. )
  137. tenant = DynamicModelChoiceField(
  138. label=_('Tenant'),
  139. queryset=Tenant.objects.all(),
  140. required=False
  141. )
  142. install_date = forms.DateField(
  143. label=_('Install date'),
  144. required=False,
  145. widget=DatePicker()
  146. )
  147. termination_date = forms.DateField(
  148. label=_('Termination date'),
  149. required=False,
  150. widget=DatePicker()
  151. )
  152. commit_rate = forms.IntegerField(
  153. required=False,
  154. label=_('Commit rate (Kbps)'),
  155. widget=NumberWithOptions(
  156. options=CircuitCommitRateChoices
  157. )
  158. )
  159. distance = forms.DecimalField(
  160. label=_('Distance'),
  161. min_value=0,
  162. required=False
  163. )
  164. distance_unit = forms.ChoiceField(
  165. label=_('Distance unit'),
  166. choices=add_blank_choice(DistanceUnitChoices),
  167. required=False,
  168. initial=''
  169. )
  170. description = forms.CharField(
  171. label=_('Description'),
  172. max_length=100,
  173. required=False
  174. )
  175. comments = CommentField()
  176. model = Circuit
  177. fieldsets = (
  178. FieldSet('provider', 'type', 'status', 'description', name=_('Circuit')),
  179. FieldSet('provider_account', 'install_date', 'termination_date', 'commit_rate', name=_('Service Parameters')),
  180. FieldSet('distance', 'distance_unit', name=_('Attributes')),
  181. FieldSet('tenant', name=_('Tenancy')),
  182. )
  183. nullable_fields = (
  184. 'tenant', 'commit_rate', 'description', 'comments',
  185. )
  186. class CircuitTerminationBulkEditForm(NetBoxModelBulkEditForm):
  187. description = forms.CharField(
  188. label=_('Description'),
  189. max_length=200,
  190. required=False
  191. )
  192. termination_type = ContentTypeChoiceField(
  193. queryset=ContentType.objects.filter(model__in=CIRCUIT_TERMINATION_TERMINATION_TYPES),
  194. widget=HTMXSelect(method='post', attrs={'hx-select': '#form_fields'}),
  195. required=False,
  196. label=_('Termination type')
  197. )
  198. termination = DynamicModelChoiceField(
  199. label=_('Termination'),
  200. queryset=Site.objects.none(), # Initial queryset
  201. required=False,
  202. disabled=True,
  203. selector=True
  204. )
  205. port_speed = forms.IntegerField(
  206. required=False,
  207. label=_('Port speed (Kbps)'),
  208. )
  209. upstream_speed = forms.IntegerField(
  210. required=False,
  211. label=_('Upstream speed (Kbps)'),
  212. )
  213. mark_connected = forms.NullBooleanField(
  214. label=_('Mark connected'),
  215. required=False,
  216. widget=BulkEditNullBooleanSelect
  217. )
  218. model = CircuitTermination
  219. fieldsets = (
  220. FieldSet(
  221. 'description',
  222. 'termination_type', 'termination',
  223. 'mark_connected', name=_('Circuit Termination')
  224. ),
  225. FieldSet('port_speed', 'upstream_speed', name=_('Termination Details')),
  226. )
  227. nullable_fields = ('description', 'termination')
  228. def __init__(self, *args, **kwargs):
  229. super().__init__(*args, **kwargs)
  230. if termination_type_id := get_field_value(self, 'termination_type'):
  231. try:
  232. termination_type = ContentType.objects.get(pk=termination_type_id)
  233. model = termination_type.model_class()
  234. self.fields['termination'].queryset = model.objects.all()
  235. self.fields['termination'].widget.attrs['selector'] = model._meta.label_lower
  236. self.fields['termination'].disabled = False
  237. self.fields['termination'].label = _(bettertitle(model._meta.verbose_name))
  238. except ObjectDoesNotExist:
  239. pass
  240. class CircuitGroupBulkEditForm(NetBoxModelBulkEditForm):
  241. description = forms.CharField(
  242. label=_('Description'),
  243. max_length=200,
  244. required=False
  245. )
  246. tenant = DynamicModelChoiceField(
  247. label=_('Tenant'),
  248. queryset=Tenant.objects.all(),
  249. required=False
  250. )
  251. model = CircuitGroup
  252. nullable_fields = (
  253. 'description', 'tenant',
  254. )
  255. class CircuitGroupAssignmentBulkEditForm(NetBoxModelBulkEditForm):
  256. member = DynamicModelChoiceField(
  257. label=_('Circuit'),
  258. queryset=Circuit.objects.all(),
  259. required=False
  260. )
  261. priority = forms.ChoiceField(
  262. label=_('Priority'),
  263. choices=add_blank_choice(CircuitPriorityChoices),
  264. required=False
  265. )
  266. model = CircuitGroupAssignment
  267. fieldsets = (
  268. FieldSet('member', 'priority'),
  269. )
  270. nullable_fields = ('priority',)
  271. class VirtualCircuitTypeBulkEditForm(NetBoxModelBulkEditForm):
  272. color = ColorField(
  273. label=_('Color'),
  274. required=False
  275. )
  276. description = forms.CharField(
  277. label=_('Description'),
  278. max_length=200,
  279. required=False
  280. )
  281. model = VirtualCircuitType
  282. fieldsets = (
  283. FieldSet('color', 'description'),
  284. )
  285. nullable_fields = ('color', 'description')
  286. class VirtualCircuitBulkEditForm(NetBoxModelBulkEditForm):
  287. provider_network = DynamicModelChoiceField(
  288. label=_('Provider network'),
  289. queryset=ProviderNetwork.objects.all(),
  290. required=False
  291. )
  292. provider_account = DynamicModelChoiceField(
  293. label=_('Provider account'),
  294. queryset=ProviderAccount.objects.all(),
  295. required=False
  296. )
  297. type = DynamicModelChoiceField(
  298. label=_('Type'),
  299. queryset=VirtualCircuitType.objects.all(),
  300. required=False
  301. )
  302. status = forms.ChoiceField(
  303. label=_('Status'),
  304. choices=add_blank_choice(CircuitStatusChoices),
  305. required=False,
  306. initial=''
  307. )
  308. tenant = DynamicModelChoiceField(
  309. label=_('Tenant'),
  310. queryset=Tenant.objects.all(),
  311. required=False
  312. )
  313. description = forms.CharField(
  314. label=_('Description'),
  315. max_length=100,
  316. required=False
  317. )
  318. comments = CommentField()
  319. model = VirtualCircuit
  320. fieldsets = (
  321. FieldSet('provider_network', 'provider_account', 'status', 'description', name=_('Virtual circuit')),
  322. FieldSet('tenant', name=_('Tenancy')),
  323. )
  324. nullable_fields = (
  325. 'provider_account', 'tenant', 'description', 'comments',
  326. )
  327. class VirtualCircuitTerminationBulkEditForm(NetBoxModelBulkEditForm):
  328. role = forms.ChoiceField(
  329. label=_('Role'),
  330. choices=add_blank_choice(VirtualCircuitTerminationRoleChoices),
  331. required=False,
  332. initial=''
  333. )
  334. description = forms.CharField(
  335. label=_('Description'),
  336. max_length=200,
  337. required=False
  338. )
  339. model = VirtualCircuitTermination
  340. fieldsets = (
  341. FieldSet('role', 'description'),
  342. )
  343. nullable_fields = ('description',)