def test_ntp_conf_contents_match(self):
        """Test rendered contents of /etc/ntp.conf for ubuntu"""
        pools = ['0.mycompany.pool.ntp.org']
        servers = ['192.168.23.3']
        cfg = {
            'ntp': {
                'pools': pools,
                'servers': servers,
            }
        }
        mycloud = self._get_cloud('ubuntu')
        side_effect = [NTP_TEMPLATE.lstrip()]

        # work backwards from util.write_file and mock out call path
        # write_ntp_config_template()
        #   cloud.get_template_filename()
        #     os.path.isfile()
        #   templater.render_to_file()
        #     templater.render_from_file()
        #         util.load_file()
        #     util.write_file()
        #
        with mock.patch.object(util, 'write_file') as mockwrite:
            with mock.patch.object(util, 'load_file', side_effect=side_effect):
                with mock.patch.object(os.path, 'isfile', return_value=True):
                    with mock.patch.object(util, 'rename'):
                        cc_ntp.write_ntp_config_template(
                            cfg.get('ntp'), mycloud)

        mockwrite.assert_called_once_with('/etc/ntp.conf',
                                          NTP_EXPECTED_UBUNTU,
                                          mode=420)
Example #2
0
    def test_ntp_conf_contents_match(self):
        """Test rendered contents of /etc/ntp.conf for ubuntu"""
        pools = ['0.mycompany.pool.ntp.org']
        servers = ['192.168.23.3']
        cfg = {
            'ntp': {
                'pools': pools,
                'servers': servers,
            }
        }
        mycloud = self._get_cloud('ubuntu')
        side_effect = [NTP_TEMPLATE.lstrip()]

        # work backwards from util.write_file and mock out call path
        # write_ntp_config_template()
        #   cloud.get_template_filename()
        #     os.path.isfile()
        #   templater.render_to_file()
        #     templater.render_from_file()
        #         util.load_file()
        #     util.write_file()
        #
        with mock.patch.object(util, 'write_file') as mockwrite:
            with mock.patch.object(util, 'load_file', side_effect=side_effect):
                with mock.patch.object(os.path, 'isfile', return_value=True):
                    with mock.patch.object(util, 'rename'):
                        cc_ntp.write_ntp_config_template(cfg.get('ntp'),
                                                         mycloud)

        mockwrite.assert_called_once_with(
            '/etc/ntp.conf',
            NTP_EXPECTED_UBUNTU,
            mode=420)
 def test_ntp_handler_real_distro_ntp_templates(self):
     """Test ntp handler renders the shipped distro ntp client templates."""
     pools = ['0.mycompany.pool.ntp.org', '3.mycompany.pool.ntp.org']
     servers = ['192.168.23.3', '192.168.23.4']
     for client in ['ntp', 'systemd-timesyncd', 'chrony']:
         for distro in cc_ntp.distros:
             distro_cfg = cc_ntp.distro_ntp_client_configs(distro)
             ntpclient = distro_cfg[client]
             confpath = (
                 os.path.join(self.new_root, ntpclient.get('confpath')[1:]))
             template = ntpclient.get('template_name')
             # find sourcetree template file
             root_dir = (
                 dirname(dirname(os.path.realpath(util.__file__))) +
                 '/templates')
             source_fn = self._get_template_path(template, distro,
                                                 basepath=root_dir)
             template_fn = self._get_template_path(template, distro)
             # don't fail if cloud-init doesn't have a template for
             # a distro,client pair
             if not os.path.exists(source_fn):
                 continue
             # Create a copy in our tmp_dir
             shutil.copy(source_fn, template_fn)
             cc_ntp.write_ntp_config_template(distro, servers=servers,
                                              pools=pools, path=confpath,
                                              template_fn=template_fn)
             content = util.load_file(confpath)
             if client in ['ntp', 'chrony']:
                 content_lines = content.splitlines()
                 expected_servers = self._get_expected_servers(servers,
                                                               distro,
                                                               client)
                 print('distro=%s client=%s' % (distro, client))
                 for sline in expected_servers:
                     self.assertIn(sline, content_lines,
                                   ('failed to render {0} conf'
                                    ' for distro:{1}'.format(client,
                                                             distro)))
                 expected_pools = self._get_expected_pools(pools, distro,
                                                           client)
                 if expected_pools != []:
                     for pline in expected_pools:
                         self.assertIn(pline, content_lines,
                                       ('failed to render {0} conf'
                                        ' for distro:{1}'.format(client,
                                                                 distro)))
             elif client == 'systemd-timesyncd':
                 expected_servers = self._get_expected_servers(servers,
                                                               distro,
                                                               client)
                 expected_pools = self._get_expected_pools(pools,
                                                           distro,
                                                           client)
                 expected_content = (
                     "# cloud-init generated file\n" +
                     "# See timesyncd.conf(5) for details.\n\n" +
                     "[Time]\nNTP=%s %s \n" % (expected_servers,
                                               expected_pools))
                 self.assertEqual(expected_content, content)
Example #4
0
    def test_defaults_pools_empty_lists_sles(self):
        """write_ntp_config_template defaults opensuse pools upon empty config.

        When both pools and servers are empty, default NR_POOL_SERVERS get
        configured.
        """
        distro = "sles"
        default_pools = cc_ntp.generate_server_names(distro)
        (confpath, template_fn) = self._generate_template()

        cc_ntp.write_ntp_config_template(
            distro,
            servers=[],
            pools=[],
            path=confpath,
            template_fn=template_fn,
            template=None,
        )
        for pool in default_pools:
            self.assertIn("opensuse", pool)
        self.assertEqual(
            "servers []\npools {0}\n".format(default_pools),
            util.load_file(confpath),
        )
        self.assertIn(
            "Adding distro default ntp pool servers: {0}".format(
                ",".join(default_pools)),
            self.logs.getvalue(),
        )
 def test_timesyncd_template(self):
     """Test timesycnd template is correct"""
     pools = ['0.mycompany.pool.ntp.org', '3.mycompany.pool.ntp.org']
     servers = ['192.168.23.3', '192.168.23.4']
     (confpath, template_fn) = self._generate_template(
         template=TIMESYNCD_TEMPLATE)
     cc_ntp.write_ntp_config_template('ubuntu',
                                      servers=servers, pools=pools,
                                      path=confpath,
                                      template_fn=template_fn,
                                      template=None)
     self.assertEqual(
         "[Time]\nNTP=%s %s \n" % (" ".join(servers), " ".join(pools)),
         util.load_file(confpath))
Example #6
0
 def test_write_ntp_config_template_uses_ntp_conf_distro_no_servers(self):
     """write_ntp_config_template reads from $client.conf.distro.tmpl"""
     servers = []
     pools = ['10.0.0.1', '10.0.0.2']
     (confpath, template_fn) = self._generate_template()
     mock_path = 'cloudinit.config.cc_ntp.temp_utils._TMPDIR'
     with mock.patch(mock_path, self.new_root):
         cc_ntp.write_ntp_config_template('ubuntu',
                                          servers=servers,
                                          pools=pools,
                                          path=confpath,
                                          template_fn=template_fn,
                                          template=None)
     self.assertEqual("servers []\npools ['10.0.0.1', '10.0.0.2']\n",
                      util.load_file(confpath))
Example #7
0
    def ntp_conf_render(self, distro):
        """ntp_conf_render
        Test rendering of a ntp.conf from template for a given distro
        """

        cfg = {'ntp': {}}
        mycloud = self._get_cloud(distro)
        distro_names = cc_ntp.generate_server_names(distro)

        with mock.patch.object(templater, 'render_to_file') as mocktmpl:
            with mock.patch.object(os.path, 'isfile', return_value=True):
                with mock.patch.object(util, 'rename'):
                    cc_ntp.write_ntp_config_template(cfg, mycloud)

        mocktmpl.assert_called_once_with(
            ('/etc/cloud/templates/ntp.conf.%s.tmpl' % distro),
            '/etc/ntp.conf',
            {'servers': [], 'pools': distro_names})
    def test_write_ntp_config_template_from_ntp_conf_tmpl_with_servers(self):
        """write_ntp_config_template reads content from ntp.conf.tmpl.

        It reads ntp.conf.tmpl if present and renders the value from servers
        key. When no pools key is defined, template is rendered using an empty
        list for pools.
        """
        distro = 'ubuntu'
        cfg = {'servers': ['192.168.2.1', '192.168.2.2']}
        mycloud = self._get_cloud(distro)
        ntp_conf = self.tmp_path("ntp.conf", self.new_root)  # Doesn't exist
        # Create ntp.conf.tmpl
        with open('{0}.tmpl'.format(ntp_conf), 'wb') as stream:
            stream.write(NTP_TEMPLATE)
        with mock.patch('cloudinit.config.cc_ntp.NTP_CONF', ntp_conf):
            cc_ntp.write_ntp_config_template(cfg, mycloud, ntp_conf)
        content = util.read_file_or_url('file://' + ntp_conf).contents
        self.assertEqual("servers ['192.168.2.1', '192.168.2.2']\npools []\n",
                         content.decode())
Example #9
0
    def test_write_ntp_config_template_defaults_pools_w_empty_lists(self):
        """write_ntp_config_template defaults pools servers upon empty config.

        When both pools and servers are empty, default NR_POOL_SERVERS get
        configured.
        """
        distro = 'ubuntu'
        pools = cc_ntp.generate_server_names(distro)
        servers = []
        (confpath, template_fn) = self._generate_template()
        mock_path = 'cloudinit.config.cc_ntp.temp_utils._TMPDIR'
        with mock.patch(mock_path, self.new_root):
            cc_ntp.write_ntp_config_template(distro,
                                             servers=servers,
                                             pools=pools,
                                             path=confpath,
                                             template_fn=template_fn,
                                             template=None)
        self.assertEqual("servers []\npools {0}\n".format(pools),
                         util.load_file(confpath))
    def ntp_conf_render(self, distro):
        """ntp_conf_render
        Test rendering of a ntp.conf from template for a given distro
        """

        cfg = {'ntp': {}}
        mycloud = self._get_cloud(distro)
        distro_names = cc_ntp.generate_server_names(distro)

        with mock.patch.object(templater, 'render_to_file') as mocktmpl:
            with mock.patch.object(os.path, 'isfile', return_value=True):
                with mock.patch.object(util, 'rename'):
                    cc_ntp.write_ntp_config_template(cfg, mycloud)

        mocktmpl.assert_called_once_with(
            ('/etc/cloud/templates/ntp.conf.%s.tmpl' % distro),
            '/etc/ntp.conf', {
                'servers': [],
                'pools': distro_names
            })
