Skip to content

Commit

Permalink
test(ec2): adopt pycloudlib public ip creation while launching instances
Browse files Browse the repository at this point in the history
  • Loading branch information
aciba90 committed Mar 26, 2024
1 parent 31451ad commit 18eb019
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 146 deletions.
128 changes: 47 additions & 81 deletions tests/integration_tests/modules/test_hotplug.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import contextlib
import time
from collections import namedtuple

Expand Down Expand Up @@ -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")
Expand Down
78 changes: 13 additions & 65 deletions tests/integration_tests/test_networking.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 18eb019

Please sign in to comment.