Merge ~chad.smith/cloud-init:feature/azure-to-network-v2 into cloud-init:master

Proposed by Chad Smith on 2019-08-05
Status: Merged
Approved by: Chad Smith on 2019-08-13
Approved revision: 5106244d7e7105079ec689ca34d93a61b3c8e045
Merge reported by: Server Team CI bot
Merged at revision: not available
Proposed branch: ~chad.smith/cloud-init:feature/azure-to-network-v2
Merge into: cloud-init:master
Diff against target: 330 lines (+130/-39)
6 files modified
cloudinit/net/__init__.py (+11/-20)
cloudinit/net/network_state.py (+8/-4)
cloudinit/net/tests/test_init.py (+10/-9)
cloudinit/sources/DataSourceAzure.py (+6/-1)
tests/unittests/test_datasource/test_azure.py (+58/-1)
tests/unittests/test_net.py (+37/-4)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve on 2019-08-06
Ryan Harper 2019-08-05 Approve on 2019-08-06
Review via email: mp+370970@code.launchpad.net

Commit message

azure/net: generate_fallback_nic emits network v2 config instead of v1

The function generate_fallback_config is used by Azure by default when
not consuming IMDS configuration data. This function is also used by any
datasource which does not implement it's own network config. This simple
fallback configuration sets up dhcp on the most likely NIC. It will now
emit network v2 instead of network v1.

This is a step toward moving all components talking in v2 and allows us
to avoid costly conversions between v1 and v2 for newer distributions
which rely on netplan.

To post a comment you must log in.

PASSED: Continuous integration, rev:850c0d90bdf26f45b5d771e77caee3d32d73ba74
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1026/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1026//rebuild

review: Approve (continuous-integration)
Ryan Harper (raharper) wrote :

One inline question.

2c1cc00... by Chad Smith on 2019-08-06

azure/net: generate_fallback_nic emits network v2 config instead of v1

The function generate_fallback_config is used by Azure by default when
not consuming IMDS configuration data. This function is also used by any
datasource which does not implement it's own network config. This simple
fallback configuration sets up dhcp on the most likely NIC. It will now
emit network v2 instead of network v1.

This is a step toward moving all components talking in v2 and allows us
to avoid costly conversions between v1 and v2 for newer distributions
which rely on netplan.

Ryan Harper (raharper) wrote :

One debugging line needs removing and some questions inline.

Chad Smith (chad.smith) :
Chad Smith (chad.smith) :

FAILED: Continuous integration, rev:9af66a67ecc80685544fd0847884ab7ea6a5d644
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1028/
Executed test runs:
    SUCCESS: Checkout
    FAILED: Unit & Style Tests

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1028//rebuild

review: Needs Fixing (continuous-integration)
5106244... by Chad Smith on 2019-08-06

azure: add route-metric to net config on non-primary dhcp interfaces

To retain default network routes on primary dhcp interface, set the
route-metric to 100 for primary interface and 200+ for any secondary
interfaces. This ensures that any dhcp routes provided by the secondary
nics will not be used as a default route for external bound traffic.

Ryan Harper (raharper) wrote :

That looks nice! One comment on where to set maxDiff, but we can do that separately

review: Approve

FAILED: Continuous integration, rev:805f4718126311bb4f6e9215f7fbfbdce6b0d8b5
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1030/
Executed test runs:
    SUCCESS: Checkout
    FAILED: Unit & Style Tests

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1030//rebuild

review: Needs Fixing (continuous-integration)

PASSED: Continuous integration, rev:5106244d7e7105079ec689ca34d93a61b3c8e045
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1031/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1031//rebuild

review: Approve (continuous-integration)
Chad Smith (chad.smith) wrote :
Download full text (3.8 KiB)

Validated on disco given eth0 (with addtional secondary IP) and eth1 (dhcp secondary NIC)
# QUESTION: am I missing a metric 200 on 10.0.0.8?

