train-juniper 0.7.1 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 86bf86dd54cabe94e072c6e3a2b64ffcdfbdf774a5f33f1a3a76012829dd71bc
4
- data.tar.gz: c2e5d2fe1ecfa259f78c2d80f76d94eaa68afb817d584c57d02bfb4c46779924
3
+ metadata.gz: 6da9bb07db2daaa3ca21d2fef18b0a200ff15597495dece758e0e509d10c13ad
4
+ data.tar.gz: 86e802113118c172748e2187e09db4c95c080f393dc083932a65386d19c82f3c
5
5
  SHA512:
6
- metadata.gz: 168356b0c2a48f7b4817acb535571c2b651d12365dc7340c96c9b2b2d6db30981516683c29965bd295459d8cbb2b2625e020a35789a3bbed4d295ce29712264e
7
- data.tar.gz: 8a209708671652728890ff96f75b3a2da922f37f93c61896881e99b387adc15ecc1e889d6e416637dc0eee011ed1f1b9b0fcd33b99c2bacfe15f2736daaa9da8
6
+ metadata.gz: 0137dee8f2547f0973d2e513491574e624f55a605993ca8e6211e1c84c77341fe840d45704903e25eaeacb6e043b1846556f2f124ee08863c591357e34c37ecb
7
+ data.tar.gz: ddd016a7cf4cc47d68e9e0f89283d874ea563abab20cc6f2e822d67658694bac3782d3cef0ef4f2a1976bfbf4b2a8652050ff87c9b9d13c18864a5c26a169482
data/.env.example CHANGED
@@ -1,29 +1,16 @@
1
- # Train-Juniper Environment Variables Example
2
- # Copy this file to .env and fill in your actual values
3
- # The plugin automatically detects these environment variables
1
+ # Example .env file for Windows testing
2
+ # Copy this to .env and fill in your actual values
4
3
 
5
- # Juniper Device Connection
6
- JUNIPER_HOST=your.device.hostname.com
7
- JUNIPER_USER=your_username
8
- JUNIPER_PASSWORD=your_password
9
- JUNIPER_PORT=22
10
- JUNIPER_TIMEOUT=60
4
+ # Target Juniper device (behind bastion)
5
+ JUNIPER_HOST=192.168.1.100
6
+ JUNIPER_USER=admin
7
+ JUNIPER_PASSWORD=device_password
11
8
 
12
- # Bastion/Jump Host (optional - only if device is behind jump host)
13
- JUNIPER_BASTION_HOST=your.jumphost.com
14
- JUNIPER_BASTION_USER=your_jump_username
15
- JUNIPER_BASTION_PORT=22
16
- JUNIPER_BASTION_PASSWORD=your_jump_password
9
+ # Bastion/Jump host
10
+ BASTION_HOST=bastion.example.com
11
+ BASTION_USER=jumpuser
12
+ BASTION_PASSWORD=bastion_password
17
13
 
18
- # Custom Proxy Command (alternative to bastion host)
19
- # JUNIPER_PROXY_COMMAND=ssh your.jumphost.com -W %h:%p
20
-
21
- # Usage Examples:
22
- # 1. Basic connection (auto-detects above variables):
23
- # inspec detect -t juniper://
24
- #
25
- # 2. Override specific values:
26
- # inspec detect -t juniper://different_user@different_host --password override_pass
27
- #
28
- # 3. Test connection:
29
- # source .env && inspec detect -t juniper:// -l debug
14
+ # Optional: Custom ports
15
+ # JUNIPER_PORT=22
16
+ # BASTION_PORT=22
data/CHANGELOG.md CHANGED
@@ -5,6 +5,59 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.7.4] - 2025-06-24
9
+
10
+ ### Added
11
+
12
+ - Add Windows plink.exe support for bastion authentication
13
+
14
+ ### Documentation
15
+
16
+ - Add Windows bastion setup guide and improve navigation
17
+ - Fix MkDocs link warnings
18
+ - Add host key acceptance instructions and InSpec testing examples
19
+ - Improve Windows documentation and standardize on inspec shell
20
+
21
+ ### Miscellaneous Tasks
22
+
23
+ - Fix linting issues in Windows test script
24
+
25
+ ### Testing
26
+
27
+ - Add Windows testing scripts and guide
28
+ - Add .env file support to Windows test scripts
29
+
30
+ ## [0.7.3] - 2025-06-23
31
+
32
+ ### Documentation
33
+
34
+ - Improve README structure for better MkDocs rendering
35
+ - Add platform support section to README
36
+
37
+ ### Fixed
38
+
39
+ - Follow standard RubyGems conventions for gem packaging
40
+ - Remove .md extensions from internal MkDocs links
41
+ - **docs**: Improve Support section formatting with subsections
42
+ - **windows**: Use PowerShell for SSH_ASKPASS on Windows and add cross-platform CI/CD
43
+ - **ci**: Add comprehensive platform support for cross-platform compatibility
44
+ - Update ffi dependency to support Ruby 3.3 on Windows
45
+ - Handle Windows PowerShell script paths in bastion proxy tests
46
+ - Use direct gem push instead of rubygems/release-gem action
47
+ - Complete release workflow implementation
48
+
49
+ ### Miscellaneous Tasks
50
+
51
+ - Add session.md to .gitignore
52
+
53
+ ### Styling
54
+
55
+ - Fix trailing whitespace in bastion proxy files
56
+
57
+ ### Testing
58
+
59
+ - Add nocov markers for Windows-specific PowerShell code
60
+
8
61
  ## [0.7.1] - 2025-06-23
