export_deadman.php 8.2 KB

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