source: trunk/ddt/ddt @ 237

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