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.

Files changed (63) hide show
  1. data/CHANGELOG +53 -0
  2. data/CONTRIBUTING.md +299 -0
  3. data/Rakefile +3 -3
  4. data/conf/redhat/facter.spec +1 -1
  5. data/install.rb +25 -10
  6. data/lib/facter.rb +16 -1
  7. data/lib/facter/arp.rb +1 -1
  8. data/lib/facter/augeasversion.rb +29 -0
  9. data/lib/facter/domain.rb +9 -10
  10. data/lib/facter/hardwareisa.rb +2 -2
  11. data/lib/facter/hostname.rb +4 -9
  12. data/lib/facter/ipaddress6.rb +9 -0
  13. data/lib/facter/kernel.rb +3 -3
  14. data/lib/facter/kernelrelease.rb +2 -4
  15. data/lib/facter/lsbmajdistrelease.rb +1 -1
  16. data/lib/facter/macaddress.rb +11 -31
  17. data/lib/facter/manufacturer.rb +5 -0
  18. data/lib/facter/memory.rb +32 -4
  19. data/lib/facter/operatingsystem.rb +6 -0
  20. data/lib/facter/operatingsystemrelease.rb +11 -2
  21. data/lib/facter/physicalprocessorcount.rb +8 -0
  22. data/lib/facter/processor.rb +38 -0
  23. data/lib/facter/ps.rb +5 -0
  24. data/lib/facter/selinux.rb +63 -48
  25. data/lib/facter/uniqueid.rb +2 -2
  26. data/lib/facter/util/config.rb +9 -0
  27. data/lib/facter/util/ip.rb +26 -3
  28. data/lib/facter/util/loader.rb +11 -0
  29. data/lib/facter/util/macaddress.rb +20 -0
  30. data/lib/facter/util/manufacturer.rb +10 -5
  31. data/lib/facter/util/resolution.rb +18 -9
  32. data/lib/facter/util/uptime.rb +6 -5
  33. data/lib/facter/util/wmi.rb +16 -0
  34. data/lib/facter/virtual.rb +15 -8
  35. data/spec/fixtures/netsh/windows_netsh_addresses_with_multiple_interfaces +35 -0
  36. data/spec/fixtures/unit/util/loader/nosuchfact.rb +1 -0
  37. data/spec/spec_helper.rb +1 -0
  38. data/spec/unit/data/windows_netsh_all_interfaces +12 -0
  39. data/spec/unit/data/windows_netsh_single_interface +7 -0
  40. data/spec/unit/data/windows_netsh_single_interface6 +18 -0
  41. data/spec/unit/domain_spec.rb +91 -0
  42. data/spec/unit/facter_spec.rb +21 -0
  43. data/spec/unit/hostname_spec.rb +38 -0
  44. data/spec/unit/id_spec.rb +6 -5
  45. data/spec/unit/interfaces_spec.rb +7 -0
  46. data/spec/unit/ipaddress6_spec.rb +19 -0
  47. data/spec/unit/macaddress_spec.rb +38 -0
  48. data/spec/unit/memory_spec.rb +26 -0
  49. data/spec/unit/operatingsystem_spec.rb +28 -0
  50. data/spec/unit/operatingsystemrelease_spec.rb +19 -8
  51. data/spec/unit/physicalprocessorcount_spec.rb +11 -0
  52. data/spec/unit/processor_spec.rb +66 -0
  53. data/spec/unit/selinux_spec.rb +1 -0
  54. data/spec/unit/util/ip_spec.rb +83 -21
  55. data/spec/unit/util/loader_spec.rb +8 -0
  56. data/spec/unit/util/macaddress_spec.rb +28 -1
  57. data/spec/unit/util/manufacturer_spec.rb +21 -0
  58. data/spec/unit/util/resolution_spec.rb +26 -14
  59. data/spec/unit/util/uptime_spec.rb +7 -1
  60. data/spec/unit/util/wmi_spec.rb +20 -0
  61. data/spec/unit/virtual_spec.rb +41 -5
  62. metadata +19 -8
  63. data/spec/spec.opts +0 -5
@@ -8,12 +8,13 @@ module Facter::Util::Uptime
8
8
  end
9
9
 
10
10
  def self.get_uptime_seconds_win
11
- require 'win32ole'
12
- wmi = WIN32OLE.connect("winmgmts://")
13
- query = wmi.ExecQuery("select * from Win32_OperatingSystem")
11
+ require 'facter/util/wmi'
12
+
14
13
  last_boot = ""
15
- query.each { |x| last_boot = x.LastBootupTime}
16
- self.compute_uptime(Time.parse(last_boot.split('.').first))
14
+ Facter::Util::WMI.execquery("select * from Win32_OperatingSystem").each do |x|
15
+ last_boot = x.LastBootupTime
16
+ end
17
+ self.compute_uptime(Time.parse(last_boot.split('.').first))
17
18
  end
18
19
 
19
20
  private
@@ -0,0 +1,16 @@
1
+ module Facter::Util::WMI
2
+ class << self
3
+ def connect(uri = wmi_resource_uri)
4
+ require 'win32ole'
5
+ WIN32OLE.connect(uri)
6
+ end
7
+
8
+ def wmi_resource_uri( host = '.' )
9
+ "winmgmts:{impersonationLevel=impersonate}!//#{host}/root/cimv2"
10
+ end
11
+
12
+ def execquery(query)
13
+ connect().execquery(query)
14
+ end
15
+ end
16
+ end
@@ -110,6 +110,9 @@ Facter.add("virtual") do
110
110
  # --- look for pci vendor id used by Parallels video card
111
111
  # --- 01:00.0 VGA compatible controller: Unknown device 1ab8:4005
112
112
  result = "parallels" if p =~ /1ab8:|[Pp]arallels/
113
+ # --- look for pci vendor id used by Xen HVM device
114
+ # --- 00:03.0 Unassigned class [ff80]: XenSource, Inc. Xen Platform Device (rev 01)
115
+ result = "xenhvm" if p =~ /XenSource/
113
116
  end
114
117
  else
115
118
  output = Facter::Util::Resolution.exec('dmidecode')
@@ -118,6 +121,7 @@ Facter.add("virtual") do
118
121
  result = "parallels" if pd =~ /Parallels/
119
122
  result = "vmware" if pd =~ /VMware/
120
123
  result = "virtualbox" if pd =~ /VirtualBox/
124
+ result = "xenhvm" if pd =~ /HVM domU/
121
125
  end
122
126
  elsif Facter.value(:kernel) == 'SunOS'
123
127
  res = Facter::Util::Resolution.new('prtdiag')
@@ -129,13 +133,14 @@ Facter.add("virtual") do
129
133
  result = "parallels" if pd =~ /Parallels/
130
134
  result = "vmware" if pd =~ /VMware/
131
135
  result = "virtualbox" if pd =~ /VirtualBox/
136
+ result = "xenhvm" if pd =~ /HVM domU/
132
137
  end
133
138
  end
134
139
  end
135
140
  end
136
141
 
137
- if FileTest.exists?("/usr/lib/vmware/bin/vmware-vmx")
138
- result = "vmware_server"
142
+ if output = Facter::Util::Resolution.exec("vmware -v")
143
+ result = output.sub(/(\S+)\s+(\S+).*/) { | text | "#{$1}_#{$2}"}.downcase
139
144
  end
140
145
  end
141
146
 
@@ -147,9 +152,9 @@ end
147
152
  #
148
153
  # Purpose: returning true or false for if a machine is virtualised or not.
149
154
  #
150
- # Resolution: The Xen domain 0 machine is virtualised to a degree, but is generally
151
- # not viewed as being a virtual machine. This checks that the machine is not
152
- # physical nor xen0, if that is the case, it is virtual.
155
+ # Resolution: Hypervisors and the like may be detected as a virtual type, but
156
+ # are not actual virtual machines, or should not be treated as such. This
157
+ # determines if the host is actually virtualized.
153
158
  #
154
159
  # Caveats:
155
160
  #
@@ -158,10 +163,12 @@ Facter.add("is_virtual") do
158
163
  confine :kernel => %w{Linux FreeBSD OpenBSD SunOS HP-UX Darwin GNU/kFreeBSD}
159
164
 
160
165
  setcode do
161
- if Facter.value(:virtual) != "physical" && Facter.value(:virtual) != "xen0"
162
- "true"
163
- else
166
+ physical_types = %w{physical xen0 vmware_server vmware_workstation openvzhn}
167
+
168
+ if physical_types.include? Facter.value(:virtual)
164
169
  "false"
170
+ else
171
+ "true"
165
172
  end
166
173
  end
167
174
  end
@@ -0,0 +1,35 @@
1
+ Address ::1 Parameters
2
+ ---------------------------------------------------------
3
+ Interface Luid : Loopback Pseudo-Interface 1
4
+ Scope Id : 0.0
5
+ Valid Lifetime : infinite
6
+ Preferred Lifetime : infinite
7
+ DAD State : Preferred
8
+ Address Type : Other
9
+
10
+ Address fe80::7128:aa90:8f2a:8375%9 Parameters
11
+ ---------------------------------------------------------
12
+ Interface Luid : Local Area Connection
13
+ Scope Id : 0.9
14
+ Valid Lifetime : infinite
15
+ Preferred Lifetime : infinite
16
+ DAD State : Preferred
17
+ Address Type : Other
18
+
19
+ Address fe80::5efe:172.16.138.216%11 Parameters
20
+ ---------------------------------------------------------
21
+ Interface Luid : isatap.localdomain
22
+ Scope Id : 0.11
23
+ Valid Lifetime : infinite
24
+ Preferred Lifetime : infinite
25
+ DAD State : Deprecated
26
+ Address Type : Other
27
+
28
+ Address 2001:0:4137:9e76:2087:77a:53ef:7527 Parameters
29
+ ---------------------------------------------------------
30
+ Interface Luid : Teredo Tunneling Pseudo-Interface
31
+ Scope Id : 0.0
32
+ Valid Lifetime : infinite
33
+ Preferred Lifetime : infinite
34
+ DAD State : Preferred
35
+ Address Type : Public
@@ -0,0 +1 @@
1
+ Facter.value(:nosuchfact)
@@ -20,5 +20,6 @@ RSpec.configure do |config|
20
20
  config.before :each do
21
21
  Facter::Util::Loader.any_instance.stubs(:load_all)
22
22
  Facter.clear
23
+ Facter.clear_messages
23
24
  end
24
25
  end
@@ -0,0 +1,12 @@
1
+ Idx Met MTU State Name
2
+ --- ---------- ---------- ------------ ---------------------------
3
+ 1 50 4294967295 connected Loopback Pseudo-Interface 1
4
+ 9 10 1500 connected Local Area Connection
5
+
6
+
7
+ Idx Met MTU State Name
8
+ --- ---------- ---------- ------------ ---------------------------
9
+ 1 50 4294967295 connected Loopback Pseudo-Interface 1
10
+ 9 10 1500 connected Local Area Connection
11
+ 11 50 1280 disconnected isatap.localdomain
12
+ 12 50 1280 connected Teredo Tunneling Pseudo-Interface
@@ -0,0 +1,7 @@
1
+ Configuration for interface "Local Area Connection"
2
+ DHCP enabled: Yes
3
+ IP Address: 172.16.138.216
4
+ Subnet Prefix: 172.16.138.0/24 (mask 255.255.255.0)
5
+ Default Gateway: 172.16.138.2
6
+ Gateway Metric: 0
7
+ InterfaceMetric: 10
@@ -0,0 +1,18 @@
1
+
2
+ Address fe80::2087:77a:53ef:7527%12 Parameters
3
+ ---------------------------------------------------------
4
+ Interface Luid : Teredo Tunneling Pseudo-Interface
5
+ Scope Id : 0.12
6
+ Valid Lifetime : infinite
7
+ Preferred Lifetime : infinite
8
+ DAD State : Preferred
9
+ Address Type : Other
10
+
11
+ Address 2001:0:4137:9e76:2087:77a:53ef:7527 Parameters
12
+ ---------------------------------------------------------
13
+ Interface Luid : Teredo Tunneling Pseudo-Interface
14
+ Scope Id : 0.0
15
+ Valid Lifetime : infinite
16
+ Preferred Lifetime : infinite
17
+ DAD State : Preferred
18
+ Address Type : Public
@@ -0,0 +1,91 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Domain name facts" do
4
+
5
+ describe "on linux" do
6
+ before do
7
+ Facter.fact(:kernel).stubs(:value).returns("Linux")
8
+ FileTest.stubs(:exists?).with("/etc/resolv.conf").returns(true)
9
+ end
10
+
11
+ it "should use the hostname binary" do
12
+ Facter::Util::Resolution.expects(:exec).with("hostname").returns "test.example.com"
13
+ Facter.fact(:domain).value.should == "example.com"
14
+ end
15
+
16
+ it "should fall back to the dnsdomainname binary" do
17
+ Facter::Util::Resolution.expects(:exec).with("hostname").returns("myhost")
18
+ Facter::Util::Resolution.expects(:exec).with("dnsdomainname").returns("example.com")
19
+ Facter.fact(:domain).value.should == "example.com"
20
+ end
21
+
22
+
23
+ it "should fall back to /etc/resolv.conf" do
24
+ Facter::Util::Resolution.expects(:exec).with("hostname").at_least_once.returns("myhost")
25
+ Facter::Util::Resolution.expects(:exec).with("dnsdomainname").at_least_once.returns("")
26
+ File.expects(:open).with('/etc/resolv.conf').at_least_once
27
+ Facter.fact(:domain).value
28
+ end
29
+
30
+ it "should attempt to resolve facts in a specific order" do
31
+ seq = sequence('domain')
32
+ Facter::Util::Resolution.stubs(:exec).with("hostname").in_sequence(seq).at_least_once
33
+ Facter::Util::Resolution.stubs(:exec).with("dnsdomainname").in_sequence(seq).at_least_once
34
+ File.expects(:open).with('/etc/resolv.conf').in_sequence(seq).at_least_once
35
+ Facter.fact(:domain).value
36
+ end
37
+
38
+ describe "when using /etc/resolv.conf" do
39
+ before do
40
+ Facter::Util::Resolution.stubs(:exec).with("hostname")
41
+ Facter::Util::Resolution.stubs(:exec).with("dnsdomainname")
42
+ @mock_file = mock()
43
+ File.stubs(:open).with("/etc/resolv.conf").yields(@mock_file)
44
+ end
45
+
46
+ it "should use the domain field over the search field" do
47
+ lines = [
48
+ "nameserver 4.2.2.1",
49
+ "search example.org",
50
+ "domain example.com",
51
+ ]
52
+ @mock_file.expects(:each).multiple_yields(*lines)
53
+ Facter.fact(:domain).value.should == 'example.com'
54
+ end
55
+
56
+ it "should fall back to the search field" do
57
+ lines = [
58
+ "nameserver 4.2.2.1",
59
+ "search example.org",
60
+ ]
61
+ @mock_file.expects(:each).multiple_yields(*lines)
62
+ Facter.fact(:domain).value.should == 'example.org'
63
+ end
64
+
65
+ it "should use the first domain in the search field" do
66
+ lines = [
67
+ "search example.org example.net",
68
+ ]
69
+ @mock_file.expects(:each).multiple_yields(*lines)
70
+ Facter.fact(:domain).value.should == 'example.org'
71
+ end
72
+ end
73
+ end
74
+
75
+ describe "on Windows" do
76
+ it "should use the DNSDomain for the first nic where ip is enabled" do
77
+ Facter.fact(:kernel).stubs(:value).returns("windows")
78
+
79
+ nic = stubs 'nic'
80
+ nic.stubs(:DNSDomain).returns("foo.com")
81
+
82
+ nic2 = stubs 'nic'
83
+ nic2.stubs(:DNSDomain).returns("bar.com")
84
+
85
+ require 'facter/util/wmi'
86
+ Facter::Util::WMI.stubs(:execquery).with("select DNSDomain from Win32_NetworkAdapterConfiguration where IPEnabled = True").returns([nic, nic2])
87
+
88
+ Facter.fact(:domain).value.should == 'foo.com'
89
+ end
90
+ end
91
+ end
@@ -185,6 +185,27 @@ describe Facter do
185
185
  end
186
186
  end
187
187
 
188
+ describe "when warning once" do
189
+ it "should only warn once" do
190
+ Kernel.stubs(:warnonce)
191
+ Kernel.expects(:warn).with('foo').once
192
+ Facter.warnonce('foo')
193
+ Facter.warnonce('foo')
194
+ end
195
+
196
+ it "should not warnonce if nil is passed" do
197
+ Kernel.stubs(:warn)
198
+ Kernel.expects(:warnonce).never
199
+ Facter.warnonce(nil)
200
+ end
201
+
202
+ it "should not warnonce if an empty string is passed" do
203
+ Kernel.stubs(:warn)
204
+ Kernel.expects(:warnonce).never
205
+ Facter.warnonce('')
206
+ end
207
+ end
208
+
188
209
  describe "when setting debugging mode" do
189
210
  it "should have debugging enabled using 1" do
190
211
  Facter.debugging(1)
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Hostname facts" do
4
+
5
+ describe "on linux" do
6
+ before do
7
+ Facter.fact(:kernel).stubs(:value).returns("Linux")
8
+ Facter.fact(:kernelrelease).stubs(:value).returns("2.6")
9
+ end
10
+
11
+ it "should use the hostname command" do
12
+ Facter::Util::Resolution.expects(:exec).with('hostname').at_least_once
13
+ Facter.fact(:hostname).value.should be_nil
14
+ end
15
+
16
+ it "should use hostname as the fact if unqualified" do
17
+ Facter::Util::Resolution.stubs(:exec).with('hostname').returns('host1')
18
+ Facter.fact(:hostname).value.should == "host1"
19
+ end
20
+
21
+ it "should truncate the domain name if qualified" do
22
+ Facter::Util::Resolution.stubs(:exec).with('hostname').returns('host1.example.com')
23
+ Facter.fact(:hostname).value.should == "host1"
24
+ end
25
+ end
26
+
27
+ describe "on darwin release R7" do
28
+ before do
29
+ Facter.fact(:kernel).stubs(:value).returns("Darwin")
30
+ Facter.fact(:kernelrelease).stubs(:value).returns("R7")
31
+ end
32
+
33
+ it "should use scutil to get the hostname" do
34
+ Facter::Util::Resolution.expects(:exec).with('/usr/sbin/scutil --get LocalHostName').returns("host1")
35
+ Facter.fact(:hostname).value.should == "host1"
36
+ end
37
+ end
38
+ end
@@ -9,9 +9,9 @@ describe "id fact" do
9
9
  kernel.each do |k|
10
10
  describe "with kernel reported as #{k}" do
11
11
  it "should return the current user" do
12
- Facter::Util::Resolution.stubs(:exec).with('uname -s').returns(k)
13
- Facter::Util::Resolution.stubs(:exec).with('lsb_release -a 2>/dev/null').returns('foo')
14
- Facter::Util::Resolution.expects(:exec).once.with('whoami', '/bin/sh').returns 'bar'
12
+ Facter.fact(:kernel).stubs(:value).returns(k)
13
+ Facter::Util::Config.stubs(:is_windows?).returns(k == 'windows')
14
+ Facter::Util::Resolution.expects(:exec).once.with('whoami').returns 'bar'
15
15
 
16
16
  Facter.fact(:id).value.should == 'bar'
17
17
  end
@@ -19,9 +19,10 @@ describe "id fact" do
19
19
  end
20
20
 
21
21
  it "should return the current user on Solaris" do
22
+ Facter::Util::Config.stubs(:is_windows?).returns(false)
22
23
  Facter::Util::Resolution.stubs(:exec).with('uname -s').returns('SunOS')
23
- Facter::Util::Resolution.expects(:exec).once.with('/usr/xpg4/bin/id -un', '/bin/sh').returns 'bar'
24
+ Facter::Util::Resolution.expects(:exec).once.with('/usr/xpg4/bin/id -un').returns 'bar'
24
25
 
25
26
  Facter.fact(:id).value.should == 'bar'
26
- end
27
+ end
27
28
  end
