From 1f0ed47524a35d7a4c55e4b83d6fad09001ed7f3 Mon Sep 17 00:00:00 2001 From: Ahmad Hassan Date: Fri, 5 Sep 2025 11:15:42 +0500 Subject: [PATCH] ops-sunbeam - Ignore ready check if renew is True in request certificates routine When the secret (holding the certificate and csr) expires, it calls the routine to request new certificates. This check ensures that new certificate generation proceeds when renew was explicitly set to True. Change-Id: Ic6200014db7d6d413f29378205d7d7af9246008b Signed-off-by: Ahmad Hassan --- ops-sunbeam/ops_sunbeam/relation_handlers.py | 2 +- .../unit_tests/test_relation_handlers.py | 84 +++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 ops-sunbeam/tests/unit_tests/test_relation_handlers.py diff --git a/ops-sunbeam/ops_sunbeam/relation_handlers.py b/ops-sunbeam/ops_sunbeam/relation_handlers.py index 4a3f349d..d79042f7 100644 --- a/ops-sunbeam/ops_sunbeam/relation_handlers.py +++ b/ops-sunbeam/ops_sunbeam/relation_handlers.py @@ -1272,7 +1272,7 @@ class TlsCertificatesHandler(RelationHandler): ) return - if self.ready: + if not renew and self.ready: logger.debug("Certificate request already complete.") return diff --git a/ops-sunbeam/tests/unit_tests/test_relation_handlers.py b/ops-sunbeam/tests/unit_tests/test_relation_handlers.py new file mode 100644 index 00000000..41d35d3a --- /dev/null +++ b/ops-sunbeam/tests/unit_tests/test_relation_handlers.py @@ -0,0 +1,84 @@ +# Copyright 2025 Canonical Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Test TestTlsCertificatesHandler for certificate renewals.""" + +from unittest.mock import ( + MagicMock, + PropertyMock, + patch, +) + +import ops_sunbeam.relation_handlers as sunbeam_rhandlers +import ops_sunbeam.test_utils as test_utils + + +class TestTlsCertificatesHandler(test_utils.CharmTestCase): + """Test for the TlsCertificatesHandler class.""" + + PATCHES = [] + + def setUp(self) -> None: + """Set up the test environment.""" + super().setUp(test_utils, self.PATCHES) + + self.mock_charm = MagicMock() + self._pk_patcher = patch.object( + sunbeam_rhandlers.TlsCertificatesHandler, + "setup_private_keys", + return_value=None, + ) + self.addCleanup(self._pk_patcher.stop) + self._pk_patcher.start() + + self.handler = sunbeam_rhandlers.TlsCertificatesHandler( + charm=self.mock_charm, + relation_name="certificates", + callback_f=MagicMock(), + mandatory=True, + ) + self.handler.i_am_allowed = MagicMock(return_value=True) + self.handler.key_names = MagicMock(return_value=["main"]) + self.handler._private_keys = {"main": "key1"} + self.handler.csrs = MagicMock(return_value={"main": "csr1"}) + self.handler.store = MagicMock() + self.handler.store.get_csr.return_value = "old_csr" + self.handler.certificates = MagicMock() + + def test_renewal_flow_with_renew_true(self) -> None: + """Test when renew=True.""" + self.handler._request_certificates(renew=True) + self.assertTrue( + self.handler.certificates.request_certificate_renewal.called, + "Renewal should be triggered when renew=True", + ) + + def test_renewal_flow_with_ready_true_renew_false(self) -> None: + """Test when renew=False and ready=True.""" + with patch.object( + sunbeam_rhandlers.TlsCertificatesHandler, + "ready", + new_callable=PropertyMock, + return_value=True, + ): + self.handler._request_certificates(renew=False) + + self.handler.certificates.request_certificate_renewal.assert_not_called() + self.handler.certificates.request_certificate_creation.assert_not_called() + + +if __name__ == "__main__": + import unittest + + unittest.main()