diff options
| author | Pieter van de Bruggen <pieter@puppetlabs.com> | 2011-04-18 13:40:31 -0700 |
|---|---|---|
| committer | Pieter van de Bruggen <pieter@puppetlabs.com> | 2011-04-18 14:08:32 -0700 |
| commit | 07b677c5f6af8def03c5c30393fd83bc3986239a (patch) | |
| tree | b28d3376b4ea835a2348ebfea898d674cb593e34 /lib/puppet/util/network_device | |
| parent | b142973a94ced6c0ff43da882189abe806c18c68 (diff) | |
| download | puppet-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.rb | 32 | ||||
| -rw-r--r-- | lib/puppet/util/network_device/cisco/device.rb | 10 | ||||
| -rw-r--r-- | lib/puppet/util/network_device/cisco/facts.rb | 72 | ||||
| -rw-r--r-- | lib/puppet/util/network_device/config.rb | 93 | ||||
| -rw-r--r-- | lib/puppet/util/network_device/transport.rb | 4 | ||||
| -rw-r--r-- | lib/puppet/util/network_device/transport/ssh.rb | 4 |
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 = "" |
