diff --git a/octane/tests/test_network.py b/octane/tests/test_network.py index 4d70d30e..24686b09 100644 --- a/octane/tests/test_network.py +++ b/octane/tests/test_network.py @@ -9,10 +9,13 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. + +import pytest import subprocess from mock import call from mock import Mock +from octane.tests import util as test_util from octane.util import network @@ -310,3 +313,27 @@ DEPLOYMENT_INFO_7_0 = { }] } } + + +IFACE_BASE = b"auto br-ex\niface br-ex inet static\n" +IFACE_ADDR = b"address 10.109.1.4/24\ngateway 10.109.1.1\n" +IFACE_SINGLEPORT = IFACE_BASE + b"bridge_ports eth0\n" +IFACE_DEFAULT = IFACE_SINGLEPORT + IFACE_ADDR +IFACE_TESTPORT = b"bridge_ports test-iface\n" +IFACE_MULTIPORT = IFACE_BASE + IFACE_TESTPORT +IFACE_MULTIPORT_EXPECTED = IFACE_BASE + b"bridge_ports eth0 test-iface\n" + + +@pytest.mark.parametrize("content,expected_content", [ + (IFACE_BASE, IFACE_SINGLEPORT), + (IFACE_DEFAULT, IFACE_DEFAULT), + (IFACE_MULTIPORT, IFACE_MULTIPORT_EXPECTED), +]) +@pytest.mark.parametrize("bridge,port", [ + ('br-ex', {'name': 'eth0'}), +]) +def test_save_port_lnx(mocker, node, content, expected_content, bridge, port): + filename = '/etc/network/interfaces.d/ifcfg-{0}'.format(bridge) + with test_util.mock_update_file(mocker, node, content, expected_content, + filename): + network.save_port_lnx(node, bridge, port) diff --git a/octane/util/network.py b/octane/util/network.py index 0d9da236..9caa9eb2 100644 --- a/octane/util/network.py +++ b/octane/util/network.py @@ -11,6 +11,7 @@ # under the License. import logging +import os import re import subprocess @@ -317,6 +318,28 @@ create_port_providers = { } +def save_port_lnx(node, bridge, port): + ifaces_path = '/etc/network/interfaces.d' + bridge_file = os.path.join(ifaces_path, 'ifcfg-{0}'.format(bridge)) + sftp = ssh.sftp(node) + with ssh.update_file(sftp, bridge_file) as (old, new): + found_bridge_port_line = False + for line in old: + if line.startswith('bridge_ports'): + found_bridge_port_line = True + if port['name'] not in line: + option, _, ports = line.rstrip().partition(' ') + line = "{0} {1} {2}\n".format(option, port['name'], ports) + new.write(line) + if not found_bridge_port_line: + new.write('bridge_ports {0}\n'.format(port['name'])) + + +save_port_providers = { + 'lnx': save_port_lnx, +} + + def create_patch_ports(node, host_config): for bridge in magic_consts.BRIDGES: port, provider = ts.get_patch_port_action(host_config, bridge) @@ -324,6 +347,9 @@ def create_patch_ports(node, host_config): cmds = create_port_cmd(bridge, port) for cmd in cmds: ssh.call(cmd, node=node) + save_port_func = save_port_providers.get(provider) + if save_port_func: + save_port_func(node, bridge, port) def flush_arp(node):