nocloud: fix network config regression

With commit
f0fe66b30b,
the network config in case of NoCloudConfigDrive was supported only if
it was in the format:

```yaml
network:
  config: ...
  version: 1|2
```

Before the commit, the following format was also supported:

```yaml
config: ...
version: 1
```

Added support for both formats and made sure that the `network` key is
not required.

Change-Id: I7478a8654443db83f0f3995839811910c468a06c
Signed-off-by: Adrian Vladu <avladu@cloudbasesolutions.com>
This commit is contained in:
Adrian Vladu
2024-06-21 14:30:14 +03:00
parent bf61aecd60
commit 1a98b6742a
2 changed files with 143 additions and 117 deletions

View File

@@ -237,10 +237,11 @@ class NoCloudNetworkConfigV1Parser(object):
networks = [] networks = []
services = [] services = []
network_config = network_config.get('network') \ if network_config and network_config.get('network'):
if network_config else {} network_config = network_config.get('network')
network_config = network_config.get('config') \ if network_config:
if network_config else None network_config = network_config.get('config')
if not network_config: if not network_config:
LOG.warning("Network configuration is empty") LOG.warning("Network configuration is empty")
return return
@@ -479,8 +480,9 @@ class NoCloudNetworkConfigV2Parser(object):
networks = [] networks = []
services = [] services = []
network_config = network_config.get('network') \ if network_config and network_config.get('network'):
if network_config else {} network_config = network_config.get('network')
if not network_config: if not network_config:
LOG.warning("Network configuration is empty") LOG.warning("Network configuration is empty")
return return
@@ -529,12 +531,21 @@ class NoCloudNetworkConfigParser(object):
@staticmethod @staticmethod
def parse(network_data): def parse(network_data):
network_data_version = network_data.get("network", {}).get("version") # we can have a network key in some cases
if network_data.get("network"):
network_data = network_data.get("network")
network_data_version = network_data.get("version")
if network_data_version == 1: if network_data_version == 1:
network_config_parser = NoCloudNetworkConfigV1Parser() network_config_parser = NoCloudNetworkConfigV1Parser()
return network_config_parser.parse(network_data) elif network_data_version == 2:
network_config_parser = NoCloudNetworkConfigV2Parser()
else:
raise exception.CloudbaseInitException(
"Unsupported network_data_version: '%s'"
% network_data_version)
return NoCloudNetworkConfigV2Parser().parse(network_data) return network_config_parser.parse(network_data)
class NoCloudConfigDriveService(baseconfigdrive.BaseConfigDriveService): class NoCloudConfigDriveService(baseconfigdrive.BaseConfigDriveService):

View File

@@ -15,6 +15,7 @@
import ddt import ddt
import importlib import importlib
import os import os
import textwrap
import unittest import unittest
import unittest.mock as mock import unittest.mock as mock
@@ -48,11 +49,10 @@ network:
config: config:
- type: router - type: router
""" """
NOCLOUD_NETWORK_CONFIG_TEST_DATA_V1 = """ NOCLOUD_NETWORK_CONFIG_TEST_DATA_V1_LEGACY = """
network: version: 1
version: 1 config:
config: - type: physical
- type: physical
name: interface0 name: interface0
mac_address: "52:54:00:12:34:00" mac_address: "52:54:00:12:34:00"
mtu: 1450 mtu: 1450
@@ -63,7 +63,7 @@ network:
gateway: 192.168.1.1 gateway: 192.168.1.1
dns_nameservers: dns_nameservers:
- 192.168.1.11 - 192.168.1.11
- type: bond - type: bond
name: bond0 name: bond0
bond_interfaces: bond_interfaces:
- gbe0 - gbe0
@@ -79,7 +79,7 @@ network:
netmask: 255.255.255.0 netmask: 255.255.255.0
dns_nameservers: dns_nameservers:
- 192.168.1.11 - 192.168.1.11
- type: vlan - type: vlan
name: vlan0 name: vlan0
vlan_link: eth1 vlan_link: eth1
vlan_id: 150 vlan_id: 150
@@ -91,12 +91,15 @@ network:
netmask: 255.255.255.0 netmask: 255.255.255.0
dns_nameservers: dns_nameservers:
- 192.168.1.11 - 192.168.1.11
- type: nameserver - type: nameserver
address: address:
- 192.168.23.2 - 192.168.23.2
- 8.8.8.8 - 8.8.8.8
search: acme.local search: acme.local
""" """
NOCLOUD_NETWORK_CONFIG_TEST_DATA_V1 = """
network:%s
""" % (textwrap.indent(NOCLOUD_NETWORK_CONFIG_TEST_DATA_V1_LEGACY, " "))
NOCLOUD_NETWORK_CONFIG_TEST_DATA_V2_EMPTY_CONFIG = """ NOCLOUD_NETWORK_CONFIG_TEST_DATA_V2_EMPTY_CONFIG = """
""" """
NOCLOUD_NETWORK_CONFIG_TEST_DATA_V2_CONFIG_IS_NOT_DICT = """ NOCLOUD_NETWORK_CONFIG_TEST_DATA_V2_CONFIG_IS_NOT_DICT = """
@@ -116,10 +119,9 @@ network:
eth0: eth0:
- test - test
""" """
NOCLOUD_NETWORK_CONFIG_TEST_DATA_V2 = """ NOCLOUD_NETWORK_CONFIG_TEST_DATA_V2_LEGACY = """
network: version: 2
version: 2 ethernets:
ethernets:
interface0: interface0:
match: match:
macaddress: "52:54:00:12:34:00" macaddress: "52:54:00:12:34:00"
@@ -145,7 +147,7 @@ network:
- 192.168.1.12 - 192.168.1.12
search: search:
- acme.local - acme.local
bonds: bonds:
bond0: bond0:
interfaces: ["gbe0", "gbe1"] interfaces: ["gbe0", "gbe1"]
match: match:
@@ -159,7 +161,7 @@ network:
addresses: addresses:
- 192.168.1.11 - 192.168.1.11
mtu: 1450 mtu: 1450
vlans: vlans:
vlan0: vlan0:
id: 150 id: 150
link: eth1 link: eth1
@@ -172,11 +174,14 @@ network:
addresses: addresses:
- 192.168.1.11 - 192.168.1.11
mtu: 1450 mtu: 1450
bridges: bridges:
br0: br0:
interfaces: ['eth0'] interfaces: ['eth0']
dhcp4: true dhcp4: true
""" """
NOCLOUD_NETWORK_CONFIG_TEST_DATA_V2 = """
network:%s
""" % (textwrap.indent(NOCLOUD_NETWORK_CONFIG_TEST_DATA_V2_LEGACY, " "))
@ddt.ddt @ddt.ddt
@@ -207,7 +212,12 @@ class TestNoCloudNetworkConfigV1Parser(unittest.TestCase):
self.assertEqual(True, expected_result[0] in self.snatcher.output[0]) self.assertEqual(True, expected_result[0] in self.snatcher.output[0])
self.assertEqual(result, expected_result[1]) self.assertEqual(result, expected_result[1])
def test_network_details_v2(self): @ddt.data(
(NOCLOUD_NETWORK_CONFIG_TEST_DATA_V1, True),
(NOCLOUD_NETWORK_CONFIG_TEST_DATA_V1_LEGACY, True)
)
@ddt.unpack
def test_network_details_v2(self, test_data, expected_result):
expected_bond = nm.Bond( expected_bond = nm.Bond(
members=["gbe0", "gbe1"], members=["gbe0", "gbe1"],
type=nm.BOND_TYPE_ACTIVE_BACKUP, type=nm.BOND_TYPE_ACTIVE_BACKUP,
@@ -275,7 +285,7 @@ class TestNoCloudNetworkConfigV1Parser(unittest.TestCase):
search='acme.local') search='acme.local')
result = self._parser.parse( result = self._parser.parse(
serialization.parse_json_yaml(NOCLOUD_NETWORK_CONFIG_TEST_DATA_V1)) serialization.parse_json_yaml(test_data))
self.assertEqual(result.links[0], expected_link) self.assertEqual(result.links[0], expected_link)
self.assertEqual(result.networks[0], expected_network) self.assertEqual(result.networks[0], expected_network)
@@ -318,7 +328,12 @@ class TestNoCloudNetworkConfigV2Parser(unittest.TestCase):
self.assertEqual(True, expected_result[0] in self.snatcher.output[0]) self.assertEqual(True, expected_result[0] in self.snatcher.output[0])
self.assertEqual(result, expected_result[1]) self.assertEqual(result, expected_result[1])
def test_network_details_v2(self): @ddt.data(
(NOCLOUD_NETWORK_CONFIG_TEST_DATA_V2, True),
(NOCLOUD_NETWORK_CONFIG_TEST_DATA_V2_LEGACY, True)
)
@ddt.unpack
def test_network_details_v2(self, test_data, expected_result):
expected_bond = nm.Bond( expected_bond = nm.Bond(
members=["gbe0", "gbe1"], members=["gbe0", "gbe1"],
type=nm.BOND_TYPE_ACTIVE_BACKUP, type=nm.BOND_TYPE_ACTIVE_BACKUP,
@@ -406,7 +421,7 @@ class TestNoCloudNetworkConfigV2Parser(unittest.TestCase):
search='acme.local') search='acme.local')
result = self._parser.parse( result = self._parser.parse(
serialization.parse_json_yaml(NOCLOUD_NETWORK_CONFIG_TEST_DATA_V2)) serialization.parse_json_yaml(test_data))
self.assertEqual(result.links[0], expected_link) self.assertEqual(result.links[0], expected_link)
self.assertEqual(result.links[1], expected_link_if1) self.assertEqual(result.links[1], expected_link_if1)