Skip to content

Instantly share code, notes, and snippets.

@JorisM
Created November 16, 2025 12:18
Show Gist options
  • Select an option

  • Save JorisM/668e5db551349e77ed0a7c45eb4063b3 to your computer and use it in GitHub Desktop.

Select an option

Save JorisM/668e5db551349e77ed0a7c45eb4063b3 to your computer and use it in GitHub Desktop.
#!/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