cisco-config-parse 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README.md +29 -0
  2. data/lib/cisco-config-parse.rb +135 -0
  3. metadata +65 -0
@@ -0,0 +1,29 @@
1
+ # cisco-config-parse
2
+
3
+ ## What?
4
+
5
+ cisco-config-parse is a gem that given a Cisco configuration file, parses it to provide an easy breakdown of information for manipulation. For example, you can get the list of interfaces as a hash with relevant details, such as the description on the port, the VLAN configuration, etc.
6
+
7
+ ## How to use
8
+
9
+ require 'cisco-config-parse'
10
+ parser = CiscoConfigParse.new(IO.readlines("/path/to/file"))
11
+ # Parse the file
12
+ parser.parse
13
+ # Get a hash of the interfaces
14
+ puts parser.get_interfaces
15
+
16
+ {"FastEthernet0"=>{}, "GigabitEthernet0/1"=>{:description=>"host0119.ilo", :access_vlan=>"21", :bpduguard=>"enable"}, "GigabitEthernet0/2"=>{:description=>"host0120.ilo", :access_vlan=>"21", :bpduguard=>"enable"}, "GigabitEthernet0/3"=>{:description=>"host0123.ilo", :access_vlan=>"21", :bpduguard=>"enable"}, "GigabitEthernet0/4"=>{:description=>"host0124.ilo", :access_vlan=>"21", :bpduguard=>"enable"}, "GigabitEthernet0/5"=>{:description=>"host0127.ilo", :access_vlan=>"21", :bpduguard=>"enable"}, "GigabitEthernet0/6"=>{:description=>"host0128.ilo", :access_vlan=>"21", :bpduguard=>"enable"}, ...[snip]
17
+
18
+ ## Methods
19
+
20
+ * *parse* - Parses the configuration, required for any other operation
21
+ * *get\_interfaces* - Returns a hash of all interfaces in config along with their details
22
+ * *get\_hostname* - Returns the hostname of the switch
23
+ * *get\_version* - Returns the version of the software running on the switch
24
+
25
+ ## Bugs? Improvements?
26
+ Probably; this does the bare minimum right now (in my case, I wanted to compare the VLANs on all interfaces on two switches. Please do let me know if anything is broken, and as always please do submit pull requests with any improvements.
27
+
28
+ ### Thanks
29
+ * Half of this code was written by Geoff Garside (https://github.com/geoffgarside), so thanks for letting me take, finish and publish!
@@ -0,0 +1,135 @@
1
+ #!/bin/env ruby
2
+
3
+ class CiscoConfigParse
4
+ def initialize(io)
5
+ @io = io
6
+ end
7
+
8
+ def parse
9
+ @io.each do |line|
10
+ if line =~ /^\!$/ or line =~ /^$/ # terminate current block
11
+ end_config
12
+ next
13
+ elsif line =~ /^\!/ # Comment
14
+ next
15
+ end
16
+ parse_config(line)
17
+ end
18
+ end
19
+
20
+ def get_interfaces
21
+ return @interfaces
22
+ end
23
+
24
+ def get_vlans
25
+ return @vlans
26
+ end
27
+
28
+ def get_hostname
29
+ return @config_hostname
30
+ end
31
+
32
+ def get_version
33
+ return @software_version
34
+ end
35
+
36
+ private
37
+ def state
38
+ @state ||= []
39
+ end
40
+ def end_config
41
+ meth = ['e_config', state].flatten.join('_')
42
+ send(meth) if respond_to?(meth)
43
+ state.pop
44
+ end
45
+ def parse_config(line)
46
+ cmd, opts = line.strip.split(' ', 2)
47
+ meth, opts = meth_and_opts(cmd, opts)
48
+ send(meth, opts) if respond_to?(meth)
49
+ end
50
+ def meth_and_opts(cmd, opts)
51
+ return negated_meth_and_opts(opts) if cmd =~ /no/
52
+ [['p_config', state, cmd.gsub('-', '_')].flatten.join('_'), opts]
53
+ end
54
+ def negated_meth_and_opts(line)
55
+ cmd, opts = line.split(' ', 2)
56
+ [['n_config', state, cmd.gsub('-', '_')].flatten.join('_'), opts]
57
+ end
58
+
59
+ protected
60
+ def p_config_hostname(str)
61
+ @config_hostname = str
62
+ end
63
+
64
+ def p_config_version(str)
65
+ @software_version = str
66
+ end
67
+
68
+ def p_config_vlan(ids)
69
+ @current_vlan = {:ids => ids}
70
+ end
71
+
72
+ def e_config_vlan
73
+ @vlans ||= {}
74
+ @vlans[@current_vlan.delete(:ids)] = @current_vlan
75
+ end
76
+
77
+ def p_config_interface(name)
78
+ state.push(:interface)
79
+ @current_interface = {:id => name}
80
+ end
81
+
82
+ def e_config_interface
83
+ @interfaces ||= {}
84
+ @interfaces[@current_interface.delete(:id)] = @current_interface
85
+ end
86
+
87
+ def p_config_interface_description(str)
88
+ @current_interface[:description] = str
89
+ end
90
+
91
+ def p_config_interface_switchport(str)
92
+ # Parse the switchport string
93
+ command = str.split(' ', 3)
94
+ case command[0]
95
+ when "trunk"
96
+ # Its a trunk command; continue to figure out what kind
97
+ if command[1] == "allowed"
98
+ # allow vlan
99
+ allowed_type = str.split(' ', 5)
100
+ # Split up the rest of the string for the list of vlans
101
+ vlan_list = str.gsub(',',' ').split(' ')
102
+ if allowed_type[3] == "add" then
103
+ @current_interface[:added_allowed_vlans] = vlan_list.slice(4, vlan_list.length)
104
+ else
105
+ @current_interface[:allowed_vlans] = vlan_list.slice(3, vlan_list.length)
106
+ end
107
+ end
108
+ when "access"
109
+ @current_interface[:access_vlan] = command[2]
110
+ end
111
+ end
112
+
113
+ def p_config_interface_inherit(str)
114
+ @current_interface[:inherit] = str
115
+ end
116
+
117
+ def p_config_interface_spanning_tree(str)
118
+ # Parse the spanning tree config options
119
+ command = str.split(' ')
120
+ case command[0]
121
+ when "port"
122
+ @current_interface[:spanning_tree_port_type] = command[2]
123
+ when "guard"
124
+ @current_interface[:spanning_tree_guard] = command[1]
125
+ when "bpduguard"
126
+ @current_interface[:bpduguard] = command[1]
127
+ end
128
+ end
129
+
130
+ def p_config_interface_channel_group(str)
131
+ # Is the port in a port channel?
132
+ @current_interface[:channel_group] = str.split(' ')[0]
133
+
134
+ end
135
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cisco-config-parse
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 5
9
+ version: 0.0.5
10
+ platform: ruby
11
+ authors:
12
+ - Laurie Denness
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2013-01-28 00:00:00 +00:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: "Parses a cisco config file on disk (probably from a tool such as Rancid) and returns simple hashes of parsed data, for example interfaces, VLANs, software version, hostname. "
22
+ email: laurie@denness.net
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README.md
29
+ files:
30
+ - README.md
31
+ - lib/cisco-config-parse.rb
32
+ has_rdoc: true
33
+ homepage: https://github.com/lozzd/cisco-config-parse
34
+ licenses: []
35
+
36
+ post_install_message:
37
+ rdoc_options:
38
+ - --charset=UTF-8
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ requirements: []
58
+
59
+ rubyforge_project: cisco-config-parse
60
+ rubygems_version: 1.3.7
61
+ signing_key:
62
+ specification_version: 2
63
+ summary: Parses a Cisco config file on disk for easy manipulation of interfaces, VLANs etc.
64
+ test_files: []
65
+