From 0c41d3aeb9b97dee1c95cd19c2cc871cc596ba89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Marques?= Date: Tue, 1 Dec 2020 15:13:49 +0000 Subject: [PATCH] Improve test configuration and execution TT26468 --- tests/test_service.py | 247 +++++++++++++----------------------------- 1 file changed, 76 insertions(+), 171 deletions(-) diff --git a/tests/test_service.py b/tests/test_service.py index 9e4c318..9d149a0 100644 --- a/tests/test_service.py +++ b/tests/test_service.py @@ -1,7 +1,9 @@ +import json import logging +from contextlib import contextmanager import pytest -from plumbum import ProcessExecutionError +from plumbum import ProcessExecutionError, local from plumbum.cmd import docker logger = logging.getLogger() @@ -16,204 +18,107 @@ def build_docker_image(): docker("build", "-t", "docker-socket-proxy:local", ".") -def _start_proxy( - container_name=CONTAINER_NAME, socket_proxy=SOCKET_PROXY, extra_args=None -): - logger.info(f"Starting {container_name} with args: {extra_args}...") - docker( +def _start_proxy(env_vars_list): + logger.info(f"Starting docker-socket-proxy container with args: {env_vars_list}...") + # HACK: receive as array to make it easier to handle dynamic env vars for docker + cmd = [ "run", "-d", - "--name", - container_name, "--privileged", "-v", "/var/run/docker.sock:/var/run/docker.sock", "-p", - f"{socket_proxy}:2375", - extra_args, - "docker-socket-proxy:local", - ) + "2375", + ] + cmd.extend(env_vars_list) + cmd.append("docker-socket-proxy:local") + ret_code, stdout, stderr = docker.run(cmd) + # Get container info + container_id = stdout.strip() + container_data = json.loads(docker("inspect", container_id)) + socket_port = container_data[0]["NetworkSettings"]["Ports"]["2375/tcp"][0][ + "HostPort" + ] + return container_id, socket_port -def _stop_and_delete_proxy( - container_name=CONTAINER_NAME, -): - logger.info(f"Removing {container_name}...") +def _stop_and_delete_proxy(container): + logger.info(f"Removing {container}...") docker( + "container", "rm", "-f", - container_name, + container, ) -def _query_docker_with_proxy(socket_proxy=SOCKET_PROXY, extra_args=None): +@contextmanager +def _docker_proxy(**env_vars): + env_vars_list = [] + for var in env_vars: + env_vars_list.extend(["-e", f"{var}={env_vars[var]}"]) + container, port = _start_proxy(env_vars_list) + # start a test container for queries + test_container = docker("run", "--rm", "-d", "nginx").strip() try: - _ret_code, stdout, stderr = docker.run( - ( - "--host", - socket_proxy, - extra_args, - ) - ) - except ProcessExecutionError as result: - stdout = result.stdout - stderr = result.stderr - return stdout + stderr + with local.env(DOCKER_HOST=f"127.0.0.1:{port}"): + yield (docker, test_container) + finally: + _stop_and_delete_proxy(container) + docker("stop", test_container) -def _check_permission(assertion, socket_proxy=SOCKET_PROXY, extra_args=None): - if "forbidden" in _query_docker_with_proxy( - socket_proxy=socket_proxy, extra_args=extra_args - ): - result = "forbidden" +def _query_docker_with_proxy(*command, allowed=True): + if allowed: + docker(command) else: - result = "allowed" - assert result == assertion + with pytest.raises(ProcessExecutionError): + docker(command) def test_default_permissions(): - container_name = f"{CONTAINER_NAME}_1" - socket_proxy = "127.0.0.1:2375" - try: - _start_proxy(container_name=container_name, socket_proxy=socket_proxy) - _check_permission("allowed", socket_proxy=socket_proxy, extra_args="version") - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["run", "--rm", "alpine"] + with _docker_proxy() as (docker, test_container): + _query_docker_with_proxy("version", allowed=True) + _query_docker_with_proxy("pull", "alpine", allowed=False) + _query_docker_with_proxy( + "run", "--rm", "alpine", "--name", test_container, allowed=False ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["pull", "alpine"] - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["logs", container_name] - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["wait", container_name] - ) - _check_permission( - "forbidden", - socket_proxy=socket_proxy, - extra_args=["rm", "-f", container_name], - ) - _check_permission( - "forbidden", - socket_proxy=socket_proxy, - extra_args=["restart", container_name], - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["network", "ls"] - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["config", "ls"] - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["service", "ls"] - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["stack", "ls"] - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["secret", "ls"] - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["plugin", "ls"] - ) - _check_permission("forbidden", socket_proxy=socket_proxy, extra_args=["info"]) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["system", "info"] - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["build", "."] - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["swarm", "init"] - ) - finally: - _stop_and_delete_proxy(container_name=container_name) + _query_docker_with_proxy("logs", test_container, allowed=False) + _query_docker_with_proxy("wait", test_container, allowed=False) + _query_docker_with_proxy("rm", "-f", test_container, allowed=False) + _query_docker_with_proxy("restart", test_container, allowed=False) + _query_docker_with_proxy("network", "ls", allowed=False) + _query_docker_with_proxy("config", "ls", allowed=False) + _query_docker_with_proxy("service", "ls", allowed=False) + _query_docker_with_proxy("stack", "ls", allowed=False) + _query_docker_with_proxy("secret", "ls", allowed=False) + _query_docker_with_proxy("plugin", "ls", allowed=False) + _query_docker_with_proxy("info", allowed=False) + _query_docker_with_proxy("system", "info", allowed=False) + _query_docker_with_proxy("build", ".", allowed=False) + _query_docker_with_proxy("swarm", "init", allowed=False) def test_container_permissions(): - container_name = f"{CONTAINER_NAME}_2" - socket_proxy = "127.0.0.1:2376" - try: - _start_proxy( - container_name=container_name, - socket_proxy=socket_proxy, - extra_args=["-e", "CONTAINERS=1"], - ) - _check_permission( - "allowed", socket_proxy=socket_proxy, extra_args=["logs", container_name] - ) - _check_permission( - "allowed", socket_proxy=socket_proxy, extra_args=["inspect", container_name] - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["wait", container_name] - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["run", "--rm", "alpine"] - ) - _check_permission( - "forbidden", - socket_proxy=socket_proxy, - extra_args=["rm", "-f", container_name], - ) - _check_permission( - "forbidden", - socket_proxy=socket_proxy, - extra_args=["restart", container_name], - ) - finally: - _stop_and_delete_proxy(container_name=container_name) + with _docker_proxy(CONTAINERS=1) as (docker, test_container): + _query_docker_with_proxy("logs", test_container, allowed=True) + _query_docker_with_proxy("inspect", test_container, allowed=True) + _query_docker_with_proxy("wait", test_container, allowed=False) + _query_docker_with_proxy("run", "--rm", "alpine", allowed=False) + _query_docker_with_proxy("rm", "-f", test_container, allowed=False) + _query_docker_with_proxy("restart", test_container, allowed=False) def test_post_permissions(): - container_name = f"{CONTAINER_NAME}_3" - socket_proxy = "127.0.0.1:2377" - try: - _start_proxy( - container_name=container_name, - socket_proxy=socket_proxy, - extra_args=["-e", "POST=1"], - ) - _check_permission( - "forbidden", - socket_proxy=socket_proxy, - extra_args=["rm", "-f", container_name], - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["pull", "alpine"] - ) - _check_permission( - "forbidden", socket_proxy=socket_proxy, extra_args=["run", "--rm", "alpine"] - ) - _check_permission( - "forbidden", - socket_proxy=socket_proxy, - extra_args=["network", "create", "foobar"], - ) - finally: - _stop_and_delete_proxy(container_name=container_name) + with _docker_proxy(POST=1) as (docker, test_container): + _query_docker_with_proxy("rm", "-f", test_container, allowed=False) + _query_docker_with_proxy("pull", "alpine", allowed=False) + _query_docker_with_proxy("run", "--rm", "alpine", allowed=False) + _query_docker_with_proxy("network", "create", "foobar", allowed=False) def test_network_post_permissions(): - container_name = f"{CONTAINER_NAME}_4" - socket_proxy = "127.0.0.1:2378" - try: - _start_proxy( - container_name=container_name, - socket_proxy=socket_proxy, - extra_args=["-e", "POST=1", "-e", "NETWORKS=1"], - ) - _check_permission( - "allowed", socket_proxy=socket_proxy, extra_args=["network", "ls"] - ) - _check_permission( - "allowed", - socket_proxy=socket_proxy, - extra_args=["network", "create", "foo"], - ) - _check_permission( - "allowed", socket_proxy=socket_proxy, extra_args=["network", "rm", "foo"] - ) - finally: - _stop_and_delete_proxy(container_name=container_name) + with _docker_proxy(POST=1, NETWORKS=1) as (docker, test_container): + _query_docker_with_proxy("network", "ls", allowed=True) + _query_docker_with_proxy("network", "create", "foo", allowed=True) + _query_docker_with_proxy("network", "rm", "foo", allowed=True)