source: trunk/ddt/ddt @ 295

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