@@ -13,4 +13,11 @@ describe "Per Interface IP facts" do
13
13
  Facter::Util::IP.stubs(:get_interfaces).returns %w{eth0:1 eth1:2}
14
14
  Facter.fact(:interfaces).value.should == %{eth0_1,eth1_2}
15
15
  end
16
+
17
+ it "should replace non-alphanumerics in an interface list with '_'" do
18
+ Facter.fact(:kernel).stubs(:value).returns("windows")
19
+
20
+ Facter::Util::IP.stubs(:get_interfaces).returns ["Local Area Connection", "Loopback \"Pseudo-Interface\" (#1)"]
21
+ Facter.fact(:interfaces).value.should == %{Local_Area_Connection,Loopback__Pseudo_Interface____1_}
22
+ end
16
23
  end
@@ -9,7 +9,15 @@ def ifconfig_fixture(filename)
9
9
  ifconfig = File.new(File.join($basedir, 'fixtures', 'ifconfig', filename)).read
10
10
  end
11
11
 
12
+ def netsh_fixture(filename)
13
+ ifconfig = File.new(File.join($basedir, 'fixtures', 'netsh', filename)).read
14
+ end
15
+
12
16
  describe "IPv6 address fact" do
17
+ before do
18
+ Facter::Util::Config.stubs(:is_windows?).returns(false)
19
+ end
20
+
13
21
  it "should return ipaddress6 information for Darwin" do
14
22
  Facter::Util::Resolution.stubs(:exec).with('uname -s').returns('Darwin')
15
23
  Facter::Util::Resolution.stubs(:exec).with('/sbin/ifconfig -a').
@@ -33,4 +41,15 @@ describe "IPv6 address fact" do
33
41
 
34
42
  Facter.value(:ipaddress6).should == "2610:10:20:209:203:baff:fe27:a7c"
35
43
  end
44
+
45
+ it "should return ipaddress6 information for Windows" do
46
+ ENV.stubs(:[]).with('SYSTEMROOT').returns('d:/windows')
47
+ Facter::Util::Config.stubs(:is_windows?).returns(true)
48
+
49
+ fixture = netsh_fixture('windows_netsh_addresses_with_multiple_interfaces')
50
+ Facter::Util::Resolution.stubs(:exec).with('d:/windows/system32/netsh interface ipv6 show address level=verbose').
51
+ returns(fixture)
52
+
53
+ Facter.value(:ipaddress6).should == "2001:0:4137:9e76:2087:77a:53ef:7527"
54
+ end
36
55
  end
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $basedir = File.expand_path(File.dirname(__FILE__) + '/..')
4
+ require File.join($basedir, 'spec_helper')
5
+
6
+ require 'facter'
7
+
8
+ def ifconfig_fixture(filename)
9
+ ifconfig = File.new(File.join($basedir, 'fixtures', 'ifconfig', filename)).read
10
+ end
11
+
12
+ def netsh_fixture(filename)
13
+ ifconfig = File.new(File.join($basedir, 'fixtures', 'netsh', filename)).read
14
+ end
15
+
16
+ describe "macaddress fact" do
17
+ before do
18
+ Facter::Util::Config.stubs(:is_windows?).returns(false)
19
+ end
20
+
21
+ it "should return macaddress information for Linux" do
22
+ Facter.fact(:kernel).stubs(:value).returns("Linux")
23
+ Facter.fact(:operatingsystem).stubs(:value).returns("Linux")
24
+ Facter::Util::Resolution.stubs(:exec).with('/sbin/ifconfig -a').
25
+ returns(ifconfig_fixture('linux_ifconfig_all_with_multiple_interfaces'))
26
+
27
+ Facter.value(:macaddress).should == "00:12:3f:be:22:01"
28
+ end
29
+
30
+ it "should return macaddress information for BSD" do
31
+ Facter.fact(:kernel).stubs(:value).returns("FreeBSD")
32
+ Facter::Util::Resolution.stubs(:exec).with('/sbin/ifconfig').
33
+ returns(ifconfig_fixture('bsd_ifconfig_all_with_multiple_interfaces'))
34
+
35
+ Facter.value(:macaddress).should == "00:0b:db:93:09:67"
36
+ end
37
+
38
+ end