pf-tools commit: r787 [ccaillet-guest] - in /branches/next-gen: debian/changelog lib/PFTools/Conf.pm lib/PFTools/Host.pm lib/PFTools/Net.pm sbin/mk_dhcp sbin/mk_interfaces sbin/mk_sitezone

parmelan-guest at users.alioth.debian.org parmelan-guest at users.alioth.debian.org
Wed Jul 28 09:35:49 UTC 2010


Author: ccaillet-guest
Date: Wed Jul 28 09:35:48 2010
New Revision: 787

URL: http://svn.debian.org/wsvn/pf-tools/?sc=1&rev=787
Log:
* doc/updatefile-syntax : TODO
  - removing dead or useless code
  - moving functions into script when they're only used into it
* lib/PFTools/Host.pm
  - creating new package for handling hosts part of the global structure
and site definition, using Getopt::Long for handling command line option(s)
* sbin/mk_dhcp : rewrite according to new global structure, using
Getopt::Long for handling command line option(s)

Added:
    branches/next-gen/lib/PFTools/Host.pm
Modified:
    branches/next-gen/debian/changelog
    branches/next-gen/lib/PFTools/Conf.pm
    branches/next-gen/lib/PFTools/Net.pm
    branches/next-gen/sbin/mk_dhcp
    branches/next-gen/sbin/mk_interfaces
    branches/next-gen/sbin/mk_sitezone

Modified: branches/next-gen/debian/changelog
URL: http://svn.debian.org/wsvn/pf-tools/branches/next-gen/debian/changelog?rev=787&op=diff
==============================================================================
--- branches/next-gen/debian/changelog (original)
+++ branches/next-gen/debian/changelog Wed Jul 28 09:35:48 2010
@@ -5,6 +5,7 @@
   definition
   * doc/networkfile-syntax : adding file describing the new grammar for
   network and zone definitions
+  * doc/updatefile-syntax : TODO
   * lib/PF-Tools/Conf.pm
     - adding __Load_conf_new for parsing new configuration file with "standard"
     ini parser and new syntax
@@ -32,14 +33,14 @@
     - Add_zone : adding zone into the new global structure
     - Add_site : adding sites into the new global structure
     - Add_network : adding network into the new global structure
+    - removing dead or useless code
+    - moving functions into script when they're only used into it
+  * lib/PFTools/Host.pm
+    - creating new package for handling hosts part of the global structure
     - Check_host_interfaces : checking interfaces for host definition
     - Add_server : adding server (hosts defined into pf-tools only for IPs
     and name accessing by filters)
     - Add_host : adding pf-tools host configuration
-    - rewrite Mk_zoneheader to __Mk_zoneheader
-    - rewrite Mk_zone to Mk_zone_for_site
-    - rewrite Mk_interfaces
-    - removing dead or useless code
   * lib/PFTools/Packages.pm
     - using new packages Parser.pm et Logger.pm
   * lib/PFTools/Update.pm
@@ -47,14 +48,16 @@
   * sbin/mk_interfaces : rewrite according with new global structure, using
   Getopt::Long for handling command line option(s)
   * sbin/mk_sitezone : rewrite from mk_privatezone according to global structure
-  and site definition
+  and site definition, using Getopt::Long for handling command line option(s)
+  * sbin/mk_dhcp : rewrite according to new global structure, using
+  Getopt::Long for handling command line option(s)
   * debian/control
     - deps update according to usage of NetAddr::IP and Net::DNS
     - uploaders and maintainers update
   * debian/compat
     - update level for avoiding warning during package build
 
- -- Christophe Caillet <quadchris at free.fr>  Tue, 27 Jul 2010 11:26:23 +0200
+ -- Christophe Caillet <quadchris at free.fr>  Wed, 28 Jul 2010 11:29:53 +0200
 
 pf-tools (0.34.0-0WIP) unstable; urgency=low
 

Modified: branches/next-gen/lib/PFTools/Conf.pm
URL: http://svn.debian.org/wsvn/pf-tools/branches/next-gen/lib/PFTools/Conf.pm?rev=787&op=diff
==============================================================================
--- branches/next-gen/lib/PFTools/Conf.pm (original)
+++ branches/next-gen/lib/PFTools/Conf.pm Wed Jul 28 09:35:48 2010
@@ -27,6 +27,7 @@
 
 use Exporter;
 use PFTools::Net;
+use PFTools::Host;
 use PFTools::Parser;
 use PFTools::Logger;
 use Data::Dumper;
@@ -60,6 +61,7 @@
 	Load_conf
 	Flush2disk_GLOBAL
 	Retrieve_GLOBAL
+	Get_host_config_from_CONFIG
 );
 
 ##########################
@@ -854,12 +856,53 @@
 	}
 }
 
-sub Retrieve_GLOBAL ($;$) {
-	my ( $pf_config, $path_global_file ) = @_;
-
-	my $flush_file = $path_global_file || $pf_config->{'path'}->{'global_struct'};
-	return retrieve ( $flush_file );
-}
+sub Retrieve_GLOBAL ($) {
+	my ( $path_global_file ) = @_;
+
+	if ( ! -e $path_global_file ) {
+		Abort ( $CODE->{'OPEN'},
+			"Unable to open global configuration storable file ".$path_global_file." : no such file or directory" );
+	}
+	return retrieve ( $path_global_file );
+}
+
+#########################################################################
+#
+# 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 :
+#  - $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 ) = @_ ;
+
+	if ( ! defined $site ) {
+		my $site_list = Get_site_from_hostname ( $hostname, $global_config );
+		if ( ! defined $site_list ) {
+			Warn ( $CODE->{'UNDEF_KEY'},
+				"Unable to retrieve site for hostname ".$hostname." : hostname not defined" );
+		}
+		elsif ( scalar @{$site_list} > 1 ) {
+			Warn ( $CODE->{'UNDEF_KEY'},
+				"Unable to retrieve site for hostname ".$hostname." : hostname appeared in multiple sites : "
+				.join ( ",", @{$site_list} ) );
+		}
+		else {
+			( $site ) = @{$site_list};
+		}
+	}
+	my $site_part					= $global_config->{'SITE'}->{'BY_NAME'}->{$site};
+	my $zone						= $site_part->{'zone'};
+	$hostname						=~ /^([^.]+)(\.([^.]+))?(\.$zone)?$/ ;
+	my ( $hostshort, $hostvlan )	= ( $1, $3 ) ;
+	my $hosttype					= Get_hosttype_from_hostname ( $hostname, $global_config );
+	return $site_part->{'HOST'}->{'BY_NAME'}->{$hosttype}->{$hostshort} ;
+}
+
 
 # Print_conf
 sub Print_conf {

Added: branches/next-gen/lib/PFTools/Host.pm
URL: http://svn.debian.org/wsvn/pf-tools/branches/next-gen/lib/PFTools/Host.pm?rev=787&op=file
==============================================================================
--- branches/next-gen/lib/PFTools/Host.pm (added)
+++ branches/next-gen/lib/PFTools/Host.pm Wed Jul 28 09:35:48 2010
@@ -1,0 +1,840 @@
+package PFTools::Host;
+##
+##  $Id: Net.pm 786 2010-07-27 15:16:09Z ccaillet-guest $
+##
+##  Copyright (C) 2010 Christophe Caillet <quadchris at free.fr>
+##
+##  This program is free software; you can redistribute it and/or
+##  modify it under the terms of the GNU General Public License
+##  as published by the Free Software Foundation; either version 2
+##  of the License, or (at your option) any later version.
+##
+##  This program is distributed in the hope that it will be useful,
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+##  GNU General Public License for more details.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, write to the Free Software
+##  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+##
+
+use strict;
+use warnings;
+
+use Exporter;
+
+our @ISA = ('Exporter');
+
+our @EXPORT = qw(
+	Get_site_from_hostname
+	Get_hosttype_from_hostname
+	Add_server
+	Add_host
+);
+
+our @EXPORT_OK = qw();
+
+use Fcntl ':mode';
+use POSIX qw(ceil floor);
+
+use PFTools::Logger;
+use PFTools::Net;
+use Data::Dumper;
+
+
+#########################################################################
+#
+# 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 ) = @_;
+	
+	if ( $ref_site->{'state'} eq 'EDGE' ) {
+		if ( defined $ref_site->{'prefix'} ) {
+			return $ref_site->{'prefix'}.'-';
+		}
+		else {
+			return $site.'-';
+		}
+	}
+	else {
+		return '';
+	}
+}
+
+#########################################################################
+#
+# 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 );
+	
+	
+	$node_last	= ( $ref_hostgroup->{'nodes'} )
+		? ( $ref_hostgroup->{'nodes'} -1 )
+		: 0;
+	$num_last		= $ref_hostgroup->{'number'} - 1;
+	$hostname_model	=~ /(%*)(_*)$/;
+	$digits			= length ($1) || 0;
+	$nodes			= length ($2) || 0;
+	# Checking nodes
+	if ( $node_last && ! $nodes ) {
+		Abort ( $CODE->{'INVALID_VALUE'},
+			"Unable to affect all ".$node_last." nodes : no _ defined in key hostname" );
+	}
+	elsif ( $node_last && ceil ( log($node_last) / log(26) ) > $nodes ) {
+		Warn ( $CODE->{'INVALID_VALUE'},
+			"Not enough places for indexing nodes definition for host ".$hostname_model );
+	}
+	# Checking hostnum
+	if ( $num_last && ! $digits ) {
+		Abort ( $CODE->{'INVALID_VALUE'},
+			"Unable to affect all host number(s) : no % defined in key hostname ".$hostname_model );
+	}
+	elsif ( $num_last && $num_last > 10**$digits ) {
+		Warn ( $CODE->{'INVALID_VALUE'},
+			"Not enough places for indexing host number(s) according to hostname ".$hostname_model );
+	}
+	return ( $num_last, $node_last );
+}
+
+#########################################################################
+#
+# 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, $digits, $nodes, $index );
+
+	$hostname = $hostname_model;
+	if ( $hostname !~ /%+/ && $hostname !~ /_+/ ) {
+		return $hostname;
+	}
+	$hostname_model	=~ /(%*)(_*)$/;
+	$digits			= length ($1) || 0;
+	$nodes			= length ($2) || 0;
+	$index			= "";
+	while ( $digits > length ( $hostnum ) ) {
+		$index .= "0";
+		$digits--;
+	}
+	$index = ( $hostnode )
+		? $index.$hostnum.$hostnode
+		: $index.$hostnum;
+	$hostname =~ s/(%*)(_*)$/$index/;
+	$hostname = $site_prefix.$hostname if ( $ref_host->{'prefix'} && $ref_host->{'prefix'} eq 'true' );
+	return $hostname;
+}
+
+#########################################################################
+#
+# 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;
+	
+	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 ( /^$site$/, @{$site_list} ) );
+				next;
+			}
+			foreach my $host ( keys %{$host_part->{$hostclass}} ) {
+				if ( $host eq $hostname ) {
+					push (  @{$site_list}, $site ) if ( ! grep ( /^$site$/, @{$site_list} ) );
+					last;
+				}
+			}
+		}
+	}
+	return $site_list;
+}
+
+#########################################################################
+#
+# STR Get_hosttype_from_hostname ( STR, STR, STR, 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
+#  - $site			: define here the site where hostname is defined
+#
+# Output :
+#  Returns a string containing the hosttype or undef if hostname doesn't exist
+#
+sub Get_hosttype_from_hostname ($$;$) {
+	my ( $hostname, $global_config, $site ) = @_;
+	my $site_list;
+
+	if ( ! defined $site ) {
+		$site_list = $global_config->{'SITE'}->{'__site_list'};
+	}
+	else {
+		$site_list = [ $site ];
+	}
+	
+	foreach my $site ( @{$site_list} ) {
+		my $host_part = $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'HOST'}->{'BY_NAME'};
+		foreach my $hostclass ( keys %{$host_part} ) {
+			return $hostclass if ( $hostclass eq $hostname );
+			foreach my $host ( keys %{$host_part->{$hostclass}} ) {
+				return $hostclass if ( $host eq $hostname );
+			}
+		}
+	}
+	return undef;
+}
+
+#########################################################################
+#
+# 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 ($$) {
+	my ( $hostname, $global_config ) = @_;
+	
+	my $hostclass = __Get_hosttype_from_hostname ( $hostname, $global_config );
+	if ( ! defined $hostclass ) {
+		Abort ( $CODE->{'UNDEF_KEY'},
+			"Unable to get hosttype from hostname ".$hostname." : unexistant hostname" );
+	}
+	my $site_list = Get_site_from_hostname ( $hostname, $global_config );
+	if ( ! defined $site_list ) {
+		Abort ( $CODE->{'UNDEF_KEY'},
+			"Unable to get site list from hostname ".$hostname." : unexistant hostname" );
+	}
+	else {
+		if ( scalar @{$site_list} > 1 ) {
+			Warn ( $CODE->{'DUPLICATE_VALUE'},
+				"Hostname ".$hostname." is defined on multiple sites : unable to choose the right one" );
+			return undef;
+		}
+		else {
+			my ( $site ) = @{$site_list};
+			return $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'HOST'}->{'BY_NAME'}->{$hostclass}->{'deployment'}->{'hostname_model'};
+		}
+	}
+}
+
+#########################################################################
+#
+# 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 );
+
+	foreach my $section ( keys %{$ref_src} ) {
+		next if ( $section !~ /^interface/ );
+		$section =~ /^interface::(((eth|bond)[\d]+)(\.(TAG[\d]+|\d+))?)$/;
+		push ( @if_list, $1 );
+	}
+	return @if_list;
+}
+
+#########################################################################
+#
+# STR Get_ip_from_hostindex ( NetAddr::IP, STR, STR, STR, INT )
+#
+# This function returns the host IP for a given number and node
+# Inputs :
+#  - $net_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
+#
+# Output :
+#  Returns a NetAddr::IP object containing the IP
+#
+sub __Get_ip_from_hostindex ($$;$$$) {
+	my ( $net_block, $ipstart, $hostnum, $hostnode, $nodes ) = @_;
+	
+	my $ip = new NetAddr::IP ( $net_block->prefix().$ipstart, $net_block->mask() );
+	if ( ! defined $ip ) {
+		Abort ( $CODE->{'UNDEF_KEY'},
+			"Unable to create IP object from prefix ".$net_block->prefix()." and host ".$ipstart );
+	}
+	if ( $hostnum ) {
+		my $add = ( $hostnode )
+			? ( $hostnum * $nodes ) + $hostnode
+			: $hostnum;
+		$ip = $ip + $add;
+	}
+	return $ip;
+}
+
+#########################################################################
+#
+# 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 ) = @_;
+
+	my $prefix = $vlan_block->prefix();
+	my $realip = __Get_ip_from_hostindex ( $vlan_block, $ipstart, $hostnum, $hostnode, $nodes ) ;
+	my $host_addr_site = $ref_site->{'HOST'}->{'BY_ADDR'};
+	if ( defined $host_addr_site->{$realip->addr()} ) {
+		Abort ( $CODE->{'DUPLICATE_VALUE'},
+			"IP ".$realip->addr()." is already in use by host ".$host_addr_site->{$realip->cidr()}
+			." on site ".$site );
+	}
+	if ( ! $vlan_block->contains ( $realip ) ) {
+		Abort ( $CODE->{'INVALID_VALUE'},
+			"IP of type ".$ip_type." is out of ".$vlan_block->cidr()." on site ".$site );
+	}
+	return $realip;
+}
+
+#####################################################################################
+#
+# 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 = [];
+
+	foreach my $key ( keys %{$ref_srv} ) {
+		next if ( $key !~ /^ipv/ );
+		my ( $type, $vlan, $num ) = split ( /\./, $key );
+		push ( @{$vlan_list}, $vlan ) if ( ! grep ( /^$vlan$/, @{$vlan_list} ) );
+	}
+	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 if ( $key !~ /^alias/ );
+		my ( $alias, $name, $host_num ) = split ( /\./, $key );
+		next if ( $host_number && $host_num && $host_num ne $host_number );
+		push ( @{$alias_list}, $name ) if ( 
+			$vlan eq $ref_parsed->{$key}
+			&& ! grep ( /^$name$/, @{$alias_list} ) );
+	}
+	return $alias_list;
+}
+
+########################################################################################
+#
+# STR __Get_vlan_tag_from_site ( STR, 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			: specify here the site's name as defined into pf-tools configuration
+#  - $global_config	: hashref containing the global configuration parsed
+#
+# Output :
+#  Returns the tag if defined undef undef if not.
+#
+sub __Get_vlan_tag_from_site ($$$) {
+	my ( $vlan, $site, $global_config ) = @_;
+	
+	foreach my $tag ( keys %{$global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'NETWORK'}->{'BY_TAG'}} ) {
+		return $tag if ( $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'NETWORK'}->{'BY_TAG'}->{$tag} eq $vlan );
+	}
+	return;
+}
+
+#########################################################################
+#
+# VOID Add_server ( STR, STR, HASHREF, HASHREF, HASHREF )
+#
+# This function adds server into global configuration
+# Inputs :
+#  - $srvfile		: filename where server is parsed
+#  - $srvname_model	: model for the server name
+#  - $srv2add		: hashref where are stored server definitions according to networkfile-syntax
+#  - $global_config	: hashref where are stored global configuration datas
+#  - $pf_config		: hashref where are stored pf-tools configuration datas
+#
+sub Add_server ($$$$$) {
+	my ( $srvfile, $srvname_model, $srv2add, $global_config, $pf_config ) = @_;
+	
+	$srvname_model					=~ /^$pf_config->{'regex'}->{'hostname'}$/ ;
+	my $shortname					= $1;
+	my $hostclass					= $shortname;
+	my $site_list					= Get_site_list ( $srv2add, $global_config );
+	my ( $host_last, $node_last )	= __Get_host_indexes ( $srv2add, $srvname_model );
+	my $nodes						= $srv2add->{'nodes'} || 0;
+	foreach my $site ( @{$site_list} ) {
+		my $site_part	= $global_config->{'SITE'}->{'BY_NAME'}->{$site};
+		if ( ! defined $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} ) {
+			$site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} = {};
+		}
+		my $srv_part	= $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass};
+		my $zone		= $site_part->{'zone'};
+		my $prefix		= __Get_site_prefix ( $site, $global_config->{'SITE'}->{'BY_NAME'}->{$site} );
+		my $vlan_list	= __Get_vlan_list_from_server ( $srv2add );
+		foreach my $hostnum ( 0 .. $host_last ) {
+			foreach my $hostnode (  0 .. $node_last ) {
+				my $srvname = __Get_hostname_from_model ( $srvname_model, $hostnum, $hostnode, $prefix );
+				if ( $srv_part->{$srvname} ) {
+					Warn ( $CODE->{'DUPLICATE_VALUE'},
+						"Hostclass ".$hostclass." already contains hostname ".$srvname." definition from file "
+						.$srvfile." and for site ".$site." : skipping this hostname" );
+					next;
+				}
+				my $srv_number	= ( $hostnode ) ? $hostnum.$hostnode : $hostnum;
+				my $short_vlan	= $srv2add->{'shortname.'.$srv_number} || $srv2add->{'shortname'} || "";
+				my $iface_idx	= 0;
+				foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+					next if ( ! $pf_config->{'features'}->{$ip_type} );
+					my $addr_key	= ( $ip_type eq 'ipv6' ) ? 'BY_ADDR6' : 'BY_ADDR';
+					my $zone_key	= ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
+					my $dhcp_key	= ( $ip_type eq 'ipv6' ) ? 'DHCP6' : 'DHCP';
+					my $suffix		= ( $ip_type eq 'ipv6' ) ? '6' : '';
+					my $zone_part	= $global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'BY_SITE'}->{$site};
+					foreach my $vlan ( @{$vlan_list} ) {
+						my $net_block	= Get_netblock_from_vlan ( $ip_type, $site_part->{'NETWORK'}->{'BY_NAME'}->{$vlan} );
+						if ( ! defined $net_block ) {
+							Abort ( $CODE->{'INVALID_VALUE'},
+								"Unable to retrieve network block of type ".$ip_type." for vlan ".$vlan
+								." on site ".$site." for host ".$srvname );
+						}
+						my $realip;
+						if ( $srv2add->{$ip_type.'.'.$vlan.'.'.$srv_number} ) {
+							$realip = __Check_host_ip ( $ip_type, $net_block, $srv2add->{$ip_type.'.'.$vlan.'.'.$srv_number}, 0, 0, 0, $site, $site_part );
+						}
+						else {
+							$realip = __Check_host_ip ( $ip_type, $net_block, $srv2add->{$ip_type.'.'.$vlan}, $hostnum, $hostnode, $nodes, $site, $site_part );
+						}
+						$srv_part->{$srvname} = {
+							'interfaces'	=> {}
+						} if ( ! defined $srv_part->{$srvname} );
+						$srv_part->{$srvname}->{'interfaces'}->{'eth'.$iface_idx} = {
+							$ip_type			=> $realip->addr(),
+							'netmask'.$suffix	=> $realip->mask(),
+							'vlan'				=> $vlan
+						};
+						$iface_idx++;
+						$site_part->{'HOST'}->{$addr_key}->{$realip->addr()} = $srvname.'.'.$vlan;
+						if ( ! defined $zone_part->{$hostclass} ){
+							$zone_part->{$hostclass} = {};
+							push ( @{$global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'__hostclass_order'}->{$site}}, $hostclass );
+						}
+						$zone_part->{$hostclass}->{$srvname.'.'.$vlan}		= "A\t".$realip->addr();
+						if ( $short_vlan eq $vlan ) {
+							if (  $shortname ne $srvname ) {
+								push ( @{$zone_part->{$hostclass}->{$shortname.'.'.$vlan}}, "A\t".$realip->addr() );
+							}
+							else {
+								$zone_part->{$hostclass}->{$shortname} = "CNAME\t".$shortname.'.'.$vlan;
+							}
+						}
+						my $alias_list = __Get_alias_list_from_server ( $srv2add, $vlan, $srv_number );
+						foreach my $alias ( @{$alias_list} ) {
+							if ( ! defined $zone_part->{$hostclass}->{$alias.'.'.$vlan} ) {
+								$zone_part->{$hostclass}->{$alias} = "CNAME\t".$shortname.'.'.$vlan;
+							}
+							if ( $shortname ne $srvname ) {
+								$zone_part->{$hostclass}->{$alias.$srv_number.'.'.$vlan}	= "CNAME\t".$srvname.'.'.$vlan;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+#####################################################################################################
+#
+# 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, $ref_host, $ref_if_list, $site, $ref_site, $pf_config ) = @_;
+	my ( @if_list, $vlan, $ifraw, $iftag, $add_if, $iface_opt );
+
+	my $network_site	= $ref_site->{'NETWORK'};
+	my $host_site		= $ref_site->{'HOST'};	
+	my $iface_section	= 'interface::'.$iface;
+	my $nodes			= $ref_host->{'hostgroup'}->{'nodes'} || 0;
+	my $host_number		= ( $hostnode ) ? $hostnum.$hostnode : $hostnum;
+	$iface =~ /^((eth|bond)[\d]+)(\.(TAG[\d]+))?$/;
+	( $ifraw, $iftag )	= ( $1, $4 );
+	$vlan		= $ref_host->{$iface_section}->{'vlan.'.$host_number} || $ref_host->{$iface_section}->{'vlan'};
+	$iface_opt	= $ref_host->{$iface_section}->{'iface_opt.'.$host_number} || $ref_host->{$iface_section}->{'iface_opt'};
+	$add_if->{'vlan'}		= $vlan;
+	$add_if->{'iface_opt'}	= $iface_opt if ( defined $iface_opt );
+	# Check MAC address if defined
+	if ( defined $ref_host->{$iface_section}->{'mac.'.$host_number} ) {
+		my $mac = $ref_host->{$iface_section}->{'mac.'.$host_number};
+		if ( $host_site->{'BY_MAC'}->{$mac} ) {
+			my ( $ifdef, $hostdef, $vlandef ) = split ( /\./, $host_site->{'BY_MAC'}->{$mac} );
+			Abort ( $CODE->{'DUPLICATE_VALUE'},
+				"MAC address ".$mac." is already defined for interface ".$ifdef." in host ".$hostdef
+				." which is on vlan ".$vlandef );
+		}
+		$add_if->{'mac'}	= $mac;
+	}
+	# Check tag
+	if ( $iftag && $iftag =~ /^\d+$/ ) {
+		Abort ( $CODE->{'INVALID_VALUE'},
+			"Tag ".$iftag." defined on section name ".$iface_section." differs from "
+			.$ref_host->{'vlan'}." network definition" );
+	}
+	if ( $iface =~ /^bond/ && ! $iftag ) {
+		# Check if slaves not in use
+		my @slaves = ( $ref_host->{$iface_section}->{'slaves.'.$host_number} )
+			? split ( /\s*,\s*/, $ref_host->{$iface_section}->{'slaves.'.$host_number} )
+			: split ( /\s*,\s*/, $ref_host->{$iface_section}->{'slaves'} );
+		foreach my $if ( @slaves ) {
+			Abort ( $CODE->{'INVALID_VALUE'},
+				"Interface ".$if." cannot be enslaved by ".$iface." : already in use for "
+				.$hostname ) if ( grep ( /$if/, @{$ref_if_list} ) );
+		}
+		$add_if->{'slaves'} = join ( " ", @slaves );
+	}
+	# Check vlan
+	if ( ! defined $network_site->{'BY_NAME'}->{$vlan} ) {
+		Abort ( $CODE->{'INVALID_VALUE'},
+			"Unknown vlan ".$vlan." on site ".$site." for interface ".$iface.
+			" defined on host ".$hostname );
+	}
+	# Check address and route values
+	foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+		next if ( ! $pf_config->{'features'}->{$ip_type} );
+		my $suffix		= ( $ip_type eq 'ipv6' ) ? '6' : '';
+		my $netblock	= Get_netblock_from_vlan ( $ip_type, $network_site->{'BY_NAME'}->{$vlan} );
+		if ( ! defined $netblock ) {
+			Abort ( $CODE->{'INVALID_VALUE'},
+				"Unable to retrieve network block of type ".$ip_type." for vlan ".$vlan
+				." on site ".$site." for host ".$hostname );
+		}
+		my $realip;
+		if ( $ref_host->{$iface_section}->{$ip_type.'.'.$host_number} ) {
+			$realip = __Check_host_ip ( $ip_type, $netblock, $ref_host->{$iface_section}->{$ip_type.'.'.$host_number}, 0, 0, 0, $site, $ref_site );
+		}
+		else {
+			$realip = __Check_host_ip ( $ip_type, $netblock, $ref_host->{$iface_section}->{$ip_type}, $hostnum, $hostnode, $nodes, $site, $ref_site );
+		}
+		$add_if->{$ip_type}				= $realip->cidr();
+# 		$add_if->{'netmask'.$suffix}	= $realip->mask();
+# 		$add_if->{'broadcast'.$suffix}	= $realip->broadcast(); $add_if->{'broadcast'.$suffix} =~ s/\/.+$//;
+		my $route_key	= ( $ip_type eq 'ipv6' ) ? '@route6' : '@route';
+		$route_key		.= $hostnum if ( $ref_host->{$iface_section}->{$route_key.'.'.$host_number} );
+		my $gw_key		= ( $ip_type eq 'ipv6' ) ? 'gateway6' : 'gateway';
+		if ( defined $ref_host->{$iface_section}->{$route_key} ) {
+			foreach my $route ( @{$ref_host->{$iface_section}->{$route_key}} ) {
+				$route =~ /^(\S+)\s*(via\s*(\S+))?$/;
+				my ( $dest, $via ) = ( $1, $3 );
+				my $route2add = '';
+				if ( $dest ne 'default' ) {
+					my $ip_dest;
+					if ( $dest =~ /[g-zG-Z]+/ ) {
+						if ( defined $network_site->{'BY_NAME'}->{$dest} ) {
+							# Dest is a defined network ... translating into IP
+							$ip_dest = new NetAddr::IP ( $network_site->{'BY_NAME'}->{$dest}->{'network'}, $network_site->{'BY_NAME'}->{$dest}->{'netmask'} );
+							$route2add .= $ip_dest->cidr()." via ";
+						}
+						else {
+							# Potentially not parsed host on this site
+							$route2add .= $dest." via ";
+						}
+					}
+					else {
+						$ip_dest = new NetAddr::IP ( $dest );
+						if ( ! defined $ip_dest ) {
+							Abort ( $CODE->{'INVALID_VALUE'},
+								"Unable to check dest IP ".$dest." of type ".$ip_type." on \@route key for interface ".$iface
+								." for host ".$hostname." on site ".$site );
+						}
+						$route2add .= $ip_dest->cidr()." via ";
+					}
+				}
+				else {
+					$route2add .= "default via ";
+				}
+				if ( $via ) {
+					my $ip_via;
+					if ( $via eq 'GATEWAY' ) {
+						if ( ! defined  $network_site->{'BY_NAME'}->{$vlan}->{$gw_key} ) {
+							Abort ( $CODE->{'INVALID_VALUE'},
+								"Unable to define default route by vlan ".$vlan." : no gateway defined on this one" );
+						}
+						$route2add .= $network_site->{'BY_NAME'}->{$vlan}->{$gw_key};
+					}
+					elsif ( $via =~ /[g-zG-Z]+/ ) {
+						# Potentially not parsed host ... skipping this case for now
+						$route2add .= $via;
+					}
+					else {
+						my $ip_via = new NetAddr::IP ( $via );
+						if ( ! defined $ip_via ) {
+							Abort ( $CODE->{'INVALID_VALUE'},
+								"Unable to check IP ".$via." of type ".$ip_type." as gateway for interface ".$iface
+								." for host ".$hostname." on site ".$site );
+						}
+						elsif ( ! $netblock->contains ( $ip_via ) ) {
+							Abort ( $CODE->{'INVALID_VALUE'},
+								"IP ".$ip_via." of type ".$ip_type." for gateway on interface ".$iface
+								." is out of ".$netblock." for host ".$hostname." on site ".$site );
+						}
+						$route2add .= $ip_via->addr();
+					}
+				}
+				push ( @{$add_if->{$route_key}}, $route2add );
+			}
+		}
+	}
+	return $add_if;
+}
+
+#########################################################################
+#
+# 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
+#
+sub Add_host ($$$$) {
+	my ( $hostfile, $host2add, $global_config, $pf_config ) = @_;
+
+	my $hostname_model	= $host2add->{'hostgroup'}->{'hostname'};
+	$hostname_model		=~ /^$pf_config->{'regex'}->{'hostname'}$/ ;
+	my $shortname		= $1;
+	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 !~ /\/$/ );
+	my ( $host_last, $node_last )	= __Get_host_indexes ( $host2add->{'hostgroup'}, $hostname_model );
+	
+	foreach my $site ( @{$site_list} ) {
+		my $site_part	= $global_config->{'SITE'}->{'BY_NAME'}->{$site};
+		if ( ! defined $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} ) {
+			$site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} = {};
+		}
+		my $host_part	= $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass};
+		my $zone		= $site_part->{'zone'};
+		my $prefix		= __Get_site_prefix ( $site, $global_config->{'SITE'}->{'BY_NAME'}->{$site} );
+		foreach my $hostnum ( 0 .. $host_last ) {
+			foreach my $hostnode (  0 .. $node_last ) {
+				my $hostname = __Get_hostname_from_model ( $hostname_model, $hostnum, $hostnode, $prefix );
+				if ( $host_part->{$hostname} ) {
+					Warn ( $CODE->{'DUPLICATE_VALUE'},
+						"Hostclass ".$hostclass." already contains hostname ".$hostname." definition from file "
+						.$hostfile." and for site ".$site." : skipping this hostname" );
+					next;
+				}
+				my $host_number = ( $hostnode ) ? $hostnum.$hostnode : $hostnum;
+				# Checking path for PXE elements kernel, initrd ...
+				foreach my $key ( 'pxefilename', 'kernel', 'initrd', 'kerneluml', 'initrduml', 'console', 'cmdline' ) {
+					my $value;
+					if ( $key eq 'console' ) {
+						$value = $host2add->{'boot'}->{$key.'.'.$host_number} || $host2add->{'boot'}->{$key} || $site_part->{$key};
+					}
+					elsif ( $key eq 'cmdline' ) {
+						$value = $host2add->{'boot'}->{$key.'.'.$host_number} || $host2add->{'boot'}->{$key} || "";
+					}
+					else {
+						$value = $host2add->{'boot'}->{$key.'.'.$host_number} || $host2add->{'boot'}->{$key};
+						next if ( ! defined $value );
+						if ( ! -e $pf_tftp_dir.$value ) {
+							Warn ( $CODE->{'OPEN'},
+								"Unable to find file ".$pf_tftp_dir.$value." for key ".$key." for host ".$hostname." from file ".$hostfile );
+						}
+					}
+					$host_part->{$hostname}->{'boot'}->{$key}	= $value;
+				}
+				my $dhcpvlan = $host2add->{'deployment'}->{'dhcpvlan.'.$host_number} || $host2add->{'deployment'}->{'dhcpvlan'} || $site_part->{'dhcpvlan'};
+				if ( ! defined $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan} ) {
+					Abort ( $CODE->{'INVALID_VALUE'},
+						"Vlan ".$dhcpvlan." defined for ".$hostname." from file ".$hostfile." doesn't exist on site ".$site );
+				}
+				foreach my $key ( 'arch', 'distrib', 'mode', 'os_type' ) {
+					my $value = $host2add->{'deployment'}->{$key.'.'.$host_number} || $host2add->{'deployment'}->{$key};
+					next if ( ! defined $value );
+					$host_part->{$hostname}->{'deployment'}->{$key} = $value;
+				}
+				$host_part->{$hostname}->{'deployment'}->{'hostname_model'} = $host2add->{'hostgroup'}->{'hostname'};
+				$host_part->{$hostname}->{'deployment'}->{'hosttype'}		= $hostclass;
+				$host_part->{$hostname}->{'dns'}->{'resolver'} = $host2add->{'dns'}->{'resolver.'.$host_number} || $host2add->{'dns'}->{'resolver'};
+				# Check interfaces
+				my @if_list = __Get_host_interfaces ($host2add);
+				foreach my $iface ( @if_list ) {
+					my $if2add = __Add_host_interface ( $iface, $hostname, $hostnum, $hostnode, $host2add, \@if_list, $site, $site_part, $pf_config );
+					my $iface_name = $iface;
+					if ( $iface =~ /^((eth|bond)[\d]+)(\.(TAG[\d]+))$/ ) {
+						$iface_name = $1.'.'.__Get_vlan_tag_from_site ( $if2add->{'vlan'}, $site, $global_config );
+					}
+					# 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 && ! defined $if2add->{'mac'} ) {
+						Abort ( $CODE->{'UNDEF_KEY'},
+							"MAC address MUST BE defined for interface ".$iface." which is on dhcpvlan ".$dhcpvlan );
+					}
+					foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+						next if ( ! $pf_config->{'features'}->{$ip_type} );
+						my $addr_key	= ( $ip_type eq 'ipv6' ) ? 'BY_ADDR6' : 'BY_ADDR';
+						my $zone_key	= ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
+						my $dhcp_key	= ( $ip_type eq 'ipv6' ) ? 'DHCP6' : 'DHCP';
+						my $suffix		= ( $ip_type eq 'ipv6' ) ? '6' : '';
+						my $zone_part	= $global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'BY_SITE'}->{$site};
+						my $dhcp_part	= $global_config->{$dhcp_key}->{'BY_SITE'}->{$site};
+						$site_part->{'HOST'}->{$addr_key}->{$if2add->{$ip_type}} = $hostname.'.'.$if2add->{'vlan'};
+						if ( ! defined $zone_part->{$hostclass} ) {
+							$zone_part->{$hostclass} = {};
+							push ( @{$global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'__hostclass_order'}->{$site}}, $hostclass );
+						}
+						$zone_part->{$hostclass}->{$hostname.'.'.$if2add->{'vlan'}}		= "A\t".$if2add->{$ip_type};
+						my $shortname_vlan	= $host2add->{'dns'}->{'shortname.'.$host_number} || $host2add->{'dns'}->{'shortname'} || "";
+						if ( $shortname_vlan eq $if2add->{'vlan'} ) {
+							push ( @{$zone_part->{$hostclass}->{$shortname.'.'.$if2add->{'vlan'}}}, "A\t".$if2add->{$ip_type} );
+							$zone_part->{$hostclass}->{$shortname} = "CNAME\t".$shortname.'.'.$if2add->{'vlan'};
+						}
+						foreach my $key ( keys %{$host2add->{'dns'}} ) {
+							next if ( $key !~ /^alias/ );
+							my ( $key_type, $alias, $host_num ) = split ( /\./, $key );
+							if ( $host2add->{'dns'}->{$key} eq $if2add->{'vlan'} ) {
+								$zone_part->{$hostclass}->{$alias.'.'.$if2add->{'vlan'}}				= "CNAME\t".$shortname.'.'.$if2add->{'vlan'};
+								$zone_part->{$hostclass}->{$alias.$host_number.'.'.$if2add->{'vlan'}}	= "CNAME\t".$hostname.'.'.$if2add->{'vlan'};
+							}
+						}
+						my $resolver = $host2add->{'dns'}->{'resolver.'.$host_number} || $host2add->{'dns'}->{'resolver'};
+						if ( $if2add->{'vlan'} eq $dhcpvlan ) {
+							if ( ! defined $dhcp_part->{$dhcpvlan} ) {
+								$dhcp_part->{$dhcpvlan} = {};
+								$dhcp_part->{$dhcpvlan}->{'subnet'}		= $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan}->{'network'.$suffix};
+								$dhcp_part->{$dhcpvlan}->{'netmask'}	= $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan}->{'netmask'.$suffix};
+								if ( $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan}->{'gateway'.$suffix} ) {
+									$dhcp_part->{$dhcpvlan}->{'routers'} = $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan}->{'gateway'.$suffix};
+								}
+							}
+							$dhcp_part->{$dhcpvlan}->{$hostclass} = {} if ( ! defined $dhcp_part->{$dhcpvlan}->{$hostclass} );
+							$dhcp_part->{$dhcpvlan}->{$hostclass}->{$hostname} = [
+								'hardware ethernet '.$if2add->{'mac'}.';',
+								'fixed-address '.$if2add->{$ip_type}.';',
+								'filename '.$host2add->{'boot'}->{'pxefilename'}.';',
+								'option domain-name-servers '.$resolver.';'
+							];
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+
+#### BACKWARD Compatibility
+sub Get_Host_Props ($$;$) {
+    my ( $hostname, $global_config, $site ) = @_ ;
+
+	return Get_host_config_from_CONFIG ( $hostname, $global_config, $site );
+}
+
+1;

