source: trunk/ddt/ddt @ 238

Last change on this file since 238 was 238, checked in by g7moreau, 6 years ago
  • Remove global variable $COMPUTER_DB et change it to local command
  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 115.1 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   exit_on_error_option($help)
1406      if $pool eq ''
1407      or $mac  eq '';
1408
1409   disable_float($pool, $mac);
1410   }
1411
1412#-------------------------------------------------------------------------------
1413
1414sub cmd_enable_float {
1415   local @ARGV = @_;
1416
1417   my $help = get_cmd_name();
1418   my ($pool, $mac);
1419
1420   GetOptions(
1421      'pool|p=s'  => \$pool,
1422      'mac|m=s'   => \$mac,
1423      );
1424
1425   exit_on_error_option($help)
1426      if $pool eq ''
1427      or $mac  eq '';
1428
1429   enable_float($pool, $mac);
1430   }
1431
1432#-------------------------------------------------------------------------------
1433# DELETE section
1434#-------------------------------------------------------------------------------
1435
1436#-------------------------------------------------------------------------------
1437#Nom: del_pc
1438#Description: supprime une machine en DHCP ou en IP statique.
1439
1440sub del_pc {
1441   my ($hostname, $domainset, $ip) = @_;
1442
1443   my $computer_db = ipamdb_load($COMPUTER_YAML);
1444
1445   control_exist_domainset($computer_db, $domainset) or exit;
1446   if ($ip ne '') {
1447      if ( control_exist_ip($computer_db, $ip) == 1 ) {
1448         die "Error: Unkown IP address: $ip\n";
1449         }
1450      my $cpt_mac=0;
1451      for my $value (@{$computer_db->{$domainset}}) {
1452         for my $id (keys %{$value}) {
1453            if ($value->{$id}->{'ip'} eq $ip) {
1454               my $timestamp = time;
1455               splice(@{$computer_db->{$domainset}}, $cpt_mac => 1);
1456               print "La machine $ip a été supprimer du domaine $domainset\n";
1457               ipamdb_save("$COMPUTER_YAML", $computer_db);
1458               exit;
1459               }
1460            }
1461         $cpt_mac++;
1462         }
1463      #print "La machine $ip n'existe pas sur le domaine $domainset.\n";
1464      }
1465   else {
1466      if ( control_exist_hostname($computer_db, $domainset, $hostname) == 1 ) {
1467         die "Error: Unkown host: $hostname, in domain set: $domainset\n";
1468         }
1469      my $cpt_mac=0;
1470      for my $value (@{$computer_db->{$domainset}}) {
1471         for my $id (keys %{$value}) {
1472            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} ne 'pool-dhcp')) {
1473               my $timestamp = time;
1474               splice(@{$computer_db->{$domainset}}, $cpt_mac => 1);
1475               print "La machine $hostname a été supprimer du domaine $domainset\n";
1476               ipamdb_save("$COMPUTER_YAML", $computer_db);
1477               exit;
1478               }
1479
1480            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} eq 'pool-dhcp')) {
1481               print "Suppression de la machine $hostname sur le domaine $domainset [FAILED]\n";
1482               print "La machine $hostname fait partie du pool DHCP $hostname.\n";
1483               exit;
1484               }
1485            }
1486         $cpt_mac++;
1487         }
1488      #print "La machine $hostname n'existe pas sur le domaine $domainset.\n";
1489      }
1490   }
1491
1492#-------------------------------------------------------------------------------
1493#Nom: del_float
1494#Description: supprime une machine d'un pool DHCP
1495
1496sub del_float {
1497   my ($pool, $mac) = @_;
1498
1499   my $computer_db = ipamdb_load($COMPUTER_YAML);
1500
1501   my $cpt_mac;
1502   if ( control_exist_mac($computer_db, $mac) == 1 ) {
1503      print "Adresse MAC $mac non trouvée.\n";
1504      exit;
1505      }
1506
1507   for my $domainset_current (keys %{$computer_db}) {
1508      next if $domainset_current eq 'dset';
1509      next if $domainset_current eq 'pool';
1510      next if $domainset_current eq 'pxe';
1511      next if $domainset_current eq 'tag';
1512      next if $domainset_current eq 'version';
1513
1514      my @domainsetdb = @{$computer_db->{$domainset_current}};
1515
1516      $cpt_mac=0;
1517      for my $value (@domainsetdb) {
1518         for my $id (keys %{$value}) {
1519
1520            if ($id eq $mac) {
1521               if ($value->{$id}->{'ip'} eq $pool) {
1522                  #splice(@{$computer_db->($domainset_current)} , $cpt_mac => 1);
1523                  splice(@{$computer_db->{$domainset_current}}, $cpt_mac => 1);
1524                  ipamdb_save("$COMPUTER_YAML", $computer_db);
1525                  print "Suppression de la machine $mac du pool $pool [OK]\n";
1526                  exit;
1527                  }
1528               else {
1529                  print "Suppression de la machine $mac [FAILED]\n";
1530                  print "La machine $mac n'appartient pas au pool $pool.\n";
1531                  exit;
1532                  }
1533               }
1534            $cpt_mac++;
1535            }
1536         }
1537      }
1538   }
1539
1540#-------------------------------------------------------------------------------
1541
1542sub cmd_del_pc {
1543   local @ARGV = @_;
1544
1545   my $help = get_cmd_name();
1546   my ($hostname, $domainset, $ip);
1547
1548   GetOptions(
1549      'hostname|h=s'    => \$hostname,
1550      'domainset|d=s'   => \$domainset,
1551      'ip|i=s'          => \$ip,
1552      );
1553
1554   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
1555   exit_on_error_option($help)
1556      if $domainset  eq '';
1557   exit_on_error_option($help)
1558      if $hostname   eq ''
1559      and $ip        eq '';
1560   exit_on_error_option($help)
1561      if $hostname   ne ''
1562      and $ip        ne '';
1563
1564   del_pc($hostname, $domainset, $ip);
1565   }
1566
1567#-------------------------------------------------------------------------------
1568
1569sub cmd_del_float {
1570   local @ARGV = @_;
1571
1572   my $help = get_cmd_name();
1573   my ($pool, $mac);
1574
1575   GetOptions(
1576      'pool|p=s'        => \$pool,
1577      'mac|m=s'         => \$mac,
1578      );
1579
1580   exit_on_error_option($help)
1581      if $pool eq ''
1582      or $mac  eq '';
1583
1584   del_float($pool, $mac);
1585   }
1586
1587#-------------------------------------------------------------------------------
1588# DOMAIN SET section
1589#-------------------------------------------------------------------------------
1590
1591sub cmd_create_domainset {
1592   local @ARGV = @_;
1593
1594   my $help = get_cmd_name();
1595   my ($domainset, $dns_extension, $comment);
1596
1597   GetOptions(
1598      'domainset|d=s'      => \$domainset,
1599      'dns-extension|e=s'  => \$dns_extension,
1600      'comment|c=s'        => \$comment,
1601      );
1602
1603   exit_on_error_option($help)
1604      if $domainset     eq ''
1605      or $dns_extension eq ''
1606      or $comment       eq '';
1607
1608   $comment = normalize_comment($comment);
1609
1610   my $computer_db = ipamdb_load($COMPUTER_YAML);
1611
1612   $computer_db->{'dset'} ||= {};
1613   die "Error: Domain Set already exists: $domainset\n" if exists $computer_db->{'dset'}{$domainset};
1614
1615   control_syntax_comment($comment)    or exit;
1616
1617   my $timestamp = time;
1618   $computer_db->{'dset'}{$domainset} = {
1619      'dns_extension'   => $dns_extension,
1620      'comment'         => $comment,
1621      'create_time'     => $timestamp,
1622      'modify_time'     => $timestamp,
1623      };
1624   $computer_db->{$domainset} ||= []; # Create empty Domain Set computer list by default
1625   ipamdb_save("$COMPUTER_YAML", $computer_db);
1626   }
1627
1628#-------------------------------------------------------------------------------
1629# POOL section
1630#-------------------------------------------------------------------------------
1631
1632#-------------------------------------------------------------------------------
1633#Nom: create_pool
1634#Description: crée un pool dans le fichier de données YAML et dans le DHCP.
1635#
1636#Commentaires: il y a un petit bug si jamais on rentre que des adresses ip qui existent déjà.
1637#              Le pool est créé mais sans adresses ip.
1638
1639sub cmd_create_pool {
1640   local @ARGV = @_;
1641
1642   my $help = get_cmd_name();
1643   my ($pool, $domainset, $file_pool, $ipaddress_pool);
1644
1645   GetOptions(
1646      'pool|p=s'           => \$pool,
1647      'domainset|d=s'      => \$domainset,
1648      'file-pool|f=s'      => \$file_pool,
1649      'ipaddress-pool|i=s' => \$ipaddress_pool,
1650      );
1651
1652   exit_on_error_option($help)
1653      if $pool             eq ''
1654      or $domainset        eq ''
1655      or $file_pool        eq ''
1656      or $ipaddress_pool   eq '';
1657
1658   my $computer_db = ipamdb_load($COMPUTER_YAML);
1659
1660   if ($computer_db->{'pool'}) {
1661      die "Error: Pool already exists: $pool\n" if exists $computer_db->{'pool'}{$pool};
1662      }
1663
1664   #--- control if the domain's pool exist ---#
1665   control_exist_domainset($computer_db, $domainset) or exit;
1666
1667   my @ip_list = ();
1668   #---control if address exist ---#
1669   if ($ipaddress_pool =~ /,/) {
1670      for my $ip (split /,/, $ipaddress_pool) {
1671         if ($ip =~ /-/) {
1672            my ($ip1, $ip2, $ip3, $range) = split /\./, $ip;
1673            my ($first, $last) = split /-/, $range;
1674            for (my $cpt = $first; $cpt <= $last; $cpt++) {
1675               my $ip_loc = "$ip1.$ip2.$ip3.$cpt";
1676               control_syntax_ip($ip_loc) or die "Error: Bad IP syntax: $ip_loc\n";
1677               control_exist_ip($computer_db, $ip_loc) or die "Error: IP address already exists: $ip_loc\n";
1678               push @ip_list, $ip_loc;
1679               }
1680            }
1681         else {
1682            control_syntax_ip($ip) or next;
1683            if ( control_exist_ip($computer_db, $ip) == 0 ) {
1684               print "L'adresse IP $ip existe déjà\n";
1685               next;
1686               }
1687            push @ip_list, $ip;
1688            }
1689         }
1690      }
1691
1692   my $timestamp = time;
1693   $computer_db->{'pool'}{$pool} = {
1694      'ip'          => [@ip_list],
1695      'enabled'     => 'yes',
1696      'create_time' => $timestamp,
1697      'modify_time' => $timestamp,
1698      'file'        => $file_pool,
1699      'domain'      => $domainset,
1700      };
1701   ipamdb_save("$COMPUTER_YAML", $computer_db);
1702   }
1703
1704#-------------------------------------------------------------------------------
1705
1706sub cmd_show_pool {
1707   local @ARGV = @_;
1708
1709   my ($no_header);
1710
1711   GetOptions(
1712      'no-header|H' => \$no_header,
1713      );
1714
1715   my $computer_db = ipamdb_load($COMPUTER_YAML);
1716
1717   printf "%-17s %-17s %s\n", 'Pool', 'File', 'DNS-Domain' if not $no_header;
1718   LOOP_ON_PXE:
1719   for my $pool ( keys %{$computer_db->{'pool'}} ) {
1720
1721      printf "%-17s %-17s %s\n",
1722         $pool,
1723         $computer_db->{'pool'}{$pool}{'file'},
1724         $computer_db->{'pool'}{$pool}{'domain'},
1725      }
1726   }
1727
1728#-------------------------------------------------------------------------------
1729# PXE section
1730#-------------------------------------------------------------------------------
1731
1732sub cmd_create_pxe {
1733   local @ARGV = @_;
1734
1735   my $help = get_cmd_name();
1736   my ($pxe_config, $ip_next_server, $filename, $comment);
1737
1738   GetOptions(
1739      'bootp|b=s'       => \$pxe_config,
1740      'next-server|n=s' => \$ip_next_server,
1741      'filename|f=s'    => \$filename,
1742      'comment|c=s'     => \$comment,
1743      );
1744
1745   exit_on_error_option($help)
1746      if $pxe_config       eq ''
1747      or $ip_next_server   eq ''
1748      or $filename         eq ''
1749      or $comment          eq '';
1750
1751   my $computer_db = ipamdb_load($COMPUTER_YAML);
1752
1753   $comment = normalize_comment($comment);
1754
1755   $computer_db->{'pxe'} ||= {};
1756   die "Error: PXE config already exists: $pxe_config\n" if exists $computer_db->{'pxe'}{$pxe_config};
1757
1758   control_syntax_ip($ip_next_server)  or die "Error: Bad IP syntax: $ip_next_server\n";
1759   control_syntax_comment($comment)    or exit;
1760
1761   my $timestamp = time;
1762   $computer_db->{'pxe'}{$pxe_config} = {
1763      'ip_next_server'  => $ip_next_server,
1764      'filename'        => $filename,
1765      'comment'         => $comment,
1766      'create_time'     => $timestamp,
1767      'modify_time'     => $timestamp,
1768      };
1769   ipamdb_save("$COMPUTER_YAML", $computer_db);
1770   }
1771
1772#-------------------------------------------------------------------------------
1773
1774sub cmd_remove_pxe {
1775   local @ARGV = @_;
1776
1777   my $help = get_cmd_name();
1778   my ($pxe_config);
1779
1780   GetOptions(
1781      'bootp|b=s' => \$pxe_config,
1782      );
1783
1784   exit_on_error_option($help)
1785      if $pxe_config eq '';
1786
1787   my $computer_db = ipamdb_load($COMPUTER_YAML);
1788
1789   $computer_db->{'pxe'} ||= {};
1790   die "Error: PXE config does not exist: $pxe_config\n" if not exists $computer_db->{'pxe'}{$pxe_config};
1791
1792   # Test if some computer use this config
1793   LOOP_ON_DOMAIN:
1794   for my $domainset_current (keys %{$computer_db}) {
1795      next if $domainset_current eq 'dset';
1796      next if $domainset_current eq 'pool';
1797      next if $domainset_current eq 'pxe';
1798      next if $domainset_current eq 'tag';
1799      next if $domainset_current eq 'version';
1800
1801      LOOP_ON_COMPUTER:
1802      for my $computer (@{$computer_db->{$domainset_current}}) {
1803         my ($mac_address, $attribute) = %{$computer};
1804
1805         if (exists $attribute->{'pxe_config'}) {
1806            my $hostname = $attribute->{'hostname'};
1807            die "Error: computer still use this PXE config: $hostname.$domainset_current $mac_address\n" if $pxe_config eq $attribute->{'pxe_config'};
1808            }
1809         }
1810      }
1811
1812   delete $computer_db->{'pxe'}{$pxe_config};
1813   ipamdb_save("$COMPUTER_YAML", $computer_db);
1814   }
1815
1816#--------------------------------------------------------------------------------
1817
1818sub cmd_show_pxe {
1819   local @ARGV = @_;
1820
1821   my ($no_header);
1822
1823   GetOptions(
1824      'no-header|H' => \$no_header,
1825      );
1826
1827   my $computer_db = ipamdb_load($COMPUTER_YAML);
1828
1829   printf "%-12s %-13s %-30s %s\n", 'PXE-Config', 'Next-Server', 'Filename', 'Comment' if not $no_header;
1830   LOOP_ON_PXE:
1831   for my $pxe_config ( keys %{$computer_db->{'pxe'}} ) {
1832      my $ip_next_server = $computer_db->{'pxe'}{$pxe_config}{'ip_next_server'};
1833      my $filename       = $computer_db->{'pxe'}{$pxe_config}{'filename'};
1834      my $comment        = $computer_db->{'pxe'}{$pxe_config}{'comment'};
1835
1836      printf "%-12s %-13s %-30s %s\n", $pxe_config, $ip_next_server, $filename, $comment;
1837      }
1838   }
1839
1840#-------------------------------------------------------------------------------
1841
1842sub cmd_enable_pxe {
1843   local @ARGV = @_;
1844
1845   my $help = get_cmd_name();
1846   my ($hostname, $domainset, $ip, $pxe_config);
1847
1848   GetOptions(
1849      'hostname|h=s'    => \$hostname,
1850      'domainset|d=s'   => \$domainset,
1851      'ip|i=s'          => \$ip,
1852      'bootp|b=s'       => \$pxe_config,
1853      );
1854
1855   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
1856   exit_on_error_option($help)
1857      if $domainset  eq ''
1858      or $pxe_config eq '';
1859   exit_on_error_option($help)
1860      if $hostname   eq ''
1861      and $ip        eq '';
1862   exit_on_error_option($help)
1863      if $hostname   ne ''
1864      and $ip        ne '';
1865
1866   my $computer_db = ipamdb_load($COMPUTER_YAML);
1867
1868   die "Error: PXE config not exists: $pxe_config\n" if not exists $computer_db->{'pxe'}{$pxe_config};
1869
1870   control_exist_domainset($computer_db, $domainset) or exit;
1871   if ($ip ne '') {
1872      control_syntax_ip($ip);
1873      if ( control_exist_ip($computer_db, $ip) == 1 ) {
1874         die "Error: Unkown IP address: $ip\n";
1875         }
1876
1877      for my $domainset_current (keys %{$computer_db}) {
1878         next if $domainset_current eq 'dset';
1879         next if $domainset_current eq 'pool';
1880         next if $domainset_current eq 'pxe';
1881         next if $domainset_current eq 'tag';
1882         next if $domainset_current eq 'version';
1883
1884         my $cpt_mac = 0;
1885         for my $computer (@{$computer_db->{$domainset_current}}) {
1886            for my $id (keys %{$computer}) {
1887               if ($computer->{$id}->{'ip'} eq $ip) {
1888                  my $timestamp = time;
1889                  $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
1890                  $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'pxe_config'}  = $pxe_config;
1891                  print "IP Address: $ip, PXE enabled in config: $pxe_config\n";
1892                  ipamdb_save("$COMPUTER_YAML", $computer_db);
1893                  exit;
1894                  }
1895               $cpt_mac++;
1896               }
1897            }
1898         }
1899      }
1900   else {
1901      if ( control_exist_hostname($computer_db, $domainset, $hostname) == 1 ) {
1902         die "Error: Unkown host: $hostname, in domain set: $domainset\n";
1903         }
1904
1905      my $cpt_mac = 0;
1906      for my $value (@{$computer_db->{$domainset}}) {
1907         for my $id (keys %{$value}) {
1908            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} ne 'pool-dhcp')) {
1909               my $timestamp = time;
1910               $computer_db->{$domainset}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
1911               $computer_db->{$domainset}[$cpt_mac]->{$id}->{'pxe_config'}  = $pxe_config;
1912               print "Host $hostname ($domainset), PXE enabled in config: $pxe_config\n";
1913               ipamdb_save("$COMPUTER_YAML", $computer_db);
1914               exit;
1915               }
1916
1917            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} eq 'pool-dhcp')) {
1918               die "Error. Host $hostname ($domainset) in a pool. No PXE possible\n";
1919               }
1920            }
1921         $cpt_mac++;
1922         }
1923      }
1924   }
1925
1926#-------------------------------------------------------------------------------
1927
1928sub cmd_disable_pxe {
1929   local @ARGV = @_;
1930
1931   my $help = get_cmd_name();
1932   my ($hostname, $domainset, $ip);
1933
1934   GetOptions(
1935      'hostname|h=s'    => \$hostname,
1936      'domainset|d=s'   => \$domainset,
1937      'ip|i=s'          => \$ip,
1938      );
1939
1940   ($hostname, $domainset) = split /\./, $hostname, 2 if $hostname =~ m/\./;
1941   exit_on_error_option($help)
1942      if $domainset  eq '';
1943   exit_on_error_option($help)
1944      if $hostname   eq ''
1945      and $ip        eq '';
1946   exit_on_error_option($help)
1947      if $hostname   ne ''
1948      and $ip        ne '';
1949
1950   my $computer_db = ipamdb_load($COMPUTER_YAML);
1951
1952   control_exist_domainset($computer_db, $domainset) or exit;
1953   if ($ip ne '') {
1954      control_syntax_ip($ip);
1955      if ( control_exist_ip($computer_db, $ip) == 1 ) {
1956         die "Error: Unkown IP address: $ip\n";
1957         }
1958
1959      for my $domainset_current (keys %{$computer_db}) {
1960         next if $domainset_current eq 'dset';
1961         next if $domainset_current eq 'pool';
1962         next if $domainset_current eq 'pxe';
1963         next if $domainset_current eq 'tag';
1964         next if $domainset_current eq 'version';
1965
1966         my $cpt_mac = 0;
1967         for my $computer (@{$computer_db->{$domainset_current}}) {
1968            for my $id (keys %{$computer}) {
1969               if ($computer->{$id}->{'ip'} eq $ip) {
1970                  next if not exists $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'pxe_config'};
1971
1972                  my $pxe_config = $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'pxe_config'};
1973                  my $timestamp  = time;
1974                  $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
1975                  delete $computer_db->{$domainset_current}[$cpt_mac]->{$id}->{'pxe_config'};
1976                  print "IP Address: $ip, PXE disable from config: $pxe_config\n";
1977                  ipamdb_save("$COMPUTER_YAML", $computer_db);
1978                  exit;
1979                  }
1980               $cpt_mac++;
1981               }
1982            }
1983         }
1984      }
1985   else {
1986      if ( control_exist_hostname($computer_db, $domainset, $hostname) == 1 ) {
1987         die "Error: Unkown host: $hostname, in domain set: $domainset\n";
1988         }
1989
1990      my $cpt_mac = 0;
1991      for my $value (@{$computer_db->{$domainset}}) {
1992         for my $id (keys %{$value}) {
1993            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} ne 'pool-dhcp')) {
1994               next if not exists $value->{$id}->{'pxe_config'};
1995
1996               my $pxe_config = $computer_db->{$domainset}[$cpt_mac]->{$id}->{'pxe_config'};
1997               my $timestamp  = time;
1998               $computer_db->{$domainset}[$cpt_mac]->{$id}->{'modify_time'} = $timestamp;
1999               delete $computer_db->{$domainset}[$cpt_mac]->{$id}->{'pxe_config'};
2000               print "Host $hostname ($domainset), PXE disable from config: $pxe_config\n";
2001               ipamdb_save("$COMPUTER_YAML", $computer_db);
2002               exit;
2003               }
2004
2005            if (($value->{$id}->{'hostname'} eq $hostname) and ($value->{$id}->{'address_type'} eq 'pool-dhcp')) {
2006               die "Error. Host $hostname ($domainset) in a pool. No PXE possible\n";
2007               }
2008            }
2009         $cpt_mac++;
2010         }
2011      }
2012   }
2013
2014#-------------------------------------------------------------------------------
2015# TAG section
2016#-------------------------------------------------------------------------------
2017
2018sub cmd_create_tag {
2019   local @ARGV = @_;
2020
2021   my $help = get_cmd_name();
2022   my ($tag, $comment);
2023
2024   GetOptions(
2025      'tag|t=s'      => \$tag,
2026      'comment|c=s'  => \$comment,
2027      );
2028
2029   exit_on_error_option($help)
2030      if $tag     eq ''
2031      or $comment eq '';
2032
2033   my $computer_db = ipamdb_load($COMPUTER_YAML);
2034
2035   $comment = normalize_comment($comment);
2036
2037   $computer_db->{'tag'} ||= {};
2038   die "Error: TAG already exists: $tag\n" if exists $computer_db->{'tag'}{$tag};
2039
2040   die "Error: TAG 'universal' is intrinsic. It's not possible to create it.\n" if $tag eq 'universal';
2041
2042   if ($tag !~ m/^ \w+ $/xms) {
2043      die "Error: Bad format for TAG (alphanumeric string): $tag\n";
2044      }
2045
2046   control_syntax_comment($comment) or exit;
2047
2048   my $timestamp = time;
2049   $computer_db->{'tag'}{$tag} = {
2050      'comment'         => $comment,
2051      'create_time'     => $timestamp,
2052      'modify_time'     => $timestamp,
2053      };
2054   ipamdb_save("$COMPUTER_YAML", $computer_db);
2055   }
2056
2057#-------------------------------------------------------------------------------
2058
2059sub cmd_remove_tag {
2060   local @ARGV = @_;
2061
2062   my $help = get_cmd_name();
2063   my ($tag);
2064
2065   GetOptions(
2066      'tag|t=s' => \$tag,
2067      );
2068
2069   exit_on_error_option($help)
2070      if $tag eq '';
2071
2072   my $computer_db = ipamdb_load($COMPUTER_YAML);
2073
2074   $computer_db->{'tag'} ||= {};
2075   die "Error: TAG does not exist: $tag\n" if not exists $computer_db->{'tag'}{$tag};
2076
2077   # Test if some computer use this config
2078   LOOP_ON_DOMAIN:
2079   for my $domainset_current (keys %{$computer_db}) {
2080      next if $domainset_current eq 'dset';
2081      next if $domainset_current eq 'pool';
2082      next if $domainset_current eq 'pxe';
2083      next if $domainset_current eq 'tag';
2084      next if $domainset_current eq 'version';
2085
2086      LOOP_ON_COMPUTER:
2087      for my $computer (@{$computer_db->{$domainset_current}}) {
2088         my ($mac_address, $attribute) = %{$computer};
2089
2090         if (exists $attribute->{'tag'}) {
2091            my $hostname = $attribute->{'hostname'};
2092            die "Error: Computer still use this TAG: $hostname.$domainset_current $mac_address\n" if $tag eq $attribute->{'tag'};
2093            }
2094         }
2095      }
2096
2097   delete $computer_db->{'tag'}{$tag};
2098   ipamdb_save("$COMPUTER_YAML", $computer_db);
2099   }
2100
2101#--------------------------------------------------------------------------------
2102
2103sub cmd_show_tag {
2104   local @ARGV = @_;
2105
2106   my ($no_header);
2107
2108   GetOptions(
2109      'no-header|H' => \$no_header,
2110      );
2111
2112   my $computer_db = ipamdb_load($COMPUTER_YAML);
2113
2114   printf "%-12s %s\n", 'TAG', 'Comment' if not $no_header;
2115   LOOP_ON_TAG:
2116   for my $tag ( keys %{$computer_db->{'tag'}} ) {
2117      my $comment = $computer_db->{'tag'}{$tag}{'comment'};
2118
2119      printf "%-12s %s\n", $tag, $comment;
2120      }
2121   }
2122
2123#--------------------------------------------------------------------------------
2124# GLOBAL section
2125#--------------------------------------------------------------------------------
2126
2127sub cmd_upgrade_db {
2128   my $flag_change;
2129
2130   my $computer_db = ipamdb_load($COMPUTER_YAML);
2131
2132   LOOP_ON_DOMAIN:
2133   for my $domainset_current (keys %{$computer_db}) {
2134      next if $domainset_current eq 'dset';
2135      next if $domainset_current eq 'pool';
2136      next if $domainset_current eq 'pxe';
2137      next if $domainset_current eq 'tag';
2138      next if $domainset_current eq 'version';
2139
2140      my @domainsetdb = @{$computer_db->{$domainset_current}};
2141
2142      LOOP_ON_COMPUTER:
2143      for my $computer (@domainsetdb) {
2144         my ($mac_address, $attribute) = %{$computer};
2145         my $new_mac = normalize_mac_address($mac_address);
2146         print "perl -pi -e 's/$mac_address:/$new_mac:/' $COMPUTER_YAML\n" if "$mac_address" ne "$new_mac";
2147
2148         my $comment = $attribute->{'comment'};
2149         $comment =~ s/\s\s+/ /g and $flag_change++;
2150         $comment =~ s/^\s+\S//  and $flag_change++;
2151         $comment =~ s/\S\s+$//  and $flag_change++;
2152         $comment =~ s{^(\d\d\d\d)\/O(\d\/\d\d)}{$1/0$2} and $flag_change++;
2153         $comment =~ s{^(\d\d\d\d\/\d\d\/)O(\d)}{$1/0$2} and $flag_change++;
2154         $comment =~ s{^(\d\d\d\d)\/(\d\d)\/(\d\d)}{$1-$2-$3} and $flag_change++;
2155         if ($comment !~ m/^\d\d\d\d-\d\d-\d\d/) {
2156            print "# no date at beginning of comment $mac_address\n";
2157            }
2158
2159         $attribute->{'comment'} = $comment;
2160         }
2161      }
2162   print "# FLAG :$flag_change\n";
2163
2164   ipamdb_save("$COMPUTER_YAML", $computer_db) if $flag_change;
2165   }
2166
2167#--------------------------------------------------------------------------------
2168
2169sub cmd_show_domainset {
2170
2171   my $computer_db = ipamdb_load($COMPUTER_YAML);
2172
2173   LOOP_ON_DOMAIN:
2174   for my $domainset_current (keys %{$computer_db}) {
2175      next if $domainset_current eq 'dset';
2176      next if $domainset_current eq 'pool';
2177      next if $domainset_current eq 'pxe';
2178      next if $domainset_current eq 'tag';
2179      next if $domainset_current eq 'version';
2180
2181      print "$domainset_current\n";
2182      }
2183   }
2184
2185#--------------------------------------------------------------------------------
2186
2187sub cmd_search_mac {
2188   local @ARGV = @_;
2189
2190   my $help = get_cmd_name();
2191   my ($mac);
2192
2193   GetOptions(
2194      'mac|m=s' => \$mac,
2195      );
2196
2197   exit_on_error_option($help)
2198      if $mac eq '';
2199
2200   $mac = normalize_mac_address($mac);
2201
2202   my $computer_db = ipamdb_load($COMPUTER_YAML);
2203
2204   control_syntax_mac_address($mac) or exit;
2205
2206   LOOP_ON_DOMAIN:
2207   for my $domainset_current (keys %{$computer_db}) {
2208      next if $domainset_current eq 'dset';
2209      next if $domainset_current eq 'pool';
2210      next if $domainset_current eq 'pxe';
2211      next if $domainset_current eq 'tag';
2212      next if $domainset_current eq 'version';
2213
2214      my @domainsetdb = @{$computer_db->{$domainset_current}};
2215
2216      LOOP_ON_COMPUTER:
2217      for my $computer (@domainsetdb) {
2218         my ($mac_address, $attribute) = %{$computer};
2219
2220         next LOOP_ON_COMPUTER if $mac_address ne $mac;
2221
2222         my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime $attribute->{'modify_time'};
2223         $year += 1900;
2224         $mon++;
2225         my $date = sprintf '%04i-%02i-%02i', $year, $mon, $mday;
2226
2227         my $comment = $attribute->{'comment'};
2228         $comment =~ s/^\d\d\d\d-\d\d-\d\d\s//;
2229
2230         my $enable = $attribute->{'enabled'};
2231         if (exists $attribute->{'pxe_config'}) {
2232            $enable .= '/' . $attribute->{'pxe_config'};
2233            }
2234         if (exists $attribute->{'tag'}) {
2235            $enable .= ':' . $attribute->{'tag'};
2236            }
2237
2238         printf "%-30s  %-20s %17s %9s %3s %10s %s\n",
2239            $attribute->{'hostname'} . '.' . $domainset_current,
2240            $attribute->{'ip'},
2241            $mac_address,
2242            $attribute->{'address_type'},
2243            $enable,
2244            $date,
2245            $comment;
2246         }
2247      }
2248   }
2249
2250#--------------------------------------------------------------------------------
2251#Nom: show
2252#Description: liste les machines à partir du fichier YAML par nom de domaine.
2253
2254sub cmd_show_host {
2255   my %ipdb = ();
2256
2257   my $computer_db = ipamdb_load($COMPUTER_YAML);
2258
2259   LOOP_ON_DOMAIN:
2260   for my $domainset_current (keys %{$computer_db}) {
2261      next if $domainset_current eq 'dset';
2262      next if $domainset_current eq 'pool';
2263      next if $domainset_current eq 'pxe';
2264      next if $domainset_current eq 'tag';
2265      next if $domainset_current eq 'version';
2266
2267      print "\n# *** List of computers in the domain set: $domainset_current ***\n";
2268      printf "%-30s  %-20s %17s %5s %7s %-10s %s\n",
2269         'Hostname',
2270         'IPv4-Address',
2271         'MAC-Address',
2272         'Type',
2273         'Status',
2274         'Date',
2275         'Comment';
2276      my @domainsetdb = @{$computer_db->{$domainset_current}};
2277
2278      LOOP_ON_COMPUTER:
2279      for my $computer (@domainsetdb) {
2280         my ($mac_address, $attribute) = %{$computer};
2281
2282         if ($attribute->{'ip'} =~ $DDT::RE::IPv4_ADDRESS) {
2283            if ( not exists $ipdb{ $attribute->{'ip'} } ) {
2284               $ipdb{ $attribute->{'ip'} } = {
2285                  'mac_address'  => $mac_address,
2286                  %{$attribute},
2287                  'domain'       => $domainset_current,
2288                  };
2289               next LOOP_ON_COMPUTER;
2290               }
2291            else {
2292               print {*STDERR} "# Warning: $attribute->{'ip'} already exists in the database !\n";
2293               }
2294            }
2295
2296         my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime $attribute->{'modify_time'};
2297         $year += 1900;
2298         $mon++;
2299         my $date = sprintf '%04i-%02i-%02i', $year, $mon, $mday;
2300
2301         my $comment = normalize_comment($attribute->{'comment'});
2302         $comment =~ s/^\d\d\d\d-\d\d-\d\d\s//;
2303
2304         my $ip = $attribute->{'ip'};
2305
2306         my $enable = $attribute->{'enabled'};
2307         if (exists $attribute->{'pxe_config'}) {
2308            $enable .= '/' . $attribute->{'pxe_config'};
2309            }
2310         if (exists $ipdb{$ip}->{'tag'}) {
2311            $enable .= ':' . $ipdb{$ip}->{'tag'};
2312            }
2313
2314         printf "%-30s  %-20s %17s %9s %3s %10s %s\n",
2315            $attribute->{'hostname'} . '.' . $domainset_current,
2316            $ip,
2317            $mac_address,
2318            $attribute->{'address_type'},
2319            $enable,
2320            $date,
2321            $comment;
2322         }
2323      }
2324
2325   print "\n# *** List of computers ordered by IP and domain set ***\n";
2326   LOOP_ON_IP_ADDRESS:
2327   foreach my $ip (Net::Netmask::sort_by_ip_address(keys %ipdb)) {
2328      my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime $ipdb{$ip}->{'modify_time'};
2329      $year += 1900;
2330      $mon++;
2331      my $date = sprintf '%04i-%02i-%02i', $year, $mon, $mday;
2332
2333      my $comment =$ipdb{$ip}->{'comment'};
2334      $comment =~ s/^\d\d\d\d-\d\d-\d\d\s//;
2335
2336      my $enable = $ipdb{$ip}->{'enabled'};
2337      if (exists $ipdb{$ip}->{'pxe_config'}) {
2338         $enable .= '/' . $ipdb{$ip}->{'pxe_config'};
2339         }
2340      if (exists $ipdb{$ip}->{'tag'}) {
2341         $enable .= ':' . $ipdb{$ip}->{'tag'};
2342         }
2343
2344      printf "%-30s %-20s %17s %9s %3s %10s %s\n",
2345         $ipdb{$ip}->{'hostname'} . '.' . $ipdb{$ip}->{'domain'},
2346         $ip,
2347         normalize_mac_address($ipdb{$ip}->{'mac_address'}),
2348         $ipdb{$ip}->{'address_type'},
2349         $enable,
2350         $date,
2351         $comment;
2352      }
2353   }
2354
2355#-------------------------------------------------------------------------------
2356#Nom: cmd_generate_dhcp_file
2357#Description: génère les fichiers de configuration des machines et des pools du dhcp
2358
2359sub cmd_generate_dhcp_file {
2360   backup_database();
2361
2362   my $computer_db = ipamdb_load($COMPUTER_YAML);
2363
2364   my %file_pool;
2365
2366   for my $domainset_current (keys %{$computer_db}) {
2367      next if $domainset_current eq 'dset';
2368      next if $domainset_current eq 'pool';
2369      next if $domainset_current eq 'pxe';
2370      next if $domainset_current eq 'tag';
2371      next if $domainset_current eq 'version';
2372
2373      open FILE_VLAN, '>', "$FOLDER_GEN_DHCP/$domainset_current";
2374      my @domainsetdb = @{$computer_db->{$domainset_current}};
2375      for my $value (@domainsetdb) {
2376         ALL_MAC_ADDRESS:
2377         for my $mac_addres (keys %{$value}) {
2378            #host pcdavoust {  deny-unknown-clients;
2379            #hardware ethernet 0:6:5b:b8:13:d1;
2380            #fixed-address 194.254.66.72;
2381            #}
2382
2383            my $hostname     = $value->{$mac_addres}{'hostname'};
2384            my $ip           = $value->{$mac_addres}{'ip'};
2385            my $comment      = $value->{$mac_addres}{'comment'};
2386            my $address_type = $value->{$mac_addres}{'address_type'};
2387            my $enabled      = $value->{$mac_addres}{'enabled'};
2388            my $tags         = $value->{$mac_addres}{'tag'} || 'universal';
2389
2390            my $buffer;
2391            if ($address_type eq 'dhcp') {
2392               if ($enabled eq 'yes') {
2393                  $buffer  = "host $hostname {\n"; # deny-unknown-clients;
2394                  $buffer .= "   hardware ethernet $mac_addres;\n";
2395                  $buffer .= "   fixed-address $ip;\n";
2396
2397                  if (exists $value->{$mac_addres}{'pxe_config'}) {
2398                     my $pxe_config     = $value->{$mac_addres}{'pxe_config'};
2399                     my $ip_next_server = $computer_db->{'pxe'}{$pxe_config}{'ip_next_server'};
2400                     my $filename       = $computer_db->{'pxe'}{$pxe_config}{'filename'};
2401                     $buffer .= "   next-server $ip_next_server;\n";
2402                     $buffer .= "   filename \"$filename\";\n";
2403                     }
2404                  $buffer .= "   #comment: $comment\n";
2405                  $buffer .= "   }\n";
2406                  $buffer .= "\n";
2407
2408                  for my $tag (split/,/, $tags) {
2409                     $file_pool{"tag-$tag"} ||= [];
2410                     push @{$file_pool{"tag-$tag"}}, "subclass \"tag-$tag\" 1:$mac_addres; # $comment\n";
2411                     }
2412                  }
2413               else {
2414                  $buffer  = "#host $hostname {\n"; # deny-unknown-clients;
2415                  $buffer .= "#   hardware ethernet $mac_addres;\n";
2416                  $buffer .= "#   fixed-address $ip;\n";
2417                  $buffer .= "#   comment: $comment \n";
2418                  $buffer .= "#   }\n";
2419                  $buffer .= "\n";
2420                  }
2421               print FILE_VLAN $buffer;
2422               }
2423            elsif ($address_type eq 'pool-dhcp') {
2424               #--- Génère les fichiers pool dhcp ---#
2425               for my $current_pool (keys %{$computer_db->{'pool'}}) {
2426                  next if $current_pool ne $ip;
2427
2428                  if ($enabled eq 'yes') {
2429                     $buffer = "subclass \"$current_pool\" 1:$mac_addres; # $comment\n";
2430
2431                     for my $tag (split/,/, $tags) {
2432                        $file_pool{"tag-$tag"} ||= [];
2433                        push @{$file_pool{"tag-$tag"}}, "subclass \"tag-$tag\" 1:$mac_addres; # $comment\n";
2434                        }
2435                     }
2436                  else {
2437                     $buffer = "#subclass \"$current_pool\" 1:$mac_addres; # $comment\n";
2438                     }
2439
2440                  my $current_pool_file_name = $computer_db->{'pool'}{$current_pool}{'file'};
2441
2442                  $file_pool{$current_pool_file_name} ||= [];
2443                  push @{$file_pool{$current_pool_file_name}}, $buffer;
2444                  }
2445               }
2446            }
2447         }
2448
2449      close FILE_VLAN;
2450
2451      for my $file_name (keys %file_pool) {
2452         open FILE_POOL, '>', "$FOLDER_GEN_DHCP/$file_name";
2453         print FILE_POOL @{$file_pool{$file_name}};
2454         close FILE_POOL;
2455         }
2456      }
2457      print "Copy DHCP files from $FOLDER_GEN_DHCP to /etc/dhcp/include/\n";
2458      exec $SCRIPT_UPDATE;
2459   }
2460
2461#-------------------------------------------------------------------------------
2462#Nom: cmd_generate_dns_file
2463#Description: génère les fichiers d'enregistrements DNS
2464
2465sub cmd_generate_dns_file {
2466   my $buffer;
2467   my $buffer_rev;
2468   my $pool_domain;
2469
2470   my $computer_db = ipamdb_load($COMPUTER_YAML);
2471
2472   for my $domainset_current (keys %{$computer_db}) {
2473      next if $domainset_current eq 'dset';
2474      next if $domainset_current eq 'pool';
2475      next if $domainset_current eq 'pxe';
2476      next if $domainset_current eq 'tag';
2477      next if $domainset_current eq 'version';
2478
2479      if ($domainset_current eq 'pool') {
2480         #next;
2481         for my $value (@{$computer_db->{$domainset_current}}) {
2482            for my $pool_name (keys %{$value}) {
2483               $pool_domain = $value->{$pool_name}->{'domain'}."\n";
2484               #print $value->{$pool_name}->{'file'};
2485               chomp $pool_domain;
2486               open FILE_FORWARD_DNS, '>>', "$FOLDER_GEN_DNS/db.$pool_domain.fwd";
2487               open FILE_REVERSE_DNS, '>>', "$FOLDER_GEN_DNS/db.$pool_domain.rev";
2488               my @T_pool_ip = @{$value->{$pool_name}->{'ip'}};
2489               for my $pool_ip (@T_pool_ip) {
2490                  my @T_split = split(/\./ , $pool_ip);
2491                  $buffer     = sprintf "%-24s IN  A  %-15s ;\n", "$pool_name$T_split[3]", $pool_ip;
2492                  $buffer_rev = "$T_split[3]   IN PTR   $pool_name$T_split[3].$pool_domain.\n";
2493                  print FILE_FORWARD_DNS $buffer;
2494                  print FILE_REVERSE_DNS $buffer_rev;
2495                  }
2496               close FILE_FORWARD_DNS;
2497               close FILE_REVERSE_DNS;
2498               }
2499            }
2500         }
2501
2502      else {
2503         #--- Création du fichier non-reverse ---#
2504         open ( FILE_FORWARD_DNS, ">> $FOLDER_GEN_DNS/db.$domainset_current.fwd");
2505         open ( FILE_REVERSE_DNS, ">> $FOLDER_GEN_DNS/db.$domainset_current.rev");
2506         my @domainsetdb = @{$computer_db->{$domainset_current}};
2507         for my $value (@domainsetdb) {
2508            for my $id (keys %{$value}) {
2509               #host pcdavoust {  deny-unknown-clients;
2510               #hardware ethernet 0:6:5b:b8:13:d1;
2511               #fixed-address 194.254.66.72;
2512               #}
2513               my $hostname = $value->{$id}->{'hostname'};
2514               my $ip       = $value->{$id}->{'ip'};
2515               my $comment  = $value->{$id}->{'comment'};
2516               my $address_type = $value->{$id}->{'address_type'};
2517               my $enabled      = $value->{$id}->{'enabled'};
2518
2519               my $dns_domain = $domainset_current;
2520               if (exists $computer_db->{'dset'}{$domainset_current}) {
2521                  $dns_domain = $computer_db->{'dset'}{$domainset_current}{'dns_extension'};
2522                  }
2523               my @T_split = split(/\./ , $ip);
2524               if  (($address_type eq 'dhcp') or ($address_type eq 'static')) {
2525                  if ($enabled eq 'yes') {
2526                     $buffer = sprintf "%-24s IN A %-15s ; %s\n", $hostname, $ip, $comment;
2527                     if (exists $value->{$id}->{'dns_extension'}
2528                           and "$value->{$id}->{'dns_extension'}" != "$dns_domain") {
2529                        print "A FAIRE\n";
2530                        }
2531                     $buffer_rev = $T_split[3]."     IN PTR   $hostname.$dns_domain.\n";
2532                     }
2533
2534                  else {
2535                     $buffer = sprintf "%-24s IN A %-15s ; %s\n", $hostname, $ip, $comment;
2536                     $buffer_rev = ";".$T_split[3]."    IN PTR   $hostname.$dns_domain.\n";
2537                     }
2538                  print FILE_REVERSE_DNS $buffer_rev;
2539                  print FILE_FORWARD_DNS $buffer;
2540                  }
2541               }
2542            #$cpt=$cpt+1;
2543            }
2544         print "- DNS: db.$domainset_current.fwd db.$domainset_current.rev [CREATE].\n";
2545         print "Ex : sort -k 4n -t . /usr/local/dhcp-dns-tools/dns/dns.hmg.priv\n";
2546         close FILE_REVERSE_DNS;
2547         close FILE_FORWARD_DNS;
2548         }
2549      }
2550   }
2551
2552#--------------------------------------------------------------------------------
2553
2554sub shell_command {
2555   my $cmd = shift;
2556
2557   require FileHandle;
2558   my $fh     = new FileHandle;
2559   my @result = ();
2560   open $fh, q{-|}, "LANG=C $cmd" or die "Can't exec $cmd\n";
2561   @result = <$fh>;
2562   close $fh;
2563   chomp @result;
2564   return @result;
2565   }
2566
2567sub cmd_check_dns {
2568   my $computer_db = ipamdb_load($COMPUTER_YAML);
2569
2570   LOOP_ON_DOMAIN:
2571   for my $domainset_current (keys %{$computer_db}) {
2572      next if $domainset_current eq 'dset';
2573      next if $domainset_current eq 'pool';
2574      next if $domainset_current eq 'pxe';
2575      next if $domainset_current eq 'tag';
2576      next if $domainset_current eq 'version';
2577
2578      my @domainsetdb = @{$computer_db->{$domainset_current}};
2579
2580      LOOP_ON_COMPUTER:
2581      for my $computer (@domainsetdb) {
2582         my ($mac_address, $attribute) = %{$computer};
2583         #my $new_mac = normalize_mac_address($mac_address);
2584         my $ip = $attribute->{'ip'};
2585         next LOOP_ON_COMPUTER if not $ip =~ m/$DDT::RE::IPv4_ADDRESS/xms;
2586         next LOOP_ON_COMPUTER if $attribute->{'enabled'} eq 'no';
2587
2588         my $dns_hostname_fq = scalar gethostbyaddr(inet_aton($ip), AF_INET);
2589         my ($dns_hostname) = split /\./, $dns_hostname_fq;
2590
2591         if ($attribute->{'hostname'} ne $dns_hostname) {
2592            print "$mac_address ($domainset_current) $ip - $dns_hostname / $attribute->{'hostname'} # $attribute->{'comment'}\n";
2593            next LOOP_ON_COMPUTER;
2594            }
2595
2596         my $packed_ip = scalar gethostbyname($dns_hostname_fq);
2597         if (defined $packed_ip) {
2598            my $ip_address = inet_ntoa($packed_ip);
2599            if ($ip ne $ip_address) {
2600               print "reverse DNS error for $dns_hostname_fq / $ip\n";
2601               next LOOP_ON_COMPUTER;
2602               }
2603            }
2604         }
2605      }
2606
2607   LOOP_ON_DNS:
2608   for my $dns ('legi.grenoble-inp.fr', 'hmg.priv') {
2609      LOOP_ON_IP:
2610      for (shell_command("host -t A -l $dns")) {
2611         # smtp2.legi.grenoble-inp.fr has address 194.254.67.37
2612         next if not m/has address/;
2613         next if not m/^(\w[\w-_\.]+\w)\s+has\saddress\s+(\d[\d\.]+\d)$/;
2614         my ($hostname_fq, $ip) = ($1, $2);
2615         control_syntax_ip($ip) or next LOOP_ON_IP;
2616         if (control_exist_ip($computer_db, $ip) == 1) {
2617            printf "Unkown IP: %015s / %s\n", $ip, $hostname_fq;
2618            next LOOP_ON_IP;
2619            }
2620         }
2621      }
2622   }
2623
2624#-------------------------------------------------------------------------------
2625#Nom: load_data_dhcp
2626#Description: permet de charger le fichier de données YAML via les fichiers de configuration
2627#             machines.
2628#            ATTENTION: LES COMMENTAIRES DU FICHIER DISPARAITRONT.
2629
2630sub load_data_dhcp {
2631   my ($domainset, $input_file) = @_;
2632
2633   my $computer_db = ipamdb_load($COMPUTER_YAML);
2634
2635   my @T_mac;
2636   my @T_host;
2637   my @T_ip;
2638   my $cpt;
2639   open (FILE, "<$input_file");
2640   my @buffer = <FILE>;
2641   close(FILE);
2642
2643   for my $ligne (@buffer) {
2644      #--
2645      $ligne =~ s/#.*$//;
2646      $ligne =~ s/\s+/ /;
2647      $ligne =~ s/^\s+//;
2648      next if $ligne eq '';
2649
2650      if ($ligne =~ /^host /) {
2651         $cpt=0;
2652         my @T_split = split(/host\s+/, $ligne);
2653         @T_host = split(/ /, $T_split[1]);
2654         chomp($T_host[0]);
2655
2656         $cpt++;
2657         }
2658
2659      if ($ligne =~ /^*ethernet /) {
2660         $ligne =~ s/;//g;
2661         @T_mac = split(/ethernet\s+/, $ligne);
2662         chomp($T_mac[1]);
2663         $cpt++;
2664         }
2665
2666      if ($ligne =~ /^*address /) {
2667         $ligne =~ s/;//g;
2668         @T_ip = split(/address\s+/, $ligne);
2669         chomp($T_ip[1]);
2670
2671         $cpt++;
2672         }
2673
2674      if ($cpt == 3) {
2675         #   print "MAC $T_mac[1] HOST $T_host[0] IP $T_ip[1].\n";
2676         my $mac = $T_mac[1];
2677         my $hostname = $T_host[0];
2678         my $ip = $T_ip[1];
2679         $cpt = 0;
2680
2681         if ( control_exist_hostname($computer_db, $domainset, $hostname) == 0 ) {
2682            print "Error: Hostname already exist in domain set attachement $domainset: $hostname\n";
2683            next;
2684            }
2685         control_syntax_mac_address($mac) or next;
2686         if ( control_exist_mac($computer_db, $mac) == 0) {
2687            print "Error: Physical MAC address already exists: $mac\n";
2688            next;
2689            }
2690
2691         control_syntax_ip($ip) or next;
2692         if ( control_exist_ip($computer_db, $ip) == 0 ) {
2693            print "Error: IP address already exists: $ip\n";
2694            next;
2695            }
2696         my $timestamp = time;
2697         push @{$computer_db->{$domainset}}, { $mac => {
2698            'hostname'     => $hostname,
2699            'ip'           => $ip,
2700            'address_type' => 'dhcp',
2701            'enabled'      => 'yes',
2702            'create_time'  => $timestamp,
2703            'modify_time'  => $timestamp,
2704            'alias'        =>  '',
2705            }};
2706         }
2707      }
2708   }
2709
2710#-------------------------------------------------------------------------------
2711#Nom: load_data_pool
2712#Description: permet de charger le fichier YAML via les fichiers de conf 'pool' du dhcp.
2713
2714sub load_data_pool {
2715   my ($domainset, $input_file) = @_;
2716
2717   my @T_mac;
2718
2719   open (FILE, "<$input_file");
2720   my @buffer = <FILE>;
2721   close(FILE);
2722
2723   my $computer_db = ipamdb_load($COMPUTER_YAML);
2724
2725   for my $ligne (@buffer) {
2726      #--
2727      $ligne =~ s/#.*$//;
2728      $ligne =~ s/\s+/ /;
2729      $ligne =~ s/^\s+//;
2730      $ligne =~ s/;//g;
2731      $ligne =~ s/"//g;
2732      next if $ligne eq '';
2733
2734      if (($ligne =~ /^subclass/)) {
2735         my @T_split = split(/ / ,$ligne);
2736         my $pool = $T_split[1];
2737
2738         @T_mac = split(/:/ , $T_split[2]);
2739         my $mac = $T_mac[1].":".$T_mac[2].":".$T_mac[3].":".$T_mac[4].":".$T_mac[5].":".$T_mac[6];
2740         control_syntax_mac_address($mac) or next;
2741         if (control_exist_mac($computer_db, $mac) == 0) {
2742            print "Error: Physical MAC address already exists: $mac\n";
2743            next;
2744            }
2745
2746         #--- cette partie teste si le pool existe.
2747         if (not exists $computer_db->{'pool'}{$pool}) {
2748            print "Error: Create pool with create_pool command before load database: $pool\n";
2749            exit;
2750            }
2751
2752         if ($computer_db->{'pool'}{'domain'} eq $domainset) {
2753            my $timestamp = time;
2754            push @{$computer_db->{$domainset}}, { $mac => {
2755               'hostname'     => $pool,
2756               'ip'           => $pool,
2757               'address_type' => 'pool-dhcp',
2758               'enabled'      => 'yes',
2759               'create_time'  => $timestamp,
2760               'modify_time'  => $timestamp,
2761               }};
2762            }
2763         else {
2764            print "Ajout de la machine $mac [FAILED]\n";
2765            print "Error: The pool doesn't exists: $pool, for the domain: $domainset\n";
2766            }
2767         }
2768      }
2769   }
2770
2771#-------------------------------------------------------------------------------
2772
2773sub load_data_file {
2774   my ($domainset, $input_file, $type_file) = @_;
2775
2776   my $computer_db = ipamdb_load($COMPUTER_YAML);
2777
2778   #$computer_db
2779   if ($type_file eq 'dhcp') {
2780      load_data_dhcp($domainset, $input_file);
2781      }
2782
2783   elsif ($type_file eq 'pool-dhcp') {
2784      load_data_pool($domainset, $input_file);
2785      }
2786
2787   ipamdb_save("$COMPUTER_YAML", $computer_db);
2788   }
2789
2790#-------------------------------------------------------------------------------
2791
2792sub cmd_load_database {
2793   local @ARGV = @_;
2794
2795   my $help = get_cmd_name();
2796   my ($domainset, $input_file, $type_file);
2797
2798   GetOptions(
2799      'domainset|d=s'   => \$domainset,
2800      'filename|f=s'    => \$input_file,
2801      'kind|k=s'        => \$type_file,
2802      );
2803
2804   exit_on_error_option($help)
2805      if $domainset  eq ''
2806      or $input_file eq ''
2807      or $type_file  eq '';
2808
2809   load_data_file($domainset, $input_file, $type_file);
2810   }
2811
2812#-------------------------------------------------------------------------------
2813#Nom: backup_database
2814#Description: sauvegarde et réinitialise les fichiers d'enregistrements DHCP.
2815
2816sub backup_database {
2817   my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime time;
2818   $year += 1900;
2819   $mon++;
2820   my $date = sprintf '%04i-%02i-%02i-%02i-%02i-%02i', $year, $mon, $mday, $hour, $min, $sec;
2821
2822   copy($COMPUTER_YAML, "$FOLDER_BACKUP/$COMPUTER_BASENAME-$date.conf") or die "Error: Database copy backup failed: $!\n";
2823   }
2824
2825#-------------------------------------------------------------------------------
2826# HELP section
2827#-------------------------------------------------------------------------------
2828
2829#-------------------------------------------------------------------------------
2830#Nom: exit_on_error_option
2831#Description: messages d'aide des options pour les différentes commandes
2832
2833sub exit_on_error_option {
2834  my ($command) = @_;
2835
2836   if ($command eq 'add-dhcp') {
2837      print "List of options for command: $command\n";
2838      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2839      print " -h : computer hostname (mandatory if option -i != 'pool'). Example: -h info8pc154\n";
2840      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A\n";
2841      print " -i : internet IP address (mandatory). Possible value: classical IP address or the keyword 'pool'\n";
2842      print " -p : name of the DHCP pool to which the machine belongs (mandatory if option -i == 'pool')\n";
2843      print " -c : comment (mandatory). Example: 2014-04-07 DELL Laptop 6400 - Olivier Toto (INFO)\n";
2844      print "Example:\n";
2845      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";
2846      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";
2847      }
2848
2849   elsif ($command eq 'add-float') {
2850      print "List of options for command: $command\n";
2851      print " -d : domain set attachment (mandatory)\n";
2852      print " -p : name of the DHCP pool to which the machine belongs (mandatory)\n";
2853      print " -m : physical MAC address (mandatory)\n";
2854      print " -c : comment (mandatory). Example: 2014-04-07 DELL Laptop 6400 - Olivier Toto (INFO)\n";
2855      print "Example:\n";
2856      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";
2857      }
2858
2859   elsif ($command eq 'add-static') {
2860      print "List of options for command: $command\n";
2861      print " -d : domain set attachment (mandatory)\n";
2862      print " -i : internet IP address (mandatory)\n";
2863      print " -h : computer hostname (mandatory)\n";
2864      print " -m : physical MAC address (mandatory)\n";
2865      print " -c : comment (mandatory). Example: 2014-04-07 DELL Laptop 6400 - Olivier Toto (INFO)\n";
2866      print "Example:\n";
2867      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";
2868      }
2869
2870   elsif ($command eq 'add-virtual') {
2871      print "List of options for command: $command\n";
2872      print " -d : domain set attachment (mandatory)\n";
2873      print " -i : internet IP address (mandatory)\n";
2874      print " -h : computer hostname (mandatory)\n";
2875      print " -c : comment (mandatory). Example: 2014-04-07 DELL Laptop 6400 - Olivier Toto (INFO)\n";
2876      print "Example:\n";
2877      print " ddt add_virtual -h legipc1 -d legi-211 -i 192.168.10.1 -c '2013-09-25 Dell OptiPlex 745 - Eric Goncalves (NRJ)\n";
2878      }
2879
2880   elsif ($command eq 'add-alias') {
2881      print "List of options for command: $command\n";
2882      print " -d : domain set attachment (mandatory)\n";
2883      print " -h : computer hostname (mandatory)\n";
2884      print " -a : computer alias name (mandatory)\n";
2885      }
2886
2887   elsif ($command eq 'create-domainset') {
2888      print "List of options for command: $command\n";
2889      print " -d : new domain set (mandatory)\n";
2890      print " -e : DNS domain name extension( mandatory). Example legi.grenoble-inp.fr\n";
2891      print " -c : comment (mandatory). Example: 2016-08-22 VLAN legi-261 (INFO)\n";
2892      print "Examples:\n";
2893      print " ddt create_domainset -d legi-264 -e legi.grenoble-inp.fr -c '2016-08-22 VLAN legi-261 (INFO)'\n";
2894      }
2895
2896   elsif ($command eq 'create-pool') {
2897      print "List of options for command: $command\n";
2898      print " -p : name of the DHCP pool. Example: pool-legi-priv\n";
2899      print " -d : domain set attachment for the pool. (domain set attachment must exist in file $COMPUTER_BASENAME.conf). Example: legi.grenoble-inp.fr\n";
2900      print " -f : configuration filename on the DHCP server for the pool\n";
2901      print " -i : adresse(s) IP ou plage d'IP. Séparateur d'adresses IP: ','. Séparateur de plage '-'\n";
2902      print "Examples:\n";
2903      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";
2904      print " ddt -p turbocavit -d legi-sector03 -f pool-legi-public -i 192.168.10.1-192.168.10.4\n";
2905      }
2906
2907   elsif ($command eq 'create-pxe') {
2908      print "List of options for command: $command\n";
2909      print " -b : name of the PXE/BOOTP configuration. Example: most\n";
2910      print " -n : internet IP address for the DHCP next-server.\n";
2911      print " -f : filename on TFTP server to load at boot\n";
2912      print " -c : comment (mandatory). Example: 2014-04-07 PXE Boot for CentOS (MOST)\n";
2913      }
2914
2915   elsif ($command eq 'remove-pxe') {
2916      print "List of options for command: $command\n";
2917      print " -b : name of the PXE/BOOTP configuration. Example: most\n";
2918      }
2919
2920   elsif ($command eq 'enable-pxe') {
2921      print "List of options for command: $command\n";
2922      print " -h : computer hostname (mandatory unless option -i)\n";
2923      print " -i : internet IP address (mandatory unless option -h)\n";
2924      print " -d : domain set attachment (mandatory if option -h)\n";
2925      print " -b : name of the PXE/BOOTP configuration. Example: most\n";
2926      }
2927
2928   elsif ($command eq 'disable-pxe') {
2929      print "List of options for command: $command\n";
2930      print " -h : computer hostname (mandatory unless option -i)\n";
2931      print " -i : internet IP address (mandatory unless option -h)\n";
2932      print " -d : domain set attachment (mandatory if option -h)\n";
2933      }
2934
2935   elsif ($command eq 'create-tag') {
2936      print "List of options for command: $command\n";
2937      print " -t : name of the TAG (mandatory). Example: restricted\n";
2938      print " -c : comment (mandatory). Example: 2014-04-07 tag restricted (INFO)\n";
2939      print "tag 'universal' is intrinsic\n";
2940      }
2941
2942   elsif ($command eq 'remove-tag') {
2943      print "List of options for command: $command\n";
2944      print " -b : name of the TAG. Example: restricted\n";
2945      }
2946
2947   elsif ($command eq 'change-mac') {
2948      print "List of options for command: $command\n";
2949      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2950      print " -h : computer hostname (mandatory unless option -i)\n";
2951      print " -i : internet IP address (mandatory unless option -h). Possible value: classical IP address or the keyword 'pool'\n";
2952      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A:22:11\n";
2953      }
2954
2955   elsif ($command eq 'change-ip') {
2956      print "List of options for command: $command\n";
2957      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2958      print " -h : computer hostname (mandatory)\n";
2959      print " -i : new internet IP address (mandatory). Possible value: classical IP address\n";
2960      }
2961
2962   elsif ($command eq 'change-host') {
2963      print "List of options for command: $command\n";
2964      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2965      print " -i : internet IP address (mandatory). Possible value: classical IP address\n";
2966      print " -h : new computer hostname (mandatory)\n";
2967      print "It's not possible to change hostname for computer that belongs to a pool\n";
2968      }
2969
2970   elsif ($command eq 'change-comment') {
2971      print "List of options for command: $command\n";
2972      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2973      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A:22:11\n";
2974      print " -c : new comment (mandatory)\n";
2975      }
2976
2977   elsif ($command eq 'change-domainset') {
2978      print "List of options for command: $command\n";
2979      print " -d : new domain set attachment (mandatory). Example: -d legi-661\n";
2980      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A:22:11\n";
2981      print " -i : internet IP address (mandatory)\n";
2982      }
2983
2984   elsif ($command eq 'change-tag') {
2985      print "List of options for command: $command\n";
2986      print " -h : computer hostname (mandatory unless option -i or -m)\n";
2987      print " -d : domain set attachment (mandatory). Example: -d legi-sector03\n";
2988      print " -i : internet IP address (mandatory unless option -h or -m)\n";
2989      print " -m : physical MAC address (mandatory unless option -h or -i, priority). Example: -m 0F:58:AB:2A:22:11\n";
2990      print " -t : list of tags separated by comma (mandatory). Example: -t internal,windows\n";
2991      }
2992
2993   elsif ($command eq 'load-database') {
2994      print "List of options for command: $command\n";
2995      print " -d : domain set attachment\n";
2996      print " -f : input file in DHCP format\n";
2997      print " -k : possible cases (kind): dhcp, pool-dhcp, fix-address\n";
2998      }
2999
3000   elsif ($command eq 'enable-pc') {
3001      print "List of options for command: $command\n";
3002      print " -h : computer hostname (mandatory unless option -i)\n";
3003      print " -i : internet IP address (mandatory unless option -h)\n";
3004      print " -d : domain set attachment (mandatory if option -h)\n";
3005      print "Examples:\n";
3006      print " ddt enable_pc -i 192.168.10.1\n";
3007      print " ddt enable_pc -d hmg.priv -h kevinpc\n";
3008      }
3009
3010   elsif ($command eq 'enable-float') {
3011      print "List of options for command: $command\n";
3012      print " -m : physical MAC address (mandatory)\n";
3013      print " -p : name of the DHCP pool (mandatory)\n";
3014      }
3015
3016   elsif ($command eq 'disable-float') {
3017      print "List of options for command: $command\n";
3018      print " -m : physical MAC address (mandatory)\n";
3019      print " -p : name of the DHCP pool (mandatory)\n";
3020      }
3021
3022   elsif ($command eq 'disable-pc') {
3023      print "List of options for command: $command\n";
3024      print " -h : computer hostname (mandatory unless option -i)\n";
3025      print " -i : internet IP address (mandatory unless option -h)\n";
3026      print " -d : domain set attachment (mandatory if option -h)\n";
3027      print "Examples:\n";
3028      print " ddt disable_pc -i 192.168.10.1\n";
3029      print " ddt disable_pc -d hmg.priv -h kevinpc\n";
3030      }
3031
3032   elsif ($command eq 'del-pc') {
3033      print "List of options for command: $command\n";
3034      print " -d : domain set attachment (mandatory)\n";
3035      print " -h : computer hostname (mandatory unless option -i)\n";
3036      print " -i : internet IP address (mandatory unless option -h)\n";
3037      }
3038
3039   elsif ($command eq 'del-float') {
3040      print "List of options for command: $command\n";
3041      print " -m : physical MAC address (mandatory)l\n";
3042      print " -p : name of the DHCP pool\n";
3043      }
3044
3045   elsif ($command eq 'search-mac') {
3046      print "List of options for command: $command\n";
3047      print " -m : physical MAC address (mandatory). Example: -m 0F:58:AB:2A:22:11\n";
3048      }
3049
3050   else {
3051      print "No help for command: $command\n";
3052      }
3053   exit;
3054   }
3055
3056#-------------------------------------------------------------------------------
3057
3058sub cmd_version {
3059
3060   print <<'END';
3061ddt - management of computer names and IP addresses
3062Copyright (C) 2006-2018 Gabriel Moreau <Gabriel.Moreau(A)univ-grenoble-alpes.fr>
3063License GNU GPL version 2 or later and Perl equivalent
3064END
3065
3066   print "Version $VERSION\n\n";
3067   print ' $Id: ddt 238 2018-06-22 20:30:05Z g7moreau $'."\n";
3068   return;
3069   }
3070
3071#-------------------------------------------------------------------------------
3072#Nom: usage
3073#Description: message d'aide sur les commandes du script
3074
3075sub cmd_help {
3076   print <<END;
3077ddt - management of computer names and IP addresses
3078
3079 ddt add-alias [--hostname|-h hostname] [--domainset|-d domainset] [--alias|-a alias]
3080 ddt add-dhcp [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3081 ddt add-float [--pool|-p pool] [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3082 ddt add-static [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3083 ddt add-virtual [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--comment|-c comment]
3084 ddt change-comment [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3085 ddt change-domainset [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3086 ddt change-host [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3087 ddt change-ip [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3088 ddt change-mac [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3089 ddt change-tag [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--tag|-t tag]
3090 ddt check-dns
3091 ddt create-domainset [--domainset|-d domainset] [--dns-extension|-e dns_extension] [--comment|-c comment]
3092 ddt create-pool [--pool|-p pool] [--domainset|-d domainset] [--file-pool|-f file_pool] [--ipaddress-pool|-i ipaddress_pool]
3093 ddt create-pxe [--bootp|-b pxe_config] [--next-server|-n next_server] [--filename|-f filename] [--comment|-c comment]
3094 ddt create-tag [--tag|-t tag] [--comment|-c comment]
3095 ddt del-float [--pool|-p pool] [--mac|-m mac]
3096 ddt del-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3097 ddt disable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3098 ddt disable-float [--pool|-p pool] [--mac|-m mac]
3099 ddt disable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3100 ddt enable-float [--pool|-p pool] [--mac|-m mac]
3101 ddt enable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3102 ddt enable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--bootp|-b pxe_config]
3103 ddt gen-dhcp-file
3104 ddt gen-dns-file
3105 ddt help
3106 ddt load-database [--domainset|-d domainset] [--filename|-f filename] [--kind|-k kind]
3107 ddt remove-pxe [--bootp|-b pxe_config]
3108 ddt remove-tag [--tag|-t tag]
3109 ddt search-mac [--mac|-m mac]
3110 ddt show-domainset
3111 ddt show
3112 ddt show-pool [--no-header|-H]
3113 ddt show-pxe [--no-header|-H]
3114 ddt show-tag [--no-header|-H]
3115 ddt version
3116
3117COMMANDS
3118
3119 * add-alias        : add an alias for a computer (like CNAME for the DNS)
3120 * add-dhcp         : add a computer with a fix DHCP IP or in a DHCP pool
3121 * add-float        : add a computer with an IP in a DHCP pool
3122 * add-static       : add a computer with a static IP
3123 * add-virtual      : add a virtual computer with a static IP but a virtual MAC (useful to declare float computer in DNS)
3124 * change-comment   : change the computer comment
3125 * change-domainset : change the domain set attachment for a computer
3126 * change-host      : change the computer hostname
3127 * change-ip        : change the computer IP address
3128 * change-mac       : change the computer physical MAC address
3129 * change-tag       : change the list of TAGs associated to a computer
3130 * check-dns        : check the DNS table for base IPs
3131 * create-domainset : create a new domain set
3132 * create-pool      : create a new pool for DHCP records
3133 * create-pxe       : create a new PXE/BOOTP configuration
3134 * create-tag       : create a new TAG
3135 * del-float        : remove a computer from a DHCP pool
3136 * del-pc           : remove a computer (DHCP or static IP) from the YAML database
3137 * disable-pc       : disable a computer (DHCP and/or DNS) (but keep it in the database)
3138 * disable-float    : disable a computer from a DHCP pool (but keep it in the database)
3139 * disable-pxe      : remove PXE/BOOTP configuration on a computer
3140 * enable-float     : enable a previous disable computer (DHCP and/or DNS)
3141 * enable-pc        : enable a previous disable computer (DHCP and/or DNS)
3142 * enable-pxe       : enable PXE/BOOTP configuration on a computer
3143 * gen-dhcp-file    : generate DHCP files for the isc DHCP server
3144 * gen-dns-file     : generate DNS files for the bind domain server
3145 * help             : this help
3146 * load-database    : load the YAML database (be careful)
3147 * remove-pxe       : remove a PXE/BOOTP configuration
3148 * remove-tag       : remove a TAG
3149 * search-mac       : search physical MAC address computer
3150 * show-domainset   : list all domain set group of computer
3151 * show             : list all computers
3152 * show-pool        : list all pool
3153 * show-pxe         : list PXE/BOOTP configuration
3154 * show-tag         : list all TAGs
3155 * version          : return program version
3156END
3157   return;
3158   }
3159
3160################################################################
3161# documentation
3162################################################################
3163
3164__END__
3165
3166=head1 NAME
3167
3168ddt - management of computer names and IP addresses
3169
3170
3171=head1 USAGE
3172
3173 ddt add-alias [--hostname|-h hostname] [--domainset|-d domainset] [--alias|-a alias]
3174 ddt add-dhcp [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3175 ddt add-float [--pool|-p pool] [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3176 ddt add-static [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3177 ddt add-virtual [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--comment|-c comment]
3178 ddt change-comment [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3179 ddt change-domainset [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3180 ddt change-host [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3181 ddt change-ip [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3182 ddt change-mac [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3183 ddt change-tag [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--tag|-t tag]
3184 ddt check-dns
3185 ddt create-domainset [--domainset|-d domainset] [--dns-extension|-e dns_extension] [--comment|-c comment]
3186 ddt create-pool [--pool|-p pool] [--domainset|-d domainset] [--file-pool|-f file_pool] [--ipaddress-pool|-i ipaddress_pool]
3187 ddt create-pxe [--bootp|-b pxe_config] [--next-server|-n next_server] [--filename|-f filename] [--comment|-c comment]
3188 ddt create-tag [--tag|-t tag] [--comment|-c comment]
3189 ddt del-float [--pool|-p pool] [--mac|-m mac]
3190 ddt del-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3191 ddt disable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3192 ddt disable-float [--pool|-p pool] [--mac|-m mac]
3193 ddt disable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3194 ddt enable-float [--pool|-p pool] [--mac|-m mac]
3195 ddt enable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3196 ddt enable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--bootp|-b pxe_config]
3197 ddt gen-dhcp-file
3198 ddt gen-dns-file
3199 ddt help
3200 ddt load-database [--domainset|-d domainset] [--filename|-f filename] [--kind|-k kind]
3201 ddt remove-pxe [--bootp|-b pxe_config]
3202 ddt remove-tag [--tag|-t tag]
3203 ddt search-mac [--mac|-m mac]
3204 ddt show-domainset
3205 ddt show
3206 ddt show-pool [--no-header|-H]
3207 ddt show-pxe [--no-header|-H]
3208 ddt show-tag [--no-header|-H]
3209 ddt version
3210
3211
3212=head1 DESCRIPTION
3213
3214DDT is an acronym for DHCP-DNS-Tools.
3215The previous command name was not C<ddt> but just C<dhcp-dns-tools>...
3216In practise, DDT is an IP Address Management (IPAM) service.
3217It has been used in the LEGI laboratory for over 10 years.
3218
3219The tool is quite effective and tries to keep things simple
3220but easily configurable for your site like a swiss army knife.
3221Everything is saved in a YAML database
3222and entries could be added, deleted, or modified by the command line.
3223
3224
3225=head1 COMMANDS
3226
3227=head2 add-alias
3228
3229 ddt add-alias [--hostname|-h hostname] [--domainset|-d domainset] [--alias|-a alias]
3230
3231=head2 add-dhcp
3232
3233 ddt add-dhcp [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3234
3235=head2 add-float
3236
3237 ddt add-float [--pool|-p pool] [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3238
3239=head2 add-static
3240
3241 ddt add-static [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--comment|-c comment]
3242
3243=head2 add-virtual
3244
3245 ddt add-virtual [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--comment|-c comment]
3246
3247=head2 change-comment
3248
3249 ddt change-comment [--domainset|-d domainset] [--mac|-m mac] [--comment|-c comment]
3250
3251=head2 change-domainset
3252
3253 ddt change-domainset [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3254
3255=head2 change-host
3256
3257 ddt change-host [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3258
3259=head2 change-ip
3260
3261 ddt change-ip [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3262
3263=head2 change-mac
3264
3265 ddt change-mac [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac]
3266
3267=head2 change-tag
3268
3269 ddt change-tag [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--mac|-m mac] [--tag|-t tag]
3270
3271=head2 check-dns
3272
3273 ddt check-dns
3274
3275=head2 create-domainset
3276
3277 ddt create-domainset [--domainset|-d domainset] [--dns-extension|-e dns_extension] [--comment|-c comment]
3278
3279=head2 create-pool
3280
3281 ddt create-pool [--pool|-p pool] [--domainset|-d domainset] [--file-pool|-f file_pool] [--ipaddress-pool|-i ipaddress_pool]
3282
3283=head2 create-pxe
3284
3285 ddt create-pxe [--bootp|-b pxe_config] [--next-server|-n next_server] [--filename|-f filename] [--comment|-c comment]
3286
3287=head2 create-tag
3288
3289 ddt create-tag [--tag|-t tag] [--comment|-c comment]
3290
3291=head2 del-float
3292
3293 ddt del-float [--pool|-p pool] [--mac|-m mac]
3294
3295=head2 del-pc
3296
3297 ddt del-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3298
3299=head2 disable-pc
3300
3301 ddt disable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3302
3303=head2 disable-float
3304
3305 ddt disable-float [--pool|-p pool] [--mac|-m mac]
3306
3307=head2 disable-pxe
3308
3309 ddt disable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3310
3311=head2 enable-float
3312
3313 ddt enable-float [--pool|-p pool] [--mac|-m mac]
3314
3315=head2 enable-pc
3316
3317 ddt enable-pc [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip]
3318
3319=head2 enable-pxe
3320
3321 ddt enable-pxe [--hostname|-h hostname] [--domainset|-d domainset] [--ip|-i ip] [--bootp|-b pxe_config]
3322
3323=head2 gen-dhcp-file
3324
3325 ddt gen-dhcp-file
3326
3327=head2 gen-dns-file
3328
3329 ddt gen-dns-file
3330
3331=head2 help
3332
3333 ddt help
3334
3335=head2 load-database
3336
3337 ddt load-database [--domainset|-d domainset] [--filename|-f filename] [--kind|-k kind]
3338
3339=head2 remove-pxe
3340
3341 ddt remove-pxe [--bootp|-b pxe_config]
3342
3343=head2 remove-tag
3344
3345 ddt remove-tag [--tag|-t tag]
3346
3347=head2 search-mac
3348
3349 ddt search-mac [--mac|-m mac]
3350
3351=head2 show-domainset
3352
3353 ddt show-domainset
3354
3355=head2 show
3356
3357 ddt show
3358
3359=head2 show-pool
3360
3361 ddt show-pool [--no-header|-H]
3362
3363=head2 show-pxe
3364
3365 ddt show-pxe [--no-header|-H]
3366
3367=head2 show-tag
3368
3369 ddt show-tag [--no-header|-H]
3370
3371=head2 version
3372
3373 ddt version
3374
3375
3376=head1 AUTHORS
3377
3378Written by Gabriel Moreau, Kevin Reverchon, Olivier De-Marchi - Grenoble - France
3379
3380
3381=head1 LICENSE AND COPYRIGHT
3382
3383Licence GNU GPL version 2 or later and Perl equivalent
3384
3385Copyright (C) 2006-2018 Gabriel Moreau <Gabriel.Moreau(A)univ-grenoble-alpes.fr>.
Note: See TracBrowser for help on using the repository browser.