Signed-off-by: James Turnbull <
ja...@lovedthanlost.net>
---
lib/facter/ipaddress.rb | 32 ++++++-------
lib/facter/kernel.rb | 6 ++-
lib/facter/macaddress.rb | 29 +++++++++---
lib/facter/util/resolution.rb | 100 ++++++++++++++++++++++++++++++++---------
4 files changed, 118 insertions(+), 49 deletions(-)
diff --git a/lib/facter/ipaddress.rb b/lib/facter/ipaddress.rb
index dd0d418..318e10f 100644
--- a/lib/facter/ipaddress.rb
+++ b/lib/facter/ipaddress.rb
@@ -1,3 +1,5 @@
+require 'rbconfig'
+
Facter.add(:ipaddress) do
confine :kernel => :linux
setcode do
@@ -111,30 +113,26 @@ end
Facter.add(:ipaddress) do
confine :kernel => %w{windows}
- setcode do
- ip = nil
- output = %x{ipconfig}
-
- output.split(/^\S/).each { |str|
- if str =~ /IP Address.*: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/
- tmp = $1
- unless tmp =~ /^127\./
- ip = tmp
- break
- end
- end
- }
- ip
- end
+ require 'socket'
+ IPSocket.getaddress(Socket.gethostname)
end
Facter.add(:ipaddress, :ldapname => "iphostnumber", :timeout => 2) do
setcode do
- require 'resolv'
+ if Config::CONFIG['host_os'] =~ /mswin|win32|dos|cygwin|mingw/i
+ require 'win32/resolv'
+ else
+ require 'resolv'
+ end
begin
if hostname = Facter.value(:hostname)
- ip = Resolv.getaddress(hostname)
+ if Config::CONFIG['host_os'] =~ /mswin|win32|dos|cygwin|mingw/i
+ ip = Win32::Resolv.get_resolv_info.last[0]
+ else
+ ip = Resolv.getaddress(hostname)
+ end
+
unless ip == "127.0.0.1"
ip
end
diff --git a/lib/facter/kernel.rb b/lib/facter/kernel.rb
index d68aa3f..66f21ce 100644
--- a/lib/facter/kernel.rb
+++ b/lib/facter/kernel.rb
@@ -2,8 +2,10 @@ Facter.add(:kernel) do
setcode do
require 'rbconfig'
case Config::CONFIG['host_os']
- when /mswin/i; 'windows'
- else Facter::Util::Resolution.exec("uname -s")
+ when /mswin|win32|dos|cygwin|mingw/i
+ 'windows'
+ else
+ Facter::Util::Resolution.exec("uname -s")
end
end
end
diff --git a/lib/facter/macaddress.rb b/lib/facter/macaddress.rb
index e8f40dc..889feea 100644
--- a/lib/facter/macaddress.rb
+++ b/lib/facter/macaddress.rb
@@ -67,13 +67,26 @@ end
Facter.add(:macaddress) do
confine :kernel => %w(windows)
setcode do
- ether = []
- output = %x{ipconfig /all}
- output.split(/\r\n/).each do |str|
- if str =~ /.*Physical Address.*: (\w{1,2}-\w{1,2}-\w{1,2}-\w{1,2}-\w{1,2}-\w{1,2})/
- ether.push($1.gsub(/-/, ":"))
- end
- end
- ether[0]
+ require 'win32ole'
+ require 'socket'
+
+ ether = nil
+ host = Socket.gethostname
+ connect_string = "winmgmts://#{host}/root/cimv2"
+
+ wmi = WIN32OLE.connect(connect_string)
+
+ query = %Q{
+ select *
+ from Win32_NetworkAdapterConfiguration
+ where IPEnabled = True
+ }
+
+ wmi.ExecQuery(query).each{ |nic|
+ ether = nic.MacAddress
+ break
+ }
+
+ ether
end
end
diff --git a/lib/facter/util/resolution.rb b/lib/facter/util/resolution.rb
index b9e28e8..774fb5c 100644
--- a/lib/facter/util/resolution.rb
+++ b/lib/facter/util/resolution.rb
@@ -11,43 +11,99 @@ require 'rbconfig'
class Facter::Util::Resolution
attr_accessor :interpreter, :code, :name, :timeout
- def self.have_which
- if ! defined?(@have_which) or @have_which.nil?
- if Config::CONFIG['host_os'] =~ /mswin/
- @have_which = false
+ WINDOWS = Config::CONFIG['host_os'] =~ /mswin|win32|dos|mingw|cygwin/i
+
+ INTERPRETER = WINDOWS ? 'cmd.exe' : '/bin/sh'
+
+ # Looks for the first occurrence of +program+ within +path+.
+ #
+ # On Windows, it looks for executables ending with the suffixes defined
+ # in your PATHEXT environment variable, or '.exe', '.bat' and '.com' if
+ # that isn't defined, which you may optionally include in the +program+
+ # name itself.
+ #
+ # Returns nil if not found.
+ #
+ # Examples:
+ #
+ # File.which('ruby') # => '/usr/local/bin/ruby'
+ # File.which('foo') # => nil
+ #
+ # # On Windows
+ # File.which('notepad') # => 'C:/Program Files/Windows'
+ # File.which('notepad.exe') # => 'C:/Program Files/Windows'
+ #--
+ # Borrowed from the ptools library.
+ #
+ def self.which(program, path=ENV['PATH'])
+ programs = [program]
+
+ if WINDOWS
+ if ENV['PATHEXT']
+ extensions = ENV['PATHEXT'].split(';').map{ |e| e.downcase }
else
- %x{which which >/dev/null 2>&1}
- @have_which = ($? == 0)
+ extensions = %w[.exe .com .bat]
end
- end
- @have_which
- end
- # Execute a chunk of code.
- def self.exec(code, interpreter = "/bin/sh")
- raise ArgumentError, "non-sh interpreters are not currently supported" unless interpreter == "/bin/sh"
- binary = code.split(/\s+/).shift
-
- if have_which
- path = nil
- if binary !~ /^\//
- path = %x{which #{binary} 2>/dev/null}.chomp
- # we don't have the binary necessary
- return nil if path == "" or path.match(/Command not found\./)
- else
- path = binary
+ # Push all variants of the program + extension onto the list of
+ # programs to search for.
+ if File.extname(program).empty?
+ unless extensions.include?(File.extname(program).downcase)
+ extensions.each{ |ext|
+ programs.push(program + ext)
+ }
+ end
end
+ end
+
+ # Catch the first path found, or nil
+ location = catch(:done){
+ path.split(File::PATH_SEPARATOR).each{ |dir|
+ programs.each{ |prog|
+ f = File.join(dir, prog)
+ if File.executable?(f) && !File.directory?(f)
+ location = File.join(dir, prog)
+
location.tr!('/', File::ALT_SEPARATOR) if File::ALT_SEPARATOR
+ throw(:done, location)
+ end
+ }
+ }
+ nil # Evaluate to nil if not found
+ }
+
+ location
+ end
- return nil unless FileTest.exists?(path)
+ # Execute a program and return the output of that program.
+ #
+ # Returns nil if the program can't be found, or if there is a problem
+ # executing the code.
+ #
+ def self.exec(code, interpreter = INTERPRETER)
+ raise ArgumentError, "invalid interpreter" unless interpreter == INTERPRETER
+ binary = File.join(File.dirname(code), File.basename(code).split.first)
+
+ path = nil
+
+ # Don't look for the binary if an absolute path is provided
+ if binary !~ /^\/|^\w:[\/\\]/i
+ path = self.which(binary)
+ return nil if path.nil?
+ else
+ path = binary
end
+ return nil unless FileTest.exists?(path)
+
out = nil
+
begin
out = %x{#{code}}.chomp
rescue => detail
$stderr.puts detail
return nil
end
+
if out == ""
return nil
else
--
1.6.6.1
--
You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To post to this group, send email to
puppe...@googlegroups.com.
To unsubscribe from this group, send email to
puppet-dev+...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/puppet-dev?hl=en.