source: trunk/ddt/ddt @ 227

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