functions.php 15 KB

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