ubuntu@SRU-worked-azure:~$ python3 -c 'from cloudinit.sources.DataSourceAzure import get_metadata_from_imds; print(get_metadata_from_imds("eth0", 1))'
{'compute': {'location': 'eastus2', 'name': 'test-sru-disco', 'offer': 'UbuntuServer', 'osType': 'Linux', 'placementGroupId': '', 'platformFaultDomain': '0', 'platformUpdateDomain': '0', 'publisher': 'Canonical', 'resourceGroupName': 'srugroup1', 'sku': '19.04-DAILY', 'subscriptionId': '12aad61c-6de4-4e53-a6c6-5aff52a83777', 'tags': '', 'version': '19.04.201908010', 'vmId': 'b838afe4-23fd-4f34-b66c-622767857444', 'vmScaleSetName': '', 'vmSize': 'Standard_DS1_v2', 'zone': ''}, 'network': {'interface': [{'ipv4': {'ipAddress': [{'privateIpAddress': '10.0.0.5', 'publicIpAddress': '40.84.36.124'}, {'privateIpAddress': '10.0.0.23', 'publicIpAddress': ''}], 'subnet': [{'address': '10.0.0.0', 'prefix': '24'}]}, 'ipv6': {'ipAddress': []}, 'macAddress': '000D3A7B7C34'}, {'ipv4': {'ipAddress': [{'privateIpAddress': '10.0.0.8', 'publicIpAddress': ''}], 'subnet': [{'address': '10.0.0.0', 'prefix': '24'}]}, 'ipv6': {'ipAddress': []}, 'macAddress': '000D3A7B9E10'}]}}
ubuntu@SRU-worked-azure:~$ cat /etc/netplan/50-cloud-init.yaml
# This file is generated from information provided by
# the datasource. Changes to it will not persist across an instance.
# To disable cloud-init's network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        eth0:
            addresses:
            - 10.0.0.23/24
            dhcp4: true
            dhcp4-overrides:
                route-metric: 100
            match:
                macaddress: 00:0d:3a:7b:7c:34
            set-name: eth0
        eth1:
            dhcp4: true
            dhcp4-overrides:
                route-metric: 200
            match:
                macaddress: 00:0d:3a:7b:9e:10
            set-name: eth1
    version: 2
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0d:3a:7b:7c:34 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.23/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.0.0.5/24 brd 10.0.0.255 scope global secondary eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::20d:3aff:fe7b:7c34/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0d:3a:7b:9e:10 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.8/24 brd 10.0.0.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::20d:3aff:fe7b:9e10/64 scope link
       valid_lft forever preferred_lft forever

ubuntu@SRU-worked-azure:~$ ip route show
default via 10.0.0.1 dev eth0 proto dhcp src 10.0.0.5 metric 100
10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.23
10.0.0.0/24 dev eth1 proto kernel scope link src 10.0.0.8
168.63.129.16 via 10.0.0.1 dev eth0 proto dhcp src 10.0.0.5 m...

Read more...

Chad Smith (chad.smith) wrote :

