diff --git a/README.md b/README.md index 613981bd..027f954e 100644 --- a/README.md +++ b/README.md @@ -71,10 +71,27 @@ registry: ### Using a different SSH user than root -The default SSH user is root, but you can change it using `ssh_user`: +The default SSH user is root, but you can change it using `ssh/user`: ```yaml -ssh_user: app +ssh: + user: app +``` + +### Using a proxy SSH host + +If you need to connect to server through a proxy host, you can use `ssh/proxy`: + +```yaml +ssh: + proxy: "192.168.0.1" # defaults to root as the user +``` + +Or with specific user: + +```yaml +ssh: + proxy: "app@192.168.0.1" ``` ### Using env variables diff --git a/lib/mrsk/commands/base.rb b/lib/mrsk/commands/base.rb index 7b7d644c..4abd70c1 100644 --- a/lib/mrsk/commands/base.rb +++ b/lib/mrsk/commands/base.rb @@ -9,7 +9,10 @@ module Mrsk::Commands end def run_over_ssh(*command, host:) - "ssh -t #{config.ssh_user}@#{host} '#{command.join(" ")}'" + "ssh".tap do |cmd| + cmd << " -J #{config.ssh_proxy.jump_proxies}" if config.ssh_proxy + cmd << " -t #{config.ssh_user}@#{host} '#{command.join(" ")}'" + end end private diff --git a/lib/mrsk/configuration.rb b/lib/mrsk/configuration.rb index c2dfc188..f5fd2da5 100644 --- a/lib/mrsk/configuration.rb +++ b/lib/mrsk/configuration.rb @@ -3,6 +3,7 @@ require "active_support/core_ext/string/inquiry" require "active_support/core_ext/module/delegation" require "pathname" require "erb" +require "net/ssh/proxy/jump" class Mrsk::Configuration delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :raw_config, allow_nil: true @@ -103,11 +104,22 @@ class Mrsk::Configuration end def ssh_user - raw_config.ssh_user || "root" + if raw_config.ssh.present? + raw_config.ssh["user"] || "root" + else + "root" + end + end + + def ssh_proxy + if raw_config.ssh.present? && raw_config.ssh["proxy"] + Net::SSH::Proxy::Jump.new \ + raw_config.ssh["proxy"].include?("@") ? raw_config.ssh["proxy"] : "root@#{raw_config.ssh["proxy"]}" + end end def ssh_options - { user: ssh_user, auth_methods: [ "publickey" ] } + { user: ssh_user, proxy: ssh_proxy, auth_methods: [ "publickey" ] }.compact end diff --git a/test/commands/app_test.rb b/test/commands/app_test.rb index aaa0e751..f38ca87f 100644 --- a/test/commands/app_test.rb +++ b/test/commands/app_test.rb @@ -110,6 +110,30 @@ class CommandsAppTest < ActiveSupport::TestCase end end + test "run over ssh" do + assert_equal "ssh -t root@1.1.1.1 'ls'", @app.run_over_ssh("ls", host: "1.1.1.1") + end + + test "run over ssh with custom user" do + @app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config.tap { |c| c[:ssh] = { "user" => "app" } }) + assert_equal "ssh -t app@1.1.1.1 'ls'", @app.run_over_ssh("ls", host: "1.1.1.1") + end + + test "run over ssh with proxy" do + @app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config.tap { |c| c[:ssh] = { "proxy" => "2.2.2.2" } }) + assert_equal "ssh -J root@2.2.2.2 -t root@1.1.1.1 'ls'", @app.run_over_ssh("ls", host: "1.1.1.1") + end + + test "run over ssh with proxy user" do + @app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config.tap { |c| c[:ssh] = { "proxy" => "app@2.2.2.2" } }) + assert_equal "ssh -J app@2.2.2.2 -t root@1.1.1.1 'ls'", @app.run_over_ssh("ls", host: "1.1.1.1") + end + + test "run over ssh with custom user with proxy" do + @app = Mrsk::Commands::App.new Mrsk::Configuration.new(@config.tap { |c| c[:ssh] = { "user" => "app", "proxy" => "2.2.2.2" } }) + assert_equal "ssh -J root@2.2.2.2 -t app@1.1.1.1 'ls'", @app.run_over_ssh("ls", host: "1.1.1.1") + end + test "current_container_id" do assert_equal \ diff --git a/test/configuration_test.rb b/test/configuration_test.rb index 5146d516..d4206dfe 100644 --- a/test/configuration_test.rb +++ b/test/configuration_test.rb @@ -139,10 +139,20 @@ class ConfigurationTest < ActiveSupport::TestCase test "ssh options" do assert_equal "root", @config.ssh_options[:user] - config = Mrsk::Configuration.new(@deploy.tap { |c| c[:ssh_user] = "app" }) + config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!(ssh: { "user" => "app" }) }) assert_equal "app", @config.ssh_options[:user] end + test "ssh options with proxy host" do + config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!(ssh: { "proxy" => "1.2.3.4" }) }) + assert_equal "root@1.2.3.4", @config.ssh_options[:proxy].jump_proxies + end + + test "ssh options with proxy host and user" do + config = Mrsk::Configuration.new(@deploy.tap { |c| c.merge!(ssh: { "proxy" => "app@1.2.3.4" }) }) + assert_equal "app@1.2.3.4", @config.ssh_options[:proxy].jump_proxies + end + test "volume_args" do assert_equal ["--volume", "/local/path:/container/path"], @config.volume_args end