Modified: branches/next-gen/lib/PFTools/Net.pm
URL: http://svn.debian.org/wsvn/pf-tools/branches/next-gen/lib/PFTools/Net.pm?rev=787&op=diff
==============================================================================
--- branches/next-gen/lib/PFTools/Net.pm (original)
+++ branches/next-gen/lib/PFTools/Net.pm Wed Jul 28 09:35:48 2010
@@ -30,14 +30,12 @@
 our @ISA = ('Exporter');
 
 our @EXPORT = qw(
-	Mk_interfaces
 	Add_network
 	Add_site
 	Add_zone
-	Add_server
-	Add_host
 	Get_site_list
 	Get_site_zone_from_GLOBAL
+	Get_netblock_from_vlan
 );
 
 our @EXPORT_OK = qw();
@@ -744,36 +742,6 @@
 
 #########################################################################
 #
-# 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 ) = @_;
-	
-	if ( $ref_site->{'state'} eq 'EDGE' ) {
-		if ( defined $ref_site->{'prefix'} ) {
-			return $ref_site->{'prefix'}.'-';
-		}
-		else {
-			return $site.'-';
-		}
-	}
-	else {
-		return '';
-	}
-}
-
-#########################################################################
-#
 # ARRAYREF __Get_site_list ( HASHREF , HASHREF )
 #
 # This function adds build the site list for a given section
