ohai 18.1.0 → 19.1.16

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -5
  3. data/lib/ohai/application.rb +1 -1
  4. data/lib/ohai/dsl/plugin/versionvii.rb +2 -2
  5. data/lib/ohai/loader.rb +7 -6
  6. data/lib/ohai/mixin/alibaba_metadata.rb +24 -27
  7. data/lib/ohai/mixin/azure_metadata.rb +11 -17
  8. data/lib/ohai/mixin/ec2_metadata.rb +18 -4
  9. data/lib/ohai/mixin/gce_metadata.rb +24 -28
  10. data/lib/ohai/mixin/json_helper.rb +36 -0
  11. data/lib/ohai/mixin/network_helper.rb +28 -1
  12. data/lib/ohai/mixin/oci_metadata.rb +42 -18
  13. data/lib/ohai/mixin/string.rb +1 -1
  14. data/lib/ohai/plugins/aix/kernel.rb +2 -2
  15. data/lib/ohai/plugins/aix/network.rb +1 -1
  16. data/lib/ohai/plugins/aix/virtualization.rb +1 -1
  17. data/lib/ohai/plugins/alibaba.rb +1 -1
  18. data/lib/ohai/plugins/cpu.rb +10 -3
  19. data/lib/ohai/plugins/darwin/platform.rb +3 -1
  20. data/lib/ohai/plugins/darwin/virtualization.rb +16 -2
  21. data/lib/ohai/plugins/ec2.rb +5 -1
  22. data/lib/ohai/plugins/eucalyptus.rb +1 -1
  23. data/lib/ohai/plugins/filesystem.rb +14 -16
  24. data/lib/ohai/plugins/freebsd/network.rb +35 -10
  25. data/lib/ohai/plugins/gce.rb +1 -1
  26. data/lib/ohai/plugins/linux/block_device.rb +1 -1
  27. data/lib/ohai/plugins/linux/interrupts.rb +2 -3
  28. data/lib/ohai/plugins/linux/lspci.rb +5 -1
  29. data/lib/ohai/plugins/linux/network.rb +4 -2
  30. data/lib/ohai/plugins/oci.rb +15 -15
  31. data/lib/ohai/plugins/packages.rb +3 -3
  32. data/lib/ohai/plugins/passwd.rb +1 -1
  33. data/lib/ohai/plugins/platform.rb +13 -1
  34. data/lib/ohai/plugins/rackspace.rb +1 -1
  35. data/lib/ohai/plugins/rpm.rb +1 -1
  36. data/lib/ohai/plugins/windows/dmi.rb +1 -1
  37. data/lib/ohai/plugins/windows/network.rb +1 -1
  38. data/lib/ohai/provides_map.rb +5 -5
  39. data/lib/ohai/runner.rb +1 -3
  40. data/lib/ohai/version.rb +1 -1
  41. data/ohai.gemspec +6 -5
  42. metadata +29 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d6704f249d63eb6abebd08dd48e408fee70bd50d5ca2304471bdcc53b80941c
4
- data.tar.gz: f761a02520c31d96e8a8bab3853f5a432d0fb9460b2901dd1a0abe4efdcdcc6b
3
+ metadata.gz: 6339d53754721217929ead82d4a232ace638f648d5e7ba2469221dfd22da54a0
4
+ data.tar.gz: 28eda66502f23a2bacf4c96407fb89193023fe76cd5f30f0ab839096def6e044
5
5
  SHA512:
6
- metadata.gz: a58f353ea899d897e4fc3cd8aa5dabe9737b8002ceda5483482ac7fceded93d40ef5581ca4e403edaa049e6f43587932945e8f1f125cb88162e31ae424a80865
7
- data.tar.gz: a58f4b0a239f206e2194abacbdbf137931057980745f0b5b9eee528ff314c21a042ae1b88a0325b12a68fc928c77817778d53d89e952bbd9d88410df35a93865
6
+ metadata.gz: c33166e19c09e55f3b28d9ee437a350666b7241b949e0b45bc1e4cc27118bc86130f2c6520c7a136de879d3e72fde0254cadbe3d562646abc7298cbb8b437731
7
+ data.tar.gz: ffd0515bda588dee888dcd1deed4a8d1275b35ddbb55d7b8913b5e87203781628820f0417df55847da3e27a2cec85b2df2e7a2cb7dcb632b9f1181d2f0575e03
data/Gemfile CHANGED
@@ -1,23 +1,23 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  source "https://rubygems.org"
3
4
 
