I have a resource I''d like to manage via augeas (/etc/conf.d/net; it''s a bash variables file) but I"m having problems figuring out how to set the values so that all of the values in the array go in. I would like it to look like this: # cat /etc/conf.d/net config_eth4=("192.168.128.2/24") config_eth5=("192.168.129.2/24") routes_eth5=("192.168.130.0/24 via 192.168.131.1") But it ends up looking like this: config_eth4=192.168.128.2/24 config_eth5=192.168.129.2/24 routes_eth5=192.168.130.0/24 The goal is to be able to assign multiple values to "ip" or "routes" for an interface. Is this something I might have to do w/ a custom type? -Doug class net { file { "/etc/conf.d/net": owner => root, group => root, mode => 0644, } # TODO remove undefined routes define interface($ip, $routes = undef) { exec { "net_restart_$name": #TODO: perform restart command => "/bin/true", refreshonly => true, } augeas { "conf.d_net_ip_$name": notify => Exec["net_restart_$name"], context => "/files/etc/conf.d/net", changes => "set config_$name $ip", } if $routes { augeas { "conf.d_net_routes_$name": notify => Exec["net_restart_$name"], context => "/files/etc/conf.d/net", changes => "set routes_$name $routes", } } else { augeas { "conf.d_net_routes_$name": notify => Exec["net_restart_$name"], context => "/files/etc/conf.d/net", changes => "rm routes_$name", onlyif => "match routes_$name size > 0", } } } } node ''example'' { include net net::interface { "eth4": ip => ["192.168.128.2/24"], } net::interface { "eth5": ip => ["192.168.129.2/24"], routes => ["192.168.130.0/24 via 192.168.131.1"],} }
On 07/29/2010 04:49 PM, Doug Warner wrote:> I have a resource I''d like to manage via augeas (/etc/conf.d/net; it''s a bash > variables file) but I"m having problems figuring out how to set the values so > that all of the values in the array go in. > > I would like it to look like this: > # cat /etc/conf.d/net > config_eth4=("192.168.128.2/24") > config_eth5=("192.168.129.2/24") > routes_eth5=("192.168.130.0/24 via 192.168.131.1") > > But it ends up looking like this: > config_eth4=192.168.128.2/24 > config_eth5=192.168.129.2/24 > routes_eth5=192.168.130.0/24 > > The goal is to be able to assign multiple values to "ip" or "routes" for an > interface. > > Is this something I might have to do w/ a custom type? >I''m trying to write a custom type based on the augeas type since I only need to do a little bit of work, but I''m not used to ruby and don''t know exactly what''s going. I''m trying to extend the augeas type to set the changes when I pass in IP and routes, but my test type isn''t working. So far I have: require ''puppet/type/augeas'' Puppet::Type.newtype(:net_interface, :parent => Puppet::Type::Augeas, :context => "/files/etc/conf.d/net", :changes => "set config_eth9/1 192.168.205.2/24" ) do @doc = "Define a network interface" newparam (:name) do desc "The name of this task. Used for uniqueness" isnamevar end newparam (:ip) do desc "The IP addresses and netblocks for this interface" defaultto :false end newparam (:routes) do desc "The routes associated with this interface" defaultto :false end end When I call this with: net_interface { ''eth4'': ip => ["192.168.128.2/24"] } nothing happens. What do I need to do here to stick values into the "changes" variable when ''ip'' or ''routes'' is set and have the augeas type run? -Doug
On 07/30/2010 03:52 PM, Doug Warner wrote:> On 07/29/2010 04:49 PM, Doug Warner wrote: >> I have a resource I''d like to manage via augeas (/etc/conf.d/net; it''s a bash >> variables file) but I"m having problems figuring out how to set the values so >> that all of the values in the array go in. >> >> I would like it to look like this: >> # cat /etc/conf.d/net >> config_eth4=("192.168.128.2/24") >> config_eth5=("192.168.129.2/24") >> routes_eth5=("192.168.130.0/24 via 192.168.131.1") >> >> But it ends up looking like this: >> config_eth4=192.168.128.2/24 >> config_eth5=192.168.129.2/24 >> routes_eth5=192.168.130.0/24 >> >> The goal is to be able to assign multiple values to "ip" or "routes" for an >> interface. >> >> Is this something I might have to do w/ a custom type? >> > > I''m trying to write a custom type based on the augeas type since I only need > to do a little bit of work, but I''m not used to ruby and don''t know exactly > what''s going. I''m trying to extend the augeas type to set the changes when I > pass in IP and routes, but my test type isn''t working. So far I have: >[snip]> > When I call this with: > net_interface { ''eth4'': ip => ["192.168.128.2/24"] } > > nothing happens. > > What do I need to do here to stick values into the "changes" variable when > ''ip'' or ''routes'' is set and have the augeas type run? >In then end I had to "punt" and write myself a custom function since I don''t have enough ruby experience to understand how to extend the augeas type. This function just returns an array of the augeas changes, so it doesn''t have all the "smarts" that my custom type would, but that''s easy to work around in the DSL. So I ended up with the below. -Doug net/lib/puppet/parser/functions/augeas_net_interface.rb: Puppet::Parser::Functions::newfunction(:augeas_net_interface, :type => :rvalue, :doc => "Creates an array of augeas changes based on arguments passed in (interface, prefix (''config'', ''routes''), and any IPs or routes" ) do |args| interface = args.shift prefix = args.shift args = [args] unless args.is_a?(Array) changes = Array.new args.each_with_index do |arg, i| debug "Assigning #{prefix} \"#{arg}\" to #{interface}" changes << "set #{prefix}_#{interface}/#{i+1} ''\"#{arg}\"''" end changes end net/manifests/init.pp (not complete): class net { file { "/etc/conf.d/net": owner => root, group => root, mode => 0644, } define interface($ip, $routes = undef) { file { "/etc/init.d/net.${name}": ensure => "/etc/init.d/net.lo", } service { "net.${name}": ensure => running, enable => true, hasstatus => true, hasrestart => true, require => [ File["/etc/init.d/net.${name}"], ], } augeas { "conf.d_net_ip_$name": notify => Service["net.${name}"], context => "/files/etc/conf.d/net", changes => augeas_net_interface($name, "config", $ip), } if $routes { augeas { "conf.d_net_routes_$name": notify => Service["net.${name}"], context => "/files/etc/conf.d/net", changes => augeas_net_interface($name, "routes", $routes), } } else { augeas { "conf.d_net_routes_$name": notify => Service["net.${name}"], context => "/files/etc/conf.d/net", changes => "rm routes_$name", onlyif => "match routes_$name size > 0", } } } }