Created
November 16, 2025 12:18
-
-
Save JorisM/668e5db551349e77ed0a7c45eb4063b3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env nu | |
| # VyOS Configuration Deployment Script with Commit-Confirm Safety | |
| const VYOS_HOST = "192.168.1.189" | |
| const VYOS_USER = "vyos" | |
| const CONFIG_FILE = "config-commands.txt" | |
| const CONFIRM_TIMEOUT = 5 # minutes before auto-rollback | |
| # Deploy VyOS configuration with commit-confirm safety | |
| def main [ | |
| --config-file: string = $CONFIG_FILE # Path to config commands file | |
| --host: string = $VYOS_HOST # VyOS hostname/IP | |
| --user: string = $VYOS_USER # SSH username | |
| --timeout: int = $CONFIRM_TIMEOUT # Confirm timeout in minutes | |
| ] { | |
| print $"(ansi green_bold)Starting VyOS configuration deployment...(ansi reset)" | |
| # Check if config file exists | |
| if not ($config_file | path exists) { | |
| print $"(ansi red_bold)Error: Config file '($config_file)' not found!(ansi reset)" | |
| exit 1 | |
| } | |
| # Load configuration commands | |
| let commands = open $config_file | lines | where $it != "" | str join "\n" | |
| print $"(ansi yellow)Loaded ($commands | lines | length) configuration commands(ansi reset)" | |
| print "" | |
| # Show what will be applied | |
| print $"(ansi cyan)Configuration to apply:(ansi reset)" | |
| print $"(ansi light_gray)----------------------------------------(ansi reset)" | |
| print $commands | |
| print $"(ansi light_gray)----------------------------------------(ansi reset)" | |
| print "" | |
| # Confirm before applying | |
| let proceed = (input $"(ansi yellow)Apply this configuration? [y/N]: (ansi reset)") | |
| if $proceed !~ "(?i)^y(es)?$" { | |
| print $"(ansi red)Deployment cancelled.(ansi reset)" | |
| exit 0 | |
| } | |
| # Apply configuration with commit-confirm | |
| print $"(ansi green)Applying configuration with ($timeout) minute commit-confirm...(ansi reset)" | |
| let ssh_commands = $"configure | |
| ($commands) | |
| commit-confirm ($timeout) | |
| exit | |
| " | |
| try { | |
| $ssh_commands | ssh $"($user)@($host)" | |
| } catch { | |
| print $"(ansi red_bold)Error: Failed to apply configuration!(ansi reset)" | |
| exit 1 | |
| } | |
| print "" | |
| print $"(ansi yellow_bold)⚠️ Configuration applied with commit-confirm!(ansi reset)" | |
| print $"(ansi yellow)Changes will automatically rollback in ($timeout) minutes if not confirmed.(ansi reset)" | |
| print "" | |
| print $"(ansi cyan)Test your configuration now (network, services, etc.)(ansi reset)" | |
| print "" | |
| # Wait for user to test and confirm | |
| let confirm = (input $"(ansi green_bold)Is everything working? Confirm changes? [y/N]: (ansi reset)") | |
| if $confirm =~ "(?i)^y(es)?$" { | |
| # Confirm the changes | |
| print $"(ansi green)Confirming configuration...(ansi reset)" | |
| try { | |
| "configure\nconfirm\nsave\nexit" | ssh $"($user)@($host)" | |
| print $"(ansi green_bold)✓ Configuration confirmed and saved!(ansi reset)" | |
| } catch { | |
| print $"(ansi red_bold)Error: Failed to confirm configuration!(ansi reset)" | |
| print $"(ansi yellow)Changes will auto-rollback in ($timeout) minutes.(ansi reset)" | |
| exit 1 | |
| } | |
| } else { | |
| print $"(ansi yellow)Confirmation skipped - changes will auto-rollback.(ansi reset)" | |
| print $"(ansi cyan)Or SSH in manually and run: 'configure; confirm; save'(ansi reset)" | |
| } | |
| } | |
| # Export current VyOS configuration to local file | |
| def "main export" [ | |
| --output: string = $CONFIG_FILE # Output file path | |
| --host: string = $VYOS_HOST # VyOS hostname/IP | |
| --user: string = $VYOS_USER # SSH username | |
| ] { | |
| print $"(ansi green)Exporting configuration from ($host)...(ansi reset)" | |
| try { | |
| let config = (ssh $"($user)@($host)" "/opt/vyatta/bin/vyatta-op-cmd-wrapper show configuration commands") | |
| $config | save -f $output | |
| print $"(ansi green_bold)✓ Configuration exported to ($output)(ansi reset)" | |
| print $"(ansi cyan) ($config | lines | length) lines exported(ansi reset)" | |
| } catch { | |
| print $"(ansi red_bold)Error: Failed to export configuration!(ansi reset)" | |
| exit 1 | |
| } | |
| } | |
| # Show diff between local config and running VyOS config | |
| def "main diff" [ | |
| --config-file: string = $CONFIG_FILE # Local config file | |
| --host: string = $VYOS_HOST # VyOS hostname/IP | |
| --user: string = $VYOS_USER # SSH username | |
| ] { | |
| print $"(ansi green)Comparing local config with running config...(ansi reset)" | |
| if not ($config_file | path exists) { | |
| print $"(ansi red_bold)Error: Config file '($config_file)' not found!(ansi reset)" | |
| exit 1 | |
| } | |
| # Get remote config | |
| let remote_config = (ssh $"($user)@($host)" "/opt/vyatta/bin/vyatta-op-cmd-wrapper show configuration commands") | |
| let remote_file = $"/tmp/vyos-remote-(random uuid).txt" | |
| $remote_config | save -f $remote_file | |
| # Show diff | |
| print "" | |
| try { | |
| diff -u $remote_file $config_file | lines | each { |line| | |
| if ($line | str starts-with "+") { | |
| print $"(ansi green)($line)(ansi reset)" | |
| } else if ($line | str starts-with "-") { | |
| print $"(ansi red)($line)(ansi reset)" | |
| } else if ($line | str starts-with "@@") { | |
| print $"(ansi cyan)($line)(ansi reset)" | |
| } else { | |
| print $line | |
| } | |
| } | |
| } catch { | |
| print $"(ansi yellow)No differences found or diff not available(ansi reset)" | |
| } | |
| rm $remote_file | |
| } | |
| # Test SSH connection to VyOS | |
| def "main test" [ | |
| --host: string = $VYOS_HOST # VyOS hostname/IP | |
| --user: string = $VYOS_USER # SSH username | |
| ] { | |
| print $"(ansi green)Testing connection to ($user)@($host)...(ansi reset)" | |
| try { | |
| let result = (ssh $"($user)@($host)" "/opt/vyatta/bin/vyatta-op-cmd-wrapper show version | grep Version") | |
| print $"(ansi green_bold)✓ Connection successful!(ansi reset)" | |
| print $"(ansi cyan)($result)(ansi reset)" | |
| } catch { | |
| print $"(ansi red_bold)✗ Connection failed!(ansi reset)" | |
| exit 1 | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment