mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-08-25 14:53:37 +00:00
Fix request URL in failsafe handling logs (#3126)
This commit is contained in:
@@ -260,6 +260,19 @@ class Member(Tags, NamedTuple('Member',
|
||||
ret['user'] = ret.pop('username')
|
||||
return ret
|
||||
|
||||
def get_endpoint_url(self, endpoint: Optional[str] = None) -> str:
|
||||
"""Get URL from member :attr:`~Member.api_url` and endpoint.
|
||||
|
||||
:param endpoint: URL path of REST API.
|
||||
|
||||
:returns: full URL for this REST API.
|
||||
"""
|
||||
url = self.api_url or ''
|
||||
if endpoint:
|
||||
scheme, netloc, _, _, _, _ = urlparse(url)
|
||||
url = urlunparse((scheme, netloc, endpoint, '', '', ''))
|
||||
return url
|
||||
|
||||
@property
|
||||
def api_url(self) -> Optional[str]:
|
||||
"""The ``api_url`` value from :attr:`~Member.data` if defined."""
|
||||
|
||||
+5
-3
@@ -1174,15 +1174,17 @@ class Ha(object):
|
||||
|
||||
:returns: a :class:`_FailsafeResponse` object.
|
||||
"""
|
||||
endpoint = 'failsafe'
|
||||
url = member.get_endpoint_url(endpoint)
|
||||
try:
|
||||
response = self.patroni.request(member, 'post', 'failsafe', data, timeout=2, retries=1)
|
||||
response = self.patroni.request(member, 'post', endpoint, data, timeout=2, retries=1)
|
||||
response_data = response.data.decode('utf-8')
|
||||
logger.info('Got response from %s %s: %s', member.name, member.api_url, response_data)
|
||||
logger.info('Got response from %s %s: %s', member.name, url, response_data)
|
||||
accepted = response.status == 200 and response_data == 'Accepted'
|
||||
# member may return its current received/replayed LSN in the "lsn" header.
|
||||
return _FailsafeResponse(member.name, accepted, parse_int(response.headers.get('lsn')))
|
||||
except Exception as e:
|
||||
logger.warning("Request failed to %s: POST %s (%s)", member.name, member.api_url, e)
|
||||
logger.warning("Request failed to %s: POST %s (%s)", member.name, url, e)
|
||||
return _FailsafeResponse(member.name, False, None)
|
||||
|
||||
def check_failsafe_topology(self) -> bool:
|
||||
|
||||
+1
-5
@@ -2,7 +2,6 @@
|
||||
import json
|
||||
|
||||
from typing import Any, Dict, Optional, Union
|
||||
from urllib.parse import urlparse, urlunparse
|
||||
|
||||
import urllib3
|
||||
|
||||
@@ -164,10 +163,7 @@ class PatroniRequest(object):
|
||||
|
||||
:returns: the response returned upon request.
|
||||
"""
|
||||
url = member.api_url or ''
|
||||
if endpoint:
|
||||
scheme, netloc, _, _, _, _ = urlparse(url)
|
||||
url = urlunparse((scheme, netloc, endpoint, '', '', ''))
|
||||
url = member.get_endpoint_url(endpoint)
|
||||
return self.request(method, url, data, **kwargs)
|
||||
|
||||
|
||||
|
||||
@@ -577,6 +577,23 @@ class TestHa(PostgresInit):
|
||||
self.p.set_role('primary')
|
||||
self.assertEqual(self.ha.update_failsafe({}), 'Running as a leader')
|
||||
|
||||
def test_call_failsafe_member(self):
|
||||
member = Member(0, 'test', 1, {'api_url': 'http://localhost:8011/patroni'})
|
||||
self.ha.patroni.request = Mock()
|
||||
self.ha.patroni.request.return_value.data = b'Accepted'
|
||||
self.ha.patroni.request.return_value.status = 200
|
||||
with patch('patroni.ha.logger.info') as mock_logger:
|
||||
ret = self.ha.call_failsafe_member({}, member)
|
||||
self.assertEqual(mock_logger.call_args_list[0][0], ('Got response from %s %s: %s', 'test', 'http://localhost:8011/failsafe', 'Accepted'))
|
||||
self.assertTrue(ret.accepted)
|
||||
|
||||
e = Exception('request failed')
|
||||
self.ha.patroni.request.side_effect = e
|
||||
with patch('patroni.ha.logger.warning') as mock_logger:
|
||||
ret = self.ha.call_failsafe_member({}, member)
|
||||
self.assertEqual(mock_logger.call_args_list[0][0], ('Request failed to %s: POST %s (%s)', 'test', 'http://localhost:8011/failsafe', e))
|
||||
self.assertFalse(ret.accepted)
|
||||
|
||||
@patch('time.sleep', Mock())
|
||||
def test_bootstrap_from_another_member(self):
|
||||
self.ha.cluster = get_cluster_initialized_with_leader()
|
||||
|
||||
Reference in New Issue
Block a user