Class: TrainPlugins::Juniper::Connection
- Inherits:
-
Train::Plugins::Transport::BaseConnection
- Object
- Train::Plugins::Transport::BaseConnection
- TrainPlugins::Juniper::Connection
- Includes:
- BastionProxy, CommandExecutor, Environment, ErrorHandling, Logging, Platform, SSHSession, Validation
- Defined in:
- lib/train-juniper/connection.rb
Overview
Main connection class for Juniper devices
Constant Summary collapse
- CommandResult =
Alias for Train CommandResult for backward compatibility
Train::Extras::CommandResult
- ENV_CONFIG =
Configuration mapping for environment variables
{ host: { env: 'JUNIPER_HOST' }, user: { env: 'JUNIPER_USER' }, password: { env: 'JUNIPER_PASSWORD' }, port: { env: 'JUNIPER_PORT', type: :int, default: Constants::DEFAULT_SSH_PORT }, timeout: { env: 'JUNIPER_TIMEOUT', type: :int, default: 30 }, bastion_host: { env: 'JUNIPER_BASTION_HOST' }, bastion_user: { env: 'JUNIPER_BASTION_USER' }, bastion_port: { env: 'JUNIPER_BASTION_PORT', type: :int, default: Constants::DEFAULT_SSH_PORT }, bastion_password: { env: 'JUNIPER_BASTION_PASSWORD' }, proxy_command: { env: 'JUNIPER_PROXY_COMMAND' } }.freeze
- SENSITIVE_OPTIONS =
List of sensitive option keys to redact in logs
%i[password bastion_password key_files proxy_command].freeze
Instance Attribute Summary collapse
-
#ssh_session ⇒ Object
readonly
Returns the value of attribute ssh_session.
Instance Method Summary collapse
-
#bastion_auth_error?(error) ⇒ Boolean
included
from ErrorHandling
Check if error is bastion authentication related.
-
#bastion_error_message(error) ⇒ String
included
from ErrorHandling
Build helpful bastion error message.
-
#build_plink_proxy_command(bastion_host, user, port, password) ⇒ String
included
from WindowsProxy
Build plink.exe proxy command for Windows bastion authentication.
-
#build_proxy_jump_string(bastion_user, bastion_port) ⇒ String
included
from BastionProxy
private
Build proxy jump string from bastion options.
-
#build_ssh_options ⇒ Object
included
from SSHSession
private
Build SSH connection options from @options.
-
#clean_output(output, cmd) ⇒ Object
included
from CommandExecutor
private
Clean command output.
-
#configure_bastion_proxy(ssh_options) ⇒ Object
included
from BastionProxy
Configure bastion proxy for SSH connection.
-
#configure_plink_proxy(ssh_options, bastion_user, bastion_port, bastion_password) ⇒ Object
included
from BastionProxy
private
Configure plink.exe proxy for Windows password authentication.
-
#configure_standard_proxy(ssh_options, bastion_user, bastion_port) ⇒ Object
included
from BastionProxy
private
Configure standard SSH proxy using Net::SSH::Proxy::Jump.
-
#connect ⇒ Object
included
from SSHSession
Establish SSH connection to Juniper device.
-
#connected? ⇒ Boolean
included
from SSHSession
Check if SSH connection is active.
-
#create_ssh_askpass_script(password) ⇒ String
included
from SshAskpass
Create temporary SSH_ASKPASS script for automated password authentication.
-
#create_unix_askpass_script(password) ⇒ String
included
from SshAskpass
private
Create Unix shell script for SSH_ASKPASS.
-
#create_windows_askpass_script(password) ⇒ String
included
from SshAskpass
private
Create Windows PowerShell script for SSH_ASKPASS.
-
#detect_attribute(attribute_name, command = 'show version') {|String| ... } ⇒ String?
included
from Platform
private
Generic detection helper for version and architecture.
-
#detect_junos_architecture ⇒ String?
included
from Platform
private
Detect JunOS architecture from device output.
-
#detect_junos_serial ⇒ String?
included
from Platform
private
Detect JunOS serial number from device output.
-
#detect_junos_version ⇒ String?
included
from Platform
private
Detect JunOS version from device output.
-
#download(remotes, local) ⇒ Object
Download files from Juniper device (not supported).
-
#env_int(key) ⇒ Integer?
included
from Environment
Helper method to get environment variable as integer Returns nil if env var is not set, empty, or not a valid integer.
-
#env_value(key) ⇒ String?
included
from Environment
Helper method to safely get environment variable value Returns nil if env var is not set or is empty string.
-
#error_result(message) ⇒ Train::Extras::CommandResult
included
from CommandExecutor
private
Factory method for error command results.
-
#extract_architecture_from_xml(output) ⇒ String?
included
from Platform
private
Extract architecture string from JunOS show version XML output.
-
#extract_from_xml(output, xpath_patterns, command_desc) {|REXML::Element| ... } ⇒ String?
included
from Platform
private
Generic XML extraction helper.
-
#extract_serial_from_xml(output) ⇒ String?
included
from Platform
private
Extract serial number from JunOS chassis hardware XML output.
-
#extract_version_from_xml(output) ⇒ String?
included
from Platform
private
Extract version string from JunOS show version XML output.
-
#file_via_connection(path) ⇒ JuniperFile
Access Juniper configuration and operational data as pseudo-files.
-
#format_junos_result(output, cmd) ⇒ Object
included
from CommandExecutor
private
Format JunOS command results.
-
#generate_bastion_proxy_command(bastion_user, bastion_port) ⇒ String
included
from BastionProxy
private
Generate SSH proxy command for bastion host using ProxyJump (-J).
-
#handle_connection_error(error) ⇒ Object
included
from ErrorHandling
Handle connection errors with helpful messages.
-
#healthy? ⇒ Boolean
Check connection health.
-
#initialize(options) ⇒ Connection
constructor
Initialize a new Juniper connection.
-
#inspect ⇒ String
Secure inspect method that uses to_s.
-
#junos_error?(output) ⇒ Boolean
included
from ErrorHandling
Check for JunOS error patterns.
-
#log_bastion_connection(bastion_host) ⇒ Object
included
from Logging
Log bastion connection attempt.
-
#log_command(cmd) ⇒ Object
included
from Logging
Log a command execution attempt.
-
#log_connection_attempt(target, port = nil) ⇒ Object
included
from Logging
Log a connection attempt.
-
#log_connection_info ⇒ Object
private
Log connection info without exposing sensitive data.
-
#log_connection_success(target) ⇒ Object
included
from Logging
Log successful connection.
-
#log_error(error, context = nil) ⇒ Object
included
from Logging
Log an error with consistent formatting.
-
#log_mock_mode ⇒ Object
included
from Logging
Log mock mode activation.
-
#log_platform_detection(platform_name, version) ⇒ Object
included
from Logging
Log platform detection results.
-
#log_ssh_options(options) ⇒ Object
included
from Logging
Log SSH session details (redacting sensitive info).
-
#mock? ⇒ Boolean
included
from SSHSession
Check if running in mock mode.
-
#mock_command_result(cmd) ⇒ Object
included
from CommandExecutor
private
Mock command execution for testing.
-
#platform ⇒ Train::Platform
included
from Platform
Platform detection for Juniper network devices.
-
#plink_available? ⇒ Boolean
included
from WindowsProxy
Check if plink.exe is available on Windows.
-
#run_command_via_connection(cmd) ⇒ CommandResult
included
from CommandExecutor
Execute commands on Juniper device via SSH.
-
#sanitize_command(cmd) ⇒ Object
included
from CommandExecutor
private
Sanitize command to prevent injection attacks.
-
#setup_bastion_password_auth ⇒ Object
included
from SshAskpass
Set up SSH_ASKPASS for bastion password authentication.
-
#success_result(output, cmd = nil) ⇒ Train::Extras::CommandResult
included
from CommandExecutor
private
Factory method for successful command results.
-
#test_and_configure_session ⇒ Object
included
from SSHSession
Test connection and configure JunOS session.
-
#to_s ⇒ Object
Secure string representation (never expose credentials).
-
#unique_identifier ⇒ String
Optional method for better UUID generation using device-specific identifiers.
-
#upload(locals, remote) ⇒ Object
Upload files to Juniper device (not supported).
-
#uri ⇒ String
Required by Train framework for node identification.
-
#validate_bastion_port! ⇒ Object
included
from Validation
Validate bastion port is in valid range.
-
#validate_connection_options! ⇒ Object
included
from Validation
Validate all connection options.
-
#validate_option_types! ⇒ Object
included
from Validation
Validate option types and ranges.
-
#validate_port! ⇒ Object
included
from Validation
Validate port is in valid range.
-
#validate_port_value!(port_key, port_name = nil) ⇒ Object
included
from Validation
private
DRY method for validating port values.
-
#validate_proxy_options! ⇒ Object
included
from Validation
private
Validate proxy configuration options (Train standard).
-
#validate_required_options! ⇒ Object
included
from Validation
Validate required options are present.
-
#validate_timeout! ⇒ Object
included
from Validation
Validate timeout is positive number.
Constructor Details
#initialize(options) ⇒ Connection
Initialize a new Juniper connection
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/train-juniper/connection.rb', line 83 def initialize() # Configure SSH connection options for Juniper devices # Support environment variables for authentication (following train-vsphere pattern) @options = .dup # Apply environment variable configuration using DRY approach ENV_CONFIG.each do |key, config| # Skip if option already has a value from command line next if @options[key] # Get value from environment env_val = config[:type] == :int ? env_int(config[:env]) : env_value(config[:env]) # Only apply env value if it exists, otherwise use default (but not for nil CLI values) if env_val @options[key] = env_val elsif !@options.key?(key) && config[:default] @options[key] = config[:default] end end @options[:keepalive] = true @options[:keepalive_interval] = Constants::SSH_KEEPALIVE_INTERVAL # Setup logger @logger = @options[:logger] || Logger.new(STDOUT, level: Constants::DEFAULT_LOG_LEVEL) # JunOS CLI prompt patterns @cli_prompt = /[%>$#]\s*$/ @config_prompt = /[%#]\s*$/ # Log connection info safely log_connection_info # Validate all connection options super(@options) # Establish SSH connection to Juniper device (unless in mock mode or skip_connect) if @options[:mock] log_mock_mode elsif !@options[:skip_connect] @logger.debug('Attempting to connect to Juniper device...') connect end end |
Instance Attribute Details
#ssh_session ⇒ Object (readonly)
Returns the value of attribute ssh_session.
56 57 58 |
# File 'lib/train-juniper/connection.rb', line 56 def ssh_session @ssh_session end |
Instance Method Details
#bastion_auth_error?(error) ⇒ Boolean Originally defined in module ErrorHandling
Check if error is bastion authentication related
#bastion_error_message(error) ⇒ String Originally defined in module ErrorHandling
Build helpful bastion error message
#build_plink_proxy_command(bastion_host, user, port, password) ⇒ String Originally defined in module WindowsProxy
Build plink.exe proxy command for Windows bastion authentication
#build_proxy_jump_string(bastion_user, bastion_port) ⇒ String (private) Originally defined in module BastionProxy
Build proxy jump string from bastion options
#build_ssh_options ⇒ Object (private) Originally defined in module SSHSession
Build SSH connection options from @options
#clean_output(output, cmd) ⇒ Object (private) Originally defined in module CommandExecutor
Clean command output
#configure_bastion_proxy(ssh_options) ⇒ Object Originally defined in module BastionProxy
Configure bastion proxy for SSH connection
#configure_plink_proxy(ssh_options, bastion_user, bastion_port, bastion_password) ⇒ Object (private) Originally defined in module BastionProxy
Configure plink.exe proxy for Windows password authentication
#configure_standard_proxy(ssh_options, bastion_user, bastion_port) ⇒ Object (private) Originally defined in module BastionProxy
Configure standard SSH proxy using Net::SSH::Proxy::Jump
#connect ⇒ Object Originally defined in module SSHSession
Establish SSH connection to Juniper device
#connected? ⇒ Boolean Originally defined in module SSHSession
Check if SSH connection is active
#create_ssh_askpass_script(password) ⇒ String Originally defined in module SshAskpass
Create temporary SSH_ASKPASS script for automated password authentication
#create_unix_askpass_script(password) ⇒ String (private) Originally defined in module SshAskpass
Create Unix shell script for SSH_ASKPASS
#create_windows_askpass_script(password) ⇒ String (private) Originally defined in module SshAskpass
Create Windows PowerShell script for SSH_ASKPASS
#detect_attribute(attribute_name, command = 'show version') {|String| ... } ⇒ String? (private) Originally defined in module Platform
Generic detection helper for version and architecture
#detect_junos_architecture ⇒ String? (private) Originally defined in module Platform
This runs safely after the connection is established
Detect JunOS architecture from device output
#detect_junos_serial ⇒ String? (private) Originally defined in module Platform
This runs safely after the connection is established
Detect JunOS serial number from device output
#detect_junos_version ⇒ String? (private) Originally defined in module Platform
This runs safely after the connection is established
Detect JunOS version from device output
#download(remotes, local) ⇒ Object
Use run_command() to retrieve configuration data instead
Download files from Juniper device (not supported)
171 172 173 |
# File 'lib/train-juniper/connection.rb', line 171 def download(remotes, local) raise NotImplementedError, Constants::DOWNLOAD_NOT_SUPPORTED end |
#env_int(key) ⇒ Integer? Originally defined in module Environment
Helper method to get environment variable as integer Returns nil if env var is not set, empty, or not a valid integer
#env_value(key) ⇒ String? Originally defined in module Environment
Helper method to safely get environment variable value Returns nil if env var is not set or is empty string
#error_result(message) ⇒ Train::Extras::CommandResult (private) Originally defined in module CommandExecutor
Factory method for error command results
#extract_architecture_from_xml(output) ⇒ String? (private) Originally defined in module Platform
Extract architecture string from JunOS show version XML output
#extract_from_xml(output, xpath_patterns, command_desc) {|REXML::Element| ... } ⇒ String? (private) Originally defined in module Platform
Generic XML extraction helper
#extract_serial_from_xml(output) ⇒ String? (private) Originally defined in module Platform
Extract serial number from JunOS chassis hardware XML output
#extract_version_from_xml(output) ⇒ String? (private) Originally defined in module Platform
Extract version string from JunOS show version XML output
#file_via_connection(path) ⇒ JuniperFile
Access Juniper configuration and operational data as pseudo-files
151 152 153 154 155 |
# File 'lib/train-juniper/connection.rb', line 151 def file_via_connection(path) # For Juniper devices, "files" are typically configuration sections # or operational command outputs rather than traditional filesystem paths JuniperFile.new(self, path) end |
#format_junos_result(output, cmd) ⇒ Object (private) Originally defined in module CommandExecutor
Format JunOS command results
#generate_bastion_proxy_command(bastion_user, bastion_port) ⇒ String (private) Originally defined in module BastionProxy
Generate SSH proxy command for bastion host using ProxyJump (-J)
#handle_connection_error(error) ⇒ Object Originally defined in module ErrorHandling
Handle connection errors with helpful messages
#healthy? ⇒ Boolean
Check connection health
181 182 183 184 185 186 187 188 |
# File 'lib/train-juniper/connection.rb', line 181 def healthy? return false unless connected? result = run_command_via_connection('show version') result.exit_status.zero? rescue StandardError false end |
#inspect ⇒ String
Secure inspect method that uses to_s
138 139 140 |
# File 'lib/train-juniper/connection.rb', line 138 def inspect to_s end |
#junos_error?(output) ⇒ Boolean Originally defined in module ErrorHandling
Check for JunOS error patterns
#log_bastion_connection(bastion_host) ⇒ Object Originally defined in module Logging
Log bastion connection attempt
#log_command(cmd) ⇒ Object Originally defined in module Logging
Log a command execution attempt
#log_connection_attempt(target, port = nil) ⇒ Object Originally defined in module Logging
Log a connection attempt
#log_connection_info ⇒ Object (private)
Log connection info without exposing sensitive data
229 230 231 232 233 |
# File 'lib/train-juniper/connection.rb', line 229 def log_connection_info = @options.except(*SENSITIVE_OPTIONS) @logger.debug("Juniper connection initialized with options: #{.inspect}") @logger.debug("Environment: JUNIPER_BASTION_USER=#{env_value('JUNIPER_BASTION_USER')} -> bastion_user=#{@options[:bastion_user]}") end |
#log_connection_success(target) ⇒ Object Originally defined in module Logging
Log successful connection
#log_error(error, context = nil) ⇒ Object Originally defined in module Logging
Log an error with consistent formatting
#log_mock_mode ⇒ Object Originally defined in module Logging
Log mock mode activation
#log_platform_detection(platform_name, version) ⇒ Object Originally defined in module Logging
Log platform detection results
#log_ssh_options(options) ⇒ Object Originally defined in module Logging
Log SSH session details (redacting sensitive info)
#mock? ⇒ Boolean Originally defined in module SSHSession
Check if running in mock mode
#mock_command_result(cmd) ⇒ Object (private) Originally defined in module CommandExecutor
Mock command execution for testing
#platform ⇒ Train::Platform Originally defined in module Platform
Uses force_platform! to bypass Train's automatic detection
Platform detection for Juniper network devices
#plink_available? ⇒ Boolean Originally defined in module WindowsProxy
Check if plink.exe is available on Windows
#run_command_via_connection(cmd) ⇒ CommandResult Originally defined in module CommandExecutor
Execute commands on Juniper device via SSH
#sanitize_command(cmd) ⇒ Object (private) Originally defined in module CommandExecutor
Sanitize command to prevent injection attacks
#setup_bastion_password_auth ⇒ Object Originally defined in module SshAskpass
Set up SSH_ASKPASS for bastion password authentication
#success_result(output, cmd = nil) ⇒ Train::Extras::CommandResult (private) Originally defined in module CommandExecutor
Factory method for successful command results
#test_and_configure_session ⇒ Object Originally defined in module SSHSession
Test connection and configure JunOS session
#to_s ⇒ Object
Secure string representation (never expose credentials)
132 133 134 |
# File 'lib/train-juniper/connection.rb', line 132 def to_s "#<#{self.class.name}:0x#{object_id.to_s(16)} @host=#{@options[:host]} @user=#{@options[:user]}>" end |
#unique_identifier ⇒ String
Tries to get Juniper device serial number, falls back to hostname
Optional method for better UUID generation using device-specific identifiers
213 214 215 216 217 218 219 220 |
# File 'lib/train-juniper/connection.rb', line 213 def unique_identifier # Don't attempt device detection in mock mode return @options[:host] if @options[:mock] # Use the platform module's serial detection which follows DRY principle serial = detect_junos_serial serial || @options[:host] end |
#upload(locals, remote) ⇒ Object
Network devices use command-based configuration instead of file uploads
Upload files to Juniper device (not supported)
162 163 164 |
# File 'lib/train-juniper/connection.rb', line 162 def upload(locals, remote) raise NotImplementedError, Constants::UPLOAD_NOT_SUPPORTED end |
#uri ⇒ String
Required by Train framework for node identification
196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/train-juniper/connection.rb', line 196 def uri base_uri = "juniper://#{@options[:user]}@#{@options[:host]}:#{@options[:port]}" # Include bastion information if connecting through a jump host if @options[:bastion_host] bastion_user = @options[:bastion_user] || @options[:user] bastion_port = @options[:bastion_port] || 22 bastion_info = "via=#{bastion_user}@#{@options[:bastion_host]}:#{bastion_port}" "#{base_uri}?#{bastion_info}" else base_uri end end |
#validate_bastion_port! ⇒ Object Originally defined in module Validation
Validate bastion port is in valid range
#validate_connection_options! ⇒ Object Originally defined in module Validation
Validate all connection options
#validate_option_types! ⇒ Object Originally defined in module Validation
Validate option types and ranges
#validate_port! ⇒ Object Originally defined in module Validation
Validate port is in valid range
#validate_port_value!(port_key, port_name = nil) ⇒ Object (private) Originally defined in module Validation
DRY method for validating port values
#validate_proxy_options! ⇒ Object (private) Originally defined in module Validation
Validate proxy configuration options (Train standard)
#validate_required_options! ⇒ Object Originally defined in module Validation
Validate required options are present
#validate_timeout! ⇒ Object Originally defined in module Validation
Validate timeout is positive number