Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

- Add all files.

  • Loading branch information...
commit 05998e72f9412bbae988824c96f5cb24d93e2aa3 0 parents
Stanislav Sedov authored August 19, 2011
118  CiscoConfig.rb
... ...
@@ -0,0 +1,118 @@
  1
+#
  2
+# A Ruby library to fetch Cisco IOS configuration via SNMP
  3
+#
  4
+# Copyright (C) 2007-2008 Stanislav Sedov <stas@FreeBSD.org>
  5
+#
  6
+# This file is in public domain
  7
+#
  8
+
  9
+#
  10
+# See http://www.cisco.com/en/US/tech/tk648/tk362/technologies_tech_note09186a0080094aa6.shtml
  11
+# for additional info.
  12
+#
  13
+
  14
+require 'snmp'
  15
+
  16
+class CiscoConfig
  17
+
  18
+  #
  19
+  # OIDs from CISCO-CONFIG-COPY-MIB-V1SMI
  20
+  #
  21
+  OIDPrefix = '1.3.6.1.4.1.9.9.96.1.1.1.1'	# common prefix
  22
+
  23
+  OIDMap = {		# name -> oid mappings
  24
+    :CopyProtocol => 2,
  25
+    :CopySourceFileType => 3,
  26
+    :CopyDestFileType => 4,
  27
+    :CopyServerAddress => 5,
  28
+    :CopyFileName => 6,
  29
+    :CopyState => 10,
  30
+    :CopyFailCause => 13,
  31
+    :CopyEntryRowStatus => 14
  32
+  }
  33
+
  34
+  #
  35
+  # Error codes
  36
+  #
  37
+  REQSTATUS = {
  38
+    1 => "unknown error",
  39
+    2 => "access denied",
  40
+    3 => "TFTP operation timed out",
  41
+    4 => "out of memory",
  42
+    5 => "no configuration",
  43
+  }
  44
+		
  45
+  #
  46
+  # Default configuration
  47
+  #
  48
+  Defconfig = {
  49
+	:host => 'localhost',
  50
+	:port => 161,
  51
+	:comm => 'public',
  52
+  }
  53
+
  54
+  def initialize(newconf = {})
  55
+    @config = Defconfig.merge(newconf)
  56
+
  57
+    @manager = SNMP::Manager.new(:Host => @config[:host], :Port => @config[:port], \
  58
+			   :Community => @config[:comm])
  59
+
  60
+    self
  61
+  end
  62
+
  63
+  def copy_from_cisco(host, file)
  64
+    id = cisco_rand	# this will became the new id
  65
+    status = 0
  66
+
  67
+    req = Array.new()
  68
+    req[0] = SNMP::VarBind.new get_oid(:CopyProtocol, id), SNMP::Integer.new(1)
  69
+    req[1] = SNMP::VarBind.new get_oid(:CopySourceFileType, id), SNMP::Integer.new(4)
  70
+    req[2] = SNMP::VarBind.new get_oid(:CopyDestFileType, id), SNMP::Integer.new(1)
  71
+    req[3] = SNMP::VarBind.new get_oid(:CopyServerAddress, id), SNMP::IpAddress.new(host)
  72
+    req[4] = SNMP::VarBind.new get_oid(:CopyFileName, id), SNMP::OctetString.new(file)
  73
+    req[5] = SNMP::VarBind.new get_oid(:CopyEntryRowStatus, id), SNMP::Integer.new(4)
  74
+
  75
+    @manager.set(req)
  76
+
  77
+    id
  78
+  end
  79
+
  80
+  def get_status(id, timeout = 10)
  81
+    status = 0
  82
+    time = 0
  83
+    while (time < 10) do
  84
+      status = @manager.get_value(get_oid(:CopyState, id)).to_i
  85
+      break if status > 2
  86
+      sleep(1)
  87
+    end
  88
+
  89
+    return "timed out" if time == 10
  90
+
  91
+    if (status == 3) then
  92
+      return "OK"
  93
+    end
  94
+
  95
+    err = @manager.get_value(get_oid(:CopyFailCause, id)).to_i
  96
+
  97
+    REQSTATUS[err]
  98
+  end
  99
+
  100
+  #
  101
+  # Return random number suitable to use in Cisco OIDs.
  102
+  # It looks like that only 24 bits are allowed
  103
+  #
  104
