diff --git a/patroni/dcs/kubernetes.py b/patroni/dcs/kubernetes.py index 5cf0367a..2b31e1bc 100644 --- a/patroni/dcs/kubernetes.py +++ b/patroni/dcs/kubernetes.py @@ -950,8 +950,8 @@ class Kubernetes(AbstractDCS): if not self._api.create_namespaced_service(self._namespace, body): return except Exception as e: - if not isinstance(e, k8s_client.rest.ApiException) or e.status != 409 or e.status != 403: - # Service already exists + # 409 - service already exists, 403 - creation forbidden + if not isinstance(e, k8s_client.rest.ApiException) or e.status not in (409, 403): return logger.exception('create_config_service failed') self._should_create_config_service = False diff --git a/tests/test_kubernetes.py b/tests/test_kubernetes.py index fbdd9b67..fe50f4b7 100644 --- a/tests/test_kubernetes.py +++ b/tests/test_kubernetes.py @@ -315,11 +315,32 @@ class TestKubernetesEndpoints(BaseTestKubernetes): @patch.object(k8s_client.CoreV1Api, 'patch_namespaced_pod', mock_namespaced_kind, create=True) @patch.object(k8s_client.CoreV1Api, 'create_namespaced_endpoints', mock_namespaced_kind, create=True) @patch.object(k8s_client.CoreV1Api, 'create_namespaced_service', - Mock(side_effect=[True, False, k8s_client.rest.ApiException(500, '')]), create=True) - def test__create_config_service(self): + Mock(side_effect=[True, + False, + k8s_client.rest.ApiException(409, ''), + k8s_client.rest.ApiException(403, ''), + k8s_client.rest.ApiException(500, ''), + Exception("Unexpected") + ]), create=True) + @patch('patroni.dcs.kubernetes.logger.exception') + def test__create_config_service(self, mock_logger_exception): self.assertIsNotNone(self.k.patch_or_create_config({'foo': 'bar'})) self.assertIsNotNone(self.k.patch_or_create_config({'foo': 'bar'})) + + self.k.patch_or_create_config({'foo': 'bar'}) + mock_logger_exception.assert_not_called() + + self.k.patch_or_create_config({'foo': 'bar'}) + mock_logger_exception.assert_not_called() + + self.k.patch_or_create_config({'foo': 'bar'}) + mock_logger_exception.assert_called_once() + self.assertEqual(('create_config_service failed',), mock_logger_exception.call_args[0]) + mock_logger_exception.reset_mock() + self.k.touch_member({'state': 'running', 'role': 'replica'}) + mock_logger_exception.assert_called_once() + self.assertEqual(('create_config_service failed',), mock_logger_exception.call_args[0]) class TestCacheBuilder(BaseTestKubernetes):