/[marcuscom]/switch-ztp/trunk/www/logicsw.php
ViewVC logotype

Contents of /switch-ztp/trunk/www/logicsw.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20639 - (show annotations) (download)
Thu Jul 25 13:51:36 2019 UTC (8 months, 1 week ago) by jclarke
File size: 19704 byte(s)
Don't update the last change date so much.

1 <?php
2 //-
3 // Copyright (c) 2011-2018 Joe Clarke <jclarke@cisco.com>
4 // All rights reserved.
5
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions
8 // are met:
9 // 1. Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // 2. Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14
15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 // SUCH DAMAGE.
26
27 include_once 'db.inc.php';
28 include_once 'swreg/swreg.inc.php';
29 require_once 'Log.php';
30 require_once 'functions.php';
31
32 $dsn = "$db_driver:host=$db_host;dbname=$db_name";
33
34 $options = [
35 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
36 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
37 PDO::ATTR_EMULATE_PREPARES => false,
38 ];
39
40 try {
41 $dbh = new PDO($dsn, $db_user, $db_pass, $options);
42 } catch (PDOException $e) {
43 die($e->getMessage());
44 }
45 $logger = Log::singleton('file', LOGFILE, TOOL_NAME.' : Logical Switches');
46 if ($logger === false) {
47 die("Failed to open logfile.\n");
48 }
49 $mask = Log::UPTO(LOG_LEVEL);
50 $logger->setMask($mask);
51
52 $base = get_base($_SERVER['SCRIPT_NAME']);
53 $ruser = '<AUTHENTICATION NOT ENABLED>';
54 if (isset($_SERVER['REMOTE_USER'])) {
55 $ruser = $_SERVER['REMOTE_USER'];
56 }
57
58 if (isset($_REQUEST['submit_top']) || isset($_REQUEST['submit_bottom'])) {
59 $pia = $_REQUEST['prev_ip_address'];
60 $ppid = $_REQUEST['prev_pid'];
61 $ploc = $_REQUEST['prev_location'];
62 $pidf = $_REQUEST['prev_is_idf'];
63 $pexp = (isset($_REQUEST['prev_exception'])) ? $_REQUEST['prev_exception'] : array();
64 $ia = $_REQUEST['address'];
65 $pid = $_REQUEST['pid'];
66 $loc = $_REQUEST['location'];
67 $exp = $_REQUEST['exception'];
68 $idf = (isset($_REQUEST['is_idf'])) ? $_REQUEST['is_idf'] : array();
69 $d = (isset($_REQUEST['delete'])) ? $_REQUEST['delete'] : array();
70 $made_change = false;
71 foreach ($pia as $sname => $value) {
72 $curr_del = (isset($d[$sname])) ? $d[$sname] : 0;
73 $errors = array();
74 if ($curr_del == 1) {
75 if ($ia[$sname] !== null && $ia[$sname] != '') {
76 $sql = 'UPDATE ADDRESSES SET used=? WHERE address=?';
77 try {
78 $sth = $dbh->prepare($sql);
79 $sth->execute(array('0', $ia[$sname]));
80 $sth->closeCursor();
81 } catch (PDOException $e) {
82 array_push($errors, "Failed to free IP address {$ia[$sname]}: {$e->getMessage()}");
83 }
84 }
85 $sql = "DELETE FROM DEVICE_MAP WHERE assigned_switch='{$sname}'";
86 try {
87 $dbh->query($sql);
88 } catch (PDOException $e) {
89 array_push($errors, "Failed to delete {$sname}: {$e->getMessage()}");
90 }
91 $sql = "DELETE FROM SWITCHES WHERE name='{$sname}'";
92 try {
93 $dbh->query($sql);
94 $logger->info("User {$ruser} deleted logical switch {$sname}");
95 } catch (PDOException $e) {
96 array_push($errors, "Failed to delete {$sname}: {$e->getMessage()}");
97 }
98 if (count($errors) == 0) {
99 $made_change = true;
100 @unlink(PORT_TMPL_DIR.'/devices/'."{$sname}-ports.tmpl");
101 }
102 continue;
103 }
104 $curr_idf = (isset($idf[$sname])) ? $idf[$sname] : 0;
105 if (!isset($ppid[$sname]) || $ppid[$sname] == '') {
106 $ppid[$sname] = '__BOGUS__';
107 }
108 if (!isset($pexp[$sname]) || $pexp[$sname] == '') {
109 $pexp[$sname] = '__BOGUS__';
110 }
111 if ($value != $ia[$sname] || $ploc[$sname] != $loc[$sname] || $ppid[$sname] != $pid[$sname] || $pidf[$sname] != $curr_idf) {
112 if ($pid[$sname] == '__BOGUS__') {
113 array_push($errors, "You must select a Product ID for {$sname}");
114 }
115 $sql = "SELECT address, reserved FROM ADDRESSES WHERE address='{$ia[$sname]}'";
116 $res = null;
117 try {
118 $res = $dbh->query($sql);
119 } catch (PDOException $e) {
120 }
121 $row = $res->fetch();
122 $newa = "'{$ia[$sname]}'";
123 if ($ia[$sname] != '' && !$row['address']) {
124 array_push($errors, "IP address {$ia[$sname]} is not valid for switch {$sname}");
125 } elseif ((ADDRESS_SCHEME == 'IDF' && $row['reserved'] == 1 && $curr_idf != 1) || (ADDRESS_SCHEME != 'IDF' && ADDRESS_SCHEME != 'DNS' && $row['reserved'] == 1)) {
126 array_push($errors, "IP address {$ia[$sname]} is reserved and cannot be used for this switch");
127 } elseif ($ia[$sname] == '') {
128 $newa = 'NULL';
129 }
130 if (count($errors) == 0) {
131 $sql = "UPDATE SWITCHES SET ip_address = $newa, location = '{$loc[$sname]}', pid = '{$pid[$sname]}', is_idf = '{$curr_idf}' WHERE name='{$sname}'";
132 try {
133 $res = $dbh->query($sql);
134 $logger->info("User {$ruser} updated logical switches: location={$loc[$sname]}, pid={$pid[$sname]}, is_idf={$curr_idf} for switch {$sname}");
135 if ($ia[$sname] != '') {
136 $sql = 'UPDATE ADDRESSES SET used=? WHERE address=?';
137 try {
138 $sth = $dbh->prepare($sql);
139 $sth->execute(array('0', $ia[$sname]));
140 $sth->closeCursor();
141 $logger->info("User {$ruser} released address {$ia[$sname]}");
142 } catch (PDOException $ie) {
143 array_push($errors, "Failed to update address usage for $sname: '{$ie->getMessage()}'");
144 }
145 }
146 if ($newa != 'NULL') {
147 $sql = 'UPDATE ADDRESSES SET used=? WHERE address=?';
148 try {
149 $sth = $dbh->prepare($sql);
150 $sth->execute(array('1', $newa));
151 $sth->closeCursor();
152 $logger->info("User {$ruser} allocated address {$newa} for {$sname}");
153 } catch (PDOException $ie) {
154 array_push($errors, "Failed to update address usage for $sname: '{$ie->getMessage()}'");
155 }
156 }
157 } catch (PDOException $e) {
158 array_push($errors, "Failed to update $sname: '{$e->getMessage()}'");
159 }
160 }
161 }
162 if (count($errors) == 0) {
163 $made_change = true;
164 if ($pexp[$sname] != $exp[$sname]) {
165 if ($exp[$sname] != '__BOGUS__') {
166 @symlink(PORT_PROFILE_DIR.'/'.$exp[$sname], PORT_TMPL_DIR.'/devices/'."{$sname}-ports.tmpl");
167 } else {
168 @unlink(PORT_TMPL_DIR.'/devices/'."{$sname}-ports.tmpl");
169 }
170 }
171 }
172 }
173 if ($made_change) {
174 $now = time();
175 $sql = 'UPDATE SYS_PROPERTIES SET value=? WHERE name=?';
176 try {
177 $sth = $dbh->prepare($sql);
178 $sth->execute([$now, 'last_logic_update']);
179 $sth->closeCursor();
180 $logger->info("User {$ruser} updated the last logic date");
181 } catch (PDOException $e) {
182 array_push($errors, "Failed to update the last logic update date: '{$e->getMessage()}'");
183 }
184 }
185 }
186
187 $wc = '';
188 if (isset($_REQUEST['filter'])) {
189 switch ($_REQUEST['filter']) {
190 case 'a':
191 $wc = '';
192 break;
193 case 'u':
194 $wc = ' WHERE ip_address IS NULL';
195 break;
196 default:
197 if (preg_match("/^pid:([\w\d-]+)/", $_REQUEST['filter'], $match)) {
198 if (array_search($match[1], $ZTP_PIDS) === false) {
199 $wc = '';
200 } else {
201 $wc = " WHERE pid = '{$match[1]}'";
202 }
203 } elseif (preg_match("/^mdf:([\w\d-_]+)/", $_REQUEST['filter'], $match)) {
204 if (array_search($match[1], $MDFS) === false) {
205 $wc = '';
206 } else {
207 $wc = ", ADDRESSES WHERE SWITCHES.ip_address = ADDRESSES.address AND ADDRESSES.location = '{$match[1]}'";
208 }
209 } else {
210 $wc = '';
211 }
212 break;
213 }
214 }
215
216 $res = null;
217 if (isset($_REQUEST['switch_name'])) {
218 $sql = 'SELECT * FROM SWITCHES WHERE name LIKE :swname1 OR ip_address LIKE :swname2 ORDER BY name';
219 try {
220 $res = $dbh->prepare($sql);
221 $res->execute(['swname1' => "%{$_REQUEST['switch_name']}%", 'swname2' => "%{$_REQUEST['switch_name']}%"]);
222 } catch (PDOException $e) {
223 echo "<p><font color=\"red\">Error querying for logical switches: {$e->getMessage()}</font></p>\r\n";
224 exit(1);
225 }
226 } else {
227 $sql = 'SELECT SWITCHES.* FROM SWITCHES '.$wc.' ORDER BY name';
228 try {
229 $res = $dbh->query($sql);
230 } catch (PDOException $e) {
231 echo "<p><font color=\"red\">Error querying for logical switches: {$e->getMessage()}</font></p>\r\n";
232 exit(1);
233 }
234 }
235
236 $switches = array();
237 while ($row = $res->fetch()) {
238 array_push($switches, $row);
239 }
240
241 $sql = 'SELECT ip_address FROM SWITCHES WHERE ip_address IS NOT NULL';
242 try {
243 $res = $dbh->query($sql);
244 } catch (PDOException $e) {
245 echo "<p><font color=\"red\">Error querying for used IP addresses: {$e->getMessage()}</font></p>\r\n";
246 exit(1);
247 }
248
249 $used = array();
250 while ($row = $res->fetch()) {
251 $used[$row['ip_address']] = true;
252 }
253
254 $sql = 'SELECT * FROM EXCEPTIONS';
255 try {
256 $res = $dbh->query($sql);
257 } catch (PDOException $e) {
258 echo "<p><font color=\"red\">Error querying for exceptions: {$e->getMessage()}</font></p>\r\n";
259 exit(1);
260 }
261
262 $exceptions = array();
263 while ($row = $res->fetch()) {
264 $exceptions[$row['name']] = array($row['pid'], $row['path']);
265 }
266
267 $filter = '';
268 if (isset($_REQUEST['filter'])) {
269 $filter = $_REQUEST['filter'];
270 }
271
272 print_header(TOOL_NAME.': Logical Switches');
273 ?>
274 <body class="flex">
275 <script language="javascript">
276 var deletes = 0;
277
278 var prop_list = ['location', 'ip_address', 'is_idf', 'pid', 'exception'];
279
280 function refresh() {
281 $.ajax({
282 url: '<?=$base?>/get_logicsw_details.php',
283 dataType: 'json',
284 success: function(data) {
285 $.each(data.response, function(k, v) {
286 $.each(prop_list, function(pi, p) {
287 if (v[p] != $('#prev_' + p + '_' + k).val()) {
288 if ($('#' + p + '_' + k).val() != $('#prev_' + p + '_' + k).val()) {
289 $('#' + p + '_' + k).css({
290 'border-style': 'solid',
291 'border-color': 'red'
292 });
293 $('input').prop('disabled', true);
294 $('select').prop('disabled', true);
295 $('#err_div').html('<p class="error">Conflicting change detected; reload page to continue.</p>');
296 return;
297 } else {
298 $('#prev_' + p + '_' + k).val(v[p]);
299 if ($('#' + p + '_' + k).attr('type') == 'checkbox') {
300 $('#' + p + '_' + k).prop('checked', (v[p] == 1));
301 } else if ($('#' + p + '_' + k).attr('type') == 'select' && v[p] == '') {
302 $('#' + p + '_' + k).val('__BOGUS__');
303 } else {
304 $('#' + p + '_' + k).val(v[p]);
305 }
306 }
307 }
308 });
309 });
310 },
311 complete: function(xhr, message) {
312 setTimeout(refresh, 5000);
313 }
314 });
315 }
316
317 $(document).ready(function() {
318 $('#devtable').DataTable({
319 "scrollY": "400px",
320 "scrollCollapse": true,
321 "paging": false
322 });
323 refresh();
324 });
325 </script>
326 <div id="headswreg">
327 <div class="apage">
328 <div id="header">
329 <h1><?=TOOL_NAME?>: Logical Switches</h1>
330 </div>
331 <br/>
332 </div>
333 </div>
334 <div class="apage">
335 <form method="POST" name="search_form" action="<?=$_SERVER['PHP_SELF']?>">
336 <table class="noborder" summary="Filter Table">
337 <tr>
338 <td class="left_act">Show Only Switches In:
339 <select name="filter" onChange="MM_jumpMenu('parent', this, 0)">
340 <option value="<?=$_SERVER['PHP_SELF']?>?filter=a" <?=($filter == 'a') ? 'selected' : ''?>>All</option>
341 <?php
342 foreach ($MDFS as $m) {
343 ?>
344 <option value="<?=$_SERVER['PHP_SELF']?>?filter=<?=$m?>" <?=($filter == $m) ? 'selected' : ''?>><?=$m?></option>
345 <?php
346 }
347 ?>
348 <option value="<?=$_SERVER['PHP_SELF']?>?filter=u" <?=($filter == 'u') ? 'selected' : ''?>>No IP Assigned</option>
349 <?php
350 foreach ($ZTP_PIDS as $spid) {
351 $selected = ($filter == "pid:$spid") ? 'selected' : ''; ?>
352 <option value="<?=$_SERVER['PHP_SELF']?>?filter=pid:<?=$spid?>" <?=$selected?>><?=$spid?></option>
353 <?php
354 }
355 ?>
356 </select></td>
357 <td class="right">Switch Search:
358 <input type="text" size="16" name="switch_name" value="<?=(isset($_REQUEST['switch_name'])) ? $_REQUEST['switch_name'] : ''?>">
359 <input type="image" value="Submit" name="search" src="/images/submit_button.png">
360 </td>
361 </tr>
362 </table>
363 </form>
364 <br/>
365 <table class="noborder" summary="Control Table">
366 <tr>
367 <td class="left"><a href="<?=$base?>/add_logic.php">Add Logical Switch</a> |
368 <a href="<?=$base?>/index.php">Physical Switches</a> |
369 <a href="<?=$base?>/port_profiles.php">Port Profiles</a></td>
370 </tr>
371 </table>
372 <form name="mod_logic_switch_form" method="POST" action="<?=$_SERVER['PHP_SELF']?>" onSubmit='if (deletes > 0) { return confirm("Are you sure you want to delete these " + deletes + " logical switch(es)?"); }'>
373 <?php
374 foreach (array_merge($_GET, $_POST) as $name => $value) {
375 if (!is_array($value)) {
376 ?>
377 <input type="hidden" name="<?=$name?>" value="<?=$value?>">
378 <?php
379 }
380 }
381 ?>
382 <div class="fbtable">
383 <table summary="Button Table" width="100%" cellspacing="0">
384 <tr>
385 <td><input type="reset" value="Reset" name="reset">
386 <input type="submit" value="Submit" id="submit_top" name="submit_top"></td>
387 </tr>
388 </table>
389 </div>
390 <br/>
391 <div id="err_div" align="center">
392 <?php
393 foreach ($errors as $error) {
394 ?>
395 <p class="error"><?=$error?></p>
396 <?php
397 }
398 ?>
399 </div>
400 <div class="fulltable">
401 <table id="devtable" class="display compact" width="100%" cellspacing="0" summary="Logical Switch Table">
402 <thead>
403 <tr>
404 <th class="headlink">Row No.</th>
405 <th class="headlink">Delete?</th>
406 <th class="headlink">Name</th>
407 <th class="headlink">Is IDF?</th>
408 <th class="headlink">IP Address</th>
409 <th class="headlink">Product ID</th>
410 <th class="headlink">SNMP Location</th>
411 <!--<th class="headlink">Ports Required</th>-->
412 <th class="headlink">Port Profile</th>
413 </tr>
414 </thead>
415 <tbody>
416 <?php
417 $i = 0;
418 foreach ($switches as $row) {
419 $name = $row['name']; ?>
420 <tr>
421 <td><?=$i + 1?>.</td>
422 <td><input type="checkbox" name="delete[<?=$name?>]" value="1" onClick="if (this.checked == true) { deletes++; } else { deletes--; }"></td>
423 <td><?=$name?></td>
424 <td><input type="hidden" id="prev_is_idf_<?=$name?>" name="prev_is_idf[<?=$name?>]" value="<?=$row['is_idf']?>">
425 <input type="checkbox" id="is_idf_<?=$name?>" name="is_idf[<?=$name?>]" value="1" <?=($row['is_idf'] == 1) ? 'checked' : ''?>></td>
426 <td><input type="hidden" id="prev_ip_address_<?=$name?>" name="prev_ip_address[<?=$name?>]" value="<?=$row['ip_address']?>">
427 <input type="text" id="ip_address_<?=$name?>" name="address[<?=$name?>]" size="16" value="<?=$row['ip_address']?>"></td>
428 <td><input type="hidden" id="prev_pid_<?=$name?>" name="prev_pid[<?=$name?>]" value="<?=$row['pid']?>">
429 <select id="pid_<?=$name?>" name="pid[<?=$name?>]">
430 <?php
431 $pidarr = array_merge($ZTP_PIDS, array('__BOGUS__'));
432 foreach ($ZTP_PIDS as $p) {
433 $selected = ($row['pid'] == $p) ? 'selected' : '';
434 if ($p == '__BOGUS__') {
435 ?>
436 <option value="__BOGUS__" <?=$selected?>>--Please Select--</option>
437 <?php
438 } else {
439 ?>
440 <option value="<?=$p?>" <?=$selected?>><?=$p?></option>
441 <?php
442 }
443 } ?>
444 </select></td>
445 <td><input type="hidden" id="prev_location_<?=$name?>" name="prev_location[<?=$name?>]" value="<?=$row['location']?>">
446 <input id="location_<?=$name?>" type="text" name="location[<?=$name?>]" size="32" value="<?=$row['location']?>"></td>
447 <!--<td><?=$row['ports_required']?></td>-->
448 <?php
449 $tbase = '';
450 if (file_exists(PORT_TMPL_DIR.'/devices/'."{$name}-ports.tmpl")) {
451 $targ = readlink(PORT_TMPL_DIR.'/devices/'."{$name}-ports.tmpl");
452 $tbase = basename($targ);
453 } ?>
454 <td><input type="hidden" id="prev_exception_<?=$name?>" name="prev_exception_<?=$name?>" value="<?=$tbase?>">
455 <select id="exception_<?=$name?>" name="exception[<?=$name?>]">
456 <option value="__BOGUS__">--Please Select--</option>
457 <?php
458 foreach ($exceptions as $exname => $exarr) {
459 $path = $exarr[1];
460 $expid = $exarr[0];
461 $selected = '';
462 if ($path == $tbase) {
463 $selected = 'selected';
464 }
465 if ($selected == '' && $expid != $row['pid'] && $expid != '__ANY__') {
466 continue;
467 } ?>
468 <option value="<?=$path?>" <?=$selected?>><?=$exname?></option>
469 <?php
470 } ?>
471 </select>&nbsp;<a href="#" onClick='var pp = document.getElementById("exception_<?=$name?>"); if (pp.value == "__BOGUS__") { alert("There is no port profile associated to this logical switch."); return false; } else { window.open("<?=$base?>/show_config.php?type=profile&cfg=" + pp.value + "&dname=<?=$name?>", "Config for profile " + pp.value, "height=650,width=980"); return false; }'><img src="/images/mag.gif" border="0" title="View port profile"></td>
472 </tr>
473 <?php
474 ++$i;
475 }
476 ?>
477 </tbody>
478 </table>
479 </div>
480 <br/>
481 <div class="fbtable">
482 <table summary="Button Table" width="100%" cellspacing="0">
483 <tr>
484 <td><input type="reset" value="Reset" name="reset">
485 <input id="submit_bottom" type="submit" value="Submit" name="submit_bottom"></td>
486 </tr>
487 </table>
488 </div>
489 </form>
490 </div>
491 </body>
492 </html>
493 <?php
494 cleanup();
495 ?>

Properties

Name Value
mcom:nokeywords yes

  ViewVC Help
Powered by ViewVC 1.1.27