From 18eb0195412110634da33684df7823158202359e Mon Sep 17 00:00:00 2001 From: Alberto Contreras Date: Tue, 26 Mar 2024 14:32:24 +0100 Subject: [PATCH] test(ec2): adopt pycloudlib public ip creation while launching instances --- .../integration_tests/modules/test_hotplug.py | 128 +++++++----------- tests/integration_tests/test_networking.py | 78 ++--------- 2 files changed, 60 insertions(+), 146 deletions(-) diff --git a/tests/integration_tests/modules/test_hotplug.py b/tests/integration_tests/modules/test_hotplug.py index 3277a7405f23..6f1d40f494a9 100644 --- a/tests/integration_tests/modules/test_hotplug.py +++ b/tests/integration_tests/modules/test_hotplug.py @@ -1,4 +1,3 @@ -import contextlib import time from collections import namedtuple @@ -238,89 +237,56 @@ def test_multi_nic_hotplug(setup_image, session_cloud: IntegrationCloud): """Tests that additional secondary NICs are routable from non-local networks after the hotplug hook is executed when network updates are configured on the HOTPLUG event.""" - ec2 = session_cloud.cloud_instance.client with session_cloud.launch(launch_kwargs={}, user_data=USER_DATA) as client: ips_before = _get_ip_addr(client) - instance_pub_ip = client.instance.ip - secondary_priv_ip = client.instance.add_network_interface() - response = ec2.describe_network_interfaces( - Filters=[ - { - "Name": "private-ip-address", - "Values": [secondary_priv_ip], - }, - ], + secondary_priv_ip = client.instance.add_network_interface( + associate_public_ip=True ) - nic_id = response["NetworkInterfaces"][0]["NetworkInterfaceId"] - - # Create Elastic IP - # Refactor after https://github.com/canonical/pycloudlib/issues/337 is - # completed - allocation = ec2.allocate_address(Domain="vpc") - try: - secondary_pub_ip = allocation["PublicIp"] - association = ec2.associate_address( - AllocationId=allocation["AllocationId"], - NetworkInterfaceId=nic_id, - ) - assert association["ResponseMetadata"]["HTTPStatusCode"] == 200 - - _wait_till_hotplug_complete(client) - - log_content = client.read_from_file("/var/log/cloud-init.log") - verify_clean_log(log_content) - - ips_after_add = _get_ip_addr(client) - - netplan_cfg = client.read_from_file( - "/etc/netplan/50-cloud-init.yaml" - ) - config = yaml.safe_load(netplan_cfg) - new_addition = [ - ip for ip in ips_after_add if ip.ip4 == secondary_priv_ip - ][0] - assert new_addition.interface in config["network"]["ethernets"] - new_nic_cfg = config["network"]["ethernets"][ - new_addition.interface - ] - assert [{"from": secondary_priv_ip, "table": 101}] == new_nic_cfg[ - "routing-policy" - ] - - assert len(ips_after_add) == len(ips_before) + 1 - - # SSH over primary NIC works - subp("nc -w 5 -zv " + instance_pub_ip + " 22", shell=True) - - # THE TEST: SSH over secondary NIC works - subp("nc -w 5 -zv " + secondary_pub_ip + " 22", shell=True) - - # Remove new NIC - client.instance.remove_network_interface(secondary_priv_ip) - _wait_till_hotplug_complete(client, expected_runs=2) - - # SSH over primary NIC works - subp("nc -w 1 -zv " + instance_pub_ip + " 22", shell=True) - - ips_after_remove = _get_ip_addr(client) - assert len(ips_after_remove) == len(ips_before) - assert secondary_priv_ip not in [ip.ip4 for ip in ips_after_remove] - - netplan_cfg = client.read_from_file( - "/etc/netplan/50-cloud-init.yaml" - ) - config = yaml.safe_load(netplan_cfg) - assert new_addition.interface not in config["network"]["ethernets"] - - log_content = client.read_from_file("/var/log/cloud-init.log") - verify_clean_log(log_content) - finally: - with contextlib.suppress(Exception): - ec2.disassociate_address( - AssociationId=association["AssociationId"] - ) - with contextlib.suppress(Exception): - ec2.release_address(AllocationId=allocation["AllocationId"]) + _wait_till_hotplug_complete(client, expected_runs=1) + + log_content = client.read_from_file("/var/log/cloud-init.log") + verify_clean_log(log_content) + + ips_after_add = _get_ip_addr(client) + + netplan_cfg = client.read_from_file("/etc/netplan/50-cloud-init.yaml") + config = yaml.safe_load(netplan_cfg) + new_addition = [ + ip for ip in ips_after_add if ip.ip4 == secondary_priv_ip + ][0] + assert new_addition.interface in config["network"]["ethernets"] + new_nic_cfg = config["network"]["ethernets"][new_addition.interface] + assert [{"from": secondary_priv_ip, "table": 101}] == new_nic_cfg[ + "routing-policy" + ] + + assert len(ips_after_add) == len(ips_before) + 1 + public_ips = client.instance.public_ips + assert len(public_ips) == 2 + + # SSH over all public ips works + for pub_ip in public_ips: + subp("nc -w 5 -zv " + pub_ip + " 22", shell=True) + + # Remove new NIC + client.instance.remove_network_interface(secondary_priv_ip) + _wait_till_hotplug_complete(client, expected_runs=2) + + public_ips = client.instance.public_ips + assert len(public_ips) == 1 + # SSH over primary NIC works + subp("nc -w 1 -zv " + public_ips[0] + " 22", shell=True) + + ips_after_remove = _get_ip_addr(client) + assert len(ips_after_remove) == len(ips_before) + assert secondary_priv_ip not in [ip.ip4 for ip in ips_after_remove] + + netplan_cfg = client.read_from_file("/etc/netplan/50-cloud-init.yaml") + config = yaml.safe_load(netplan_cfg) + assert new_addition.interface not in config["network"]["ethernets"] + + log_content = client.read_from_file("/var/log/cloud-init.log") + verify_clean_log(log_content) @pytest.mark.skipif(CURRENT_RELEASE <= FOCAL, reason="See LP: #2055397") diff --git a/tests/integration_tests/test_networking.py b/tests/integration_tests/test_networking.py index 6c133c33151b..0c4ed11c1349 100644 --- a/tests/integration_tests/test_networking.py +++ b/tests/integration_tests/test_networking.py @@ -310,77 +310,25 @@ def test_ec2_multi_nic_reboot(setup_image, session_cloud: IntegrationCloud): """Tests that additional secondary NICs and secondary IPs on them are routable from non-local networks after a reboot event when network updates are configured on every boot.""" - ec2 = session_cloud.cloud_instance.client with session_cloud.launch(launch_kwargs={}, user_data=USER_DATA) as client: - # Add secondary NIC - secondary_priv_ip_0 = client.instance.add_network_interface() - response = ec2.describe_network_interfaces( - Filters=[ - { - "Name": "private-ip-address", - "Values": [secondary_priv_ip_0], - }, - ], + # Add secondary NIC with two private and public ips + client.instance.add_network_interface( + ipv4_address_count=2, ipv4_public_ip_count=2 ) - nic_id = response["NetworkInterfaces"][0]["NetworkInterfaceId"] - # Add secondary IP to secondary NIC - association_0 = ec2.assign_private_ip_addresses( - NetworkInterfaceId=nic_id, SecondaryPrivateIpAddressCount=1 - ) - assert association_0["ResponseMetadata"]["HTTPStatusCode"] == 200 - secondary_priv_ip_1 = association_0["AssignedPrivateIpAddresses"][0][ - "PrivateIpAddress" - ] - - # Assing elastic IPs - # Refactor after https://github.com/canonical/pycloudlib/issues/337 is - # completed - allocation_0 = ec2.allocate_address(Domain="vpc") - allocation_1 = ec2.allocate_address(Domain="vpc") - try: - secondary_pub_ip_0 = allocation_0["PublicIp"] - secondary_pub_ip_1 = allocation_1["PublicIp"] - association_0 = ec2.associate_address( - AllocationId=allocation_0["AllocationId"], - NetworkInterfaceId=nic_id, - PrivateIpAddress=secondary_priv_ip_0, - ) - assert association_0["ResponseMetadata"]["HTTPStatusCode"] == 200 - association_1 = ec2.associate_address( - AllocationId=allocation_1["AllocationId"], - NetworkInterfaceId=nic_id, - PrivateIpAddress=secondary_priv_ip_1, - ) - assert association_1["ResponseMetadata"]["HTTPStatusCode"] == 200 - - # Reboot to update network config - client.execute("cloud-init clean --logs") - client.restart() + public_ips = client.instance.public_ips + assert len(public_ips) == 3 - log_content = client.read_from_file("/var/log/cloud-init.log") - verify_clean_log(log_content) + # Reboot to update network config + client.execute("cloud-init clean --logs") + client.restart() - # SSH over primary NIC works - instance_pub_ip = client.instance.ip - subp("nc -w 5 -zv " + instance_pub_ip + " 22", shell=True) + log_content = client.read_from_file("/var/log/cloud-init.log") + verify_clean_log(log_content) - # SSH over secondary NIC works - subp("nc -w 5 -zv " + secondary_pub_ip_0 + " 22", shell=True) - subp("nc -w 5 -zv " + secondary_pub_ip_1 + " 22", shell=True) - finally: - with contextlib.suppress(Exception): - ec2.disassociate_address( - AssociationId=association_0["AssociationId"] - ) - with contextlib.suppress(Exception): - ec2.release_address(AllocationId=allocation_0["AllocationId"]) - with contextlib.suppress(Exception): - ec2.disassociate_address( - AssociationId=association_1["AssociationId"] - ) - with contextlib.suppress(Exception): - ec2.release_address(AllocationId=allocation_1["AllocationId"]) + # SSH over primary and secondary NIC works + for ip in public_ips: + subp("nc -w 5 -zv " + ip + " 22", shell=True) @pytest.mark.adhoc # costly instance not available in all regions / azs