@@ -799,7 +767,7 @@
 
 #########################################################################
 #
-# NetAddr::IP __Get_netblock_from_vlan ( STR , HASHREF )
+# NetAddr::IP Get_netblock_from_vlan ( STR , HASHREF )
 #
 # This function build a NetAddr::IP object, in the same time permits the control
 # of IP values defined for a given network definition
@@ -810,7 +778,7 @@
 # Output :
 #  Return a NetAddr::IP object containing the netblock for a specifed network definition
 #
-sub __Get_netblock_from_vlan ($$) {
+sub Get_netblock_from_vlan ($$) {
 	my ( $type, $net_hash ) = @_;
 	
 	my $suffix = ( $type eq 'ipv6' ) ? '6' : '';
@@ -864,7 +832,7 @@
 	foreach my $ip_type ( 'ipv4', 'ipv6' ) {
 		next if ( ! $pf_config->{'features'}->{$ip_type} );
 		my $suffix		= ( $ip_type eq 'ipv6') ? '6' : '';
-		my $net_block	= __Get_netblock_from_vlan ( $ip_type, $ref_net );
+		my $net_block	= Get_netblock_from_vlan ( $ip_type, $ref_net );
 		my $zone_key	= ( $ip_type eq 'ipv6') ? 'ZONE6' : 'ZONE';
 		my $dhcp_key	= ( $ip_type eq 'ipv6') ? 'DHCP6' : 'DHCP';
 		my $netaddr_key	= ( $ip_type eq 'ipv6') ? 'BY_ADDR6' : 'BY_ADDR';
@@ -929,891 +897,6 @@
 	}
 }
 
-#########################################################################
-#
-# 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 );
-	
-	
-	$node_last	= ( $ref_hostgroup->{'nodes'} )
-		? ( $ref_hostgroup->{'nodes'} -1 )
-		: 0;
-	$num_last		= $ref_hostgroup->{'number'} - 1;
-	$hostname_model	=~ /(%*)(_*)$/;
-	$digits			= length ($1) || 0;
-	$nodes			= length ($2) || 0;
-	# Checking nodes
-	if ( $node_last && ! $nodes ) {
-		Abort ( $CODE->{'INVALID_VALUE'},
-			"Unable to affect all ".$node_last." nodes : no _ defined in key hostname" );
-	}
-	elsif ( $node_last && ceil ( log($node_last) / log(26) ) > $nodes ) {
-		Warn ( $CODE->{'INVALID_VALUE'},
-			"Not enough places for indexing nodes definition for host ".$hostname_model );
-	}
-	# Checking hostnum
-	if ( $num_last && ! $digits ) {
-		Abort ( $CODE->{'INVALID_VALUE'},
-			"Unable to affect all host number(s) : no % defined in key hostname ".$hostname_model );
-	}
-	elsif ( $num_last && $num_last > 10**$digits ) {
-		Warn ( $CODE->{'INVALID_VALUE'},
-			"Not enough places for indexing host number(s) according to hostname ".$hostname_model );
-	}
-	return ( $num_last, $node_last );
-}
-
-#########################################################################
-#
-# 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, $digits, $nodes, $index );
-
-	$hostname = $hostname_model;
-	if ( $hostname !~ /%+/ && $hostname !~ /_+/ ) {
-		return $hostname;
-	}
-	$hostname_model	=~ /(%*)(_*)$/;
-	$digits			= length ($1) || 0;
-	$nodes			= length ($2) || 0;
-	$index			= "";
-	while ( $digits > length ( $hostnum ) ) {
-		$index .= "0";
-		$digits--;
-	}
-	$index = ( $hostnode )
-		? $index.$hostnum.$hostnode
-		: $index.$hostnum;
-	$hostname =~ s/(%*)(_*)$/$index/;
-	$hostname = $site_prefix.$hostname if ( $ref_host->{'prefix'} && $ref_host->{'prefix'} eq 'true' );
-	return $hostname;
-}
-
-#########################################################################
-#
-# 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;
-	
-	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 ( /^$site$/, @{$site_list} ) );
-				next;
-			}
-			foreach my $host ( keys %{$host_part->{$hostclass}} ) {
-				if ( $host eq $hostname ) {
-					push (  @{$site_list}, $site ) if ( ! grep ( /^$site$/, @{$site_list} ) );
-					last;
-				}
-			}
-		}
-	}
-	return $site_list;
-}
-
-#########################################################################
-#
-# STR Get_hosttype_from_hostname ( STR, STR, STR, 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
-#  - $site			: define here the site where hostname is defined
-#
-# Output :
-#  Returns a string containing the hosttype or undef if hostname doesn't exist
-#
-sub Get_hosttype_from_hostname ($$;$) {
-	my ( $hostname, $global_config, $site ) = @_;
-	my $site_list;
-
-	if ( ! defined $site ) {
-		$site_list = $global_config->{'SITE'}->{'__site_list'};
-	}
-	else {
-		$site_list = [ $site ];
-	}
-	
-	foreach my $site ( @{$site_list} ) {
-		my $host_part = $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'HOST'}->{'BY_NAME'};
-		foreach my $hostclass ( keys %{$host_part} ) {
-			return $hostclass if ( $hostclass eq $hostname );
-			foreach my $host ( keys %{$host_part->{$hostclass}} ) {
-				return $hostclass if ( $host eq $hostname );
-			}
-		}
-	}
-	return undef;
-}
-
-#########################################################################
-#
-# 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 ($$) {
-	my ( $hostname, $global_config ) = @_;
-	
-	my $hostclass = __Get_hosttype_from_hostname ( $hostname, $global_config );
-	if ( ! defined $hostclass ) {
-		Abort ( $CODE->{'UNDEF_KEY'},
-			"Unable to get hosttype from hostname ".$hostname." : unexistant hostname" );
-	}
-	my $site_list = Get_site_from_hostname ( $hostname, $global_config );
-	if ( ! defined $site_list ) {
-		Abort ( $CODE->{'UNDEF_KEY'},
-			"Unable to get site list from hostname ".$hostname." : unexistant hostname" );
-	}
-	else {
-		if ( scalar @{$site_list} > 1 ) {
-			Warn ( $CODE->{'DUPLICATE_VALUE'},
-				"Hostname ".$hostname." is defined on multiple sites : unable to choose the right one" );
-			return undef;
-		}
-		else {
-			my ( $site ) = @{$site_list};
-			return $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'HOST'}->{'BY_NAME'}->{$hostclass}->{'deployment'}->{'hostname_model'};
-		}
-	}
-}
-
-#########################################################################
-#
-# 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 );
-
-	foreach my $section ( keys %{$ref_src} ) {
-		next if ( $section !~ /^interface/ );
-		$section =~ /^interface::(((eth|bond)[\d]+)(\.(TAG[\d]+|\d+))?)$/;
-		push ( @if_list, $1 );
-	}
-	return @if_list;
-}
-
-#########################################################################
-#
-# STR Get_ip_from_hostindex ( NetAddr::IP, STR, STR, STR, INT )
-#
-# This function returns the host IP for a given number and node
-# Inputs :
-#  - $net_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
-#
-# Output :
-#  Returns a NetAddr::IP object containing the IP
-#
-sub __Get_ip_from_hostindex ($$;$$$) {
-	my ( $net_block, $ipstart, $hostnum, $hostnode, $nodes ) = @_;
-	
-	my $ip = new NetAddr::IP ( $net_block->prefix().$ipstart, $net_block->mask() );
-	if ( ! defined $ip ) {
-		Abort ( $CODE->{'UNDEF_KEY'},
-			"Unable to create IP object from prefix ".$net_block->prefix()." and host ".$ipstart );
-	}
-	if ( $hostnum ) {
-		my $add = ( $hostnode )
-			? ( $hostnum * $nodes ) + $hostnode
-			: $hostnum;
-		$ip = $ip + $add;
-	}
-	return $ip;
-}
-
-#########################################################################
-#
-# 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 ) = @_;
-
-	my $prefix = $vlan_block->prefix();
-	my $realip = __Get_ip_from_hostindex ( $vlan_block, $ipstart, $hostnum, $hostnode, $nodes ) ;
-	my $host_addr_site = $ref_site->{'HOST'}->{'BY_ADDR'};
-	if ( defined $host_addr_site->{$realip->addr()} ) {
-		Abort ( $CODE->{'DUPLICATE_VALUE'},
-			"IP ".$realip->addr()." is already in use by host ".$host_addr_site->{$realip->cidr()}
-			." on site ".$site );
-	}
-	if ( ! $vlan_block->contains ( $realip ) ) {
-		Abort ( $CODE->{'INVALID_VALUE'},
-			"IP of type ".$ip_type." is out of ".$vlan_block->cidr()." on site ".$site );
-	}
-	return $realip;
-}
-
-#####################################################################################
-#
-# 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 = [];
-
-	foreach my $key ( keys %{$ref_srv} ) {
-		next if ( $key !~ /^ipv/ );
-		my ( $type, $vlan, $num ) = split ( /\./, $key );
-		push ( @{$vlan_list}, $vlan ) if ( ! grep ( /^$vlan$/, @{$vlan_list} ) );
-	}
-	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 if ( $key !~ /^alias/ );
-		my ( $alias, $name, $host_num ) = split ( /\./, $key );
-		next if ( $host_number && $host_num && $host_num ne $host_number );
-		push ( @{$alias_list}, $name ) if ( 
-			$vlan eq $ref_parsed->{$key}
-			&& ! grep ( /^$name$/, @{$alias_list} ) );
-	}
-	return $alias_list;
-}
-
-########################################################################################
-#
-# STR __Get_vlan_tag_from_site ( STR, 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			: specify here the site's name as defined into pf-tools configuration
-#  - $global_config	: hashref containing the global configuration parsed
-#
-# Output :
-#  Returns the tag if defined undef undef if not.
-#
-sub __Get_vlan_tag_from_site ($$$) {
-	my ( $vlan, $site, $global_config ) = @_;
-	
-	foreach my $tag ( keys %{$global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'NETWORK'}->{'BY_TAG'}} ) {
-		return $tag if ( $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'NETWORK'}->{'BY_TAG'}->{$tag} eq $vlan );
-	}
-	return;
-}
-
-#########################################################################
-#
-# VOID Add_server ( STR, STR, HASHREF, HASHREF, HASHREF )
-#
-# This function adds server into global configuration
-# Inputs :
-#  - $srvfile		: filename where server is parsed
-#  - $srvname_model	: model for the server name
-#  - $srv2add		: hashref where are stored server definitions according to networkfile-syntax
-#  - $global_config	: hashref where are stored global configuration datas
-#  - $pf_config		: hashref where are stored pf-tools configuration datas
-#
-sub Add_server ($$$$$) {
-	my ( $srvfile, $srvname_model, $srv2add, $global_config, $pf_config ) = @_;
-	
-	$srvname_model					=~ /^$pf_config->{'regex'}->{'hostname'}$/ ;
-	my $shortname					= $1;
-	my $hostclass					= $shortname;
-	my $site_list					= Get_site_list ( $srv2add, $global_config );
-	my ( $host_last, $node_last )	= __Get_host_indexes ( $srv2add, $srvname_model );
-	my $nodes						= $srv2add->{'nodes'} || 0;
-	foreach my $site ( @{$site_list} ) {
-		my $site_part	= $global_config->{'SITE'}->{'BY_NAME'}->{$site};
-		if ( ! defined $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} ) {
-			$site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} = {};
-		}
-		my $srv_part	= $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass};
-		my $zone		= $site_part->{'zone'};
-		my $prefix		= __Get_site_prefix ( $site, $global_config->{'SITE'}->{'BY_NAME'}->{$site} );
-		my $vlan_list	= __Get_vlan_list_from_server ( $srv2add );
-		foreach my $hostnum ( 0 .. $host_last ) {
-			foreach my $hostnode (  0 .. $node_last ) {
-				my $srvname = __Get_hostname_from_model ( $srvname_model, $hostnum, $hostnode, $prefix );
-				if ( $srv_part->{$srvname} ) {
-					Warn ( $CODE->{'DUPLICATE_VALUE'},
-						"Hostclass ".$hostclass." already contains hostname ".$srvname." definition from file "
-						.$srvfile." and for site ".$site." : skipping this hostname" );
-					next;
-				}
-				my $srv_number	= ( $hostnode ) ? $hostnum.$hostnode : $hostnum;
-				my $short_vlan	= $srv2add->{'shortname.'.$srv_number} || $srv2add->{'shortname'} || "";
-				my $iface_idx	= 0;
-				foreach my $ip_type ( 'ipv4', 'ipv6' ) {
-					next if ( ! $pf_config->{'features'}->{$ip_type} );
-					my $addr_key	= ( $ip_type eq 'ipv6' ) ? 'BY_ADDR6' : 'BY_ADDR';
-					my $zone_key	= ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
-					my $dhcp_key	= ( $ip_type eq 'ipv6' ) ? 'DHCP6' : 'DHCP';
-					my $suffix		= ( $ip_type eq 'ipv6' ) ? '6' : '';
-					my $zone_part	= $global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'BY_SITE'}->{$site};
-					foreach my $vlan ( @{$vlan_list} ) {
-						my $net_block	= __Get_netblock_from_vlan ( $ip_type, $site_part->{'NETWORK'}->{'BY_NAME'}->{$vlan} );
-						if ( ! defined $net_block ) {
-							Abort ( $CODE->{'INVALID_VALUE'},
-								"Unable to retrieve network block of type ".$ip_type." for vlan ".$vlan
-								." on site ".$site." for host ".$srvname );
-						}
-						my $realip;
-						if ( $srv2add->{$ip_type.'.'.$vlan.'.'.$srv_number} ) {
-							$realip = __Check_host_ip ( $ip_type, $net_block, $srv2add->{$ip_type.'.'.$vlan.'.'.$srv_number}, 0, 0, 0, $site, $site_part );
-						}
-						else {
-							$realip = __Check_host_ip ( $ip_type, $net_block, $srv2add->{$ip_type.'.'.$vlan}, $hostnum, $hostnode, $nodes, $site, $site_part );
-						}
-						$srv_part->{$srvname} = {
-							'interfaces'	=> {}
-						} if ( ! defined $srv_part->{$srvname} );
-						$srv_part->{$srvname}->{'interfaces'}->{'eth'.$iface_idx} = {
-							$ip_type			=> $realip->addr(),
-							'netmask'.$suffix	=> $realip->mask(),
-							'vlan'				=> $vlan
-						};
-						$iface_idx++;
-						$site_part->{'HOST'}->{$addr_key}->{$realip->addr()} = $srvname.'.'.$vlan;
-						if ( ! defined $zone_part->{$hostclass} ){
-							$zone_part->{$hostclass} = {};
-							push ( @{$global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'__hostclass_order'}->{$site}}, $hostclass );
-						}
-						$zone_part->{$hostclass}->{$srvname.'.'.$vlan}		= "A\t".$realip->addr();
-						if ( $short_vlan eq $vlan && $shortname ne $srvname ) {
-							print $shortname."\n";
-							print Dumper $zone_part->{$hostclass};
-							push ( @{$zone_part->{$hostclass}->{$shortname.'.'.$vlan}}, "A\t".$realip->addr() );
-						}
-						my $alias_list = __Get_alias_list_from_server ( $srv2add, $vlan, $srv_number );
-						foreach my $alias ( @{$alias_list} ) {
-							if ( ! defined $zone_part->{$hostclass}->{$alias.'.'.$vlan} ) {
-								$zone_part->{$hostclass}->{$alias.'.'.$vlan} = "CNAME\t".$shortname.'.'.$vlan;
-							}
-							if ( $shortname ne $srvname ) {
-								$zone_part->{$hostclass}->{$alias.$srv_number.'.'.$vlan}	= "CNAME\t".$srvname.'.'.$vlan;
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-}
-
-#####################################################################################################
-#
-# 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, $ref_host, $ref_if_list, $site, $ref_site, $pf_config ) = @_;
-	my ( @if_list, $vlan, $ifraw, $iftag, $add_if, $iface_opt );
-
-	my $network_site	= $ref_site->{'NETWORK'};
-	my $host_site		= $ref_site->{'HOST'};	
-	my $iface_section	= 'interface::'.$iface;
-	my $nodes			= $ref_host->{'hostgroup'}->{'nodes'} || 0;
-	my $host_number		= ( $hostnode ) ? $hostnum.$hostnode : $hostnum;
-	$iface =~ /^((eth|bond)[\d]+)(\.(TAG[\d]+))?$/;
-	( $ifraw, $iftag )	= ( $1, $4 );
-	$vlan		= $ref_host->{$iface_section}->{'vlan.'.$host_number} || $ref_host->{$iface_section}->{'vlan'};
-	$iface_opt	= $ref_host->{$iface_section}->{'iface_opt.'.$host_number} || $ref_host->{$iface_section}->{'iface_opt'};
-	$add_if->{'vlan'}		= $vlan;
-	$add_if->{'iface_opt'}	= $iface_opt if ( defined $iface_opt );
-	# Check MAC address if defined
-	if ( defined $ref_host->{$iface_section}->{'mac.'.$host_number} ) {
-		my $mac = $ref_host->{$iface_section}->{'mac.'.$host_number};
-		if ( $host_site->{'BY_MAC'}->{$mac} ) {
-			my ( $ifdef, $hostdef, $vlandef ) = split ( /\./, $host_site->{'BY_MAC'}->{$mac} );
-			Abort ( $CODE->{'DUPLICATE_VALUE'},
-				"MAC address ".$mac." is already defined for interface ".$ifdef." in host ".$hostdef
-				." which is on vlan ".$vlandef );
-		}
-		$add_if->{'mac'}	= $mac;
-	}
-	# Check tag
-	if ( $iftag && $iftag =~ /^\d+$/ ) {
-		Abort ( $CODE->{'INVALID_VALUE'},
-			"Tag ".$iftag." defined on section name ".$iface_section." differs from "
-			.$ref_host->{'vlan'}." network definition" );
-	}
-	if ( $iface =~ /^bond/ && ! $iftag ) {
-		# Check if slaves not in use
-		my @slaves = ( $ref_host->{$iface_section}->{'slaves.'.$host_number} )
-			? split ( /\s*,\s*/, $ref_host->{$iface_section}->{'slaves.'.$host_number} )
-			: split ( /\s*,\s*/, $ref_host->{$iface_section}->{'slaves'} );
-		foreach my $if ( @slaves ) {
-			Abort ( $CODE->{'INVALID_VALUE'},
-				"Interface ".$if." cannot be enslaved by ".$iface." : already in use for "
-				.$hostname ) if ( grep ( /$if/, @{$ref_if_list} ) );
-		}
-		$add_if->{'slaves'} = join ( " ", @slaves );
-	}
-	# Check vlan
-	if ( ! defined $network_site->{'BY_NAME'}->{$vlan} ) {
-		Abort ( $CODE->{'INVALID_VALUE'},
-			"Unknown vlan ".$vlan." on site ".$site." for interface ".$iface.
-			" defined on host ".$hostname );
-	}
-	# Check address and route values
-	foreach my $ip_type ( 'ipv4', 'ipv6' ) {
-		next if ( ! $pf_config->{'features'}->{$ip_type} );
-		my $suffix		= ( $ip_type eq 'ipv6' ) ? '6' : '';
-		my $netblock	= __Get_netblock_from_vlan ( $ip_type, $network_site->{'BY_NAME'}->{$vlan} );
-		if ( ! defined $netblock ) {
-			Abort ( $CODE->{'INVALID_VALUE'},
-				"Unable to retrieve network block of type ".$ip_type." for vlan ".$vlan
-				." on site ".$site." for host ".$hostname );
-		}
-		my $realip;
-		if ( $ref_host->{$iface_section}->{$ip_type.'.'.$host_number} ) {
-			$realip = __Check_host_ip ( $ip_type, $netblock, $ref_host->{$iface_section}->{$ip_type.'.'.$host_number}, 0, 0, 0, $site, $ref_site );
-		}
-		else {
-			$realip = __Check_host_ip ( $ip_type, $netblock, $ref_host->{$iface_section}->{$ip_type}, $hostnum, $hostnode, $nodes, $site, $ref_site );
-		}
-		$add_if->{$ip_type}				= $realip->cidr();
-# 		$add_if->{'netmask'.$suffix}	= $realip->mask();
-# 		$add_if->{'broadcast'.$suffix}	= $realip->broadcast(); $add_if->{'broadcast'.$suffix} =~ s/\/.+$//;
-		my $route_key	= ( $ip_type eq 'ipv6' ) ? '@route6' : '@route';
-		$route_key		.= $hostnum if ( $ref_host->{$iface_section}->{$route_key.'.'.$host_number} );
-		my $gw_key		= ( $ip_type eq 'ipv6' ) ? 'gateway6' : 'gateway';
-		if ( defined $ref_host->{$iface_section}->{$route_key} ) {
-			foreach my $route ( @{$ref_host->{$iface_section}->{$route_key}} ) {
-				$route =~ /^(\S+)\s*(via\s*(\S+))?$/;
-				my ( $dest, $via ) = ( $1, $3 );
-				my $route2add = '';
-				if ( $dest ne 'default' ) {
-					my $ip_dest;
-					if ( $dest =~ /[g-zG-Z]+/ ) {
-						if ( defined $network_site->{'BY_NAME'}->{$dest} ) {
-							# Dest is a defined network ... translating into IP
-							$ip_dest = new NetAddr::IP ( $network_site->{'BY_NAME'}->{$dest}->{'network'}, $network_site->{'BY_NAME'}->{$dest}->{'netmask'} );
-							$route2add .= $ip_dest->cidr()." via ";
-						}
-						else {
-							# Potentially not parsed host on this site
-							$route2add .= $dest." via ";
-						}
-					}
-					else {
-						$ip_dest = new NetAddr::IP ( $dest );
-						if ( ! defined $ip_dest ) {
-							Abort ( $CODE->{'INVALID_VALUE'},
-								"Unable to check dest IP ".$dest." of type ".$ip_type." on \@route key for interface ".$iface
-								." for host ".$hostname." on site ".$site );
-						}
-						$route2add .= $ip_dest->cidr()." via ";
-					}
-				}
-				else {
-					$route2add .= "default via ";
-				}
-				if ( $via ) {
-					my $ip_via;
-					if ( $via eq 'GATEWAY' ) {
-						if ( ! defined  $network_site->{'BY_NAME'}->{$vlan}->{$gw_key} ) {
-							Abort ( $CODE->{'INVALID_VALUE'},
-								"Unable to define default route by vlan ".$vlan." : no gateway defined on this one" );
-						}
-						$route2add .= $network_site->{'BY_NAME'}->{$vlan}->{$gw_key};
-					}
-					elsif ( $via =~ /[g-zG-Z]+/ ) {
-						# Potentially not parsed host ... skipping this case for now
-						$route2add .= $via;
-					}
-					else {
-						my $ip_via = new NetAddr::IP ( $via );
-						if ( ! defined $ip_via ) {
-							Abort ( $CODE->{'INVALID_VALUE'},
-								"Unable to check IP ".$via." of type ".$ip_type." as gateway for interface ".$iface
-								." for host ".$hostname." on site ".$site );
-						}
-						elsif ( ! $netblock->contains ( $ip_via ) ) {
-							Abort ( $CODE->{'INVALID_VALUE'},
-								"IP ".$ip_via." of type ".$ip_type." for gateway on interface ".$iface
-								." is out of ".$netblock." for host ".$hostname." on site ".$site );
-						}
-						$route2add .= $ip_via->addr();
-					}
-				}
-				push ( @{$add_if->{$route_key}}, $route2add );
-			}
-		}
-	}
-	return $add_if;
-}
-
-#########################################################################
-#
-# 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
-#
-sub Add_host ($$$$) {
-	my ( $hostfile, $host2add, $global_config, $pf_config ) = @_;
-
-	my $hostname_model	= $host2add->{'hostgroup'}->{'hostname'};
-	$hostname_model		=~ /^$pf_config->{'regex'}->{'hostname'}$/ ;
-	my $shortname		= $1;
-	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 !~ /\/$/ );
-	my ( $host_last, $node_last )	= __Get_host_indexes ( $host2add->{'hostgroup'}, $hostname_model );
-	
-	foreach my $site ( @{$site_list} ) {
-		my $site_part	= $global_config->{'SITE'}->{'BY_NAME'}->{$site};
-		if ( ! defined $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} ) {
-			$site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} = {};
-		}
-		my $host_part	= $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass};
-		my $zone		= $site_part->{'zone'};
-		my $prefix		= __Get_site_prefix ( $site, $global_config->{'SITE'}->{'BY_NAME'}->{$site} );
-		foreach my $hostnum ( 0 .. $host_last ) {
-			foreach my $hostnode (  0 .. $node_last ) {
-				my $hostname = __Get_hostname_from_model ( $hostname_model, $hostnum, $hostnode, $prefix );
-				if ( $host_part->{$hostname} ) {
-					Warn ( $CODE->{'DUPLICATE_VALUE'},
-						"Hostclass ".$hostclass." already contains hostname ".$hostname." definition from file "
-						.$hostfile." and for site ".$site." : skipping this hostname" );
-					next;
-				}
-				my $host_number = ( $hostnode ) ? $hostnum.$hostnode : $hostnum;
-				# Checking path for PXE elements kernel, initrd ...
-				foreach my $key ( 'pxefilename', 'kernel', 'initrd', 'kerneluml', 'initrduml', 'console', 'cmdline' ) {
-					my $value;
-					if ( $key eq 'console' ) {
-						$value = $host2add->{'boot'}->{$key.'.'.$host_number} || $host2add->{'boot'}->{$key} || $site_part->{$key};
-					}
-					elsif ( $key eq 'cmdline' ) {
-						$value = $host2add->{'boot'}->{$key.'.'.$host_number} || $host2add->{'boot'}->{$key} || "";
-					}
-					else {
-						$value = $host2add->{'boot'}->{$key.'.'.$host_number} || $host2add->{'boot'}->{$key};
-						next if ( ! defined $value );
-						if ( ! -e $pf_tftp_dir.$value ) {
-							Warn ( $CODE->{'OPEN'},
-								"Unable to find file ".$pf_tftp_dir.$value." for key ".$key." for host ".$hostname." from file ".$hostfile );
-						}
-					}
-					$host_part->{$hostname}->{'boot'}->{$key}	= $value;
-				}
-				my $dhcpvlan = $host2add->{'deployment'}->{'dhcpvlan.'.$host_number} || $host2add->{'deployment'}->{'dhcpvlan'} || $site_part->{'dhcpvlan'};
-				if ( ! defined $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan} ) {
-					Abort ( $CODE->{'INVALID_VALUE'},
-						"Vlan ".$dhcpvlan." defined for ".$hostname." from file ".$hostfile." doesn't exist on site ".$site );
-				}
-				foreach my $key ( 'arch', 'distrib', 'mode', 'os_type' ) {
-					my $value = $host2add->{'deployment'}->{$key.'.'.$host_number} || $host2add->{'deployment'}->{$key};
-					next if ( ! defined $value );
-					$host_part->{$hostname}->{'deployment'}->{$key} = $value;
-				}
-				$host_part->{$hostname}->{'deployment'}->{'hostname_model'} = $host2add->{'hostgroup'}->{'hostname'};
-				$host_part->{$hostname}->{'dns'}->{'resolver'} = $host2add->{'dns'}->{'resolver.'.$host_number} || $host2add->{'dns'}->{'resolver'};
-				# Check interfaces
-				my @if_list = __Get_host_interfaces ($host2add);
-				foreach my $iface ( @if_list ) {
-					my $if2add = __Add_host_interface ( $iface, $hostname, $hostnum, $hostnode, $host2add, \@if_list, $site, $site_part, $pf_config );
-					my $iface_name = $iface;
-					if ( $iface =~ /^((eth|bond)[\d]+)(\.(TAG[\d]+))$/ ) {
-						$iface_name = $1.'.'.__Get_vlan_tag_from_site ( $if2add->{'vlan'}, $site, $global_config );
-					}
-					# 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 && ! defined $if2add->{'mac'} ) {
-						Abort ( $CODE->{'UNDEF_KEY'},
-							"MAC address MUST BE defined for interface ".$iface." which is on dhcpvlan ".$dhcpvlan );
-					}
-					foreach my $ip_type ( 'ipv4', 'ipv6' ) {
-						next if ( ! $pf_config->{'features'}->{$ip_type} );
-						my $addr_key	= ( $ip_type eq 'ipv6' ) ? 'BY_ADDR6' : 'BY_ADDR';
-						my $zone_key	= ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
-						my $dhcp_key	= ( $ip_type eq 'ipv6' ) ? 'DHCP6' : 'DHCP';
-						my $suffix		= ( $ip_type eq 'ipv6' ) ? '6' : '';
-						my $zone_part	= $global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'BY_SITE'}->{$site};
-						my $dhcp_part	= $global_config->{$dhcp_key}->{'BY_SITE'}->{$site};
-						$site_part->{'HOST'}->{$addr_key}->{$if2add->{$ip_type}} = $hostname.'.'.$if2add->{'vlan'};
-						if ( ! defined $zone_part->{$hostclass} ) {
-							$zone_part->{$hostclass} = {};
-							push ( @{$global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'__hostclass_order'}->{$site}}, $hostclass );
-						}
-						$zone_part->{$hostclass}->{$hostname.'.'.$if2add->{'vlan'}}		= "A\t".$if2add->{$ip_type};
-						my $shortname_vlan	= $host2add->{'dns'}->{'shortname.'.$host_number} || $host2add->{'dns'}->{'shortname'} || "";
-						if ( $shortname_vlan eq $if2add->{'vlan'} ) {
-							push ( @{$zone_part->{$hostclass}->{$shortname.'.'.$if2add->{'vlan'}}}, "A\t".$if2add->{$ip_type} );
-						}
-						foreach my $key ( keys %{$host2add->{'dns'}} ) {
-							next if ( $key !~ /^alias/ );
-							my ( $key_type, $alias, $host_num ) = split ( /\./, $key );
-							if ( $host2add->{'dns'}->{$key} eq $if2add->{'vlan'} ) {
-								$zone_part->{$hostclass}->{$alias.'.'.$if2add->{'vlan'}}				= "CNAME\t".$shortname.'.'.$if2add->{'vlan'};
-								$zone_part->{$hostclass}->{$alias.$host_number.'.'.$if2add->{'vlan'}}	= "CNAME\t".$hostname.'.'.$if2add->{'vlan'};
-							}
-						}
-						my $resolver = $host2add->{'dns'}->{'resolver.'.$host_number} || $host2add->{'dns'}->{'resolver'};
-						if ( $if2add->{'vlan'} eq $dhcpvlan ) {
-							if ( ! defined $dhcp_part->{$dhcpvlan} ) {
-								$dhcp_part->{$dhcpvlan} = {};
-								$dhcp_part->{$dhcpvlan}->{'subnet'}		= $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan}->{'network'.$suffix};
-								$dhcp_part->{$dhcpvlan}->{'netmask'}	= $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan}->{'netmask'.$suffix};
-								if ( $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan}->{'gateway'.$suffix} ) {
-									$dhcp_part->{$dhcpvlan}->{'routers'} = $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan}->{'gateway'.$suffix};
-								}
-							}
-							$dhcp_part->{$dhcpvlan}->{$hostclass} = {} if ( ! defined $dhcp_part->{$dhcpvlan}->{$hostclass} );
-							$dhcp_part->{$dhcpvlan}->{$hostclass}->{$hostname} = [
-								'hardware ethernet '.$if2add->{'mac'}.';',
-								'fixed-address '.$if2add->{$ip_type}.';',
-								'filename '.$host2add->{'boot'}->{'pxefilename'}.';',
-								'option domain-name-servers '.$resolver.';'
-							];
-						}
-					}
-				}
-			}
-		}
-	}
-}
-
-#########################################################################
-#
-# 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 :
-#  - $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 ) = @_ ;
-
-	if ( ! defined $site ) {
-		my $site_list = Get_site_from_hostname ( $hostname, $global_config );
-		if ( ! defined $site_list ) {
-			Warn ( $CODE->{'UNDEF_KEY'},
-				"Unable to retrieve site for hostname ".$hostname." : hostname not defined" );
-		}
-		elsif ( scalar @{$site_list} > 1 ) {
-			Warn ( $CODE->{'UNDEF_KEY'},
-				"Unable to retrieve site for hostname ".$hostname." : hostname appeared in multiple sites : "
-				.join ( ",", @{$site_list} ) );
-		}
-		else {
-			( $site ) = @{$site_list};
-		}
-	}
-	my $site_part					= $global_config->{'SITE'}->{'BY_NAME'}->{$site};
-	my $zone						= $site_part->{'zone'};
-	$hostname						=~ /^([^.]+)(\.([^.]+))?(\.$zone)?$/ ;
-	my ( $hostshort, $hostvlan )	= ( $1, $3 ) ;
-	my $hosttype					= Get_hosttype_from_hostname ( $hostname, $global_config );
-	return $site_part->{'HOST'}->{'BY_NAME'}->{$hosttype}->{$hostshort} ;
-}
-
-#### BACKWARD Compatibility
-sub Get_Host_Props ($$;$) {
-    my ( $hostname, $global_config, $site ) = @_ ;
-
-	return Get_host_config_from_CONFIG ( $hostname, $global_config, $site );
-}
-
-#
-#	VOID Mk_interfaces (STRING $host, STRING $fic_iface, HASHREF $Z)
-#
-#	Construit le fichier de declaration d'interfaces $fic_iface pour la
-#	machine $host a partir des informations contenues dans la structure $Z
-#
-#======================================================================================
-sub Mk_interfaces ($$$;$){
-    my ( $hostname, $global_config, $pf_config, $site ) = @_;
-
-	my $hostclass	= Get_hosttype_from_hostname ( $hostname, $global_config );
-	my $resolve		= 0;
-	my $properties	= Get_host_config_from_CONFIG ( $hostname, $global_config, $site );
-	my $interfaces	= {};
-	my $routes		= {};
-	
-	foreach my $iface ( 'lo', sort keys %{$properties->{'interfaces'}} ) {
-		push ( @{$interfaces->{'__order'}}, $iface );
-		my $if_part = $properties->{'interfaces'}->{$iface} if ( defined $properties->{'interfaces'}->{$iface});
-		push ( @{$interfaces->{$iface}}, "auto ".$iface );
-		if ( $if_part->{'method'} ) {
-			push ( @{$interfaces->{$iface}}, "iface ".$iface." inet ".$if_part->{'method'} );
-		}
-		elsif ( $iface eq 'lo' ) {
-			push ( @{$interfaces->{$iface}}, "iface ".$iface." inet loopback" );
-		}
-		else {
-			push ( @{$interfaces->{$iface}}, "iface ".$iface." inet static" );
-		}
-		next if ( ( $if_part->{'method'} && $if_part->{'method'} eq 'dhcp' ) || $iface eq 'lo' );
-		foreach my $ip_type ( 'ipv4', 'ipv6' ) {
-			next if ( ! $pf_config->{'features'}->{$ip_type} );
-			my $suffix = ( $ip_type eq 'ipv6' ) ? '6' : '';
-			my $ip = new NetAddr::IP ( $if_part->{$ip_type} );
-			push ( @{$interfaces->{$iface}}, "\tslaves\t\t".$if_part->{'slaves'} ) if ( $if_part->{'slaves'} );
-			push ( @{$interfaces->{$iface}}, "\taddress\t\t".$ip->addr() );
-			push ( @{$interfaces->{$iface}}, "\tnetmask\t\t".$ip->mask() );
-			my $net	= $ip->network(); push ( @{$interfaces->{$iface}}, "\tnetwork\t\t".$net->addr() );
-			my $broad = $ip->broadcast(); push ( @{$interfaces->{$iface}}, "\tbroadcast\t".$broad->addr() );
-			foreach my $route ( @{$if_part->{'@route'.$suffix}} ) {
-				$route =~ /^([^\s]+)\s*(via ([^\s]+))?$/;
-				push ( @{$routes->{$1}}, $iface." ".$route );
-			}
-			if ( $iface =~ /^([^\.]+)\.\d+$/ ) {
-				push ( @{$interfaces->{$iface}}, "\tvlan_raw_device\t".$1 );
-				if ( $if_part->{'iface_opt'} && $if_part->{'iface_opt'} !~ /mtu/ ) {
-					$if_part->{'iface_opt'} .= ",mtu 1496";
-				}
-				else {
-					$if_part->{'iface_opt'} = "mtu 1496";
-				}
-			}
-			if ( defined $if_part->{'iface_opt'} ) {
-				foreach my $option ( split ( /\s*,\s*/, $if_part->{'iface_opt'} ) ) {
-					push ( @{$interfaces->{$iface}}, "\tup\t\t/sbin/ip link set ".$iface." ".$option );
-				}
-			}
-			
-		}
-	}
-	foreach my $dest ( keys %{$routes} ) {
-		if ( scalar @{$routes->{$dest}} > 1 ) {
-			foreach my $entry ( @{$routes->{$dest}} ) {
-				my ( $if, $dst, $via, $gw ) = split ( /\s+/, $entry );
-				if ( ! defined $gw ) {
-					Warn ( $CODE->{'UNDEF_KEY'},
-						"Unable to add a route for destination ".$dst." with multiple gateway without gateway definition"
-						." on hostname ".$hostname );
-					last;
-				}
-				push ( @{$interfaces->{$if}}, "\tup\t\t/sbin/ip route add ".$dst." scope global via ".$gw." dev ".$if );
-			}
-		}
-		else {
-			my ( $entry ) = @{$routes->{$dest}};
-			my ( $if, $dst, $via, $gw ) = split ( /\s+/, $entry );
-			if ( $dst eq 'default' ) {
-				if ( ! defined $gw ) {
-					Abort ( $CODE->{'UNDEF_KEY'},
-						"Unable to define default route without gateway defined for interface ".$if." on hostname ".$hostname );
-				}
-				push ( @{$interfaces->{$if}}, "\tgateway\t\t$gw" );
-			}
-			else {
-				push ( @{$interfaces->{$if}}, "\tup\t\t/sbin/ip route add ".$entry." dev ".$if );
-			}
-		}
-	}
-	return $interfaces;
-}
 
 #
 #	STRING/ARRAY Resolv (STRING $host, HASHREF $Z)

