source: trunk/ddt/ddt @ 296

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