source: trunk/ddt/ddt @ 301

Last change on this file since 301 was 301, checked in by g7moreau, 6 years ago
  • Small work on disable_float
  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 115.9 KB
Line 
1#!/usr/bin/perl
2#
3# Copyright (C) 2006-2018 Gabriel Moreau <Gabriel.Moreau(A)univ-grenoble-alpes.fr>
4# License GNU GPL version 2 or later and Perl equivalent
5#
6# apt-get install perl-base perl-modules libyaml-syck-perl libnet-netmask-perl libreadonly-perl libfile-touch-perl libtext-table-perl
7
8package DDT::RE;
9
10use strict;
11#use warnings;
12
13use Readonly;
14
15Readonly our $MAC_ADDRESS  => qr{ (?: [0-9A-F]{2} :){5} [0-9A-F]{2} }xms;
16Readonly our $IPv4_ADDRESS => qr{ [0-9]{1,3} \. [0-9]{1,3} \. [0-9]{1,3} \. [0-9]{1,3} }xms;
17
18
19package main;
20
21use strict;
22#use warnings;
23use version; our $VERSION = version->declare('0.9.7');
24
25use Getopt::Long qw(GetOptions);
26#use YAML;
27use YAML::Syck;
28use Net::Netmask;
29use File::Touch;
30use File::Copy;
31use Socket;
32use Text::Table;
33
34my $command = shift @ARGV || 'help';
35
36my %cmd_db = (
37   'add-alias'          => \&cmd_add_alias,
38   'add-dhcp'           => \&cmd_add_dhcp,
39   'add-float'          => \&cmd_add_float,
40   'add-static'         => \&cmd_add_static,
41   'add-virtual'        => \&cmd_add_virtual,
42   'change-comment'     => \&cmd_change_comment,
43   'change-domainset'   => \&cmd_change_domainset,
44   'change-host'        => \&cmd_change_host,
45   'change-ip'          => \&cmd_change_ip,
46   'change-mac'         => \&cmd_change_mac,
47   'change-tag'         => \&cmd_change_tag,
48   'check-dns'          => \&cmd_check_dns,
49   'create-domainset'   => \&cmd_create_domainset,
50   'create-pool'        => \&cmd_create_pool,
51   'create-pxe'         => \&cmd_create_pxe,
52   'create-tag'         => \&cmd_create_tag,
53   'del-pc'             => \&cmd_del_pc,
54   'del-float'          => \&cmd_del_float,
55   'disable-pc'         => \&cmd_disable_pc,
56   'disable-float'      => \&cmd_disable_float,
57   'disable-pxe'        => \&cmd_disable_pxe,
58   'enable-pc'          => \&cmd_enable_pc,
59   'enable-float'       => \&cmd_enable_float,
60   'enable-pxe'         => \&cmd_enable_pxe,
61   'gen-dhcp-file'      => \&cmd_generate_dhcp_file,
62   'gen-dns-file'       => \&cmd_generate_dns_file,
63   'help'               => \&cmd_help,
64   'load-database'      => \&cmd_load_database,
65   'remove-pxe'         => \&cmd_remove_pxe,
66   'remove-tag'         => \&cmd_remove_tag,
67   'search-mac'         => \&cmd_search_mac,
68   'show'               => \&cmd_show_host,
69   'show-domainset'     => \&cmd_show_domainset,
70   'show-pool'          => \&cmd_show_pool,
71   'show-pxe'           => \&cmd_show_pxe,
72   'show-tag'           => \&cmd_show_tag,
73   'upgrade-db'         => \&cmd_upgrade_db,
74   'version'            => \&cmd_version,
75   );
76
77#-------------------------------------------------------------------------------
78
79my $CONFIG;
80
81my $xdg_config_home = $ENV{'XDG_CONFIG_HOME'} || "$ENV{'HOME'}/.config";
82$CONFIG = config_load("$xdg_config_home/ddt/config.yml") if -e "$xdg_config_home/ddt/config.yml";
83
84my $COMPUTER_BASENAME   = $CONFIG->{'database'}{'basename'} || 'ddt';
85my $COMPUTER_EXT        = $CONFIG->{'database'}{'ext'}      || 'db';
86
87my $FOLDER_APP          = $CONFIG->{'database'}{'folder'}   || '/var/lib/ddt';
88my $FOLDER_BACKUP       = $CONFIG->{'database'}{'backup'}   || "$FOLDER_APP/backup";
89my $FOLDER_GEN_DHCP     = $CONFIG->{'generate'}{'dhcp'}     || "$FOLDER_APP/dhcp";
90my $FOLDER_GEN_DNS      = $CONFIG->{'generate'}{'dns'}      || "$FOLDER_APP/dns";
91my $SCRIPT_UPDATE       = $CONFIG->{'script'}{'update'}     || '/usr/share/ddt/update-dhcp-server';
92
93my $COMPUTER_YAML       = "$FOLDER_APP/$COMPUTER_BASENAME.$COMPUTER_EXT";
94
95#-------------------------------------------------------------------------------
96
97mkdir $FOLDER_APP, 0755      if not -d $FOLDER_APP;
98mkdir $FOLDER_BACKUP, 0755   if not -d $FOLDER_BACKUP;
99mkdir $FOLDER_GEN_DHCP, 0755 if not -d $FOLDER_GEN_DHCP;
100mkdir $FOLDER_GEN_DNS, 0755  if not -d $FOLDER_GEN_DNS;
101
102if (defined $cmd_db{$command}) {
103   $cmd_db{$command}->(@ARGV);
104   }
105else {
106   print {*STDERR} "ddt: command $command not found\n\n";
107   $cmd_db{'help'}->();
108   exit 1;
109   }
110
111exit;
112
113#--------------------------------------------------------------------------------
114# LOAD SAVE section
115#--------------------------------------------------------------------------------
116
117sub config_load {
118   my $config_file = shift;
119
120   my $configdb = YAML::Syck::LoadFile($config_file);
121
122   return $configdb;
123   }
124
125#---------------------------------------------------------------
126# Load computer database
127
128sub ipamdb_load {
129   my $database_yaml = shift;
130
131   touch $database_yaml if not -e $database_yaml;
132   my $computer_db = YAML::Syck::LoadFile($database_yaml);
133
134   # add database version if not exist
135   if (not exists $computer_db->{'version'}) {
136      $computer_db->{'version'} = 1;
137      }
138
139   return $computer_db;
140   }
141
142#---------------------------------------------------------------
143# Save computer database
144
145sub ipamdb_save {
146   my ($database_yaml, $computer_db) = @_;
147
148   my $dirdb = $database_yaml;
149      $dirdb =~ s{ / [^/]* $}{}xms;
150   mkdir "$dirdb", 0755 unless -d "$dirdb";
151   YAML::Syck::DumpFile($database_yaml, $computer_db);
152
153   return $computer_db;
154   }
155
156#--------------------------------------------------------------------------------
157# CONTROL section
158#--------------------------------------------------------------------------------
159
160sub control_exist_pool {
161   my ($computer_db, $pool) = @_;
162
163   return exists $computer_db->{'pool'}{$pool} ? 1 : 0;
164   }
165
166#-------------------------------------------------------------------------------
167#Nom: control_exist_domainset
168#Description: controle l'existence d'un domain set dans le fichier YAML
169#             return 0 (faux) ou 1 (vrai)
170
171sub control_exist_domainset {
172   my ($computer_db, $domainset) = @_;
173
174   return 1 if exists $computer_db->{$domainset};
175
176   print {*STDERR} "Error: domain set $domainset not found\n";
177   return 0;
178   }
179
180#-------------------------------------------------------------------------------
181#Nom: control_exist_hostname
182#Description: controle l'existence d'un nom de machine dans le fichier YAML
183#             return 0 (si trouvé) ou 1 (si non trouvé)
184
185sub control_exist_hostname {
186   my ($computer_db, $domainset, $hostname) = @_;
187
188   if ($computer_db->{$domainset} eq '') {
189      return 1;
190      }
191
192   my @domainsetdb = @{$computer_db->{$domainset}};
193
194   for my $value (@domainsetdb) {
195      for my $id (keys %{$value}) {
196         if ($value->{$id}->{'hostname'} eq $hostname) {
197            #print "Error: Hostname already exist: $hostname\n";
198            return 0;
199            }
200         }
201      }
202   return 1;
203   }
204
205#-------------------------------------------------------------------------------
206#Nom: control_exist_mac
207#Description: controle l'existence d'une adresse MAC dans le fichier YAML
208#             return 0 (si trouvé) ou 1 (si non trouvé)
209
210sub control_exist_mac {
211   my ($computer_db, $mac) = @_;
212
213   for my $domainset_current (keys %{$computer_db}) {
214      next if $domainset_current eq 'dset';
215      next if $domainset_current eq 'pool';
216      next if $domainset_current eq 'pxe';
217      next if $domainset_current eq 'tag';
218      next if $domainset_current eq 'version';
219
220      my @domainsetdb = @{$computer_db->{$domainset_current}};
221      for my $value (@domainsetdb) {
222         for my $id (keys %{$value}) {
223            if ($id eq $mac) {
224               #print "Error: Physical MAC address already exists: $mac\n";
225               return 0;
226               }
227            }
228         }
229      }
230   return 1;
231   }
232
233#-------------------------------------------------------------------------------
234#Nom: control_exist_ip
235#Description: controle l'existence d'une adresse IP dans le fichier YAML
236#             return 0 (si trouvé) ou 1 (si non trouvé)
237
238sub control_exist_ip {
239   my ($computer_db, $ip) = @_;
240
241   for my $domainset_current (keys %{$computer_db}) {
242      next if $domainset_current eq 'dset';
243      next if $domainset_current eq 'pool';
244      next if $domainset_current eq 'pxe';
245      next if $domainset_current eq 'tag';
246      next if $domainset_current eq 'version';
247
248      for my $value (@{$computer_db->{$domainset_current}}) {
249         for my $id (keys %{$value}) {
250            #print "Erreur: cette adresse IP $ip existe déjà\n";
251            return 0 if $value->{$id}{'ip'} eq $ip;
252            }
253         }
254      }
255
256   for my $current_pool (keys %{$computer_db->{'pool'}}) {
257         #--- Cette partie pour tester les ip des pools est bonne ne plus la changer ---#
258      my @T_pool_ip = @{ $computer_db->{'pool'}{$current_pool}{'ip'}};
259
260      for my $pool_ip (@T_pool_ip) {
261         #print "Erreur: cette adresse IP $ip existe déjà\n";
262         return 0 if $pool_ip eq $ip;
263         }
264      }
265
266   return 1;
267   }
268
269#-------------------------------------------------------------------------------------
270#Nom: control_syntaxe_mac
271#Description: controle la syntaxe d'une adresse MAC (juste la longueur pas les valeurs)
272#             return 0 (si trouvé) ou 1 (si non trouvé)
273
274sub control_syntax_mac_address {
275   my $mac = shift;
276
277   if (scalar(split /:/, $mac) == 6 and $mac =~ $DDT::RE::MAC_ADDRESS) {
278      return 1;
279      }
280
281   print {*STDERR} "Error: Bad MAC syntax: $mac\n";
282   return 0;
283   }
284
285#-------------------------------------------------------------------------------------
286#Nom: control_syntax_ip
287#Description: controle la syntaxe d'une adresse IP (juste la longueur pas les valeurs)
288#             return 0 (si trouvé) ou 1 (si non trouvé)
289
290sub control_syntax_ip {
291   my $ip = shift;
292
293   if ($ip ne 'pool') {
294      my @ip_split = split /\./, $ip;
295
296      if ( scalar(@ip_split) != 4 ) {
297         print {*STDERR} "Error: Bad IP syntax: $ip\n";
298         return 0;
299         }
300      }
301   return 1;
302   }
303
304#-------------------------------------------------------------------------------------
305
306sub control_syntax_comment {
307   my $comment = shift;
308
309   if ($comment !~ m{^20\d\d-\d\d-\d\d\s}) {
310      print {*STDERR} "Syntax Error: No date like 2014-01-10 at the beginning: $comment\n";
311      return 0;
312      }
313
314   if ($comment !~ m{\(\w+\)$}) {
315      print {*STDERR} "Syntax Error: No (SERVICE) at the end: $comment\n";
316      return 0;
317      }
318
319   if ($comment =~ m{\s\s}) {
320      print {*STDERR} "Syntax Error: Double space: $comment\n";
321      return 0;
322      }
323   return 1;
324   }
325
326#--------------------------------------------------------------------------------
327# UTILITY section
328#--------------------------------------------------------------------------------
329
330sub get_cmd_name {
331   my ($pkg, $sub) = split /::/, (caller(1))[3];
332   $sub =~ s/^cmd_//;
333   $sub =~ s/_/-/g;
334   return $sub;
335   }
336
337#-------------------------------------------------------------------------------
338
339sub normalize_mac_address {
340   my $mac_address = shift;
341
342   # D07E-28D1-7AB8 or d07e28-d17ab8
343   if ($mac_address =~ m{^ (?: [0-9A-Fa-f]{4} -){2} [0-9A-Fa-f]{4} $}xms
344      or $mac_address =~ m{^ [0-9A-Fa-f]{6} - [0-9A-Fa-f]{6} $}xms) {
345      $mac_address =~ s/-//g;
346      return join q{:}, unpack('(A2)*', uc($mac_address));
347      }
348
349   return join q{:}, map { substr( uc("00$_"), -2) } split m/ [:-] /xms, $mac_address;
350   }
351
352#-------------------------------------------------------------------------------
353
354sub normalize_comment {
355   my $comment = shift;
356
357   $comment =~ s{^(20\d\d)/(\d\d)/(\d\d)\s(.*)$}{$1-$2-$3 $4};
358
359   return $comment;
360   }
361
362#--------------------------------------------------------------------------------
363
364sub get_mac_from_hostname {
365   my ($computer_db, $domainset, $hostname, $mac) = @_;
366
367   return $mac if $mac ne '';
368   return ''   if $hostname eq '';
369
370   LOOP_ON_COMPUTER:
371   for my $computer (@{$computer_db->{$domainset}}) {
372      my ($mac_address, $attribute) = %{$computer};
373
374      next LOOP_ON_COMPUTER if $attribute->{'hostname'} ne $hostname;
375
376      return $mac_address;
377      }
378   }
379
380#--------------------------------------------------------------------------------
381
382sub get_mac_from_ip {
383   my ($computer_db, $domainset, $ip, $mac) = @_;
384
385   return $mac if $mac ne '';
386   return ''   if $ip eq '';
387
388   LOOP_ON_COMPUTER:
389   for my $computer (@{$computer_db->{$domainset}}) {
390      my ($mac_address, $attribute) = %{$computer};
391
392      next LOOP_ON_COMPUTER if $attribute->{'ip'} ne $ip;
393      return $mac_address;
394      }
395   }
396
397#--------------------------------------------------------------------------------
398# return a tuple (hash computer, iostat)
399# iostat 0/ok, 1/not exist
400
401sub get_computer_from_mac {
402   my ($computer_db, $domainset, $mac) = @_;
403
404   LOOP_ON_COMPUTER:
405   for my $computer (@{$computer_db->{$domainset}}) {
406      my ($mac_address, $attribute) = %{$computer};
407
408      next LOOP_ON_COMPUTER if $mac_address ne $mac;
409
410      return $attribute, 0;
411      }
412   return {}, 1;
413   }
414
415#-------------------------------------------------------------------------------
416# ADD computer section
417#-------------------------------------------------------------------------------
418
419#-------------------------------------------------------------------------------
420#Nom: add_alias
421#Description: ajoute un alias pour une machine. Pour la fonctionnalité CNAME dans le DNS.
422
423sub add_alias {
424   my ($computer_db, $hostname, $domainset, $alias) = @_;
425
426   control_exist_domainset($computer_db, $domainset) or exit;
427   control_exist_hostname($computer_db, $domainset, $hostname) or die "Error: Hostname already exist in domain set attachement $domainset: $hostname\n";
428
429   my @domainsetdb = @{$computer_db->{$domainset}};
430   my $cpt=0;
431   for my $value (@domainsetdb) {
432      for my $id (keys %{$value}) {
433
434         if ($value->{$id}->{'hostname'} eq $hostname) {
435            print  $value->{$id}->{'alias'};
436            $alias = $alias . ' ' . $value->{$id}->{'alias'};
437            $computer_db->{$domainset}[$cpt]{$id}{'alias'}        = $alias;
438            $computer_db->{$domainset}[$cpt]{$id}{'modify_time'}  = time;
439            ipamdb_save("$COMPUTER_YAML", $computer_db);
440            print "Update attribute alias [OK]\n";
441            exit;
442            }
443         }
444      $cpt=$cpt+1;
445      }
446   }
447
448#-------------------------------------------------------------------------------
449#Nom: add_static
450#Description: ajoute une machine non dhcp (donc à adressage fixe dans le fichier YAML)
451
452sub add_static {
453   my ($computer_db, $hostname, $domainset, $ip, $mac, $comment) = @_;
454
455   $mac = normalize_mac_address($mac);
456   $comment = normalize_comment($comment);
457   control_exist_hostname($computer_db, $domainset, $hostname) or die "Error: Hostname already exist in domain set attachement $domainset: $hostname\n";
458   control_syntax_mac_address($mac)                   or exit;
459   control_exist_mac($computer_db, $mac)              or die "Error: Physical MAC address already exists: $mac\n";
460   control_syntax_ip($ip)                             or exit;
461   control_exist_ip($computer_db, $ip)                or die "Error: IP address already exist in domain set attachement $domainset: $ip\n";
462   control_syntax_comment($comment)                   or exit;
463   my $timestamp = time;
464   push @{$computer_db->{$domainset}}, { $mac => {
465      'hostname'     => $hostname,
466      'ip'           => $ip,
467      'address_type' => 'static',
468      'enabled'      => 'yes',
469      'create_time'  => $timestamp,
470      'modify_time'  => $timestamp,
471      'comment'      => $comment,
472      'alias'        =>  '',
473      }};
474   print "Add the computer: $hostname, IP: $ip, MAC: $mac, Domain Set: $domainset\n";
475
476   ipamdb_save("$COMPUTER_YAML", $computer_db);
477   }
478
479
480#-------------------------------------------------------------------------------
481#Nom: add_dhcp
482#Description: section à corriger pour prendre en compte l'ajout d'une machine dans un pool dhcp
483#--- usage: ddt add_dhcp -d legi-sector03 -h meolpacif -m 00:18:F3:03:6F:66 -i 194.254.66.165
484
485sub add_dhcp {
486   my ($computer_db, $hostname, $domainset, $ip, $mac, $comment) = @_;
487
488   my $timestamp = time;
489   $mac = normalize_mac_address($mac);
490   $comment = normalize_comment($comment);
491   control_exist_domainset($computer_db, $domainset)  or exit;
492   control_exist_hostname($computer_db, $domainset, $hostname) or die "Error: Hostname already exist in domain set attachement $domainset: $hostname\n";
493   control_syntax_mac_address($mac)                   or exit;
494   control_exist_mac($computer_db, $mac)              or die "Error: Physical MAC address already exists: $mac\n";
495   control_syntax_ip($ip)                             or exit;
496   control_exist_ip($computer_db, $ip)                or die "Error: IP address already exist in domain set attachement $domainset: $ip.\n";
497   control_syntax_comment($comment)                   or exit;
498
499   push @{$computer_db->{$domainset}}, { $mac => {
500      'hostname'     => $hostname,
501      'ip'           => $ip,
502      'address_type' => 'dhcp',
503      'enabled'      => 'yes',
504      'create_time'  => $timestamp,
505      'modify_time'  => $timestamp,
506      'comment'      => $comment,
507      'alias'        => '',
508      }};
509   print "Add the computer: $hostname, IP: $ip, MAC: $mac, Domain Set: $domainset\n";
510
511   ipamdb_save("$COMPUTER_YAML", $computer_db);
512   }
513
514#-------------------------------------------------------------------------------
515#--- usage: ddt add_float -d legi-sector03 -h meolpacif -m 00:18:F3:03:6F:66 -i 194.254.66.165
516
517sub add_float {
518   my ($computer_db, $pool, $domainset, $mac, $comment) = @_;
519
520   my $timestamp = time;
521   $mac = normalize_mac_address($mac);
522   $comment = normalize_comment($comment);
523   control_exist_domainset($computer_db, $domainset)  or exit;
524   control_syntax_mac_address($mac)                   or exit;
525   control_exist_mac($computer_db, $mac)              or die "Error: Physical MAC address already exists: $mac\n";
526   control_exist_pool($computer_db, $pool)            or die "Error: The pool doesn't exists: $pool\n";
527   control_syntax_comment($comment)                   or exit;
528   push @{$computer_db->{$domainset}}, { $mac => {
529      'hostname'     => $pool,
530      'ip'           => $pool,
531      'address_type' => 'pool-dhcp',
532      'enabled'      => 'yes',
533      'create_time'  => $timestamp,
534      'modify_time'  => $timestamp,
535      'comment'      => $comment,
536      }};
537   print "Add the computer in pool MAC: $mac, Domain Set: $domainset, Pool: $pool\n";
538
539   ipamdb_save("$COMPUTER_YAML", $computer_db);
540   }
541
542#-------------------------------------------------------------------------------
543# ADD computer section
544#-------------------------------------------------------------------------------
545
546sub cmd_add_alias {
547   local @ARGV = @_;
548
549   my $help = get_cmd_name();
550   my ($hostname, $domainset, $alias);
551
552   GetOptions(
553      'hostname|h=s'    => \$hostname,
554      'domainset|d=s'   => \$domainset,
555      'alias|a=s'       => \$alias,
556      );
557
558   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
559   exit_on_error_option($help)
560      if $hostname   eq ''
561      or $domainset  eq ''
562      or $alias      eq '';
563
564   my $computer_db = ipamdb_load($COMPUTER_YAML);
565   add_alias($computer_db, $hostname, $domainset, $alias);
566   }
567
568#-------------------------------------------------------------------------------
569
570sub cmd_add_dhcp {
571   local @ARGV = @_;
572
573   my $help = get_cmd_name();
574   my ($hostname, $domainset, $ip, $mac, $comment);
575
576   GetOptions(
577      'hostname|h=s'    => \$hostname,
578      'domainset|d=s'   => \$domainset,
579      'ip|i=s'          => \$ip,
580      'mac|m=s'         => \$mac,
581      'comment|c=s'     => \$comment,
582      );
583
584   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
585   exit_on_error_option($help)
586      if $hostname   eq ''
587      or $domainset  eq ''
588      or $ip         eq ''
589      or $mac        eq ''
590      or $comment    eq '';
591
592   my $computer_db = ipamdb_load($COMPUTER_YAML);
593   add_dhcp($computer_db, $hostname, $domainset, $ip, $mac, $comment);
594   }
595
596#-------------------------------------------------------------------------------
597
598sub cmd_add_float {
599   local @ARGV = @_;
600
601   my $help = get_cmd_name();
602   my ($pool, $domainset, $mac, $comment);
603
604   GetOptions(
605      'pool|p=s'        => \$pool,
606      'domainset|d=s'   => \$domainset,
607      'mac|m=s'         => \$mac,
608      'comment|c=s'     => \$comment,
609      );
610
611   ($pool, $domainset) = split /\./, $pool, 2 if $pool =~ m/\./;
612   exit_on_error_option($help)
613      if $pool       eq ''
614      or $domainset  eq ''
615      or $mac        eq ''
616      or $comment    eq '';
617
618   my $computer_db = ipamdb_load($COMPUTER_YAML);
619   add_float($computer_db, $pool, $domainset, $mac, $comment);
620   }
621
622#-------------------------------------------------------------------------------
623
624sub cmd_add_static {
625   local @ARGV = @_;
626
627   my $help = get_cmd_name();
628   my ($hostname, $domainset, $ip, $mac, $comment);
629
630   GetOptions(
631      'hostname|h=s'    => \$hostname,
632      'domainset|d=s'   => \$domainset,
633      'ip|i=s'          => \$ip,
634      'mac|m=s'         => \$mac,
635      'comment|c=s'     => \$comment,
636      );
637
638   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
639   exit_on_error_option($help)
640      if $hostname   eq ''
641      or $domainset  eq ''
642      or $ip         eq ''
643      or $mac        eq ''
644      or $comment    eq '';
645
646   my $computer_db = ipamdb_load($COMPUTER_YAML);
647   add_static($computer_db, $hostname, $domainset, $ip, $mac, $comment);
648   }
649
650#-------------------------------------------------------------------------------
651# No real computer, just an entry A in DNS with virtual MAC
652
653sub cmd_add_virtual {
654   local @ARGV = @_;
655
656   my $help = get_cmd_name();
657   my ($hostname, $domainset, $ip, $comment);
658
659   GetOptions(
660      'hostname|h=s'    => \$hostname,
661      'domainset|d=s'   => \$domainset,
662      'ip|i=s'          => \$ip,
663      'comment|c=s'     => \$comment,
664      );
665
666   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
667   exit_on_error_option($help)
668      if $hostname   eq ''
669      or $domainset  eq ''
670      or $ip         eq ''
671      or $comment    eq '';
672
673   my $computer_db = ipamdb_load($COMPUTER_YAML);
674
675   $comment = normalize_comment($comment);
676   my $timestamp = time;
677
678   control_exist_domainset($computer_db, $domainset)           or exit;
679   control_exist_hostname($computer_db, $domainset, $hostname) or die "Error: Hostname already exist in domain set attachement $domainset: $hostname\n";
680   control_syntax_ip($ip)                                      or exit;
681   control_exist_ip($computer_db, $ip)                         or die "Error: IP address already exist in domain set attachement $domainset: $ip.\n";
682   control_syntax_comment($comment)                            or exit;
683
684   my $mac = join ':', 'FF', 'FF', map({sprintf("%02X", $_)} split(/\./, $ip));
685   control_syntax_mac_address($mac)             or exit;
686   control_exist_mac($computer_db, $mac)         or die "Error: Virtual Physical MAC address already exists: $mac\n";
687
688   push @{$computer_db->{$domainset}}, { $mac => {
689      'hostname'     => $hostname,
690      'ip'           => $ip,
691      'address_type' => 'static',
692      'enabled'      => 'yes',
693      'create_time'  => $timestamp,
694      'modify_time'  => $timestamp,
695      'comment'      => $comment,
696      }};
697   print "Add the virtual computer: $hostname, IP: $ip, Domain Set: $domainset\n";
698
699   ipamdb_save("$COMPUTER_YAML", $computer_db);
700   }
701
702#-------------------------------------------------------------------------------
703# CHANGE computer section
704#-------------------------------------------------------------------------------
705
706#-------------------------------------------------------------------------------
707#Nom: change_mac
708#Description: change la mac adresse d'une machine en saisissant soit l'ip
709#             soit le nom de la mahcine et spécifiant le domaine
710#--- usage: ddt change_mac -d legi-sector03 -h meolpacif -m 00:18:F3:03:6F:66
711#--- usage: ddt change_mac -d legi-sector03 -i 194.254.66.187 -m 00:18:F3:03:6F:66
712
713sub change_mac {
714   my ($hostname, $domainset, $ip, $mac) = @_;
715
716   my $computer_db = ipamdb_load($COMPUTER_YAML);
717
718   $mac = normalize_mac_address($mac);
719   control_exist_domainset($computer_db, $domainset)  or exit;
720   control_syntax_mac_address($mac)                   or exit;
721   control_exist_mac($computer_db, $mac)              or die "Error: Physical MAC address already exists: $mac\n";
722   if ($ip ne '') {
723      control_syntax_ip($ip) or exit;
724      if ( control_exist_ip($computer_db, $ip) == 1 ) {
725         print "Error: Unkown IP address: $ip\n";
726         exit;
727         }
728      my @domainsetdb = @{$computer_db->{$domainset}};
729      my $cpt = 0;
730      for my $value (@domainsetdb) {
731         for my $id (keys %{$value}) {
732            if ($value->{$id}->{'ip'} eq $ip) {
733               my $host = $value->{$id};
734               $host->{'modify_time'} = time;
735               $computer_db->{$domainset}->[$cpt] = { $mac => $host };
736               ipamdb_save("$COMPUTER_YAML", $computer_db);
737               print "Update [OK]\n";
738               print "Hostname: $host->{'hostname'}\n";
739               print "MAC: $mac\n";
740               print "IP: $host->{'ip'}\n";
741               exit;
742               }
743            $cpt++;
744            }
745         }
746         #print "Mise à jour de l'adresse MAC [FAILED]\n";
747         #print "l'adresse IP n'existe pas sur le domaine $domainset\n";
748      }
749   elsif ($hostname ne '') {
750      if ( control_exist_hostname($computer_db, $domainset, $hostname) == 1 ) {
751         die "Error: Unkown host: $hostname, in domain set: $domainset\n";
752         }
753      my @domainsetdb = @{$computer_db->{$domainset}};
754      my $cpt = 0;
755      for my $value (@domainsetdb) {
756         for my $id (keys %{$value}) {
757            if ($value->{$id}->{'hostname'} eq $hostname) {
758               my $host = $value->{$id};
759               $host->{'modify_time'} = time;
760               $computer_db->{$domainset}->[$cpt] = { $mac => $host };
761               ipamdb_save("$COMPUTER_YAML", $computer_db);
762               print "Update [OK]\n";
763               print "Hostname: $host->{'hostname'}\n";
764               print "MAC: $mac\n";
765               print "IP: $host->{'ip'}\n";
766               exit;
767               }
768            }
769         $cpt++;
770         }
771      }
772   }
773
774#-------------------------------------------------------------------------------
775#Nom: change_ip
776#Description: change l'adresse IP d'une machine en saisissant le nom de la machine
777#             et le domaine
778
779sub change_ip {
780   my ($hostname, $domainset, $ip) = @_;
781
782   my $computer_db = ipamdb_load($COMPUTER_YAML);
783
784   control_exist_domainset($computer_db, $domainset) or exit;
785   if ( control_exist_hostname($computer_db, $domainset, $hostname) == 1 ) {
786      die "Error: Unkown host: $hostname, in domain set: $domainset\n";
787      }
788   control_syntax_ip($ip) or exit;
789   control_exist_ip($computer_db, $ip) or die "Error: IP address already exist in domain set attachement $domainset: $ip\n";
790   my @domainsetdb = @{$computer_db->{$domainset}};
791   my $cpt = 0;
792   for my $value (@domainsetdb) {
793      for my $id (keys %{$value}) {
794         if (($value->{$id}->{'hostname'} eq $hostname)
795               and (
796                  ($value->{$id}->{'address_type'} eq 'dhcp')
797                  or ($value->{$id}->{'address_type'} eq 'static')
798                  )
799               ) {
800            $computer_db->{$domainset}[$cpt]{$id}{'ip'} = $ip;
801            $computer_db->{$domainset}[$cpt]{$id}{'modify_time'} = time;
802            ipamdb_save("$COMPUTER_YAML", $computer_db);
803            print "Update [OK]\n";
804            print "Hostname: $hostname\n";
805            print "MAC: $id\n";
806            print "IP: $ip\n";
807            exit;
808            }
809         else {
810            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} eq 'pool-dhcp')) {
811               print "Modification de l'adresse IP [FAILED]\n";
812               print "La machine $hostname sur le domain set $domainset fait partie du pool DHCP ".$value->{$id}->{'ip'}."\n";
813               print "Veuillez la supprimer du pool et la recréer avec l'adresse IP que vous souhaitez.\n";
814               exit;
815               }
816            }
817         }
818      $cpt++;
819      }
820   }
821
822#-------------------------------------------------------------------------------
823#Nom: change_host
824#Description: change le computer hostname en saisissant l'IP et le domaine
825
826sub change_host {
827   my ($hostname, $domainset, $ip) = @_;
828
829   my $computer_db = ipamdb_load($COMPUTER_YAML);
830
831   control_exist_domainset($computer_db, $domainset) or exit;
832   control_syntax_ip($ip)   or exit;
833   if ( control_exist_ip($computer_db, $ip) == 1 ) {
834      print "Error: Unkown IP address: $ip\n";
835      exit;
836      }
837   control_exist_hostname($computer_db, $domainset, $hostname) or die "Error: Hostname already exist in domain set attachement $domainset: $hostname\n";
838
839   my @domainsetdb = @{$computer_db->{$domainset}};
840   my $cpt = 0;
841   for my $value (@domainsetdb) {
842      for my $id (keys %{$value}) {
843         if ($value->{$id}->{'ip'} eq $ip) {
844            $computer_db->{$domainset}[$cpt]{$id}{'hostname'} = $hostname;
845            $computer_db->{$domainset}[$cpt]{$id}{'modify_time'} = time;
846            ipamdb_save("$COMPUTER_YAML", $computer_db);
847            print "Update [OK]\n";
848            print "Hostname: $hostname\n";
849            print "MAC: $id\n";
850            print "IP: $ip\n";
851            exit;
852            }
853         }
854      $cpt++;
855      }
856   print "Error: Failed to update computer hostname\n";
857   print "L'adresse IP: $ip n'existe pas dans le domaine: $domainset.\n";
858   }
859
860#--------------------------------------------------------------------------------
861
862sub cmd_change_mac {
863   local @ARGV = @_;
864
865   my $help = get_cmd_name();
866   my ($hostname, $domainset, $ip, $mac);
867
868   GetOptions(
869      'hostname|h=s'    => \$hostname,
870      'domainset|d=s'   => \$domainset,
871      'ip|i=s'          => \$ip,
872      'mac|m=s'         => \$mac,
873      );
874
875   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
876   exit_on_error_option($help)
877      if $domainset  eq ''
878      or $mac        eq '';
879   exit_on_error_option($help)
880      if $hostname   ne ''
881      and $ip        ne '';
882
883   change_mac($hostname, $domainset, $ip, $mac);
884   }
885
886#--------------------------------------------------------------------------------
887
888sub cmd_change_ip {
889   local @ARGV = @_;
890
891   my $help = get_cmd_name();
892   my ($hostname, $domainset, $ip);
893
894   GetOptions(
895      'hostname|h=s'    => \$hostname,
896      'domainset|d=s'   => \$domainset,
897      'ip|i=s'          => \$ip,
898      );
899
900   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
901   exit_on_error_option($help)
902      if $hostname   eq ''
903      or $domainset  eq ''
904      or $ip         eq '';
905
906   change_ip($hostname, $domainset, $ip);
907   }
908
909#--------------------------------------------------------------------------------
910
911sub cmd_change_host {
912   local @ARGV = @_;
913
914   my $help = get_cmd_name();
915   my ($hostname, $domainset, $ip);
916
917   GetOptions(
918      'hostname|h=s'    => \$hostname,
919      'domainset|d=s'   => \$domainset,
920      'ip|i=s'          => \$ip,
921      );
922
923   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
924   exit_on_error_option($help)
925      if $hostname   eq ''
926      or $domainset  eq ''
927      or $ip         eq '';
928
929   change_host($hostname, $domainset, $ip);
930   }
931
932#--------------------------------------------------------------------------------
933
934sub cmd_change_comment {
935   local @ARGV = @_;
936
937   my $help = get_cmd_name();
938   my ($domainset, $mac, $comment);
939
940   GetOptions(
941      'domainset|d=s'   => \$domainset,
942      'mac|m=s'         => \$mac,
943      'comment|c=s'     => \$comment,
944      );
945
946   exit_on_error_option($help)
947      if $domainset  eq ''
948      or $mac        eq ''
949      or $comment    eq '';
950
951   $mac     = normalize_mac_address($mac);
952   $comment = normalize_comment($comment);
953
954   my $computer_db = ipamdb_load($COMPUTER_YAML);
955
956   control_exist_domainset($computer_db, $domainset)   or exit;
957   control_syntax_mac_address($mac)                   or exit;
958   control_syntax_comment($comment)                   or exit;
959
960   my @domainsetdb = @{$computer_db->{$domainset}};
961   my $cpt = 0;
962   for my $value (@domainsetdb) {
963      for my $id (keys %{$value}) {
964         if ($id eq $mac) {
965            my $host = $computer_db->{$domainset}[$cpt]{$mac};
966            $host->{'comment'}     = $comment;
967            $host->{'modify_time'} = time;
968
969            ipamdb_save("$COMPUTER_YAML", $computer_db);
970            exit;
971            }
972         }
973      $cpt++;
974      }
975   print "Mise à jour du commentaire de la machine [FAILED]\n";
976   print "L'adresse MAC: $mac n'existe pas dans le domaine: $domainset.\n";
977   }
978
979#--------------------------------------------------------------------------------
980
981sub cmd_change_domainset {
982   local @ARGV = @_;
983
984   my $help = get_cmd_name();
985   my ($domainset, $ip, $mac);
986
987   GetOptions(
988      'domainset|d=s'   => \$domainset,
989      'ip|i=s'          => \$ip,
990      'mac|m=s'         => \$mac,
991      );
992
993   exit_on_error_option($help)
994      if $domainset  eq ''
995      or $ip         eq ''
996      or $mac        eq '';
997
998   $mac = normalize_mac_address($mac);
999
1000   my $computer_db = ipamdb_load($COMPUTER_YAML);
1001
1002   control_exist_domainset($computer_db, $domainset)   or exit;
1003   control_syntax_ip($ip)                             or exit;
1004   control_syntax_mac_address($mac)                   or exit;
1005
1006   LOOP_ON_DOMAINSET:
1007   for my $domainset_current (keys %{$computer_db}) {
1008      next if $domainset_current eq 'dset';
1009      next if $domainset_current eq 'pool';
1010      next if $domainset_current eq 'pxe';
1011      next if $domainset_current eq 'tag';
1012      next if $domainset_current eq 'version';
1013
1014      my @domainsetdb = @{$computer_db->{$domainset_current}};
1015      my $cpt_mac = 0;
1016      for my $value (@domainsetdb) {
1017         for my $id (keys %{$value}) {
1018            if ($id eq $mac) {
1019               my $host = $computer_db->{$domainset_current}[$cpt_mac]{$mac};
1020               next LOOP_ON_DOMAINSET if $host->{'ip'} ne $ip;
1021
1022               $host->{'modify_time'} = time;
1023               splice(@{$computer_db->{$domainset_current}}, $cpt_mac => 1);
1024               push @{$computer_db->{$domainset}}, { $mac => $host };
1025
1026               ipamdb_save("$COMPUTER_YAML", $computer_db);
1027               exit;
1028               }
1029            }
1030         $cpt_mac++;
1031         }
1032      }
1033   print "Update of domain set $domainset [FAILED]\n";
1034   print "L'adresse MAC: $mac ou l'adresse IP: $ip n'existe pas dans la base\n";
1035   }
1036
1037#--------------------------------------------------------------------------------
1038
1039sub cmd_change_tag {
1040   local @ARGV = @_;
1041
1042   my $help = get_cmd_name();
1043   my ($hostname, $domainset, $ip, $mac, $tags);
1044
1045   GetOptions(
1046      'hostname|h=s'    => \$hostname,
1047      'domainset|d=s'   => \$domainset,
1048      'ip|i=s'          => \$ip,
1049      'mac|m=s'         => \$mac,
1050      'tag|t=s'         => \$tags,
1051      );
1052
1053   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
1054
1055   exit_on_error_option($help)
1056      if $domainset  eq ''
1057      or $tags       eq '';
1058   exit_on_error_option($help)
1059      if $mac        eq ''
1060      and $hostname  eq ''
1061      and $ip        eq '';
1062
1063   $mac = normalize_mac_address($mac);
1064
1065   my $computer_db = ipamdb_load($COMPUTER_YAML);
1066
1067   if ($tags !~ m/^ (?:\w+,)* \w+ $/xms) {
1068      die "Error: Bad format for tags (comma separated list): $tags\n";
1069      }
1070
1071   for my $tag (split/,/, $tags) {
1072      next if $tag eq 'universal';
1073      die "Error: TAG doesn't exist in the database. Create it before with create_tag: $tag\n" if not exists $computer_db->{'tag'}{$tag};
1074      }
1075
1076   control_exist_domainset($computer_db, $domainset) or exit;
1077
1078   $mac = get_mac_from_ip($computer_db, $domainset, $ip, $mac)             if $ip ne '';
1079   $mac = get_mac_from_hostname($computer_db, $domainset, $hostname, $mac) if $hostname ne '';
1080   control_syntax_mac_address($mac) or exit;
1081
1082   LOOP_ON_COMPUTER:
1083   for my $computer (@{$computer_db->{$domainset}}) {
1084      my ($mac_address, $attribute) = %{$computer};
1085
1086      next LOOP_ON_COMPUTER if $mac_address ne $mac;
1087
1088      $attribute->{'tag'}         = $tags;
1089      $attribute->{'modify_time'} = time;
1090
1091      delete $attribute->{'tag'} if $tags eq 'universal';
1092      ipamdb_save("$COMPUTER_YAML", $computer_db);
1093      exit;
1094      }
1095   print "Mise à jour du commentaire de la machine [FAILED]\n";
1096   print "L'adresse MAC: $mac n'existe pas dans le domaine: $domainset.\n";
1097   }
1098
1099#-------------------------------------------------------------------------------
1100# ACTIVATION section
1101#-------------------------------------------------------------------------------
1102
1103#-------------------------------------------------------------------------------
1104#Nom: disable_pc
1105#Description: désactive une machine (du DHCP ou en IP statique, et du DNS) (champs enabled=non)
1106
1107sub disable_pc {
1108   my ($hostname, $domainset, $ip) = @_;
1109
1110   my $computer_db = ipamdb_load($COMPUTER_YAML);
1111
1112   if ($ip ne '') {
1113      control_syntax_ip($ip);
1114      if ( control_exist_ip($computer_db, $ip) == 1 ) {
1115         print "Error: Unkown IP address: $ip\n";
1116         exit;
1117         }
1118
1119      for my $domainset_current (keys %{$computer_db}) {
1120         next if $domainset_current eq 'dset';
1121         next if $domainset_current eq 'pool';
1122         next if $domainset_current eq 'pxe';
1123         next if $domainset_current eq 'tag';
1124         next if $domainset_current eq 'version';
1125
1126         my @domainsetdb = @{$computer_db->{$domainset_current}};
1127         my $cpt_mac = 0;
1128         for my $value (@domainsetdb) {
1129            for my $id (keys %{$value}) {
1130
1131               if ($value->{$id}->{'ip'} eq $ip) {
1132                  my $timestamp = time;
1133                  $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
1134                  $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'enabled'} = 'no';
1135                  print "L'adresse IP: $ip a été désactivée. Valeur du champs enabled: [".$computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'enabled'}."]\n";
1136                  ipamdb_save("$COMPUTER_YAML", $computer_db);
1137                  exit;
1138                  }
1139               $cpt_mac++;
1140               }
1141            }
1142         }
1143      }
1144   else {
1145      control_exist_domainset($computer_db, $domainset);
1146      if ( control_exist_hostname($computer_db, $domainset, $hostname) == 1 ) {
1147         die "Error: Unkown host: $hostname, in domain set: $domainset\n";
1148         }
1149
1150      my $cpt_mac = 0;
1151      for my $value (@{$computer_db->{$domainset}}) {
1152         for my $id (keys %{$value}) {
1153            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} ne 'pool-dhcp')) {
1154               my $timestamp = time;
1155               $computer_db->{$domainset}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
1156               $computer_db->{$domainset}[$cpt_mac]->{$id}->{'enabled'} = 'no';
1157               print "La machine $hostname (domaine: $domainset) a été désactivé du DHCP. Valeur du champs enabled: [".$computer_db->{$domainset}[$cpt_mac]->{$id}->{'enabled'}."]\n";
1158               ipamdb_save("$COMPUTER_YAML", $computer_db);
1159               exit;
1160               }
1161
1162            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} eq 'pool-dhcp')) {
1163               print "Désactivation de la machine $hostname sur le domaine $domainset [FAILED]\n";
1164               print "La machine $hostname fait partie du pool $hostname.\n";
1165               exit;
1166               }
1167            }
1168         $cpt_mac++;
1169         }
1170      }
1171   #print "Error: Hostname already exist in domain set attachement $domainset: $hostname\n";
1172   }
1173
1174#-------------------------------------------------------------------------------
1175
1176sub disable_float {
1177   my ($pool, $mac) = @_;
1178
1179   my $computer_db = ipamdb_load($COMPUTER_YAML);
1180
1181   my $cpt_mac;
1182   if ( control_exist_mac($computer_db, $mac) == 1 ) {
1183      print "Error: Unkown physical MAC address: $mac\n";
1184      exit;
1185      }
1186
1187   for my $domainset_current (keys %{$computer_db}) {
1188      next if $domainset_current eq 'dset';
1189      next if $domainset_current eq 'pool';
1190      next if $domainset_current eq 'pxe';
1191      next if $domainset_current eq 'tag';
1192      next if $domainset_current eq 'version';
1193
1194      my @domainsetdb = @{$computer_db->{$domainset_current}};
1195
1196      #$cpt_mac=0;
1197      for my $computer (@domainsetdb) {
1198         for my $mac_current (keys %{$computer}) {
1199            if ($mac_current eq $mac) {
1200               if ($computer->{$mac}{'ip'} eq $pool) {
1201                  #splice(@{$computer_db->($domainset_current)} , $cpt_mac => 1);
1202                  my $timestamp = time;
1203                  $computer->{$mac}{'modify_time'} = $timestamp;
1204                  $computer->{$mac}{'enabled'}     = 'no';
1205                  ipamdb_save("$COMPUTER_YAML", $computer_db);
1206                  print "Disabling machine $mac from pool $pool [OK]\n";
1207                  print "+-> Status:" . $computer->{$mac}{'enabled'} . "\n";
1208                  exit;
1209                  }
1210               else {
1211                  print "Computer disable $mac [FAILED]\n";
1212                  print "+-> The computer $mac does not belong to the $pool pool.\n";
1213                  exit;
1214                  }
1215               }
1216            #$cpt_mac++;
1217            }
1218         }
1219      }
1220   }
1221
1222#-------------------------------------------------------------------------------
1223#Nom: enable_pc
1224#Description: active une machine désactivée(du DHCP ou en IP statique, et du DNS) (champs enabled=non)
1225
1226sub enable_pc {
1227   my ($hostname, $domainset, $ip) = @_;
1228
1229   my $computer_db = ipamdb_load($COMPUTER_YAML);
1230
1231   control_exist_domainset($computer_db, $domainset) or exit;
1232   if ($ip ne '') {
1233      control_syntax_ip($ip);
1234      if ( control_exist_ip($computer_db, $ip) == 1 ) {
1235         print "Error: Unkown IP address: $ip\n";
1236         exit;
1237         }
1238
1239      for my $domainset_current (keys %{$computer_db}) {
1240         next if $domainset_current eq 'dset';
1241         next if $domainset_current eq 'pool';
1242         next if $domainset_current eq 'pxe';
1243         next if $domainset_current eq 'tag';
1244         next if $domainset_current eq 'version';
1245
1246         my @domainsetdb = @{$computer_db->{$domainset_current}};
1247         my $cpt_mac=0;
1248         for my $value (@domainsetdb) {
1249            for my $id (keys %{$value}) {
1250               if ($value->{$id}->{'ip'} eq $ip) {
1251                  my $timestamp = time;
1252                  $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
1253                  $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'enabled'} = 'yes';
1254                  print "L'adresse IP: $ip a été réactivée. Valeur du champs enabled: [".$computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'enabled'}."]\n";
1255                  ipamdb_save("$COMPUTER_YAML", $computer_db);
1256                  exit;
1257                  }
1258               $cpt_mac=$cpt_mac+1;
1259               }
1260            }
1261         }
1262      }
1263   else {
1264      if ( control_exist_hostname($computer_db, $domainset, $hostname) == 1 ) {
1265         die "Error: Unkown host: $hostname, in domain set: $domainset\n";
1266         }
1267
1268      my $cpt_mac=0;
1269      for my $value (@{$computer_db->{$domainset}}) {
1270         for my $id (keys %{$value}) {
1271            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} ne 'pool-dhcp')) {
1272               my $timestamp = time;
1273               $computer_db->{$domainset}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
1274               $computer_db->{$domainset}[$cpt_mac]->{$id}->{'enabled'} = 'yes';
1275               print "La machine $hostname (domaine: $domainset) a été réactivée du DHCP. Valeur du champs enabled: [".$computer_db->{$domainset}[$cpt_mac]->{$id}->{'enabled'}."]\n";
1276               ipamdb_save("$COMPUTER_YAML", $computer_db);
1277               exit;
1278               }
1279
1280            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} eq 'pool-dhcp')) {
1281               print "Réactivation de la machine $hostname sur le domaine $domainset [FAILED]\n";
1282               print "La machine $hostname fait partie du pool $hostname.\n";
1283               exit;
1284               }
1285            }
1286         $cpt_mac++;
1287         }
1288      }
1289   #print "La machine $hostname n'existe pas sur le domaineset: $domainset\n";
1290   }
1291
1292#-------------------------------------------------------------------------------
1293
1294sub enable_float {
1295   my ($pool, $mac) = @_;
1296
1297   my $computer_db = ipamdb_load($COMPUTER_YAML);
1298
1299   my $cpt_mac;
1300   if ( control_exist_mac($computer_db, $mac) == 1 ) {
1301      print "Adresse MAC $mac non trouvée.\n";
1302      exit;
1303      }
1304
1305   for my $domainset_current (keys %{$computer_db}) {
1306      next if $domainset_current eq 'dset';
1307      next if $domainset_current eq 'pool';
1308      next if $domainset_current eq 'pxe';
1309      next if $domainset_current eq 'tag';
1310      next if $domainset_current eq 'version';
1311
1312      my @domainsetdb = @{$computer_db->{$domainset_current}};
1313
1314      $cpt_mac=0;
1315      for my $value (@domainsetdb) {
1316         for my $id (keys %{$value}) {
1317            if ($id eq $mac) {
1318               if ($value->{$id}->{'ip'} eq $pool) {
1319                  #splice(@{$computer_db->($domainset_current)} , $cpt_mac => 1);
1320                  my $timestamp = time;
1321                  $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
1322                  $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'enabled'} = 'yes';
1323                  ipamdb_save("$COMPUTER_YAML", $computer_db);
1324                  print "Réactivation de la machine $mac du pool $pool [OK]\n";
1325                  exit;
1326                  }
1327               else {
1328                  print "Réactivation de la machine $mac [FAILED]\n";
1329                  print "La machine $mac n'appartient pas au pool $pool.\n";
1330                  exit;
1331                  }
1332               }
1333            $cpt_mac++;
1334            }
1335         }
1336      }
1337   }
1338
1339#-------------------------------------------------------------------------------
1340
1341sub cmd_enable_pc {
1342   local @ARGV = @_;
1343
1344   my $help = get_cmd_name();
1345   my ($hostname, $domainset, $ip);
1346
1347   GetOptions(
1348      'hostname|h=s'    => \$hostname,
1349      'domainset|d=s'   => \$domainset,
1350      'ip|i=s'          => \$ip,
1351      );
1352
1353   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
1354   exit_on_error_option($help)
1355      if $domainset  eq '';
1356   exit_on_error_option($help)
1357      if $hostname   eq ''
1358      and $ip        eq '';
1359   exit_on_error_option($help)
1360      if $hostname   ne ''
1361      and $ip        ne '';
1362
1363   enable_pc($hostname, $domainset, $ip);
1364   }
1365
1366#-------------------------------------------------------------------------------
1367
1368sub cmd_disable_pc {
1369   local @ARGV = @_;
1370
1371   my $help = get_cmd_name();
1372   my ($hostname, $domainset, $ip);
1373
1374   GetOptions(
1375      'hostname|h=s'    => \$hostname,
1376      'domainset|d=s'   => \$domainset,
1377      'ip|i=s'          => \$ip,
1378      );
1379
1380   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
1381   exit_on_error_option($help)
1382      if $domainset  eq '';
1383   exit_on_error_option($help)
1384      if $hostname   eq ''
1385      and $ip        eq '';
1386   exit_on_error_option($help)
1387      if $hostname   ne ''
1388      and $ip        ne '';
1389
1390   disable_pc($hostname, $domainset, $ip);
1391   }
1392
1393#-------------------------------------------------------------------------------
1394
1395sub cmd_disable_float {
1396   local @ARGV = @_;
1397
1398   my $help = get_cmd_name();
1399   my ($pool, $mac);
1400
1401   GetOptions(
1402      'pool|p=s'  => \$pool,
1403      'mac|m=s'   => \$mac,
1404      );
1405
1406   ($pool) = split /\./, $pool, 2 if $pool =~ m/\./;
1407   exit_on_error_option($help)
1408      if $pool eq ''
1409      or $mac  eq '';
1410
1411   disable_float($pool, $mac);
1412   }
1413
1414#-------------------------------------------------------------------------------
1415
1416sub cmd_enable_float {
1417   local @ARGV = @_;
1418
1419   my $help = get_cmd_name();
1420   my ($pool, $mac);
1421
1422   GetOptions(
1423      'pool|p=s'  => \$pool,
1424      'mac|m=s'   => \$mac,
1425      );
1426
1427   ($pool) = split /\./, $pool, 2 if $pool =~ m/\./;
1428   exit_on_error_option($help)
1429      if $pool eq ''
1430      or $mac  eq '';
1431
1432   enable_float($pool, $mac);
1433   }
1434
1435#-------------------------------------------------------------------------------
1436# DELETE section
1437#-------------------------------------------------------------------------------
1438
1439#-------------------------------------------------------------------------------
1440#Nom: del_pc
1441#Description: supprime une machine en DHCP ou en IP statique.
1442
1443sub del_pc {
1444   my ($hostname, $domainset, $ip) = @_;
1445
1446   my $computer_db = ipamdb_load($COMPUTER_YAML);
1447
1448   control_exist_domainset($computer_db, $domainset) or exit;
1449   if ($ip ne '') {
1450      if ( control_exist_ip($computer_db, $ip) == 1 ) {
1451         die "Error: Unkown IP address: $ip\n";
1452         }
1453      my $cpt_mac=0;
1454      for my $value (@{$computer_db->{$domainset}}) {
1455         for my $id (keys %{$value}) {
1456            if ($value->{$id}->{'ip'} eq $ip) {
1457               my $timestamp = time;
1458               splice(@{$computer_db->{$domainset}}, $cpt_mac => 1);
1459               print "La machine $ip a été supprimer du domaine $domainset\n";
1460               ipamdb_save("$COMPUTER_YAML", $computer_db);
1461               exit;
1462               }
1463            }
1464         $cpt_mac++;
1465         }
1466      #print "La machine $ip n'existe pas sur le domaine $domainset.\n";
1467      }
1468   else {
1469      if ( control_exist_hostname($computer_db, $domainset, $hostname) == 1 ) {
1470         die "Error: Unkown host: $hostname, in domain set: $domainset\n";
1471         }
1472      my $cpt_mac=0;
1473      for my $value (@{$computer_db->{$domainset}}) {
1474         for my $id (keys %{$value}) {
1475            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} ne 'pool-dhcp')) {
1476               my $timestamp = time;
1477               splice(@{$computer_db->{$domainset}}, $cpt_mac => 1);
1478               print "La machine $hostname a été supprimer du domaine $domainset\n";
1479               ipamdb_save("$COMPUTER_YAML", $computer_db);
1480               exit;
1481               }
1482
1483            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} eq 'pool-dhcp')) {
1484               print "Suppression de la machine $hostname sur le domaine $domainset [FAILED]\n";
1485               print "La machine $hostname fait partie du pool DHCP $hostname.\n";
1486               exit;
1487               }
1488            }
1489         $cpt_mac++;
1490         }
1491      #print "La machine $hostname n'existe pas sur le domaine $domainset.\n";
1492      }
1493   }
1494
1495#-------------------------------------------------------------------------------
1496#Nom: del_float
1497#Description: supprime une machine d'un pool DHCP
1498
1499sub del_float {
1500   my ($pool, $mac) = @_;
1501
1502   my $computer_db = ipamdb_load($COMPUTER_YAML);
1503
1504   my $cpt_mac;
1505   if ( control_exist_mac($computer_db, $mac) == 1 ) {
1506      print "Adresse MAC $mac non trouvée.\n";
1507      exit;
1508      }
1509
1510   for my $domainset_current (keys %{$computer_db}) {
1511      next if $domainset_current eq 'dset';
1512      next if $domainset_current eq 'pool';
1513      next if $domainset_current eq 'pxe';
1514      next if $domainset_current eq 'tag';
1515      next if $domainset_current eq 'version';
1516
1517      my @domainsetdb = @{$computer_db->{$domainset_current}};
1518
1519      $cpt_mac=0;
1520      for my $value (@domainsetdb) {
1521         for my $id (keys %{$value}) {
1522
1523            if ($id eq $mac) {
1524               if ($value->{$id}->{'ip'} eq $pool) {
1525                  #splice(@{$computer_db->($domainset_current)} , $cpt_mac => 1);
1526                  splice(@{$computer_db->{$domainset_current}}, $cpt_mac => 1);
1527                  ipamdb_save("$COMPUTER_YAML", $computer_db);
1528                  print "Suppression de la machine $mac du pool $pool [OK]\n";
1529                  exit;
1530                  }
1531               else {
1532                  print "Suppression de la machine $mac [FAILED]\n";
1533                  print "La machine $mac n'appartient pas au pool $pool.\n";
1534                  exit;
1535                  }
1536               }
1537            $cpt_mac++;
1538            }
1539         }
1540      }
1541   }
1542
1543#-------------------------------------------------------------------------------
1544
1545sub cmd_del_pc {
1546   local @ARGV = @_;
1547
1548   my $help = get_cmd_name();
1549   my ($hostname, $domainset, $ip);
1550
1551   GetOptions(
1552      'hostname|h=s'    => \$hostname,
1553      'domainset|d=s'   => \$domainset,
1554      'ip|i=s'          => \$ip,
1555      );
1556
1557   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
1558   exit_on_error_option($help)
1559      if $domainset  eq '';
1560   exit_on_error_option($help)
1561      if $hostname   eq ''
1562      and $ip        eq '';
1563   exit_on_error_option($help)
1564      if $hostname   ne ''
1565      and $ip        ne '';
1566
1567   del_pc($hostname, $domainset, $ip);
1568   }
1569
1570#-------------------------------------------------------------------------------
1571
1572sub cmd_del_float {
1573   local @ARGV = @_;
1574
1575   my $help = get_cmd_name();
1576   my ($pool, $mac);
1577
1578   GetOptions(
1579      'pool|p=s'        => \$pool,
1580      'mac|m=s'         => \$mac,
1581      );
1582
1583   ($pool) = split /\./, $pool, 2 if $pool =~ m/\./;
1584   exit_on_error_option($help)
1585      if $pool eq ''
1586      or $mac  eq '';
1587
1588   del_float($pool, $mac);
1589   }
1590
1591#-------------------------------------------------------------------------------
1592# DOMAIN SET section
1593#-------------------------------------------------------------------------------
1594
1595sub cmd_create_domainset {
1596   local @ARGV = @_;
1597
1598   my $help = get_cmd_name();
1599   my ($domainset, $dns_extension, $comment);
1600
1601   GetOptions(
1602      'domainset|d=s'      => \$domainset,
1603      'dns-extension|e=s'  => \$dns_extension,
1604      'comment|c=s'        => \$comment,
1605      );
1606
1607   exit_on_error_option($help)
1608      if $domainset     eq ''
1609      or $dns_extension eq ''
1610      or $comment       eq '';
1611
1612   $comment = normalize_comment($comment);
1613
1614   my $computer_db = ipamdb_load($COMPUTER_YAML);
1615
1616   $computer_db->{'dset'} ||= {};
1617   die "Error: Domain Set already exists: $domainset\n" if exists $computer_db->{'dset'}{$domainset};
1618
1619   control_syntax_comment($comment)    or exit;
1620
1621   my $timestamp = time;
1622   $computer_db->{'dset'}{$domainset} = {
1623      'dns_extension'   => $dns_extension,
1624      'comment'         => $comment,
1625      'create_time'     => $timestamp,
1626      'modify_time'     => $timestamp,
1627      };
1628   $computer_db->{$domainset} ||= []; # Create empty Domain Set computer list by default
1629   ipamdb_save("$COMPUTER_YAML", $computer_db);
1630   }
1631
1632#-------------------------------------------------------------------------------
1633# POOL section
1634#-------------------------------------------------------------------------------
1635
1636#-------------------------------------------------------------------------------
1637#Nom: create_pool
1638#Description: crée un pool dans le fichier de données YAML et dans le DHCP.
1639#
1640#Commentaires: il y a un petit bug si jamais on rentre que des adresses ip qui existent déjà.
1641#              Le pool est créé mais sans adresses ip.
1642
1643sub cmd_create_pool {
1644   local @ARGV = @_;
1645
1646   my $help = get_cmd_name();
1647   my ($pool, $domainset, $file_pool, $ipaddress_pool);
1648
1649   GetOptions(
1650      'pool|p=s'           => \$pool,
1651      'domainset|d=s'      => \$domainset,
1652      'file-pool|f=s'      => \$file_pool,
1653      'ipaddress-pool|i=s' => \$ipaddress_pool,
1654      );
1655
1656   exit_on_error_option($help)
1657      if $pool             eq ''
1658      or $domainset        eq ''
1659      or $file_pool        eq ''
1660      or $ipaddress_pool   eq '';
1661
1662   my $computer_db = ipamdb_load($COMPUTER_YAML);
1663
1664   if ($computer_db->{'pool'}) {
1665      die "Error: Pool already exists: $pool\n" if exists $computer_db->{'pool'}{$pool};
1666      }
1667
1668   #--- control if the domain's pool exist ---#
1669   control_exist_domainset($computer_db, $domainset) or exit;
1670
1671   my @ip_list = ();
1672   #---control if address exist ---#
1673   if ($ipaddress_pool =~ /,/) {
1674      for my $ip (split /,/, $ipaddress_pool) {
1675         if ($ip =~ /-/) {
1676            my ($ip1, $ip2, $ip3, $range) = split /\./, $ip;
1677            my ($first, $last) = split /-/, $range;
1678            for (my $cpt = $first; $cpt <= $last; $cpt++) {
1679               my $ip_loc = "$ip1.$ip2.$ip3.$cpt";
1680               control_syntax_ip($ip_loc) or die "Error: Bad IP syntax: $ip_loc\n";
1681               control_exist_ip($computer_db, $ip_loc) or die "Error: IP address already exists: $ip_loc\n";
1682               push @ip_list, $ip_loc;
1683               }
1684            }
1685         else {
1686            control_syntax_ip($ip) or next;
1687            if ( control_exist_ip($computer_db, $ip) == 0 ) {
1688               print "L'adresse IP $ip existe déjà\n";
1689               next;
1690               }
1691            push @ip_list, $ip;
1692            }
1693         }
1694      }
1695
1696   my $timestamp = time;
1697   $computer_db->{'pool'}{$pool} = {
1698      'ip'          => [@ip_list],
1699      'enabled'     => 'yes',
1700      'create_time' => $timestamp,
1701      'modify_time' => $timestamp,
1702      'file'        => $file_pool,
1703      'domain'      => $domainset,
1704      };
1705   ipamdb_save("$COMPUTER_YAML", $computer_db);
1706   }
1707
1708#-------------------------------------------------------------------------------
1709
1710sub cmd_show_pool {
1711   local @ARGV = @_;
1712
1713   my ($no_header);
1714
1715   GetOptions(
1716      'no-header|H' => \$no_header,
1717      );
1718
1719   my $computer_db = ipamdb_load($COMPUTER_YAML);
1720
1721   printf "%-17s %-17s %s\n", 'Pool', 'File', 'DNS-Domain' if not $no_header;
1722   LOOP_ON_PXE:
1723   for my $pool ( keys %{$computer_db->{'pool'}} ) {
1724
1725      printf "%-17s %-17s %s\n",
1726         $pool,
1727         $computer_db->{'pool'}{$pool}{'file'},
1728         $computer_db->{'pool'}{$pool}{'domain'},
1729      }
1730   }
1731
1732#-------------------------------------------------------------------------------
1733# PXE section
1734#-------------------------------------------------------------------------------
1735
1736sub cmd_create_pxe {
1737   local @ARGV = @_;
1738
1739   my $help = get_cmd_name();
1740   my ($pxe_config, $ip_next_server, $filename, $comment);
1741
1742   GetOptions(
1743      'bootp|b=s'       => \$pxe_config,
1744      'next-server|n=s' => \$ip_next_server,
1745      'filename|f=s'    => \$filename,
1746      'comment|c=s'     => \$comment,
1747      );
1748
1749   exit_on_error_option($help)
1750      if $pxe_config       eq ''
1751      or $ip_next_server   eq ''
1752      or $filename         eq ''
1753      or $comment          eq '';
1754
1755   my $computer_db = ipamdb_load($COMPUTER_YAML);
1756
1757   $comment = normalize_comment($comment);
1758
1759   $computer_db->{'pxe'} ||= {};
1760   die "Error: PXE config already exists: $pxe_config\n" if exists $computer_db->{'pxe'}{$pxe_config};
1761
1762   control_syntax_ip($ip_next_server)  or die "Error: Bad IP syntax: $ip_next_server\n";
1763   control_syntax_comment($comment)    or exit;
1764
1765   my $timestamp = time;
1766   $computer_db->{'pxe'}{$pxe_config} = {
1767      'ip_next_server'  => $ip_next_server,
1768      'filename'        => $filename,
1769      'comment'         => $comment,
1770      'create_time'     => $timestamp,
1771      'modify_time'     => $timestamp,
1772      };
1773   ipamdb_save("$COMPUTER_YAML", $computer_db);
1774   }
1775
1776#-------------------------------------------------------------------------------
1777
1778sub cmd_remove_pxe {
1779   local @ARGV = @_;
1780
1781   my $help = get_cmd_name();
1782   my ($pxe_config);
1783
1784   GetOptions(
1785      'bootp|b=s' => \$pxe_config,
1786      );
1787
1788   exit_on_error_option($help)
1789      if $pxe_config eq '';
1790
1791   my $computer_db = ipamdb_load($COMPUTER_YAML);
1792
1793   $computer_db->{'pxe'} ||= {};
1794   die "Error: PXE config does not exist: $pxe_config\n" if not exists $computer_db->{'pxe'}{$pxe_config};
1795
1796   # Test if some computer use this config
1797   LOOP_ON_DOMAIN:
1798   for my $domainset_current (keys %{$computer_db}) {
1799      next if $domainset_current eq 'dset';
1800      next if $domainset_current eq 'pool';
1801      next if $domainset_current eq 'pxe';
1802      next if $domainset_current eq 'tag';
1803      next if $domainset_current eq 'version';
1804
1805      LOOP_ON_COMPUTER:
1806      for my $computer (@{$computer_db->{$domainset_current}}) {
1807         my ($mac_address, $attribute) = %{$computer};
1808
1809         if (exists $attribute->{'pxe_config'}) {
1810            my $hostname = $attribute->{'hostname'};
1811            die "Error: computer still use this PXE config: $hostname.$domainset_current $mac_address\n" if $pxe_config eq $attribute->{'pxe_config'};
1812            }
1813         }
1814      }
1815
1816   delete $computer_db->{'pxe'}{$pxe_config};
1817   ipamdb_save("$COMPUTER_YAML", $computer_db);
1818   }
1819
1820#--------------------------------------------------------------------------------
1821
1822sub cmd_show_pxe {
1823   local @ARGV = @_;
1824
1825   my ($no_header);
1826
1827   GetOptions(
1828      'no-header|H' => \$no_header,
1829      );
1830
1831   my $computer_db = ipamdb_load($COMPUTER_YAML);
1832
1833   printf "%-12s %-13s %-30s %s\n", 'PXE-Config', 'Next-Server', 'Filename', 'Comment' if not $no_header;
1834   LOOP_ON_PXE:
1835   for my $pxe_config ( keys %{$computer_db->{'pxe'}} ) {
1836      my $ip_next_server = $computer_db->{'pxe'}{$pxe_config}{'ip_next_server'};
1837      my $filename       = $computer_db->{'pxe'}{$pxe_config}{'filename'};
1838      my $comment        = $computer_db->{'pxe'}{$pxe_config}{'comment'};
1839
1840      printf "%-12s %-13s %-30s %s\n", $pxe_config, $ip_next_server, $filename, $comment;
1841      }
1842   }
1843
1844#-------------------------------------------------------------------------------
1845
1846sub cmd_enable_pxe {
1847   local @ARGV = @_;
1848
1849   my $help = get_cmd_name();
1850   my ($hostname, $domainset, $ip, $pxe_config);
1851
1852   GetOptions(
1853      'hostname|h=s'    => \$hostname,
1854      'domainset|d=s'   => \$domainset,
1855      'ip|i=s'          => \$ip,
1856      'bootp|b=s'       => \$pxe_config,
1857      );
1858
1859   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
1860   exit_on_error_option($help)
1861      if $domainset  eq ''
1862      or $pxe_config eq '';
1863   exit_on_error_option($help)
1864      if $hostname   eq ''
1865      and $ip        eq '';
1866   exit_on_error_option($help)
1867      if $hostname   ne ''
1868      and $ip        ne '';
1869
1870   my $computer_db = ipamdb_load($COMPUTER_YAML);
1871
1872   die "Error: PXE config not exists: $pxe_config\n" if not exists $computer_db->{'pxe'}{$pxe_config};
1873
1874   control_exist_domainset($computer_db, $domainset) or exit;
1875   if ($ip ne '') {
1876      control_syntax_ip($ip);
1877      if ( control_exist_ip($computer_db, $ip) == 1 ) {
1878         die "Error: Unkown IP address: $ip\n";
1879         }
1880
1881      for my $domainset_current (keys %{$computer_db}) {
1882         next if $domainset_current eq 'dset';
1883         next if $domainset_current eq 'pool';
1884         next if $domainset_current eq 'pxe';
1885         next if $domainset_current eq 'tag';
1886         next if $domainset_current eq 'version';
1887
1888         my $cpt_mac = 0;
1889         for my $computer (@{$computer_db->{$domainset_current}}) {
1890            for my $id (keys %{$computer}) {
1891               if ($computer->{$id}->{'ip'} eq $ip) {
1892                  my $timestamp = time;
1893                  $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
1894                  $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'pxe_config'}  = $pxe_config;
1895                  print "IP Address: $ip, PXE enabled in config: $pxe_config\n";
1896                  ipamdb_save("$COMPUTER_YAML", $computer_db);
1897                  exit;
1898                  }
1899               $cpt_mac++;
1900               }
1901            }
1902         }
1903      }
1904   else {
1905      if ( control_exist_hostname($computer_db, $domainset, $hostname) == 1 ) {
1906         die "Error: Unkown host: $hostname, in domain set: $domainset\n";
1907         }
1908
1909      my $cpt_mac = 0;
1910      for my $value (@{$computer_db->{$domainset}}) {
1911         for my $id (keys %{$value}) {
1912            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} ne 'pool-dhcp')) {
1913               my $timestamp = time;
1914               $computer_db->{$domainset}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
1915               $computer_db->{$domainset}[$cpt_mac]->{$id}->{'pxe_config'}  = $pxe_config;
1916               print "Host $hostname ($domainset), PXE enabled in config: $pxe_config\n";
1917               ipamdb_save("$COMPUTER_YAML", $computer_db);
1918               exit;
1919               }
1920
1921            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} eq 'pool-dhcp')) {
1922               die "Error. Host $hostname ($domainset) in a pool. No PXE possible\n";
1923               }
1924            }
1925         $cpt_mac++;
1926         }
1927      }
1928   }
1929
1930#-------------------------------------------------------------------------------
1931
1932sub cmd_disable_pxe {
1933   local @ARGV = @_;
1934
1935   my $help = get_cmd_name();
1936   my ($hostname, $domainset, $ip);
1937
1938   GetOptions(
1939      'hostname|h=s'    => \$hostname,
1940      'domainset|d=s'   => \$domainset,
1941      'ip|i=s'          => \$ip,
1942      );
1943
1944   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
1945   exit_on_error_option($help)
1946      if $domainset  eq '';
1947   exit_on_error_option($help)
1948      if $hostname   eq ''
1949      and $ip        eq '';
1950   exit_on_error_option($help)
1951      if $hostname   ne ''
1952      and $ip        ne '';
1953
1954   my $computer_db = ipamdb_load($COMPUTER_YAML);
1955
1956   control_exist_domainset($computer_db, $domainset) or exit;
1957   if ($ip ne '') {
1958      control_syntax_ip($ip);
1959      if ( control_exist_ip($computer_db, $ip) == 1 ) {
1960         die "Error: Unkown IP address: $ip\n";
1961         }
1962
1963      for my $domainset_current (keys %{$computer_db}) {
1964         next if $domainset_current eq 'dset';
1965         next if $domainset_current eq 'pool';
1966         next if $domainset_current eq 'pxe';
1967         next if $domainset_current eq 'tag';
1968         next if $domainset_current eq 'version';
1969
1970         my $cpt_mac = 0;
1971         for my $computer (@{$computer_db->{$domainset_current}}) {
1972            for my $id (keys %{$computer}) {
1973               if ($computer->{$id}->{'ip'} eq $ip) {
1974                  next if not exists $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'pxe_config'};
1975
1976                  my $pxe_config = $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'pxe_config'};
1977                  my $timestamp  = time;
1978                  $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
1979                  delete $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'pxe_config'};
1980                  print "IP Address: $ip, PXE disable from config: $pxe_config\n";
1981                  ipamdb_save("$COMPUTER_YAML", $computer_db);
1982                  exit;
1983                  }
1984               $cpt_mac++;
1985               }
1986            }
1987         }
1988      }
1989   else {
1990      if ( control_exist_hostname($computer_db, $domainset, $hostname) == 1 ) {
1991         die "Error: Unkown host: $hostname, in domain set: $domainset\n";
1992         }
1993
1994      my $cpt_mac = 0;
1995      for my $value (@{$computer_db->{$domainset}}) {
1996         for my $id (keys %{$value}) {
1997            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} ne 'pool-dhcp')) {
1998               next if not exists $value->{$id}->{'pxe_config'};
1999
2000               my $pxe_config = $computer_db->{$domainset}[$cpt_mac]->{$id}->{'pxe_config'};
2001               my $timestamp  = time;
2002               $computer_db->{$domainset}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
2003               delete $computer_db->{$domainset}[$cpt_mac]->{$id}->{'pxe_config'};
2004               print "Host $hostname ($domainset), PXE disable from config: $pxe_config\n";
2005               ipamdb_save("$COMPUTER_YAML", $computer_db);
2006               exit;
2007               }
2008
2009            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} eq 'pool-dhcp')) {
2010               die "Error. Host $hostname ($domainset) in a pool. No PXE possible\n";
2011               }
2012            }
2013         $cpt_mac++;
2014         }
2015      }
2016   }
2017
2018#-------------------------------------------------------------------------------
2019# TAG section
2020#-------------------------------------------------------------------------------
2021
2022sub cmd_create_tag {
2023   local @ARGV = @_;
2024
2025   my $help = get_cmd_name();
2026   my ($tag, $comment);
2027
2028   GetOptions(
2029      'tag|t=s'      => \$tag,
2030      'comment|c=s'  => \$comment,
2031      );
2032
2033   exit_on_error_option($help)
2034      if $tag     eq ''
2035      or $comment eq '';
2036
2037   my $computer_db = ipamdb_load($COMPUTER_YAML);
2038
2039   $comment = normalize_comment($comment);
2040
2041   $computer_db->{'tag'} ||= {};
2042   die "Error: TAG already exists: $tag\n" if exists $computer_db->{'tag'}{$tag};
2043
2044   die "Error: TAG 'universal' is intrinsic. It's not possible to create it.\n" if $tag eq 'universal';
2045
2046   if ($tag !~ m/^ \w+ $/xms) {
2047      die "Error: Bad format for TAG (alphanumeric string): $tag\n";
2048      }
2049
2050   control_syntax_comment($comment) or exit;
2051
2052   my $timestamp = time;
2053   $computer_db->{'tag'}{$tag} = {
2054      'comment'         => $comment,
2055      'create_time'     => $timestamp,
2056      'modify_time'     => $timestamp,
2057      };
2058   ipamdb_save("$COMPUTER_YAML", $computer_db);
2059   }
2060
2061#-------------------------------------------------------------------------------
2062
2063sub cmd_remove_tag {
2064   local @ARGV = @_;
2065
2066   my $help = get_cmd_name();
2067   my ($tag);
2068
2069   GetOptions(
2070      'tag|t=s' => \$tag,
2071      );
2072
2073   exit_on_error_option($help)
2074      if $tag eq '';
2075
2076   my $computer_db = ipamdb_load($COMPUTER_YAML);
2077
2078   $computer_db->{'tag'} ||= {};
2079   die "Error: TAG does not exist: $tag\n" if not exists $computer_db->{'tag'}{$tag};
2080
2081   # Test if some computer use this config
2082   LOOP_ON_DOMAIN:
2083   for my $domainset_current (keys %{$computer_db}) {
2084      next if $domainset_current eq 'dset';
2085      next if $domainset_current eq 'pool';
2086      next if $domainset_current eq 'pxe';
2087      next if $domainset_current eq 'tag';
2088      next if $domainset_current eq 'version';
2089
2090      LOOP_ON_COMPUTER:
2091      for my $computer (@{$computer_db->{$domainset_current}}) {
2092         my ($mac_address, $attribute) = %{$computer};
2093
2094         if (exists $attribute->{'tag'}) {
2095            my $hostname = $attribute->{'hostname'};
2096            die "Error: Computer still use this TAG: $hostname.$domainset_current $mac_address\n" if $tag eq $attribute->{'tag'};
2097            }
2098         }
2099      }
2100
2101   delete $computer_db->{'tag'}{$tag};
2102   ipamdb_save("$COMPUTER_YAML", $computer_db);
2103   }
2104
2105#--------------------------------------------------------------------------------
2106
2107sub cmd_show_tag {
2108   local @ARGV = @_;
2109
2110   my ($no_header);
2111
2112   GetOptions(
2113      'no-header|H' => \$no_header,
2114      );
2115
2116   my $computer_db = ipamdb_load($COMPUTER_YAML);
2117
2118   printf "%-12s %s\n", 'TAG', 'Comment' if not $no_header;
2119   LOOP_ON_TAG:
2120   for my $tag ( keys %{$computer_db->{'tag'}} ) {
2121      my $comment = $computer_db->{'tag'}{$tag}{'comment'};
2122
2123      printf "%-12s %s\n", $tag, $comment;
2124      }
2125   }
2126
2127#--------------------------------------------------------------------------------
2128# GLOBAL section
2129#--------------------------------------------------------------------------------
2130
2131sub cmd_upgrade_db {
2132   my $flag_change;
2133
2134   my $computer_db = ipamdb_load($COMPUTER_YAML);
2135
2136   LOOP_ON_DOMAIN:
2137   for my $domainset_current (keys %{$computer_db}) {
2138      next if $domainset_current eq 'dset';
2139      next if $domainset_current eq 'pool';
2140      next if $domainset_current eq 'pxe';
2141      next if $domainset_current eq 'tag';
2142      next if $domainset_current eq 'version';
2143
2144      my @domainsetdb = @{$computer_db->{$domainset_current}};
2145
2146      LOOP_ON_COMPUTER:
2147      for my $computer (@domainsetdb) {
2148         my ($mac_address, $attribute) = %{$computer};
2149         my $new_mac = normalize_mac_address($mac_address);
2150         print "perl -pi -e 's/$mac_address:/$new_mac:/' $COMPUTER_YAML\n" if "$mac_address" ne "$new_mac";
2151
2152         my $comment = $attribute->{'comment'};
2153         $comment =~ s/\s\s+/ /g and $flag_change++;
2154         $comment =~ s/^\s+\S//  and $flag_change++;
2155         $comment =~ s/\S\s+$//  and $flag_change++;
2156         $comment =~ s{^(\d\d\d\d)\/O(\d\/\d\d)}{$1/0$2} and $flag_change++;
2157         $comment =~ s{^(\d\d\d\d\/\d\d\/)O(\d)}{$1/0$2} and $flag_change++;
2158         $comment =~ s{^(\d\d\d\d)\/(\d\d)\/(\d\d)}{$1-$2-$3} and $flag_change++;
2159         if ($comment !~ m/^\d\d\d\d-\d\d-\d\d/) {
2160            print "# no date at beginning of comment $mac_address\n";
2161            }
2162
2163         $attribute->{'comment'} = $comment;
2164         }
2165      }
2166   print "# FLAG :$flag_change\n";
2167
2168   ipamdb_save("$COMPUTER_YAML", $computer_db) if $flag_change;
2169   }
2170
2171#--------------------------------------------------------------------------------
2172
2173sub cmd_show_domainset {
2174
2175   my $computer_db = ipamdb_load($COMPUTER_YAML);
2176
2177   LOOP_ON_DOMAIN:
2178   for my $domainset_current (keys %{$computer_db}) {
2179      next if $domainset_current eq 'dset';
2180      next if $domainset_current eq 'pool';
2181      next if $domainset_current eq 'pxe';
2182      next if $domainset_current eq 'tag';
2183      next if $domainset_current eq 'version';
2184
2185      print "$domainset_current\n";
2186      }
2187   }
2188
2189#--------------------------------------------------------------------------------
2190
2191sub cmd_search_mac {
2192   local @ARGV = @_;
2193
2194   my $help = get_cmd_name();
2195   my ($mac);
2196
2197   GetOptions(
2198      'mac|m=s' => \$mac,
2199      );
2200
2201   exit_on_error_option($help)
2202      if $mac eq '';
2203
2204   $mac = normalize_mac_address($mac);
2205
2206   my $computer_db = ipamdb_load($COMPUTER_YAML);
2207
2208   control_syntax_mac_address($mac) or exit;
2209
2210   LOOP_ON_DOMAIN:
2211   for my $domainset_current (keys %{$computer_db}) {
2212      next if $domainset_current eq 'dset';
2213      next if $domainset_current eq 'pool';
2214      next if $domainset_current eq 'pxe';
2215      next if $domainset_current eq 'tag';
2216      next if $domainset_current eq 'version';
2217
2218      my @domainsetdb = @{$computer_db->{$domainset_current}};
2219
2220      LOOP_ON_COMPUTER:
2221      for my $computer (@domainsetdb) {
2222         my ($mac_address, $attribute) = %{$computer};
2223
2224         next LOOP_ON_COMPUTER if $mac_address ne $mac;
2225
2226         my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime $attribute->{'modify_time'};
2227         $year += 1900;
2228         $mon++;
2229         my $date = sprintf '%04i-%02i-%02i', $year, $mon, $mday;
2230
2231         my $comment = $attribute->{'comment'};
2232         $comment =~ s/^\d\d\d\d-\d\d-\d\d\s//;
2233
2234         my $enable = $attribute->{'enabled'};
2235         if (exists $attribute->{'pxe_config'}) {
2236            $enable .= '/' . $attribute->{'pxe_config'};
2237            }
2238         if (exists $attribute->{'tag'}) {
2239            $enable .= ':' . $attribute->{'tag'};
2240            }
2241
2242         printf "%-30s  %-20s %17s %9s %3s %10s %s\n",
2243            $attribute->{'hostname'} . '.' . $domainset_current,
2244            $attribute->{'ip'},
2245            $mac_address,
2246            $attribute->{'address_type'},
2247            $enable,
2248            $date,
2249            $comment;
2250         }
2251      }
2252   }
2253
2254#--------------------------------------------------------------------------------
2255#Nom: show
2256#Description: liste les machines à partir du fichier YAML par nom de domaine.
2257
2258sub cmd_show_host {
2259   my %ipdb = ();
2260
2261   my $computer_db = ipamdb_load($COMPUTER_YAML);
2262
2263   my $tb_computer = Text::Table->new(
2264     {align  => 'left',   align_title => 'left',   title => 'Hostname.DomainSet'},
2265     {is_sep => 1,        body        => '  '},
2266     {align  => 'left',   align_title => 'left',   title => 'IPv4-Address'},
2267     {is_sep => 1,        body        => '  '},
2268     {align  => 'center', align_title => 'center', title => 'MAC-Address'},
2269     {is_sep => 1,        body        => '  '},
2270     {align  => 'right',  align_title => 'right',  title => 'Type'},
2271     {align  => 'right',  align_title => 'right',  title => 'Status'},
2272     {is_sep => 1,        body        => '  '},
2273     {align  => 'left',   align_title => 'left',   title => 'Date'},
2274     {align  => 'left',   align_title => 'left',   title => 'Comment'},
2275     );
2276
2277  LOOP_ON_DOMAIN:
2278   for my $domainset_current (sort keys %{$computer_db}) {
2279      next if $domainset_current eq 'dset';
2280      next if $domainset_current eq 'pool';
2281      next if $domainset_current eq 'pxe';
2282      next if $domainset_current eq 'tag';
2283      next if $domainset_current eq 'version';
2284
2285      my @domainsetdb = @{$computer_db->{$domainset_current}};
2286
2287      LOOP_ON_COMPUTER:
2288      for my $computer (@domainsetdb) {
2289         my ($mac_address, $attribute) = %{$computer};
2290         my $ip = $attribute->{'ip'};
2291
2292         if ($ip =~ m/$DDT::RE::IPv4_ADDRESS/xms) {
2293            if ( not exists $ipdb{$ip} ) {
2294               $ipdb{$ip} = {
2295                  'mac_address'  => $mac_address,
2296                  %{$attribute},
2297                  'domainset'    => $domainset_current,
2298                  };
2299               }
2300            else {
2301               print {*STDERR} "# Warning: $ip already exists in the database with MAC $mac_address!\n";
2302               }
2303            next LOOP_ON_COMPUTER;
2304            }
2305
2306         my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime $attribute->{'modify_time'};
2307         $year += 1900;
2308         $mon++;
2309         my $date = sprintf '%04i-%02i-%02i', $year, $mon, $mday;
2310
2311         my $comment = normalize_comment($attribute->{'comment'});
2312         $comment =~ s/^\d\d\d\d-\d\d-\d\d\s//;
2313
2314         my $enable = $attribute->{'enabled'};
2315         if (exists $attribute->{'pxe_config'}) {
2316            $enable .= '/' . $attribute->{'pxe_config'};
2317            }
2318         if (exists $attribute->{'tag'}) {
2319            $enable .= ':' . $attribute->{'tag'};
2320            }
2321
2322         #printf "%-30s  %-20s %17s %9s %3s %10s %s\n",
2323         $tb_computer->add(
2324            $attribute->{'hostname'} . '.' . $domainset_current,
2325            $ip,
2326            $mac_address,
2327            $attribute->{'address_type'},
2328            $enable,
2329            $date,
2330            $comment,
2331            );
2332         }
2333      #print "\n# *** List of pool computers in the domain set: $domainset_current ***\n";
2334      }
2335
2336   #print "\n# *** List of computers ordered by IP and domain set ***\n";
2337   LOOP_ON_IP_ADDRESS:
2338   foreach my $ip (Net::Netmask::sort_by_ip_address(keys %ipdb)) {
2339      my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime $ipdb{$ip}->{'modify_time'};
2340      $year += 1900;
2341      $mon++;
2342      my $date = sprintf '%04i-%02i-%02i', $year, $mon, $mday;
2343
2344      my $comment =$ipdb{$ip}->{'comment'};
2345      $comment =~ s/^\d\d\d\d-\d\d-\d\d\s//;
2346
2347      my $enable = $ipdb{$ip}->{'enabled'};
2348      if (exists $ipdb{$ip}->{'pxe_config'}) {
2349         $enable .= '/' . $ipdb{$ip}->{'pxe_config'};
2350         }
2351      if (exists $ipdb{$ip}->{'tag'}) {
2352         $enable .= ':' . $ipdb{$ip}->{'tag'};
2353         }
2354
2355      #printf "%-30s %-20s %17s %9s %3s %10s %s\n",
2356      $tb_computer->add(
2357         $ipdb{$ip}->{'hostname'} . '.' . $ipdb{$ip}->{'domainset'},
2358         $ip,
2359         normalize_mac_address($ipdb{$ip}->{'mac_address'}),
2360         $ipdb{$ip}->{'address_type'},
2361         $enable,
2362         $date,
2363         $comment
2364         );
2365      }
2366
2367   print $tb_computer->title();
2368   print $tb_computer->rule('-');
2369   print $tb_computer->body();
2370   }
2371
2372#-------------------------------------------------------------------------------
2373#Nom: cmd_generate_dhcp_file
2374#Description: génère les fichiers de configuration des machines et des pools du dhcp
2375
2376sub cmd_generate_dhcp_file {
2377   backup_database();
2378
2379   my $computer_db = ipamdb_load($COMPUTER_YAML);
2380
2381   my %file_pool;
2382
2383   for my $domainset_current (keys %{$computer_db}) {
2384      next if $domainset_current eq 'dset';
2385      next if $domainset_current eq 'pool';
2386      next if $domainset_current eq 'pxe';
2387      next if $domainset_current eq 'tag';
2388      next if $domainset_current eq 'version';
2389
2390      open FILE_VLAN, '>', "$FOLDER_GEN_DHCP/$domainset_current";
2391      my @domainsetdb = @{$computer_db->{$domainset_current}};
2392      for my $value (@domainsetdb) {
2393         ALL_MAC_ADDRESS:
2394         for my $mac_addres (keys %{$value}) {
2395            #host pcdavoust {  deny-unknown-clients;
2396            #hardware ethernet 0:6:5b:b8:13:d1;
2397            #fixed-address 194.254.66.72;
2398            #}
2399
2400            my $hostname     = $value->{$mac_addres}{'hostname'};
2401            my $ip           = $value->{$mac_addres}{'ip'};
2402            my $comment      = $value->{$mac_addres}{'comment'};
2403            my $address_type = $value->{$mac_addres}{'address_type'};
2404            my $enabled      = $value->{$mac_addres}{'enabled'};
2405            my $tags         = $value->{$mac_addres}{'tag'} || 'universal';
2406
2407            my $buffer;
2408            if ($address_type eq 'dhcp') {
2409               if ($enabled eq 'yes') {
2410                  $buffer  = "host $hostname {\n"; # deny-unknown-clients;
2411                  $buffer .= "   hardware ethernet $mac_addres;\n";
2412                  $buffer .= "   fixed-address $ip;\n";
2413
2414                  if (exists $value->{$mac_addres}{'pxe_config'}) {
2415                     my $pxe_config     = $value->{$mac_addres}{'pxe_config'};
2416                     my $ip_next_server = $computer_db->{'pxe'}{$pxe_config}{'ip_next_server'};
2417                     my $filename       = $computer_db->{'pxe'}{$pxe_config}{'filename'};
2418                     $buffer .= "   next-server $ip_next_server;\n";
2419                     $buffer .= "   filename \"$filename\";\n";
2420                     }
2421                  $buffer .= "   #comment: $comment\n";
2422                  $buffer .= "   }\n";
2423                  $buffer .= "\n";
2424
2425                  for my $tag (split/,/, $tags) {
2426                     $file_pool{"tag-$tag"} ||= [];
2427                     push @{$file_pool{"tag-$tag"}}, "subclass \"tag-$tag\" 1:$mac_addres; # $comment\n";
2428                     }
2429                  }
2430               else {
2431                  $buffer  = "#host $hostname {\n"; # deny-unknown-clients;
2432                  $buffer .= "#   hardware ethernet $mac_addres;\n";
2433                  $buffer .= "#   fixed-address $ip;\n";
2434                  $buffer .= "#   comment: $comment \n";
2435                  $buffer .= "#   }\n";
2436                  $buffer .= "\n";
2437                  }
2438               print FILE_VLAN $buffer;
2439               }
2440            elsif ($address_type eq 'pool-dhcp') {
2441               #--- Génère les fichiers pool dhcp ---#
2442               for my $current_pool (keys %{$computer_db->{'pool'}}) {
2443                  next if $current_pool ne $ip;
2444
2445                  if ($enabled eq 'yes') {
2446                     $buffer = "subclass \"$current_pool\" 1:$mac_addres; # $comment\n";
2447
2448                     for my $tag (split/,/, $tags) {
2449                        $file_pool{"tag-$tag"} ||= [];
2450                        push @{$file_pool{"tag-$tag"}}, "subclass \"tag-$tag\" 1:$mac_addres; # $comment\n";
2451                        }
2452                     }
2453                  else {
2454                     $buffer = "#subclass \"$current_pool\" 1:$mac_addres; # $comment\n";
2455                     }
2456
2457                  my $current_pool_file_name = $computer_db->{'pool'}{$current_pool}{'file'};
2458
2459                  $file_pool{$current_pool_file_name} ||= [];
2460                  push @{$file_pool{$current_pool_file_name}}, $buffer;
2461                  }
2462               }
2463            }
2464         }
2465
2466      close FILE_VLAN;
2467
2468      for my $file_name (keys %file_pool) {
2469         open FILE_POOL, '>', "$FOLDER_GEN_DHCP/$file_name";
2470         print FILE_POOL @{$file_pool{$file_name}};
2471         close FILE_POOL;
2472         }
2473      }
2474      print "Copy DHCP files from $FOLDER_GEN_DHCP to /etc/dhcp/include/\n";
2475      exec $SCRIPT_UPDATE;
2476   }
2477
2478#-------------------------------------------------------------------------------
2479#Nom: cmd_generate_dns_file
2480#Description: génère les fichiers d'enregistrements DNS
2481
2482sub cmd_generate_dns_file {
2483   my $buffer;
2484   my $buffer_rev;
2485   my $pool_domain;
2486
2487   my $computer_db = ipamdb_load($COMPUTER_YAML);
2488
2489   for my $domainset_current (keys %{$computer_db}) {
2490      next if $domainset_current eq 'dset';
2491      next if $domainset_current eq 'pool';
2492      next if $domainset_current eq 'pxe';
2493      next if $domainset_current eq 'tag';
2494      next if $domainset_current eq 'version';
2495
2496      if ($domainset_current eq 'pool') {
2497         #next;
2498         for my $value (@{$computer_db->{$domainset_current}}) {
2499            for my $pool_name (keys %{$value}) {
2500               $pool_domain = $value->{$pool_name}->{'domain'}."\n";
2501               #print $value->{$pool_name}->{'file'};
2502               chomp $pool_domain;
2503               open FILE_FORWARD_DNS, '>>', "$FOLDER_GEN_DNS/db.$pool_domain.fwd";
2504               open FILE_REVERSE_DNS, '>>', "$FOLDER_GEN_DNS/db.$pool_domain.rev";
2505               my @T_pool_ip = @{$value->{$pool_name}->{'ip'}};
2506               for my $pool_ip (@T_pool_ip) {
2507                  my @T_split = split(/\./ , $pool_ip);
2508                  $buffer     = sprintf "%-24s IN  A  %-15s ;\n", "$pool_name$T_split[3]", $pool_ip;
2509                  $buffer_rev = "$T_split[3]   IN PTR   $pool_name$T_split[3].$pool_domain.\n";
2510                  print FILE_FORWARD_DNS $buffer;
2511                  print FILE_REVERSE_DNS $buffer_rev;
2512                  }
2513               close FILE_FORWARD_DNS;
2514               close FILE_REVERSE_DNS;
2515               }
2516            }
2517         }
2518
2519      else {
2520         #--- Création du fichier non-reverse ---#
2521         open ( FILE_FORWARD_DNS, ">> $FOLDER_GEN_DNS/db.$domainset_current.fwd");
2522         open ( FILE_REVERSE_DNS, ">> $FOLDER_GEN_DNS/db.$domainset_current.rev");
2523         my @domainsetdb = @{$computer_db->{$domainset_current}};
2524         for my $value (@domainsetdb) {
2525            for my $id (keys %{$value}) {
2526               #host pcdavoust {  deny-unknown-clients;
2527               #hardware ethernet 0:6:5b:b8:13:d1;
2528               #fixed-address 194.254.66.72;
2529               #}
2530               my $hostname = $value->{$id}->{'hostname'};
2531               my $ip       = $value->{$id}->{'ip'};
2532               my $comment  = $value->{$id}->{'comment'};
2533               my $address_type = $value->{$id}->{'address_type'};
2534               my $enabled      = $value->{$id}->{'enabled'};
2535
2536               my $dns_domain = $domainset_current;
2537               if (exists $computer_db->{'dset'}{$domainset_current}) {
2538                  $dns_domain = $computer_db->{'dset'}{$domainset_current}{'dns_extension'};
2539                  }
2540               my @T_split = split(/\./ , $ip);
2541               if  (($address_type eq 'dhcp') or ($address_type eq 'static')) {
2542                  if ($enabled eq 'yes') {
2543                     $buffer = sprintf "%-24s IN A %-15s ; %s\n", $hostname, $ip, $comment;
2544                     if (exists $value->{$id}->{'dns_extension'}
2545                           and "$value->{$id}->{'dns_extension'}" != "$dns_domain") {
2546                        print "A FAIRE\n";
2547                        }
2548                     $buffer_rev = $T_split[3]."     IN PTR   $hostname.$dns_domain.\n";
2549                     }
2550
2551                  else {
2552                     $buffer = sprintf "%-24s IN A %-15s ; %s\n", $hostname, $ip, $comment;
2553                     $buffer_rev = ";".$T_split[3]."    IN PTR   $hostname.$dns_domain.\n";
2554                     }
2555                  print FILE_REVERSE_DNS $buffer_rev;
2556                  print FILE_FORWARD_DNS $buffer;
2557                  }
2558               }
2559            #$cpt=$cpt+1;
2560            }
2561         print "- DNS: db.$domainset_current.fwd db.$domainset_current.rev [CREATE].\n";
2562         print "Ex : sort -k 4n -t . /usr/local/dhcp-dns-tools/dns/dns.hmg.priv\n";
2563         close FILE_REVERSE_DNS;
2564         close FILE_FORWARD_DNS;
2565         }
2566      }
2567   }
2568
2569#--------------------------------------------------------------------------------
2570
2571sub shell_command {
2572   my $cmd = shift;
2573
2574   require FileHandle;
2575   my $fh     = new FileHandle;
2576   my @result = ();
2577   open $fh, q{-|}, "LANG=C $cmd" or die "Can't exec $cmd\n";
2578   @result = <$fh>;
2579   close $fh;
2580   chomp @result;
2581   return @result;
2582   }
2583
2584sub cmd_check_dns {
2585   my $computer_db = ipamdb_load($COMPUTER_YAML);
2586
2587   LOOP_ON_DOMAIN:
2588   for my $domainset_current (keys %{$computer_db}) {
2589      next if $domainset_current eq 'dset';
2590      next if $domainset_current eq 'pool';
2591      next if $domainset_current eq 'pxe';
2592      next if $domainset_current eq 'tag';
2593      next if $domainset_current eq 'version';
2594
2595      my @domainsetdb = @{$computer_db->{$domainset_current}};
2596
2597      LOOP_ON_COMPUTER:
2598      for my $computer (@domainsetdb) {
2599         my ($mac_address, $attribute) = %{$computer};
2600         #my $new_mac = normalize_mac_address($mac_address);
2601         my $ip = $attribute->{'ip'};
2602         next LOOP_ON_COMPUTER if not $ip =~ m/$DDT::RE::IPv4_ADDRESS/xms;
2603         next LOOP_ON_COMPUTER if $attribute->{'enabled'} eq 'no';
2604
2605         my $dns_hostname_fq = scalar gethostbyaddr(inet_aton($ip), AF_INET);
2606         my ($dns_hostname) = split /\./, $dns_hostname_fq;
2607
2608         if ($attribute->{'hostname'} ne $dns_hostname) {
2609            print "$mac_address ($domainset_current) $ip - $dns_hostname / $attribute->{'hostname'} # $attribute->{'comment'}\n";
2610            next LOOP_ON_COMPUTER;
2611            }
2612
2613         my $packed_ip = scalar gethostbyname($dns_hostname_fq);
2614         if (defined $packed_ip) {
2615            my $ip_address = inet_ntoa($packed_ip);
2616            if ($ip ne $ip_address) {
2617               print "reverse DNS error for $dns_hostname_fq / $ip\n";
2618               next LOOP_ON_COMPUTER;
2619               }
2620            }
2621         }
2622      }
2623
2624   LOOP_ON_DNS:
2625   for my $dns ('legi.grenoble-inp.fr', 'hmg.priv') {
2626      LOOP_ON_IP:
2627      for (shell_command("host -t A -l $dns")) {
2628         # smtp2.legi.grenoble-inp.fr has address 194.254.67.37
2629         next if not m/has address/;
2630         next if not m/^(\w[\w-_\.]+\w)\s+has\saddress\s+(\d[\d\.]+\d)$/;
2631         my ($hostname_fq, $ip) = ($1, $2);
2632         control_syntax_ip($ip) or next LOOP_ON_IP;
2633         if (control_exist_ip($computer_db, $ip) == 1) {
2634            printf "Unkown IP: %015s / %s\n", $ip, $hostname_fq;
2635            next LOOP_ON_IP;
2636            }
2637         }
2638      }
2639   }
2640
2641#-------------------------------------------------------------------------------
2642#Nom: load_data_dhcp
2643#Description: permet de charger le fichier de données YAML via les fichiers de configuration
2644#             machines.
2645#            ATTENTION: LES COMMENTAIRES DU FICHIER DISPARAITRONT.
2646
2647sub load_data_dhcp {
2648   my ($domainset, $input_file) = @_;
2649
2650   my $computer_db = ipamdb_load($COMPUTER_YAML);
2651
2652   my @T_mac;
2653   my @T_host;
2654   my @T_ip;
2655   my $cpt;
2656   open (FILE, "<$input_file");
2657   my @buffer = <FILE>;
2658   close(FILE);
2659
2660   for my $ligne (@buffer) {
2661      #--
2662      $ligne =~ s/#.*$//;
2663      $ligne =~ s/\s+/ /;
2664      $ligne =~ s/^\s+//;
2665      next if $ligne eq '';
2666
2667      if ($ligne =~ /^host /) {
2668         $cpt=0;
2669         my @T_split = split(/host\s+/, $ligne);
2670         @T_host = split(/ /, $T_split[1]);
2671         chomp($T_host[0]);
2672
2673         $cpt++;
2674         }
2675
2676      if ($ligne =~ /^*ethernet /) {
2677         $ligne =~ s/;//g;
2678         @T_mac = split(/ethernet\s+/, $ligne);
2679         chomp($T_mac[1]);
2680         $cpt++;
2681         }
2682
2683      if ($ligne =~ /^*address /) {
2684         $ligne =~ s/;//g;
2685         @T_ip = split(/address\s+/, $ligne);
2686         chomp($T_ip[1]);
2687
2688         $cpt++;
2689         }
2690
2691      if ($cpt == 3) {
2692         #   print "MAC $T_mac[1] HOST $T_host[0] IP $T_ip[1].\n";
2693         my $mac = $T_mac[1];
2694         my $hostname = $T_host[0];
2695         my $ip = $T_ip[1];
2696         $cpt = 0;
2697
2698         if ( control_exist_hostname($computer_db, $domainset, $hostname) == 0 ) {
2699            print "Error: Hostname already exist in domain set attachement $domainset: $hostname\n";
2700            next;
2701            }
2702         control_syntax_mac_address($mac) or next;
2703         if ( control_exist_mac($computer_db, $mac) == 0) {
2704            print "Error: Physical MAC address already exists: $mac\n";
2705            next;
2706            }
2707
2708         control_syntax_ip($ip) or next;
2709         if ( control_exist_ip($computer_db, $ip) == 0 ) {
2710            print "Error: IP address already exists: $ip\n";
2711            next;
2712            }
2713         my $timestamp = time;
2714         push @{$computer_db->{$domainset}}, { $mac => {
2715            'hostname'     => $hostname,
2716            'ip'           => $ip,
2717            'address_type' => 'dhcp',
2718            'enabled'      => 'yes',
2719            'create_time'  => $timestamp,
2720            'modify_time'  => $timestamp,
2721            'alias'        =>  '',
2722            }};
2723         }
2724      }
2725   }
2726
2727#-------------------------------------------------------------------------------
2728#Nom: load_data_pool
2729#Description: permet de charger le fichier YAML via les fichiers de conf 'pool' du dhcp.
2730
2731sub load_data_pool {
2732   my ($domainset, $input_file) = @_;
2733
2734   my @T_mac;
2735
2736   open (FILE, "<$input_file");
2737   my @buffer = <FILE>;
2738   close(FILE);
2739
2740   my $computer_db = ipamdb_load($COMPUTER_YAML);
2741
2742   for my $ligne (@buffer) {
2743      #--
2744      $ligne =~ s/#.*$//;
2745      $ligne =~ s/\s+/ /;
2746      $ligne =~ s/^\s+//;
2747      $ligne =~ s/;//g;
2748      $ligne =~ s/"//g;
2749      next if $ligne eq '';
2750
2751      if (($ligne =~ /^subclass/)) {
2752         my @T_split = split(/ / ,$ligne);
2753         my $pool = $T_split[1];
2754
2755         @T_mac = split(/:/ , $T_split[2]);
2756         my $mac = $T_mac[1].":".$T_mac[2].":".$T_mac[3].":".$T_mac[4].":".$T_mac[5].":".$T_mac[6];
2757         control_syntax_mac_address($mac) or next;
2758         if (control_exist_mac($computer_db, $mac) == 0) {
2759            print "Error: Physical MAC address already exists: $mac\n";
2760            next;
2761            }
2762
2763         #--- cette partie teste si le pool existe.
2764         if (not exists $computer_db->{'pool'}{$pool}) {
2765            print "Error: Create pool with create_pool command before load database: $pool\n";
2766            exit;
2767            }
2768
2769         if ($computer_db->{'pool'}{'domain'} eq $domainset) {
2770            my $timestamp = time;
2771            push @{$computer_db->{$domainset}}, { $mac => {
2772               'hostname'     => $pool,
2773               'ip'           => $pool,
2774               'address_type' => 'pool-dhcp',
2775               'enabled'      => 'yes',
2776               'create_time'  => $timestamp,
2777               'modify_time'  => $timestamp,
2778               }};
2779            }
2780         else {
2781            print "Ajout de la machine $mac [FAILED]\n";
2782            print "Error: The pool doesn't exists: $pool, for the domain: $domainset\n";
2783            }
2784         }
2785      }
2786   }
2787
2788#-------------------------------------------------------------------------------
2789
2790sub load_data_file {
2791   my ($domainset, $input_file, $type_file) = @_;
2792
2793   my $computer_db = ipamdb_load($COMPUTER_YAML);
2794
2795   #$computer_db
2796   if ($type_file eq 'dhcp') {
2797      load_data_dhcp($domainset, $input_file);
2798      }
2799
2800   elsif ($type_file eq 'pool-dhcp') {
2801      load_data_pool($domainset, $input_file);
2802      }
2803
2804   ipamdb_save("$COMPUTER_YAML", $computer_db);
2805   }
2806
2807#-------------------------------------------------------------------------------
2808
2809sub cmd_load_database {
2810   local @ARGV = @_;
2811
2812   my $help = get_cmd_name();
2813   my ($domainset, $input_file, $type_file);
2814
2815   GetOptions(
2816      'domainset|d=s'   => \$domainset,
2817      'filename|f=s'    => \$input_file,
2818      'kind|k=s'        => \$type_file,
2819      );
2820
2821   exit_on_error_option($help)
2822      if $domainset  eq ''
2823      or $input_file eq ''
2824      or $type_file  eq '';
2825
2826   load_data_file($domainset, $input_file, $type_file);
2827   }
2828
2829#-------------------------------------------------------------------------------
2830#Nom: backup_database
2831#Description: sauvegarde et réinitialise les fichiers d'enregistrements DHCP.
2832
2833sub backup_database {
2834   my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime time;
2835   $year += 1900;
2836   $mon++;
2837   my $date = sprintf '%04i-%02i-%02i-%02i-%02i-%02i', $year, $mon, $mday, $hour, $min, $sec;
2838
2839   copy($COMPUTER_YAML, "$FOLDER_BACKUP/$COMPUTER_BASENAME-$date.conf") or die "Error: Database copy backup failed: $!\n";
2840   }
2841
2842#-------------------------------------------------------------------------------
2843# HELP section
2844#-------------------------------------------------------------------------------
2845
2846#-------------------------------------------------------------------------------
2847#Nom: exit_on_error_option
2848#Description: messages d'aide des options pour les différentes commandes
2849
2850sub exit_on_error_option {
2851  my ($command) = @_;
2852
2853   if ($command eq 'add-dhcp') {
2854      print "List of options for command: $command\n";
2855      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2856      print " -h : computer hostname (mandatory if option -i != 'pool'). Example: -h info8pc154\n";
2857      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A\n";
2858      print " -i : internet IP address (mandatory). Possible value: classical IP address or the keyword 'pool'\n";
2859      print " -p : name of the DHCP pool to which the machine belongs (mandatory if option -i == 'pool')\n";
2860      print " -c : comment (mandatory). Example: 2014-04-07 DELL Laptop 6400 - Olivier Toto (INFO)\n";
2861      print "Example:\n";
2862      print " ddt add_dhcp -h most1mc130 -d legi-661 -i 194.254.66.130 -m 00:17:F2:D3:2B:FF -c '2008-07-03 Mac Book Guillaume Balleyrac (MOST)\n";
2863      print " ddt add_dhcp -p pool-stagiaire -i pool -d hmg.priv -m 02:00:54:55:4E:01 -c '2008-09-02 Portable Perso - Laanaia Nabil - Achim Wirth (MEIGE)\n";
2864      }
2865
2866   elsif ($command eq 'add-float') {
2867      print "List of options for command: $command\n";
2868      print " -d : domain set attachment (mandatory)\n";
2869      print " -p : name of the DHCP pool to which the machine belongs (mandatory)\n";
2870      print " -m : physical MAC address (mandatory)\n";
2871      print " -c : comment (mandatory). Example: 2014-04-07 DELL Laptop 6400 - Olivier Toto (INFO)\n";
2872      print "Example:\n";
2873      print " ddt add_float -p pool-stagiaire -d hmg.priv -i 192.168.10.1 -m 00:AB:1B:CC:AA:2F -c '2013-09-25 Dell OptiPlex 745 - Eric Goncalves (NRJ)\n";
2874      }
2875
2876   elsif ($command eq 'add-static') {
2877      print "List of options for command: $command\n";
2878      print " -d : domain set attachment (mandatory)\n";
2879      print " -i : internet IP address (mandatory)\n";
2880      print " -h : computer hostname (mandatory)\n";
2881      print " -m : physical MAC address (mandatory)\n";
2882      print " -c : comment (mandatory). Example: 2014-04-07 DELL Laptop 6400 - Olivier Toto (INFO)\n";
2883      print "Example:\n";
2884      print " ddt add_static -h legipc1 -d hmg.priv -i 192.168.10.1 -m 00:AB:1B:CC:AA:2F -c '2013-09-25 Dell OptiPlex 745 - Eric Goncalves (NRJ)\n";
2885      }
2886
2887   elsif ($command eq 'add-virtual') {
2888      print "List of options for command: $command\n";
2889      print " -d : domain set attachment (mandatory)\n";
2890      print " -i : internet IP address (mandatory)\n";
2891      print " -h : computer hostname (mandatory)\n";
2892      print " -c : comment (mandatory). Example: 2014-04-07 DELL Laptop 6400 - Olivier Toto (INFO)\n";
2893      print "Example:\n";
2894      print " ddt add_virtual -h legipc1 -d legi-211 -i 192.168.10.1 -c '2013-09-25 Dell OptiPlex 745 - Eric Goncalves (NRJ)\n";
2895      }
2896
2897   elsif ($command eq 'add-alias') {
2898      print "List of options for command: $command\n";
2899      print " -d : domain set attachment (mandatory)\n";
2900      print " -h : computer hostname (mandatory)\n";
2901      print " -a : computer alias name (mandatory)\n";
2902      }
2903
2904   elsif ($command eq 'create-domainset') {
2905      print "List of options for command: $command\n";
2906      print " -d : new domain set (mandatory)\n";
2907      print " -e : DNS domain name extension( mandatory). Example legi.grenoble-inp.fr\n";
2908      print " -c : comment (mandatory). Example: 2016-08-22 VLAN legi-261 (INFO)\n";
2909      print "Examples:\n";
2910      print " ddt create_domainset -d legi-264 -e legi.grenoble-inp.fr -c '2016-08-22 VLAN legi-261 (INFO)'\n";
2911      }
2912
2913   elsif ($command eq 'create-pool') {
2914      print "List of options for command: $command\n";
2915      print " -p : name of the DHCP pool. Example: pool-legi-priv\n";
2916      print " -d : domain set attachment for the pool. (domain set attachment must exist in file $COMPUTER_BASENAME.conf). Example: legi.grenoble-inp.fr\n";
2917      print " -f : configuration filename on the DHCP server for the pool\n";
2918      print " -i : adresse(s) IP ou plage d'IP. Séparateur d'adresses IP: ','. Séparateur de plage '-'\n";
2919      print "Examples:\n";
2920      print " ddt -p pool-hmg -d hmg.priv -f pool.hmg.priv -i 192.168.10.1,192.168.10.2,192.168.10.3\n";
2921      print " ddt -p turbocavit -d legi-sector03 -f pool-legi-public -i 192.168.10.1-192.168.10.4\n";
2922      }
2923
2924   elsif ($command eq 'create-pxe') {
2925      print "List of options for command: $command\n";
2926      print " -b : name of the PXE/BOOTP configuration. Example: most\n";
2927      print " -n : internet IP address for the DHCP next-server.\n";
2928      print " -f : filename on TFTP server to load at boot\n";
2929      print " -c : comment (mandatory). Example: 2014-04-07 PXE Boot for CentOS (MOST)\n";
2930      }
2931
2932   elsif ($command eq 'remove-pxe') {
2933      print "List of options for command: $command\n";
2934      print " -b : name of the PXE/BOOTP configuration. Example: most\n";
2935      }
2936
2937   elsif ($command eq 'enable-pxe') {
2938      print "List of options for command: $command\n";
2939      print " -h : computer hostname (mandatory unless option -i)\n";
2940      print " -i : internet IP address (mandatory unless option -h)\n";
2941      print " -d : domain set attachment (mandatory if option -h)\n";
2942      print " -b : name of the PXE/BOOTP configuration. Example: most\n";
2943      }
2944
2945   elsif ($command eq 'disable-pxe') {
2946      print "List of options for command: $command\n";
2947      print " -h : computer hostname (mandatory unless option -i)\n";
2948      print " -i : internet IP address (mandatory unless option -h)\n";
2949      print " -d : domain set attachment (mandatory if option -h)\n";
2950      }
2951
2952   elsif ($command eq 'create-tag') {
2953      print "List of options for command: $command\n";
2954      print " -t : name of the TAG (mandatory). Example: restricted\n";
2955      print " -c : comment (mandatory). Example: 2014-04-07 tag restricted (INFO)\n";
2956      print "tag 'universal' is intrinsic\n";
2957      }
2958
2959   elsif ($command eq 'remove-tag') {
2960      print "List of options for command: $command\n";
2961      print " -b : name of the TAG. Example: restricted\n";
2962      }
2963
2964   elsif ($command eq 'change-mac') {
2965      print "List of options for command: $command\n";
2966      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2967      print " -h : computer hostname (mandatory unless option -i)\n";
2968      print " -i : internet IP address (mandatory unless option -h). Possible value: classical IP address or the keyword 'pool'\n";
2969      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A:22:11\n";
2970      }
2971
2972   elsif ($command eq 'change-ip') {
2973      print "List of options for command: $command\n";
2974      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2975      print " -h : computer hostname (mandatory)\n";
2976      print " -i : new internet IP address (mandatory). Possible value: classical IP address\n";
2977      }
2978
2979   elsif ($command eq 'change-host') {
2980      print "List of options for command: $command\n";
2981      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2982      print " -i : internet IP address (mandatory). Possible value: classical IP address\n";
2983      print " -h : new computer hostname (mandatory)\n";
2984      print "It's not possible to change hostname for computer that belongs to a pool\n";
2985      }
2986
2987   elsif ($command eq 'change-comment') {
2988      print "List of options for command: $command\n";
2989      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2990      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A:22:11\n";
2991      print " -c : new comment (mandatory)\n";
2992      }
2993
2994   elsif ($command eq 'change-domainset') {
2995      print "List of options for command: $command\n";
2996      print " -d : new domain set attachment (mandatory). Example: -d legi-661\n";
2997      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A:22:11\n";
2998      print " -i : internet IP address (mandatory)\n";
2999      }
3000
3001   elsif ($command eq 'change-tag') {
3002      print "List of options for command: $command\n";
3003      print " -h : computer hostname (mandatory unless option -i or -m)\n";
3004      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
3005      print " -i : internet IP address (mandatory unless option -h or -m)\n";
3006      print " -m : physical MAC address (mandatory unless option -h or -i, priority). Example: -m 0F:58:AB:2A:22:11\n";
3007      print " -t : list of tags separated by comma (mandatory). Example: -t internal,windows\n";
3008      }
3009
3010   elsif ($command eq 'load-database') {
3011      print "List of options for command: $command\n";
3012      print " -d : domain set attachment\n";
3013      print " -f : input file in DHCP format\n";
3014      print " -k : possible cases (kind): dhcp, pool-dhcp, fix-address\n";
3015      }
3016
3017   elsif ($command eq 'enable-pc') {
3018      print "List of options for command: $command\n";
3019      print " -h : computer hostname (mandatory unless option -i)\n";
3020      print " -i : internet IP address (mandatory unless option -h)\n";
3021      print " -d : domain set attachment (mandatory if option -h)\n";
3022      print "Examples:\n";
3023      print " ddt enable_pc -i 192.168.10.1\n";
3024      print " ddt enable_pc -d hmg.priv -h kevinpc\n";
3025      }
3026
3027   elsif ($command eq 'enable-float') {
3028      print "List of options for command: $command\n";
3029      print " -m : physical MAC address (mandatory)\n";
3030      print " -p : name of the DHCP pool (mandatory)\n";
3031      }
3032
3033   elsif ($command eq 'disable-float') {
3034      print "List of options for command: $command\n";
3035      print " -m : physical MAC address (mandatory)\n";
3036      print " -p : name of the DHCP pool (mandatory)\n";
3037      }
3038
3039   elsif ($command eq 'disable-pc') {
3040      print "List of options for command: $command\n";
3041      print " -h : computer hostname (mandatory unless option -i)\n";
3042      print " -i : internet IP address (mandatory unless option -h)\n";
3043      print " -d : domain set attachment (mandatory if option -h)\n";
3044      print "Examples:\n";
3045      print " ddt disable_pc -i 192.168.10.1\n";
3046      print " ddt disable_pc -d hmg.priv -h kevinpc\n";
3047      }
3048
3049   elsif ($command eq 'del-pc') {
3050      print "List of options for command: $command\n";
3051      print " -d : domain set attachment (mandatory)\n";
3052      print " -h : computer hostname (mandatory unless option -i)\n";
3053      print " -i : internet IP address (mandatory unless option -h)\n";
3054      }
3055
3056   elsif ($command eq 'del-float') {
3057      print "List of options for command: $command\n";
3058      print " -m : physical MAC address (mandatory)l\n";
3059      print " -p : name of the DHCP pool\n";
3060      }
3061
3062   elsif ($command eq 'search-mac') {
3063      print "List of options for command: $command\n";
3064      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A:22:11\n";
3065      }
3066
3067   else {
3068      print "No help for command: $command\n";
3069      }
3070   exit;
3071   }
3072
3073#-------------------------------------------------------------------------------
3074
3075sub cmd_version {
3076
3077   print <<'END';
3078ddt - management of computer names and IP addresses
3079Copyright (C) 2006-2018 Gabriel Moreau <Gabriel.Moreau(A)univ-grenoble-alpes.fr>
3080License GNU GPL version 2 or later and Perl equivalent
3081END
3082
3083   print "Version $VERSION\n\n";
3084   print ' $Id: ddt 301 2018-07-18 12:12:55Z g7moreau $'."\n";
3085   return;
3086   }
3087
3088#-------------------------------------------------------------------------------
3089#Nom: usage
3090#Description: message d'aide sur les commandes du script
3091
3092sub cmd_help {
3093   print <<END;
3094ddt - management of computer names and IP addresses
3095
3096 ddt add-alias [--hostname|-h hostname] [--domainset|-d domainset] [--alias|-a alias]
3097 ddt add-dhcp [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3098 ddt add-float [--pool|-p pool] [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3099 ddt add-static [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3100 ddt add-virtual [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--comment|-c comment]
3101 ddt change-comment [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3102 ddt change-domainset [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3103 ddt change-host [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3104 ddt change-ip [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3105 ddt change-mac [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3106 ddt change-tag [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--tag|-t tag]
3107 ddt check-dns
3108 ddt create-domainset [--domainset|-d domainset] [--dns-extension|-e dns_extension] [--comment|-c comment]
3109 ddt create-pool [--pool|-p pool] [--domainset|-d domainset] [--file-pool|-f file_pool] [--ipaddress-pool|-i ipaddress_pool]
3110 ddt create-pxe [--bootp|-b pxe_config] [--next-server|-n next_server] [--filename|-f filename] [--comment|-c comment]
3111 ddt create-tag [--tag|-t tag] [--comment|-c comment]
3112 ddt del-float [--pool|-p pool] [--mac|-m mac]
3113 ddt del-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3114 ddt disable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3115 ddt disable-float [--pool|-p pool] [--mac|-m mac]
3116 ddt disable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3117 ddt enable-float [--pool|-p pool] [--mac|-m mac]
3118 ddt enable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3119 ddt enable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--bootp|-b pxe_config]
3120 ddt gen-dhcp-file
3121 ddt gen-dns-file
3122 ddt help
3123 ddt load-database [--domainset|-d domainset] [--filename|-f filename] [--kind|-k kind]
3124 ddt remove-pxe [--bootp|-b pxe_config]
3125 ddt remove-tag [--tag|-t tag]
3126 ddt search-mac [--mac|-m mac]
3127 ddt show-domainset
3128 ddt show
3129 ddt show-pool [--no-header|-H]
3130 ddt show-pxe [--no-header|-H]
3131 ddt show-tag [--no-header|-H]
3132 ddt version
3133
3134COMMANDS
3135
3136 * add-alias        : add an alias for a computer (like CNAME for the DNS)
3137 * add-dhcp         : add a computer with a fix DHCP IP or in a DHCP pool
3138 * add-float        : add a computer with an IP in a DHCP pool
3139 * add-static       : add a computer with a static IP
3140 * add-virtual      : add a virtual computer with a static IP but a virtual MAC (useful to declare float computer in DNS)
3141 * change-comment   : change the computer comment
3142 * change-domainset : change the domain set attachment for a computer
3143 * change-host      : change the computer hostname
3144 * change-ip        : change the computer IP address
3145 * change-mac       : change the computer physical MAC address
3146 * change-tag       : change the list of TAGs associated to a computer
3147 * check-dns        : check the DNS table for base IPs
3148 * create-domainset : create a new domain set
3149 * create-pool      : create a new pool for DHCP records
3150 * create-pxe       : create a new PXE/BOOTP configuration
3151 * create-tag       : create a new TAG
3152 * del-float        : remove a computer from a DHCP pool
3153 * del-pc           : remove a computer (DHCP or static IP) from the YAML database
3154 * disable-pc       : disable a computer (DHCP and/or DNS) (but keep it in the database)
3155 * disable-float    : disable a computer from a DHCP pool (but keep it in the database)
3156 * disable-pxe      : remove PXE/BOOTP configuration on a computer
3157 * enable-float     : enable a previous disable computer (DHCP and/or DNS)
3158 * enable-pc        : enable a previous disable computer (DHCP and/or DNS)
3159 * enable-pxe       : enable PXE/BOOTP configuration on a computer
3160 * gen-dhcp-file    : generate DHCP files for the isc DHCP server
3161 * gen-dns-file     : generate DNS files for the bind domain server
3162 * help             : this help
3163 * load-database    : load the YAML database (be careful)
3164 * remove-pxe       : remove a PXE/BOOTP configuration
3165 * remove-tag       : remove a TAG
3166 * search-mac       : search physical MAC address computer
3167 * show-domainset   : list all domain set group of computer
3168 * show             : list all computers
3169 * show-pool        : list all pool
3170 * show-pxe         : list PXE/BOOTP configuration
3171 * show-tag         : list all TAGs
3172 * version          : return program version
3173END
3174   return;
3175   }
3176
3177################################################################
3178# documentation
3179################################################################
3180
3181__END__
3182
3183=head1 NAME
3184
3185ddt - management of computer names and IP addresses
3186
3187
3188=head1 USAGE
3189
3190 ddt add-alias [--hostname|-h hostname] [--domainset|-d domainset] [--alias|-a alias]
3191 ddt add-dhcp [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3192 ddt add-float [--pool|-p pool] [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3193 ddt add-static [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3194 ddt add-virtual [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--comment|-c comment]
3195 ddt change-comment [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3196 ddt change-domainset [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3197 ddt change-host [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3198 ddt change-ip [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3199 ddt change-mac [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3200 ddt change-tag [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--tag|-t tag]
3201 ddt check-dns
3202 ddt create-domainset [--domainset|-d domainset] [--dns-extension|-e dns_extension] [--comment|-c comment]
3203 ddt create-pool [--pool|-p pool] [--domainset|-d domainset] [--file-pool|-f file_pool] [--ipaddress-pool|-i ipaddress_pool]
3204 ddt create-pxe [--bootp|-b pxe_config] [--next-server|-n next_server] [--filename|-f filename] [--comment|-c comment]
3205 ddt create-tag [--tag|-t tag] [--comment|-c comment]
3206 ddt del-float [--pool|-p pool] [--mac|-m mac]
3207 ddt del-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3208 ddt disable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3209 ddt disable-float [--pool|-p pool] [--mac|-m mac]
3210 ddt disable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3211 ddt enable-float [--pool|-p pool] [--mac|-m mac]
3212 ddt enable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3213 ddt enable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--bootp|-b pxe_config]
3214 ddt gen-dhcp-file
3215 ddt gen-dns-file
3216 ddt help
3217 ddt load-database [--domainset|-d domainset] [--filename|-f filename] [--kind|-k kind]
3218 ddt remove-pxe [--bootp|-b pxe_config]
3219 ddt remove-tag [--tag|-t tag]
3220 ddt search-mac [--mac|-m mac]
3221 ddt show-domainset
3222 ddt show
3223 ddt show-pool [--no-header|-H]
3224 ddt show-pxe [--no-header|-H]
3225 ddt show-tag [--no-header|-H]
3226 ddt version
3227
3228
3229=head1 DESCRIPTION
3230
3231DDT is an acronym for DHCP-DNS-Tools.
3232The previous command name was not C<ddt> but just C<dhcp-dns-tools>...
3233In practise, DDT is an IP Address Management (IPAM) service.
3234It has been used in the LEGI laboratory for over 10 years.
3235
3236The tool is quite effective and tries to keep things simple
3237but easily configurable for your site like a swiss army knife.
3238Everything is saved in a YAML database
3239and entries could be added, deleted, or modified by the command line.
3240
3241
3242=head1 COMMANDS
3243
3244=head2 add-alias
3245
3246 ddt add-alias [--hostname|-h hostname] [--domainset|-d domainset] [--alias|-a alias]
3247
3248=head2 add-dhcp
3249
3250 ddt add-dhcp [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3251
3252=head2 add-float
3253
3254 ddt add-float [--pool|-p pool] [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3255
3256=head2 add-static
3257
3258 ddt add-static [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3259
3260=head2 add-virtual
3261
3262 ddt add-virtual [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--comment|-c comment]
3263
3264=head2 change-comment
3265
3266 ddt change-comment [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3267
3268=head2 change-domainset
3269
3270 ddt change-domainset [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3271
3272=head2 change-host
3273
3274 ddt change-host [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3275
3276=head2 change-ip
3277
3278 ddt change-ip [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3279
3280=head2 change-mac
3281
3282 ddt change-mac [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3283
3284=head2 change-tag
3285
3286 ddt change-tag [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--tag|-t tag]
3287
3288=head2 check-dns
3289
3290 ddt check-dns
3291
3292=head2 create-domainset
3293
3294 ddt create-domainset [--domainset|-d domainset] [--dns-extension|-e dns_extension] [--comment|-c comment]
3295
3296=head2 create-pool
3297
3298 ddt create-pool [--pool|-p pool] [--domainset|-d domainset] [--file-pool|-f file_pool] [--ipaddress-pool|-i ipaddress_pool]
3299
3300=head2 create-pxe
3301
3302 ddt create-pxe [--bootp|-b pxe_config] [--next-server|-n next_server] [--filename|-f filename] [--comment|-c comment]
3303
3304=head2 create-tag
3305
3306 ddt create-tag [--tag|-t tag] [--comment|-c comment]
3307
3308=head2 del-float
3309
3310 ddt del-float [--pool|-p pool] [--mac|-m mac]
3311
3312=head2 del-pc
3313
3314 ddt del-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3315
3316=head2 disable-pc
3317
3318 ddt disable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3319
3320=head2 disable-float
3321
3322 ddt disable-float [--pool|-p pool] [--mac|-m mac]
3323
3324=head2 disable-pxe
3325
3326 ddt disable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3327
3328=head2 enable-float
3329
3330 ddt enable-float [--pool|-p pool] [--mac|-m mac]
3331
3332=head2 enable-pc
3333
3334 ddt enable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3335
3336=head2 enable-pxe
3337
3338 ddt enable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--bootp|-b pxe_config]
3339
3340=head2 gen-dhcp-file
3341
3342 ddt gen-dhcp-file
3343
3344=head2 gen-dns-file
3345
3346 ddt gen-dns-file
3347
3348=head2 help
3349
3350 ddt help
3351
3352=head2 load-database
3353
3354 ddt load-database [--domainset|-d domainset] [--filename|-f filename] [--kind|-k kind]
3355
3356=head2 remove-pxe
3357
3358 ddt remove-pxe [--bootp|-b pxe_config]
3359
3360=head2 remove-tag
3361
3362 ddt remove-tag [--tag|-t tag]
3363
3364=head2 search-mac
3365
3366 ddt search-mac [--mac|-m mac]
3367
3368=head2 show-domainset
3369
3370 ddt show-domainset
3371
3372=head2 show
3373
3374 ddt show
3375
3376=head2 show-pool
3377
3378 ddt show-pool [--no-header|-H]
3379
3380=head2 show-pxe
3381
3382 ddt show-pxe [--no-header|-H]
3383
3384=head2 show-tag
3385
3386 ddt show-tag [--no-header|-H]
3387
3388=head2 version
3389
3390 ddt version
3391
3392
3393=head1 AUTHORS
3394
3395Written by Gabriel Moreau, Kevin Reverchon, Olivier De-Marchi - Grenoble - France
3396
3397
3398=head1 LICENSE AND COPYRIGHT
3399
3400Licence GNU GPL version 2 or later and Perl equivalent
3401
3402Copyright (C) 2006-2018 Gabriel Moreau <Gabriel.Moreau(A)univ-grenoble-alpes.fr>.
Note: See TracBrowser for help on using the repository browser.