#!/bin/sh #! -*-perl-*- eval 'exec perl -x -S $0 ${1+"$@"}' if 0; # This file is part of Ping903 # Copyright (C) 2020-2023 Sergey Poznyakoff # # Ping903 is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # Ping903 is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ping903. If not, see . =head1 NAME dbload - Load IP addresses from database into Ping903 =head1 SYNOPSIS B [B<-D> I] [B<-P> I] [B<-U> I] [B<-c> I] [B<-d> I] [B<-h> I] [B<-p> I] [B<-q> I] [B<-t> I] [B<-u> I] [B<--column>=I] [B<--database>=I] [B<--defaults-file>=I] [B<--driver>=I] [B<--host>=I] [B<--params>=I] [B<--password>=I] [B<--port>=I] [B<--query>=I] [B<--table>=I
] [B<--url>=I] [B<--user>=I] =head1 DESCRIPTION Reads IP addresses from the database and adds them to the list of monitored hosts of L. Most parameters are configurable. You need to supply at least the database connection information and the query to use. For the latter, use the B<--table> and B<--column> options together. For really complex queries, use the B<--query> option instead. See below for details. On success, prints on standard output the number of IP addresses loaded and exits with status 0. On error, displays on standard error the detailed diagnostic information as obtained from the server and exits with status 1. =head1 OPTIONS =head2 General options =over 4 =item B<-U>, B<--url>=I URL of the running L daemon. Default is C. =back =head2 Database connection options =over 4 =item B<-D>, B<--driver>=I Sets L database driver name. Default is C. =item B<-h>, B<--host>=I Name or IP address of the database server. =item B<-P>, B<--port>=I Port number the database server listens on. =item B<-d>, B<--database>=I Name of the database to use. =item B<-u>, B<--user>=I Database user name. =item B<-p>, B<--password>=I Database password. =item B<--defaults-file>=I Name of the MySQL defaults file to use. This option is used only if DBI driver B is used. By default, the file F<.my.cnf> in the home directory is used, if it exists. =item B<--params>=I Additional parameters for the DBI driver. For detailed information, refer to the documentation of the driver in use. =back =head2 Query to extract IP addresses from the database Three options are provided: =over 4 =item B<-t>, B<--table>=I
Name of the table which holds IP addresses. =item B<-c>, B<--column>=I Name of the column in I
where IP address is stored. If need be, you can use SQL expression as well. =item B<-q>, B<--query>=I SQL query to use in order to obtain IP addresses. This overrides the two options above. =back Normally you would use a combination of B<--table> and B<--column> options. For example, if you have a database table C, which has a column C, that holds IP address in dotted-quad form, you would use the following options: --table=hosts --column=ip If the table holds IP addresses in numeric form, use the following instead (MySQL is assumed): --table=hosts --column='INET_NTOA(ip)' Finally, if a complex query is needed to extract IP addresses (e.g. joining several tables, etc.), supply it in full, via the B<--query> option. =head2 Informative options =over 4 =item B<-?> Display short help summary. =item B<--usage> Display command line usage summary. =item B<--help> Display a detailed program manual. =back =head1 SEE ALSO L, L. =cut use strict; use warnings; use JSON; use LWP::UserAgent; use DBI; use Getopt::Long qw(:config gnu_getopt no_ignore_case); use File::Spec; use Pod::Usage; use Pod::Man; my $baseurl = 'http://localhost:8080'; my $driver = 'mysql'; my @connarg; my $dbuser; my $dbpass; my $dbparams; my $deffile; my $table = 'hosts'; my $column = 'ip'; my $query; GetOptions( 'U|url=s' => \$baseurl, 'D|driver=s' => \$driver, 'd|database=s' => sub { push @connarg, "database=$_[1]" }, 'h|host=s' => sub { push @connarg, "host=$_[1]" }, 'P|port=s' => sub { push @connarg, "port=$_[1]" }, 'u|user=s' => \$dbuser, 'p|password=s' => \$dbpass, 'params=s' => \$dbparams, 'defaults-file=s' => \$deffile, 't|table=s' => \$table, 'c|column=s' => \$column, 'q|query=s' => \$query, 'help' => sub { pod2usage(-exitstatus => 0, -verbose => 2); }, 'usage' => sub { pod2usage(-exitstatus => 0, -verbose => 0); }, 'hh|?' => sub { pod2usage(-message => "dbload - load IP addresses to ping903", -exitstatus => 0); }, ) or exit(1); unless ($query) { $query = qq{SELECT $column FROM $table}; } push @connarg, $dbparams if $dbparams; if ($driver eq 'mysql') { if (!$deffile) { my $f = File::Spec->catfile($ENV{HOME}, '.my.cnf'); if (-f $f) { $deffile = $f; } } push @connarg, ";mysql_read_default_file=$deffile"; } my $arg = join(':', ('DBI',$driver,@connarg)); my $dbh = DBI->connect($arg, $dbuser, $dbpass, { RaiseError => 0, PrintError => 1, AutoCommit => 1}) or pod2usage(-output => \*STDERR, -exitstatus => 1, -verbose => 0); my $res = $dbh->selectall_arrayref($query, { RaiseError => 0, PrintError => 1 }) or pod2usage(-output => \*STDERR, -exitstatus => 1, -verbose => 0); my $json_text = JSON->new->encode({ 'mode' => 'replace', 'ip-list' => [ map { $_->[0] } @$res ] }); my $ua = new LWP::UserAgent; my $response = $ua->post("$baseurl/config/ip-list", 'Content-Type' => 'application/json', 'Content' => $json_text); if ($response->is_success) { my $n = @$res; print "Loaded $n addresses\n"; } else { print STDERR $response->status_line,"\n"; my $ctype = $response->header('Content-Type'); if ($ctype && $ctype eq 'application/json') { my $expl = JSON->new->decode($response->decoded_content); if (exists($expl->{index})) { print STDERR "Item $expl->{index}: "; } print STDERR "$expl->{message}\n"; } exit(1); }