Skip to content

Commit

Permalink
Add support for multiple publish ip addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
phoozle committed Dec 4, 2024
1 parent 0bafa02 commit e597ae6
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
2 changes: 1 addition & 1 deletion lib/kamal/cli/proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def boot

desc "boot_config <set|get|reset>", "Manage kamal-proxy boot configuration"
option :publish, type: :boolean, default: true, desc: "Publish the proxy ports on the host"
option :publish_host_ip, type: :string, desc: "Host IP address to bind HTTP/HTTPS traffic to. Defaults to all interfaces"
option :publish_host_ip, type: :string, repeatable: true, default: nil, desc: "Host IP address to bind HTTP/HTTPS traffic to. Defaults to all interfaces"
option :http_port, type: :numeric, default: Kamal::Configuration::PROXY_HTTP_PORT, desc: "HTTP port to publish on the host"
option :https_port, type: :numeric, default: Kamal::Configuration::PROXY_HTTPS_PORT, desc: "HTTPS port to publish on the host"
option :log_max_size, type: :string, default: Kamal::Configuration::PROXY_LOG_MAX_SIZE, desc: "Max size of proxy logs"
Expand Down
32 changes: 28 additions & 4 deletions lib/kamal/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,16 @@ def env_tag(name)
env_tags.detect { |t| t.name == name.to_s }
end

def proxy_publish_args(http_port, https_port, bind_ip = nil)
publish_http = [ bind_ip, http_port, PROXY_HTTP_PORT ].compact.join(":")
publish_https = [ bind_ip, https_port, PROXY_HTTPS_PORT ].compact.join(":")
argumentize "--publish", [ publish_http, publish_https ]
def proxy_publish_args(http_port, https_port, bind_ips = nil)
ensure_valid_bind_ips(bind_ips)

(bind_ips || [ nil ]).map do |bind_ip|
bind_ip = format_bind_ip(bind_ip)
publish_http = [ bind_ip, http_port, PROXY_HTTP_PORT ].compact.join(":")
publish_https = [ bind_ip, https_port, PROXY_HTTPS_PORT ].compact.join(":")

argumentize "--publish", [ publish_http, publish_https ]
end.join(" ")
end

def proxy_logging_args(max_size)
Expand Down Expand Up @@ -346,6 +352,15 @@ def ensure_valid_kamal_version
true
end

def ensure_valid_bind_ips(bind_ips)
bind_ips.present? && bind_ips.each do |ip|
next if ip =~ Resolv::IPv4::Regex || ip =~ Resolv::IPv6::Regex
raise Kamal::ConfigurationError, "Invalid publish IP address: #{ip}"
end

true
end

def ensure_retain_containers_valid
raise Kamal::ConfigurationError, "Must retain at least 1 container" if retain_containers < 1

Expand Down Expand Up @@ -377,6 +392,15 @@ def ensure_unique_hosts_for_ssl_roles
true
end

def format_bind_ip(ip)
# Ensure IPv6 address inside square brackets - e.g. [::1]
if ip =~ Resolv::IPv6::Regex && ip !~ /\[.*\]/
"[#{ip}]"
else
ip
end
end

def role_names
raw_config.servers.is_a?(Array) ? [ "web" ] : raw_config.servers.keys.sort
end
Expand Down
19 changes: 18 additions & 1 deletion test/cli/proxy_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ class CliProxyTest < CliTestCase
end
end

test "boot_config set custom bind ip" do
test "boot_config set bind IP" do
run_command("boot_config", "set", "--publish-host-ip", "127.0.0.1").tap do |output|
%w[ 1.1.1.1 1.1.1.2 ].each do |host|
assert_match "Running /usr/bin/env mkdir -p .kamal/proxy on #{host}", output
Expand All @@ -290,6 +290,23 @@ class CliProxyTest < CliTestCase
end
end

test "boot_config set multiple bind IPs" do
run_command("boot_config", "set", "--publish-host-ip", "127.0.0.1", "--publish-host-ip", "::1").tap do |output|
%w[ 1.1.1.1 1.1.1.2 ].each do |host|
assert_match "Running /usr/bin/env mkdir -p .kamal/proxy on #{host}", output
assert_match "Uploading \"--publish 127.0.0.1:80:80 --publish 127.0.0.1:443:443 --publish [::1]:80:80 --publish [::1]:443:443 --log-opt max-size=10m\" to .kamal/proxy/options on #{host}", output
end
end
end

test "boot_config set invalid bind IPs" do
exception = assert_raises do
run_command("boot_config", "set", "--publish-host-ip", "1.2.3.invalidIP", "--publish-host-ip", "::1")
end

assert_includes exception.message, "Invalid publish IP address: 1.2.3.invalidIP"
end

test "boot_config set docker options" do
run_command("boot_config", "set", "--docker_options", "label=foo=bar", "add_host=thishost:thathost").tap do |output|
%w[ 1.1.1.1 1.1.1.2 ].each do |host|
Expand Down

0 comments on commit e597ae6

Please sign in to comment.