add tests and a dynamic config section generator

This commit is contained in:
Kevin Hanselman 2019-03-30 14:56:12 -04:00
parent f41f9d25d2
commit 5f5ce51ce7
3 changed files with 207 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.yaml

122
gen_cfg_section.py Normal file
View File

@ -0,0 +1,122 @@
import argparse
import os
import re
from urllib.request import urlopen
import yaml
def parse_cli_args():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument(
'api_versions',
nargs='+',
help=(
'Docker API version(s) to support. ' +
'If exactly two versions are passed, ' +
'it will act as a range.'
)
)
parser.add_argument(
'--yaml-dir',
help='Save and load Swagger YAML files from this directory'
)
parser.add_argument(
'--add-comments',
action='store_true',
help='Add comments to the haproxy.cfg output'
)
return parser.parse_args()
def parse_api_versions(api_versions):
if len(api_versions) == 2:
min_ver = int(float(api_versions[0]) * 100)
max_ver = int(float(api_versions[1]) * 100)
assert min_ver < max_ver
return [f'{ver / 100.0:.2f}' for ver in range(min_ver, max_ver + 1)]
return api_versions
def create_cfg_line(endpoint):
return r' http-request allow if {{ path,url_dec -m reg -i ^(/v[\d\.]+)?/{} }} {{ env({}) -m bool }}'.format(
endpoint, re.sub(r'[^A-Z]', '', endpoint.upper())
)
def create_cfg_comment(endpoint, api_versions):
version_nums = [float(ver) for ver in api_versions]
return ' # /{} first seen: v{:.2f}, last seen: v{:.2f}'.format(
endpoint,
min(version_nums),
max(version_nums),
)
def get_base_endpoints(swagger):
return set(
path_name.split('/')[1]
for path_name in swagger['paths'].keys()
)
def load_swagger_yaml(api_version, yaml_dir=None):
if yaml_dir:
yaml_path = os.path.join(
cli_args.yaml_dir,
f"docker_v{api_version.replace('.', '_')}.yaml"
)
if os.path.isfile(yaml_path):
print(f'Reading file {yaml_path!r}...')
with open(yaml_path) as fd:
return yaml.safe_load(fd)
swagger_url = 'https://docs.docker.com/engine/api/v{}/swagger.yaml'.format(
api_version
)
print(f'Downloading Docker API version {api_version}...')
with urlopen(swagger_url) as fd:
swagger = yaml.safe_load(fd)
if yaml_dir:
print(f'Writing file {yaml_path!r}...')
with open(yaml_path, 'w') as fd:
yaml.dump(swagger, fd)
return swagger
if __name__ == '__main__':
cli_args = parse_cli_args()
api_versions = parse_api_versions(cli_args.api_versions)
if cli_args.yaml_dir:
os.makedirs(cli_args.yaml_dir, exist_ok=True)
swaggers = {}
for api_version in api_versions:
swaggers[api_version] = load_swagger_yaml(
api_version,
yaml_dir=cli_args.yaml_dir
)
all_base_endpoints = {}
for api_version, swagger in swaggers.items():
for endpoint in get_base_endpoints(swagger):
if endpoint in all_base_endpoints:
all_base_endpoints[endpoint].append(api_version)
else:
all_base_endpoints[endpoint] = [api_version]
for base_endpoint, api_versions in sorted(all_base_endpoints.items()):
if cli_args.add_comments:
print()
print(create_cfg_comment(base_endpoint, api_versions))
print(create_cfg_line(base_endpoint))

84
run_tests.sh Executable file
View 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