4
5
  gemspec
5
6
 
6
- # pull these gems from main of chef/chef so that we're testing against what we will release
7
+ # pull these gems from main of chef/chef so that we"re testing against what we will release
8
+ gem "appbundler"
7
9
  gem "chef-config", git: "https://github.com/chef/chef", branch: "main", glob: "chef-config/chef-config.gemspec"
8
10
  gem "chef-utils", git: "https://github.com/chef/chef", branch: "main", glob: "chef-utils/chef-utils.gemspec"
9
-
11
+ gem "ffi", "~> 1.17", force_ruby_platform: true
10
12
  # NOTE: do not submit PRs to add pry as a dep, add to your Gemfile.local
11
13
  group :development do
12
- gem "chefstyle", "2.2.2"
14
+ gem "cookstyle", ">= 7.32.8"
13
15
  gem "ipaddr_extensions"
14
16
  gem "rake", ">= 10.1.0"
15
17
  gem "rspec-collection_matchers", "~> 1.0"
16
18
  gem "rspec-core", "~> 3.0"
17
19
  gem "rspec-expectations", "~> 3.0"
18
20
  gem "rspec-mocks", "~> 3.0"
19
- gem "rubocop-performance", "1.16.0"
20
- gem "rubocop-rspec"
21
21
  end
22
22
 
23
23
  group :debug do
@@ -49,7 +49,7 @@ class Ohai::Application
49
49
  short: "-l LEVEL",
50
50
  long: "--log_level LEVEL",
51
51
  description: "Set the log level (debug, info, warn, error, fatal)",
52
- proc: lambda { |l| l.to_sym }
52
+ proc: lambda(&:to_sym)
53
53
 
54
54
  option :log_location,
55
55
  short: "-L LOGLOCATION",
@@ -149,11 +149,11 @@ module Ohai
149
149
  end
150
150
 
151
151
  def provides(*paths)
152
- logger.warn("[UNSUPPORTED OPERATION] \'provides\' is no longer supported in a \'collect_data\' context. Please specify \'provides\' before collecting plugin data. Ignoring command \'provides #{paths.join(", ")}")
152
+ logger.warn("[UNSUPPORTED OPERATION] 'provides' is no longer supported in a 'collect_data' context. Please specify 'provides' before collecting plugin data. Ignoring command 'provides #{paths.join(", ")}")
153
153
  end
154
154
 
155
155
  def require_plugin(*args)
156
- logger.warn("[UNSUPPORTED OPERATION] \'require_plugin\' is no longer supported. Please use \'depends\' instead.\nIgnoring plugin(s) #{args.join(", ")}")
156
+ logger.warn("[UNSUPPORTED OPERATION] 'require_plugin' is no longer supported. Please use 'depends' instead.\nIgnoring plugin(s) #{args.join(", ")}")
157
157
  end
158
158
 
159
159
  def configuration(option, *options)
data/lib/ohai/loader.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  #
2
3
  # Author:: Claire McQuin (<claire@chef.io>)
3
4
  # Copyright:: Copyright (c) Chef Software Inc.
@@ -97,10 +98,10 @@ module Ohai
97
98
  # @return [Object] class object for the ohai plugin defined in the file
98
99
  def load_plugin_class(plugin_path)
99
100
  # Read the contents of the plugin to understand if it's a V6 or V7 plugin.
100
- contents = ""
101
+ contents = nil
101
102
  begin
102
103
  logger.trace("Loading plugin at #{plugin_path}")
103
- contents << IO.read(plugin_path)
104
+ contents = File.read(plugin_path)
104
105
  rescue IOError, Errno::ENOENT
105
106
  logger.warn("Unable to open or read plugin at #{plugin_path}")
106
107
  return nil
