diff --git a/patroni/postgresql/config.py b/patroni/postgresql/config.py index bcab56a0..18f5c055 100644 --- a/patroni/postgresql/config.py +++ b/patroni/postgresql/config.py @@ -911,10 +911,12 @@ class ConfigHandler(object): return re.sub(r'([:\\])', r'\\\1', str(value)) # 'host' could be several comma-separated hostnames, in this case we need to write on pgpass line per host - hosts = map(escape, filter(None, map(str.strip, - (record.get('host', '') or '*').split(',')))) # pyright: ignore [reportUnknownArgumentType] + hosts = [escape(host) for host in filter(None, map(str.strip, + (record.get('host', '') or '*').split(',')))] # pyright: ignore [reportUnknownArgumentType] + if any(host.startswith('/') for host in hosts) and 'localhost' not in hosts: + hosts.append('localhost') record = {n: escape(record.get(n) or '*') for n in ('port', 'user', 'password')} - return '\n'.join('{host}:{port}:*:{user}:{password}'.format(**record, host=host) for host in hosts) + return ''.join('{host}:{port}:*:{user}:{password}\n'.format(**record, host=host) for host in hosts) def write_pgpass(self, record: Dict[str, Any]) -> Dict[str, str]: """Maybe creates :attr:`_passfile` based on connection parameters. diff --git a/tests/test_postgresql.py b/tests/test_postgresql.py index 76b51aeb..383c3a3a 100644 --- a/tests/test_postgresql.py +++ b/tests/test_postgresql.py @@ -262,6 +262,10 @@ class TestPostgresql(BaseTestPostgresql): self.p.config.write_pgpass({'host': 'localhost', 'port': '5432', 'user': 'foo'}) self.p.config.write_pgpass({'host': 'localhost', 'port': '5432', 'user': 'foo', 'password': 'bar'}) + def test__pgpass_content(self): + pgpass = self.p.config._pgpass_content({'host': '/tmp', 'port': '5432', 'user': 'foo', 'password': 'bar'}) + self.assertEqual(pgpass, "/tmp:5432:*:foo:bar\nlocalhost:5432:*:foo:bar\n") + def test_checkpoint(self): with patch.object(MockCursor, 'fetchone', Mock(return_value=(True, ))): self.assertEqual(self.p.checkpoint({'user': 'postgres'}), 'is_in_recovery=true')