+  def cisco_rand
  105
+    rand(1 << 24)
  106
+  end
  107
+
  108
+  private :cisco_rand
  109
+
  110
+  #
  111
+  # Returns full IOS OID according to name provided
  112
+  #
  113
+  def get_oid(name, id)
  114
+    OIDPrefix + '.' + OIDMap[name].to_s + ".#{id}"
  115
+  end
  116
+
  117
+  private :get_oid
  118
+end
54  README.markdown
Source Rendered
... ...
@@ -0,0 +1,54 @@
  1
+Cisco_config.rb
  2
+===============
  3
+
  4
+What is it?
  5
+-----------
  6
+
  7
+This library allows one to access Cisco routers and switches configuration via
  8
+SNMP.  Using SNMP access it triggers a command on the device that will upload
  9
+the configuration file to the TFTP server specified.
  10
+
  11
+
  12
+How?
  13
+----
  14
+
  15
+```ruby
  16
+require 'CiscoConfig'
  17
+
  18
+cisco = CiscoConfig.new(:host => 'router0.example.org', :comm => 'secretcommunity')
  19
+rnd = cisco.copy_from_cisco('tftpserver.example.com', 'config/cisco0.conf')
  20
+```
  21
+
  22
+This snipplet will tell the device accessible via 'router0.example.com' to upload it's
  23
+configuration to the TFTP sever at 'tftpserver.example.com'.  The second argument of
  24
+the `copy_from_cisco` method is the actual filename to save the configuration to.
  25
+You should also specifiy the SNMP community configured on your device via the `:comm`
  26
+keyword argument of the constructor.
  27
+
  28
+
  29
+Interface
  30
+---------
  31
+
  32
+The `CiscoConfig` class provides the following methods:
  33
+
  34
+* `new(config = {})`.  The constructor accepts the Hash table containing the device access
  35
+   configuration.  Specifically, the following options are supported right now:
  36
+   * :host -- the hostname of the device
  37
+   * :port -- the device SNMP port
  38
+   * :comm -- SNMP community name.
  39
+
  40
+* `copy_from_cisco(tftp_host, tftp_file)`.  This method triggers the device upload command.
  41
+  The configuration file will be uploaded to the host identified by `tftp_host` under
  42
+  the `tftp_file` filename.  The destination directory of `tftp_file` should already exist.
  43
+  The method will return numerical ID of the command, which can be used to check for the
  44
+  status later.
  45
+
  46
+* `get_status(id, timeout = 10)`.  This method returns the status of the previous command
  47
+  identified by 'id'.  It will wait up to `timeout` seconds for the operation to complete if
  48
+  it is in progress.
  49
+
  50
+
  51
+Comments
  52
+--------
  53
+
  54
+Send your comments and/or suggestions to <stas@FreeBSD.org>.
25  examples/copy_config.rb
... ...
@@ -0,0 +1,25 @@
  1
+#!/usr/bin/env ruby18
  2
+#
  3
+# This example shows how to use the CiscoConfig library to download the configuration file
  4
+# from the Cisco router/swiftch and check it into the repository if it has changed.  This
  5
+# script can be run from the cron to keep track of configuration changes.
  6
+#
  7
+require 'rubygems'
  8
+require 'CiscoConfig'
  9
+
  10
+begin
  11
+  cisco = CiscoConfig.new(:host => 'router0.example.org', :comm => 'secretcommunity')
  12
+  rnd = cisco.copy_from_cisco('tftpserver.example.com', 'config/cisco0.conf')
  13
+
  14
+  status = cisco.get_status(rnd)
  15
+  if (status != "OK") then
  16
+	puts "Error retrieving config: #{status}"
  17
+  end
  18
+
  19
+  system('sed -i ""  -e "/ntp clock-period/d" /mnt/tftpserver/tftproot/config/cisco0.conf')
  20
+
  21
+  lines = `(cd /mnt/tftpserver/tftproot/config && /usr/local/bin/hg diff) 2>/dev/null | wc -l`.to_i
  22
+  exit if (lines == 0)
  23
+
  24
+  system("cd /mnt/tftpserver/tftproot/config && /usr/local/bin/hg ci -m 'cisco0 config autocommit' 2>/dev/null")
  25
+end

0 notes on commit 05998e7

Please sign in to comment.
Something went wrong with that request. Please try again.