Skip to content

Commit

Permalink
DataSourceEc2: use metadata's NIC ordering to determine route-metrics (
Browse files Browse the repository at this point in the history
…#342)

We want to set route-metrics such that NICs are configured with the priority that they are given in the network metadata that we receive from the IMDS.  (This switches away from using MAC ordering.)

This also required the following test changes:

* reverse the sort order of the MACs in test data (so that they would trigger the bug being fixed)
* fix up the key names in `NIC2_MD` (which were under_scored instead of dash-separated)
* use a full interface dict (rather than a minimal one) for `TestConvertEc2MetadataNetworkConfig`

LP: #1876312
  • Loading branch information
OddBloke authored May 1, 2020
1 parent 25698b1 commit 70dbccb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 20 deletions.
5 changes: 3 additions & 2 deletions cloudinit/sources/DataSourceEc2.py
Original file line number Diff line number Diff line change
Expand Up @@ -762,13 +762,14 @@ def convert_ec2_metadata_network_config(
netcfg['ethernets'][nic_name] = dev_config
return netcfg
# Apply network config for all nics and any secondary IPv4/v6 addresses
nic_idx = 1
for mac, nic_name in sorted(macs_to_nics.items()):
nic_metadata = macs_metadata.get(mac)
if not nic_metadata:
continue # Not a physical nic represented in metadata
# device-number is zero-indexed, we want it 1-indexed for the
# multiplication on the following line
nic_idx = int(nic_metadata['device-number']) + 1
dhcp_override = {'route-metric': nic_idx * 100}
nic_idx += 1
dev_config = {'dhcp4': True, 'dhcp4-overrides': dhcp_override,
'dhcp6': False,
'match': {'macaddress': mac.lower()},
Expand Down
41 changes: 23 additions & 18 deletions tests/unittests/test_datasource/test_ec2.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
# python3 -c 'import json
# from cloudinit.ec2_utils import get_instance_metadata as gm
# print(json.dumps(gm("2016-09-02"), indent=1, sort_keys=True))'
# Note that the MAC addresses have been modified to sort in the opposite order
# to the device-number attribute, to test LP: #1876312
DEFAULT_METADATA = {
"ami-id": "ami-8b92b4ee",
"ami-launch-index": "0",
Expand Down Expand Up @@ -77,15 +79,15 @@
"vpc-ipv4-cidr-blocks": "172.31.0.0/16",
"vpc-ipv6-cidr-blocks": "2600:1f16:aeb:b200::/56"
},
"06:17:04:d7:26:0A": {
"06:17:04:d7:26:08": {
"device-number": "1", # Only IPv4 local config
"interface-id": "eni-e44ef49f",
"ipv4-associations": {"": "172.3.3.16"},
"ipv6s": "", # No IPv6 config
"local-hostname": ("ip-172-3-3-16.us-east-2."
"compute.internal"),
"local-ipv4s": "172.3.3.16",
"mac": "06:17:04:d7:26:0A",
"mac": "06:17:04:d7:26:08",
"owner-id": "950047163771",
"public-hostname": ("ec2-172-3-3-16.us-east-2."
"compute.amazonaws.com"),
Expand Down Expand Up @@ -152,19 +154,19 @@
}

NIC2_MD = {
"device_number": "1",
"interface_id": "eni-043cdce36ded5e79f",
"local_hostname": "ip-172-31-47-221.us-east-2.compute.internal",
"local_ipv4s": "172.31.47.221",
"device-number": "1",
"interface-id": "eni-043cdce36ded5e79f",
"local-hostname": "ip-172-31-47-221.us-east-2.compute.internal",
"local-ipv4s": "172.31.47.221",
"mac": "0a:75:69:92:e2:16",
"owner_id": "329910648901",
"security_group_ids": "sg-0d68fef37d8cc9b77",
"security_groups": "launch-wizard-17",
"subnet_id": "subnet-9d7ba0d1",
"subnet_ipv4_cidr_block": "172.31.32.0/20",
"vpc_id": "vpc-a07f62c8",
"vpc_ipv4_cidr_block": "172.31.0.0/16",
"vpc_ipv4_cidr_blocks": "172.31.0.0/16"
"owner-id": "329910648901",
"security-group-ids": "sg-0d68fef37d8cc9b77",
"security-groups": "launch-wizard-17",
"subnet-id": "subnet-9d7ba0d1",
"subnet-ipv4-cidr-block": "172.31.32.0/20",
"vpc-id": "vpc-a07f62c8",
"vpc-ipv4-cidr-block": "172.31.0.0/16",
"vpc-ipv4-cidr-blocks": "172.31.0.0/16"
}

SECONDARY_IP_METADATA_2018_09_24 = {
Expand Down Expand Up @@ -423,7 +425,7 @@ def test_network_config_property_set_dhcp4(self):
m_find_fallback.return_value = 'eth9'
ds.get_data()

mac1 = '06:17:04:d7:26:0A' # IPv4 only in DEFAULT_METADATA
mac1 = '06:17:04:d7:26:08' # IPv4 only in DEFAULT_METADATA
expected = {'version': 2, 'ethernets': {'eth9': {
'match': {'macaddress': mac1.lower()}, 'set-name': 'eth9',
'dhcp4': True, 'dhcp6': False}}}
Expand Down Expand Up @@ -790,9 +792,12 @@ class TestConvertEc2MetadataNetworkConfig(test_helpers.CiTestCase):
def setUp(self):
super(TestConvertEc2MetadataNetworkConfig, self).setUp()
self.mac1 = '06:17:04:d7:26:09'
interface_dict = copy.deepcopy(
DEFAULT_METADATA['network']['interfaces']['macs'][self.mac1])
# These tests are written assuming the base interface doesn't have IPv6
interface_dict.pop('ipv6s')
self.network_metadata = {
'interfaces': {'macs': {
self.mac1: {'mac': self.mac1, 'public-ipv4s': '172.31.2.16'}}}}
'interfaces': {'macs': {self.mac1: interface_dict}}}

def test_convert_ec2_metadata_network_config_skips_absent_macs(self):
"""Any mac absent from metadata is skipped by network config."""
Expand Down Expand Up @@ -875,7 +880,7 @@ def test_convert_ec2_metadata_network_config_handles_local_v4_and_v6(self):

def test_convert_ec2_metadata_network_config_handles_multiple_nics(self):
"""DHCP route-metric increases on secondary NICs for IPv4 and IPv6."""
mac2 = '06:17:04:d7:26:0a'
mac2 = '06:17:04:d7:26:08'
macs_to_nics = {self.mac1: 'eth9', mac2: 'eth10'}
network_metadata_both = copy.deepcopy(self.network_metadata)
# Add 2nd nic info
Expand Down

0 comments on commit 70dbccb

Please sign in to comment.