def test_apply_network_config_fallback_freebsd(self): fbsd_distro = self._get_distro('freebsd') # a weak attempt to verify that we don't have an implementation # of _write_network_config or apply_network_config in fbsd now, # which would make this test not actually test the fallback. self.assertRaises( NotImplementedError, fbsd_distro._write_network_config, BASE_NET_CFG) # now run mynetcfg = { 'config': [{"type": "physical", "name": "eth0", "mac_address": "c0:d6:9f:2c:e8:80", "subnets": [{"type": "dhcp"}]}], 'version': 1} rc_conf = '/etc/rc.conf' read_bufs = { rc_conf: 'initial-rc-conf-not-validated', '/etc/resolv.conf': 'initial-resolv-conf-not-validated', } tmpd = self.tmp_dir() populate_dir(tmpd, read_bufs) with self.reRooted(tmpd): with mock.patch("cloudinit.distros.freebsd.util.subp", return_value=('vtnet0', '')): fbsd_distro.apply_network_config(mynetcfg, bring_up=False) results = dir2dict(tmpd) self.assertIn(rc_conf, results) self.assertCfgEquals('ifconfig_vtnet0="DHCP"', results[rc_conf]) self.assertEqual(0o644, get_mode(rc_conf, tmpd))
def test_run_hook_up_creates_dir(self): """If dir does not exist, run_hook should create it.""" subd = self.tmp_path("subdir", self.tmp) nic = 'eth1' dhc.run_hook(nic, 'up', data_d=subd, env=self.ex_env) self.assertEqual(set([nic + ".json"]), set(dir2dict(subd + os.path.sep)))
def test_run_hook_up(self): """Test expected use of run_hook_up.""" nic = 'eth0' dhc.run_hook(nic, 'up', data_d=self.tmp, env=self.ex_env) found = dir2dict(self.tmp + os.path.sep) self.assertEqual([nic + ".json"], list(found.keys())) self.assertEqual(self.expected, json.loads(found[nic + ".json"]))
def test_basic_static(self): """Just the most basic static config. note 'lo' should not be rendered as an interface.""" entries = { 'eth0': { 'auto': True, 'dns-nameservers': ['8.8.8.8'], 'bootproto': 'static', 'address': '10.0.0.2', 'gateway': '10.0.0.1', 'netmask': '255.255.255.0' }, 'lo': { 'auto': True } } target = self.tmp_dir() devs = _render_network(entries, target=target) files = dir2dict(target, prefix=target) self.assertEqual(['eth0'], devs) self.assertEqual( { '/etc/netctl/eth0': '\n'.join([ "Address=10.0.0.2/255.255.255.0", "Connection=ethernet", "DNS=('8.8.8.8')", "Gateway=10.0.0.1", "IP=static", "Interface=eth0", "" ]), '/etc/resolv.conf': 'nameserver 8.8.8.8\n' }, files)
def _apply_and_verify_freebsd(self, apply_fn, config, expected_cfgs=None, bringup=False): if not expected_cfgs: raise ValueError('expected_cfg must not be None') tmpd = None with mock.patch('cloudinit.net.freebsd.available') as m_avail: m_avail.return_value = True with self.reRooted(tmpd) as tmpd: util.ensure_dir('/etc') util.ensure_file('/etc/rc.conf') util.ensure_file('/etc/resolv.conf') apply_fn(config, bringup) results = dir2dict(tmpd) for cfgpath, expected in expected_cfgs.items(): print("----------") print(expected) print("^^^^ expected | rendered VVVVVVV") print(results[cfgpath]) print("----------") self.assertEqual(set(expected.split('\n')), set(results[cfgpath].split('\n'))) self.assertEqual(0o644, get_mode(cfgpath, tmpd))
def test_simple_write_freebsd_from_v2eni(self): fbsd_distro = self._get_distro('freebsd') rc_conf = '/etc/rc.conf' read_bufs = { rc_conf: 'initial-rc-conf-not-validated', '/etc/resolv.conf': 'initial-resolv-conf-not-validated', } tmpd = self.tmp_dir() populate_dir(tmpd, read_bufs) with self.reRooted(tmpd): with mock.patch("cloudinit.distros.freebsd.util.subp", return_value=('vtnet0', '')): fbsd_distro.apply_network(BASE_NET_CFG_FROM_V2, False) results = dir2dict(tmpd) self.assertIn(rc_conf, results) self.assertCfgEquals( dedent('''\ ifconfig_vtnet0="192.168.1.5 netmask 255.255.255.0" ifconfig_vtnet1="DHCP" defaultrouter="192.168.1.254" '''), results[rc_conf]) self.assertEqual(0o644, get_mode(rc_conf, tmpd))
def test_apply_network_config_fallback_freebsd(self): fbsd_distro = self._get_distro('freebsd') # a weak attempt to verify that we don't have an implementation # of _write_network_config or apply_network_config in fbsd now, # which would make this test not actually test the fallback. self.assertRaises( NotImplementedError, fbsd_distro._write_network_config, BASE_NET_CFG) # now run mynetcfg = { 'config': [{"type": "physical", "name": "eth0", "mac_address": "c0:d6:9f:2c:e8:80", "subnets": [{"type": "dhcp"}]}], 'version': 1} rc_conf = '/etc/rc.conf' read_bufs = { rc_conf: 'initial-rc-conf-not-validated', '/etc/resolv.conf': 'initial-resolv-conf-not-validated', } tmpd = self.tmp_dir() populate_dir(tmpd, read_bufs) with self.reRooted(tmpd): with mock.patch("cloudinit.distros.freebsd.util.subp", return_value=('vtnet0', '')): fbsd_distro.apply_network_config(mynetcfg, bring_up=False) results = dir2dict(tmpd) self.assertIn(rc_conf, results) self.assertCfgEquals('ifconfig_vtnet0="DHCP"', results[rc_conf]) self.assertEqual(0o644, get_mode(rc_conf, tmpd))
def test_simple_write_freebsd_from_v2eni(self): fbsd_distro = self._get_distro('freebsd') rc_conf = '/etc/rc.conf' read_bufs = { rc_conf: 'initial-rc-conf-not-validated', '/etc/resolv.conf': 'initial-resolv-conf-not-validated', } tmpd = self.tmp_dir() populate_dir(tmpd, read_bufs) with self.reRooted(tmpd): with mock.patch("cloudinit.distros.freebsd.util.subp", return_value=('vtnet0', '')): fbsd_distro.apply_network(BASE_NET_CFG_FROM_V2, False) results = dir2dict(tmpd) self.assertIn(rc_conf, results) self.assertCfgEquals( dedent('''\ ifconfig_vtnet0="192.168.1.5 netmask 255.255.255.0" ifconfig_vtnet1="DHCP" defaultrouter="192.168.1.254" '''), results[rc_conf]) self.assertEqual(0o644, get_mode(rc_conf, tmpd))
def test_run_hook_up_dhcp4_prefix(self): """Test run_hook filters correctly with older DHCP4_ data.""" nic = 'eth0' dhc.run_hook(nic, 'up', data_d=self.tmp, env=self.ex_env_dhcp4) found = dir2dict(self.tmp + os.path.sep) self.assertEqual([nic + ".json"], list(found.keys())) self.assertEqual(self.expected, json.loads(found[nic + ".json"]))
def test_handle_args(self): """quick test of call to handle_args.""" nic = 'eth0' args = argparse.Namespace(event=dhc.UP, interface=nic) with mock.patch.dict("os.environ", clear=True, values=self.ex_env): dhc.handle_args(dhc.NAME, args, data_d=self.tmp) found = dir2dict(self.tmp + os.path.sep) self.assertEqual([nic + ".json"], list(found.keys())) self.assertEqual(self.expected, json.loads(found[nic + ".json"]))
def test_run_hook_down_deletes(self): """down should delete the created json file.""" nic = 'eth1' populate_dir(self.tmp, { nic + ".json": "{'abcd'}", 'myfile.txt': 'text' }) dhc.run_hook(nic, 'down', data_d=self.tmp, env={'old_host_name': 'x1'}) self.assertEqual(set(['myfile.txt']), set(dir2dict(self.tmp + os.path.sep)))
def _apply_and_verify(self, apply_fn, config, expected_cfgs=None, bringup=False): if not expected_cfgs: raise ValueError('expected_cfg must not be None') tmpd = None with mock.patch('cloudinit.net.sysconfig.available') as m_avail: m_avail.return_value = True with self.reRooted(tmpd) as tmpd: apply_fn(config, bringup) results = dir2dict(tmpd) for cfgpath, expected in expected_cfgs.items(): self.assertCfgEquals(expected, results[cfgpath]) self.assertEqual(0o644, get_mode(cfgpath, tmpd))
def _apply_and_verify(self, apply_fn, config, expected_cfgs=None, bringup=False): if not expected_cfgs: raise ValueError('expected_cfg must not be None') tmpd = None with mock.patch('cloudinit.net.sysconfig.available') as m_avail: m_avail.return_value = True with self.reRooted(tmpd) as tmpd: apply_fn(config, bringup) results = dir2dict(tmpd) for cfgpath, expected in expected_cfgs.items(): self.assertCfgEquals(expected, results[cfgpath]) self.assertEqual(0o644, get_mode(cfgpath, tmpd))
def _apply_and_verify(self, apply_fn, config, expected_cfgs=None, bringup=False): if not expected_cfgs: raise ValueError('expected_cfg must not be None') tmpd = None with mock.patch('cloudinit.net.networkd.available') as m_avail: m_avail.return_value = True with self.reRooted(tmpd) as tmpd: apply_fn(config, bringup) results = dir2dict(tmpd) for cfgpath, expected in expected_cfgs.items(): actual = self.create_conf_dict(results[cfgpath].splitlines()) self.compare_dicts(actual, expected) self.assertEqual(0o644, get_mode(cfgpath, tmpd))
def _apply_and_verify(self, apply_fn, config, expected_cfgs=None, bringup=False, with_netplan=False): if not expected_cfgs: raise ValueError('expected_cfg must not be None') tmpd = None with mock.patch('cloudinit.net.netplan.available', return_value=with_netplan): with self.reRooted(tmpd) as tmpd: apply_fn(config, bringup) results = dir2dict(tmpd) for cfgpath, expected in expected_cfgs.items(): print("----------") print(expected) print("^^^^ expected | rendered VVVVVVV") print(results[cfgpath]) print("----------") self.assertEqual(expected, results[cfgpath]) self.assertEqual(0o644, get_mode(cfgpath, tmpd))
def _apply_and_verify_netplan(self, apply_fn, config, expected_cfgs=None, bringup=False): if not expected_cfgs: raise ValueError('expected_cfg must not be None') tmpd = None with mock.patch('cloudinit.net.netplan.available', return_value=True): with mock.patch("cloudinit.net.netplan.get_devicelist", return_value=self.devlist): with self.reRooted(tmpd) as tmpd: apply_fn(config, bringup) results = dir2dict(tmpd) for cfgpath, expected in expected_cfgs.items(): print("----------") print(expected) print("^^^^ expected | rendered VVVVVVV") print(results[cfgpath]) print("----------") self.assertEqual(expected, results[cfgpath]) self.assertEqual(0o644, get_mode(cfgpath, tmpd))
def test_basic_static(self): """Just the most basic static config. note 'lo' should not be rendered as an interface.""" entries = {'eth0': {'auto': True, 'dns-nameservers': ['8.8.8.8'], 'bootproto': 'static', 'address': '10.0.0.2', 'gateway': '10.0.0.1', 'netmask': '255.255.255.0'}, 'lo': {'auto': True}} target = self.tmp_dir() devs = _render_network(entries, target=target) files = dir2dict(target, prefix=target) self.assertEqual(['eth0'], devs) self.assertEqual( {'/etc/netctl/eth0': '\n'.join([ "Address=10.0.0.2/255.255.255.0", "Connection=ethernet", "DNS=('8.8.8.8')", "Gateway=10.0.0.1", "IP=static", "Interface=eth0", ""]), '/etc/resolv.conf': 'nameserver 8.8.8.8\n'}, files)
def _render_and_read(self, network_config=None, state=None, netplan_path=None, target=None): if target is None: target = self.tmp_dir() os.mkdir("%s/etc" % target) with open("%s/etc/rc.conf" % target, 'a') as fd: fd.write("# dummy rc.conf\n") with open("%s/etc/resolv.conf" % target, 'a') as fd: fd.write("# dummy resolv.conf\n") if network_config: ns = cloudinit.net.network_state.parse_net_config_data( network_config) elif state: ns = state else: raise ValueError("Expected data or state, got neither") renderer = cloudinit.net.freebsd.Renderer() renderer.render_network_state(ns, target=target) return dir2dict(target)
def call(self, rootd=None, mocks=None, func="main", args=None, files=None, policy_dmi=DI_DEFAULT_POLICY, policy_no_dmi=DI_DEFAULT_POLICY_NO_DMI, ec2_strict_id=DI_EC2_STRICT_ID_DEFAULT): if args is None: args = [] if mocks is None: mocks = [] if files is None: files = {} if rootd is None: rootd = self.tmp_dir() unset = '_unset' wrap = self.tmp_path(path="_shwrap", dir=rootd) populate_dir(rootd, files) # DI_DEFAULT_POLICY* are declared always as to not rely # on the default in the code. This is because SRU releases change # the value in the code, and thus tests would fail there. head = [ "DI_MAIN=noop", "DEBUG_LEVEL=2", "DI_LOG=stderr", "PATH_ROOT='%s'" % rootd, ". " + self.dsid_path, 'DI_DEFAULT_POLICY="%s"' % policy_dmi, 'DI_DEFAULT_POLICY_NO_DMI="%s"' % policy_no_dmi, 'DI_EC2_STRICT_ID_DEFAULT="%s"' % ec2_strict_id, "" ] def write_mock(data): ddata = {'out': None, 'err': None, 'ret': 0, 'RET': None} ddata.update(data) for k in ddata: if ddata[k] is None: ddata[k] = unset return SHELL_MOCK_TMPL % ddata mocklines = [] defaults = [ { 'name': 'detect_virt', 'RET': 'none', 'ret': 1 }, { 'name': 'uname', 'out': UNAME_MYSYS }, { 'name': 'blkid', 'out': BLKID_EFI_ROOT }, { 'name': 'ovf_vmware_transport_guestinfo', 'out': 'No value found', 'ret': 1 }, { 'name': 'dmi_decode', 'ret': 1, 'err': 'No dmidecode program. ERROR.' }, ] written = [d['name'] for d in mocks] for data in mocks: mocklines.append(write_mock(data)) for d in defaults: if d['name'] not in written: mocklines.append(write_mock(d)) endlines = [func + ' ' + ' '.join(['"%s"' % s for s in args])] with open(wrap, "w") as fp: fp.write('\n'.join(head + mocklines + endlines) + "\n") rc = 0 try: out, err = util.subp(['sh', '-c', '. %s' % wrap], capture=True) except util.ProcessExecutionError as e: rc = e.exit_code out = e.stdout err = e.stderr cfg = None cfg_out = os.path.join(rootd, 'run/cloud-init/cloud.cfg') if os.path.exists(cfg_out): contents = util.load_file(cfg_out) try: cfg = safeyaml.load(contents) except Exception as e: cfg = {"_INVALID_YAML": contents, "_EXCEPTION": str(e)} return CallReturn(rc, out, err, cfg, dir2dict(rootd))