facter 2.0.2 → 2.1.0

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 (120) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +14 -0
  3. data/ext/project_data.yaml +9 -6
  4. data/lib/facter/core/execution/base.rb +3 -3
  5. data/lib/facter/core/suitable.rb +1 -5
  6. data/lib/facter/dhcp_servers.rb +39 -0
  7. data/lib/facter/ec2.rb +33 -26
  8. data/lib/facter/ec2/rest.rb +130 -0
  9. data/lib/facter/fqdn.rb +2 -0
  10. data/lib/facter/gce.rb +16 -0
  11. data/lib/facter/gce/metadata.rb +87 -0
  12. data/lib/facter/kernelmajversion.rb +8 -0
  13. data/lib/facter/kernelrelease.rb +8 -0
  14. data/lib/facter/memory.rb +21 -15
  15. data/lib/facter/netmask.rb +1 -1
  16. data/lib/facter/operatingsystem.rb +20 -0
  17. data/lib/facter/operatingsystemmajrelease.rb +2 -1
  18. data/lib/facter/operatingsystemrelease.rb +19 -0
  19. data/lib/facter/osfamily.rb +3 -1
  20. data/lib/facter/partitions.rb +35 -0
  21. data/lib/facter/physicalprocessorcount.rb +9 -0
  22. data/lib/facter/processor.rb +25 -25
  23. data/lib/facter/util/config.rb +3 -1
  24. data/lib/facter/util/dhcp_servers.rb +43 -0
  25. data/lib/facter/util/ec2.rb +5 -0
  26. data/lib/facter/util/formatter.rb +2 -1
  27. data/lib/facter/util/ip.rb +1 -1
  28. data/lib/facter/util/loader.rb +10 -1
  29. data/lib/facter/util/manufacturer.rb +15 -16
  30. data/lib/facter/util/memory.rb +12 -12
  31. data/lib/facter/util/netmask.rb +1 -1
  32. data/lib/facter/util/operatingsystem.rb +21 -0
  33. data/lib/facter/util/partitions.rb +41 -0
  34. data/lib/facter/util/partitions/linux.rb +65 -0
  35. data/lib/facter/util/posix.rb +16 -0
  36. data/lib/facter/util/processor.rb +8 -10
  37. data/lib/facter/util/resolution.rb +4 -0
  38. data/lib/facter/util/values.rb +29 -0
  39. data/lib/facter/util/virtual.rb +32 -3
  40. data/lib/facter/util/windows_root.rb +2 -32
  41. data/lib/facter/version.rb +1 -1
  42. data/lib/facter/virtual.rb +53 -12
  43. data/spec/fixtures/ifconfig/openbsd_bridge_rules +11 -0
  44. data/spec/fixtures/unit/dhcp_servers/nmcli_devices +4 -0
  45. data/spec/fixtures/unit/dhcp_servers/nmcli_devices_disconnected +4 -0
  46. data/spec/fixtures/unit/dhcp_servers/nmcli_eth0_dhcp +36 -0
  47. data/spec/fixtures/unit/dhcp_servers/nmcli_eth0_static +24 -0
  48. data/spec/fixtures/unit/dhcp_servers/nmcli_wlan0_dhcp +49 -0
  49. data/spec/fixtures/unit/dhcp_servers/nmcli_wlan0_static +37 -0
  50. data/spec/fixtures/unit/dhcp_servers/route +3 -0
  51. data/spec/fixtures/unit/dhcp_servers/route_nogw +1 -0
  52. data/spec/fixtures/unit/ec2/rest/meta-data/root +20 -0
  53. data/spec/fixtures/unit/gce/metadata/metadata.json +69 -0
  54. data/spec/fixtures/unit/kernelrelease/openbsd-5.3 +2 -0
  55. data/spec/fixtures/unit/kernelrelease/openbsd-5.3-current +3 -0
  56. data/spec/fixtures/unit/memory/aix-svmon +9 -0
  57. data/spec/fixtures/unit/memory/aix-swap_l +2 -0
  58. data/spec/fixtures/unit/memory/darwin-swapinfo-multiple +3 -0
  59. data/spec/fixtures/unit/memory/darwin-swapinfo-single +2 -0
  60. data/spec/fixtures/unit/memory/darwin-vm_stat +13 -0
  61. data/spec/fixtures/unit/memory/dragonfly-vmstat +3 -0
  62. data/spec/fixtures/unit/memory/freebsd-vmstat +3 -0
  63. data/spec/fixtures/unit/memory/linux-proc_meminfo +10 -0
  64. data/spec/fixtures/unit/memory/openbsd-vmstat +3 -0
  65. data/spec/fixtures/unit/memory/smartos_zone_swap_l-single +2 -0
  66. data/spec/fixtures/unit/memory/solaris-prtconf +4 -0
  67. data/spec/fixtures/unit/memory/solaris-swap_l-multiple +3 -0
  68. data/spec/fixtures/unit/memory/solaris-swap_l-single +2 -0
  69. data/spec/fixtures/unit/memory/solaris-vmstat +3 -0
  70. data/spec/fixtures/unit/netmask/ifconfig_aix_7.txt +3 -0
  71. data/spec/fixtures/unit/util/dhcp_servers/route +3 -0
  72. data/spec/fixtures/unit/util/dhcp_servers/route_nogw +1 -0
  73. data/spec/fixtures/unit/util/manufacturer/smartos_smbios +533 -0
  74. data/spec/fixtures/unit/util/operatingsystem/cumuluslinux.txt +8 -0
  75. data/spec/fixtures/unit/util/operatingsystem/redhat-7.txt +12 -0
  76. data/spec/fixtures/unit/util/operatingsystem/sabayon.txt +7 -0
  77. data/spec/fixtures/unit/util/operatingsystem/wheezy.txt +9 -0
  78. data/spec/fixtures/unit/util/partitions/partitions/mount +9 -0
  79. data/spec/fixtures/virtual/proc_1_cgroup/in_a_container +9 -0
  80. data/spec/fixtures/virtual/proc_1_cgroup/in_a_docker_container +8 -0
  81. data/spec/fixtures/virtual/proc_1_cgroup/not_in_a_container +9 -0
  82. data/spec/spec_helper.rb +1 -1
  83. data/spec/unit/core/execution/base_spec.rb +3 -5
  84. data/spec/unit/core/execution/posix_spec.rb +2 -2
  85. data/spec/unit/core/suitable_spec.rb +10 -0
  86. data/spec/unit/dhcp_servers_spec.rb +152 -0
  87. data/spec/unit/ec2/rest_spec.rb +145 -0
  88. data/spec/unit/ec2_spec.rb +87 -147
  89. data/spec/unit/fqdn_spec.rb +16 -0
  90. data/spec/unit/gce/metadata_spec.rb +49 -0
  91. data/spec/unit/gce_spec.rb +34 -0
  92. data/spec/unit/interfaces_spec.rb +9 -9
  93. data/spec/unit/kernelmajversion_spec.rb +14 -9
  94. data/spec/unit/kernelrelease_spec.rb +16 -0
  95. data/spec/unit/macaddress_spec.rb +12 -0
  96. data/spec/unit/memory_spec.rb +53 -122
  97. data/spec/unit/netmask_spec.rb +11 -0
  98. data/spec/unit/operatingsystem_spec.rb +19 -0
  99. data/spec/unit/operatingsystemmajrelease_spec.rb +1 -1
  100. data/spec/unit/operatingsystemrelease_spec.rb +8 -0
  101. data/spec/unit/osfamily_spec.rb +62 -0
  102. data/spec/unit/partitions_spec.rb +48 -0
  103. data/spec/unit/physicalprocessorcount_spec.rb +9 -0
  104. data/spec/unit/processor_spec.rb +15 -7
  105. data/spec/unit/util/config_spec.rb +13 -0
  106. data/spec/unit/util/dhcp_servers_spec.rb +63 -0
  107. data/spec/unit/util/ec2_spec.rb +4 -0
  108. data/spec/unit/util/formatter_spec.rb +50 -0
  109. data/spec/unit/util/loader_spec.rb +4 -4
  110. data/spec/unit/util/macosx_spec.rb +3 -2
  111. data/spec/unit/util/manufacturer_spec.rb +44 -0
  112. data/spec/unit/util/operatingsystem_spec.rb +92 -0
  113. data/spec/unit/util/partitions/partitions_spec.rb +67 -0
  114. data/spec/unit/util/partitions_spec.rb +19 -0
  115. data/spec/unit/util/posix_spec.rb +11 -0
  116. data/spec/unit/util/values_spec.rb +40 -0
  117. data/spec/unit/util/virtual_spec.rb +72 -2
  118. data/spec/unit/virtual_spec.rb +67 -18
  119. metadata +116 -4
  120. data/spec/fixtures/unit/util/loader/nosuchfact.rb +0 -1
@@ -0,0 +1,8 @@
1
+ NAME="Cumulus Linux"
2
+ VERSION_ID=1.5.2
3
+ VERSION="1.5.2-28283a7-201311181623-final"
4
+ PRETTY_NAME="Cumulus Linux"
5
+ ID=cumulus-linux
6
+ ID_LIKE=debian
7
+ CPE_NAME=cpe:/o:cumulusnetworks:cumulus_linux:1.5.2-28283a7-201311181623-final
8
+ HOME_URL="http://www.cumulusnetworks.com/"
@@ -0,0 +1,12 @@
1
+ NAME="Red Hat Enterprise Linux Everything"
2
+ VERSION="7.0 (Maipo)"
3
+ ID="rhel"
4
+ VERSION_ID="7.0"
5
+ PRETTY_NAME="Red Hat Enterprise Linux Everything 7.0 (Maipo)"
6
+ ANSI_COLOR="0;31"
7
+ CPE_NAME="cpe:/o:redhat:enterprise_linux:7.0:beta:everything"
8
+
9
+ REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7"
10
+ REDHAT_BUGZILLA_PRODUCT_VERSION=7.0
11
+ REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
12
+ REDHAT_SUPPORT_PRODUCT_VERSION=7.0
@@ -0,0 +1,7 @@
1
+ NAME=Sabayon
2
+ ID=sabayon
3
+ PRETTY_NAME="Sabayon/Linux"
4
+ ANSI_COLOR="1;32"
5
+ HOME_URL="http://www.sabayon.org/"
6
+ SUPPORT_URL="http://forum.sabayon.org/"
7
+ BUG_REPORT_URL="https://bugs.sabayon.org/"
@@ -0,0 +1,9 @@
1
+ PRETTY_NAME="Debian GNU/Linux 7 (wheezy)"
2
+ NAME="Debian GNU/Linux"
3
+ VERSION_ID="7"
4
+ VERSION="7 (wheezy)"
5
+ ID=debian
6
+ ANSI_COLOR="1;31"
7
+ HOME_URL="http://www.debian.org/"
8
+ SUPPORT_URL="http://www.debian.org/support/"
9
+ BUG_REPORT_URL="http://bugs.debian.org/"
@@ -0,0 +1,9 @@
1
+ proc on /proc type proc (rw,noexec,nosuid,nodev)
2
+ sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
3
+ none on /sys/fs/cgroup type tmpfs (rw)
4
+ udev on /dev type devtmpfs (rw,mode=0755)
5
+ devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
6
+ tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
7
+ /dev/sda1 on /home type ext4 (rw)
8
+ /dev/sdb2 on / type ext4 (rw,errors=remount-ro)
9
+ /dev/sdc3 on /var type ext4 (rw,errors=remount-ro)
@@ -0,0 +1,9 @@
1
+ 9:hugetlb:/lxc/e411045bbbc61eca5d3af7eb0764c30833606f51d20c176f406afbdb47bb04be
2
+ 8:perf_event:/lxc/e411045bbbc61eca5d3af7eb0764c30833606f51d20c176f406afbdb47bb04be
3
+ 7:blkio:/lxc/e411045bbbc61eca5d3af7eb0764c30833606f51d20c176f406afbdb47bb04be
4
+ 6:freezer:/lxc/e411045bbbc61eca5d3af7eb0764c30833606f51d20c176f406afbdb47bb04be
5
+ 5:devices:/lxc/e411045bbbc61eca5d3af7eb0764c30833606f51d20c176f406afbdb47bb04be
6
+ 4:memory:/lxc/e411045bbbc61eca5d3af7eb0764c30833606f51d20c176f406afbdb47bb04be
7
+ 3:cpuacct:/lxc/e411045bbbc61eca5d3af7eb0764c30833606f51d20c176f406afbdb47bb04be
8
+ 2:cpu:/lxc/e411045bbbc61eca5d3af7eb0764c30833606f51d20c176f406afbdb47bb04be
9
+ 1:cpuset:/lxc/e411045bbbc61eca5d3af7eb0764c30833606f51d20c176f406afbdb47bb04be
@@ -0,0 +1,8 @@
1
+ 9:perf_event:/
2
+ 8:blkio:/
3
+ 7:freezer:/
4
+ 6:devices:/docker/0e3c605ac1470c776c34a8eff362a0c816bcaac78559a43955173bd786281b7f
5
+ 5:memory:/
6
+ 4:cpuacct:/
7
+ 3:cpu:/docker/0e3c605ac1470c776c34a8eff362a0c816bcaac78559a43955173bd786281b7f
8
+ 2:cpuset:/
@@ -0,0 +1,9 @@
1
+ 9:hugetlb:/
2
+ 8:perf_event:/
3
+ 7:blkio:/
4
+ 6:freezer:/
5
+ 5:devices:/
6
+ 4:memory:/
7
+ 3:cpuacct:/
8
+ 2:cpu:/
9
+ 1:cpuset:/
@@ -38,7 +38,7 @@ LogSpecOrder.log_spec_order
38
38
  RSpec.configure do |config|