9
62
 
10
63
  ### Added
@@ -26,6 +79,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
26
79
  - Add v0.7.0 to mkdocs and automate nav updates
27
80
  - **coverage**: Properly handle SimpleCov :nocov: markers in analysis
28
81
  - **docs**: Move Security Policy to About section in navigation
82
+ - Resolve RuboCop violations for CI/CD compliance
83
+ - Update release task to handle GitHub Actions gem publishing
84
+ - Resolve final RuboCop issues in release task
29
85
 
30
86
  ### Miscellaneous Tasks
31
87
 
data/README.md CHANGED
@@ -175,11 +175,11 @@ This allows maximum flexibility while providing sensible defaults for common sce
175
175
  | `key_files` | SSH private key files | - | - |
176
176
  | `keys_only` | Use only specified keys | false | - |
177
177
 
178
- **Notes**:
179
- - Cannot specify both `bastion_host` and `proxy_command` simultaneously
180
- - If `bastion_user` not provided, falls back to using main `user` for bastion authentication
181
- - If `bastion_password` not provided, falls back to using main `password` for bastion authentication
182
- - Supports automated password authentication via SSH_ASKPASS mechanism
178
+ !!! note "Important Configuration Notes"
179
+ - Cannot specify both `bastion_host` and `proxy_command` simultaneously
180
+ - If `bastion_user` not provided, falls back to using main `user` for bastion authentication
181
+ - If `bastion_password` not provided, falls back to using main `password` for bastion authentication
182
+ - Supports automated password authentication via SSH_ASKPASS mechanism
183
183
 
184
184
  ### InSpec Configuration File
185
185
 
