summaryrefslogtreecommitdiffstats
path: root/lib/puppet/util/network_device
diff options
context:
space:
mode:
authorPieter van de Bruggen <pieter@puppetlabs.com>2011-04-18 13:40:31 -0700
committerPieter van de Bruggen <pieter@puppetlabs.com>2011-04-18 14:08:32 -0700
commit07b677c5f6af8def03c5c30393fd83bc3986239a (patch)
treeb28d3376b4ea835a2348ebfea898d674cb593e34 /lib/puppet/util/network_device
parentb142973a94ced6c0ff43da882189abe806c18c68 (diff)
downloadpuppet-07b677c5f6af8def03c5c30393fd83bc3986239a.tar.gz
puppet-07b677c5f6af8def03c5c30393fd83bc3986239a.tar.xz
puppet-07b677c5f6af8def03c5c30393fd83bc3986239a.zip
Merge remote-tracking branch 'community/feature/puppet-device' into 2.7.x
Reviewed-By: Mike Stahnke
Diffstat (limited to 'lib/puppet/util/network_device')
-rw-r--r--lib/puppet/util/network_device/base.rb32
-rw-r--r--lib/puppet/util/network_device/cisco/device.rb10
-rw-r--r--lib/puppet/util/network_device/cisco/facts.rb72
-rw-r--r--lib/puppet/util/network_device/config.rb93
-rw-r--r--lib/puppet/util/network_device/transport.rb4
-rw-r--r--lib/puppet/util/network_device/transport/ssh.rb4
6 files changed, 195 insertions, 20 deletions
diff --git a/lib/puppet/util/network_device/base.rb b/lib/puppet/util/network_device/base.rb
index ff96c8693..7d6c3fc44 100644
--- a/lib/puppet/util/network_device/base.rb
+++ b/lib/puppet/util/network_device/base.rb
@@ -3,27 +3,25 @@ require 'uri'
require 'puppet/util/network_device/transport'
require 'puppet/util/network_device/transport/base'
-module Puppet::Util::NetworkDevice
- class Base
+class Puppet::Util::NetworkDevice::Base
- attr_accessor :url, :transport
+ attr_accessor :url, :transport
- def initialize(url)
- @url = URI.parse(url)
+ def initialize(url)
+ @url = URI.parse(url)
- @autoloader = Puppet::Util::Autoload.new(
- self,
- "puppet/util/network_device/transport",
- :wrap => false
- )
+ @autoloader = Puppet::Util::Autoload.new(
+ self,
+ "puppet/util/network_device/transport",
+ :wrap => false
+ )
- if @autoloader.load(@url.scheme)
- @transport = Puppet::Util::NetworkDevice::Transport.const_get(@url.scheme.capitalize).new
- @transport.host = @url.host
- @transport.port = @url.port || case @url.scheme ; when "ssh" ; 22 ; when "telnet" ; 23 ; end
- @transport.user = @url.user
- @transport.password = @url.password
- end
+ if @autoloader.load(@url.scheme)
+ @transport = Puppet::Util::NetworkDevice::Transport.const_get(@url.scheme.capitalize).new
+ @transport.host = @url.host
+ @transport.port = @url.port || case @url.scheme ; when "ssh" ; 22 ; when "telnet" ; 23 ; end
+ @transport.user = @url.user
+ @transport.password = @url.password
end
end
end \ No newline at end of file
diff --git a/lib/puppet/util/network_device/cisco/device.rb b/lib/puppet/util/network_device/cisco/device.rb
index 1f350991a..005470e13 100644
--- a/lib/puppet/util/network_device/cisco/device.rb
+++ b/lib/puppet/util/network_device/cisco/device.rb
@@ -3,6 +3,7 @@ require 'puppet/util'
require 'puppet/util/network_device/base'
require 'puppet/util/network_device/ipcalc'
require 'puppet/util/network_device/cisco/interface'
+require 'puppet/util/network_device/cisco/facts'
require 'ipaddr'
class Puppet::Util::NetworkDevice::Cisco::Device < Puppet::Util::NetworkDevice::Base
@@ -91,6 +92,15 @@ class Puppet::Util::NetworkDevice::Cisco::Device < Puppet::Util::NetworkDevice::
interface
end
+ def facts
+ @facts ||= Puppet::Util::NetworkDevice::Cisco::Facts.new(transport)
+ facts = {}
+ command do |ng|
+ facts = @facts.retrieve
+ end
+ facts
+ end
+
def interface(name)
ifname = canonalize_ifname(name)
interface = parse_interface(ifname)
diff --git a/lib/puppet/util/network_device/cisco/facts.rb b/lib/puppet/util/network_device/cisco/facts.rb
new file mode 100644
index 000000000..40e2b37c2
--- /dev/null
+++ b/lib/puppet/util/network_device/cisco/facts.rb
@@ -0,0 +1,72 @@
+
+require 'puppet/util/network_device/cisco'
+require 'puppet/util/network_device/ipcalc'
+
+# this retrieves facts from a cisco device
+class Puppet::Util::NetworkDevice::Cisco::Facts
+
+ attr_reader :transport
+
+ def initialize(transport)
+ @transport = transport
+ end
+
+ def retrieve
+ facts = {}
+ facts.merge(parse_show_ver)
+ end
+
+ def parse_show_ver
+ facts = {}
+ out = @transport.command("sh ver")
+ lines = out.split("\n")
+ lines.shift; lines.pop
+ lines.each do |l|
+ case l
+ # cisco WS-C2924C-XL (PowerPC403GA) processor (revision 0x11) with 8192K/1024K bytes of memory.
+ # Cisco 1841 (revision 5.0) with 355328K/37888K bytes of memory.
+ # Cisco 877 (MPC8272) processor (revision 0x200) with 118784K/12288K bytes of memory.
+ # cisco WS-C2960G-48TC-L (PowerPC405) processor (revision C0) with 61440K/4088K bytes of memory.
+ # cisco WS-C2950T-24 (RC32300) processor (revision R0) with 19959K bytes of memory.
+ when /[cC]isco ([\w-]+) (?:\(([\w-]+)\) processor )?\(revision (.+)\) with (\d+[KMG])(?:\/(\d+[KMG]))? bytes of memory\./
+ facts[:hardwaremodel] = $1
+ facts[:processor] = $2 if $2
+ facts[:hardwarerevision] = $3
+ facts[:memorysize] = $4
+ # uptime
+ # Switch uptime is 1 year, 12 weeks, 6 days, 22 hours, 32 minutes
+ # c2950 uptime is 3 weeks, 1 day, 23 hours, 36 minutes
+ # c2960 uptime is 2 years, 27 weeks, 5 days, 21 hours, 30 minutes
+ # router uptime is 5 weeks, 1 day, 3 hours, 30 minutes
+ when /^\s*([\w-]+)\s+uptime is (.*?)$/
+ facts[:hostname] = $1
+ facts[:uptime] = $2
+ facts[:uptime_seconds] = uptime_to_seconds($2)
+ facts[:uptime_days] = facts[:uptime_seconds] / 86400
+ # "IOS (tm) C2900XL Software (C2900XL-C3H2S-M), Version 12.0(5)WC10, RELEASE SOFTWARE (fc1)"=> { :operatingsystem => "IOS", :operatingsystemrelease => "12.0(5)WC10", :operatingsystemmajrelease => "12.0", :operatingsystemfeature => "C3H2S"},
+ # "IOS (tm) C2950 Software (C2950-I6K2L2Q4-M), Version 12.1(22)EA8a, RELEASE SOFTWARE (fc1)"=> { :operatingsystem => "IOS", :operatingsystemrelease => "12.1(22)EA8a", :operatingsystemmajrelease => "12.1", :operatingsystemfeature => "I6K2L2Q4"},
+ # "Cisco IOS Software, C2960 Software (C2960-LANBASEK9-M), Version 12.2(44)SE, RELEASE SOFTWARE (fc1)"=>{ :operatingsystem => "IOS", :operatingsystemrelease => "12.2(44)SE", :operatingsystemmajrelease => "12.2", :operatingsystemfeature => "LANBASEK9"},
+ # "Cisco IOS Software, C870 Software (C870-ADVIPSERVICESK9-M), Version 12.4(11)XJ4, RELEASE SOFTWARE (fc2)"=>{ :operatingsystem => "IOS", :operatingsystemrelease => "12.4(11)XJ40", :operatingsystemmajrelease => "12.4XJ", :operatingsystemfeature => "ADVIPSERVICESK9"},
+ # "Cisco IOS Software, 1841 Software (C1841-ADVSECURITYK9-M), Version 12.4(24)T4, RELEASE SOFTWARE (fc2)" =>{ :operatingsystem => "IOS", :operatingsystemrelease => "12.4(24)T4", :operatingsystemmajrelease => "12.4T", :operatingsystemfeature => "ADVSECURITYK9"},
+ when /(?:Cisco )?(IOS)\s*(?:\(tm\) |Software, )?(?:\w+)\s+Software\s+\(\w+-(\w+)-\w+\), Version ([0-9.()A-Za-z]+),/
+ facts[:operatingsystem] = $1
+ facts[:operatingsystemrelease] = $3
+ facts[:operatingsystemmajrelease] = ios_major_version(facts[:operatingsystemrelease])
+ facts[:operatingsystemfeature] = $2
+ end
+ end
+ facts
+ end
+
+ def ios_major_version(version)
+ version.gsub(/^(\d+)\.(\d+)\(.+\)([A-Z]+)([\da-z]+)?/, '\1.\2\3')
+ end
+
+ def uptime_to_seconds(uptime)
+ captures = (uptime.match /^(?:(?:(?:(?:(\d+) years?,)?\s*(\d+) weeks?,)?\s*(\d+) days?,)?\s*(\d+) hours?,)?\s*(\d+) minutes?$/).captures
+ seconds = captures.zip([31536000, 604800, 86400, 3600, 60]).inject(0) do |total, (x,y)|
+ total + (x.nil? ? 0 : x.to_i * y)
+ end
+ end
+
+end \ No newline at end of file
diff --git a/lib/puppet/util/network_device/config.rb b/lib/puppet/util/network_device/config.rb
new file mode 100644
index 000000000..17f4e254c
--- /dev/null
+++ b/lib/puppet/util/network_device/config.rb
@@ -0,0 +1,93 @@
+require 'ostruct'
+require 'puppet/util/loadedfile'
+
+class Puppet::Util::NetworkDevice::Config < Puppet::Util::LoadedFile
+
+ def self.main
+ @main ||= self.new
+ end
+
+ def self.devices
+ main.devices || []
+ end
+
+ attr_reader :devices
+
+ def exists?
+ FileTest.exists?(@file)
+ end
+
+ def initialize()
+ @file = Puppet[:deviceconfig]
+
+ raise Puppet::DevError, "No device config file defined" unless @file
+ return unless self.exists?
+ super(@file)
+ @devices = {}
+
+ read(true) # force reading at start
+ end
+
+ # Read the configuration file.
+ def read(force = false)
+ return unless FileTest.exists?(@file)
+
+ parse if force or changed?
+ end
+
+ private
+
+ def parse
+ begin
+ devices = {}
+ device = nil
+ File.open(@file) { |f|
+ count = 1
+ f.each { |line|
+ case line
+ when /^\s*#/ # skip comments
+ count += 1
+ next
+ when /^\s*$/ # skip blank lines
+ count += 1
+ next
+ when /^\[([\w.]+)\]\s*$/ # [device.fqdn]
+ name = $1
+ name.chomp!
+ raise ConfigurationError, "Duplicate device found at line #{count}, already found at #{device.line}" if devices.include?(name)
+ device = OpenStruct.new
+ device.name = name
+ device.line = count
+ Puppet.debug "found device: #{device.name} at #{device.line}"
+ devices[name] = device
+ when /^\s*(type|url)\s+(.+)$/
+ parse_directive(device, $1, $2, count)
+ else
+ raise ConfigurationError, "Invalid line #{count}: #{line}"
+ end
+ count += 1
+ }
+ }
+ rescue Errno::EACCES => detail
+ Puppet.err "Configuration error: Cannot read #{@file}; cannot serve"
+ #raise Puppet::Error, "Cannot read #{@config}"
+ rescue Errno::ENOENT => detail
+ Puppet.err "Configuration error: '#{@file}' does not exit; cannot serve"
+ end
+
+ @devices = devices
+ end
+
+ def parse_directive(device, var, value, count)
+ case var
+ when "type"
+ device.provider = value
+ when "url"
+ device.url = value
+ else
+ raise ConfigurationError,
+ "Invalid argument '#{var}' at line #{count}"
+ end
+ end
+
+end \ No newline at end of file
diff --git a/lib/puppet/util/network_device/transport.rb b/lib/puppet/util/network_device/transport.rb
index e64fe9b69..cef8f3859 100644
--- a/lib/puppet/util/network_device/transport.rb
+++ b/lib/puppet/util/network_device/transport.rb
@@ -1,5 +1,3 @@
# stub
-module Puppet::Util::NetworkDevice
- module Transport
- end
+module Puppet::Util::NetworkDevice::Transport
end \ No newline at end of file
diff --git a/lib/puppet/util/network_device/transport/ssh.rb b/lib/puppet/util/network_device/transport/ssh.rb
index b3cf51b8a..bf0e7193c 100644
--- a/lib/puppet/util/network_device/transport/ssh.rb
+++ b/lib/puppet/util/network_device/transport/ssh.rb
@@ -31,6 +31,10 @@ class Puppet::Util::NetworkDevice::Transport::Ssh < Puppet::Util::NetworkDevice:
@ssh = Net::SSH.start(host, user, :port => port, :password => password, :timeout => timeout)
rescue TimeoutError
raise TimeoutError, "timed out while opening an ssh connection to the host"
+ rescue Net::SSH::AuthenticationFailed
+ raise Puppet::Error, "SSH authentication failure connecting to #{host} as #{user}"
+ rescue Net::SSH::Exception => detail
+ raise Puppet::Error, "SSH connection failure to #{host}"
end
@buf = ""