mirror of
https://github.com/Tecnativa/docker-socket-proxy
synced 2025-01-03 04:10:55 +00:00
Add first version of tests
From https://github.com/Tecnativa/docker-socket-proxy/pull/14
This commit is contained in:
parent
a07d4ae4d9
commit
0a0b6f8f12
177
poetry.lock
generated
Normal file
177
poetry.lock
generated
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
[[package]]
|
||||||
|
name = "atomicwrites"
|
||||||
|
version = "1.4.0"
|
||||||
|
description = "Atomic file writes."
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "attrs"
|
||||||
|
version = "20.3.0"
|
||||||
|
description = "Classes Without Boilerplate"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"]
|
||||||
|
docs = ["furo", "sphinx", "zope.interface"]
|
||||||
|
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"]
|
||||||
|
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorama"
|
||||||
|
version = "0.4.4"
|
||||||
|
description = "Cross-platform colored terminal text."
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iniconfig"
|
||||||
|
version = "1.1.1"
|
||||||
|
description = "iniconfig: brain-dead simple config-ini parsing"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "packaging"
|
||||||
|
version = "20.4"
|
||||||
|
description = "Core utilities for Python packages"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
pyparsing = ">=2.0.2"
|
||||||
|
six = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pluggy"
|
||||||
|
version = "0.13.1"
|
||||||
|
description = "plugin and hook calling mechanisms for python"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["pre-commit", "tox"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "plumbum"
|
||||||
|
version = "1.6.9"
|
||||||
|
description = "Plumbum: shell combinators library"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.6,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "py"
|
||||||
|
version = "1.9.0"
|
||||||
|
description = "library with cross-python path, ini-parsing, io, code, log facilities"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pyparsing"
|
||||||
|
version = "2.4.7"
|
||||||
|
description = "Python parsing module"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pytest"
|
||||||
|
version = "6.1.2"
|
||||||
|
description = "pytest: simple powerful testing with Python"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.5"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
|
||||||
|
attrs = ">=17.4.0"
|
||||||
|
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||||
|
iniconfig = "*"
|
||||||
|
packaging = "*"
|
||||||
|
pluggy = ">=0.12,<1.0"
|
||||||
|
py = ">=1.8.2"
|
||||||
|
toml = "*"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
checkqa_mypy = ["mypy (==0.780)"]
|
||||||
|
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "six"
|
||||||
|
version = "1.15.0"
|
||||||
|
description = "Python 2 and 3 compatibility utilities"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.10.2"
|
||||||
|
description = "Python Library for Tom's Obvious, Minimal Language"
|
||||||
|
category = "dev"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
lock-version = "1.1"
|
||||||
|
python-versions = "^3.8"
|
||||||
|
content-hash = "aad93df5d769d433d8739fc1fb317b1d53d9e8ddd18efaaaf8a864d543734c5a"
|
||||||
|
|
||||||
|
[metadata.files]
|
||||||
|
atomicwrites = [
|
||||||
|
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
|
||||||
|
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
|
||||||
|
]
|
||||||
|
attrs = [
|
||||||
|
{file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"},
|
||||||
|
{file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"},
|
||||||
|
]
|
||||||
|
colorama = [
|
||||||
|
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
||||||
|
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
||||||
|
]
|
||||||
|
iniconfig = [
|
||||||
|
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
|
||||||
|
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
||||||
|
]
|
||||||
|
packaging = [
|
||||||
|
{file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"},
|
||||||
|
{file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"},
|
||||||
|
]
|
||||||
|
pluggy = [
|
||||||
|
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
|
||||||
|
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
|
||||||
|
]
|
||||||
|
plumbum = [
|
||||||
|
{file = "plumbum-1.6.9-py2.py3-none-any.whl", hash = "sha256:91418dcc66b58ab9d2e3b04b3d1e0d787dc45923154fb8b4a826bd9316dba0d6"},
|
||||||
|
{file = "plumbum-1.6.9.tar.gz", hash = "sha256:16b9e19d96c80f2e9d051ef5f04927b834a6ac0ce5d2768eb8662b5cd53e43df"},
|
||||||
|
]
|
||||||
|
py = [
|
||||||
|
{file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"},
|
||||||
|
{file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"},
|
||||||
|
]
|
||||||
|
pyparsing = [
|
||||||
|
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
|
||||||
|
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
|
||||||
|
]
|
||||||
|
pytest = [
|
||||||
|
{file = "pytest-6.1.2-py3-none-any.whl", hash = "sha256:4288fed0d9153d9646bfcdf0c0428197dba1ecb27a33bb6e031d002fa88653fe"},
|
||||||
|
{file = "pytest-6.1.2.tar.gz", hash = "sha256:c0a7e94a8cdbc5422a51ccdad8e6f1024795939cc89159a0ae7f0b316ad3823e"},
|
||||||
|
]
|
||||||
|
six = [
|
||||||
|
{file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
|
||||||
|
{file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"},
|
||||||
|
]
|
||||||
|
toml = [
|
||||||
|
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
|
||||||
|
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
||||||
|
]
|
16
pyproject.toml
Normal file
16
pyproject.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[tool.poetry]
|
||||||
|
name = "docker-socket-proxy"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
authors = ["Tecnativa S.L"]
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = "^3.8"
|
||||||
|
plumbum = "^1.6.9"
|
||||||
|
|
||||||
|
[tool.poetry.dev-dependencies]
|
||||||
|
pytest = "^6.1.2"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core>=1.0.0"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
84
tests/run_tests.sh
Executable file
84
tests/run_tests.sh
Executable file
@ -0,0 +1,84 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
proxy_container=docksockprox_test
|
||||||
|
socket_proxy=127.0.0.1:2375
|
||||||
|
|
||||||
|
start_proxy() {
|
||||||
|
echo "Starting $proxy_container with args: ${*}..."
|
||||||
|
docker run -d --name "$proxy_container" \
|
||||||
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
|
-p "${socket_proxy}:2375" \
|
||||||
|
"$@" \
|
||||||
|
tecnativa/docker-socket-proxy &>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_proxy() {
|
||||||
|
echo "Removing ${proxy_container}..."
|
||||||
|
docker rm -f "$proxy_container" &>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
docker_with_proxy() {
|
||||||
|
docker --host "$socket_proxy" "$@" 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
assert() {
|
||||||
|
assertion=$1
|
||||||
|
shift 1
|
||||||
|
if docker_with_proxy "$@" | grep -qi 'forbidden'; then
|
||||||
|
result='forbidden'
|
||||||
|
else
|
||||||
|
result='allowed'
|
||||||
|
fi
|
||||||
|
if [ "$assertion" == "$result" ]; then
|
||||||
|
printf '%s' 'PASS'
|
||||||
|
else
|
||||||
|
printf '%s' 'FAIL'
|
||||||
|
fi
|
||||||
|
echo " | assert 'docker $*' is $assertion"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
trap delete_proxy EXIT
|
||||||
|
|
||||||
|
start_proxy
|
||||||
|
assert allowed version
|
||||||
|
assert forbidden run --rm alpine
|
||||||
|
assert forbidden pull alpine
|
||||||
|
assert forbidden logs "$proxy_container"
|
||||||
|
assert forbidden wait "$proxy_container"
|
||||||
|
assert forbidden rm -f "$proxy_container"
|
||||||
|
assert forbidden restart "$proxy_container"
|
||||||
|
assert forbidden network ls
|
||||||
|
assert forbidden config ls
|
||||||
|
assert forbidden service ls
|
||||||
|
assert forbidden stack ls
|
||||||
|
assert forbidden secret ls
|
||||||
|
assert forbidden plugin ls
|
||||||
|
assert forbidden info
|
||||||
|
assert forbidden system info
|
||||||
|
assert forbidden build .
|
||||||
|
assert forbidden swarm init
|
||||||
|
|
||||||
|
delete_proxy
|
||||||
|
start_proxy -e CONTAINERS=1
|
||||||
|
assert allowed logs "$proxy_container"
|
||||||
|
assert allowed inspect "$proxy_container"
|
||||||
|
assert forbidden wait "$proxy_container"
|
||||||
|
assert forbidden run --rm alpine
|
||||||
|
assert forbidden rm -f "$proxy_container"
|
||||||
|
assert forbidden restart "$proxy_container"
|
||||||
|
|
||||||
|
delete_proxy
|
||||||
|
start_proxy -e POST=1
|
||||||
|
assert forbidden rm -f "$proxy_container"
|
||||||
|
assert forbidden pull alpine
|
||||||
|
assert forbidden run --rm alpine
|
||||||
|
assert forbidden network create foobar
|
||||||
|
|
||||||
|
delete_proxy
|
||||||
|
start_proxy -e NETWORKS=1 -e POST=1
|
||||||
|
assert allowed network ls
|
||||||
|
assert allowed network create foo
|
||||||
|
assert allowed network rm foo
|
90
tests/test_service.py
Normal file
90
tests/test_service.py
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
|
||||||
|
import pytest
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from plumbum import ProcessExecutionError, local
|
||||||
|
from plumbum.cmd import docker
|
||||||
|
from plumbum.machines.local import LocalCommand
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
CONTAINER_NAME = "docksockprox_test"
|
||||||
|
SOCKET_PROXY = "127.0.0.1:2375"
|
||||||
|
|
||||||
|
|
||||||
|
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(
|
||||||
|
"run",
|
||||||
|
"-d",
|
||||||
|
"--name", container_name,
|
||||||
|
"--privileged",
|
||||||
|
"-v", "/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"-p", f"{socket_proxy}:2375",
|
||||||
|
extra_args,
|
||||||
|
"tecnativa/docker-socket-proxy",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _stop_and_delete_proxy(
|
||||||
|
container_name=CONTAINER_NAME,
|
||||||
|
socket_proxy=SOCKET_PROXY,
|
||||||
|
):
|
||||||
|
logger.info(f"Removing {container_name}...")
|
||||||
|
docker(
|
||||||
|
"rm",
|
||||||
|
"-f",
|
||||||
|
container_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _query_docker_with_proxy(socket_proxy=SOCKET_PROXY, extra_args=None):
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
def _check_permission(assertion, extra_args=None):
|
||||||
|
if "forbidden" in _query_docker_with_proxy(extra_args=extra_args):
|
||||||
|
result = "forbidden"
|
||||||
|
else:
|
||||||
|
result = "allowed"
|
||||||
|
assert result == assertion
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_permissions():
|
||||||
|
try:
|
||||||
|
_start_proxy()
|
||||||
|
_check_permission("allowed", extra_args="version")
|
||||||
|
_check_permission("forbidden", ["run", "--rm", "alpine"])
|
||||||
|
_check_permission("forbidden", ["pull", "alpine"])
|
||||||
|
_check_permission("forbidden", ["logs", CONTAINER_NAME])
|
||||||
|
_check_permission("forbidden", ["wait", CONTAINER_NAME])
|
||||||
|
_check_permission("forbidden", ["rm", "-f", CONTAINER_NAME])
|
||||||
|
_check_permission("forbidden", ["restart", CONTAINER_NAME])
|
||||||
|
_check_permission("forbidden", ["network", "ls"])
|
||||||
|
_check_permission("forbidden", ["config", "ls"])
|
||||||
|
_check_permission("forbidden", ["service", "ls"])
|
||||||
|
_check_permission("forbidden", ["stack", "ls"])
|
||||||
|
_check_permission("forbidden", ["secret", "ls"])
|
||||||
|
_check_permission("forbidden", ["plugin", "ls"])
|
||||||
|
_check_permission("forbidden", ["info"])
|
||||||
|
_check_permission("forbidden", ["system", "info"])
|
||||||
|
_check_permission("forbidden", ["build", "."])
|
||||||
|
_check_permission("forbidden", ["swarm", "init"])
|
||||||
|
finally:
|
||||||
|
pass
|
||||||
|
_stop_and_delete_proxy()
|
Loading…
Reference in New Issue
Block a user