Skip to content

Commit

Permalink
fix(azure): Reconfigure secondary NICs by removing route to DNS via t…
Browse files Browse the repository at this point in the history
…hem.

As from Bionic, systemd has associated DNS server with secondary NICs,
this causes delay in the DNS resolution from Jammy and forwards. We see
it evidently in the cloud-init logs where resolving the url takes way more
seconds.
  • Loading branch information
CalvoM committed May 8, 2024
1 parent cf72d7f commit 0a06fb5
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 9 deletions.
39 changes: 34 additions & 5 deletions cloudinit/sources/DataSourceAzure.py
Original file line number Diff line number Diff line change
Expand Up @@ -1482,18 +1482,23 @@ def availability_zone(self):
def _generate_network_config(self):
"""Generate network configuration according to configuration."""
# Use IMDS network metadata, if configured.
fxn = add_dhcp_config_for_primary_and_secondary_nics_to_network_config
if (
self._metadata_imds
and self._metadata_imds != sources.UNSET
and self.ds_cfg.get("apply_network_config")
):
try:
return generate_network_config_from_instance_network_metadata(
self._metadata_imds["network"],
apply_network_config_for_secondary_ips=self.ds_cfg.get(
"apply_network_config_for_secondary_ips"
),
netcfg = (
generate_network_config_from_instance_network_metadata(
self._metadata_imds["network"],
apply_network_config_for_secondary_ips=self.ds_cfg.get(
"apply_network_config_for_secondary_ips"
),
)
)
net_cfg = fxn(netcfg)
return net_cfg
except Exception as e:
LOG.error(
"Failed generating network config "
Expand Down Expand Up @@ -1945,6 +1950,30 @@ def load_azure_ds_dir(source_dir):
return (md, ud, cfg, {"ovf-env.xml": contents})


def add_dhcp_config_for_primary_and_secondary_nics_to_network_config(
netconfig: dict,
) -> dict:
"""
Configure the ephemeral and hotplug details.
parameters:
netconfig: dict, Network config details with other ethernet devices.
returns the updated network configuration
"""
netconfig["ethernets"]["primary"] = {
"dhcp4": True,
"match": {"driver": "hv_netvsc", "name": "eth0"},
}
netconfig["ethernets"]["secondary"] = {
"dhcp4": True,
"dhcp4-overrides": {"use-dns": False},
"optional": True,
"match": {"driver": "hv_netvsc", "name": "!eth0"},
}

return netconfig


@azure_ds_telemetry_reporter
def generate_network_config_from_instance_network_metadata(
network_metadata: dict,
Expand Down
45 changes: 44 additions & 1 deletion tests/integration_tests/datasources/test_azure.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import datetime

import pytest
import yaml
from pycloudlib.azure.util import AzureCreateParams, AzureParams
from pycloudlib.cloud import ImageType

from tests.integration_tests.clouds import IntegrationCloud
from tests.integration_tests.conftest import get_validated_source
from tests.integration_tests.instances import IntegrationInstance
from tests.integration_tests.integration_settings import PLATFORM
from tests.integration_tests.releases import CURRENT_RELEASE
from tests.integration_tests.releases import BIONIC, CURRENT_RELEASE


def _check_for_eject_errors(
Expand Down Expand Up @@ -45,3 +49,42 @@ def test_azure_eject(session_cloud: IntegrationCloud):
session_cloud.cloud_instance.delete_image(snapshot_id)
else:
_check_for_eject_errors(instance)


@pytest.mark.skipif(PLATFORM != "azure", reason="Test is Azure specific")
@pytest.mark.skipif(
CURRENT_RELEASE < BIONIC, reason="Easier to test on Bionic+"
)
def test_azure_multi_nic_setup(
setup_image, session_cloud: IntegrationCloud
) -> None:
"""Integration test for https://warthogs.atlassian.net/browse/CPC-3999.
Azure should have the primary NIC only route to DNS.
Ensure other NICs do not have route to DNS.
"""
us = datetime.datetime.now().strftime("%f")
rg_params = AzureParams(f"ci-test-multi-nic-setup-{us}", None)
nic_one = AzureCreateParams(f"ci-nic1-test-{us}", rg_params.name, None)
nic_two = AzureCreateParams(f"ci-nic2-test-{us}", rg_params.name, None)
with session_cloud.launch(
launch_kwargs={
"resource_group_params": rg_params,
"network_interfaces_params": [nic_one, nic_two],
}
) as snapshot_instance:
_check_for_eject_errors(snapshot_instance)
if CURRENT_RELEASE.series == "bionic":
ret = snapshot_instance.execute("systemd-resolve --status")
assert ret.ok, ret.stderr
assert ret.stdout.count("Current Scopes: DNS") == 1
else:
ret = snapshot_instance.execute("resolvectl dns")
assert ret.ok, ret.stderr
routes = yaml.safe_load(ret.stdout)
routes_devices = list(routes.keys())
eth1_dev = [dev for dev in routes_devices if "(eth1)" in dev][0]
assert routes[eth1_dev] is None
# check the instance can resolve something
res = snapshot_instance.execute("resolvectl query google.com")
assert res.ok, res.stderr
46 changes: 43 additions & 3 deletions tests/unittests/sources/test_azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,17 @@ def test_single_ipv4_nic_configuration(
"dhcp6": False,
"match": {"macaddress": "00:0d:3a:04:75:98"},
"set-name": "eth0",
}
},
"primary": {
"dhcp4": True,
"match": {"driver": "hv_netvsc", "name": "eth0"},
},
"secondary": {
"dhcp4": True,
"dhcp4-overrides": {"use-dns": False},
"optional": True,
"match": {"driver": "hv_netvsc", "name": "!eth0"},
},
},
"version": 2,
}
Expand Down Expand Up @@ -1557,7 +1567,17 @@ def test_network_config_set_from_imds(self):
"dhcp6": False,
"dhcp4": True,
"dhcp4-overrides": {"route-metric": 100},
}
},
"primary": {
"dhcp4": True,
"match": {"driver": "hv_netvsc", "name": "eth0"},
},
"secondary": {
"dhcp4": True,
"dhcp4-overrides": {"use-dns": False},
"optional": True,
"match": {"driver": "hv_netvsc", "name": "!eth0"},
},
},
"version": 2,
}
Expand Down Expand Up @@ -1595,6 +1615,16 @@ def test_network_config_set_from_imds_route_metric_for_secondary_nic(self):
"dhcp4": True,
"dhcp4-overrides": {"route-metric": 300},
},
"primary": {
"dhcp4": True,
"match": {"driver": "hv_netvsc", "name": "eth0"},
},
"secondary": {
"dhcp4": True,
"dhcp4-overrides": {"use-dns": False},
"optional": True,
"match": {"driver": "hv_netvsc", "name": "!eth0"},
},
},
"version": 2,
}
Expand Down Expand Up @@ -1626,7 +1656,17 @@ def test_network_config_set_from_imds_for_secondary_nic_no_ip(self):
"dhcp6": False,
"dhcp4": True,
"dhcp4-overrides": {"route-metric": 100},
}
},
"primary": {
"dhcp4": True,
"match": {"driver": "hv_netvsc", "name": "eth0"},
},
"secondary": {
"dhcp4": True,
"dhcp4-overrides": {"use-dns": False},
"optional": True,
"match": {"driver": "hv_netvsc", "name": "!eth0"},
},
},
"version": 2,
}
Expand Down

0 comments on commit 0a06fb5

Please sign in to comment.