Repository: zalando/patroni
Pull request #2423 (2022-09-29 06:49:47)

Fix exception handling in create_config_service
The recently updated condition used to produce erroneous exception line in logs

CyberDem0n: :+1:
coveralls: ## Pull Request Test Coverage Report for [Build 3149193808](https://coveralls.io/builds/52859431)

* **1** of **1**   **(100.0%)**  changed or added relevant line in **1** file are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage remained the same at **99.883%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/52859431/badge)](https://coveralls.io/builds/52859431) |
| :-- | --: |
| Change from base [Build 3149188835](https://coveralls.io/builds/52859268): |  0.0% |
| Covered Lines: | 11129 |
| Relevant Lines: | 11142 |

---
##### 💛  - [Coveralls](https://coveralls.io)

hughcapet: 👍 

Patch:
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
 


Test patch:
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):