Example #11
0
    def test_ntp_conf_custom_pools_and_server(self):
        distro = 'ubuntu'
        pools = ['0.mycompany.pool.ntp.org']
        servers = ['192.168.23.3']
        cfg = {
            'ntp': {
                'pools': pools,
                'servers': servers,
            }
        }
        mycloud = self._get_cloud(distro)

        with mock.patch.object(templater, 'render_to_file') as mocktmpl:
            with mock.patch.object(os.path, 'isfile', return_value=True):
                with mock.patch.object(util, 'rename'):
                    cc_ntp.write_ntp_config_template(cfg.get('ntp'), mycloud)

        mocktmpl.assert_called_once_with(
            ('/etc/cloud/templates/ntp.conf.%s.tmpl' % distro),
            '/etc/ntp.conf',
            {'servers': servers, 'pools': pools})
    def test_write_ntp_config_template_uses_ntp_conf_distro_no_servers(self):
        """write_ntp_config_template reads content from ntp.conf.distro.tmpl.

        It reads ntp.conf.<distro>.tmpl before attempting ntp.conf.tmpl. It
        renders the value from the keys servers and pools. When no
        servers value is present, template is rendered using an empty list.
        """
        distro = 'ubuntu'
        cfg = {'pools': ['10.0.0.1', '10.0.0.2']}
        mycloud = self._get_cloud(distro)
        ntp_conf = self.tmp_path('ntp.conf', self.new_root)  # Doesn't exist
        # Create ntp.conf.tmpl which isn't read
        with open('{0}.tmpl'.format(ntp_conf), 'wb') as stream:
            stream.write(b'NOT READ: ntp.conf.<distro>.tmpl is primary')
        # Create ntp.conf.tmpl.<distro>
        with open('{0}.{1}.tmpl'.format(ntp_conf, distro), 'wb') as stream:
            stream.write(NTP_TEMPLATE)
        with mock.patch('cloudinit.config.cc_ntp.NTP_CONF', ntp_conf):
            cc_ntp.write_ntp_config_template(cfg, mycloud, ntp_conf)
        content = util.read_file_or_url('file://' + ntp_conf).contents
        self.assertEqual("servers []\npools ['10.0.0.1', '10.0.0.2']\n",
                         content.decode())
    def test_ntp_conf_custom_pools_and_server(self):
        distro = 'ubuntu'
        pools = ['0.mycompany.pool.ntp.org']
        servers = ['192.168.23.3']
        cfg = {
            'ntp': {
                'pools': pools,
                'servers': servers,
            }
        }
        mycloud = self._get_cloud(distro)

        with mock.patch.object(templater, 'render_to_file') as mocktmpl:
            with mock.patch.object(os.path, 'isfile', return_value=True):
                with mock.patch.object(util, 'rename'):
                    cc_ntp.write_ntp_config_template(cfg.get('ntp'), mycloud)

        mocktmpl.assert_called_once_with(
            ('/etc/cloud/templates/ntp.conf.%s.tmpl' % distro),
            '/etc/ntp.conf', {
                'servers': servers,
                'pools': pools
            })
    def test_write_ntp_config_template_defaults_pools_empty_lists_sles(self):
        """write_ntp_config_template defaults pools servers upon empty config.

        When both pools and servers are empty, default NR_POOL_SERVERS get
        configured.
        """
        distro = 'sles'
        mycloud = self._get_cloud(distro)
        ntp_conf = self.tmp_path('ntp.conf', self.new_root)  # Doesn't exist
        # Create ntp.conf.tmpl
        with open('{0}.tmpl'.format(ntp_conf), 'wb') as stream:
            stream.write(NTP_TEMPLATE)
        with mock.patch('cloudinit.config.cc_ntp.NTP_CONF', ntp_conf):
            cc_ntp.write_ntp_config_template({}, mycloud, ntp_conf)
        content = util.read_file_or_url('file://' + ntp_conf).contents
        default_pools = [
            "{0}.opensuse.pool.ntp.org".format(x)
            for x in range(0, cc_ntp.NR_POOL_SERVERS)
        ]
        self.assertEqual("servers []\npools {0}\n".format(default_pools),
                         content.decode())
        self.assertIn(
            "Adding distro default ntp pool servers: {0}".format(
                ",".join(default_pools)), self.logs.getvalue())
    def test_ntp_handler_timesyncd(self, m_ntp_install):
        """Test ntp handler configures timesyncd"""
        m_ntp_install.return_value = False
        distro = 'ubuntu'
        cfg = {
            'servers': ['192.168.2.1', '192.168.2.2'],
            'pools': ['0.mypool.org'],
        }
        mycloud = self._get_cloud(distro)
        tsyncd_conf = self.tmp_path("timesyncd.conf", self.new_root)
        # Create timesyncd.conf.tmpl
        template = '{0}.tmpl'.format(tsyncd_conf)
        print(template)
        with open(template, 'wb') as stream:
            stream.write(TIMESYNCD_TEMPLATE)
        with mock.patch('cloudinit.config.cc_ntp.TIMESYNCD_CONF', tsyncd_conf):
            cc_ntp.write_ntp_config_template(cfg,
                                             mycloud,
                                             tsyncd_conf,
                                             template='timesyncd.conf')

        content = util.read_file_or_url('file://' + tsyncd_conf).contents
        self.assertEqual("[Time]\nNTP=192.168.2.1 192.168.2.2 0.mypool.org \n",
                         content.decode())
Example #16
0
    def test_defaults_pools_empty_lists_sles(self):
        """write_ntp_config_template defaults opensuse pools upon empty config.

        When both pools and servers are empty, default NR_POOL_SERVERS get
        configured.
        """
        distro = 'sles'
        default_pools = cc_ntp.generate_server_names(distro)
        (confpath, template_fn) = self._generate_template()

        cc_ntp.write_ntp_config_template(distro,
                                         servers=[],
                                         pools=[],
                                         path=confpath,
                                         template_fn=template_fn,
                                         template=None)
        content = util.read_file_or_url('file://' + confpath).contents
        for pool in default_pools:
            self.assertIn('opensuse', pool)
        self.assertEqual("servers []\npools {0}\n".format(default_pools),
                         content.decode())
        self.assertIn(
            "Adding distro default ntp pool servers: {0}".format(
                ",".join(default_pools)), self.logs.getvalue())