From a9cdbb2721b6076ba30f1e3f3bc6c8b220c62b48 Mon Sep 17 00:00:00 2001 From: Adrian Vladu Date: Mon, 2 Dec 2019 18:39:31 +0200 Subject: [PATCH] Implement cloud-config ntp plugin Implemented NTP cloud-config plugin, which requires in the cloud-config userdata the ntp key with the servers and pools subkeys, that will contain the NTP pools / servers. Fixes: https://github.com/cloudbase/cloudbase-init/issues/28 Change-Id: Idf2898616f8fc9a7d47dbcae1d2e86bee1023d71 --- .../cloudconfigplugins/factory.py | 2 + .../cloudconfigplugins/set_ntp.py | 47 ++++++++++++++++++ .../cloudconfigplugins/test_set_ntp.py | 49 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 cloudbaseinit/plugins/common/userdataplugins/cloudconfigplugins/set_ntp.py create mode 100644 cloudbaseinit/tests/plugins/common/userdataplugins/cloudconfigplugins/test_set_ntp.py diff --git a/cloudbaseinit/plugins/common/userdataplugins/cloudconfigplugins/factory.py b/cloudbaseinit/plugins/common/userdataplugins/cloudconfigplugins/factory.py index 1ed26757..6812f2cf 100644 --- a/cloudbaseinit/plugins/common/userdataplugins/cloudconfigplugins/factory.py +++ b/cloudbaseinit/plugins/common/userdataplugins/cloudconfigplugins/factory.py @@ -28,6 +28,8 @@ PLUGINS = { 'cloudconfigplugins.set_hostname.SetHostnamePlugin', 'hostname': 'cloudbaseinit.plugins.common.userdataplugins.' 'cloudconfigplugins.set_hostname.SetHostnamePlugin', + 'ntp': 'cloudbaseinit.plugins.common.userdataplugins.' + 'cloudconfigplugins.set_ntp.SetNtpPlugin', } diff --git a/cloudbaseinit/plugins/common/userdataplugins/cloudconfigplugins/set_ntp.py b/cloudbaseinit/plugins/common/userdataplugins/cloudconfigplugins/set_ntp.py new file mode 100644 index 00000000..f5fcb702 --- /dev/null +++ b/cloudbaseinit/plugins/common/userdataplugins/cloudconfigplugins/set_ntp.py @@ -0,0 +1,47 @@ +# Copyright 2019 Cloudbase Solutions Srl +# +# 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. + +from oslo_log import log as oslo_logging + +from cloudbaseinit.osutils import factory +from cloudbaseinit.plugins.common.userdataplugins.cloudconfigplugins import ( + base +) + +LOG = oslo_logging.getLogger(__name__) + + +class SetNtpPlugin(base.BaseCloudConfigPlugin): + """Change the NTP servers according to the cloud-config userdata. + + Following keys can be present: + + enabled: Whether to enable the NTP changes. Defaults to True. + servers: A list of NTP servers. Defaults to empty list. + pools: A list of NTP pool servers. Defaults to empty list. + + Pools and servers lists are concatenated and applied to the NTP config. + """ + + def process(self, data): + ntp_servers = [] + ntp_servers.extend(data.get('servers', [])) + ntp_servers.extend(data.get('pools', [])) + + if data.get('enabled', True) and ntp_servers: + LOG.info("Changing NTP servers to %s." % ntp_servers) + osutils = factory.get_os_utils() + osutils.set_ntp_client_config(ntp_servers) + + return False diff --git a/cloudbaseinit/tests/plugins/common/userdataplugins/cloudconfigplugins/test_set_ntp.py b/cloudbaseinit/tests/plugins/common/userdataplugins/cloudconfigplugins/test_set_ntp.py new file mode 100644 index 00000000..30ac4889 --- /dev/null +++ b/cloudbaseinit/tests/plugins/common/userdataplugins/cloudconfigplugins/test_set_ntp.py @@ -0,0 +1,49 @@ +# Copyright 2019 Cloudbase Solutions Srl +# +# 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. + +import unittest + +try: + import unittest.mock as mock +except ImportError: + import mock + +from oslo_config import cfg + +from cloudbaseinit.plugins.common.userdataplugins.cloudconfigplugins import ( + set_ntp +) + + +CONF = cfg.CONF + + +class SetNtpPluginTest(unittest.TestCase): + + def setUp(self): + self._set_ntp = set_ntp.SetNtpPlugin() + + @mock.patch('cloudbaseinit.osutils.factory.get_os_utils') + def _test_process(self, mock_data, mock_get_os_utils): + mock_os_util = mock.MagicMock() + mock_os_util.set_ntp_client_config.return_value = True + mock_get_os_utils.return_value = mock_os_util + result_process = self._set_ntp.process(mock_data) + self.assertFalse(result_process) + + def test_process_no_servers(self): + self._test_process({}) + + def test_process_servers_pools(self): + self._test_process({'servers': ['one', 'two'], 'pools': 'one'})