ohai 6.14.0 → 6.16.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
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