diff options
| -rwxr-xr-x | cloudinit/sources/DataSourceAzure.py | 8 | ||||
| -rw-r--r-- | tests/unittests/test_datasource/test_azure.py | 40 | 
2 files changed, 47 insertions, 1 deletions
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py index 04ff2131..bedf8ea0 100755 --- a/cloudinit/sources/DataSourceAzure.py +++ b/cloudinit/sources/DataSourceAzure.py @@ -1969,6 +1969,7 @@ def _generate_network_config_from_imds_metadata(imds_metadata) -> dict:      netconfig = {'version': 2, 'ethernets': {}}      network_metadata = imds_metadata['network']      for idx, intf in enumerate(network_metadata['interface']): +        has_ip_address = False          # First IPv4 and/or IPv6 address will be obtained via DHCP.          # Any additional IPs of each type will be set as static          # addresses. @@ -1978,6 +1979,11 @@ def _generate_network_config_from_imds_metadata(imds_metadata) -> dict:                        'dhcp6': False}          for addr_type in ('ipv4', 'ipv6'):              addresses = intf.get(addr_type, {}).get('ipAddress', []) +            # If there are no available IP addresses, then we don't +            # want to add this interface to the generated config. +            if not addresses: +                continue +            has_ip_address = True              if addr_type == 'ipv4':                  default_prefix = '24'              else: @@ -1998,7 +2004,7 @@ def _generate_network_config_from_imds_metadata(imds_metadata) -> dict:                  dev_config['addresses'].append(                      '{ip}/{prefix}'.format(                          ip=privateIp, prefix=netPrefix)) -        if dev_config: +        if dev_config and has_ip_address:              mac = ':'.join(re.findall(r'..', intf['macAddress']))              dev_config.update({                  'match': {'macaddress': mac.lower()}, diff --git a/tests/unittests/test_datasource/test_azure.py b/tests/unittests/test_datasource/test_azure.py index e363c1f9..d64b538e 100644 --- a/tests/unittests/test_datasource/test_azure.py +++ b/tests/unittests/test_datasource/test_azure.py @@ -159,6 +159,22 @@ SECONDARY_INTERFACE = {      }  } +SECONDARY_INTERFACE_NO_IP = { +    "macAddress": "220D3A047598", +    "ipv6": { +        "ipAddress": [] +    }, +    "ipv4": { +        "subnet": [ +            { +                "prefix": "24", +                "address": "10.0.1.0" +            } +        ], +        "ipAddress": [] +    } +} +  IMDS_NETWORK_METADATA = {      "interface": [          { @@ -1139,6 +1155,30 @@ scbus-1 on xpt0 bus 0          dsrc.get_data()          self.assertEqual(expected_network_config, dsrc.network_config) +    @mock.patch('cloudinit.sources.DataSourceAzure.device_driver', +                return_value=None) +    def test_network_config_set_from_imds_for_secondary_nic_no_ip( +            self, m_driver): +        """If an IP address is empty then there should no config for it.""" +        sys_cfg = {'datasource': {'Azure': {'apply_network_config': True}}} +        odata = {} +        data = {'ovfcontent': construct_valid_ovf_env(data=odata), +                'sys_cfg': sys_cfg} +        expected_network_config = { +            'ethernets': { +                'eth0': {'set-name': 'eth0', +                         'match': {'macaddress': '00:0d:3a:04:75:98'}, +                         'dhcp6': False, +                         'dhcp4': True, +                         'dhcp4-overrides': {'route-metric': 100}}}, +            'version': 2} +        imds_data = copy.deepcopy(NETWORK_METADATA) +        imds_data['network']['interface'].append(SECONDARY_INTERFACE_NO_IP) +        self.m_get_metadata_from_imds.return_value = imds_data +        dsrc = self._get_ds(data) +        dsrc.get_data() +        self.assertEqual(expected_network_config, dsrc.network_config) +      def test_availability_zone_set_from_imds(self):          """Datasource.availability returns IMDS platformFaultDomain."""          sys_cfg = {'datasource': {'Azure': {'apply_network_config': True}}}  | 
