source: trunk/ddt/ddt @ 239

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