export_deadman.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. <?php
  2. //-
  3. // Copyright (c) 2011-2018 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. include_once 'swreg_creds.inc.php';
  27. require_once 'Log.php';
  28. require_once 'functions.php';
  29. function error_to_exception($severity, $message, $file, $line)
  30. {
  31. if (!(error_reporting() & $severity)) {
  32. return;
  33. }
  34. throw new ErrorException($message, 0, $severity, $file, $line);
  35. }
  36. set_error_handler('error_to_exception');
  37. $dsn = "$db_driver:host=$db_host;dbname=$db_name";
  38. $options = [
  39. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  40. PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
  41. PDO::ATTR_EMULATE_PREPARES => false,
  42. ];
  43. if (EXPORT_DEADMAN === false) {
  44. exit(0);
  45. }
  46. try {
  47. $dbh = new PDO($dsn, $db_user, $db_pass, $options);
  48. } catch (PDOException $e) {
  49. die($e->getMessage() . "\n");
  50. }
  51. $logger = Log::singleton('file', LOGFILE, TOOL_NAME . ' : Exporter');
  52. if ($logger === false) {
  53. die("Failed to open logfile.\n");
  54. }
  55. $mask = Log::MAX(LOG_LEVEL);
  56. $logger->setMask($mask);
  57. $is_script = false;
  58. if (isset($argv) && $argv !== null) {
  59. $is_script = true;
  60. $options = getopt('t:f');
  61. if (!isset($options['t'])) {
  62. echo "usage: {$argv[0]} -t <TIME> [-f]\n";
  63. exit(1);
  64. }
  65. $sql = "SELECT value FROM SYS_PROPERTIES WHERE name='last_logic_update'";
  66. try {
  67. $res = $dbh->query($sql);
  68. } catch (PDOException $e) {
  69. echo "ERROR: Failed to get last update time: '{$e->getMessage()}'\n";
  70. exit(1);
  71. }
  72. $now = time();
  73. $row = $res->fetch();
  74. if ($now - $row['value'] >= ($options['t'] * 60)) {
  75. if (!isset($options['f'])) {
  76. // Logic data was not updated recently enough.
  77. exit(0);
  78. } else {
  79. echo "Logic data was not updated recently enough, but forcing run anyway.\n";
  80. }
  81. }
  82. }
  83. $sql = "SELECT * FROM DEVICE_MAP WHERE checked_out='1' AND (device_status='1' OR device_status='2') ORDER BY LPAD(lower(assigned_switch), 10, 0)";
  84. $res = null;
  85. try {
  86. $res = $dbh->query($sql);
  87. } catch (PDOException $e) {
  88. $msg = "Error querying for physical switches: {$e->getMessage()}";
  89. if ($is_script) {
  90. echo $msg . "\n";
  91. } else {
  92. echo "<p><font color=\"red\">{$msg}</font></p>\r\n";
  93. }
  94. exit(1);
  95. }
  96. // Map from defined constant to variable.
  97. $GIT_HOME = GIT_HOME;
  98. $YAML_FILE = "{$GIT_HOME}/network/ansible/vars/targets.yml";
  99. exec("cd $GIT_HOME && GIT_SSH_COMMAND='ssh -i $GIT_HOME/../../.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' /usr/local/bin/git pull", $output, $result);
  100. if ($result != 0) {
  101. if (!$is_script) {
  102. echo "<p><font color=\"red\">Error updating git repo:</p>\r\n";
  103. echo "<pre>\r\n";
  104. } else {
  105. echo "Error updating git repo:\n";
  106. }
  107. foreach ($output as $line) {
  108. echo "$line";
  109. if ($is_script) {
  110. echo "\n";
  111. } else {
  112. echo "\r\n";
  113. }
  114. }
  115. if (!$is_script) {
  116. echo "</pre></font>\r\n";
  117. }
  118. exit(1);
  119. }
  120. try {
  121. $targets = yaml_parse_file($YAML_FILE);
  122. } catch (Exception $e) {
  123. $msg = "Error parsing YAML file: '{$e->getMessage()}'";
  124. if ($is_script) {
  125. echo $msg . "\n";
  126. } else {
  127. echo "<p><font color=\"red\">{$msg}</font></p>\r\n";
  128. }
  129. exit(1);
  130. }
  131. $infra = $targets['targets']['infra'];
  132. $new_infra = [];
  133. foreach ($infra as $target) {
  134. if (!preg_match('/^sw-([0-9]+|oob)/', $target['name'])) {
  135. array_push($new_infra, $target);
  136. continue;
  137. }
  138. }
  139. while ($row = $res->fetch()) {
  140. $target = [];
  141. $target['name'] = $row['assigned_switch'];
  142. $sql = 'SELECT ip_address, location FROM SWITCHES WHERE name = :name';
  143. $sw_res = null;
  144. try {
  145. $sw_res = $dbh->prepare($sql);
  146. $sw_res->execute(['name' => $row['assigned_switch']]);
  147. } catch (PDOException $e) {
  148. $msg = "Error querying for IP address for {$row['assigned_switch']}: {$e->getMessage()}";
  149. if ($is_script) {
  150. echo $msg . "\n";
  151. } else {
  152. echo "<p><font color=\"red\">{$msg}</font></p>\r\n";
  153. }
  154. continue;
  155. }
  156. $sw_row = $sw_res->fetch();
  157. if ($sw_row['location'] === null || $sw_row['location'] == '') {
  158. continue;
  159. }
  160. $target['ipv4'] = $sw_row['ip_address'];
  161. $target['location'] = $sw_row['location'];
  162. $target['platform'] = 'ietfcisco';
  163. $target['deployed'] = 'True';
  164. array_push($new_infra, $target);
  165. }
  166. $targets['targets']['infra'] = $new_infra;
  167. try {
  168. $yaml = yaml_emit($targets, YAML_UTF8_ENCODING, YAML_LN_BREAK);
  169. $yaml = preg_replace('/^---/', '', $yaml);
  170. } catch (Exception $e) {
  171. $msg = "Failed to generate YAML: '{$e->getMessage()}'";
  172. if ($is_script) {
  173. echo $msg . "\n";
  174. } else {
  175. echo "<p><font color=\"red\">{$msg}</font></p>";
  176. }
  177. exit(1);
  178. }
  179. try {
  180. $fd = fopen($YAML_FILE, 'w');
  181. $header = <<<'HEADER'
  182. ---
  183. # Targets for Smokeping and Deadman
  184. # Target format:
  185. # name: Display name of the target
  186. # hostname: Hostname of the target
  187. # ipv4: IPv4 address
  188. # ipv6: IPv6 address
  189. # deployed (optional): If False, then the target will not be added (default:
  190. # True)
  191. # location (optional): Location where element is deployed
  192. #
  193. #
  194. # If the target doesn't have a v4 or v6, then the target will be looked
  195. # up by hostname and one v4 and one v6 address will be added to the config.
  196. ###
  197. HEADER;
  198. fwrite($fd, $header);
  199. fwrite($fd, $yaml);
  200. fclose($fd);
  201. } catch (Exception $e) {
  202. $msg = "Failed to write data to file: '{$e->getMessage()}";
  203. if ($is_script) {
  204. echo $msg . "\n";
  205. } else {
  206. echo "<p><font color=\"red\">{$msg}</font></p>";
  207. }
  208. exit(1);
  209. }
  210. exec("cd $GIT_HOME && GIT_SSH_COMMAND='ssh -i $GIT_HOME/../../.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' /usr/local/bin/git commit -m 'Update switch targets from ZTP' $YAML_FILE", $output, $result);
  211. if ($result != 0) {
  212. if ($output[0] != "Your branch is up to date" && $output[0] != "Already up to date.") {
  213. if (!$is_script) {
  214. echo "<p><font color=\"red\">Error committing changes to git:</p>\r\n";
  215. echo "<pre>\r\n";
  216. } else {
  217. echo "Error committing changes to git:\n";
  218. }
  219. foreach ($output as $line) {
  220. echo "$line";
  221. if ($is_script) {
  222. echo "\n";
  223. } else {
  224. echo "\r\n";
  225. }
  226. }
  227. if (!$is_script) {
  228. echo "</pre></font>\r\n";
  229. }
  230. exit(1);
  231. } else {
  232. if ($is_script) {
  233. exit(0);
  234. } else {
  235. echo "<script>window.close();</script>";
  236. }
  237. }
  238. }
  239. exec("cd $GIT_HOME && GIT_SSH_COMMAND='ssh -i $GIT_HOME/../../.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' /usr/local/bin/git push", $output, $result);
  240. if ($result != 0) {
  241. if (!$is_script) {
  242. echo "<p><font color=\"red\">Error pushing changes to git:</p>\r\n";
  243. echo "<pre>\r\n";
  244. } else {
  245. echo "Error pushing changes to git:\n";
  246. }
  247. foreach ($output as $line) {
  248. echo "$line";
  249. if ($is_script) {
  250. echo "\n";
  251. } else {
  252. echo "\r\n";
  253. }
  254. }
  255. if (!$is_script) {
  256. echo "</pre></font>\r\n";
  257. }
  258. exit(1);
  259. }
  260. touch('/tmp/deadman_change.dat');
  261. if ($is_script) {
  262. exit(0);
  263. }
  264. ?>
  265. <script>
  266. window.close();
  267. </script>