Skip to content

Instantly share code, notes, and snippets.

@btm
Created March 1, 2012 01:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save btm/ac4dc1a6ce291a75b7c6 to your computer and use it in GitHub Desktop.
Save btm/ac4dc1a6ce291a75b7c6 to your computer and use it in GitHub Desktop.
commit 76c6859c1d075e68329f3a4cf17178052ce8d665
Author: Bryan McLellan <btm@opscode.com>
Date: Wed Feb 29 17:00:54 2012 -0800
OHAI-326: Populate ipaddress with a logical choice
When we have a default gateway we use its interface to populate the ipaddress
attribute. When an interface has multiple addresses be sure to choose one that
is on the same network as the default gateway.
diff --git a/lib/ohai/plugins/network.rb b/lib/ohai/plugins/network.rb
index b5881a8..ab83605 100644
--- a/lib/ohai/plugins/network.rb
+++ b/lib/ohai/plugins/network.rb
@@ -16,6 +16,8 @@
# limitations under the License.
#
+require 'ipaddress'
+
provides "network", "counters/network"
network Mash.new unless network
@@ -26,22 +28,33 @@ counters[:network] = Mash.new unless counters[:network]
require_plugin "hostname"
require_plugin "#{os}::network"
-def find_ip_and_mac(addresses)
+def find_ip_and_mac(addresses, match = nil)
ip = nil; mac = nil
addresses.keys.each do |addr|
- ip = addr if addresses[addr]["family"].eql?("inet")
+ if match.nil?
+ ip = addr if addresses[addr]["family"].eql?("inet")
+ else
+ ip = addr if addresses[addr]["family"].eql?("inet") && network_contains_address(match, addr, addresses[addr][:netmask])
+ end
mac = addr if addresses[addr]["family"].eql?("lladdr")
break if (ip and mac)
end
+ Ohai::Log.debug("Found IPv4 address #{ip} with MAC #{mac} #{match.nil? ? '' : 'matching address ' + match}")
[ip, mac]
end
+def network_contains_address(address_to_match, network_ip, network_mask)
+ network = IPAddress "#{network_ip}/#{network_mask}"
+ host = IPAddress address_to_match
+ network.include?(host)
+end
+
# If we have a default interface that has addresses, populate the short-cut attributes
if network[:default_interface] and
network["interfaces"][network[:default_interface]] and
network["interfaces"][network[:default_interface]]["addresses"]
Ohai::Log.debug("Using default interface for default ip and mac address")
- im = find_ip_and_mac(network["interfaces"][network[:default_interface]]["addresses"])
+ im = find_ip_and_mac(network["interfaces"][network[:default_interface]]["addresses"], network[:default_gateway])
ipaddress im.shift
macaddress im.shift
else
diff --git a/ohai.gemspec b/ohai.gemspec
index 939f2da..526c17c 100644
--- a/ohai.gemspec
+++ b/ohai.gemspec
@@ -22,6 +22,7 @@ spec = Gem::Specification.new do |s|
s.add_dependency "mixlib-cli"
s.add_dependency "mixlib-config"
s.add_dependency "mixlib-log"
+ s.add_dependency "ipaddress"
s.add_development_dependency "rspec-core"
s.add_development_dependency "rspec-expectations"
s.add_development_dependency "rspec-mocks"
@bknowles
Copy link

bknowles commented Mar 1, 2012

This makes a lot of sense to me, but am I misunderstanding the comment on on line 41? This won't work with IPv6 addresses?

I wouldn't consider failure to work with IPv6 addresses to be a show-stopper, but it seems to me that this would be an issue that would need to be resolved sooner rather than later.

Checking a random Rackspace/CentOS 5.6 node that I've been working with lately, it seems that this logic would do what I would want -- the external interface is returned by Ohai as "default_interface" and the gateway on the default_interface is labeled as the "default_gateway".

I'm assuming that you've checked a pretty wide array of combinations of cloud providers and OS types to make sure that this code is functioning as expected?

Thanks!

@btm
Copy link
Author

btm commented Mar 1, 2012

This particular plugin has never worked with IPv6.

      ip = addr if addresses[addr]["family"].eql?("inet")

We would have to look for an 'inet6' address there but this brings up more process questions; how do we decide when to prefer IPv6 over IPv4?

As it is, this plugin has to be a kludge because we have to guess what interface you consider your primary address, there isn't a definitive answer.

I haven't done significant testing because something I cannot pinpoint is irking me. I spent some time trying to get some old spec tests [1] working because we have none here before realizing that they wouldn't be useful.

Thanks for your help Brad.

[1] http://tickets.opscode.com/browse/OHAI-286

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment