Codebase list facter / fc6a207
Merge pull request #445 from zaphod42/issues/stable/20938-noise-on-stderr-from-domain-fact (#20938) Ignore stderr from domain commands Adrien Thebo 10 years ago
2 changed file(s) with 156 addition(s) and 116 deletion(s). Raw diff Collapse all Expand all
2222 # Get the domain from various sources; the order of these
2323 # steps is important
2424
25 # In some OS 'hostname -f' will change the hostname to '-f'
26 # We know that Solaris and HP-UX exhibit this behavior
27 # On good OS, 'hostname -f' will return the FQDN which is preferable
28 # Due to dangerous behavior of 'hostname -f' on old OS, we will explicitly opt-in
25 # In some OS 'hostname -f' will change the hostname to '-f'
26 # We know that Solaris and HP-UX exhibit this behavior
27 # On good OS, 'hostname -f' will return the FQDN which is preferable
28 # Due to dangerous behavior of 'hostname -f' on old OS, we will explicitly opt-in
2929 # 'hostname -f' --hkenney May 9, 2012
30 hostname_command = 'hostname'
30 basic_hostname = 'hostname 2> /dev/null'
31 full_hostname = 'hostname -f 2> /dev/null'
3132 can_do_hostname_f = Regexp.union /Linux/i, /FreeBSD/i, /Darwin/i
32 hostname_command = 'hostname -f' if Facter.value(:kernel) =~ can_do_hostname_f
3333
34
34 hostname_command = if Facter.value(:kernel) =~ can_do_hostname_f
35 full_hostname
36 else
37 basic_hostname
38 end
39
3540 if name = Facter::Util::Resolution.exec(hostname_command) \
3641 and name =~ /.*?\.(.+$)/
3742
3843 return_value = $1
39 elsif domain = Facter::Util::Resolution.exec('dnsdomainname') \
44 elsif domain = Facter::Util::Resolution.exec('dnsdomainname 2> /dev/null') \
4045 and domain =~ /.+/
4146
4247 return_value = domain
00 #! /usr/bin/env ruby
11
22 require 'spec_helper'
3 require 'stringio'
34
45 describe "Domain name facts" do
56
6 { :linux => {:kernel => "Linux", :hostname_command => "hostname -f"},
7 :solaris => {:kernel => "SunOS", :hostname_command => "hostname"},
8 :darwin => {:kernel => "Darwin", :hostname_command => "hostname -f"},
9 :freebsd => {:kernel => "FreeBSD", :hostname_command => "hostname -f"},
10 :hpux => {:kernel => "HP-UX", :hostname_command => "hostname"},
11 }.each do |key, nested_hash|
12
13 describe "on #{key}" do
7 def resolv_conf_contains(*lines)
8 file_handle = StringIO.new(lines.join("\n"))
9 FileTest.stubs(:exists?).with("/etc/resolv.conf").returns(true)
10 File.stubs(:open).with("/etc/resolv.conf").yields(file_handle)
11 end
12
13 [
14 { :kernel => "Linux", :hostname_command => "hostname -f 2> /dev/null" },
15 { :kernel => "SunOS", :hostname_command => "hostname 2> /dev/null" },
16 { :kernel => "Darwin", :hostname_command => "hostname -f 2> /dev/null" },
17 { :kernel => "FreeBSD", :hostname_command => "hostname -f 2> /dev/null" },
18 { :kernel => "HP-UX", :hostname_command => "hostname 2> /dev/null" },
19 ].each do |scenario|
20
21 describe "on #{scenario[:kernel]}" do
22 let(:hostname_command) { scenario[:hostname_command] }
23 let(:dnsdomain_command) { "dnsdomainname 2> /dev/null" }
24
25 def the_hostname_is(value)
26 Facter::Util::Resolution.stubs(:exec).with(hostname_command).returns(value)
27 end
28
29 def the_dnsdomainname_is(value)
30 Facter::Util::Resolution.stubs(:exec).with(dnsdomain_command).returns(value)
31 end
32
1433 before do
15 Facter.fact(:kernel).stubs(:value).returns(nested_hash[:kernel])
16 FileTest.stubs(:exists?).with("/etc/resolv.conf").returns(true)
17 end
18
19 let :hostname_command do
20 nested_hash[:hostname_command]
21 end
22
34 Facter.fact(:kernel).stubs(:value).returns(scenario[:kernel])
35 end
36
2337 it "should use the hostname binary" do
24 Facter::Util::Resolution.expects(:exec).with(hostname_command).returns "test.example.com"
38 the_hostname_is("test.example.com")
39
2540 Facter.fact(:domain).value.should == "example.com"
2641 end
27
42
2843 it "should fall back to the dnsdomainname binary" do
29 Facter::Util::Resolution.expects(:exec).with(hostname_command).returns("myhost")
30 Facter::Util::Resolution.expects(:exec).with("dnsdomainname").returns("example.com")
44 the_hostname_is("myhost")
45 the_dnsdomainname_is("example.com")
46
3147 Facter.fact(:domain).value.should == "example.com"
3248 end
33
34
49
3550 it "should fall back to /etc/resolv.conf" do
36 Facter::Util::Resolution.expects(:exec).with(hostname_command).at_least_once.returns("myhost")
37 Facter::Util::Resolution.expects(:exec).with("dnsdomainname").at_least_once.returns("")
38 File.expects(:open).with('/etc/resolv.conf').at_least_once
39 Facter.fact(:domain).value
40 end
41
42 it "should attempt to resolve facts in a specific order" do
43 seq = sequence('domain')
44 Facter::Util::Resolution.stubs(:exec).with(hostname_command).in_sequence(seq).at_least_once
45 Facter::Util::Resolution.stubs(:exec).with("dnsdomainname").in_sequence(seq).at_least_once
46 File.expects(:open).with('/etc/resolv.conf').in_sequence(seq).at_least_once
47 Facter.fact(:domain).value
48 end
49
50 describe "Top level domain" do
51 the_hostname_is("myhost")
52 the_dnsdomainname_is("")
53
54 resolv_conf_contains("domain testing.com")
55
56 Facter.fact(:domain).value.should == "testing.com"
57 end
58
59 describe "Top level domain" do
5160 it "should find the domain name" do
52 Facter::Util::Resolution.expects(:exec).with(hostname_command).returns "ns01.tld"
53 Facter::Util::Resolution.expects(:exec).with("dnsdomainname").never
54 File.expects(:exists?).with('/etc/resolv.conf').never
55 Facter.fact(:domain).value.should == "tld"
56 end
57 end
58
61 the_hostname_is("ns01.tld")
62
63 Facter.fact(:domain).value.should == "tld"
64 end
65 end
66
5967 describe "when using /etc/resolv.conf" do
6068 before do
61 Facter::Util::Resolution.stubs(:exec).with(hostname_command)
62 Facter::Util::Resolution.stubs(:exec).with("dnsdomainname")
63 @mock_file = mock()
64 File.stubs(:open).with("/etc/resolv.conf").yields(@mock_file)
65 end
66
69 the_hostname_is("")
70 the_dnsdomainname_is("")
71 end
72
6773 it "should use the domain field over the search field" do
68 lines = [
69 "nameserver 4.2.2.1",
70 "search example.org",
71 "domain example.com",
72 ]
73 @mock_file.expects(:each).multiple_yields(*lines)
74 resolv_conf_contains(
75 "nameserver 4.2.2.1",
76 "search example.org",
77 "domain example.com"
78 )
79
7480 Facter.fact(:domain).value.should == 'example.com'
7581 end
7682
7783 it "should fall back to the search field" do
78 lines = [
79 "nameserver 4.2.2.1",
80 "search example.org",
81 ]
82 @mock_file.expects(:each).multiple_yields(*lines)
84 resolv_conf_contains(
85 "nameserver 4.2.2.1",
86 "search example.org"
87 )
88
8389 Facter.fact(:domain).value.should == 'example.org'
8490 end
85
91
8692 it "should use the first domain in the search field" do
87 lines = [
88 "search example.org example.net",
89 ]
90 @mock_file.expects(:each).multiple_yields(*lines)
93 resolv_conf_contains("search example.org example.net")
94
9195 Facter.fact(:domain).value.should == 'example.org'
9296 end
93
97
9498 # Test permutations of domain and search, where 'domain' can be a value of
9599 # the search keyword and the domain keyword
96100 # and also where 'search' can be a value of the search keyword and the
106110 # Why someone would have their machines named 'www.domain' or 'www.search', I
107111 # don't know, but we'll at least handle it properly
108112 [
109 ["domain domain", "domain"],
110 ["domain search", "search"],
111 ["search domain", "domain"],
112 ["search search", "search"],
113 ["search domain notdomain", "domain"],
114 [["#search notdomain","search search"], "search"],
115 [["# search notdomain","search search"], "search"],
116 [["#domain notdomain","domain domain"], "domain"],
117 [["# domain notdomain","domain domain"], "domain"],
113 [["domain domain"], "domain"],
114 [["domain search"], "search"],
115 [["search domain"], "domain"],
116 [["search search"], "search"],
117 [["search domain notdomain"], "domain"],
118 [["#search notdomain", "search search"], "search"],
119 [["# search notdomain", "search search"], "search"],
120 [["#domain notdomain", "domain domain"], "domain"],
121 [["# domain notdomain", "domain domain"], "domain"],
118122 ].each do |tuple|
119 field = tuple[0]
123 conf = tuple[0]
120124 expect = tuple[1]
121 it "should return #{expect} from \"#{field}\"" do
122 lines = [
123 field
124 ].flatten
125 @mock_file.expects(:each).multiple_yields(*lines)
125 it "should return #{expect} from \"#{conf}\"" do
126 resolv_conf_contains(*conf)
127
126128 Facter.fact(:domain).value.should == expect
127129 end
128130 end
129131 end
130132 end
131 end
133 end
132134
133135 describe "on Windows" do
134136 before(:each) do
172174 end
173175 end
174176
175 describe "with trailing dots" do
176 describe "on Windows" do
177 describe "with trailing dots" do
178 describe "on Windows" do
177179 before do
178180 Facter.fact(:kernel).stubs(:value).returns("windows")
179181 require 'facter/util/registry'
180182 require 'facter/util/wmi'
181183 end
182
184
183185 [{:registry => 'testdomain.', :wmi => '', :expect => 'testdomain'},
184186 {:registry => '', :wmi => 'testdomain.', :expect => 'testdomain'},
185187 ].each do |scenario|
186188
187 describe "scenarios" do
189 describe "scenarios" do
188190 before(:each) do
189191 Facter::Util::Registry.stubs(:hklm_read).returns(scenario[:registry])
190192 nic = stubs 'nic'
191193 nic.stubs(:DNSDomain).returns(scenario[:wmi])
192194 Facter::Util::WMI.stubs(:execquery).with("select DNSDomain from Win32_NetworkAdapterConfiguration where IPEnabled = True").returns([nic])
193195 end
194
196
195197 it "should return #{scenario[:expect]}" do
196198 Facter.fact(:domain).value.should == scenario[:expect]
197199 end
198
200
199201 it "should remove trailing dots" do
200202 Facter.fact(:domain).value.should_not =~ /\.$/
201203 end
202 end
203 end
204 end
205 end
204206 end
205207
206208 describe "on everything else" do
209211 FileTest.stubs(:exists?).with("/etc/resolv.conf").returns(true)
210212 end
211213
212 [{:hostname => 'host.testdomain.', :dnsdomainname => '', :resolve_domain => '', :resolve_search => '', :expect => 'testdomain'},
213 {:hostname => '', :dnsdomainname => 'testdomain.', :resolve_domain => '', :resolve_search => '', :expect => 'testdomain'},
214 {:hostname => '', :dnsdomainname => '', :resolve_domain => 'testdomain.', :resolve_search => '', :expect => 'testdomain'},
215 {:hostname => '', :dnsdomainname => '', :resolve_domain => '', :resolve_search => 'testdomain.', :expect => 'testdomain'},
216 {:hostname => '', :dnsdomainname => '', :resolve_domain => '', :resolve_search => '', :expect => nil}
214 [
215 {
216 :scenario => 'when there is only a hostname',
217 :hostname => 'host.testdomain.',
218 :dnsdomainname => '',
219 :resolve_domain => '',
220 :resolve_search => '',
221 :expect => 'testdomain'
222 },
223 {
224 :scenario => 'when there is only a domain name',
225 :hostname => '',
226 :dnsdomainname => 'testdomain.',
227 :resolve_domain => '',
228 :resolve_search => '',
229 :expect => 'testdomain'
230 },
231 {
232 :scenario => 'when there is only a resolve domain',
233 :hostname => '',
234 :dnsdomainname => '',
235 :resolve_domain => 'testdomain.',
236 :resolve_search => '',
237 :expect => 'testdomain'
238 },
239 {
240 :scenario => 'when there is only a resolve search',
241 :hostname => '',
242 :dnsdomainname => '',
243 :resolve_domain => '',
244 :resolve_search => 'testdomain.',
245 :expect => 'testdomain'
246 },
247 {
248 :scenario => 'when there is no information available',
249 :hostname => '',
250 :dnsdomainname => '',
251 :resolve_domain => '',
252 :resolve_search => '',
253 :expect => nil
254 }
217255 ].each do |scenario|
218256
219 describe "scenarios" do
220 before(:each) do
221 Facter::Util::Resolution.stubs(:exec).with("hostname -f").returns(scenario[:hostname])
222 Facter::Util::Resolution.stubs(:exec).with("dnsdomainname").returns(scenario[:dnsdomainname])
223 @mock_file = mock()
224 File.stubs(:open).with("/etc/resolv.conf").yields(@mock_file)
225 lines = [
226 "search #{scenario[:resolve_search]}",
227 "domain #{scenario[:resolve_domain]}",
228 ]
229 @mock_file.stubs(:each).multiple_yields(*lines)
257 describe scenario[:scenario] do
258 before(:each) do
259 Facter::Util::Resolution.stubs(:exec).with("hostname -f 2> /dev/null").returns(scenario[:hostname])
260 Facter::Util::Resolution.stubs(:exec).with("dnsdomainname 2> /dev/null").returns(scenario[:dnsdomainname])
261 resolv_conf_contains(
262 "search #{scenario[:resolve_search]}",
263 "domain #{scenario[:resolve_domain]}"
264 )
230265 end
231266
232267 it "should remove trailing dots" do
237272 Facter.fact(:domain).value.should == scenario[:expect]
238273 end
239274 end
240 end
275 end
241276 end
242277 end
243278 end