source: trunk/backuppc-silzigan/backuppc-silzigan @ 413

Last change on this file since 413 was 413, checked in by g7moreau, 5 years ago
  • Add nmap test
  • Property svn:executable set to *
File size: 10.6 KB
Line 
1#!/usr/bin/perl
2#
3# 2011/06/21 gabriel
4#
5# apt-get install iputils-ping rsync nmap perl-base libyaml-perl libio-all-perl libfile-finder-perl libnet-ldap-perl
6
7use strict;
8use warnings;
9
10use YAML;
11use IO::All;
12use File::Basename;
13use File::Finder;
14use Net::LDAP;
15use List::Util qw(shuffle);
16
17my %CMD_DB = (
18   help           => \&cmd_help,
19   version        => \&cmd_version,
20   generate       => \&cmd_generate,
21   update         => \&cmd_update,
22   init           => \&cmd_init_db,
23   'exclude-list' => \&cmd_exclude_list,
24   );
25
26my ($LDAP_H, $LDAP_BASE);
27my $LIMIT_TIMESTAMP = time() - (8 * 24 * 3600); # 8 days
28
29my $cmd = shift @ARGV || 'help';
30if (defined $CMD_DB{$cmd}) {
31   $CMD_DB{$cmd}->(@ARGV);
32   }
33else {
34   print {*STDERR} "backuppc-silzigan: command $cmd not found\n\n";
35   $CMD_DB{help}->();
36   exit 1;
37   }
38
39exit;
40
41sub open_ldap {
42   # AuthLDAPUrl          "ldap://ldapserver.mylab.fr/ou=Users,dc=mylab,dc=fr?uid?sub"
43   # AuthLDAPBindDN       "cn=ldapconnect,ou=System,dc=mylab,dc=fr"
44   # AuthLDAPBindPassword "Rhalala128"
45
46   my ($masterLDAP, $masterDN, $masterPw);
47
48   for my $config_line (io('/etc/apache2/conf.d/backuppc.conf')->chomp->slurp) {
49      ($masterLDAP, $LDAP_BASE) = ($1, $2) if $config_line =~ m{ ^\s* AuthLDAPUrl [^/]+ // ([^/]+) / (ou=[^?]+) }xms;
50      $masterDN = $1 if $config_line =~ m{ ^\s* AuthLDAPBindDN \s+ " ([^"]+) " }xms;
51      $masterPw = $1 if $config_line =~ m{ ^\s* AuthLDAPBindPassword \s+ " ([^"]+) " }xms;
52      }
53
54   $LDAP_H = Net::LDAP->new( "$masterLDAP" ) or die "$@";
55   my $mesg = $LDAP_H->bind("$masterDN", password => "$masterPw");
56
57   return;
58   }
59
60sub close_ldap {
61   $LDAP_H->unbind();
62   return;
63   }
64
65sub cmd_update {
66   my $search_config_file = File::Finder->type('f')->name('*.yaml');
67   for my $config_file (File::Finder->eval($search_config_file)->in('/etc/backuppc')) {
68      cmd_generate("$config_file");
69      }
70
71   update_hosts();
72   }
73
74sub cmd_generate {
75   my $config_file = shift;
76   
77   my $CONFIG = YAML::LoadFile($config_file);
78
79   $CONFIG->{default}{namespace} ||= basename($config_file, '.yaml');
80   $CONFIG->{default}{path}      ||= "/etc/backuppc/auto/$CONFIG->{default}{namespace}";
81   $CONFIG->{default}{hosts}     ||= "$CONFIG->{default}{path}/hosts";
82   $CONFIG->{default}{exclude}   ||= "/usr/lib/kont/etc/backuppc/exclude.txt";
83
84   if (not -d "/etc/backuppc/auto/$CONFIG->{default}{namespace}") {
85      io("/etc/backuppc/auto/$CONFIG->{default}{namespace}")->mkpath({mode => 0755});
86      }
87
88   print '' > io($CONFIG->{default}{hosts});
89
90   open_ldap();
91   LOOP_ON_COMPUTER:
92   for my $computer ( keys %{$CONFIG->{computers}}) {
93      my $login = $CONFIG->{computers}{$computer}{login} || 'root';
94
95      LOOP_ON_USER:
96      for my $user (  keys %{$CONFIG->{computers}{$computer}{users}}) {
97         my $pathshare = $CONFIG->{computers}{$computer}{share}
98                   || $CONFIG->{default}{share}
99                   || "/home/users";
100         my $share  = $CONFIG->{computers}{$computer}{users}{$user}{share}
101                   || "$pathshare/$user";
102         my $status = $CONFIG->{computers}{$computer}{users}{$user}{status}
103                   || $CONFIG->{computers}{$computer}{status}
104                   || $CONFIG->{default}{status}
105                   || 'auto';
106         my $admin  = $CONFIG->{computers}{$computer}{users}{$user}{admin}
107                   || $CONFIG->{computers}{$computer}{admin}
108                   || $CONFIG->{default}{admin}
109                   || 'root';
110
111         my $exclude = $CONFIG->{computers}{$computer}{users}{$user}{exclude}
112                   || $CONFIG->{computers}{$computer}{exclude}
113                   || '';
114
115         my @exclude_list = ();
116         if (ref($exclude) eq "ARRAY") {
117            push @exclude_list, @{$exclude};
118            }
119         else {
120            push @exclude_list, $exclude if not $exclude =~ m/^$/;
121            }
122         push @exclude_list, io($CONFIG->{default}{exclude})->chomp->slurp;
123         my $exclude_string = join ",\n", map { "    '$_'" } @exclude_list;
124
125         if ($status eq "auto") {
126            $status = "disable";
127            my $ldb = $LDAP_H->search(
128               base     => "$LDAP_BASE",
129               filter   => "(uid=$user)",
130               attrs    => ['shadowExpire', 'sambaKickoffTime'],
131               );
132            if (not $ldb->code ) {
133
134               LDAP_RESULT:
135               foreach my $entry ($ldb->entries) {
136
137                  my $user_expire_timestamp = $entry->get_value('sambaKickoffTime') || 0;
138                  my $user_shadow_expire = $entry->get_value('shadowExpire') || 0;
139
140                  if ($user_shadow_expire == 0) {
141                     $status = "enable";
142                     last LDAP_RESULT;
143                     }
144                  elsif (
145                     ( $user_expire_timestamp ne "" )
146                        and ( $user_expire_timestamp >  $LIMIT_TIMESTAMP )
147                     ) {
148                     $status = "enable";
149                     last LDAP_RESULT;
150                     }
151
152                  }
153               }
154            }
155
156         write_config($user, $computer, $share, $login, $admin, $status, $CONFIG, $exclude_string);
157
158         }
159
160      if (exists $CONFIG->{computers}{$computer}{subfolder}) {
161         my $home_path = $CONFIG->{computers}{$computer}{subfolder};
162         my @ls = `/bin/ping -W 2 -c 1 $computer > /dev/null 2>&1 && {
163            /usr/bin/nmap  -p 22 -PN $computer | grep -q '^22/tcp[[:space:]]*open\b' && {
164               /usr/bin/rsync --dry-run $login\@$computer:$home_path /tmp/backuppc-test/ || echo Error for $login\@$computer | logger -t backuppc-silzigan;
165               };
166            };`;
167
168         $home_path =~ s{/[^/]*$}{};
169         LINE:
170         for my $line (@ls) {
171            chomp $line;
172            next LINE if not $line =~ m/skipping\sdirectory/;
173            next LINE if $line =~ m/lost+found/;
174            next LINE if $line =~ m/administrator/;
175            my ($user) = reverse split /\s+/, $line;
176            $user =~ s{/$}{};
177            $user =~ s{.*/}{};
178            next LINE if not $user =~ m/^\w/;
179
180            my $share = "$home_path/$user";
181
182            my @exclude_list = ();
183            push @exclude_list, io($CONFIG->{default}{exclude})->chomp->slurp;
184            my $exclude_string = join ",\n", map { "    '$_'" } @exclude_list;
185
186            my $admin = $CONFIG->{computers}{$computer}{admin}
187                     || $CONFIG->{default}{admin}
188                     || 'root';
189
190            my $status = "disable";
191            my $ldb = $LDAP_H->search(
192               base     => "$LDAP_BASE",
193               filter   => "(uid=$user)",
194               attrs    => ['shadowExpire', 'sambaKickoffTime'],
195               );
196            if (not $ldb->code ) {
197
198               LDAP_RESULT:
199               foreach my $entry ($ldb->entries) {
200
201                  my $user_expire_timestamp = $entry->get_value('sambaKickoffTime') || 0;
202                  my $user_shadow_expire = $entry->get_value('shadowExpire') || 0;
203
204                  if ($user_shadow_expire == 0) {
205                     $status = "enable";
206                     last LDAP_RESULT;
207                     }
208                  elsif (
209                     ( $user_expire_timestamp ne "" )
210                        and ( $user_expire_timestamp >  $LIMIT_TIMESTAMP )
211                     ) {
212                     $status = "enable";
213                     last LDAP_RESULT;
214                     }
215
216                  }
217               }
218
219            write_config($user, $computer, $share, $login, $admin, $status, $CONFIG, $exclude_string);
220            }
221         }
222      }
223   close_ldap();
224   }
225
226sub cmd_exclude_list {
227   print io('/usr/lib/kont/etc/backuppc/exclude.txt')->all;
228   }
229
230sub write_config {
231   my ($user, $computer, $share, $login, $admin, $status, $CONFIG, $exclude) = @_;
232   my ($c) = split /\./, $computer;
233   my $backup_name = $c . '_'. $user;
234
235   return if $status eq 'disable' and not -e "/var/lib/backuppc/pc/$backup_name/backups";
236
237   print "$backup_name 0 $login $admin,$user\n" >> io($CONFIG->{default}{hosts});
238
239   my $share_string = "'$share'";
240   if (ref($share) eq "ARRAY") {
241      $share_string = join ', ', map("'$_'", @{$share});
242      }
243
244#   my $exclude = join ",\n", map { "    '$_'" } io('/usr/lib/kont/etc/backuppc/exclude.txt')->chomp->slurp;
245
246   print <<END > io("$CONFIG->{default}{path}/$backup_name.pl");
247\$Conf{XferMethod} = 'rsync';
248\$Conf{ClientNameAlias} = '$computer';
249\$Conf{RsyncShareName} = [ $share_string ];
250\$Conf{RsyncClientCmd} = '\$sshPath -q -x -l $login \$host \$rsyncPath \$argList+';
251\$Conf{RsyncClientRestoreCmd} = '\$sshPath -q -x -l $login \$host \$rsyncPath \$argList+';
252\$Conf{BackupFilesExclude} = {
253  '$share' => [
254$exclude
255  ]
256};
257END
258
259   print '$Conf{FullPeriod} = "-2";' >> io("$CONFIG->{default}{path}/$backup_name.pl") if $status eq 'disable';
260   symlink "$CONFIG->{default}{path}/$backup_name.pl", "/etc/backuppc/pc/$backup_name.pl";
261   }
262
263sub update_hosts {
264   io->catfile('/etc/backuppc/hosts.main') > io('/etc/backuppc/hosts.order');
265   my @hosts = io('/etc/backuppc/hosts.main')->chomp->slurp;
266
267   my $search_host_file = File::Finder->type('f')->name('hosts');
268   for my $host_file (File::Finder->eval($search_host_file)->in('/etc/backuppc/auto')) {
269      print "#\n# $host_file\n#\n" >> io('/etc/backuppc/hosts.order');
270      io->catfile("$host_file") >> io('/etc/backuppc/hosts.order');
271      push @hosts, io("$host_file")->chomp->slurp;
272      }
273   my ($first, @host) = grep(/./, grep(!/^#/, @hosts));
274   print "$first\n" > io('/etc/backuppc/hosts');
275   print "$_\n" >> io('/etc/backuppc/hosts') for shuffle(@host);
276   }
277
278sub cmd_init_db {
279   my $cfg = {
280      computers => {
281         'machine36.hmg.priv' => {
282            login => 'root',
283            share => '/home/users/%u',
284            status => 'auto',
285            users => {
286               'dupond' => {
287                  share => [ '/home/users/dupond', '/var/www/dupond' ],
288                  status => 'enable',
289                  },
290               'durand' => {
291                  share => '/home/users/durand',
292                  },
293               },
294            },
295         },
296      };
297
298   YAML::DumpFile("/tmp/template-backuppc.yaml", $cfg);
299   }
300
301sub cmd_help {
302   print <<'END';
303backuppc-silzigan - cut into small pieces a computer configuration for backuppc
304
305 backuppc-silzigan init
306 backuppc-silzigan generate config_file.yaml
307 backuppc-silzigan update
308 backuppc-silzigan help
309 backuppc-silzigan version
310 backuppc-silzigan exclude-list
311END
312   return;
313   }
314
315sub cmd_version {
316   print <<'END';
317backuppc-silzigan - cut into small pieces a computer configuration for backuppc
318Copyright (C) 2011-2019 Gabriel Moreau
319
320$Id: backuppc-silzigan..host.legilnx32 3821 2013-12-20 08:03:14Z g7moreau $
321END
322   return;
323   }
Note: See TracBrowser for help on using the repository browser.