ohai 6.14.0 → 6.16.0.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. data/lib/ohai/mixin/ec2_metadata.rb +61 -6
  2. data/lib/ohai/plugins/cloud.rb +69 -5
  3. data/lib/ohai/plugins/darwin/system_profiler.rb +44 -7
  4. data/lib/ohai/plugins/freebsd/virtualization.rb +16 -0
  5. data/lib/ohai/plugins/java.rb +1 -1
  6. data/lib/ohai/plugins/kernel.rb +1 -0
  7. data/lib/ohai/plugins/linode.rb +53 -0
  8. data/lib/ohai/plugins/linux/platform.rb +6 -2
  9. data/lib/ohai/plugins/network.rb +130 -44
  10. data/lib/ohai/plugins/{aix/ssh_host_key.rb → nodejs.rb} +15 -7
  11. data/lib/ohai/plugins/openstack.rb +46 -0
  12. data/lib/ohai/plugins/rackspace.rb +35 -1
  13. data/lib/ohai/plugins/solaris2/filesystem.rb +1 -1
  14. data/lib/ohai/plugins/solaris2/network.rb +2 -1
  15. data/lib/ohai/plugins/solaris2/platform.rb +2 -2
  16. data/lib/ohai/plugins/ssh_host_key.rb +63 -0
  17. data/lib/ohai/plugins/virtualization.rb +1 -1
  18. data/lib/ohai/plugins/windows/cpu.rb +20 -3
  19. data/lib/ohai/plugins/windows/kernel.rb +0 -19
  20. data/lib/ohai/plugins/windows/kernel_devices.rb +39 -0
  21. data/lib/ohai/system.rb +3 -2
  22. data/lib/ohai/version.rb +1 -1
  23. data/spec/spec_helper.rb +14 -1
  24. data/spec/support/platform_helpers.rb +31 -0
  25. data/spec/{ohai → unit}/mixin/command_spec.rb +0 -0
  26. data/spec/{ohai → unit}/mixin/from_file_spec.rb +0 -0
  27. data/spec/{ohai → unit}/plugins/c_spec.rb +0 -0
  28. data/spec/{ohai → unit}/plugins/chef_spec.rb +20 -12
  29. data/spec/unit/plugins/cloud_spec.rb +159 -0
  30. data/spec/{ohai → unit}/plugins/darwin/hostname_spec.rb +0 -0
  31. data/spec/{ohai → unit}/plugins/darwin/kernel_spec.rb +0 -0
  32. data/spec/{ohai → unit}/plugins/darwin/network_spec.rb +4 -2
  33. data/spec/{ohai → unit}/plugins/darwin/platform_spec.rb +0 -0
  34. data/spec/unit/plugins/darwin/system_profiler_output.rb +79525 -0
  35. data/spec/unit/plugins/darwin/system_profiler_spec.rb +48 -0
  36. data/spec/{ohai → unit}/plugins/dmi_spec.rb +0 -0
  37. data/spec/unit/plugins/ec2_spec.rb +199 -0
  38. data/spec/{ohai → unit}/plugins/erlang_spec.rb +0 -0
  39. data/spec/{ohai → unit}/plugins/eucalyptus_spec.rb +5 -5
  40. data/spec/{ohai → unit}/plugins/fail_spec.rb +0 -0
  41. data/spec/{ohai → unit}/plugins/freebsd/hostname_spec.rb +0 -0
  42. data/spec/{ohai → unit}/plugins/freebsd/kernel_spec.rb +0 -0
  43. data/spec/{ohai → unit}/plugins/freebsd/platform_spec.rb +0 -0
  44. data/spec/unit/plugins/freebsd/virtualization_spec.rb +99 -0
  45. data/spec/{ohai → unit}/plugins/groovy_spec.rb +0 -0
  46. data/spec/{ohai → unit}/plugins/hostname_spec.rb +0 -0
  47. data/spec/{ohai → unit}/plugins/java_spec.rb +0 -0
  48. data/spec/{ohai → unit}/plugins/kernel_spec.rb +0 -0
  49. data/spec/unit/plugins/linode_spec.rb +156 -0
  50. data/spec/{ohai → unit}/plugins/linux/cpu_spec.rb +0 -0
  51. data/spec/{ohai → unit}/plugins/linux/filesystem_spec.rb +0 -0
  52. data/spec/{ohai → unit}/plugins/linux/hostname_spec.rb +0 -0
  53. data/spec/{ohai → unit}/plugins/linux/kernel_spec.rb +0 -0
  54. data/spec/{ohai → unit}/plugins/linux/lsb_spec.rb +0 -0
  55. data/spec/{ohai → unit}/plugins/linux/network_spec.rb +3 -60
  56. data/spec/{ohai → unit}/plugins/linux/platform_spec.rb +10 -0
  57. data/spec/{ohai → unit}/plugins/linux/uptime_spec.rb +0 -0
  58. data/spec/{ohai → unit}/plugins/linux/virtualization_spec.rb +0 -0
  59. data/spec/{ohai → unit}/plugins/lua_spec.rb +0 -0
  60. data/spec/{ohai → unit}/plugins/mono_spec.rb +0 -0
  61. data/spec/{ohai → unit}/plugins/netbsd/hostname_spec.rb +0 -0
  62. data/spec/{ohai → unit}/plugins/netbsd/kernel_spec.rb +0 -0
  63. data/spec/{ohai → unit}/plugins/netbsd/platform_spec.rb +0 -0
  64. data/spec/unit/plugins/network_spec.rb +829 -0
  65. data/spec/unit/plugins/nodejs_spec.rb +51 -0
  66. data/spec/{ohai → unit}/plugins/ohai_spec.rb +0 -0
  67. data/spec/{ohai → unit}/plugins/ohai_time_spec.rb +0 -0
  68. data/spec/{ohai → unit}/plugins/openbsd/hostname_spec.rb +0 -0
  69. data/spec/{ohai → unit}/plugins/openbsd/kernel_spec.rb +0 -0
  70. data/spec/{ohai → unit}/plugins/openbsd/platform_spec.rb +0 -0
  71. data/spec/{ohai → unit}/plugins/os_spec.rb +0 -0
  72. data/spec/{ohai → unit}/plugins/passwd_spec.rb +0 -0
  73. data/spec/{ohai → unit}/plugins/perl_spec.rb +0 -0
  74. data/spec/{ohai → unit}/plugins/php_spec.rb +0 -0
  75. data/spec/{ohai → unit}/plugins/platform_spec.rb +0 -0
  76. data/spec/{ohai → unit}/plugins/python_spec.rb +0 -0
  77. data/spec/{ohai → unit}/plugins/rackspace_spec.rb +26 -0
  78. data/spec/{ohai → unit}/plugins/ruby_spec.rb +0 -0
  79. data/spec/{ohai → unit}/plugins/sigar/network_route_spec.rb +1 -0
  80. data/spec/{ohai → unit}/plugins/solaris2/hostname_spec.rb +0 -0
  81. data/spec/{ohai → unit}/plugins/solaris2/kernel_spec.rb +0 -0
  82. data/spec/{ohai → unit}/plugins/solaris2/network_spec.rb +8 -1
  83. data/spec/{ohai → unit}/plugins/solaris2/platform_spec.rb +0 -0
  84. data/spec/{ohai → unit}/plugins/solaris2/virtualization_spec.rb +0 -0
  85. data/spec/unit/plugins/ssh_host_keys_spec.rb +77 -0
  86. data/spec/{ohai → unit}/system_spec.rb +0 -0
  87. metadata +221 -184
  88. data/lib/ohai/plugins/darwin/ssh_host_key.rb +0 -25
  89. data/lib/ohai/plugins/freebsd/ssh_host_key.rb +0 -26
  90. data/lib/ohai/plugins/hpux/ssh_host_key.rb +0 -26
  91. data/lib/ohai/plugins/linux/ssh_host_key.rb +0 -26
  92. data/lib/ohai/plugins/netbsd/ssh_host_key.rb +0 -26
  93. data/lib/ohai/plugins/openbsd/ssh_host_key.rb +0 -26
  94. data/lib/ohai/plugins/solaris2/ssh_host_key.rb +0 -26
  95. data/spec/ohai/plugins/cloud_spec.rb +0 -113
  96. data/spec/ohai/plugins/ec2_spec.rb +0 -120
