class TestRenderCloudCfg: cmd = [sys.executable, cloud_init_project_dir("tools/render-cloudcfg")] tmpl_path = cloud_init_project_dir("config/cloud.cfg.tmpl") @pytest.mark.parametrize("variant", (DISTRO_VARIANTS)) def test_variant_sets_distro_in_cloud_cfg(self, variant, tmpdir): outfile = tmpdir.join("outcfg").strpath subp.subp(self.cmd + ["--variant", variant, self.tmpl_path, outfile]) with open(outfile) as stream: system_cfg = util.load_yaml(stream.read()) if variant == "unknown": variant = "ubuntu" # Unknown is defaulted to ubuntu assert system_cfg["system_info"]["distro"] == variant @pytest.mark.parametrize("variant", (DISTRO_VARIANTS)) def test_variant_sets_default_user_in_cloud_cfg(self, variant, tmpdir): outfile = tmpdir.join("outcfg").strpath subp.subp(self.cmd + ["--variant", variant, self.tmpl_path, outfile]) with open(outfile) as stream: system_cfg = util.load_yaml(stream.read()) default_user_exceptions = { "amazon": "ec2-user", "debian": "ubuntu", "unknown": "ubuntu", } default_user = system_cfg["system_info"]["default_user"]["name"] assert default_user == default_user_exceptions.get(variant, variant) @pytest.mark.parametrize( "variant,renderers", ( ("freebsd", ["freebsd"]), ("netbsd", ["netbsd"]), ("openbsd", ["openbsd"]), ("ubuntu", ["netplan", "eni", "sysconfig"]), ), ) def test_variant_sets_network_renderer_priority_in_cloud_cfg( self, variant, renderers, tmpdir ): outfile = tmpdir.join("outcfg").strpath subp.subp(self.cmd + ["--variant", variant, self.tmpl_path, outfile]) with open(outfile) as stream: system_cfg = util.load_yaml(stream.read()) assert renderers == system_cfg["system_info"]["network"]["renderers"]
def get_module_variable(var_name) -> dict: """Inspect modules and get variable from module matching var_name""" schemas = {} files = list( Path(cloud_init_project_dir("cloudinit/config/")).glob("cc_*.py") ) modules = [mod.stem for mod in files] for module in modules: importlib.import_module("cloudinit.config.{}".format(module)) for k, v in sys.modules.items(): path = Path(k) if "cloudinit.config" == path.stem and path.suffix[1:4] == "cc_": module_name = path.suffix[1:] members = inspect.getmembers(v) schemas[module_name] = None for name, value in members: if name == var_name: schemas[module_name] = value break return schemas
def _get_meta_doc_examples(): examples_dir = Path(cloud_init_project_dir("doc/examples")) assert examples_dir.is_dir() return ( str(f) for f in examples_dir.glob("cloud-config*.txt") if not f.name.startswith("cloud-config-archive") )
def test_cloud_init_project_dir(self): """Assert cloud_init_project_dir produces an expected location Compare the returned value to an alternate (naive) implementation """ assert (str(Path(self.top_dir, "test")) == test_helpers.cloud_init_project_dir("test") == str( Path(self._get_top_level_dir_alt_implementation(), "test")))
def test_write_etc_hosts_suse_template(self): cfg = { "manage_etc_hosts": "template", "hostname": "cloud-init.test.us", } shutil.copytree( t_help.cloud_init_project_dir("templates"), "%s/etc/cloud/templates" % self.tmp, ) distro = self._fetch_distro("sles") paths = helpers.Paths({}) paths.template_tpl = "%s" % self.tmp + "/etc/cloud/templates/%s.tmpl" ds = None cc = cloud.Cloud(ds, paths, {}, distro, None) self.patchUtils(self.tmp) cc_update_etc_hosts.handle("test", cfg, cc, LOG, []) contents = util.load_file("%s/etc/hosts" % self.tmp) if "127.0.1.1 cloud-init.test.us cloud-init" not in contents: self.assertIsNone("No entry for 127.0.1.1 in etc/hosts") if "::1 cloud-init.test.us cloud-init" not in contents: self.assertIsNone("No entry for 127.0.0.1 in etc/hosts")
import httpretty from cloudinit import util from cloudinit.config import cc_chef from tests.unittests.helpers import ( FilesystemMockingTestCase, HttprettyTestCase, cloud_init_project_dir, mock, skipIf, ) from tests.unittests.util import get_cloud LOG = logging.getLogger(__name__) CLIENT_TEMPL = cloud_init_project_dir("templates/chef_client.rb.tmpl") # This is adjusted to use http because using with https causes issue # in some openssl/httpretty combinations. # https://github.com/gabrielfalcao/HTTPretty/issues/242 # We saw issue in opensuse 42.3 with # httpretty=0.8.8-7.1 ndg-httpsclient=0.4.0-3.2 pyOpenSSL=16.0.0-4.1 OMNIBUS_URL_HTTP = cc_chef.OMNIBUS_URL.replace("https:", "http:") class TestInstallChefOmnibus(HttprettyTestCase): def setUp(self): super(TestInstallChefOmnibus, self).setUp() self.new_root = self.tmp_dir() @mock.patch("cloudinit.config.cc_chef.OMNIBUS_URL", OMNIBUS_URL_HTTP)
def get_module_names() -> List[str]: """Return list of module names in cloudinit/config""" files = list( Path(cloud_init_project_dir("cloudinit/config/")).glob("cc_*.py")) return [mod.stem for mod in files]
class TestGenerateResolvConf: dist = MockDistro() tmpl_fn = t_help.cloud_init_project_dir("templates/resolv.conf.tmpl") @mock.patch("cloudinit.config.cc_resolv_conf.templater.render_to_file") def test_dist_resolv_conf_fn(self, m_render_to_file): self.dist.resolve_conf_fn = "/tmp/resolv-test.conf" generate_resolv_conf(self.tmpl_fn, mock.MagicMock(), self.dist.resolve_conf_fn) assert [mock.call(mock.ANY, self.dist.resolve_conf_fn, mock.ANY)] == m_render_to_file.call_args_list @mock.patch("cloudinit.config.cc_resolv_conf.templater.render_to_file") def test_target_fname_is_used_if_passed(self, m_render_to_file): path = "/use/this/path" generate_resolv_conf(self.tmpl_fn, mock.MagicMock(), path) assert [mock.call(mock.ANY, path, mock.ANY)] == m_render_to_file.call_args_list # Patch in templater so we can assert on the actual generated content @mock.patch("cloudinit.templater.util.write_file") # Parameterise with the value to be passed to generate_resolv_conf as the # params parameter, and the expected line after the header as # expected_extra_line. @pytest.mark.parametrize( "params,expected_extra_line", [ # No options ({}, None), # Just a true flag ({ "options": { "foo": True } }, "options foo"), # Just a false flag ({ "options": { "foo": False } }, None), # Just an option ({ "options": { "foo": "some_value" } }, "options foo:some_value"), # A true flag and an option ( { "options": { "foo": "some_value", "bar": True } }, "options bar foo:some_value", ), # Two options ( { "options": { "foo": "some_value", "bar": "other_value" } }, "options bar:other_value foo:some_value", ), # Everything ( { "options": { "foo": "some_value", "bar": "other_value", "baz": False, "spam": True, } }, "options spam bar:other_value foo:some_value", ), ], ) def test_flags_and_options(self, m_write_file, params, expected_extra_line): target_fn = "/etc/resolv.conf" generate_resolv_conf(self.tmpl_fn, params, target_fn) expected_content = EXPECTED_HEADER if expected_extra_line is not None: # If we have any extra lines, expect a trailing newline expected_content += "\n".join([expected_extra_line, ""]) assert [mock.call(mock.ANY, expected_content, mode=mock.ANY)] == m_write_file.call_args_list
def ConfigFile(path: str): return WrappedConfigFile(cloud_init_project_dir(path))