Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Riverbed #3317

Merged
merged 6 commits into from
Nov 16, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [Unreleased]

### Added
- model for Riverbed Steelhead (@Swaeltjie)
- removed time command from uplink EP4440-DP OLT model
- model for uplink EP4440-DP OLT (@AAm-kun)
- model for Siklu Multihaul TG radios (@bdg-robert)
Expand Down
123 changes: 123 additions & 0 deletions examples/device-simulation/yaml/riverbed_915.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
init_prompt: |-
Riverbed SteelHead
Last login: Fri Nov 1 05:55:01 2024 from 192.0.2.1
steelhead >
commands:
enable: |-
enable
steelhead #
terminal length 0: |-
terminal length 0
steelhead #
terminal width 1024: |-
terminal width 1024
steelhead #
show version: |-
show version
Product name: rbt_sh
Product release: X.Y.Z
Build ID: #1234
Build date: YYYY-MM-DD HH:MM:SS
Build arch: x86_64
Built by: builduser@buildhost

Uptime: 100d 10h 10m 10s

Product model: ModelName (ModelVariant)
System memory: XXXX MB used / XXXX MB free / XXXX MB total
Number of CPUs: XX
CPU load averages: X.XX / X.XX / X.XX
steelhead #
show hardware all: |-
show hardware all
Hardware revision: RevX
Mainboard: MainboardDescription
Slot 0: .......... ModuleDescription0
Slot 1: .......... ModuleDescription1
Slot 2: .......... ModuleDescription2
System led: Color
steelhead #
show info: |-
show info
Current User: admin

Status: Normal
Config: config.bak
Appliance Up Time: 100d 10h 10m 10s
Service Up Time: 90d 20h 20m 20s
Managed by CMC: no
Temperature (C): XX

Serial: SERIAL1234567
Model: ModelName (ModelVariant)
Revision: RevX
Version: X.Y.Z
steelhead #
show running-config: |-
show running-config
##
## Network interface configuration
##
interface inpath0_0 description "Interface Description"
no interface inpath0_0 dhcp
no interface inpath0_0 dhcp dynamic-dns
no interface inpath0_0 dhcpv6
no interface inpath0_0 dhcpv6 dynamic-dns
##
## Secure device access configuration
##
access enable
##
## Port Labels
##
port-label "Label" port "PortNumbers"
tacacs-server host 192.0.2.254 key secretkey
username admin password 7 secretpassword
snmp-server community public
ntp server 192.0.2.100 key 1
ip security shared secret mysecret
!
end
steelhead #
exit: ""
oxidized_output: |
! Date of version: YYYY-MM-DD HH:MM:SS UTC
! Serial: SERIAL1234567
! Product name: rbt_sh
! Product release: X.Y.Z
! Build ID: #1234
! Build date: YYYY-MM-DD HH:MM:SS
! Build arch: x86_64
! Built by: builduser@buildhost
! Product model: ModelName (ModelVariant)
! Number of CPUs: XX
! Hardware revision: RevX
! Mainboard: MainboardDescription
! Slot 0: ModuleDescription0
! Slot 1: ModuleDescription1
! Slot 2: ModuleDescription2
! System led: Color
##
## Network interface configuration
##
interface inpath0_0 description "Interface Description"
no interface inpath0_0 dhcp
no interface inpath0_0 dhcp dynamic-dns
no interface inpath0_0 dhcpv6
no interface inpath0_0 dhcpv6 dynamic-dns
##
## Secure device access configuration
##
access enable
##
## Port Labels
##
port-label "Label" port "PortNumbers"
tacacs-server host 192.0.2.254 key <secret hidden>
username admin password <secret hidden>
snmp-server community <configuration removed>
ntp server 192.0.2.100 key <secret hidden>
ip security shared secret <secret hidden>
!
end
131 changes: 131 additions & 0 deletions lib/oxidized/model/riverbed.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
class Riverbed < Oxidized::Model
using Refinements