@@ -110,9 +111,9 @@ module Ohai
110
111
  if contents.include?("Ohai.plugin")
111
112
  load_v7_plugin_class(contents, plugin_path)
112
113
  else
113
- raise Exceptions::IllegalPluginDefinition, "[DEPRECATION] Plugin at #{plugin_path}"\
114
- " is a version 6 plugin. Version 6 plugins are no longer supported by Ohai. This"\
115
- " plugin will need to be updated to the v7 Ohai plugin format. See"\
114
+ raise Exceptions::IllegalPluginDefinition, "[DEPRECATION] Plugin at #{plugin_path}" \
115
+ " is a version 6 plugin. Version 6 plugins are no longer supported by Ohai. This" \
116
+ " plugin will need to be updated to the v7 Ohai plugin format. See" \
116
117
  " https://docs.chef.io/ohai_custom.html for v7 syntax."
117
118
  end
118
119
  end
@@ -151,7 +152,7 @@ module Ohai
151
152
  rescue Ohai::Exceptions::IllegalPluginDefinition => e
152
153
  logger.warn("Plugin Definition Error: <#{plugin_path}>: #{e.message}")
153
154
  rescue NoMethodError => e
154
- logger.warn("Plugin Method Error: <#{plugin_path}>: unsupported operation \'#{e.name}\'")
155
+ logger.warn("Plugin Method Error: <#{plugin_path}>: unsupported operation '#{e.name}'")
155
156
  rescue SyntaxError => e
156
157
  # split on occurrences of
157
158
  # <env>: syntax error,
@@ -18,6 +18,9 @@
18
18
 
19
19
  require "net/http" unless defined?(Net::HTTP)
20
20
 
21
+ require_relative "../mixin/json_helper"
22
+ include Ohai::Mixin::JsonHelper
23
+
21
24
  module Ohai
22
25
  module Mixin
23
26
  #
@@ -38,36 +41,30 @@ module Ohai
38
41
  conn.get("/2016-01-01/#{uri}", { "User-Agent" => "chef-ohai/#{Ohai::VERSION}" })
39
42
  end
40
43
 
41
- def fetch_metadata(id = "")
44
+ def fetch_metadata(id = "", is_directory = true)
42
45
  response = http_get(id)
43
- return nil unless response.code == "200"
46
+ if response.code == "200"
44
47
 
45
- if json?(response.body)
46
- data = String(response.body)
47
- parser = FFI_Yajl::Parser.new
48
- parser.parse(data)
49
- elsif response.body.include?("\n")
50
- temp = {}
51
- response.body.split("\n").each do |sub_attr|
52
- temp[sanitize_key(sub_attr)] = fetch_metadata("#{id}/#{sub_attr}")
48
+ if !is_directory
49
+ json_data = parse_json(response.body)
50
+ if json_data.nil?
51
+ response.body
52
+ else
53
+ json_data
54
+ end
55
+ elsif is_directory
56
+ temp = {}
57
+ response.body.split("\n").each do |sub_attr|
58
+ if "#{id}/#{sub_attr}" != "/user-data"
59
+ uri = id == "" ? "#{id}#{sub_attr}/" : "#{id}#{sub_attr}"
60
+ temp[sanitize_key(sub_attr).gsub(/_$/, "")] = fetch_metadata(uri, has_trailing_slash?(uri))
61
+ end
62
+ end
63
+ temp
53
64
  end
54
- temp
55
65
  else
56
- response.body
57
- end
58
- end
59
-
60
- # @param [String] data that might be JSON
61
- #
62
- # @return [Boolean] is the data JSON or not?
63
- def json?(data)
64
- data = String(data)
65
- parser = FFI_Yajl::Parser.new
66
- begin
67
- parser.parse(data)
68
- true
69
- rescue FFI_Yajl::ParseError
70
- false
66
+ logger.warn("Mixin AlibabaMetadata: Received response code #{response.code} requesting metadata for id='#{id}'")
67
+ nil
71
68
  end
72
69
  end
73
70
 
@@ -75,7 +72,7 @@ module Ohai
75
72
  #
