pf-tools/pf-tools: 45 new changesets

parmelan-guest at users.alioth.debian.org parmelan-guest at users.alioth.debian.org
Fri Nov 12 12:41:31 UTC 2010


details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/0ffded9c633b
changeset: 947:0ffded9c633b
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Mon Nov 08 10:29:32 2010 +0100
description:
Style + more tests on vlan tags

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/b9e3ceeafe84
changeset: 948:b9e3ceeafe84
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Mon Nov 08 14:29:25 2010 +0100
description:
PFTools::Conf::Network: style

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/e028e720f696
changeset: 949:e028e720f696
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Nov 09 17:54:12 2010 +0100
description:
Extend the test configuration

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/cf561310bb22
changeset: 950:cf561310bb22
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Nov 09 17:56:33 2010 +0100
description:
perltidy

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/618b17e739e1
changeset: 951:618b17e739e1
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Wed Nov 10 18:14:49 2010 +0100
description:
Style

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/5b594674a685
changeset: 952:5b594674a685
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Wed Nov 10 18:28:57 2010 +0100
description:
Style __build_host_list()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/e2e006320089
changeset: 953:e2e006320089
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Wed Nov 10 23:28:46 2010 +0100
description:
Style __get_hostnum_from_model()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/7d2c8e9069a4
changeset: 954:7d2c8e9069a4
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Wed Nov 10 23:37:59 2010 +0100
description:
Style __get_hostname_from_model()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/bdc3aecedbfd
changeset: 955:bdc3aecedbfd
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Wed Nov 10 23:45:54 2010 +0100
description:
__add_deployment_on_host_entry(): style

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/a4981e93a2d7
changeset: 956:a4981e93a2d7
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 14:58:14 2010 +0100
description:
__add_boot_on_host_entry() + s/$site_part/$site_part_ref/

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/92e2e628cf23
changeset: 957:92e2e628cf23
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 14:58:45 2010 +0100
description:
perltidy

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/c1e89929e83d
changeset: 958:c1e89929e83d
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 15:16:36 2010 +0100
description:
*_part -> *_part_ref + comments

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/68f966f58cd3
changeset: 959:68f966f58cd3
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 15:24:28 2010 +0100
description:
__add_deployment_on_host_entry(): style + comments

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/f5d7669759f1
changeset: 960:f5d7669759f1
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 15:59:49 2010 +0100
description:
__add_zone_entry(): style

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/ad583a3f48fe
changeset: 961:ad583a3f48fe
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 16:13:04 2010 +0100
description:
__add_dhcp_entry(): style

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/5b5056894693
changeset: 962:5b5056894693
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 17:26:42 2010 +0100
description:
__build_iface_entry(), formerly known as __Add_host_interface()

* too many arguments => use named arguments
* new functions __build_route_destination() and __build_route_gateway() to make
  __build_iface_entry() more readable
* style

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/244027cad4c8
changeset: 963:244027cad4c8
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 17:35:08 2010 +0100
description:
__build_route_gateway(): use named arguments

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/f6357c83adf4
changeset: 964:f6357c83adf4
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 17:46:16 2010 +0100
description:
__build_host_from_server(): style + comments

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/6adc7248ecca
changeset: 965:6adc7248ecca
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 17:50:41 2010 +0100
description:
__get_vlan_tag_from_site()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/b7143471d596
changeset: 966:b7143471d596
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 17:52:23 2010 +0100
description:
Remove unused function: __Get_alias_list_from_server()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/1c274e9a3671
changeset: 967:1c274e9a3671
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 17:53:21 2010 +0100
description:
Remove unused function: __Get_vlan_list_from_server()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/df31aff3407e
changeset: 968:df31aff3407e
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 19:18:53 2010 +0100
description:
__Check_host_ip() -> __get_host_ip()

* named arguments
* documentation
* style

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/fe274200bb29
changeset: 969:fe274200bb29
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 23:11:10 2010 +0100
description:
__get_host_interfaces() style and comments

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/5c7275ace592
changeset: 970:5c7275ace592
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 23:30:27 2010 +0100
description:
__get_host_indexes()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/0604127b9477
changeset: 971:0604127b9477
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Nov 11 23:43:04 2010 +0100
description:
add_host(): named parameters

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/307938983007
changeset: 972:307938983007
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 00:02:24 2010 +0100
description:
add_host

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/83edba523a94
changeset: 973:83edba523a94
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 00:06:56 2010 +0100
description:
Two files forgotten in changeset e028e720f696

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/1cecd2438bba
changeset: 974:1cecd2438bba
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 00:16:16 2010 +0100
description:
get_site_from_hostname()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/6c0c9194af89
changeset: 975:6c0c9194af89
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 00:17:42 2010 +0100
description:
perltidy

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/83da626c83f6
changeset: 976:83da626c83f6
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 00:23:00 2010 +0100
description:
Rename get_site_from_hostname() -> get_site_list_from_hostname()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/5aeea255b83f
changeset: 977:5aeea255b83f
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 00:28:40 2010 +0100
description:
get_uniq_site_from_hostname()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/fb64f8eb5a84
changeset: 978:fb64f8eb5a84
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 00:32:18 2010 +0100
description:
get_zone_from_hostname()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/c3d1d514d19c
changeset: 979:c3d1d514d19c
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 00:36:39 2010 +0100
description:
get_hosttype_from_hostname()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/0d6292eb411d
changeset: 980:0d6292eb411d
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 00:40:26 2010 +0100
description:
get_iface_vlan_from_hostname()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/36bc16856d39
changeset: 981:36bc16856d39
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 00:41:51 2010 +0100
description:
Remove unused function: Get_hostname_model_from_hostname()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/117b9c9607bf
changeset: 982:117b9c9607bf
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 00:45:36 2010 +0100
description:
get_zone_from_site()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/84e154be6af7
changeset: 983:84e154be6af7
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 00:56:04 2010 +0100
description:
get_host_config()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/3c18117551db
changeset: 984:3c18117551db
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 01:02:06 2010 +0100
description:
get_vlan_config

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/694bc5bd39fc
changeset: 985:694bc5bd39fc
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 01:21:06 2010 +0100
description:
get_pkgtype_from_hostname() and get_cmdline()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/e5d85d57638d
changeset: 986:e5d85d57638d
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 01:26:05 2010 +0100
description:
get_cmdline_from_host_ref(), get_distrib_from_host_ref()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/472ecb3f144e
changeset: 987:472ecb3f144e
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 01:27:40 2010 +0100
description:
get_mode_from_host_ref()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/5ee7da1692b4
changeset: 988:5ee7da1692b4
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 02:01:22 2010 +0100
description:
resolve_hostname_from_global_config()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/0a34dca9bb3d
changeset: 989:0a34dca9bb3d
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 02:29:34 2010 +0100
description:
Add tests for resolve_hostname_from_global_config()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/a60ea5615e05
changeset: 990:a60ea5615e05
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 12:07:38 2010 +0100
description:
resolve_hostname_from_global_config(): use named arguments + documentation

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/e756fd4d6365
changeset: 991:e756fd4d6365
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Fri Nov 12 13:36:18 2010 +0100
description:
get_vlan_config_from_CONFIG() was renamed to get_vlan_config(), really

diffstat:

9 files changed, 59 insertions(+), 34 deletions(-)
filters/filter_privateresolve                                          |    2 
lib/PFTools/Conf.pm                                                    |    2 
lib/PFTools/Conf/Network.pm                                            |    5 -
lib/PFTools/Structqueries.pm                                           |   44 +++++-----
lib/PFTools/Update/ADDMOUNT.pm                                         |    6 -
t/13.conf.cfg1/config-export/MODEL/model-rdeploy                       |   18 ++++
t/13.conf.cfg1/config-export/SITE/cbv4-pfds/CONFIG/hostfile-cbv4-spawn |    2 
t/13.conf.cfg1/config-export/SITE/cbv4/CONFIG/hostfile-cbv4-rdeploy    |   12 ++
t/13.conf.t                                                            |    2 

diffs (4373 lines):

diff -r d6a9b9a18fdc -r e756fd4d6365 filters/filter_distrib
--- a/filters/filter_distrib	Sun Nov 07 18:29:34 2010 +0100
+++ b/filters/filter_distrib	Fri Nov 12 13:36:18 2010 +0100
@@ -90,7 +90,7 @@
 
 unless( $options->{'site'} ) {
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
-        || Get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
+        || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
 }
 
 if ( $options->{'input'} eq '' || $options->{'output'} eq '' ) {
diff -r d6a9b9a18fdc -r e756fd4d6365 filters/filter_privateresolve
--- a/filters/filter_privateresolve	Sun Nov 07 18:29:34 2010 +0100
+++ b/filters/filter_privateresolve	Fri Nov 12 13:36:18 2010 +0100
@@ -106,12 +106,13 @@
 
 unless ( $options->{'site'} ) {
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
-        || Get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
+        || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
 }
 
-$options->{'zone'} = Get_zone_from_site_GLOBAL(
-    $options->{'site'}, $GLOBAL_STRUCT
-) unless $options->{'zone'};
+unless ( $options->{'zone'} ) {
+    $options->{'zone'}
+        = get_zone_from_site( $options->{'site'}, $GLOBAL_STRUCT );
+}
 
 my $filtered_src = Search_and_replace(
     $options->{'host'},
diff -r d6a9b9a18fdc -r e756fd4d6365 filters/filter_vlan2if
--- a/filters/filter_vlan2if	Sun Nov 07 18:29:34 2010 +0100
+++ b/filters/filter_vlan2if	Fri Nov 12 13:36:18 2010 +0100
@@ -95,7 +95,7 @@
 
 unless( $options->{'site'} ) {
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
-        || Get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
+        || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
 }
 
 if ( $options->{'input'} eq '' || $options->{'output'} eq '' ) {
diff -r d6a9b9a18fdc -r e756fd4d6365 lib/PFTools/Conf.pm
--- a/lib/PFTools/Conf.pm	Sun Nov 07 18:29:34 2010 +0100
+++ b/lib/PFTools/Conf.pm	Fri Nov 12 13:36:18 2010 +0100
@@ -509,9 +509,9 @@
         @{ $net_parsed->{'__sections_order'} };
 
     my %add_function_for = (
-        q{zone}    => sub { Add_zone(@_); },
-        q{site}    => sub { Add_site(@_); },
-        q{network} => sub { Add_network(@_); },
+        q{zone}    => sub { add_zone(@_); },
+        q{site}    => sub { add_site(@_); },
+        q{network} => sub { add_network(@_); },
         q{server}  => sub { add_server(@_); },
         q{service} => sub { __add_service(@_); },
     );
@@ -645,10 +645,7 @@
         $pf_config
     );
     my $hosttype
-        = Get_hosttype_from_hostname( $hostname, $global_config, $site );
-    unless ($hosttype) {
-        croak qq{Unable to get hosttype from hostname $hostname};
-    }
+        = get_hosttype_from_hostname( $hostname, $global_config, $site );
 
     # Hosttype configuration file e.g. update-<hosttype>
     my $hosttype_file = __get_config_path( $hosttype, $pf_config, $site );
@@ -909,7 +906,7 @@
         qw( start_file section_name section_ref global_config pf_config hash_subst )
         };
 
-    my $site_list = Get_site_list( $section_ref, $global_config );
+    my $site_list = get_site_list_from_section( $section_ref, $global_config );
     foreach my $site ( @{$site_list} ) {
         my $service_part
             = $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'SERVICE'}
@@ -920,8 +917,13 @@
             my $host_parsed
                 = Load_conf( $hostfile, $hash_subst, q{host}, $pf_config );
             add_host(
-                $hostfile, q{host}, $host_parsed, $global_config,
-                $pf_config
+                {
+                    start_file    => $hostfile,
+                    host_type     => q{host},
+                    host_ref      => $host_parsed,
+                    global_config => $global_config,
+                    pf_config     => $pf_config,
+                }
             );
             push @{ $service_part->{$section_name} }, $host;
         }
@@ -964,7 +966,7 @@
         # Run the real checks
         check_section_structure(
             $section, $section_type, $parsed->{$section},
-            $context
+            $context, $file
         );
     }
 
diff -r d6a9b9a18fdc -r e756fd4d6365 lib/PFTools/Conf/Host.pm
--- a/lib/PFTools/Conf/Host.pm	Sun Nov 07 18:29:34 2010 +0100
+++ b/lib/PFTools/Conf/Host.pm	Fri Nov 12 13:36:18 2010 +0100
@@ -25,7 +25,7 @@
 use Carp;
 use English qw( -no_match_vars );    # Avoids regex performance penalty
 use Fcntl ':mode';
-use List::MoreUtils qw( any uniq );
+use List::MoreUtils qw( any );
 use POSIX qw(ceil floor);
 
 use PFTools::Conf::Syntax qw( $DEF_SECTIONS );
@@ -39,178 +39,238 @@
 
 our @EXPORT_OK = qw();
 
+=head2 add_host($args)
 