# Define the prompt
PROMPT = /^.*\s*[\w-]+\s*[#>]\s*$/i
Swaeltjie marked this conversation as resolved.
Show resolved Hide resolved
prompt PROMPT

# Define comment character
comment '! '

# Use procs to remove unwanted lines
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • The "Last login" message should never appear, as Oxidized does not interpret the initial prompt.
  • Do not use procs directly. Use cmd :all

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the entire procs block.

procs do
# Remove "Last login" message
proc { |output| output.gsub!(/^Last login:.*\n/, '') }
end

# Remove sensitive information
cmd :secret do |cfg|
cfg.gsub! /^(\s*tacacs-server (.+ )?key) .+/, '\\1 <secret hidden>'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer space to \s when possible, as \s also matches \n and \r

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced \s with explicit spaces to match only space characters.

cfg.gsub! /^(\s*username .+ (password|secret) \d) .+/, '\\1 <secret hidden>'
cfg.gsub! /^(\s*ntp server .+ key) .+/, '\\1 <secret hidden>'
cfg.gsub! /^(\s*ntp peer .+ key) .+/, '\\1 <secret hidden>'
cfg.gsub! /^(\s*snmp-server community).*/, '\\1 <configuration removed>'
cfg.gsub! /^(\s*ip security shared secret).*/, '\\1 <secret hidden>'
cfg.gsub! /^(\s*service shared-secret secret client).*/, '\\1 <secret hidden>'
cfg.gsub! /^(\s*service shared-secret secret server).*/, '\\1 <secret hidden>'
cfg
end

# Get version information and store it
cmd 'show version' do |cfg|
# Remove the command echo and the hostname from the output
cfg = cfg.cut_head
cfg.gsub!(PROMPT, '')

# Extract relevant information
comments = []
cfg.each_line do |line|
line.strip!
comments << "Product name: #{Regexp.last_match(1)}" if line =~ /^Product name:\s+(.*)$/
comments << "Product release: #{Regexp.last_match(1)}" if line =~ /^Product release:\s+(.*)$/
comments << "Build ID: #{Regexp.last_match(1)}" if line =~ /^Build ID:\s+(.*)$/
comments << "Build date: #{Regexp.last_match(1)}" if line =~ /^Build date:\s+(.*)$/
comments << "Build arch: #{Regexp.last_match(1)}" if line =~ /^Build arch:\s+(.*)$/
comments << "Built by: #{Regexp.last_match(1)}" if line =~ /^Built by:\s+(.*)$/
comments << "Product model: #{Regexp.last_match(1)}" if line =~ /^Product model:\s+(.*)$/
comments << "Number of CPUs: #{Regexp.last_match(1)}" if line =~ /^Number of CPUs:\s+(.*)$/
end
@version_info = comments.join("\n")
''
end

# Get hardware information and store it
cmd 'show hardware all' do |cfg|
# Remove the command echo and the hostname from the output
cfg = cfg.cut_head
cfg.gsub!(PROMPT, '')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using cut_both

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced with cfg = cfg.cut_both to remove both the first and last lines in one step.


# Extract relevant information
comments = []
cfg.each_line do |line|
line.strip!
comments << "Hardware revision: #{Regexp.last_match(1)}" if line =~ /^Hardware revision:\s+(.*)$/
comments << "Mainboard: #{Regexp.last_match(1)}" if line =~ /^Mainboard:\s+(.*)$/
if line =~ /^Slot (\d+):\s+\.*\s+(.*)$/
slot_number = Regexp.last_match(1)
slot_info = Regexp.last_match(2)
comments << "Slot #{slot_number}: #{slot_info}"
end
comments << "System led: #{Regexp.last_match(1)}" if line =~ /^System led:\s+(.*)$/
end
@hardware_info = comments.join("\n")
''
end

# Get serial information from 'show info' command
cmd 'show info' do |cfg|
# Remove the command echo and the hostname from the output
cfg = cfg.cut_head
cfg.gsub!(PROMPT, '')

# Extract the 'Serial:' line
cfg.each_line do |line|
line.strip!
@serial_info = "Serial: #{Regexp.last_match(1)}" if line =~ /^Serial:\s+(.*)$/
end
''
end

# Get the running configuration
cmd 'show running-config' do |cfg|
# Remove the first and last lines (command echo and hostname)
cfg = cfg.cut_head.cut_tail

# Process lines containing '##'
cfg = cfg.each_line.map do |line|
if line =~ /^(.*##.*?##)(.*)$/
# Split the line into comment and rest
comment_part = Regexp.last_match(1).strip
command_part = Regexp.last_match(2).strip
comment_line = comment(comment_part)
if command_part.empty?
comment_line + "\n"
else
comment_line + "\n" + command_part + "\n"
end
else
line
end
end.join

# Prepend date, version, hardware, and serial information to the configuration
header = []
header << comment("Date of version: #{Time.now.strftime('%Y-%m-%d %H:%M:%S %Z')}")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Printing the time is not a good idea, as oxidized will store a config after every fetch. The idea is to strip everything changing out, and store the configs in git, so you only get differences and not thousand of identical files.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the line that adds the date to the header.

header << comment(@serial_info) if @serial_info
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be simpler to output these informations above and not store them into a variable? Most other models do so.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified the code to output the extracted information directly as comments within the cmd blocks.

header << @version_info.each_line.map { |line| comment line }.join if @version_info
header << @hardware_info.each_line.map { |line| comment line }.join if @hardware_info
header.join("\n") + "\n" + cfg
end

# SSH configuration
cfg :ssh do
post_login do
# Always enter enable mode
cmd 'enable'
cmd 'terminal length 0'
cmd 'terminal width 1024'
end
pre_logout 'exit'
end
end