facter 1.6.0 → 1.6.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of facter might be problematic. Click here for more details.
- data/CHANGELOG +53 -0
- data/CONTRIBUTING.md +299 -0
- data/Rakefile +3 -3
- data/conf/redhat/facter.spec +1 -1
- data/install.rb +25 -10
- data/lib/facter.rb +16 -1
- data/lib/facter/arp.rb +1 -1
- data/lib/facter/augeasversion.rb +29 -0
- data/lib/facter/domain.rb +9 -10
- data/lib/facter/hardwareisa.rb +2 -2
- data/lib/facter/hostname.rb +4 -9
- data/lib/facter/ipaddress6.rb +9 -0
- data/lib/facter/kernel.rb +3 -3
- data/lib/facter/kernelrelease.rb +2 -4
- data/lib/facter/lsbmajdistrelease.rb +1 -1
- data/lib/facter/macaddress.rb +11 -31
- data/lib/facter/manufacturer.rb +5 -0
- data/lib/facter/memory.rb +32 -4
- data/lib/facter/operatingsystem.rb +6 -0
- data/lib/facter/operatingsystemrelease.rb +11 -2
- data/lib/facter/physicalprocessorcount.rb +8 -0
- data/lib/facter/processor.rb +38 -0
- data/lib/facter/ps.rb +5 -0
- data/lib/facter/selinux.rb +63 -48
- data/lib/facter/uniqueid.rb +2 -2
- data/lib/facter/util/config.rb +9 -0
- data/lib/facter/util/ip.rb +26 -3
- data/lib/facter/util/loader.rb +11 -0
- data/lib/facter/util/macaddress.rb +20 -0
- data/lib/facter/util/manufacturer.rb +10 -5
- data/lib/facter/util/resolution.rb +18 -9
- data/lib/facter/util/uptime.rb +6 -5
- data/lib/facter/util/wmi.rb +16 -0
- data/lib/facter/virtual.rb +15 -8
- data/spec/fixtures/netsh/windows_netsh_addresses_with_multiple_interfaces +35 -0
- data/spec/fixtures/unit/util/loader/nosuchfact.rb +1 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/data/windows_netsh_all_interfaces +12 -0
- data/spec/unit/data/windows_netsh_single_interface +7 -0
- data/spec/unit/data/windows_netsh_single_interface6 +18 -0
- data/spec/unit/domain_spec.rb +91 -0
- data/spec/unit/facter_spec.rb +21 -0
- data/spec/unit/hostname_spec.rb +38 -0
- data/spec/unit/id_spec.rb +6 -5
- data/spec/unit/interfaces_spec.rb +7 -0
- data/spec/unit/ipaddress6_spec.rb +19 -0
- data/spec/unit/macaddress_spec.rb +38 -0
- data/spec/unit/memory_spec.rb +26 -0
- data/spec/unit/operatingsystem_spec.rb +28 -0
- data/spec/unit/operatingsystemrelease_spec.rb +19 -8
- data/spec/unit/physicalprocessorcount_spec.rb +11 -0
- data/spec/unit/processor_spec.rb +66 -0
- data/spec/unit/selinux_spec.rb +1 -0
- data/spec/unit/util/ip_spec.rb +83 -21
- data/spec/unit/util/loader_spec.rb +8 -0
- data/spec/unit/util/macaddress_spec.rb +28 -1
- data/spec/unit/util/manufacturer_spec.rb +21 -0
- data/spec/unit/util/resolution_spec.rb +26 -14
- data/spec/unit/util/uptime_spec.rb +7 -1
- data/spec/unit/util/wmi_spec.rb +20 -0
- data/spec/unit/virtual_spec.rb +41 -5
- metadata +19 -8
- data/spec/spec.opts +0 -5
data/lib/facter/processor.rb
CHANGED
@@ -104,3 +104,41 @@ if Facter.value(:kernel) == "OpenBSD"
|
|
104
104
|
end
|
105
105
|
end
|
106
106
|
end
|
107
|
+
|
108
|
+
if Facter.value(:kernel) == "windows"
|
109
|
+
processor_list = []
|
110
|
+
|
111
|
+
Thread::exclusive do
|
112
|
+
require 'facter/util/wmi'
|
113
|
+
|
114
|
+
# get each physical processor
|
115
|
+
Facter::Util::WMI.execquery("select * from Win32_Processor").each do |proc|
|
116
|
+
# not supported before 2008
|
117
|
+
begin
|
118
|
+
processor_num = proc.NumberOfLogicalProcessors
|
119
|
+
rescue RuntimeError => e
|
120
|
+
processor_num = 1
|
121
|
+
end
|
122
|
+
|
123
|
+
processor_num.times do |i|
|
124
|
+
processor_list << proc.Name.squeeze(" ")
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
processor_list.each_with_index do |name, i|
|
130
|
+
Facter.add("Processor#{i}") do
|
131
|
+
confine :kernel => :windows
|
132
|
+
setcode do
|
133
|
+
name
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
Facter.add("ProcessorCount") do
|
139
|
+
confine :kernel => :windows
|
140
|
+
setcode do
|
141
|
+
processor_list.length.to_s
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
data/lib/facter/ps.rb
CHANGED
data/lib/facter/selinux.rb
CHANGED
@@ -10,69 +10,84 @@
|
|
10
10
|
# Fact for SElinux
|
11
11
|
# Written by immerda admin team (admin(at)immerda.ch)
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
sestatus_cmd = '/usr/sbin/sestatus'
|
14
|
+
|
15
|
+
# This supports the fact that the selinux mount point is not always in the
|
16
|
+
# same location -- the selinux mount point is operating system specific.
|
17
|
+
def selinux_mount_point
|
18
|
+
if FileTest.exists?('/proc/self/mountinfo')
|
19
|
+
File.open('/proc/self/mountinfo') do |f|
|
20
|
+
f.grep(/selinuxfs/) do |line|
|
21
|
+
line.split[4]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
else
|
25
|
+
"/selinux"
|
26
|
+
end
|
27
|
+
end
|
15
28
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
29
|
+
Facter.add("selinux") do
|
30
|
+
confine :kernel => :linux
|
31
|
+
setcode do
|
32
|
+
result = "false"
|
33
|
+
if FileTest.exists?("#{selinux_mount_point}/enforce")
|
34
|
+
if FileTest.exists?("/proc/self/attr/current")
|
35
|
+
if (File.read("/proc/self/attr/current") != "kernel\0")
|
36
|
+
result = "true"
|
24
37
|
end
|
25
|
-
|
38
|
+
end
|
26
39
|
end
|
40
|
+
result
|
41
|
+
end
|
27
42
|
end
|
28
43
|
|
29
44
|
Facter.add("selinux_enforced") do
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
37
|
-
result
|
45
|
+
confine :selinux => :true
|
46
|
+
setcode do
|
47
|
+
result = "false"
|
48
|
+
if FileTest.exists?("#{selinux_mount_point}/enforce") and
|
49
|
+
File.read("#{selinux_mount_point}/enforce") =~ /1/i
|
50
|
+
result = "true"
|
38
51
|
end
|
52
|
+
result
|
53
|
+
end
|
39
54
|
end
|
40
55
|
|
41
56
|
Facter.add("selinux_policyversion") do
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
57
|
+
confine :selinux => :true
|
58
|
+
setcode do
|
59
|
+
File.read("#{selinux_mount_point}/policyvers")
|
60
|
+
end
|
46
61
|
end
|
47
62
|
|
48
63
|
Facter.add("selinux_current_mode") do
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
64
|
+
confine :selinux => :true
|
65
|
+
setcode do
|
66
|
+
result = 'unknown'
|
67
|
+
mode = Facter::Util::Resolution.exec(sestatus_cmd)
|
68
|
+
mode.each_line { |l| result = $1 if l =~ /^Current mode\:\s+(\w+)$/i }
|
69
|
+
result.chomp
|
70
|
+
end
|
56
71
|
end
|
57
72
|
|
58
73
|
Facter.add("selinux_config_mode") do
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
74
|
+
confine :selinux => :true
|
75
|
+
setcode do
|
76
|
+
result = 'unknown'
|
77
|
+
mode = Facter::Util::Resolution.exec(sestatus_cmd)
|
78
|
+
mode.each_line { |l| result = $1 if l =~ /^Mode from config file\:\s+(\w+)$/i }
|
79
|
+
result.chomp
|
80
|
+
end
|
66
81
|
end
|
67
82
|
|
68
83
|
Facter.add("selinux_config_policy") do
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
84
|
+
confine :selinux => :true
|
85
|
+
setcode do
|
86
|
+
result = 'unknown'
|
87
|
+
mode = Facter::Util::Resolution.exec(sestatus_cmd)
|
88
|
+
mode.each_line { |l| result = $1 if l =~ /^Policy from config file\:\s+(\w+)$/i }
|
89
|
+
result.chomp
|
90
|
+
end
|
76
91
|
end
|
77
92
|
|
78
93
|
# This is a legacy fact which returns the old selinux_mode fact value to prevent
|
@@ -80,8 +95,8 @@ end
|
|
80
95
|
# See ticket #6677.
|
81
96
|
|
82
97
|
Facter.add("selinux_mode") do
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
98
|
+
confine :selinux => :true
|
99
|
+
setcode do
|
100
|
+
Facter.value(:selinux_config_policy)
|
101
|
+
end
|
87
102
|
end
|
data/lib/facter/uniqueid.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
Facter.add(:uniqueid) do
|
2
|
-
setcode 'hostid'
|
3
|
-
confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS SuSE SLES Debian Ubuntu Gentoo AIX OEL OVS GNU/kFreeBSD}
|
2
|
+
setcode 'hostid'
|
3
|
+
confine :operatingsystem => %w{Solaris Linux Fedora RedHat CentOS Scientific SLC SuSE SLES Debian Ubuntu Gentoo AIX OEL OracleLinux OVS GNU/kFreeBSD}
|
4
4
|
end
|
data/lib/facter/util/ip.rb
CHANGED
@@ -27,12 +27,17 @@ module Facter::Util::IP
|
|
27
27
|
:ipaddress => /\s+inet (\S+)\s.*/,
|
28
28
|
:macaddress => /(\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2})/,
|
29
29
|
:netmask => /.*\s+netmask (\S+)\s.*/
|
30
|
+
},
|
31
|
+
:windows => {
|
32
|
+
:ipaddress => /\s+IP Address:\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
|
33
|
+
:ipaddress6 => /Address ((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/,
|
34
|
+
:netmask => /\s+Subnet Prefix:\s+\S+\s+\(mask ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\)/
|
30
35
|
}
|
31
36
|
}
|
32
37
|
|
33
|
-
# Convert an interface name into purely
|
38
|
+
# Convert an interface name into purely alphanumeric characters.
|
34
39
|
def self.alphafy(interface)
|
35
|
-
interface.gsub(/[
|
40
|
+
interface.gsub(/[^a-z0-9_]/i, '_')
|
36
41
|
end
|
37
42
|
|
38
43
|
def self.convert_from_hex?(kernel)
|
@@ -55,6 +60,10 @@ module Facter::Util::IP
|
|
55
60
|
def self.get_interfaces
|
56
61
|
return [] unless output = Facter::Util::IP.get_all_interface_output()
|
57
62
|
|
63
|
+
# windows interface names contain spaces and are quoted and can appear multiple
|
64
|
+
# times as ipv4 and ipv6
|
65
|
+
return output.scan(/\s* connected\s*(\S.*)/).flatten.uniq if Facter.value(:kernel) == 'windows'
|
66
|
+
|
58
67
|
# Our regex appears to be stupid, in that it leaves colons sitting
|
59
68
|
# at the end of interfaces. So, we have to trim those trailing
|
60
69
|
# characters. I tried making the regex better but supporting all
|
@@ -70,6 +79,9 @@ module Facter::Util::IP
|
|
70
79
|
output = %x{/usr/sbin/ifconfig -a}
|
71
80
|
when 'HP-UX'
|
72
81
|
output = %x{/bin/netstat -in | sed -e 1d}
|
82
|
+
when 'windows'
|
83
|
+
output = %x|#{ENV['SYSTEMROOT']}/system32/netsh interface ip show interface|
|
84
|
+
output += %x|#{ENV['SYSTEMROOT']}/system32/netsh interface ipv6 show interface|
|
73
85
|
end
|
74
86
|
output
|
75
87
|
end
|
@@ -91,6 +103,17 @@ module Facter::Util::IP
|
|
91
103
|
output
|
92
104
|
end
|
93
105
|
|
106
|
+
def self.get_output_for_interface_and_label(interface, label)
|
107
|
+
return get_single_interface_output(interface) unless Facter.value(:kernel) == 'windows'
|
108
|
+
|
109
|
+
if label == 'ipaddress6'
|
110
|
+
output = %x|#{ENV['SYSTEMROOT']}/system32/netsh interface ipv6 show address \"#{interface}\"|
|
111
|
+
else
|
112
|
+
output = %x|#{ENV['SYSTEMROOT']}/system32/netsh interface ip show address \"#{interface}\"|
|
113
|
+
end
|
114
|
+
output
|
115
|
+
end
|
116
|
+
|
94
117
|
def self.get_bonding_master(interface)
|
95
118
|
if Facter.value(:kernel) != 'Linux'
|
96
119
|
return nil
|
@@ -139,7 +162,7 @@ module Facter::Util::IP
|
|
139
162
|
hwaddrre = /^Slave Interface: #{interface}\n[^\n].+?\nPermanent HW addr: (([0-9a-fA-F]{2}:?)*)$/m
|
140
163
|
value = hwaddrre.match(bondinfo.to_s)[1].upcase
|
141
164
|
else
|
142
|
-
output_int =
|
165
|
+
output_int = get_output_for_interface_and_label(interface, label)
|
143
166
|
|
144
167
|
output_int.each_line do |s|
|
145
168
|
if s =~ regex
|
data/lib/facter/util/loader.rb
CHANGED
@@ -2,6 +2,11 @@ require 'facter'
|
|
2
2
|
|
3
3
|
# Load facts on demand.
|
4
4
|
class Facter::Util::Loader
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@loaded = []
|
8
|
+
end
|
9
|
+
|
5
10
|
# Load all resolutions for a single fact.
|
6
11
|
def load(fact)
|
7
12
|
# Now load from the search path
|
@@ -68,10 +73,16 @@ class Facter::Util::Loader
|
|
68
73
|
end
|
69
74
|
|
70
75
|
def load_file(file)
|
76
|
+
return if @loaded.include? file
|
71
77
|
# We have to specify Kernel.load, because we have a load method.
|
72
78
|
begin
|
79
|
+
# Store the file path so we don't try to reload it
|
80
|
+
@loaded << file
|
73
81
|
Kernel.load(file)
|
74
82
|
rescue ScriptError => detail
|
83
|
+
# Don't store the path if the file can't be loaded
|
84
|
+
# in case it's loadable later on.
|
85
|
+
@loaded.delete(file)
|
75
86
|
warn "Error loading fact #{file} #{detail}"
|
76
87
|
end
|
77
88
|
end
|
@@ -2,6 +2,10 @@
|
|
2
2
|
#
|
3
3
|
module Facter::Util::Macaddress
|
4
4
|
|
5
|
+
def self.standardize(macaddress)
|
6
|
+
macaddress.split(":").map{|x| "0#{x}"[-2..-1]}.join(":")
|
7
|
+
end
|
8
|
+
|
5
9
|
module Darwin
|
6
10
|
def self.macaddress
|
7
11
|
iface = default_interface
|
@@ -25,4 +29,20 @@ module Facter::Util::Macaddress
|
|
25
29
|
'/sbin/ifconfig'
|
26
30
|
end
|
27
31
|
end
|
32
|
+
|
33
|
+
module Windows
|
34
|
+
def macaddress
|
35
|
+
require 'facter/util/wmi'
|
36
|
+
|
37
|
+
query = "select MACAddress from Win32_NetworkAdapterConfiguration where IPEnabled = True"
|
38
|
+
|
39
|
+
ether = nil
|
40
|
+
Facter::Util::WMI.execquery(query).each do |nic|
|
41
|
+
ether = nic.MacAddress
|
42
|
+
break
|
43
|
+
end
|
44
|
+
ether
|
45
|
+
end
|
46
|
+
module_function :macaddress
|
47
|
+
end
|
28
48
|
end
|
@@ -53,9 +53,9 @@ module Facter::Manufacturer
|
|
53
53
|
def self.sysctl_find_system_info(name)
|
54
54
|
name.each do |sysctlkey,facterkey|
|
55
55
|
Facter.add(facterkey) do
|
56
|
-
confine :kernel => :openbsd
|
56
|
+
confine :kernel => [:openbsd, :darwin]
|
57
57
|
setcode do
|
58
|
-
Facter::Util::Resolution.exec("sysctl -n "
|
58
|
+
Facter::Util::Resolution.exec("sysctl -n #{sysctlkey} 2>/dev/null")
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
@@ -79,12 +79,18 @@ module Facter::Manufacturer
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
82
|
+
|
83
|
+
Facter.add('serialnumber') do
|
84
|
+
setcode do
|
85
|
+
Facter::Util::Resolution.exec("/usr/sbin/sneep")
|
86
|
+
end
|
87
|
+
end
|
82
88
|
end
|
83
89
|
|
84
90
|
def self.win32_find_system_info(name)
|
85
|
-
require '
|
91
|
+
require 'facter/util/wmi'
|
86
92
|
value = ""
|
87
|
-
wmi =
|
93
|
+
wmi = Facter::Util::WMI.connect()
|
88
94
|
name.each do |facterkey, win32key|
|
89
95
|
query = wmi.ExecQuery("select * from Win32_#{win32key.last}")
|
90
96
|
Facter.add(facterkey) do
|
@@ -96,5 +102,4 @@ module Facter::Manufacturer
|
|
96
102
|
end
|
97
103
|
end
|
98
104
|
end
|
99
|
-
|
100
105
|
end
|
@@ -4,16 +4,14 @@
|
|
4
4
|
# confinements specified must all be true for the resolution to be
|
5
5
|
# suitable.
|
6
6
|
require 'facter/util/confine'
|
7
|
+
require 'facter/util/config'
|
7
8
|
|
8
9
|
require 'timeout'
|
9
|
-
require 'rbconfig'
|
10
10
|
|
11
11
|
class Facter::Util::Resolution
|
12
12
|
attr_accessor :interpreter, :code, :name, :timeout
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
INTERPRETER = WINDOWS ? 'cmd.exe' : '/bin/sh'
|
14
|
+
INTERPRETER = Facter::Util::Config.is_windows? ? "cmd.exe" : "/bin/sh"
|
17
15
|
|
18
16
|
def self.have_which
|
19
17
|
if ! defined?(@have_which) or @have_which.nil?
|
@@ -32,8 +30,8 @@ class Facter::Util::Resolution
|
|
32
30
|
# Returns nil if the program can't be found, or if there is a problem
|
33
31
|
# executing the code.
|
34
32
|
#
|
35
|
-
def self.exec(code, interpreter =
|
36
|
-
|
33
|
+
def self.exec(code, interpreter = nil)
|
34
|
+
Facter.warnonce "The interpreter parameter to 'exec' is deprecated and will be removed in a future version." if interpreter
|
37
35
|
|
38
36
|
# Try to guess whether the specified code can be executed by looking at the
|
39
37
|
# first word. If it cannot be found on the PATH defer on resolving the fact
|
@@ -45,7 +43,7 @@ class Facter::Util::Resolution
|
|
45
43
|
# Windows' %x{} throws Errno::ENOENT when the command is not found, so we
|
46
44
|
# can skip the check there. This is good, since builtins cannot be found
|
47
45
|
# elsewhere.
|
48
|
-
if have_which and !
|
46
|
+
if have_which and !Facter::Util::Config.is_windows?
|
49
47
|
path = nil
|
50
48
|
binary = code.split.first
|
51
49
|
if code =~ /^\//
|
@@ -116,6 +114,7 @@ class Facter::Util::Resolution
|
|
116
114
|
|
117
115
|
# Set our code for returning a value.
|
118
116
|
def setcode(string = nil, interp = nil, &block)
|
117
|
+
Facter.warnonce "The interpreter parameter to 'setcode' is deprecated and will be removed in a future version." if interp
|
119
118
|
if string
|
120
119
|
@code = string
|
121
120
|
@interpreter = interp || INTERPRETER
|
@@ -127,6 +126,16 @@ class Facter::Util::Resolution
|
|
127
126
|
end
|
128
127
|
end
|
129
128
|
|
129
|
+
def interpreter
|
130
|
+
Facter.warnonce "The 'Facter::Util::Resolution.interpreter' method is deprecated and will be removed in a future version."
|
131
|
+
@interpreter
|
132
|
+
end
|
133
|
+
|
134
|
+
def interpreter=(interp)
|
135
|
+
Facter.warnonce "The 'Facter::Util::Resolution.interpreter=' method is deprecated and will be removed in a future version."
|
136
|
+
@interpreter = interp
|
137
|
+
end
|
138
|
+
|
130
139
|
# Is this resolution mechanism suitable on the system in question?
|
131
140
|
def suitable?
|
132
141
|
unless defined? @suitable
|
@@ -143,7 +152,7 @@ class Facter::Util::Resolution
|
|
143
152
|
# How we get a value for our resolution mechanism.
|
144
153
|
def value
|
145
154
|
result = nil
|
146
|
-
return result if @code == nil
|
155
|
+
return result if @code == nil
|
147
156
|
|
148
157
|
starttime = Time.now.to_f
|
149
158
|
|
@@ -152,7 +161,7 @@ class Facter::Util::Resolution
|
|
152
161
|
if @code.is_a?(Proc)
|
153
162
|
result = @code.call()
|
154
163
|
else
|
155
|
-
result = Facter::Util::Resolution.exec(@code
|
164
|
+
result = Facter::Util::Resolution.exec(@code)
|
156
165
|
end
|
157
166
|
end
|
158
167
|
rescue Timeout::Error => detail
|