1
0
mirror of https://github.com/Tecnativa/docker-socket-proxy synced 2024-12-22 06:38:07 +00:00

Improve test configuration and execution

TT26468
This commit is contained in:
João Marques 2020-12-01 15:13:49 +00:00
parent f3366b55cb
commit 0c41d3aeb9

View File

@ -1,7 +1,9 @@
import json
import logging import logging
from contextlib import contextmanager
import pytest import pytest
from plumbum import ProcessExecutionError from plumbum import ProcessExecutionError, local
from plumbum.cmd import docker from plumbum.cmd import docker
logger = logging.getLogger() logger = logging.getLogger()
@ -16,204 +18,107 @@ def build_docker_image():
docker("build", "-t", "docker-socket-proxy:local", ".") docker("build", "-t", "docker-socket-proxy:local", ".")
def _start_proxy( def _start_proxy(env_vars_list):
container_name=CONTAINER_NAME, socket_proxy=SOCKET_PROXY, extra_args=None 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
logger.info(f"Starting {container_name} with args: {extra_args}...") cmd = [
docker(
"run", "run",
"-d", "-d",
"--name",
container_name,
"--privileged", "--privileged",
"-v", "-v",
"/var/run/docker.sock:/var/run/docker.sock", "/var/run/docker.sock:/var/run/docker.sock",
"-p", "-p",
f"{socket_proxy}:2375", "2375",
extra_args, ]
"docker-socket-proxy:local", 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( def _stop_and_delete_proxy(container):
container_name=CONTAINER_NAME, logger.info(f"Removing {container}...")
):
logger.info(f"Removing {container_name}...")
docker( docker(
"container",
"rm", "rm",
"-f", "-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: try:
_ret_code, stdout, stderr = docker.run( with local.env(DOCKER_HOST=f"127.0.0.1:{port}"):
( yield (docker, test_container)
"--host", finally:
socket_proxy, _stop_and_delete_proxy(container)
extra_args, docker("stop", test_container)
)
)
except ProcessExecutionError as result:
stdout = result.stdout
stderr = result.stderr
return stdout + stderr
def _check_permission(assertion, socket_proxy=SOCKET_PROXY, extra_args=None): def _query_docker_with_proxy(*command, allowed=True):
if "forbidden" in _query_docker_with_proxy( if allowed:
socket_proxy=socket_proxy, extra_args=extra_args docker(command)
):
result = "forbidden"
else: else:
result = "allowed" with pytest.raises(ProcessExecutionError):
assert result == assertion docker(command)
def test_default_permissions(): def test_default_permissions():
container_name = f"{CONTAINER_NAME}_1" with _docker_proxy() as (docker, test_container):
socket_proxy = "127.0.0.1:2375" _query_docker_with_proxy("version", allowed=True)
try: _query_docker_with_proxy("pull", "alpine", allowed=False)
_start_proxy(container_name=container_name, socket_proxy=socket_proxy) _query_docker_with_proxy(
_check_permission("allowed", socket_proxy=socket_proxy, extra_args="version") "run", "--rm", "alpine", "--name", test_container, allowed=False
_check_permission(
"forbidden", socket_proxy=socket_proxy, extra_args=["run", "--rm", "alpine"]
) )
_check_permission( _query_docker_with_proxy("logs", test_container, allowed=False)
"forbidden", socket_proxy=socket_proxy, extra_args=["pull", "alpine"] _query_docker_with_proxy("wait", test_container, allowed=False)
) _query_docker_with_proxy("rm", "-f", test_container, allowed=False)
_check_permission( _query_docker_with_proxy("restart", test_container, allowed=False)
"forbidden", socket_proxy=socket_proxy, extra_args=["logs", container_name] _query_docker_with_proxy("network", "ls", allowed=False)
) _query_docker_with_proxy("config", "ls", allowed=False)
_check_permission( _query_docker_with_proxy("service", "ls", allowed=False)
"forbidden", socket_proxy=socket_proxy, extra_args=["wait", container_name] _query_docker_with_proxy("stack", "ls", allowed=False)
) _query_docker_with_proxy("secret", "ls", allowed=False)
_check_permission( _query_docker_with_proxy("plugin", "ls", allowed=False)
"forbidden", _query_docker_with_proxy("info", allowed=False)
socket_proxy=socket_proxy, _query_docker_with_proxy("system", "info", allowed=False)
extra_args=["rm", "-f", container_name], _query_docker_with_proxy("build", ".", allowed=False)
) _query_docker_with_proxy("swarm", "init", allowed=False)
_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)
def test_container_permissions(): def test_container_permissions():
container_name = f"{CONTAINER_NAME}_2" with _docker_proxy(CONTAINERS=1) as (docker, test_container):
socket_proxy = "127.0.0.1:2376" _query_docker_with_proxy("logs", test_container, allowed=True)
try: _query_docker_with_proxy("inspect", test_container, allowed=True)
_start_proxy( _query_docker_with_proxy("wait", test_container, allowed=False)
container_name=container_name, _query_docker_with_proxy("run", "--rm", "alpine", allowed=False)
socket_proxy=socket_proxy, _query_docker_with_proxy("rm", "-f", test_container, allowed=False)
extra_args=["-e", "CONTAINERS=1"], _query_docker_with_proxy("restart", test_container, allowed=False)
)
_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)
def test_post_permissions(): def test_post_permissions():
container_name = f"{CONTAINER_NAME}_3" with _docker_proxy(POST=1) as (docker, test_container):
socket_proxy = "127.0.0.1:2377" _query_docker_with_proxy("rm", "-f", test_container, allowed=False)
try: _query_docker_with_proxy("pull", "alpine", allowed=False)
_start_proxy( _query_docker_with_proxy("run", "--rm", "alpine", allowed=False)
container_name=container_name, _query_docker_with_proxy("network", "create", "foobar", allowed=False)
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)
def test_network_post_permissions(): def test_network_post_permissions():
container_name = f"{CONTAINER_NAME}_4" with _docker_proxy(POST=1, NETWORKS=1) as (docker, test_container):
socket_proxy = "127.0.0.1:2378" _query_docker_with_proxy("network", "ls", allowed=True)
try: _query_docker_with_proxy("network", "create", "foo", allowed=True)
_start_proxy( _query_docker_with_proxy("network", "rm", "foo", allowed=True)
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)