39
39
  config.mock_with :mocha
40
40
 
41
- if Facter::Util::Config.is_windows?
41
+ if Facter::Util::Config.is_windows? && RUBY_VERSION =~ /^1\./
42
42
  require 'win32console'
43
43
  config.output_stream = $stdout
44
44
  config.error_stream = $stderr
@@ -5,7 +5,7 @@ describe Facter::Core::Execution::Base do
5
5
 
6
6
  describe "#with_env" do
7
7
  it "should execute the caller's block with the specified env vars" do
8
- test_env = { "LANG" => "C", "FOO" => "BAR" }
8
+ test_env = { 'LANG' => 'C', 'LC_ALL' => 'C', 'FOO' => 'BAR' }
9
9
  subject.with_env test_env do
10
10
  test_env.keys.each do |key|
11
11
  ENV[key].should == test_env[key]
@@ -64,13 +64,11 @@ describe Facter::Core::Execution::Base do
64
64
 
65
65
  describe "#execute" do
66
66
 
67
- it "switches LANG to C when executing the command" do
68
- subject.expects(:with_env).with('LANG' => 'C')
67
+ it "switches LANG and LC_ALL to C when executing the command" do
68
+ subject.expects(:with_env).with('LC_ALL' => 'C', 'LANG' => 'C')
69
69
  subject.execute('foo')
70
70
  end
71
71
 
72
- it "switches LC_ALL to C when executing the command"
73
-
74
72
  it "expands the command before running it" do
