chengxilo opened a new pull request, #3923:
URL: https://github.com/apache/iggy/pull/3923
## Which issue does this PR address?
Closes #3890
## Rationale
A wildcard bind says which interfaces a node accepts on, not where a
client reaches it, so publishing it as an address hands clients a target they
cannot dial.
## What changed?
`node.advertised_address` supplies it, and the server now refuses to start
when server is configured with wildcard bind while leaves it unset.
### **Breaking:**
deployments binding `0.0.0.0` without a roster must declare an address. The
Helm chart can derives it from the Service DNS name and the shipped compose
files name their service; anything else needs `IGGY_NODE_ADVERTISED_ADDRESS`. A
`cluster.nodes` ip must now be a literal IP, and no declared address may be
the unspecified one.
### Some detail regarding new behavior:
<details>
<summary>When would it boot?</summary>
## Standalone (`cluster.enabled = false`)
| `tcp.address` | `node.advertised_address` | Boot | Metadata publishes |
| --- | --- | --- | --- |
| `127.0.0.1:8090` | unset | ✅ | `127.0.0.1` (derived from the bind) |
| `127.0.0.1:8090` | `broker.example.com` | ✅ | `broker.example.com`
(declared wins) |
| `0.0.0.0:8090` | unset | ❌ **rejected** | — |
| `0.0.0.0:8090` | `broker.example.com` | ✅ | `broker.example.com` |
| any | `0.0.0.0` / `::` | ❌ **rejected** | — |
| any | `broker:8090` (carries a port) | ❌ **rejected** | — |
## Cluster (`cluster.enabled = true`)
`tcp.address` only picks the bind interface here — **ports come from the
roster** — so a wildcard is perfectly
normal.
| Roster field | Value | Boot |
| --- | --- | --- |
| `nodes[].ip` | `172.28.0.101` | ✅ |
| `nodes[].ip` | `0.0.0.0` / `::` | ❌ **rejected** |
| `nodes[].ip` | `iggy-server` (any hostname) | ❌ **rejected**, points at
`advertised_address` |
| `advertised_address` | unset | ✅ → publishes `ip` |
| `advertised_address` | `broker.example.com` | ✅ → publishes it |
| `advertised_address` | `0.0.0.0` / `::` | ❌ **rejected** |
| selector `address` | `0.0.0.0` / `::` | ❌ **rejected**, error names the
CIDR |
| `node.advertised_address` | set | ✅ but **ignored**, warns at startup |
Which address a client is told (`advertised_for`):
```
selector matching the client's source IP (longest prefix) →
advertised_address → ip
```
## Both modes
| `tcp.address` | Boot |
| --- | --- |
| `:8090` (empty host) | ❌ **rejected** — Rust's `SocketAddr` has no such
spelling |
| `localhost:8090` (hostname) | ❌ **rejected** — a literal IP is required |
| anything else that does not parse | ❌ **rejected**, one message naming
the fix |
## Edge cases
| Situation | Behavior |
| --- | --- |
| `cluster.enabled = false` with `[[cluster.nodes]]` left behind | Roster
is **neither resolved nor validated** —
boots even if an ip is a hostname |
| A selector whose CIDR does not parse | ❌ rejected (previously dropped in
silence) |
That last row is a side fix: a malformed selector used to be swallowed,
surfacing only as "clients on one network
get the catch-all address" with nothing to debug.
Every ❌ row was verified against a real `iggy-server` binary.
</details>
## Local Execution
- Passed
- Pre-commit hooks ran
## AI Usage
1. Claude Code (Opus)
2. Diagnosis and implementation
3. Reviewed line by line with my best effort. BUT I am not very familiar
with the server side code, so I am not sure if these changes introduce any
side-effect that I didn't notice. According to the changed part, I think it
looks ok.
4. Yes
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]