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 -%>

Reply via email to