importsw.pl 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. #!/usr/bin/perl
  2. use strict;
  3. use DBI;
  4. use vars qw($PID_3560 $PID_3750 $DB_USER $DB_PASS);
  5. require 'dbi.ph';
  6. sub trim($) {
  7. my ($str) = shift;
  8. $str //= '';
  9. $str =~ s/^\s+//g;
  10. $str =~ s/\s+$//g;
  11. return $str;
  12. }
  13. $PID_3560 = 'WS-C3560CG-8PC-S';
  14. $PID_3750 = 'WS-C3750X';
  15. my $dsn = "DBI:mysql:database=noc";
  16. my $dbh = DBI->connect($dsn, $DB_USER, $DB_PASS, {PrintError => 0})
  17. or die "ERROR: Failed to connect to the database.";
  18. open(IN, "/home/jclarke/invsw.csv")
  19. or die "ERROR: Failed to open /home/jclarke/invsw.csv for reading.";
  20. my @contents = <IN>;
  21. close(IN);
  22. my $header = $contents[0];
  23. chomp $header;
  24. my @elements = split(/,/, $header);
  25. for (my $i = 1 ; $i < scalar(@contents) ; $i++) {
  26. my %field = (
  27. 'Hostname' => '',
  28. 'Ports' => '',
  29. 'Serial' => '',
  30. 'Location' => '',
  31. 'MDF' => '',
  32. 'IDF' => '',
  33. 'Template' => '',
  34. 'IP' => '',
  35. );
  36. my $line = $contents[$i];
  37. chomp $line;
  38. my @fields = split(/,/, $line);
  39. for (my $j = 0 ; $j < scalar(@elements) ; $j++) {
  40. $field{$elements[$j]} = trim($fields[$j]);
  41. }
  42. my $query = '';
  43. my ($sth, $res, $ref, @params);
  44. if ($field{'Hostname'} ne '') {
  45. if ($field{'IP'} ne '') {
  46. $query =
  47. 'SELECT address FROM ADDRESSES WHERE address = ?';
  48. $sth = $dbh->prepare($query);
  49. if (!$sth) {
  50. print STDERR
  51. "ERROR: Failed to prepare query '$query': "
  52. . $dbh->errstr . "\n";
  53. next;
  54. }
  55. @params = ($field{'IP'});
  56. $res = $sth->execute(@params);
  57. if (!$res) {
  58. print STDERR
  59. "ERROR: Failed to execute query '$query': "
  60. . $dbh->errstr . "\n";
  61. next;
  62. }
  63. $ref = $sth->fetchrow_hashref;
  64. if (!$ref) {
  65. print STDERR
  66. "ERROR: No matching IP address record for $field{'IP'}\n";
  67. print STDERR "XXX: Line is '$line'\n";
  68. next;
  69. }
  70. $query =
  71. 'SELECT name FROM SWITCHES WHERE ip_address = ? AND name != ?';
  72. $sth = $dbh->prepare($query);
  73. if (!$sth) {
  74. print STDERR "Failed to prepare '$query': "
  75. . $dbh->errstr . "\n";
  76. next;
  77. }
  78. @params = ($ref->{'address'}, $field{'Hostname'});
  79. $res = $sth->execute(@params);
  80. if (!$res) {
  81. print STDERR
  82. "Failed to execute query '$query': "
  83. . $dbh->errstr . "\n";
  84. next;
  85. }
  86. if ($sth->rows != 0) {
  87. my $r = $sth->fetchrow_hashref;
  88. print STDERR
  89. "Duplicate IP detected for IP $field{'IP'}, hostname $field{'Hostname'} (current device is "
  90. . $r->{'name'} . ")\n";
  91. $query =
  92. 'UPDATE ADDRESSES SET used=? WHERE address=?';
  93. $sth = $dbh->prepare($query);
  94. if (!$sth) {
  95. print STDERR
  96. "Failed to prepare query '$query': "
  97. . $dbh->errstr . "\n";
  98. next;
  99. }
  100. @params = ('1', $field{'IP'});
  101. $res = $sth->execute(@params);
  102. if (!$res) {
  103. print STDERR
  104. "Failed to execute query '$query': "
  105. . $dbh->errstr . "\n";
  106. next;
  107. }
  108. next;
  109. }
  110. $field{'IP'} = $ref->{'address'};
  111. } else {
  112. $query =
  113. 'SELECT address FROM ADDRESSES WHERE location=? AND used=? LIMIT 1';
  114. $query =
  115. 'SELECT ip_address FROM SWITCHES WHERE name = ?';
  116. $sth = $dbh->prepare($query);
  117. if (!$sth) {
  118. print STDERR
  119. "Failed to prepare query '$query': "
  120. . $dbh->errstr . "\n";
  121. next;
  122. }
  123. @params = ($field{'IDF'});
  124. $res = $sth->execute(@params);
  125. if (!$res) {
  126. print STDERR
  127. "Failed to execute query '$query': "
  128. . $dbh->errstr . "\n";
  129. next;
  130. }
  131. my $r = $sth->fetchrow_hashref;
  132. my ($subnet) =
  133. ($r->{'ip_address'} =~ /^(\d+\.\d+\.\d+\.)/);
  134. $query =
  135. 'SELECT address FROM ADDRESSES WHERE location = ? AND address LIKE ? AND used = ? AND reserved = ? ORDER BY INET_ATON(address) LIMIT 1';
  136. $sth = $dbh->prepare($query);
  137. if (!$sth) {
  138. print STDERR
  139. "Failed to prepare query '$query': "
  140. . $dbh->errstr . "\n";
  141. next;
  142. }
  143. @params = ($field{'MDF'}, $subnet . '%', '0', '0');
  144. $res = $sth->execute(@params);
  145. if (!$res) {
  146. print STDERR
  147. "Failed to execute query '$query': "
  148. . $dbh->errstr . "\n";
  149. next;
  150. }
  151. $r = $sth->fetchrow_hashref;
  152. $field{'IP'} = $r->{'address'};
  153. }
  154. $query = 'UPDATE ADDRESSES SET used=? WHERE address=?';
  155. $sth = $dbh->prepare($query);
  156. if (!$sth) {
  157. print STDERR "Failed to prepare query '$query': "
  158. . $dbh->errstr . "\n";
  159. next;
  160. }
  161. @params = ('1', $field{'IP'});
  162. $res = $sth->execute(@params);
  163. if (!$res) {
  164. print STDERR "Failed to execute query '$query': "
  165. . $dbh->errstr . "\n";
  166. next;
  167. }
  168. $query =
  169. 'UPDATE DEVICE_MAP SET assigned_switch = NULL, checked_out=? WHERE assigned_switch = ?';
  170. $sth = $dbh->prepare($query);
  171. if (!$sth) {
  172. print STDERR "Failed to prepare query '$query': "
  173. . $dbh->errstr . "\n";
  174. next;
  175. }
  176. @params = ('0', $field{'Hostname'});
  177. $res = $sth->execute(@params);
  178. if (!$res) {
  179. print STDERR "Failed to execute query '$query': "
  180. . $dbh->errstr . "\n";
  181. next;
  182. }
  183. $query =
  184. 'REPLACE INTO SWITCHES (name, ip_address, pid, location, ports_required) VALUES (?, ?, ?, ?, ?)';
  185. $sth = $dbh->prepare($query);
  186. if (!$sth) {
  187. print STDERR "Failed to insert switch record: "
  188. . $dbh->errstr . "\n";
  189. next;
  190. }
  191. my $model;
  192. if ($field{'Ports'} == 24 || $field{'Ports'} == 48) {
  193. $model = $PID_3750;
  194. } else {
  195. $model = $PID_3560;
  196. }
  197. @params = (
  198. $field{'Hostname'}, $field{'IP'}, $model,
  199. $field{'Location'}, $field{'Ports'}
  200. );
  201. $res = $sth->execute(@params);
  202. if (!$res) {
  203. print STDERR "Failed to insert switch record: "
  204. . $dbh->errstr . "\n";
  205. next;
  206. }
  207. if ($field{'Template'} ne '') {
  208. $query = 'SELECT path FROM EXCEPTIONS WHERE name = ?';
  209. $sth = $dbh->prepare($query);
  210. if (!$sth) {
  211. print STDERR "Failed to prepare query '$query':"
  212. . $dbh->errstr . "\n";
  213. next;
  214. }
  215. @params = ($field{'Template'});
  216. $res = $sth->execute(@params);
  217. if (!$res) {
  218. print STDERR "Failed to execute query '$query':"
  219. . $dbh->errstr . "\n";
  220. next;
  221. }
  222. if ($sth->rows == 0) {
  223. print STDERR
  224. "Unable to find $field{'Template'} in EXCEPTIONS\n";
  225. next;
  226. }
  227. my $r = $sth->fetchrow_hashref;
  228. symlink($r->{'path'},
  229. '/tftpboot/'
  230. . $field{'Hostname'}
  231. . '-ports.tmpl');
  232. }
  233. if ($field{'Serial'} ne '') {
  234. $query =
  235. 'SELECT serial_number, max_ports FROM DEVICE_MAP WHERE serial_number=?';
  236. $sth = $dbh->prepare($query);
  237. if (!$sth) {
  238. print STDERR "Failed to prepare query '$query':"
  239. . $dbh->errstr . "\n";
  240. next;
  241. }
  242. @params = ($field{'Serial'});
  243. $res = $sth->execute(@params);
  244. if (!$res) {
  245. print STDERR
  246. "Failed to execute query '$query': "
  247. . $dbh->errstr . "\n";
  248. next;
  249. }
  250. if ($sth->rows == 0) {
  251. print STDERR
  252. "Unable to find $field{'Serial'} in DEVICE_MAP\n";
  253. next;
  254. } else {
  255. my $r = $sth->fetchrow_hashref;
  256. if ($r->{'max_ports'} ne $field{'Ports'}) {
  257. print STDERR
  258. "Ports required for $field{'Hostname'} do not match max ports provided by $field{'Serial'} (required: $field{'Ports'}, provided: "
  259. . $r->{'max_ports'} . ")\n";
  260. next;
  261. }
  262. }
  263. $query =
  264. 'UPDATE DEVICE_MAP SET assigned_switch=?, checked_out=? WHERE serial_number=?';
  265. $sth = $dbh->prepare($query);
  266. if (!$sth) {
  267. print STDERR
  268. "Failed to prepare query '$query': "
  269. . $dbh->errstr . "\n";
  270. next;
  271. }
  272. @params = ($field{'Hostname'}, '1', $field{'Serial'});
  273. $res = $sth->execute(@params);
  274. if (!$res) {
  275. print STDERR
  276. "Failed to execute query '$query' for ($field{'Hostname'}, $field{'Serial'}): "
  277. . $dbh->errstr . "\n";
  278. next;
  279. }
  280. }
  281. }
  282. }