tables.py 28 KB

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