Warning: infrabin
exposes sensitive endpoints and should NEVER be used on the public Internet.
infrabin
is an HTTP server that exposes a set of JSON endpoints. It can be used to simulate blue/green deployments, to test routing and failover or as a general swiss-knife for your infrastructure.
docker run -d -p 8080:8080 maruina/infrabin
# Apply only what you need
kubectl apply -f k8s/namespace.yml
kubectl apply -f k8s/deployment.yml
kubectl apply -f k8s/service.yml
# Example ingress rule to be changed according the k8s configuration
cat <<EOF | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: infrabin
namespace: infrabin
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: infrabin.<DOMAIN>
http:
paths:
- path: /
backend:
serviceName: infrabin
servicePort: 8080
EOF
To override the default settings:
-e PORT=<PORT>
to changeinfrabin
listening port. Default to 8080.-e THREADS=<THREADS>
to changeuwsgi
threads number. Default to 8.-e MAX_DELAY=<MAX_DELAY>
to change the maximum value for the/delay
endpoint. Default to 120.-e MAX_RETRIES=<MAX_RETRIES>
to change the maximum value for the/retry
endpoint. Default to 3.-e MAX_SIZE=<MAX_SIZE>
to change the maximum value for the/bytes
endpoint. Default to 1024 * 1024 Kb (1 Mb).-e USE_ENVOY_PREFLIGHT=true
wrap theuwsgi
process around https://github.com/monzo/envoy-preflight to work with envoy and any other service mesh envoy-based. Default tofalse
.
GET /
- returns: a JSON with the server hostname and
{"message": "infrabin is running"}
.
- returns: a JSON with the server hostname and
GET /headers
- returns: a JSON with the request headers, method and origin IP address.
GET /networks
- returns: a JSON with the
AF_INET
address family info for all the network interfaces.
- returns: a JSON with the
GET /network/<interface>
- returns: a JSON with the
AF_INET
address family info of the target interface or404
if the network interface does not exist.
- returns: a JSON with the
GET /healthcheck/liveness
- returns: the JSON
{"message": "liveness probe healthy"}
if healthy or the status code503
if unhealthy.
- returns: the JSON
POST /healthcheck/liveness/pass
- returns:
204
on success, resetting the/healthcheck/liveness
endpoint to be healthy.
- returns:
POST /healthcheck/liveness/fail
- returns:
204
on success, forcing the/healthcheck/liveness
endpoint to be unhealthy.
- returns:
GET /healthcheck/readiness
- returns: the JSON
{"message": "readiness probe healthy"}
if healthy or the status code503
if unhealthy.
- returns: the JSON
POST /healthcheck/readiness/pass
- returns:
204
on success, resetting the/healthcheck/readiness
endpoint to be healthy.
- returns:
POST /healthcheck/readiness/fail
- returns:
204
on success, forcing the/healthcheck/readiness
endpoint to be unhealthy.
- returns:
GET /env/<env_var>
- returns: the value of
env_var
or404
if the environment variable does not exist.
- returns: the value of
GET /aws/<metadata_endpoint>
- returns: the value of the target AWS
metadata_endpoint
,501
ifinfrabin
can not open the AWS metadata URL, or404
if the metadata endpoint does not exist. See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html#instancedata-data-categories for the available endpoints.
- returns: the value of the target AWS
GET /connectivity
- returns: the JSON
{"dns":{"status": "ok"}, "egress": {"status": "ok"}}
ifinfrabin
can resolvegoogle.com
using Google's DNS and can connect tohttps://www.google.com
. If a test fails,infrabin
returns"status": "error"
and thereason
.
- returns: the JSON
POST /connectivity
- arguments (JSON):
nameservers
(optional): a list of DNS nameserverquery
(optional): the DNS domain to resolveegress_url
(optional): the remote url to open
- returns: same as
GET /connectivity
or400
if the request is malformed.
- arguments (JSON):
GET /gzip
- returns: the JSON
{"message": "this is gzip compressed"}
gzip compressed.
- returns: the JSON
POST /proxy
- arguments (JSON):
url
(required): the proxy urlmethod
(optional): the HTTP method to use with the proxypayload
(optional): the JSON data to pass to the proxy
- returns:
400
if the request if malformed or a JSON with the a response for every request. If successful, the response containsstatus: ok
, thestatus_code
and theheaders
. If unsuccessful, the response containsstatus: error
and thereason
. If the environment variablehttp_proxy
is set,infrabin
will make the request through the proxy.
- arguments (JSON):
GET /delay/<sec>
- returns:
200
aftermin(<sec>, <MAX_DELAY>)
seconds.
- returns:
GET /status/<status_code>
- returns: the requested
status_code
.
- returns: the requested
GET /retry
- returns:
503
for<MAX_RETRIES>
times, then one200
.
- returns:
GET /retry/max_retries
- returns: the current value for the maximum number of retries.
GET, POST /bytes/<n>
- returns:
200
on success andmin(n, <MAX_SIZE>)
binary payload.
- returns:
GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH /mirror
- returns: a response with the same request headers and data sent to
infrabin
.
- returns: a response with the same request headers and data sent to
GET /fibonacci/<n>
- returns: a JSON with the nth Fibonacci number.
POST /log
- arguments (JSON):
message
(required): a string to logseverity
(optional, default toINFO
): a valid Python logging level
- returns:
200
on success or400
if the request is malformed.
- arguments (JSON):
infrabin
exports Prometheus metrics at the /metrics
endpoint.
POST /status
curl -d '{"nameservers":["208.67.222.222"],"query":"facebook.com","egress_url":"https://www.facebook.com"}' -H "Content-Type: application/json" -X POST localhost:8080/status
{
"dns": {
"status": "ok"
},
"egress": {
"status": "ok"
}
}
POST /proxy
curl -d '[{"url":"https://www.google.com"},{"url":"http://httpbin.org/post","method":"POST","payload":{"key":"42"}}]' -H "Content-Type: application/json" -X POST localhost:8080/proxy
{
"http://httpbin.org/post": {
"headers": {
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Origin": "*",
"Connection": "keep-alive",
"Content-Length": "435",
"Content-Type": "application/json",
"Date": "Sat, 19 Aug 2017 23:39:35 GMT",
"Server": "meinheld/0.6.1",
"Via": "1.1 vegur",
"X-Powered-By": "Flask",
"X-Processed-Time": "0.00157999992371"
},
"status": "ok",
"status_code": 200
},
"https://www.google.com": {
"headers": {
"Alt-Svc": "quic=\":443\"; ma=2592000; v=\"39,38,37,35\"",
"Cache-Control": "private, max-age=0",
"Content-Encoding": "gzip",
"Content-Type": "text/html; charset=ISO-8859-1",
"Date": "Sat, 19 Aug 2017 23:39:35 GMT",
"Expires": "-1",
"P3P": "CP=\"This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info.\"",
"Server": "gws",
"Set-Cookie": "NID=110=gR5VUAdefT9VbTSdOHEaiP-_ryClfvAV3ovON-uOh7d59L8YsQjkQsbDwSNMwEl0JOj-7aXIQnbceL5WGZGnmbz9GFWFHsHPqRsCPaquyHIsboWMNkzhVr4Te2E6-D94; expires=Sun, 18-Feb-2018 23:39:35 GMT; path=/; domain=.google.co.uk; HttpOnly",
"Transfer-Encoding": "chunked",
"X-Frame-Options": "SAMEORIGIN",
"X-XSS-Protection": "1; mode=block"
},
"status": "ok",
"status_code": 200
}
}
GET /fibonacci/10
curl localhost:8080/fibonacci/10
{
"response": 55
}
Clone the repository and create a local Python 3 virtual environment
brew install pipenv
git clone git@github.com:maruina/infrabin.git
cd infrabin
pipenv --python 3.7
pipenv shell
make install-dev
Run infrabin
locally
pipenv shell
make run-dev
Run the tests
pipenv shell
make test