# internal function that holds the host data. We could store it in a yaml file as well but that would require nushell to read it from disk every single time def hosts [] { [ {{#each cfg.ssh_hosts}} { nu: false name: (non-empty "{{this.name}}") ip: (non-empty "{{this.ip}}") port: (non-empty "{{this.port}}") username: (non-empty "{{this.username}}") mac: (non-empty "{{this.mac}}") } {{/each}} ] } def non-empty [entry: string] { if ($entry | str length) == 0 { null } else { $entry } } def "nu-complete wol" [] { hosts |where mac != '' |get name } def "nu-complete nu" [] { hosts |where nu |get name } def "nu-complete hosts" [] { hosts |get name } def "nu-complete scripts" [] { $nu.scope.commands |where is_custom |get -i command } # Returns ssh connection as url to be consumed by original ssh command def get-url [ host: record ] { if 'ip' in ($host|columns) { echo $"ssh://($host.username)@($host.ip):($host.port)" } else { echo $"ssh://($host.username)@($host.name).($host.domain):($host.port)" } } # Connect over ssh to one of predefined hosts, execute nushell commands and parse them on the host export def ssh [ hostname: string@"nu-complete hosts" # name of the host you want to connect to ...args # commands you wish to run on the host ] { let host = (hosts|where name == $hostname|get -i 0) if $host == null { ^ssh $hostname ...$args } if ($host.nu) { if ($args|length) > 0 { ^ssh (get-url $host) (build-string ($args|str join ' ') '|to json -r')|from json } else { ^ssh (get-url $host) } } else { ^ssh (get-url $host) ...$args } } # Connect over ssh to one of predefined hosts, execute nushell script with arguments passed from the host export def "ssh script" [ hostname: string@"nu-complete nu" # name of the host you want to connect to script: string@"nu-complete scripts" # name of the script ...args # arguments you wish to pass to the script in key=value format ] { let span = (metadata $script).span if $script in ($nu.scope.commands|where is_custom|get command) { let host = (hosts|where name == $hostname|get 0) let full_command = (build-string (view-source $script) '; ' $script ' ' ($args|str join ' ') '|to json -r') ^ssh (get-url $host) ($full_command)|from json } else { error make { msg: $"($script) is not a custom command, use regular ssh command instead" label: { text: "Not a custom command", start: $span.start, end: $span.end } } } } # Turns on specified hosts using Wake on Lan export def wake [ ...names: string@"nu-complete wol" # list of host names to wake ] { hosts |where name in $names |each {|host| if $host.mac != '' { echo $"Waking ($host.name)" wakeonlan $host.mac|ignore } else { error make { msg: $"($host.name) does not support Wake on Lan" } } } }