-
-
Save btm/ac4dc1a6ce291a75b7c6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |
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.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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!