Fix the interface filenames for Red Hat amphora images

Code was not using the correct filenames for the 'route',
'route6', 'rule' and 'rule6' files on Red Hat images.
Changed to use config option 'agent_server_network_file'
if it's specified, else the file of the correct name, and
added unit tests for each.

Change-Id: I335287da66524d026f0c42086d885b478c568bbd
Task: 37881
Story: 2007051
This commit is contained in:
Paul Peereboom 2019-12-24 14:16:32 +01:00
parent 8f032d884e
commit 93cd9fc075
3 changed files with 219 additions and 15 deletions

View File

@ -355,24 +355,30 @@ class RH(BaseOS):
name = self._map_package_name(package_name)
return "rpm -q --queryformat %{{VERSION}} {name}".format(name=name)
def get_network_interface_file(self, interface):
@staticmethod
def _get_network_interface_file(prefix, interface):
if CONF.amphora_agent.agent_server_network_file:
return CONF.amphora_agent.agent_server_network_file
if CONF.amphora_agent.agent_server_network_dir:
return os.path.join(CONF.amphora_agent.agent_server_network_dir,
'ifcfg-' + interface)
network_dir = consts.RH_AMP_NET_DIR_TEMPLATE.format(
netns=consts.AMPHORA_NAMESPACE)
return os.path.join(network_dir, 'ifcfg-' + interface)
network_dir = CONF.amphora_agent.agent_server_network_dir
else:
network_dir = consts.RH_AMP_NET_DIR_TEMPLATE.format(
netns=consts.AMPHORA_NAMESPACE)
return os.path.join(network_dir, prefix + interface)
def get_network_interface_file(self, interface):
return self._get_network_interface_file('ifcfg-', interface)
def get_alias_network_interface_file(self, interface):
return self.get_network_interface_file(interface + ':0')
def get_static_routes_interface_file(self, interface):
return self.get_network_interface_file('route-' + interface)
def get_static_routes_interface_file(self, interface, version):
route = 'route6-' if version == 6 else 'route-'
return self._get_network_interface_file(route, interface)
def get_route_rules_interface_file(self, interface):
return self.get_network_interface_file('rule-' + interface)
def get_route_rules_interface_file(self, interface, version):
rule = 'rule6-' if version == 6 else 'rule-'
return self._get_network_interface_file(rule, interface)
def get_network_path(self):
return '/etc/sysconfig/network-scripts'
@ -430,7 +436,8 @@ class RH(BaseOS):
render_host_routes, template_vip_alias)
routes_interface_file_path = (
self.get_static_routes_interface_file(primary_interface))
self.get_static_routes_interface_file(primary_interface,
ip.version))
template_routes = j2_env.get_template(self.ROUTE_ETH_X_CONF)
self.write_static_routes_interface_file(
@ -441,7 +448,8 @@ class RH(BaseOS):
if (CONF.controller_worker.loadbalancer_topology ==
consts.TOPOLOGY_SINGLE):
route_rules_interface_file_path = (
self.get_route_rules_interface_file(primary_interface))
self.get_route_rules_interface_file(primary_interface,
ip.version))
template_rules = j2_env.get_template(self.RULE_ETH_X_CONF)
self.write_static_routes_interface_file(
@ -491,16 +499,32 @@ class RH(BaseOS):
if fixed_ips:
host_routes = []
host_routes_ipv6 = []
for fixed_ip in fixed_ips:
host_routes.extend(self.get_host_routes(fixed_ip))
ip_addr = fixed_ip['ip_address']
ip = ipaddress.ip_address(ip_addr if isinstance(
ip_addr, six.text_type) else six.u(ip_addr))
if ip.version == 6:
host_routes_ipv6.extend(self.get_host_routes(fixed_ip))
else:
host_routes.extend(self.get_host_routes(fixed_ip))
routes_interface_file_path = (
self.get_static_routes_interface_file(netns_interface))
self.get_static_routes_interface_file(netns_interface, 4))
template_routes = j2_env.get_template(self.ROUTE_ETH_X_CONF)
self.write_static_routes_interface_file(
routes_interface_file_path, netns_interface,
host_routes, template_routes, None, None, None)
routes_interface_file_path_ipv6 = (
self.get_static_routes_interface_file(netns_interface, 6))
template_routes = j2_env.get_template(self.ROUTE_ETH_X_CONF)
self.write_static_routes_interface_file(
routes_interface_file_path_ipv6, netns_interface,
host_routes_ipv6, template_routes, None, None, None)
self._write_ifup_ifdown_local_scripts_if_possible()
@classmethod

