tables.py 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001
  1. import django_tables2 as tables
  2. from django_tables2.utils import Accessor
  3. from tenancy.tables import COL_TENANT
  4. from utilities.tables import (
  5. BaseTable, BooleanColumn, ButtonsColumn, ChoiceFieldColumn, ColorColumn, ColoredLabelColumn, LinkedCountColumn,
  6. TagColumn, ToggleColumn,
  7. )
  8. from .models import (
  9. Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
  10. DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate,
  11. InventoryItem, Manufacturer, Platform, PowerFeed, PowerOutlet, PowerOutletTemplate, PowerPanel, PowerPort,
  12. PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site,
  13. VirtualChassis,
  14. )
  15. MPTT_LINK = """
  16. {% if record.get_children %}
  17. <span style="padding-left: {{ record.get_ancestors|length }}0px "><i class="fa fa-caret-right"></i>
  18. {% else %}
  19. <span style="padding-left: {{ record.get_ancestors|length }}9px">
  20. {% endif %}
  21. <a href="{{ record.get_absolute_url }}">{{ record.name }}</a>
  22. </span>
  23. """
  24. DEVICE_LINK = """
  25. <a href="{% url 'dcim:device' pk=record.pk %}">
  26. {{ record.name|default:'<span class="label label-info">Unnamed device</span>' }}
  27. </a>
  28. """
  29. RACKGROUP_ELEVATIONS = """
  30. <a href="{% url 'dcim:rack_elevation_list' %}?site={{ record.site.slug }}&group_id={{ record.pk }}" class="btn btn-xs btn-primary" title="View elevations">
  31. <i class="fa fa-eye"></i>
  32. </a>
  33. """
  34. UTILIZATION_GRAPH = """
  35. {% load helpers %}
  36. {% utilization_graph value %}
  37. """
  38. CABLE_TERMINATION_PARENT = """
  39. {% if value.device %}
  40. <a href="{{ value.device.get_absolute_url }}">{{ value.device }}</a>
  41. {% elif value.circuit %}
  42. <a href="{{ value.circuit.get_absolute_url }}">{{ value.circuit }}</a>
  43. {% elif value.power_panel %}
  44. <a href="{{ value.power_panel.get_absolute_url }}">{{ value.power_panel }}</a>
  45. {% endif %}
  46. """
  47. CABLE_LENGTH = """
  48. {% if record.length %}{{ record.length }} {{ record.get_length_unit_display }}{% else %}&mdash;{% endif %}
  49. """
  50. INTERFACE_IPADDRESSES = """
  51. {% for ip in record.ip_addresses.unrestricted %}
  52. <a href="{{ ip.get_absolute_url }}">{{ ip }}</a><br />
  53. {% endfor %}
  54. """
  55. INTERFACE_TAGGED_VLANS = """
  56. {% for vlan in record.tagged_vlans.unrestricted %}
  57. <a href="{{ vlan.get_absolute_url }}">{{ vlan }}</a><br />
  58. {% endfor %}
  59. """
  60. CONNECTION_STATUS = """
  61. <span class="label label-{% if record.connection_status %}success{% else %}danger{% endif %}">{{ record.get_connection_status_display }}</span>
  62. """
  63. #
  64. # Regions
  65. #
  66. class RegionTable(BaseTable):
  67. pk = ToggleColumn()
  68. name = tables.TemplateColumn(
  69. template_code=MPTT_LINK,
  70. orderable=False
  71. )
  72. site_count = tables.Column(
  73. verbose_name='Sites'
  74. )
  75. actions = ButtonsColumn(Region)
  76. class Meta(BaseTable.Meta):
  77. model = Region
  78. fields = ('pk', 'name', 'slug', 'site_count', 'description', 'actions')
  79. default_columns = ('pk', 'name', 'site_count', 'description', 'actions')
  80. #
  81. # Sites
  82. #
  83. class SiteTable(BaseTable):
  84. pk = ToggleColumn()
  85. name = tables.LinkColumn(
  86. order_by=('_name',)
  87. )
  88. status = ChoiceFieldColumn()
  89. region = tables.Column(
  90. linkify=True
  91. )
  92. tenant = tables.TemplateColumn(
  93. template_code=COL_TENANT
  94. )
  95. tags = TagColumn(
  96. url_name='dcim:site_list'
  97. )
  98. class Meta(BaseTable.Meta):
  99. model = Site
  100. fields = (
  101. 'pk', 'name', 'slug', 'status', 'facility', 'region', 'tenant', 'asn', 'time_zone', 'description',
  102. 'physical_address', 'shipping_address', 'latitude', 'longitude', 'contact_name', 'contact_phone',
  103. 'contact_email', 'tags',
  104. )
  105. default_columns = ('pk', 'name', 'status', 'facility', 'region', 'tenant', 'asn', 'description')
  106. #
  107. # Rack groups
  108. #
  109. class RackGroupTable(BaseTable):
  110. pk = ToggleColumn()
  111. name = tables.TemplateColumn(
  112. template_code=MPTT_LINK,
  113. orderable=False
  114. )
  115. site = tables.LinkColumn(
  116. viewname='dcim:site',
  117. args=[Accessor('site__slug')],
  118. verbose_name='Site'
  119. )
  120. rack_count = tables.Column(
  121. verbose_name='Racks'
  122. )
  123. actions = ButtonsColumn(
  124. model=RackGroup,
  125. prepend_template=RACKGROUP_ELEVATIONS
  126. )
  127. class Meta(BaseTable.Meta):
  128. model = RackGroup
  129. fields = ('pk', 'name', 'site', 'rack_count', 'description', 'slug', 'actions')
  130. default_columns = ('pk', 'name', 'site', 'rack_count', 'description', 'actions')
  131. #
  132. # Rack roles
  133. #
  134. class RackRoleTable(BaseTable):
  135. pk = ToggleColumn()
  136. name = tables.Column(linkify=True)
  137. rack_count = tables.Column(verbose_name='Racks')
  138. color = ColorColumn()
  139. actions = ButtonsColumn(RackRole)
  140. class Meta(BaseTable.Meta):
  141. model = RackRole
  142. fields = ('pk', 'name', 'rack_count', 'color', 'description', 'slug', 'actions')
  143. default_columns = ('pk', 'name', 'rack_count', 'color', 'description', 'actions')
  144. #
  145. # Racks
  146. #
  147. class RackTable(BaseTable):
  148. pk = ToggleColumn()
  149. name = tables.LinkColumn(
  150. order_by=('_name',)
  151. )
  152. site = tables.LinkColumn(
  153. viewname='dcim:site',
  154. args=[Accessor('site__slug')]
  155. )
  156. tenant = tables.TemplateColumn(
  157. template_code=COL_TENANT
  158. )
  159. status = ChoiceFieldColumn()
  160. role = ColoredLabelColumn()
  161. u_height = tables.TemplateColumn(
  162. template_code="{{ record.u_height }}U",
  163. verbose_name='Height'
  164. )
  165. class Meta(BaseTable.Meta):
  166. model = Rack
  167. fields = (
  168. 'pk', 'name', 'site', 'group', 'status', 'facility_id', 'tenant', 'role', 'serial', 'asset_tag', 'type',
  169. 'width', 'u_height',
  170. )
  171. default_columns = ('pk', 'name', 'site', 'group', 'status', 'facility_id', 'tenant', 'role', 'u_height')
  172. class RackDetailTable(RackTable):
  173. device_count = LinkedCountColumn(
  174. viewname='dcim:device_list',
  175. url_params={'rack_id': 'pk'},
  176. verbose_name='Devices'
  177. )
  178. get_utilization = tables.TemplateColumn(
  179. template_code=UTILIZATION_GRAPH,
  180. orderable=False,
  181. verbose_name='Space'
  182. )
  183. get_power_utilization = tables.TemplateColumn(
  184. template_code=UTILIZATION_GRAPH,
  185. orderable=False,
  186. verbose_name='Power'
  187. )
  188. tags = TagColumn(
  189. url_name='dcim:rack_list'
  190. )
  191. class Meta(RackTable.Meta):
  192. fields = (
  193. 'pk', 'name', 'site', 'group', 'status', 'facility_id', 'tenant', 'role', 'serial', 'asset_tag', 'type',
  194. 'width', 'u_height', 'device_count', 'get_utilization', 'get_power_utilization', 'tags',
  195. )
  196. default_columns = (
  197. 'pk', 'name', 'site', 'group', 'status', 'facility_id', 'tenant', 'role', 'u_height', 'device_count',
  198. 'get_utilization', 'get_power_utilization',
  199. )
  200. #
  201. # Rack reservations
  202. #
  203. class RackReservationTable(BaseTable):
  204. pk = ToggleColumn()
  205. reservation = tables.Column(
  206. accessor='pk',
  207. linkify=True
  208. )
  209. site = tables.Column(
  210. accessor=Accessor('rack__site'),
  211. linkify=True
  212. )
  213. tenant = tables.TemplateColumn(
  214. template_code=COL_TENANT
  215. )
  216. rack = tables.Column(
  217. linkify=True
  218. )
  219. unit_list = tables.Column(
  220. orderable=False,
  221. verbose_name='Units'
  222. )
  223. tags = TagColumn(
  224. url_name='dcim:rackreservation_list'
  225. )
  226. actions = ButtonsColumn(RackReservation)
  227. class Meta(BaseTable.Meta):
  228. model = RackReservation
  229. fields = (
  230. 'pk', 'reservation', 'site', 'rack', 'unit_list', 'user', 'created', 'tenant', 'description', 'tags',
  231. 'actions',
  232. )
  233. default_columns = (
  234. 'pk', 'reservation', 'site', 'rack', 'unit_list', 'user', 'description', 'actions',
  235. )
  236. #
  237. # Manufacturers
  238. #
  239. class ManufacturerTable(BaseTable):
  240. pk = ToggleColumn()
  241. name = tables.LinkColumn()
  242. devicetype_count = tables.Column(
  243. verbose_name='Device Types'
  244. )
  245. inventoryitem_count = tables.Column(
  246. verbose_name='Inventory Items'
  247. )
  248. platform_count = tables.Column(
  249. verbose_name='Platforms'
  250. )
  251. slug = tables.Column()
  252. actions = ButtonsColumn(Manufacturer, pk_field='slug')
  253. class Meta(BaseTable.Meta):
  254. model = Manufacturer
  255. fields = (
  256. 'pk', 'name', 'devicetype_count', 'inventoryitem_count', 'platform_count', 'description', 'slug', 'actions',
  257. )
  258. #
  259. # Device types
  260. #
  261. class DeviceTypeTable(BaseTable):
  262. pk = ToggleColumn()
  263. model = tables.Column(
  264. linkify=True,
  265. verbose_name='Device Type'
  266. )
  267. is_full_depth = BooleanColumn(
  268. verbose_name='Full Depth'
  269. )
  270. instance_count = LinkedCountColumn(
  271. viewname='dcim:device_list',
  272. url_params={'device_type_id': 'pk'},
  273. verbose_name='Instances'
  274. )
  275. tags = TagColumn(
  276. url_name='dcim:devicetype_list'
  277. )
  278. class Meta(BaseTable.Meta):
  279. model = DeviceType
  280. fields = (
  281. 'pk', 'model', 'manufacturer', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role',
  282. 'instance_count', 'tags',
  283. )
  284. default_columns = (
  285. 'pk', 'model', 'manufacturer', 'part_number', 'u_height', 'is_full_depth', 'instance_count',
  286. )
  287. #
  288. # Device type components
  289. #
  290. class ComponentTemplateTable(BaseTable):
  291. pk = ToggleColumn()
  292. name = tables.Column(
  293. order_by=('_name',)
  294. )
  295. class ConsolePortTemplateTable(ComponentTemplateTable):
  296. actions = ButtonsColumn(
  297. model=ConsolePortTemplate,
  298. buttons=('edit', 'delete')
  299. )
  300. class Meta(BaseTable.Meta):
  301. model = ConsolePortTemplate
  302. fields = ('pk', 'name', 'label', 'type', 'description', 'actions')
  303. empty_text = "None"
  304. class ConsoleServerPortTemplateTable(ComponentTemplateTable):
  305. actions = ButtonsColumn(
  306. model=ConsoleServerPortTemplate,
  307. buttons=('edit', 'delete')
  308. )
  309. class Meta(BaseTable.Meta):
  310. model = ConsoleServerPortTemplate
  311. fields = ('pk', 'name', 'label', 'type', 'description', 'actions')
  312. empty_text = "None"
  313. class PowerPortTemplateTable(ComponentTemplateTable):
  314. actions = ButtonsColumn(
  315. model=PowerPortTemplate,
  316. buttons=('edit', 'delete')
  317. )
  318. class Meta(BaseTable.Meta):
  319. model = PowerPortTemplate
  320. fields = ('pk', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'actions')
  321. empty_text = "None"
  322. class PowerOutletTemplateTable(ComponentTemplateTable):
  323. actions = ButtonsColumn(
  324. model=PowerOutletTemplate,
  325. buttons=('edit', 'delete')
  326. )
  327. class Meta(BaseTable.Meta):
  328. model = PowerOutletTemplate
  329. fields = ('pk', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'actions')
  330. empty_text = "None"
  331. class InterfaceTemplateTable(ComponentTemplateTable):
  332. mgmt_only = BooleanColumn(
  333. verbose_name='Management Only'
  334. )
  335. actions = ButtonsColumn(
  336. model=InterfaceTemplate,
  337. buttons=('edit', 'delete')
  338. )
  339. class Meta(BaseTable.Meta):
  340. model = InterfaceTemplate
  341. fields = ('pk', 'name', 'label', 'mgmt_only', 'type', 'description', 'actions')
  342. empty_text = "None"
  343. class FrontPortTemplateTable(ComponentTemplateTable):
  344. rear_port_position = tables.Column(
  345. verbose_name='Position'
  346. )
  347. actions = ButtonsColumn(
  348. model=FrontPortTemplate,
  349. buttons=('edit', 'delete')
  350. )
  351. class Meta(BaseTable.Meta):
  352. model = FrontPortTemplate
  353. fields = ('pk', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'actions')
  354. empty_text = "None"
  355. class RearPortTemplateTable(ComponentTemplateTable):
  356. actions = ButtonsColumn(
  357. model=RearPortTemplate,
  358. buttons=('edit', 'delete')
  359. )
  360. class Meta(BaseTable.Meta):
  361. model = RearPortTemplate
  362. fields = ('pk', 'name', 'label', 'type', 'positions', 'description', 'actions')
  363. empty_text = "None"
  364. class DeviceBayTemplateTable(ComponentTemplateTable):
  365. actions = ButtonsColumn(
  366. model=DeviceBayTemplate,
  367. buttons=('edit', 'delete')
  368. )
  369. class Meta(BaseTable.Meta):
  370. model = DeviceBayTemplate
  371. fields = ('pk', 'name', 'label', 'description', 'actions')
  372. empty_text = "None"
  373. #
  374. # Device roles
  375. #
  376. class DeviceRoleTable(BaseTable):
  377. pk = ToggleColumn()
  378. device_count = LinkedCountColumn(
  379. viewname='dcim:device_list',
  380. url_params={'role': 'slug'},
  381. verbose_name='Devices'
  382. )
  383. vm_count = LinkedCountColumn(
  384. viewname='virtualization:virtualmachine_list',
  385. url_params={'role': 'slug'},
  386. verbose_name='VMs'
  387. )
  388. color = ColorColumn()
  389. vm_role = BooleanColumn()
  390. actions = ButtonsColumn(DeviceRole, pk_field='slug')
  391. class Meta(BaseTable.Meta):
  392. model = DeviceRole
  393. fields = ('pk', 'name', 'device_count', 'vm_count', 'color', 'vm_role', 'description', 'slug', 'actions')
  394. default_columns = ('pk', 'name', 'device_count', 'vm_count', 'color', 'vm_role', 'description', 'actions')
  395. #
  396. # Platforms
  397. #
  398. class PlatformTable(BaseTable):
  399. pk = ToggleColumn()
  400. device_count = LinkedCountColumn(
  401. viewname='dcim:device_list',
  402. url_params={'platform': 'slug'},
  403. verbose_name='Devices'
  404. )
  405. vm_count = LinkedCountColumn(
  406. viewname='virtualization:virtualmachine_list',
  407. url_params={'platform': 'slug'},
  408. verbose_name='VMs'
  409. )
  410. actions = ButtonsColumn(Platform, pk_field='slug')
  411. class Meta(BaseTable.Meta):
  412. model = Platform
  413. fields = (
  414. 'pk', 'name', 'manufacturer', 'device_count', 'vm_count', 'slug', 'napalm_driver', 'napalm_args',
  415. 'description', 'actions',
  416. )
  417. default_columns = (
  418. 'pk', 'name', 'manufacturer', 'device_count', 'vm_count', 'napalm_driver', 'description', 'actions',
  419. )
  420. #
  421. # Devices
  422. #
  423. class DeviceTable(BaseTable):
  424. pk = ToggleColumn()
  425. name = tables.TemplateColumn(
  426. order_by=('_name',),
  427. template_code=DEVICE_LINK
  428. )
  429. status = ChoiceFieldColumn()
  430. tenant = tables.TemplateColumn(
  431. template_code=COL_TENANT
  432. )
  433. site = tables.Column(
  434. linkify=True
  435. )
  436. rack = tables.Column(
  437. linkify=True
  438. )
  439. device_role = ColoredLabelColumn(
  440. verbose_name='Role'
  441. )
  442. device_type = tables.LinkColumn(
  443. viewname='dcim:devicetype',
  444. args=[Accessor('device_type__pk')],
  445. verbose_name='Type',
  446. text=lambda record: record.device_type.display_name
  447. )
  448. primary_ip = tables.Column(
  449. linkify=True,
  450. verbose_name='IP Address'
  451. )
  452. primary_ip4 = tables.Column(
  453. linkify=True,
  454. verbose_name='IPv4 Address'
  455. )
  456. primary_ip6 = tables.Column(
  457. linkify=True,
  458. verbose_name='IPv6 Address'
  459. )
  460. cluster = tables.LinkColumn(
  461. viewname='virtualization:cluster',
  462. args=[Accessor('cluster__pk')]
  463. )
  464. virtual_chassis = tables.LinkColumn(
  465. viewname='dcim:virtualchassis',
  466. args=[Accessor('virtual_chassis__pk')]
  467. )
  468. vc_position = tables.Column(
  469. verbose_name='VC Position'
  470. )
  471. vc_priority = tables.Column(
  472. verbose_name='VC Priority'
  473. )
  474. tags = TagColumn(
  475. url_name='dcim:device_list'
  476. )
  477. class Meta(BaseTable.Meta):
  478. model = Device
  479. fields = (
  480. 'pk', 'name', 'status', 'tenant', 'device_role', 'device_type', 'platform', 'serial', 'asset_tag', 'site',
  481. 'rack', 'position', 'face', 'primary_ip', 'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis',
  482. 'vc_position', 'vc_priority', 'tags',
  483. )
  484. default_columns = (
  485. 'pk', 'name', 'status', 'tenant', 'site', 'rack', 'device_role', 'device_type', 'primary_ip',
  486. )
  487. class DeviceImportTable(BaseTable):
  488. name = tables.TemplateColumn(
  489. template_code=DEVICE_LINK
  490. )
  491. status = ChoiceFieldColumn()
  492. tenant = tables.TemplateColumn(
  493. template_code=COL_TENANT
  494. )
  495. site = tables.Column(
  496. linkify=True
  497. )
  498. rack = tables.Column(
  499. linkify=True
  500. )
  501. device_role = tables.Column(
  502. verbose_name='Role'
  503. )
  504. device_type = tables.Column(
  505. verbose_name='Type'
  506. )
  507. class Meta(BaseTable.Meta):
  508. model = Device
  509. fields = ('name', 'status', 'tenant', 'site', 'rack', 'position', 'device_role', 'device_type')
  510. empty_text = False
  511. #
  512. # Device components
  513. #
  514. class DeviceComponentTable(BaseTable):
  515. pk = ToggleColumn()
  516. device = tables.Column(
  517. linkify=True
  518. )
  519. name = tables.Column(
  520. linkify=True,
  521. order_by=('_name',)
  522. )
  523. cable = tables.Column(
  524. linkify=True
  525. )
  526. class Meta(BaseTable.Meta):
  527. order_by = ('device', 'name')
  528. class ConsolePortTable(DeviceComponentTable):
  529. tags = TagColumn(
  530. url_name='dcim:consoleport_list'
  531. )
  532. class Meta(DeviceComponentTable.Meta):
  533. model = ConsolePort
  534. fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'cable', 'tags')
  535. default_columns = ('pk', 'device', 'name', 'label', 'type', 'description')
  536. class ConsoleServerPortTable(DeviceComponentTable):
  537. tags = TagColumn(
  538. url_name='dcim:consoleserverport_list'
  539. )
  540. class Meta(DeviceComponentTable.Meta):
  541. model = ConsoleServerPort
  542. fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'cable', 'tags')
  543. default_columns = ('pk', 'device', 'name', 'label', 'type', 'description')
  544. class PowerPortTable(DeviceComponentTable):
  545. tags = TagColumn(
  546. url_name='dcim:powerport_list'
  547. )
  548. class Meta(DeviceComponentTable.Meta):
  549. model = PowerPort
  550. fields = (
  551. 'pk', 'device', 'name', 'label', 'type', 'description', 'maximum_draw', 'allocated_draw', 'cable', 'tags',
  552. )
  553. default_columns = ('pk', 'device', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description')
  554. class PowerOutletTable(DeviceComponentTable):
  555. tags = TagColumn(
  556. url_name='dcim:poweroutlet_list'
  557. )
  558. class Meta(DeviceComponentTable.Meta):
  559. model = PowerOutlet
  560. fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'power_port', 'feed_leg', 'cable', 'tags')
  561. default_columns = ('pk', 'device', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description')
  562. class BaseInterfaceTable(BaseTable):
  563. enabled = BooleanColumn()
  564. ip_addresses = tables.TemplateColumn(
  565. template_code=INTERFACE_IPADDRESSES,
  566. orderable=False,
  567. verbose_name='IP Addresses'
  568. )
  569. untagged_vlan = tables.Column(linkify=True)
  570. tagged_vlans = tables.TemplateColumn(
  571. template_code=INTERFACE_TAGGED_VLANS,
  572. orderable=False,
  573. verbose_name='Tagged VLANs'
  574. )
  575. class InterfaceTable(DeviceComponentTable, BaseInterfaceTable):
  576. tags = TagColumn(
  577. url_name='dcim:interface_list'
  578. )
  579. class Meta(DeviceComponentTable.Meta):
  580. model = Interface
  581. fields = (
  582. 'pk', 'device', 'name', 'label', 'enabled', 'type', 'mgmt_only', 'mtu', 'mode', 'mac_address',
  583. 'description', 'cable', 'tags', 'ip_addresses', 'untagged_vlan', 'tagged_vlans',
  584. )
  585. default_columns = ('pk', 'device', 'name', 'label', 'enabled', 'type', 'description')
  586. class FrontPortTable(DeviceComponentTable):
  587. rear_port_position = tables.Column(
  588. verbose_name='Position'
  589. )
  590. tags = TagColumn(
  591. url_name='dcim:frontport_list'
  592. )
  593. class Meta(DeviceComponentTable.Meta):
  594. model = FrontPort
  595. fields = (
  596. 'pk', 'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'cable', 'tags',
  597. )
  598. default_columns = ('pk', 'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description')
  599. class RearPortTable(DeviceComponentTable):
  600. tags = TagColumn(
  601. url_name='dcim:rearport_list'
  602. )
  603. class Meta(DeviceComponentTable.Meta):
  604. model = RearPort
  605. fields = ('pk', 'device', 'name', 'label', 'type', 'positions', 'description', 'cable', 'tags')
  606. default_columns = ('pk', 'device', 'name', 'label', 'type', 'description')
  607. class DeviceBayTable(DeviceComponentTable):
  608. installed_device = tables.Column(
  609. linkify=True
  610. )
  611. tags = TagColumn(
  612. url_name='dcim:devicebay_list'
  613. )
  614. class Meta(DeviceComponentTable.Meta):
  615. model = DeviceBay
  616. fields = ('pk', 'device', 'name', 'label', 'installed_device', 'description', 'tags')
  617. default_columns = ('pk', 'device', 'name', 'label', 'installed_device', 'description')
  618. class InventoryItemTable(DeviceComponentTable):
  619. manufacturer = tables.Column(
  620. linkify=True
  621. )
  622. discovered = BooleanColumn()
  623. tags = TagColumn(
  624. url_name='dcim:inventoryitem_list'
  625. )
  626. cable = None # Override DeviceComponentTable
  627. class Meta(DeviceComponentTable.Meta):
  628. model = InventoryItem
  629. fields = (
  630. 'pk', 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description',
  631. 'discovered', 'tags',
  632. )
  633. default_columns = ('pk', 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag')
  634. #
  635. # Cables
  636. #
  637. class CableTable(BaseTable):
  638. pk = ToggleColumn()
  639. id = tables.Column(
  640. linkify=True,
  641. verbose_name='ID'
  642. )
  643. termination_a_parent = tables.TemplateColumn(
  644. template_code=CABLE_TERMINATION_PARENT,
  645. accessor=Accessor('termination_a'),
  646. orderable=False,
  647. verbose_name='Side A'
  648. )
  649. termination_a = tables.LinkColumn(
  650. accessor=Accessor('termination_a'),
  651. orderable=False,
  652. verbose_name='Termination A'
  653. )
  654. termination_b_parent = tables.TemplateColumn(
  655. template_code=CABLE_TERMINATION_PARENT,
  656. accessor=Accessor('termination_b'),
  657. orderable=False,
  658. verbose_name='Side B'
  659. )
  660. termination_b = tables.LinkColumn(
  661. accessor=Accessor('termination_b'),
  662. orderable=False,
  663. verbose_name='Termination B'
  664. )
  665. status = ChoiceFieldColumn()
  666. length = tables.TemplateColumn(
  667. template_code=CABLE_LENGTH,
  668. order_by='_abs_length'
  669. )
  670. color = ColorColumn()
  671. tags = TagColumn(
  672. url_name='dcim:cable_list'
  673. )
  674. class Meta(BaseTable.Meta):
  675. model = Cable
  676. fields = (
  677. 'pk', 'id', 'label', 'termination_a_parent', 'termination_a', 'termination_b_parent', 'termination_b',
  678. 'status', 'type', 'color', 'length', 'tags',
  679. )
  680. default_columns = (
  681. 'pk', 'id', 'label', 'termination_a_parent', 'termination_a', 'termination_b_parent', 'termination_b',
  682. 'status', 'type',
  683. )
  684. #
  685. # Device connections
  686. #
  687. class ConsoleConnectionTable(BaseTable):
  688. console_server = tables.Column(
  689. accessor=Accessor('path__destination__device'),
  690. orderable=False,
  691. linkify=True,
  692. verbose_name='Console Server'
  693. )
  694. console_server_port = tables.Column(
  695. accessor=Accessor('path__destination'),
  696. orderable=False,
  697. linkify=True,
  698. verbose_name='Port'
  699. )
  700. device = tables.Column(
  701. linkify=True
  702. )
  703. name = tables.Column(
  704. linkify=True,
  705. verbose_name='Console Port'
  706. )
  707. connection_status = tables.TemplateColumn(
  708. accessor=Accessor('path__is_connected'),
  709. orderable=False,
  710. template_code=CONNECTION_STATUS,
  711. verbose_name='Status'
  712. )
  713. class Meta(BaseTable.Meta):
  714. model = ConsolePort
  715. fields = ('console_server', 'console_server_port', 'device', 'name', 'connection_status')
  716. class PowerConnectionTable(BaseTable):
  717. pdu = tables.Column(
  718. accessor=Accessor('path__destination__device'),
  719. orderable=False,
  720. linkify=True,
  721. verbose_name='PDU'
  722. )
  723. outlet = tables.Column(
  724. accessor=Accessor('path__destination'),
  725. orderable=False,
  726. linkify=True,
  727. verbose_name='Outlet'
  728. )
  729. device = tables.Column(
  730. linkify=True
  731. )
  732. name = tables.Column(
  733. linkify=True,
  734. verbose_name='Power Port'
  735. )
  736. connection_status = tables.TemplateColumn(
  737. accessor=Accessor('path__is_connected'),
  738. orderable=False,
  739. template_code=CONNECTION_STATUS,
  740. verbose_name='Status'
  741. )
  742. class Meta(BaseTable.Meta):
  743. model = PowerPort
  744. fields = ('pdu', 'outlet', 'device', 'name', 'connection_status')
  745. class InterfaceConnectionTable(BaseTable):
  746. device_a = tables.Column(
  747. accessor=Accessor('device'),
  748. linkify=True,
  749. verbose_name='Device A'
  750. )
  751. interface_a = tables.Column(
  752. accessor=Accessor('name'),
  753. linkify=True,
  754. verbose_name='Interface A'
  755. )
  756. device_b = tables.Column(
  757. accessor=Accessor('path__destination__device'),
  758. orderable=False,
  759. linkify=True,
  760. verbose_name='Device B'
  761. )
  762. interface_b = tables.Column(
  763. accessor=Accessor('path__destination'),
  764. orderable=False,
  765. linkify=True,
  766. verbose_name='Interface B'
  767. )
  768. connection_status = tables.TemplateColumn(
  769. accessor=Accessor('path__is_connected'),
  770. orderable=False,
  771. template_code=CONNECTION_STATUS,
  772. verbose_name='Status'
  773. )
  774. class Meta(BaseTable.Meta):
  775. model = Interface
  776. fields = (
  777. 'device_a', 'interface_a', 'device_b', 'interface_b', 'connection_status',
  778. )
  779. #
  780. # Virtual chassis
  781. #
  782. class VirtualChassisTable(BaseTable):
  783. pk = ToggleColumn()
  784. name = tables.Column(
  785. linkify=True
  786. )
  787. master = tables.Column(
  788. linkify=True
  789. )
  790. member_count = LinkedCountColumn(
  791. viewname='dcim:device_list',
  792. url_params={'virtual_chassis_id': 'pk'},
  793. verbose_name='Members'
  794. )
  795. tags = TagColumn(
  796. url_name='dcim:virtualchassis_list'
  797. )
  798. class Meta(BaseTable.Meta):
  799. model = VirtualChassis
  800. fields = ('pk', 'name', 'domain', 'master', 'member_count', 'tags')
  801. default_columns = ('pk', 'name', 'domain', 'master', 'member_count')
  802. #
  803. # Power panels
  804. #
  805. class PowerPanelTable(BaseTable):
  806. pk = ToggleColumn()
  807. name = tables.LinkColumn()
  808. site = tables.LinkColumn(
  809. viewname='dcim:site',
  810. args=[Accessor('site__slug')]
  811. )
  812. powerfeed_count = LinkedCountColumn(
  813. viewname='dcim:powerfeed_list',
  814. url_params={'power_panel_id': 'pk'},
  815. verbose_name='Feeds'
  816. )
  817. tags = TagColumn(
  818. url_name='dcim:powerpanel_list'
  819. )
  820. class Meta(BaseTable.Meta):
  821. model = PowerPanel
  822. fields = ('pk', 'name', 'site', 'rack_group', 'powerfeed_count', 'tags')
  823. default_columns = ('pk', 'name', 'site', 'rack_group', 'powerfeed_count')
  824. #
  825. # Power feeds
  826. #
  827. class PowerFeedTable(BaseTable):
  828. pk = ToggleColumn()
  829. name = tables.LinkColumn()
  830. power_panel = tables.Column(
  831. linkify=True
  832. )
  833. rack = tables.Column(
  834. linkify=True
  835. )
  836. status = ChoiceFieldColumn()
  837. type = ChoiceFieldColumn()
  838. max_utilization = tables.TemplateColumn(
  839. template_code="{{ value }}%"
  840. )
  841. available_power = tables.Column(
  842. verbose_name='Available power (VA)'
  843. )
  844. tags = TagColumn(
  845. url_name='dcim:powerfeed_list'
  846. )
  847. class Meta(BaseTable.Meta):
  848. model = PowerFeed
  849. fields = (
  850. 'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase',
  851. 'max_utilization', 'available_power', 'tags',
  852. )
  853. default_columns = (
  854. 'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase',
  855. )