@@ -280,7 +280,8 @@ Train.create('juniper', {
280
280
 
281
281
  ### Common Authentication Issues
282
282
 
283
- #### ❌ **Error**: "No bastion password specified"
283
+ #### ❌ Error: "No bastion password specified"
284
+
284
285
  **Solution**: Train doesn't have `--bastion-password`. Use one of these patterns:
285
286
  ```bash
286
287
  # Same password for both (most common)
@@ -293,7 +294,8 @@ inspec detect -t "juniper://user@device?bastion_host=jump" --key-files ~/.ssh/id
293
294
  inspec detect -t "juniper://user@device?proxy_command=sshpass%20-p%20jumppass%20ssh%20jumpuser@jump%20-W%20%h:%p" --password "device_pass"
294
295
  ```
295
296
 
296
- #### ❌ **Error**: "Authentication failed"
297
+ #### ❌ Error: "Authentication failed"
298
+
297
299
  **Solutions**:
298
300
  ```bash
299
301
  # Verify bastion connection first
@@ -309,7 +311,8 @@ inspec detect -t "juniper://user@device?bastion_host=jump&proxy_command=ssh%20-v
309
311
  inspec detect -t "juniper://user@device?bastion_host=jump" --password "pass" -l debug
310
312
  ```
311
313
 
312
- #### ❌ **Error**: "Connection timeout"
314
+ #### ❌ Error: "Connection timeout"
315
+
313
316
  **Solutions**:
314
317
  ```bash
315
318
  # Increase timeouts
@@ -349,6 +352,7 @@ result = connection.run_command('show version')
349
352
  ```
350
353
 
351
354
  Mock mode provides:
355
+
352
356
  - ✅ Realistic JunOS command outputs
353
357
  - ✅ Platform detection (JunOS 12.1X47-D15.4)
354
358
  - ✅ Error simulation for negative testing
@@ -393,10 +397,30 @@ This plugin implements the Train Plugin V1 API with:
393
397
  - **Platform** (`lib/train-juniper/platform.rb`) - JunOS platform detection
394
398
  - **Version** (`lib/train-juniper/version.rb`) - Plugin version management
395
399
 
400
+ ### Platform Support
401
+
402
+ This gem supports a wide range of platforms to ensure maximum compatibility:
403
+
404
+ | Platform | Description | Use Case |
405
+ |----------|-------------|----------|
406
+ | `ruby` | Platform-independent | Pure Ruby installations |
407
+ | `x86_64-linux` | Standard Linux | Most Linux servers and CI/CD |
408
+ | `aarch64-linux` | ARM64 Linux | AWS Graviton, Raspberry Pi |
409
+ | `x86_64-linux-musl` | Alpine Linux | Docker containers |
410
+ | `x86_64-darwin` | Intel macOS | Older Mac workstations |
411
+ | `arm64-darwin-*` | Apple Silicon macOS | Modern Mac workstations |
412
+ | `x64-mingw-ucrt` | Windows (UCRT) | Windows 10/11 with modern Ruby ([bastion setup](windows-bastion-setup.md)) |
413
+ | `x86_64-freebsd` | FreeBSD | Network appliances (JunOS heritage) |
414
+ | `x86_64-solaris` | Solaris/illumos | Enterprise environments |
415
+
416
+ !!! note "Platform Compatibility"
417
+ This comprehensive platform support ensures the plugin works wherever InSpec runs, from developer workstations to CI/CD pipelines to production jump hosts. The FreeBSD support is particularly relevant given that JunOS is based on FreeBSD.
418
+
396
419
  ### Documentation
397
420
 
398
421
  - **[Installation Guide](installation.md)** - Complete installation instructions
399
422
  - **[Basic Usage](basic-usage.md)** - Getting started with the plugin
423
+ - **[Windows Bastion Setup](windows-bastion-setup.md)** - Windows bastion/jump host authentication guide
400
424
  - **[Release Process](RELEASE_PROCESS.md)** - How to cut releases and publish gems
401
425
  - **[Project Roadmap](ROADMAP.md)** - Future development plans and contribution opportunities
402
426
 
@@ -407,19 +431,29 @@ This plugin implements the Train Plugin V1 API with:
407
431
 
408
432
  ## Contributing
409
433
 
434
+ We welcome contributions! Here's how to get started:
435
+
410
436
  1. Fork the repository
411
- 2. Create a feature branch
437
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
412
438
  3. Make your changes with tests
413
- 4. Run `bundle exec rake test`
439
+ 4. Run `bundle exec rake test` to ensure tests pass
414
440
  5. Submit a pull request
415
441
 
442
+ Please see our [Contributing Guide](CONTRIBUTING.md) for more details.
443
+
416
444
  ## Support and Contact
417
445
 
446
+ ### General Support
447
+
418
448
  For questions, feature requests, or general support:
449
+
419
450
  - Email: [saf@mitre.org](mailto:saf@mitre.org)
420
451
  - GitHub Issues: [https://github.com/mitre/train-juniper/issues](https://github.com/mitre/train-juniper/issues)
421
452
 
453
+ ### Security Issues
454
+
422
455
  For security issues or vulnerabilities:
456
+
423
457
  - Email: [saf-security@mitre.org](mailto:saf-security@mitre.org)
424
458
  - GitHub Security: [https://github.com/mitre/train-juniper/security](https://github.com/mitre/train-juniper/security)
425
459
 
@@ -1,26 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'train-juniper/constants'
4
+ require 'train-juniper/connection/windows_proxy'
5
+ require 'train-juniper/connection/ssh_askpass'
4
6
 
5
7
  module TrainPlugins
6
8
  module Juniper
7
9
  # Handles bastion host proxy configuration and authentication
8
10
  module BastionProxy
11
+ include WindowsProxy
12
+ include SshAskpass
13
+
9
14
  # Configure bastion proxy for SSH connection
10
15
  # @param ssh_options [Hash] SSH options to modify
11
16
  def configure_bastion_proxy(ssh_options)
12
- require 'net/ssh/proxy/jump' unless defined?(Net::SSH::Proxy::Jump)
13
-
14
- # Build proxy jump string from bastion options
15
17
  bastion_user = @options[:bastion_user] || @options[:user]
16
18
  bastion_port = @options[:bastion_port]
19
+ bastion_password = @options[:bastion_password] || @options[:password]
17
20
 
18
- proxy_jump = if bastion_port == Constants::DEFAULT_SSH_PORT
19
- "#{bastion_user}@#{@options[:bastion_host]}"
20
- else
21
- "#{bastion_user}@#{@options[:bastion_host]}:#{bastion_port}"
22
- end
21
+ # On Windows with password auth, use plink.exe if available
22
+ if Gem.win_platform? && bastion_password && plink_available?
23
+ configure_plink_proxy(ssh_options, bastion_user, bastion_port, bastion_password)
24
+ else
25
+ configure_standard_proxy(ssh_options, bastion_user, bastion_port)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ # Configure standard SSH proxy using Net::SSH::Proxy::Jump
32
+ # @param ssh_options [Hash] SSH options to modify
33
+ # @param bastion_user [String] Username for bastion
34
+ # @param bastion_port [Integer] Port for bastion
35
+ def configure_standard_proxy(ssh_options, bastion_user, bastion_port)
36
+ require 'net/ssh/proxy/jump' unless defined?(Net::SSH::Proxy::Jump)
23
37
 
38
+ proxy_jump = build_proxy_jump_string(bastion_user, bastion_port)
24
39
  @logger.debug("Using bastion host: #{proxy_jump}")
25
40
 
26
41
  # Set up automated password authentication via SSH_ASKPASS
@@ -29,30 +44,35 @@ module TrainPlugins
29
44
  ssh_options[:proxy] = Net::SSH::Proxy::Jump.new(proxy_jump)
30
45
  end
31
46
 
32
- # Set up SSH_ASKPASS for bastion password authentication
33
- def setup_bastion_password_auth
34
- bastion_password = @options[:bastion_password] || @options[:password]
35
- return unless bastion_password
36
-
37
- @ssh_askpass_script = create_ssh_askpass_script(bastion_password)
38
- ENV['SSH_ASKPASS'] = @ssh_askpass_script
39
- ENV['SSH_ASKPASS_REQUIRE'] = 'force'
40
- @logger.debug('Configured SSH_ASKPASS for automated bastion authentication')
47
+ # Configure plink.exe proxy for Windows password authentication
48
+ # @param ssh_options [Hash] SSH options to modify
49
+ # @param bastion_user [String] Username for bastion
50
+ # @param bastion_port [Integer] Port for bastion
51
+ # @param bastion_password [String] Password for bastion
52
+ def configure_plink_proxy(ssh_options, bastion_user, bastion_port, bastion_password)
53
+ require 'net/ssh/proxy/command' unless defined?(Net::SSH::Proxy::Command)
54
+
55
+ proxy_cmd = build_plink_proxy_command(
56
+ @options[:bastion_host],
57
+ bastion_user,
58
+ bastion_port,
59
+ bastion_password
60
+ )
61
+
62
+ @logger.debug('Using plink.exe for bastion proxy')
63
+ ssh_options[:proxy] = Net::SSH::Proxy::Command.new(proxy_cmd)
41
64
  end
42
65
 
43
- # Create temporary SSH_ASKPASS script for automated password authentication
44
- # @param password [String] The password to use
45
- # @return [String] Path to the created script
46
- def create_ssh_askpass_script(password)
47
- require 'tempfile'
48
-
49
- script = Tempfile.new(['ssh_askpass', '.sh'])
50
- script.write("#!/bin/bash\necho '#{password}'\n")
51
- script.close
52
- File.chmod(0o755, script.path)
53
-
54
- @logger.debug("Created SSH_ASKPASS script at #{script.path}")
55
- script.path
66
+ # Build proxy jump string from bastion options
67
+ # @param bastion_user [String] Username for bastion
68
+ # @param bastion_port [Integer] Port for bastion
69
+ # @return [String] Proxy jump string
70
+ def build_proxy_jump_string(bastion_user, bastion_port)
71
+ if bastion_port == Constants::DEFAULT_SSH_PORT
72
+ "#{bastion_user}@#{@options[:bastion_host]}"
73
+ else
74
+ "#{bastion_user}@#{@options[:bastion_host]}:#{bastion_port}"
75
+ end
56
76
  end
57
77
 
58
78
  # Generate SSH proxy command for bastion host using ProxyJump (-J)
@@ -68,11 +88,7 @@ module TrainPlugins
68
88
  end
69
89
 
70
90
  # Use ProxyJump (-J) which handles password authentication properly
71
- jump_host = if bastion_port == Constants::DEFAULT_SSH_PORT
72
- "#{bastion_user}@#{@options[:bastion_host]}"
73
- else
74
- "#{bastion_user}@#{@options[:bastion_host]}:#{bastion_port}"
75
- end
91
+ jump_host = build_proxy_jump_string(bastion_user, bastion_port)
76
92
  args += ['-J', jump_host]
77
93
 
78
94
  # Add SSH keys if specified
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tempfile'
4
+
5
+ module TrainPlugins
6
+ module Juniper
7
+ # SSH_ASKPASS script management for automated password authentication
8
+ module SshAskpass
9
+ # Set up SSH_ASKPASS for bastion password authentication
10
+ def setup_bastion_password_auth
11
+ bastion_password = @options[:bastion_password] || @options[:password]
12
+ return unless bastion_password
13
+
14
+ @ssh_askpass_script = create_ssh_askpass_script(bastion_password)
15
+ ENV['SSH_ASKPASS'] = @ssh_askpass_script
16
+ ENV['SSH_ASKPASS_REQUIRE'] = 'force'
17
+ @logger.debug('Configured SSH_ASKPASS for automated bastion authentication')
18
+ end
19
+
20
+ # Create temporary SSH_ASKPASS script for automated password authentication
21
+ # @param password [String] The password to use
22
+ # @return [String] Path to the created script
23
+ def create_ssh_askpass_script(password)
24
+ if Gem.win_platform?
25
+ create_windows_askpass_script(password)
26
+ else
27
+ create_unix_askpass_script(password)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ # Create Windows PowerShell script for SSH_ASKPASS
34
+ # @param password [String] The password to use
35
+ # @return [String] Path to the wrapper batch file
36
+ def create_windows_askpass_script(password)
37
+ # :nocov:
38
+ # Create Windows PowerShell script
39
+ script = Tempfile.new(['ssh_askpass', '.ps1'])
40
+ # PowerShell handles escaping better, just escape quotes
41
+ escaped_password = password.gsub("'", "''")
42
+ script.write("Write-Output '#{escaped_password}'\r\n")
43
+ script.close
44
+
45
+ # Create a wrapper batch file to execute PowerShell with bypass policy
46
+ wrapper = Tempfile.new(['ssh_askpass_wrapper', '.bat'])
47
+ wrapper.write("@echo off\r\npowershell.exe -ExecutionPolicy Bypass -File \"#{script.path}\"\r\n")
48
+ wrapper.close
49
+
50
+ @logger.debug("Created SSH_ASKPASS PowerShell script at #{script.path} with wrapper at #{wrapper.path}")
51
+ wrapper.path
52
+ # :nocov:
53
+ end
54
+
55
+ # Create Unix shell script for SSH_ASKPASS
56
+ # @param password [String] The password to use
57
+ # @return [String] Path to the created script
58
+ def create_unix_askpass_script(password)
59
+ script = Tempfile.new(['ssh_askpass', '.sh'])
60
+ script.write("#!/bin/bash\necho '#{password}'\n")
61
+ script.close
62
+ File.chmod(0o755, script.path)
63
+
64
+ @logger.debug("Created SSH_ASKPASS script at #{script.path}")
65
+ script.path
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'shellwords'
4
+
5
+ module TrainPlugins
6
+ module Juniper
7
+ # Windows-specific proxy handling using plink.exe
8
+ # This pattern is used by various Ruby projects for Windows SSH support,
9
+ # including hglib.rb (Mercurial) and follows Net::SSH::Proxy::Command patterns
10
+ module WindowsProxy
11
+ # Check if plink.exe is available on Windows
12
+ # @return [Boolean] true if plink.exe is found in PATH
13
+ def plink_available?
14
+ return false unless Gem.win_platform?
15
+
16
+ ENV['PATH'].split(File::PATH_SEPARATOR).any? do |path|
17
+ File.exist?(File.join(path, 'plink.exe'))
18
+ end
19
+ end
20
+
21
+ # Build plink.exe proxy command for Windows bastion authentication
22
+ # @param bastion_host [String] Bastion hostname
23
+ # @param user [String] Username for bastion
24
+ # @param port [Integer] Port for bastion
25
+ # @param password [String] Password for bastion
26
+ # @return [String] Complete plink command string
27
+ def build_plink_proxy_command(bastion_host, user, port, password)
28
+ parts = []
29
+ parts << 'plink.exe'
30
+ parts << '-batch' # Non-interactive mode
31
+ parts << '-ssh' # Force SSH protocol (not telnet)
32
+ parts << '-pw'
33
+ parts << (password.include?(' ') ? "\"#{password}\"" : password)
34
+
35
+ if port && port != 22
36
+ parts << '-P'
37
+ parts << port.to_s
38
+ end
39
+
40
+ parts << "#{user}@#{bastion_host}"
41
+ parts << '-nc'
42
+ parts << '%h:%p' # Netcat mode for proxying
43
+
44
+ parts.join(' ')
45
+ end
46
+ end
47
+ end
48
+ end
@@ -8,6 +8,6 @@
8
8
  module TrainPlugins
9
9
  module Juniper
10
10
  # Version number of the train-juniper plugin
11
- VERSION = '0.7.1'
11
+ VERSION = '0.7.4'
12
12
  end
13
13
  end
@@ -68,8 +68,8 @@ Gem::Specification.new do |spec|
68
68
  spec.add_dependency 'net-ssh', '>= 2.9', '< 8.0'
69
69
 
70
70
  # FFI dependency - required by train-core
71
- # Match InSpec 7's FFI version range for compatibility
72
- spec.add_dependency 'ffi', '>= 1.15.5', '< 1.17.0'
71
+ # Updated to support Ruby 3.3 on Windows (ffi 1.17.x required)
72
+ spec.add_dependency 'ffi', '>= 1.15.5', '< 1.18.0'
73
73
 
74
74
  # Development dependencies
75
75
  spec.add_development_dependency 'bundler', '~> 2.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: train-juniper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - MITRE Corporation
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-23 00:00:00.000000000 Z
11
+ date: 2025-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: train-core
@@ -53,7 +53,7 @@ dependencies:
53
53
  version: 1.15.5
54
54
  - - "<"
55
55
  - !ruby/object:Gem::Version
56
- version: 1.17.0
56
+ version: 1.18.0
57
57
  type: :runtime
58
58
  prerelease: false
59
59
  version_requirements: !ruby/object:Gem::Requirement
@@ -63,7 +63,7 @@ dependencies:
63
63
  version: 1.15.5
64
64
  - - "<"
65
65
  - !ruby/object:Gem::Version
66
- version: 1.17.0
66
+ version: 1.18.0
67
67
  - !ruby/object:Gem::Dependency
68
68
  name: bundler
69
69
  requirement: !ruby/object:Gem::Requirement
@@ -227,8 +227,10 @@ files:
227
227
  - lib/train-juniper/connection/bastion_proxy.rb
228
228
  - lib/train-juniper/connection/command_executor.rb
229
229
  - lib/train-juniper/connection/error_handling.rb
230
+ - lib/train-juniper/connection/ssh_askpass.rb
230
231
  - lib/train-juniper/connection/ssh_session.rb
231
232
  - lib/train-juniper/connection/validation.rb
233
+ - lib/train-juniper/connection/windows_proxy.rb
232
234
  - lib/train-juniper/constants.rb
233
235
  - lib/train-juniper/file_abstraction/juniper_file.rb
234
236
  - lib/train-juniper/helpers/environment.rb