Xavier Beaudouin wrote:
> Assuming I have eth0 given by a dhcp I'd like to setup it to static
> ip... and
>
> eth1
> eth2
> eth3
>
> to another IP as well.
>
> For example facter gave me ipaddress => 172.16.20.11 <http://172.16.20.11>
>
> so eth0 will have 172.16.20.11 <http://172.16.20.11>, with gateway .254
> eth1 will have 172.17.20.11 <http://172.17.20.11>
> eth2 will have 172.18.20.11 <http://172.18.20.11>
> and
> eth3 will have 172.19.20.11 <http://172.19.20.11>..
>
> Now I don't know how to extract "last" number of IPv4 address and if
> there is nice way on RHEL4 with puppet to set interfaces without rewrite
> files "by hand" with puppet.
There are two parts to this question. The first is how to calculate the
addresses for eth1, eth2 and eth3 from the address of eth0, and the other
is how to actually configure eth1, eth2 and eth3.
For the first part, your question inspired me to write a custom function,
which I named regsubst(), for doing regexp replacement on text strings.
I have attached that one for your use. With it, you can do:
$ipre = '^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$'
$i1 = regsubst($ipaddress_eth0, $ipre, '\1')
$i2 = regsubst($ipaddress_eth0, $ipre, '\2')
$i3 = regsubst($ipaddress_eth0, $ipre, '\3')
$i4 = regsubst($ipaddress_eth0, $ipre, '\4')
Now you have the four octets from the eth0 address in $i1, $i2, $i3 and $i4,
respectively. If you use Puppet 0.24.6 (or later, presumably), you can
then do
$i2_1 = $i2 + 1
$i2_2 = $i2 + 2
$i2_3 = $i2 + 3
$ip_1 = "$i1.$i2_1.$i3.$i4"
$ip_2 = "$i1.$i2_2.$i3.$i4"
$ip_3 = "$i1.$i2_3.$i3.$i4"
after which you have the new addresses in $ip_1, $ip_2 and $ip_3. The
variables $i2_1, $i2_2 and $i2_3 are just intermediaries that I don't
think you can get away without.
For actually configuring eth1, eth2 and eth3, I use a custom define:
define rh_interface($bootproto="static",
$ipaddress="",
$netmask="",
$gateway="",
$onboot="yes",
$ensure="up",
$persistent_dhcp="yes")
{
file {
"/etc/sysconfig/network-scripts/ifcfg-$name":
content => template("FILES/rh-ifcfg.erb"),
owner => "root", group => "root", mode => 0444,
notify => Exec["rh_interface--ifconfig--$name/$ensure"];
}
case $ensure {
"up": {
exec {
"rh_interface--ifconfig--$name/up":
command => "/sbin/ifdown '$name' && /sbin/ifup '$name'",
refreshonly => true,
path => "/bin:/usr/bin:/sbin:/usr/sbin";
}
}
"down": {
exec {
"rh_interface--ifconfig--$name/down":
command => "/sbin/ifdown '$name'",
refreshonly => true,
path => "/bin:/usr/bin:/sbin:/usr/sbin";
}
}
default: {
fail("Bad ensure parameter to rh_interface $title: $ensure")
}
}
}
This is RedHat specific; it won't work on for example Gentoo, Solaris,
or Debian. It uses an ERB template to do its job, which I have also
attached (rh-ifcfg.erb). You need to change that path to it in the
definition above.
(Puppet used to have a resource type for defining network interfaces.
Unfortunately it didn't work, and was removed a while ago. Hopefully
Puppet will develop a new interface type, that actually works.)
Using rh_interface, you can then do
rh_interface {
"eth1": ipaddress => $ip_1, netmask => "255.255.0.0";
"eth2": ipaddress => $ip_2, netmask => "255.255.0.0";
"eth3": ipaddress => $ip_3, netmask => "255.255.0.0";
}
in your node definitions.
Thank you for giving me the inspiration to do this! I have actually
wanted to do precisely this, but never got around to implement something
that worked. (My use case was giving IP addresses to Infiniband
interfaces. Neither ISC dhcpd, nor the dhclient program that ships
with Fedora/RHEL/CentOS, can handle Infiniband networks.)
Hope this helps.
/Bellman
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Puppet Users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/puppet-users?hl=en
-~----------~----~----~----~------~----~------~--~---
module Puppet::Parser::Functions
newfunction(:regsubst, :type => :rvalue,
:doc => "\
Perform regexp replacement on a string.
Parameters (in order):
str The string to operate on.
regexp The regular expression matching the string. If you
want it anchored at the start and/or end of the string,
you must do that with ^ and $ yourself.
replacement Replacement string. Can contain back references
to what was matched using \\0, \\1, and so on.
flags Optional. String of single letter flags for how
the regexp is interpreted:
E Extended regexps
I Ignore case in regexps
M Multiline regexps
G Global replacement; all occurances of the
regexp in the string will be replaced.
Without this, only the first occurance will
be replaced.
lang Optional. How to handle multibyte characters. A
single-character string with the following values:
N None
E EUC
S SJIS
U UTF-8
Examples:
Get the third octet from the node's IP address:
$i3 = regsubst($ipaddress,
'^([0-9]+)[.]([0-9]+)[.]([0-9]+)[.]([0-9]+)$',
'\3')
Put angle brackets around each octet in the node's IP address:
$x = regsubst($ipaddress, '([0-9]+)', '<\1>', 'G') "
) do |args|
flag_mapping = {
"E" => Regexp::EXTENDED,
"I" => Regexp::IGNORECASE,
"M" => Regexp::MULTILINE,
}
if args.length < 3 or args.length > 5
self.fail("regsub(): wrong number of arguments" +
" (#{args.length}; min 3, max 5)")
end
str, regexp, replacement, flags, lang = args
reflags = 0
global = false
(flags or "").each_byte do |f|
f = f.chr
if f == "G"
global = true
else
fvalue = flag_mapping[f]
if !fvalue
self.fail("regsub(): bad flag `#{f}'")
end
reflags |= fvalue
end
end
re = Regexp.compile(regexp, reflags, lang)
if global
result = str.gsub(re, replacement)
else
result = str.sub(re, replacement)
end
return result
end
end
<%
base_iface = name.split(':')[0]
hwaddr = eval("nsc_macaddress_#{base_iface}", binding)
i1,i2,i3,i4 = ipaddress.split('.')
i = (i1.to_i<<24) + (i2.to_i<<16) + (i3.to_i<<8) + i4.to_i
m1,m2,m3,m4 = netmask.split('.')
m = (m1.to_i<<24) + (m2.to_i<<16) + (m3.to_i<<8) + m4.to_i
nw = i & m
bc = i | (~m & 0xffffffff)
bc1 = bc>>24 & 0xff
bc2 = bc>>16 & 0xff
bc3 = bc>>8 & 0xff
bc4 = bc & 0xff
broadcast = sprintf("%d.%d.%d.%d", bc1, bc2, bc3, bc4)
-%>
DEVICE=<%= name %>
BOOTPROTO=<%= bootproto %>
HWADDR=<%= hwaddr %>
ONBOOT=<%= onboot %>
<% case bootproto
when 'static': -%>
IPADDR=<%= ipaddress %>
NETMASK=<%= netmask %>
BROADCAST=<%= broadcast %>
<% if gateway != "" -%>
GATEWAY=<%= gateway %>
<% end -%>
<% when 'dhcp': -%>
DHCP_HOSTNAME=<%= fqdn %>
PERSISTENT_DHCLIENT=<%= persistent_dhcp[0..0] %>
<% else
raise Exception.new("Bad bootproto #{bootproto}, not static or dhcp")
end -%>