Modified: branches/next-gen/sbin/mk_dhcp
URL: http://svn.debian.org/wsvn/pf-tools/branches/next-gen/sbin/mk_dhcp?rev=787&op=diff
==============================================================================
--- branches/next-gen/sbin/mk_dhcp (original)
+++ branches/next-gen/sbin/mk_dhcp Wed Jul 28 09:35:48 2010
@@ -24,141 +24,138 @@
 use strict;
 use warnings;
 
-use PFTools::Net;
-use PFTools::Conf ;
-use PFTools::Update;
+use Getopt::Long qw( :config ignore_case_always bundling );
+use PFTools::Conf;
+use PFTools::Logger;
 
-sub Mk_dhcp {
-    my ( $head, $fic, $Z ) = @_;
-    my $oldout;
-    my $vlan;
-    my $s;
+#####################################
+# Vars
+my $HELP				= 0;
+my $HEADER				= '';
+my $SITE				= '';
+my $GLOBAL_STORE_FILE	= '';
+my $PF_CONFIG_FILE		= '';
+my $PF_CONFIG			= {};
+my $OUTPUT_FILE			= '';
+my $GLOBAL_STRUCT		= {};
 
-    my $dhcpvlanregex
-	= '^([^.]+)\.('
-	. join( '|', @{ $Z->{'SOA'}->{'dhcpvlan'} } )
-	. ')(\.*)?$';
+my $program = $0;
+$program =~ s%.*/%%; # cheap basename
 
-    open( FIC, ">" . $fic ) || die "Cannot open " . $fic . " : " . $!;
-    $oldout = select(FIC);
+my $version = sprintf( "svn-r%s", q$Revision$ =~ /([\d.]+)/ );
 
-    open( HEAD, "<" . $head ) || die "Cannot open " . $head . " : " . $!;
+#####################################
+# Functions
 
-    while (<HEAD>) {
-	print;
-    }
+sub Do_help {
+    print STDERR << "# ENDHELP";
+    $program - version $version
 
-    close(HEAD);
-
-    print "\n";
-
-    foreach $vlan ( @{ $Z->{'SOA'}->{'dhcpvlan'} } ) {
-	printf( "# %s\n",
-	    $Z->{'NETWORK'}->{'BY_NAME'}->{$vlan}->{'comment'} );
-	printf(
-	    "subnet %s netmask %s {\n}\n\n",
-	    $Z->{'NETWORK'}->{'BY_NAME'}->{$vlan}->{'network'},
-	    $Z->{'NETWORK'}->{'BY_NAME'}->{$vlan}->{'netmask'}
-	);
-    }
-
-    print "\n";
-
-    foreach $s ( sort ( keys %{ $Z->{'SERVERS'}->{'BY_ADDR'} } ) ) {
-	foreach my $host ( @{$Z->{'SERVERS'}->{'BY_ADDR'}->{$s}} ) {
-
-	    print "# ",         $host->{'comment'}, "\n";
-	    print "# number: ", $host->{'number'},  "\n";
-	    print "# nodes:  ", $host->{'nodes'},   "\n" if ( defined( $host->{'nodes'} ) && $host->{'nodes'} > 1 );
-	    print "\n";
-
-	    foreach my $m ( sort ( keys %{ $host->{'SRVLIST'} } ) ) {
-		my $nam;
-		my $M = $host->{'SRVLIST'}->{$m};
-
-		foreach $nam ( sort ( keys %{ $M->{'zone'} } ) ) {
-		    if ( $nam =~ /$dhcpvlanregex/ ) {
-			my $nam2 = $1;
-
-			my $hostnum = $nam2;
-			$hostnum =~ s/^.*?(\d*)[a-z]*$/$1/;
-			$hostnum =~ s/^0*//;
-			if ( $hostnum eq "" ) { $hostnum = 0; }
-
-			if ( defined( $M->{'zone'}->{$nam}->{'ether'} ) ) {
-			    printf( "host %s {\n", $nam2 );
-			    printf( "  hardware ethernet %s;\n", $M->{'zone'}->{$nam}->{'ether'} );
-			    printf( "  fixed-address %s.%s;\n", $nam, $Z->{'SOA'}->{'name'} );
-
-			    if ( defined( $M->{'filename'} ) && $M->{'filename'} ne "" ) {
-				printf( "  filename \"%s\";\n", $M->{'filename'} );
-			    }
-
-			    if ( $M->{'initrd'} ) { printf qq{# initrd "%s";\n}, $M->{'initrd'}; }
-
-			    if ( $M->{'cmdline'} ) { printf qq{# cmdline "%s";\n}, $M->{'cmdline'}; }
-
-			    if ( $M->{'console'} ) { printf qq{# console "%s";\n}, $M->{'console'}; }
-
-			    if ( defined( $M->{'pxefilename'} ) && $M->{'pxefilename'} ne "" ) {
-				if ( $M->{'arch'} eq 'amd64' ) {
-				    printf( "# pxefilename \"%s\";\n", $M->{'arch'}."/".$M->{'pxefilename'} );
-				}
-				else {
-				    printf( "# pxefilename \"%s\";\n", $M->{'pxefilename'} );
-				}
-			    }
-
-			    if ( defined( $M->{'pxelinuxconf'} ) && $M->{'pxelinuxconf'} ne "" ) {
-				printf( "  option option-209 \"%s\";\n", $M->{'pxelinuxconf'} );
-			    }
-
-			    my @dns = Get_dns_from_zone( $Z, $M, $hostnum );
-
-			    if ( $#dns >= 0 && defined $dns[0] ) {
-				printf( "  option domain-name-servers %s;\n", join( ", ", @dns ) );
-			    }
-
-			    print "}\n\n";
-			}
-			if ( defined( $M->{'zone'}->{$nam}->{'vmether'} ) && ( $PFTOOLS_VARS->{'VMWARE'} || $PFTOOLS_VARS->{'UML'} ) ) {
-			    printf( "host %s {\n", $nam2 );
-			    printf( "  hardware ethernet %s;\n", $M->{'zone'}->{$nam}->{'vmether'} );
-			    printf( "  fixed-address %s.%s;\n", $nam, $Z->{'SOA'}->{'name'} );
-
-			    if ( defined( $M->{'vmwfilename'} ) && $M->{'vmwfilename'} ne "" ) {
-				printf( "  filename \"%s\";\n", $M->{'vmwfilename'} );
-			    }
-
-			    if ( defined( $M->{'pxelinuxconf'} ) && $M->{'pxelinuxconf'} ne "" ) {
-				printf( "  option option-209 \"%s\";\n", $M->{'pxelinuxconf'} );
-			    }
-
-			    my @dns = Get_dns_from_zone( $Z, $M, $hostnum );
-
-			    if ( $#dns >= 0 && defined $dns[0] ) {
-				printf( "  option domain-name-servers %s;\n", join( ", ", @dns ) );
-			    }
-
-			    print "}\n\n";
-			}
-		    }
-		}
-	    }
-	}
-	
-	print "\n";
-    }
-
-    $| = 1;
-    select($oldout);
-    close(FIC);
+Usage:	$0 [options]
+	--help		: print help and exit
+	-H --header : header file for dhcp configuration
+	-s --site	: site on which hostname is defined
+	--store		: file where global structure datas are in storable format (optional)
+	-c --config	: pf-tools config file (optional)
+	-o --output	: output file default value is /etc/network/interfaces
+    
+# ENDHELP
 }
 
-my ($HEAD, $SRC, $DST) = @ARGV;
-unless ( $HEAD and $SRC and $DST ) {
-    die "Usage: $0 head src dest\n";
+sub Mk_dhcp ($$) {
+	my ( $header_file, $site_part ) = @_;
+	my $dhcp = [];
+
+	if ( $header_file ne '' ) {
+		if ( ! -e $header_file ) {
+			Abort ( $CODE->{'OPEN'},
+				"Unable to open DHCP header file ".$header_file." : no such file or directory" );
+		}
+		elsif ( ! open ( HEAD, $header_file ) ) {
+			Abort ( $CODE->{'OPEN'},
+				"Unable to open DHCP header file ".$header_file );
+		}
+		foreach ( <HEAD> ) {
+			chomp;
+			push ( @{$dhcp}, $_ );
+		}
+		close ( HEAD );
+	}
+
+	foreach my $vlan ( keys %{$site_part} ) {
+		push ( @{$dhcp}, "subnet ".$site_part->{$vlan}->{'subnet'}
+			." netmask ".$site_part->{$vlan}->{'netmask'}." {" );
+		if ( $site_part->{$vlan}->{'routers'} ) {
+			push ( @{$dhcp}, "\toption routers ".$site_part->{$vlan}->{'routers'}.";", '' );
+		}
+		foreach my $hostclass ( keys %{$site_part->{$vlan}} ) {
+			next if ( $hostclass =~ /^(subnet|netmask|routers)$/);
+			my $host_part = $site_part->{$vlan}->{$hostclass};
+			foreach my $host ( keys %{$host_part} ) {
+				push ( @{$dhcp}, "\thost ".$host." {");
+				foreach my $def ( @{$host_part->{$host}} ) {
+					push ( @{$dhcp}, "\t\t".$def );
+				}
+				push ( @{$dhcp}, "\t}" );
+			}
+		}
+		push ( @{$dhcp}, "}", '' );
+	}
+	return $dhcp;
 }
 
-Mk_dhcp( Get_source($HEAD), $DST, Init_lib_net( Get_source($SRC) ) );
+############################################
+### MAIN
 
+GetOptions (
+	'help'			=> \$HELP,
+	'H|header=s'	=> \$HEADER,
+	'site|s=s'		=> \$SITE,
+	'config|c=s'	=> \$PF_CONFIG_FILE,
+	'store=s'		=> \$GLOBAL_STORE_FILE,
+	'output|o=s'	=> \$OUTPUT_FILE
+) or die "Didn't grok options (see --help).\n";
+
+if ( $HELP ) {
+	Do_help ();
+	exit 0;
+}
+
+if ( $PF_CONFIG_FILE ne '' ) {
+	if ( ! -e $PF_CONFIG_FILE ) {
+		Abort ( $CODE->{'OPEN'},
+			"Unable to open configuration file ".$PF_CONFIG_FILE." : no such file or directory" );
+	}
+	$PF_CONFIG = Init_PF_CONFIG ( $PF_CONFIG_FILE );
+}
+else {
+	$PF_CONFIG = Init_PF_CONFIG ();
+}
+
+$GLOBAL_STORE_FILE = $PF_CONFIG->{'path'}->{'global_struct'} if ( $GLOBAL_STORE_FILE eq '' );
+$GLOBAL_STRUCT = Retrieve_GLOBAL ( $GLOBAL_STORE_FILE );
+
+if ( ! defined $GLOBAL_STRUCT ) {
+	Abort ( $CODE->{'UNDEF_KEY'},
+		"An error occured during retrieve from the storable file ".$GLOBAL_STORE_FILE );
+}
+
+if ( $SITE eq '' && ! defined $PF_CONFIG->{'location'}->{'site'} ) {
+	Abort ( $CODE->{'UNDEF_KEY'},
+		"A site MUST BE defined for building DNS zone forward" );
+}
+elsif ( ! defined $GLOBAL_STRUCT->{'DHCP'}->{'BY_SITE'}->{$SITE} ) {
+	Abort ( $CODE->{'UNDEF_KEY'},
+		"Site ".$SITE." is not defined into global configuration" );
+}
+else {
+	my $DHCP = Mk_dhcp ( $HEADER, $GLOBAL_STRUCT->{'DHCP'}->{'BY_SITE'}->{$SITE} );
+	unless ( open ( DHCP, ">".$OUTPUT_FILE ) ) {
+		Abort ( $CODE->{'OPEN'},
+			"Unable to open zone file ".$OUTPUT_FILE );
+	}
+	print DHCP join ( "\n", @{$DHCP} );
+	close ( DHCP );
+}
+
+exit 0;

Modified: branches/next-gen/sbin/mk_interfaces
URL: http://svn.debian.org/wsvn/pf-tools/branches/next-gen/sbin/mk_interfaces?rev=787&op=diff
==============================================================================
--- branches/next-gen/sbin/mk_interfaces (original)
+++ branches/next-gen/sbin/mk_interfaces Wed Jul 28 09:35:48 2010
@@ -25,7 +25,7 @@
 
 use Getopt::Long qw( :config ignore_case_always bundling );
 use PFTools::Conf;
-use PFTools::Net;
+use PFTools::Host;
 use PFTools::Logger;
 use Sys::Hostname;
 
@@ -45,6 +45,9 @@
 
 my $version = sprintf( "svn-r%s", q$Revision$ =~ /([\d.]+)/ );
 
+###################################
+# Funtions
+
 sub Do_help {
     print STDERR << "# ENDHELP";
     $program - version $version
@@ -60,6 +63,100 @@
 # ENDHELP
 }
 
+#
+#	VOID Mk_interfaces (STRING $host, STRING $fic_iface, HASHREF $Z)
+#
+#	Construit le fichier de declaration d'interfaces $fic_iface pour la
+#	machine $host a partir des informations contenues dans la structure $Z
+#
+#======================================================================================
+sub Mk_interfaces ($$$;$){
+    my ( $hostname, $global_config, $pf_config, $site ) = @_;
+
+	my $resolve		= 0;
+	my $properties	= Get_host_config_from_CONFIG ( $hostname, $global_config, $site );
+	my $hostclass	= $properties->{'deployment'}->{'hosttype'};
+	my $interfaces	= {};
+	my $routes		= {};
+	
+	foreach my $iface ( 'lo', sort keys %{$properties->{'interfaces'}} ) {
+		push ( @{$interfaces->{'__order'}}, $iface );
+		my $if_part = $properties->{'interfaces'}->{$iface} if ( defined $properties->{'interfaces'}->{$iface});
+		push ( @{$interfaces->{$iface}}, "auto ".$iface );
+		if ( $if_part->{'method'} ) {
+			push ( @{$interfaces->{$iface}}, "iface ".$iface." inet ".$if_part->{'method'} );
+		}
+		elsif ( $iface eq 'lo' ) {
+			push ( @{$interfaces->{$iface}}, "iface ".$iface." inet loopback" );
+		}
+		else {
+			push ( @{$interfaces->{$iface}}, "iface ".$iface." inet static" );
+		}
+		next if ( ( $if_part->{'method'} && $if_part->{'method'} eq 'dhcp' ) || $iface eq 'lo' );
+		foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+			next if ( ! $pf_config->{'features'}->{$ip_type} );
+			my $suffix = ( $ip_type eq 'ipv6' ) ? '6' : '';
+			my $ip = new NetAddr::IP ( $if_part->{$ip_type} );
+			push ( @{$interfaces->{$iface}}, "\tslaves\t\t".$if_part->{'slaves'} ) if ( $if_part->{'slaves'} );
+			push ( @{$interfaces->{$iface}}, "\taddress\t\t".$ip->addr() );
+			push ( @{$interfaces->{$iface}}, "\tnetmask\t\t".$ip->mask() );
+			my $net	= $ip->network(); push ( @{$interfaces->{$iface}}, "\tnetwork\t\t".$net->addr() );
+			my $broad = $ip->broadcast(); push ( @{$interfaces->{$iface}}, "\tbroadcast\t".$broad->addr() );
+			foreach my $route ( @{$if_part->{'@route'.$suffix}} ) {
+				$route =~ /^([^\s]+)\s*(via ([^\s]+))?$/;
+				push ( @{$routes->{$1}}, $iface." ".$route );
+			}
+			if ( $iface =~ /^([^\.]+)\.\d+$/ ) {
+				push ( @{$interfaces->{$iface}}, "\tvlan_raw_device\t".$1 );
+				if ( $if_part->{'iface_opt'} && $if_part->{'iface_opt'} !~ /mtu/ ) {
+					$if_part->{'iface_opt'} .= ",mtu 1496";
+				}
+				else {
+					$if_part->{'iface_opt'} = "mtu 1496";
+				}
+			}
+			if ( defined $if_part->{'iface_opt'} ) {
+				foreach my $option ( split ( /\s*,\s*/, $if_part->{'iface_opt'} ) ) {
+					push ( @{$interfaces->{$iface}}, "\tup\t\t/sbin/ip link set ".$iface." ".$option );
+				}
+			}
+			
+		}
+	}
+	foreach my $dest ( keys %{$routes} ) {
+		if ( scalar @{$routes->{$dest}} > 1 ) {
+			foreach my $entry ( @{$routes->{$dest}} ) {
+				my ( $if, $dst, $via, $gw ) = split ( /\s+/, $entry );
+				if ( ! defined $gw ) {
+					Warn ( $CODE->{'UNDEF_KEY'},
+						"Unable to add a route for destination ".$dst." with multiple gateway without gateway definition"
+						." on hostname ".$hostname );
+					last;
+				}
+				push ( @{$interfaces->{$if}}, "\tup\t\t/sbin/ip route add ".$dst." scope global via ".$gw." dev ".$if );
+			}
+		}
+		else {
+			my ( $entry ) = @{$routes->{$dest}};
+			my ( $if, $dst, $via, $gw ) = split ( /\s+/, $entry );
+			if ( $dst eq 'default' ) {
+				if ( ! defined $gw ) {
+					Abort ( $CODE->{'UNDEF_KEY'},
+						"Unable to define default route without gateway defined for interface ".$if." on hostname ".$hostname );
+				}
+				push ( @{$interfaces->{$if}}, "\tgateway\t\t$gw" );
+			}
+			else {
+				push ( @{$interfaces->{$if}}, "\tup\t\t/sbin/ip route add ".$entry." dev ".$if );
+			}
+		}
+	}
+	return $interfaces;
+}
+
+##################################
+### MAIN
+
 GetOptions (
 	'help'			=> \$HELP,
 	'host|h=s'		=> \$HOSTNAME,
@@ -85,23 +182,15 @@
 	$PF_CONFIG = Init_PF_CONFIG ();
 }
 
-if ( $GLOBAL_STORE_FILE eq '' ) {
-	$GLOBAL_STRUCT = Retrieve_GLOBAL ( $PF_CONFIG->{'path'}->{'global_struct'} );
-}
-elsif ( ! -e $GLOBAL_STORE_FILE ) {
-	Abort ( $CODE->{'OPEN'},
-		"Unable to open global configuration storable file ".$GLOBAL_STORE_FILE." : no such file or directory" );
-}
-else {
-	$GLOBAL_STRUCT = Retrieve_GLOBAL ( $GLOBAL_STORE_FILE );
-}
+$GLOBAL_STORE_FILE = $PF_CONFIG->{'path'}->{'global_struct'} if ( $GLOBAL_STORE_FILE eq '' );
+$GLOBAL_STRUCT = Retrieve_GLOBAL ( $GLOBAL_STORE_FILE );
 
 if ( ! defined $GLOBAL_STRUCT ) {
 	Abort ( $CODE->{'UNDEF_KEY'},
 		"An error occured during retrieve from the storable file ".$GLOBAL_STORE_FILE );
 }
 
-if ( $SITE eq '' || ! defined $PF_CONFIG->{'location'}->{'site'} ) {
+if ( $SITE eq '' && ! defined $PF_CONFIG->{'location'}->{'site'} ) {
 	my $site_list = Get_site_from_hostname ( $HOSTNAME, $GLOBAL_STRUCT );
 	if ( ! defined $site_list ) {
 		Abort ( $CODE->{'UNDEF_KEY'},

Modified: branches/next-gen/sbin/mk_sitezone
URL: http://svn.debian.org/wsvn/pf-tools/branches/next-gen/sbin/mk_sitezone?rev=787&op=diff
==============================================================================
--- branches/next-gen/sbin/mk_sitezone (original)
+++ branches/next-gen/sbin/mk_sitezone Wed Jul 28 09:35:48 2010
@@ -165,6 +165,11 @@
 	'output|o=s'	=> \$OUTPUT_FILE
 ) or die "Didn't grok options (see --help).\n";
 
+if ( $HELP ) {
+	Do_help ();
+	exit 0;
+}
+
 if ( $PF_CONFIG_FILE ne '' ) {
 	if ( ! -e $PF_CONFIG_FILE ) {
 		Abort ( $CODE->{'OPEN'},
@@ -176,23 +181,15 @@
 	$PF_CONFIG = Init_PF_CONFIG ();
 }
 
-if ( $GLOBAL_STORE_FILE eq '' ) {
-	$GLOBAL_STRUCT = Retrieve_GLOBAL ( $PF_CONFIG->{'path'}->{'global_struct'} );
-}
-elsif ( ! -e $GLOBAL_STORE_FILE ) {
-	Abort ( $CODE->{'OPEN'},
-		"Unable to open global configuration storable file ".$GLOBAL_STORE_FILE." : no such file or directory" );
-}
-else {
-	$GLOBAL_STRUCT = Retrieve_GLOBAL ( $GLOBAL_STORE_FILE );
-}
+$GLOBAL_STORE_FILE = $PF_CONFIG->{'path'}->{'global_struct'} if ( $GLOBAL_STORE_FILE eq '' );
+$GLOBAL_STRUCT = Retrieve_GLOBAL ( $GLOBAL_STORE_FILE );
 
 if ( ! defined $GLOBAL_STRUCT ) {
 	Abort ( $CODE->{'UNDEF_KEY'},
 		"An error occured during retrieve from the storable file ".$GLOBAL_STORE_FILE );
 }
 
-if ( $SITE eq '' || ! defined $PF_CONFIG->{'location'}->{'site'} ) {
+if ( $SITE eq '' && ! defined $PF_CONFIG->{'location'}->{'site'} ) {
 	Abort ( $CODE->{'UNDEF_KEY'},
 		"A site MUST BE defined for building DNS zone forward" );
 }




More information about the pf-tools-commits mailing list