diff --git a/patroni/api.py b/patroni/api.py index 327cf779..801b36ba 100644 --- a/patroni/api.py +++ b/patroni/api.py @@ -300,8 +300,8 @@ class RestApiHandler(BaseHTTPRequestHandler): members = [m for m in cluster.members if m.name != cluster.leader.name and m.api_url] if not members: return 'failover is not possible: cluster does not have members except leader' - for _, reachable, _, _, tags in self.server.patroni.ha.fetch_nodes_statuses(members): - if reachable and not tags.get('nofailover', False): + for st in self.server.patroni.ha.fetch_nodes_statuses(members): + if st.failover_limitation() is None: return None return 'failover is not possible: no good candidates have been found' diff --git a/patroni/ha.py b/patroni/ha.py index 8d27b6b5..90c7def5 100644 --- a/patroni/ha.py +++ b/patroni/ha.py @@ -26,6 +26,7 @@ class _MemberStatus(namedtuple('_MemberStatus', 'member,reachable,in_recovery,wa in_recovery - `!True` if pg_is_in_recovery() == true wal_position - value of `replayed_location` or `location` from JSON, dependin on its role. tags - dictionary with values of different tags (i.e. nofailover) + watchdog_failed - indicates that watchdog is required by configuration but not available or failed """ @classmethod def from_api_response(cls, member, json): diff --git a/patroni/version.py b/patroni/version.py index 6f4fa58f..72837bdc 100644 --- a/patroni/version.py +++ b/patroni/version.py @@ -1 +1 @@ -__version__ = '1.3' +__version__ = '1.3.1' diff --git a/tests/test_api.py b/tests/test_api.py index 02277c76..37d05ece 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -6,6 +6,7 @@ import unittest from mock import Mock, patch from patroni.api import RestApiHandler, RestApiServer from patroni.dcs import ClusterConfig, Member +from patroni.ha import _MemberStatus from patroni.utils import tzutc from six import BytesIO as IO from six.moves import BaseHTTPServer @@ -38,7 +39,7 @@ class MockPostgresql(object): class MockWatchdog(object): - is_healthy = True + is_healthy = False class MockHa(object): @@ -64,7 +65,7 @@ class MockHa(object): @staticmethod def fetch_nodes_statuses(members): - return [[None, True, None, None, {}]] + return [_MemberStatus(None, True, None, None, {}, False)] @staticmethod def schedule_future_restart(data):