source: trunk/ddt/ddt @ 297

Last change on this file since 297 was 297, checked in by g7moreau, 6 years ago
  • small error, better title and print only if values
  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 116.2 KB
Line 
1#!/usr/bin/perl
2#
3# Copyright (C) 2006-2018 Gabriel Moreau <Gabriel.Moreau(A)univ-grenoble-alpes.fr>
4# License GNU GPL version 2 or later and Perl equivalent
5#
6# apt-get install perl-base perl-modules libyaml-syck-perl libnet-netmask-perl libreadonly-perl libfile-touch-perl 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         {is_sep => 1,        body        => '  '},
2274         {align  => 'left',   align_title => 'left',   title => 'IPv4-Address'},
2275         {is_sep => 1,        body        => '  '},
2276         {align  => 'center', align_title => 'center', title => 'MAC-Address'},
2277         {is_sep => 1,        body        => '  '},
2278         {align  => 'right',  align_title => 'right',  title => 'Type'},
2279         {align  => 'right',  align_title => 'right',  title => 'Status'},
2280         {is_sep => 1,        body        => '  '},
2281         {align  => 'left',   align_title => 'left',   title => 'Date'},
2282         {align  => 'left',   align_title => 'left',   title => 'Comment'},
2283         );
2284
2285      #printf "%-30s  %-20s %17s %5s %7s %-10s %s\n",
2286      #   'Hostname',
2287      #   'IPv4-Address',
2288      #   'MAC-Address',
2289      #   'Type',
2290      #   'Status',
2291      #   'Date',
2292      #   'Comment';
2293      my @domainsetdb = @{$computer_db->{$domainset_current}};
2294
2295      LOOP_ON_COMPUTER:
2296      for my $computer (@domainsetdb) {
2297         my ($mac_address, $attribute) = %{$computer};
2298         my $ip = $attribute->{'ip'};
2299
2300         if ($ip =~ m/$DDT::RE::IPv4_ADDRESS/xms) {
2301            if ( not exists $ipdb{$ip} ) {
2302               $ipdb{$ip} = {
2303                  'mac_address'  => $mac_address,
2304                  %{$attribute},
2305                  'domainset'    => $domainset_current,
2306                  };
2307               next LOOP_ON_COMPUTER;
2308               }
2309            else {
2310               print {*STDERR} "# Warning: $ip already exists in the database !\n";
2311               }
2312            }
2313
2314         my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime $attribute->{'modify_time'};
2315         $year += 1900;
2316         $mon++;
2317         my $date = sprintf '%04i-%02i-%02i', $year, $mon, $mday;
2318
2319         my $comment = normalize_comment($attribute->{'comment'});
2320         $comment =~ s/^\d\d\d\d-\d\d-\d\d\s//;
2321
2322         my $enable = $attribute->{'enabled'};
2323         if (exists $attribute->{'pxe_config'}) {
2324            $enable .= '/' . $attribute->{'pxe_config'};
2325            }
2326         if (exists $attribute->{'tag'}) {
2327            $enable .= ':' . $attribute->{'tag'};
2328            }
2329
2330         #printf "%-30s  %-20s %17s %9s %3s %10s %s\n",
2331         $tb_computer->add(
2332            $attribute->{'hostname'} . '.' . $domainset_current,
2333            $ip,
2334            $mac_address,
2335            $attribute->{'address_type'},
2336            $enable,
2337            $date,
2338            $comment,
2339            );
2340         }
2341
2342      if ($tb->body_height) {
2343         print "\n# *** List of pool computers in the domain set: $domainset_current ***\n";
2344         print $tb_computer->title();
2345         print $tb_computer->rule('-');
2346         print $tb_computer->body();
2347         }
2348      }
2349
2350   print "\n# *** List of computers ordered by IP and domain set ***\n";
2351   LOOP_ON_IP_ADDRESS:
2352   foreach my $ip (Net::Netmask::sort_by_ip_address(keys %ipdb)) {
2353      my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime $ipdb{$ip}->{'modify_time'};
2354      $year += 1900;
2355      $mon++;
2356      my $date = sprintf '%04i-%02i-%02i', $year, $mon, $mday;
2357
2358      my $comment =$ipdb{$ip}->{'comment'};
2359      $comment =~ s/^\d\d\d\d-\d\d-\d\d\s//;
2360
2361      my $enable = $ipdb{$ip}->{'enabled'};
2362      if (exists $ipdb{$ip}->{'pxe_config'}) {
2363         $enable .= '/' . $ipdb{$ip}->{'pxe_config'};
2364         }
2365      if (exists $ipdb{$ip}->{'tag'}) {
2366         $enable .= ':' . $ipdb{$ip}->{'tag'};
2367         }
2368
2369      printf "%-30s %-20s %17s %9s %3s %10s %s\n",
2370         $ipdb{$ip}->{'hostname'} . '.' . $ipdb{$ip}->{'domainset'},
2371         $ip,
2372         normalize_mac_address($ipdb{$ip}->{'mac_address'}),
2373         $ipdb{$ip}->{'address_type'},
2374         $enable,
2375         $date,
2376         $comment;
2377      }
2378   }
2379
2380#-------------------------------------------------------------------------------
2381#Nom: cmd_generate_dhcp_file
2382#Description: génère les fichiers de configuration des machines et des pools du dhcp
2383
2384sub cmd_generate_dhcp_file {
2385   backup_database();
2386
2387   my $computer_db = ipamdb_load($COMPUTER_YAML);
2388
2389   my %file_pool;
2390
2391   for my $domainset_current (keys %{$computer_db}) {
2392      next if $domainset_current eq 'dset';
2393      next if $domainset_current eq 'pool';
2394      next if $domainset_current eq 'pxe';
2395      next if $domainset_current eq 'tag';
2396      next if $domainset_current eq 'version';
2397
2398      open FILE_VLAN, '>', "$FOLDER_GEN_DHCP/$domainset_current";
2399      my @domainsetdb = @{$computer_db->{$domainset_current}};
2400      for my $value (@domainsetdb) {
2401         ALL_MAC_ADDRESS:
2402         for my $mac_addres (keys %{$value}) {
2403            #host pcdavoust {  deny-unknown-clients;
2404            #hardware ethernet 0:6:5b:b8:13:d1;
2405            #fixed-address 194.254.66.72;
2406            #}
2407
2408            my $hostname     = $value->{$mac_addres}{'hostname'};
2409            my $ip           = $value->{$mac_addres}{'ip'};
2410            my $comment      = $value->{$mac_addres}{'comment'};
2411            my $address_type = $value->{$mac_addres}{'address_type'};
2412            my $enabled      = $value->{$mac_addres}{'enabled'};
2413            my $tags         = $value->{$mac_addres}{'tag'} || 'universal';
2414
2415            my $buffer;
2416            if ($address_type eq 'dhcp') {
2417               if ($enabled eq 'yes') {
2418                  $buffer  = "host $hostname {\n"; # deny-unknown-clients;
2419                  $buffer .= "   hardware ethernet $mac_addres;\n";
2420                  $buffer .= "   fixed-address $ip;\n";
2421
2422                  if (exists $value->{$mac_addres}{'pxe_config'}) {
2423                     my $pxe_config     = $value->{$mac_addres}{'pxe_config'};
2424                     my $ip_next_server = $computer_db->{'pxe'}{$pxe_config}{'ip_next_server'};
2425                     my $filename       = $computer_db->{'pxe'}{$pxe_config}{'filename'};
2426                     $buffer .= "   next-server $ip_next_server;\n";
2427                     $buffer .= "   filename \"$filename\";\n";
2428                     }
2429                  $buffer .= "   #comment: $comment\n";
2430                  $buffer .= "   }\n";
2431                  $buffer .= "\n";
2432
2433                  for my $tag (split/,/, $tags) {
2434                     $file_pool{"tag-$tag"} ||= [];
2435                     push @{$file_pool{"tag-$tag"}}, "subclass \"tag-$tag\" 1:$mac_addres; # $comment\n";
2436                     }
2437                  }
2438               else {
2439                  $buffer  = "#host $hostname {\n"; # deny-unknown-clients;
2440                  $buffer .= "#   hardware ethernet $mac_addres;\n";
2441                  $buffer .= "#   fixed-address $ip;\n";
2442                  $buffer .= "#   comment: $comment \n";
2443                  $buffer .= "#   }\n";
2444                  $buffer .= "\n";
2445                  }
2446               print FILE_VLAN $buffer;
2447               }
2448            elsif ($address_type eq 'pool-dhcp') {
2449               #--- Génère les fichiers pool dhcp ---#
2450               for my $current_pool (keys %{$computer_db->{'pool'}}) {
2451                  next if $current_pool ne $ip;
2452
2453                  if ($enabled eq 'yes') {
2454                     $buffer = "subclass \"$current_pool\" 1:$mac_addres; # $comment\n";
2455
2456                     for my $tag (split/,/, $tags) {
2457                        $file_pool{"tag-$tag"} ||= [];
2458                        push @{$file_pool{"tag-$tag"}}, "subclass \"tag-$tag\" 1:$mac_addres; # $comment\n";
2459                        }
2460                     }
2461                  else {
2462                     $buffer = "#subclass \"$current_pool\" 1:$mac_addres; # $comment\n";
2463                     }
2464
2465                  my $current_pool_file_name = $computer_db->{'pool'}{$current_pool}{'file'};
2466
2467                  $file_pool{$current_pool_file_name} ||= [];
2468                  push @{$file_pool{$current_pool_file_name}}, $buffer;
2469                  }
2470               }
2471            }
2472         }
2473
2474      close FILE_VLAN;
2475
2476      for my $file_name (keys %file_pool) {
2477         open FILE_POOL, '>', "$FOLDER_GEN_DHCP/$file_name";
2478         print FILE_POOL @{$file_pool{$file_name}};
2479         close FILE_POOL;
2480         }
2481      }
2482      print "Copy DHCP files from $FOLDER_GEN_DHCP to /etc/dhcp/include/\n";
2483      exec $SCRIPT_UPDATE;
2484   }
2485
2486#-------------------------------------------------------------------------------
2487#Nom: cmd_generate_dns_file
2488#Description: génère les fichiers d'enregistrements DNS
2489
2490sub cmd_generate_dns_file {
2491   my $buffer;
2492   my $buffer_rev;
2493   my $pool_domain;
2494
2495   my $computer_db = ipamdb_load($COMPUTER_YAML);
2496
2497   for my $domainset_current (keys %{$computer_db}) {
2498      next if $domainset_current eq 'dset';
2499      next if $domainset_current eq 'pool';
2500      next if $domainset_current eq 'pxe';
2501      next if $domainset_current eq 'tag';
2502      next if $domainset_current eq 'version';
2503
2504      if ($domainset_current eq 'pool') {
2505         #next;
2506         for my $value (@{$computer_db->{$domainset_current}}) {
2507            for my $pool_name (keys %{$value}) {
2508               $pool_domain = $value->{$pool_name}->{'domain'}."\n";
2509               #print $value->{$pool_name}->{'file'};
2510               chomp $pool_domain;
2511               open FILE_FORWARD_DNS, '>>', "$FOLDER_GEN_DNS/db.$pool_domain.fwd";
2512               open FILE_REVERSE_DNS, '>>', "$FOLDER_GEN_DNS/db.$pool_domain.rev";
2513               my @T_pool_ip = @{$value->{$pool_name}->{'ip'}};
2514               for my $pool_ip (@T_pool_ip) {
2515                  my @T_split = split(/\./ , $pool_ip);
2516                  $buffer     = sprintf "%-24s IN  A  %-15s ;\n", "$pool_name$T_split[3]", $pool_ip;
2517                  $buffer_rev = "$T_split[3]   IN PTR   $pool_name$T_split[3].$pool_domain.\n";
2518                  print FILE_FORWARD_DNS $buffer;
2519                  print FILE_REVERSE_DNS $buffer_rev;
2520                  }
2521               close FILE_FORWARD_DNS;
2522               close FILE_REVERSE_DNS;
2523               }
2524            }
2525         }
2526
2527      else {
2528         #--- Création du fichier non-reverse ---#
2529         open ( FILE_FORWARD_DNS, ">> $FOLDER_GEN_DNS/db.$domainset_current.fwd");
2530         open ( FILE_REVERSE_DNS, ">> $FOLDER_GEN_DNS/db.$domainset_current.rev");
2531         my @domainsetdb = @{$computer_db->{$domainset_current}};
2532         for my $value (@domainsetdb) {
2533            for my $id (keys %{$value}) {
2534               #host pcdavoust {  deny-unknown-clients;
2535               #hardware ethernet 0:6:5b:b8:13:d1;
2536               #fixed-address 194.254.66.72;
2537               #}
2538               my $hostname = $value->{$id}->{'hostname'};
2539               my $ip       = $value->{$id}->{'ip'};
2540               my $comment  = $value->{$id}->{'comment'};
2541               my $address_type = $value->{$id}->{'address_type'};
2542               my $enabled      = $value->{$id}->{'enabled'};
2543
2544               my $dns_domain = $domainset_current;
2545               if (exists $computer_db->{'dset'}{$domainset_current}) {
2546                  $dns_domain = $computer_db->{'dset'}{$domainset_current}{'dns_extension'};
2547                  }
2548               my @T_split = split(/\./ , $ip);
2549               if  (($address_type eq 'dhcp') or ($address_type eq 'static')) {
2550                  if ($enabled eq 'yes') {
2551                     $buffer = sprintf "%-24s IN A %-15s ; %s\n", $hostname, $ip, $comment;
2552                     if (exists $value->{$id}->{'dns_extension'}
2553                           and "$value->{$id}->{'dns_extension'}" != "$dns_domain") {
2554                        print "A FAIRE\n";
2555                        }
2556                     $buffer_rev = $T_split[3]."     IN PTR   $hostname.$dns_domain.\n";
2557                     }
2558
2559                  else {
2560                     $buffer = sprintf "%-24s IN A %-15s ; %s\n", $hostname, $ip, $comment;
2561                     $buffer_rev = ";".$T_split[3]."    IN PTR   $hostname.$dns_domain.\n";
2562                     }
2563                  print FILE_REVERSE_DNS $buffer_rev;
2564                  print FILE_FORWARD_DNS $buffer;
2565                  }
2566               }
2567            #$cpt=$cpt+1;
2568            }
2569         print "- DNS: db.$domainset_current.fwd db.$domainset_current.rev [CREATE].\n";
2570         print "Ex : sort -k 4n -t . /usr/local/dhcp-dns-tools/dns/dns.hmg.priv\n";
2571         close FILE_REVERSE_DNS;
2572         close FILE_FORWARD_DNS;
2573         }
2574      }
2575   }
2576
2577#--------------------------------------------------------------------------------
2578
2579sub shell_command {
2580   my $cmd = shift;
2581
2582   require FileHandle;
2583   my $fh     = new FileHandle;
2584   my @result = ();
2585   open $fh, q{-|}, "LANG=C $cmd" or die "Can't exec $cmd\n";
2586   @result = <$fh>;
2587   close $fh;
2588   chomp @result;
2589   return @result;
2590   }
2591
2592sub cmd_check_dns {
2593   my $computer_db = ipamdb_load($COMPUTER_YAML);
2594
2595   LOOP_ON_DOMAIN:
2596   for my $domainset_current (keys %{$computer_db}) {
2597      next if $domainset_current eq 'dset';
2598      next if $domainset_current eq 'pool';
2599      next if $domainset_current eq 'pxe';
2600      next if $domainset_current eq 'tag';
2601      next if $domainset_current eq 'version';
2602
2603      my @domainsetdb = @{$computer_db->{$domainset_current}};
2604
2605      LOOP_ON_COMPUTER:
2606      for my $computer (@domainsetdb) {
2607         my ($mac_address, $attribute) = %{$computer};
2608         #my $new_mac = normalize_mac_address($mac_address);
2609         my $ip = $attribute->{'ip'};
2610         next LOOP_ON_COMPUTER if not $ip =~ m/$DDT::RE::IPv4_ADDRESS/xms;
2611         next LOOP_ON_COMPUTER if $attribute->{'enabled'} eq 'no';
2612
2613         my $dns_hostname_fq = scalar gethostbyaddr(inet_aton($ip), AF_INET);
2614         my ($dns_hostname) = split /\./, $dns_hostname_fq;
2615
2616         if ($attribute->{'hostname'} ne $dns_hostname) {
2617            print "$mac_address ($domainset_current) $ip - $dns_hostname / $attribute->{'hostname'} # $attribute->{'comment'}\n";
2618            next LOOP_ON_COMPUTER;
2619            }
2620
2621         my $packed_ip = scalar gethostbyname($dns_hostname_fq);
2622         if (defined $packed_ip) {
2623            my $ip_address = inet_ntoa($packed_ip);
2624            if ($ip ne $ip_address) {
2625               print "reverse DNS error for $dns_hostname_fq / $ip\n";
2626               next LOOP_ON_COMPUTER;
2627               }
2628            }
2629         }
2630      }
2631
2632   LOOP_ON_DNS:
2633   for my $dns ('legi.grenoble-inp.fr', 'hmg.priv') {
2634      LOOP_ON_IP:
2635      for (shell_command("host -t A -l $dns")) {
2636         # smtp2.legi.grenoble-inp.fr has address 194.254.67.37
2637         next if not m/has address/;
2638         next if not m/^(\w[\w-_\.]+\w)\s+has\saddress\s+(\d[\d\.]+\d)$/;
2639         my ($hostname_fq, $ip) = ($1, $2);
2640         control_syntax_ip($ip) or next LOOP_ON_IP;
2641         if (control_exist_ip($computer_db, $ip) == 1) {
2642            printf "Unkown IP: %015s / %s\n", $ip, $hostname_fq;
2643            next LOOP_ON_IP;
2644            }
2645         }
2646      }
2647   }
2648
2649#-------------------------------------------------------------------------------
2650#Nom: load_data_dhcp
2651#Description: permet de charger le fichier de données YAML via les fichiers de configuration
2652#             machines.
2653#            ATTENTION: LES COMMENTAIRES DU FICHIER DISPARAITRONT.
2654
2655sub load_data_dhcp {
2656   my ($domainset, $input_file) = @_;
2657
2658   my $computer_db = ipamdb_load($COMPUTER_YAML);
2659
2660   my @T_mac;
2661   my @T_host;
2662   my @T_ip;
2663   my $cpt;
2664   open (FILE, "<$input_file");
2665   my @buffer = <FILE>;
2666   close(FILE);
2667
2668   for my $ligne (@buffer) {
2669      #--
2670      $ligne =~ s/#.*$//;
2671      $ligne =~ s/\s+/ /;
2672      $ligne =~ s/^\s+//;
2673      next if $ligne eq '';
2674
2675      if ($ligne =~ /^host /) {
2676         $cpt=0;
2677         my @T_split = split(/host\s+/, $ligne);
2678         @T_host = split(/ /, $T_split[1]);
2679         chomp($T_host[0]);
2680
2681         $cpt++;
2682         }
2683
2684      if ($ligne =~ /^*ethernet /) {
2685         $ligne =~ s/;//g;
2686         @T_mac = split(/ethernet\s+/, $ligne);
2687         chomp($T_mac[1]);
2688         $cpt++;
2689         }
2690
2691      if ($ligne =~ /^*address /) {
2692         $ligne =~ s/;//g;
2693         @T_ip = split(/address\s+/, $ligne);
2694         chomp($T_ip[1]);
2695
2696         $cpt++;
2697         }
2698
2699      if ($cpt == 3) {
2700         #   print "MAC $T_mac[1] HOST $T_host[0] IP $T_ip[1].\n";
2701         my $mac = $T_mac[1];
2702         my $hostname = $T_host[0];
2703         my $ip = $T_ip[1];
2704         $cpt = 0;
2705
2706         if ( control_exist_hostname($computer_db, $domainset, $hostname) == 0 ) {
2707            print "Error: Hostname already exist in domain set attachement $domainset: $hostname\n";
2708            next;
2709            }
2710         control_syntax_mac_address($mac) or next;
2711         if ( control_exist_mac($computer_db, $mac) == 0) {
2712            print "Error: Physical MAC address already exists: $mac\n";
2713            next;
2714            }
2715
2716         control_syntax_ip($ip) or next;
2717         if ( control_exist_ip($computer_db, $ip) == 0 ) {
2718            print "Error: IP address already exists: $ip\n";
2719            next;
2720            }
2721         my $timestamp = time;
2722         push @{$computer_db->{$domainset}}, { $mac => {
2723            'hostname'     => $hostname,
2724            'ip'           => $ip,
2725            'address_type' => 'dhcp',
2726            'enabled'      => 'yes',
2727            'create_time'  => $timestamp,
2728            'modify_time'  => $timestamp,
2729            'alias'        =>  '',
2730            }};
2731         }
2732      }
2733   }
2734
2735#-------------------------------------------------------------------------------
2736#Nom: load_data_pool
2737#Description: permet de charger le fichier YAML via les fichiers de conf 'pool' du dhcp.
2738
2739sub load_data_pool {
2740   my ($domainset, $input_file) = @_;
2741
2742   my @T_mac;
2743
2744   open (FILE, "<$input_file");
2745   my @buffer = <FILE>;
2746   close(FILE);
2747
2748   my $computer_db = ipamdb_load($COMPUTER_YAML);
2749
2750   for my $ligne (@buffer) {
2751      #--
2752      $ligne =~ s/#.*$//;
2753      $ligne =~ s/\s+/ /;
2754      $ligne =~ s/^\s+//;
2755      $ligne =~ s/;//g;
2756      $ligne =~ s/"//g;
2757      next if $ligne eq '';
2758
2759      if (($ligne =~ /^subclass/)) {
2760         my @T_split = split(/ / ,$ligne);
2761         my $pool = $T_split[1];
2762
2763         @T_mac = split(/:/ , $T_split[2]);
2764         my $mac = $T_mac[1].":".$T_mac[2].":".$T_mac[3].":".$T_mac[4].":".$T_mac[5].":".$T_mac[6];
2765         control_syntax_mac_address($mac) or next;
2766         if (control_exist_mac($computer_db, $mac) == 0) {
2767            print "Error: Physical MAC address already exists: $mac\n";
2768            next;
2769            }
2770
2771         #--- cette partie teste si le pool existe.
2772         if (not exists $computer_db->{'pool'}{$pool}) {
2773            print "Error: Create pool with create_pool command before load database: $pool\n";
2774            exit;
2775            }
2776
2777         if ($computer_db->{'pool'}{'domain'} eq $domainset) {
2778            my $timestamp = time;
2779            push @{$computer_db->{$domainset}}, { $mac => {
2780               'hostname'     => $pool,
2781               'ip'           => $pool,
2782               'address_type' => 'pool-dhcp',
2783               'enabled'      => 'yes',
2784               'create_time'  => $timestamp,
2785               'modify_time'  => $timestamp,
2786               }};
2787            }
2788         else {
2789            print "Ajout de la machine $mac [FAILED]\n";
2790            print "Error: The pool doesn't exists: $pool, for the domain: $domainset\n";
2791            }
2792         }
2793      }
2794   }
2795
2796#-------------------------------------------------------------------------------
2797
2798sub load_data_file {
2799   my ($domainset, $input_file, $type_file) = @_;
2800
2801   my $computer_db = ipamdb_load($COMPUTER_YAML);
2802
2803   #$computer_db
2804   if ($type_file eq 'dhcp') {
2805      load_data_dhcp($domainset, $input_file);
2806      }
2807
2808   elsif ($type_file eq 'pool-dhcp') {
2809      load_data_pool($domainset, $input_file);
2810      }
2811
2812   ipamdb_save("$COMPUTER_YAML", $computer_db);
2813   }
2814
2815#-------------------------------------------------------------------------------
2816
2817sub cmd_load_database {
2818   local @ARGV = @_;
2819
2820   my $help = get_cmd_name();
2821   my ($domainset, $input_file, $type_file);
2822
2823   GetOptions(
2824      'domainset|d=s'   => \$domainset,
2825      'filename|f=s'    => \$input_file,
2826      'kind|k=s'        => \$type_file,
2827      );
2828
2829   exit_on_error_option($help)
2830      if $domainset  eq ''
2831      or $input_file eq ''
2832      or $type_file  eq '';
2833
2834   load_data_file($domainset, $input_file, $type_file);
2835   }
2836
2837#-------------------------------------------------------------------------------
2838#Nom: backup_database
2839#Description: sauvegarde et réinitialise les fichiers d'enregistrements DHCP.
2840
2841sub backup_database {
2842   my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime time;
2843   $year += 1900;
2844   $mon++;
2845   my $date = sprintf '%04i-%02i-%02i-%02i-%02i-%02i', $year, $mon, $mday, $hour, $min, $sec;
2846
2847   copy($COMPUTER_YAML, "$FOLDER_BACKUP/$COMPUTER_BASENAME-$date.conf") or die "Error: Database copy backup failed: $!\n";
2848   }
2849
2850#-------------------------------------------------------------------------------
2851# HELP section
2852#-------------------------------------------------------------------------------
2853
2854#-------------------------------------------------------------------------------
2855#Nom: exit_on_error_option
2856#Description: messages d'aide des options pour les différentes commandes
2857
2858sub exit_on_error_option {
2859  my ($command) = @_;
2860
2861   if ($command eq 'add-dhcp') {
2862      print "List of options for command: $command\n";
2863      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2864      print " -h : computer hostname (mandatory if option -i != 'pool'). Example: -h info8pc154\n";
2865      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A\n";
2866      print " -i : internet IP address (mandatory). Possible value: classical IP address or the keyword 'pool'\n";
2867      print " -p : name of the DHCP pool to which the machine belongs (mandatory if option -i == 'pool')\n";
2868      print " -c : comment (mandatory). Example: 2014-04-07 DELL Laptop 6400 - Olivier Toto (INFO)\n";
2869      print "Example:\n";
2870      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";
2871      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";
2872      }
2873
2874   elsif ($command eq 'add-float') {
2875      print "List of options for command: $command\n";
2876      print " -d : domain set attachment (mandatory)\n";
2877      print " -p : name of the DHCP pool to which the machine belongs (mandatory)\n";
2878      print " -m : physical MAC address (mandatory)\n";
2879      print " -c : comment (mandatory). Example: 2014-04-07 DELL Laptop 6400 - Olivier Toto (INFO)\n";
2880      print "Example:\n";
2881      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";
2882      }
2883
2884   elsif ($command eq 'add-static') {
2885      print "List of options for command: $command\n";
2886      print " -d : domain set attachment (mandatory)\n";
2887      print " -i : internet IP address (mandatory)\n";
2888      print " -h : computer hostname (mandatory)\n";
2889      print " -m : physical MAC address (mandatory)\n";
2890      print " -c : comment (mandatory). Example: 2014-04-07 DELL Laptop 6400 - Olivier Toto (INFO)\n";
2891      print "Example:\n";
2892      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";
2893      }
2894
2895   elsif ($command eq 'add-virtual') {
2896      print "List of options for command: $command\n";
2897      print " -d : domain set attachment (mandatory)\n";
2898      print " -i : internet IP address (mandatory)\n";
2899      print " -h : computer hostname (mandatory)\n";
2900      print " -c : comment (mandatory). Example: 2014-04-07 DELL Laptop 6400 - Olivier Toto (INFO)\n";
2901      print "Example:\n";
2902      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";
2903      }
2904
2905   elsif ($command eq 'add-alias') {
2906      print "List of options for command: $command\n";
2907      print " -d : domain set attachment (mandatory)\n";
2908      print " -h : computer hostname (mandatory)\n";
2909      print " -a : computer alias name (mandatory)\n";
2910      }
2911
2912   elsif ($command eq 'create-domainset') {
2913      print "List of options for command: $command\n";
2914      print " -d : new domain set (mandatory)\n";
2915      print " -e : DNS domain name extension( mandatory). Example legi.grenoble-inp.fr\n";
2916      print " -c : comment (mandatory). Example: 2016-08-22 VLAN legi-261 (INFO)\n";
2917      print "Examples:\n";
2918      print " ddt create_domainset -d legi-264 -e legi.grenoble-inp.fr -c '2016-08-22 VLAN legi-261 (INFO)'\n";
2919      }
2920
2921   elsif ($command eq 'create-pool') {
2922      print "List of options for command: $command\n";
2923      print " -p : name of the DHCP pool. Example: pool-legi-priv\n";
2924      print " -d : domain set attachment for the pool. (domain set attachment must exist in file $COMPUTER_BASENAME.conf). Example: legi.grenoble-inp.fr\n";
2925      print " -f : configuration filename on the DHCP server for the pool\n";
2926      print " -i : adresse(s) IP ou plage d'IP. Séparateur d'adresses IP: ','. Séparateur de plage '-'\n";
2927      print "Examples:\n";
2928      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";
2929      print " ddt -p turbocavit -d legi-sector03 -f pool-legi-public -i 192.168.10.1-192.168.10.4\n";
2930      }
2931
2932   elsif ($command eq 'create-pxe') {
2933      print "List of options for command: $command\n";
2934      print " -b : name of the PXE/BOOTP configuration. Example: most\n";
2935      print " -n : internet IP address for the DHCP next-server.\n";
2936      print " -f : filename on TFTP server to load at boot\n";
2937      print " -c : comment (mandatory). Example: 2014-04-07 PXE Boot for CentOS (MOST)\n";
2938      }
2939
2940   elsif ($command eq 'remove-pxe') {
2941      print "List of options for command: $command\n";
2942      print " -b : name of the PXE/BOOTP configuration. Example: most\n";
2943      }
2944
2945   elsif ($command eq 'enable-pxe') {
2946      print "List of options for command: $command\n";
2947      print " -h : computer hostname (mandatory unless option -i)\n";
2948      print " -i : internet IP address (mandatory unless option -h)\n";
2949      print " -d : domain set attachment (mandatory if option -h)\n";
2950      print " -b : name of the PXE/BOOTP configuration. Example: most\n";
2951      }
2952
2953   elsif ($command eq 'disable-pxe') {
2954      print "List of options for command: $command\n";
2955      print " -h : computer hostname (mandatory unless option -i)\n";
2956      print " -i : internet IP address (mandatory unless option -h)\n";
2957      print " -d : domain set attachment (mandatory if option -h)\n";
2958      }
2959
2960   elsif ($command eq 'create-tag') {
2961      print "List of options for command: $command\n";
2962      print " -t : name of the TAG (mandatory). Example: restricted\n";
2963      print " -c : comment (mandatory). Example: 2014-04-07 tag restricted (INFO)\n";
2964      print "tag 'universal' is intrinsic\n";
2965      }
2966
2967   elsif ($command eq 'remove-tag') {
2968      print "List of options for command: $command\n";
2969      print " -b : name of the TAG. Example: restricted\n";
2970      }
2971
2972   elsif ($command eq 'change-mac') {
2973      print "List of options for command: $command\n";
2974      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2975      print " -h : computer hostname (mandatory unless option -i)\n";
2976      print " -i : internet IP address (mandatory unless option -h). Possible value: classical IP address or the keyword 'pool'\n";
2977      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A:22:11\n";
2978      }
2979
2980   elsif ($command eq 'change-ip') {
2981      print "List of options for command: $command\n";
2982      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2983      print " -h : computer hostname (mandatory)\n";
2984      print " -i : new internet IP address (mandatory). Possible value: classical IP address\n";
2985      }
2986
2987   elsif ($command eq 'change-host') {
2988      print "List of options for command: $command\n";
2989      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2990      print " -i : internet IP address (mandatory). Possible value: classical IP address\n";
2991      print " -h : new computer hostname (mandatory)\n";
2992      print "It's not possible to change hostname for computer that belongs to a pool\n";
2993      }
2994
2995   elsif ($command eq 'change-comment') {
2996      print "List of options for command: $command\n";
2997      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2998      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A:22:11\n";
2999      print " -c : new comment (mandatory)\n";
3000      }
3001
3002   elsif ($command eq 'change-domainset') {
3003      print "List of options for command: $command\n";
3004      print " -d : new domain set attachment (mandatory). Example: -d legi-661\n";
3005      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A:22:11\n";
3006      print " -i : internet IP address (mandatory)\n";
3007      }
3008
3009   elsif ($command eq 'change-tag') {
3010      print "List of options for command: $command\n";
3011      print " -h : computer hostname (mandatory unless option -i or -m)\n";
3012      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
3013      print " -i : internet IP address (mandatory unless option -h or -m)\n";
3014      print " -m : physical MAC address (mandatory unless option -h or -i, priority). Example: -m 0F:58:AB:2A:22:11\n";
3015      print " -t : list of tags separated by comma (mandatory). Example: -t internal,windows\n";
3016      }
3017
3018   elsif ($command eq 'load-database') {
3019      print "List of options for command: $command\n";
3020      print " -d : domain set attachment\n";
3021      print " -f : input file in DHCP format\n";
3022      print " -k : possible cases (kind): dhcp, pool-dhcp, fix-address\n";
3023      }
3024
3025   elsif ($command eq 'enable-pc') {
3026      print "List of options for command: $command\n";
3027      print " -h : computer hostname (mandatory unless option -i)\n";
3028      print " -i : internet IP address (mandatory unless option -h)\n";
3029      print " -d : domain set attachment (mandatory if option -h)\n";
3030      print "Examples:\n";
3031      print " ddt enable_pc -i 192.168.10.1\n";
3032      print " ddt enable_pc -d hmg.priv -h kevinpc\n";
3033      }
3034
3035   elsif ($command eq 'enable-float') {
3036      print "List of options for command: $command\n";
3037      print " -m : physical MAC address (mandatory)\n";
3038      print " -p : name of the DHCP pool (mandatory)\n";
3039      }
3040
3041   elsif ($command eq 'disable-float') {
3042      print "List of options for command: $command\n";
3043      print " -m : physical MAC address (mandatory)\n";
3044      print " -p : name of the DHCP pool (mandatory)\n";
3045      }
3046
3047   elsif ($command eq 'disable-pc') {
3048      print "List of options for command: $command\n";
3049      print " -h : computer hostname (mandatory unless option -i)\n";
3050      print " -i : internet IP address (mandatory unless option -h)\n";
3051      print " -d : domain set attachment (mandatory if option -h)\n";
3052      print "Examples:\n";
3053      print " ddt disable_pc -i 192.168.10.1\n";
3054      print " ddt disable_pc -d hmg.priv -h kevinpc\n";
3055      }
3056
3057   elsif ($command eq 'del-pc') {
3058      print "List of options for command: $command\n";
3059      print " -d : domain set attachment (mandatory)\n";
3060      print " -h : computer hostname (mandatory unless option -i)\n";
3061      print " -i : internet IP address (mandatory unless option -h)\n";
3062      }
3063
3064   elsif ($command eq 'del-float') {
3065      print "List of options for command: $command\n";
3066      print " -m : physical MAC address (mandatory)l\n";
3067      print " -p : name of the DHCP pool\n";
3068      }
3069
3070   elsif ($command eq 'search-mac') {
3071      print "List of options for command: $command\n";
3072      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A:22:11\n";
3073      }
3074
3075   else {
3076      print "No help for command: $command\n";
3077      }
3078   exit;
3079   }
3080
3081#-------------------------------------------------------------------------------
3082
3083sub cmd_version {
3084
3085   print <<'END';
3086ddt - management of computer names and IP addresses
3087Copyright (C) 2006-2018 Gabriel Moreau <Gabriel.Moreau(A)univ-grenoble-alpes.fr>
3088License GNU GPL version 2 or later and Perl equivalent
3089END
3090
3091   print "Version $VERSION\n\n";
3092   print ' $Id: ddt 297 2018-07-18 10:36:37Z g7moreau $'."\n";
3093   return;
3094   }
3095
3096#-------------------------------------------------------------------------------
3097#Nom: usage
3098#Description: message d'aide sur les commandes du script
3099
3100sub cmd_help {
3101   print <<END;
3102ddt - management of computer names and IP addresses
3103
3104 ddt add-alias [--hostname|-h hostname] [--domainset|-d domainset] [--alias|-a alias]
3105 ddt add-dhcp [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3106 ddt add-float [--pool|-p pool] [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3107 ddt add-static [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3108 ddt add-virtual [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--comment|-c comment]
3109 ddt change-comment [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3110 ddt change-domainset [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3111 ddt change-host [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3112 ddt change-ip [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3113 ddt change-mac [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3114 ddt change-tag [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--tag|-t tag]
3115 ddt check-dns
3116 ddt create-domainset [--domainset|-d domainset] [--dns-extension|-e dns_extension] [--comment|-c comment]
3117 ddt create-pool [--pool|-p pool] [--domainset|-d domainset] [--file-pool|-f file_pool] [--ipaddress-pool|-i ipaddress_pool]
3118 ddt create-pxe [--bootp|-b pxe_config] [--next-server|-n next_server] [--filename|-f filename] [--comment|-c comment]
3119 ddt create-tag [--tag|-t tag] [--comment|-c comment]
3120 ddt del-float [--pool|-p pool] [--mac|-m mac]
3121 ddt del-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3122 ddt disable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3123 ddt disable-float [--pool|-p pool] [--mac|-m mac]
3124 ddt disable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3125 ddt enable-float [--pool|-p pool] [--mac|-m mac]
3126 ddt enable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3127 ddt enable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--bootp|-b pxe_config]
3128 ddt gen-dhcp-file
3129 ddt gen-dns-file
3130 ddt help
3131 ddt load-database [--domainset|-d domainset] [--filename|-f filename] [--kind|-k kind]
3132 ddt remove-pxe [--bootp|-b pxe_config]
3133 ddt remove-tag [--tag|-t tag]
3134 ddt search-mac [--mac|-m mac]
3135 ddt show-domainset
3136 ddt show
3137 ddt show-pool [--no-header|-H]
3138 ddt show-pxe [--no-header|-H]
3139 ddt show-tag [--no-header|-H]
3140 ddt version
3141
3142COMMANDS
3143
3144 * add-alias        : add an alias for a computer (like CNAME for the DNS)
3145 * add-dhcp         : add a computer with a fix DHCP IP or in a DHCP pool
3146 * add-float        : add a computer with an IP in a DHCP pool
3147 * add-static       : add a computer with a static IP
3148 * add-virtual      : add a virtual computer with a static IP but a virtual MAC (useful to declare float computer in DNS)
3149 * change-comment   : change the computer comment
3150 * change-domainset : change the domain set attachment for a computer
3151 * change-host      : change the computer hostname
3152 * change-ip        : change the computer IP address
3153 * change-mac       : change the computer physical MAC address
3154 * change-tag       : change the list of TAGs associated to a computer
3155 * check-dns        : check the DNS table for base IPs
3156 * create-domainset : create a new domain set
3157 * create-pool      : create a new pool for DHCP records
3158 * create-pxe       : create a new PXE/BOOTP configuration
3159 * create-tag       : create a new TAG
3160 * del-float        : remove a computer from a DHCP pool
3161 * del-pc           : remove a computer (DHCP or static IP) from the YAML database
3162 * disable-pc       : disable a computer (DHCP and/or DNS) (but keep it in the database)
3163 * disable-float    : disable a computer from a DHCP pool (but keep it in the database)
3164 * disable-pxe      : remove PXE/BOOTP configuration on a computer
3165 * enable-float     : enable a previous disable computer (DHCP and/or DNS)
3166 * enable-pc        : enable a previous disable computer (DHCP and/or DNS)
3167 * enable-pxe       : enable PXE/BOOTP configuration on a computer
3168 * gen-dhcp-file    : generate DHCP files for the isc DHCP server
3169 * gen-dns-file     : generate DNS files for the bind domain server
3170 * help             : this help
3171 * load-database    : load the YAML database (be careful)
3172 * remove-pxe       : remove a PXE/BOOTP configuration
3173 * remove-tag       : remove a TAG
3174 * search-mac       : search physical MAC address computer
3175 * show-domainset   : list all domain set group of computer
3176 * show             : list all computers
3177 * show-pool        : list all pool
3178 * show-pxe         : list PXE/BOOTP configuration
3179 * show-tag         : list all TAGs
3180 * version          : return program version
3181END
3182   return;
3183   }
3184
3185################################################################
3186# documentation
3187################################################################
3188
3189__END__
3190
3191=head1 NAME
3192
3193ddt - management of computer names and IP addresses
3194
3195
3196=head1 USAGE
3197
3198 ddt add-alias [--hostname|-h hostname] [--domainset|-d domainset] [--alias|-a alias]
3199 ddt add-dhcp [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3200 ddt add-float [--pool|-p pool] [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3201 ddt add-static [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3202 ddt add-virtual [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--comment|-c comment]
3203 ddt change-comment [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3204 ddt change-domainset [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3205 ddt change-host [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3206 ddt change-ip [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3207 ddt change-mac [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3208 ddt change-tag [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--tag|-t tag]
3209 ddt check-dns
3210 ddt create-domainset [--domainset|-d domainset] [--dns-extension|-e dns_extension] [--comment|-c comment]
3211 ddt create-pool [--pool|-p pool] [--domainset|-d domainset] [--file-pool|-f file_pool] [--ipaddress-pool|-i ipaddress_pool]
3212 ddt create-pxe [--bootp|-b pxe_config] [--next-server|-n next_server] [--filename|-f filename] [--comment|-c comment]
3213 ddt create-tag [--tag|-t tag] [--comment|-c comment]
3214 ddt del-float [--pool|-p pool] [--mac|-m mac]
3215 ddt del-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3216 ddt disable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3217 ddt disable-float [--pool|-p pool] [--mac|-m mac]
3218 ddt disable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3219 ddt enable-float [--pool|-p pool] [--mac|-m mac]
3220 ddt enable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3221 ddt enable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--bootp|-b pxe_config]
3222 ddt gen-dhcp-file
3223 ddt gen-dns-file
3224 ddt help
3225 ddt load-database [--domainset|-d domainset] [--filename|-f filename] [--kind|-k kind]
3226 ddt remove-pxe [--bootp|-b pxe_config]
3227 ddt remove-tag [--tag|-t tag]
3228 ddt search-mac [--mac|-m mac]
3229 ddt show-domainset
3230 ddt show
3231 ddt show-pool [--no-header|-H]
3232 ddt show-pxe [--no-header|-H]
3233 ddt show-tag [--no-header|-H]
3234 ddt version
3235
3236
3237=head1 DESCRIPTION
3238
3239DDT is an acronym for DHCP-DNS-Tools.
3240The previous command name was not C<ddt> but just C<dhcp-dns-tools>...
3241In practise, DDT is an IP Address Management (IPAM) service.
3242It has been used in the LEGI laboratory for over 10 years.
3243
3244The tool is quite effective and tries to keep things simple
3245but easily configurable for your site like a swiss army knife.
3246Everything is saved in a YAML database
3247and entries could be added, deleted, or modified by the command line.
3248
3249
3250=head1 COMMANDS
3251
3252=head2 add-alias
3253
3254 ddt add-alias [--hostname|-h hostname] [--domainset|-d domainset] [--alias|-a alias]
3255
3256=head2 add-dhcp
3257
3258 ddt add-dhcp [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3259
3260=head2 add-float
3261
3262 ddt add-float [--pool|-p pool] [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3263
3264=head2 add-static
3265
3266 ddt add-static [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3267
3268=head2 add-virtual
3269
3270 ddt add-virtual [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--comment|-c comment]
3271
3272=head2 change-comment
3273
3274 ddt change-comment [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3275
3276=head2 change-domainset
3277
3278 ddt change-domainset [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3279
3280=head2 change-host
3281
3282 ddt change-host [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3283
3284=head2 change-ip
3285
3286 ddt change-ip [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3287
3288=head2 change-mac
3289
3290 ddt change-mac [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3291
3292=head2 change-tag
3293
3294 ddt change-tag [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--tag|-t tag]
3295
3296=head2 check-dns
3297
3298 ddt check-dns
3299
3300=head2 create-domainset
3301
3302 ddt create-domainset [--domainset|-d domainset] [--dns-extension|-e dns_extension] [--comment|-c comment]
3303
3304=head2 create-pool
3305
3306 ddt create-pool [--pool|-p pool] [--domainset|-d domainset] [--file-pool|-f file_pool] [--ipaddress-pool|-i ipaddress_pool]
3307
3308=head2 create-pxe
3309
3310 ddt create-pxe [--bootp|-b pxe_config] [--next-server|-n next_server] [--filename|-f filename] [--comment|-c comment]
3311
3312=head2 create-tag
3313
3314 ddt create-tag [--tag|-t tag] [--comment|-c comment]
3315
3316=head2 del-float
3317
3318 ddt del-float [--pool|-p pool] [--mac|-m mac]
3319
3320=head2 del-pc
3321
3322 ddt del-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3323
3324=head2 disable-pc
3325
3326 ddt disable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3327
3328=head2 disable-float
3329
3330 ddt disable-float [--pool|-p pool] [--mac|-m mac]
3331
3332=head2 disable-pxe
3333
3334 ddt disable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3335
3336=head2 enable-float
3337
3338 ddt enable-float [--pool|-p pool] [--mac|-m mac]
3339
3340=head2 enable-pc
3341
3342 ddt enable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3343
3344=head2 enable-pxe
3345
3346 ddt enable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--bootp|-b pxe_config]
3347
3348=head2 gen-dhcp-file
3349
3350 ddt gen-dhcp-file
3351
3352=head2 gen-dns-file
3353
3354 ddt gen-dns-file
3355
3356=head2 help
3357
3358 ddt help
3359
3360=head2 load-database
3361
3362 ddt load-database [--domainset|-d domainset] [--filename|-f filename] [--kind|-k kind]
3363
3364=head2 remove-pxe
3365
3366 ddt remove-pxe [--bootp|-b pxe_config]
3367
3368=head2 remove-tag
3369
3370 ddt remove-tag [--tag|-t tag]
3371
3372=head2 search-mac
3373
3374 ddt search-mac [--mac|-m mac]
3375
3376=head2 show-domainset
3377
3378 ddt show-domainset
3379
3380=head2 show
3381
3382 ddt show
3383
3384=head2 show-pool
3385
3386 ddt show-pool [--no-header|-H]
3387
3388=head2 show-pxe
3389
3390 ddt show-pxe [--no-header|-H]
3391
3392=head2 show-tag
3393
3394 ddt show-tag [--no-header|-H]
3395
3396=head2 version
3397
3398 ddt version
3399
3400
3401=head1 AUTHORS
3402
3403Written by Gabriel Moreau, Kevin Reverchon, Olivier De-Marchi - Grenoble - France
3404
3405
3406=head1 LICENSE AND COPYRIGHT
3407
3408Licence GNU GPL version 2 or later and Perl equivalent
3409
3410Copyright (C) 2006-2018 Gabriel Moreau <Gabriel.Moreau(A)univ-grenoble-alpes.fr>.
Note: See TracBrowser for help on using the repository browser.