class Object
Constants
- ETHERNET_ENCAPS
Public Instance Methods
given the SystemType value from WMI's Win32_ComputerSystem class msdn.microsoft.com/en-us/library/aa394102(v=vs.85).aspx return the architecture type @param [String] sys_type SystemType value from Win32_ComputerSystem @return [String] x86_64 or i386
# File lib/ohai/plugins/kernel.rb, line 84 def arch_lookup(sys_type) return "x86_64" if sys_type == "x64-based PC" return "i386" if sys_type == "X86-based PC" sys_type end
# File lib/ohai/plugins/solaris2/network.rb, line 76 def arpname_to_ifname(iface, arpname) iface.each_key do |ifn| return ifn if ifn.split(":")[0].eql?(arpname) end nil end
Determines the platform version for F5 Big-IP systems
@deprecated
@returns [String] bigip Linux version from /etc/f5-release
# File lib/ohai/plugins/linux/platform.rb, line 109 def bigip_version release_contents = File.read("/etc/f5-release") release_contents.match(/BIG-IP release (\S*)/)[1] # http://rubular.com/r/O8nlrBVqSb rescue NoMethodError, Errno::ENOENT, Errno::EACCES # rescue regex failure, file missing, or permission denied logger.warn("Detected F5 Big-IP, but /etc/f5-release could not be parsed to determine platform_version") nil end
see if a WMI name is blacklisted so we can avoid writing out useless data to ohai @param [String] name the wmi name to check @return [Boolean] is the wmi name blacklisted
# File lib/ohai/plugins/kernel.rb, line 141 def blacklisted_wmi_name?(name) [ "creation_class_name", # this is just the wmi name "cs_creation_class_name", # this is just the wmi name "oem_logo_bitmap", # this is the entire OEM bitmap file "total_swap_space_size", # already in memory plugin "total_virtual_memory_size", # already in memory plugin "total_virtual_memory_size", # already in memory plugin "free_physical_memory", # already in memory plugin "free_space_in_paging_files", # already in memory plugin "free_virtual_memory", # already in memory plugin ].include?(name) end
common *bsd code for collecting modules data @return [Mash]
# File lib/ohai/plugins/kernel.rb, line 43 def bsd_modules(path) modules = Mash.new so = shell_out((Ohai.abs_path(path)).to_s) so.stdout.lines do |line| # 1 7 0xc0400000 97f830 kernel if line =~ /(\d+)\s+(\d+)\s+([0-9a-fx]+)\s+([0-9a-fx]+)\s+([a-zA-Z0-9\_]+)/ modules[$5] = { size: $4, refcount: $2 } end end modules end
# File lib/ohai/plugins/c.rb, line 99 def check_for_cl # ms cl collect("cl /?") do |so| description = so.stderr.lines.first.chomp if description =~ /Compiler Version ([\d\.]+)/ @c[:cl] = Mash.new @c[:cl][:version] = $1 @c[:cl][:description] = description end end end
# File lib/ohai/plugins/c.rb, line 111 def check_for_devenv # ms vs collect("devenv.com /?") do |so| lines = so.stdout.split($/) description = lines[0].length == 0 ? lines[1] : lines[0] if description =~ /Visual Studio Version ([\d\.]+)/ @c[:vs] = Mash.new @c[:vs][:version] = $1.chop @c[:vs][:description] = description end end end
checking the routing tables why ? 1) to set the default gateway and default interfaces attributes 2) on some occasions, the best way to select node is to look at
the routing table source field.
3) and since we're at it, let's populate some :routes attributes (going to do that for both inet and inet6 addresses)
# File lib/ohai/plugins/linux/network.rb, line 75 def check_routing_table(family, iface, default_route_table) so = shell_out("ip -o -f #{family[:name]} route show table #{default_route_table}") so.stdout.lines do |line| line.strip! logger.trace("Plugin Network: Parsing #{line}") if line =~ /\\/ parts = line.split('\\') route_dest = parts.shift.strip route_endings = parts elsif line =~ /^([^\s]+)\s(.*)$/ route_dest = $1 route_endings = [$2] else next end route_endings.each do |route_ending| if route_ending =~ /\bdev\s+([^\s]+)\b/ route_int = $1 else logger.trace("Plugin Network: Skipping route entry without a device: '#{line}'") next end route_int = "venet0:0" if is_openvz? && !is_openvz_host? && route_int == "venet0" && iface["venet0:0"] unless iface[route_int] logger.trace("Plugin Network: Skipping previously unseen interface from 'ip route show': #{route_int}") next end route_entry = Mash.new(destination: route_dest, family: family[:name]) %w{via scope metric proto src}.each do |k| # http://rubular.com/r/pwTNp65VFf route_entry[k] = $1 if route_ending =~ /\b#{k}\s+([^\s]+)/ end # a sanity check, especially for Linux-VServer, OpenVZ and LXC: # don't report the route entry if the src address isn't set on the node # unless the interface has no addresses of this type at all if route_entry[:src] addr = iface[route_int][:addresses] unless addr.nil? || addr.key?(route_entry[:src]) || addr.values.all? { |a| a["family"] != family[:name] } logger.trace("Plugin Network: Skipping route entry whose src does not match the interface IP") next end end iface[route_int][:routes] = Array.new unless iface[route_int][:routes] iface[route_int][:routes] << route_entry end end iface end
returns the default route with the lowest metric (unspecified metric is 0)
# File lib/ohai/plugins/linux/network.rb, line 388 def choose_default_route(routes) routes.select do |r| r[:destination] == "default" end.min do |x, y| (x[:metric].nil? ? 0 : x[:metric].to_i) <=> (y[:metric].nil? ? 0 : y[:metric].to_i) end end
# File lib/ohai/plugins/c.rb, line 23 def collect(cmd, &block) so = shell_out(cmd) if so.exitstatus == 0 yield(so) else logger.trace("Plugin C: '#{cmd}' failed. Skipping data.") end rescue Ohai::Exceptions::Exec logger.trace("Plugin C: '#{cmd}' binary could not be found. Skipping data.") end
# File lib/ohai/plugins/hostname.rb, line 58 def collect_domain # Domain is everything after the first dot if fqdn fqdn =~ /.+?\.(.*)/ domain $1 end end
# File lib/ohai/plugins/c.rb, line 48 def collect_gcc # gcc # Sample output on os x: # Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 # Apple LLVM version 7.3.0 (clang-703.0.29) # Target: x86_64-apple-darwin15.4.0 # Thread model: posix # InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin # # # Sample output on Linux: # Using built-in specs. # COLLECT_GCC=gcc # COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper # Target: x86_64-linux-gnu # Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-trace --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu # Thread model: posix # gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) gcc = Mash.new collect("gcc -v") do |so| so.stderr.each_line do |line| case line when /^(.*version\s(\S*).*)/ gcc[:description] = $1 gcc[:version] = $2 when /^Target:\s(.*)/ gcc[:target] = $1 when /^Configured with:\s(.*)/ gcc[:configured_with] = $1 when /^Thread model:\s(.*)/ gcc[:thread_model] = $1 end end end @c[:gcc] = gcc unless gcc.empty? end
# File lib/ohai/plugins/c.rb, line 85 def collect_glibc # glibc ["/lib/libc.so.6", "/lib64/libc.so.6"].each do |glibc| collect( Ohai.abs_path( glibc )) do |so| description = so.stdout.split($/).first if description =~ /(\d+\.\d+\.?\d*)/ @c[:glibc] = Mash.new @c[:glibc][:version] = $1 @c[:glibc][:description] = description end end end end
# File lib/ohai/plugins/hostname.rb, line 66 def collect_hostname # Hostname is everything before the first dot if machinename machinename =~ /([^.]+)\.?/ hostname $1 elsif fqdn fqdn =~ /(.+?)\./ hostname $1 end end
# File lib/ohai/plugins/packages.rb, line 143 def collect_ips_packages so = shell_out("pkg list -H") # Output format is # NAME (PUBLISHER) VERSION IFO so.stdout.lines.each do |pkg| tokens = pkg.split if tokens.length == 3 # No publisher info name, version, = tokens else name, publisher, version, = tokens publisher = publisher[1..-2] end packages[name] = { "version" => version } packages[name]["publisher"] = publisher if publisher end end
# File lib/ohai/plugins/filesystem.rb, line 555 def collect_old_version(shell_outs) mount_hash = parse_df_or_mount shell_outs[:mount] df_hash = parse_df_or_mount shell_outs[:df_Pk] mount_hash.each do |key, hash| df_hash[key].merge!(hash) if df_hash.key?(key) end mount_hash.merge(df_hash) end
# File lib/ohai/plugins/joyent.rb, line 36 def collect_pkgsrc data = ::File.read("/opt/local/etc/pkg_install.conf") rescue nil if data /PKG_PATH=(.*)/.match(data)[1] rescue nil end end
# File lib/ohai/plugins/joyent.rb, line 27 def collect_product_file data = ::File.read("/etc/product") rescue nil if data data.strip.split("\n") else [] end end
# File lib/ohai/plugins/packages.rb, line 81 def collect_programs_from_registry_key(key_path) # from http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129(v=vs.85).aspx if ::RbConfig::CONFIG["target_cpu"] == "i386" reg_type = Win32::Registry::KEY_READ | 0x100 elsif ::RbConfig::CONFIG["target_cpu"] == "x86_64" reg_type = Win32::Registry::KEY_READ | 0x200 else reg_type = Win32::Registry::KEY_READ end Win32::Registry::HKEY_LOCAL_MACHINE.open(key_path, reg_type) do |reg| reg.each_key do |key, _wtime| pkg = reg.open(key) name = pkg["DisplayName"] rescue nil next if name.nil? package = packages[name] = Mash.new WINDOWS_ATTRIBUTE_ALIASES.each do |registry_attr, package_attr| value = pkg[registry_attr] rescue nil package[package_attr] = value unless value.nil? end end end end
# File lib/ohai/plugins/solaris2/virtualization.rb, line 27 def collect_solaris_guestid command = "/usr/sbin/zoneadm list -p" so = shell_out(command) so.stdout.split(":").first end
# File lib/ohai/plugins/c.rb, line 140 def collect_sunpro # sun pro collect("cc -V -flags") do |so| output = so.stderr.split if so.stderr =~ /^cc: Sun C/ && output.size >= 4 @c[:sunpro] = Mash.new @c[:sunpro][:version] = output[3] @c[:sunpro][:description] = so.stderr.chomp end end end
# File lib/ohai/plugins/packages.rb, line 160 def collect_sysv_packages so = shell_out("pkginfo -l") # Each package info is separated by a blank line chunked_lines = so.stdout.lines.map(&:strip).chunk do |line| !line.empty? || nil end chunked_lines.each do |_, lines| # rubocop: disable Performance/HashEachMethods package = {} lines.each do |line| key, value = line.split(":", 2) package[key.strip.downcase] = value.strip unless value.nil? end # pkginst is the installed package name packages[package["pkginst"]] = package.tap do |p| p.delete("pkginst") end end end
# File lib/ohai/plugins/uptime.rb, line 32 def collect_uptime(path) # kern.boottime: { sec = 1232765114, usec = 823118 } Fri Jan 23 18:45:14 2009 so = shell_out("#{Ohai.abs_path(path)} kern.boottime") so.stdout.lines do |line| if line =~ /kern.boottime:\D+(\d+)/ usec = Time.new.to_i - $1.to_i return [usec, seconds_to_human(usec)] end end [nil, nil] end
# File lib/ohai/plugins/c.rb, line 124 def collect_xlc # ibm xlc so = shell_out("xlc -qversion") if so.exitstatus == 0 || (so.exitstatus >> 8) == 249 description = so.stdout.split($/).first if description =~ /V(\d+\.\d+)/ @c[:xlc] = Mash.new @c[:xlc][:version] = $1 @c[:xlc][:description] = description.strip end end rescue Ohai::Exceptions::Exec logger.trace("Plugin C: 'xlc' binary could not be found. Skipping data.") end
# File lib/ohai/plugins/linux/mdadm.rb, line 24 def create_raid_device_mash(stdout) device_mash = Mash.new device_mash[:device_counts] = Mash.new stdout.lines.each do |line| case line when /Version\s+: ([0-9.]+)/ device_mash[:version] = Regexp.last_match[1].to_f when /Raid Level\s+: raid([0-9]+)/ device_mash[:level] = Regexp.last_match[1].to_i when /Array Size.*\(([0-9.]+)/ device_mash[:size] = Regexp.last_match[1].to_f when /State\s+: ([a-z]+)/ device_mash[:state] = Regexp.last_match[1] when /Total Devices\s+: ([0-9]+)/ device_mash[:device_counts][:total] = Regexp.last_match[1].to_i when /Raid Devices\s+: ([0-9]+)/ device_mash[:device_counts][:raid] = Regexp.last_match[1].to_i when /Working Devices\s+: ([0-9]+)/ device_mash[:device_counts][:working] = Regexp.last_match[1].to_i when /Failed Devices\s+: ([0-9]+)/ device_mash[:device_counts][:failed] = Regexp.last_match[1].to_i when /Active Devices\s+: ([0-9]+)/ device_mash[:device_counts][:active] = Regexp.last_match[1].to_i when /Spare Devices\s+: ([0-9]+)/ device_mash[:device_counts][:spare] = Regexp.last_match[1].to_i end end device_mash end
Common sources go here. Put sources that need to be different per-platform under their collect_data block.
# File lib/ohai/plugins/shard.rb, line 63 def create_seed(&block) sources = Ohai.config[:plugin][:shard_seed][:sources] || default_sources data = "" sources.each do |src| data << case src when :fqdn fqdn when :hostname hostname when :machine_id machine_id when :machinename machinename else yield(src) end end shard_seed digest_algorithm.hexdigest(data)[0...7].to_i(16) end
# File lib/ohai/plugins/darwin/network.rb, line 53 def darwin_encaps_lookup(ifname) return "Loopback" if ifname.eql?("lo") return "1394" if ifname.eql?("fw") return "IPIP" if ifname.eql?("gif") return "6to4" if ifname.eql?("stf") return "dot1q" if ifname.eql?("vlan") "Unknown" end
# File lib/ohai/plugins/shard.rb, line 40 def default_digest_algorithm if fips && fips["kernel"]["enabled"] # Even though it is being used safely, FIPS-mode will still blow up on # any use of MD5 so default to SHA2 instead. "sha256" else "md5" end end
# File lib/ohai/plugins/shard.rb, line 31 def default_sources case collect_os when "linux", "darwin", "windows" [:machinename, :serial, :uuid] else [:machinename] end end
Grab the version from the VERSION_ID field and use the kernel release if that's not available. It should be there for everything, but rolling releases like arch / gentoo where we've traditionally used the kernel as the version @return String
the OS version
# File lib/ohai/plugins/linux/platform.rb, line 292 def determine_os_version # centos only includes the major version in os-release for some reason if os_release_info["ID"] == "centos" get_redhatish_version(File.read("/etc/redhat-release").chomp) else os_release_info["VERSION_ID"] || shell_out("/bin/uname -r").stdout.strip end end
# File lib/ohai/plugins/shard.rb, line 50 def digest_algorithm case Ohai.config[:plugin][:shard_seed][:digest_algorithm] || default_digest_algorithm when "md5" require "digest/md5" Digest::MD5 when "sha256" require "openssl/digest" OpenSSL::Digest::SHA256 end end
# File lib/ohai/plugins/darwin/virtualization.rb, line 41 def docker_exists? which("docker") end
# File lib/ohai/plugins/docker.rb, line 24 def docker_info_json so = shell_out("docker info --format '{{json .}}'") if so.exitstatus == 0 return JSON.parse(so.stdout) end rescue Ohai::Exceptions::Exec logger.trace('Plugin Docker: Could not shell_out "docker info --format \'{{json .}}\'". Skipping plugin') end
# File lib/ohai/plugins/docker.rb, line 33 def docker_ohai_data(shellout_data) docker Mash.new docker[:version_string] = shellout_data["ServerVersion"] docker[:version] = shellout_data["ServerVersion"].split("-")[0] if shellout_data["ServerVersion"] # guard this so missing data doesn't fail the run docker[:runtimes] = shellout_data["Runtimes"] docker[:root_dir] = shellout_data["DockerRootDir"] docker[:containers] = {} docker[:containers][:total] = shellout_data["Containers"] docker[:containers][:running] = shellout_data["ContainersRunning"] docker[:containers][:paused] = shellout_data["ContainersPaused"] docker[:containers][:stopped] = shellout_data["ContainersStopped"] docker[:plugins] = shellout_data["Plugins"] docker[:networking] = {} docker[:networking][:ipv4_forwarding] = shellout_data["IPv4Forwarding"] docker[:networking][:bridge_nf_iptables] = shellout_data["BridgeNfIptables"] docker[:networking][:bridge_nf_ipv6_iptables] = shellout_data["BridgeNfIp6tables"] docker[:swarm] = shellout_data["Swarm"] end
# File lib/ohai/plugins/libvirt.rb, line 28 def emu @emu ||= (virtualization[:system].eql?("kvm") ? "qemu" : virtualization[:system]) end
Returns a Mash
loaded with encryption details
Uses Win32_EncryptableVolume and encryption_properties
to return encryption details of volumes.
Returns an empty Mash
in case of any WMI exception.
@note We are fetching Encryption Status only as of now
@see msdn.microsoft.com/en-us/library/windows/desktop/aa376483(v=vs.85).aspx
@return [Mash]
# File lib/ohai/plugins/windows/filesystem.rb, line 62 def encryptable_info wmi = WmiLite::Wmi.new("Root\\CIMV2\\Security\\MicrosoftVolumeEncryption") disks = wmi.instances_of("Win32_EncryptableVolume") encryption_properties(disks) rescue WmiLite::WmiException Ohai::Log.debug("Unable to access Win32_EncryptableVolume. Skipping encryptable details") Mash.new end
Refines and calculates encryption properties out of given instances
@param [WmiLite::Wmi::Instance] disks
@return [Mash] Each drive containing following properties:
* :encryption_status (String)
# File lib/ohai/plugins/windows/filesystem.rb, line 110 def encryption_properties(disks) properties = Mash.new disks.each do |disk| drive = disk["driveletter"] property = Mash.new property[:encryption_status] = disk["conversionstatus"] ? CONVERSION_STATUS[disk["conversionstatus"]] : "" properties[drive] = property end properties end
determine layer 1 details for the interface using ethtool
# File lib/ohai/plugins/linux/network.rb, line 150 def ethernet_layer_one(iface) return iface unless ethtool_binary_path keys = %w{ Speed Duplex Port Transceiver Auto-negotiation MDI-X } iface.each_key do |tmp_int| next unless iface[tmp_int][:encapsulation] == "Ethernet" so = shell_out("#{ethtool_binary_path} #{tmp_int}") so.stdout.lines do |line| line.chomp! logger.trace("Plugin Network: Parsing ethtool output: #{line}") line.lstrip! k, v = line.split(": ") next unless keys.include? k k.downcase!.tr!("-", "_") if k == "speed" k = "link_speed" # This is not necessarily the maximum speed the NIC supports v = v[/\d+/].to_i end iface[tmp_int][k] = v end end iface end
determine ring parameters for the interface using ethtool
# File lib/ohai/plugins/linux/network.rb, line 174 def ethernet_ring_parameters(iface) return iface unless ethtool_binary_path iface.each_key do |tmp_int| next unless iface[tmp_int][:encapsulation] == "Ethernet" so = shell_out("#{ethtool_binary_path} -g #{tmp_int}") logger.trace("Plugin Network: Parsing ethtool output: #{so.stdout}") type = nil iface[tmp_int]["ring_params"] = {} so.stdout.lines.each do |line| next if line.start_with?("Ring parameters for") next if line.strip.nil? if line =~ /Pre-set maximums/ type = "max" next end if line =~ /Current hardware settings/ type = "current" next end key, val = line.split(/:\s+/) if type && val ring_key = "#{type}_#{key.downcase.tr(' ', '_')}" iface[tmp_int]["ring_params"][ring_key] = val.to_i end end end iface end
# File lib/ohai/plugins/linux/network.rb, line 40 def ethtool_binary_path @ethtool ||= which("ethtool") end
# File lib/ohai/plugins/darwin/network.rb, line 69 def excluded_setting?(setting) setting.match("_sw_cksum") end
# File lib/ohai/plugins/ssh_host_key.rb, line 23 def extract_keytype?(content) case content[0] when "ssh-dss" [ "dsa", nil ] when "ssh-rsa" [ "rsa", nil ] when /^ecdsa/ [ "ecdsa", content[0] ] when "ssh-ed25519" [ "ed25519", nil ] else [ nil, nil ] end end
# File lib/ohai/plugins/linux/network.rb, line 52 def extract_neighbors(family, iface, neigh_attr) so = shell_out("ip -f #{family[:name]} neigh show") so.stdout.lines do |line| if line =~ /^([a-f0-9\:\.]+)\s+dev\s+([^\s]+)\s+lladdr\s+([a-fA-F0-9\:]+)/ interface = iface[$2] unless interface logger.warn("neighbor list has entries for unknown interface #{interface}") next end interface[neigh_attr] ||= Mash.new interface[neigh_attr][$1] = $3.downcase end end iface end
ipv4/ipv6 routes are different enough that having a single algorithm to select the favored route for both creates unnecessary complexity this method attempts to deduce the route that is most important to the user, which is later used to deduce the favored values for {ip,mac,ip6}address we only consider routes that are default routes, or those routes that get us to the gateway for a default route
# File lib/ohai/plugins/linux/network.rb, line 427 def favored_default_route_linux(routes, iface, default_route, family) routes.select do |r| if family[:name] == "inet" # the route must have a source address next if r[:src].nil? || r[:src].empty? # the interface specified in the route must exist route_interface = iface[r[:dev]] next if route_interface.nil? # the interface specified in the route must exist # the interface must have no addresses, or if it has the source address, the address must not # be a link-level address next unless interface_valid_for_route?(route_interface, r[:src], "inet") # the route must either be a default route, or it must have a gateway which is accessible via the route next unless route_is_valid_default_route?(r, default_route) true elsif family[:name] == "inet6" iface[r[:dev]] && iface[r[:dev]][:state] == "up" && route_is_valid_default_route?(r, default_route) end end.min_by do |r| # sorting the selected routes: # - getting default routes first # - then sort by metric # - then by prefixlen [ r[:destination] == "default" ? 0 : 1, r[:metric].nil? ? 0 : r[:metric].to_i, # for some reason IPAddress doesn't accept "::/0", it doesn't like prefix==0 # just a quick workaround: use 0 if IPAddress fails begin IPAddress( r[:destination] == "default" ? family[:default_route] : r[:destination] ).prefix rescue 0 end, ] end end
Selects default interface and returns its information
@note Interface with least metric value should be prefered as default_route
@param configuration [Mash] Configuration of interfaces as iface_config
[<interface_index> => {<interface_configurations>}]
@return [Hash<:index, :interface_index, :default_ip_gateway, :ip_connection_metric>]
# File lib/ohai/plugins/windows/network.rb, line 100 def favored_default_route_windows(configuration) return nil unless configuration.is_a?(Hash) config = configuration.dup config.inject([]) do |arr, (k, v)| if v["default_ip_gateway"] arr << { index: v["index"], interface_index: v["interface_index"], default_ip_gateway: prefer_ipv4(v["default_ip_gateway"]), ip_connection_metric: v["ip_connection_metric"] } end arr end.min_by { |r| r[:ip_connection_metric] } end
# File lib/ohai/plugins/azure.rb, line 86 def fetch_ip_data(data, type, field) ips = [] data[type]["ipAddress"].each do |val| ips << val[field] unless val[field].empty? end ips end
return the contents of a file if the file exists @param path abs path to the file @return [String] contents of the file if it exists
# File lib/ohai/plugins/ec2.rb, line 100 def file_val_if_exists(path) if ::File.exist?(path) ::File.read(path) end end
# File lib/ohai/plugins/filesystem.rb, line 29 def find_device(name) %w{/dev /dev/mapper}.each do |dir| path = File.join(dir, name) return path if File.exist?(path) end name end
finds ip address / interface for interface with default route based on passed in family. returns [ipaddress, interface] uses 1st ip if no default route is found
# File lib/ohai/plugins/network.rb, line 63 def find_ip(family = "inet") ips = sorted_ips(family) # return if there aren't any #{family} addresses! return [ nil, nil ] if ips.empty? # shortcuts to access default #{family} interface and gateway int_attr = Ohai::Mixin::NetworkConstants::FAMILIES[family] + "_interface" gw_attr = Ohai::Mixin::NetworkConstants::FAMILIES[family] + "_gateway" if network[int_attr] # working with the address(es) of the default network interface gw_if_ips = ips.select do |v| v[:iface] == network[int_attr] end if gw_if_ips.empty? logger.warn("Plugin Network: [#{family}] no ip address on #{network[int_attr]}") elsif network[gw_attr] && network["interfaces"][network[int_attr]] && network["interfaces"][network[int_attr]]["addresses"] if [ "0.0.0.0", "::", /^fe80:/ ].any? { |pat| pat === network[gw_attr] } # link level default route logger.trace("Plugin Network: link level default #{family} route, picking ip from #{network[gw_attr]}") r = gw_if_ips.first else # checking network masks r = gw_if_ips.select do |v| network_contains_address(network[gw_attr], v[:ipaddress], v[:iface]) end.first if r.nil? r = gw_if_ips.first logger.trace("Plugin Network: [#{family}] no ipaddress/mask on #{network[int_attr]} matching the gateway #{network[gw_attr]}, picking #{r[:ipaddress]}") else logger.trace("Plugin Network: [#{family}] Using default interface #{network[int_attr]} and default gateway #{network[gw_attr]} to set the default ip to #{r[:ipaddress]}") end end else # return the first ip address on network[int_attr] r = gw_if_ips.first end else r = ips.first logger.trace("Plugin Network: [#{family}] no default interface, picking the first ipaddress") end return [ nil, nil ] if r.nil? || r.empty? [ r[:ipaddress].to_s, r[:iface] ] end
select mac address of first interface with family of lladdr
# File lib/ohai/plugins/network.rb, line 114 def find_mac_from_iface(iface) r = network["interfaces"][iface]["addresses"].select { |k, v| v["family"] == "lladdr" } r.nil? || r.first.nil? ? nil : r.first.first end
# File lib/ohai/plugins/passwd.rb, line 7 def fix_encoding(str) str.force_encoding(Encoding.default_external) if str.respond_to?(:force_encoding) str end
hostname : short hostname machinename : output of hostname command (might be short on solaris) fqdn : result of canonicalizing hostname using DNS or /etc/hosts domain : domain part of FQDN
hostname and machinename should always exist fqdn and domain may be broken if DNS is broken on the host
# File lib/ohai/plugins/hostname.rb, line 42 def from_cmd(cmd) so = shell_out(cmd) so.stdout.split($/)[0] end
# File lib/ohai/plugins/solaris2/network.rb, line 84 def full_interface_name(iface, part_name, index) iface.each do |name, attrs| next unless attrs && attrs.respond_to?(:[]) return name if /^#{part_name}($|:)/.match(name) && attrs[:index] == index end nil end
# File lib/ohai/plugins/darwin/virtualization.rb, line 37 def fusion_exists? ::File.exist?("/Applications/VMware\ Fusion.app/") end
# File lib/ohai/plugins/zpools.rb, line 29 def gather_pool_info pools = Mash.new begin # Grab ZFS zpools overall health and attributes so = shell_out("zpool list -H -o name,size,alloc,free,cap,dedup,health,version") so.stdout.lines do |line| case line when /^([-_0-9A-Za-z]*)\s+([.0-9]+[MGTPE])\s+([.0-9]+[MGTPE])\s+([.0-9]+[MGTPE])\s+(\d+%)\s+([.0-9]+x)\s+([-_0-9A-Za-z]+)\s+(\d+|-)$/ Ohai::Log.debug("Plugin Zpools: Parsing zpool list line: #{line.chomp}") pools[$1] = Mash.new pools[$1][:pool_size] = sanitize_value($2) pools[$1][:pool_allocated] = sanitize_value($3) pools[$1][:pool_free] = sanitize_value($4) pools[$1][:capacity_used] = sanitize_value($5) pools[$1][:dedup_factor] = sanitize_value($6) pools[$1][:health] = sanitize_value($7) pools[$1][:zpool_version] = sanitize_value($8) end end rescue Ohai::Exceptions::Exec Ohai::Log.debug('Plugin Zpools: Could not shell_out "zpool list -H -o name,size,alloc,free,cap,dedup,health,version". Skipping plugin.') end pools end
# File lib/ohai/plugins/filesystem.rb, line 107 def generate_deprecated_solaris_view(fs, old_zfs) view = generate_deprecated_view(fs) old_zfs.each do |fsname, attributes| view[fsname] ||= Mash.new view[fsname][:fs_type] = "zfs" view[fsname][:mount] = attributes[:values][:mountpoint] if attributes[:values].key?("mountpoint") view[fsname][:device] = fsname view[fsname][:zfs_values] = attributes[:values] view[fsname][:zfs_sources] = attributes[:sources] # parents will already be here # but we want to nuke "zfs_properties" view[fsname].delete("zfs_properties") end view end
# File lib/ohai/plugins/filesystem.rb, line 98 def generate_deprecated_view(fs) view = generate_device_view(fs) view.each do |device, entry| view[device][:mount] = entry[:mounts].first view[device].delete(:mounts) end view end
# File lib/ohai/plugins/filesystem.rb, line 65 def generate_device_view(fs) view = {} fs.each_value do |entry| view[entry[:device]] ||= Mash.new entry.each do |key, val| next if %w{device mount}.include?(key) view[entry[:device]][key] = val end view[entry[:device]][:mounts] ||= [] if entry[:mount] view[entry[:device]][:mounts] << entry[:mount] end end view end
# File lib/ohai/plugins/filesystem.rb, line 81 def generate_mountpoint_view(fs) view = {} fs.each_value do |entry| next unless entry[:mount] view[entry[:mount]] ||= Mash.new entry.each do |key, val| next if %w{mount device}.include?(key) view[entry[:mount]][key] = val end view[entry[:mount]][:devices] ||= [] if entry[:device] view[entry[:mount]][:devices] << entry[:device] end end view end
Fill cloud hash with azure values
# File lib/ohai/plugins/cloud.rb, line 267 def get_azure_values azure["metadata"]["network"]["public_ipv4"].each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :public) } azure["metadata"]["network"]["public_ipv6"].each { |ipaddr| @cloud_attr_obj.add_ipv6_addr(ipaddr, :public) } azure["metadata"]["network"]["local_ipv4"].each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :private) } azure["metadata"]["network"]["local_ipv6"].each { |ipaddr| @cloud_attr_obj.add_ipv6_addr(ipaddr, :private) } @cloud_attr_obj.public_hostname = azure["public_fqdn"] @cloud_attr_obj.provider = "azure" end
Fill cloud hash with digital_ocean values
# File lib/ohai/plugins/cloud.rb, line 290 def get_digital_ocean_values @cloud_attr_obj.add_ipv4_addr(digital_ocean["interfaces"]["public"][0]["ipv4"]["ip_address"], :public) rescue NoMethodError @cloud_attr_obj.add_ipv4_addr(digital_ocean["interfaces"]["private"][0]["ipv4"]["ip_address"], :private) rescue NoMethodError @cloud_attr_obj.add_ipv6_addr(digital_ocean["interfaces"]["public"][0]["ipv6"]["ip_address"], :public) rescue NoMethodError @cloud_attr_obj.add_ipv6_addr(digital_ocean["interfaces"]["private"][0]["ipv6"]["ip_address"], :private) rescue NoMethodError @cloud_attr_obj.provider = "digital_ocean" end
# File lib/ohai/plugins/shard.rb, line 23 def get_dmi_property(dmi, thing) %w{system base_board chassis}.each do |section| unless dmi[section][thing].strip.empty? return dmi[section][thing] end end end
# File lib/ohai/plugins/libvirt.rb, line 50 def get_domain_data domain_data = Mash.new virtconn.list_domains.each do |d| dv = virtconn.lookup_domain_by_id d domain_data[dv.name] = Mash.new domain_data[dv.name][:id] = d %w{os_type uuid}.each { |a| domain_data[dv.name][a] = dv.send(a) } %w{cpu_time max_mem memory nr_virt_cpu state}.each { |a| domain_data[dv.name][a] = dv.info.send(a) } end domain_data end
Fill cloud hash with ec2 values
# File lib/ohai/plugins/cloud.rb, line 156 def get_ec2_values @cloud_attr_obj.add_ipv4_addr(ec2["public_ipv4"], :public) @cloud_attr_obj.add_ipv4_addr(ec2["local_ipv4"], :private) @cloud_attr_obj.public_hostname = ec2["public_hostname"] @cloud_attr_obj.local_hostname = ec2["local_hostname"] @cloud_attr_obj.provider = "ec2" end
# File lib/ohai/plugins/cloud.rb, line 223 def get_eucalyptus_values @cloud_attr_obj.add_ipv4_addr(eucalyptus["public_ipv4"], :public) @cloud_attr_obj.add_ipv4_addr(eucalyptus["local_ipv4"], :private) @cloud_attr_obj.public_hostname = eucalyptus["public_hostname"] @cloud_attr_obj.local_hostname = eucalyptus["local_hostname"] @cloud_attr_obj.provider = "eucalyptus" end
# File lib/ohai/plugins/cloud.rb, line 125 def get_gce_values public_ips = gce["instance"]["networkInterfaces"].collect do |interface| if interface.key?("accessConfigs") interface["accessConfigs"].collect { |ac| ac["externalIp"] unless ac["externalIp"] == "" } end end.flatten.compact private_ips = gce["instance"]["networkInterfaces"].collect do |interface| interface["ip"] end.compact public_ips.each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :public) } private_ips.each { |ipaddr| @cloud_attr_obj.add_ipv4_addr(ipaddr, :private) } @cloud_attr_obj.local_hostname = gce["instance"]["hostname"] @cloud_attr_obj.provider = "gce" end
Names rackspace ipv6 address for interface
Parameters¶ ↑
- name<Symbol>
-
Use :public_ip or :private_ip
- eth<Symbol>
-
Interface name of public or private ip
# File lib/ohai/plugins/rackspace.rb, line 88 def get_global_ipv6_address(name, eth) network[:interfaces][eth][:addresses].each do |key, info| # check if we got an ipv6 address and if its in global scope if info["family"] == "inet6" && info["scope"] == "Global" rackspace[name] = key break # break when we found an address end end end
Get the rackspace instance_id
# File lib/ohai/plugins/rackspace.rb, line 114 def get_instance_id so = shell_out("xenstore-read name") if so.exitstatus == 0 rackspace[:instance_id] = so.stdout.gsub(/instance-/, "") end rescue Ohai::Exceptions::Exec logger.trace("Plugin Rackspace: Unable to find xenstore-read, cannot capture instance ID information for Rackspace cloud") nil end
Names linode ip address
name - symbol of ohai name (e.g. :public_ip) eth - Interface name (e.g. :eth0)
Alters linode mash with new interface based on name parameter
# File lib/ohai/plugins/linode.rb, line 45 def get_ip_address(name, eth) if ( eth_iface = network[:interfaces][eth] ) eth_iface[:addresses].each do |key, info| linode[name] = key if info["family"] == "inet" end end end
# File lib/ohai/plugins/java.rb, line 23 def get_java_info so = shell_out("java -mx64m -version") # Sample output: # java version "1.8.0_60" # Java(TM) SE Runtime Environment (build 1.8.0_60-b27) # Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode) if so.exitstatus == 0 java = Mash.new so.stderr.split(/\r?\n/).each do |line| case line when /(?:java|openjdk) version \"([0-9\.\_]+)\"/ java[:version] = $1 when /^(.+Runtime Environment.*) \((build)\s*(.+)\)$/ java[:runtime] = { "name" => $1, "build" => $3 } when /^(.+ (Client|Server) VM) \(build\s*(.+)\)$/ java[:hotspot] = { "name" => $1, "build" => $3 } end end languages[:java] = java unless java.empty? end rescue Ohai::Exceptions::Exec logger.trace('Plugin Java: Could not shell_out "java -mx64m -version". Skipping plugin') end
Fill cloud hash with linode values
# File lib/ohai/plugins/cloud.rb, line 202 def get_linode_values @cloud_attr_obj.add_ipv4_addr(linode["public_ip"], :public) @cloud_attr_obj.add_ipv4_addr(linode["private_ip"], :private) @cloud_attr_obj.public_hostname = linode["public_hostname"] @cloud_attr_obj.local_hostname = linode["local_hostname"] @cloud_attr_obj.provider = "linode" end
returns the mac address from the collection of all address types
# File lib/ohai/plugins/eucalyptus.rb, line 32 def get_mac_address(addresses) detected_addresses = addresses.detect { |address, keypair| keypair == { "family" => "lladdr" } } if detected_addresses return detected_addresses.first else return "" end end
returns the macaddress for interface from a hash of interfaces (iface elsewhere in this file)
# File lib/ohai/plugins/linux/network.rb, line 383 def get_mac_for_interface(interfaces, interface) interfaces[interface][:addresses].select { |k, v| v["family"] == "lladdr" }.first.first unless interfaces[interface][:addresses].nil? || interfaces[interface][:flags].include?("NOARP") end
# File lib/ohai/plugins/libvirt.rb, line 62 def get_network_data network_data = Mash.new virtconn.list_networks.each do |n| nv = virtconn.lookup_network_by_name n network_data[n] = Mash.new %w{bridge_name uuid}.each { |a| network_data[n][a] = nv.send(a) } end network_data end
# File lib/ohai/plugins/libvirt.rb, line 43 def get_node_data node_data = Mash.new ni = virtconn.node_get_info %w{cores cpus memory mhz model nodes sockets threads}.each { |a| node_data[a] = ni.send(a) } node_data end
Fill cloud hash with openstack values
# File lib/ohai/plugins/cloud.rb, line 245 def get_openstack_values @cloud_attr_obj.add_ipv4_addr(openstack["public_ipv4"], :public) @cloud_attr_obj.add_ipv4_addr(openstack["local_ipv4"], :private) @cloud_attr_obj.public_hostname = openstack["public_hostname"] @cloud_attr_obj.local_hostname = openstack["local_hostname"] @cloud_attr_obj.provider = openstack["provider"] end
Get the rackspace private networks
# File lib/ohai/plugins/rackspace.rb, line 126 def get_private_networks so = shell_out("xenstore-ls vm-data/networking") if so.exitstatus == 0 networks = [] so.stdout.split("\n").map { |l| l.split("=").first.strip }.map do |item| so = shell_out("xenstore-read vm-data/networking/#{item}") if so.exitstatus == 0 networks.push(FFI_Yajl::Parser.new.parse(so.stdout)) else logger.trace("Plugin Rackspace: Unable to capture custom private networking information for Rackspace cloud") return false end end # these networks are already known to ohai, and are not 'private networks' networks.delete_if { |hash| hash["label"] == "private" } networks.delete_if { |hash| hash["label"] == "public" } end rescue Ohai::Exceptions::Exec logger.trace("Plugin Rackspace: Unable to capture custom private networking information for Rackspace cloud") nil end
Fill cloud hash with rackspace values
# File lib/ohai/plugins/cloud.rb, line 178 def get_rackspace_values @cloud_attr_obj.add_ipv4_addr(rackspace["public_ipv4"], :public) @cloud_attr_obj.add_ipv4_addr(rackspace["local_ipv4"], :private) @cloud_attr_obj.add_ipv6_addr(rackspace["public_ipv6"], :public) @cloud_attr_obj.add_ipv6_addr(rackspace["local_ipv6"], :private) @cloud_attr_obj.public_hostname = rackspace["public_hostname"] @cloud_attr_obj.local_hostname = rackspace["local_hostname"] @cloud_attr_obj.provider = "rackspace" end
@deprecated
# File lib/ohai/plugins/linux/platform.rb, line 38 def get_redhatish_platform(contents) contents[/^Red Hat/i] ? "redhat" : contents[/(\w+)/i, 1].downcase end
Amazon Linux AMI release 2013.09 Amazon Linux 2 Amazon Linux 2 (Karoo) Fedora release 28 (Twenty Eight) CentOS release 5.8 (Final) CentOS release 6.7 (Final) Red Hat Enterprise Linux Server release 7.5 (Maipo)
@param contents [String] the contents of /etc/redhat-release
@returns [String] the version string
# File lib/ohai/plugins/linux/platform.rb, line 54 def get_redhatish_version(contents) contents[/Rawhide/i] ? contents[/((\d+) \(Rawhide\))/i, 1].downcase : contents[/(release)? ([\d\.]+)/, 2] end
Get the rackspace region
# File lib/ohai/plugins/rackspace.rb, line 100 def get_region so = shell_out("xenstore-ls vm-data/provider_data") if so.exitstatus == 0 so.stdout.split("\n").each do |line| rackspace[:region] = line.split[2].delete('\"') if line =~ /^region/ end end rescue Ohai::Exceptions::Exec logger.trace("Plugin Rackspace: Unable to find xenstore-ls, cannot capture region information for Rackspace cloud") nil end
Fill cloud hash with softlayer values
# File lib/ohai/plugins/cloud.rb, line 312 def get_softlayer_values @cloud_attr_obj.add_ipv4_addr(softlayer["public_ipv4"], :public) @cloud_attr_obj.add_ipv4_addr(softlayer["local_ipv4"], :private) @cloud_attr_obj.public_hostname = softlayer["public_fqdn"] @cloud_attr_obj.provider = "softlayer" end
# File lib/ohai/plugins/libvirt.rb, line 72 def get_storage_data storage_data = Mash.new virtconn.list_storage_pools.each do |pool| sp = virtconn.lookup_storage_pool_by_name pool storage_data[pool] = Mash.new %w{autostart uuid}.each { |a| storage_data[pool][a] = sp.send(a) } %w{allocation available capacity state}.each { |a| storage_data[pool][a] = sp.info.send(a) } storage_data[pool][:volumes] = Mash.new sp.list_volumes.each do |v| storage_data[pool][:volumes][v] = Mash.new sv = sp.lookup_volume_by_name v %w{key name path}.each { |a| storage_data[pool][:volumes][v][a] = sv.send(a) } %w{allocation capacity type}.each { |a| storage_data[pool][:volumes][v][a] = sv.info.send(a) } end end storage_data end
# File lib/ohai/plugins/vmware.rb, line 43 def get_vm_attributes(vmtools_path) if !File.exist?(vmtools_path) logger.trace("Plugin VMware: #{vmtools_path} not found") else vmware Mash.new begin # vmware-toolbox-cmd stat <param> commands # Iterate through each parameter supported by the "vwware-toolbox-cmd stat" command, assign value # to attribute "vmware[:<parameter>]" %w{hosttime speed sessionid balloon swap memlimit memres cpures cpulimit}.each do |param| vmware[param] = from_cmd("#{vmtools_path} stat #{param}") if vmware[param] =~ /UpdateInfo failed/ vmware[param] = nil end end # vmware-toolbox-cmd <param> status commands # Iterate through each parameter supported by the "vwware-toolbox-cmd status" command, assign value # to attribute "vmware[:<parameter>]" %w{upgrade timesync}.each do |param| vmware[param] = from_cmd("#{vmtools_path} #{param} status") end rescue logger.trace("Plugin VMware: Error while collecting VMware guest attributes") end end end
# File lib/ohai/plugins/azure.rb, line 56 def has_dhcp_option_245? has_245 = false if File.exist?("/var/lib/dhcp/dhclient.eth0.leases") File.open("/var/lib/dhcp/dhclient.eth0.leases").each do |line| if line =~ /unknown-245/ logger.trace("Plugin Azure: Found unknown-245 DHCP option used by Azure.") has_245 = true break end end end has_245 end
look for digitalocean string in dmi bios data
# File lib/ohai/plugins/digital_ocean.rb, line 30 def has_do_dmi? begin # detect a vendor of "DigitalOcean" if dmi[:bios][:all_records][0][:Vendor] == "DigitalOcean" logger.trace("Plugin DigitalOcean: has_do_dmi? == true") return true end rescue NoMethodError # dmi[:bios][:all_records][0][:Vendor] may not exist end logger.trace("Plugin DigitalOcean: has_do_dmi? == false") false end
look for amazon string in dmi vendor bios data within the sys tree. this works even if the system lacks dmidecode use by the Dmi plugin this gets us detection of new Xen-less HVM instances that are within a VPC @return [Boolean] do we have Amazon DMI data?
# File lib/ohai/plugins/ec2.rb, line 42 def has_ec2_amazon_dmi? # detect a version of '4.2.amazon' if file_val_if_exists("/sys/class/dmi/id/bios_vendor") =~ /Amazon/ logger.trace("Plugin EC2: has_ec2_amazon_dmi? == true") true else logger.trace("Plugin EC2: has_ec2_amazon_dmi? == false") false end end
looks at the identifying number WMI value to see if it starts with ec2. this is actually the same value we're looking at in has_ec2_xen_uuid? on linux hosts @return [Boolean] do we have a Xen Identifying Number or not?
# File lib/ohai/plugins/ec2.rb, line 83 def has_ec2_identifying_number? if RUBY_PLATFORM =~ /mswin|mingw32|windows/ require "wmi-lite/wmi" wmi = WmiLite::Wmi.new if wmi.first_of("Win32_ComputerSystemProduct")["identifyingnumber"] =~ /^ec2/ logger.trace("Plugin EC2: has_ec2_identifying_number? == true") return true end else logger.trace("Plugin EC2: has_ec2_identifying_number? == false") false end end
look for amazon string in dmi bios version data within the sys tree. this works even if the system lacks dmidecode use by the Dmi plugin this gets us detection of HVM instances that are within a VPC @return [Boolean] do we have Amazon DMI data?
# File lib/ohai/plugins/ec2.rb, line 57 def has_ec2_xen_dmi? # detect a version of '4.2.amazon' if file_val_if_exists("/sys/class/dmi/id/bios_version") =~ /amazon/ logger.trace("Plugin EC2: has_ec2_xen_dmi? == true") true else logger.trace("Plugin EC2: has_ec2_xen_dmi? == false") false end end
looks for a xen UUID that starts with ec2 from within the Linux sys tree @return [Boolean] do we have a Xen UUID or not?
# File lib/ohai/plugins/ec2.rb, line 70 def has_ec2_xen_uuid? if file_val_if_exists("/sys/hypervisor/uuid") =~ /^ec2/ logger.trace("Plugin EC2: has_ec2_xen_uuid? == true") return true end logger.trace("Plugin EC2: has_ec2_xen_uuid? == false") false end
detect if the mac address starts with d0:0d
# File lib/ohai/plugins/eucalyptus.rb, line 42 def has_euca_mac? network[:interfaces].each_value do |iface| mac = get_mac_address(iface[:addresses]) if mac =~ /^[dD]0:0[dD]:/ logger.trace("Plugin Eucalyptus: has_euca_mac? == true (#{mac})") return true end end logger.trace("Plugin Eucalyptus: has_euca_mac? == false") false end
look for GCE string in dmi vendor bios data within the sys tree. this works even if the system lacks dmidecode use by the Dmi plugin @return [Boolean] do we have Google Compute Engine DMI data?
# File lib/ohai/plugins/gce.rb, line 29 def has_gce_dmi? if file_val_if_exists("/sys/class/dmi/id/product_name") =~ /Google Compute Engine/ logger.trace("Plugin GCE: has_gce_dmi? == true") true else logger.trace("Plugin GCE: has_gce_dmi? == false") false end end
looks at the Manufacturer and Model WMI values to see if they starts with Google. @return [Boolean] Are the manufacturer and model Google?
# File lib/ohai/plugins/gce.rb, line 50 def has_gce_system_info? if RUBY_PLATFORM =~ /mswin|mingw32|windows/ require "wmi-lite/wmi" wmi = WmiLite::Wmi.new computer_system = wmi.first_of("Win32_ComputerSystem") if computer_system["Manufacturer"] =~ /^Google/ && computer_system["Model"] =~ /^Google/ logger.trace("Plugin GCE: has_gce_system_info? == true") return true end else logger.trace("Plugin GCE: has_gce_system_info? == false") false end end
Checks for matching linode kernel name
Returns true or false
# File lib/ohai/plugins/linode.rb, line 26 def has_linode_kernel? if ( kernel_data = kernel ) kernel_data[:release].split("-").last =~ /linode/ end end
Checks for the rackspace manufacturer on Windows
Return¶ ↑
- true
-
If the rackspace cloud can be identified
- false
-
Otherwise
# File lib/ohai/plugins/rackspace.rb, line 50 def has_rackspace_manufacturer? return false unless RUBY_PLATFORM =~ /mswin|mingw32|windows/ require "wmi-lite/wmi" wmi = WmiLite::Wmi.new if wmi.first_of("Win32_ComputerSystem")["PrimaryOwnerName"] == "Rackspace" logger.trace("Plugin Rackspace: has_rackspace_manufacturer? == true") return true end end
Checks for rackspace provider attribute
Return¶ ↑
- true
-
If rackspace provider attribute found
- false
-
Otherwise
# File lib/ohai/plugins/rackspace.rb, line 37 def has_rackspace_metadata? so = shell_out("xenstore-read vm-data/provider_data/provider") if so.exitstatus == 0 so.stdout.strip.casecmp("rackspace") == 0 end rescue Ohai::Exceptions::Exec false end
On Mac OS X, the development tools include “stubs” for JVM executables that prompt the user to install the JVM if they desire. In our case we simply wish to detect if the JVM is there and do not want to trigger a popup window. As a workaround, we can run the java_home executable and check its exit status to determine if the `java` executable is the real one or the OS X stub. In the terminal, it looks like this:
$ /usr/libexec/java_home Unable to find any JVMs matching version "(null)". No Java runtime present, try --request to install. $ echo $? 1
This check always returns true when not on darwin because it is just a workaround for this particular annoyance.
# File lib/ohai/plugins/java.rb, line 64 def has_real_java? return true unless on_darwin? shell_out("/usr/libexec/java_home").status.success? end
looks for `scaleway` keyword in kernel command line @return [Boolean] do we have the keyword or not?
# File lib/ohai/plugins/scaleway.rb, line 28 def has_scaleway_cmdline? if ::File.read("/proc/cmdline") =~ /scaleway/ logger.trace("Plugin Scaleway: has_scaleway_cmdline? == true") return true end logger.trace("Plugin Scaleway: has_scaleway_cmdline? == false") false end
check for either the waagent or the unknown-245 DHCP option that Azure uses blog.mszcool.com/index.php/2015/04/detecting-if-a-virtual-machine-runs-in-microsoft-azure-linux-windows-to-protect-your-software-when-distributed-via-the-azure-marketplace/
# File lib/ohai/plugins/azure.rb, line 49 def has_waagent? if File.exist?("/usr/sbin/waagent") || Dir.exist?('C:\WindowsAzure') logger.trace("Plugin Azure: Found waagent used by Azure.") true end end
Helpers
# File lib/ohai/plugins/aix/network.rb, line 27 def hex_to_dec_netmask(netmask) # example '0xffff0000' -> '255.255.0.0' dec = netmask[2..3].to_i(16).to_s(10) [4, 6, 8].each { |n| dec = dec + "." + netmask[n..n + 1].to_i(16).to_s(10) } dec end
common initial kernel attribute values @return [Mash] basic kernel properties from uname
# File lib/ohai/plugins/kernel.rb, line 30 def init_kernel kernel Mash.new [["uname -s", :name], ["uname -r", :release], ["uname -v", :version], ["uname -m", :machine], ["uname -p", :processor]].each do |cmd, property| so = shell_out(cmd) kernel[property] = so.stdout.split($/)[0] end kernel end
create the basic structure we'll store our data in
# File lib/ohai/plugins/azure.rb, line 71 def initialize_metadata_mash_compute metadata = Mash.new metadata["compute"] = Mash.new metadata end
# File lib/ohai/plugins/azure.rb, line 77 def initialize_metadata_mash_network(metadata) metadata["network"] = Mash.new metadata["network"]["interfaces"] = Mash.new %w{public_ipv4 local_ipv4 public_ipv6 local_ipv6}.each do |type| metadata["network"][type] = [] end metadata end
# File lib/ohai/plugins/linux/network.rb, line 406 def interface_address_not_link_level?(iface, address) !(iface[:addresses][address][:scope].casecmp("link") == 0) end
Returns interface code for an interface
Interface Index (if present, Index otherwise) will be converted in hexadecimal format
@param int_idx [String or nil] the interface index of interface @param idx [String] the index of interface
@return [String]
@example Interface Code when interface index is present
plugin.interface_code("1", "1") #=> "ox1"
@example Interface Code when interface index is not present
plugin.interface_code(nil, "2") #=> "ox2"
# File lib/ohai/plugins/windows/network.rb, line 70 def interface_code(int_idx, idx) sprintf("0x%x", (int_idx || idx)).downcase end
# File lib/ohai/plugins/linux/network.rb, line 396 def interface_has_no_addresses_in_family?(iface, family) return true if iface[:addresses].nil? iface[:addresses].values.all? { |addr| addr["family"] != family } end
# File lib/ohai/plugins/linux/network.rb, line 401 def interface_have_address?(iface, address) return false if iface[:addresses].nil? iface[:addresses].key?(address) end
# File lib/ohai/plugins/linux/network.rb, line 410 def interface_valid_for_route?(iface, address, family) return true if interface_has_no_addresses_in_family?(iface, family) interface_have_address?(iface, address) && interface_address_not_link_level?(iface, address) end
# File lib/ohai/plugins/darwin/virtualization.rb, line 33 def ioreg_exists? which("ioreg") end
# File lib/ohai/plugins/linux/network.rb, line 36 def ipv6_enabled? File.exist? "/proc/net/if_inet6" end
# File lib/ohai/plugins/linux/network.rb, line 44 def is_openvz? @openvz ||= ::File.directory?("/proc/vz") end
# File lib/ohai/plugins/linux/network.rb, line 48 def is_openvz_host? is_openvz? && ::File.directory?("/proc/bc") end
# File lib/ohai/plugins/joyent.rb, line 43 def is_smartos? platform == "smartos" end
modern linux distros include a /etc/os-release file, which we now rely on for OS detection. For older distros that do not include that file we fall back to our pre-Ohai 15 detection logic, which is the method below. No new functionality should be added to this logic.
@deprecated
# File lib/ohai/plugins/linux/platform.rb, line 186 def legacy_platform_detection # platform [ and platform_version ? ] should be lower case to avoid dealing with RedHat/Redhat/redhat matching if File.exist?("/etc/oracle-release") contents = File.read("/etc/oracle-release").chomp platform "oracle" platform_version get_redhatish_version(contents) elsif File.exist?("/etc/enterprise-release") contents = File.read("/etc/enterprise-release").chomp platform "oracle" platform_version get_redhatish_version(contents) elsif File.exist?("/etc/f5-release") platform "bigip" platform_version bigip_version elsif File.exist?("/etc/debian_version") # Ubuntu and Debian both have /etc/debian_version # Ubuntu should always have a working lsb, debian does not by default if lsb[:id] =~ /Ubuntu/i platform "ubuntu" platform_version lsb[:release] else platform "debian" platform_version File.read("/etc/debian_version").chomp end elsif File.exist?("/etc/parallels-release") contents = File.read("/etc/parallels-release").chomp platform get_redhatish_platform(contents) platform_version contents.match(/(\d\.\d\.\d)/)[0] elsif File.exist?("/etc/Eos-release") platform "arista_eos" platform_version File.read("/etc/Eos-release").strip.split[-1] elsif File.exist?("/etc/redhat-release") contents = File.read("/etc/redhat-release").chomp platform get_redhatish_platform(contents) platform_version get_redhatish_version(contents) elsif File.exist?("/etc/system-release") contents = File.read("/etc/system-release").chomp platform get_redhatish_platform(contents) platform_version get_redhatish_version(contents) elsif File.exist?("/etc/SuSE-release") suse_release = File.read("/etc/SuSE-release") suse_version = suse_release.scan(/VERSION = (\d+)\nPATCHLEVEL = (\d+)/).flatten.join(".") suse_version = suse_release[/VERSION = ([\d\.]{2,})/, 1] if suse_version == "" platform_version suse_version if suse_release =~ /^openSUSE/ # opensuse releases >= 42 are openSUSE Leap if platform_version.to_i < 42 platform "opensuse" else platform "opensuseleap" end else platform "suse" end elsif os_release_file_is_cisco? raise "unknown Cisco /etc/os-release or /etc/cisco-release ID_LIKE field" if os_release_info["ID_LIKE"].nil? || !os_release_info["ID_LIKE"].include?("wrlinux") case os_release_info["ID"] when "nexus" platform "nexus" when "ios_xr" platform "ios_xr" else raise "unknown Cisco /etc/os-release or /etc/cisco-release ID field" end platform_version os_release_info["VERSION"] elsif File.exist?("/etc/slackware-version") platform "slackware" platform_version File.read("/etc/slackware-version").scan(/(\d+|\.+)/).join elsif File.exist?("/etc/exherbo-release") platform "exherbo" # no way to determine platform_version in a rolling release distribution # kernel release will be used - ex. 3.13 platform_version shell_out("/bin/uname -r").stdout.strip elsif File.exist?("/usr/lib/os-release") contents = File.read("/usr/lib/os-release") if /clear-linux-os/ =~ contents # Clear Linux https://clearlinux.org/ platform "clearlinux" platform_version contents[/VERSION_ID=(\d+)/, 1] end elsif lsb[:id] =~ /RedHat/i platform "redhat" platform_version lsb[:release] elsif lsb[:id] =~ /Amazon/i platform "amazon" platform_version lsb[:release] elsif lsb[:id] =~ /ScientificSL/i platform "scientific" platform_version lsb[:release] elsif lsb[:id] =~ /XenServer/i platform "xenserver" platform_version lsb[:release] elsif lsb[:id] =~ /XCP/i platform "xcp" platform_version lsb[:release] elsif lsb[:id] # LSB can provide odd data that changes between releases, so we currently fall back on it rather than dealing with its subtleties platform lsb[:id].downcase platform_version lsb[:release] end end
determine link stats, vlans, queue length, and state for an interface using ip
# File lib/ohai/plugins/linux/network.rb, line 204 def link_statistics(iface, net_counters) so = shell_out("ip -d -s link") tmp_int = nil on_rx = true so.stdout.lines do |line| if line =~ IPROUTE_INT_REGEX tmp_int = $2 iface[tmp_int] ||= Mash.new net_counters[tmp_int] ||= Mash.new end if line =~ /^\s+(ip6tnl|ipip)/ iface[tmp_int][:tunnel_info] = {} words = line.split words.each_with_index do |word, index| case word when "external" iface[tmp_int][:tunnel_info][word] = true when "any", "ipip6", "ip6ip6" iface[tmp_int][:tunnel_info][:proto] = word when "remote", "local", "encaplimit", "hoplimit", "tclass", "flowlabel", "addrgenmode", "numtxqueues", "numrxqueues", "gso_max_size", "gso_max_segs" iface[tmp_int][:tunnel_info][word] = words[index + 1] end end end if line =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/ int = on_rx ? :rx : :tx net_counters[tmp_int][int] ||= Mash.new net_counters[tmp_int][int][:bytes] = $1 net_counters[tmp_int][int][:packets] = $2 net_counters[tmp_int][int][:errors] = $3 net_counters[tmp_int][int][:drop] = $4 if int == :rx net_counters[tmp_int][int][:overrun] = $5 else net_counters[tmp_int][int][:carrier] = $5 net_counters[tmp_int][int][:collisions] = $6 end on_rx = !on_rx end if line =~ /qlen (\d+)/ net_counters[tmp_int][:tx] ||= Mash.new net_counters[tmp_int][:tx][:queuelen] = $1 end if line =~ /vlan id (\d+)/ || line =~ /vlan protocol ([\w\.]+) id (\d+)/ if $2 tmp_prot = $1 tmp_id = $2 else tmp_id = $1 end iface[tmp_int][:vlan] ||= Mash.new iface[tmp_int][:vlan][:id] = tmp_id iface[tmp_int][:vlan][:protocol] = tmp_prot if tmp_prot vlan_flags = line.scan(/(REORDER_HDR|GVRP|LOOSE_BINDING)/) if vlan_flags.length > 0 iface[tmp_int][:vlan][:flags] = vlan_flags.flatten.uniq end end if line =~ /state (\w+)/ iface[tmp_int]["state"] = $1.downcase end end iface end
# File lib/ohai/plugins/linux/network.rb, line 25 def linux_encaps_lookup(encap) return "Loopback" if encap.eql?("Local Loopback") || encap.eql?("loopback") return "PPP" if encap.eql?("Point-to-Point Protocol") return "SLIP" if encap.eql?("Serial Line IP") return "VJSLIP" if encap.eql?("VJ Serial Line IP") return "IPIP" if encap.eql?("IPIP Tunnel") return "6to4" if encap.eql?("IPv6-in-IPv4") return "Ethernet" if encap.eql?("ether") encap end
# File lib/ohai/plugins/libvirt.rb, line 32 def load_libvirt require "libvirt" # this is the ruby-libvirt gem not the libvirt gem logger.trace("Plugin Libvirt: Successfully loaded ruby-libvirt gem") rescue LoadError logger.trace("Plugin Libvirt: Can't load gem ruby-libvirt.") end
# File lib/ohai/plugins/darwin/network.rb, line 73 def locate_interface(ifaces, ifname, mac) return ifname unless ifaces[ifname].nil? # oh well, time to go hunting! return ifname.chop if ifname =~ /\*$/ ifaces.each_key do |ifc| ifaces[ifc][:addresses].each_key do |addr| return ifc if addr.eql? mac end end nil end
Returns a Mash
loaded with logical details
Uses Win32_LogicalDisk and logical_properties
to return encryption details of volumes.
Returns an empty Mash
in case of any WMI exception.
@see docs.microsoft.com/en-us/windows/desktop/CIMWin32Prov/win32-logicaldisk
@return [Mash]
# File lib/ohai/plugins/windows/filesystem.rb, line 39 def logical_info wmi = WmiLite::Wmi.new("Root\\CIMV2") # Note: we should really be parsing Win32_Volume and Win32_Mapped drive. disks = wmi.instances_of("Win32_LogicalDisk") logical_properties(disks) rescue WmiLite::WmiException Ohai::Log.debug("Unable to access Win32_LogicalDisk. Skipping logical details") Mash.new end
Refines and calculates logical properties out of given instances
@param [WmiLite::Wmi::Instance] disks
@return [Mash] Each drive containing following properties:
* :kb_size (Integer) * :kb_available (Integer) * :kb_used (Integer) * :percent_used (Integer) * :mount (String) * :fs_type (String) * :volume_name (String)
# File lib/ohai/plugins/windows/filesystem.rb, line 85 def logical_properties(disks) properties = Mash.new disks.each do |disk| property = Mash.new drive = disk["deviceid"] property[:kb_size] = disk["size"].to_i / 1000 property[:kb_available] = disk["freespace"].to_i / 1000 property[:kb_used] = property[:kb_size] - property[:kb_available] property[:percent_used] = (property[:kb_size] == 0 ? 0 : (property[:kb_used] * 100 / property[:kb_size])) property[:mount] = disk["name"] property[:fs_type] = disk["filesystem"].to_s.downcase property[:volume_name] = disk["volumename"].to_s.downcase properties[drive] = property end properties end
# File lib/ohai/plugins/digital_ocean.rb, line 44 def looks_like_digital_ocean? return true if hint?("digital_ocean") return true if has_do_dmi? && can_socket_connect?(Ohai::Mixin::DOMetadata::DO_METADATA_ADDR, 80) false end
a single check that combines all the various detection methods for EC2 @return [Boolean] Does the system appear to be on EC2
# File lib/ohai/plugins/ec2.rb, line 108 def looks_like_ec2? return true if hint?("ec2") # Even if it looks like EC2 try to connect first if has_ec2_xen_uuid? || has_ec2_amazon_dmi? || has_ec2_xen_dmi? || has_ec2_identifying_number? return true if can_socket_connect?(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80) end end
# File lib/ohai/plugins/eucalyptus.rb, line 55 def looks_like_euca? # Try non-blocking connect so we don't "block" if # the metadata service doesn't respond hint?("eucalyptus") || has_euca_mac? && can_socket_connect?(Ohai::Mixin::Ec2Metadata::EC2_METADATA_ADDR, 80) end
Identifies the linode cloud by preferring the hint, then
Returns true or false
# File lib/ohai/plugins/linode.rb, line 35 def looks_like_linode? hint?("linode") || has_linode_kernel? end
a single check that combines all the various detection methods for Scaleway @return [Boolean] Does the system appear to be on Scaleway
# File lib/ohai/plugins/scaleway.rb, line 39 def looks_like_scaleway? return true if hint?("scaleway") return true if has_scaleway_cmdline? && can_socket_connect?(Ohai::Mixin::ScalewayMetadata::SCALEWAY_METADATA_ADDR, 80) false end
# File lib/ohai/plugins/linux/virtualization.rb, line 25 def lxc_version_exists? which("lxc-version") || which("lxc-start") end
# File lib/ohai/plugins/windows/network.rb, line 28 def mac_addresses(iface) prop = iface[:configuration][:mac_address] || iface[:instance][:network_addresses] [prop].flatten.map { |addr| addr.include?(":") ? addr : addr.scan(/.{1,2}/).join(":") } end
# File lib/ohai/plugins/linux/network.rb, line 286 def match_iproute(iface, line, cint) if line =~ IPROUTE_INT_REGEX cint = $2 iface[cint] = Mash.new if cint =~ /^(\w+)(\d+.*)/ iface[cint][:type] = $1 iface[cint][:number] = $2 end if line =~ /mtu (\d+)/ iface[cint][:mtu] = $1 end flags = line.scan(/(UP|BROADCAST|DEBUG|LOOPBACK|POINTTOPOINT|NOTRAILERS|LOWER_UP|NOARP|PROMISC|ALLMULTI|SLAVE|MASTER|MULTICAST|DYNAMIC)/) if flags.length > 1 iface[cint][:flags] = flags.flatten.uniq end end cint end
Merges all the various properties of filesystems
@param [Array<Mash>] disks_info
Array of the Mashes containing disk properties
@return [Mash]
# File lib/ohai/plugins/windows/filesystem.rb, line 128 def merge_info(disks_info) fs = Mash.new disks_info.each do |info| info.each do |disk, data| if fs[disk] fs[disk].merge!(data) else fs[disk] = data.dup end end end fs end
# File lib/ohai/plugins/windows/network.rb, line 48 def msft_adapter_data data = {} wmi = WmiLite::Wmi.new("ROOT/StandardCimv2") data[:addresses] = wmi.instances_of("MSFT_NetIPAddress") data[:adapters] = wmi.instances_of("MSFT_NetAdapter") data end
address_to_match: String
ipaddress: IPAddress iface: String
# File lib/ohai/plugins/network.rb, line 122 def network_contains_address(address_to_match, ipaddress, iface) if ( peer = network["interfaces"][iface]["addresses"][ipaddress.to_s][:peer] ) IPAddress(peer) == IPAddress(address_to_match) else ipaddress.include? IPAddress(address_to_match) end end
# File lib/ohai/plugins/windows/network.rb, line 33 def network_data @network_data ||= begin data = {} wmi = WmiLite::Wmi.new data[:addresses] = wmi.instances_of("Win32_NetworkAdapterConfiguration") # If we are running on windows nano or another operating system from the future # that does not populate the deprecated win32_* WMI classes, then we should # grab data from the newer MSFT_* classes return msft_adapter_data if data[:addresses].count == 0 data[:adapters] = wmi.instances_of("Win32_NetworkAdapter") data end end
# File lib/ohai/plugins/linux/virtualization.rb, line 29 def nova_exists? which("nova") end
# File lib/ohai/plugins/java.rb, line 69 def on_darwin? RUBY_PLATFORM.downcase.include?("darwin") end
# File lib/ohai/plugins/cloud.rb, line 121 def on_gce? gce != nil end
do we have the openstack dmi data
# File lib/ohai/plugins/openstack.rb, line 30 def openstack_dmi? # detect a manufacturer of OpenStack Foundation if get_attribute(:dmi, :system, :all_records, 0, :Manufacturer) =~ /OpenStack/ logger.trace("Plugin Openstack: has_openstack_dmi? == true") true elsif get_attribute(:dmi, :system, :product_name) == "OpenStack Compute" logger.trace("Plugin Openstack: has_openstack_dmi? == true") true else logger.trace("Plugin Openstack: has_openstack_dmi? == false") false end end
check for the ohai hint and log trace messaging
# File lib/ohai/plugins/openstack.rb, line 45 def openstack_hint? if hint?("openstack") logger.trace("Plugin Openstack: openstack hint present") true else logger.trace("Plugin Openstack: openstack hint not present") false end end
dreamhost systems have the dhc-user on them
# File lib/ohai/plugins/openstack.rb, line 56 def openstack_provider return "dreamhost" if get_attribute("etc", "passwd", "dhc-user") "openstack" end
If /etc/os-release indicates we are Cisco based
@returns [Boolean] if we are Cisco according to /etc/os-release
# File lib/ohai/plugins/linux/platform.rb, line 98 def os_release_file_is_cisco? File.exist?("/etc/os-release") && os_release_info["CISCO_RELEASE_INFO"] end
Cached /etc/os-release info Hash. Also has logic for Cisco Nexus switches that pulls the chained CISCO_RELEASE_INFO file into the Hash (other distros can also reuse this method safely).
@returns [Hash] the canonical, cached Hash of /etc/os-release info or nil
# File lib/ohai/plugins/linux/platform.rb, line 81 def os_release_info @os_release_info ||= begin os_release_info = read_os_release_info("/etc/os-release") cisco_release_info = os_release_info["CISCO_RELEASE_INFO"] if os_release_info if cisco_release_info && File.exist?(cisco_release_info) os_release_info.merge!(read_os_release_info(cisco_release_info)) end os_release_info end end
decode the OSType field from WMI Win32_OperatingSystem class msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx @param [Integer] sys_type OSType value from Win32_OperatingSystem @return [String] the human consumable OS type value
# File lib/ohai/plugins/kernel.rb, line 104 def os_type_decode(sys_type) case sys_type when 18 then "WINNT" # most likely so first when 0 then "Unknown" when 1 then "Other" when 14 then "MSDOS" when 15 then "WIN3x" when 16 then "WIN95" when 17 then "WIN98" when 19 then "WINCE" else nil end end
# File lib/ohai/plugins/cpu.rb, line 30 def parse_bsd_dmesg(&block) cpuinfo = Mash.new cpuinfo["flags"] = [] File.open("/var/run/dmesg.boot").each do |line| case line when /CPU:\s+(.+) \(([\d.]+).+\)/ cpuinfo["model_name"] = $1 cpuinfo["mhz"] = $2 when /Features=.+<(.+)>/ cpuinfo["flags"].concat($1.downcase.split(",")) # Features2=0x80000001<SSE3,<b31>> when /Features2=[a-f\dx]+<(.+)>/ cpuinfo["flags"].concat($1.downcase.split(",")) else yield(cpuinfo, line) end end cpuinfo end
# File lib/ohai/plugins/filesystem.rb, line 123 def parse_common_df(out) fs = {} out.each_line do |line| case line when /^Filesystem\s+1024-blocks/ next when /^(.+?)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+\%)\s+(.+)$/ key = "#{$1},#{$6}" fs[key] = Mash.new fs[key][:device] = $1 fs[key][:kb_size] = $2 fs[key][:kb_used] = $3 fs[key][:kb_available] = $4 fs[key][:percent_used] = $5 fs[key][:mount] = $6 end end fs end
# File lib/ohai/plugins/powershell.rb, line 74 def parse_compatible_versions so = shell_out("#{powershell_command} \"#{version_command}\"") versions = [] so.stdout.strip.each_line do |line| versions << line.strip end versions end
# File lib/ohai/plugins/filesystem.rb, line 501 def parse_df_or_mount(shell_out) oldie = Mash.new shell_out.lines.each do |line| fields = line.split case line # headers and horizontal rules to skip when /^\s*(node|---|^Filesystem\s+1024-blocks)/ next # strictly a df entry when /^(.+?)\s+([0-9-]+)\s+([0-9-]+)\s+([0-9-]+)\s+([0-9-]+\%*)\s+(.+)$/ if $1 == "Global" dev = "#{$1}:#{$6}" else dev = $1 end mountpoint = $6 key = "#{dev},#{mountpoint}" oldie[key] ||= Mash.new oldie[key][:kb_size] = $2 oldie[key][:kb_used] = $3 oldie[key][:kb_available] = $4 oldie[key][:percent_used] = $5 oldie[key][:mount] = mountpoint oldie[key][:device] = dev # an entry starting with 'G' or / (E.G. /tmp or /var) when /^\s*(G.*?|\/\w)/ if fields[0] == "Global" dev = fields[0] + ":" + fields[1] else dev = fields[0] end mountpoint = fields[1] key = "#{dev},#{mountpoint}" oldie[key] ||= Mash.new oldie[key][:mount] = mountpoint oldie[key][:fs_type] = fields[2] oldie[key][:mount_options] = fields[6].split(",") oldie[key][:device] = dev # entries occupying the 'Node' column parsed here else dev = fields[0] + ":" + fields[1] mountpoint = fields[2] key = "#{dev},#{mountpoint}" oldie[key] ||= Mash.new oldie[key][:mount] = mountpoint oldie[key][:device] = dev oldie[key][:fs_type] = fields[3] oldie[key][:mount_options] = fields[7].split(",") end end oldie end
# File lib/ohai/plugins/linux/network.rb, line 307 def parse_ip_addr(iface) so = shell_out("ip addr") cint = nil so.stdout.lines do |line| cint = match_iproute(iface, line, cint) parse_ip_addr_link_line(cint, iface, line) cint = parse_ip_addr_inet_line(cint, iface, line) parse_ip_addr_inet6_line(cint, iface, line) end end
# File lib/ohai/plugins/linux/network.rb, line 366 def parse_ip_addr_inet6_line(cint, iface, line) if line =~ /inet6 ([a-f0-9\:]+)\/(\d+) scope (\w+)( .*)?/ iface[cint][:addresses] ||= Mash.new tmp_addr = $1 tags = $4 || "" tags = tags.split(" ") iface[cint][:addresses][tmp_addr] = { "family" => "inet6", "prefixlen" => $2, "scope" => ($3.eql?("host") ? "Node" : $3.capitalize), "tags" => tags, } end end
# File lib/ohai/plugins/linux/network.rb, line 329 def parse_ip_addr_inet_line(cint, iface, line) if line =~ /inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(\/(\d{1,2}))?/ tmp_addr, tmp_prefix = $1, $3 tmp_prefix ||= "32" original_int = nil # Are we a formerly aliased interface? if line =~ /#{cint}:(\d+)$/ sub_int = $1 alias_int = "#{cint}:#{sub_int}" original_int = cint cint = alias_int end iface[cint] ||= Mash.new # Create the fake alias interface if needed iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][tmp_addr] = { "family" => "inet", "prefixlen" => tmp_prefix } iface[cint][:addresses][tmp_addr][:netmask] = IPAddr.new("255.255.255.255").mask(tmp_prefix.to_i).to_s if line =~ /peer (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ iface[cint][:addresses][tmp_addr][:peer] = $1 end if line =~ /brd (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ iface[cint][:addresses][tmp_addr][:broadcast] = $1 end if line =~ /scope (\w+)/ iface[cint][:addresses][tmp_addr][:scope] = ($1.eql?("host") ? "Node" : $1.capitalize) end # If we found we were an alias interface, restore cint to its original value cint = original_int unless original_int.nil? end cint end
# File lib/ohai/plugins/linux/network.rb, line 319 def parse_ip_addr_link_line(cint, iface, line) if line =~ /link\/(\w+) ([\da-f\:]+) / iface[cint][:encapsulation] = linux_encaps_lookup($1) unless $2 == "00:00:00:00:00:00" iface[cint][:addresses] ||= Mash.new iface[cint][:addresses][$2.upcase] = { "family" => "lladdr" } end end end
# File lib/ohai/plugins/filesystem.rb, line 37 def parse_line(line, cmdtype) case cmdtype when "lsblk" regex = /NAME="(\S+).*?" UUID="(\S*)" LABEL="(\S*)" FSTYPE="(\S*)"/ if line =~ regex dev = $1 dev = find_device(dev) unless dev.start_with?("/") uuid = $2 label = $3 fs_type = $4 return { dev: dev, uuid: uuid, label: label, fs_type: fs_type } end when "blkid" bits = line.split dev = bits.shift.split(":")[0] f = { dev: dev } bits.each do |keyval| if keyval =~ /(\S+)="(\S+)"/ key = $1.downcase.to_sym key = :fs_type if key == :type f[key] = $2 end end return f end nil end
# File lib/ohai/plugins/darwin/network.rb, line 23 def parse_media(media_string) media = Hash.new line_array = media_string.split(" ") 0.upto(line_array.length - 1) do |i| unless line_array[i].eql?("none") if line_array[i + 1] =~ /^\<([a-zA-Z\-\,]+)\>$/ media[line_array[i]] = Hash.new unless media.key?(line_array[i]) if media[line_array[i]].key?("options") $1.split(",").each do |opt| media[line_array[i]]["options"] << opt unless media[line_array[i]]["options"].include?(opt) end else media[line_array[i]]["options"] = $1.split(",") end else if line_array[i].eql?("autoselect") media["autoselect"] = Hash.new unless media.key?("autoselect") media["autoselect"]["options"] = [] end end else media["none"] = { "options" => [] } end end media end
# File lib/ohai/plugins/azure.rb, line 95 def parse_metadata return nil unless can_socket_connect?(Ohai::Mixin::AzureMetadata::AZURE_METADATA_ADDR, 80) endpoint_data = fetch_metadata return nil if endpoint_data.nil? metadata = initialize_metadata_mash_compute # blindly add everything in compute to our data structure endpoint_data["compute"].each do |k, v| metadata["compute"][k] = v end # receiving network output is not guaranteed unless endpoint_data["network"].nil? metadata = initialize_metadata_mash_network(metadata) # parse out per interface interface IP data endpoint_data["network"]["interface"].each do |int| metadata["network"]["interfaces"][int["macAddress"]] = Mash.new metadata["network"]["interfaces"][int["macAddress"]]["mac"] = int["macAddress"] metadata["network"]["interfaces"][int["macAddress"]]["public_ipv6"] = fetch_ip_data(int, "ipv6", "publicIpAddress") metadata["network"]["interfaces"][int["macAddress"]]["public_ipv4"] = fetch_ip_data(int, "ipv4", "publicIpAddress") metadata["network"]["interfaces"][int["macAddress"]]["local_ipv6"] = fetch_ip_data(int, "ipv6", "privateIpAddress") metadata["network"]["interfaces"][int["macAddress"]]["local_ipv4"] = fetch_ip_data(int, "ipv4", "privateIpAddress") end # aggregate the total IP data %w{public_ipv4 local_ipv4 public_ipv6 local_ipv6}.each do |type| metadata["network"]["interfaces"].each_value do |val| metadata["network"][type].concat val[type] unless val[type].empty? end end end metadata end
using a temporary var to hold routes and their interface name
# File lib/ohai/plugins/linux/network.rb, line 139 def parse_routes(family, iface) iface.collect do |i, iv| if iv[:routes] iv[:routes].collect do |r| r.merge(dev: i) if r[:family] == family[:name] end.compact end end.compact.flatten end
decode the PCSystemType field from WMI Win32_OperatingSystem class msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx @param [Integer] type the integer value from PCSystemType @return [String] the human consumable OS type value
# File lib/ohai/plugins/kernel.rb, line 122 def pc_system_type_decode(type) case type when 4 then "Enterprise Server" # most likely so first when 0 then "Unspecified" when 1 then "Desktop" when 2 then "Mobile" when 3 then "Workstation" when 5 then "SOHO Server" when 6 then "Appliance PC" when 7 then "Performance Server" when 8 then "Maximum" else nil end end
Determines the platform_family based on the platform
@param plat [String] the platform name
@returns [String] platform_family value
# File lib/ohai/plugins/linux/platform.rb, line 140 def platform_family_from_platform(plat) case plat when /debian/, /ubuntu/, /linuxmint/, /raspbian/, /cumulus/, /kali/ # apt-get+dpkg almost certainly goes here "debian" when /oracle/, /centos/, /redhat/, /scientific/, /enterpriseenterprise/, /xcp/, /xenserver/, /cloudlinux/, /ibm_powerkvm/, /parallels/, /nexus_centos/, /clearos/, /bigip/ # Note that 'enterpriseenterprise' is oracle's LSB "distributor ID" # NOTE: "rhel" should be reserved exclusively for recompiled rhel versions that are nearly perfectly compatible down to the platform_version. # The operating systems that are "rhel" should all be as compatible as rhel7 = centos7 = oracle7 = scientific7 (98%-ish core RPM version compatibility # and the version numbers MUST track the upstream). The appropriate EPEL version repo should work nearly perfectly. Some variation like the # oracle kernel version differences and tuning and extra packages are clearly acceptable. Almost certainly some distros above (xenserver?) # should not be in this list. Please use fedora, below, instead. Also note that this is the only platform_family with this strict of a rule, # see the example of the debian platform family for how the rest of the platform_family designations should be used. "rhel" when /amazon/ "amazon" when /suse/, /sles/, /opensuse/, /opensuseleap/, /sled/ "suse" when /fedora/, /pidora/, /arista_eos/ # In the broadest sense: RPM-based, fedora-derived distributions which are not strictly re-compiled RHEL (if it uses RPMs, and smells more like redhat and less like # SuSE it probably goes here). "fedora" when /nexus/, /ios_xr/ "wrlinux" when /gentoo/ "gentoo" when /slackware/ "slackware" when /arch/, /manjaro/, /antergos/ "arch" when /exherbo/ "exherbo" when /alpine/ "alpine" when /clearlinux/ "clearlinux" when /mangeia/ "mandriva" end end
our platform names don't match os-release. given a time machine they would but ohai came before the os-release file. This method remaps the os-release names to the ohai names
@param id [String] the platform ID from /etc/os-release
@returns [String] the platform name to use in Ohai
# File lib/ohai/plugins/linux/platform.rb, line 125 def platform_id_remap(id) # this catches the centos guest shell in the nexus switch which identifies itself as centos return "nexus_centos" if id == "centos" && os_release_file_is_cisco? # remap based on the hash of platforms PLATFORM_MAPPINGS[id] || id end
# File lib/ohai/plugins/powershell.rb, line 65 def powershell_command ["powershell.exe", "-NoLogo", "-NonInteractive", "-NoProfile", "-Command", ].join(" ") end
Returns IPV4 address from list of addresses containing IPV4 and IPV6 formats
@param addresses [Array<String>] List of addresses
@return [String]
@example When list contains both IPV4 and IPV6 formats
plugin.prefer_ipv4([IPV4, IPV6]) #=> "IPV4"
@example When list contains only IPV6 format
plugin.prefer_ipv4([IPV6]) #=> "IPV6"
# File lib/ohai/plugins/windows/network.rb, line 85 def prefer_ipv4(addresses) return nil unless addresses.is_a?(Array) addresses.find { |ip| IPAddress.valid_ipv4?(ip) } || addresses.find { |ip| IPAddress.valid_ipv6?(ip) } end
# File lib/ohai/plugins/darwin/virtualization.rb, line 29 def prlctl_exists? which("prlctl") end
given the ProductType value from WMI's Win32_OperatingSystem class msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx return either workstation or server @param [Integer] type ProductType value from Win32_OperatingSystem @return [String] Workstation or Server
# File lib/ohai/plugins/kernel.rb, line 95 def product_type_decode(type) return "Workstation" if type == 1 "Server" end
Reads an os-release-info file and parse it into a hash
@param file [String] the filename to read (e.g. '/etc/os-release')
@returns [Hash] the file parsed into a Hash or nil
# File lib/ohai/plugins/linux/platform.rb, line 65 def read_os_release_info(file) return nil unless File.exist?(file) File.read(file).split.inject({}) do |map, line| key, value = line.split("=") map[key] = value.gsub(/\A"|"\Z/, "") if value map end end
forward and reverse lookup to canonicalize FQDN (hostname -f equivalent) this is ipv6-safe, works on ruby 1.8.7+
# File lib/ohai/plugins/hostname.rb, line 49 def resolve_fqdn hostname = from_cmd("hostname") addrinfo = Socket.getaddrinfo(hostname, nil).first iaddr = IPAddr.new(addrinfo[3]) Socket.gethostbyaddr(iaddr.hton)[0] rescue nil end
# File lib/ohai/plugins/linux/network.rb, line 416 def route_is_valid_default_route?(route, default_route) # if the route destination is a default route, it's good return true if route[:destination] == "default" # the default route has a gateway and the route matches the gateway !default_route[:via].nil? && IPAddress(route[:destination]).include?(IPAddress(default_route[:via])) end
# File lib/ohai/plugins/ruby.rb, line 23 def run_ruby(command) cmd = "ruby -e \"require 'rbconfig'; #{command}\"" so = shell_out(cmd) so.stdout.strip end
# File lib/ohai/plugins/filesystem.rb, line 143 def run_with_check(bin, &block) yield rescue Ohai::Exceptions::Exec => e unless Ohai.config[:plugin][:filesystem][:allow_partial_data] raise e end logger.warn("Plugin Filesystem: #{bin} binary is not available. Some data will not be available.") end
If zpool status doesn't know about a field it returns '-'. We don't want to fill a field with that
# File lib/ohai/plugins/zpools.rb, line 25 def sanitize_value(value) value == "-" ? nil : value end
# File lib/ohai/plugins/darwin/network.rb, line 62 def scope_lookup(scope) return "Node" if scope.eql?("::1") return "Link" if scope =~ /^fe80\:/ return "Site" if scope =~ /^fec0\:/ "Global" end
given the OperatingSystemSKU value from WMI's Win32_OperatingSystem class msdn.microsoft.com/en-us/library/aa394239(v=vs.85).aspx return if we're on a Server Core installation @param [String] sku OperatingSystemSKU value from Win32_OperatingSystem @return [boolean]
# File lib/ohai/plugins/kernel.rb, line 60 def server_core?(sku) return true if [ 12, # Server Datacenter Core 39, # Server Datacenter without Hyper-V Core 14, # Server Enterprise Core 41, # Server Enterprise without Hyper-V Core 13, # Server Standard Core 40, # Server Standard without Hyper-V Core 63, # Small Business Server Premium Core 53, # Server Solutions Premium Core 46, # Storage Server Enterprise Core 43, # Storage Server Express Core 44, # Storage Server Standard Core 45, # Storage Server Workgroup Core 29 # Web Server Core ].include?(sku) false end
# File lib/ohai/plugins/solaris2/network.rb, line 69 def solaris_encaps_lookup(ifname) return "Ethernet" if ETHERNET_ENCAPS.include?(ifname) return "Ethernet" if ifname.eql?("net") return "Loopback" if ifname.eql?("lo") "Unknown" end
from interface data create array of hashes with ipaddress, scope, and iface sorted by scope, prefixlen and then ipaddress where longest prefixes first
# File lib/ohai/plugins/network.rb, line 30 def sorted_ips(family = "inet") raise "bad family #{family}" unless %w{inet inet6}.include? family # priority of ipv6 link scopes to sort by later scope_prio = [ "global", "site", "link", "host", "node", nil ] # grab ipaddress, scope, and iface for sorting later ipaddresses = [] Mash[network["interfaces"]].each do |iface, iface_v| next if iface_v.nil? || !iface_v.key?("addresses") iface_v["addresses"].each do |addr, addr_v| next if addr_v.nil? || (not addr_v.key? "family") || addr_v["family"] != family ipaddresses << { ipaddress: addr_v["prefixlen"] ? IPAddress("#{addr}/#{addr_v["prefixlen"]}") : IPAddress("#{addr}/#{addr_v["netmask"]}"), scope: addr_v["scope"].nil? ? nil : addr_v["scope"].downcase, iface: iface, } end end # sort ip addresses by scope, by prefixlen and then by ip address # 128 - prefixlen: longest prefixes first ipaddresses.sort_by do |v| [ ( scope_prio.index(v[:scope]) || 999999 ), 128 - v[:ipaddress].prefix.to_i, ( family == "inet" ? v[:ipaddress].to_u32 : v[:ipaddress].to_u128 ), ] end end
# File lib/ohai/plugins/linux/lspci.rb, line 41 def standard_array(devices, d_id, tag, line) if !devices[d_id][tag].kind_of?(Array) devices[d_id][tag] = [line] else devices[d_id][tag].push(line) end end
# File lib/ohai/plugins/linux/lspci.rb, line 35 def standard_form(devices, d_id, hhhh, tag, line) tmp = line.scan(/(.*)\s\[(#{hhhh})\]/)[0] devices[d_id]["#{tag}_name"] = tmp[0] devices[d_id]["#{tag}_id"] = tmp[1] end
# File lib/ohai/plugins/darwin/hardware.rb, line 22 def system_profiler(datatype) sp_cmd = "system_profiler #{datatype} -xml" # Hardware queries sp_std = shell_out(sp_cmd) Plist.parse_xml(sp_std.stdout) end
# File lib/ohai/plugins/darwin/virtualization.rb, line 25 def vboxmanage_exists? which("VBoxManage") end
query virtualbox for a list of #{query_type} items these queries return a result set that is delimited by multiple successive newlines, with each block containing key/value pairs delimited by a colon (:) and column aligned
the keys of each k/v pair are normalized to lowercase
# File lib/ohai/plugins/virtualbox.rb, line 83 def vboxmanage_list_blocks(query_type, name_key) # ignore unrecognized query type supported_queries = %w{ bridgedifs dhcpservers dvds hdds hostdvds hostfloppies hostonlyifs natnets } return nil unless supported_queries.include? query_type results = Mash.new so_cmd = "VBoxManage list --sorted #{query_type}" logger.trace(so_cmd) so = shell_out(so_cmd) # raise an exception if the command fails # so.error! if so.exitstatus == 0 # break the result into paragraph blocks, on successive newlines so.stdout.each_line("") do |blk| # remove the multiple newlines of each record blk.chomp!.chomp! # initialize a blank record hash record = Mash.new # parse the record block into key/value pairs blk.each_line() do |line| next unless line.include? ":" # split the line into key/value pair key, right = line.split(":", 2) # strip the leading/trailing whitespace if the value is not nil value = right.nil? ? "" : right.strip record[key.downcase] = value end # insert the record into the list of results if record.key? name_key.downcase name = record.delete(name_key.downcase) results[name] = record end end end results rescue Ohai::Exceptions::Exec logger.trace("Plugin VboxHost: Could not run '#{so_cmd}'. Skipping data") end
query virtualbox for each configured vm, as well as each guest's individual configuration settings
# File lib/ohai/plugins/virtualbox.rb, line 27 def vboxmanage_list_vms vms = Mash.new so_cmd = "VBoxManage list --sorted vms" logger.trace(so_cmd) so = shell_out(so_cmd) if so.exitstatus == 0 # parse the output so.stdout.lines.each do |line| case line when /^"(\S*)" \{(\S*)\}$/ name = Regexp.last_match(1) uuid = Regexp.last_match(2) vms[name] = vboxmanage_vminfo(uuid) end end end vms rescue Ohai::Exceptions::Exec logger.trace("Plugin VboxHost: Could not run 'VBoxManage list --sorted vms'. Skipping data") end
query the vminfo for particular guest instance, normalizing the fields so that they're not enclosed in double-quotes (“)
# File lib/ohai/plugins/virtualbox.rb, line 51 def vboxmanage_vminfo(machine_id) vm = Mash.new so_cmd = "VBoxManage showvminfo #{machine_id} --machinereadable" logger.trace(so_cmd) so = shell_out(so_cmd) if so.exitstatus == 0 so.stdout.lines.each do |line| line.chomp! left, right = line.split("=") # remove enclosing quotes, if needed key = left.delete_prefix('"').delete_suffix('"') # skip the name attribute since that is the parent key next if key == "name" vm[key.downcase] = right.delete_prefix('"').delete_suffix('"') end end vm rescue Ohai::Exceptions::Exec logger.trace("Plugin VboxHost: Could not run '#{so_cmd}'. Skipping data") end
# File lib/ohai/plugins/powershell.rb, line 58 def version_command [ "$progresspreference = 'silentlycontinue'", "$PSVersionTable.PSCompatibleVersions | foreach {$_.tostring()}", ].join("; ") end
# File lib/ohai/plugins/libvirt.rb, line 39 def virtconn @virt_connect ||= Libvirt.open_read_only("#{emu}:///system") end
# File lib/ohai/plugins/windows/network.rb, line 23 def windows_encaps_lookup(encap) return "Ethernet" if encap.eql?("Ethernet 802.3") encap end
# File lib/ohai/plugins/c.rb, line 34 def xcode_installed? logger.trace("Plugin C: Checking for Xcode Command Line Tools.") so = shell_out("/usr/bin/xcode-select -p") if so.exitstatus == 0 logger.trace("Plugin C: Xcode Command Line Tools found.") return true else logger.trace("Plugin C: Xcode Command Line Tools not found.") return false end rescue Ohai::Exceptions::Exec logger.trace("Plugin C: xcode-select binary could not be found. Skipping data.") end