diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2016-12-21 18:55:32 -0800 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2016-12-22 09:44:04 -0800 |
commit | d1d43a53bfec01746208296f16a9c35056e522a1 (patch) | |
tree | 8a124bc72cd7142b3ebe0162f21fdeb6d1a6f1b7 /lib | |
parent | 857ce79d05fe5c35bb85ad4ca583c023a523a71a (diff) | |
download | chef-d1d43a53bfec01746208296f16a9c35056e522a1.tar.gz |
cleanup of ifconfig and route providerslcg/route-ifconfig
* run_command elimination
* shell_out array usage
* other misc cleanup
Signed-off-by: Lamont Granquist <lamont@scriptkiddie.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/chef/provider/ifconfig.rb | 115 | ||||
-rw-r--r-- | lib/chef/provider/ifconfig/aix.rb | 51 | ||||
-rw-r--r-- | lib/chef/provider/ifconfig/debian.rb | 45 | ||||
-rw-r--r-- | lib/chef/provider/ifconfig/redhat.rb | 24 | ||||
-rw-r--r-- | lib/chef/provider/route.rb | 370 |
5 files changed, 296 insertions, 309 deletions
diff --git a/lib/chef/provider/ifconfig.rb b/lib/chef/provider/ifconfig.rb index 4cfb257bb9..4f32baaadb 100644 --- a/lib/chef/provider/ifconfig.rb +++ b/lib/chef/provider/ifconfig.rb @@ -58,7 +58,7 @@ class Chef end def load_current_resource - @current_resource = Chef::Resource::Ifconfig.new(@new_resource.name) + @current_resource = Chef::Resource::Ifconfig.new(new_resource.name) @ifconfig_success = true @interfaces = {} @@ -69,27 +69,26 @@ class Chef @int_name = line[0..9].strip @interfaces[@int_name] = { "hwaddr" => (line =~ /(HWaddr)/ ? ($') : "nil").strip.chomp } else - @interfaces[@int_name]["inet_addr"] = (line =~ /inet addr:(\S+)/ ? ($1) : "nil") if line =~ /inet addr:/ - @interfaces[@int_name]["bcast"] = (line =~ /Bcast:(\S+)/ ? ($1) : "nil") if line =~ /Bcast:/ - @interfaces[@int_name]["mask"] = (line =~ /Mask:(\S+)/ ? ($1) : "nil") if line =~ /Mask:/ - @interfaces[@int_name]["mtu"] = (line =~ /MTU:(\S+)/ ? ($1) : "nil") if line =~ /MTU:/ - @interfaces[@int_name]["metric"] = (line =~ /Metric:(\S+)/ ? ($1) : "nil") if line =~ /Metric:/ + @interfaces[@int_name]["inet_addr"] = (line =~ /inet addr:(\S+)/ ? Regexp.last_match(1) : "nil") if line =~ /inet addr:/ + @interfaces[@int_name]["bcast"] = (line =~ /Bcast:(\S+)/ ? Regexp.last_match(1) : "nil") if line =~ /Bcast:/ + @interfaces[@int_name]["mask"] = (line =~ /Mask:(\S+)/ ? Regexp.last_match(1) : "nil") if line =~ /Mask:/ + @interfaces[@int_name]["mtu"] = (line =~ /MTU:(\S+)/ ? Regexp.last_match(1) : "nil") if line =~ /MTU:/ + @interfaces[@int_name]["metric"] = (line =~ /Metric:(\S+)/ ? Regexp.last_match(1) : "nil") if line =~ /Metric:/ end - if @interfaces.has_key?(@new_resource.device) - @interface = @interfaces.fetch(@new_resource.device) - - @current_resource.target(@new_resource.target) - @current_resource.device(@new_resource.device) - @current_resource.inet_addr(@interface["inet_addr"]) - @current_resource.hwaddr(@interface["hwaddr"]) - @current_resource.bcast(@interface["bcast"]) - @current_resource.mask(@interface["mask"]) - @current_resource.mtu(@interface["mtu"]) - @current_resource.metric(@interface["metric"]) - end + next unless @interfaces.key?(new_resource.device) + @interface = @interfaces.fetch(new_resource.device) + + current_resource.target(new_resource.target) + current_resource.device(new_resource.device) + current_resource.inet_addr(@interface["inet_addr"]) + current_resource.hwaddr(@interface["hwaddr"]) + current_resource.bcast(@interface["bcast"]) + current_resource.mask(@interface["mask"]) + current_resource.mtu(@interface["mtu"]) + current_resource.metric(@interface["metric"]) end - @current_resource + current_resource end def define_resource_requirements @@ -104,14 +103,12 @@ class Chef def action_add # check to see if load_current_resource found interface in ifconfig - unless @current_resource.inet_addr - unless @new_resource.device == loopback_device + unless current_resource.inet_addr + unless new_resource.device == loopback_device command = add_command - converge_by ("run #{command} to add #{@new_resource}") do - run_command( - :command => command - ) - Chef::Log.info("#{@new_resource} added") + converge_by("run #{command.join(' ')} to add #{new_resource}") do + shell_out_compact!(command) + Chef::Log.info("#{new_resource} added") end end end @@ -122,31 +119,25 @@ class Chef def action_enable # check to see if load_current_resource found ifconfig # enables, but does not manage config files - unless @current_resource.inet_addr - unless @new_resource.device == loopback_device - command = enable_command - converge_by ("run #{command} to enable #{@new_resource}") do - run_command( - :command => command - ) - Chef::Log.info("#{@new_resource} enabled") - end - end + return if current_resource.inet_addr + return if new_resource.device == loopback_device + command = enable_command + converge_by("run #{command.join(' ')} to enable #{new_resource}") do + shell_out_compact!(command) + Chef::Log.info("#{new_resource} enabled") end end def action_delete # check to see if load_current_resource found the interface - if @current_resource.device + if current_resource.device command = delete_command - converge_by ("run #{command} to delete #{@new_resource}") do - run_command( - :command => command - ) - Chef::Log.info("#{@new_resource} deleted") + converge_by("run #{command.join(' ')} to delete #{new_resource}") do + shell_out_compact!(command) + Chef::Log.info("#{new_resource} deleted") end else - Chef::Log.debug("#{@new_resource} does not exist - nothing to do") + Chef::Log.debug("#{new_resource} does not exist - nothing to do") end delete_config end @@ -154,21 +145,19 @@ class Chef def action_disable # check to see if load_current_resource found the interface # disables, but leaves config files in place. - if @current_resource.device + if current_resource.device command = disable_command - converge_by ("run #{command} to disable #{@new_resource}") do - run_command( - :command => command - ) - Chef::Log.info("#{@new_resource} disabled") + converge_by("run #{command.join(' ')} to disable #{new_resource}") do + shell_out_compact!(command) + Chef::Log.info("#{new_resource} disabled") end else - Chef::Log.debug("#{@new_resource} does not exist - nothing to do") + Chef::Log.debug("#{new_resource} does not exist - nothing to do") end end def can_generate_config? - ! @config_template.nil? && ! @config_path.nil? + !@config_template.nil? && !@config_path.nil? end def resource_for_config(path) @@ -182,40 +171,40 @@ class Chef config = resource_for_config(@config_path) config.content(template.result(b)) config.run_action(:create) - @new_resource.updated_by_last_action(true) if config.updated? + new_resource.updated_by_last_action(true) if config.updated? end def delete_config return unless can_generate_config? config = resource_for_config(@config_path) config.run_action(:delete) - @new_resource.updated_by_last_action(true) if config.updated? + new_resource.updated_by_last_action(true) if config.updated? end private def add_command - command = "ifconfig #{@new_resource.device} #{@new_resource.target}" - command << " netmask #{@new_resource.mask}" if @new_resource.mask - command << " metric #{@new_resource.metric}" if @new_resource.metric - command << " mtu #{@new_resource.mtu}" if @new_resource.mtu + command = [ "ifconfig", new_resource.device, new_resource.target ] + command += [ "netmask", new_resource.mask ] if new_resource.mask + command += [ "metric", new_resource.metric ] if new_resource.metric + command += [ "mtu", new_resource.mtu ] if new_resource.mtu command end def enable_command - command = "ifconfig #{@new_resource.device} #{@new_resource.target}" - command << " netmask #{@new_resource.mask}" if @new_resource.mask - command << " metric #{@new_resource.metric}" if @new_resource.metric - command << " mtu #{@new_resource.mtu}" if @new_resource.mtu + command = [ "ifconfig", new_resource.device, new_resource.target ] + command += [ "netmask", new_resource.mask ] if new_resource.mask + command += [ "metric", new_resource.metric ] if new_resource.metric + command += [ "mtu", new_resource.mtu ] if new_resource.mtu command end def disable_command - "ifconfig #{@new_resource.device} down" + [ "ifconfig", new_resource.device, "down" ] end def delete_command - "ifconfig #{@new_resource.device} down" + [ "ifconfig", new_resource.device, "down" ] end def loopback_device diff --git a/lib/chef/provider/ifconfig/aix.rb b/lib/chef/provider/ifconfig/aix.rb index 81164db304..788b609fcf 100644 --- a/lib/chef/provider/ifconfig/aix.rb +++ b/lib/chef/provider/ifconfig/aix.rb @@ -25,61 +25,56 @@ class Chef provides :ifconfig, platform: %w{aix} def load_current_resource - @current_resource = Chef::Resource::Ifconfig.new(@new_resource.name) + @current_resource = Chef::Resource::Ifconfig.new(new_resource.name) @interface_exists = false found_interface = false interface = {} - @status = shell_out("ifconfig -a") + @status = shell_out_compact("ifconfig", "-a") @status.stdout.each_line do |line| if !found_interface if line =~ /^(\S+):\sflags=(\S+)/ - # We have interface name, if this is the interface for @current_resource, load info else skip till next interface is found. - if $1 == @new_resource.device + # We have interface name, if this is the interface for current_resource, load info else skip till next interface is found. + if Regexp.last_match(1) == new_resource.device # Found interface found_interface = true @interface_exists = true - @current_resource.target(@new_resource.target) - @current_resource.device($1) - interface[:flags] = $2 - @current_resource.metric($1) if line =~ /metric\s(\S+)/ - end - end - else - # parse interface related information, stop when next interface is found. - if line =~ /^(\S+):\sflags=(\S+)/ - # we are done parsing interface info and hit another one, so stop. - found_interface = false - break - else - if found_interface - # read up interface info - @current_resource.inet_addr($1) if line =~ /inet\s(\S+)\s/ - @current_resource.bcast($1) if line =~ /broadcast\s(\S+)/ - @current_resource.mask(hex_to_dec_netmask($1)) if line =~ /netmask\s(\S+)\s/ + current_resource.target(new_resource.target) + current_resource.device(Regexp.last_match(1)) + interface[:flags] = Regexp.last_match(2) + current_resource.metric(Regexp.last_match(1)) if line =~ /metric\s(\S+)/ end end + elsif line =~ /^(\S+):\sflags=(\S+)/ + # we are done parsing interface info and hit another one, so stop. + found_interface = false + break + elsif found_interface + # read up interface info + current_resource.inet_addr(Regexp.last_match(1)) if line =~ /inet\s(\S+)\s/ + current_resource.bcast(Regexp.last_match(1)) if line =~ /broadcast\s(\S+)/ + current_resource.mask(hex_to_dec_netmask(Regexp.last_match(1))) if line =~ /netmask\s(\S+)\s/ end end - @current_resource + current_resource end private def add_command # ifconfig changes are temporary, chdev persist across reboots. - raise Chef::Exceptions::Ifconfig, "interface metric attribute cannot be set for :add action" if @new_resource.metric - command = "chdev -l #{@new_resource.device} -a netaddr=#{@new_resource.name}" - command << " -a netmask=#{@new_resource.mask}" if @new_resource.mask - command << " -a mtu=#{@new_resource.mtu}" if @new_resource.mtu + raise Chef::Exceptions::Ifconfig, "interface metric attribute cannot be set for :add action" if new_resource.metric + command = [ "chdev", "-l", new_resource.device, "-a", "netaddr=#{new_resource.name}" ] + command += [ "-a", "netmask=#{new_resource.mask}" ] if new_resource.mask + command += [ "-a", "mtu=#{new_resource.mtu}" ] if new_resource.mtu command end def delete_command # ifconfig changes are temporary, chdev persist across reboots. - "chdev -l #{@new_resource.device} -a state=down" + [ "chdev", "-l", new_resource.device, "-a", "state=down" ] end def loopback_device diff --git a/lib/chef/provider/ifconfig/debian.rb b/lib/chef/provider/ifconfig/debian.rb index 872b0db152..369c222b7a 100644 --- a/lib/chef/provider/ifconfig/debian.rb +++ b/lib/chef/provider/ifconfig/debian.rb @@ -26,32 +26,32 @@ class Chef provides :ifconfig, platform: %w{ubuntu}, platform_version: ">= 11.10" provides :ifconfig, platform: %w{debian}, platform_version: ">= 7.0" - INTERFACES_FILE = "/etc/network/interfaces" - INTERFACES_DOT_D_DIR = "/etc/network/interfaces.d" + INTERFACES_FILE = "/etc/network/interfaces".freeze + INTERFACES_DOT_D_DIR = "/etc/network/interfaces.d".freeze def initialize(new_resource, run_context) super(new_resource, run_context) @config_template = %{ -<% if @new_resource.device %> -<% if @new_resource.onboot == "yes" %>auto <%= @new_resource.device %><% end %> -<% case @new_resource.bootproto +<% if new_resource.device %> +<% if new_resource.onboot == "yes" %>auto <%= new_resource.device %><% end %> +<% case new_resource.bootproto when "dhcp" %> -iface <%= @new_resource.device %> inet dhcp +iface <%= new_resource.device %> inet dhcp <% when "bootp" %> -iface <%= @new_resource.device %> inet bootp +iface <%= new_resource.device %> inet bootp <% else %> -iface <%= @new_resource.device %> inet static - <% if @new_resource.target %>address <%= @new_resource.target %><% end %> - <% if @new_resource.mask %>netmask <%= @new_resource.mask %><% end %> - <% if @new_resource.network %>network <%= @new_resource.network %><% end %> - <% if @new_resource.bcast %>broadcast <%= @new_resource.bcast %><% end %> - <% if @new_resource.metric %>metric <%= @new_resource.metric %><% end %> - <% if @new_resource.hwaddr %>hwaddress <%= @new_resource.hwaddr %><% end %> - <% if @new_resource.mtu %>mtu <%= @new_resource.mtu %><% end %> +iface <%= new_resource.device %> inet static + <% if new_resource.target %>address <%= new_resource.target %><% end %> + <% if new_resource.mask %>netmask <%= new_resource.mask %><% end %> + <% if new_resource.network %>network <%= new_resource.network %><% end %> + <% if new_resource.bcast %>broadcast <%= new_resource.bcast %><% end %> + <% if new_resource.metric %>metric <%= new_resource.metric %><% end %> + <% if new_resource.hwaddr %>hwaddress <%= new_resource.hwaddr %><% end %> + <% if new_resource.mtu %>mtu <%= new_resource.mtu %><% end %> <% end %> <% end %> } - @config_path = "#{INTERFACES_DOT_D_DIR}/ifcfg-#{@new_resource.device}" + @config_path = "#{INTERFACES_DOT_D_DIR}/ifcfg-#{new_resource.device}" end def generate_config @@ -69,12 +69,13 @@ iface <%= @new_resource.device %> inet static # roll our own file_edit resource, this will not get reported until we have a file_edit resource interfaces_dot_d_for_regexp = INTERFACES_DOT_D_DIR.gsub(/\./, '\.') # escape dots for the regexp regexp = %r{^\s*source\s+#{interfaces_dot_d_for_regexp}/\*\s*$} - unless ::File.exists?(INTERFACES_FILE) && regexp.match(IO.read(INTERFACES_FILE)) - converge_by("modifying #{INTERFACES_FILE} to source #{INTERFACES_DOT_D_DIR}") do - conf = Chef::Util::FileEdit.new(INTERFACES_FILE) - conf.insert_line_if_no_match(regexp, "source #{INTERFACES_DOT_D_DIR}/*") - conf.write_file - end + + return if ::File.exist?(INTERFACES_FILE) && regexp.match(IO.read(INTERFACES_FILE)) + + converge_by("modifying #{INTERFACES_FILE} to source #{INTERFACES_DOT_D_DIR}") do + conf = Chef::Util::FileEdit.new(INTERFACES_FILE) + conf.insert_line_if_no_match(regexp, "source #{INTERFACES_DOT_D_DIR}/*") + conf.write_file end end diff --git a/lib/chef/provider/ifconfig/redhat.rb b/lib/chef/provider/ifconfig/redhat.rb index 0c28e6407a..841e725b94 100644 --- a/lib/chef/provider/ifconfig/redhat.rb +++ b/lib/chef/provider/ifconfig/redhat.rb @@ -27,19 +27,19 @@ class Chef def initialize(new_resource, run_context) super(new_resource, run_context) @config_template = %{ -<% if @new_resource.device %>DEVICE=<%= @new_resource.device %><% end %> -<% if @new_resource.onboot == "yes" %>ONBOOT=<%= @new_resource.onboot %><% end %> -<% if @new_resource.bootproto %>BOOTPROTO=<%= @new_resource.bootproto %><% end %> -<% if @new_resource.target %>IPADDR=<%= @new_resource.target %><% end %> -<% if @new_resource.mask %>NETMASK=<%= @new_resource.mask %><% end %> -<% if @new_resource.network %>NETWORK=<%= @new_resource.network %><% end %> -<% if @new_resource.bcast %>BROADCAST=<%= @new_resource.bcast %><% end %> -<% if @new_resource.onparent %>ONPARENT=<%= @new_resource.onparent %><% end %> -<% if @new_resource.hwaddr %>HWADDR=<%= @new_resource.hwaddr %><% end %> -<% if @new_resource.metric %>METRIC=<%= @new_resource.metric %><% end %> -<% if @new_resource.mtu %>MTU=<%= @new_resource.mtu %><% end %> +<% if new_resource.device %>DEVICE=<%= new_resource.device %><% end %> +<% if new_resource.onboot == "yes" %>ONBOOT=<%= new_resource.onboot %><% end %> +<% if new_resource.bootproto %>BOOTPROTO=<%= new_resource.bootproto %><% end %> +<% if new_resource.target %>IPADDR=<%= new_resource.target %><% end %> +<% if new_resource.mask %>NETMASK=<%= new_resource.mask %><% end %> +<% if new_resource.network %>NETWORK=<%= new_resource.network %><% end %> +<% if new_resource.bcast %>BROADCAST=<%= new_resource.bcast %><% end %> +<% if new_resource.onparent %>ONPARENT=<%= new_resource.onparent %><% end %> +<% if new_resource.hwaddr %>HWADDR=<%= new_resource.hwaddr %><% end %> +<% if new_resource.metric %>METRIC=<%= new_resource.metric %><% end %> +<% if new_resource.mtu %>MTU=<%= new_resource.mtu %><% end %> } - @config_path = "/etc/sysconfig/network-scripts/ifcfg-#{@new_resource.device}" + @config_path = "/etc/sysconfig/network-scripts/ifcfg-#{new_resource.device}" end end diff --git a/lib/chef/provider/route.rb b/lib/chef/provider/route.rb index 7c6f91cdca..f2b7b33419 100644 --- a/lib/chef/provider/route.rb +++ b/lib/chef/provider/route.rb @@ -21,209 +21,211 @@ require "chef/mixin/command" require "chef/provider" require "ipaddr" -class Chef::Provider::Route < Chef::Provider - include Chef::Mixin::Command - - provides :route - - attr_accessor :is_running - - MASK = { "0.0.0.0" => "0", - "128.0.0.0" => "1", - "192.0.0.0" => "2", - "224.0.0.0" => "3", - "240.0.0.0" => "4", - "248.0.0.0" => "5", - "252.0.0.0" => "6", - "254.0.0.0" => "7", - "255.0.0.0" => "8", - "255.128.0.0" => "9", - "255.192.0.0" => "10", - "255.224.0.0" => "11", - "255.240.0.0" => "12", - "255.248.0.0" => "13", - "255.252.0.0" => "14", - "255.254.0.0" => "15", - "255.255.0.0" => "16", - "255.255.128.0" => "17", - "255.255.192.0" => "18", - "255.255.224.0" => "19", - "255.255.240.0" => "20", - "255.255.248.0" => "21", - "255.255.252.0" => "22", - "255.255.254.0" => "23", - "255.255.255.0" => "24", - "255.255.255.128" => "25", - "255.255.255.192" => "26", - "255.255.255.224" => "27", - "255.255.255.240" => "28", - "255.255.255.248" => "29", - "255.255.255.252" => "30", - "255.255.255.254" => "31", - "255.255.255.255" => "32" } - - def hex2ip(hex_data) - # Cleanup hex data - hex_ip = hex_data.to_s.downcase.gsub(/[^0-9a-f]/, "") - - # Check hex data format (IP is a 32bit integer, so should be 8 chars long) - return nil if hex_ip.length != hex_data.length || hex_ip.length != 8 - - # Extract octets from hex data - octets = hex_ip.scan(/../).reverse.collect { |octet| [octet].pack("H2").unpack("C").first } - - # Validate IP - ip = octets.join(".") - begin - IPAddr.new(ip, Socket::AF_INET).to_s - rescue ArgumentError - Chef::Log.debug("Invalid IP address data: hex=#{hex_ip}, ip=#{ip}") - return nil - end - end - - def whyrun_supported? - true - end +class Chef + class Provider + class Route < Chef::Provider + include Chef::Mixin::Command + + provides :route + + attr_accessor :is_running + + MASK = { "0.0.0.0" => "0", + "128.0.0.0" => "1", + "192.0.0.0" => "2", + "224.0.0.0" => "3", + "240.0.0.0" => "4", + "248.0.0.0" => "5", + "252.0.0.0" => "6", + "254.0.0.0" => "7", + "255.0.0.0" => "8", + "255.128.0.0" => "9", + "255.192.0.0" => "10", + "255.224.0.0" => "11", + "255.240.0.0" => "12", + "255.248.0.0" => "13", + "255.252.0.0" => "14", + "255.254.0.0" => "15", + "255.255.0.0" => "16", + "255.255.128.0" => "17", + "255.255.192.0" => "18", + "255.255.224.0" => "19", + "255.255.240.0" => "20", + "255.255.248.0" => "21", + "255.255.252.0" => "22", + "255.255.254.0" => "23", + "255.255.255.0" => "24", + "255.255.255.128" => "25", + "255.255.255.192" => "26", + "255.255.255.224" => "27", + "255.255.255.240" => "28", + "255.255.255.248" => "29", + "255.255.255.252" => "30", + "255.255.255.254" => "31", + "255.255.255.255" => "32" }.freeze + + def hex2ip(hex_data) + # Cleanup hex data + hex_ip = hex_data.to_s.downcase.gsub(/[^0-9a-f]/, "") + + # Check hex data format (IP is a 32bit integer, so should be 8 chars long) + return nil if hex_ip.length != hex_data.length || hex_ip.length != 8 + + # Extract octets from hex data + octets = hex_ip.scan(/../).reverse.collect { |octet| [octet].pack("H2").unpack("C").first } + + # Validate IP + ip = octets.join(".") + begin + IPAddr.new(ip, Socket::AF_INET).to_s + rescue ArgumentError + Chef::Log.debug("Invalid IP address data: hex=#{hex_ip}, ip=#{ip}") + return nil + end + end - def load_current_resource - self.is_running = false + def whyrun_supported? + true + end - # cidr or quad dot mask - if @new_resource.netmask - new_ip = IPAddr.new("#{@new_resource.target}/#{@new_resource.netmask}") - else - new_ip = IPAddr.new(@new_resource.target) - end + def load_current_resource + self.is_running = false + + # cidr or quad dot mask + new_ip = if new_resource.netmask + IPAddr.new("#{new_resource.target}/#{new_resource.netmask}") + else + IPAddr.new(new_resource.target) + end + + # For linux, we use /proc/net/route file to read proc table info + return if node[:os] != "linux" + + route_file = ::File.open("/proc/net/route", "r") + + # Read all routes + while (line = route_file.gets) + # Get all the fields for a route + _, destination, gateway, _, _, _, _, mask = line.split + + # Convert hex-encoded values to quad-dotted notation (e.g. 0064A8C0 => 192.168.100.0) + destination = hex2ip(destination) + gateway = hex2ip(gateway) + mask = hex2ip(mask) + + # Skip formatting lines (header, etc) + next unless destination && gateway && mask + Chef::Log.debug("#{new_resource} system has route: dest=#{destination} mask=#{mask} gw=#{gateway}") + + # check if what were trying to configure is already there + # use an ipaddr object with ip/mask this way we can have + # a new resource be in cidr format (i don't feel like + # expanding bitmask by hand. + # + running_ip = IPAddr.new("#{destination}/#{mask}") + Chef::Log.debug("#{new_resource} new ip: #{new_ip.inspect} running ip: #{running_ip.inspect}") + self.is_running = true if running_ip == new_ip && gateway == new_resource.gateway + end - # For linux, we use /proc/net/route file to read proc table info - if node[:os] == "linux" - route_file = ::File.open("/proc/net/route", "r") - - # Read all routes - while (line = route_file.gets) - # Get all the fields for a route - iface, destination, gateway, flags, refcnt, use, metric, mask, mtu, window, irtt = line.split - - # Convert hex-encoded values to quad-dotted notation (e.g. 0064A8C0 => 192.168.100.0) - destination = hex2ip(destination) - gateway = hex2ip(gateway) - mask = hex2ip(mask) - - # Skip formatting lines (header, etc) - next unless destination && gateway && mask - Chef::Log.debug("#{@new_resource} system has route: dest=#{destination} mask=#{mask} gw=#{gateway}") - - # check if what were trying to configure is already there - # use an ipaddr object with ip/mask this way we can have - # a new resource be in cidr format (i don't feel like - # expanding bitmask by hand. - # - running_ip = IPAddr.new("#{destination}/#{mask}") - Chef::Log.debug("#{@new_resource} new ip: #{new_ip.inspect} running ip: #{running_ip.inspect}") - self.is_running = true if running_ip == new_ip && gateway == @new_resource.gateway + route_file.close end - route_file.close - end - end + def action_add + # check to see if load_current_resource found the route + if is_running + Chef::Log.debug("#{new_resource} route already active - nothing to do") + else + command = generate_command(:add) + converge_by("run #{command.join(' ')} to add route") do + shell_out_compact!(command) + Chef::Log.info("#{new_resource} added") + end + end - def action_add - # check to see if load_current_resource found the route - if is_running - Chef::Log.debug("#{@new_resource} route already active - nothing to do") - else - command = generate_command(:add) - converge_by ("run #{command} to add route") do - run_command( :command => command ) - Chef::Log.info("#{@new_resource} added") + # for now we always write the file (ugly but its what it is) + generate_config end - end - #for now we always write the file (ugly but its what it is) - generate_config - end + def action_delete + if is_running + command = generate_command(:delete) + converge_by("run #{command.join(' ')} to delete route ") do + shell_out_compact!(command) + Chef::Log.info("#{new_resource} removed") + end + else + Chef::Log.debug("#{new_resource} route does not exist - nothing to do") + end - def action_delete - if is_running - command = generate_command(:delete) - converge_by ("run #{command} to delete route ") do - run_command( :command => command ) - Chef::Log.info("#{@new_resource} removed") + # for now we always write the file (ugly but its what it is) + generate_config end - else - Chef::Log.debug("#{@new_resource} route does not exist - nothing to do") - end - - #for now we always write the file (ugly but its what it is) - generate_config - end - def generate_config - conf = Hash.new - case node[:platform] - when "centos", "redhat", "fedora" - # walk the collection - run_context.resource_collection.each do |resource| - if resource.is_a? Chef::Resource::Route - # default to eth0 - if resource.device - dev = resource.device - else - dev = "eth0" + def generate_config + conf = {} + case node[:platform] + when "centos", "redhat", "fedora" + # walk the collection + run_context.resource_collection.each do |resource| + next unless resource.is_a? Chef::Resource::Route + # default to eth0 + dev = if resource.device + resource.device + else + "eth0" + end + + conf[dev] = "" if conf[dev].nil? + case @action + when :add + conf[dev] << config_file_contents(:add, target: resource.target, netmask: resource.netmask, gateway: resource.gateway) if resource.action == [:add] + when :delete + # need to do this for the case when the last route on an int + # is removed + conf[dev] << config_file_contents(:delete) + end end - - conf[dev] = String.new if conf[dev].nil? - case @action - when :add - conf[dev] << config_file_contents(:add, :target => resource.target, :netmask => resource.netmask, :gateway => resource.gateway) if resource.action == [:add] - when :delete - # need to do this for the case when the last route on an int - # is removed - conf[dev] << config_file_contents(:delete) + conf.each do |k, v| + network_file_name = "/etc/sysconfig/network-scripts/route-#{k}" + converge_by("write route route.#{k}\n#{conf[k]} to #{network_file_name}") do + network_file = ::File.new(network_file_name, "w") + network_file.puts(conf[k]) + Chef::Log.debug("#{new_resource} writing route.#{k}\n#{conf[k]}") + network_file.close + end end end end - conf.each do |k, v| - network_file_name = "/etc/sysconfig/network-scripts/route-#{k}" - converge_by ("write route route.#{k}\n#{conf[k]} to #{network_file_name}") do - network_file = ::File.new(network_file_name, "w") - network_file.puts(conf[k]) - Chef::Log.debug("#{@new_resource} writing route.#{k}\n#{conf[k]}") - network_file.close + + def generate_command(action) + target = new_resource.target + target = "#{target}/#{MASK[new_resource.netmask.to_s]}" if new_resource.netmask + + case action + when :add + command = [ "ip", "route", "replace", target ] + command += [ "via", new_resource.gateway ] if new_resource.gateway + command += [ "dev", new_resource.device ] if new_resource.device + when :delete + command = [ "ip", "route", "delete", target ] + command += [ "via", new_resource.gateway ] if new_resource.gateway end - end - end - end - def generate_command(action) - common_route_items = "" - common_route_items << "/#{MASK[@new_resource.netmask.to_s]}" if @new_resource.netmask - common_route_items << " via #{@new_resource.gateway} " if @new_resource.gateway - - case action - when :add - command = "ip route replace #{@new_resource.target}" - command << common_route_items - command << " dev #{@new_resource.device} " if @new_resource.device - when :delete - command = "ip route delete #{@new_resource.target}" - command << common_route_items - end + command + end - return command - end + def config_file_contents(action, options = {}) + content = "" + case action + when :add + content << (options[:target]).to_s + content << "/#{options[:netmask]}" if options[:netmask] + content << " via #{options[:gateway]}" if options[:gateway] + content << "\n" + end - def config_file_contents(action, options = {}) - content = "" - case action - when :add - content << "#{options[:target]}" - content << "/#{options[:netmask]}" if options[:netmask] - content << " via #{options[:gateway]}" if options[:gateway] - content << "\n" + content + end end - - return content end end |