76
73
  # @return [Boolean] is there a trailing /?
77
74
  def has_trailing_slash?(data)
78
- !!( data =~ %r{/$} )
75
+ !!(data =~ %r{/$})
79
76
  end
80
77
 
81
78
  def sanitize_key(key)
@@ -18,6 +18,9 @@
18
18
 
19
19
  require "net/http" unless defined?(Net::HTTP)
20
20
 
21
+ require_relative "../mixin/json_helper"
22
+ include Ohai::Mixin::JsonHelper
23
+
21
24
  module Ohai
22
25
  module Mixin
23
26
  #
@@ -38,7 +41,8 @@ module Ohai
38
41
  AZURE_SUPPORTED_VERSIONS ||= %w{ 2018-10-01 2019-02-01 2019-03-11 2019-04-30 2019-06-01
39
42
  2019-06-04 2019-08-01 2019-08-15 2019-11-01 2020-06-01
40
43
  2020-07-15 2020-09-01 2020-10-01 2020-12-01 2021-01-01
41
- 2021-02-01 2021-03-01 2021-05-01 2021-10-01 }.freeze
44
+ 2021-02-01 2021-03-01 2021-05-01 2021-10-01 2021-11-01
45
+ 2021-11-15 2021-12-13 2023-07-01 }.freeze
42
46
 
43
47
  def best_api_version
44
48
  @api_version ||= begin
@@ -81,26 +85,16 @@ module Ohai
81
85
  conn.get(uri, { "Metadata" => "true" })
82
86
  end
83
87
 
84
- # parse JSON data from a String to a Hash
85
- #
86
- # @param [String] response_body json as string to parse
87
- #
88
- # @return [Hash]
89
- def parse_json(response_body)
90
- data = String(response_body)
91
- parser = FFI_Yajl::Parser.new
92
- parser.parse(data)
93
- rescue FFI_Yajl::ParseError
94
- logger.warn("Mixin AzureMetadata: Metadata response is NOT valid JSON")
95
- nil
96
- end
97
-
98
- def fetch_metadata(api_version = nil)
88
+ def fetch_metadata(_api_version = nil)
99
89
  metadata_url = "/metadata/instance?api-version=#{best_api_version}"
100
90
  logger.trace("Mixin AzureMetadata: Fetching metadata from host #{AZURE_METADATA_ADDR} at #{metadata_url}")
101
91
  response = http_get(metadata_url)
102
92
  if response.code == "200"
103
- parse_json(response.body)
93
+ json_data = parse_json(response.body)
94
+ if json_data.nil?
95
+ logger.warn("Mixin AzureMetadata: Metadata response is NOT valid JSON")
96
+ end
97
+ json_data
104
98
  else
105
99
  logger.warn("Mixin AzureMetadata: Received response code #{response.code} requesting metadata")
106
100
  nil
@@ -20,6 +20,9 @@
20
20
 
21
21
  require "net/http" unless defined?(Net::HTTP)
22
22
 
23
+ require_relative "../mixin/json_helper"
24
+ include Ohai::Mixin::JsonHelper
25
+
23
26
  module Ohai
24
27
  module Mixin
25
28
  ##
@@ -229,9 +232,14 @@ module Ohai
229
232
  @fetch_dynamic_data ||= begin
230
233
  response = http_client.get("/#{best_api_version}/dynamic/instance-identity/document/", { 'X-aws-ec2-metadata-token': v2_token })
231
234
 
232
- if json?(response.body) && response.code == "200"
233
- FFI_Yajl::Parser.parse(response.body)
235
+ if response.code == "200"
236
+ json_data = parse_json(response.body, {})
237
+ if json_data.nil?
238
+ logger.warn("Mixin Ec2Metadata: Metadata response is NOT valid JSON")
239
+ end
240
+ json_data
234
241
  else
242
+ logger.warn("Mixin Ec2Metadata: Received response code #{response.code} requesting metadata")
235
243
  {}
236
244
  end
237
245
  end
@@ -240,8 +248,14 @@ module Ohai
240
248
  private
241
249
 
242
250
  def expand_path(file_name)