-#########################################################################
-#
-# VOID add_host ( STR, HASHREF, HASHREF, HASHREF )
-#
-# This function adds host into global configuration, zone informations
-# and dhcp entries if needed
-# Inputs :
-#  - $hostfile		: filename where host is parsed
-#  - $host2add		: hashref where are stored host definitions according to hostfile-syntax
-#  - $global_config	: hashref where are stored global configuration datas
-#  - $pf_config		: hashref where are stored pf-tools configuration datas
-#
+This function adds a host to the global configuration. $args is a reference to
+a hash containing the following named parameters:
+
+=over
+
+=item I<start_file>
+
+Filename containing the host definition
+
+=item I<section_name>
+
+The host name
+
+=item I<section_ref>
+
+Reference to a hash containing the parsed host
+
+=item I<global_config>
+
+Reference to the global configuration hash (the host will be added in this hash)
+
+=item I<pf_config>
+
+Reference to the pf-tools configuration hash
+
+=back
+
+=cut
+
 sub add_host {
-    my ( $hostfile, $type, $host2add, $global_config, $pf_config ) = @_;
+    my ($arguments_ref) = @_;
 
-    my $boot_def       = $DEF_SECTIONS->{'host'}->{'boot'};
-    my $dep_def        = $DEF_SECTIONS->{'host'}->{'deployment'};
-    my $hostname_model = $host2add->{'hostgroup'}->{'hostname'};
-    $hostname_model
-        =~ m{ \A $pf_config->{'regex'}->{'hostname_model'} \z }xms;
-    my $shortname = $+{HOSTTYPE};
-    my $hostclass = $host2add->{'hostgroup'}->{'hosttype'} || $shortname;
-    my $site_list = Get_site_list( $host2add->{'hostgroup'}, $global_config );
-    my $pf_tftp_dir = $pf_config->{'path'}->{'tftp_dir'};
-    $pf_tftp_dir .= '/' if $pf_tftp_dir !~ m{ [/] \z }xms;
+    my ($start_file, $host_type, $host_ref,
+        $global_config, $pf_config
+        )
+        = @$arguments_ref{
+        qw( start_file host_type host_ref
+            global_config pf_config )
+        };
+
+    my $boot_def = $DEF_SECTIONS->{'host'}->{'boot'};
+    my $dep_def  = $DEF_SECTIONS->{'host'}->{'deployment'};
+
+    my $hostname_model = $host_ref->{'hostgroup'}->{'hostname'};
+    unless (
+        $hostname_model
+        =~ m{ \A $pf_config->{'regex'}->{'hostname_model'} \z }xms
+        )
+    {
+        croak qq{Invalid hostname model name $hostname_model};
+    }
+    my $shortname = $LAST_PAREN_MATCH{'HOSTTYPE'};
+    my $hostclass = $host_ref->{'hostgroup'}->{'hosttype'} || $shortname;
+
     my ( $host_last, $node_last )
-        = __Get_host_indexes( $host2add->{'hostgroup'}, $hostname_model );
+        = __get_host_indexes( $host_ref->{'hostgroup'}, $hostname_model );
 
+    my $site_list = get_site_list_from_section(
+        $host_ref->{'hostgroup'},
+        $global_config
+    );
     foreach my $site ( @{$site_list} ) {
-        my $site_part = $global_config->{'SITE'}->{'BY_NAME'}->{$site};
-        unless ( $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} ) {
-            $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} = {};
-            push(
-                @{ $site_part->{'HOST'}->{'__hostclass_pxe'} },
-                $hostclass
-            ) if ( $type eq 'host' );
+        my $site_part_ref = $global_config->{'SITE'}->{'BY_NAME'}->{$site};
+
+        unless ( $site_part_ref->{'HOST'}->{'BY_NAME'}->{$hostclass} ) {
+            $site_part_ref->{'HOST'}->{'BY_NAME'}->{$hostclass} = {};
+            if ( $host_type eq 'host' ) {
+                push @{ $site_part_ref->{'HOST'}->{'__hostclass_pxe'} },
+                    $hostclass;
+            }
         }
-        my $host_part = $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass};
-        my $zone      = $site_part->{'zone'};
-        my $prefix    = __Get_site_prefix( $site, $site_part );
-        my $host_list = __Build_hostlist(
+
+        my $host_part_ref
+            = $site_part_ref->{'HOST'}->{'BY_NAME'}->{$hostclass};
+        my $zone      = $site_part_ref->{'zone'};
+        my $prefix    = __get_site_prefix( $site, $site_part_ref );
+        my $host_list = __build_host_list(
             {
-                'host_last'      => $host_last,
-                'node_last'      => $node_last,
-                'host_part'      => $host_part,
+                'last_hostnum'   => $host_last,
+                'last_hostnode'  => $node_last,
+                'host_part_ref'  => $host_part_ref,
                 'hostname_model' => $hostname_model,
                 'prefix'         => $prefix,
             }
         );
+
         foreach my $hostname ( sort keys %{$host_list} ) {
             my $host_number = $host_list->{$hostname}->{'host_number'};
             my $index       = $host_list->{$hostname}->{'index'};
             my $hostnum     = $host_list->{$hostname}->{'hostnum'};
             my $hostnode    = $host_list->{$hostname}->{'hostnode'} || 0;
             my $dhcpvlan =
-                $host2add->{'deployment'}->{"dhcpvlan\.$host_number"}
-                || $host2add->{'deployment'}->{'dhcpvlan'}
-                || $site_part->{'dhcpvlan'};
+                $host_ref->{'deployment'}->{"dhcpvlan\.$host_number"}
+                || $host_ref->{'deployment'}->{'dhcpvlan'}
+                || $site_part_ref->{'dhcpvlan'};
 
-            unless ( $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan} ) {
+            unless ( $site_part_ref->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan} ) {
                 croak qq{ERROR: Unknown DHCP vlan $dhcpvlan for $hostname};
             }
-            $host_part->{$hostname}->{'deployment'} =
-                __Add_deployment_on_host_entry(
-                $type, $host2add, $hostclass, $host_number, $dhcpvlan
+
+            $host_part_ref->{$hostname}->{'deployment'}
+                = __build_deployment_entry_for_host(
+                $host_type, $host_ref, $hostclass,
+                $host_number, $dhcpvlan
                 );
-            if ( $type eq 'host' ) {
-                $host_part->{$hostname}->{'boot'} = __Add_boot_on_host_entry(
-                    $host2add, $host_number, $site_part, $pf_config,
-                );
-                $host_part->{$hostname}->{'dns'}->{'resolver'} =
-                    $host2add->{'dns'}->{"resolver\.$host_number"}
-                    || $host2add->{'dns'}->{'resolver'};
+
+            if ( $host_type eq 'host' ) {
+                $host_part_ref->{$hostname}->{'boot'}
+                    = __build_boot_entry_for_host(
+                    $host_ref, $host_number,
+                    $hostname, $site_part_ref, $pf_config,
+                    );
+                $host_part_ref->{$hostname}->{'dns'}->{'resolver'}
+                    = $host_ref->{'dns'}->{"resolver\.$host_number"}
+                    || $host_ref->{'dns'}->{'resolver'};
             }
 
             # Check interfaces
-            my @if_list = __Get_host_interfaces($host2add);
+            my @if_list = __get_host_interfaces($host_ref);
             foreach my $iface (@if_list) {
-                my $if2add = __Add_host_interface(
-                    $iface, $hostname, $hostnum, $hostnode,
-                    $host_number, $host2add, \@if_list, $site,
-                    $site_part, $pf_config
+                my $new_iface_ref = __build_iface_entry(
+                    {
+                        iface_name     => $iface,
+                        hostname       => $hostname,
+                        hostnum        => $hostnum,
+                        hostnode       => $hostnode,
+                        host_ref       => $host_ref,
+                        iface_list_ref => \@if_list,
+                        site_name      => $site,
+                        site_ref       => $site_part_ref,
+                        pf_config      => $pf_config,
+                    }
                 );
+
                 my $iface_name = $iface;
-                if ($iface =~ m{\A
-                                    (
-                                        (eth|bond)[\d]+)
-                                        (\.(TAG[\d]+)
-                                    )
-                        
-                                \z}xms
+                if ($iface =~ m{
+                        \A
+                            (
+                                (eth|bond)[\d]+)
+                                (\.(TAG[\d]+)
+                            )
+                
+                        \z
+                    }xms
                     )
                 {
-                    $iface_name =
-                        $1 . '.'
-                        . __Get_vlan_tag_from_site(
-                        $if2add->{'vlan'}, $site_part
-                        );
+                    my $name = $1;
+                    my $tag  = __get_vlan_tag_from_site( $new_iface_ref->{'vlan'},
+                        $site_part_ref );
+                    $iface_name = qq{$name.$tag};
                 }
 
                 # Adding interface and IPs into site's zone
-                $host_part->{$hostname}->{'interfaces'} = {}
-                    if ( !defined $host_part->{$hostname}->{'interfaces'} );
-                $host_part->{$hostname}->{'interfaces'}->{$iface_name}
-                    = $if2add;
-                $site_part->{'HOST'}->{'BY_MAC'}->{ $if2add->{'mac'} }
-                    = $iface . '.' . $hostname . '.' . $if2add->{'vlan'}
-                    if ( $if2add->{'mac'} );
-                if ($if2add->{'vlan'} eq $dhcpvlan
-                    && $type eq 'host'
-                    && !defined $if2add->{'mac'}
+                $host_part_ref->{$hostname}->{'interfaces'}->{$iface_name}
+                    = $new_iface_ref;
+                if ( $new_iface_ref->{'mac'} ) {
+                    $site_part_ref->{'HOST'}->{'BY_MAC'}
+                        ->{ $new_iface_ref->{'mac'} }
+                        = qq($iface.$hostname.$new_iface_ref->{'vlan'});
+                }
+
+                if ($new_iface_ref->{'vlan'} eq $dhcpvlan
+                        and $host_type eq 'host'
+                        and not $new_iface_ref->{'mac'}
                     )
                 {
-                    croak qq{ERROR: MAC MUST BE defined for DHCP on $iface};
+                    croak qq{ERROR: $hostname: MAC address is mandatory on $iface for DHCP};
                 }
+
                 foreach my $ip_type ( 'ipv4', 'ipv6' ) {
-                    next if ( !$pf_config->{'features'}->{$ip_type} );
-                    my $suffix   = ( $ip_type eq 'ipv6' ) ? '6' : '';
-                    my $addr_key = "BY_ADDR" . $suffix;
-                    my $zone_key = "ZONE" . $suffix;
-                    my $dhcp_key = "DHCP" . $suffix;
-                    my $zone_ip  = $if2add->{$ip_type};
-                    $zone_ip =~ s{ [/] .+ \z }{}xms;
-                    my $zone_part
+                    next unless $pf_config->{'features'}->{$ip_type};
+
+                    my $ip_type_suffix = $ip_type eq 'ipv6' ? '6' : '';
+                    my $addr_key = qq{BY_ADDR$ip_type_suffix};
+                    my $zone_key = qq{ZONE$ip_type_suffix};
+                    my $dhcp_key = qq{DHCP$ip_type_suffix};
+
+                    my $zone_part_ref
                         = $global_config->{$zone_key}->{'BY_NAME'}
                         ->{$zone}->{'BY_SITE'}->{$site};
-                    my $dhcp_part
+                    my $dhcp_part_ref
                         = $global_config->{$dhcp_key}->{'BY_SITE'}
                         ->{$site};
-                    $site_part->{'HOST'}->{$addr_key}->{ $if2add->{$ip_type} }
-                        = $hostname . '.' . $if2add->{'vlan'};
-                    __Add_zone_entry(
+                    $site_part_ref->{'HOST'}->{$addr_key}
+                        ->{ $new_iface_ref->{$ip_type} }
+                        = qq/$hostname.$new_iface_ref->{'vlan'}/;
+
+                    __add_zone_entry(
                         {
                             'hostname'      => $hostname,
                             'hostclass'     => $hostclass,
-                            'host_part'     => $host_part,
+                            'host_part_ref' => $host_part_ref,
                             'host_number'   => $host_number,
-                            'iface_def'     => $if2add,
+                            'iface_def'     => $new_iface_ref,
                             'zone_name'     => $zone,
-                            'zone_part'     => $zone_part,
+                            'zone_part_ref' => $zone_part_ref,
                             'ip_type'       => $ip_type,
                             'shortname'     => $shortname,
                             'site'          => $site,
-                            'dns_def'       => $host2add->{'dns'},
+                            'dns_def_ref'   => $host_ref->{'dns'},
                             'index'         => $index,
                             'global_config' => $global_config,
                         }
                     );
+
                     my $resolver =
-                        $host2add->{'dns'}->{"resolver\.$host_number"}
-                        || $host2add->{'dns'}->{'resolver'};
-                    __Add_dhcp_entry(
-                        {
-                            'dhcp_part' => $dhcp_part,
-                            'dhcpvlan'  => $dhcpvlan,
-                            'vlan_def' =>
-                                $site_part->{'NETWORK'}->{'BY_NAME'}
-                                ->{$dhcpvlan},
-                            'iface_def' => $if2add,
-                            'resolver'  => $resolver,
-                            'hostname'  => $hostname,
-                            'hostclass' => $hostclass,
-                            'ip_type'   => $ip_type,
-                            'pxefilename' =>
-                                $host2add->{'boot'}->{'pxefilename'},
-                        }
+                        $host_ref->{'dns'}->{"resolver.$host_number"}
+                        || $host_ref->{'dns'}->{'resolver'};
+
+                    if ($new_iface_ref->{'vlan'} eq $dhcpvlan
+                        and $host_type eq 'host'
                         )
-                        if (
-                        $if2add->{'vlan'} eq $dhcpvlan
-                        && $type eq 'host'
-                        );
+                    {
+                        __add_dhcp_entry(
+                            {
+                                'dhcp_part_ref' => $dhcp_part_ref,
+                                'dhcp_vlan'     => $dhcpvlan,
+                                'vlan_def_ref' =>
+                                    $site_part_ref->{'NETWORK'}->{'BY_NAME'}
+                                    ->{$dhcpvlan},
+                                'iface_def_ref' => $new_iface_ref,
+                                'resolver'      => $resolver,
+                                'hostname'      => $hostname,
+                                'hostclass'     => $hostclass,
+                                'ip_type'       => $ip_type,
+                                'pxefilename' =>
+                                    $host_ref->{'boot'}->{'pxefilename'},
+                            }
+                            )
+                    }
                 }
             }
         }
@@ -219,10 +279,11 @@
     return;
 }
 
-=head2 add_server($args)
+=head2 add_server($arguments_ref)
 
 Build a host definition from a server definition, then call C<add_host()>.
-I<$args> is a reference to a hash containing the following named parameters :
+I<$arguments_ref> is a reference to a hash containing the following named
+parameters :
 
 =over
 
@@ -251,108 +312,123 @@
 =cut
 
 sub add_server {
-    my ($args) = @_;
+    my ($arguments_ref) = @_;
 
     my ($start_file, $section_name, $section_ref,
         $global_config, $pf_config
         )
-        = @$args{
+        = @$arguments_ref{
         qw( start_file section_name section_ref global_config pf_config )
         };
 
-    my $host = __build_host_from_server( $section_name, $section_ref );
+    my $host_ref = __build_host_from_server( $section_name, $section_ref );
 
-    return add_host(
-        $start_file, q{server}, $host, $global_config,
-        $pf_config
-    );
+    my $add_host_args_ref = {
+        start_file    => $start_file,
+        host_type     => q{server},
+        host_ref      => $host_ref,
+        global_config => $global_config,
+        pf_config     => $pf_config,
+    };
+
+    return add_host( $add_host_args_ref );
 }
 
+=head2 __get_site_prefix ( $site_name, $site_ref )
 
-#########################################################################
-#
-# STR __Get_site_prefix ( STR , HASHREF )
-#
-# This function returns the site's prefix value
-# Inputs :
-#  - $site		: site name
-#  - $ref_site	: hashref where are stored site definitions according to networkfile-syntax
-#
-# Output :
-#  Return a string containing the site prefix as defined into site parsed data.
-#
-# WARNING : by convention only EDGE sites are authorized for prefixing hostname
-#
-sub __Get_site_prefix {
-    my ( $site, $ref_site ) = @_;
+This function returns the site's prefix value, or an empty string.
 
-    if ( $ref_site->{'state'} eq 'EDGE' ) {
-        if ( defined $ref_site->{'prefix'} ) {
-            return $ref_site->{'prefix'} . '-';
-        }
-        else {
-            return $site . '-';
-        }
+=over
+
+=item I<$site_name> the name of the site
+
+=item I<$sites_ref> a reference to the site definition hash
+
+=back
+
+B<WARNING>: by convention only EDGE sites can have a prefix.
+
+=cut
+
+sub __get_site_prefix {
+    my ( $site_name, $site_ref ) = @_;
+
+    # Only EDGE sites can have a prefix
+    if ( $site_ref->{'state'} ne 'EDGE' ) {
+        return q{};
     }
-    else {
-        return '';
-    }
+
+    my $prefix = $site_ref->{'prefix'} || $site_name;
+
+    # FIXME: what if $prefix is empty?
+    return $prefix . q{-};
 }
 
-#########################################################################
-#
-# ARRAY __Get_host_indexes ( HASHREF, STR )
-#
-# This function returns the maximum numbers and nodes for a specified hostgroup definition
-# Inputs :
-#  - $ref_hostgroup		: hashref containing the section where site key is defined
-#  - $hostname_model	: string containing the model definition for building hostname
-#
-# Output :
-#  Returns a list containing last number and last nodes for a hostgroup
-#
-sub __Get_host_indexes {
-    my ( $ref_hostgroup, $hostname_model ) = @_;
-    my ( $node_last, $num_last, $digits, $nodes );
+=head2 __get_host_indexes( $hostgroup_ref, $hostname_model )
 
-    unless ( $ref_hostgroup or $hostname_model ) {
-        croak q{ERROR: $ref_hostgroup and $hostname_model MUST BE defined};
+This function returns a list of two elements: the maximum number and node for
+a specified hostgroup definition.
+
+=over
+
+=item I<$hostgroup_ref> is a reference to the hash describing FIXME
+
+=item I<$hostname_model> is the host model name
+
+=cut
+
+sub __get_host_indexes {
+    my ( $hostgroup_ref, $hostname_model ) = @_;
+
+    unless ( $hostgroup_ref and $hostname_model ) {
+        croak q{ERROR: $hostgroup_ref and $hostname_model are mandatory};
     }
-    unless ( ref $ref_hostgroup eq 'HASH' ) {
-        croak q{ERROR: bad ref for $ref_hostgroup};
+    if ( ref $hostgroup_ref ne 'HASH' ) {
+        croak q{ERROR: Invalid non-hash reference $hostgroup_ref};
     }
     if ( ref $hostname_model ) {
-        croak q{ERROR: $hostname_model MUST BE a string};
+        croak q{ERROR: Invalid non-scalar $hostname_model};
     }
-    $node_last
-        = ( $ref_hostgroup->{'nodes'} )
-        ? ( $ref_hostgroup->{'nodes'} - 1 )
-        : 0;
-    $num_last = $ref_hostgroup->{'number'} - 1;
+
+    my $last_num = $hostgroup_ref->{'number'} - 1;
+    my $last_node
+        = $hostgroup_ref->{'nodes'} ? ( $hostgroup_ref->{'nodes'} - 1 ) : 0;
+
+    my ( $digits, $nodes );
     if ( $hostname_model =~ m{ ([%]*) ([_]*) \z }xms ) {
         $digits = length($1) || 0;
         $nodes  = length($2) || 0;
     }
 
     # Checking nodes
-    if ( $node_last && !$nodes ) {
-        croak q{ERROR: Bad definition _ on key hostname};
+    if ( $last_node and not $nodes ) {
+        croak qq{ERROR: $hostname_model: bad node (_) definition};
     }
-    elsif ( $node_last && ceil( log($node_last) / log(26) ) > $nodes ) {
-        carp q{WARN: $node_last exceeds maximum nodes allowed};
+    if ( $last_node and ceil( log($last_node) / log(26) ) > $nodes ) {
+        croak qq{ERROR: $hostname_model: $last_node exceeds maximum nodes allowed};
     }
 
     # Checking hostnum
-    if ( $num_last && !$digits ) {
-        croak q{ERROR: Bad definition % on key hostname};
+    if ( $last_num and not $digits ) {
+        croak qq{ERROR: $hostname_model: bad num (%) definition};
     }
-    elsif ( $num_last && $num_last > 10**$digits ) {
-        carp q{WARN: $num_last exceeds maximum host numbers allowed};
+    if ( $last_num and $last_num > 10**$digits ) {
+        croak qq{ERROR: $last_num exceeds maximum host numbers allowed};
     }
-    return ( $num_last, $node_last );
+
+    return ( $last_num, $last_node );
 }
 
-sub __Get_hostnumber_from_model {
+=head2 __get_hostnum_from_model( $model, $num, $node )
+
+Returns the HOSTNUM computed from the host model, number and node.
+
+For instance, for the model I<foo%%_>, number I<1> and node I<a>, the result
+would be I<01a>.
+
+=cut
+
+sub __get_hostnum_from_model {
     my ( $model, $num, $node ) = @_;
 
     my ( $digits_string, $nodes_string )
@@ -379,62 +455,54 @@
 
     my $index = q{};
     while ( $digits > length $num ) {
-        $index .= "0";
+        $index .= q{0};
         $digits--;
     }
 
+    # FIXME in this implementation the node is appended as is, so the
+    # $nodes_string length is not used at all... bug or feature?
     $node ||= q{};
 
     return $index . $num . $node;
 }
 
-#########################################################################
-#
-# STR __Get_hostname_from_model ( STR, STR, STR, STR, HASHREF )
-#
-# This function returns the hostname for a given model, number and node
-# Inputs :
-#  - $hostname_model	: string containing the model definition for building hostname
-#  - $hostnum			: string containing the number
-#  - $hostnode			: string containing th node
-#  - $site_prefix		: string containing the site's prefix
-#  - $ref_host			: hashref containing the parsed sections where host is defined
-#
-# Output :
-#  Returns a string containing th hostname
-#
-sub __Get_hostname_from_model {
-    my ( $hostname_model, $hostnum, $hostnode, $site_prefix, $ref_host ) = @_;
-    my ( $hostname, $index );
+=head2 __get_hostname_from_model( $hostname_model, $hostnum, $hostnode, $site_prefix, $host_ref )
 
-    $hostname = $hostname_model;
-    $index    = __Get_hostnumber_from_model(
-        $hostname_model, $hostnum, $hostnode
-    );
-    $hostname =~ s{ ([%]*) ([_]*) \z }{$index}xms;
-    $hostname = $site_prefix . $hostname
-        if $ref_host->{'prefix'} and $ref_host->{'prefix'} eq 'true';
+Returns the real hostname.
+
+For instance, for the model I<bar%%_>, number I<1>, node I<a> and site_prefix
+I<foo->, the result would be I<foo-bar01a>.
+
+=cut
+
+sub __get_hostname_from_model {
+    my ( $hostname_model, $hostnum, $hostnode, $site_prefix, $host_ref ) = @_;
+
+    my $index
+        = __get_hostnum_from_model( $hostname_model, $hostnum, $hostnode );
+    ( my $hostname = $hostname_model ) =~ s{ [%]* [_]* \z }{$index}xms;
+
+    # FIXME if ( $host_ref->{'prefix'} ) {
+    if ( $host_ref->{'prefix'} and $host_ref->{'prefix'} eq 'true' ) {
+        $hostname = $site_prefix . $hostname;
+    }
 
     return $hostname;
 }
 
-#########################################################################
-#
-# STR __Get_host_interfaces ( HASHREF )
-#
-# This function returns the interfaces list for a given parsed hostfile
-# Inputs :
-#  - $ref_src	: string containing the model definition for building hostname
-#
-# Output :
-#  Returns an arrayref containing the interfaces list
-#
-sub __Get_host_interfaces {
-    my ($ref_src) = @_;
-    my (@if_list);
+=head2 __get_host_interfaces($host_ref)
 
-    foreach my $section ( keys %{$ref_src} ) {
-        my ($if) = $section =~ m{
+This function returns the list of interfaces for a given host.  I<$host_ref>
+is a reference to the host configuration hash (parsed hostfile).
+
+=cut
+
+sub __get_host_interfaces {
+    my ($host_ref) = @_;
+
+    my @if_list = ();
+    foreach my $section ( keys %{$host_ref} ) {
+        my ($iface) = $section =~ m{
             \A
             interface::
             (
@@ -450,207 +518,235 @@
             )
             \z
         }xms;
-        next unless $if;
+        next unless $iface;
 
-        push @if_list, $if;
+        push @if_list, $iface;
     }
 
     return @if_list;
 }
 
-#########################################################################
-#
-# STR __Check_host_ip ( STR, NetAddr::IP, STR, STR, STR, INT, STR, HASHREF )
-#
-# This function returns the host IP for a given number and node
-# Inputs :
-#  - $ip_type		: specify here the IP type allowed values are ipv4 or ipv6
-#  - $vlan_block	: NetAddr::IP object containing the subnet of the IP
-#  - $ipstart		: string containing the pf-tools IP definition
-#  - $hostnum		: string containing the number of the specified host
-#  - $hostnode		: string containing the node of the specified host
-#  - $nodes			: specify here the number of nodes for the specified hostclass
-#  - $site			: specify here the site of the specified host
-#  - $ref_site		: specify here the hashref of site definition into global configuration
-#
-# Output :
-#  Returns a NetAddr::IP object containing the checked IP
-#
-sub __Check_host_ip {
-    my ($ip_type, $vlan_block, $ipstart, $hostnum, $hostnode, $nodes, $site,
-        $ref_site
-        )
-        = @_;
+=head2 __get_host_ip($arguments_ref)
 
-    unless ( ref($vlan_block) eq 'NetAddr::IP' ) {
-        croak q{ERROR: Invalid $vlan_block object};
+This function returns a NetAddr::IP object representing the host IP address
+for a given number and node.
+
+I<$arguments_ref> is a reference to a hash of named parameters:
+
+=over
+
+=item I<ip_type> ipv4 or ipv6
+
+=item I<subnet_ref> NetAddr::IP object representing the subnet
+
+=item I<ipstart> the pf-tools IP definition (string)
+
+=item I<hostnum> the host number
+
+=item I<hostnode> the host node
+
+=item I<nodes> number of nodes for this hostclass
+
+=item I<site_name> the site name
+
+=item I<site_ref> a reference to the site definition hash
+
+=cut
+
+sub __get_host_ip {
+    my ($arguments_ref) = @_;
+
+    my @argument_names = qw(
+        ip_type   subnet_ref   ipstart   hostnum   hostnode   nodes
+        site_name site_ref
+    );
+    my (
+        $ip_type, $subnet_ref, $ipstart, $hostnum, $hostnode, $nodes,
+        $site_name, $site_ref
+    ) = @$arguments_ref{@argument_names};
+
+    unless ( ref $subnet_ref eq 'NetAddr::IP' ) {
+        croak q{ERROR: Invalid $subnet_ref object};
     }
-    my $realip = NetAddr::IP->new(
-        $vlan_block->prefix() . $ipstart, $vlan_block->mask()
-    );
-    unless ($realip) {
-        croak qq{ERROR: Bad IP with $vlan_block->prefix() and $ipstart};
+
+    my $ip_address = NetAddr::IP->new( $subnet_ref->prefix() . $ipstart,
+        $subnet_ref->mask() );
+    unless ($ip_address) {
+        croak qq{ERROR: Invalid IP with $subnet_ref->prefix() and $ipstart};
     }
+
     if ($hostnum) {
         my $add = ($hostnode) ? ( $hostnum * $nodes ) + $hostnode : $hostnum;
-        $realip = $realip + $add;
+        $ip_address = $ip_address + $add;
     }
-    my $host_addr_site = $ref_site->{'HOST'}->{'BY_ADDR'};
-    if ( defined $host_addr_site->{ $realip->cidr() } ) {
-        croak qq{ERROR: $realip->addr() already defined on site $site};
+
+    my $host_addr_site = $site_ref->{'HOST'}->{'BY_ADDR'};
+    if ( defined $host_addr_site->{ $ip_address->cidr() } ) {
+        croak
+            qq{ERROR: $ip_address->addr() already defined on site $site_name};
     }
-    unless ( $vlan_block->contains($realip) ) {
-        croak qq{ERROR: $realip->addr() is out of range $vlan_block->cidr()};
+    unless ( $subnet_ref->contains($ip_address) ) {
+        croak
+            qq{ERROR: $ip_address->addr() is out of range $subnet_ref->cidr()};
     }
-    return $realip;
+
+    return $ip_address;
 }
 
-#####################################################################################
-#
-# STR __Get_vlan_list_from_server ( HASHREF )
-#
-# This function returns the vlan list for a given parsed server
-# Inputs :
-#  - $ref_srv	: hashref containing the server definition as parsed with Load_conf
-#
-# Output :
-#  Returns an arrayref containing the vlan list
-#
-sub __Get_vlan_list_from_server {
-    my ($ref_srv) = @_;
-    my @vlan_list = ();
+=head2 __get_vlan_tag_from_site( $vlan, $site_ref )
 
-    foreach my $key ( keys %{$ref_srv} ) {
-        next unless $key =~ m{ \A ipv }xms;
+This function returns the 802.1Q VLAN tag ID for I<$vlan> as defined in
+I<$site_ref>.
 
-        my ( $type, $vlan, $num ) = split m{ [.] }xms, $key;
-        push @vlan_list, $vlan;
-    }
+=cut
 
-    @vlan_list = uniq @vlan_list;
+sub __get_vlan_tag_from_site {
+    my ( $vlan, $site_ref ) = @_;
 
-    return \@vlan_list;
-}
-
-########################################################################################
-#
-# STR __Get_alias_list_from_server ( HASHREF, STR[, STR] )
-#
-# This function returns the DNS alias list from a given parsed server and a specified vlan
-# Inputs :
-#  - $ref_parsed	: hashref containing the server definition as parsed with Load_conf
-#  - $vlan			: specify here the vlan name as defined into pf-tools configuration
-#  - $host_number	: specify here the host index (host's number and host's node)
-#
-# Output :
-#  Returns an arrayref containing the alias list
-#
-sub __Get_alias_list_from_server {
-    my ( $ref_parsed, $vlan, $host_number ) = @_;
-
-    my @alias_list = ();
-    foreach my $key ( keys %{$ref_parsed} ) {
-        next unless $key =~ m{ \A alias }xms;
-
-        my ( $alias, $name, $host_num ) = split m{ [.] }xms, $key;
-        next if $host_number and $host_num and $host_num ne $host_number;
-
-        if ( $vlan eq $ref_parsed->{$key} ) {
-            push @alias_list, $name;
+    my $net_ref = $site_ref->{'NETWORK'}->{'BY_TAG'};
+    foreach my $tag ( keys %{$net_ref} ) {
+        if ( $net_ref->{$tag} eq $vlan ) {
+            return $tag;
         }
     }
 
-    @alias_list = uniq @alias_list;
-
-    return \@alias_list;
-}
-
-########################################################################################
-#
-# STR __Get_vlan_tag_from_site ( STR, HASHREF )
-#
-# This function returns the 802.1q tag for a specified vlan and from a site defined into
-# global configuration structure
-# Inputs :
-#  - $vlan			: specify here the vlan's name as defined into pf-tools configuration
-#  - $site_part		: specify here the site's part of gloabl hash structure
-#
-# Output :
-#  Returns the tag if defined undef undef if not.
-#
-sub __Get_vlan_tag_from_site {
-    my ( $vlan, $site_part ) = @_;
-
-    my $net_part = $site_part->{'NETWORK'}->{'BY_TAG'};
-    foreach my $tag ( keys %{$net_part} ) {
-        return $tag if ( $net_part->{$tag} eq $vlan );
-    }
     return;
 }
 
+=head2 __build_host_from_server( $server_name, $server_ref )
+
+Builds a host definition hash from a server definition hash.
+
+=cut
+
 sub __build_host_from_server {
-    my ( $srv_name, $ref_srv ) = @_;
-    my $result    = {};
-    my $iface_idx = 0;
-    $result->{'hostgroup'}->{'hostname'} = $srv_name;
-    foreach my $key ( keys %{$ref_srv} ) {
+    my ( $server_name, $server_ref ) = @_;
+
+    my $result = {
+        hostgroup => {
+            hostname => $server_name,
+        },
+    };
+
+    my $iface_index = 0;
+    foreach my $key ( keys %{$server_ref} ) {
         next if $key eq 'type' or $key =~ m{ \A __ }xms;
 
-        my $suffix;
         my ( $key_type, $spec, $hostnum ) = split( m{ [.] }xms, $key );
         if ( $key_type eq 'alias' ) {
-            $result->{'dns'}->{$key} = $ref_srv->{$key};
+            $result->{'dns'}->{$key} = $server_ref->{$key};
+            next;
         }
-        elsif ( $key_type =~ m{ \A ipv }xms ) {
-            $suffix = ($hostnum) ? qq{\.$hostnum} : q{};
-            $result->{qq{interface::eth$iface_idx}} = {
+
+        # FIXME this obviously does not handle IPv6
+        if ( $key_type =~ m{ \A ipv }xms ) {
+            my $suffix = $hostnum ? qq{\.$hostnum} : q{};
+            $result->{qq{interface::eth$iface_index}} = {
                 qq{vlan$suffix} => $spec,
-                qq{ipv4$suffix} => $ref_srv->{$key},
+                qq{ipv4$suffix} => $server_ref->{$key},
             };
-            $iface_idx++;
+            $iface_index++;
+            next;
         }
-        elsif ( $key_type eq 'shortname' ) {
+
+        if ( $key_type eq 'shortname' ) {
             my $key_name = $key_type . ( $spec ? qq{\.$spec} : q{} );
-            $result->{'dns'}->{$key_name} = $ref_srv->{$key};
+            $result->{'dns'}->{$key_name} = $server_ref->{$key};
+            next;
         }
-        elsif ( $key_type =~ m{\A (comment|order|number|nodes|site) \z}xms ) {
-            $result->{'hostgroup'}->{$key_type} = $ref_srv->{$key};
+
+        if ( $key_type =~ m{ \A (comment|order|number|nodes|site) \z }xms ) {
+            $result->{'hostgroup'}->{$key_type} = $server_ref->{$key};
+            next;
         }
     }
     return $result;
 }
 
-#####################################################################################################
-#
-# HASHREF __Add_host_interface ( STR, STR, STR, STR, HASHREF, ARRAYREF, STR, HASHREF, HASHREF )
-#
-# This function creates the structure to add into global configuration for an interface defintion
-# Inputs :
-#  - $iface			: specify here the interface name e.g. ethX or bondY
-#  - $hostname		: specify here the hostname
-#  - $hostnum		: specify here the host number
-#  - $hostnode		: specify here the host node
-#  - $ref_host		: hashref containing the host definition as parsed according to networkfile-syntax
-#  - $ref_if_list	: arrayref where is stored the interface list of the given hostname
-#  - $site			: specify here the site of the specified hostname
-#  - $ref_site		: hashref where are stored the site definition into global configuration
-#  - $pf_config		: hashref where are stored pf-tools configuration datas
-#
-sub __Add_host_interface {
-    my ($iface,    $hostname,    $hostnum, $hostnode, $index,
-        $ref_host, $ref_if_list, $site,    $ref_site, $pf_config
-    ) = @_;
+=head2 __build_iface_entry ( FIXME )
 
-    my $net_site      = $ref_site->{'NETWORK'}->{'BY_NAME'};
-    my $host_site     = $ref_site->{'HOST'};
-    my $iface_section = 'interface::' . $iface;
-    my $iface_def     = $ref_host->{$iface_section};
-    my $nodes         = $ref_host->{'hostgroup'}->{'nodes'} || 0;
-    my $host_number   = ($hostnode) ? $hostnum . $hostnode : $hostnum;
+This functions builds the configuration structure for a given host interface.
 
-    my ( $ifraw, $iftag ) = $iface =~ m{
+Arguments: 
+
+=over
+
+=item I<iface_name> the interface name
+
+=item I<hostname> the host name
+
+=item I<hostnum> the host number
+
+=item I<hostnode> the host node
+
+=item I<host_ref> a reference to the I<hostname> host configuration hash
+
+=item I<iface_list_ref> a reference to a list of the interfaces for I<hostname>
+
+=item I<site_name> the site name
+
+=item I<site_ref> a reference to the I<site> configuration hash
+
+=item I<pf_config> a reference to the global pf-tools configuration hash
+
+=cut
+
+sub __build_iface_entry {
+    my ($arguments_ref) = @_;
+
+    my @argument_names = qw(
+        iface_name    hostname   hostnum
+        hostnode      host_ref   iface_list_ref
+        site_name     site_ref   pf_config
+    );
+    my ($iface_name, $hostname, $hostnum,
+        $hostnode,   $host_ref, $iface_list_ref,
+        $site_name,  $site_ref, $pf_config
+    ) = @$arguments_ref{@argument_names};
+
+    my $net_site_ref       = $site_ref->{'NETWORK'}->{'BY_NAME'};
+    my $host_site_ref      = $site_ref->{'HOST'};
+    my $iface_section_name = qq{interface::$iface_name};
+    my $iface_section_ref  = $host_ref->{$iface_section_name};
+    my $nodes              = $host_ref->{'hostgroup'}->{'nodes'} || 0;
+    my $host_number        = $hostnum . ( $hostnode ? $hostnode : q{} );
+
+    # Check vlan
+    my $vlan = $iface_section_ref->{"vlan.$host_number"}
+        || $iface_section_ref->{'vlan'};
+    unless ( $net_site_ref->{$vlan} ) {
+        croak
+            qq{ERROR: site $site_name host $hostname: unknown $vlan for $iface_name};
+    }
+
+    my $result = {
+        'vlan' => $vlan,
+    };
+
+    # Iface option(s)
+    if (my $iface_options
+        = $iface_section_ref->{ 'iface_opt.' . $host_number }
+        || $iface_section_ref->{'iface_opt'}
+        )
+    {
+        $result->{'iface_opt'} = $iface_options;
+    }
+
+    # Check optional MAC address
+    if ( my $mac_address = $iface_section_ref->{"mac.$host_number"} ) {
+        if ( $host_site_ref->{'BY_MAC'}->{$mac_address} ) {
+            my ( $used_if, $used_host, $used_vlan ) = split m{ [.] }xms,
+                $host_site_ref->{'BY_MAC'}->{$mac_address};
+            croak
+                qq{ERROR: MAC address $mac_address already used by host $used_host iface $used_if vlan $used_vlan};
+        }
+        $result->{'mac'} = $mac_address;
+    }
+
+    # Check optional 802.1Q tag
+    my ($iface_tag) = $iface_name =~ m{
         \A
-        (                   # $ifraw
+        (?:
             (?:
                 eth | bond
             )
@@ -658,106 +754,87 @@
         )
         (?:
             [.]
-            (               # $iftag
+            (               # $iface_tag
                 TAG[\d]+
             )
         )?
         \z
     }xms;
-
-    # Check vlan
-    my $vlan = $iface_def->{ 'vlan.' . $host_number } || $iface_def->{'vlan'};
-    unless ( $net_site->{$vlan} ) {
-        croak qq{ERROR: Unknown $vlan for $iface on $hostname on site $site};
-    }
-    my $add_if = {
-        'vlan' => $vlan,
-    };
-
-    # Iface option(s)
-    my $iface_opt = $iface_def->{ 'iface_opt.' . $host_number }
-        || $iface_def->{'iface_opt'};
-    $add_if->{'iface_opt'} = $iface_opt if ( defined $iface_opt );
-
-    # Check MAC address if defined
-    my $mac = $iface_def->{ 'mac.' . $host_number } || "";
-    if ( $mac ne "" ) {
-        if ( $host_site->{'BY_MAC'}->{$mac} ) {
-            my ( $macif, $machost, $macvlan ) = split(
-                m{ [.] }xms,
-                $host_site->{'BY_MAC'}->{$mac}
-            );
-            croak qq{ERROR: $mac already defined for $macif on $machost};
-        }
-        $add_if->{'mac'} = $mac;
+    if ($iface_tag
+        and $iface_tag =~ m{\A \d+ \z}xms
+        and $iface_tag ne $net_site_ref->{$vlan}->{'tag'}
+        )
+    {
+        croak
+            qq{ERROR: $iface_tag for $iface_section_name differs from $vlan def};
     }
 
-    # Check tag
-    my $net_tag = $net_site->{$vlan}->{'tag'};
-    if ( $iftag && $iftag =~ m{\A \d+ \z}xms && $net_tag ne $iftag ) {
-        croak qq{ERROR: $iftag for $iface_section differs from $vlan def};
-    }
+    # Bondig "master interface"?
+    if ( $iface_name =~ m{ \A bond }xms and not $iface_tag ) {
 
-    if ( $iface =~ m{ \A bond }xms and not $iftag ) {
+        # Check if slaves are not in use
+        my $slave_ifaces_string = $iface_section_ref->{"slaves.$host_number"}
+            || $iface_section_ref->{'slaves'};
 
-        # Check if slaves not in use
-        my $slaves_iface_def
-            = $iface_def->{ 'slaves.' . $host_number }
-            ? $iface_def->{ 'slaves.' . $host_number }
-            : $iface_def->{'slaves'};
-
-        my @slaves = split m{ \s* [,] \s* }xms, $slaves_iface_def;
-        foreach my $if (@slaves) {
-            if ( any { $_ eq $if } @{$ref_if_list} ) {
+        my @slave_ifaces = split m{ \s* [,] \s* }xms, $slave_ifaces_string;
+        foreach my $slave_iface (@slave_ifaces) {
+            if ( any { $_ eq $slave_iface } @{$iface_list_ref} ) {
                 croak
-                    qq{ERROR: host $hostname: $if already in use, cannot be enslaved to $iface};
+                    qq{ERROR: host $hostname: $slave_iface already in use, cannot be enslaved to $iface_name};
             }
         }
 
-        $add_if->{'slaves'} = join q{ }, @slaves;
-        $add_if->{'mode'} =
-            $iface_def->{ 'mode.' . $host_number }
-            || $iface_def->{'mode'};
-        $add_if->{'options'}
-            = $iface_def->{ 'options.' . $host_number }
-            || $iface_def->{'options'};
+        $result->{'slaves'} = join q{ }, @slave_ifaces;
+        $result->{'mode'} = $iface_section_ref->{"mode.$host_number"}
+            || $iface_section_ref->{'mode'};
+        $result->{'options'} = $iface_section_ref->{"options.$host_number"}
+            || $iface_section_ref->{'options'};
     }
 
     # Check address and route values
     foreach my $ip_type (qw( ipv4 ipv6 )) {
         next unless $pf_config->{'features'}->{$ip_type};
 
-        my $netblock = get_netblock_from_vlan( $ip_type, $net_site->{$vlan} );
+        my $netblock
+            = get_netblock_from_vlan( $ip_type, $net_site_ref->{$vlan} );
         unless ($netblock) {
-            croak qq{ERROR: getting $ip_type subnet for $vlan on $hostname};
+            croak
+                qq{ERROR: host $hostname: unknown $ip_type subnet for $vlan};
         }
 
-        my @params = ( $ip_type, $netblock );
         my $ip_type_dot_host_number = join q{.}, $ip_type, $host_number;
-        if ( $iface_def->{$ip_type_dot_host_number} ) {
-            push @params, $iface_def->{$ip_type_dot_host_number}, 0, 0, 0;
-        }
-        else {
-            push @params, $iface_def->{$ip_type}, $hostnum, $hostnode, $nodes;
-        }
-        push @params, $site, $ref_site;
+        my $ipstart = $iface_section_ref->{$ip_type_dot_host_number}
+            || $iface_section_ref->{$ip_type};
+        my $param_hostnum
+            = $iface_section_ref->{$ip_type_dot_host_number} ? 0 : $hostnum;
+        my $param_hostnode
+            = $iface_section_ref->{$ip_type_dot_host_number} ? 0 : $hostnode;
+        my $param_nodes
+            = $iface_section_ref->{$ip_type_dot_host_number} ? 0 : $nodes;
 
-        my $realip = __Check_host_ip(@params);
-        $add_if->{$ip_type} = $realip->cidr();
+        my $params_ref = {
+            ip_type    => $ip_type,
+            subnet_ref => $netblock,
+            ipstart    => $ipstart,
+            hostnum    => $param_hostnum,
+            hostnode   => $param_hostnode,
+            nodes      => $param_nodes,
+            site_name  => $site_name,
+            site_ref   => $site_ref,
+        };
+
+        my $realip = __get_host_ip($params_ref);
+        $result->{$ip_type} = $realip->cidr();
 
         my $suffix    = $ip_type eq 'ipv6' ? '6' : q{};
         my $route_key = '@route' . $suffix;
         my $gw_key    = 'gateway' . $suffix;
 
         my @route_list;
-        foreach my $rkey ( keys %{$iface_def} ) {
-            next unless $rkey =~ m{ \A $route_key }xmso;
+        foreach my $key ( keys %{$iface_section_ref} ) {
+            next unless $key =~ m{ \A $route_key }xmso;
 
-            # if ( $rkey =~ m{ [.] $host_number \z }xmso ) {
-            #     push @route_list, @{ $iface_def->{$rkey} };
-            # }
-
-            push @route_list, @{ $iface_def->{$rkey} };
+            push @route_list, @{ $iface_section_ref->{$key} };
         }
 
         foreach my $route (@route_list) {
@@ -778,265 +855,392 @@
             }xmso;
             next unless $destination;
 
-            my $route2add;
-            if ( $destination eq 'default' ) {
-                $route2add = $destination;
-            }
-            else {
-                if ( $destination =~ m{ [g-zG-Z]+ }xms )
-                {    # FIXME why not a-z ??
-                    if ( $net_site->{$destination} ) {
+            my $new_route
+                = __build_route_destination(
+                $destination, $net_site_ref,
+                $hostname
+                );
 
-                        # Dest is a defined network ... translating into IP
-                        my $ip_dest = NetAddr::IP->new(
-                            $net_site->{$destination}->{'network'},
-                            $net_site->{$destination}->{'netmask'}
-                        );
-                        $route2add = $ip_dest->cidr();
+            if ($via) {
+                my $gateway = __build_route_gateway(
+                    {
+                        via          => $via,
+                        net_site_ref => $net_site_ref,
+                        hostname     => $hostname,
+                        vlan         => $vlan,
+                        gw_key       => $gw_key,
+                        netblock     => $netblock,
                     }
-                    else {
-
-                        # Potentially not parsed host on this site
-                        $route2add = $destination;
-                    }
-                }
-                else {
-                    my $ip_dest = NetAddr::IP->new($destination);
-                    unless ($ip_dest) {
-                        croak qq{ERROR: Bad route $route for $hostname};
-                    }
-                    $route2add = $ip_dest->cidr();
-                }
+                );
+                $new_route .= qq{ via $gateway};
             }
 
-            if ($via) {
-                $route2add .= q{ via };
-
-                if ( $via eq 'GATEWAY' ) {
-                    my $gateway = $net_site->{$vlan}->{$gw_key};
-                    unless ($gateway) {
-                        croak qq{ERROR: Unknown gateway for $vlan};
-                    }
-                    $route2add .= $gateway;
-                }
-                elsif ( $via =~ m{ [g-zG-Z]+ }xms ) {   # FIXME why not a-z ??
-
-                    # Potentially not parsed host ...
-                    # skipping this case for now
-                    $route2add .= $via;
-                }
-                else {
-                    my $ip_via = NetAddr::IP->new($via);
-                    unless ($ip_via) {
-                        croak qq{ERROR: Bad gateway for $route on $hostname};
-                    }
-                    unless ( $netblock->contains($ip_via) ) {
-                        croak qq{ERROR: $ip_via is not on $netblock->cidr()};
-                    }
-                    $route2add .= $ip_via->addr();
-                }
-            }
-
-            push( @{ $add_if->{$route_key} }, $route2add );
+            push @{ $result->{$route_key} }, $new_route;
         }
     }
 
-    return $add_if;
+    return $result;
 }
 
-sub __Add_dhcp_entry {
-    my ($param) = @_;
+=head2 __build_route_destination( $destination, $net_site_ref, $hostname )
 
-    my $dhcp_part = $param->{'dhcp_part'};
-    my $dhcpvlan  = $param->{'dhcpvlan'};
-    my $resolver  = $param->{'resolver'};
-    my $hostname  = $param->{'hostname'};
-    my $hostclass = $param->{'hostclass'};
-    my $suffix    = ( $param->{'ip_type'} eq 'ipv6' ) ? 6 : '';
-    unless ( $dhcp_part->{$dhcpvlan} ) {
-        $dhcp_part->{$dhcpvlan} = {
-            'subnet'  => $param->{'vlan_def'}->{"network$suffix"},
-            'netmask' => $param->{'vlan_def'}->{"netmask$suffix"},
+This functions verifies the destination and tries to translates it to a known
+IP address/prefix (CIDR notation).
+
+=cut
+
+sub __build_route_destination {
+    my ( $destination, $net_site_ref, $hostname ) = @_;
+
+    # the default destination is easy
+    if ( $destination eq 'default' ) {
+        return $destination;
+    }
+
+    # $destination is clearly not an IP address or address/prefix
+    if ( $destination =~ m{ [a-zA-Z]+ }xms ) {
+
+        # $destination is a known network, translate it to CIDR notation
+        if ( $net_site_ref->{$destination} ) {
+            my $ip_dest = NetAddr::IP->new(
+                $net_site_ref->{$destination}->{'network'},
+                $net_site_ref->{$destination}->{'netmask'}
+            );
+
+            return $ip_dest->cidr();
+        }
+
+        # potentially not parsed host on this site
+        return $destination;
+    }
+
+    # $destination must be an IP address or address/prefix
+    my $ip_dest = NetAddr::IP->new($destination);
+    unless ($ip_dest) {
+        croak qq{ERROR: host $hostname: bad route destination $destination};
+    }
+
+    return $ip_dest->cidr();
+}
+
+=head2 __build_route_gateway( $via, $net_site_ref, $hostname, $vlan, $gw_key, $netblock )
+
+This functions verifies the gateway I<$via> and possibly translates it to an
+IP address.
+
+=cut
+
+sub __build_route_gateway {
+    my ($arguments_ref) = @_;
+
+    my @argument_names = qw(
+        via   net_site_ref   hostname   vlan   gw_key   netblock
+    );
+    my ( $via, $net_site_ref, $hostname, $vlan, $gw_key, $netblock )
+        = @$arguments_ref{@argument_names};
+
+    # 'GATEWAY' means "the known gateway for this vlan"
+    if ( $via eq 'GATEWAY' ) {
+        my $gateway = $net_site_ref->{$vlan}->{$gw_key};
+        unless ($gateway) {
+            croak qq{ERROR: Host $hostname: unknown gateway for $vlan};
+        }
+
+        return $gateway;
+    }
+
+    # $via is clearly not an IP address, leave it as-is
+    if ( $via =~ m{ [a-zA-Z]+ }xms ) {
+        return $via;
+    }
+
+    # $via must be an IP address
+    my $ip_via = NetAddr::IP->new($via);
+    unless ($ip_via) {
+        croak qq{ERROR: host $hostname: bad route gateway $via};
+    }
+    unless ( $netblock->contains($ip_via) ) {
+        croak
+            qq{ERROR: host $hostname: gateway $ip_via is not in $netblock->cidr()};
+    }
+
+    return $ip_via->addr();
+}
+
+=head2 __add_dhcp_entry( $arguments_ref )
+
+This function adds the DHCP configuration for a host.
+
+=cut
+
+sub __add_dhcp_entry {
+    my ($arguments_ref) = @_;
+
+    my @argument_names = qw(
+        dhcp_part_ref  dhcp_vlan        resolver
+        hostname       hostclass        ip_type
+        vlan_def_ref   iface_def_ref    pxefilename
+    );
+    my ($dhcp_part_ref, $dhcp_vlan,     $resolver,
+        $hostname,      $hostclass,     $ip_type,
+        $vlan_def_ref,  $iface_def_ref, $pxefilename
+    ) = @$arguments_ref{@argument_names};
+
+    my $ip_type_suffix = $ip_type eq 'ipv6' ? 6 : q{};
+    unless ( $dhcp_part_ref->{$dhcp_vlan} ) {
+        $dhcp_part_ref->{$dhcp_vlan} = {
+            'subnet'  => $vlan_def_ref->{"network$ip_type_suffix"},
+            'netmask' => $vlan_def_ref->{"netmask$ip_type_suffix"},
+            'routers' => $vlan_def_ref->{"gateway$ip_type_suffix"},
         };
-        if ( $param->{'vlan_def'}->{"gateway$suffix"} ) {
-            $dhcp_part->{$dhcpvlan}->{'routers'} =
-                $param->{'vlan_def'}->{"gateway$suffix"};
-        }
     }
-    $dhcp_part->{$dhcpvlan}->{$hostclass} = {}
-        unless ( $dhcp_part->{$dhcpvlan}->{$hostclass} );
-    my $fixed_addr = $param->{'iface_def'}->{ $param->{'ip_type'} };
-    $fixed_addr =~ s{ [/] [\d]+ \z }{}xms;
-    $dhcp_part->{$dhcpvlan}->{$hostclass}->{$hostname} = [
-        'hardware ethernet ' . $param->{'iface_def'}->{'mac'} . ";",
-        'fixed-address ' . $fixed_addr . ';',
-        'filename ' . $param->{'pxefilename'} . ';',
-        'option domain-name-servers ' . $resolver . ';',
+
+    ( my $fixed_addr = $iface_def_ref->{$ip_type} )
+        =~ s{ [/] [\d]+ \z }{}xms;    # remove CIDE prefix size
+
+    $dhcp_part_ref->{$dhcp_vlan}->{$hostclass}->{$hostname} = [
+        qq/hardware ethernet $iface_def_ref->{'mac'};/,
+        qq/fixed-address $fixed_addr;/,
+        qq/filename $pxefilename;/,
+        qq/option domain-name-servers $resolver;/,
     ];
 
     return;
 }
 
-sub __Add_zone_entry {
-    my ($param)  = @_;
-    my $host_res = {};
-    my $zone_res = {};
+=head2 __add_zone_entry($arguments_ref)
 
-    my $hostname  = $param->{'hostname'}  or return;
-    my $hostclass = $param->{'hostclass'} or return;
-    my $host_number = $param->{'host_number'};
-    my $vlan        = $param->{'iface_def'}->{'vlan'};
-    my $zone_ip     = $param->{'iface_def'}->{ $param->{'ip_type'} };
-    $zone_ip =~ s{/[\d]+ \z}{}xms;
-    my $zone_part = $param->{'zone_part'};
-    my $zone_key  = ( $param->{'ip_type'} eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
-    my $zone      = $param->{'zone_name'};
-    my $shortname = $param->{'shortname'};
-    my $site      = $param->{'site'};
+This function adds the host information to the zone hash.
 
-    unless ( $param->{'zone_part'}->{$hostclass} ) {
-        $param->{'zone_part'}->{$hostclass} = {};
-        push(
-            @{  $param->{'global_config'}->{$zone_key}->{'BY_NAME'}
-                    ->{$zone}->{'__hostclass_order'}->{$site}
-                },
-            $hostclass
-        );
+=cut
+
+sub __add_zone_entry {
+    my ($arguments_ref) = @_;
+
+    my @argument_names = qw(
+        hostname    hostclass       host_number   host_part_ref
+        iface_def   zone_part_ref   dns_def_ref   ip_type
+        zone_name   shortname       site          global_config
+        index
+    );
+    my ($hostname,  $hostclass,     $host_number, $host_part_ref,
+        $iface_def, $zone_part_ref, $dns_def_ref, $ip_type,
+        $zone_name, $shortname,     $site,        $global_config,
+        $index
+        )
+        = @$arguments_ref{@argument_names};
+
+    unless ($hostname) {
+        croak q{ERROR: $hostname is mandatory};
     }
-    my $host_part = $param->{'host_part'};
-    $zone_res->{ $hostname . '.' . $vlan } = "A\t$zone_ip";
+    unless ($hostclass) {
+        croak q{ERROR: $hostclass is mandatory};
+    }
 
-    $zone_part->{$hostclass}->{ $hostname . '.' . $vlan } = "A\t$zone_ip";
-    my $shortname_vlan = $param->{'dns_def'}->{"shortname\.$host_number"}
-        || $param->{'dns_def'}->{'shortname'};
-    return unless $shortname_vlan;
-    if ( $shortname ne $hostname && $shortname_vlan eq $vlan ) {
-        if ( !$zone_part->{$hostclass}->{"$shortname\.$vlan"} ) {
-            $zone_part->{$hostclass}->{"$shortname\.$vlan"} = [
-                "A\t$zone_ip",
-            ];
+    ( my $zone_ip = $iface_def->{$ip_type} )
+        =~ s{ [/ ][\d]+ \z }{}xms;    # remove the CIDR prefix size
+
+    my $zone_key = ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
+
+    unless ( $zone_part_ref->{$hostclass} ) {
+        push @{
+            $global_config->{$zone_key}->{'BY_NAME'}->{$zone_name}
+                ->{'__hostclass_order'}->{$site}
+            },
+            $hostclass;
+    }
+
+    my $vlan = $iface_def->{'vlan'};
+    $zone_part_ref->{$hostclass}->{ $hostname . '.' . $vlan } = "A\t$zone_ip";
+
+    my $shortname_vlan = $dns_def_ref->{"shortname\.$host_number"}
+        || $dns_def_ref->{'shortname'};
+    unless ($shortname_vlan) {
+        croak qq{ERROR: hostname $hostname: shortname is mandatory};
+    }
+
+    if ( $shortname ne $hostname and $shortname_vlan eq $vlan ) {
+        if ( not $zone_part_ref->{$hostclass}->{"$shortname\.$vlan"} ) {
+            $zone_part_ref->{$hostclass}->{"$shortname\.$vlan"}
+                = [ "A\t$zone_ip", ];
         }
         else {
-            push(
-                @{ $zone_part->{$hostclass}->{"$shortname\.$vlan"} },
-                "A\t$zone_ip"
-            );
-            $zone_part->{$hostclass}->{$shortname}
-                = "CNAME\t$shortname\.$vlan";
+            push @{ $zone_part_ref->{$hostclass}->{"$shortname\.$vlan"} },
+                qq{A\t$zone_ip};
+            $zone_part_ref->{$hostclass}->{$shortname}
+                = qq{CNAME\t$shortname.$vlan};
         }
     }
-    foreach my $key ( keys %{ $param->{'dns_def'} } ) {
+
+    foreach my $key ( keys %{$dns_def_ref} ) {
         next unless $key =~ m{ \A alias }xms;
 
-        my ( $key_type, $alias, $host_num ) = split( m{ [.] }xms, $key );
-        $host_part->{$alias} = $shortname;
-        $host_part->{ $alias . $param->{'index'} } = $hostname;
-        if ( $param->{'dns_def'}->{$key} eq $vlan ) {
-            $zone_part->{$hostclass}->{$alias} = "CNAME\t$shortname\.$vlan";
-            $zone_part->{$hostclass}->{ $alias . $param->{'index'} } =
-                "CNAME\t$hostname\.$vlan";
+        my ( $key_type, $alias, $host_num ) = split m{ [.] }xms, $key;
+        $host_part_ref->{$alias} = $shortname;
+        $host_part_ref->{ $alias . $index } = $hostname;
+
+        if ( $dns_def_ref->{$key} eq $vlan ) {
+            $zone_part_ref->{$hostclass}->{$alias}
+                = qq{CNAME\t$shortname\.$vlan};
+            $zone_part_ref->{$hostclass}->{ $alias . $index }
+                = qq{CNAME\t$hostname\.$vlan};
         }
     }
 
     return;
 }
 
-sub __Add_boot_on_host_entry {
-    my ( $host2add, $host_number, $site_part, $pf_config ) = @_;
+=head2 __build_boot_entry_for_host( $host_part_ref, $host_number, $hostname, $site_part_ref, $pf_config )
+
+This function builds the boot configuration structure for a host.
+
+=cut
+
+sub __build_boot_entry_for_host {
+    my ($host_part_ref, $host_number, $hostname,
+        $site_part_ref, $pf_config
+    ) = @_;
 
     my $result = {};
 
     # Checking path for PXE elements kernel, initrd ...
     my $boot_def = $DEF_SECTIONS->{'host'}->{'boot'};
+
+BOOT_KEY:
     foreach my $key ( keys %{$boot_def} ) {
-        next if $key =~ m{ \A MANDATORY }xms;
-        my $value = $host2add->{'boot'}->{"$key\.$host_number"}
-            || $host2add->{'boot'}->{$key};
-        unless ($value) {
-            if ( $key =~ m{ \A (console|cmdline) \z }xms ) {
-                $value = ( $key eq 'console' )
-                    ? $site_part->{$key}
-                    : q{};
-            }
+        next if $key eq q{MANDATORY_KEYS};
+
+        my $value = $host_part_ref->{'boot'}->{"$key\.$host_number"}
+            || $host_part_ref->{'boot'}->{$key};
+
+        # Special case for the default console value
+        if ( $key eq q{console} and not $value ) {
+            $value = $site_part_ref->{$key};
         }
-        next unless $value;
 
-        # FIXME this should be done on the deploy-host only
-        if ($key !~ m{ \A (console|cmdline) \z }xms
-            && !-e $pf_config->{'path'}->{'tftp_dir'} . $value
+        next BOOT_KEY unless $value;
+
+        # This check should be done only on the deploy hosts
+        if ($hostname =~ m{ \A $pf_config->{'regex'}->{'deploy_hosts'} \z }xms
+            and $key !~ m{ \A (console|cmdline) \z }xms
             )
         {
-            carp
-                qq{WARN: $value in $pf_config->{'path'}->{'tftp_dir'} doesn't exist};
+            my $filename = join '/', $pf_config->{'path'}->{'tftp_dir'},
+                $value;
+            carp qq{WARNING: host $hostname: $filename doesn't exist};
         }
+
         $result->{$key} = $value;
     }
+
     return $result;
 }
 
-sub __Add_deployment_on_host_entry {
-    my ( $type, $host2add, $hostclass, $host_number, $dhcpvlan ) = @_;
-    my $result = {};
+=head2 __build_deployment_entry_for_host( $type, $host_part_ref, $hostclass, $host_number, $dhcpvlan )
 
-    unless ( $type or $host2add or $hostclass ) {
+This function adds the deployment configuration structyre for a host.
+
+=cut
+
+sub __build_deployment_entry_for_host {
+    my ( $type, $host_part_ref, $hostclass, $host_number, $dhcpvlan ) = @_;
+
+    unless ( $type and $host_part_ref and $hostclass ) {
         croak q{ERROR: one or more parameter is not defined};
     }
-    if ( ref $type || ref $hostclass ) {
+    if ( ref $type or ref $hostclass ) {
         croak q{ERROR: $type and/or $hostclass MUST BE a string};
     }
-    unless ( ref $host2add eq 'HASH' ) {
-        croak q{ERROR: non-ref $host2add};
+    unless ( ref $host_part_ref eq 'HASH' ) {
+        croak q{ERROR: non-hashref $host_part_ref};
     }
+
     my $dep_def = $DEF_SECTIONS->{'host'}->{'deployment'};
-    $result = {
-        'hostname_model' => $host2add->{'hostgroup'}->{'hostname'},
+    my $result  = {
+        'hostname_model' => $host_part_ref->{'hostgroup'}->{'hostname'},
         'hosttype'       => $hostclass,
-        'order'          => $host2add->{'hostgroup'}->{'order'},
+        'order'          => $host_part_ref->{'hostgroup'}->{'order'},
     };
+
+    # nothing to do if $type eq 'server'
     if ( $type eq 'host' ) {
         foreach my $key ( keys %{$dep_def} ) {
-            my $value = $host2add->{'deployment'}->{"$key\.$host_number"}
-                || $host2add->{'deployment'}->{$key};
+            my $value = $host_part_ref->{'deployment'}->{"$key\.$host_number"}
+                || $host_part_ref->{'deployment'}->{$key};
             next unless $value;
             $result->{$key} = $value;
         }
         $result->{'dhcpvlan'} = $dhcpvlan;
     }
+
     return $result;
 }
 
-sub __Build_hostlist {
-    my ($param) = @_;
+=head2 __build_host_list($arguments_ref)
+
+Builds a hash of hosts for a given model, returns a reference to this hash.
+$arguments_ref is a reference to a hash structure containing the following
+keys:
+
+=over
+
+=item I<last_hostnum> the hostnum upper limit
+
+=item I<last_hostnode> the hostnode upper limit
+
+=item I<host_part_ref> a reference to the host part in the global
+configuration structure
+
+=item I<hostname_model> name of the hostname model
+
+=item I<prefix> the site prefix
+
+=back
+
+=cut
+
+sub __build_host_list {
+    my ($arguments_ref) = @_;
+
+    my ($last_hostnum, $last_hostnode, $host_part_ref,
+        $hostname_model, $prefix
+        )
+        = @$arguments_ref{
+        qw( last_hostnum last_hostnode host_part_ref hostname_model prefix )
+        };
 
     my $result = {};
-    foreach my $hostnum ( 0 .. $param->{'host_last'} ) {
-        foreach my $hostnode ( 0 .. $param->{'node_last'} ) {
-            my $hostname = __Get_hostname_from_model(
-                $param->{'hostname_model'},
-                $hostnum,
-                $hostnode,
-                $param->{'prefix'}
-            );
-            if ( $param->{'host_part'}->{$hostname} ) {
-                carp qq{WARN: Skipping $hostname : already defined};
+    foreach my $hostnum ( 0 .. $last_hostnum ) {
+        foreach my $hostnode ( 0 .. $last_hostnode ) {
+            my $hostname
+                = __get_hostname_from_model(
+                $hostname_model, $hostnum,
+                $hostnode,       $prefix
+                );
+
+            # Only carp, not croak, on already defined hostname
+            if ( $host_part_ref->{$hostname} ) {
+                carp qq{WARNING: Skipping already defined $hostname};
                 next;
             }
-            my $index = __Get_hostnumber_from_model(
-                $param->{'hostname_model'},
-                $hostnum,
+
+            my $index
+                = __get_hostnum_from_model(
+                $hostname_model, $hostnum,
                 $hostnode
-            );
-            my $host_number = ($hostnode)
-                ? $hostnum . $hostnode
-                : $hostnum;
+                );
+            my $host_number = $hostnum . ( $hostnode ? $hostnode : q{} );
             $result->{$hostname} = {
                 'hostnum'     => $hostnum,
                 'index'       => $index,
                 'host_number' => $host_number,
             };
-            $result->{$hostname}->{'hostnode'} = $hostnode if ($hostnode);
+            if ($hostnode) {
+                $result->{$hostname}->{'hostnode'} = $hostnode;
+            }
         }
     }
+
     return $result;
 }
 
diff -r d6a9b9a18fdc -r e756fd4d6365 lib/PFTools/Conf/Network.pm
--- a/lib/PFTools/Conf/Network.pm	Sun Nov 07 18:29:34 2010 +0100
+++ b/lib/PFTools/Conf/Network.pm	Fri Nov 12 13:36:18 2010 +0100
@@ -33,14 +33,14 @@
 use PFTools::Structqueries;
 
 our @EXPORT = qw(
-    Add_network
-    Add_site
-    Add_zone
+    add_network
+    add_site
+    add_zone
 );
 
 our @EXPORT_OK = qw();
 
-=head2 Add_zone($args)
+=head2 add_zone($args)
 
 This function adds a zone to the global configuration. $args is a reference to
 a hash containing the following named parameters:
@@ -71,10 +71,10 @@
 
 =cut
 
-sub Add_zone {
+sub add_zone {
     my ($args) = @_;
 
-    my ($start_file,    $section_name, $section_ref,
+    my ($start_file, $section_name, $section_ref,
         $global_config, $pf_config
         )
         = @$args{
@@ -102,7 +102,7 @@
     return;
 }
 
-=head2 Add_site($args)
+=head2 add_site($args)
 
 This function adds a site to the global configuration. $args is a reference to
 a hash containing the following named parameters:
@@ -133,10 +133,10 @@
 
 =cut
 
-sub Add_site {
+sub add_site {
     my ($args) = @_;
 
-    my ($start_file,    $section_name, $section_ref,
+    my ($start_file, $section_name, $section_ref,
         $global_config, $pf_config
         )
         = @$args{
@@ -206,7 +206,7 @@
     return;
 }
 
-=head2 Add_network($args)
+=head2 add_network($args)
 
 This function adds a network to the global configuration. $args is a reference to
 a hash containing the following named parameters:
@@ -237,10 +237,10 @@
 
 =cut
 
-sub Add_network {
+sub add_network {
     my ($args) = @_;
 
-    my ($start_file,    $section_name, $section_ref,
+    my ($start_file, $section_name, $section_ref,
         $global_config, $pf_config
         )
         = @$args{
@@ -248,7 +248,7 @@
         };
 
     my $site_part = $global_config->{'SITE'};
-    my $site_list = Get_site_list( $section_ref, $global_config );
+    my $site_list = get_site_list_from_section( $section_ref, $global_config );
     my $net2add   = {
         scope => $section_ref->{'scope'},
     };
@@ -256,10 +256,8 @@
         if $section_ref->{'comment'};
 
     # Check TAG
-    if ($section_ref->{'tag'}
-        && ( $section_ref->{'tag'} < 0 || $section_ref->{'tag'} > 4095 )
-        )
-    {
+    my $tag = $section_ref->{'tag'};
+    if ( $tag and ( $tag < 0 or $tag > 4095 ) ) {
         croak
             qq{ERROR: Invalid tag $section_ref->{'tag'} from file $start_file};
     }
@@ -268,7 +266,10 @@
     foreach my $ip_type (qw( ipv4 ipv6 )) {
         next unless $pf_config->{'features'}->{$ip_type};
 
-        my $suffix = $ip_type eq 'ipv6' ? '6' : q{};
+        my $suffix
+            = $ip_type eq 'ipv6'
+            ? '6'
+            : q{};    # FIXME __get_suffix_from_ip_type ?
         my $net_block   = get_netblock_from_vlan( $ip_type, $section_ref );
         my $zone_key    = qq{ZONE$suffix};
         my $dhcp_key    = qq{DHCP$suffix};
@@ -277,13 +278,14 @@
         $net2add->{"network$suffix"} = $net_block->addr();
         $net2add->{"netmask$suffix"} = $net_block->mask();
 
-        if ( $section_ref->{$gw_key} ) {
+        if ( my $gateway = $section_ref->{$gw_key} ) {
             my $ip_gw = NetAddr::IP->new(
-                $net_block->prefix() . $section_ref->{$gw_key},
+                $net_block->prefix() . $gateway,
                 $net_block->mask()
             );
             unless ($ip_gw) {
-                croak qq{ERROR: Invalid $ip_type gateway on $section_name};
+                croak
+                    qq{ERROR: Invalid $ip_type gateway $gateway in $section_name};
             }
             unless ( $net_block->contains($ip_gw) ) {
                 croak qq{ERROR: $ip_gw->addr() is not in $net_block->cidr()};
@@ -291,66 +293,67 @@
             $net2add->{$gw_key} = $ip_gw->addr();
         }
 
-        $net2add->{'tag'} = $section_ref->{'tag'};
+        $net2add->{'tag'} = $tag;
 
         foreach my $site ( @{$site_list} ) {
             my $net_part = $site_part->{'BY_NAME'}->{$site}->{'NETWORK'};
             if ( $net_part->{'BY_NAME'}->{$section_name} ) {
+
+                # FIXME is this not a fatal error?
                 carp
-                    qq{WARN: $section_name from $start_file is already defined};
+                    qq{WARN: file $start_file section $section_name: already defined};
                 next;
             }
-            if (
-                $section_ref->{'tag'}
-                && $net_part->{'BY_TAG'}->{ $section_ref->{'tag'} }
-                )
+
+            if ( $tag and $net_part->{'BY_TAG'}->{$tag} )
             {
                 croak
-                    qq{ERROR: Duplicate tag  $section_ref->{'tag'} for $section_name};
+                    qq{ERROR: File $start_file section $section_name: duplicate tag $tag};
             }
-            if (
-                $net_part->{'BY_ADDR'}->{ $net_block->cidr() }
-                && $net_part->{'BY_ADDR'}->{ $net_block->cidr() } ne
-                $section_name
-                )
-            {
-                croak qq{ERROR: subnet for $section_name already in use};
+
+            my $network_name = $net_part->{'BY_ADDR'}->{ $net_block->cidr() };
+            if ( $network_name and $network_name ne $section_name ) {
+                croak
+                    qq{ERROR: File $start_file section $section_name: subnet already in use as $network_name};
             }
 
             # Adding network to the network part of the global structure
-            my $dhcp_part = $global_config->{$dhcp_key}->{'BY_SITE'}->{$site};
-            $net_part->{'BY_NAME'}->{$section_name}           = $net2add;
+            $net_part->{'BY_NAME'}->{$section_name} = $net2add;
             $net_part->{$netaddr_key}->{ $net_block->cidr() } = $section_name;
-            $net_part->{'BY_TAG'}->{ $section_ref->{'tag'} }  = $section_name
-                if $section_ref->{'tag'};
+            if ($tag) {
+                $net_part->{'BY_TAG'}->{$tag} = $section_name;
+            }
 
        # Adding entries for network, netmask, broadcast etc. into the DNS zone
             my $zone
                 = $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'zone'};
             my $zone_part = $global_config->{$zone_key}->{'BY_NAME'}->{$zone};
-            push @{ $zone_part->{'__network_order'}->{$site} }, $section_name;
-            $zone_part->{'BY_SITE'}->{$site}->{$section_name} = {};
+
+            my $zone_ref = {};
 
             # Adding IPv4 entries
-            $zone_part->{'BY_SITE'}->{$site}->{$section_name}->{'network'}
-                = "A\t" . $net_block->addr();
-            $zone_part->{'BY_SITE'}->{$site}->{$section_name}->{'netmask'}
-                = "A\t" . $net_block->mask();
+            # FIXME what about IPv6? (see $suffix above?)
+            $zone_ref->{'network'} = qq{A\t} . $net_block->addr();
+            $zone_ref->{'netmask'} = qq{A\t} . $net_block->mask();
+
             my $broadcast = $net_block->broadcast();
             $broadcast =~ s{ [/].* \z }{}xms;    # remove /prefix
-            $zone_part->{'BY_SITE'}->{$site}->{$section_name}->{'broadcast'}
-                = "A\t" . $broadcast;
-            $zone_part->{'BY_SITE'}->{$site}->{$section_name}->{'gateway'}
-                = "A\t" . $net2add->{$gw_key}
+            $zone_ref->{'broadcast'} = qq{A\t} . $broadcast;
 
-                if defined $net2add->{$gw_key};
+            if ( $net2add->{$gw_key} ) {
+                $zone_ref->{'gateway'} = qq{A\t} . $net2add->{$gw_key};
+            }
 
-            if ( defined $dhcp_part->{$section_name} ) {
-                $dhcp_part->{$section_name}->{'subnet'}  = $net_block->addr();
-                $dhcp_part->{$section_name}->{'netmask'} = $net_block->mask();
-                if ( defined $net2add->{'gateway'} ) {
-                    $dhcp_part->{$section_name}->{'routers'}
-                        = $net2add->{'gateway'};
+            push @{ $zone_part->{'__network_order'}->{$site} }, $section_name;
+            $zone_part->{'BY_SITE'}->{$site}->{$section_name} = $zone_ref;
+
+            my $dhcp_part = $global_config->{$dhcp_key}->{'BY_SITE'}->{$site}
+                ->{$section_name};
+            if ($dhcp_part) {
+                $dhcp_part->{'subnet'}  = $net_block->addr();
+                $dhcp_part->{'netmask'} = $net_block->mask();
+                if ( $net2add->{'gateway'} ) {
+                    $dhcp_part->{'routers'} = $net2add->{'gateway'};
                 }
             }
         }
@@ -359,4 +362,6 @@
     return;
 }
 
-1;
+
+1;    # Magic true value required at end of module
+
diff -r d6a9b9a18fdc -r e756fd4d6365 lib/PFTools/Conf/Syntax.pm
--- a/lib/PFTools/Conf/Syntax.pm	Sun Nov 07 18:29:34 2010 +0100
+++ b/lib/PFTools/Conf/Syntax.pm	Fri Nov 12 13:36:18 2010 +0100
@@ -317,7 +317,7 @@
 
 =head2
 
-check_section_structure( $section_name, $section_type, $section_hash, $context )
+check_section_structure( $section_name, $section_type, $section_hash, $context, $file )
 
 Check $section_hash validity against $DEF_SECTIONS. Returns a true value on
 success, or croaks on errors.
@@ -325,7 +325,7 @@
 =cut
 
 sub check_section_structure {
-    my ( $section_name, $section_type, $section_hash, $context ) = @_;
+    my ( $section_name, $section_type, $section_hash, $context, $file ) = @_;
 
     my $int_context = $context eq 'model' ? 'host' : $context;
 
@@ -354,7 +354,7 @@
             }xms
             )
         {
-            croak qq{ERROR: Invalid section name $section_name};
+            croak qq{ERROR: Invalid section name $section_name in file $file};
         }
         $iface_type = $+{iftype};
 
@@ -380,7 +380,7 @@
         last if $section_type eq 'hostgroup' and $context eq 'model';
         if ( !defined $section_tmp->{$key} ) {
             croak
-                qq{Mandatory key $key must be defined in section $section_name in context $context};
+                qq{Mandatory key $key must be defined in section $section_name context $context file $file};
         }
     }
 
@@ -416,7 +416,7 @@
 
             if ( $value !~ m{ \A $definition->{$key} \z }xms ) {
                 croak
-                    qq{Value '$value' for key $key_name in section $section_name doesn't match $definition->{$key}};
+                    qq{Value '$value' for key $key_name in section $section_name file $file doesn't match $definition->{$key}};
             }
         }
     }
diff -r d6a9b9a18fdc -r e756fd4d6365 lib/PFTools/Structqueries.pm
--- a/lib/PFTools/Structqueries.pm	Sun Nov 07 18:29:34 2010 +0100
+++ b/lib/PFTools/Structqueries.pm	Fri Nov 12 13:36:18 2010 +0100
@@ -27,95 +27,95 @@
 use base qw( Exporter );
 use Carp;
 use English qw( -no_match_vars );    # Avoids regex performance penalty
+use List::MoreUtils qw( uniq );
 
 #use PFTools::Logger;
 
 our @EXPORT = qw(
     Get_zone_from_hostname
-    Get_zone_from_site_GLOBAL
-    Get_hosttype_from_hostname
-    Get_iface_vlan_from_hostname
-    Get_uniq_site_from_hostname
-    Get_site_from_hostname
-    Get_site_list
-    Get_cmdline_from_hostprops
-    Get_distrib_from_hostprops
-    Get_mode_from_hostprops
-    Get_pkgtype_from_hostname
-    Get_host_config_from_CONFIG
-    Get_vlan_config_from_CONFIG
-    Resolv_hostname_from_GLOBAL
+    get_zone_from_site
+    get_hosttype_from_hostname
+    get_iface_vlan_from_hostname
+    get_uniq_site_from_hostname
+    get_site_list_from_hostname
+    get_site_list_from_section
+    get_cmdline_from_host_ref
+    get_distrib_from_host_ref
+    get_mode_from_host_ref
+    get_pkgtype_from_hostname
+    get_host_config
+    get_vlan_config
+    resolve_hostname_from_global_config
 );
 
 our @EXPORT_OK = qw ();
 
-sub Get_uniq_site_from_hostname {
+=head2 get_uniq_site_from_hostname( $hostname, $global_config )
+
+If the given hostname is defined in only one site, return that site name.
+
+=cut
+
+sub get_uniq_site_from_hostname {
     my ( $hostname, $global_config ) = @_;
 
-    my $ref_list = Get_site_from_hostname( $hostname, $global_config );
-    unless( $ref_list ) {
-        carp qq{ERROR: Uknown host $hostname};
-        return;
+    my $list_ref = get_site_list_from_hostname( $hostname, $global_config );
+    unless ($list_ref) {
+        croak qq{ERROR: Uknown host $hostname};
     }
-    if ( scalar @{$ref_list} > 1 ) {
-        carp qq{ERROR: Multiple sites for hostname $hostname};
-        return;
+    if ( scalar @{$list_ref} > 1 ) {
+        croak qq{ERROR: Multiple sites for hostname $hostname};
     }
-    return shift @{$ref_list};
+
+    return shift @{$list_ref};
 }
 
-#########################################################################
-#
-# STR Get_zone_from_hostname ( STR, HASHREF, STR )
-#
-# This function adds build the site list for a given section
-# Inputs :
-#  - $site			: site name
-#  - $global_config	: hashref where is stored global configuration
-#
-# Output :
-#  Return a string containing the zone name for the specified site.
-#
-sub Get_zone_from_hostname {
+=head2 get_zone_from_hostname( $hostname, $global_config, $site )
+
+This function returns the zone name for a site. The site is determined either
+by I<$site>, or by I<$hostname> if I<$site> is not specified.
+
+=cut
+
+sub get_zone_from_hostname {
     my ( $hostname, $global_config, $site ) = @_;
 
-    unless( $site ) {
-        $site = Get_uniq_site_from_hostname ( $hostname, $global_config );
-    }
+    $site ||= get_uniq_site_from_hostname( $hostname, $global_config );
+
     return $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'zone'};
 }
 
 =head2
 
-Get_hosttype_from_hostname ( $hostname, $global_config, $site )
+get_hosttype_from_hostname ( $hostname, $global_config, $site )
 
 Returns the hosttype.
 
 =cut
 
-sub Get_hosttype_from_hostname {
+sub get_hosttype_from_hostname {
     my ( $hostname, $global_config, $site ) = @_;
 
-    if (not $hostname) {
+    if ( not $hostname ) {
         croak q{ERROR: Invalid empty or undefined $hostname};
     }
-    if (ref $hostname) {
+    if ( ref $hostname ) {
         croak q{ERROR: Invalid non-scalar $hostname};
     }
 
-    if (not $global_config) {
+    if ( not $global_config ) {
         croak q{ERROR: Invalid empty or undefined $global_config};
     }
-    if (ref $global_config ne 'HASH') {
+    if ( ref $global_config ne 'HASH' ) {
         croak q{ERROR: Invalid non-hashref $global_config};
     }
 
-    if ($site and ref $site) {
+    if ( $site and ref $site ) {
         croak q{ERROR: Invalid non-scalar $site};
     }
 
-    my $site_list = ( $site )
-        ? [ $site ]
+    my $site_list = ($site)
+        ? [$site]
         : $global_config->{'SITE'}->{'__site_list'};
 
     foreach my $site ( @{$site_list} ) {
@@ -131,259 +131,352 @@
         }
     }
 
-    croak qq{ERROR: Unable to get hosttype from hostname $hostname on site } . ($site ? $site : q{});
+    croak qq{ERROR: Unable to get hosttype from hostname $hostname on site }
+        . ( $site ? $site : q{} );
 }
 
-#########################################################################
-#
-# STR Get_iface_vlan_from_hostname ( STR, HASHREF )
-#
-# This function returns the interface for a given vlan
-# Inputs :
-#  - $vlan		: string containing the vlan name
-#  - $ref_host	: hashref containing the host properties from global configuration
-#
-# Output :
-#  Returns a string containing the interface or undef
-#
-sub Get_iface_vlan_from_hostname {
-    my ( $vlan, $ref_host ) = @_;
+=head2 get_iface_vlan_from_hostname( $vlan, $host_ref )
 
-    foreach my $iface ( keys %{ $ref_host->{'interfaces'} } ) {
-        return $iface
-            if ( $ref_host->{'interfaces'}->{$iface}->{'vlan'} eq $vlan );
+This function returns the interface name for a given vlan.
+
+=cut
+
+sub get_iface_vlan_from_hostname {
+    my ( $vlan, $host_ref ) = @_;
+
+    foreach my $iface ( keys %{ $host_ref->{'interfaces'} } ) {
+        if ( $host_ref->{'interfaces'}->{$iface}->{'vlan'} eq $vlan ) {
+            return $iface;
+        }
     }
+
     return;
 }
 
-#########################################################################
-#
-# STR Get_hostname_model_from_hostname ( STR, HASHREF )
-#
-# This function returns the hostname for a given model, number and node
-# Inputs :
-#  - $hostname		: string containing the model definition for building hostname
-#  - $global_config	: hashref containing the parsed global configuration
-#
-# Output :
-#  Returns a string containing the hosttype or undef if hostname doesn't exist
-#
-sub Get_hostname_model_from_hostname {
+=head2 get_site_list_from_hostname( $hostname, $global_config )
+
+This function returns the list of sites for a given hostname.
+
+=cut
+
+sub get_site_list_from_hostname {
     my ( $hostname, $global_config ) = @_;
 
-    my $hostclass = Get_hosttype_from_hostname( $hostname, $global_config );
-    my $site = Get_uniq_site_from_hostname ( $hostname, $global_config );
-    return $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'HOST'}
-                ->{'BY_NAME'}->{$hostclass}->{'deployment'}
-                ->{'hostname_model'};
-}
-
-#########################################################################
-#
-# STR Get_site_from_hostname ( STR, STR, STR, STR, HASHREF )
-#
-# This function returns the sites list for a given hostname
-# Inputs :
-#  - $hostname		: string containing the model definition for building hostname
-#  - $global_config	: hashref containing the parsed global configuration
-#
-# Output :
-#  Returns an array ref containing the sites list or undef if hostname doesn't exist
-#
-sub Get_site_from_hostname {
-    my ( $hostname, $global_config ) = @_;
-    my $site_list;
-
+    my @site_list = ();
     foreach my $site ( @{ $global_config->{'SITE'}->{'__site_list'} } ) {
         my $host_part
             = $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'HOST'}
             ->{'BY_NAME'};
         foreach my $hostclass ( keys %{$host_part} ) {
             if ( $hostclass eq $hostname ) {
-                push( @{$site_list}, $site )
-                    if( !grep( m{\A $site \z}xms, @{$site_list} ) );
+                push @site_list, $site;
                 next;
             }
+
             foreach my $host ( keys %{ $host_part->{$hostclass} } ) {
-                if( $host eq $hostname ) {
-                    push( @{$site_list}, $site )
-                        if( !grep( m{\A $site \z}xms, @{$site_list} ) );
+                if ( $host eq $hostname ) {
+                    push @site_list, $site;
                     last;
                 }
             }
         }
     }
-    return $site_list;
+
+    @site_list = uniq @site_list;
+
+    return \@site_list;
 }
 
-sub Get_zone_from_site_GLOBAL {
-    my ( $site, $global_config ) = @_;
+=head2 get_zone_from_site( $site_name, $global_config )
 
-    return $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'zone'};
+Returns a reference to the hash describing the zone for a given site.
+
+=cut
+
+sub get_zone_from_site {
+    my ( $site_name, $global_config ) = @_;
+
+    return $global_config->{'SITE'}->{'BY_NAME'}->{$site_name}->{'zone'};
 }
 
-#########################################################################
-#
-# ARRAYREF Get_site_list ( HASHREF , HASHREF )
-#
-# This function adds build the site list for a given section
-# Inputs :
-#  - $sect_hash		: hashref containing the section where site key is defined
-#  - $global_config	: hashref where is stored global configuration
-#
-# Output :
-#  Return an array reference containing the built site list.
-#
-sub Get_site_list {
-    my ( $sect_hash, $global_config ) = @_;
-    my $ref_list;
+=head2 get_site_list_from_section ( $section_ref, $global_config )
 
-    if ( $sect_hash->{'site'} eq 'ALL' ) {
+This function builds up the list of sites specified in a given section (hash).
+Returns a reference to the list.
+
+=cut
+
+sub get_site_list_from_section {
+    my ( $section_ref, $global_config ) = @_;
+
+    if ( $section_ref->{'site'} eq 'ALL' ) {
         return $global_config->{'SITE'}->{'__site_list'};
     }
-    else {
-        @{$ref_list} = split( m{\s*\,\s*}, $sect_hash->{'site'} );
-        return $ref_list;
-    }
+
+    my @site_list = split m{ \s* [,] \s* }xms, $section_ref->{'site'};
+
+# FIXME also permit '@site' notation ?
+# @site_list = ( @$section_ref->{'@site'}, split m{ \s* [,] \s* }xms, $section_ref->{'site'} );
+
+    return \@site_list;
 }
 
-#########################################################################
-#
-# VOID Get_host_config_from_CONFIG ( STR, HASHREF[, STR] )
-#
-# This function try to determine site from hostname if site is not defined
-# and return host definition from global configuration structure
-# Inputs :u
-#  - $hostname		: filename where server is parsed
-#  - $global_config	: hashref where are stored global configuration datas
-#  - $site			: define here the site where hostname is defined (optional)
-#
-sub Get_host_config_from_CONFIG {
-    my ( $hostname, $global_config, $site ) = @_;
+=head2 get_host_config( $hostname, $global_config, $site_name )
 
-    $site ||= Get_uniq_site_from_hostname( $hostname, $global_config );
+This function returns a reference to the host config hash for I<$hostname.
+I<$site_name> is optional.
 
-    my $hosttype = Get_hosttype_from_hostname( $hostname, $global_config, $site );
+=cut
 
-    my $site_part = $global_config->{'SITE'}->{'BY_NAME'}->{$site};
+sub get_host_config {
+    my ( $hostname, $global_config, $site_name ) = @_;
+
+    $site_name ||= get_uniq_site_from_hostname( $hostname, $global_config );
+
+    my $hosttype
+        = get_hosttype_from_hostname( $hostname, $global_config, $site_name );
+
+    my $site_part = $global_config->{'SITE'}->{'BY_NAME'}->{$site_name};
     my $zone      = $site_part->{'zone'};
-    my ( $hostshort, $hostvlan ) = $hostname =~ m{\A ([^.]+)(\.([^.]+))?(\.$zone)? \z}xms;
+    my ( $hostshort )
+        = $hostname =~ m{
+            \A
+                (               # -> $hostshort
+                    [^.]+       # hostname
+                )
+                (?:
+                    [.]
+                    (?:
+                        [^.]+   # vlan name
+                    )
+                )?
+                (?:
+                    [.]
+                    $zone       # zone name
+                )?
+            \z
+        }xms;
+
     unless ($hostshort) {
-        croak qq{ERROR: Unable to get hostshort/hostvlan from hostname $hostname};
+        croak
+            qq{ERROR: Unable to get hostshort from hostname $hostname};
     }
 
-    my $host_config = $site_part->{'HOST'}->{'BY_NAME'}->{$hosttype}->{$hostshort};
+    my $host_config
+        = $site_part->{'HOST'}->{'BY_NAME'}->{$hosttype}->{$hostshort};
+
     return $host_config;
 }
 
-sub Get_vlan_config_from_CONFIG {
-    my ( $vlan, $global_config, $site ) = @_;
+=head2 get_vlan_config( $vlan_name, $global_config, $site_name )
 
-    unless( $site ) {
-        carp q{ERROR: $site MUST BE defined};
-        return;
+This function returns a reference to the vlan config hash for I<$vlan_name>.
+I<$site_name> is mandatory.
+
+=cut
+
+sub get_vlan_config {
+    my ( $vlan_name, $global_config, $site_name ) = @_;
+
+    unless ($site_name) {
+        croak q{ERROR: $site MUST BE defined};
     }
-    my $site_part = $global_config->{'SITE'}->{'BY_NAME'}->{$site};
-    return $site_part->{'NETWORK'}->{'BY_NAME'}->{$vlan};
+
+    my $site_part = $global_config->{'SITE'}->{'BY_NAME'}->{$site_name};
+
+    return $site_part->{'NETWORK'}->{'BY_NAME'}->{$vlan_name};
 }
 
-sub Get_pkgtype_from_hostname {
-    my ( $hostname, $global_config, $site ) = @_;
+=head2 get_pkgtype_from_hostname( $hostname, $global_config, $site_name )
 
-    my $host_props = Get_host_config_from_CONFIG(
-        $hostname, $global_config, $site
+This function returns the pkgtype for I<$hostname>. I<$site_name> is optional.
+The only pkgtype currently implemented is 'deb'.
+
+=cut
+
+sub get_pkgtype_from_hostname {
+    my ( $hostname, $global_config, $site_name ) = @_;
+
+    my $host_props = get_host_config( $hostname, $global_config, $site_name);
+    unless ($host_props) {
+        croak qq{ERROR: $hostname: no config found};
+    }
+
+    my %pkgtype_for = (
+        debian => q{deb},
+        ubuntu => q{deb},
     );
-    return unless( $host_props );
+
     my $mode = $host_props->{'deployment'}->{'mode'};
-    if ( $mode =~ m{\A (debian|ubuntu) \z}xms ) {
-        return 'deb';
+    if (not exists $pkgtype_for{$mode}) {
+        croak qq{ERROR: Unknown/not implemented deployment mode $mode};
     }
-    else {
-        carp qq{ERROR: Unknown or not implemented deployment mode $mode};
-        return;
-    }
+
+    return $pkgtype_for{$mode};
 }
 
-sub Get_cmdline_from_hostprops {
-    my ($host_props) = @_;
-    my ( $bond_cmdline, $cmdline );
+=head2 get_cmdline_from_host_ref($host_ref)
 
-    $cmdline = $host_props->{'boot'}->{'cmdline'} || "";
-    foreach my $iface ( sort keys %{ $host_props->{'interfaces'} } ) {
-        next unless( $iface =~ m{\A bond}xms );
-        $bond_cmdline = "bonding.mode="
-            . $host_props->{'interfaces'}->{$iface}->{'mode'} . " ";
-        foreach my $opt (
-            split(
-                m{\s*,\s*}, $host_props->{'interfaces'}->{$iface}->{'options'}
-            )
-            )
+Returns a list of two elements. The second one contains the bonding-related
+part of the cmdline, the first one is the rest.
+
+=cut
+
+sub get_cmdline_from_host_ref {
+    my ($host_ref) = @_;
+
+    my $cmdline = $host_ref->{'boot'}->{'cmdline'} || q{};
+    my $bond_cmdline;
+    foreach my $iface ( sort keys %{ $host_ref->{'interfaces'} } ) {
+        next unless $iface =~ m{\A bond }xms;
+
+        $bond_cmdline
+            = qq/bonding.mode=$host_ref->{'interfaces'}->{$iface}->{'mode'}/;
+        foreach my $opt ( split m{ \s* [,] \s* }xms,
+            $host_ref->{'interfaces'}->{$iface}->{'options'} )
         {
-            $bond_cmdline .= "bonding." . $opt . " ";
+            $bond_cmdline .= qq{ bonding.$opt};
         }
-        $bond_cmdline =~ s{\s* \z}{}xms;
+
         last;
     }
+
     return ( $cmdline, $bond_cmdline );
 }
 
-sub Get_distrib_from_hostprops {
-    my ($host_props) = @_;
+=head2 get_distrib_from_host_ref($host_ref)
 
-    if ( ref $host_props ne 'HASH' ) {
-        croak q{ERROR: Invalid non-hashref $host_props};
+Returns the distribution name for the host described by I<$host_ref>.
+
+=cut
+
+sub get_distrib_from_host_ref {
+    my ($host_ref) = @_;
+
+    if ( ref $host_ref ne 'HASH' ) {
+        croak q{ERROR: Invalid non-hashref $host_ref};
     }
 
-    return $host_props->{'deployment'}->{'distrib'};
+    return $host_ref->{'deployment'}->{'distrib'};
 }
 
-sub Get_mode_from_hostprops {
-    my ($host_props) = @_;
+=head2 get_mode_from_host_ref($host_ref)
 
-    return $host_props->{'deployment'}->{'mode'};
+Returns the deployment mode for the host described by I<$host_ref>.
+
+=cut
+
+sub get_mode_from_host_ref {
+    my ($host_ref) = @_;
+
+    return $host_ref->{'deployment'}->{'mode'};
 }
 
-sub Resolv_hostname_from_GLOBAL {
-    my ( $hostname, $ip_type, $global_config, $site, $zone, $hosttype ) = @_;
-    my $resolved = [];
+=head2 resolve_hostname_from_global_config($arguments_ref)
 
-    my $zone_key = ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
-    $hostname =~ m{\A ([^.]+)(\.([^.]+))? \z}xms;
-    my ( $hostshort, $hostvlan ) = ( $1, $3 );
+Resolves (translates to an IP address) I<$hostname>, using the global
+configuration hash. Returns a reference to the list of IP addresses.
+
+I<$arguments_ref> is a reference to a hash structure containing the following
+keys:
+
+=over
+
+=item I<hostname> the hostname to resolve
+
+=item I<ip_type> ipv4 or ipv6
+
+=item I<global_config> a reference to the global pf-tools configuration hash
+
+=item I<site_name> the site name
+
+=item I<zone_name> the zone name
+
+=item I<hosttype> the hosttype
+
+=back
+
+=cut
+
+sub resolve_hostname_from_global_config {
+    my ($arguments_ref) = @_;
+
+    my @argument_names = qw(
+        hostname    ip_type     global_config
+        site_name   zone_name   hosttype
+    );
+
+    my ($hostname,  $ip_type,   $global_config,
+        $site_name, $zone_name, $hosttype
+        )
+        = @$arguments_ref{@argument_names};
+
+    my ( $hostshort, $hostvlan )
+        = $hostname =~ m{
+            \A
+                (               # -> $hostshort
+                    [^.]+
+                )
+                (?:
+                    [.]
+                    (           # -> $hostvlan
+                        [^.]+
+                    )
+                )?
+            \z
+        }xms;
+
+    my $zone_key = $ip_type eq 'ipv6' ? 'ZONE6' : 'ZONE';
     my $zone_part
-        = $global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'BY_SITE'}
-        ->{$site};
-    if( $hostname =~ m{\A (network|netmask|broadcast|gateway) }xms ) {
-        return if ( $hostvlan && !defined $zone_part->{$hostvlan} );
-        my ( $type, $field )
-            = split( m{\s+}, $zone_part->{$hostvlan}->{$hostshort} );
-        push( @{$resolved}, $field );
+        = $global_config->{$zone_key}->{'BY_NAME'}->{$zone_name}->{'BY_SITE'}
+        ->{$site_name};
+
+    if ( $hostname =~ m{\A (network|netmask|broadcast|gateway) }xms ) {
+        if ( $hostvlan and not $zone_part->{$hostvlan} ) {
+            return;
+        }
+
+        my ( $type, $field ) = split m{ \s+ }xms,
+            $zone_part->{$hostvlan}->{$hostshort};
+        return [$field];
+    }
+
+    my @fields;
+    if ( ref $zone_part->{$hosttype}->{$hostname} eq 'ARRAY' ) {
+        @fields = @{ $zone_part->{$hosttype}->{$hostname} };
     }
     else {
-        foreach my $entry ( keys %{ $zone_part->{$hosttype} } ) {
-            next if ( $entry !~ m{\A $hostname \z}xms ); # FIXME next unless $entry eq $hostname
-            my @fields;
-            if ( ref( $zone_part->{$hosttype}->{$entry} ) eq 'ARRAY' ) {
-                @fields = @{ $zone_part->{$hosttype}->{$entry} };
-            }
-            else {
-                @fields = ( $zone_part->{$hosttype}->{$entry} );
-            }
-            foreach my $line (@fields) {
-                my ( $type, $field ) = split( m{\s+}, $line );
-                if ( $type eq 'A' ) {
-                    push( @{$resolved}, $field );
+        @fields = ( $zone_part->{$hosttype}->{$hostname} );
+    }
+
+    my @result = ();
+LINE:
+    foreach my $line (@fields) {
+        my ( $type, $field ) = split m{ \s+ }xms, $line;
+        if ( $type eq 'A' ) {
+            push @result, $field;
+            next LINE;
+        }
+
+        if ( $type eq 'CNAME' ) {
+            my $cname_resolved
+                = resolve_hostname_from_global_config(
+                {
+                    hostname      => $field,
+                    ip_type       => $ip_type,
+                    global_config => $global_config,
+                    site_name     => $site_name,
+                    zone_name     => $zone_name,
+                    hosttype      => $hosttype,
                 }
-                elsif ( $type eq 'CNAME' ) {
-                    my $cname_resolved = Resolv_hostname_from_GLOBAL(
-                        $field, $global_config, $site, $zone, $hosttype
-                    );
-                    push( @{$resolved}, @{$cname_resolved} );
-                }
-            }
+                );
+            push @result, @{$cname_resolved};
+            next LINE;
         }
     }
-    return $resolved;
+
+    return \@result;
 }
 
-1;
+1;    # Magic true value required at end of module
+
diff -r d6a9b9a18fdc -r e756fd4d6365 lib/PFTools/Update/ADDMOUNT.pm
--- a/lib/PFTools/Update/ADDMOUNT.pm	Sun Nov 07 18:29:34 2010 +0100
+++ b/lib/PFTools/Update/ADDMOUNT.pm	Fri Nov 12 13:36:18 2010 +0100
@@ -70,20 +70,12 @@
 
     my $ip = $host;
     $host =~ m{\A ([^\.]+)(\..*)? \z}xms;
-    my $zone = Get_zone_from_hostname( $1, $global_config );
-    unless( $zone ) {
-        carp qq{ERROR: Unable to retrieve zone for $host};
-        return;
-    }
+    my $zone = get_zone_from_hostname( $1, $global_config );
     $ip =~ s{\.$zone \z}{}xms;
     $ip =~ m{\A ([^.]+)(\.([^.]+))? \z}xms;
     my ( $hostshort, $hostvlan ) = ( $1, $3 );
-    my $hosttype = Get_hosttype_from_hostname( $hostshort, $global_config );
-    unless( $hosttype ) {
-        carp qq{ERROR: Unable to retrieve hosttype for $host};
-        return;
-    }
-    my $site_list = Get_site_from_hostname( $hostshort, $global_config );
+    my $hosttype = get_hosttype_from_hostname( $hostshort, $global_config );
+    my $site_list = get_site_list_from_hostname( $hostshort, $global_config );
     my $site;
     if ( ! defined $site_list || scalar @{$site_list} > 1 ) {
         carp qq{ERROR: Unknown or multiple site for $host};
@@ -93,8 +85,16 @@
         $site = shift @{$site_list};
     }
     if( ! isipaddr( $ip ) ) {
-        my $resolved = Resolv_hostname_from_GLOBAL(
-            $ip, $global_config, $site, $zone, $hosttype
+        my $resolved = resolve_hostname_from_global_config(
+            {
+                hostname      => $ip,
+                global_config => $global_config,
+                site_name     => $site,
+                zone_name     => $zone,
+                hosttype      => $hosttype,
+
+                # FIXME ip_type => ????,
+            }
         );
         if ( ! defined $resolved || scalar @{$resolved} > 1 ) {
             carp qq{ERROR: Unknown or multiple IPs for $host};
diff -r d6a9b9a18fdc -r e756fd4d6365 lib/PFTools/Utils.pm
--- a/lib/PFTools/Utils.pm	Sun Nov 07 18:29:34 2010 +0100
+++ b/lib/PFTools/Utils.pm	Fri Nov 12 13:36:18 2010 +0100
@@ -49,7 +49,6 @@
     Mk_zone_for_site
     Change_kopt_for_hostname
 
-    Resolv_hostname_from_GLOBAL
     Search_and_replace
 );
 
@@ -196,7 +195,7 @@
         $pf_script, $pf_config )
         = @_;
 
-    my $iface = Get_iface_vlan_from_hostname(
+    my $iface = get_iface_vlan_from_hostname(
         $host_props->{'deployment'}->{'dhcpvlan'}, $host_props );
     my $mac           = $host_props->{'interfaces'}->{$iface}->{'mac'};
     my $pxe_boot_file = $mac;
@@ -217,7 +216,7 @@
     );
     my $preseed_md5 = Get_MD5SUM_for_preseedfile( $preseed, $pf_config );
     my $tpl = Template::Tiny->new( TRIM => 1 );
-    my $cmdline = join( " ", Get_cmdline_from_hostprops($host_props) );
+    my $cmdline = join q{ }, get_cmdline_from_host_ref($host_props);
     $cmdline    =~ s{\A \s*}{}xms;
     my $pxe_subst = {
         'iface'   => $iface,
@@ -414,18 +413,12 @@
 sub Mk_resolvconf {
     my ( $hostname, $global_config, $site, $output ) = @_;
 
-    my $host_props = Get_host_config_from_CONFIG(
-        $hostname, $global_config, $site
-    );
+    my $host_props = get_host_config( $hostname, $global_config, $site );
     unless( $host_props ) {
         carp qq{ERROR: Unknown hostname $hostname on site $site};
         return;
     }
-    my $domain = Get_zone_from_hostname( $hostname, $global_config, $site );
-    unless( $domain ) {
-        carp qq{ERROR: Unable to get domain from hostname $hostname};
-        return;
-    }
+    my $domain = get_zone_from_hostname( $hostname, $global_config, $site );
 
     my @dns = split( m{\s*,\s*}, $host_props->{'dns'}->{'resolver'} );
 
@@ -468,37 +461,37 @@
         return;
     }
     if ( $type_resolve eq 'cnf' ) {
-        $site ||= Get_uniq_site_from_hostname( $hostname, $global_config );
-        unless( $site ) {
-            carp qq{ERROR: Invalid site from hostname $hostname};
-            return;
-        }
-        my $zone = Get_zone_from_hostname( $hostname, $global_config, $site );
+        $site ||= get_uniq_site_from_hostname( $hostname, $global_config );
+        my $zone = get_zone_from_hostname( $hostname, $global_config, $site );
         $hostname =~ s{\.$zone \z}{}xms;
         $hostname =~ m{\A ([^.]+)(\.([^.]+))? \z}xms;
         my ( $hostshort, $hostvlan ) = ( $1, $3 );
-        if ( !defined $hosttype
-            && $hostshort !~ m{\A (network|netmask|broadcast|gateway|prefix)}xms )
+        if (!defined $hosttype
+            && $hostshort
+            !~ m{\A (network|netmask|broadcast|gateway|prefix)}xms
+            )
         {
-            $hosttype = Get_hosttype_from_hostname(
-                $hostshort, $global_config, $site
-            );
-            unless( $hosttype ) {
-                carp qq{ERROR: Unable to retrieve hosttype from $hostname};
-                return;
-            }
+            $hosttype
+                = get_hosttype_from_hostname( $hostshort, $global_config,
+                $site );
         }
         elsif( $hostshort =~ m{\A prefix \z}xms ) {
-            my $vlan_def = Get_vlan_config_from_CONFIG(
-                $hostvlan, $global_config, $site
-            );
+            my $vlan_def
+                = get_vlan_config( $hostvlan, $global_config, $site );
             my $netblock = get_netblock_from_vlan( $ip_type, $vlan_def );
             my $prefix   = $netblock->cidr();
             $prefix      =~ s{\A [^/]+\/([\d]+) \z}{$1}xms;
             return [ $prefix ];
         }
-        return Resolv_hostname_from_GLOBAL(
-            $hostname, $ip_type, $global_config, $site, $zone, $hosttype
+        return resolve_hostname_from_global_config(
+            {
+                hostname      => $hostname,
+                ip_type       => $ip_type,
+                global_config => $global_config,
+                site_name     => $site,
+                zone_name     => $zone,
+                hosttype      => $hosttype,
+            }
         );
     }
     else {
@@ -593,7 +586,7 @@
         my $vlan2 = $vlan;
         $vlan2 =~ s{POPNAME}{$hash_subst->{'POPNAME'}};
 
-        my $eth = Get_iface_vlan_from_hostname( $vlan2, $host_props );
+        my $eth = get_iface_vlan_from_hostname( $vlan2, $host_props );
 
         if( defined $eth ) {
             my $neweth = $eth;
@@ -624,13 +617,10 @@
         carp q{ERROR: Unable to resolve from configuration};
         return;
     }
-    my $hosttype = Get_hosttype_from_hostname(
-        $hostname, $global_config, $site
-    );
+    my $hosttype
+        = get_hosttype_from_hostname( $hostname, $global_config, $site );
     my $subst = Init_SUBST( $hostname, $hosttype, $pf_config );
-    my $host_props = Get_host_config_from_CONFIG(
-        $hostname, $global_config, $site
-    );
+    my $host_props = get_host_config( $hostname, $global_config, $site );
 
     my $input_hl = IO::File->new( $input_file );
     unless( $input_hl ) {
@@ -676,14 +666,12 @@
     @{$tmp_hosts} = <$input_hl>;
     $input_hl->close();
 
-    my $host_props = Get_host_config_from_CONFIG(
-        $hostname, $global_config, $site
-    );
+    my $host_props = get_host_config( $hostname, $global_config, $site );
     unless( $host_props ) {
         carp qq{ERROR: Unknown hostname $hostname};
         return;
     }
-    my $iface_dhcpvlan = Get_iface_vlan_from_hostname(
+    my $iface_dhcpvlan = get_iface_vlan_from_hostname(
         $host_props->{'deployment'}->{'dhcpvlan'}, $host_props
     );
     my $ip_deploy = $host_props->{'interfaces'}->{$iface_dhcpvlan}->{'ipv4'};
@@ -742,9 +730,7 @@
         $global_config, $pf_config )
         = @_;
 
-    my $host_props = Get_host_config_from_CONFIG(
-        $hostname, $global_config, $site
-    );
+    my $host_props = get_host_config( $hostname, $global_config, $site );
     unless( $host_props ) {
         croak qq{ERROR: Unknown $hostname on $site};
     }
@@ -797,14 +783,12 @@
         = @_;
     my $tmp_grub = [];
 
-    my $host_props = Get_host_config_from_CONFIG(
-        $hostname, $global_config, $site
-    );
+    my $host_props = get_host_config( $hostname, $global_config, $site );
     unless( $host_props ) {
         croak qq{ERROR: Unknown $hostname on $site};
     }
     my $mode = $host_props->{'deployment'}->{'mode'};
-    my $cmdline = join( " ", Get_cmdline_from_hostprops($host_props) );
+    my $cmdline = join q{ }, get_cmdline_from_host_ref($host_props);
     $cmdline =~ s{\A\s*}{}; # Removing trailing space
     $grub_version = "" if ( $grub_version == 1 );
 
@@ -863,9 +847,7 @@
     my ( $hostname, $global_config, $pf_config, $site ) = @_;
 
     my $resolve = 0;
-    my $properties = Get_host_config_from_CONFIG(
-        $hostname, $global_config, $site
-    );
+    my $properties = get_host_config( $hostname, $global_config, $site );
     unless( $properties ) {
         carp qq{ERROR: Unknown $hostname on $site};
         return;
@@ -1100,27 +1082,17 @@
         croak q{ERROR: "Unable to checkout configuration from VCS system"};
     }
 #    Unset_deferredlog();
-    my $hosttype = Get_hosttype_from_hostname(
-        $hostname, $global_config, $site
-    );
+    my $hosttype
+        = get_hosttype_from_hostname( $hostname, $global_config, $site );
     my $hash_subst = Init_SUBST( $hostname, $hosttype, $pf_config );
-    my $host_props = Get_host_config_from_CONFIG(
-        $hostname, $global_config, $site
-    );
+    my $host_props = get_host_config( $hostname, $global_config, $site );
     unless( $host_props ) {
         croak qq{ERROR: Unknown hostname $hostname};
     }
-    $hash_subst->{'DISTRIB'} = Get_distrib_from_hostprops( $host_props );
-    $hash_subst->{'MODE'}    = Get_mode_from_hostprops( $host_props );
-    if ( !defined $options->{'pkg_type'} ) {
-        unless ( 
-            $options->{'pkg_type'} = Get_pkgtype_from_hostname(
-                $hostname, $global_config, $site
-            )
-        ) {
-            croak qq{ERROR: Unable to retrieve package type from $hostname};
-        }
-    }
+    $hash_subst->{'DISTRIB'} = get_distrib_from_host_ref($host_props);
+    $hash_subst->{'MODE'}    = get_mode_from_host_ref($host_props);
+    $options->{'pkg_type'}
+        ||= get_pkgtype_from_hostname( $hostname, $global_config, $site );
     my $host_config = Get_config_for_hostname_on_site(
         $hostname, $site, $hash_subst, $global_config, $pf_config
     );
diff -r d6a9b9a18fdc -r e756fd4d6365 sbin/fix_hosts
--- a/sbin/fix_hosts	Sun Nov 07 18:29:34 2010 +0100
+++ b/sbin/fix_hosts	Fri Nov 12 13:36:18 2010 +0100
@@ -100,7 +100,7 @@
 
 unless( $options->{'site'} ) {
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
-        || Get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
+        || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
 }
 
 my $fixed_input = Fix_hosts(
diff -r d6a9b9a18fdc -r e756fd4d6365 sbin/mk_grubopt
--- a/sbin/mk_grubopt	Sun Nov 07 18:29:34 2010 +0100
+++ b/sbin/mk_grubopt	Fri Nov 12 13:36:18 2010 +0100
@@ -93,7 +93,7 @@
 
 unless( $options->{'site'} ) {
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
-        || Get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
+        || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
 }
 
 unless( $GLOBAL_STRUCT->{'DHCP'}->{'BY_SITE'}->{$options->{'site'}} ) {
diff -r d6a9b9a18fdc -r e756fd4d6365 sbin/mk_interfaces
--- a/sbin/mk_interfaces	Sun Nov 07 18:29:34 2010 +0100
+++ b/sbin/mk_interfaces	Fri Nov 12 13:36:18 2010 +0100
@@ -96,7 +96,7 @@
 
 unless( $options->{'site'} ) {
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
-        || Get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
+        || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
 }
 
 my $iface = Mk_interfaces(
diff -r d6a9b9a18fdc -r e756fd4d6365 sbin/mk_resolvconf
--- a/sbin/mk_resolvconf	Sun Nov 07 18:29:34 2010 +0100
+++ b/sbin/mk_resolvconf	Fri Nov 12 13:36:18 2010 +0100
@@ -89,7 +89,7 @@
 
 unless( $options->{'site'} ) {
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
-        || Get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
+        || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
 }
 
 unless(
diff -r d6a9b9a18fdc -r e756fd4d6365 sbin/mk_sourceslist
--- a/sbin/mk_sourceslist	Sun Nov 07 18:29:34 2010 +0100
+++ b/sbin/mk_sourceslist	Fri Nov 12 13:36:18 2010 +0100
@@ -128,7 +128,7 @@
 
 unless( $options->{'site'} ) {
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
-        || Get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
+        || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
 }
 
 $options->{'add'} =~ s{,}{ }g;
diff -r d6a9b9a18fdc -r e756fd4d6365 sbin/update-config
--- a/sbin/update-config	Sun Nov 07 18:29:34 2010 +0100
+++ b/sbin/update-config	Fri Nov 12 13:36:18 2010 +0100
@@ -85,7 +85,7 @@
 }
 
 $options->{'site'} ||= $PF_CONFIG->{'location'}->{'site'}
-    || Get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
+    || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
 
 if ( $options->{'quiet'} ) {
     print qq{$program started in quiet mode...\n};
diff -r d6a9b9a18fdc -r e756fd4d6365 t/13.conf.cfg1/config-export/COMMON/private-network
--- a/t/13.conf.cfg1/config-export/COMMON/private-network	Sun Nov 07 18:29:34 2010 +0100
+++ b/t/13.conf.cfg1/config-export/COMMON/private-network	Fri Nov 12 13:36:18 2010 +0100
@@ -37,6 +37,7 @@
     dhcpvlan    = vlan-systeme
     console     = default
     zone        = private
+#    prefix	= cbv4
 
 [vip-spawn]
     type                = server
@@ -97,3 +98,9 @@
     site    = cbv4-pfds
     @host   = CONFSITE_cbv4-pfds:/hostfile-cbv4-spawn
 
+[admins-cbv4]
+    type    = service
+    comment = Administration hosts (CBV4)
+    site    = cbv4
+    @host   = CONFSITE_cbv4:/hostfile-cbv4-rdeploy
+
diff -r d6a9b9a18fdc -r e756fd4d6365 t/13.conf.cfg1/config-export/MODEL/model-rdeploy
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/t/13.conf.cfg1/config-export/MODEL/model-rdeploy	Fri Nov 12 13:36:18 2010 +0100
@@ -0,0 +1,36 @@
+[hostgroup]
+    comment     = Model for rdeploy servers
+    site        = cbv4
+
+[boot]
+    kernel      = vmlinuz-2.6.26.5-universal-grm2.1.12
+    kerneluml   = linux-uml-elf-2.4.26-gr1.9.15
+    pxefilename = pxelinux.0
+    console     = default
+#   cmdline     = pci=bfsort
+
+[dns]
+    shortname   = vlan-systeme
+    resolver    = nsprivate.private,spawn.private
+
+[interface::eth0]
+    vlan        = vlan-systeme
+
+#[interface::eth0.TAG1]
+#    vlan        = vlan-admindsi
+
+#[interface::eth5]
+#    vlan        = vlan-middledsi
+
+#[interface::bond0]
+#    options     = miimon=100
+#    mode        = active-backup
+#    slaves      = eth2,eth3
+#    @route      = default via GATEWAY
+#    vlan        = vlan-pfds-ext
+
+[deployment]
+    mode        = debian
+    arch        = amd64
+    distrib     = lenny
+
diff -r d6a9b9a18fdc -r e756fd4d6365 t/13.conf.cfg1/config-export/SITE/cbv4-pfds/CONFIG/hostfile-cbv4-spawn
--- a/t/13.conf.cfg1/config-export/SITE/cbv4-pfds/CONFIG/hostfile-cbv4-spawn	Sun Nov 07 18:29:34 2010 +0100
+++ b/t/13.conf.cfg1/config-export/SITE/cbv4-pfds/CONFIG/hostfile-cbv4-spawn	Fri Nov 12 13:36:18 2010 +0100
@@ -26,9 +26,9 @@
 	mac.0 = 00:1e:c9:ff:08:e3
 #	vlan = vlan-systeme
 
-#[interface::eth0.TAG1]
-#	vlan	= vlan-pfds-int
-#	ipv4	= 167.0
+[interface::eth0.TAG1]
+	vlan	= vlan-pfds-int
+	ipv4	= 167.0
 
 [hostgroup]
 	model		= MODSITE_cbv4-pfds:/model-cbv4-pfds
diff -r d6a9b9a18fdc -r e756fd4d6365 t/13.conf.cfg1/config-export/SITE/cbv4/CONFIG/hostfile-cbv4-rdeploy
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/t/13.conf.cfg1/config-export/SITE/cbv4/CONFIG/hostfile-cbv4-rdeploy	Fri Nov 12 13:36:18 2010 +0100
@@ -0,0 +1,24 @@
+[dns]
+#	shortname = vlan-systeme
+	alias.ntp = vlan-systeme
+#	resolver = nsprivate.private,spawn.private
+	alias.filer = vlan-systeme
+
+[interface::eth0]
+	ipv4 = 167.0
+	mac.0 = 00:1e:c9:ff:08:e4
+	mac.1 = 00:1e:c9:ff:42:0b
+	vlan = vlan-systeme
+
+#[interface::eth0.TAG1]
+#	ipv4	= 111.167.0
+#	vlan	= vlan-admindsi
+
+[hostgroup]
+	model		= MOD:model-rdeploy
+	number		= 2
+	comment		= Rdeploy server
+	order 		= 1
+	hostname	= cbv4-rdeploy%%
+#	site		= cbv4
+
diff -r d6a9b9a18fdc -r e756fd4d6365 t/13.conf.t
--- a/t/13.conf.t	Sun Nov 07 18:29:34 2010 +0100
+++ b/t/13.conf.t	Fri Nov 12 13:36:18 2010 +0100
@@ -40,7 +40,9 @@
 is PFTools::Conf::__sort_net_section( $parsed_net, 'foo', 'bar' ), 1
     => 'Returns 1 if inversed order';
 
-my @ordered = sort { PFTools::Conf::__sort_net_section( $parsed_net, $a, $b ) } qw( foo bar baz );
+my @ordered
+    = sort { PFTools::Conf::__sort_net_section( $parsed_net, $a, $b ) }
+    qw( foo bar baz );
 my @expected_order = qw( bar foo baz );
 is_deeply \@ordered, \@expected_order
     => 'Sorts correctly';
@@ -65,10 +67,10 @@
 my $config = Init_PF_CONFIG();
 is_deeply $config, $default_pf_config
     => q{Returns the default config}
-        or note explain $config;
+    or note explain $config;
 
-throws_ok { Init_PF_CONFIG( '/non-existent-file' ) }
-    qr{\A ERROR: }xms
+throws_ok { Init_PF_CONFIG('/non-existent-file') }
+qr{\A ERROR: }xms
     => 'Dies with error message if non-existent configuration file';
 
 my $test_config_file = '/tmp/test_configuration';
@@ -86,19 +88,20 @@
 
 my $test_configuration = {
     debian => {
+
         # fake => 'value', # this one ignored: unknown key
         preseed => 'mypreseed',
     },
 };
 
 throws_ok { Init_PF_CONFIG($test_config_file) }
-    qr{\A ERROR: }xms
+qr{\A ERROR: }xms
     => 'Dies with error message if configuration file has bad permissions';
 
 chmod 0600, $test_config_file
     or die qq{chmod $test_config_file: $OS_ERROR};
 
-my $parsed_configuration = Init_PF_CONFIG( $test_config_file );
+my $parsed_configuration = Init_PF_CONFIG($test_config_file);
 ok ref $parsed_configuration eq 'HASH' && keys %{$parsed_configuration}
     => 'Returns a non-empty hashref';
 
@@ -112,7 +115,7 @@
     => 'Correctly sets $PF_CONFIG'
     or note explain $current_pf_config;
 
-$parsed_configuration = Init_PF_CONFIG( );
+$parsed_configuration = Init_PF_CONFIG();
 is_deeply $parsed_configuration, $expected_configuration
     => q{Correctly returns the real configuration on subsequent implicit calls}
     or note explain $parsed_configuration;
@@ -128,28 +131,28 @@
 
 $test_configuration = {
     path => {
-        status_dir      => q{/tmp/pf-test/var/lib/pf-tools},
-        distrib_dir     => q{/tmp/pf-test/distrib},
-        tftp_dir        => q{/tmp/pf-test/distrib/tftpboot},
-        pxefiles_dir    => q{/tmp/pf-test/distrib/tftpboot/pxelinux.cfg},
-        global_struct   => q{/tmp/pf-test/var/lib/pf-tools/global.stor},
-        deploy_docroot  => q{/tmp/pf-test/var/www},
-        preseed_dir     => q{/tmp/pf-test/var/www/preseed},
-        checkout_dir    => q{/tmp/pf-test/var/lib/cvsguest},
-        templates_dir   => q{/tmp/pf-test/usr/share/pf-tools/templates},
-        common_config   => q{update-common},
-        start_file      => q{private-network},
+        status_dir     => q{/tmp/pf-test/var/lib/pf-tools},
+        distrib_dir    => q{/tmp/pf-test/distrib},
+        tftp_dir       => q{/tmp/pf-test/distrib/tftpboot},
+        pxefiles_dir   => q{/tmp/pf-test/distrib/tftpboot/pxelinux.cfg},
+        global_struct  => q{/tmp/pf-test/var/lib/pf-tools/global.stor},
+        deploy_docroot => q{/tmp/pf-test/var/www},
+        preseed_dir    => q{/tmp/pf-test/var/www/preseed},
+        checkout_dir   => q{/tmp/pf-test/var/lib/cvsguest},
+        templates_dir  => q{/tmp/pf-test/usr/share/pf-tools/templates},
+        common_config  => q{update-common},
+        start_file     => q{private-network},
     },
     vcs => {
-        vcsroot         => q{/tmp/pf-test/var/lib/cvs/repository},
+        vcsroot => q{/tmp/pf-test/var/lib/cvs/repository},
     },
     location => {
-        site            => q{cbv4-pfds},
-        zone            => q{private},
+        site => q{cbv4-pfds},
+        zone => q{private},
     },
 };
 $expected_configuration = merge( $default_pf_config, $test_configuration );
-$parsed_configuration = Init_PF_CONFIG( $test_config_file );
+$parsed_configuration = Init_PF_CONFIG($test_config_file);
 is_deeply $parsed_configuration, $expected_configuration
     => qq{File $test_config_file correctly merged with the default configuration}
     or note explain $parsed_configuration;
@@ -160,7 +163,7 @@
 
 # Restore the default configuration for the other tests
 reset_pf_config();
-$parsed_configuration = Init_PF_CONFIG( );
+$parsed_configuration = Init_PF_CONFIG();
 is_deeply $parsed_configuration, $default_pf_config
     => q{Correctly restores the default configuration}
     or note explain $parsed_configuration;
@@ -171,14 +174,14 @@
 can_ok( 'PFTools::Conf', qw( Init_SUBST ) );
 
 throws_ok { Init_SUBST( undef, { foo => 1 } ) }
-    qr{\A ERROR: [ ] Hosttype [ ] parameter [ ] must [ ] be [ ] a [ ] string }xms
+qr{\A ERROR: [ ] Hosttype [ ] parameter [ ] must [ ] be [ ] a [ ] string }xms
     => 'Dies if $hosttype specified but not a scalar';
 
 lives_ok { Init_SUBST( undef, 'foo' ) }
-    'Accepts a scalar for $hosttype';
+'Accepts a scalar for $hosttype';
 
-throws_ok { Init_SUBST( '1nvalid_hostname!' ) }
-    qr{\A ERROR: [ ] Invalid [ ] hostname }xms
+throws_ok { Init_SUBST('1nvalid_hostname!') }
+qr{\A ERROR: [ ] Invalid [ ] hostname }xms
     => 'Dies if invalid $hostname';
 
 # OS_RELEASE is always taken from the local host
@@ -187,49 +190,50 @@
 # FIXME: add real tests for HOSTCLUSTER et HOSTNODEINDEX
 my $expected_subst_for = {
     'abv1-ncdn-lvs00' => {
-        'HOSTMINUTE' => 0,
-        'HOSTDIGITS' => '00',
-        'HOSTNUM' => 0,
-        'HOSTNAME' => 'abv1-ncdn-lvs00',
+        'HOSTMINUTE'    => 0,
+        'HOSTDIGITS'    => '00',
+        'HOSTNUM'       => 0,
+        'HOSTNAME'      => 'abv1-ncdn-lvs00',
         'HOSTNODEINDEX' => '',
-        'DOMAINNAME' => 'private',
-        'OS_RELEASE' => $os_release,
-        'HOSTHOUR' => 0,
-        'HOSTTYPE' => 'abv1-ncdn-lvs',
-        'HOSTCLUSTER' => '00',
-        'POPNAME' => 'abv1'
+        'DOMAINNAME'    => 'private',
+        'OS_RELEASE'    => $os_release,
+        'HOSTHOUR'      => 0,
+        'HOSTTYPE'      => 'abv1-ncdn-lvs',
+        'HOSTCLUSTER'   => '00',
+        'POPNAME'       => 'abv1'
     },
     'cor1-spawn00' => {
-        'HOSTMINUTE' => 0,
-        'HOSTDIGITS' => '00',
-        'HOSTNUM' => 0,
-        'HOSTNAME' => 'cor1-spawn00',
+        'HOSTMINUTE'    => 0,
+        'HOSTDIGITS'    => '00',
+        'HOSTNUM'       => 0,
+        'HOSTNAME'      => 'cor1-spawn00',
         'HOSTNODEINDEX' => '',
-        'DOMAINNAME' => 'private',
-        'OS_RELEASE' => $os_release,
-        'HOSTHOUR' => 0,
-        'HOSTTYPE' => 'cor1-spawn',
-        'HOSTCLUSTER' => '00',
-        'POPNAME' => 'cor1'
+        'DOMAINNAME'    => 'private',
+        'OS_RELEASE'    => $os_release,
+        'HOSTHOUR'      => 0,
+        'HOSTTYPE'      => 'cor1-spawn',
+        'HOSTCLUSTER'   => '00',
+        'POPNAME'       => 'cor1'
     },
     'cor1-spawn01' => {
-        'HOSTMINUTE' => 1,
-        'HOSTDIGITS' => '01',
-        'HOSTNUM' => 1,
-        'HOSTNAME' => 'cor1-spawn01',
+        'HOSTMINUTE'    => 1,
+        'HOSTDIGITS'    => '01',
+        'HOSTNUM'       => 1,
+        'HOSTNAME'      => 'cor1-spawn01',
         'HOSTNODEINDEX' => '',
-        'DOMAINNAME' => 'private',
-        'OS_RELEASE' => $os_release,
-        'HOSTHOUR' => 1,
-        'HOSTTYPE' => 'cor1-spawn',
-        'HOSTCLUSTER' => '01',
-        'POPNAME' => 'cor1'
+        'DOMAINNAME'    => 'private',
+        'OS_RELEASE'    => $os_release,
+        'HOSTHOUR'      => 1,
+        'HOSTTYPE'      => 'cor1-spawn',
+        'HOSTCLUSTER'   => '01',
+        'POPNAME'       => 'cor1'
     },
 };
 
-foreach my $hostname ( keys %{ $expected_subst_for } ) {
+foreach my $hostname ( keys %{$expected_subst_for} ) {
+
     # we must fake the 'private' domainname
-    my $got = Init_SUBST($hostname, undef, undef, 'private');
+    my $got = Init_SUBST( $hostname, undef, undef, 'private' );
     is_deeply $got, $expected_subst_for->{$hostname}
         => qq{Returns the correct information for host $hostname}
         or note explain $got;
@@ -240,17 +244,17 @@
 can_ok( 'PFTools::Conf', qw( Get_source ) );
 
 throws_ok { Get_source() }
-    qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] source }xms
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] source }xms
     => 'Dies if empty/undef $source';
 
 throws_ok { Get_source( q{foo bar baz}, undef, q{non-hashref $hash_subst} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-href [ ] [\$] hash_subst }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-href [ ] [\$] hash_subst }xms
     => q{Dies on non-hashref $hash_subst};
 
 throws_ok {
     Get_source( q{foo bar baz}, undef, undef, q{non-hashref $pf_config} );
 }
-    qr{ \A ERROR: [ ] Invalid [ ] non-href [ ] [\$] pf_config }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-href [ ] [\$] pf_config }xms
     => q{Dies on non-hashref $pf_config};
 
 throws_ok {
@@ -260,33 +264,35 @@
     => q{Dies on invalid $pf_config (no path.checkout_dir)};
 
 throws_ok {
-    Get_source( q{foo bar baz}, undef, undef,
-        { path => { checkout_dir => '/tmp/co_dir' } } );
+    Get_source(
+        q{foo bar baz}, undef, undef,
+        { path => { checkout_dir => '/tmp/co_dir' } }
+    );
 }
 qr{ \A ERROR: [ ] Undefined [ ] configuration [ ] parameter: [ ] vcs.module}xms
     => q{Dies on invalid $pf_config (no vcs.module)};
 
-is Get_source( q{MODSITE_FOOBAR:/my/path/to/file} ),
+is Get_source(q{MODSITE_FOOBAR:/my/path/to/file}),
     q{/var/lib/cvsguest/config/SITE/FOOBAR/MODEL/my/path/to/file}
     => q{Good result for MODSITE_*:};
 
-is Get_source( q{MOD:/my/path/to/file} ),
+is Get_source(q{MOD:/my/path/to/file}),
     q{/var/lib/cvsguest/config/MODEL/my/path/to/file}
     => q{Good result for MOD:};
 
-is Get_source( q{CONFSITE_FOOBAR:/my/path/to/file} ),
+is Get_source(q{CONFSITE_FOOBAR:/my/path/to/file}),
     q{/var/lib/cvsguest/config/SITE/FOOBAR/CONFIG/my/path/to/file}
     => q{Good result for CONFSITE_*:};
 
-is Get_source( q{CONF:/my/path/to/file} ),
+is Get_source(q{CONF:/my/path/to/file}),
     q{/var/lib/cvsguest/config/CONFIG/my/path/to/file}
     => q{Good result for CONF:};
 
-is Get_source( q{SITE_FOOBAR:/my/path/to/file} ),
+is Get_source(q{SITE_FOOBAR:/my/path/to/file}),
     q{/var/lib/cvsguest/config/SITE/FOOBAR/my/path/to/file}
     => q{Good result for SITE_*:};
 
-is Get_source( q{SITE:/my/path/to/file} ),
+is Get_source(q{SITE:/my/path/to/file}),
     q{/var/lib/cvsguest/config/SITE/my/path/to/file}
     => q{Good result for SITE:};
 
@@ -302,23 +308,23 @@
     q{/var/lib/cvsguest/config/myhost/my/path/to/file.00}
     => q{Good result for HOST: and %HOSTDIGITS%};
 
-is Get_source( q{COMMON:/my/path/to/file} ),
+is Get_source(q{COMMON:/my/path/to/file}),
     q{/var/lib/cvsguest/config/COMMON/my/path/to/file}
     => q{Good result for COMMON:};
 
-is Get_source( q{CONFIG:/my/path/to/file} ),
+is Get_source(q{CONFIG:/my/path/to/file}),
     q{/var/lib/cvsguest/config/my/path/to/file}
     => q{Good result for CONFIG:/};
 
-is Get_source( q{CONFIG:my/path/to/file} ),
+is Get_source(q{CONFIG:my/path/to/file}),
     q{/var/lib/cvsguest/config/my/path/to/file}
     => q{Good result for CONFIG:};
 
-is Get_source( q{CVS:config/my/path/to/file} ),
+is Get_source(q{CVS:config/my/path/to/file}),
     q{/var/lib/cvsguest/config/my/path/to/file}
     => q{Good result for CVS:};
 
-is Get_source( q{GLOBAL:/my/path/to/file} ),
+is Get_source(q{GLOBAL:/my/path/to/file}),
     q{/var/lib/cvsguest/config/GLOBAL/my/path/to/file}
     => q{Good result for CONFIG:};
 
@@ -329,21 +335,32 @@
 ok !defined PFTools::Conf::__get_config_path()
     => 'Returns undef if no args';
 
-throws_ok { PFTools::Conf::__get_config_path( { foo => 'bar' }, { pf => 'config' }, 'site' ) }
-    qr{ \A ERROR: }xms
+throws_ok {
+    PFTools::Conf::__get_config_path( { foo => 'bar' },
+        { pf => 'config' }, 'site' );
+}
+qr{ \A ERROR: }xms
     => q{Dies if non-scalar $host_value};
 
-throws_ok { PFTools::Conf::__get_config_path( 'host_value', { pf => 'config' }, { foo => 'bar' } ) }
-    qr{ \A ERROR: }xms
+throws_ok {
+    PFTools::Conf::__get_config_path(
+        'host_value',
+        { pf  => 'config' },
+        { foo => 'bar' }
+    );
+}
+qr{ \A ERROR: }xms
     => q{Dies if non-scalar $site};
 
-throws_ok { PFTools::Conf::__get_config_path( 'host_value', 'pf_config', 'site' ) }
-    qr{ \A ERROR: }xms
+throws_ok {
+    PFTools::Conf::__get_config_path( 'host_value', 'pf_config', 'site' );
+}
+qr{ \A ERROR: }xms
     => q{Dies if non-href $pf_config};
 
 my $pf_config_overrides = {
     path => {
-        status_dir => '/tmp/pftools-conf-test/status_dir',
+        status_dir   => '/tmp/pftools-conf-test/status_dir',
         checkout_dir => '/tmp/pftools-conf-test/checkout_dir',
     },
     location => {
@@ -351,14 +368,19 @@
     },
 };
 my $pf_config = clone_merge( $default_pf_config, $pf_config_overrides );
-ok !defined PFTools::Conf::__get_config_path( 'unknown-host', $pf_config, 'unknown-site' )
+ok !
+    defined PFTools::Conf::__get_config_path( 'unknown-host', $pf_config,
+    'unknown-site' )
     => q{Returns undef if no matching file found};
 
-make_path( qw(
-    /tmp/pftools-conf-test/checkout_dir/config/SITE/test-site/CONFIG
-    /tmp/pftools-conf-test/checkout_dir/config/CONFIG
-) );
-my $site_config_file = q{/tmp/pftools-conf-test/checkout_dir/config/SITE/test-site/CONFIG/update-mytest};
+make_path(
+    qw(
+        /tmp/pftools-conf-test/checkout_dir/config/SITE/test-site/CONFIG
+        /tmp/pftools-conf-test/checkout_dir/config/CONFIG
+        )
+);
+my $site_config_file
+    = q{/tmp/pftools-conf-test/checkout_dir/config/SITE/test-site/CONFIG/update-mytest};
 $fh = IO::File->new( $site_config_file, '>' )
     or die "open $site_config_file: $OS_ERROR";
 $fh->print( <<'EOT' )
@@ -374,13 +396,14 @@
     $site_config_file
     => q{Returns the site specific file if it exists};
 
-my $global_config_file = q{/tmp/pftools-conf-test/checkout_dir/config/CONFIG/update-mytest};
+my $global_config_file
+    = q{/tmp/pftools-conf-test/checkout_dir/config/CONFIG/update-mytest};
 move( $site_config_file, $global_config_file );
 is PFTools::Conf::__get_config_path( 'mytest', $pf_config, 'test-site' ),
     $global_config_file
     => q{Returns the global file if no site-specific file found};
 unlink $global_config_file;
-remove_tree( qw( /tmp/pftools-conf-test/ ) );
+remove_tree(qw( /tmp/pftools-conf-test/ ));
 
 
 ########################################################################
@@ -388,54 +411,59 @@
 can_ok( 'PFTools::Conf', qw( Load_conf ) );
 
 throws_ok { Load_conf() }
-    qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] file }xms
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] file }xms
     => q{Dies if empty $file};
 
 throws_ok { Load_conf( 'file', {} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] context }xms
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] context }xms
     => q{Dies if empty $context};
 
 throws_ok { Load_conf( {}, {}, 'context', {} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] file }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] file }xms
     => q{Dies if non-scalar $file};
 
 throws_ok { Load_conf( 'file', {}, {}, {} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] context }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] context }xms
     => q{Dies if non-scalar $context};
 
 throws_ok { Load_conf( 'file', 'subst', 'context', {} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] hash_subst }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] hash_subst }xms
     => q{Dies if non-hashref $hash_subst};
 
 throws_ok { Load_conf( 'file', {}, 'context', 'pf_config' ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] pf_config }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] pf_config }xms
     => q{Dies if non-hashref $pf_config};
 
 throws_ok { Load_conf( 'file', {}, 'context', {} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] context [ ] }xms
+qr{ \A ERROR: [ ] Invalid [ ] context [ ] }xms
     => q{Dies if invalid $context};
 
 throws_ok { Load_conf( 'inexistent file', {}, 'config', $pf_config ) }
-    qr{ \A ERROR: [ ] Unable [ ] to [ ] load [ ] }xms
+qr{ \A ERROR: [ ] Unable [ ] to [ ] load [ ] }xms
     => q{Dies if inexistent $file};
 
 # Let's go back to our test configuration
 $test_config_file = 't/13.conf.cfg1/etc/pf-tools.1.conf';
-my $test_pf_config = Init_PF_CONFIG( $test_config_file ); # already tested OK above
+my $test_pf_config
+    = Init_PF_CONFIG($test_config_file);    # already tested OK above
 
-my $cwd = getcwd;
+my $cwd             = getcwd;
 my $test_config_dir = qq{$cwd/t/13.conf.cfg1};
-my $test_hostname = hostname;
-my $test_hash_subst = Init_SUBST($test_hostname, undef, $test_pf_config, 'private');
+my $test_hostname   = hostname;
+my $test_hash_subst
+    = Init_SUBST( $test_hostname, undef, $test_pf_config, 'private' );
 
 # bypass cvs/svn/whatever for the moment
 unlink q{/tmp/pf-test/var/lib/cvsguest/config};
-make_path( q{/tmp/pf-test/var/lib/cvsguest} );
-symlink qq{$cwd/t/13.conf.cfg1/config-export}, q{/tmp/pf-test/var/lib/cvsguest/config}
+make_path(q{/tmp/pf-test/var/lib/cvsguest});
+symlink qq{$cwd/t/13.conf.cfg1/config-export},
+    q{/tmp/pf-test/var/lib/cvsguest/config}
     or diag qq{symlink: $OS_ERROR};
 
-$parsed_configuration = Load_conf( q{COMMON:private-network}, $test_hash_subst,
-    q{network}, $test_pf_config );
+$parsed_configuration = Load_conf(
+    q{COMMON:private-network}, $test_hash_subst,
+    q{network},                $test_pf_config
+);
 
 ok ref $parsed_configuration eq 'HASH'
     => q{Returns a hashref};
@@ -453,7 +481,16 @@
         'vlan-admindsi',
         'vlan-middledsi',
         'admins',
+        'admins-cbv4',
     ],
+    'admins-cbv4' => {
+        '@host' => [
+            'CONFSITE_cbv4:/hostfile-cbv4-rdeploy',
+        ],
+        'comment' => 'Administration hosts (CBV4)',
+        'site'    => 'cbv4',
+        'type'    => 'service',
+    },
     'admins' => {
         '@host' => [
             'CONFSITE_cbv4-pfds:/hostfile-cbv4-spawn',
@@ -575,8 +612,10 @@
     or note explain $parsed_configuration;
 
 
-$parsed_configuration = Load_conf( q{CONFSITE_cbv4-pfds:/hostfile-cbv4-spawn}, $test_hash_subst,
-    q{host}, $test_pf_config );
+$parsed_configuration = Load_conf(
+    q{CONFSITE_cbv4-pfds:/hostfile-cbv4-spawn}, $test_hash_subst,
+    q{host},                                    $test_pf_config
+);
 $expected_configuration = {
     '__sections_order' => [
         'boot',
@@ -587,6 +626,7 @@
         'hostgroup',
         'interface::eth4',
         'interface::bond0',
+        'interface::eth0.TAG1',
     ],
     'boot' => {
         'console'     => 'default',
@@ -629,6 +669,10 @@
         'mac.1' => '00:1e:c9:ff:42:0a',
         'vlan'  => 'vlan-systeme',
     },
+    'interface::eth0.TAG1' => {
+        'ipv4' => '167.0',
+        'vlan' => 'vlan-pfds-int',
+    },
     'interface::eth4' => {
         'ipv4' => '41',
         'vlan' => 'vlan-admindsi',
@@ -643,8 +687,10 @@
     => q{Returns the expected configuration hash in host context}
     or note explain $parsed_configuration;
 
-$parsed_configuration = Load_conf( q{MODSITE_cbv4-pfds:/model-cbv4-pfds}, $test_hash_subst,
-    q{model}, $test_pf_config );
+$parsed_configuration = Load_conf(
+    q{MODSITE_cbv4-pfds:/model-cbv4-pfds}, $test_hash_subst,
+    q{model},                              $test_pf_config
+);
 $expected_configuration = {
     '__sections_order' => [
         'boot',
@@ -699,7 +745,9 @@
     or note explain $parsed_configuration;
 
 
-diag( qq{FIXME: add other files in $test_config_dir to test Load_conf() with real files and 'config' context} );
+diag(
+    qq{FIXME: add other files in $test_config_dir to test Load_conf() with real files and 'config' context}
+);
 
 
 ########################################################################
@@ -707,22 +755,24 @@
 can_ok( 'PFTools::Conf', qw( Init_GLOBAL_NETCONFIG ) );
 
 throws_ok { Init_GLOBAL_NETCONFIG() }
-    qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] start_file }xms
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] start_file }xms
     => q{Dies if empty $start_file};
 
 throws_ok { Init_GLOBAL_NETCONFIG( {} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] start_file }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] start_file }xms
     => q{Dies if non-scalar $start_file};
 
 throws_ok { Init_GLOBAL_NETCONFIG( 'start_file', 'hash_subst' ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] hash_subst }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] hash_subst }xms
     => q{Dies if non-hashref $hash_subst};
 
 throws_ok { Init_GLOBAL_NETCONFIG( 'start_file', {}, 'pf_config' ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] pf_config }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] pf_config }xms
     => q{Dies if non-hashref $pf_config};
 
-$parsed_configuration = Init_GLOBAL_NETCONFIG( q{COMMON:private-network}, $test_hash_subst, $test_pf_config );
+$parsed_configuration
+    = Init_GLOBAL_NETCONFIG( q{COMMON:private-network}, $test_hash_subst,
+    $test_pf_config );
 $expected_configuration = {
     'DHCP' => {
         'BY_SITE' => {
@@ -740,19 +790,33 @@
                             'fixed-address 10.1.167.0;',
                             'filename pxelinux.0;',
                             'option domain-name-servers nsprivate.private,spawn.private;'
-                            ]
+                        ],
                     },
                     'netmask' => '255.255.0.0',
-                    'subnet'  => '10.1.0.0'
-                    }
+                    'subnet'  => '10.1.0.0',
+                },
             },
             'cbv4' => {
                 'vlan-systeme' => {
-                    'netmask' => '255.255.0.0',
-                    'subnet'  => '10.1.0.0'
-                    }
-                }
-            }
+                    'netmask'      => '255.255.0.0',
+                    'subnet'       => '10.1.0.0',
+                    'cbv4-rdeploy' => {
+                        'cbv4-rdeploy01' => [
+                            'hardware ethernet 00:1e:c9:ff:42:0b;',
+                            'fixed-address 10.1.167.1;',
+                            'filename pxelinux.0;',
+                            'option domain-name-servers nsprivate.private,spawn.private;'
+                        ],
+                        'cbv4-rdeploy00' => [
+                            'hardware ethernet 00:1e:c9:ff:08:e4;',
+                            'fixed-address 10.1.167.0;',
+                            'filename pxelinux.0;',
+                            'option domain-name-servers nsprivate.private,spawn.private;'
+                        ],
+                    },
+                },
+            },
+        },
     },
     'SITE' => {
         'EDGE' => [
@@ -825,7 +889,11 @@
                                         'ipv4' => '10.1.167.1/16',
                                         'mac'  => '00:1e:c9:ff:42:0a',
                                         'vlan' => 'vlan-systeme'
-                                        }
+                                    },
+                                    'eth0.39' => {
+                                        'ipv4' => '10.2.167.1/16',
+                                        'vlan' => 'vlan-pfds-int',
+                                    },
                                 },
                                 'deployment' => {
                                     'dhcpvlan'       => 'vlan-systeme',
@@ -870,8 +938,12 @@
                                     'eth0' => {
                                         'ipv4' => '10.1.167.0/16',
                                         'mac'  => '00:1e:c9:ff:08:e3',
-                                        'vlan' => 'vlan-systeme'
-                                        }
+                                        'vlan' => 'vlan-systeme',
+                                    },
+                                    'eth0.39' => {
+                                        'ipv4' => '10.2.167.0/16',
+                                        'vlan' => 'vlan-pfds-int',
+                                    },
                                 },
                                 'deployment' => {
                                     'dhcpvlan'       => 'vlan-systeme',
@@ -930,6 +1002,8 @@
                         '192.168.1.99/24' => 'vip-spawn.vlan-pfds-ext',
                         '10.1.167.0/16'   => 'cbv4-spawn00.vlan-systeme',
                         '10.1.167.1/16'   => 'cbv4-spawn01.vlan-systeme',
+                        '10.2.167.0/16'   => 'cbv4-spawn00.vlan-pfds-int',
+                        '10.2.167.1/16'   => 'cbv4-spawn01.vlan-pfds-int',
                         '10.3.2.42/24'    => 'cbv4-spawn01.vlan-middledsi',
                         '192.168.1.97/24' => 'cbv4-spawn00.vlan-pfds-ext',
                         '10.1.1.254/16'   => 'vip-spawn.vlan-systeme'
@@ -1011,15 +1085,95 @@
             },
             'cbv4' => {
                 'HOST' => {
-                    'BY_NAME' => {},
-                    'BY_ADDR' => {},
-                    'BY_MAC'  => {}
+                    'BY_NAME' => {
+                        'cbv4-rdeploy' => {
+                            'ntp01'          => 'cbv4-rdeploy01',
+                            'ntp'            => 'cbv4-rdeploy',
+                            'cbv4-rdeploy01' => {
+                                'dns' => {
+                                    'resolver' =>
+                                        'nsprivate.private,spawn.private'
+                                },
+                                'boot' => {
+                                    'kernel' =>
+                                        'vmlinuz-2.6.26.5-universal-grm2.1.12',
+                                    'pxefilename' => 'pxelinux.0',
+                                    'console'     => 'default'
+                                },
+                                'interfaces' => {
+                                    'eth0' => {
+                                        'ipv4' => '10.1.167.1/16',
+                                        'mac'  => '00:1e:c9:ff:42:0b',
+                                        'vlan' => 'vlan-systeme'
+                                    },
+                                },
+                                'deployment' => {
+                                    'dhcpvlan'       => 'vlan-systeme',
+                                    'hosttype'       => 'cbv4-rdeploy',
+                                    'arch'           => 'amd64',
+                                    'mode'           => 'debian',
+                                    'order'          => '1',
+                                    'distrib'        => 'lenny',
+                                    'hostname_model' => 'cbv4-rdeploy%%'
+                                    }
+                            },
+                            'cbv4-rdeploy00' => {
+                                'dns' => {
+                                    'resolver' =>
+                                        'nsprivate.private,spawn.private'
+                                },
+                                'boot' => {
+                                    'kernel' =>
+                                        'vmlinuz-2.6.26.5-universal-grm2.1.12',
+                                    'pxefilename' => 'pxelinux.0',
+                                    'console'     => 'default'
+                                },
+                                'interfaces' => {
+                                    'eth0' => {
+                                        'ipv4' => '10.1.167.0/16',
+                                        'mac'  => '00:1e:c9:ff:08:e4',
+                                        'vlan' => 'vlan-systeme',
+                                    },
+                                },
+                                'deployment' => {
+                                    'dhcpvlan'       => 'vlan-systeme',
+                                    'hosttype'       => 'cbv4-rdeploy',
+                                    'arch'           => 'amd64',
+                                    'mode'           => 'debian',
+                                    'order'          => '1',
+                                    'distrib'        => 'lenny',
+                                    'hostname_model' => 'cbv4-rdeploy%%'
+                                    }
+                            },
+                            'ntp00'   => 'cbv4-rdeploy00',
+                            'filer01' => 'cbv4-rdeploy01',
+                            'filer00' => 'cbv4-rdeploy00',
+                            'filer'   => 'cbv4-rdeploy',
+                        },
+                    },
+                    '__hostclass_pxe' => [
+                        'cbv4-rdeploy',
+                    ],
+                    'BY_ADDR' => {
+                        '10.1.167.0/16' => 'cbv4-rdeploy00.vlan-systeme',
+                        '10.1.167.1/16' => 'cbv4-rdeploy01.vlan-systeme',
+                    },
+                    'BY_MAC' => {
+                        '00:1e:c9:ff:42:0b' =>
+                            'eth0.cbv4-rdeploy01.vlan-systeme',
+                        '00:1e:c9:ff:08:e4' =>
+                            'eth0.cbv4-rdeploy00.vlan-systeme'
+                    },
                 },
                 'location' => 'Courbevoie',
                 'zone'     => 'private',
                 'console'  => 'default',
                 'SERVICE'  => {
-                    'BY_NAME' => {}
+                    'BY_NAME' => {
+                        'admins-cbv4' => [
+                            'CONFSITE_cbv4:/hostfile-cbv4-rdeploy'
+                        ],
+                    },
                 },
                 'coment'   => 'CBV4 POP',
                 'room'     => 'CBV4 Room Name',
@@ -1083,7 +1237,9 @@
                                 'A	10.1.167.1'
                             ],
                             'spawn01' => 'CNAME	cbv4-spawn01.vlan-systeme',
-                            'cbv4-spawn01.vlan-systeme' => 'A	10.1.167.1',
+                            'cbv4-spawn01.vlan-systeme'  => 'A	10.1.167.1',
+                            'cbv4-spawn00.vlan-pfds-int' => 'A	10.2.167.0',
+                            'cbv4-spawn01.vlan-pfds-int' => 'A	10.2.167.1',
                             'spawn' => 'CNAME	cbv4-spawn.vlan-systeme'
                         },
                         'cbv4-pfds-filer' => {
@@ -1118,15 +1274,34 @@
                             'broadcast' => 'A	10.1.255.255',
                             'network'   => 'A	10.1.0.0',
                             'netmask'   => 'A	255.255.0.0'
-                            }
-                        }
+                        },
+                        'cbv4-rdeploy' => {
+                            'ntp00'   => 'CNAME	cbv4-rdeploy00.vlan-systeme',
+                            'ntp'     => 'CNAME	cbv4-rdeploy.vlan-systeme',
+                            'ntp01'   => 'CNAME	cbv4-rdeploy01.vlan-systeme',
+                            'filer'   => 'CNAME	cbv4-rdeploy.vlan-systeme',
+                            'filer00' => 'CNAME	cbv4-rdeploy00.vlan-systeme',
+                            'filer01' => 'CNAME	cbv4-rdeploy01.vlan-systeme',
+                            'cbv4-rdeploy00.vlan-systeme' => 'A	10.1.167.0',
+                            'cbv4-rdeploy' =>
+                                'CNAME	cbv4-rdeploy.vlan-systeme',
+                            'cbv4-rdeploy.vlan-systeme' => [
+                                'A	10.1.167.0',
+                                'A	10.1.167.1'
+                            ],
+                            'cbv4-rdeploy01.vlan-systeme' => 'A	10.1.167.1',
+                        },
+                    },
                 },
                 '__hostclass_order' => {
                     'cbv4-pfds' => [
                         'vip-spawn',
                         'cbv4-pfds-filer',
                         'cbv4-spawn'
-                        ]
+                    ],
+                    'cbv4' => [
+                        'cbv4-rdeploy',
+                    ],
                 },
                 'SOA' => {
                     '@ns' => [
@@ -1162,7 +1337,7 @@
                         'vlan-systeme'
                         ]
                     }
-                }
+            },
         },
         'BY_SITE' => {
             'cbv4-pfds' => 'private',
@@ -1170,59 +1345,64 @@
             }
         }
 };
-$expected_configuration->{'SITE'}{'BY_NAME'}{'cbv4'}{'NETWORK'}{'BY_NAME'}{'vlan-systeme'}
-    = $expected_configuration->{'SITE'}{'BY_NAME'}{'cbv4-pfds'}{'NETWORK'}{'BY_NAME'}
+$expected_configuration->{'SITE'}{'BY_NAME'}{'cbv4'}{'NETWORK'}{'BY_NAME'}
+    {'vlan-systeme'}
+    = $expected_configuration->{'SITE'}{'BY_NAME'}{'cbv4-pfds'}{'NETWORK'}
+    {'BY_NAME'}
     {'vlan-systeme'};
 
 is_deeply $parsed_configuration, $expected_configuration
     => q{Returns the expected configuration hash}
     or note explain $parsed_configuration;
 
-$parsed_configuration = Init_GLOBAL_NETCONFIG( q{COMMON:private-network}, $test_hash_subst );
+$parsed_configuration
+    = Init_GLOBAL_NETCONFIG( q{COMMON:private-network}, $test_hash_subst );
 is_deeply $parsed_configuration, $expected_configuration
     => q{Returns the expected configuration hash when no explicit $pf_config was given}
     or note explain $parsed_configuration;
 
 
 ########################################################################
-note('Testing PFTools::Structqueries::Get_hosttype_from_hostname');
-can_ok( 'PFTools::Structqueries', qw( Get_hosttype_from_hostname ) );
+note('Testing PFTools::Structqueries::get_hosttype_from_hostname');
+can_ok( 'PFTools::Structqueries', qw( get_hosttype_from_hostname ) );
 
 my $global_config = $parsed_configuration;
 
-throws_ok { Get_hosttype_from_hostname() }
-    qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] undefined [ ] [\$] hostname }xms
+throws_ok { get_hosttype_from_hostname() }
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] undefined [ ] [\$] hostname }xms
     => 'Dies if no hostname';
 
-throws_ok { Get_hosttype_from_hostname( {} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] hostname }xms
+throws_ok { get_hosttype_from_hostname( {} ) }
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] hostname }xms
     => q{Dies if non-scalar $hostname};
 
-throws_ok { Get_hosttype_from_hostname( 'hostname' ) }
-    qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] undefined [ ] [\$] global_config }xms
+throws_ok { get_hosttype_from_hostname('hostname') }
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] undefined [ ] [\$] global_config }xms
     => 'Dies if no global_config';
 
-throws_ok { Get_hosttype_from_hostname( 'hostname', 'global_config' ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] global_config }xms
+throws_ok { get_hosttype_from_hostname( 'hostname', 'global_config' ) }
+qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] global_config }xms
     => q{Dies if non-hashref $global_config};
 
-throws_ok { Get_hosttype_from_hostname( 'hostname', {}, {} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] site }xms
+throws_ok { get_hosttype_from_hostname( 'hostname', {}, {} ) }
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] site }xms
     => q{Dies if non-scalar $site};
 
-throws_ok { Get_hosttype_from_hostname( 'hostname', {} ) }
-    qr{ \A ERROR: [ ] Unable [ ] to [ ] get [ ] hosttype [ ] from [ ] hostname }xms
+throws_ok { get_hosttype_from_hostname( 'hostname', {} ) }
+qr{ \A ERROR: [ ] Unable [ ] to [ ] get [ ] hosttype [ ] from [ ] hostname }xms
     => q{Dies if unknown hostname};
 
-$parsed_configuration = Get_hosttype_from_hostname( 'cbv4-spawn00',
-    $global_config, 'cbv4-pfds' );
+$parsed_configuration = get_hosttype_from_hostname(
+    'cbv4-spawn00',
+    $global_config, 'cbv4-pfds'
+);
 is $parsed_configuration, q{cbv4-spawn}
     => q{Returns the correct hosttype}
     or diag explain $parsed_configuration;
 
 # $site is optional
-lives_ok { Get_hosttype_from_hostname( 'cbv4-spawn00', $global_config ) }
-    'OK if no $site';
+lives_ok { get_hosttype_from_hostname( 'cbv4-spawn00', $global_config ) }
+'OK if no $site';
 
 
 ########################################################################
@@ -1230,31 +1410,39 @@
 can_ok( 'PFTools::Conf', qw( Get_config_for_hostname_on_site ) );
 
 throws_ok { Get_config_for_hostname_on_site() }
-    qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] undefined [ ] [\$] hostname }xms
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] undefined [ ] [\$] hostname }xms
     => 'Dies if no hostname';
 
 throws_ok { Get_config_for_hostname_on_site( {} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] hostname }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] hostname }xms
     => q{Dies if non-scalar $hostname};
 
-throws_ok { Get_config_for_hostname_on_site( 'hostname' ) }
-    qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] undefined [ ] [\$] site }xms
+throws_ok { Get_config_for_hostname_on_site('hostname') }
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] undefined [ ] [\$] site }xms
     => 'Dies if no site';
 
 throws_ok { Get_config_for_hostname_on_site( 'hostname', {} ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] site }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] site }xms
     => q{Dies if non-scalar $site};
 
-throws_ok { Get_config_for_hostname_on_site( 'hostname', 'site', 'hash_subst' ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] hash_subst }xms
+throws_ok {
+    Get_config_for_hostname_on_site( 'hostname', 'site', 'hash_subst' );
+}
+qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] hash_subst }xms
     => q{Dies if non-hashref $hash_subst};
 
-throws_ok { Get_config_for_hostname_on_site( 'hostname', 'site', {}, 'global_config' ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] global_config }xms
+throws_ok {
+    Get_config_for_hostname_on_site( 'hostname', 'site', {},
+        'global_config' );
+}
+qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] global_config }xms
     => q{Dies if non-hashref $global_config};
 
-throws_ok { Get_config_for_hostname_on_site( 'hostname', 'site', {}, {}, 'pf_config' ) }
-    qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] pf_config }xms
+throws_ok {
+    Get_config_for_hostname_on_site( 'hostname', 'site', {}, {},
+        'pf_config' );
+}
+qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] pf_config }xms
     => q{Dies if non-hashref $pf_config};
 
 $parsed_configuration = Get_config_for_hostname_on_site(
@@ -1392,13 +1580,91 @@
     => q{Returns the expected configuration hash}
     or note explain $parsed_configuration;
 
+########################################################################
+note('Testing PFTools::Structqueries::resolve_hostname_from_global_config');
+can_ok( 'PFTools::Structqueries', qw( resolve_hostname_from_global_config ) );
+
+my $result = resolve_hostname_from_global_config(
+    {
+        hostname      => q{cbv4-rdeploy00.vlan-systeme},
+        ip_type       => q{ipv4},
+        global_config => $global_config,
+        site_name     => q{cbv4},
+        zone_name     => q{private},
+        hosttype      => q{cbv4-rdeploy},
+    }
+);
+my $expected_result = [ q{10.1.167.0} ];
+is_deeply $result, $expected_result
+    => q{Returns the expected result for one A value}
+    or note explain $expected_result;
+
+$result = resolve_hostname_from_global_config(
+    {
+        hostname      => q{cbv4-rdeploy.vlan-systeme},
+        ip_type       => q{ipv4},
+        global_config => $global_config,
+        site_name     => q{cbv4},
+        zone_name     => q{private},
+        hosttype      => q{cbv4-rdeploy},
+    }
+);
+$expected_result = [ q{10.1.167.0}, q{10.1.167.1} ];
+is_deeply $result, $expected_result
+    => q{Returns the expected result for two A values}
+    or note explain $expected_result;
+
+$result = resolve_hostname_from_global_config(
+    {
+        hostname      => q{ntp},
+        ip_type       => q{ipv4},
+        global_config => $global_config,
+        site_name     => q{cbv4},
+        zone_name     => q{private},
+        hosttype      => q{cbv4-rdeploy},
+    }
+);
+$expected_result = [ q{10.1.167.0}, q{10.1.167.1} ];
+is_deeply $result, $expected_result
+    => q{Returns the expected result for a CNAME resolving to two A values}
+    or note explain $expected_result;
+
+$result = resolve_hostname_from_global_config(
+    {
+        hostname      => q{network.vlan-unknown},
+        ip_type       => q{ipv4},
+        global_config => $global_config,
+        site_name     => q{cbv4},
+        zone_name     => q{private},
+        hosttype      => q{whatever},
+    }
+);
+$expected_result = undef;
+is_deeply $result, $expected_result
+    => q{Returns the expected result for an unknown vlan}
+    or note explain $expected_result;
+
+$result = resolve_hostname_from_global_config(
+    {
+        hostname      => q{network.vlan-systeme},
+        ip_type       => q{ipv4},
+        global_config => $global_config,
+        site_name     => q{cbv4},
+        zone_name     => q{private},
+        hosttype      => q{whatever},
+    }
+);
+$expected_result = [ q{10.1.0.0} ];
+is_deeply $result, $expected_result
+    => q{Returns the expected result for a known vlan}
+    or note explain $expected_result;
 
 
 #TODO: {
 #    local $TODO = 'Depends on other, still failing, tests';
 #} # END TODO
 
-remove_tree( q{/tmp/pf-test} );
+remove_tree(q{/tmp/pf-test});
 
 __END__
 
diff -r d6a9b9a18fdc -r e756fd4d6365 tools/Display_IP_config
--- a/tools/Display_IP_config	Sun Nov 07 18:29:34 2010 +0100
+++ b/tools/Display_IP_config	Fri Nov 12 13:36:18 2010 +0100
@@ -183,7 +183,7 @@
 
 unless( $options->{'site'} ) {
     unless( $PF_CONFIG->{'location'}->{'site'} ) {
-        my $site_list = Get_site_from_hostname(
+        my $site_list = get_site_list_from_hostname(
             $options->{'host'}, $GLOBAL_STRUCT
         );
         unless( $site_list ) {
@@ -251,7 +251,7 @@
                 print "srv type --> ".$srv_type."\n";
                 foreach my $srv ( @{ $srv_type_list->{$prio}->{$srv_type} } ) {
                     print "\t" . $srv . "\n";
-                    my $host_props = Get_host_config_from_CONFIG(
+                    my $host_props = get_host_config((
                         $srv, $GLOBAL_STRUCT, $options->{'site'}
                     );
                     my $srv_net = get_srv_iface(



More information about the pf-tools-commits mailing list