index.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. <?php
  2. //-
  3. // Copyright (c) 2011-2017 Joe Clarke <jclarke@cisco.com>
  4. // All rights reserved.
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions
  7. // are met:
  8. // 1. Redistributions of source code must retain the above copyright
  9. // notice, this list of conditions and the following disclaimer.
  10. // 2. Redistributions in binary form must reproduce the above copyright
  11. // notice, this list of conditions and the following disclaimer in the
  12. // documentation and/or other materials provided with the distribution.
  13. // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  14. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16. // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  17. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  19. // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  20. // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22. // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  23. // SUCH DAMAGE.
  24. include_once 'db.inc.php';
  25. include_once 'swreg/swreg.inc.php';
  26. require_once 'Log.php';
  27. require_once 'functions.php';
  28. $dsn = "$db_driver:host=$db_host;dbname=$db_name";
  29. $options = [
  30. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  31. PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
  32. PDO::ATTR_EMULATE_PREPARES => false,
  33. ];
  34. try {
  35. $dbh = new PDO($dsn, $db_user, $db_pass, $options);
  36. } catch (PDOException $e) {
  37. die($e->getMessage());
  38. }
  39. $logger = Log::singleton('file', LOGFILE, TOOL_NAME . ' : Physical Switches');
  40. if ($logger === false) {
  41. die("Failed to open logfile.\n");
  42. }
  43. $mask = Log::MAX(LOG_LEVEL);
  44. $logger->setMask($mask);
  45. $base = get_base($_SERVER['SCRIPT_NAME']);
  46. $ruser = '<AUTHENTICATION NOT ENABLED>';
  47. if (isset($_SERVER['REMOTE_USER'])) {
  48. $ruser = $_SERVER['REMOTE_USER'];
  49. }
  50. $errors = array();
  51. if (isset($_REQUEST['prev_checked'])) {
  52. $pc = $_REQUEST['prev_checked'];
  53. $pas = $_REQUEST['prev_assigned_switch'];
  54. $c = (isset($_REQUEST['checked'])) ? $_REQUEST['checked'] : array();
  55. $as = $_REQUEST['assigned_switch'];
  56. $d = (isset($_REQUEST['delete'])) ? $_REQUEST['delete'] : array();
  57. $rz = (isset($_REQUEST['reztp'])) ? $_REQUEST['reztp'] : array();
  58. foreach ($pc as $swsn => $value) {
  59. $curr_del = (isset($d[$swsn])) ? $d[$swsn] : 0;
  60. $curr_rz = (isset($rz[$swsn])) ? $rz[$swsn] : 0;
  61. if ($curr_del == 1) {
  62. $sql = "DELETE FROM DEVICE_MAP WHERE serial_number=:sn";
  63. try {
  64. $sth = $dbh->prepare($sql);
  65. $sth->execute(['sn' => $swsn]);
  66. $sth->closeCursor();
  67. $logger->info("User {$ruser} deleted physical switch {$swsn}");
  68. } catch (PDOException $e) {
  69. array_push($errors, "Failed to delete switch {$swsn}: {$e->getMessage()}");
  70. }
  71. continue;
  72. }
  73. if ($curr_rz == 1) {
  74. $sql = "UPDATE DEVICE_MAP SET should_re_ztp=:rz WHERE serial_number=:sn";
  75. try {
  76. $sth = $dbh->prepare($sql);
  77. $sth->execute(['sn' => $swsn, 'rz' => 2]);
  78. $sth->closeCursor();
  79. $logger->info("User {$ruser} set physical switch {$swsn} to re-ZTP");
  80. } catch (PDOException $e) {
  81. array_push($errors, "Failed to set switch {$swsn} to re-ZTP: {$e->getMessage()}");
  82. }
  83. }
  84. $curr_checked = (isset($c[$swsn])) ? $c[$swsn] : 0;
  85. if ($value != $curr_checked || $pas[$swsn] != $as[$swsn]) {
  86. $nc = $curr_checked;
  87. $additional = '';
  88. if ($nc == 1 && $as == '__BOGUS__') {
  89. array_push($errors, "You must select a logical switch assignment for $swsn");
  90. } else {
  91. if ($nc == 0 || $as == '__BOGUS__') {
  92. $nas = 'NULL';
  93. $additional = ", provisioned_status = '" . PROVISION_UNKNOWN . "', device_status = '" . REACHABILITY_NEVER_REACHABLE . "'";
  94. } else {
  95. $nas = "'{$as[$swsn]}'";
  96. }
  97. $sql = "UPDATE DEVICE_MAP SET checked_out='{$nc}', assigned_switch = {$nas} {$additional} WHERE serial_number='{$swsn}'";
  98. try {
  99. $dbh->query($sql);
  100. $logger->info("User {$ruser} updated physical switches, checked_out={$nc}, assigned_switch={$nas} for serial_number={$swsn}");
  101. } catch (PDOException $e) {
  102. array_push($errors, "Failed to update $swsn: '{$e->getMessage()}'");
  103. }
  104. }
  105. }
  106. }
  107. }
  108. $wc = '';
  109. if (isset($_REQUEST['filter'])) {
  110. switch ($_REQUEST['filter']) {
  111. case 'a':
  112. $wc = '';
  113. break;
  114. case 'p':
  115. $wc = 'WHERE assigned_switch IS NOT NULL';
  116. break;
  117. case 'up':
  118. $wc = 'WHERE assigned_switch IS NULL';
  119. break;
  120. case 'vu':
  121. $wc = 'WHERE provisioned_status=\'' . PROVISION_UNKNOWN . '\'';
  122. break;
  123. case 'vi':
  124. $wc = 'WHERE provisioned_status=\'' . PROVISION_IN_PROGRESS . '\'';
  125. break;
  126. case 'vf':
  127. $wc = 'WHERE provisioned_status=\'' . PROVISION_FAIL . '\'';
  128. break;
  129. case 'vs':
  130. $wc = 'WHERE provisioned_status=\'' . PROVISION_SUCCESS . '\'';
  131. break;
  132. case 'r':
  133. $wc = 'WHERE device_status=\'' . REACHABILITY_REACHABLE . '\'';
  134. break;
  135. case 'ur':
  136. $wc = 'WHERE provisioned_status=\'' . PROVISION_SUCCESS . '\' AND (device_status=\'' . REACHABILITY_NEVER_REACHABLE . '\' OR device_status=\'' . REACHABILITY_NOW_UNREACHABLE . '\')';
  137. break;
  138. default:
  139. if (preg_match("/^pid:([\w\d-]+)/", $_REQUEST['filter'], $match)) {
  140. $wc = "WHERE pid = '{$match[1]}'";
  141. } else {
  142. $wc = '';
  143. }
  144. break;
  145. }
  146. }
  147. $res = null;
  148. if (isset($_REQUEST['switch_name'])) {
  149. $sql = "SELECT * FROM DEVICE_MAP WHERE serial_number LIKE :swname1 OR assigned_switch LIKE :swname2 ORDER BY LPAD(lower(serial_number), 10, 0)";
  150. try {
  151. $res = $dbh->prepare($sql);
  152. $res->execute(['swname1' => "%{$_REQUEST['switch_name']}%", 'swname2' => "%{$_REQUEST['switch_name']}%"]);
  153. } catch (PDOException $e) {
  154. echo "<p><font color=\"red\">Error querying for physical switches: {$e->getMessage()}</font></p>\r\n";
  155. exit(1);
  156. }
  157. } else {
  158. $sql = 'SELECT * FROM DEVICE_MAP ' . $wc . ' ORDER BY LPAD(lower(serial_number), 10, 0)';
  159. try {
  160. $res = $dbh->query($sql);
  161. } catch (PDOException $e) {
  162. echo "<p><font color=\"red\">Error querying for physical switches: {$e->getMessage()}</font></p>\r\n";
  163. exit(1);
  164. }
  165. }
  166. $sql = 'SELECT name, pid FROM SWITCHES WHERE ip_address IS NOT NULL ORDER BY name';
  167. $ls_res = null;
  168. try {
  169. $ls_res = $dbh->query($sql);
  170. } catch (PDOException $e) {
  171. echo "<p><font color=\"red\">Error querying for logical switches: {$e->getMessage()}</font></p>\r\n";
  172. exit(1);
  173. }
  174. $lswitches = array();
  175. while ($row = $ls_res->fetch()) {
  176. if (!isset($lswitches[$row['pid']])) {
  177. $lswitches[$row['pid']] = array('__BOGUS__', $row['name']);
  178. } else {
  179. array_push($lswitches[$row['pid']], $row['name']);
  180. }
  181. }
  182. $switches = array();
  183. while ($row = $res->fetch()) {
  184. array_push($switches, $row);
  185. }
  186. $sql = 'SELECT DISTINCT(pid) AS pid FROM DEVICE_MAP';
  187. try {
  188. $res = $dbh->query($sql);
  189. } catch (PDOException $e) {
  190. echo "<p><font color=\"red\">Error querying for PIDs: {$e->getMessage()}</font></p>\r\n";
  191. exit(1);
  192. }
  193. $pids = array();
  194. while ($row = $res->fetch()) {
  195. $pids[$row['pid']] = true;
  196. }
  197. $sql = 'SELECT assigned_switch FROM DEVICE_MAP WHERE assigned_switch IS NOT NULL';
  198. try {
  199. $res = $dbh->query($sql);
  200. } catch (PDOException $e) {
  201. echo "<p><font color=\"red\">Error querying for assigned switches: {$e->getMessage()}</font></p>\r\n";
  202. exit(1);
  203. }
  204. $used = array();
  205. while ($row = $res->fetch()) {
  206. $used[$row['assigned_switch']] = true;
  207. }
  208. $filt = null;
  209. if (!isset($_REQUEST['filter'])) {
  210. $filt = '';
  211. } else {
  212. $filt = $_REQUEST['filter'];
  213. }
  214. print_header(TOOL_NAME . ': Physical Switches');
  215. ?>
  216. <body class="flex">
  217. <script language="javascript">
  218. var deletes = 0;
  219. var PROVISION_UNKNOWN = <?= PROVISION_UNKNOWN ?>;
  220. var PROVISION_IN_PROGRESS = <?= PROVISION_IN_PROGRESS ?>;
  221. var PROVISION_FAIL = <?= PROVISION_FAIL ?>;
  222. var PROVISION_SUCCESS = <?= PROVISION_SUCCESS ?>;
  223. var REACHABILITY_NEVER_REACHABLE = <?= REACHABILITY_NEVER_REACHABLE ?>;
  224. var REACHABILITY_NOW_UNREACHABLE = <?= REACHABILITY_NOW_UNREACHABLE ?>;
  225. var REACHABILITY_REACHABLE = <?= REACHABILITY_REACHABLE ?>;
  226. var row_intervals = {};
  227. function refresh() {
  228. $.ajax({
  229. url: '<?= $base ?>/get_dev_stats.php',
  230. dataType: 'json',
  231. success: function (data) {
  232. $.each(data.response, function (k, v) {
  233. var rtext = '&nbsp;';
  234. var color = '#FFFFFF';
  235. var rtitle = 'Not yet assigned';
  236. var prs = v.provisioned_status;
  237. var ds = v.device_status;
  238. if (prs == PROVISION_SUCCESS) {
  239. color = '#00FF00';
  240. rtitle = 'Bootstrap validated successfully';
  241. rtext += '&nbsp;&nbsp;&nbsp;';
  242. } else if (prs == PROVISION_UNKNOWN || prs == PROVISION_IN_PROGRESS) {
  243. color = '#919191';
  244. rtitle = 'Not yet bootstrapped';
  245. if (prs == PROVISION_IN_PROGRESS) {
  246. rtitle = 'Bootstrapping in progress';
  247. rtext += '&nbsp;';
  248. }
  249. } else {
  250. color = '#FF0000';
  251. rtitle = 'Bootstrap validation failed';
  252. rtext += '&nbsp;&nbsp;';
  253. }
  254. rtext += '<input type="hidden" id="pros' + k + '" value="' + prs + '">';
  255. if (prs != PROVISION_IN_PROGRESS) {
  256. if ('undefined' !== typeof row_intervals[k]) {
  257. $('#psr_' + k).stop(true, true);
  258. clearInterval(row_intervals[k]);
  259. $('#psr_' + k).stop(true, true);
  260. }
  261. }
  262. $('#psr_' + k).css('background', color);
  263. $('#psr_' + k).html('<span style="display: none">' + prs + '</span>' + rtext);
  264. $('#psr_' + k).attr('title', rtitle);
  265. if (prs == PROVISION_IN_PROGRESS) {
  266. if ('undefined' !== typeof row_intervals[k]) {
  267. clearInterval(row_intervals[k]);
  268. $('#psr_' + k).stop(true, true);
  269. }
  270. var pulseint = setInterval(function () {
  271. $('#psr_' + k).animate({
  272. backgroundColor: '#919191',
  273. }, 1000).animate({
  274. backgroundColor: '#f5f5f5',
  275. }, 1000);
  276. }, 1500);
  277. row_intervals[k] = pulseint;
  278. }
  279. color = '#FFFFFF';
  280. rtext = '&nbsp;';
  281. rtitle = 'Not yet assigned';
  282. if (ds == REACHABILITY_NEVER_REACHABLE && prs == PROVISION_SUCCESS) {
  283. color = '#FF0000';
  284. rtitle = 'Device was never reachable';
  285. } else if (ds == REACHABILITY_NEVER_REACHABLE) {
  286. color = '#919191';
  287. rtitle = 'Not yet bootstrapped';
  288. rtext += '&nbsp;';
  289. } else if (ds == REACHABILITY_NOW_UNREACHABLE) {
  290. color = '#FFFF00';
  291. rtitle = 'Device has been reachable, but is not reachable now';
  292. rtext += '&nbsp;&nbsp;';
  293. } else {
  294. color = '#00FF00';
  295. rtitle = 'Device is reachable';
  296. rtext += '&nbsp;&nbsp;&nbsp;';
  297. }
  298. $('#dsr_' + k).css('background', color);
  299. $('#dsr_' + k).html('<span style="display: none">' + ds + '</span>' + rtext);
  300. $('#dsr_' + k).attr('title', rtitle);
  301. });
  302. },
  303. complete: function (xhr, message) {
  304. setTimeout(refresh, 30000);
  305. }
  306. });
  307. }
  308. function reztp_all() {
  309. if ($('#reztp_all_box').is(':checked')) {
  310. $('.reztp').each(function () {
  311. $(this).prop('checked', true);
  312. });
  313. } else {
  314. $('.reztp').each(function () {
  315. $(this).prop('checked', false);
  316. });
  317. }
  318. return true;
  319. }
  320. function toggle_reztp_all(elem) {
  321. if (!$(elem).is(':checked')) {
  322. $('#reztp_all_box').prop('checked', false);
  323. }
  324. }
  325. function check_confirm() {
  326. var delete_conf = true;
  327. var reztp_conf = true;
  328. if (deletes > 0) {
  329. delete_conf = confirm("Are you sure you want to delete these " + deletes + " physical switch(es)?");
  330. }
  331. $('.reztp').each(function () {
  332. if ($(this).is(':checked')) {
  333. one_checked = true;
  334. return;
  335. }
  336. });
  337. if (one_checked) {
  338. reztp_conf = confirm("Are you sure you want to re-ZTP these switches?");
  339. }
  340. return reztp_conf && delete_conf;
  341. }
  342. if (window.history.replaceState) {
  343. window.history.replaceState(null, null, window.location.href);
  344. }
  345. $(document).ready(function () {
  346. $('#devtable').DataTable({
  347. "scrollY": "400px",
  348. "scrollCollapse": true,
  349. "paging": false
  350. });
  351. refresh();
  352. });
  353. </script>
  354. <div id="headswreg">
  355. <div class="apage">
  356. <div id="header">
  357. <h1>
  358. <?= TOOL_NAME ?>: Physical Switches
  359. </h1>
  360. </div>
  361. <br />
  362. </div>
  363. </div>
  364. <div class="apage">
  365. <form method="POST" name="search_form" action="<?= $_SERVER['PHP_SELF'] ?>">
  366. <table class="noborder" summary="Filter Table">
  367. <tr>
  368. <td class="left_act">Show Only:
  369. <select name="filter" onChange="MM_jumpMenu('parent', this, 0)">
  370. <option value="<?= $_SERVER['PHP_SELF'] ?>?filter=a" <?= ($filt == 'a') ? 'selected' : '' ?>>All</option>
  371. <option value="<?= $_SERVER['PHP_SELF'] ?>?filter=p" <?= ($filt == 'p') ? 'selected' : '' ?>>Assigned
  372. </option>
  373. <option value="<?= $_SERVER['PHP_SELF'] ?>?filter=up" <?= ($filt == 'up') ? 'selected' : '' ?>>Unassigned
  374. </option>
  375. <option value="<?= $_SERVER['PHP_SELF'] ?>?filter=vu" <?= ($filt == 'vu') ? 'selected' : '' ?>>Not Yet
  376. Bootstrapped</option>
  377. <option value="<?= $_SERVER['PHP_SELF'] ?>?filter=vi" <?= ($filt == 'vi') ? 'selected' : '' ?>>Bootstrapping
  378. In
  379. Progress</option>
  380. <option value="<?= $_SERVER['PHP_SELF'] ?>?filter=vf" <?= ($filt == 'vf') ? 'selected' : '' ?>>Verification
  381. Failed</option>
  382. <option value="<?= $_SERVER['PHP_SELF'] ?>?filter=vs" <?= ($filt == 'vs') ? 'selected' : '' ?>>Verification
  383. Succeeded</option>
  384. <option value="<?= $_SERVER['PHP_SELF'] ?>?filter=r" <?= ($filt == 'r') ? 'selected' : '' ?>>Reachable
  385. </option>
  386. <option value="<?= $_SERVER['PHP_SELF'] ?>?filter=ur" <?= ($filt == 'ur') ? 'selected' : '' ?>>Unreachable
  387. </option>
  388. <?php
  389. foreach ($pids as $lsp => $value) {
  390. $selected = ($filt == "pid:$lsp") ? 'selected' : ''; ?>
  391. <option value="<?= $_SERVER['PHP_SELF'] ?>?filter=pid:<?= $lsp ?>" <?= $selected ?>>
  392. <?= $lsp ?>
  393. </option>
  394. <?php
  395. }
  396. ?>
  397. </select>
  398. </td>
  399. <td class="right">Switch Search:
  400. <input type="text" size="16" name="switch_name"
  401. value="<?= (isset($_REQUEST['switch_name'])) ? $_REQUEST['switch_name'] : '' ?>">
  402. <input type="image" value="Submit" name="search" src="/images/submit_button.png">
  403. </td>
  404. </tr>
  405. </table>
  406. </form>
  407. <br />
  408. <table class="noborder" summary="Control Table">
  409. <tr>
  410. <td class="left"><a href="<?= $base ?>/add_phys.php">Add Physical Switch</a> |
  411. <?php
  412. if (EXPORT_PRIME === true) {
  413. ?>
  414. <a href="#" onClick="window.open('<?= $base ?>/export.php')">Export to Prime / DNS</a> |
  415. <?php
  416. }
  417. if (EXPORT_DEADMAN === true) {
  418. ?>
  419. <a href="#" onClick="window.open('<?= $base ?>/export_deadman.php')">Export To Ansible</a> |
  420. <?php
  421. } ?>
  422. <a href="<?= $base ?>/logicsw.php">Logical Switches</a>
  423. </td>
  424. </tr>
  425. </table>
  426. <form name="mod_phys_switch_form" method="POST" action="<?= $_SERVER['PHP_SELF'] ?>"
  427. onSubmit='return check_confirm();'>
  428. <?php
  429. foreach (array_merge($_GET, $_POST) as $name => $value) {
  430. if (!is_array($value)) {
  431. ?>
  432. <input type="hidden" name="<?= $name ?>" value="<?= $value ?>">
  433. <?php
  434. }
  435. }
  436. ?>
  437. <div class="btable">
  438. <table summary="Button Table" width="100%" cellspacing="0">
  439. <tr>
  440. <td><input type="reset" value="Reset" name="reset">
  441. <input type="submit" value="Submit" name="submit">
  442. </td>
  443. </tr>
  444. </table>
  445. </div>
  446. <br />
  447. <div align="center">
  448. <?php
  449. foreach ($errors as $error) {
  450. ?>
  451. <p class="error">
  452. <?= $error ?>
  453. </p>
  454. <?php
  455. }
  456. ?>
  457. </div>
  458. <div class="maintable">
  459. <table id="devtable" class="cell-border compact" width="100%" cellspacing="0" summary="Physical Switch Table">
  460. <thead>
  461. <tr>
  462. <th class="headlink">Row No.</th>
  463. <th class="headlink">Delete?</th>
  464. <th class="headlink">Assigned?</th>
  465. <th class="headlink">Re-ZTP? <input type="checkbox" id="reztp_all_box" onchange="return reztp_all();">
  466. </th>
  467. <th class="headlink">Serial Number</th>
  468. <th class="headlink">Product ID</th>
  469. <th class="headlink">Max Ports</th>
  470. <th class="headlink">Assigned Logical<br />Switch</th>
  471. <th class="headlink">Provision<br />Status</th>
  472. <th class="headlink">Reachability</th>
  473. </tr>
  474. </thead>
  475. <tbody>
  476. <?php
  477. $i = 0;
  478. foreach ($switches as $row) {
  479. $sn = $row['serial_number'];
  480. $checked = false;
  481. $will_rz = false;
  482. if ($row['checked_out'] == 1) {
  483. $checked = true;
  484. }
  485. if ($row['should_re_ztp'] > 0) {
  486. $will_rz = true;
  487. } ?>
  488. <tr>
  489. <td>
  490. <?= $i + 1 ?>.
  491. </td>
  492. <td><input type="checkbox" name="delete[<?= $sn ?>]" value="1"
  493. onClick="if (this.checked == true) { deletes++; } else { deletes--; }"></td>
  494. <td><input type="hidden" name="prev_checked[<?= $sn ?>]" value="<?= $row['checked_out'] ?>">
  495. <input id="checked_<?= $i ?>" type="checkbox" name="checked[<?= $sn ?>]" value="1" <?= ($checked) ? 'checked' : '' ?>>
  496. </td>
  497. <td><input id="reztp_<?= $i ?>" class="reztp" type="checkbox" name="reztp[<?= $sn ?>]" value="1"
  498. onchange="toggle_reztp_all(this);" <?= ($will_rz) ? 'disabled' : '' ?>></td>
  499. <td>
  500. <?= $row['serial_number'] ?>
  501. </td>
  502. <td>
  503. <?= $row['pid'] ?>
  504. </td>
  505. <td>
  506. <?= $row['max_ports'] ?>
  507. </td>
  508. <td><input type="hidden" name="prev_assigned_switch[<?= $sn ?>]" value="<?= $row['assigned_switch'] ?>">
  509. <select id="asw<?= $i ?>" name="assigned_switch[<?= $sn ?>]"
  510. onChange='var elem = document.getElementById("checked_<?= $i ?>"); if (this.value == "__BOGUS__") { elem.checked = false; } else { elem.checked = true; }'>
  511. <?php
  512. $has_avail = false;
  513. foreach ($lswitches[$row['pid']] as $lsw) {
  514. $selected = ($row['assigned_switch'] == $lsw) ? 'selected' : '';
  515. if ($selected == '' && isset($used[$lsw]) && $used[$lsw] === true) {
  516. continue;
  517. }
  518. if ($lsw == '__BOGUS__') {
  519. ?>
  520. <option value="__BOGUS__" <?= $selected ?>>--Please Select--</option>
  521. <?php
  522. } else {
  523. $has_avail = true; ?>
  524. <option value="<?= $lsw ?>" <?= $selected ?>>
  525. <?= $lsw ?>
  526. </option>
  527. <?php
  528. }
  529. }
  530. if (!$has_avail) {
  531. ?>
  532. <option value="__BOGUS__" <?= $selected ?>>--Please Select--</option>
  533. <?php
  534. } ?>
  535. </select>
  536. &nbsp;<a href="#"
  537. onClick='var lsw = document.getElementById("asw<?= $i ?>"); if (lsw.value == "__BOGUS__") { alert("There is no logical switch associated to this device."); return false; } else { window.open("<?= $base ?>/logicsw.php?switch_name=" + lsw.value, "Logical switch " + lsw.value, "height=480,width=1048"); return false; }'><img
  538. src="/images/switch.gif" border="0" title="View logical switch"></a>&nbsp;<a href="#"
  539. onClick='var pros = document.getElementById("pros<?= $row['serial_number'] ?>"); var lsw = document.getElementById("asw<?= $i ?>"); if (pros.value < PROVISION_FAIL) { alert("This switch config has not yet been generated."); return false; } else { window.open("<?= $base ?>/show_config.php?cfg=" + lsw.value + "-config.txt&dname=" + lsw.value, "Config for switch " + lsw.value, "height=650,width=980"); return false; }'><img
  540. src="/images/mag.gif" border="0" title="View switch config"></a>
  541. </td>
  542. <?php
  543. $color = '#FFFFFF';
  544. $rtext = 'N/A';
  545. $rtitle = 'Not yet assigned'; ?>
  546. <td id="psr_<?= $row['serial_number'] ?>" style="background: <?= $color ?>;" title="<?= $rtitle ?>"><input
  547. type="hidden" id="pros<?= $row['serial_number'] ?>" value="<?= $row['provisioned_status'] ?>"><span
  548. style="display: none">
  549. <?= $row['provisioned_status'] ?>
  550. </span>
  551. <?= $rtext ?>
  552. </td>
  553. <?php
  554. $color = '#FFFFFF';
  555. $rtext = 'N/A';
  556. $rtitle = 'Not yet assigned'; ?>
  557. <td id="dsr_<?= $row['serial_number'] ?>" style="background: <?= $color ?>;" title="<?= $rtitle ?>"><span
  558. style="display: none">
  559. <?= $row['device_status'] ?>
  560. </span>
  561. <?= $rtext ?>
  562. </td>
  563. </tr>
  564. <?php
  565. ++$i;
  566. }
  567. ?>
  568. </tbody>
  569. </table>
  570. </div>
  571. <br />
  572. <div class="btable">
  573. <table summary="Button Table" width="100%" cellspacing="0">
  574. <tr>
  575. <td><input type="reset" value="Reset" name="reset">
  576. <input type="submit" value="Submit" name="submit">
  577. </td>
  578. </tr>
  579. </table>
  580. </div>
  581. </form>
  582. </div>
  583. </body>
  584. </html>
  585. <?php
  586. cleanup();
  587. ?>