Conditionally use python instead of cURL
The healthcheck_curl has always been a bit bonky with the proxies
management, especially the "no_proxy" environment variable: since there
isn't any real RFC describing the content of this variable, there isn't
any unified handling.
This leads to situation where an Operator puts some CIDR notation inside
this variable, while curl doesn't handle it.
This change adds a new python script. Since it uses python-requests, it
will have a proper support for the CIDR notation[1].
It will be called if and only if either NO_PROXY or no_proxy environment
variables are set and non-empty.
One can also force the script usage by passing HEALTHCHECK_CURL_PY=1,
such as:
podman exec -e "HEALTHCHECK_CURL_PY=1" container /healthchecks/you-healthcheck
The output is 100% iso-compatible, and if someone wants to know what
healthcheck is used, they can check the User-Agent on the target logs.
This change is motivated by, at least, the following existing issues:
https://bugzilla.redhat.com/show_bug.cgi?id=1837458
https://bugzilla.redhat.com/show_bug.cgi?id=1883657
[1] 589c454733/requests/utils.py (L663-L684)
Change-Id: If56cd0fa986ef193d036b73e0ab84a88d59147e3
This commit is contained in:
@@ -9,6 +9,7 @@ else
|
||||
fi
|
||||
: ${HEALTHCHECK_CURL_MAX_TIME:=10}
|
||||
: ${HEALTHCHECK_CURL_USER_AGENT:=curl-healthcheck}
|
||||
: ${HEALTHCHECK_CURL_PY_USER_AGENT:=pyrequests-healthcheck}
|
||||
: ${HEALTHCHECK_CURL_WRITE_OUT:='\n%{http_code} %{remote_ip}:%{remote_port} %{time_total} seconds\n'}
|
||||
: ${HEALTHCHECK_CURL_OUTPUT:='/dev/null'}
|
||||
|
||||
@@ -30,11 +31,19 @@ healthcheck_curl () {
|
||||
return 1
|
||||
fi
|
||||
export NSS_SDB_USE_CACHE=no
|
||||
curl -g -k -q -s -S --fail -o "${HEALTHCHECK_CURL_OUTPUT}" \
|
||||
if [ -n "${HEALTHCHECK_CURL_PY+x}" ] || [ -n "${no_proxy+x}" ] || [ -n "${NO_PROXY+x}" ]; then
|
||||
${HEALTHCHECK_SCRIPTS:-/usr/share/openstack-tripleo-common/healthcheck}/http-healthcheck.py \
|
||||
--max-time "${HEALTHCHECK_CURL_MAX_TIME}" \
|
||||
--user-agent "${HEALTHCHECK_CURL_PY_USER_AGENT}" \
|
||||
--write-out "${HEALTHCHECK_CURL_WRITE_OUT}" \
|
||||
"$@" || return 1
|
||||
else
|
||||
curl -g -k -q -s -S --fail -o "${HEALTHCHECK_CURL_OUTPUT}" \
|
||||
--max-time "${HEALTHCHECK_CURL_MAX_TIME}" \
|
||||
--user-agent "${HEALTHCHECK_CURL_USER_AGENT}" \
|
||||
--write-out "${HEALTHCHECK_CURL_WRITE_OUT}" \
|
||||
"$@" || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
healthcheck_port () {
|
||||
|
||||
44
healthcheck/http-healthcheck.py
Executable file
44
healthcheck/http-healthcheck.py
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/python3
|
||||
import argparse
|
||||
import os
|
||||
import requests
|
||||
|
||||
default_output = ("\n%(http_code)s %(remote_ip)s:%(remote_port)s "
|
||||
"%(time_total)s seconds\n")
|
||||
|
||||
parser = argparse.ArgumentParser(description='Check remote HTTP')
|
||||
parser.add_argument('uri', metavar='URI', type=str, nargs=1,
|
||||
help='Remote URI to check')
|
||||
parser.add_argument('--max-time', type=int, default=10,
|
||||
help=('Maximum time in seconds that you allow the'
|
||||
' whole operation to take.')
|
||||
)
|
||||
parser.add_argument('--user-agent', type=str, default='pyrequests-healthcheck',
|
||||
help=('Specify the User-Agent string to send to the'
|
||||
' HTTP server.')
|
||||
)
|
||||
parser.add_argument('--write-out', type=str, default=default_output,
|
||||
help=('Display information on stdout after a completed'
|
||||
' transfer.')
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
uri = args.uri[0]
|
||||
output = args.write_out.replace('%{', '%(').replace('}', ')s') \
|
||||
.replace('\\n', os.linesep)
|
||||
|
||||
headers = {'User-Agent': args.user_agent}
|
||||
with requests.get(uri, headers=headers, timeout=args.max_time,
|
||||
allow_redirects=True, stream=True, verify=False) as req:
|
||||
r_ip, r_port = req.raw._original_response.fp.raw._sock.getpeername()
|
||||
resp = {'http_code': req.status_code,
|
||||
'remote_ip': r_ip,
|
||||
'remote_port': r_port,
|
||||
'time_total': req.elapsed.total_seconds()
|
||||
}
|
||||
try:
|
||||
print(output % resp)
|
||||
except KeyError:
|
||||
print(default_output % resp)
|
||||
except ValueError:
|
||||
print(default_output % resp)
|
||||
Reference in New Issue
Block a user