243
- path = file_name.gsub(/\=.*$/, "/")
244
- # ignore "./" and "../"
251
+ # First substitution - exactly matches original behavior but safer
252
+ path = if file_name.include?("=")
253
+ file_name[0...file_name.index("=")] + "/"
254
+ else
255
+ file_name.dup
256
+ end
257
+
258
+ # Handle relative path components
245
259
  path.gsub(%r{/\.\.?(?:/|$)}, "/")
246
260
  .sub(%r{^\.\.?(?:/|$)}, "")
247
261
  .sub(/^$/, "/")
@@ -17,13 +17,16 @@
17
17
 
18
18
  require "net/http" unless defined?(Net::HTTP)
19
19
 
20
+ require_relative "../mixin/json_helper"
21
+ include Ohai::Mixin::JsonHelper
22
+
20
23
  module Ohai
21
24
  module Mixin
22
25
  module GCEMetadata
23
26
 
24
27
  # Trailing dot to host is added to avoid DNS search path
25
28
  GCE_METADATA_ADDR ||= "metadata.google.internal."
26
- GCE_METADATA_URL ||= "/computeMetadata/v1/?recursive=true"
29
+ GCE_METADATA_URL ||= "/computeMetadata/v1"
27
30
 
28
31
  # fetch the meta content with a timeout and the required header
29
32
  def http_get(uri)
@@ -36,35 +39,28 @@ module Ohai
36
39
  end
37
40
 
38
41
  def fetch_metadata(id = "")
39
- response = http_get("#{GCE_METADATA_URL}/#{id}")
40
- return nil unless response.code == "200"
41
-
42
- if json?(response.body)
43
- data = String(response.body)
44
- parser = FFI_Yajl::Parser.new
45
- parser.parse(data)
46
- elsif has_trailing_slash?(id) || (id == "")
47
- temp = {}
48
- response.body.split("\n").each do |sub_attr|
49
- temp[sanitize_key(sub_attr)] = fetch_metadata("#{id}#{sub_attr}")
42
+ url = "#{GCE_METADATA_URL}/#{id}"
43
+ url = "#{url}?recursive=true" if url.end_with?("/")
44
+ response = http_get(url)
45
+ if response.code == "200"
46
+ json_data = parse_json(response.body)
47
+ if json_data.nil?
48
+ logger.warn("Mixin GCEMetadata: Metadata response is NOT valid JSON for id='#{id}'")
49
+ if has_trailing_slash?(id) || (id == "")
50
+ temp = {}
51
+ response.body.split("\n").each do |sub_attr|
52
+ temp[sanitize_key(sub_attr)] = fetch_metadata("#{id}#{sub_attr}")
53
+ end
54
+ temp
55
+ else
56
+ response.body
57
+ end
58
+ else
59
+ json_data
50
60
  end
51
- temp
52
61
  else
53
- response.body
54
- end
55
- end
56
-
57
- # @param [String] data that might be JSON
58
- #
59
- # @return [Boolean] is the data JSON or not?
60
- def json?(data)
61
- data = String(data)
62
- parser = FFI_Yajl::Parser.new
63
- begin
64
- parser.parse(data)
65
- true
66
- rescue FFI_Yajl::ParseError
67
- false
62
+ logger.warn("Mixin GCEMetadata: Received response code #{response.code} requesting metadata for id='#{id}'")
63
+ nil
68
64
  end
69
65
  end
70
66
 
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Author:: Renato Covarrubias (<rnt@rnt.cl>)
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ module Ohai
19
+ module Mixin
20
+ module JsonHelper
21
+ # parse JSON data from a String to a Hash
22
+ #
23
+ # @param [String] response_body json as string to parse
24
+ # @param [Object] return_on_parse_error value to return if parsing fails
25
+ #
26
+ # @return [Hash]
27
+ def parse_json(response_body, return_on_parse_error = nil)
28
+ data = String(response_body)
29
+ parser = FFI_Yajl::Parser.new
30
+ parser.parse(data)
31
+ rescue FFI_Yajl::ParseError
32
+ return_on_parse_error
33
+ end
34
+ end
35
+ end
36
+ end
@@ -19,6 +19,7 @@
19
19
  #
