Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP3:GA
cloud-init.7450
0001-switch-to-using-iproute2-tools.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-switch-to-using-iproute2-tools.patch of Package cloud-init.7450
From 48c4dcd464d8c6daccf09b3dccc664ad347b34ce Mon Sep 17 00:00:00 2001 From: Robert Schweikert <rjschwei@suse.com> Date: Mon, 18 Dec 2017 13:34:21 -0500 Subject: [PATCH] - switch to using iproute2 tools + ifconfig, netstat and other tools are being deprecated, switch to using tools that are part of iproute2 for implementations that support these tools --- cloudinit/config/cc_disable_ec2_metadata.py | 14 +- .../config/tests/test_disable_ec2_metadata.py | 72 +++++ cloudinit/netinfo.py | 302 +++++++++++++++------ cloudinit/tests/test_netinfo.py | 174 +++++++++++- 4 files changed, 474 insertions(+), 88 deletions(-) create mode 100644 cloudinit/config/tests/test_disable_ec2_metadata.py diff --git a/cloudinit/config/cc_disable_ec2_metadata.py b/cloudinit/config/cc_disable_ec2_metadata.py index c56319b5..8a166ddf 100644 --- a/cloudinit/config/cc_disable_ec2_metadata.py +++ b/cloudinit/config/cc_disable_ec2_metadata.py @@ -32,13 +32,23 @@ from cloudinit.settings import PER_ALWAYS frequency = PER_ALWAYS -REJECT_CMD = ['route', 'add', '-host', '169.254.169.254', 'reject'] +REJECT_CMD_IF = ['route', 'add', '-host', '169.254.169.254', 'reject'] +REJECT_CMD_IP = ['ip', 'route', 'add', 'prohibit', '169.254.169.254'] def handle(name, cfg, _cloud, log, _args): disabled = util.get_cfg_option_bool(cfg, "disable_ec2_metadata", False) if disabled: - util.subp(REJECT_CMD, capture=False) + reject_cmd = None + if util.which('ifconfig'): + reject_cmd = REJECT_CMD_IF + elif util.which('ip'): + reject_cmd = REJECT_CMD_IP + else: + log.error(('Neither "route" nor "ip" command found, unable to ' + 'manipulate routing table')) + return + util.subp(reject_cmd, capture=False) else: log.debug(("Skipping module named %s," " disabling the ec2 route not enabled"), name) diff --git a/cloudinit/config/tests/test_disable_ec2_metadata.py b/cloudinit/config/tests/test_disable_ec2_metadata.py new file mode 100644 index 00000000..bade814e --- /dev/null +++ b/cloudinit/config/tests/test_disable_ec2_metadata.py @@ -0,0 +1,72 @@ +# This file is part of cloud-init. See LICENSE file for license information. + +"""Tests cc_disable_ec2_metadata handler""" + +import cloudinit.config.cc_disable_ec2_metadata as ec2_meta + +from cloudinit.tests.helpers import CiTestCase, mock + +import logging + +LOG = logging.getLogger(__name__) + +DISABLE_CFG = {'disable_ec2_metadata': 'true'} + + +class TestEC2MetadataRoute(CiTestCase): + + @mock.patch('cloudinit.config.cc_disable_ec2_metadata.util.which') + @mock.patch('cloudinit.config.cc_disable_ec2_metadata.util.subp') + def test_disable_ifconfig(self, m_subp, m_which): + """Set the route if ifconfig command is available""" + m_subp.side_effect = command_check_ifconfig + m_which.side_effect = side_effect_use_ifconfig + ec2_meta.handle('foo', DISABLE_CFG, None, LOG, None) + + @mock.patch('cloudinit.config.cc_disable_ec2_metadata.util.which') + @mock.patch('cloudinit.config.cc_disable_ec2_metadata.util.subp') + def test_disable_ip(self, m_subp, m_which): + """Set the route if ip command is available""" + m_subp.side_effect = command_check_ip + m_which.side_effect = side_effect_use_ip + ec2_meta.handle('foo', DISABLE_CFG, None, LOG, None) + + @mock.patch('cloudinit.config.cc_disable_ec2_metadata.util.which') + @mock.patch('cloudinit.config.cc_disable_ec2_metadata.util.subp') + def test_disable_no_tool(self, m_subp, m_which): + """Set the route if ip command is available""" + m_subp.side_effect = command_dont_reach + m_which.side_effect = side_effect_has_no_tool + ec2_meta.handle('foo', DISABLE_CFG, None, LOG, None) + + +def side_effect_use_ifconfig(tool): + if tool == 'ifconfig': + return True + else: + return False + + +def side_effect_use_ip(tool): + if tool == 'ip': + return True + else: + return False + + +def side_effect_has_no_tool(tool): + return False + + +def command_check_ifconfig(cmd, capture): + assert(cmd == ['route', 'add', '-host', '169.254.169.254', 'reject']) + + +def command_check_ip(cmd, capture): + assert(cmd == ['ip', 'route', 'add', 'prohibit', '169.254.169.254']) + + +def command_dont_reach(cmd, capture): + assert('Test should not have reached this location' == 0) + +# vi: ts=4 expandtab diff --git a/cloudinit/netinfo.py b/cloudinit/netinfo.py index 993b26cf..baad3f92 100644 --- a/cloudinit/netinfo.py +++ b/cloudinit/netinfo.py @@ -19,6 +19,117 @@ LOG = logging.getLogger() def netdev_info(empty=""): + if util.which('ifconfig'): + return _netdev_info_from_ifconfig(empty) + elif util.which('ip'): + return _netdev_info_from_ip(empty) + else: + LOG.error(('Neither "ifconfig" nor "ip" command found, unable to ' + 'collect network device information')) + return {} + + +def route_info(): + if util.which('netstat'): + return _route_info_from_netstat() + elif util.which('ip'): + return _route_info_from_ip() + else: + LOG.error(('Neither "netstat" nor "ip" command found, unable to ' + 'collect routing information')) + return {} + + +def getgateway(): + try: + routes = route_info() + except Exception: + pass + else: + for r in routes.get('ipv4', []): + if r['flags'].find("G") >= 0: + return "%s[%s]" % (r['gateway'], r['iface']) + return None + + +def netdev_pformat(): + lines = [] + try: + netdev = netdev_info(empty=".") + except Exception: + lines.append(util.center("Net device info failed", '!', 80)) + else: + fields = ['Device', 'Up', 'Address', 'Mask', 'Scope', 'Hw-Address'] + tbl = SimpleTable(fields) + for (dev, d) in sorted(netdev.items()): + tbl.add_row([dev, d["up"], d["addr"], d["mask"], ".", d["hwaddr"]]) + if d.get('addr6'): + tbl.add_row([dev, d["up"], + d["addr6"], ".", d.get("scope6"), d["hwaddr"]]) + netdev_s = tbl.get_string() + max_len = len(max(netdev_s.splitlines(), key=len)) + header = util.center("Net device info", "+", max_len) + lines.extend([header, netdev_s]) + return "\n".join(lines) + + +def route_pformat(): + lines = [] + try: + routes = route_info() + except Exception as e: + lines.append(util.center('Route info failed', '!', 80)) + util.logexc(LOG, "Route info failed: %s" % e) + else: + if routes.get('ipv4'): + fields_v4 = ['Route', 'Destination', 'Gateway', + 'Genmask', 'Interface', 'Flags'] + tbl_v4 = SimpleTable(fields_v4) + for (n, r) in enumerate(routes.get('ipv4')): + route_id = str(n) + tbl_v4.add_row([route_id, r['destination'], + r['gateway'], r['genmask'], + r['iface'], r['flags']]) + route_s = tbl_v4.get_string() + max_len = len(max(route_s.splitlines(), key=len)) + header = util.center("Route IPv4 info", "+", max_len) + lines.extend([header, route_s]) + if routes.get('ipv6'): + fields_v6 = ['Route', 'Proto', 'Recv-Q', 'Send-Q', + 'Local Address', 'Foreign Address', 'State'] + tbl_v6 = SimpleTable(fields_v6) + for (n, r) in enumerate(routes.get('ipv6')): + route_id = str(n) + tbl_v6.add_row([route_id, r['proto'], + r['recv-q'], r['send-q'], + r['local address'], r['foreign address'], + r['state']]) + route_s = tbl_v6.get_string() + max_len = len(max(route_s.splitlines(), key=len)) + header = util.center("Route IPv6 info", "+", max_len) + lines.extend([header, route_s]) + return "\n".join(lines) + + +def debug_info(prefix='ci-info: '): + lines = [] + netdev_lines = netdev_pformat().splitlines() + if prefix: + for line in netdev_lines: + lines.append("%s%s" % (prefix, line)) + else: + lines.extend(netdev_lines) + route_lines = route_pformat().splitlines() + if prefix: + for line in route_lines: + lines.append("%s%s" % (prefix, line)) + else: + lines.extend(route_lines) + return "\n".join(lines) + + +def _netdev_info_from_ifconfig(empty=""): + """Use legacy ifconfig output""" fields = ("hwaddr", "addr", "bcast", "mask") (ifcfg_out, _err) = util.subp(["ifconfig", "-a"], rcs=[0, 1]) devs = {} @@ -84,7 +195,54 @@ def netdev_info(empty=""): return devs -def route_info(): +def _netdev_info_from_ip(empty=""): + """Use ip to get network information""" + fields = ("hwaddr", "addr", "bcast", "mask") + (ipdata_out, _err) = util.subp(["ip", "a"], rcs=[0, 1]) + devs = {} + this_device = None + for line in str(ipdata_out).splitlines(): + if len(line) == 0: + continue + if line[0].isdigit(): + prts = line.strip().split(':') + this_device = prts[1].strip() + devs[this_device] = {} + for field in fields: + devs[this_device][field] = '' + devs[this_device]['up'] = False + status_info = re.match('(<)(.*)(>)', prts[-1].strip()).group(2) + status_info = status_info.lower().split(',') + if 'up' in status_info: + devs[this_device]['up'] = True + if 'broadcast' in status_info and 'multicast' in status_info: + devs[this_device]['bcast'] = 'multicast' + continue + conf_data = line.strip() + conf_data_prts = conf_data.split() + if conf_data.startswith('inet '): + devs[this_device]['addr'] = conf_data_prts[1] + if 'brd' in conf_data_prts: + loc = conf_data_prts.index('brd') + devs[this_device]['bcast'] = conf_data_prts[loc + 1] + if conf_data.startswith('inet6'): + devs[this_device]['addr6'] = conf_data_prts[1] + if 'scope' in conf_data_prts: + loc = conf_data_prts.index('scope') + devs[this_device]['scope6'] = conf_data_prts[loc + 1] + if conf_data.startswith('link/ether'): + devs[this_device]['hwaddr'] = conf_data_prts[1] + + if empty != "": + for (_devname, dev) in devs.items(): + for field in dev: + if dev[field] == "": + dev[field] = empty + + return devs + + +def _route_info_from_netstat(): (route_out, _err) = util.subp(["netstat", "-rn"], rcs=[0, 1]) routes = {} @@ -150,91 +308,69 @@ def route_info(): return routes -def getgateway(): - try: - routes = route_info() - except Exception: - pass - else: - for r in routes.get('ipv4', []): - if r['flags'].find("G") >= 0: - return "%s[%s]" % (r['gateway'], r['iface']) - return None - - -def netdev_pformat(): - lines = [] - try: - netdev = netdev_info(empty=".") - except Exception: - lines.append(util.center("Net device info failed", '!', 80)) - else: - fields = ['Device', 'Up', 'Address', 'Mask', 'Scope', 'Hw-Address'] - tbl = SimpleTable(fields) - for (dev, d) in sorted(netdev.items()): - tbl.add_row([dev, d["up"], d["addr"], d["mask"], ".", d["hwaddr"]]) - if d.get('addr6'): - tbl.add_row([dev, d["up"], - d["addr6"], ".", d.get("scope6"), d["hwaddr"]]) - netdev_s = tbl.get_string() - max_len = len(max(netdev_s.splitlines(), key=len)) - header = util.center("Net device info", "+", max_len) - lines.extend([header, netdev_s]) - return "\n".join(lines) +def _route_info_from_ip(): + """Detremine route information from ip route command""" + routes = {} + routes['ipv4'] = [] + routes['ipv6'] = [] + # IPv4 + (route_out, _err) = util.subp(['ip', '-4', 'route', 'list'], rcs=[0, 1]) -def route_pformat(): - lines = [] - try: - routes = route_info() - except Exception as e: - lines.append(util.center('Route info failed', '!', 80)) - util.logexc(LOG, "Route info failed: %s" % e) - else: - if routes.get('ipv4'): - fields_v4 = ['Route', 'Destination', 'Gateway', - 'Genmask', 'Interface', 'Flags'] - tbl_v4 = SimpleTable(fields_v4) - for (n, r) in enumerate(routes.get('ipv4')): - route_id = str(n) - tbl_v4.add_row([route_id, r['destination'], - r['gateway'], r['genmask'], - r['iface'], r['flags']]) - route_s = tbl_v4.get_string() - max_len = len(max(route_s.splitlines(), key=len)) - header = util.center("Route IPv4 info", "+", max_len) - lines.extend([header, route_s]) - if routes.get('ipv6'): - fields_v6 = ['Route', 'Proto', 'Recv-Q', 'Send-Q', - 'Local Address', 'Foreign Address', 'State'] - tbl_v6 = SimpleTable(fields_v6) - for (n, r) in enumerate(routes.get('ipv6')): - route_id = str(n) - tbl_v6.add_row([route_id, r['proto'], - r['recv-q'], r['send-q'], - r['local address'], r['foreign address'], - r['state']]) - route_s = tbl_v6.get_string() - max_len = len(max(route_s.splitlines(), key=len)) - header = util.center("Route IPv6 info", "+", max_len) - lines.extend([header, route_s]) - return "\n".join(lines) + entries = route_out.splitlines() + for line in entries: + route_info = line.strip().split() + dest = route_info[0] + if route_info[0] == 'default': + dest = '0.0.0.0' + flags = '' + gw = '0.0.0.0' + if 'via' in route_info: + loc = route_info.index('via') + # The NH (Next Hop) is basically equivalent to the gateway + gw = route_info[loc + 1] + flags = 'G' + loc = route_info.index('dev') + dev = route_info[loc + 1] + entry = { + 'destination': dest, + 'gateway': gw, + 'genmask': '', + 'flags': flags, + 'metric': '0', + 'ref': '0', + 'use': '0', + 'iface': dev + } + routes['ipv4'].append(entry) + # IPv6 + (route_out, _err) = util.subp(['ip', '-6', 'route', 'list'], rcs=[0, 1]) -def debug_info(prefix='ci-info: '): - lines = [] - netdev_lines = netdev_pformat().splitlines() - if prefix: - for line in netdev_lines: - lines.append("%s%s" % (prefix, line)) - else: - lines.extend(netdev_lines) - route_lines = route_pformat().splitlines() - if prefix: - for line in route_lines: - lines.append("%s%s" % (prefix, line)) - else: - lines.extend(route_lines) - return "\n".join(lines) + entries = route_out.splitlines() + for line in entries: + route_info = line.strip().split() + ip = route_info[0] + if ip == 'default': + ip = '::' + proto = 'tcp6' + if 'proto' in route_info: + loc = route_info.index('proto') + proto = route_info[loc + 1] + gw = '' + if 'via' in route_info: + loc = route_info.index('via') + # The NH (Next Hop) is basically equivalent to the gateway + gw = route_info[loc + 1] + entry = { + 'proto': proto, + 'recv-q': '0', + 'send-q': '0', + 'local address': ip, + 'foreign address': gw, + 'state': '', + } + routes['ipv6'].append(entry) + return routes # vi: ts=4 expandtab diff --git a/cloudinit/tests/test_netinfo.py b/cloudinit/tests/test_netinfo.py index 7dea2e41..3dc557cc 100644 --- a/cloudinit/tests/test_netinfo.py +++ b/cloudinit/tests/test_netinfo.py @@ -2,7 +2,7 @@ """Tests netinfo module functions and classes.""" -from cloudinit.netinfo import netdev_pformat, route_pformat +from cloudinit.netinfo import getgateway, netdev_pformat, route_pformat from cloudinit.tests.helpers import CiTestCase, mock @@ -27,6 +27,48 @@ lo Link encap:Local Loopback collisions:0 txqueuelen:1 """ +SAMPLE_IP_A_OUT = ( + '1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN ' + 'group default qlen 1000\n' + 'link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n' + 'inet 127.0.0.1/8 scope host lo\n' + ' valid_lft forever preferred_lft forever\n' + 'inet6 ::1/128 scope host\n' + ' valid_lft forever preferred_lft forever\n' + '2: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state ' + 'UP group default qlen 1000\n' + 'link/ether 84:3a:4b:09:6f:ec brd ff:ff:ff:ff:ff:ff\n' + 'inet 192.168.1.101/24 brd 192.168.1.255 scope global wlp3s0\n' + ' valid_lft forever preferred_lft forever\n' + 'inet 192.168.1.3/24 brd 192.168.1.255 scope global secondary wlp3s0\n' + ' valid_lft forever preferred_lft forever\n' + 'inet6 fe80::863a:4bff:fe09:6fec/64 scope link\n' + ' valid_lft forever preferred_lft forever' +) + +SAMPLE_ROUTE_INFO = { + 'ipv4': [ + { + 'genmask': '0.0.0.0', + 'use': '0', + 'iface': 'eth1', + 'flags': 'UG', + 'metric': '0', + 'destination': '0.0.0.0', + 'ref': '0', + 'gateway': '192.168.1.1'}, + { + 'genmask': '255.0.0.0', + 'use': '0', + 'iface': 'eth2', + 'flags': 'UG', + 'metric': '0', + 'destination': '10.0.0.0', + 'ref': '0', + 'gateway': '10.163.8.1'} + ] +} + SAMPLE_ROUTE_OUT = '\n'.join([ '0.0.0.0 192.168.2.1 0.0.0.0 UG 0 0 0' ' enp0s25', @@ -35,6 +77,20 @@ SAMPLE_ROUTE_OUT = '\n'.join([ '192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0' ' enp0s25']) +SAMPLE_ROUTE_OUT_IP_V4 = '\n'.join([ + 'default via 192.168.1.1 dev br0', + '10.0.0.0/8 via 10.163.8.1 dev tun0', + '10.163.8.1 dev tun0 proto kernel scope link src 10.163.8.118 ', + '137.65.0.0/16 via 10.163.8.1 dev tun0']) + +SAMPLE_ROUTE_OUT_IP_V6 = '\n'.join([ + '2621:111:80c0:8080:12:160:68:53 dev eth0 proto kernel metric 256 expires ' + '9178sec pref medium', + '2621:111:80c0:8080::/64 dev eth0 proto ra metric 100 pref medium', + 'fe80::1 dev eth0 proto static metric 100 pref medium', + 'fe80::/64 dev eth0 proto kernel metric 256 pref medium', + 'default via fe80::1 dev eth0 proto static metric 100 pref medium', + '2620:113:80c0:8000::/50 dev tun0 metric 1024 pref medium']) NETDEV_FORMATTED_OUT = '\n'.join([ '+++++++++++++++++++++++++++++++++++++++Net device info+++++++++++++++++++' @@ -56,6 +112,26 @@ NETDEV_FORMATTED_OUT = '\n'.join([ '+---------+------+------------------------------+---------------+-------+' '-------------------+']) +NETDEV_FORMATTED_OUT_IP = '\n'.join([ + '++++++++++++++++++++++++++++++++++Net device info++++++++++++++++++++++' + '++++++++++++', + '+--------+------+------------------------------+------+-------+----------' + '---------+', + '| Device | Up | Address | Mask | Scope | Hw-Ad' + 'dress |', + '+--------+------+------------------------------+------+-------+----------' + '---------+', + '| lo | True | 127.0.0.1/8 | . | . | .' + ' |', + '| lo | True | ::1/128 | . | host | .' + ' |', + '| wlp3s0 | True | 192.168.1.3/24 | . | . | 84:3a:4b:' + '09:6f:ec |', + '| wlp3s0 | True | fe80::863a:4bff:fe09:6fec/64 | . | link | 84:3a:4b:' + '09:6f:ec |', + '+--------+------+------------------------------+------+-------+----------' + '---------+']) + ROUTE_FORMATTED_OUT = '\n'.join([ '+++++++++++++++++++++++++++++Route IPv4 info++++++++++++++++++++++++++' '+++', @@ -86,21 +162,113 @@ ROUTE_FORMATTED_OUT = '\n'.join([ '+-------+-------------+-------------+---------------+---------------+' '-----------------+-------+']) +ROUTE_FORMATTED_OUT_IP = '\n'.join([ + '+++++++++++++++++++++++++++Route IPv4 info+++++++++++++++++++++++++++', + '+-------+---------------+-------------+---------+-----------+-------+', + '| Route | Destination | Gateway | Genmask | Interface | Flags |', + '+-------+---------------+-------------+---------+-----------+-------+', + '| 0 | 0.0.0.0 | 192.168.1.1 | | br0 | G |', + '| 1 | 10.0.0.0/8 | 10.163.8.1 | | tun0 | G |', + '| 2 | 10.163.8.1 | 0.0.0.0 | | tun0 | |', + '| 3 | 137.65.0.0/16 | 10.163.8.1 | | tun0 | G |', + '+-------+---------------+-------------+---------+-----------+-------+', + '++++++++++++++++++++++++++++++++++++++++Route IPv6 info++++++++++++++' + '+++++++++++++++++++++++++++', + '+-------+--------+--------+--------+---------------------------------' + '+-----------------+-------+', + '| Route | Proto | Recv-Q | Send-Q | Local Address ' + '| Foreign Address | State |', + '+-------+--------+--------+--------+---------------------------------' + '+-----------------+-------+', + '| 0 | kernel | 0 | 0 | 2621:111:80c0:8080:12:160:68:53 ' + '| | |', + '| 1 | ra | 0 | 0 | 2621:111:80c0:8080::/64 ' + '| | |', + '| 2 | static | 0 | 0 | fe80::1 ' + '| | |', + '| 3 | kernel | 0 | 0 | fe80::/64 ' + '| | |', + '| 4 | static | 0 | 0 | :: ' + '| fe80::1 | |', + '| 5 | tcp6 | 0 | 0 | 2620:113:80c0:8000::/50 ' + '| | |', + '+-------+--------+--------+--------+---------------------------------' + '+-----------------+-------+']) + class TestNetInfo(CiTestCase): maxDiff = None + @mock.patch('cloudinit.netinfo.route_info') + def test_getdateway_route(self, m_route_info): + """getgateway finds the first gateway""" + m_route_info.return_value = SAMPLE_ROUTE_INFO + gateway = getgateway() + self.assertEqual('192.168.1.1[eth1]', gateway) + + @mock.patch('cloudinit.netinfo.util.which') @mock.patch('cloudinit.netinfo.util.subp') - def test_netdev_pformat(self, m_subp): + def test_netdev_pformat_ifconfig(self, m_subp, m_which): """netdev_pformat properly rendering network device information.""" m_subp.return_value = (SAMPLE_IFCONFIG_OUT, '') + m_which.side_effect = side_effect_use_ifconfig content = netdev_pformat() self.assertEqual(NETDEV_FORMATTED_OUT, content) + @mock.patch('cloudinit.netinfo.util.which') @mock.patch('cloudinit.netinfo.util.subp') - def test_route_pformat(self, m_subp): + def test_netdev_pformat_ip(self, m_subp, m_which): + """netdev_pformat properly rendering network device information.""" + m_subp.return_value = (SAMPLE_IP_A_OUT, '') + m_which.side_effect = side_effect_use_ip + content = netdev_pformat() + self.assertEqual(NETDEV_FORMATTED_OUT_IP, content) + + @mock.patch('cloudinit.netinfo.util.which') + @mock.patch('cloudinit.netinfo.util.subp') + def test_route_pformat_netstat(self, m_subp, m_which): """netdev_pformat properly rendering network device information.""" m_subp.return_value = (SAMPLE_ROUTE_OUT, '') + m_which.side_effect = side_effect_use_netstat content = route_pformat() self.assertEqual(ROUTE_FORMATTED_OUT, content) + + @mock.patch('cloudinit.netinfo.util.which') + @mock.patch('cloudinit.netinfo.util.subp') + def test_route_pformat_ip(self, m_subp, m_which): + """netdev_pformat properly rendering network device information.""" + m_subp.side_effect = side_effect_return_route_info + m_which.side_effect = side_effect_use_ip + content = route_pformat() + self.assertEqual(ROUTE_FORMATTED_OUT_IP, content) + + +def side_effect_use_ifconfig(tool): + if tool == 'ifconfig': + return True + else: + return False + + +def side_effect_use_ip(tool): + if tool == 'ip': + return True + else: + return False + + +def side_effect_use_netstat(tool): + if tool == 'netstat': + return True + else: + return False + + +def side_effect_return_route_info(cmd, rcs=None): + if '-4' in list(cmd): + return (SAMPLE_ROUTE_OUT_IP_V4, 0) + else: + return (SAMPLE_ROUTE_OUT_IP_V6, 0) + +# vi: ts=4 expandtab -- 2.13.6
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor