Skip to content

fix(proxy): validate the loadbalancer key and make true resolvable - #21

Merged
mhenrixon merged 1 commit into
dashfrom
issue-3-validate-loadbalancer-key
Jul 25, 2026
Merged

mhenrixon merged 1 commit into
dashfrom
issue-3-validate-loadbalancer-key

Conversation

@mhenrixon

Copy link
Copy Markdown
Collaborator

Summary

proxy/loadbalancer had no validator entry, so the generic example-based check (loadbalancer: lb.example.com is a String) let anything "stringish" through:

Config Before After
loadbalancer: 123 passed, 123 reached SSHKit as a host proxy/loadbalancer: should be true, false, or a single host
loadbalancer: "" passed, silently fell back to auto-activation rejected
loadbalancer: "lb1,lb2" passed, treated as one host named lb1,lb2 rejected
loadbalancer: true effective_loadbalancer returned true → on(true) and proxy_hosts.include?(true) resolves to the primary role's first host
loadbalancer: false disabled (unchanged) disabled

Changes:

  • lib/kamal/configuration/validator/proxy.rb — validate_loadbalancer!: accepts true/false or a non-blank single-host string (no whitespace, no commas).
  • lib/kamal/configuration/proxy.rb — effective_loadbalancer resolves true to the primary role's first host, via a new primary_role_first_host helper the auto-activation branch also uses.
  • lib/kamal/configuration.rb — ensure_valid_loadbalancer: loadbalancer: true with no servers: (accessories-only) has nothing to resolve to, so it raises at config time instead of silently disabling the loadbalancer.
  • lib/kamal/configuration/docs/proxy.yml — document true/false and that the host may live outside servers:.

Deviation from the issue

The issue asks for the host to be validated as "a host that belongs to a proxy role". That would break the feature's documented primary use case: a dedicated loadbalancer host outside servers: — docs/proxy.yml shows loadbalancer: lb.example.com, test/fixtures/deploy_with_loadbalancer.yml uses it, and loadbalancer_on_proxy_host? exists precisely to branch on whether the host is a proxy host (it picks the load-balancer container name when it isn't). Since a dedicated host is legal and unverifiable from deploy.yml, only the shape can be validated — so this PR validates shape and fixes the one value that was genuinely broken (true).

Closes #3

Test plan

  • bundle exec ruby -Itest test/configuration/proxy_test.rb — 49 runs, 0 failures
  • Full unit suite: only the 7 pre-existing builder/Docker failures (identical on dash, host-arch dependent)
  • bundle exec rubocop --parallel
  • Backwards compatibility: existing loadbalancer: <host> and loadbalancer: false configs are unaffected; deploy_with_loadbalancer*.yml fixtures still pass

## Summary
The dash-only `proxy/loadbalancer` key had no validator entry, so anything
stringish slipped through: `loadbalancer: 123` reached SSHKit as a host, and
`loadbalancer: ""` silently fell back to auto-activation. `loadbalancer: true`
was worse — `effective_loadbalancer` returned the boolean itself, so `on(true)`
and `proxy_hosts.include?(true)` ran with a non-host.

The validator now accepts `true`, `false`, or a single non-blank host string
(rejecting whitespace/comma lists), and `effective_loadbalancer` resolves
`true` to the primary role's first host. An accessories-only config with
`loadbalancer: true` has no host to resolve to, so it raises at config time.

Host membership is deliberately not checked: a dedicated loadbalancer host
outside `servers:` is the documented primary use case (docs/proxy.yml,
deploy_with_loadbalancer.yml), so only the shape can be validated.

## Test Coverage
- `true` resolves to the primary role's first host and enables load balancing
- `false` opts out of auto-activation for a multi-host primary role
- `true` without any servers raises a ConfigurationError
- 123, "", "  ", comma lists and whitespace hosts are rejected
- an array value still reports the generic type error

## Verification
- [x] bundle exec rubocop --parallel passes
- [x] unit tests pass (7 pre-existing builder/Docker failures unrelated, same on dash)

Refs #3
@mhenrixon mhenrixon self-assigned this Jul 25, 2026
@mhenrixon mhenrixon added documentation Improvements or additions to documentation dx Developer experience — agent commands and rules, generators, local tooling labels Jul 25, 2026
@mhenrixon
mhenrixon merged commit 307baec into dash Jul 25, 2026
17 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation dx Developer experience — agent commands and rules, generators, local tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

R1: Validate the loadbalancer: config key

1 participant