20
20
 
21
21
  require "socket" unless defined?(Socket)
22
+ require "resolv" unless defined?(Resolv)
22
23
 
23
24
  module Ohai
24
25
  module Mixin
@@ -37,6 +38,12 @@ module Ohai
37
38
  dec
38
39
  end
39
40
 
41
+ # Addrinfo#ip*? methods return true on AI_CANONNAME Addrinfo records that match
42
+ # the ipv* scheme and #ip? always returns true unless a non tcp Addrinfo
43
+ def ip?(hostname)
44
+ Resolv::IPv4::Regex.match?(hostname) || Resolv::IPv6::Regex.match?(hostname)
45
+ end
46
+
40
47
  # This does a forward and reverse lookup on the hostname to return what should be
41
48
  # the FQDN for the host determined by name lookup (generally DNS). If the forward
42
49
  # lookup fails this will throw. If the reverse lookup fails this will return the
@@ -47,7 +54,27 @@ module Ohai
47
54
  # server), and the method should return the hostname and not the IP address.
48
55
  #
49
56
  def canonicalize_hostname(hostname)
50
- Addrinfo.getaddrinfo(hostname, nil, nil, nil, nil, Socket::AI_CANONNAME).first.canonname
57
+ ai = Addrinfo
58
+ .getaddrinfo(hostname, nil, nil, nil, nil, Socket::AI_CANONNAME)
59
+ .first
60
+
61
+ canonname = ai&.canonname
62
+ # use canonname if it's an FQDN
63
+ # This API is preferred as it never gives us an IP address for broken DNS
64
+ # (see https://github.com/chef/ohai/pull/1705)
65
+ # However, we have found that Windows hosts that are not joined to a domain
66
+ # can return a non-qualified hostname).
67
+ # Use a '.' in the canonname as indicator of FQDN
68
+ return canonname if canonname.include?(".")
69
+
70
+ # If we got a non-qualified name, then we do a standard reverse resolve
71
+ # which, assuming DNS is working, will work around that windows bug
72
+ # (and maybe others)
73
+ canonname = ai&.getnameinfo&.first
74
+ return canonname unless ip?(canonname)
75
+
76
+ # if all else fails, return the name we were given as a safety
77
+ hostname
51
78
  end
52
79
 
53
80
  def canonicalize_hostname_with_retries(hostname)
@@ -18,6 +18,9 @@
18
18
 
19
19
  require "net/http" unless defined?(Net::HTTP)
20
20
 
21
+ require_relative "../mixin/json_helper"
22
+ include Ohai::Mixin::JsonHelper
23
+
21
24
  module Ohai
22
25
  module Mixin
23
26
  module OCIMetadata
@@ -25,6 +28,39 @@ module Ohai
25
28
  OCI_METADATA_URL = "/opc/v2"
26
29
  CHASSIS_ASSET_TAG_FILE = "/sys/devices/virtual/dmi/id/chassis_asset_tag"
27
30
 
31
+ # Get the chassis asset tag from DMI information
32
+ # On Linux: reads from sysfs
33
+ # On Windows: queries WMI Win32_SystemEnclosure
34
+ def chassis_asset_tag
35
+ if RUBY_PLATFORM =~ /mswin|mingw|windows/
36
+ get_chassis_asset_tag_windows
37
+ else
38
+ get_chassis_asset_tag_linux
39
+ end
40
+ end
41
+
42
+ # Read chassis asset tag from Linux sysfs
43
+ def get_chassis_asset_tag_linux
44
+ return unless ::File.exist?(CHASSIS_ASSET_TAG_FILE)
45
+
46
+ ::File.read(CHASSIS_ASSET_TAG_FILE).strip
47
+ rescue => e
48
+ logger.debug("Mixin OciMetadata: Failed to read chassis asset tag from #{CHASSIS_ASSET_TAG_FILE}: #{e}")
49
+ nil
50
+ end
51
+
52
+ # Read chassis asset tag from Windows WMI
53
+ def get_chassis_asset_tag_windows
54
+ require "wmi-lite/wmi" unless defined?(WmiLite::Wmi)
55
+
56
+ wmi = WmiLite::Wmi.new
57
+ enclosure = wmi.first_of("Win32_SystemEnclosure")
58
+ enclosure&.[]("SMBIOSAssetTag")
59
+ rescue => e
60
+ logger.debug("Mixin OciMetadata: Failed to read chassis asset tag from WMI: #{e}")
61
+ nil
62
+ end
63
+
28
64
  # fetch the meta content with a timeout and the required header
29
65
  def http_get(uri)
30
66
  conn = Net::HTTP.start(OCI_METADATA_ADDR)
@@ -38,29 +74,17 @@ module Ohai
38
74
  )
39
75
  end
40
76
 
41
- # parse JSON data from a String to a Hash
42
- #
43
- # @param [String] response_body json as string to parse
44
- #
45
- # @return [Hash]
46
- def parse_json(response_body)
47
- data = String(response_body)
48
- parser = FFI_Yajl::Parser.new
49
- parser.parse(data)
50
- rescue FFI_Yajl::ParseError
51
- logger.warn("Mixin OciMetadata: Metadata response is NOT valid JSON")
52
- nil
53
- end
54
-
55
77
  # Fetch metadata from api
56
78
  def fetch_metadata(metadata = "instance")
57
79
  response = http_get("#{OCI_METADATA_URL}/#{metadata}")
58
- return nil unless response.code == "200"
59
-
60
80
  if response.code == "200"
61
- parse_json(response.body)
81
+ json_data = parse_json(response.body)
82
+ if json_data.nil?
83
+ logger.warn("Mixin OciMetadata: Metadata response is NOT valid JSON")
84
+ end
85
+ json_data
62
86
  else
63
- logger.warn("Mixin OciMetadata: Received response code #{response.code} requesting metadata")
87
+ logger.debug("Mixin OciMetadata: Received response code #{response.code} requesting #{metadata}")
64
88
  nil
65
89
  end
66
90
  end
@@ -25,7 +25,7 @@ class String
25
25
  # ActiveSupport::CoreExtensions::String::Inflections
26
26
  # @return [String]
27
27
  def wmi_underscore
28
- gsub(/::/, "/").gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
28
+ gsub("::", "/").gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
29
29
  .gsub(/([a-z\d])([A-Z])/, '\1_\2').tr("-", "_").downcase
30
30
  end
31
31
  end
@@ -26,11 +26,11 @@ Ohai.plugin(:Kernel) do
26
26
 
27
27
  uname_so = shell_out("uname -rvp").stdout.split
28
28
 
29
- kernel[:name] = "aix" # this is here for historical reasons, but it's always aix
29
+ kernel[:name] = "aix" # this is here for historical reasons, but it's always aix
30
30
  kernel[:release] = uname_so[0]
31
31
  kernel[:version] = uname_so[1]
32
32
  kernel[:machine] = uname_so[2]
33
- kernel[:bits] = shell_out("getconf KERNEL_BITMODE").stdout.strip
33
+ kernel[:bits] = shell_out("getconf KERNEL_BITMODE").stdout.strip
34
34
 
35
35
  modules = Mash.new
36
36
  so = shell_out("genkex -d")
@@ -120,7 +120,7 @@ Ohai.plugin(:Network) do
120
120
  interface = $6
121
121
  ifaces[interface][:routes] ||= []
122
122
  ifaces[interface][:routes] << Mash.new( destination: $1, family: family,
123
- via: $2, flags: $3)
123
+ via: $2, flags: $3)
124
124
  end
125
125
  end
126
126
  end
@@ -143,7 +143,7 @@ Ohai.plugin(:Virtualization) do
143
143
  evalstr = "wpars['#{wpar_name}']"
144
144
  breadcrumb = attribute.split(".")
145
145
  breadcrumb.each do |node|
146
- evalstr << "[\'#{node}\']"
146
+ evalstr << "['#{node}']"
147
147
  end
148
148
  wpars[wpar_name][breadcrumb[-1]] = eval evalstr # rubocop: disable Security/Eval
149
149
  end
