📜 ⬆️ ⬇️

Back up configuration switches, or fasten a little automation to GLPI

Sometimes, in our work, there is a need to account for all network equipment: types, models, addresses, firmware, wiring diagrams, and so on. And now, after reviewing several software options, the choice fell on the open draft GLPI . The functionality of the system is rich, specifically in our case, used to account for "hardware" and, most importantly, to account for the connection diagrams (which port of which switch is connected to where). As part of the organization’s core business (providing access to the Internet), a need arose (of course, not suddenly, but strictly according to plan) to back up the configuration of switches, why and why this operation is necessary — everyone should know this. And how to implement this, in conjunction with the GLPI will be this article.

To implement our plans, you need a list of addresses of equipment and a list of manufacturers, all this data is in the GLPI database, of course, if you have previously brought them there. IP addresses are needed to connect over the network, and why do we need to know the manufacturer? The fact is that each manufacturer of network equipment, for various reasons, introduces its own “original” ideas there and, therefore, the commands for controlling the hardware are different. In our particular case, there are only two manufacturers, but nothing prevents the list from expanding.
We will perform the copying operation of the config through a telnet connection, the same can be done via SNMP, but in this case, the entire SNMP hardware for recording (command execution) is closed.

The implementation language was PERL. Why so? Well, at that time I was sawing, on it, still some software (RDR assembler and disassembler, web snout to it) and, according to this, pearl. As the OS - GNU / Linux.

Let's start the code:
')
We connect the necessary modules:

#!/usr/bin/perl use Net::Telnet (); use IO::File; use Getopt::Long; use DBI; 

The function of removing spaces is implemented independently, why and why, I do not remember, but let it be:

 #     sub trim { my($string)=@_; for ($string) { s/^\s+//; s/\s+$//; } return $string; } 

In order not to get up two times, archiving, copying and deleting old files is simultaneously implemented in the script. System commands are used whenever possible:

 #   $date = `/bin/date "+%Y%m%d"`; $date = trim($date); $arch = "tar -czvf /var/srv/backup/conf/conf-".$date.".tgz /var/lib/tftpboot/"; my $result = `$arch`; #      $del = '/bin/find /var/srv/backup/conf/ -ctime +7 -name conf-*.tgz -exec rm {} \; -print > /var/log/switch-conf_backup.log'; my $delResult = `$del`; 

Connect to the database:

 #   GLPI  my $dsn = 'DBI:mysql:glpi:192.168.123.222'; my $db_user_name = 'user'; my $db_password = 'password'; my ($id, $password); my $dbh = DBI->connect($dsn, $db_user_name, $db_password); 

We select the necessary addresses of the switches of the desired manufacturer and, accordingly, “pull” the procedures we need (which will be described below):

 my $sth = $dbh->prepare(qq{SELECT ip FROM glpi_networkequipments WHERE manufacturers_id=1 AND states_id=1}); $sth->execute(); while (my ($ip) = $sth->fetchrow_array()) { # print "$ip\n"; if ($ip eq "" || $ip =~ /^#+/) { #   .  ,  :) } else { #    connectSwitchEdgeCore("$ip"); } } $sth->finish(); #   D-Link   "" my $sth = $dbh->prepare(qq{SELECT ip FROM glpi_networkequipments WHERE manufacturers_id=3 AND states_id=1}); $sth->execute(); while (my ($ip) = $sth->fetchrow_array()) { if ($ip eq "" || $ip =~ /^#+/) { } else { connectSwitchDlink("$ip"); } } $sth->finish(); $dbh->disconnect(); 

It is worth noting that the values ​​of manufacturers_id and states_id (the first is the manufacturer’s code, the second is the status of the equipment (“put into operation”, “in the project”, etc.)) and, most likely, will differ, because they are created automatically when adding positions to the database. In this case, the manufacturer “1” is EdgeCore (“3” - D-Link) and the status “1” is “Enabled” i.e. commissioned. Tracking status is necessary in order to exclude attempts to connect with inactive, for various reasons, hardware.

Then there are two, almost identical, procedures that implement the dialogue between the script and the switchboard on the topic “and copy your current config to the tftp server”:

 # telnet-        tftp  #     EdgeCore sub connectSwitchEdgeCore { $hostname = "$_[0]"; $username = "user"; $passwd = "password"; $date = `/bin/date "+%Y%m%d"`; $str_fn=$hostname; print $str_fn; $tftpserver="20.20.20.20"; $conn = new Net::Telnet ( Timeout=>3, Errmode=>'return', Prompt => '/\#.?$/i'); $conn->open(Host => $hostname); $conn->waitfor('/ame[: ]*$/'); $conn->print($username); $conn->waitfor('/ord[: ]*$/'); $conn->print($passwd); $conn->print("copy running-config tftp"); $conn->waitfor('/ess[: ]*$/'); $conn->print($tftpserver); $conn->waitfor('/ame[: ]*$/'); $conn->print($str_fn); $conn->print("exit"); $conn->print("logout"); } #     D-Link sub connectSwitchDlink { $hostname = "$_[0]"; $username = "user"; $passwd = "password"; $date = `/bin/date "+%Y%m%d"`; $str_fn=$hostname; print "$str_fn\n"; $tftpserver="20.20.20.20"; $conn = new Net::Telnet ( Timeout=>3, Errmode=>'return', Prompt => '/\#.?$/i'); $conn->open(Host => $hostname); $conn->waitfor('/ame[: ]*$/'); $conn->print($username); $conn->waitfor('/ord[: ]*$/'); $conn->print($passwd); $conn->print("upload cfg_toTFTP $tftpserver dest_file $hostname"); $conn->waitfor('/Success/'); $conn->print("logout"); } 

The server address and connection parameters with the database, it was more logical to put it in a separate file, but due to the location of the celestial bodies at that moment, it was left so. The print commands are left for logging. The script is run on cron-time.

That is how simple and easy the routine operation was automated. Traditionally, source code is available here .

PS I thought what stream to place the article, tossed between "Administration" and "Development", eventually settled on the first option.

Source: https://habr.com/ru/post/336850/


All Articles