diff options
36 files changed, 699 insertions, 92 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 09ae2da..34b192c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +# 0.20.0 +- FEATURE: gpg support for CSV source (@elmobp) +- FEATURE: slackdiff (@natm) +- FEATURE: gitcrypt output model (@clement-parisot) +- FEATURE: model specific credentials (@davromaniak) +- FEATURE: hierarchical json in http source model +- FEATURE: next-adds-job config toggle (to add new job when ever /next is called) +- FEATURE: netgear model (@aschaber1) +- FEATURE: zhone model (@rfdrake) +- FEATURE: tplink model (@mediumo) +- FEATURE: oneos model (@crami) +- FEATURE: cisco NGA model (@udhos) +- FEATURE: voltaire model (@clement-parisot) +- FEATURE: siklu model (@bdg-robert) +- FEATURE: voss model (@ospfbgp) +- BUGFIX: ios, cumulus, ironware, nxos, fiberdiver, aosw, fortios, comware, procurve, opengear, timos, routeros, junos, asa, aireos, mlnxos, pfsense, saos, powerconnect, firewareos, quantaos + # 0.19.0 - FEATURE: allow setting ssh_keys (not relying on openssh config) (@denvera) - FEATURE: fujitsupy model (@stokbaek) diff --git a/Gemfile.lock b/Gemfile.lock index 2c887c1..229a55c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,10 @@ PATH remote: . specs: - oxidized (0.18.0) + oxidized (0.20.0) asetus (~> 0.1) net-ssh (~> 3.0.2) - net-telnet + net-telnet (~> 0) rugged (~> 0.21, >= 0.21.4) slop (~> 3.5) @@ -12,20 +12,20 @@ GEM remote: https://rubygems.org/ specs: asetus (0.3.0) - coderay (1.1.0) + coderay (1.1.1) + git (1.3.0) metaclass (0.0.4) method_source (0.8.2) - minitest (5.9.0) - mocha (1.1.0) + minitest (5.10.1) + mocha (1.2.1) metaclass (~> 0.0.1) net-ssh (3.0.2) net-telnet (0.1.1) - pry (0.10.3) + pry (0.11.0.pre2) coderay (~> 1.1.0) method_source (~> 0.8.1) - slop (~> 3.4) rake (10.5.0) - rugged (0.23.3) + rugged (0.25.1.1) slop (3.6.0) PLATFORMS @@ -41,4 +41,4 @@ DEPENDENCIES rake (~> 10.0) BUNDLED WITH - 1.11.2 + 1.14.6 @@ -1,5 +1,9 @@ # Oxidized [![Build Status](https://travis-ci.org/Shopify/oxidized.svg)](https://travis-ci.org/Shopify/oxidized) [![Gem Version](https://badge.fury.io/rb/oxidized.svg)](http://badge.fury.io/rb/oxidized) [![Join the chat at https://gitter.im/oxidized/Lobby](https://badges.gitter.im/oxidized/Lobby.svg)](https://gitter.im/oxidized/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +** Is your company using Oxidized and has Ruby developers on staff? I'd love help from an extra maintainer!** + +[WANTED: MAINTAINER](#help-needed) + Oxidized is a network device configuration backup tool. It's a RANCID replacement! * automatically adds/removes threads to meet configured retrieval interval @@ -66,6 +70,11 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen * [C4CMTS](lib/oxidized/model/c4cmts.rb) * Aruba * [AOSW](lib/oxidized/model/aosw.rb) + * AudioCodes + * [AudioCodes](lib/oxdized/model/audiocodes.rb) + * Avaya + * [VOSS (VSP Operating System Software)](lib/oxidized/model/voss.rb) + * [BOSS (Baystack Operating System Software)](lib/oxidized/model/boss.rb) * Brocade * [FabricOS](lib/oxidized/model/fabricos.rb) * [Ironware](lib/oxidized/model/ironware.rb) @@ -81,12 +90,15 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen * Cisco * [AireOS](lib/oxidized/model/aireos.rb) * [ASA](lib/oxidized/model/asa.rb) + * [AsyncOS](lib/oxidized/model/asyncos.rb) * [CatOS](lib/oxidized/model/catos.rb) * [IOS](lib/oxidized/model/ios.rb) * [IOSXR](lib/oxidized/model/iosxr.rb) * [NGA](lib/oxidized/model/cisconga.rb) * [NXOS](lib/oxidized/model/nxos.rb) + * [SMA](lib/oxidized/model/ciscosma.rb) * [SMB (Nikola series)](lib/oxidized/model/ciscosmb.rb) + * [UCS](lib/oxidized/model/ucs.rb) * Citrix * [NetScaler (Virtual Applicance)](lib/oxidized/model/netscaler.rb) * Coriant (former Tellabs) @@ -96,6 +108,8 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen * [Linux](lib/oxidized/model/cumulus.rb) * DataCom * [DmSwitch 3000](lib/oxidized/model/datacom.rb) + * DCN + * [DCN](lib/oxidized/model/ios.rb) - Map this to ios. * DELL * [PowerConnect](lib/oxidized/model/powerconnect.rb) * [AOSW](lib/oxidized/model/aosw.rb) @@ -104,8 +118,9 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen * Ericsson/Redback * [IPOS (former SEOS)](lib/oxidized/model/ipos.rb) * Extreme Networks - * [XOS](lib/oxidized/model/xos.rb) + * [Enterasys](/lib/oxidized/model/enterasys.rb) * [WM](lib/oxidized/model/mtrlrfs.rb) + * [XOS](lib/oxidized/model/xos.rb) * F5 * [TMOS](lib/oxidized/model/tmos.rb) * Force10 @@ -117,6 +132,8 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen * [PRIMERGY Blade switch 1/10Gbe](lib/oxidized/model/fujitsupy.rb) * Hatteras * [Hatteras](lib/oxidized/model/hatteras.rb) + * Hirschmann + * [HiOS](lib/oxidized/model/hirschmann.rb) * HP * [Comware (HP A-series, H3C, 3Com)](lib/oxidized/model/comware.rb) * [Procurve](lib/oxidized/model/procurve.rb) @@ -137,6 +154,8 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen * MRV * [MasterOS](lib/oxidized/model/masteros.rb) * [FiberDriver](lib/oxidized/model/fiberdriver.rb) + * Netgear + * [Netgear](lib/oxidized/model/netgear.rb) * Netonix * [WISP Switch (As Netonix)](lib/oxidized/model/netonix.rb) * Nokia (formerly TiMetra, Alcatel, Alcatel-Lucent) @@ -165,6 +184,8 @@ Oxidized is a network device configuration backup tool. It's a RANCID replacemen * [EdgeSwitch](lib/oxidized/model/edgeswitch.rb) * Watchguard * [Fireware OS](lib/oxidized/model/firewareos.rb) + * Westell + * [Westell 8178G, Westell 8266G](lib/oxidized/model/weos.rb) * Zhone * [Zhone (OLT and MX)](lib/oxidized/model/zhoneolt.rb) * Zyxel @@ -838,6 +859,22 @@ map: name: 1 group: 2 ``` +For model specific credentials + +``` +models: + junos: + username: admin + password: password + ironware: + username: admin + password: password + vars: + enable: enablepassword + apc_aos: + username: apc + password: password +``` ### Triggered backups @@ -872,6 +909,7 @@ Command is executed with the following environment: ``` OX_EVENT OX_NODE_NAME +OX_NODE_IP OX_NODE_FROM OX_NODE_MSG OX_NODE_GROUP @@ -989,6 +1027,9 @@ hooks: channel: "#network-changes" ``` +Note the channel name must be in quotes. + + # Extra ## Ubuntu SystemV init setup @@ -1014,11 +1055,9 @@ chown oxidized:oxidized /var/run/oxidized 3.)Make oxidized start on boot ``` -update-rc.d oxidized deafults +update-rc.d oxidized defaults ``` -Note the channel name must be in quotes. - # Ruby API The following objects exist in Oxidized. @@ -1052,6 +1091,39 @@ The following objects exist in Oxidized. * 'junos', 'ios', 'ironware' and 'powerconnect' implemented +# Help Needed + +As things stand right now, `oxidized` is maintained by a single person. A great +many [contributors](https://github.com/ytti/oxidized/graphs/contributors) have +helped further the software, however contributions are not the same as ongoing +owner- and maintainership. It appears that many companies use the software to +manage their network infrastructure, this is great news! But without additional +help to maintain the software and put out releases, the future of oxidized +might be less bright. The current pace of development and the much needed +refactoring simply are not sustainable if they are to be driven by a single +person. + +## Maintainer duties and expectations + +* 4 hours per week to perform triage on issues, review pull requests and help answer any questions from users. +* Above average knowledge of the Ruby programming language. +* Professional experience with both oxidized and some other config backup tool (like rancid). +* Ability to keep a cool head, and enjoy interaction with end users! :) +* A desire and passion to help drive `oxidized` towards its `1.x.x` stage of life + * help refactor the code + * rework the core infrastructure +* Permission from your employer to contribute to open source projects + +## YES, I WANT TO HELP + +Awesome! Simply send an email to Saku Ytti <saku@ytti.fi>. + +## Further reading + +Brian Anderson (from Rust fame) wrote an [excellent +post](http://brson.github.io/2017/04/05/minimally-nice-maintainer) on what it +means to be a maintainer. + # License and Copyright Copyright 2013-2015 Saku Ytti <saku@ytti.fi> diff --git a/docs/VRP-Huawei.md b/docs/VRP-Huawei.md new file mode 100644 index 0000000..9e97b7d --- /dev/null +++ b/docs/VRP-Huawei.md @@ -0,0 +1,27 @@ +Huawei VRP Configuration +======================== + +Create a user with no privileges + + <HUAWEI> system-view + [~HUAWEI] aaa + [~HUAWEI-aaa] local-user oxidized password irreversible-cipher verysecret + [*HUAWEI-aaa] local-user oxidized level 1 + [*HUAWEI-aaa] local-user oxidized service-type terminal ssh + [*HUAWEI-aaa] commit + +The commands Oxidized executes are: + +1. screen-length 0 temporary +2. display version +3. display device +4. display current-configuration all + +Command 2 and 3 can be executed without issues, but 1 and 4 are only available for higher level users. Instead of making Oxidized a read/write user on your device, lower the priviledge-level for commands 1 and 4: + + <HUAWEI> system-view + [~HUAWEI] command-privilege level 1 view global display current-configuration all + [*HUAWEI] command-privilege level 1 view shell screen-length + [*HUAWEI] commit + +Oxidized can now retrieve your configuration!
\ No newline at end of file diff --git a/extra/oxidized-report-git-commits b/extra/oxidized-report-git-commits index 2fd4870..db36ecf 100755 --- a/extra/oxidized-report-git-commits +++ b/extra/oxidized-report-git-commits @@ -17,64 +17,45 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# 20170615 - Andre Sencioles <asenci@gmail.com> +# Removed requirement for Git working directory +# Check job status +# +# # usage: add the following hook to the oxidized config file: # # hooks: # email_output: # type: exec # events: [post_store, node_fail] -# cmd: '/home/oxidized/extra/oxidized-report-git-commits ~/gitdir/ | mail -s "Oxidized updates for ${OX_NODE_NAME}" update-recipient@example.com' +# cmd: '/home/oxidized/extra/oxidized-report-git-commits | mail -s "Oxidized updates for ${OX_NODE_NAME}" update-recipient@example.com' # async: true # timeout: 120 # # -# The script takes a single argument, namely a git working directory name, -# e.g. "~/gitdir/". This is only used as a staging directory and should -# not be set to be the same as the git repo directory. -# -PATH=${PATH}:/usr/local/bin:/usr/local/sbin -export PATH +echo "Node name: ${OX_NODE_NAME}" +echo "Group name: ${OX_NODE_GROUP}" +echo "Job status: ${OX_JOB_STATUS}" +echo "Job time: ${OX_JOB_TIME}" -gitdir=$1 +if [ "${OX_EVENT}" = "node_fail" ]; then + echo 'Job failed' + exit 64 +fi -if [ X${OX_REPO_COMMITREF} = "X" ]; then - echo \$OX_REPO_COMMITREF not set +if [ -z "${OX_REPO_COMMITREF}" ]; then + echo '$OX_REPO_COMMITREF not set' exit 64 fi -if [ X${OX_REPO_NAME} = "X" ]; then - echo \$OX_REPO_NAME not set +if [ -z "${OX_REPO_NAME}" ]; then + echo '$OX_REPO_NAME not set' exit 64 fi -if [ ! -d ${gitdir}/.git ]; then - git clone -q ${OX_REPO_NAME} ${gitdir} - - ret=$? - if [ X"${ret}" != X0 ] && [ X"${ret}" != X1 ]; then - echo git clone failed: aborting. - exit 128 - fi -fi - -cd ${gitdir} - -git pull -q > /dev/null 2>&1 -ret=$? -if [ X"${ret}" != X0 ] && [ X"${ret}" != X1 ]; then - echo git pull failed: aborting. - exit 128 -fi - -# Git is probably working at this stage, so safe to emit more info - -echo "Node name: ${OX_NODE_NAME}" -echo "Group Name: ${OX_NODE_GROUP}" -echo "Job Time: ${OX_JOB_TIME}" -echo "Git Commit ID: ${OX_REPO_COMMITREF}" -echo "Git Repo: ${OX_REPO_NAME}" -echo "Local working dir: ${gitdir}" +echo "Git repo: ${OX_REPO_NAME}" +echo "Git commit ID: ${OX_REPO_COMMITREF}" echo "" -git diff --no-color ${OX_REPO_COMMITREF}~1..${OX_REPO_COMMITREF} +git --bare --git-dir="${OX_REPO_NAME}" diff --no-color "${OX_REPO_COMMITREF}~1..${OX_REPO_COMMITREF}" diff --git a/extra/oxidized.service b/extra/oxidized.service index ba60bd5..e474608 100644 --- a/extra/oxidized.service +++ b/extra/oxidized.service @@ -1,12 +1,16 @@ #For debian 8 put it in /lib/systemd/system/ +#For RHEL / CentOS 7 put it in /etc/systemd/system/ #and call it with systemctl start oxidized.service [Unit] Description=Oxidized - Network Device Configuration Backup Tool +After=network-online.target multi-user.target +Wants=network-online.target [Service] ExecStart=/usr/local/bin/oxidized User=oxidized +KillSignal=SIGINT [Install] WantedBy=multi-user.target diff --git a/lib/oxidized/config.rb b/lib/oxidized/config.rb index aba8b63..23af9c2 100644 --- a/lib/oxidized/config.rb +++ b/lib/oxidized/config.rb @@ -31,6 +31,7 @@ module Oxidized asetus.default.next_adds_job = false # if true, /next adds job, so device is fetched immmeiately asetus.default.vars = {} # could be 'enable'=>'enablePW' asetus.default.groups = {} # group level configuration + asetus.default.models = {} # model level configuration asetus.default.pid = File.join(Oxidized::Config::Root, 'pid') asetus.default.input.default = 'ssh, telnet' diff --git a/lib/oxidized/config/vars.rb b/lib/oxidized/config/vars.rb index 09f9781..d926ee2 100644 --- a/lib/oxidized/config/vars.rb +++ b/lib/oxidized/config/vars.rb @@ -8,8 +8,12 @@ module Oxidized::Config::Vars r ||= Oxidized.config.groups[@node.group].vars[name.to_s] end end + if Oxidized.config.models.has_key?(@node.model.class.name.to_s.downcase) + if Oxidized.config.models[@node.model.class.name.to_s.downcase].vars.has_key?(name.to_s) + r ||= Oxidized.config.models[@node.model.class.name.to_s.downcase].vars[name.to_s] + end + end r ||= Oxidized.config.vars[name.to_s] if Oxidized.config.vars.has_key?(name.to_s) r end end - diff --git a/lib/oxidized/hook/exec.rb b/lib/oxidized/hook/exec.rb index 58d6fd5..fa8aff1 100644 --- a/lib/oxidized/hook/exec.rb +++ b/lib/oxidized/hook/exec.rb @@ -67,6 +67,7 @@ class Exec < Oxidized::Hook if ctx.node env.merge!( "OX_NODE_NAME" => ctx.node.name.to_s, + "OX_NODE_IP" => ctx.node.ip.to_s, "OX_NODE_FROM" => ctx.node.from.to_s, "OX_NODE_MSG" => ctx.node.msg.to_s, "OX_NODE_GROUP" => ctx.node.group.to_s, diff --git a/lib/oxidized/input/ssh.rb b/lib/oxidized/input/ssh.rb index 858d5cd..27e81e0 100644 --- a/lib/oxidized/input/ssh.rb +++ b/lib/oxidized/input/ssh.rb @@ -24,20 +24,23 @@ module Oxidized secure = Oxidized.config.input.ssh.secure @log = File.open(Oxidized::Config::Log + "/#{@node.ip}-ssh", 'w') if Oxidized.config.input.debug? port = vars(:ssh_port) || 22 + + ssh_opts = { + :port => port.to_i, + :password => @node.auth[:password], :timeout => Oxidized.config.timeout, + :paranoid => secure, + :auth_methods => %w(none publickey password keyboard-interactive), + :number_of_password_prompts => 0, + } + if proxy_host = vars(:ssh_proxy) proxy_command = "ssh " proxy_command += "-o StrictHostKeyChecking=no " unless secure proxy_command += "#{proxy_host} -W %h:%p" proxy = Net::SSH::Proxy::Command.new(proxy_command) + ssh_opts[:proxy] = proxy end - ssh_opts = { - :port => port.to_i, - :password => @node.auth[:password], :timeout => Oxidized.config.timeout, - :paranoid => secure, - :auth_methods => %w(none publickey password keyboard-interactive), - :number_of_password_prompts => 0, - :proxy => proxy, - } + ssh_opts[:keys] = vars(:ssh_keys).is_a?(Array) ? vars(:ssh_keys) : [vars(:ssh_keys)] if vars(:ssh_keys) ssh_opts[:kex] = vars(:ssh_kex).split(/,\s*/) if vars(:ssh_kex) ssh_opts[:encryption] = vars(:ssh_encryption).split(/,\s*/) if vars(:ssh_encryption) diff --git a/lib/oxidized/model/asa.rb b/lib/oxidized/model/asa.rb index 038dd6b..9df4206 100644 --- a/lib/oxidized/model/asa.rb +++ b/lib/oxidized/model/asa.rb @@ -20,6 +20,11 @@ class ASA < Oxidized::Model cfg end + # check for multiple contexts + cmd 'show mode' do |cfg| + @is_multiple_context = cfg.include? 'multiple' + end + cmd 'show version' do |cfg| # avoid commits due to uptime / ixo-router01 up 2 mins 28 secs / ixo-router01 up 1 days 2 hours cfg = cfg.each_line.select { |line| not line.match /(\s+up\s+\d+\s+)|(.*days.*)/ } @@ -31,25 +36,12 @@ class ASA < Oxidized::Model comment cfg end - cmd 'more system:running-config' do |cfg| - cfg = cfg.each_line.to_a[3..-1].join - cfg.gsub! /^: [^\n]*\n/, '' - # backup any xml referenced in the configuration. - anyconnect_profiles = cfg.scan(Regexp.new('(\sdisk0:/.+\.xml)')).flatten - anyconnect_profiles.each do |profile| - cfg << (comment profile + "\n" ) - cmd ("more" + profile) do |xml| - cfg << (comment xml) - end + post do + if @is_multiple_context + multiple_context + else + single_context end - # if DAP is enabled, also backup dap.xml - if cfg.rindex(/dynamic-access-policy-record\s(?!DfltAccessPolicy)/) - cfg << (comment "disk0:/dap.xml\n") - cmd "more disk0:/dap.xml" do |xml| - cfg << (comment xml) - end - end - cfg end cfg :ssh do @@ -62,5 +54,48 @@ class ASA < Oxidized::Model post_login 'terminal pager 0' pre_logout 'exit' end + + def single_context + # Single context mode + cmd 'more system:running-config' do |cfg| + cfg = cfg.each_line.to_a[3..-1].join + cfg.gsub! /^: [^\n]*\n/, '' + # backup any xml referenced in the configuration. + anyconnect_profiles = cfg.scan(Regexp.new('(\sdisk0:/.+\.xml)')).flatten + anyconnect_profiles.each do |profile| + cfg << (comment profile + "\n" ) + cmd ("more" + profile) do |xml| + cfg << (comment xml) + end + end + # if DAP is enabled, also backup dap.xml + if cfg.rindex(/dynamic-access-policy-record\s(?!DfltAccessPolicy)/) + cfg << (comment "disk0:/dap.xml\n") + cmd "more disk0:/dap.xml" do |xml| + cfg << (comment xml) + end + end + cfg + end + end + + def multiple_context + # Multiple context mode + cmd 'changeto system' do |cfg| + cmd 'show running-config' do |systemcfg| + allcfg = "\n\n" + systemcfg + "\n\n" + contexts = systemcfg.scan(/^context (\S+)$/) + files = systemcfg.scan(/config-url (\S+)$/) + contexts.each_with_index do |cont, i| + allcfg = allcfg + "\n\n----------========== [ CONTEXT " + cont.join(" ") + " FILE " + files[i].join(" ") + " ] ==========----------\n\n" + cmd "more " + files[i].join(" ") do |cfgcontext| + allcfg = allcfg + "\n\n" + cfgcontext + end + end + cfg = allcfg + end + cfg + end + end end diff --git a/lib/oxidized/model/asyncos.rb b/lib/oxidized/model/asyncos.rb new file mode 100644 index 0000000..875690b --- /dev/null +++ b/lib/oxidized/model/asyncos.rb @@ -0,0 +1,49 @@ +class AsyncOS < Oxidized::Model + + # ESA prompt "(mail.example.com)> " + prompt /^\r*([(][\w. ]+[)][#>]\s+)$/ + comment '! ' + + # Select passphrase display option + expect /\[\S+\]>\s/ do |data, re| + send "3\n" + data.sub re, '' + end + + # handle paging + expect /-Press Any Key For More-+.*$/ do |data, re| + send " " + data.sub re, '' + end + + cmd 'version' do |cfg| + comment cfg + end + + cmd 'showconfig' do |cfg| + #Delete hour and date which change each run + #cfg.gsub! /\sCurrent Time: \S+\s\S+\s+\S+\s\S+\s\S+/, ' Current Time:' + # Delete select passphrase display option + cfg.gsub! /Choose the passphrase option:/, '' + cfg.gsub! /1. Mask passphrases \(Files with masked passphrases cannot be loaded using/, '' + cfg.gsub! /loadconfig command\)/, '' + cfg.gsub! /2. Encrypt passphrases/, '' + cfg.gsub! /3. Plain passphrases/, '' + cfg.gsub! /^3$/, '' + #Delete space + cfg.gsub! /\n\s{25,26}/, '' + #Delete after line + cfg.gsub! /([-\\\/,.\w><@]+)(\s{25,27})/,"\\1" + # Add a carriage return + cfg.gsub! /([-\\\/,.\w><@]+)(\s{6})([-\\\/,.\w><@]+)/,"\\1\n\\2\\3" + # Delete prompt + cfg.gsub! /^\r*([(][\w. ]+[)][#>]\s+)$/, '' + cfg + + end + + cfg :ssh do + pre_logout "exit" + end + +end diff --git a/lib/oxidized/model/audiocodes.rb b/lib/oxidized/model/audiocodes.rb new file mode 100644 index 0000000..b7ee70e --- /dev/null +++ b/lib/oxidized/model/audiocodes.rb @@ -0,0 +1,32 @@ +class AudioCodes < Oxidized::Model + +# Pull config from AudioCodes Mediant devices from version > 7.0 + + prompt /^\r?([\w.@() -]+[#>]\s?)$/ + comment '## ' + + expect /\s*--MORE--$/ do |data, re| + + send ' ' + + data.sub re, '' + + end + + cmd 'show running-config' do |cfg| + cfg + end + + cfg :ssh do + username /^login as:\s$/ + password /^.+password:\s$/ + pre_logout 'exit' + end + + cfg :telnet do + username /^Username:\s$/ + password /^Password:\s$/ + pre_logout 'exit' + end + +end diff --git a/lib/oxidized/model/boss.rb b/lib/oxidized/model/boss.rb new file mode 100644 index 0000000..02201a1 --- /dev/null +++ b/lib/oxidized/model/boss.rb @@ -0,0 +1,76 @@ +class Boss < Oxidized::Model + # Avaya Baystack Operating System Software(BOSS) + # Created by danielcoxman@gmail.com + # May 15, 2017 + # This was tested on ers3510, ers5530, ers4850, ers5952 + # ssh and telnet were tested with banner and without + + comment '! ' + + prompt /^[^\s#>]+[#>]$/ + + # Handle the banner + # to disable the banner on BOSS the configuration parameter is "banner disabled" + expect /Enter Ctrl-Y to begin\./ do |data, re| + send "\cY" + data.sub re, '' + end + + # Handle the Failed retries since last login + # no known way to disable other than to implement radius authentication + expect /Press ENTER to continue/ do |data, re| + send "\n" + data.sub re, '' + end + + # Handle the menu on the older BOSS example ers55xx, ers56xx + # to disable them menu on BOSS the configuration parameter is "cmd-interface cli" + expect /ommand Line Interface\.\.\./ do |data, re| + send "c" + data.sub re, '' + end + + # needed for proper formatting + cmd('') { |cfg| comment "#{cfg}\n" } + + # Do a sys-info and check and see if it supports stack + cmd 'show sys-info' do |cfg| + @stack = true if cfg.match /Stack/ + cfg.gsub! /(^((.*)sysUpTime(.*))$)/, 'removed sysUpTime' + cfg.gsub! /(^((.*)sysNtpTime(.*))$)/, 'removed sysNtpTime' + cfg.gsub! /(^((.*)sysRtcTime(.*))$)/, 'removed sysNtpTime' + # remove timestamp + cfg.gsub! /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} .*/, '' + comment "#{cfg}\n" + end + + # if a stack then collect the stacking information + cmd 'show stack-info' do |cfg| + if @stack + # remove timestamp + cfg.gsub! /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} .*/, '' + comment "#{cfg}\n" + end + end + + cmd 'show running-config' do |cfg| + cfg.gsub! /^show running-config/, '! show running-config' + # remove timestamp + cfg.gsub! /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} .*/, '' + cfg.gsub! /^[^\s#>]+[#>]$/, '' + cfg.gsub! /^! clock set.*/, '! removed clock set' + cfg + end + + cfg :telnet do + username /Username: / + password /Password: / + end + + cfg :telnet, :ssh do + pre_logout 'logout' + post_login 'terminal length 0' + post_login 'terminal width 132' + end + +end diff --git a/lib/oxidized/model/ciscosma.rb b/lib/oxidized/model/ciscosma.rb new file mode 100644 index 0000000..a52e38a --- /dev/null +++ b/lib/oxidized/model/ciscosma.rb @@ -0,0 +1,45 @@ +class CiscoSMA < Oxidized::Model + + # SMA prompt "mail.example.com> " + prompt /^\r*([-\w. ]+\.[-\w. ]+\.[-\w. ]+[#>]\s+)$/ + comment '! ' + + # Select passphrase display option + expect /using loadconfig command\. \[Y\]\>/ do |data, re| + send "y\n" + data.sub re, '' + end + + # handle paging + expect /-Press Any Key For More-+.*$/ do |data, re| + send " " + data.sub re, '' + end + + cmd 'version' do |cfg| + comment cfg + end + + cmd 'showconfig' do |cfg| + #Delete hour and date which change each run + #cfg.gsub! /\sCurrent Time: \S+\s\S+\s+\S+\s\S+\s\S+/, ' Current Time:' + # Delete select passphrase display option + cfg.gsub! /Do you want to mask the password\? Files with masked passwords cannot be loaded/, '' + cfg.gsub! /^\s+y/, '' + # Delete space + cfg.gsub! /\n\s{25}/, '' + # Delete after line + cfg.gsub! /([\/\-,.\w><@]+)(\s{27})/,"\\1" + # Add a carriage return + cfg.gsub! /([\/\-,.\w><@]+)(\s{6,8})([\/\-,.\w><@]+)/,"\\1\n\\2\\3" + # Delete prompt + cfg.gsub! /^\r*([-\w. ]+\.[-\w. ]+\.[-\w. ]+[#>]\s+)$/, '' + cfg + + end + + cfg :ssh do + pre_logout "exit" + end + +end diff --git a/lib/oxidized/model/dlink.rb b/lib/oxidized/model/dlink.rb index 5756bad..0d08793 100644 --- a/lib/oxidized/model/dlink.rb +++ b/lib/oxidized/model/dlink.rb @@ -15,6 +15,7 @@ class Dlink < Oxidized::Model end cmd 'show switch' do |cfg| + cfg.gsub! /^System\ Uptime\s.+/, '' # Omit constantly changing uptime info comment cfg end diff --git a/lib/oxidized/model/enterasys.rb b/lib/oxidized/model/enterasys.rb new file mode 100644 index 0000000..708d380 --- /dev/null +++ b/lib/oxidized/model/enterasys.rb @@ -0,0 +1,30 @@ +class Enterasys < Oxidized::Model + + # Enterasys B3/C3 models # + + prompt /^.+\w\(su\)->\s?$/ + + comment '!' + + cmd :all do |cfg| + cfg.each_line.to_a[2..-3].map{|line|line.delete("\r").rstrip}.join("\n") + "\n" + end + + cmd 'show system hardware' do |cfg| + comment cfg + end + + cmd 'show config' do |cfg| + cfg.gsub! /^This command shows non-default configurations only./, '' + cfg.gsub! /^Use 'show config all' to show both default and non-default configurations./, '' + cfg.gsub! /^!|#.*/, '' + cfg.gsub! /^$\n/, '' + + cfg + end + + cfg :ssh do + pre_logout 'exit' + end + +end diff --git a/lib/oxidized/model/fortios.rb b/lib/oxidized/model/fortios.rb index cdaa282..0249933 100644 --- a/lib/oxidized/model/fortios.rb +++ b/lib/oxidized/model/fortios.rb @@ -38,6 +38,7 @@ class FortiOS < Oxidized::Model #do not include if variable "show_autoupdate" is set to false if defined?(vars(:fortios_autoupdate)).nil? || vars(:fortios_autoupdate) cfg << cmd('diagnose autoupdate version') do |cfg| + cfg.gsub! /(FDS Address\n---------\n).*/, '\\1IP Address removed' comment cfg.each_line.reject { |line| line.match /Last Update|Result/ }.join end end diff --git a/lib/oxidized/model/hirschmann.rb b/lib/oxidized/model/hirschmann.rb new file mode 100644 index 0000000..82432d7 --- /dev/null +++ b/lib/oxidized/model/hirschmann.rb @@ -0,0 +1,41 @@ +class Hirschmann < Oxidized::Model + + prompt /^[\(\w\s\w\)]+\s[>|#]+?$/ + + comment '## ' + + #Handle pager + expect /^--More--.*$/ do |data, re| + send 'a' + data.sub re, '' + end + + cmd :all do |cfg| + cfg.each_line.to_a[1..-2].join + end + + cmd 'show sysinfo' do |cfg| + cfg.gsub! /^System Up Time.*\n/, "" + cfg.gsub! /^System Date and Time.*\n/, "" + cfg.gsub! /^CPU Utilization.*\n/, "" + cfg.gsub! /^Memory.*\n/, "" + cfg.gsub! /^Average CPU Utilization.*\n/, "" + comment cfg + end + + cmd 'show running-config' do |cfg| + cfg.gsub! /^users.*\n/, "" + cfg + end + + cfg :telnet do + username /^User:/ + password /^Password:/ + end + + cfg :telnet, :ssh do + post_login 'enable' + pre_logout 'logout' + end + +end diff --git a/lib/oxidized/model/ipos.rb b/lib/oxidized/model/ipos.rb index 5efd831..938f12d 100644 --- a/lib/oxidized/model/ipos.rb +++ b/lib/oxidized/model/ipos.rb @@ -3,7 +3,7 @@ class IPOS < Oxidized::Model # Ericsson SSR (IPOS) # Redback SE (SEOS) - prompt /^([\[\]\w.@-]+[#>]\s?)$/ + prompt /^([\[\]\w.@-]+[#:>]\s?)$/ comment '! ' cmd 'show chassis' do |cfg| @@ -52,6 +52,12 @@ class IPOS < Oxidized::Model cfg :telnet, :ssh do post_login 'terminal length 0' + if vars :enable + post_login do + cmd "enable" + cmd vars(:enable) + end + end pre_logout do send "exit\n" send "n\n" diff --git a/lib/oxidized/model/ironware.rb b/lib/oxidized/model/ironware.rb index 9715c65..3ab8da1 100644 --- a/lib/oxidized/model/ironware.rb +++ b/lib/oxidized/model/ironware.rb @@ -34,6 +34,8 @@ class IronWare < Oxidized::Model cfg.gsub! /(^((.*)Current temp(.*))$)/, '' #remove unwanted lines current temperature cfg.gsub! /Speed = [A-Z-]{2,6} \(\d{2,3}\%\)/, '' #remove unwanted lines Speed Fans cfg.gsub! /current speed is [A-Z]{2,6} \(\d{2,3}\%\)/, '' + cfg.gsub! /Fan \d* - STATUS: OK \D*\d*./, '' # Fix for ADX Fan speed reporting + cfg.gsub! /\d* deg C/, '' # Fix for ADX temperature reporting cfg.gsub! /([\[]*)1([\]]*)<->([\[]*)2([\]]*)(<->([\[]*)3([\]]*))*/, '' cfg.gsub! /\d{2}\.\d deg-C/, 'XX.X deg-C' if cfg.include? "TEMPERATURE" @@ -50,6 +52,7 @@ class IronWare < Oxidized::Model end cmd 'show flash' do |cfg| + cfg.gsub! /(\d+) bytes/, '' # Fix for ADX flash size comment cfg end diff --git a/lib/oxidized/model/netgear.rb b/lib/oxidized/model/netgear.rb new file mode 100644 index 0000000..38aaca7 --- /dev/null +++ b/lib/oxidized/model/netgear.rb @@ -0,0 +1,40 @@ +class Netgear < Oxidized::Model + + comment '!' + prompt /^(\([\w-]+\)\s[#>])$/ + + cmd :secret do |cfg| + cfg.gsub!(/password (\S+)/, 'password <hidden>') + cfg + end + + cfg :telnet do + username /^User:/ + end + + cfg :telnet, :ssh do + if vars :enable + post_login do + send "enable\n" + # Interpret enable: true as meaning we won't be prompted for a password + unless vars(:enable).is_a? TrueClass + expect /[pP]assword:\s?$/ + send vars(:enable) + "\n" + end + expect /^.+[#]$/ + end + end + post_login 'terminal length 0' + # quit / logout will sometimes prompt the user: + # + # The system has unsaved changes. + # Would you like to save them now? (y/n) + # + # So it is safer simply to disconnect and not issue a pre_logout command + end + + cmd 'show running-config' do |cfg| + cfg.gsub! /^(!.*Time).*$/, '\1' + end + +end diff --git a/lib/oxidized/model/panos.rb b/lib/oxidized/model/panos.rb index 68d80c3..67ccaec 100644 --- a/lib/oxidized/model/panos.rb +++ b/lib/oxidized/model/panos.rb @@ -28,6 +28,6 @@ class PanOS < Oxidized::Model cfg :ssh do post_login 'set cli pager off' - pre_logout 'exit' + pre_logout 'quit' end end diff --git a/lib/oxidized/model/pfsense.rb b/lib/oxidized/model/pfsense.rb index 782969e..5849160 100644 --- a/lib/oxidized/model/pfsense.rb +++ b/lib/oxidized/model/pfsense.rb @@ -3,7 +3,7 @@ class PfSense < Oxidized::Model # use other use than 'admin' user, 'admin' user cannot get ssh/exec. See issue #535 cmd :all do |cfg| - cfg.each_line.to_a[1..-2].join + cfg.each_line.to_a[1..-1].join end cmd 'cat /cf/conf/config.xml' do |cfg| diff --git a/lib/oxidized/model/planet.rb b/lib/oxidized/model/planet.rb index 05a369a..9ce9cf9 100644 --- a/lib/oxidized/model/planet.rb +++ b/lib/oxidized/model/planet.rb @@ -39,9 +39,10 @@ class Planet < Oxidized::Model cfg = cfg.each_line.to_a[0...-2] - # Strip system time and system uptime from planet gs switches + # Strip system (up)time and temperature cfg = cfg.reject { |line| line.match /System Time\s*:.*/ } cfg = cfg.reject { |line| line.match /System Uptime\s*:.*/ } + cfg = cfg.reject { |line| line.match /Temperature\s*:.*/ } comment cfg.join end diff --git a/lib/oxidized/model/procurve.rb b/lib/oxidized/model/procurve.rb index 7dcf1fd..180b703 100644 --- a/lib/oxidized/model/procurve.rb +++ b/lib/oxidized/model/procurve.rb @@ -30,6 +30,7 @@ class Procurve < Oxidized::Model cfg.gsub! /^(snmp-server community).*/, '\\1 <configuration removed>' cfg.gsub! /^(snmp-server host).*/, '\\1 <configuration removed>' cfg.gsub! /^(radius-server host).*/, '\\1 <configuration removed>' + cfg.gsub! /^(radius-server key).*/, '\\1 <configuration removed>' cfg end @@ -37,6 +38,18 @@ class Procurve < Oxidized::Model comment cfg end + cmd 'show modules' do |cfg| + comment cfg + end + + cmd 'show interfaces transceiver' do |cfg| + comment cfg + end + + cmd 'show flash' do |cfg| + comment cfg + end + # not supported on all models cmd 'show system-information' do |cfg| cfg = cfg.split("\n")[0..-8].join("\n") diff --git a/lib/oxidized/model/quantaos.rb b/lib/oxidized/model/quantaos.rb index 274440d..5197aa8 100644 --- a/lib/oxidized/model/quantaos.rb +++ b/lib/oxidized/model/quantaos.rb @@ -12,7 +12,7 @@ class QuantaOS < Oxidized::Model end cfg :telnet do - username /^Username:/ + username /^User(name)?:/ password /^Password:/ end diff --git a/lib/oxidized/model/routeros.rb b/lib/oxidized/model/routeros.rb index 5717100..f391fb9 100644 --- a/lib/oxidized/model/routeros.rb +++ b/lib/oxidized/model/routeros.rb @@ -10,11 +10,18 @@ class RouterOS < Oxidized::Model comment cfg end - cmd '/export' do |cfg| - cfg.gsub! /\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]/, '' # strip ANSI colours - cfg.gsub! /\\\r\n\s+/, '' # strip new line - cfg = cfg.split("\n").select { |line| not line[/^\#\s\w{3}\/\d{2}\/\d{4}.*$/] } - cfg.join("\n") + "\n" + cmd '/system history print' do |cfg| + comment cfg + end + + post do + run_cmd = vars(:remove_secret) ? '/export hide-sensitive' : '/export' + cmd run_cmd do |cfg| + cfg.gsub! /\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K]/, '' # strip ANSI colours + cfg.gsub! /\\\r\n\s+/, '' # strip new line + cfg = cfg.split("\n").select { |line| not line[/^\#\s\w{3}\/\d{2}\/\d{4}.*$/] } + cfg.join("\n") + "\n" + end end cfg :telnet do @@ -22,6 +29,10 @@ class RouterOS < Oxidized::Model password /^Password:/ end + cfg :telnet, :ssh do + pre_logout 'quit' + end + cfg :ssh do exec true end diff --git a/lib/oxidized/model/ucs.rb b/lib/oxidized/model/ucs.rb new file mode 100644 index 0000000..a1f6c10 --- /dev/null +++ b/lib/oxidized/model/ucs.rb @@ -0,0 +1,31 @@ +class UCS < Oxidized::Model + + prompt /^(\r?[\w.@_()-]+[#]\s?)$/ + comment '! ' + + cmd 'show version brief' do |cfg| + comment cfg + end + + cmd 'show chassis detail' do |cfg| + comment cfg + end + + cmd 'show fabric-interconnect detail' do |cfg| + comment cfg + end + + cmd 'show configuration all | no-more' do |cfg| + cfg + end + + cfg :ssh, :telnet do + post_login 'terminal length 0' + pre_logout 'exit' + end + + cfg :telnet do + username /^login:/ + password /^Password:/ + end +end diff --git a/lib/oxidized/model/voss.rb b/lib/oxidized/model/voss.rb new file mode 100644 index 0000000..6b15fb3 --- /dev/null +++ b/lib/oxidized/model/voss.rb @@ -0,0 +1,42 @@ +class Voss < Oxidized::Model + # Avaya VSP Operating System Software(VOSS) + # Created by danielcoxman@gmail.com + # May 25, 2017 + # This was tested on vsp4k and vsp8k + + comment '# ' + + prompt /^[^\s#>]+[#>]$/ + + # needed for proper formatting after post_login + cmd('') { |cfg| comment "#{cfg}\n" } + + # Get sys-info and remove information that changes such has temperature and power + cmd 'show sys-info' do |cfg| + cfg.gsub! /(^((.*)SysUpTime(.*))$)/, 'removed SysUpTime' + cfg.gsub! /^((.*)Temperature Info \:(.*\r?\n){4})/, 'removed Temperature Info and 3 more lines' + cfg.gsub! /(^((.*)AmbientTemperature(.*)\:(.*))$)/, 'removed AmbientTemperature' + cfg.gsub! /(^((.*)Temperature(.*)\:(.*))$)/, 'removed Temperature' + cfg.gsub! /(^((.*)Total Power Usage(.*)\:(.*))$)/, 'removed Total Power Usage' + comment "#{cfg}\n" + end + + # more the config rather than doing a show run + cmd 'more config.cfg' do |cfg| + cfg + cfg.gsub! /^[^\s#>]+[#>]$/, '' + cfg.gsub! /^more config.cfg/, '# more config.cfg' + end + + cfg :telnet do + username /Login: $/ + password /Password: $/ + end + + cfg :telnet, :ssh do + pre_logout 'exit' + post_login 'enable' + post_login 'terminal more disable' + end + +end diff --git a/lib/oxidized/model/vrp.rb b/lib/oxidized/model/vrp.rb index 12a9ca3..98229c3 100644 --- a/lib/oxidized/model/vrp.rb +++ b/lib/oxidized/model/vrp.rb @@ -4,6 +4,12 @@ class VRP < Oxidized::Model prompt /^(<[\w.-]+>)$/ comment '# ' + cmd :secret do |cfg| + cfg.gsub! /(pin verify (?:auto|)).*/, '\\1 <PIN hidden>' + cfg.gsub! /(%\^%#.*%\^%#)/, '<secret hidden>' + cfg + end + cmd :all do |cfg| cfg.each_line.to_a[1..-2].join end diff --git a/lib/oxidized/model/weos.rb b/lib/oxidized/model/weos.rb new file mode 100644 index 0000000..1b20286 --- /dev/null +++ b/lib/oxidized/model/weos.rb @@ -0,0 +1,22 @@ +class WEOS < Oxidized::Model + + #Westell WEOS, works with Westell 8178G, Westell 8266G + + prompt /^(\s[\w.@-]+[#>]\s?)$/ + + cmd :all do |cfg| + cfg.each_line.to_a[1..-2].join + end + + cmd 'show running-config' do |cfg| + cfg + end + + cfg :telnet do + username /login:/ + password /assword:/ + post_login 'cli more disable' + pre_logout 'logout' + end + +end diff --git a/lib/oxidized/model/xos.rb b/lib/oxidized/model/xos.rb index 6f1323f..90f6f4a 100644 --- a/lib/oxidized/model/xos.rb +++ b/lib/oxidized/model/xos.rb @@ -29,6 +29,10 @@ class XOS < Oxidized::Model cmd 'show configuration' + cmd 'show policy detail' do |cfg| + comment cfg + end + cfg :telnet do username /^login:/ password /^\r*password:/ diff --git a/lib/oxidized/node.rb b/lib/oxidized/node.rb index cf71e48..8d0d0af 100644 --- a/lib/oxidized/node.rb +++ b/lib/oxidized/node.rb @@ -216,6 +216,14 @@ module Oxidized end end + #model + if Oxidized.config.models.has_key?(@model.class.name.to_s.downcase) + if Oxidized.config.models[@model.class.name.to_s.downcase].has_key?(key_str) + value = Oxidized.config.models[@model.class.name.to_s.downcase][key_str] + Oxidized.logger.debug "node.rb: setting node key '#{key}' to value '#{value}' from model" + end + end + #node value = opt[key_sym] || value Oxidized.logger.debug "node.rb: returning node key '#{key}' with value '#{value}'" diff --git a/lib/oxidized/version.rb b/lib/oxidized/version.rb index 073aae9..221cffa 100644 --- a/lib/oxidized/version.rb +++ b/lib/oxidized/version.rb @@ -1,3 +1,3 @@ module Oxidized - VERSION = '0.19.0' + VERSION = '0.20.0' end diff --git a/oxidized.gemspec b/oxidized.gemspec index ea088e7..a8e3eb5 100644 --- a/oxidized.gemspec +++ b/oxidized.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |s| s.required_ruby_version = '>= 2.0.0' s.add_runtime_dependency 'asetus', '~> 0.1' s.add_runtime_dependency 'slop', '~> 3.5' - s.add_runtime_dependency 'net-ssh', '~> 3.0.2' + s.add_runtime_dependency 'net-ssh', '~> 4.1.0' s.add_runtime_dependency 'rugged', '~> 0.21', '>= 0.21.4' if defined?(RUBY_VERSION) && RUBY_VERSION > '2.3' |