75
73
  subject.stubs(:`).returns ''
76
74
  subject.expects(:expand_command).with('foo').returns '/bin/foo'
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
+ require 'facter/util/config'
2
3
 
3
- describe Facter::Core::Execution::Posix, :as_plaform => :posix do
4
-
4
+ describe Facter::Core::Execution::Posix, :unless => Facter::Util::Config.is_windows? do
5
5
  describe "#search_paths" do
6
6
  it "should use the PATH environment variable plus /sbin and /usr/sbin on unix" do
7
7
  ENV.expects(:[]).with('PATH').returns "/bin:/usr/bin"
@@ -92,5 +92,15 @@ describe Facter::Core::Suitable do
92
92
 
93
93
  expect(subject).to_not be_suitable
94
94
  end
95
+
96
+ it "recalculates suitability on every invocation" do
97
+ subject.confine :kernel => 'Linux'
98
+
99
+ subject.confines.first.stubs(:true?).returns false
100
+ expect(subject).to_not be_suitable
101
+ subject.confines.first.unstub(:true?)
102
+ subject.confines.first.stubs(:true?).returns true
103
+ expect(subject).to be_suitable
104
+ end
95
105
  end
96
106
  end
@@ -0,0 +1,152 @@
1
+ require 'spec_helper'
2
+
3
+ describe "DHCP server facts" do
4
+ describe "on Linux OS's" do
5
+ before :each do
6
+ Facter.fact(:kernel).stubs(:value).returns 'Linux'
7
+ Facter::Util::FileRead.stubs(:read).with('/proc/net/route').returns(my_fixture_read('route'))
8
+ end
9
+
10
+ describe "with nmcli version <= 0.9.8 available" do
11
+ before :each do
12
+ Facter::Core::Execution.stubs(:which).with('nmcli').returns('/usr/bin/nmcli')
13
+ Facter::Core::Execution.stubs(:exec).with('nmcli --version').returns('nmcli tool, version 0.9.8.0')
14
+ end
15
+
16
+ describe "with a main interface configured with DHCP" do
17
+ before :each do
18
+ Facter::Core::Execution.stubs(:exec).with("nmcli d").returns(my_fixture_read("nmcli_devices"))
19
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d list iface eth0").returns(my_fixture_read("nmcli_eth0_dhcp"))
20
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d list iface wlan0").returns(my_fixture_read("nmcli_wlan0_dhcp"))
21
+ end
22
+
23
+ it "should produce a dhcp_servers fact that includes values for 'system' as well as each dhcp enabled interface" do
24
+ Facter.fact(:dhcp_servers).value.should == { 'system' => '192.168.1.1', 'eth0' => '192.168.1.1', 'wlan0' => '192.168.2.1' }
25
+ end
26
+ end
27
+
28
+ describe "with a main interface NOT configured with DHCP" do
29
+ before :each do
30
+ Facter::Core::Execution.stubs(:exec).with("nmcli d").returns(my_fixture_read("nmcli_devices"))
31
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d list iface eth0").returns(my_fixture_read("nmcli_eth0_static"))
32
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d list iface wlan0").returns(my_fixture_read("nmcli_wlan0_dhcp"))
33
+ end
34
+
35
+ it "should a dhcp_servers fact that includes values for each dhcp enables interface and NO 'system' value" do
36
+ Facter.fact(:dhcp_servers).value.should == {'wlan0' => '192.168.2.1' }
37
+ end
38
+ end
39
+
40
+ describe "with no default gateway" do
41
+ before :each do
42
+ Facter::Util::FileRead.stubs(:read).with('/proc/net/route').returns(my_fixture_read('route_nogw'))
43
+ Facter::Core::Execution.stubs(:exec).with("nmcli d").returns(my_fixture_read("nmcli_devices"))
44
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d list iface eth0").returns(my_fixture_read("nmcli_eth0_dhcp"))
45
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d list iface wlan0").returns(my_fixture_read("nmcli_wlan0_dhcp"))
46
+ end
47
+
48
+ it "should a dhcp_servers fact that includes values for each dhcp enables interface and NO 'system' value" do
49
+ Facter.fact(:dhcp_servers).value.should == {'eth0' => '192.168.1.1', 'wlan0' => '192.168.2.1' }
50
+ end
51
+ end
52
+
53
+ describe "with no DHCP enabled interfaces" do
54
+ before :each do
55
+ Facter::Core::Execution.stubs(:exec).with("nmcli d").returns(my_fixture_read("nmcli_devices"))
56
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d list iface eth0").returns(my_fixture_read("nmcli_eth0_static"))
57
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d list iface wlan0").returns(my_fixture_read("nmcli_wlan0_static"))
58
+ end
59
+
60
+ it "should not produce a dhcp_servers fact" do
61
+ Facter.fact(:dhcp_servers).value.should be_nil
62
+ end
63
+ end
64
+
65
+ describe "with no CONNECTED devices" do
66
+ before :each do
67
+ Facter::Core::Execution.stubs(:exec).with("nmcli d").returns(my_fixture_read("nmcli_devices_disconnected"))
68
+ end
69
+
70
+ it "should not produce a dhcp_servers fact" do
71
+ Facter.fact(:dhcp_servers).value.should be_nil
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "with nmcli version >= 0.9.9 available" do
77
+ before :each do
78
+ Facter::Core::Execution.stubs(:which).with('nmcli').returns('/usr/bin/nmcli')
79
+ Facter::Core::Execution.stubs(:exec).with('nmcli --version').returns('nmcli tool, version 0.9.9.0-20.git20131003.fc20')
80
+ end
81
+
82
+ describe "with a main interface configured with DHCP" do
83
+ before :each do
84
+ Facter::Core::Execution.stubs(:exec).with("nmcli d").returns(my_fixture_read("nmcli_devices"))
85
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d show eth0").returns(my_fixture_read("nmcli_eth0_dhcp"))
86
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d show wlan0").returns(my_fixture_read("nmcli_wlan0_dhcp"))
87
+ end
88
+
89
+ it "should produce a dhcp_servers fact that includes values for 'system' as well as each dhcp enabled interface" do
90
+ Facter.fact(:dhcp_servers).value.should == { 'system' => '192.168.1.1', 'eth0' => '192.168.1.1', 'wlan0' => '192.168.2.1' }
91
+ end
92
+ end
93
+
94
+ describe "with a main interface NOT configured with DHCP" do
95
+ before :each do
96
+ Facter::Core::Execution.stubs(:exec).with("nmcli d").returns(my_fixture_read("nmcli_devices"))
97
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d show eth0").returns(my_fixture_read("nmcli_eth0_static"))
98
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d show wlan0").returns(my_fixture_read("nmcli_wlan0_dhcp"))
99
+ end
100
+
101
+ it "should a dhcp_servers fact that includes values for each dhcp enables interface and NO 'system' value" do
102
+ Facter.fact(:dhcp_servers).value.should == {'wlan0' => '192.168.2.1' }
103
+ end
104
+ end
105
+
106
+ describe "with no default gateway" do
107
+ before :each do
108
+ Facter::Util::FileRead.stubs(:read).with('/proc/net/route').returns(my_fixture_read('route_nogw'))
109
+ Facter::Core::Execution.stubs(:exec).with("nmcli d").returns(my_fixture_read("nmcli_devices"))
110
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d show eth0").returns(my_fixture_read("nmcli_eth0_dhcp"))
111
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d show wlan0").returns(my_fixture_read("nmcli_wlan0_dhcp"))
112
+ end
113
+
114
+ it "should a dhcp_servers fact that includes values for each dhcp enables interface and NO 'system' value" do
115
+ Facter.fact(:dhcp_servers).value.should == {'eth0' => '192.168.1.1', 'wlan0' => '192.168.2.1' }
116
+ end
117
+ end
118
+
119
+ describe "with no DHCP enabled interfaces" do
120
+ before :each do
121
+ Facter::Core::Execution.stubs(:exec).with("nmcli d").returns(my_fixture_read("nmcli_devices"))
122
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d show eth0").returns(my_fixture_read("nmcli_eth0_static"))
123
+ Facter::Core::Execution.stubs(:exec).with("nmcli -f all d show wlan0").returns(my_fixture_read("nmcli_wlan0_static"))
124
+ end
125
+
126
+ it "should not produce a dhcp_servers fact" do
127
+ Facter.fact(:dhcp_servers).value.should be_nil
128
+ end
129
+ end
130
+
131
+ describe "with no CONNECTED devices" do
132
+ before :each do
133
+ Facter::Core::Execution.stubs(:exec).with("nmcli d").returns(my_fixture_read("nmcli_devices_disconnected"))
134
+ end
135
+
136
+ it "should not produce a dhcp_servers fact" do
137
+ Facter.fact(:dhcp_servers).value.should be_nil
138
+ end
139
+ end
140
+ end
141
+
142
+ describe "without nmcli available" do
143
+ before :each do
144
+ Facter::Core::Execution.stubs(:which).with('nmcli').returns(nil)
145
+ end
146
+
147
+ it "should not produce a dhcp_server fact" do
148
+ Facter.fact(:dhcp_servers).value.should be_nil
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,145 @@
1
+ require 'spec_helper'
2
+ require 'facter/ec2/rest'
3
+
4
+ shared_examples_for "an ec2 rest querier" do
5
+ describe "determining if the uri is reachable" do
6
+ it "retries if the connection times out" do
7
+ subject.stubs(:open).returns(stub(:read => nil))
8
+ Timeout.expects(:timeout).with(0.2).twice.raises(Timeout::Error).returns(true)
9
+ expect(subject).to be_reachable
10
+ end
11
+
12
+ it "retries if the connection is reset" do
13
+ subject.expects(:open).twice.raises(Errno::ECONNREFUSED).returns(StringIO.new("woo"))
14
+ expect(subject).to be_reachable
15
+ end
16
+
17
+ it "is false if the given uri returns a 404" do
18
+ subject.expects(:open).with(anything).once.raises(OpenURI::HTTPError.new("404 Not Found", StringIO.new("woo")))
19
+ expect(subject).to_not be_reachable
20
+ end
21
+
22
+ it "is false if the connection always times out" do
23
+ Timeout.expects(:timeout).with(0.2).times(3).raises(Timeout::Error)
24
+ expect(subject).to_not be_reachable
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ describe Facter::EC2::Metadata do
31
+
32
+ subject { described_class.new('http://0.0.0.0/latest/meta-data/') }
33
+
34
+ let(:response) { StringIO.new }
35
+
36
+ describe "fetching a metadata endpoint" do
37
+ it "splits the body into an array" do
38
+ response.string = my_fixture_read("meta-data/root")
39
+ subject.stubs(:open).with("http://0.0.0.0/latest/meta-data/").returns response
40
+ output = subject.fetch_endpoint('')
41
+
42
+ expect(output).to eq %w[
43
+ ami-id ami-launch-index ami-manifest-path block-device-mapping/ hostname
44
+ instance-action instance-id instance-type kernel-id local-hostname
45
+ local-ipv4 mac metrics/ network/ placement/ profile public-hostname
46
+ public-ipv4 public-keys/ reservation-id
47
+ ]
48
+ end
49
+
50
+ it "reformats keys that are array indices" do
51
+ response.string = "0=adrien@grey/"
52
+ subject.stubs(:open).with("http://0.0.0.0/latest/meta-data/public-keys/").returns response
53
+ output = subject.fetch_endpoint("public-keys/")
54
+
55
+ expect(output).to eq %w[0/]
56
+ end
57
+
58
+ it "returns nil if the endpoint returns a 404" do
59
+ Facter.expects(:log_exception).never
60
+ subject.stubs(:open).with("http://0.0.0.0/latest/meta-data/public-keys/1/").raises OpenURI::HTTPError.new("404 Not Found", response)
61
+ output = subject.fetch_endpoint('public-keys/1/')
62
+
63
+ expect(output).to be_nil
64
+ end
65
+
66
+ it "logs an error if the endpoint raises a non-404 HTTPError" do
67
+ Facter.expects(:log_exception).with(instance_of(OpenURI::HTTPError), anything)
68
+
69
+ subject.stubs(:open).with("http://0.0.0.0/latest/meta-data/").raises OpenURI::HTTPError.new("418 I'm a Teapot", response)
70
+ output = subject.fetch_endpoint("")
71
+
72
+ expect(output).to be_nil
73
+ end
74
+
75
+ it "logs an error if the endpoint raises a connection error" do
76
+ Facter.expects(:log_exception).with(instance_of(Errno::ECONNREFUSED), anything)
77
+
78
+ subject.stubs(:open).with("http://0.0.0.0/latest/meta-data/").raises Errno::ECONNREFUSED
79
+ output = subject.fetch_endpoint('')
80
+
81
+ expect(output).to be_nil
82
+ end
83
+ end
84
+
85
+ describe "recursively fetching the EC2 metadata API" do
86
+ it "queries the given endpoint for metadata keys" do
87
+ subject.expects(:fetch_endpoint).with("").returns([])
88
+ subject.fetch
89
+ end
90
+
91
+ it "fetches the value for a simple metadata key" do
92
+ subject.expects(:fetch_endpoint).with("").returns(['indexthing'])
93
+ subject.expects(:fetch_endpoint).with("indexthing").returns(['first', 'second'])
94
+
95
+ output = subject.fetch
96
+ expect(output).to eq({'indexthing' => ['first', 'second']})
97
+ end
98
+
99
+ it "unwraps metadata values that are in single element arrays" do
100
+ subject.expects(:fetch_endpoint).with("").returns(['ami-id'])
101
+ subject.expects(:fetch_endpoint).with("ami-id").returns(['i-12x'])
102
+
103
+ output = subject.fetch
104
+ expect(output).to eq({'ami-id' => 'i-12x'})
105
+ end
106
+
107
+ it "recursively queries an endpoint if the key ends with '/'" do
108
+ subject.expects(:fetch_endpoint).with("").returns(['metrics/'])
109
+ subject.expects(:fetch_endpoint).with("metrics/").returns(['vhostmd'])
110
+ subject.expects(:fetch_endpoint).with("metrics/vhostmd").returns(['woo'])
111
+
112
+ output = subject.fetch
113
+ expect(output).to eq({'metrics' => {'vhostmd' => 'woo'}})
114
+ end
115
+ end
116
+
117
+ it_behaves_like "an ec2 rest querier"
118
+ end
119
+
120
+ describe Facter::EC2::Userdata do
121
+
122
+ subject { described_class.new('http://0.0.0.0/latest/user-data/') }
123
+
124
+ let(:response) { StringIO.new }
125
+
126
+ describe "reaching the userdata" do
127
+ it "queries the userdata URI" do
128
+ subject.expects(:open).with('http://0.0.0.0/latest/user-data/').returns(response)
129
+ subject.fetch
130
+ end
131
+
132
+ it "returns the result of the query without modification" do
133
+ response.string = "clooouuuuud"
134
+ subject.expects(:open).with('http://0.0.0.0/latest/user-data/').returns(response)
135
+ expect(subject.fetch).to eq "clooouuuuud"
136
+ end
137
+
138
+ it "is nil if the URI returned a 404" do
139
+ subject.expects(:open).with('http://0.0.0.0/latest/user-data/').once.raises(OpenURI::HTTPError.new("404 Not Found", StringIO.new("woo")))
140
+ expect(subject.fetch).to be_nil
141
+ end
142
+ end
143
+
144
+ it_behaves_like "an ec2 rest querier"
145
+ end
@@ -1,187 +1,127 @@
1
- #! /usr/bin/env ruby
2
-
3
1
  require 'spec_helper'
4
- require 'facter/util/ec2'
5
-
6
- describe "ec2 facts" do
7
- # This is the standard prefix for making an API call in EC2 (or fake)
8
- # environments.
9
- let(:api_prefix) { "http://169.254.169.254" }
10
-
11
- describe "when running on ec2" do
12
- before :each do
13
- # This is an ec2 instance, not a eucalyptus instance
14
- Facter::Util::EC2.stubs(:has_euca_mac?).returns(false)
15
- Facter::Util::EC2.stubs(:has_openstack_mac?).returns(false)
16
- Facter::Util::EC2.stubs(:has_ec2_arp?).returns(true)
17
-
18
- # Assume we can connect
19
- Facter::Util::EC2.stubs(:can_connect?).returns(true)
20
- end
2
+ require 'facter/ec2/rest'
21
3
 
22
- it "should create flat meta-data facts" do
23
- Object.any_instance.expects(:open).
24
- with("#{api_prefix}/2008-02-01/meta-data/").
25
- at_least_once.returns(StringIO.new("foo"))
4
+ describe "ec2_metadata" do
5
+ let(:querier) { stub('EC2 metadata querier') }
26
6
 
27
- Object.any_instance.expects(:open).
28
- with("#{api_prefix}/2008-02-01/meta-data/foo").
29
- at_least_once.returns(StringIO.new("bar"))
7
+ before do
8
+ Facter::EC2::Metadata.stubs(:new).returns querier
30
9
 
31
- Facter.collection.internal_loader.load(:ec2)
32
-
33
- Facter.fact(:ec2_foo).value.should == "bar"
34
- end
10
+ # Prevent flattened facts from forcing evaluation of the ec2 metadata fact
11
+ Facter.stubs(:value).with(:ec2_metadata)
12
+ Facter.collection.internal_loader.load(:ec2)
13
+ Facter.unstub(:value)
14
+ end
35
15
 
36
- it "should create flat meta-data facts with comma seperation" do
37
- Object.any_instance.expects(:open).
38
- with("#{api_prefix}/2008-02-01/meta-data/").
39
- at_least_once.returns(StringIO.new("foo"))
16
+ subject { Facter.fact(:ec2_metadata).resolution(:rest) }
40
17
 
41
- Object.any_instance.expects(:open).
42
- with("#{api_prefix}/2008-02-01/meta-data/foo").
43
- at_least_once.returns(StringIO.new("bar\nbaz"))
18
+ it "is unsuitable if the virtual fact is not xen" do
19
+ querier.stubs(:reachable?).returns false
20
+ Facter.fact(:virtual).stubs(:value).returns "kvm"
21
+ expect(subject).to_not be_suitable
22
+ end
44
23
 
45
- Facter.collection.internal_loader.load(:ec2)
24
+ it "is unsuitable if ec2 endpoint is not reachable" do
25
+ Facter.fact(:virtual).stubs(:value).returns "xen"
26
+ querier.stubs(:reachable?).returns false
27
+ expect(subject).to_not be_suitable
28
+ end
46
29
 
47
- Facter.fact(:ec2_foo).value.should == "bar,baz"
30
+ describe "when the ec2 endpoint is reachable" do
31
+ before do
32
+ querier.stubs(:reachable?).returns true
48
33
  end
49
34
 
50
- it "should create structured meta-data facts" do
51
- Object.any_instance.expects(:open).
52
- with("#{api_prefix}/2008-02-01/meta-data/").
53
- at_least_once.returns(StringIO.new("foo/"))
54
-
55
- Object.any_instance.expects(:open).
56
- with("#{api_prefix}/2008-02-01/meta-data/foo/").
57
- at_least_once.returns(StringIO.new("bar"))
35
+ it "is suitable if the virtual fact is xen" do
36
+ Facter.fact(:virtual).stubs(:value).returns "xen"
37
+ subject.suitable?
58
38
 
59
- Object.any_instance.expects(:open).
60
- with("#{api_prefix}/2008-02-01/meta-data/foo/bar").
61
- at_least_once.returns(StringIO.new("baz"))
62
-
63
- Facter.collection.internal_loader.load(:ec2)
64
-
65
- Facter.fact(:ec2_foo_bar).value.should == "baz"
39
+ expect(subject).to be_suitable
66
40
  end
67
41
 
68
- it "should create ec2_user_data fact" do
69
- # No meta-data
70
- Object.any_instance.expects(:open).
71
- with("#{api_prefix}/2008-02-01/meta-data/").
72
- at_least_once.returns(StringIO.new(""))
73
-
74
- Facter::Util::EC2.stubs(:read_uri).
75
- with("#{api_prefix}/latest/user-data/").
76
- returns("test")
77
-
78
- Facter.collection.internal_loader.load(:ec2)
79
- Facter.fact(:ec2_userdata).value.should == ["test"]
42
+ it "is suitable if the virtual fact is xenu" do
43
+ Facter.fact(:virtual).stubs(:value).returns "xenu"
44
+ expect(subject).to be_suitable
80
45
  end
81
46
  end
82
47
 
83
- describe "when running on eucalyptus" do
84
- before :each do
85
- # Return false for ec2, true for eucalyptus
86
- Facter::Util::EC2.stubs(:has_euca_mac?).returns(true)
87
- Facter::Util::EC2.stubs(:has_openstack_mac?).returns(false)
88
- Facter::Util::EC2.stubs(:has_ec2_arp?).returns(false)
48
+ it "resolves the value by recursively querying the rest endpoint" do
49
+ querier.expects(:fetch).returns({"hello" => "world"})
50
+ expect(subject.value).to eq({"hello" => "world"})
51
+ end
52
+ end
89
53
 
90
- # Assume we can connect
91
- Facter::Util::EC2.stubs(:can_connect?).returns(true)
92
- end
54
+ describe "ec2_userdata" do
55
+ let(:querier) { stub('EC2 metadata querier') }
93
56
 
94
- it "should create ec2_user_data fact" do
95
- # No meta-data
96
- Object.any_instance.expects(:open).\
97
- with("#{api_prefix}/2008-02-01/meta-data/").\
98
- at_least_once.returns(StringIO.new(""))
57
+ before do
58
+ Facter::EC2::Userdata.stubs(:new).returns querier
99
59
 
100
- Facter::Util::EC2.stubs(:read_uri).
101
- with("#{api_prefix}/latest/user-data/").
102
- returns("test")
60
+ # Prevent flattened facts from forcing evaluation of the ec2 metadata fact
61
+ Facter.stubs(:value).with(:ec2_metadata)
62
+ Facter.collection.internal_loader.load(:ec2)
63
+ Facter.unstub(:value)
64
+ end
103
65
 
104
- # Force a fact load
105
- Facter.collection.internal_loader.load(:ec2)
66
+ subject { Facter.fact(:ec2_userdata).resolution(:rest) }
106
67
 
107
- Facter.fact(:ec2_userdata).value.should == ["test"]
108
- end
68
+ it "is unsuitable if the virtual fact is not xen" do
69
+ querier.stubs(:reachable?).returns(true)
70
+ Facter.fact(:virtual).stubs(:value).returns "kvm"
71
+ expect(subject).to_not be_suitable
109
72
  end
110
73
 
111
- describe "when running on openstack" do
112
- before :each do
113
- # Return false for ec2, true for eucalyptus
114
- Facter::Util::EC2.stubs(:has_openstack_mac?).returns(true)
115
- Facter::Util::EC2.stubs(:has_euca_mac?).returns(false)
116
- Facter::Util::EC2.stubs(:has_ec2_arp?).returns(false)
74
+ it "is unsuitable if ec2 endpoint is not reachable" do
75
+ Facter.fact(:virtual).stubs(:value).returns "xen"
76
+ querier.stubs(:reachable?).returns false
77
+ expect(subject).to_not be_suitable
78
+ end
117
79
 
118
- # Assume we can connect
119
- Facter::Util::EC2.stubs(:can_connect?).returns(true)
80
+ describe "when the ec2 endpoint is reachable" do
81
+ before do
82
+ querier.stubs(:reachable?).returns true
120
83
  end
121
84
 
122
- it "should create ec2_user_data fact" do
123
- # No meta-data
124
- Object.any_instance.expects(:open).\
125
- with("#{api_prefix}/2008-02-01/meta-data/").\
126
- at_least_once.returns(StringIO.new(""))
127
-
128
- Facter::Util::EC2.stubs(:read_uri).
129
- with("#{api_prefix}/latest/user-data/").
130
- returns("test")
131
-
132
- # Force a fact load
133
- Facter.collection.internal_loader.load(:ec2)
134
-
135
- Facter.fact(:ec2_userdata).value.should == ["test"]
85
+ it "is suitable if the virtual fact is xen" do
86
+ Facter.fact(:virtual).stubs(:value).returns "xen"
87
+ expect(subject).to be_suitable
136
88
  end
137
89
 
138
- it "should return nil if open fails" do
139
- Facter.stubs(:warn) # do not pollute test output
140
- Facter.expects(:warn).with('Could not retrieve ec2 metadata: host unreachable')
141
-
142
- Object.any_instance.expects(:open).
143
- with("#{api_prefix}/2008-02-01/meta-data/").
144
- at_least_once.raises(RuntimeError, 'host unreachable')
145
-
146
- Facter::Util::EC2.stubs(:read_uri).
147
- with("#{api_prefix}/latest/user-data/").
148
- raises(RuntimeError, 'host unreachable')
149
-
150
- # Force a fact load
151
- Facter.collection.internal_loader.load(:ec2)
152
-
153
- Facter.fact(:ec2_userdata).value.should be_nil
90
+ it "is suitable if the virtual fact is xenu" do
91
+ Facter.fact(:virtual).stubs(:value).returns "xenu"
92
+ expect(subject).to be_suitable
154
93
  end
94
+ end
155
95
 
96
+ it "resolves the value by fetching the rest endpoint" do
97
+ querier.expects(:fetch).returns "user data!"
98
+ expect(subject.value).to eq "user data!"
156
99
  end
100
+ end
157
101
 
158
- describe "when api connect test fails" do
159
- before :each do
160
- Facter.stubs(:warnonce)
161
- end
102
+ describe "flattened versions of ec2 facts" do
103
+ # These facts are tricky to test because they are dynamic facts, and they are
104
+ # generated from a fact that is defined in the same file. In order to pull
105
+ # this off we need to define the ec2_metadata fact ahead of time so that we
106
+ # can stub the value, and then manually load the correct files.
162
107
 
163
- it "should not populate ec2_userdata" do
164
- # Emulate ec2 for now as it matters little to this test
165
- Facter::Util::EC2.stubs(:has_euca_mac?).returns(true)
166
- Facter::Util::EC2.stubs(:has_ec2_arp?).never
167
- Facter::Util::EC2.expects(:can_connect?).at_least_once.returns(false)
108
+ it "unpacks the ec2_metadata fact" do
109
+ Facter.define_fact(:ec2_metadata).stubs(:value).returns({"hello" => "world"})
110
+ Facter.collection.internal_loader.load(:ec2)
168
111
 
169
- # The API should never be called at this point
170
- Object.any_instance.expects(:open).
171
- with("#{api_prefix}/2008-02-01/meta-data/").never
172
- Object.any_instance.expects(:open).
173
- with("#{api_prefix}/2008-02-01/user-data/").never
112
+ expect(Facter.value("ec2_hello")).to eq "world"
113
+ end
174
114
 
175
- # Force a fact load
176
- Facter.collection.internal_loader.load(:ec2)
115
+ it "does not set any flat ec2 facts if the ec2_metadata fact is nil" do
116
+ Facter.define_fact(:ec2_metadata).stubs(:value)
117
+ Facter.define_fact(:ec2_userdata).stubs(:value).returns(nil)
177
118
 
178
- Facter.fact(:ec2_userdata).should == nil
179
- end
119
+ Facter.collection.internal_loader.load(:ec2)
180
120
 
181
- it "should rescue the exception" do
182
- Facter::Util::EC2.expects(:open).with("#{api_prefix}:80/").raises(Timeout::Error)
121
+ all_facts = Facter.collection.to_hash
183
122
 
184
- Facter::Util::EC2.should_not be_can_connect
185
- end
123
+ ec2_facts = all_facts.keys.select { |k| k =~ /^ec2_/ }
124
+ expect(ec2_facts).to be_empty
186
125
  end
126
+
187
127
  end