facter 1.7.2 → 1.7.3.rc1
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/README.md +8 -0
- data/Rakefile +10 -4
- data/ext/build_defaults.yaml +4 -3
- data/ext/debian/changelog.erb +7 -1
- data/ext/debian/control +2 -2
- data/ext/redhat/facter.spec.erb +1 -1
- data/install.rb +1 -1
- data/lib/facter/domain.rb +11 -3
- data/lib/facter/hardwaremodel.rb +7 -2
- data/lib/facter/ipaddress.rb +16 -4
- data/lib/facter/ipaddress6.rb +12 -3
- data/lib/facter/macaddress.rb +1 -1
- data/lib/facter/netmask.rb +19 -0
- data/lib/facter/util/directory_loader.rb +1 -1
- data/lib/facter/util/ip.rb +14 -18
- data/lib/facter/util/ip/windows.rb +215 -0
- data/lib/facter/util/macaddress.rb +3 -9
- data/lib/facter/util/netmask.rb +1 -1
- data/lib/facter/util/parser.rb +30 -19
- data/lib/facter/version.rb +1 -1
- data/lib/facter/virtual.rb +5 -5
- data/spec/fixtures/unit/ipaddress/ifconfig_non_english_locale.txt +18 -0
- data/spec/lib/facter_spec/windows_network.rb +64 -0
- data/spec/spec_helper.rb +25 -7
- data/spec/unit/architecture_spec.rb +1 -0
- data/spec/unit/domain_spec.rb +37 -6
- data/spec/unit/ec2_spec.rb +1 -1
- data/spec/unit/facter_spec.rb +2 -2
- data/spec/unit/hardwaremodel_spec.rb +16 -1
- data/spec/unit/ipaddress6_spec.rb +106 -13
- data/spec/unit/ipaddress_spec.rb +100 -22
- data/spec/unit/macaddress_spec.rb +0 -4
- data/spec/unit/memory_spec.rb +8 -7
- data/spec/unit/netmask_spec.rb +62 -5
- data/spec/unit/util/ip/windows_spec.rb +48 -0
- data/spec/unit/util/ip_spec.rb +9 -21
- data/spec/unit/util/macaddress_spec.rb +52 -10
- data/spec/unit/util/parser_spec.rb +32 -3
- data/spec/unit/util/virtual_spec.rb +9 -4
- data/spec/unit/zfs_version_spec.rb +4 -5
- data/spec/unit/zpool_version_spec.rb +4 -5
- metadata +480 -477
- data/ext/osx/PackageInfo.plist +0 -36
- data/ext/osx/createpackage.sh +0 -179
- data/spec/fixtures/netsh/windows_netsh_addresses_with_multiple_interfaces +0 -35
data/README.md
CHANGED
@@ -20,6 +20,14 @@ Adding your own facts
|
|
20
20
|
See the [Adding Facts](http://docs.puppetlabs.com/guides/custom_facts.html)
|
21
21
|
page for details of how to add your own custom facts to Facter.
|
22
22
|
|
23
|
+
Running Specs
|
24
|
+
-------------
|
25
|
+
|
26
|
+
* bundle install --path .bundle/gems
|
27
|
+
* bundle exec rake spec
|
28
|
+
|
29
|
+
Note: external facts in the system facts.d directory can cause spec failures.
|
30
|
+
|
23
31
|
Further Information
|
24
32
|
-------------------
|
25
33
|
|
data/Rakefile
CHANGED
@@ -10,13 +10,19 @@ require 'rake'
|
|
10
10
|
|
11
11
|
begin
|
12
12
|
load File.join(File.dirname(__FILE__), 'ext', 'packaging', 'packaging.rake')
|
13
|
-
require 'rubygems'
|
14
|
-
require 'rspec'
|
15
|
-
require 'rspec/core/rake_task'
|
16
|
-
require 'rcov'
|
17
13
|
rescue LoadError
|
18
14
|
end
|
19
15
|
|
16
|
+
['rubygems',
|
17
|
+
'rspec',
|
18
|
+
'rspec/core/rake_task',
|
19
|
+
'rcov',].each do |lib|
|
20
|
+
begin
|
21
|
+
require lib
|
22
|
+
rescue LoadError
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
20
26
|
Dir['tasks/**/*.rake'].each { |t| load t }
|
21
27
|
|
22
28
|
build_defs_file = 'ext/build_defaults.yaml'
|
data/ext/build_defaults.yaml
CHANGED
@@ -9,15 +9,16 @@ gpg_name: 'info@puppetlabs.com'
|
|
9
9
|
gpg_key: '4BD6EC30'
|
10
10
|
sign_tar: FALSE
|
11
11
|
# a space separated list of mock configs
|
12
|
-
final_mocks: 'pl-el-5-i386 pl-el-5-x86_64 pl-el-6-i386 pl-el-6-x86_64 pl-fedora-17-i386 pl-fedora-17-x86_64 pl-fedora-18-i386 pl-fedora-18-x86_64'
|
13
|
-
yum_host: '
|
12
|
+
final_mocks: 'pl-el-5-i386 pl-el-5-x86_64 pl-el-6-i386 pl-el-6-x86_64 pl-fedora-17-i386 pl-fedora-17-x86_64 pl-fedora-18-i386 pl-fedora-18-x86_64 pl-fedora-19-i386 pl-fedora-19-x86_64'
|
13
|
+
yum_host: 'yum.puppetlabs.com'
|
14
14
|
yum_repo_path: '/opt/repository/yum/'
|
15
15
|
build_gem: TRUE
|
16
16
|
build_dmg: TRUE
|
17
17
|
build_ips: TRUE
|
18
|
-
apt_host: '
|
18
|
+
apt_host: 'apt.puppetlabs.com'
|
19
19
|
apt_repo_url: 'http://apt.puppetlabs.com'
|
20
20
|
apt_repo_path: '/opt/repository/incoming'
|
21
21
|
ips_repo: '/var/pkgrepo'
|
22
22
|
ips_store: '/opt/repository'
|
23
23
|
ips_host: 'solaris-11-ips-repo.acctest.dc1.puppetlabs.net'
|
24
|
+
tar_host: 'downloads.puppetlabs.com'
|
data/ext/debian/changelog.erb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
-
facter (<%= @debversion %>)
|
1
|
+
facter (<%= @debversion %>) lucid unstable sid wheezy lucid squeeze precise quantal raring; urgency=low
|
2
2
|
|
3
3
|
* Update to version <% @debversion %>
|
4
4
|
|
5
5
|
-- Puppet Labs Release <info@puppetlabs.com> <%= Time.now.strftime("%a, %d %b %Y %H:%M:%S %z")%>
|
6
6
|
|
7
|
+
facter (1.7.2-1puppetlabs2) lucid unstable sid wheezy lucid squeeze precise; urgency=low
|
8
|
+
|
9
|
+
* Remove dependenices on libssl-ruby from facter as they are not used
|
10
|
+
|
11
|
+
-- Matthaus Owens <matthaus@puppetlabs.com> Thu, 11 Jul 2013 13:11:30 +0000
|
12
|
+
|
7
13
|
facter (1.7.0-0.1rc1puppetlabs1) hardy lucid oneiric unstable sid wheezy lucid squeeze precise; urgency=low
|
8
14
|
|
9
15
|
* Add dependency on virt-what to facter for better virutalization detection
|
data/ext/debian/control
CHANGED
@@ -2,13 +2,13 @@ Source: facter
|
|
2
2
|
Section: ruby
|
3
3
|
Priority: optional
|
4
4
|
Maintainer: Puppet Labs <info@puppetlabs.com>
|
5
|
-
Build-Depends: cdbs, debhelper (>> 7), ruby | ruby-interpreter
|
5
|
+
Build-Depends: cdbs, debhelper (>> 7), ruby | ruby-interpreter
|
6
6
|
Standards-Version: 3.9.1
|
7
7
|
Homepage: http://www.puppetlabs.com
|
8
8
|
|
9
9
|
Package: facter
|
10
10
|
Architecture: any
|
11
|
-
Depends: ${shlibs:Depends}, ${misc:Depends}, ruby | ruby-interpreter,
|
11
|
+
Depends: ${shlibs:Depends}, ${misc:Depends}, ruby | ruby-interpreter, dmidecode [i386 amd64 ia64], virt-what, pciutils
|
12
12
|
Description: Ruby module for collecting simple facts about a host operating system
|
13
13
|
Some of the facts are preconfigured, such as the hostname and the operating
|
14
14
|
system. Additional facts can be added through simple Ruby scripts.
|
data/ext/redhat/facter.spec.erb
CHANGED
data/install.rb
CHANGED
@@ -60,7 +60,7 @@ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'lib')))
|
|
60
60
|
require 'facter'
|
61
61
|
@operatingsystem = Facter[:operatingsystem].value
|
62
62
|
|
63
|
-
PREREQS = %w{
|
63
|
+
PREREQS = %w{cgi}
|
64
64
|
|
65
65
|
InstallOptions = OpenStruct.new
|
66
66
|
|
data/lib/facter/domain.rb
CHANGED
@@ -29,11 +29,14 @@ Facter.add(:domain) do
|
|
29
29
|
# Due to dangerous behavior of 'hostname -f' on old OS, we will explicitly opt-in
|
30
30
|
# 'hostname -f' --hkenney May 9, 2012
|
31
31
|
basic_hostname = 'hostname 2> /dev/null'
|
32
|
+
windows_hostname = 'hostname > NUL'
|
32
33
|
full_hostname = 'hostname -f 2> /dev/null'
|
33
34
|
can_do_hostname_f = Regexp.union /Linux/i, /FreeBSD/i, /Darwin/i
|
34
35
|
|
35
36
|
hostname_command = if Facter.value(:kernel) =~ can_do_hostname_f
|
36
37
|
full_hostname
|
38
|
+
elsif Facter.value(:kernel) == "windows"
|
39
|
+
windows_hostname
|
37
40
|
else
|
38
41
|
basic_hostname
|
39
42
|
end
|
@@ -42,7 +45,7 @@ Facter.add(:domain) do
|
|
42
45
|
and name =~ /.*?\.(.+$)/
|
43
46
|
|
44
47
|
return_value = $1
|
45
|
-
elsif domain = Facter::Util::Resolution.exec('dnsdomainname 2> /dev/null') \
|
48
|
+
elsif Facter.value(:kernel) != "windows" and domain = Facter::Util::Resolution.exec('dnsdomainname 2> /dev/null') \
|
46
49
|
and domain =~ /.+/
|
47
50
|
|
48
51
|
return_value = domain
|
@@ -76,10 +79,15 @@ Facter.add(:domain) do
|
|
76
79
|
if domain == ""
|
77
80
|
require 'facter/util/wmi'
|
78
81
|
Facter::Util::WMI.execquery("select DNSDomain from Win32_NetworkAdapterConfiguration where IPEnabled = True").each { |nic|
|
79
|
-
|
80
|
-
|
82
|
+
if nic.DNSDomain && nic.DNSDomain.length > 0
|
83
|
+
domain = nic.DNSDomain
|
84
|
+
break
|
85
|
+
end
|
81
86
|
}
|
82
87
|
end
|
88
|
+
|
89
|
+
domain ||= ''
|
90
|
+
|
83
91
|
domain.gsub(/\.$/, '')
|
84
92
|
end
|
85
93
|
end
|
data/lib/facter/hardwaremodel.rb
CHANGED
@@ -32,17 +32,22 @@ Facter.add(:hardwaremodel) do
|
|
32
32
|
# http://source.winehq.org/source/include/winnt.h#L568
|
33
33
|
# http://msdn.microsoft.com/en-us/library/windows/desktop/aa394373(v=vs.85).aspx
|
34
34
|
# http://msdn.microsoft.com/en-us/library/windows/desktop/windows.system.processorarchitecture.aspx
|
35
|
+
# http://linux.derkeiler.com/Mailing-Lists/Kernel/2008-05/msg12924.html (anything over 6 is still i686)
|
35
36
|
# Also, arm and neutral are included because they are valid for the upcoming
|
36
37
|
# windows 8 release. --jeffweiss 23 May 2012
|
37
38
|
require 'facter/util/wmi'
|
38
39
|
model = ""
|
40
|
+
architecture_level = nil
|
41
|
+
|
39
42
|
Facter::Util::WMI.execquery("select Architecture, Level, AddressWidth from Win32_Processor").each do |cpu|
|
43
|
+
architecture_level = (cpu.Level > 5) ? 6 : cpu.Level;
|
44
|
+
|
40
45
|
model =
|
41
46
|
case cpu.Architecture
|
42
47
|
when 11 then 'neutral' # PROCESSOR_ARCHITECTURE_NEUTRAL
|
43
48
|
when 10 then 'i686' # PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
|
44
49
|
when 9 then # PROCESSOR_ARCHITECTURE_AMD64
|
45
|
-
cpu.AddressWidth == 32 ? "i#{
|
50
|
+
cpu.AddressWidth == 32 ? "i#{architecture_level}86" : 'x64' # 32 bit OS on 64 bit CPU
|
46
51
|
when 8 then 'msil' # PROCESSOR_ARCHITECTURE_MSIL
|
47
52
|
when 7 then 'alpha64' # PROCESSOR_ARCHITECTURE_ALPHA64
|
48
53
|
when 6 then 'ia64' # PROCESSOR_ARCHITECTURE_IA64
|
@@ -51,7 +56,7 @@ Facter.add(:hardwaremodel) do
|
|
51
56
|
when 3 then 'powerpc' # PROCESSOR_ARCHITECTURE_PPC
|
52
57
|
when 2 then 'alpha' # PROCESSOR_ARCHITECTURE_ALPHA
|
53
58
|
when 1 then 'mips' # PROCESSOR_ARCHITECTURE_MIPS
|
54
|
-
when 0 then "i#{
|
59
|
+
when 0 then "i#{architecture_level}86" # PROCESSOR_ARCHITECTURE_INTEL
|
55
60
|
else 'unknown' # PROCESSOR_ARCHITECTURE_UNKNOWN
|
56
61
|
end
|
57
62
|
break
|
data/lib/facter/ipaddress.rb
CHANGED
@@ -33,11 +33,13 @@ Facter.add(:ipaddress) do
|
|
33
33
|
regexp = /inet (?:addr:)?([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
|
34
34
|
output.split("\n").each do |line|
|
35
35
|
match = regexp.match(line)
|
36
|
-
if match
|
37
|
-
|
36
|
+
if match and not /^127\./.match(match[1])
|
37
|
+
ip = match[1]
|
38
|
+
break
|
38
39
|
end
|
39
40
|
end
|
40
41
|
end
|
42
|
+
ip
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
@@ -104,8 +106,18 @@ end
|
|
104
106
|
Facter.add(:ipaddress) do
|
105
107
|
confine :kernel => %w{windows}
|
106
108
|
setcode do
|
107
|
-
require '
|
108
|
-
|
109
|
+
require 'facter/util/ip/windows'
|
110
|
+
ipaddr = nil
|
111
|
+
|
112
|
+
adapters = Facter::Util::IP::Windows.get_preferred_ipv4_adapters
|
113
|
+
adapters.find do |nic|
|
114
|
+
nic.IPAddress.any? do |addr|
|
115
|
+
ipaddr = addr if Facter::Util::IP::Windows.valid_ipv4_address?(addr)
|
116
|
+
ipaddr
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
ipaddr
|
109
121
|
end
|
110
122
|
end
|
111
123
|
|
data/lib/facter/ipaddress6.rb
CHANGED
@@ -26,7 +26,7 @@ require 'facter/util/ip'
|
|
26
26
|
def get_address_after_token(output, token, return_first=false)
|
27
27
|
ip = nil
|
28
28
|
|
29
|
-
output.scan(/#{token}
|
29
|
+
String(output).scan(/#{token}\s?((?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/).each do |match|
|
30
30
|
match = match.first
|
31
31
|
unless match =~ /fe80.*/ or match == "::1"
|
32
32
|
ip = match
|
@@ -66,8 +66,17 @@ end
|
|
66
66
|
Facter.add(:ipaddress6) do
|
67
67
|
confine :kernel => :windows
|
68
68
|
setcode do
|
69
|
-
|
69
|
+
require 'facter/util/ip/windows'
|
70
|
+
ipaddr = nil
|
70
71
|
|
71
|
-
|
72
|
+
adapters = Facter::Util::IP::Windows.get_preferred_ipv6_adapters
|
73
|
+
adapters.find do |nic|
|
74
|
+
nic.IPAddress.any? do |addr|
|
75
|
+
ipaddr = addr if Facter::Util::IP::Windows.valid_ipv6_address?(addr)
|
76
|
+
ipaddr
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
ipaddr
|
72
81
|
end
|
73
82
|
end
|
data/lib/facter/macaddress.rb
CHANGED
@@ -29,7 +29,7 @@ Facter.add(:macaddress) do
|
|
29
29
|
ether = []
|
30
30
|
output = Facter::Util::IP.exec_ifconfig(["-a","2>/dev/null"])
|
31
31
|
|
32
|
-
output.each_line do |s|
|
32
|
+
String(output).each_line do |s|
|
33
33
|
ether.push($1) if s =~ /(?:ether|HWaddr) ((\w{1,2}:){5,}\w{1,2})/
|
34
34
|
end
|
35
35
|
Facter::Util::Macaddress.standardize(ether[0])
|
data/lib/facter/netmask.rb
CHANGED
@@ -21,3 +21,22 @@ Facter.add("netmask") do
|
|
21
21
|
Facter::NetMask.get_netmask
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
25
|
+
Facter.add(:netmask) do
|
26
|
+
confine :kernel => :windows
|
27
|
+
setcode do
|
28
|
+
require 'facter/util/ip/windows'
|
29
|
+
|
30
|
+
mask = nil
|
31
|
+
|
32
|
+
adapters = Facter::Util::IP::Windows.get_preferred_ipv4_adapters
|
33
|
+
adapters.find do |nic|
|
34
|
+
nic.IPSubnet.any? do |subnet|
|
35
|
+
mask = subnet if Facter::Util::IP::Windows.valid_ipv4_address?(subnet)
|
36
|
+
mask
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
mask
|
41
|
+
end
|
42
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# A Facter plugin that loads external facts.
|
2
2
|
#
|
3
3
|
# Default Unix Directories:
|
4
|
-
# /etc/facter/facts.d, /etc/
|
4
|
+
# /etc/facter/facts.d", "/etc/puppetlabs/facter/facts.d"
|
5
5
|
#
|
6
6
|
# Default Windows Direcotires:
|
7
7
|
# C:\ProgramData\Puppetlabs\facter\facts.d (2008)
|
data/lib/facter/util/ip.rb
CHANGED
@@ -31,11 +31,7 @@ module Facter::Util::IP
|
|
31
31
|
:macaddress => /(\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2})/,
|
32
32
|
:netmask => /.*\s+netmask (\S+)\s.*/
|
33
33
|
},
|
34
|
-
:windows => {
|
35
|
-
:ipaddress => /\s+IP Address:\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
|
36
|
-
:ipaddress6 => /Address ((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/,
|
37
|
-
:netmask => /\s+Subnet Prefix:\s+\S+\s+\(mask ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\)/
|
38
|
-
}
|
34
|
+
:windows => {}
|
39
35
|
}
|
40
36
|
|
41
37
|
# Convert an interface name into purely alphanumeric characters.
|
@@ -61,11 +57,12 @@ module Facter::Util::IP
|
|
61
57
|
end
|
62
58
|
|
63
59
|
def self.get_interfaces
|
64
|
-
|
60
|
+
if Facter.value(:kernel) == 'windows'
|
61
|
+
require 'facter/util/ip/windows'
|
62
|
+
return Facter::Util::IP::Windows.interfaces
|
63
|
+
end
|
65
64
|
|
66
|
-
|
67
|
-
# times as ipv4 and ipv6
|
68
|
-
return output.scan(/\s* connected\s*(\S.*)/).flatten.uniq if Facter.value(:kernel) == 'windows'
|
65
|
+
return [] unless output = Facter::Util::IP.get_all_interface_output()
|
69
66
|
|
70
67
|
# Our regex appears to be stupid, in that it leaves colons sitting
|
71
68
|
# at the end of interfaces. So, we have to trim those trailing
|
@@ -89,9 +86,6 @@ module Facter::Util::IP
|
|
89
86
|
output.sub!(/^[^\n]*\n/, "") # delete the header line.
|
90
87
|
output
|
91
88
|
end
|
92
|
-
when 'windows'
|
93
|
-
output = %x|#{ENV['SYSTEMROOT']}/system32/netsh.exe interface ip show interface|
|
94
|
-
output += %x|#{ENV['SYSTEMROOT']}/system32/netsh.exe interface ipv6 show interface|
|
95
89
|
end
|
96
90
|
output
|
97
91
|
end
|
@@ -172,12 +166,9 @@ module Facter::Util::IP
|
|
172
166
|
def self.get_output_for_interface_and_label(interface, label)
|
173
167
|
return get_single_interface_output(interface) unless Facter.value(:kernel) == 'windows'
|
174
168
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
output = %x|#{ENV['SYSTEMROOT']}/system32/netsh.exe interface ip show address \"#{interface}\"|
|
179
|
-
end
|
180
|
-
output
|
169
|
+
require 'facter/util/ip/windows'
|
170
|
+
output = Facter::Util::IP::Windows.value_for_interface_and_label(interface, label)
|
171
|
+
output ? output : ""
|
181
172
|
end
|
182
173
|
|
183
174
|
def self.get_bonding_master(interface)
|
@@ -220,6 +211,11 @@ module Facter::Util::IP
|
|
220
211
|
# @return [String] representing the requested value. An empty array is
|
221
212
|
# returned if the kernel is not supported by the REGEX_MAP constant.
|
222
213
|
def self.get_interface_value(interface, label)
|
214
|
+
if Facter.value(:kernel) == 'windows'
|
215
|
+
require 'facter/util/ip/windows'
|
216
|
+
return Facter::Util::IP::Windows.value_for_interface_and_label(interface, label)
|
217
|
+
end
|
218
|
+
|
223
219
|
tmp1 = []
|
224
220
|
|
225
221
|
kernel = Facter.value(:kernel).downcase.to_sym
|
@@ -0,0 +1,215 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'facter/util/wmi'
|
4
|
+
require 'facter/util/ip'
|
5
|
+
|
6
|
+
class Facter::Util::IP::Windows
|
7
|
+
# The WMI query used to return ip information
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
WMI_IP_INFO_QUERY = 'SELECT Description, ServiceName, IPAddress, IPConnectionMetric, InterfaceIndex, Index, IPSubnet, MACAddress, MTU, SettingID FROM Win32_NetworkAdapterConfiguration WHERE IPConnectionMetric IS NOT NULL AND IPEnabled = TRUE'
|
13
|
+
|
14
|
+
# Mapping fact names to WMI properties of the Win32_NetworkAdapterConfiguration
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
WINDOWS_LABEL_WMI_MAP = {
|
18
|
+
:ipaddress => 'IPAddress',
|
19
|
+
:ipaddress6 => 'IPAddress',
|
20
|
+
:macaddress => 'MACAddress',
|
21
|
+
:netmask => 'IPSubnet'
|
22
|
+
}
|
23
|
+
|
24
|
+
def self.to_s
|
25
|
+
'windows'
|
26
|
+
end
|
27
|
+
|
28
|
+
# Windows doesn't display netmask in hex.
|
29
|
+
#
|
30
|
+
# @return [Boolean] false by default
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
def self.convert_netmask_from_hex?
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
# Retrieves a list of unique interfaces names.
|
38
|
+
#
|
39
|
+
# @return [Array<String>]
|
40
|
+
#
|
41
|
+
# @api private
|
42
|
+
def self.interfaces
|
43
|
+
interface_names = []
|
44
|
+
|
45
|
+
network_adapter_configurations.map do |nic|
|
46
|
+
Facter::Util::WMI.execquery("SELECT * FROM Win32_NetworkAdapter WHERE Index = #{nic.Index}").each do |nic|
|
47
|
+
interface_names << nic.NetConnectionId
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
interface_names.uniq
|
52
|
+
end
|
53
|
+
|
54
|
+
# Get the value of an interface and label. For example, you may want to find
|
55
|
+
# the MTU for eth0.
|
56
|
+
#
|
57
|
+
# @param [String] interface the name of the interface returned by the {#interfaces} method.
|
58
|
+
# @param [String] label the type of value to return, e.g. ipaddress
|
59
|
+
# @return [String] the value, or nil if not defined
|
60
|
+
#
|
61
|
+
# @api private
|
62
|
+
def self.value_for_interface_and_label(interface, label)
|
63
|
+
wmi_value = WINDOWS_LABEL_WMI_MAP[label.downcase.to_sym]
|
64
|
+
label_value = nil
|
65
|
+
Facter::Util::WMI.execquery("SELECT Index FROM Win32_NetworkAdapter WHERE NetConnectionID = '#{interface}'").each do |nic|
|
66
|
+
Facter::Util::WMI.execquery("SELECT #{wmi_value} FROM Win32_NetworkAdapterConfiguration WHERE Index = #{nic.Index}").each do |nic_config|
|
67
|
+
case label.downcase.to_sym
|
68
|
+
when :ipaddress
|
69
|
+
nic_config.IPAddress.any? do |addr|
|
70
|
+
label_value = addr if valid_ipv4_address?(addr)
|
71
|
+
label_value
|
72
|
+
end
|
73
|
+
when :ipaddress6
|
74
|
+
nic_config.IPAddress.any? do |addr|
|
75
|
+
label_value = addr if Facter::Util::IP::Windows.valid_ipv6_address?(addr)
|
76
|
+
label_value
|
77
|
+
end
|
78
|
+
when :netmask
|
79
|
+
nic_config.IPSubnet.any? do |addr|
|
80
|
+
label_value = addr if Facter::Util::IP::Windows.valid_ipv4_address?(addr)
|
81
|
+
label_value
|
82
|
+
end
|
83
|
+
when :macaddress
|
84
|
+
label_value = nic_config.MACAddress
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
label_value
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns an array of partial Win32_NetworkAdapterConfiguration objects.
|
93
|
+
#
|
94
|
+
# @return [Array<WIN32OLE>] objects
|
95
|
+
#
|
96
|
+
# @api private
|
97
|
+
def self.network_adapter_configurations
|
98
|
+
nics = []
|
99
|
+
# WIN32OLE doesn't implement Enumerable
|
100
|
+
Facter::Util::WMI.execquery(WMI_IP_INFO_QUERY).each do |nic|
|
101
|
+
nics << nic
|
102
|
+
end
|
103
|
+
nics
|
104
|
+
end
|
105
|
+
|
106
|
+
# Gets a list of active IPv4 network adapter configurations sorted by the
|
107
|
+
# lowest IP connection metric. If two configurations have the same metric,
|
108
|
+
# then the IPv4 specific binding order as specified in the registry will
|
109
|
+
# be used.
|
110
|
+
#
|
111
|
+
# @return [Array<WIN32OLE>]
|
112
|
+
#
|
113
|
+
# @api private
|
114
|
+
def self.get_preferred_ipv4_adapters
|
115
|
+
get_preferred_network_adapters(Bindings4.new)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Gets a list of active IPv6 network adapter configurations sorted by the
|
119
|
+
# lowest IP connection metric. If two configurations have the same metric,
|
120
|
+
# then the IPv6 specific binding order as specified in the registry will
|
121
|
+
# be used.
|
122
|
+
#
|
123
|
+
# @return [Array<WIN32OLE>]
|
124
|
+
#
|
125
|
+
# @api private
|
126
|
+
def self.get_preferred_ipv6_adapters
|
127
|
+
get_preferred_network_adapters(Bindings6.new)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Gets a list of active network adapter configurations sorted by the lowest
|
131
|
+
# IP connection metric. If two configurations have the same metric, then
|
132
|
+
# the adapter binding order as specified in the registry will be used.
|
133
|
+
# Note the order may different for IPv4 vs IPv6 addresses.
|
134
|
+
#
|
135
|
+
# @see http://support.microsoft.com/kb/894564
|
136
|
+
# @return [Array<WIN32OLE>]
|
137
|
+
#
|
138
|
+
# @api private
|
139
|
+
def self.get_preferred_network_adapters(bindings)
|
140
|
+
network_adapter_configurations.select do |nic|
|
141
|
+
bindings.bindings.include?(nic.SettingID)
|
142
|
+
end.sort do |nic_left,nic_right|
|
143
|
+
cmp = nic_left.IPConnectionMetric <=> nic_right.IPConnectionMetric
|
144
|
+
if cmp == 0
|
145
|
+
bindings.bindings[nic_left.SettingID] <=> bindings.bindings[nic_right.SettingID]
|
146
|
+
else
|
147
|
+
cmp
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
class Bindings4
|
153
|
+
def initialize
|
154
|
+
@key = 'SYSTEM\CurrentControlSet\Services\Tcpip\Linkage'
|
155
|
+
end
|
156
|
+
|
157
|
+
def bindings
|
158
|
+
require 'facter/util/registry'
|
159
|
+
bindings = {}
|
160
|
+
|
161
|
+
Facter::Util::Registry.hklm_read(@key, 'Bind').each_with_index do |entry, index|
|
162
|
+
match_data = entry.match(/\\Device\\(\{.*\})/)
|
163
|
+
unless match_data.nil?
|
164
|
+
bindings[match_data[1]] = index
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
bindings
|
169
|
+
rescue
|
170
|
+
{}
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
class Bindings6 < Bindings4
|
175
|
+
def initialize
|
176
|
+
@key = 'SYSTEM\CurrentControlSet\Services\Tcpip6\Linkage'
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# Determines if the value passed in is a valid ipv4 address.
|
181
|
+
#
|
182
|
+
# @param [String] ip_address the IPv4 address to validate
|
183
|
+
# @return [Boolean]
|
184
|
+
#
|
185
|
+
# @api private
|
186
|
+
def self.valid_ipv4_address?(ip_address)
|
187
|
+
String(ip_address).scan(/(?:[0-9]{1,3}\.){3}[0-9]{1,3}/).each do |match|
|
188
|
+
# excluding 169.254.x.x in Windows - this is the DHCP APIPA
|
189
|
+
# meaning that if the node cannot get an ip address from the dhcp server,
|
190
|
+
# it auto-assigns a private ip address
|
191
|
+
unless match == "127.0.0.1" or match =~ /^169.254.*/
|
192
|
+
return !!match
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
false
|
197
|
+
end
|
198
|
+
|
199
|
+
# Determines if the value passed in is a valid ipv6 address.
|
200
|
+
#
|
201
|
+
# @param [String] ip_address the IPv6 address to validate
|
202
|
+
# @return [Boolean]
|
203
|
+
#
|
204
|
+
# @api private
|
205
|
+
def self.valid_ipv6_address?(ip_address)
|
206
|
+
String(ip_address).scan(/(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4}/).each do |match|
|
207
|
+
unless match =~ /fe80.*/ or match == "::1"
|
208
|
+
return !!match
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
false
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|