"""The NoCloud seed: cloud-init's user-data, meta-data and network-config on an ISO.""" from __future__ import annotations import io import pycdlib import yaml from napalm_vmware.provision.seed import meta_data, network_config, nocloud_iso, user_data class TestUserData: def test_is_a_cloud_config(self): text = user_data({"hostname": "web01", "packages": ["open-vm-tools"]}, None) assert text.startswith("#cloud-config\n") assert yaml.safe_load(text) == {"hostname": "web01", "packages": ["open-vm-tools"]} def test_ssh_keys_are_added_without_duplicates(self): config = {"ssh_authorized_keys": ["ssh-ed25519 AAA a"]} text = user_data(config, ["ssh-ed25519 AAA a", "ssh-ed25519 BBB b"]) assert yaml.safe_load(text)["ssh_authorized_keys"] == [ "ssh-ed25519 AAA a", "ssh-ed25519 BBB b", ] assert config == {"ssh_authorized_keys": ["ssh-ed25519 AAA a"]} # caller's dict untouched def test_meta_data(): assert yaml.safe_load(meta_data("web01", "iid-1")) == { "instance-id": "iid-1", "local-hostname": "web01", } class TestNetworkConfig: def test_dhcp_nics_matched_by_mac(self): cfg = network_config([("00:50:56:aa:bb:cc", True), ("00:50:56:aa:bb:dd", False)]) assert cfg == { "version": 2, "ethernets": { "nic0": {"match": {"macaddress": "00:50:56:aa:bb:cc"}, "dhcp4": True}, }, } def test_no_dhcp_nic_means_no_network_config(self): assert network_config([("00:50:56:aa:bb:cc", False)]) is None def _read(iso: bytes, name: str) -> str: reader = pycdlib.PyCdlib() reader.open_fp(io.BytesIO(iso)) out = io.BytesIO() reader.get_file_from_iso_fp(out, rr_path=f"/{name}") reader.close() return out.getvalue().decode() class TestIso: def test_carries_the_three_files_under_their_cloud_init_names(self): iso = nocloud_iso("#cloud-config\n{}\n", "instance-id: x\n", {"version": 2}) assert _read(iso, "user-data") == "#cloud-config\n{}\n" assert _read(iso, "meta-data") == "instance-id: x\n" assert yaml.safe_load(_read(iso, "network-config")) == {"version": 2} def test_volume_label_is_cidata(self): """cloud-init's NoCloud datasource finds the seed by this label.""" reader = pycdlib.PyCdlib() reader.open_fp(io.BytesIO(nocloud_iso("u", "m", None))) assert reader.pvd.volume_identifier.decode().strip() == "cidata" reader.close() def test_without_network_config(self): reader = pycdlib.PyCdlib() reader.open_fp(io.BytesIO(nocloud_iso("u", "m", None))) names = [ c.rock_ridge.name().decode() for c in reader.list_children(rr_path="/") if c.rock_ridge ] reader.close() assert "network-config" not in names