Landing as secondary NICs with unique gateways is not a primary network use-case in Azure. Netplan additional route-metric overrides on secondary NICs has been validated on OpenStack vms where unique gateways per-nic are simpler to setup.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py
index f3cec79..ea707c0 100644
--- a/cloudinit/net/__init__.py
+++ b/cloudinit/net/__init__.py
@@ -265,32 +265,23 @@ def find_fallback_nic(blacklist_drivers=None):
265265
266266
267def generate_fallback_config(blacklist_drivers=None, config_driver=None):267def generate_fallback_config(blacklist_drivers=None, config_driver=None):
268 """Determine which attached net dev is most likely to have a connection and268 """Generate network cfg v2 for dhcp on the NIC most likely connected."""
269 generate network state to run dhcp on that interface"""
270
271 if not config_driver:269 if not config_driver:
272 config_driver = False270 config_driver = False
273271
274 target_name = find_fallback_nic(blacklist_drivers=blacklist_drivers)272 target_name = find_fallback_nic(blacklist_drivers=blacklist_drivers)
275 if target_name:273 if not target_name:
276 target_mac = read_sys_net_safe(target_name, 'address')
277 nconf = {'config': [], 'version': 1}
278 cfg = {'type': 'physical', 'name': target_name,
279 'mac_address': target_mac, 'subnets': [{'type': 'dhcp'}]}
280 # inject the device driver name, dev_id into config if enabled and
281 # device has a valid device driver value
282 if config_driver:
283 driver = device_driver(target_name)
284 if driver:
285 cfg['params'] = {
286 'driver': driver,
287 'device_id': device_devid(target_name),
288 }
289 nconf['config'].append(cfg)
290 return nconf
291 else:
292 # can't read any interfaces addresses (or there are none); give up274 # can't read any interfaces addresses (or there are none); give up
293 return None275 return None
276 target_mac = read_sys_net_safe(target_name, 'address')
277 cfg = {'dhcp4': True, 'set-name': target_name,
278 'match': {'macaddress': target_mac.lower()}}
279 if config_driver:
280 driver = device_driver(target_name)
281 if driver:
282 cfg['match']['driver'] = driver
283 nconf = {'ethernets': {target_name: cfg}, 'version': 2}
284 return nconf
294285
295286
296def extract_physdevs(netcfg):287def extract_physdevs(netcfg):
diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
index 0ca576b..c0c415d 100644
--- a/cloudinit/net/network_state.py
+++ b/cloudinit/net/network_state.py
@@ -596,6 +596,7 @@ class NetworkStateInterpreter(object):
596 eno1:596 eno1:
597 match:597 match:
598 macaddress: 00:11:22:33:44:55598 macaddress: 00:11:22:33:44:55
599 driver: hv_netsvc
599 wakeonlan: true600 wakeonlan: true
600 dhcp4: true601 dhcp4: true
601 dhcp6: false602 dhcp6: false
@@ -631,15 +632,18 @@ class NetworkStateInterpreter(object):
631 'type': 'physical',632 'type': 'physical',
632 'name': cfg.get('set-name', eth),633 'name': cfg.get('set-name', eth),
633 }634 }
634 mac_address = cfg.get('match', {}).get('macaddress', None)635 match = cfg.get('match', {})
636 mac_address = match.get('macaddress', None)
635 if not mac_address:637 if not mac_address:
636 LOG.debug('NetworkState Version2: missing "macaddress" info '638 LOG.debug('NetworkState Version2: missing "macaddress" info '
637 'in config entry: %s: %s', eth, str(cfg))639 'in config entry: %s: %s', eth, str(cfg))
638 phy_cmd.update({'mac_address': mac_address})640 phy_cmd['mac_address'] = mac_address
639641 driver = match.get('driver', None)
642 if driver:
643 phy_cmd['params'] = {'driver': driver}
640 for key in ['mtu', 'match', 'wakeonlan']:644 for key in ['mtu', 'match', 'wakeonlan']:
641 if key in cfg:645 if key in cfg:
642 phy_cmd.update({key: cfg.get(key)})646 phy_cmd[key] = cfg[key]
643647
644 subnets = self._v2_to_v1_ipcfg(cfg)648 subnets = self._v2_to_v1_ipcfg(cfg)
645 if len(subnets) > 0:649 if len(subnets) > 0:
diff --git a/cloudinit/net/tests/test_init.py b/cloudinit/net/tests/test_init.py
index e6e77d7..d2e38f0 100644
--- a/cloudinit/net/tests/test_init.py
+++ b/cloudinit/net/tests/test_init.py
@@ -212,9 +212,9 @@ class TestGenerateFallbackConfig(CiTestCase):
212 mac = 'aa:bb:cc:aa:bb:cc'212 mac = 'aa:bb:cc:aa:bb:cc'
213 write_file(os.path.join(self.sysdir, 'eth1', 'address'), mac)213 write_file(os.path.join(self.sysdir, 'eth1', 'address'), mac)
214 expected = {214 expected = {
215 'config': [{'type': 'physical', 'mac_address': mac,215 'ethernets': {'eth1': {'match': {'macaddress': mac},
216 'name': 'eth1', 'subnets': [{'type': 'dhcp'}]}],216 'dhcp4': True, 'set-name': 'eth1'}},
217 'version': 1}217 'version': 2}
218 self.assertEqual(expected, net.generate_fallback_config())218 self.assertEqual(expected, net.generate_fallback_config())
219219
220 def test_generate_fallback_finds_dormant_eth_with_mac(self):220 def test_generate_fallback_finds_dormant_eth_with_mac(self):
@@ -223,9 +223,9 @@ class TestGenerateFallbackConfig(CiTestCase):
223 mac = 'aa:bb:cc:aa:bb:cc'223 mac = 'aa:bb:cc:aa:bb:cc'
224 write_file(os.path.join(self.sysdir, 'eth0', 'address'), mac)224 write_file(os.path.join(self.sysdir, 'eth0', 'address'), mac)
225 expected = {225 expected = {
226 'config': [{'type': 'physical', 'mac_address': mac,226 'ethernets': {'eth0': {'match': {'macaddress': mac}, 'dhcp4': True,
227 'name': 'eth0', 'subnets': [{'type': 'dhcp'}]}],227 'set-name': 'eth0'}},
228 'version': 1}228 'version': 2}
229 self.assertEqual(expected, net.generate_fallback_config())229 self.assertEqual(expected, net.generate_fallback_config())
230230
231 def test_generate_fallback_finds_eth_by_operstate(self):231 def test_generate_fallback_finds_eth_by_operstate(self):
@@ -233,9 +233,10 @@ class TestGenerateFallbackConfig(CiTestCase):
233 mac = 'aa:bb:cc:aa:bb:cc'233 mac = 'aa:bb:cc:aa:bb:cc'
234 write_file(os.path.join(self.sysdir, 'eth0', 'address'), mac)234 write_file(os.path.join(self.sysdir, 'eth0', 'address'), mac)
235 expected = {235 expected = {
236 'config': [{'type': 'physical', 'mac_address': mac,236 'ethernets': {
237 'name': 'eth0', 'subnets': [{'type': 'dhcp'}]}],237 'eth0': {'dhcp4': True, 'match': {'macaddress': mac},
238 'version': 1}238 'set-name': 'eth0'}},
239 'version': 2}
239 valid_operstates = ['dormant', 'down', 'lowerlayerdown', 'unknown']240 valid_operstates = ['dormant', 'down', 'lowerlayerdown', 'unknown']
240 for state in valid_operstates:241 for state in valid_operstates:
241 write_file(os.path.join(self.sysdir, 'eth0', 'operstate'), state)242 write_file(os.path.join(self.sysdir, 'eth0', 'operstate'), state)
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
index d2fad9b..e6ed2f3 100755
--- a/cloudinit/sources/DataSourceAzure.py
+++ b/cloudinit/sources/DataSourceAzure.py
@@ -1241,7 +1241,7 @@ def parse_network_config(imds_metadata):
1241 privateIpv4 = addr4['privateIpAddress']1241 privateIpv4 = addr4['privateIpAddress']
1242 if privateIpv4:1242 if privateIpv4:
1243 if dev_config.get('dhcp4', False):1243 if dev_config.get('dhcp4', False):
1244 # Append static address config for nic > 11244 # Append static address config for ip > 1
1245 netPrefix = intf['ipv4']['subnet'][0].get(1245 netPrefix = intf['ipv4']['subnet'][0].get(
1246 'prefix', '24')1246 'prefix', '24')
1247 if not dev_config.get('addresses'):1247 if not dev_config.get('addresses'):
@@ -1251,6 +1251,11 @@ def parse_network_config(imds_metadata):
1251 ip=privateIpv4, prefix=netPrefix))1251 ip=privateIpv4, prefix=netPrefix))
1252 else:1252 else:
1253 dev_config['dhcp4'] = True1253 dev_config['dhcp4'] = True
1254 # non-primary interfaces should have a higher
1255 # route-metric (cost) so default routes prefer
1256 # primary nic due to lower route-metric value
1257 dev_config['dhcp4-overrides'] = {
1258 'route-metric': (idx + 1) * 100}
1254 for addr6 in intf['ipv6']['ipAddress']:1259 for addr6 in intf['ipv6']['ipAddress']:
1255 privateIpv6 = addr6['privateIpAddress']1260 privateIpv6 = addr6['privateIpAddress']
1256 if privateIpv6:1261 if privateIpv6:
diff --git a/tests/unittests/test_datasource/test_azure.py b/tests/unittests/test_datasource/test_azure.py
index 2de2aea..4d57ceb 100644
--- a/tests/unittests/test_datasource/test_azure.py
+++ b/tests/unittests/test_datasource/test_azure.py
@@ -12,6 +12,7 @@ from cloudinit.tests.helpers import (
12 HttprettyTestCase, CiTestCase, populate_dir, mock, wrap_and_call,12 HttprettyTestCase, CiTestCase, populate_dir, mock, wrap_and_call,
13 ExitStack, resourceLocation)13 ExitStack, resourceLocation)
1414
15import copy
15import crypt16import crypt
16import httpretty17import httpretty
17import json18import json
@@ -129,6 +130,26 @@ NETWORK_METADATA = {
129 }130 }
130}131}
131132
133SECONDARY_INTERFACE = {
134 "macAddress": "220D3A047598",
135 "ipv6": {
136 "ipAddress": []
137 },
138 "ipv4": {
139 "subnet": [
140 {
141 "prefix": "24",
142 "address": "10.0.1.0"
143 }
144 ],
145 "ipAddress": [
146 {
147 "privateIpAddress": "10.0.1.5",
148 }
149 ]
150 }
151}
152
132MOCKPATH = 'cloudinit.sources.DataSourceAzure.'153MOCKPATH = 'cloudinit.sources.DataSourceAzure.'
133154
134155
@@ -619,8 +640,43 @@ scbus-1 on xpt0 bus 0
619 'ethernets': {640 'ethernets': {
620 'eth0': {'set-name': 'eth0',641 'eth0': {'set-name': 'eth0',
621 'match': {'macaddress': '00:0d:3a:04:75:98'},642 'match': {'macaddress': '00:0d:3a:04:75:98'},
622 'dhcp4': True}},643 'dhcp4': True,
644 'dhcp4-overrides': {'route-metric': 100}}},
645 'version': 2}
646 dsrc = self._get_ds(data)
647 dsrc.get_data()
648 self.assertEqual(expected_network_config, dsrc.network_config)
649
650 def test_network_config_set_from_imds_route_metric_for_secondary_nic(self):
651 """Datasource.network_config adds route-metric to secondary nics."""
652 sys_cfg = {'datasource': {'Azure': {'apply_network_config': True}}}
653 odata = {}
654 data = {'ovfcontent': construct_valid_ovf_env(data=odata),
655 'sys_cfg': sys_cfg}
656 expected_network_config = {
657 'ethernets': {
658 'eth0': {'set-name': 'eth0',
659 'match': {'macaddress': '00:0d:3a:04:75:98'},
660 'dhcp4': True,
661 'dhcp4-overrides': {'route-metric': 100}},
662 'eth1': {'set-name': 'eth1',
663 'match': {'macaddress': '22:0d:3a:04:75:98'},
664 'dhcp4': True,
665 'dhcp4-overrides': {'route-metric': 200}},
666 'eth2': {'set-name': 'eth2',
667 'match': {'macaddress': '33:0d:3a:04:75:98'},
668 'dhcp4': True,
669 'dhcp4-overrides': {'route-metric': 300}}},
623 'version': 2}670 'version': 2}
671 imds_data = copy.deepcopy(NETWORK_METADATA)
672 imds_data['network']['interface'].append(SECONDARY_INTERFACE)
673 third_intf = copy.deepcopy(SECONDARY_INTERFACE)
674 third_intf['macAddress'] = third_intf['macAddress'].replace('22', '33')
675 third_intf['ipv4']['subnet'][0]['address'] = '10.0.2.0'
676 third_intf['ipv4']['ipAddress'][0]['privateIpAddress'] = '10.0.2.6'
677 imds_data['network']['interface'].append(third_intf)
678
679 self.m_get_metadata_from_imds.return_value = imds_data
624 dsrc = self._get_ds(data)680 dsrc = self._get_ds(data)
625 dsrc.get_data()681 dsrc.get_data()
626 self.assertEqual(expected_network_config, dsrc.network_config)682 self.assertEqual(expected_network_config, dsrc.network_config)
@@ -925,6 +981,7 @@ scbus-1 on xpt0 bus 0
925 expected_cfg = {981 expected_cfg = {
926 'ethernets': {982 'ethernets': {
927 'eth0': {'dhcp4': True,983 'eth0': {'dhcp4': True,
984 'dhcp4-overrides': {'route-metric': 100},
928 'match': {'macaddress': '00:0d:3a:04:75:98'},985 'match': {'macaddress': '00:0d:3a:04:75:98'},
929 'set-name': 'eth0'}},986 'set-name': 'eth0'}},
930 'version': 2}987 'version': 2}
diff --git a/tests/unittests/test_net.py b/tests/unittests/test_net.py
index 1840ade..4f7e420 100644
--- a/tests/unittests/test_net.py
+++ b/tests/unittests/test_net.py
@@ -2156,7 +2156,7 @@ DEFAULT_DEV_ATTRS = {
2156 "carrier": False,2156 "carrier": False,
2157 "dormant": False,2157 "dormant": False,
2158 "operstate": "down",2158 "operstate": "down",
2159 "address": "07-1C-C6-75-A4-BE",2159 "address": "07-1c-c6-75-a4-be",
2160 "device/driver": None,2160 "device/driver": None,
2161 "device/device": None,2161 "device/device": None,
2162 "name_assign_type": "4",2162 "name_assign_type": "4",
@@ -2207,6 +2207,39 @@ class TestGenerateFallbackConfig(CiTestCase):
2207 @mock.patch("cloudinit.net.sys_dev_path")2207 @mock.patch("cloudinit.net.sys_dev_path")
2208 @mock.patch("cloudinit.net.read_sys_net")2208 @mock.patch("cloudinit.net.read_sys_net")
2209 @mock.patch("cloudinit.net.get_devicelist")2209 @mock.patch("cloudinit.net.get_devicelist")
2210 def test_device_driver_v2(self, mock_get_devicelist, mock_read_sys_net,
2211 mock_sys_dev_path):
2212 """Network configuration for generate_fallback_config is version 2."""
2213 devices = {
2214 'eth0': {
2215 'bridge': False, 'carrier': False, 'dormant': False,
2216 'operstate': 'down', 'address': '00:11:22:33:44:55',
2217 'device/driver': 'hv_netsvc', 'device/device': '0x3',
2218 'name_assign_type': '4'},
2219 'eth1': {
2220 'bridge': False, 'carrier': False, 'dormant': False,
2221 'operstate': 'down', 'address': '00:11:22:33:44:55',
2222 'device/driver': 'mlx4_core', 'device/device': '0x7',
2223 'name_assign_type': '4'},
2224
2225 }
2226
2227 tmp_dir = self.tmp_dir()
2228 _setup_test(tmp_dir, mock_get_devicelist,
2229 mock_read_sys_net, mock_sys_dev_path,
2230 dev_attrs=devices)
2231
2232 network_cfg = net.generate_fallback_config(config_driver=True)
2233 expected = {
2234 'ethernets': {'eth0': {'dhcp4': True, 'set-name': 'eth0',
2235 'match': {'macaddress': '00:11:22:33:44:55',
2236 'driver': 'hv_netsvc'}}},
2237 'version': 2}
2238 self.assertEqual(expected, network_cfg)
2239
2240 @mock.patch("cloudinit.net.sys_dev_path")
2241 @mock.patch("cloudinit.net.read_sys_net")
2242 @mock.patch("cloudinit.net.get_devicelist")
2210 def test_device_driver(self, mock_get_devicelist, mock_read_sys_net,2243 def test_device_driver(self, mock_get_devicelist, mock_read_sys_net,
2211 mock_sys_dev_path):2244 mock_sys_dev_path):
2212 devices = {2245 devices = {
@@ -2486,7 +2519,7 @@ class TestRhelSysConfigRendering(CiTestCase):
2486#2519#
2487BOOTPROTO=dhcp2520BOOTPROTO=dhcp
2488DEVICE=eth10002521DEVICE=eth1000
2489HWADDR=07-1C-C6-75-A4-BE2522HWADDR=07-1c-c6-75-a4-be
2490NM_CONTROLLED=no2523NM_CONTROLLED=no
2491ONBOOT=yes2524ONBOOT=yes
2492STARTMODE=auto2525STARTMODE=auto
@@ -3030,7 +3063,7 @@ class TestOpenSuseSysConfigRendering(CiTestCase):
3030#3063#
3031BOOTPROTO=dhcp3064BOOTPROTO=dhcp
3032DEVICE=eth10003065DEVICE=eth1000
3033HWADDR=07-1C-C6-75-A4-BE3066HWADDR=07-1c-c6-75-a4-be
3034NM_CONTROLLED=no3067NM_CONTROLLED=no
3035ONBOOT=yes3068ONBOOT=yes
3036STARTMODE=auto3069STARTMODE=auto
@@ -3342,13 +3375,13 @@ class TestNetplanNetRendering(CiTestCase):
33423375
3343 expected = """3376 expected = """
3344network:3377network:
3345 version: 2
3346 ethernets:3378 ethernets:
3347 eth1000:3379 eth1000:
3348 dhcp4: true3380 dhcp4: true
3349 match:3381 match:
3350 macaddress: 07-1c-c6-75-a4-be3382 macaddress: 07-1c-c6-75-a4-be
3351 set-name: eth10003383 set-name: eth1000
3384 version: 2
3352"""3385"""
3353 self.assertEqual(expected.lstrip(), contents.lstrip())3386 self.assertEqual(expected.lstrip(), contents.lstrip())
3354 self.assertEqual(1, mock_clean_default.call_count)3387 self.assertEqual(1, mock_clean_default.call_count)

Subscribers

People subscribed via source and target branches