From e49998d6237d00c584509281dbae9967e153cb95 Mon Sep 17 00:00:00 2001 From: Jan Bundesmann Date: Fri, 14 Nov 2025 15:58:21 +0100 Subject: [PATCH] feat: Add methods to manage autosign entries for puppet on a SmartProxy (#1376) Co-authored-by: Jan Bundesmann (cherry picked from commit 32df4df478bf1648e490c036d6900f05ce9ad26a) --- nailgun/entities.py | 26 ++++++++++++++++++++++++++ tests/test_entities.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/nailgun/entities.py b/nailgun/entities.py index 5b1b429c..b5289b81 100644 --- a/nailgun/entities.py +++ b/nailgun/entities.py @@ -7773,6 +7773,32 @@ def import_puppetclasses(self, synchronous=True, timeout=None, **kwargs): client.post(path, **kwargs), self._server_config, synchronous, timeout ) + def add_autosign_entry(self, certname, **kwargs): + """Add an entry to the puppetserver's autosign file. + + :param certname: Name the host is going to register with + """ + kwargs = kwargs.copy() + kwargs.update(self._server_config.get_client_kwargs()) + path = f'{self.path()}/autosign' + return _handle_response( + client.post(path, data={'id': certname}, **kwargs), + self._server_config, + ) + + def delete_autosign_entry(self, certname, **kwargs): + """Delete an entry from the puppetserver's autosign file. + + :param certname: Name of the host to be deleted from the autosign file + """ + kwargs = kwargs.copy() + kwargs.update(self._server_config.get_client_kwargs()) + path = f'{self.path()}/autosign/{certname}' + return _handle_response( + client.delete(path, **kwargs), + self._server_config, + ) + def read(self, entity=None, attrs=None, ignore=None, params=None): """Ignore ``download_policy`` field as it's never returned by the server. diff --git a/tests/test_entities.py b/tests/test_entities.py index efbdddcb..db28b6d0 100644 --- a/tests/test_entities.py +++ b/tests/test_entities.py @@ -3443,6 +3443,39 @@ def test_import_puppetclasses(self): if 'environment' in param: self.assertIn('/environments', post.call_args[0][0]) + def test_add_autosign_entry(self): + """Call :meth:`nailgun.entities.SmartProxy.add_autosign_entry`. + + Assert that + * correct fqdn is sent, + * proper path is built. + """ + certname = "host.example.com" + with self.subTest(): + with mock.patch.object(client, 'post') as post: + self.smart_proxy.add_autosign_entry(certname) + self.assertEqual(post.call_count, 1) + self.assertIn(f'{self.smart_proxy.path()}/autosign', post.call_args[0][0]) + self.assertEqual(len(post.call_args[1]), 1) + self.assertEqual(post.call_args[1], {'data': {'id': 'host.example.com'}}) + + def test_delete_autosign_entry(self): + """Call :meth:`nailgun.entities.SmartProxy.add_autosign_entry`. + + Assert that + * correct fqdn is sent, + * proper path is built. + """ + certname = "host.example.com" + with self.subTest(): + with mock.patch.object(client, 'delete') as delete: + self.smart_proxy.delete_autosign_entry(certname) + self.assertEqual(delete.call_count, 1) + self.assertIn( + f'{self.smart_proxy.path()}/autosign/{certname}', delete.call_args[0][0] + ) + self.assertEqual(len(delete.call_args[1]), 0) + class SubscriptionTestCase(TestCase): """Tests for :class:`nailgun.entities.Subscription`."""