View File

@ -163,6 +163,114 @@ class TestOSUtils(base.TestCase):
get_network_interface_file(consts.NETNS_PRIMARY_INTERFACE))
self.assertEqual(ubuntu_real_nic_path, ubuntu_interface_file)
def _test_RH_get_static_routes_interface_file(self, version):
conf = self.useFixture(oslo_fixture.Config(config.cfg.CONF))
fake_agent_server_network_dir = "/path/to/interface"
fake_agent_server_network_file = "/path/to/interfaces_file"
route = 'route6' if version == 6 else 'route'
rh_route_name = '{route}-{nic}'.format(
route=route, nic=consts.NETNS_PRIMARY_INTERFACE)
rh_fake_route_path = os.path.join(fake_agent_server_network_dir,
rh_route_name)
rh_real_route_path = os.path.join(
consts.RH_AMP_NET_DIR_TEMPLATE.format(
netns=consts.AMPHORA_NAMESPACE),
rh_route_name)
# Check that agent_server_network_file is returned, when provided
conf.config(group="amphora_agent",
agent_server_network_file=fake_agent_server_network_file)
rh_route_file = (
self.rh_os_util.
get_static_routes_interface_file(consts.NETNS_PRIMARY_INTERFACE,
version))
self.assertEqual(fake_agent_server_network_file, rh_route_file)
# Check that agent_server_network_dir is used, when provided
conf.config(group="amphora_agent", agent_server_network_file=None)
conf.config(group="amphora_agent",
agent_server_network_dir=fake_agent_server_network_dir)
rh_route_file = (
self.rh_os_util.
get_static_routes_interface_file(consts.NETNS_PRIMARY_INTERFACE,
version))
self.assertEqual(rh_fake_route_path, rh_route_file)
# Check When neither agent_server_network_dir or
# agent_server_network_file where provided.
conf.config(group="amphora_agent", agent_server_network_file=None)
conf.config(group="amphora_agent", agent_server_network_dir=None)
rh_route_file = (
self.rh_os_util.
get_static_routes_interface_file(consts.NETNS_PRIMARY_INTERFACE,
version))
self.assertEqual(rh_real_route_path, rh_route_file)
def test_RH_get_static_routes_interface_file(self):
self._test_RH_get_static_routes_interface_file(4)
def test_RH_get_static_routes_interface_file_ipv6(self):
self._test_RH_get_static_routes_interface_file(6)
def _test_RH_get_route_rules_interface_file(self, version):
conf = self.useFixture(oslo_fixture.Config(config.cfg.CONF))
fake_agent_server_network_dir = "/path/to/interface"
fake_agent_server_network_file = "/path/to/interfaces_file"
rule = 'rule6' if version == 6 else 'rule'
rh_route_rules_name = '{rule}-{nic}'.format(
rule=rule, nic=consts.NETNS_PRIMARY_INTERFACE)
rh_fake_route_rules_path = os.path.join(fake_agent_server_network_dir,
rh_route_rules_name)
rh_real_route_rules_path = os.path.join(
consts.RH_AMP_NET_DIR_TEMPLATE.format(
netns=consts.AMPHORA_NAMESPACE),
rh_route_rules_name)
# Check that agent_server_network_file is returned, when provided
conf.config(group="amphora_agent",
agent_server_network_file=fake_agent_server_network_file)
rh_route_rules_file = (
self.rh_os_util.
get_route_rules_interface_file(consts.NETNS_PRIMARY_INTERFACE,
version))
self.assertEqual(fake_agent_server_network_file, rh_route_rules_file)
# Check that agent_server_network_dir is used, when provided
conf.config(group="amphora_agent", agent_server_network_file=None)
conf.config(group="amphora_agent",
agent_server_network_dir=fake_agent_server_network_dir)
rh_route_rules_file = (
self.rh_os_util.
get_route_rules_interface_file(consts.NETNS_PRIMARY_INTERFACE,
version))
self.assertEqual(rh_fake_route_rules_path, rh_route_rules_file)
# Check When neither agent_server_network_dir or
# agent_server_network_file where provided.
conf.config(group="amphora_agent", agent_server_network_file=None)
conf.config(group="amphora_agent", agent_server_network_dir=None)
rh_route_rules_file = (
self.rh_os_util.
get_route_rules_interface_file(consts.NETNS_PRIMARY_INTERFACE,
version))
self.assertEqual(rh_real_route_rules_path, rh_route_rules_file)
def test_RH_get_route_rules_interface_file(self):
self._test_RH_get_route_rules_interface_file(4)
def test_RH_get_route_rules_interface_file_ipv6(self):
self._test_RH_get_route_rules_interface_file(6)
def test_cmd_get_version_of_installed_package(self):
package_name = 'foo'
ubuntu_cmd = "dpkg-query -W -f=${{Version}} {name}".format(
@ -303,13 +411,32 @@ class TestOSUtils(base.TestCase):
)
def test_write_port_interface_file(self):
FIXED_IP = u'192.0.2.2'
NEXTHOP = u'192.0.2.1'
DEST = u'198.51.100.0/24'
host_routes = [
{'nexthop': NEXTHOP, 'destination': ipaddress.ip_network(DEST)}
]
FIXED_IP_IPV6 = u'2001:db8::2'
NEXTHOP_IPV6 = u'2001:db8::1'
DEST_IPV6 = u'2001:db8:51:100::/64'
host_routes_ipv6 = [
{'nexthop': NEXTHOP_IPV6,
'destination': ipaddress.ip_network(DEST_IPV6)}
]
ip_addr = {'ip_address': FIXED_IP, 'host_routes': host_routes}
ipv6_addr = {'ip_address': FIXED_IP_IPV6,
'host_routes': host_routes_ipv6}
netns_interface = 'eth1234'
MTU = 1450
fixed_ips = []
fixed_ips = [ip_addr, ipv6_addr]
path = 'mypath'
mock_template = mock.MagicMock()
mock_open = self.useFixture(test_utils.OpenFixture(path)).mock_open
mock_gen_text = mock.MagicMock()
mock_local_scripts = mock.MagicMock()
mock_wr_fi = mock.MagicMock()
with mock.patch('os.open'), mock.patch.object(
os, 'fdopen', mock_open), mock.patch.object(
@ -324,6 +451,51 @@ class TestOSUtils(base.TestCase):
mock_gen_text.assert_called_once_with(
netns_interface, fixed_ips, MTU, mock_template)
mock_gen_text.reset_mock()
with mock.patch('os.open'), mock.patch.object(
os, 'fdopen', mock_open), mock.patch.object(
osutils.BaseOS, '_generate_network_file_text',
mock_gen_text), mock.patch.object(
osutils.RH, '_write_ifup_ifdown_local_scripts_if_possible',
mock_local_scripts), mock.patch.object(
osutils.RH, 'write_static_routes_interface_file', mock_wr_fi):
self.rh_os_util.write_port_interface_file(
netns_interface=netns_interface,
fixed_ips=fixed_ips,
mtu=MTU,
interface_file_path=path,
template_port=mock_template)
rh_route_name = 'route-{nic}'.format(nic=netns_interface)
rh_real_route_path = os.path.join(
consts.RH_AMP_NET_DIR_TEMPLATE.format(
netns=consts.AMPHORA_NAMESPACE),
rh_route_name)
rh_route_name_ipv6 = 'route6-{nic}'.format(nic=netns_interface)
rh_real_route_path_ipv6 = os.path.join(
consts.RH_AMP_NET_DIR_TEMPLATE.format(
netns=consts.AMPHORA_NAMESPACE),
rh_route_name_ipv6)
exp_routes = [
{'network': ipaddress.ip_network(DEST), 'gw': NEXTHOP}
]
exp_routes_ipv6 = [
{'network': ipaddress.ip_network(DEST_IPV6), 'gw': NEXTHOP_IPV6}
]
expected_calls = [
mock.call(rh_real_route_path, netns_interface,
exp_routes, mock.ANY, None, None, None),
mock.call(rh_real_route_path_ipv6, netns_interface,
exp_routes_ipv6, mock.ANY, None, None, None)]
mock_gen_text.assert_called_once_with(
netns_interface, fixed_ips, MTU, mock_template)
self.assertEqual(2, mock_wr_fi.call_count)
mock_wr_fi.assert_has_calls(expected_calls)
mock_local_scripts.assert_called_once()
@mock.patch('shutil.copy2')
@mock.patch('os.makedirs')
@mock.patch('shutil.copytree')

View File

@ -0,0 +1,8 @@
---
fixes:
- |
Fixed code that configured the CentOS/Red Hat amphora images to use the
correct names for the network 'ifcfg' files for static routes and
routing rules. It was using the wrong name for the routes file,
and did not support IPv6 in either file. For more information, see
https://storyboard.openstack.org/#!/story/2007051