@@ -54,7 +54,7 @@ Ohai.plugin(:Alibaba) do
54
54
  # a single check that combines all the various detection methods for Alibaba
55
55
  # @return [Boolean] Does the system appear to be on Alibaba
56
56
  def looks_like_alibaba?
57
- return true if hint?("alibaba") || has_ali_dmi?
57
+ hint?("alibaba") || has_ali_dmi?
58
58
  end
59
59
 
60
60
  collect_data do
@@ -63,7 +63,8 @@ Ohai.plugin(:CPU) do
63
63
  def parse_lscpu(cpu_info)
64
64
  lscpu_info = Mash.new
65
65
  begin
66
- so = shell_out("lscpu")
66
+ # Pipe to cat to retain previous output on newer util-linux (see lscpu(1))
67
+ so = shell_out("lscpu | cat")
67
68
  cpu_cores = shell_out("lscpu -p=CPU,CORE,SOCKET")
68
69
  if so.exitstatus == 0 && cpu_cores.exitstatus == 0
69
70
  lscpu_info[:numa_node_cpus] = Mash.new
@@ -96,10 +97,12 @@ Ohai.plugin(:CPU) do
96
97
  end
97
98
  when /^Thread\(s\) per core:\s+(.+)/ # http://rubular.com/r/lOw2pRrw1q
98
99
  lscpu_info[:threads_per_core] = $1.to_i
99
- when /^Core\(s\) per socket:\s+(.+)/ # http://rubular.com/r/lOw2pRrw1q
100
+ when /^Core\(s\) per (?:socket|cluster):\s+(.+)/ # http://rubular.com/r/lOw2pRrw1q
100
101
  lscpu_info[:cores_per_socket] = $1.to_i
101
102
  when /^Socket\(s\):\s+(.+)/ # http://rubular.com/r/DIzmPtJFvK
102
103
  lscpu_info[:sockets] = $1.to_i
104
+ when /^Clusters\(s\):\s+(.+)/
105
+ lscpu_info[:clusters] = $1.to_i
103
106
  when /^Socket\(s\) per book:\s+(.+)/
104
107
  lscpu_info[:sockets_per_book] = $1.to_i
105
108
  when /^Book\(s\) per drawer:\s+(.+)/
@@ -110,6 +113,10 @@ Ohai.plugin(:CPU) do
110
113
  lscpu_info[:numa_nodes] = $1.to_i
111
114
  when /^Vendor ID:\s+(.+)/
112
115
  lscpu_info[:vendor_id] = $1
116
+ when /^BIOS Vendor ID:\s+(.+)/
117
+ lscpu_info[:bios_vendor_id] = $1
118
+ when /^BIOS Model name:\s+(.+)/
119
+ lscpu_info[:bios_model_name] = $1.strip
113
120
  when /^Machine type:\s+(.+)/
114
121
  lscpu_info[:machine_type] = $1
115
122
  when /^CPU family:\s+(.+)/
@@ -630,6 +637,6 @@ Ohai.plugin(:CPU) do
630
637
 
631
638
  cpu[:total] = logical_processors
632
639
  cpu[:cores] = cores
633
- cpu[:real] = processors.length
640
+ cpu[:real] = processors.length
634
641
  end
635
642
  end
@@ -18,7 +18,7 @@
18
18
  #
19
19
 
20
20
  Ohai.plugin(:Platform) do
21
- provides "platform", "platform_version", "platform_build", "platform_family"
21
+ provides "platform", "platform_version", "platform_version_extra", "platform_build", "platform_family"
22
22
 
23
23
  collect_data(:darwin) do
24
24
  so = shell_out(Ohai.abs_path( "/usr/bin/sw_vers" ).to_s)
@@ -26,6 +26,8 @@ Ohai.plugin(:Platform) do
26
26
  case line
27
27
  when /^ProductVersion:\s+(.+)$/
28
28
  platform_version $1
29
+ when /^ProductVersionExtra:\s+(.+)$/
30
+ platform_version_extra $1
29
31
  when /^BuildVersion:\s+(.+)$/
30
32
  platform_build $1
31
33
  end