From abd07978e0711c39658d77ca87c7711451080be8 Mon Sep 17 00:00:00 2001 From: Xiayu <1013230155@qq.com> Date: Wed, 17 Feb 2016 01:45:05 +0000 Subject: [PATCH] Astara appliance oslo.rootwrap Use oslo.rootwrap to replace the default root_helper sudo. Change-Id: I5875cd647a4cc4f60f3058a98ea8a829cf056c43 Implements: blueprint astara-rootwrap --- ansible/tasks/astara.yml | 21 +++++++ ansible/templates/gunicorn | 1 + astara_router/api/v1/system.py | 2 +- astara_router/drivers/arp.py | 2 +- astara_router/drivers/base.py | 2 +- astara_router/drivers/bird.py | 8 +-- astara_router/drivers/dnsmasq.py | 9 +-- astara_router/drivers/hostname.py | 2 +- astara_router/drivers/ip.py | 4 +- astara_router/drivers/iptables.py | 10 +-- astara_router/drivers/loadbalancer/nginx.py | 2 +- astara_router/drivers/metadata.py | 10 +-- astara_router/drivers/ping.py | 6 +- .../elements/debug-user/package-installs.yaml | 1 + etc/rootwrap.conf | 27 ++++++++ etc/rootwrap.d/network.filters | 38 ++++++++++++ requirements.txt | 1 + scripts/etc/init.d/astara-router-api-server | 2 +- setup.cfg | 1 + test/unit/drivers/test_arp.py | 12 ++-- test/unit/drivers/test_bird.py | 14 +++-- test/unit/drivers/test_dnsmasq.py | 8 ++- test/unit/drivers/test_hostname.py | 9 ++- test/unit/drivers/test_ip.py | 62 +++++++++++-------- test/unit/drivers/test_iptables.py | 10 +-- 25 files changed, 190 insertions(+), 74 deletions(-) create mode 100644 ansible/templates/gunicorn create mode 100644 diskimage-builder/elements/debug-user/package-installs.yaml create mode 100644 etc/rootwrap.conf create mode 100644 etc/rootwrap.d/network.filters diff --git a/ansible/tasks/astara.yml b/ansible/tasks/astara.yml index 450f4e3..e2fadb5 100644 --- a/ansible/tasks/astara.yml +++ b/ansible/tasks/astara.yml @@ -29,12 +29,33 @@ - name: install gunicorn config file template: src=gunicorn.j2 dest=/etc/astara_gunicorn_config.py +- name: add gunicorn user + command: useradd -r gunicorn + - name: install init.d files copy: src={{playbook_dir}}/../scripts/etc/init.d/{{item}} dest=/etc/init.d/{{item}} mode=0555 with_items: - metadata - astara-router-api-server +- name: install rootwrap config file + copy: src={{playbook_dir}}/../etc/rootwrap.conf dest=/etc/rootwrap.conf mode=0555 + +- name: create /etc/rootwrap.d/ + file: path=/etc/rootwrap.d/ state=directory + +- name: install rootwrap rules file + copy: src={{playbook_dir}}/../etc/rootwrap.d/ dest=/etc/rootwrap.d/ mode=0555 + with_items: + - network.filters + +- stat: path=/etc/sudoers.d + register: sudoers_dir + +- name: install sudoer file + when: sudoers_dir.stat.exists == True + template: src=gunicorn dest=/etc/sudoers.d/gunicorn mode=0440 + - name: create /usr/local/share/astara/ file: path=/usr/local/share/astara state=directory diff --git a/ansible/templates/gunicorn b/ansible/templates/gunicorn new file mode 100644 index 0000000..54f6c86 --- /dev/null +++ b/ansible/templates/gunicorn @@ -0,0 +1 @@ +gunicorn ALL = (root) NOPASSWD: /usr/local/bin/astara-rootwrap /etc/rootwrap.conf * diff --git a/astara_router/api/v1/system.py b/astara_router/api/v1/system.py index c68e50d..8c6ed91 100644 --- a/astara_router/api/v1/system.py +++ b/astara_router/api/v1/system.py @@ -42,7 +42,7 @@ def _get_cache(): _cache = make_region().configure( 'dogpile.cache.dbm', arguments={ - "filename": "/etc/astara-state" + "filename": "/tmp/astara-state" } ) return _cache diff --git a/astara_router/drivers/arp.py b/astara_router/drivers/arp.py index 27741fa..5b8e9c4 100644 --- a/astara_router/drivers/arp.py +++ b/astara_router/drivers/arp.py @@ -83,7 +83,7 @@ class ARPManager(base.Manager): A class to interact with entries in the ARP cache. Currently only really provides support for deleting stuff from the cache. """ - EXECUTABLE = '/usr/sbin/arp' + EXECUTABLE = 'arp' def send_gratuitous_arp_for_floating_ips(self, config, generic_to_host): """ diff --git a/astara_router/drivers/base.py b/astara_router/drivers/base.py index 439db74..17632a2 100644 --- a/astara_router/drivers/base.py +++ b/astara_router/drivers/base.py @@ -24,7 +24,7 @@ class Manager(object): modules. """ - def __init__(self, root_helper='sudo'): + def __init__(self, root_helper='sudo astara-rootwrap /etc/rootwrap.conf'): """ Initializes Manager class. provides a facility to specify how this class accesses escalated privileges. Defaults to 'sudo'. diff --git a/astara_router/drivers/bird.py b/astara_router/drivers/bird.py index d8fbc4e..b88b4db 100644 --- a/astara_router/drivers/bird.py +++ b/astara_router/drivers/bird.py @@ -30,7 +30,7 @@ class BirdManager(base.Manager): """ A class to interact with BIRD, an internet routing protocol daemon. """ - def __init__(self, root_helper='sudo'): + def __init__(self, root_helper='sudo astara-rootwrap /etc/rootwrap.conf'): """ Initializes BirdManager class. @@ -59,11 +59,11 @@ class BirdManager(base.Manager): Restart the BIRD daemon using the system provided init scripts. """ try: - utils.execute(['/etc/init.d/bird6', 'status'], self.root_helper) + utils.execute(['service', 'bird6', 'status'], self.root_helper) except: # pragma no cover - utils.execute(['/etc/init.d/bird6', 'start'], self.root_helper) + utils.execute(['service', 'bird6', 'start'], self.root_helper) else: # pragma no cover - utils.execute(['/etc/init.d/bird6', 'reload'], self.root_helper) + utils.execute(['service', 'bird6', 'reload'], self.root_helper) def build_config(config, interface_map): diff --git a/astara_router/drivers/dnsmasq.py b/astara_router/drivers/dnsmasq.py index 11dbf69..7d90453 100644 --- a/astara_router/drivers/dnsmasq.py +++ b/astara_router/drivers/dnsmasq.py @@ -29,7 +29,7 @@ DEFAULT_LEASE = 86400 class DHCPManager(base.Manager): """A class to manage dnsmasq.""" - def __init__(self, root_helper='sudo'): + def __init__(self, root_helper='sudo astara-rootwrap /etc/rootwrap.conf'): """ Initializes DHCPManager class. @@ -45,7 +45,8 @@ class DHCPManager(base.Manager): """ for f in os.listdir(CONF_DIR): if f.endswith('.conf'): - os.remove(os.path.join(CONF_DIR, f)) + utils.execute(['rm', '-f', os.path.join(CONF_DIR, f)], + self.root_helper) def update_network_dhcp_config(self, ifname, network): """ @@ -139,7 +140,7 @@ class DHCPManager(base.Manager): Restarts dnsmasq service using the system provided init script. """ try: - utils.execute([RC_PATH, 'stop'], self.root_helper) + utils.execute(['service', 'dnsmasq', 'stop'], self.root_helper) except: pass @@ -149,7 +150,7 @@ class DHCPManager(base.Manager): remaining -= 1 try: utils.execute( - [RC_PATH, 'start'], self.root_helper + ['service', 'dnsmasq', 'start'], self.root_helper ) return except Exception: diff --git a/astara_router/drivers/hostname.py b/astara_router/drivers/hostname.py index 9115e52..b46acab 100644 --- a/astara_router/drivers/hostname.py +++ b/astara_router/drivers/hostname.py @@ -20,7 +20,7 @@ from astara_router import utils class HostnameManager(base.Manager): - EXECUTABLE = '/bin/hostname' + EXECUTABLE = 'hostname' def update(self, config): self.update_hostname(config) diff --git a/astara_router/drivers/ip.py b/astara_router/drivers/ip.py index 26f36e4..0b5cc10 100644 --- a/astara_router/drivers/ip.py +++ b/astara_router/drivers/ip.py @@ -39,9 +39,9 @@ class IPManager(base.Manager): configuration information. """ - EXECUTABLE = '/sbin/ip' + EXECUTABLE = 'ip' - def __init__(self, root_helper='sudo'): + def __init__(self, root_helper='sudo astara-rootwrap /etc/rootwrap.conf'): """Initializes resources for the IPManager class""" super(IPManager, self).__init__(root_helper) self.next_generic_index = 0 diff --git a/astara_router/drivers/iptables.py b/astara_router/drivers/iptables.py index f441416..2c3fc32 100644 --- a/astara_router/drivers/iptables.py +++ b/astara_router/drivers/iptables.py @@ -89,14 +89,14 @@ class IPTablesManager(base.Manager): netfilter-persistent as a plugin, so use that instead if it is available ''' - _init = '/etc/init.d/%s-persistent' - if os.path.isfile(_init % 'netfilter'): + _init = '%s-persistent' + if os.path.isfile('/etc/init.d/netfilter-persistent'): init = _init % 'netfilter' else: init = _init % 'iptables' utils.execute( - [init, 'restart'], + ['service', init, 'restart'], self.root_helper ) @@ -108,8 +108,8 @@ class IPTablesManager(base.Manager): :rtype: str ''' - v4 = utils.execute(['iptables', '-L', '-n']) - v6 = utils.execute(['ip6tables', '-L', '-n']) + v4 = utils.execute(['iptables', '-L', '-n'], self.root_helper) + v6 = utils.execute(['ip6tables', '-L', '-n'], self.root_helper) return v4 + v6 def get_external_network(self, config): diff --git a/astara_router/drivers/loadbalancer/nginx.py b/astara_router/drivers/loadbalancer/nginx.py index ba01ea9..f22cc26 100644 --- a/astara_router/drivers/loadbalancer/nginx.py +++ b/astara_router/drivers/loadbalancer/nginx.py @@ -33,7 +33,7 @@ class NginxLB(base.Manager): os.path.dirname(__file__), 'nginx.conf.template') INIT = 'nginx' - def __init__(self, root_helper='sudo'): + def __init__(self, root_helper='sudo astara-rootwrap /etc/rootwrap.conf'): """ Initializes DHCPManager class. diff --git a/astara_router/drivers/metadata.py b/astara_router/drivers/metadata.py index 0882312..19addc6 100644 --- a/astara_router/drivers/metadata.py +++ b/astara_router/drivers/metadata.py @@ -30,7 +30,7 @@ class MetadataManager(base.Manager): A class to provide facilities to interact with the Nova metadata service. """ - def __init__(self, root_helper='sudo'): + def __init__(self, root_helper='sudo astara-rootwrap /etc/rootwrap.conf'): """ Initializes MetataManager class. @@ -88,20 +88,20 @@ class MetadataManager(base.Manager): determined to be stopped. """ try: - execute(['/etc/init.d/metadata', 'status'], self.root_helper) + execute(['service', 'metadata', 'status'], self.root_helper) except: - execute(['/etc/init.d/metadata', 'start'], self.root_helper) + execute(['service', 'metadata', 'start'], self.root_helper) def restart(self): """ Restarts the metadata service using the init script. """ try: - execute(['/etc/init.d/metadata', 'stop'], self.root_helper) + execute(['service', 'metadata', 'stop'], self.root_helper) except: # failure is ok here pass - execute(['/etc/init.d/metadata', 'start'], self.root_helper) + execute(['service', 'metadata', 'start'], self.root_helper) def build_config(config): diff --git a/astara_router/drivers/ping.py b/astara_router/drivers/ping.py index 8aea4af..1f4076c 100644 --- a/astara_router/drivers/ping.py +++ b/astara_router/drivers/ping.py @@ -28,11 +28,11 @@ class PingManager(base.Manager): """ exe_map = { - 4: '/bin/ping', - 6: '/bin/ping6' + 4: 'ping', + 6: 'ping6' } - def __init__(self, root_helper='sudo'): + def __init__(self, root_helper='sudo astara-rootwrap /etc/rootwrap.conf'): """ Initializes PingManager class. diff --git a/diskimage-builder/elements/debug-user/package-installs.yaml b/diskimage-builder/elements/debug-user/package-installs.yaml new file mode 100644 index 0000000..e3fb5c5 --- /dev/null +++ b/diskimage-builder/elements/debug-user/package-installs.yaml @@ -0,0 +1 @@ +vim: diff --git a/etc/rootwrap.conf b/etc/rootwrap.conf new file mode 100644 index 0000000..cbb96cd --- /dev/null +++ b/etc/rootwrap.conf @@ -0,0 +1,27 @@ +# Configuration for astara-rootwrap +# This file should be owned by (and only-writeable by) the root user + +[DEFAULT] +# List of directories to load filter definitions from (separated by ','). +# These directories MUST all be only writeable by root ! +filters_path=/etc/rootwrap.d + +# List of directories to search executables in, in case filters do not +# explicitely specify a full path (separated by ',') +# If not specified, defaults to system PATH environment variable. +# These directories MUST all be only writeable by root ! +exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin + +# Enable logging to syslog +# Default value is False +use_syslog=False + +# Which syslog facility to use. +# Valid values include auth, authpriv, syslog, local0, local1... +# Default value is 'syslog' +syslog_log_facility=syslog + +# Which messages to log. +# INFO means log all usage +# ERROR means only log unsuccessful attempts +syslog_log_level=ERROR diff --git a/etc/rootwrap.d/network.filters b/etc/rootwrap.d/network.filters new file mode 100644 index 0000000..c1ffa50 --- /dev/null +++ b/etc/rootwrap.d/network.filters @@ -0,0 +1,38 @@ +# astara-rootwrap command filters for astara-appliance +# This file should be owned by (and only-writeable by) the root user + +[Filters] +# astara_router/drivers/bird.py: +mv_bird: RegExpFilter, mv, root, mv, /tmp/bird6\.conf, /etc/bird/bird6\.conf + +# astara_router/drivers/arp.py: 'arp'.. +arp: CommandFilter, /usr/sbin/arp, root + +# astara_router/drivers/dnsmasq.py: +mv_dnsmasq: RegExpFilter, mv, root, mv, /tmp/dnsmasq\.conf, /etc/dnsmasq\.d/.*\.conf +rm: CommandFilter, rm, root + +# astara_router/drivers/hostname.py: +hostname: CommandFilter, /bin/hostname, root +mv_hostname: RegExpFilter, mv, root, mv, /tmp/hostname, /etc/hostname +mv_hosts: RegExpFilter, mv, root, mv, /tmp/hosts, /etc/hosts + +# astara_router/drivers/ip.py: +ip: IpFilter, ip, root +sysctl: CommandFilter, sysctl, root +conntrack: CommandFilter, conntrack, root + +# astara_router/drivers/ping.py: +ping: CommandFilter, ping, root +ping6: CommandFilter, ping6, root + +# astara_router/drivers/iptables.py: +mv_rules: RegExpFilter, mv, root, mv, /tmp/ip.*tables\.rules, /etc/iptables/rules\.v.* +iptables: CommandFilter, iptables, root +ip6tables: CommandFilter, ip6tables, root + +# astara_router/drivers/metadata.py: +mv_metadata: RegExpFilter, mv, root, mv, /tmp/metadata\.conf, /etc/metadata\.conf + +# astara services +services: CommandFilter, service, root diff --git a/requirements.txt b/requirements.txt index a2d58f2..243fe9e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ netaddr!=0.7.16,>=0.7.12 # BSD eventlet>=0.18.2 # MIT requests!=2.9.0,>=2.8.1 # Apache-2.0 greenlet>=0.3.2 # MIT +oslo.rootwrap>=2.0.0 # Apache-2.0 diff --git a/scripts/etc/init.d/astara-router-api-server b/scripts/etc/init.d/astara-router-api-server index 8a5ace4..cdaa334 100755 --- a/scripts/etc/init.d/astara-router-api-server +++ b/scripts/etc/init.d/astara-router-api-server @@ -13,7 +13,7 @@ PATH=/bin:/usr/bin:/sbin:/usr/sbin DAEMON="/usr/bin/gunicorn" NAME="astara-router-api-server" -OPTIONS="--pythonpath /usr/local/share/astara -c /etc/astara_gunicorn_config.py astara_router.api.server:app" +OPTIONS="--user gunicorn --pythonpath /usr/local/share/astara -c /etc/astara_gunicorn_config.py astara_router.api.server:app" PIDFILE=/var/run/gunicorn.pid test -x $DAEMON || exit 0 diff --git a/setup.cfg b/setup.cfg index 7cbe06a..ecbd939 100644 --- a/setup.cfg +++ b/setup.cfg @@ -35,6 +35,7 @@ console_scripts = astara-api-dev-server=astara_router.api.server:main astara-metadata-proxy=astara_router.metadata_proxy:main astara-gratuitous-arp=astara_router.drivers.arp:send_gratuitous_arp + astara-rootwrap=oslo_rootwrap.cmd:main [build_sphinx] all_files = 1 diff --git a/test/unit/drivers/test_arp.py b/test/unit/drivers/test_arp.py index 7f95c31..0d1c1d5 100644 --- a/test/unit/drivers/test_arp.py +++ b/test/unit/drivers/test_arp.py @@ -131,16 +131,20 @@ class ARPTest(unittest2.TestCase): ) assert execute.call_args_list == [ mock.call( - ['astara-gratuitous-arp', 'eth1', '172.16.77.50'], 'sudo' + ['astara-gratuitous-arp', 'eth1', '172.16.77.50'], + 'sudo astara-rootwrap /etc/rootwrap.conf' ), mock.call( - ['astara-gratuitous-arp', 'eth1', '172.16.77.51'], 'sudo' + ['astara-gratuitous-arp', 'eth1', '172.16.77.51'], + 'sudo astara-rootwrap /etc/rootwrap.conf' ), mock.call( - ['astara-gratuitous-arp', 'eth1', '172.16.77.52'], 'sudo' + ['astara-gratuitous-arp', 'eth1', '172.16.77.52'], + 'sudo astara-rootwrap /etc/rootwrap.conf' ), mock.call( - ['astara-gratuitous-arp', 'eth1', '172.16.77.53'], 'sudo' + ['astara-gratuitous-arp', 'eth1', '172.16.77.53'], + 'sudo astara-rootwrap /etc/rootwrap.conf' ) ] diff --git a/test/unit/drivers/test_bird.py b/test/unit/drivers/test_bird.py index c0fd0c3..8e7cfd6 100644 --- a/test/unit/drivers/test_bird.py +++ b/test/unit/drivers/test_bird.py @@ -90,14 +90,16 @@ class BirdTestCase(TestCase): ) self.mock_execute.assert_called_once_with( ['mv', '/tmp/bird6.conf', '/etc/bird/bird6.conf'], - 'sudo' + 'sudo astara-rootwrap /etc/rootwrap.conf' ) def test_restart(self): self.mgr.restart() self.mock_execute.assert_has_calls([ - mock.call(['/etc/init.d/bird6', 'status'], 'sudo'), - mock.call(['/etc/init.d/bird6', 'reload'], 'sudo'), + mock.call(['service', 'bird6', 'status'], + 'sudo astara-rootwrap /etc/rootwrap.conf'), + mock.call(['service', 'bird6', 'reload'], + 'sudo astara-rootwrap /etc/rootwrap.conf'), ]) def test_restart_failure(self): @@ -105,8 +107,10 @@ class BirdTestCase(TestCase): execute.side_effect = [Exception('status failed!'), None] self.mgr.restart() execute.assert_has_calls([ - mock.call(['/etc/init.d/bird6', 'status'], 'sudo'), - mock.call(['/etc/init.d/bird6', 'start'], 'sudo'), + mock.call(['service', 'bird6', 'status'], + 'sudo astara-rootwrap /etc/rootwrap.conf'), + mock.call(['service', 'bird6', 'start'], + 'sudo astara-rootwrap /etc/rootwrap.conf'), ]) def test_build_config(self): diff --git a/test/unit/drivers/test_dnsmasq.py b/test/unit/drivers/test_dnsmasq.py index 8848519..0c307da 100644 --- a/test/unit/drivers/test_dnsmasq.py +++ b/test/unit/drivers/test_dnsmasq.py @@ -109,7 +109,7 @@ class DnsmasqTestCase(TestCase): ) self.mock_execute.assert_called_once_with( ['mv', '/tmp/dnsmasq.conf', '/etc/dnsmasq.d/em1.conf'], - 'sudo' + 'sudo astara-rootwrap /etc/rootwrap.conf' ) def test_build_dhcp_config(self): @@ -136,6 +136,8 @@ class DnsmasqTestCase(TestCase): def test_restart(self): self.mgr.restart() self.mock_execute.assert_has_calls([ - mock.call(['/etc/init.d/dnsmasq', 'stop'], 'sudo'), - mock.call(['/etc/init.d/dnsmasq', 'start'], 'sudo') + mock.call(['service', 'dnsmasq', 'stop'], + 'sudo astara-rootwrap /etc/rootwrap.conf'), + mock.call(['service', 'dnsmasq', 'start'], + 'sudo astara-rootwrap /etc/rootwrap.conf') ]) diff --git a/test/unit/drivers/test_hostname.py b/test/unit/drivers/test_hostname.py index 596f917..a08c235 100644 --- a/test/unit/drivers/test_hostname.py +++ b/test/unit/drivers/test_hostname.py @@ -41,8 +41,10 @@ class HostnameTestCase(TestCase): def test_update_hostname(self): self.mgr.update_hostname(CONFIG) self.mock_execute.assert_has_calls([ - mock.call(['/bin/hostname', 'astara'], 'sudo'), - mock.call(['mv', '/tmp/hostname', '/etc/hostname'], 'sudo') + mock.call(['hostname', 'astara'], + 'sudo astara-rootwrap /etc/rootwrap.conf'), + mock.call(['mv', '/tmp/hostname', '/etc/hostname'], + 'sudo astara-rootwrap /etc/rootwrap.conf') ]) def test_update_hosts(self): @@ -53,6 +55,7 @@ class HostnameTestCase(TestCase): ])) self.mgr.update_hosts(CONFIG) self.mock_execute.assert_has_calls([ - mock.call(['mv', '/tmp/hosts', '/etc/hosts'], 'sudo') + mock.call(['mv', '/tmp/hosts', '/etc/hosts'], + 'sudo astara-rootwrap /etc/rootwrap.conf') ]) self.mock_replace_file.assert_has_calls([expected]) diff --git a/test/unit/drivers/test_ip.py b/test/unit/drivers/test_ip.py index 465ea5b..06f4dd3 100644 --- a/test/unit/drivers/test_ip.py +++ b/test/unit/drivers/test_ip.py @@ -75,7 +75,7 @@ class IPTestCase(TestCase): self.assertEqual(interfaces, [iface_a, iface_b]) self.mock_execute.assert_has_calls( - [mock.call(['/sbin/ip', 'addr', 'show'])]) + [mock.call(['ip', 'addr', 'show'])]) def test_get_interface(self): iface_a = mock.Mock() @@ -93,7 +93,7 @@ class IPTestCase(TestCase): self.assertEqual(iface_a.ifname, 'ge0') self.mock_execute.assert_has_calls( - [mock.call(['/sbin/ip', 'addr', 'show'])]) + [mock.call(['ip', 'addr', 'show'])]) def test_ensure_mapping(self): attr = 'get_interfaces' @@ -149,7 +149,8 @@ class IPTestCase(TestCase): mgr.generic_mapping = {'ge0': 'em0'} mgr.up(iface) self.mock_execute.assert_has_calls( - [mock.call(['/sbin/ip', 'link', 'set', 'em0', 'up'], 'sudo')]) + [mock.call(['ip', 'link', 'set', 'em0', 'up'], + 'sudo astara-rootwrap /etc/rootwrap.conf')]) def test_down(self): iface = mock.Mock() @@ -164,7 +165,8 @@ class IPTestCase(TestCase): mgr.down(iface) self.mock_execute.assert_has_calls( - [mock.call(['/sbin/ip', 'link', 'set', 'em0', 'down'], 'sudo')]) + [mock.call(['ip', 'link', 'set', 'em0', 'down'], + 'sudo astara-rootwrap /etc/rootwrap.conf')]) def test_set_mtu(self): iface = mock.Mock() @@ -180,8 +182,8 @@ class IPTestCase(TestCase): mgr.set_mtu(iface) self.mock_execute.assert_has_calls( - [mock.call(['/sbin/ip', 'link', 'set', 'em0', 'mtu', '1280'], - 'sudo')]) + [mock.call(['ip', 'link', 'set', 'em0', 'mtu', '1280'], + 'sudo astara-rootwrap /etc/rootwrap.conf')]) def _update_interface_test_hlpr(self, new_iface, old_iface, ignore_link_local=True): @@ -263,7 +265,7 @@ class IPTestCase(TestCase): ) def test_address_add(self): - cmd = '/sbin/ip' + cmd = 'ip' v4 = netaddr.IPNetwork('192.168.105.2/24') v6 = netaddr.IPNetwork('fdca:3ba5:a17a:acda:20c:29ff:fe94:723d/64') iface = mock.Mock(all_addresses=[v4, v6], ifname='em0') @@ -278,19 +280,21 @@ class IPTestCase(TestCase): mock.call([ cmd, 'addr', 'add', '192.168.105.2/24', 'brd', '+', 'dev', 'em0' - ], 'sudo'), - mock.call([cmd, 'link', 'set', 'em0', 'up'], 'sudo'), + ], 'sudo astara-rootwrap /etc/rootwrap.conf'), + mock.call([cmd, 'link', 'set', 'em0', 'up'], + 'sudo astara-rootwrap /etc/rootwrap.conf'), mock.call([cmd, 'addr', 'show', 'em0']), mock.call([ cmd, '-6', 'addr', 'add', 'fdca:3ba5:a17a:acda:20c:29ff:fe94:723d/64', 'dev', 'em0' - ], 'sudo'), - mock.call([cmd, 'link', 'set', 'em0', 'up'], 'sudo'), + ], 'sudo astara-rootwrap /etc/rootwrap.conf'), + mock.call([cmd, 'link', 'set', 'em0', 'up'], + 'sudo astara-rootwrap /etc/rootwrap.conf'), mock.call([cmd, 'addr', 'show', 'em0']) ] def test_address_remove(self): - cmd = '/sbin/ip' + cmd = 'ip' v4 = netaddr.IPNetwork('192.168.105.2/24') v6 = netaddr.IPNetwork('fdca:3ba5:a17a:acda:20c:29ff:fe94:723d/64') iface = mock.Mock(all_addresses=[]) @@ -299,12 +303,15 @@ class IPTestCase(TestCase): mgr = ip.IPManager() mgr._update_addresses('em0', iface, old_iface) assert self.mock_execute.call_args_list == [ - mock.call([cmd, 'addr', 'del', str(v4), 'dev', 'em0'], 'sudo'), - mock.call(['conntrack', '-D', '-d', str(v4.ip)], 'sudo'), - mock.call(['conntrack', '-D', '-q', str(v4.ip)], 'sudo'), + mock.call([cmd, 'addr', 'del', str(v4), 'dev', 'em0'], + 'sudo astara-rootwrap /etc/rootwrap.conf'), + mock.call(['conntrack', '-D', '-d', str(v4.ip)], + 'sudo astara-rootwrap /etc/rootwrap.conf'), + mock.call(['conntrack', '-D', '-q', str(v4.ip)], + 'sudo astara-rootwrap /etc/rootwrap.conf'), mock.call([ cmd, '-6', 'addr', 'del', str(v6), 'dev', 'em0' - ], 'sudo'), + ], 'sudo astara-rootwrap /etc/rootwrap.conf'), ] def test_update_set(self): @@ -331,15 +338,18 @@ class IPTestCase(TestCase): assert self.mock_execute.call_args_list == [ mock.call([ - '/sbin/ip', 'addr', 'add', str(a), 'dev', 'em0' - ], 'sudo'), - mock.call(['/sbin/ip', 'link', 'set', 'em0', 'up'], 'sudo'), - mock.call(['/sbin/ip', 'addr', 'show', 'em0']), + 'ip', 'addr', 'add', str(a), 'dev', 'em0' + ], 'sudo astara-rootwrap /etc/rootwrap.conf'), + mock.call(['ip', 'link', 'set', 'em0', 'up'], + 'sudo astara-rootwrap /etc/rootwrap.conf'), + mock.call(['ip', 'addr', 'show', 'em0']), mock.call([ - '/sbin/ip', 'addr', 'del', str(c), 'dev', 'em0' - ], 'sudo'), - mock.call(['conntrack', '-D', '-d', str(c.ip)], 'sudo'), - mock.call(['conntrack', '-D', '-q', str(c.ip)], 'sudo'), + 'ip', 'addr', 'del', str(c), 'dev', 'em0' + ], 'sudo astara-rootwrap /etc/rootwrap.conf'), + mock.call(['conntrack', '-D', '-d', str(c.ip)], + 'sudo astara-rootwrap /etc/rootwrap.conf'), + mock.call(['conntrack', '-D', '-q', str(c.ip)], + 'sudo astara-rootwrap /etc/rootwrap.conf'), ] def test_update_set_no_diff(self): @@ -394,7 +404,7 @@ class TestDisableDAD(TestCase): assert self.mock_execute.call_args_list == [ mock.call([ 'sysctl', '-w', 'net.ipv6.conf.eth0.accept_dad=0' - ], 'sudo'), + ], 'sudo astara-rootwrap /etc/rootwrap.conf'), ] def test_dad_for_internal(self): @@ -409,7 +419,7 @@ class TestDisableDAD(TestCase): assert self.mock_execute.call_args_list == [ mock.call([ 'sysctl', '-w', 'net.ipv6.conf.eth2.accept_dad=0' - ], 'sudo'), + ], 'sudo astara-rootwrap /etc/rootwrap.conf'), ] def test_sysctl_failure(self): diff --git a/test/unit/drivers/test_iptables.py b/test/unit/drivers/test_iptables.py index ad6a9c1..e3829c8 100644 --- a/test/unit/drivers/test_iptables.py +++ b/test/unit/drivers/test_iptables.py @@ -163,11 +163,11 @@ class TestIPTablesRouterConfiguration(TestCase): assert self.execute.call_args_list == [ mock.call( ['mv', '/tmp/ip4tables.rules', '/etc/iptables/rules.v4'], - 'sudo' + 'sudo astara-rootwrap /etc/rootwrap.conf' ), mock.call( ['mv', '/tmp/ip6tables.rules', '/etc/iptables/rules.v6'], - 'sudo' + 'sudo astara-rootwrap /etc/rootwrap.conf' ) ] @@ -177,7 +177,8 @@ class TestIPTablesRouterConfiguration(TestCase): mgr = iptables.IPTablesManager() mgr.restart() assert self.execute.call_args_list == [ - mock.call(['/etc/init.d/iptables-persistent', 'restart'], 'sudo') + mock.call(['service', 'iptables-persistent', 'restart'], + 'sudo astara-rootwrap /etc/rootwrap.conf') ] @mock.patch('os.path.isfile') @@ -186,7 +187,8 @@ class TestIPTablesRouterConfiguration(TestCase): mgr = iptables.IPTablesManager() mgr.restart() assert self.execute.call_args_list == [ - mock.call(['/etc/init.d/netfilter-persistent', 'restart'], 'sudo') + mock.call(['service', 'netfilter-persistent', 'restart'], + 'sudo astara-rootwrap /etc/rootwrap.conf') ] def test_mixed_floating_ip_versions(self):