Repository: zalando/patroni

Issue:
Patroni fails to completely strip enclosing brackets around IPv6 addresses as part of a list when port is specified
**Describe the bug**
When specifying PostgreSQL listen IPv6 addresses (postgresql.listen) in the Patroni configuration, Patroni fails to strip all enclosing brackets around IPv6 addresses, leaving the leading bracket on the last IPv6 address in the list.

Example:

_/etc/patroni/patroni.yml_:
```
...
postgresql:
  config_dir: /var/lib/pgsql/14/data
  listen: '127.0.0.1, 2001:db8::11, [2001:db8::1:2]:5678'
...
```

Resulting _/var/lib/pgsql/14/data/postgresql.conf_:
```
...
listen_addresses = '127.0.0.1, 2001:db8::11, [2001:db8::1:2'
port = '5678'
...
```

However if only a single IPv6 address is specified, it works correctly:

_/etc/patroni/patroni.yml_:
```
...
postgresql:
  config_dir: /var/lib/pgsql/14/data
  listen: '[2001:db8::1:2]:5678'
...
```

Resulting _/var/lib/pgsql/14/data/postgresql.conf_:
```
...
listen_addresses = 2001:db8::1:2'
port = '5678'
...
```



**To Reproduce**
Steps to reproduce the behavior:
Configure Patroni with postgresql.listen with a list of IPv6 addresses, with the last address in the list being a bracket-enclosed IPv6 address with a port

**Expected behavior**
Patroni should correctly strip all enclosing brackets from IPv6 addresses

**Environment**
- Patroni version: 2.1.3
- PostgreSQL version: 14.1
- DCS (and its version): etcd 3.4.18

**Patroni configuration file**
```
...
postgresql:
  config_dir: /var/lib/pgsql/14/data
  listen: '127.0.0.1, 2001:db8::11, [2001:db8::1:2]:5678'
...
```

**Have you tried to use GitHub issue search?**
Yes


Discussion:
The thing is that PostgreSQL doesn't support IPv6 addresses in square braces.
Patroni may strip them out, but it still be the ugly workaround for the incorrect configuration.
The problem is that if you don't use square brackets, and you want to specify a port, it's ambiguous:

Example:

```
2001:db8::1:5432
```

Does this mean `2001:db8::1` with port `5432` or does it mean `2001:db8::1:5432` with no port specified?

The other option of course (that makes the most sense to me, but breaks backward compatbility) would be to have a separate configuration item (something like `postgresql.port`) for specifying the port, since Postgres doesn't support listening on different ports on multiple addresses anyways. The current configuration method is confusing since it only supports taking a port on the last address in the list, and having a dedicated field for it makes more sense.
Just to clarify, the actual issue is that Patroni doesn't completely strip all the brackets, not that it strips them at all. I've updated the issue title and description to remove the ambiguity
The `postgresql.listen` has the format `host:port` and it is documented. I.e., whatever goes after the latest colon is the port.

If you like, you can open a PR that allows to configure a port separately from the listen address, but I am not sure that it will really improve the config due to ambiguity where to put it: `postgresql.port` vs `postgresql.parameters.port`.

Or, please go ahead and strip all square brackets (but only after splitting hosts by comma).

Resolving patch:
diff --git a/patroni/utils.py b/patroni/utils.py
--- a/patroni/utils.py
+++ b/patroni/utils.py
@@ -362,7 +362,7 @@ def polling_loop(timeout, interval=1):
 def split_host_port(value, default_port):
     t = value.rsplit(':', 1)
     if ':' in t[0]:
-        t[0] = t[0].strip('[]')
+        t[0] = ','.join([h.strip().strip('[]') for h in t[0].split(',')])
     t.append(default_port)
     return t[0], int(t[1])
 


Test patch: