functions.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. <?php
  2. #-
  3. # Copyright (c) 2011-2016 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. #
  28. require_once 'Log.php';
  29. function cleanup() {
  30. global $logger, $dbh;
  31. $dbh->disconnect();
  32. $logger->close();
  33. }
  34. function print_header($title) {
  35. ?>
  36. <!DOCTYPE html>
  37. <html>
  38. <head>
  39. <title><?=$title?></title>
  40. <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
  41. <link rel="stylesheet" href="<?=get_base($_SERVER['SCRIPT_NAME'])?>/mini.css" type="text/css">
  42. <link rel="stylesheet" type="text/css" href="<?=get_base($_SERVER['SCRIPT_NAME'])?>/jquery.dataTables.min.css">
  43. <script language="javascript" src="<?=get_base($_SERVER['SCRIPT_NAME'])?>/jquery-1.12.3.js"></script>
  44. <script language="javascript" src="<?=get_base($_SERVER['SCRIPT_NAME'])?>/jquery.dataTables.min.js"></script>
  45. <script language="javascript" src="<?=get_base($_SERVER['SCRIPT_NAME'])?>/jquery.color-animation.js"></script>
  46. <script language="JavaScript" src="<?=get_base($_SERVER['SCRIPT_NAME'])?>/functions.js"></script>
  47. <style type="text/css">
  48. .style1 { font-family: "Trebuchet MS" }
  49. </style>
  50. <script language="javascript">
  51. <!--
  52. function MM_reloadPage(init) {
  53. if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
  54. document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; onresize=MM_reloadPage; }}
  55. else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) location.reload();
  56. }
  57. MM_reloadPage(true);
  58. //-->
  59. </script>
  60. </head>
  61. <?php
  62. }
  63. function get_row_color($row) {
  64. return (($row % 2 != 0) ? "bgcolor=\"#f0f0f0\"" : "");
  65. }
  66. function get_base($script) {
  67. $base = dirname($script);
  68. if ($base == "/") {
  69. $base = "";
  70. }
  71. return $base;
  72. }
  73. function generate_port_profile($start_port, $end_port, $vlan, $pid) {
  74. global $VLANS, $PID_MAP, $PORT_TYPES;
  75. $zpid = $pid;
  76. if (isset($PID_MAP[$pid])) {
  77. $zpid = $PID_MAP[$pid];
  78. }
  79. $profile = "interface range {$PORT_TYPES[$zpid]}$start_port - $end_port\n";
  80. if (file_exists(PORT_TMPL_DIR . '/ports.tmpl')) {
  81. $profile .= file_get_contents(PORT_TMPL_DIR . '/ports.tmpl');
  82. }
  83. if (file_exists(PORT_TMPL_DIR . '/' . $zpid . '/ports.tmpl')) {
  84. $profile .= file_get_contents(PORT_TMPL_DIR . '/' . $zpid . '/ports.tmpl');
  85. }
  86. if ($vlan == 'DYNAMIC') {
  87. if (file_exists(PORT_TMPL_DIR . '/DYNAMIC/ports.tmpl')) {
  88. $profile .= file_get_contents(PORT_TMPL_DIR . '/DYNAMIC/ports.tmpl');
  89. }
  90. if (file_exists(PORT_TMPL_DIR . '/DYNAMIC/' . $zpid . '/ports.tmpl')) {
  91. $profile .= file_get_contents(PORT_TMPL_DIR . '/DYNAMIC/' . $zpid . '/ports.tmpl');
  92. }
  93. } else if ($vlan == 'TRUNK' || $vlan == 'UPLINK TRUNK') {
  94. if ($vlan == 'UPLINK TRUNK') {
  95. $profile .= " description STATIC: Uplink Trunk Port\n";
  96. } else {
  97. $profile .= " description STATIC: Trunk Port\n";
  98. }
  99. if (file_exists(PORT_TMPL_DIR . '/TRUNK/ports.tmpl')) {
  100. $profile .= file_get_contents(PORT_TMPL_DIR . '/TRUNK/ports.tmpl');
  101. }
  102. if (file_exists(PORT_TMPL_DIR . '/TRUNK/' . $zpid . '/ports.tmpl')) {
  103. $profile .= file_get_contents(PORT_TMPL_DIR . '/TRUNK/' . $zpid . '/ports.tmpl');
  104. }
  105. if ($vlan == 'UPLINK TRUNK') {
  106. if (file_exists(PORT_TMPL_DIR . '/TRUNK/uplink/ports.tmpl')) {
  107. $profile .= file_get_contents(PORT_TMPL_DIR . '/TRUNK/uplink/ports.tmpl');
  108. }
  109. if (file_exists(PORT_TMPL_DIR . '/TRUNK/uplink/' . $zpid . '/ports.tmpl')) {
  110. $profile .= file_get_contents(PORT_TMPL_DIR . '/TRUNK/uplink/' . $zpid . '/ports.tmpl');
  111. }
  112. }
  113. } else {
  114. $vi = $VLANS[$vlan];
  115. $profile .= " description STATIC: $vlan Access Port\n";
  116. $profile .= " switchport access vlan $vi\n";
  117. if (file_exists(PORT_TMPL_DIR . '/ACCESS/ports.tmpl')) {
  118. $profile .= file_get_contents(PORT_TMPL_DIR . '/ACCESS/ports.tmpl');
  119. }
  120. if (file_exists(PORT_TMPL_DIR . '/ACCESS/' . $zpid . '/ports.tmpl')) {
  121. $profile .= file_get_contents(PORT_TMPL_DIR . '/ACCESS/' . $zpid . '/ports.tmpl');
  122. }
  123. if (file_exists(PORT_TMPL_DIR . '/ACCESS/' . $vi . '/ports.tmpl')) {
  124. $profile .= file_get_contents(PORT_TMPL_DIR . '/ACCESS/' . $vi . '/ports.tmpl');
  125. }
  126. if (file_exists(PORT_TMPL_DIR . '/ACCESS/' . $vi . '/' . $zpid . '/ports.tmpl')) {
  127. $profile .= file_get_contents(PORT_TMPL_DIR . '/ACCESS/' . $vi . '/' . $zpid . '/ports.tmpl');
  128. }
  129. }
  130. return $profile;
  131. }
  132. function call_hook($hook, $args) {
  133. global $HOOKS;
  134. $hook_parts = explode(':', $hook);
  135. $hook_name = '$HOOKS';
  136. foreach ($hook_parts as $hp) {
  137. $hook_name .= "[$hp]";
  138. }
  139. @eval('$hook_val = ' . $hook_name . ';');
  140. if (!isset($hook_val) || $hook_val == '') {
  141. return;
  142. }
  143. $argstr = $hook . ' ';
  144. foreach ($args as $arg) {
  145. $argstr .= escapeshellarg($arg) . ' ';
  146. }
  147. $argstr = trim($argstr);
  148. @exec("$hook_val $argstr");
  149. }
  150. function get_PI_REST($url, $p = false, $decode = true, $timeout = 300) {
  151. $cookie = false;
  152. $error = "";
  153. if (DEBUG >= 5) {
  154. print "<h3>calling $url with params:</h3>";
  155. var_dump($p);
  156. }
  157. $i = 0;
  158. $res = false;
  159. while ($i < REST_RETRIES) {
  160. $res = fetch_url($url, $cookie, $error, $p, $timeout);
  161. if ($res) break;
  162. sleep(3);
  163. $i++;
  164. }
  165. if ($res) {
  166. if ($decode) {
  167. $json = json_decode($res, true);
  168. return $json;
  169. } else {
  170. return $res;
  171. }
  172. }
  173. return false;
  174. }
  175. function apicGetTicket($host, $user, $pass, &$error) {
  176. $cookie = false;
  177. $url = 'https://' . $host . '/api/v1/ticket';
  178. $p = array();
  179. $p['post'] = json_encode(array("username" => $user, "password" => $pass));
  180. $p['header']['Content-Type'] = 'application/json';
  181. $i = 0;
  182. $res = false;
  183. while ($i < REST_RETRIES) {
  184. $res = fetch_url($url, $cookie, $error, $p);
  185. if ($res) break;
  186. sleep(REST_RETRY_INTERVAL);
  187. $i++;
  188. }
  189. if ($res) {
  190. $json = json_decode($res, true);
  191. return $json['response']['serviceTicket'];
  192. }
  193. return false;
  194. }
  195. function apicAddDevice($host, $ticket, $projid, $device, $sn, $pid, &$msg, $config = NULL, $image = NULL) {
  196. $cookie = false;
  197. $error = "";
  198. $url = 'https://' . $host . '/api/v1/pnp-project/' . $projid . '/device';
  199. $p = array();
  200. $params = array();
  201. $params['hostName'] = $device;
  202. $params['serialNumber'] = $sn;
  203. $params['platformId'] = $pid;
  204. if ($config) {
  205. $params['configId'] = $config;
  206. }
  207. if ($image) {
  208. $params['imageId'] = $image;
  209. }
  210. $p['post'] = json_encode($params);
  211. $p['header']['Content-Type'] = 'application/json';
  212. $p['header']['X-Auth-Token'] = $ticket;
  213. $i = 0;
  214. $res = false;
  215. while ($i < REST_RETRIES) {
  216. $res = fetch_url($url, $cookie, $error, $p);
  217. if ($res) break;
  218. sleep(REST_RETRY_INTERVAL);
  219. $i++;
  220. }
  221. if ($res) {
  222. $json = json_decode($res, true);
  223. return apicGetTaskResult($host, $ticket, $json['response']['taskId'], $msg);
  224. }
  225. $msg = $error;
  226. return false;
  227. }
  228. function apicGetTaskResult($host, $ticket, $task, &$msg, $timeout = 60) {
  229. $cookie = false;
  230. $error = "";
  231. $url = 'https://' . $host . '/api/v1/task/' . $task;
  232. $p = array();
  233. $p['header']['X-Auth-Token'] = $ticket;
  234. $done = false;
  235. $j = 0;
  236. while ($j < $timeout) {
  237. $i = 0;
  238. $res = false;
  239. while ($i < REST_RETRIES) {
  240. $res = fetch_url($url, $cookie, $error, $p);
  241. if ($res) break;
  242. sleep(REST_RETRY_INTERVAL);
  243. $i++;
  244. }
  245. if ($res) {
  246. $json = json_decode($res, true);
  247. if (isset($json['response']['isError']) && $json['response']['isError'] === true) {
  248. $msg = $json['response']['failureReason'];
  249. return false;
  250. }
  251. if (isset($json['response']['endTime']) && $json['response']['endTime'] >= $json['response']['startTime']) {
  252. return true;
  253. }
  254. # This allows the timeout to be specified in seconds.
  255. sleep(1);
  256. $j++;
  257. }
  258. }
  259. if ($error != "") {
  260. $msg = $error;
  261. } else {
  262. $msg = "Failed to get result from APIC-EM";
  263. }
  264. return false;
  265. }
  266. function apicGetProject($host, $ticket, $proj, &$error) {
  267. $cookie = false;
  268. $url = 'https://' . $host . '/api/v1/pnp-project/count';
  269. $p = array();
  270. $p['header']['X-Auth-Token'] = $ticket;
  271. $i = 0;
  272. $res = false;
  273. while ($i < REST_RETRIES) {
  274. $res = fetch_url($url, $cookie, $error, $p);
  275. if ($res) break;
  276. sleep(REST_RETRY_INTERVAL);
  277. $i++;
  278. }
  279. if ($res) {
  280. $json = json_decode($res, true);
  281. $count = $json['response'];
  282. $url = 'https://' . $host . '/api/v1/pnp-project';
  283. $offset = 1;
  284. $limit = 500;
  285. do {
  286. $p['get']['offset'] = $offset;
  287. $p['get']['limit'] = $limit;
  288. $i = 0;
  289. $res = false;
  290. while ($i < REST_RETRIES) {
  291. $res = fetch_url($url, $cookie, $error, $p);
  292. if ($res) break;
  293. sleep(REST_RETRY_INTERVAL);
  294. $i++;
  295. }
  296. if ($res) {
  297. $json = json_decode($res, true);
  298. foreach ($json['response'] as $s) {
  299. if ($s['siteName'] == $proj) {
  300. return $s;
  301. }
  302. }
  303. }
  304. $offset += $limit;
  305. } while ($offset + $limit < $count);
  306. }
  307. return false;
  308. }
  309. function apicUpdateProject($host, $ticket, $projid, $proj, $ip, &$msg, $path = '/') {
  310. $cookie = false;
  311. $error = "";
  312. $url = 'https://' . $host . '/api/v1/pnp-project';
  313. $p = array();
  314. $params = array();
  315. $params['id'] = $projid;
  316. $params['siteName'] = $proj;
  317. $params['tftpServer'] = $ip;
  318. $params['tftpPath'] = $path;
  319. $p['put'] = json_encode($params);
  320. $p['header']['Content-Type'] = 'application/json';
  321. $p['header']['X-Auth-Token'] = $ticket;
  322. $i = 0;
  323. $res = false;
  324. while ($i < REST_RETRIES) {
  325. $res = fetch_url($url, $cookie, $error, $p);
  326. if ($res) break;
  327. sleep(REST_RETRY_INTERVAL);
  328. $i++;
  329. }
  330. if ($res) {
  331. $json = json_decode($res, true);
  332. return apicGetTaskResult($host, $ticket, $json['response']['taskId'], $msg);
  333. }
  334. $msg = $error;
  335. return false;
  336. }
  337. function fetch_url($url, &$cookie, &$error, $p = false, $timeout = REST_TIMEOUT) {
  338. $ch = curl_init();
  339. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  340. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
  341. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
  342. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  343. if (DEBUG > 5) {
  344. curl_setopt($ch, CURLOPT_HEADER, true);
  345. curl_setopt($ch, CURLINFO_HEADER_OUT, true);
  346. curl_setopt($ch, CURLOPT_VERBOSE, true);
  347. } else {
  348. curl_setopt($ch, CURLOPT_HEADER, false);
  349. }
  350. if (isset($p['get'])) {
  351. $url .= '?' . http_build_query($p['get']);
  352. }
  353. if (isset($p['post'])) {
  354. curl_setopt($ch, CURLOPT_POST, count($p['post']));
  355. curl_setopt($ch, CURLOPT_POSTFIELDS, $p['post']);
  356. }
  357. if (isset($p['put'])) {
  358. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
  359. $p['header']['Content-Length'] = strlen($p['put']);
  360. curl_setopt($ch, CURLOPT_POSTFIELDS, $p['put']);
  361. }
  362. if (isset($p['header'])) {
  363. foreach ($p['header'] as $name => $value) $header[] = $name . ': ' . $value;
  364. curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  365. }
  366. if (isset($p['cookie'])) {
  367. curl_setopt($ch, CURLOPT_COOKIE, $p['cookie']);
  368. }
  369. if (isset($p['authentication'])) {
  370. curl_setopt($ch, CURLOPT_USERPWD, $p['authentication']['user'].':'.$p['authentication']['password']);
  371. }
  372. curl_setopt($ch, CURLOPT_URL, $url);
  373. $response = curl_exec($ch);
  374. $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  375. $error = 'cURL error num: ' . curl_errno($ch) . ' => ' . curl_error($ch);
  376. if (DEBUG >= 5) {
  377. print "<h3>Request:</h3>";
  378. var_dump(curl_getinfo($ch));
  379. print "<h3>Response:</h3>";
  380. var_dump($response);
  381. print curl_error($ch) . "\n";
  382. }
  383. if (empty($response)) {
  384. if (DEBUG > 0) {
  385. echo "WARNING: empty response from URL<br/>\n";
  386. curl_close($ch);
  387. return false;
  388. }
  389. } else {
  390. if (empty($httpcode)) {
  391. if (DEBUG > 0) {
  392. echo "WARNING: no HTTP code was returned\n$response\n";
  393. curl_close($ch);
  394. return false;
  395. }
  396. } elseif ($httpcode != 200 && $httpcode != 202) {
  397. if (DEBUG > 0) {
  398. echo "ERROR: the server returned http code: $httpcode\n$response\n";
  399. }
  400. if (DEBUG > 1) {
  401. print "<h3>Request:</h3>";
  402. var_dump(curl_getinfo($ch));
  403. print "<h3>Response:</h3>";
  404. var_dump($response);
  405. }
  406. curl_close($ch);
  407. $cookie = false;
  408. $error = $httpcode;
  409. return false;
  410. } else {
  411. curl_close($ch);
  412. return $response;
  413. }
  414. }
  415. }
  416. ?>