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