1[% SET user_can_port_control = user_has_role('port_control') %]
2<table id="dp-data-table" class="table table-bordered table-striped" width="100%" cellspacing="0">
3  <thead>
4    <tr>
5      <th></th>
6      [% FOREACH item IN settings.port_columns %]
7      [% NEXT IF item.name == 'c_admin' %]
8      [% NEXT IF item.name == 'c_nodes' AND params.c_nodes AND params.c_neighbors %]
9        [% NEXT UNLESS params.${item.name} %]
10        [% SET th_class = '' %]
11        [% IF (item.name == 'c_port' OR item.name == 'c_descr' OR item.name == 'c_name') %]
12          [% SET th_class = ' class="portsort"' %]
13        [% END %]
14        <th[% th_class | none %]>
15          [% IF item.name == 'c_neighbors' %]
16          [% IF params.c_nodes %]
17          Connected Nodes &amp; Devices
18          [% ELSE %]
19          Connected Devices
20          [% END %]
21          [% ELSE %]
22          [% item.label | html_entity %]
23          [% END %]
24        </th>
25      [% END %]
26    </tr>
27  </thead>
28  <tbody>
29    [% FOREACH row IN results %]
30    [% SET portname = row.port %]
31    <tr>
32      <td class="nd_center-cell nd_devport-icon">
33        [% IF row.up_admin != 'up' %]
34        <i class="icon-remove icon-large"></i>
35        [% ELSIF row.up == 'up' AND row.stp == 'blocking' AND vlans.$portname.vlan_count < 2 %]
36        <i class="icon-ban-circle text-info icon-large"></i>
37        [% ELSIF row.error_disable_cause %]
38        <i class="icon-exclamation-sign text-error icon-large"></i>
39        [% ELSIF row.has_column_loaded('is_free') AND row.is_free %]
40        <i class="icon-circle-arrow-down text-success icon-large"></i>
41        [% ELSIF row.up_admin == 'up' AND (row.up != 'up' AND row.up != 'dormant') %]
42          [% IF params.port_state == 'free' %]
43          <i class="icon-circle-arrow-down text-success icon-large"></i>
44          [% ELSE %]
45          <i class="icon-arrow-down text-error icon-large"></i>
46          [% END %]
47        [% ELSE %]
48        <i class="icon-angle-up text-success icon-large"></i>
49        [% END %]
50        [% IF row.slave_of %]<br/>
51          [% IF row.get_column('agg_master_up_admin') != 'up' %]
52            <small><i class="icon-group muted"></i></small>
53          [% ELSIF row.get_column('agg_master_up') == 'up' %]
54            <small><i class="icon-group text-success"></i></small>
55          [% ELSE %]
56            <small><i class="icon-group text-error"></i></small>
57          [% END %]
58        [% END %]
59      </td>
60
61      [% FOREACH config IN settings._extra_device_port_cols %]
62        [% NEXT UNLESS config.position == 'left' AND params.${config.name} %]
63        <td>
64          [% TRY %]
65          [% INCLUDE "plugin/${config.name}/device_port_column.tt" %]
66          [% CATCH %]
67          <!-- dummy content required by Template Toolkit TRY -->
68          [% END %]
69        </td>
70      [% END %]
71
72      [% IF params.c_port %]
73      [% IF user_can_port_control AND params.c_admin %]
74      [% IF row.up_admin == 'up' %]
75      <td nowrap class="nd_editable-cell" data-action="down"
76        data-order="[% row.port | html_entity %]" data-filter="[% row.port | html_entity %]"
77        data-field="c_port" data-for-device="[% device.ip | html_entity %]" data-for-port="[% row.port | html_entity %]">
78      [% ELSE %]
79      <td nowrap class="nd_editable-cell" data-action="up"
80        data-order="[% row.port | html_entity %]" data-filter="[% row.port | html_entity %]"
81        data-field="c_port" data-for-device="[% device.ip | html_entity %]" data-for-port="[% row.port | html_entity %]">
82      [% END %]
83      [% ELSE %]
84      <td nowrap data-order="[% row.port | html_entity %]" data-filter="[% row.port | html_entity %]">
85      [% END %]
86        <a class="nd_log-icon"
87          href="[% uri_for('/report/portlog') | none %]?q=[% device.ip | uri %]&f=[% row.port | uri %]">
88          <i class="icon-file-text-alt"
89            rel="tooltip" data-placement="top" data-offset="3"
90            data-animation="" data-title="View Port Log"></i>
91        </a>
92      [% IF user_can_port_control AND params.c_admin %]
93      [% IF row.up_admin == 'up' %]
94        <span class="nd_hand-icon">
95          <i class="icon-bullseye" data-action="bounce"
96            rel="tooltip" data-placement="top" data-offset="3"
97            data-animation="" data-title="Bounce Port"></i>
98          <i class="icon-hand-down"
99            rel="tooltip" data-placement="top" data-offset="3"
100            data-animation="" data-title="Disable Port"></i>
101        </span>
102      [% ELSE %]
103        <span class="nd_hand-icon">
104          <i class="icon-bullseye" data-action="bounce" style="display: none"
105            rel="tooltip" data-placement="top" data-offset="3"
106            data-animation="" data-title="Bounce Port"></i>
107          <i class="icon-hand-up"
108            rel="tooltip" data-placement="top" data-offset="3"
109            data-animation="" data-title="Enable Port"></i>
110        </span>
111      [% END %]
112      [% END %]
113        <a class="nd_this-port-only nd_port-only-first" href="[% device_ports | none %]&q=[% params.q | uri %]&f=[% row.port | uri %]&prefer=port">
114          [% IF row.is_master %]
115            <small><i class="icon-group muted"></i></small>&nbsp;
116          [% END %]
117        [% row.port | html_entity %]</a>
118        [% IF row.slave_of %]<br/>
119          <a class="nd_this-port-only" href="[% device_ports | none %]&q=[% params.q | uri %]&f=[% row.slave_of | uri %]&prefer=port">
120          [% row.slave_of | html_entity %]</a>
121        [% END %]
122      </td>
123      [% END %]
124
125      [% FOREACH config IN settings._extra_device_port_cols %]
126        [% NEXT UNLESS config.position == 'mid' AND params.${config.name} %]
127        <td>
128          [% TRY %]
129          [% INCLUDE "plugin/${config.name}/device_port_column.tt" %]
130          [% CATCH %]
131          <!-- dummy content required by Template Toolkit TRY -->
132          [% END %]
133        </td>
134      [% END %]
135
136      [% IF params.c_descr %]
137      <td nowrap>[% row.descr | html_entity %]</td>
138      [% END %]
139
140      [% IF params.c_comment %]
141      <td nowrap>[% row.last_comment | html_entity %]</td>
142      [% END %]
143
144      [% IF params.c_type %]
145      <td>[% row.type | html_entity %]</td>
146      [% END %]
147
148      [% IF params.c_duplex %]
149      <td>
150        [% IF row.up == 'up' AND row.duplex %]
151        [% (row.duplex_admin.ucfirst || 'Auto') | html_entity %] / [% row.duplex.ucfirst | html_entity %]
152        [% END %]
153      </td>
154      [% END %]
155
156      [% IF params.c_lastchange %]
157      <td>[% row.lastchange_stamp | html_entity %]</td>
158      [% END %]
159
160      [% IF params.c_name %]
161      [% IF user_can_port_control AND params.c_admin %]
162      <td nowrap class="nd_editable-cell" contenteditable="true"
163          data-field="c_name" data-for-device="[% device.ip | html_entity %]" data-for-port="[% row.port | html_entity %]">
164      <i class="icon-edit nd_edit-icon"></i>
165      [% ELSE %]
166      <td nowrap class="nd_editable-cell">
167      [% END %]
168      <div class="nd_editable-cell-content">
169        [% row.name | html_entity %]
170      </div>
171      </td>
172      [% END %]
173
174      [% IF params.c_speed %]
175      <td>[% row.speed | html_entity %]</td>
176      [% END %]
177
178      [% IF params.c_speed_admin %]
179      <td>[% row.speed_admin | html_entity %]</td>
180      [% END %]
181
182      [% IF params.c_error %]
183      <td>[% row.error_disable_cause | html_entity %]</td>
184      [% END %]
185
186      [% IF params.c_mac %]
187      <td>[% row.mac | html_entity %]</td>
188      [% END %]
189
190      [% IF params.c_mtu %]
191      <td>[% row.mtu | html_entity %]</td>
192      [% END %]
193
194      [% IF params.c_pvid %]
195      [% IF user_can_port_control AND params.c_admin %]
196      <td class="nd_editable-cell" contenteditable="true" data-default="[% row.vlan | html_entity %]"
197        data-field="c_pvid" data-for-device="[% device.ip | html_entity %]" data-for-port="[% row.port | html_entity %]">
198      <i class="icon-edit nd_edit-icon"></i>
199      <div class="nd_editable-cell-content">
200        [% IF row.vlan AND row.vlan > 0 %][% row.vlan | html_entity %][% END %]
201      </div>
202      </td>
203      [% ELSE %]
204      <td>
205        [% IF row.vlan AND row.vlan > 0 %]
206        <a class="nd_linkcell"
207          href="[% uri_for('/search') | none %]?tab=vlan&q=[% row.vlan | uri %]">
208            [% row.vlan | html_entity %]</a>
209        [% END %]
210      </td>
211      [% END %]
212      [% END %]
213
214      [% IF params.c_vmember %]
215      <td>
216        [% IF vlans.$portname.vlan_count <= settings.devport_vlan_limit %]
217          [% SET vlan_count = vlans.$portname.vlan_count %]
218          [% SET output = '' %]
219          [% FOREACH vlan IN vlans.$portname.vlan_set.nsort %]
220            [% IF vlan == 0 %][% SET vlan_count = (vlan_count - 1) %][% NEXT %][% END %]
221            [% SET output = output _
222              '<a href="' _ uri_for('/search') _ '?tab=vlan&q=' _ vlan _ '">' _ vlan _ '</a>' %]
223            [% IF NOT loop.last %][% SET output = output _ ', ' %][% END %]
224          [% END %]
225          [% IF vlan_count > 10 %] [%# TODO make this a settable variable %]
226            [% SET output = '<div class="nd_vlan-total">(' _ vlan_count
227              _ ')</div><span class="nd_linkcell nd_collapse-vlans">
228                <div class="nd_arrow-up-down-left icon-chevron-up icon-large"></div>Show VLANs</span>
229                <div class="nd_collapsing nd_collapse-pre-hidden">' _ output %]
230            [% SET output = output _ '</div>' %]
231          [% END %]
232          [% output | none %]
233        [% ELSE %]
234        <i class="icon-asterisk text-warning"></i> ([% vlans.$portname.vlan_count %] is too many to list)
235        [% END %]
236      </td>
237      [% END %]
238
239      [% IF params.c_power %]
240        [% IF row.power %]
241          [% IF row.power.admin == 'true' %]
242            [% IF user_can_port_control AND params.c_admin %]
243              <td nowrap data-action="false"
244                data-field="c_power" data-for-device="[% device.ip | html_entity %]"
245                data-for-port="[% row.port | html_entity %]">
246
247                <i class="icon-off nd_power-icon nd_power-on"
248                  rel="tooltip" data-placement="top" data-offset="3"
249                  data-animation="" data-title="Disable Power"></i>
250            [% ELSE %]
251              <td nowrap>
252                <i class="icon-off nd_power-on"></i>
253            [% END %]
254                <span>
255                [% IF row.power.power AND row.power.power > 0 %]
256                  [% row.power.power | html_entity %]&nbsp;mW
257                [% ELSE %]
258                  ([% row.power.status | html_entity %])
259                [% END %]
260                </span>
261          [% ELSE %]
262            [% IF user_can_port_control AND params.c_admin %]
263              <td nowrap data-action="true"
264                data-field="c_power" data-for-device="[% device.ip | html_entity %]"
265                data-for-port="[% row.port | html_entity %]">
266
267                <i class="icon-off nd_power-icon"
268                  rel="tooltip" data-placement="top" data-offset="3"
269                  data-animation="" data-title="Enable Power"></i>
270            [% ELSE %]
271              <td>
272                <i class="icon-off"></i>
273            [% END %]
274          [% END %]
275              </td>
276        [% ELSE %]
277          <td></td>
278        [% END %]
279      [% END %]
280
281      [% IF params.c_ssid %]
282      <td>[% row.ssid.ssid | html_entity %]</td>
283      [% END %]
284
285      [% IF params.c_nodes OR params.c_neighbors %]
286      <td>
287        [% IF params.c_neighbors AND (row.remote_ip OR row.is_uplink) %]
288          [% IF row.get_column('neighbor_ip') %]
289            <i class="icon-link[% ' text-warning' IF row.manual_topo %]"></i>
290            [% IF row.remote_is_phone %]
291              <i class="icon-phone"></i>&nbsp;
292            [% ELSIF row.remote_is_wap %]
293              <i class="icon-rss"></i>&nbsp;
294            [% END %]
295            <a href="[% device_ports | none %]&q=[% row.get_column('neighbor_ip') | uri %]">
296                [% row.get_column('neighbor_dns').remove(settings.domain_suffix) || row.get_column('neighbor_ip') | html_entity %]</a>
297            [% IF row.remote_port and has_snmp(row.remote_type) %]
298                -
299                <a href="[% device_ports | none %]&q=[% row.get_column('neighbor_ip') | uri %]&f=[% row.remote_port | uri %]&prefer=port">
300                    [% row.remote_port | html_entity %]</a>
301            [% END %]
302            <br/>
303            [% IF params.n_inventory and row.remote_inventory %]
304              [% row.remote_inventory | html_entity %]<br/>
305            [% END %]
306            [% IF params.n_detailed_inventory and (row.remote_id or row.remote_type) %]
307              ([% 'id: '_ row.remote_id IF row.remote_id %]
308              [% ' type: '_ row.remote_type IF row.remote_type %])<br/>
309            [% END %]
310          [% ELSIF row.remote_ip %]
311            [% '<i class="icon-unlink text-error"></i>&nbsp;' IF has_snmp(row.remote_type) %]
312            [% IF row.remote_is_phone %]
313              <i class="icon-phone"></i>&nbsp;
314            [% ELSIF row.remote_is_wap %]
315              <i class="icon-rss"></i>&nbsp;
316            [% END %]
317            <a href="[% search_node | none %]&q=[% row.remote_ip | uri %]">
318              [% row.remote_ip | html_entity %]
319              [% IF row.remote_port and has_snmp(row.remote_type) %]
320                - [% row.remote_port | html_entity %]
321              [% END %]
322            </a><br/>
323            [% IF params.n_inventory and row.remote_inventory %]
324              [% row.remote_inventory | html_entity %]<br/>
325            [% END %]
326            [% IF params.n_detailed_inventory and (row.remote_id or row.remote_type) %]
327              ([% 'id: '_ row.remote_id IF row.remote_id %]
328              [% ' type: '_ row.remote_type IF row.remote_type %])<br/>
329            [% END %]
330          [% ELSE %]
331            [% '<i class="icon-unlink text-error"></i>&nbsp; (possible uplink)' IF has_snmp(row.remote_type) %]
332          [% END %]
333        [% END %]
334        [% IF params.c_nodes %]
335        [% FOREACH node IN row.$nodes %]
336          [% '<br/>' IF (row.remote_ip OR row.is_uplink) OR NOT loop.first %]
337          [% '<i class="icon-book"></i>&nbsp; ' IF NOT node.active %]
338          [% '<i class="icon-signal"></i>&nbsp;' IF node.wireless.defined %]
339          <a href="[% search_node | none %]&q=[% node.net_mac.$mac_format_call | uri %]">
340            [% node.net_mac.$mac_format_call | html_entity %]</a>
341          [% IF (node.vlan > 0) && (node.vlan != row.vlan) %]
342            (on vlan [% node.vlan | html_entity %])
343          [% END %]
344          [% IF params.n_ssid AND node.wireless.defined %]
345            (SSID:
346            [% FOREACH wlan IN node.wireless %]
347              <a href="[%+ uri_for('/report/portssid') %]?ssid=[% wlan.ssid | uri %]">[% wlan.ssid | html_entity %]</a>
348            [% END %]
349            )
350          [% END %]
351          [% IF params.n_vendor AND node.oui.defined %]
352            (Vendor:
353            [% FOREACH oui IN node.oui %]
354              <a href="[%+ uri_for('/report/nodevendor') %]?vendor=[% oui.abbrev | uri %]">[% oui.abbrev | html_entity %]</a>
355            [% END %]
356            )
357          [% END %]
358          [% ' (' _ node.time_last_age _ ')' IF params.n_age %]
359          [% IF params.n_ip4 OR params.n_ip6 %]
360            [% FOREACH ip IN node.$ips %]
361            <br/>&nbsp; [% '<i class="icon-book"></i>&nbsp; ' IF NOT ip.active %]
362              [% SET dns = ip.dns %]
363              [% IF dns %]
364              <a href="[% search_node | none %]&q=[% ip.ip | uri %]">[% dns | html_entity %] ([% ip.ip | html_entity %])</a>
365              [% ELSE %]
366              <a href="[% search_node | none %]&q=[% ip.ip | uri %]">[% ip.ip | html_entity %]</a>
367              [% END %]
368            [% END %]
369          [% END %]
370          [% IF params.n_netbios %]
371            [% FOREACH nbt IN node.netbios %]
372            <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\\<a href="[% uri_for('/report/netbios') | none %]?domain=[% nbt.domain | uri %]" title="Nodes in this Domain">[% nbt.domain | html_entity %]</a>\<a href="[% search_node | none %]&q=[% nbt.nbname | uri %]">[% nbt.nbname | html_entity %]</a>
373            <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[% nbt.nbuser || '[No User]' | html_entity %]@<a href="[% search_node | none %]&q=[% nbt.ip | uri %]">[% nbt.ip | html_entity %]</a>
374            [% END %]
375          [% END %]
376        [% END %]
377        [% END %]
378        [% IF user_can_port_control AND params.c_admin %]
379        <a class="nd_log-icon"
380          href="[% uri_for('/admin/topology') | none %]?dev1=[% device.ip | uri %]&port1=[% row.port | uri %]">
381          <i class="icon-link text-warning"
382            rel="tooltip" data-placement="top" data-offset="3"
383            data-animation="" data-title="Manual Topology"></i>
384        </a>
385        [% END %]
386      </td>
387      [% END %]
388
389      [% IF params.c_stp %]
390      <td>[% row.stp | html_entity %]</td>
391      [% END %]
392
393      [% IF params.c_up %]
394      <td>
395        [% row.up_admin.ucfirst | html_entity %] / [% row.up.ucfirst | html_entity %]
396      </td>
397      [% END %]
398
399      [% FOREACH config IN settings._extra_device_port_cols %]
400        [% NEXT UNLESS config.position == 'right' AND params.${config.name} %]
401        <td>
402          [% TRY %]
403          [% INCLUDE "plugin/${config.name}/device_port_column.tt" %]
404          [% CATCH %]
405          <!-- dummy content required by Template Toolkit TRY -->
406          [% END %]
407        </td>
408      [% END %]
409    </tr>
410    [% END %]
411  </tbody>
412</table>
413
414[% IF user_can_port_control %]
415<div id="nd_portlog" class="nd_modal nd_deep-horizon modal hide fade" tabindex="-1"
416    role="dialog" aria-hidden="true">
417  <div class="modal-body">
418    <blockquote>
419      <ul><li><p>Please provide a reason for changing the Port Configuration</p></li></ul>
420    </blockquote>
421    <select id="nd_portlog-reason" class="input-block-level" name="reason">
422      [% FOREACH pair IN settings.port_control_reasons.pairs %]
423        <option[% ' selected="selected"' IF pair.key == 'other' %] value="[% pair.key | html_entity %]">
424          [% pair.value | html_entity %]</option>
425      [% END %]
426    </select>
427    <textarea id="nd_portlog-log" class="input-block-level" rows="2" name="log"
428      placeholder="Enter a log message"></textarea>
429  </div>
430  <div class="modal-footer">
431    <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
432    <button id="nd_portlog-submit" class="btn btn-info" data-dismiss="modal">Continue</button>
433  </div>
434</div>
435[% END %]
436
437<script>
438$(document).ready(function() {
439    $('#dp-data-table').dataTable({
440        "columnDefs": [
441            { "sortable": false, "targets": 0 },
442            { "searchable": false, "targets": 0 },
443            { "type": 'portsort', "targets": [ 'portsort' ] }
444        ],
445        "order": [[ 1, 'asc' ]],
446[% INCLUDE 'ajax/datatabledefaults.tt' -%]
447    } );
448} );
449</script>
450