facter 1.6.1 → 1.6.2
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 +31 -0
- data/Rakefile +41 -36
- data/conf/redhat/facter.spec +11 -4
- data/conf/solaris/pkginfo +1 -1
- data/install.rb +286 -286
- data/lib/facter.rb +211 -211
- data/lib/facter/Cfkey.rb +24 -24
- data/lib/facter/application.rb +1 -0
- data/lib/facter/architecture.rb +21 -29
- data/lib/facter/domain.rb +34 -34
- data/lib/facter/facterversion.rb +1 -1
- data/lib/facter/fqdn.rb +8 -8
- data/lib/facter/hardwareisa.rb +2 -2
- data/lib/facter/hardwaremodel.rb +12 -12
- data/lib/facter/hostname.rb +14 -14
- data/lib/facter/id.rb +3 -3
- data/lib/facter/interfaces.rb +13 -13
- data/lib/facter/ipaddress.rb +101 -101
- data/lib/facter/iphostnumber.rb +12 -12
- data/lib/facter/kernel.rb +7 -7
- data/lib/facter/kernelmajversion.rb +3 -3
- data/lib/facter/kernelrelease.rb +12 -12
- data/lib/facter/kernelversion.rb +5 -5
- data/lib/facter/lsb.rb +14 -14
- data/lib/facter/lsbmajdistrelease.rb +8 -8
- data/lib/facter/macaddress.rb +44 -44
- data/lib/facter/macosx.rb +21 -21
- data/lib/facter/manufacturer.rb +28 -28
- data/lib/facter/memory.rb +143 -115
- data/lib/facter/netmask.rb +4 -4
- data/lib/facter/network.rb +4 -4
- data/lib/facter/operatingsystem.rb +73 -69
- data/lib/facter/operatingsystemrelease.rb +85 -79
- data/lib/facter/osfamily.rb +31 -0
- data/lib/facter/path.rb +3 -3
- data/lib/facter/physicalprocessorcount.rb +8 -0
- data/lib/facter/processor.rb +91 -72
- data/lib/facter/ps.rb +3 -3
- data/lib/facter/puppetversion.rb +7 -7
- data/lib/facter/rubysitedir.rb +5 -5
- data/lib/facter/rubyversion.rb +1 -1
- data/lib/facter/ssh.rb +16 -16
- data/lib/facter/timezone.rb +3 -3
- data/lib/facter/uniqueid.rb +2 -2
- data/lib/facter/util/collection.rb +96 -96
- data/lib/facter/util/confine.rb +30 -30
- data/lib/facter/util/fact.rb +95 -95
- data/lib/facter/util/ip.rb +173 -173
- data/lib/facter/util/loader.rb +88 -88
- data/lib/facter/util/macosx.rb +46 -46
- data/lib/facter/util/manufacturer.rb +78 -78
- data/lib/facter/util/memory.rb +63 -63
- data/lib/facter/util/netmask.rb +34 -34
- data/lib/facter/util/plist.rb +1 -1
- data/lib/facter/util/plist/generator.rb +177 -177
- data/lib/facter/util/plist/parser.rb +166 -166
- data/lib/facter/util/processor.rb +88 -0
- data/lib/facter/util/resolution.rb +154 -154
- data/lib/facter/util/uptime.rb +42 -42
- data/lib/facter/util/values.rb +9 -9
- data/lib/facter/util/virtual.rb +68 -58
- data/lib/facter/util/vlans.rb +17 -17
- data/lib/facter/virtual.rb +105 -110
- data/lib/facter/vlans.rb +6 -6
- data/spec/fixtures/cpuinfo/amd64dual +57 -0
- data/spec/fixtures/cpuinfo/amd64quad +79 -0
- data/spec/fixtures/cpuinfo/amd64solo +23 -0
- data/spec/fixtures/cpuinfo/amd64tri +86 -0
- data/spec/fixtures/cpuinfo/bbg3-armel +12 -0
- data/spec/fixtures/cpuinfo/beaglexm-armel +12 -0
- data/spec/fixtures/cpuinfo/panda-armel +17 -0
- data/spec/fixtures/cpuinfo/ppc64 +19 -0
- data/spec/fixtures/cpuinfo/sparc +10 -0
- data/spec/fixtures/processorcount/solaris-sparc-kstat-cpu-info +1216 -0
- data/spec/fixtures/processorcount/solaris-x86_64-kstat-cpu-info +225 -0
- data/spec/integration/facter_spec.rb +18 -18
- data/spec/spec_helper.rb +10 -1
- data/spec/unit/architecture_spec.rb +54 -0
- data/spec/unit/domain_spec.rb +23 -0
- data/spec/unit/memory_spec.rb +78 -1
- data/spec/unit/physicalprocessorcount_spec.rb +41 -35
- data/spec/unit/processor_spec.rb +183 -2
- data/spec/unit/util/processor_spec.rb +62 -0
- data/spec/unit/util/uptime_spec.rb +4 -4
- data/spec/unit/util/virtual_spec.rb +26 -5
- data/spec/unit/virtual_spec.rb +47 -2
- data/spec/watchr.rb +125 -0
- metadata +20 -4
data/lib/facter/util/confine.rb
CHANGED
@@ -4,38 +4,38 @@
|
|
4
4
|
require 'facter/util/values'
|
5
5
|
|
6
6
|
class Facter::Util::Confine
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
attr_accessor :fact, :values
|
8
|
+
|
9
|
+
include Facter::Util::Values
|
10
|
+
|
11
|
+
# Add the restriction. Requires the fact name, an operator, and the value
|
12
|
+
# we're comparing to.
|
13
|
+
def initialize(fact, *values)
|
14
|
+
raise ArgumentError, "The fact name must be provided" unless fact
|
15
|
+
raise ArgumentError, "One or more values must be provided" if values.empty?
|
16
|
+
@fact = fact
|
17
|
+
@values = values
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
return "'%s' '%s'" % [@fact, @values.join(",")]
|
22
|
+
end
|
23
|
+
|
24
|
+
# Evaluate the fact, returning true or false.
|
25
|
+
def true?
|
26
|
+
unless fact = Facter[@fact]
|
27
|
+
Facter.debug "No fact for %s" % @fact
|
28
|
+
return false
|
18
29
|
end
|
30
|
+
value = convert(fact.value)
|
19
31
|
|
20
|
-
|
21
|
-
return "'%s' '%s'" % [@fact, @values.join(",")]
|
22
|
-
end
|
32
|
+
return false if value.nil?
|
23
33
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
return false
|
29
|
-
end
|
30
|
-
value = convert(fact.value)
|
31
|
-
|
32
|
-
return false if value.nil?
|
33
|
-
|
34
|
-
@values.each do |v|
|
35
|
-
v = convert(v)
|
36
|
-
next unless v.class == value.class
|
37
|
-
return true if value == v
|
38
|
-
end
|
39
|
-
return false
|
34
|
+
@values.each do |v|
|
35
|
+
v = convert(v)
|
36
|
+
next unless v.class == value.class
|
37
|
+
return true if value == v
|
40
38
|
end
|
39
|
+
return false
|
40
|
+
end
|
41
41
|
end
|
data/lib/facter/util/fact.rb
CHANGED
@@ -2,119 +2,119 @@ require 'facter'
|
|
2
2
|
require 'facter/util/resolution'
|
3
3
|
|
4
4
|
class Facter::Util::Fact
|
5
|
-
|
5
|
+
TIMEOUT = 5
|
6
|
+
|
7
|
+
attr_accessor :name, :ldapname
|
8
|
+
|
9
|
+
# Create a new fact, with no resolution mechanisms.
|
10
|
+
def initialize(name, options = {})
|
11
|
+
@name = name.to_s.downcase.intern
|
12
|
+
|
13
|
+
# LAK:NOTE: This is slow for many options, but generally we won't have any and at
|
14
|
+
# worst we'll have one. If we add more, this should be made more efficient.
|
15
|
+
options.each do |name, value|
|
16
|
+
case name
|
17
|
+
when :ldapname; self.ldapname = value
|
18
|
+
else
|
19
|
+
raise ArgumentError, "Invalid fact option '%s'" % name
|
20
|
+
end
|
21
|
+
end
|
6
22
|
|
7
|
-
|
23
|
+
@ldapname ||= @name.to_s
|
8
24
|
|
9
|
-
|
10
|
-
|
11
|
-
@name = name.to_s.downcase.intern
|
25
|
+
@resolves = []
|
26
|
+
@searching = false
|
12
27
|
|
13
|
-
|
14
|
-
|
15
|
-
options.each do |name, value|
|
16
|
-
case name
|
17
|
-
when :ldapname; self.ldapname = value
|
18
|
-
else
|
19
|
-
raise ArgumentError, "Invalid fact option '%s'" % name
|
20
|
-
end
|
21
|
-
end
|
28
|
+
@value = nil
|
29
|
+
end
|
22
30
|
|
23
|
-
|
31
|
+
# Add a new resolution mechanism. This requires a block, which will then
|
32
|
+
# be evaluated in the context of the new mechanism.
|
33
|
+
def add(&block)
|
34
|
+
raise ArgumentError, "You must pass a block to Fact<instance>.add" unless block_given?
|
24
35
|
|
25
|
-
|
26
|
-
@searching = false
|
36
|
+
resolve = Facter::Util::Resolution.new(@name)
|
27
37
|
|
28
|
-
|
29
|
-
end
|
38
|
+
resolve.instance_eval(&block)
|
30
39
|
|
31
|
-
|
32
|
-
# be evaluated in the context of the new mechanism.
|
33
|
-
def add(&block)
|
34
|
-
raise ArgumentError, "You must pass a block to Fact<instance>.add" unless block_given?
|
40
|
+
@resolves << resolve
|
35
41
|
|
36
|
-
|
42
|
+
# Immediately sort the resolutions, so that we always have
|
43
|
+
# a sorted list for looking up values.
|
44
|
+
@resolves.sort! { |a, b| b.weight <=> a.weight }
|
37
45
|
|
38
|
-
|
46
|
+
return resolve
|
47
|
+
end
|
39
48
|
|
40
|
-
|
49
|
+
# Flush any cached values.
|
50
|
+
def flush
|
51
|
+
@value = nil
|
52
|
+
@suitable = nil
|
53
|
+
end
|
41
54
|
|
42
|
-
|
43
|
-
|
44
|
-
|
55
|
+
# Return the value for a given fact. Searches through all of the mechanisms
|
56
|
+
# and returns either the first value or nil.
|
57
|
+
def value
|
58
|
+
return @value if @value
|
45
59
|
|
46
|
-
|
60
|
+
if @resolves.length == 0
|
61
|
+
Facter.debug "No resolves for %s" % @name
|
62
|
+
return nil
|
47
63
|
end
|
48
64
|
|
49
|
-
|
50
|
-
|
51
|
-
@value = nil
|
52
|
-
@suitable = nil
|
53
|
-
end
|
65
|
+
searching do
|
66
|
+
@value = nil
|
54
67
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
if @resolves.length == 0
|
61
|
-
Facter.debug "No resolves for %s" % @name
|
62
|
-
return nil
|
63
|
-
end
|
64
|
-
|
65
|
-
searching do
|
66
|
-
@value = nil
|
67
|
-
|
68
|
-
foundsuits = false
|
69
|
-
@value = @resolves.inject(nil) { |result, resolve|
|
70
|
-
next unless resolve.suitable?
|
71
|
-
foundsuits = true
|
72
|
-
|
73
|
-
tmp = resolve.value
|
74
|
-
|
75
|
-
break tmp unless tmp.nil? or tmp == ""
|
76
|
-
}
|
77
|
-
|
78
|
-
unless foundsuits
|
79
|
-
Facter.debug "Found no suitable resolves of %s for %s" % [@resolves.length, @name]
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
if @value.nil?
|
84
|
-
# nothing
|
85
|
-
Facter.debug("value for %s is still nil" % @name)
|
86
|
-
return nil
|
87
|
-
else
|
88
|
-
return @value
|
89
|
-
end
|
90
|
-
end
|
68
|
+
foundsuits = false
|
69
|
+
@value = @resolves.inject(nil) { |result, resolve|
|
70
|
+
next unless resolve.suitable?
|
71
|
+
foundsuits = true
|
91
72
|
|
92
|
-
|
73
|
+
tmp = resolve.value
|
93
74
|
|
94
|
-
|
95
|
-
|
96
|
-
|
75
|
+
break tmp unless tmp.nil? or tmp == ""
|
76
|
+
}
|
77
|
+
|
78
|
+
unless foundsuits
|
79
|
+
Facter.debug "Found no suitable resolves of %s for %s" % [@resolves.length, @name]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
if @value.nil?
|
84
|
+
# nothing
|
85
|
+
Facter.debug("value for %s is still nil" % @name)
|
86
|
+
return nil
|
87
|
+
else
|
88
|
+
return @value
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
# Are we in the midst of a search?
|
95
|
+
def searching?
|
96
|
+
@searching
|
97
|
+
end
|
98
|
+
|
99
|
+
# Lock our searching process, so we never ge stuck in recursion.
|
100
|
+
def searching
|
101
|
+
if searching?
|
102
|
+
Facter.debug "Caught recursion on %s" % @name
|
103
|
+
|
104
|
+
# return a cached value if we've got it
|
105
|
+
if @value
|
106
|
+
return @value
|
107
|
+
else
|
108
|
+
return nil
|
109
|
+
end
|
97
110
|
end
|
98
111
|
|
99
|
-
#
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
if @value
|
106
|
-
return @value
|
107
|
-
else
|
108
|
-
return nil
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# If we've gotten this far, we're not already searching, so go ahead and do so.
|
113
|
-
@searching = true
|
114
|
-
begin
|
115
|
-
yield
|
116
|
-
ensure
|
117
|
-
@searching = false
|
118
|
-
end
|
112
|
+
# If we've gotten this far, we're not already searching, so go ahead and do so.
|
113
|
+
@searching = true
|
114
|
+
begin
|
115
|
+
yield
|
116
|
+
ensure
|
117
|
+
@searching = false
|
119
118
|
end
|
119
|
+
end
|
120
120
|
end
|
data/lib/facter/util/ip.rb
CHANGED
@@ -1,202 +1,202 @@
|
|
1
1
|
# A base module for collecting IP-related
|
2
2
|
# information from all kinds of platforms.
|
3
3
|
module Facter::Util::IP
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
}
|
4
|
+
# A map of all the different regexes that work for
|
5
|
+
# a given platform or set of platforms.
|
6
|
+
REGEX_MAP = {
|
7
|
+
:linux => {
|
8
|
+
:ipaddress => /inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
|
9
|
+
:ipaddress6 => /inet6 addr: ((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/,
|
10
|
+
:macaddress => /(?:ether|HWaddr)\s+(\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2})/,
|
11
|
+
:netmask => /Mask:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
|
12
|
+
},
|
13
|
+
:bsd => {
|
14
|
+
:aliases => [:openbsd, :netbsd, :freebsd, :darwin, :"gnu/kfreebsd", :dragonfly],
|
15
|
+
:ipaddress => /inet\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
|
16
|
+
:ipaddress6 => /inet6 ((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/,
|
17
|
+
:macaddress => /(?:ether|lladdr)\s+(\w?\w:\w?\w:\w?\w:\w?\w:\w?\w:\w?\w)/,
|
18
|
+
:netmask => /netmask\s+0x(\w{8})/
|
19
|
+
},
|
20
|
+
:sunos => {
|
21
|
+
:ipaddress => /inet\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/,
|
22
|
+
:ipaddress6 => /inet6 ((?![fe80|::1])(?>[0-9,a-f,A-F]*\:{1,2})+[0-9,a-f,A-F]{0,4})/,
|
23
|
+
:macaddress => /(?:ether|lladdr)\s+(\w?\w:\w?\w:\w?\w:\w?\w:\w?\w:\w?\w)/,
|
24
|
+
:netmask => /netmask\s+(\w{8})/
|
25
|
+
},
|
26
|
+
:"hp-ux" => {
|
27
|
+
:ipaddress => /\s+inet (\S+)\s.*/,
|
28
|
+
:macaddress => /(\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2}:\w{1,2})/,
|
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]+)\)/
|
36
35
|
}
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
}
|
37
|
+
|
38
|
+
# Convert an interface name into purely alphanumeric characters.
|
39
|
+
def self.alphafy(interface)
|
40
|
+
interface.gsub(/[^a-z0-9_]/i, '_')
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.convert_from_hex?(kernel)
|
44
|
+
kernels_to_convert = [:sunos, :openbsd, :netbsd, :freebsd, :darwin, :"hp-ux", :"gnu/kfreebsd", :dragonfly]
|
45
|
+
kernels_to_convert.include?(kernel)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.supported_platforms
|
49
|
+
REGEX_MAP.inject([]) do |result, tmp|
|
50
|
+
key, map = tmp
|
51
|
+
if map[:aliases]
|
52
|
+
result += map[:aliases]
|
53
|
+
else
|
54
|
+
result << key
|
55
|
+
end
|
56
|
+
result
|
41
57
|
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.get_interfaces
|
61
|
+
return [] unless output = Facter::Util::IP.get_all_interface_output()
|
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
|
+
|
67
|
+
# Our regex appears to be stupid, in that it leaves colons sitting
|
68
|
+
# at the end of interfaces. So, we have to trim those trailing
|
69
|
+
# characters. I tried making the regex better but supporting all
|
70
|
+
# platforms with a single regex is probably a bit too much.
|
71
|
+
output.scan(/^\S+/).collect { |i| i.sub(/:$/, '') }.uniq
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.get_all_interface_output
|
75
|
+
case Facter.value(:kernel)
|
76
|
+
when 'Linux', 'OpenBSD', 'NetBSD', 'FreeBSD', 'Darwin', 'GNU/kFreeBSD', 'DragonFly'
|
77
|
+
output = %x{/sbin/ifconfig -a}
|
78
|
+
when 'SunOS'
|
79
|
+
output = %x{/usr/sbin/ifconfig -a}
|
80
|
+
when 'HP-UX'
|
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|
|
46
85
|
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
86
|
+
output
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.get_single_interface_output(interface)
|
90
|
+
output = ""
|
91
|
+
case Facter.value(:kernel)
|
92
|
+
when 'Linux', 'OpenBSD', 'NetBSD', 'FreeBSD', 'Darwin', 'GNU/kFreeBSD', 'DragonFly'
|
93
|
+
output = %x{/sbin/ifconfig #{interface}}
|
94
|
+
when 'SunOS'
|
95
|
+
output = %x{/usr/sbin/ifconfig #{interface}}
|
96
|
+
when 'HP-UX'
|
97
|
+
mac = ""
|
98
|
+
ifc = %x{/usr/sbin/ifconfig #{interface}}
|
99
|
+
%x{/usr/sbin/lanscan}.scan(/(\dx\S+).*UP\s+(\w+\d+)/).each {|i| mac = i[0] if i.include?(interface) }
|
100
|
+
mac = mac.sub(/0x(\S+)/,'\1').scan(/../).join(":")
|
101
|
+
output = ifc + "\n" + mac
|
58
102
|
end
|
103
|
+
output
|
104
|
+
end
|
59
105
|
|
60
|
-
|
61
|
-
|
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'
|
106
|
+
def self.get_output_for_interface_and_label(interface, label)
|
107
|
+
return get_single_interface_output(interface) unless Facter.value(:kernel) == 'windows'
|
66
108
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
output.scan(/^\S+/).collect { |i| i.sub(/:$/, '') }.uniq
|
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}\"|
|
72
113
|
end
|
114
|
+
output
|
115
|
+
end
|
73
116
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
output = %x{/sbin/ifconfig -a}
|
78
|
-
when 'SunOS'
|
79
|
-
output = %x{/usr/sbin/ifconfig -a}
|
80
|
-
when 'HP-UX'
|
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|
|
85
|
-
end
|
86
|
-
output
|
117
|
+
def self.get_bonding_master(interface)
|
118
|
+
if Facter.value(:kernel) != 'Linux'
|
119
|
+
return nil
|
87
120
|
end
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
when 'Linux', 'OpenBSD', 'NetBSD', 'FreeBSD', 'Darwin', 'GNU/kFreeBSD'
|
93
|
-
output = %x{/sbin/ifconfig #{interface}}
|
94
|
-
when 'SunOS'
|
95
|
-
output = %x{/usr/sbin/ifconfig #{interface}}
|
96
|
-
when 'HP-UX'
|
97
|
-
mac = ""
|
98
|
-
ifc = %x{/usr/sbin/ifconfig #{interface}}
|
99
|
-
%x{/usr/sbin/lanscan}.scan(/(\dx\S+).*UP\s+(\w+\d+)/).each {|i| mac = i[0] if i.include?(interface) }
|
100
|
-
mac = mac.sub(/0x(\S+)/,'\1').scan(/../).join(":")
|
101
|
-
output = ifc + "\n" + mac
|
102
|
-
end
|
103
|
-
output
|
121
|
+
# We need ip instead of ifconfig because it will show us
|
122
|
+
# the bonding master device.
|
123
|
+
if not FileTest.executable?("/sbin/ip")
|
124
|
+
return nil
|
104
125
|
end
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
else
|
112
|
-
output = %x|#{ENV['SYSTEMROOT']}/system32/netsh interface ip show address \"#{interface}\"|
|
113
|
-
end
|
114
|
-
output
|
126
|
+
# A bonding interface can never be an alias interface. Alias
|
127
|
+
# interfaces do have a colon in their name and the ip link show
|
128
|
+
# command throws an error message when we pass it an alias
|
129
|
+
# interface.
|
130
|
+
if interface =~ /:/
|
131
|
+
return nil
|
115
132
|
end
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
# the bonding master device.
|
123
|
-
if not FileTest.executable?("/sbin/ip")
|
124
|
-
return nil
|
125
|
-
end
|
126
|
-
# A bonding interface can never be an alias interface. Alias
|
127
|
-
# interfaces do have a colon in their name and the ip link show
|
128
|
-
# command throws an error message when we pass it an alias
|
129
|
-
# interface.
|
130
|
-
if interface =~ /:/
|
131
|
-
return nil
|
132
|
-
end
|
133
|
-
regex = /SLAVE[,>].* (bond[0-9]+)/
|
134
|
-
ethbond = regex.match(%x{/sbin/ip link show #{interface}})
|
135
|
-
if ethbond
|
136
|
-
device = ethbond[1]
|
137
|
-
else
|
138
|
-
device = nil
|
139
|
-
end
|
140
|
-
device
|
133
|
+
regex = /SLAVE[,>].* (bond[0-9]+)/
|
134
|
+
ethbond = regex.match(%x{/sbin/ip link show #{interface}})
|
135
|
+
if ethbond
|
136
|
+
device = ethbond[1]
|
137
|
+
else
|
138
|
+
device = nil
|
141
139
|
end
|
140
|
+
device
|
141
|
+
end
|
142
142
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
kernel = Facter.value(:kernel).downcase.to_sym
|
143
|
+
def self.get_interface_value(interface, label)
|
144
|
+
tmp1 = []
|
147
145
|
|
148
|
-
|
149
|
-
unless map = REGEX_MAP[kernel] || REGEX_MAP.values.find { |tmp| tmp[:aliases] and tmp[:aliases].include?(kernel) }
|
150
|
-
return []
|
151
|
-
end
|
146
|
+
kernel = Facter.value(:kernel).downcase.to_sym
|
152
147
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
# becomes a slave of a bonding device to the master MAC address.
|
158
|
-
# We have to dig a bit to get the original/real MAC address of the interface.
|
159
|
-
bonddev = get_bonding_master(interface)
|
160
|
-
if label == 'macaddress' and bonddev
|
161
|
-
bondinfo = IO.readlines("/proc/net/bonding/#{bonddev}")
|
162
|
-
hwaddrre = /^Slave Interface: #{interface}\n[^\n].+?\nPermanent HW addr: (([0-9a-fA-F]{2}:?)*)$/m
|
163
|
-
value = hwaddrre.match(bondinfo.to_s)[1].upcase
|
164
|
-
else
|
165
|
-
output_int = get_output_for_interface_and_label(interface, label)
|
166
|
-
|
167
|
-
output_int.each_line do |s|
|
168
|
-
if s =~ regex
|
169
|
-
value = $1
|
170
|
-
if label == 'netmask' && convert_from_hex?(kernel)
|
171
|
-
value = value.scan(/../).collect do |byte| byte.to_i(16) end.join('.')
|
172
|
-
end
|
173
|
-
tmp1.push(value)
|
174
|
-
end
|
175
|
-
end
|
148
|
+
# If it's not directly in the map or aliased in the map, then we don't know how to deal with it.
|
149
|
+
unless map = REGEX_MAP[kernel] || REGEX_MAP.values.find { |tmp| tmp[:aliases] and tmp[:aliases].include?(kernel) }
|
150
|
+
return []
|
151
|
+
end
|
176
152
|
|
177
|
-
|
178
|
-
|
153
|
+
# Pull the correct regex out of the map.
|
154
|
+
regex = map[label.to_sym]
|
155
|
+
|
156
|
+
# Linux changes the MAC address reported via ifconfig when an ethernet interface
|
157
|
+
# becomes a slave of a bonding device to the master MAC address.
|
158
|
+
# We have to dig a bit to get the original/real MAC address of the interface.
|
159
|
+
bonddev = get_bonding_master(interface)
|
160
|
+
if label == 'macaddress' and bonddev
|
161
|
+
bondinfo = IO.readlines("/proc/net/bonding/#{bonddev}")
|
162
|
+
hwaddrre = /^Slave Interface: #{interface}\n[^\n].+?\nPermanent HW addr: (([0-9a-fA-F]{2}:?)*)$/m
|
163
|
+
value = hwaddrre.match(bondinfo.to_s)[1].upcase
|
164
|
+
else
|
165
|
+
output_int = get_output_for_interface_and_label(interface, label)
|
166
|
+
|
167
|
+
output_int.each_line do |s|
|
168
|
+
if s =~ regex
|
169
|
+
value = $1
|
170
|
+
if label == 'netmask' && convert_from_hex?(kernel)
|
171
|
+
value = value.scan(/../).collect do |byte| byte.to_i(16) end.join('.')
|
179
172
|
end
|
173
|
+
tmp1.push(value)
|
180
174
|
end
|
175
|
+
end
|
176
|
+
|
177
|
+
if tmp1
|
178
|
+
value = tmp1.shift
|
179
|
+
end
|
181
180
|
end
|
181
|
+
end
|
182
182
|
|
183
|
-
|
184
|
-
|
183
|
+
def self.get_network_value(interface)
|
184
|
+
require 'ipaddr'
|
185
185
|
|
186
|
-
|
187
|
-
|
186
|
+
ipaddress = get_interface_value(interface, "ipaddress")
|
187
|
+
netmask = get_interface_value(interface, "netmask")
|
188
188
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
end
|
189
|
+
if ipaddress && netmask
|
190
|
+
ip = IPAddr.new(ipaddress, Socket::AF_INET)
|
191
|
+
subnet = IPAddr.new(netmask, Socket::AF_INET)
|
192
|
+
network = ip.mask(subnet.to_s).to_s
|
194
193
|
end
|
194
|
+
end
|
195
195
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
end
|
196
|
+
def self.get_arp_value(interface)
|
197
|
+
arp = Facter::Util::Resolution.exec("arp -en -i #{interface} | sed -e 1d")
|
198
|
+
if arp =~ /^\S+\s+\w+\s+(\S+)\s+\w\s+\S+$/
|
199
|
+
return $1
|
201
200
|
end
|
201
|
+
end
|
202
202
|
end
|