@@ -25,9 +25,11 @@ module Ohai
25
25
  module Ec2Metadata
26
26
 
27
27
  EC2_METADATA_ADDR = "169.254.169.254" unless defined?(EC2_METADATA_ADDR)
28
- EC2_METADATA_URL = "/2008-02-01/meta-data" unless defined?(EC2_METADATA_URL)
29
- EC2_USERDATA_URL = "/2008-02-01/user-data" unless defined?(EC2_USERDATA_URL)
28
+ EC2_METADATA_URL = "/2012-01-12/meta-data" unless defined?(EC2_METADATA_URL)
29
+ EC2_USERDATA_URL = "/2012-01-12/user-data" unless defined?(EC2_USERDATA_URL)
30
30
  EC2_ARRAY_VALUES = %w(security-groups)
31
+ EC2_ARRAY_DIR = %w(network/interfaces/macs)
32
+ EC2_JSON_DIR = %w(iam)
31
33
 
32
34
  def can_metadata_connect?(addr, port, timeout=2)
33
35
  t = Socket.new(Socket::Constants::AF_INET, Socket::Constants::SOCK_STREAM, 0)
@@ -62,16 +64,53 @@ module Ohai
62
64
  def fetch_metadata(id='')
63
65
  metadata = Hash.new
64
66
  http_client.get("#{EC2_METADATA_URL}/#{id}").body.split("\n").each do |o|
65
- key = "#{id}#{o.gsub(/\=.*$/, '/')}"
67
+ key = expand_path("#{id}#{o}")
66
68
  if key[-1..-1] != '/'
67
- metadata[key.gsub(/\-|\//, '_').to_sym] =
69
+ metadata[metadata_key(key)] =
68
70
  if EC2_ARRAY_VALUES.include? key
69
71
  http_client.get("#{EC2_METADATA_URL}/#{key}").body.split("\n")
70
72
  else
71
73
  http_client.get("#{EC2_METADATA_URL}/#{key}").body
72
74
  end
73
- else
74
- fetch_metadata(key).each{|k,v| metadata[k] = v}
75
+ elsif not key.eql?(id) and not key.eql?('/')
76
+ name = key[0..-2]
77
+ sym = metadata_key(name)
78
+ if EC2_ARRAY_DIR.include?(name)
79
+ metadata[sym] = fetch_dir_metadata(key)
80
+ elsif EC2_JSON_DIR.include?(name)
81
+ metadata[sym] = fetch_json_dir_metadata(key)
82
+ else
83
+ fetch_metadata(key).each{|k,v| metadata[k] = v}
84
+ end
85
+ end
86
+ end
87
+ metadata
88
+ end
89
+
90
+ def fetch_dir_metadata(id)
91
+ metadata = Hash.new
92
+ http_client.get("#{EC2_METADATA_URL}/#{id}").body.split("\n").each do |o|
93
+ key = expand_path(o)
94
+ if key[-1..-1] != '/'
95
+ metadata[metadata_key(key)] = http_client.get("#{EC2_METADATA_URL}/#{id}#{key}").body
96
+ elsif not key.eql?('/')
97
+ metadata[key[0..-2]] = fetch_dir_metadata("#{id}#{key}")
98
+ end
99
+ end
100
+ metadata
101
+ end
102
+
103
+ def fetch_json_dir_metadata(id)
104
+ metadata = Hash.new
105
+ http_client.get("#{EC2_METADATA_URL}/#{id}").body.split("\n").each do |o|
106
+ key = expand_path(o)
107
+ if key[-1..-1] != '/'
108
+ data = http_client.get("#{EC2_METADATA_URL}/#{id}#{key}").body
109
+ json = StringIO.new(data)
110
+ parser = Yajl::Parser.new
111
+ metadata[metadata_key(key)] = parser.parse(json)
112
+ elsif not key.eql?('/')
113
+ metadata[key[0..-2]] = fetch_json_dir_metadata("#{id}#{key}")
75
114
  end
76
115
  end
77
116
  metadata
@@ -81,6 +120,22 @@ module Ohai
81
120
  response = http_client.get("#{EC2_USERDATA_URL}/")
82
121
  response.code == "200" ? response.body : nil
83
122
  end
123
+
124
+ private
125
+
126
+ def expand_path(file_name)
127
+ uri = URI.parse(file_name.gsub(/\=.*$/, '/'))
128
+ path = uri.normalize.to_s
129
+ # ignore "./" and "../"
130
+ path.gsub(%r{/\.\.?(?:/|$)}, '/').
131
+ sub(%r{^\.\.?(?:/|$)}, '').
132
+ sub(%r{^$}, '/')
133
+ end
134
+
135
+ def metadata_key(key)
136
+ key.gsub(/\-|\//, '_')
137
+ end
138
+
84
139
  end
85
140
  end
86
141
  end
@@ -19,6 +19,8 @@ provides "cloud"
19
19
  require_plugin "ec2"
20
20
  require_plugin "rackspace"
21
21
  require_plugin "eucalyptus"
22
+ require_plugin "linode"
23
+ require_plugin "openstack"
22
24
 
23
25
  # Make top-level cloud hashes
24
26
  #
@@ -42,7 +44,7 @@ def on_ec2?
42
44
  end
43
45
 
44
46
  # Fill cloud hash with ec2 values
45
- def get_ec2_values
47
+ def get_ec2_values
46
48
  cloud[:public_ips] << ec2['public_ipv4']
47
49
  cloud[:private_ips] << ec2['local_ipv4']
48
50
  cloud[:public_ipv4] = ec2['public_ipv4']
@@ -52,7 +54,7 @@ def get_ec2_values
52
54
  cloud[:provider] = "ec2"
53
55
  end
54
56
 
55
- # setup ec2 cloud
57
+ # setup ec2 cloud
56
58
  if on_ec2?
57
59
  create_objects
58
60
  get_ec2_values
@@ -73,21 +75,53 @@ end
73
75
 
74
76
  # Fill cloud hash with rackspace values
75
77
  def get_rackspace_values
76
- cloud[:public_ips] << rackspace['public_ip']
77
- cloud[:private_ips] << rackspace['private_ip']
78
+ cloud[:public_ips] << rackspace['public_ipv4'] if rackspace['public_ipv4']
79
+ cloud[:private_ips] << rackspace['local_ipv4'] if rackspace['local_ipv4']
78
80
  cloud[:public_ipv4] = rackspace['public_ipv4']
81
+ cloud[:public_ipv6] = rackspace['public_ipv6']
79
82
  cloud[:public_hostname] = rackspace['public_hostname']
80
83
  cloud[:local_ipv4] = rackspace['local_ipv4']
84
+ cloud[:local_ipv6] = rackspace['local_ipv6']
81
85
  cloud[:local_hostname] = rackspace['local_hostname']
82
86
  cloud[:provider] = "rackspace"
83
87
  end
84
88
 
85
- # setup rackspace cloud
89
+ # setup rackspace cloud
86
90
  if on_rackspace?
87
91
  create_objects
88
92
  get_rackspace_values
89
93
  end
90
94
 
95
+ # ----------------------------------------
96
+ # linode
97
+ # ----------------------------------------
98
+
99
+ # Is current cloud linode?
100
+ #
101
+ # === Return
102
+ # true:: If linode Hash is defined
103
+ # false:: Otherwise
104
+ def on_linode?
105
+ linode != nil
106
+ end
107
+
108
+ # Fill cloud hash with linode values
109
+ def get_linode_values
110
+ cloud[:public_ips] << linode['public_ip']
111
+ cloud[:private_ips] << linode['private_ip']
112
+ cloud[:public_ipv4] = linode['public_ipv4']
113
+ cloud[:public_hostname] = linode['public_hostname']
114
+ cloud[:local_ipv4] = linode['local_ipv4']
115
+ cloud[:local_hostname] = linode['local_hostname']
116
+ cloud[:provider] = "linode"
117
+ end
118
+
119
+ # setup linode cloud data
120
+ if on_linode?
121
+ create_objects
122
+ get_linode_values
123
+ end
124
+
91
125
  # ----------------------------------------
92
126
  # eucalyptus
93
127
  # ----------------------------------------
@@ -115,3 +149,33 @@ if on_eucalyptus?
115
149
  create_objects
116
150
  get_eucalyptus_values
117
151
  end
152
+
153
+ # ----------------------------------------
154
+ # openstack
155
+ # ----------------------------------------
156
+
157
+ # Is current cloud openstack-based?
158
+ #
159
+ # === Return
160
+ # true:: If openstack Hash is defined
161
+ # false:: Otherwise
162
+ def on_openstack?
163
+ openstack != nil
164
+ end
165
+
166
+ # Fill cloud hash with openstack values
167
+ def get_openstack_values
168
+ cloud[:public_ips] << openstack['public_ipv4']
169
+ cloud[:private_ips] << openstack['local_ipv4']
170
+ cloud[:public_ipv4] = openstack['public_ipv4']
171
+ cloud[:public_hostname] = openstack['public_hostname']
172
+ cloud[:local_ipv4] = openstack['local_ipv4']
173
+ cloud[:local_hostname] = openstack['local_hostname']
174
+ cloud[:provider] = openstack['provider']
175
+ end
176
+
177
+ # setup openstack cloud
178
+ if on_openstack?
179
+ create_objects
180
+ get_openstack_values
181
+ end
@@ -15,19 +15,56 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
  #
18
-
19
18
  provides "system_profile"
20
19
 
21
- begin
20
+ begin
22
21
  require 'plist'
23
22
 
24
23
  system_profile Array.new
25
- popen4("system_profiler -xml -detailLevel mini") do |pid, stdin, stdout, stderr|
26
- stdin.close
27
- Plist::parse_xml(stdout.read).each do |e|
28
- system_profile << e
24
+ items Array.new
25
+ detail_level = {
26
+ 'mini' => [
27
+ "SPParallelATAData",
28
+ "SPAudioData",
29
+ "SPBluetoothData",
30
+ "SPCardReaderData",
31
+ "SPDiagnosticsData",
32
+ "SPDiscBurningData",
33
+ "SPEthernetData",
34
+ "SPFibreChannelData",
35
+ "SPFireWireData",
36
+ "SPDisplaysData",
37
+ "SPHardwareRAIDData",
38
+ "SPMemoryData",
39
+ "SPModemData",
40
+ "SPNetworkData",
41
+ "SPPCIData",
42
+ "SPParallelSCSIData",
43
+ "SPPrintersSoftwareData",
44
+ "SPPrintersData",
45
+ "SPSASData",
46
+ "SPSerialATAData",
47
+ "SPSoftwareData",
48
+ "SPThunderboltData",
49
+ "SPUSBData",
50
+ "SPWWANData",
51
+ "SPAirPortData"
52
+ ],
53
+ 'full' => [
54
+ "SPHardwareDataType"
55
+ ]
56
+ }
57
+
58
+ detail_level.each do |level, data_types|
59
+ popen4("system_profiler -xml -detailLevel #{level} #{data_types.join(' ')}") do |pid, stdin, stdout, stderr|
60
+ stdin.close
61
+ Plist::parse_xml(stdout.read).each do |e|
62
+ items << e
63
+ end
29
64
  end
30
65
  end
66
+
67
+ system_profile items.sort_by { |h| h['_dataType'] }
31
68
  rescue LoadError => e
32
69
  Ohai::Log.debug("Can't load gem: #{e})")
33
- end
70
+ end
@@ -25,6 +25,22 @@ if from("sysctl -n security.jail.jailed").to_i == 1
25
25
  virtualization[:role] = "guest"
26
26
  end
27
27
 
28
+ # detect from modules
29
+ popen4("/sbin/kldstat") do |pid, stdin, stdout, stderr|
30
+ stdin.close
31
+ stdout.each do |line|
32
+ case line
33
+ when /vboxdrv/
34
+ virtualization[:system] = "vbox"
35
+ virtualization[:role] = "host"
36
+ when /vboxguest/
37
+ virtualization[:system] = "vbox"
38
+ virtualization[:role] = "guest"
39
+ end
40
+ end
41
+ end
42
+
43
+
28
44
  # XXX doesn't work when jail is there but not running (ezjail-admin stop)
29
45
  if from("jls -n \| wc -l").to_i >= 1
30
46
  virtualization[:system] = "jail"
@@ -23,7 +23,7 @@ java = Mash.new
23
23
 
24
24
  status, stdout, stderr = nil
25
25
  if RUBY_PLATFORM.downcase.include?("darwin")
26
- if system("/usr/libexec/java_home 2&>1 >/dev/null")
26
+ if system("/usr/libexec/java_home 2>&1 >/dev/null")
27
27
  status, stdout, stderr = run_command(:no_status_check => true, :command => "java -version")
28
28
  end
29
29
  else
@@ -24,6 +24,7 @@ kernel Mash.new
24
24
  case languages[:ruby][:host_os]
25
25
  when /mswin|mingw32|windows/
26
26
  require_plugin "windows::kernel"
27
+ require_plugin "windows::kernel_devices"
27
28
  else
28
29
  kernel[:name] = from("uname -s")
29
30
  kernel[:release] = from("uname -r")
@@ -0,0 +1,53 @@
1
+ #
2
+ # Author:: Aaron Kalin (<akalin@martinisoftware.com>)
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ provides "linode"
18
+
19
+ require_plugin "kernel"
20
+ require_plugin "network"
21
+
22
+ # Checks for matching linode kernel name
23
+ #
24
+ # Returns true or false
25
+ def has_linode_kernel?
26
+ kernel[:release].split('-').last =~ /linode/
27
+ end
28
+
29
+ # Identifies the linode cloud by preferring the hint, then
30
+ #
31
+ # Returns true or false
32
+ def looks_like_linode?
33
+ hint?('linode') || has_linode_kernel?
34
+ end
35
+
36
+ # Names linode ip address
37
+ #
38
+ # name - symbol of ohai name (e.g. :public_ip)
39
+ # eth - Interface name (e.g. :eth0)
40
+ #
41
+ # Alters linode mash with new interface based on name parameter
42
+ def get_ip_address(name, eth)
43
+ network[:interfaces][eth][:addresses].each do |key, info|
44
+ linode[name] = key if info['family'] == 'inet'
45
+ end
46
+ end
47
+
48
+ # Setup linode mash if it is a linode system
49
+ if looks_like_linode?
50
+ linode Mash.new
51
+ get_ip_address(:public_ip, :eth0)
52
+ get_ip_address(:private_ip, "eth0:1")
53
+ end
@@ -44,7 +44,11 @@ elsif File.exists?("/etc/debian_version")
44
44
  platform "ubuntu"
45
45
  platform_version lsb[:release]
46
46
  else
47
- platform "debian"
47
+ if File.exists?("/usr/bin/raspi-config")
48
+ platform "raspbian"
49
+ else
50
+ platform "debian"
51
+ end
48
52
  platform_version File.read("/etc/debian_version").chomp
49
53
  end
50
54
  elsif File.exists?("/etc/redhat-release")
@@ -85,7 +89,7 @@ end
85
89
 
86
90
 
87
91
  case platform
88
- when /debian/, /ubuntu/, /linuxmint/
92
+ when /debian/, /ubuntu/, /linuxmint/, /raspbian/
89
93
  platform_family "debian"
90
94
  when /fedora/
91
95
  platform_family "fedora"
@@ -25,63 +25,149 @@ network[:interfaces] = Mash.new unless network[:interfaces]
25
25
  counters Mash.new unless counters
26
26
  counters[:network] = Mash.new unless counters[:network]
27
27
 
28
- ipaddress nil
29
- ip6address
30
- macaddress nil
31
-
32
28
  require_plugin "hostname"
33
29
  require_plugin "#{os}::network"
34
30
 
35
- # ipaddress and macaddress can be set from the #{os}::network plugin
36
- return unless ipaddress.nil?
31
+ FAMILIES = {
32
+ "inet" => "default",
33
+ "inet6" => "default_inet6"
34
+ }
35
+
36
+ def sorted_ips(family = "inet")
37
+ raise "bad family #{family}" unless [ "inet", "inet6" ].include? family
38
+
39
+ # going to use that later to sort by scope
40
+ scope_prio = [ "global", "site", "link", "host", "node", nil ]
41
+
42
+ ipaddresses = []
43
+ # ipaddresses going to hold #{family} ipaddresses and their scope
44
+ Mash[network['interfaces']].each do |iface, iface_v|
45
+ iface_v['addresses'].each do |addr, addr_v|
46
+ next if addr_v.nil? or not addr_v.has_key? "family" or addr_v['family'] != family
47
+ ipaddresses << {
48
+ :ipaddress => addr_v["prefixlen"] ? IPAddress("#{addr}/#{addr_v["prefixlen"]}") : IPAddress("#{addr}/#{addr_v["netmask"]}"),
49
+ :scope => addr_v["scope"].nil? ? nil : addr_v["scope"].downcase,
50
+ :iface => iface
51
+ }
52
+ end
53
+ end
54
+
55
+ # sort ip addresses by scope, by prefixlen and then by ip address
56
+ # 128 - prefixlen: longest prefixes first
57
+ ipaddresses.sort_by do |v|
58
+ [ ( scope_prio.index(v[:scope]) or 999999 ),
59
+ 128 - v[:ipaddress].prefix.to_i,
60
+ ( family == "inet" ? v[:ipaddress].to_u32 : v[:ipaddress].to_u128 )
61
+ ]
62
+ end
63
+ end
64
+
65
+ def find_ip(family = "inet")
66
+ r=sorted_ips(family)
67
+
68
+ # return if there isn't any #{family} address !
69
+ return [ nil, nil ] if r.empty?
37
70
 
38
- def find_ip_and_mac(addresses, match = nil)
39
- ip = nil; mac = nil; ip6 = nil
40
- addresses.keys.each do |addr|
41
- if match.nil?
42
- ip = addr if addresses[addr]["family"].eql?("inet")
71
+ # shortcuts to access default #{family} interface and gateway
72
+ int_attr = FAMILIES[family] +"_interface"
73
+ gw_attr = FAMILIES[family] + "_gateway"
74
+
75
+ # If we have a default interface that has addresses,
76
+ # populate the short-cut attributes
77
+ if network[int_attr]
78
+
79
+ # network[int_attr] exists, the choosen ip must be exist on this interface
80
+ r = r.select do |v|
81
+ v[:iface] == network[int_attr]
82
+ end
83
+ if r.empty?
84
+ Ohai::Log.warn("[#{family}] no ip on #{network[int_attr]}")
85
+ elsif network[gw_attr] and
86
+ network["interfaces"][network[int_attr]] and
87
+ network["interfaces"][network[int_attr]]["addresses"]
88
+ if [ "0.0.0.0", "::" ].include? network[gw_attr]
89
+ # link level default route
90
+ Ohai::Log.debug("link level default #{family} route, picking ip from #{network[gw_attr]}")
91
+ r = r.first
92
+ else
93
+ r = r.select do |v|
94
+ network_contains_address(network[gw_attr], v[:ipaddress], v[:iface])
95
+ end.first
96
+ if r.nil?
97
+ Ohai::Log.warn("[#{family}] no ipaddress/mask on #{network[int_attr]} matching the gateway #{network[gw_attr]}")
98
+ else
99
+ Ohai::Log.debug("[#{family}] Using default interface #{network[int_attr]} and default gateway #{network[gw_attr]} to set the default ip to #{r[:ipaddress]}")
100
+ end
101
+ end
43
102
  else
44
- ip = addr if addresses[addr]["family"].eql?("inet") && network_contains_address(match, addr, addresses[addr])
103
+ # return the first ip address on network[int_attr]
104
+ r = r.first
45
105
  end
46
- ip6 = addr if addresses[addr]["family"].eql?("inet6") && addresses[addr]["scope"].eql?("Global")
47
- mac = addr if addresses[addr]["family"].eql?("lladdr")
48
- break if (ip and mac)
106
+ else
107
+ r = r.first
108
+ Ohai::Log.info("[#{family}] no default interface, picking the first ipaddress")
49
109
  end
50
- Ohai::Log.debug("Found IPv4 address #{ip} with MAC #{mac} #{match.nil? ? '' : 'matching address ' + match}")
51
- Ohai::Log.debug("Found IPv6 address #{ip6}") if ip6
52
- [ip, mac, ip6]
110
+
111
+ return [ nil, nil ] if r.nil? or r.empty?
112
+
113
+ [ r[:ipaddress].to_s, r[:iface] ]
53
114
  end
54
115
 
55
- def network_contains_address(address_to_match, network_ip, network_opts)
56
- if network_opts[:peer]
57
- network_opts[:peer] == address_to_match
116
+ def find_mac_from_iface(iface)
117
+ r = network["interfaces"][iface]["addresses"].select{|k,v| v["family"]=="lladdr"}
118
+ r.nil? or r.first.nil? ? nil : r.first.first
119
+ end
120
+
121
+ def network_contains_address(address_to_match, ipaddress, iface)
122
+ # address_to_match: String
123
+ # ipaddress: IPAddress
124
+ # iface: String
125
+ if peer = network["interfaces"][iface]["addresses"][ipaddress.to_s][:peer]
126
+ IPAddress(peer) == IPAddress(address_to_match)
58
127
  else
59
- network = IPAddress "#{network_ip}/#{network_opts[:netmask]}"
60
- host = IPAddress address_to_match
61
- network.include?(host)
128
+ ipaddress.include? IPAddress(address_to_match)
62
129
  end
63
130
  end
64
131
 
65
- # If we have a default interface that has addresses, populate the short-cut attributes
66
- # 0.0.0.0 is not a valid gateway address in this case
67
- if network[:default_interface] and
68
- network[:default_gateway] and
69
- network[:default_gateway] != "0.0.0.0" and
70
- network["interfaces"][network[:default_interface]] and
71
- network["interfaces"][network[:default_interface]]["addresses"]
72
- Ohai::Log.debug("Using default interface for default ip and mac address")
73
- im = find_ip_and_mac(network["interfaces"][network[:default_interface]]["addresses"], network[:default_gateway])
74
- ipaddress im.shift
75
- macaddress im.shift
76
- ip6address im.shift
77
- else
78
- network["interfaces"].keys.sort.each do |iface|
79
- if network["interfaces"][iface]["encapsulation"].eql?("Ethernet")
80
- Ohai::Log.debug("Picking ip and mac address from first Ethernet interface")
81
- im = find_ip_and_mac(network["interfaces"][iface]["addresses"])
82
- ipaddress im.shift
83
- macaddress im.shift
84
- return if (ipaddress and macaddress)
132
+ # ipaddress, ip6address and macaddress can be set by the #{os}::network plugin
133
+ # atm it is expected macaddress is set at the same time than ipaddress
134
+ # if ipaddress is set and macaddress is nil, that means the interface
135
+ # ipaddress is bound to has the NOARP flag
136
+
137
+
138
+ results = {}
139
+
140
+ # inet family is treated before inet6
141
+ FAMILIES.keys.sort.each do |family|
142
+ r = {}
143
+ ( r["ip"], r["iface"] ) = find_ip(family)
144
+ r["mac"] = find_mac_from_iface(r["iface"]) unless r["iface"].nil?
145
+ # don't overwrite attributes if they've already been set by the "#{os}::network" plugin
146
+ if family == "inet" and ipaddress.nil?
147
+ if r["ip"].nil?
148
+ Ohai::Log.warn("unable to detect ipaddress")
149
+ # i don't issue this warning if r["ip"] exists and r["mac"].nil?
150
+ # as it could be a valid setup with a NOARP default_interface
151
+ Ohai::Log.warn("unable to detect macaddress")
152
+ else
153
+ ipaddress r["ip"]
154
+ macaddress r["mac"]
155
+ end
156
+ elsif family == "inet6" and ip6address.nil?
157
+ if r["ip"].nil?
158
+ Ohai::Log.warn("unable to detect ip6address")
159
+ else
160
+ ip6address r["ip"]
161
+ if r["mac"] and macaddress.nil? and ipaddress.nil?
162
+ Ohai::Log.info("macaddress set to #{r["mac"]} from the ipv6 setup")
163
+ macaddress r["mac"]
164
+ end
85
165
  end
86
166
  end
167
+ results[family] = r
168
+ end
169
+
170
+ if results["inet"]["iface"] and results["inet6"]["iface"] and
171
+ results["inet"]["iface"] != results["inet6"]["iface"]
172
+ Ohai::Log.info("ipaddress and ip6address are set from different interfaces (#{results["inet"]["iface"]} & #{results["inet6"]["iface"]}), macaddress has been set using the ipaddress interface")
87
173
  end