source: trunk/ddt/ddt @ 221

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