forked from bortzmeyer/check_expire
Timeouts in HTTP requests
This commit is contained in:
parent
a3a1f8c0d4
commit
6b4f5b228e
38
check_expire
38
check_expire
@ -43,10 +43,10 @@ domain = None
|
|||||||
critical_t = datetime.timedelta(days=2)
|
critical_t = datetime.timedelta(days=2)
|
||||||
warning_t = datetime.timedelta(days=7)
|
warning_t = datetime.timedelta(days=7)
|
||||||
unixtime = False
|
unixtime = False
|
||||||
# TODO implement timeout for HTTPS requests. -t option. Does Requests allow it?
|
timeout = 20 # Seconds
|
||||||
|
|
||||||
def usage(msg=None):
|
def usage(msg=None):
|
||||||
print("Usage: %s -H domain-name [-c critical -w warning -u]" % sys.argv[0], end="")
|
print("Usage: %s -H domain-name [-c critical -w warning -u -t timeout]" % sys.argv[0], end="")
|
||||||
if msg is not None and msg != "":
|
if msg is not None and msg != "":
|
||||||
print(" (%s)" % msg)
|
print(" (%s)" % msg)
|
||||||
else:
|
else:
|
||||||
@ -73,6 +73,13 @@ def warning(msg=None):
|
|||||||
details()
|
details()
|
||||||
sys.exit(STATE_WARNING)
|
sys.exit(STATE_WARNING)
|
||||||
|
|
||||||
|
def unknown(msg=None):
|
||||||
|
if msg is None:
|
||||||
|
msg = "Unknown"
|
||||||
|
print("%s UNKNOWN: %s" % (domain, msg), end="")
|
||||||
|
details()
|
||||||
|
sys.exit(STATE_UNKNOWN)
|
||||||
|
|
||||||
def ok(msg=None):
|
def ok(msg=None):
|
||||||
if msg is None:
|
if msg is None:
|
||||||
msg = "Unknown message but everything is OK"
|
msg = "Unknown message but everything is OK"
|
||||||
@ -81,8 +88,10 @@ def ok(msg=None):
|
|||||||
sys.exit(STATE_OK)
|
sys.exit(STATE_OK)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
optlist, args = getopt.getopt (sys.argv[1:], "c:hH:uvVw:",
|
optlist, args = getopt.getopt (sys.argv[1:], "c:hH:t:uvVw:",
|
||||||
["critical=", "expiration", "help", "unixtime", "verbose", "version", "warning="])
|
["critical=", "expiration", "help",
|
||||||
|
"timeout=", "unixtime", "verbose",
|
||||||
|
"version", "warning="])
|
||||||
for option, value in optlist:
|
for option, value in optlist:
|
||||||
if option == "--critical" or option == "-c":
|
if option == "--critical" or option == "-c":
|
||||||
critical_t = datetime.timedelta(days=int(value))
|
critical_t = datetime.timedelta(days=int(value))
|
||||||
@ -91,6 +100,10 @@ try:
|
|||||||
sys.exit(STATE_OK)
|
sys.exit(STATE_OK)
|
||||||
elif option == "--hostname" or option == "-H":
|
elif option == "--hostname" or option == "-H":
|
||||||
domain = value
|
domain = value
|
||||||
|
elif option == "--timeout" or option == "-t":
|
||||||
|
timeout = int(value)
|
||||||
|
elif option == "--unixtime" or option == "-u":
|
||||||
|
unixtime = True
|
||||||
elif option == "--verbose" or option == "-v":
|
elif option == "--verbose" or option == "-v":
|
||||||
verbose = True
|
verbose = True
|
||||||
elif option == "--version" or option == "-V":
|
elif option == "--version" or option == "-V":
|
||||||
@ -98,8 +111,6 @@ try:
|
|||||||
sys.exit(STATE_OK)
|
sys.exit(STATE_OK)
|
||||||
elif option == "--warning" or option == "-w":
|
elif option == "--warning" or option == "-w":
|
||||||
warning_t = datetime.timedelta(days=int(value))
|
warning_t = datetime.timedelta(days=int(value))
|
||||||
elif option == "--unixtime" or option == "-u":
|
|
||||||
unixtime = True
|
|
||||||
else:
|
else:
|
||||||
# Should never occur, it is trapped by getopt
|
# Should never occur, it is trapped by getopt
|
||||||
print("Unknown option %s" % option)
|
print("Unknown option %s" % option)
|
||||||
@ -113,13 +124,19 @@ if len(args) != 0:
|
|||||||
if domain is None:
|
if domain is None:
|
||||||
usage("-H is mandatory")
|
usage("-H is mandatory")
|
||||||
sys.exit(STATE_UNKNOWN)
|
sys.exit(STATE_UNKNOWN)
|
||||||
database = ianardap.IanaRDAPDatabase()
|
try:
|
||||||
|
database = ianardap.IanaRDAPDatabase()
|
||||||
|
except Exception as e:
|
||||||
|
unknown("Exception when retrieving the IANA database: \"%s\"" % e)
|
||||||
server = database.find(domain)
|
server = database.find(domain)
|
||||||
if server is None:
|
if server is None:
|
||||||
error("No RDAP server found for %s" % domain)
|
unknown("No RDAP server found for %s" % domain)
|
||||||
if server.endswith("/"):
|
if server.endswith("/"):
|
||||||
server = server[:-1] # Donuts RDAP server balks when there are two slashes and reply 404
|
server = server[:-1] # Donuts RDAP server balks when there are two slashes and reply 404
|
||||||
response = requests.get("%s/domain/%s" % (server, domain))
|
try:
|
||||||
|
response = requests.get("%s/domain/%s" % (server, domain), timeout=timeout)
|
||||||
|
except requests.exceptions.Timeout:
|
||||||
|
unknown("Timeout when trying to reach %s" % server)
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
error("Invalid RDAP return code: %s" % response.status_code)
|
error("Invalid RDAP return code: %s" % response.status_code)
|
||||||
rdap = json.loads(response.content)
|
rdap = json.loads(response.content)
|
||||||
@ -136,8 +153,7 @@ for event in rdap["events"]:
|
|||||||
dt = re.sub(r"\+([0-9]{2}):([0-9]{2})$", r"+\1\2", event["eventDate"])
|
dt = re.sub(r"\+([0-9]{2}):([0-9]{2})$", r"+\1\2", event["eventDate"])
|
||||||
expiration = datetime.datetime.strptime(dt, RFC3339TZ)
|
expiration = datetime.datetime.strptime(dt, RFC3339TZ)
|
||||||
else:
|
else:
|
||||||
print("No recognized format for datetime \"%s\"" % event["eventDate"])
|
unknown("No recognized format for datetime \"%s\"" % event["eventDate"])
|
||||||
sys.exit(STATE_UNKNOWN)
|
|
||||||
now = datetime.datetime.now(tz=UTCINFO)
|
now = datetime.datetime.now(tz=UTCINFO)
|
||||||
if unixtime == True:
|
if unixtime == True:
|
||||||
print(int(expiration.strftime("%s")))
|
print(int(expiration.strftime("%s")))
|
||||||
|
@ -17,6 +17,7 @@ import fcntl
|
|||||||
IANABASE = "https://data.iana.org/rdap/dns.json"
|
IANABASE = "https://data.iana.org/rdap/dns.json"
|
||||||
CACHE = os.environ["HOME"] + "/.ianardapcache.json"
|
CACHE = os.environ["HOME"] + "/.ianardapcache.json"
|
||||||
MAXAGE = 24 # Hours
|
MAXAGE = 24 # Hours
|
||||||
|
IANATIMEOUT = 10
|
||||||
|
|
||||||
class IanaRDAPDatabase():
|
class IanaRDAPDatabase():
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ class IanaRDAPDatabase():
|
|||||||
self.unlock()
|
self.unlock()
|
||||||
else:
|
else:
|
||||||
self.unlock()
|
self.unlock()
|
||||||
response = requests.get(IANABASE)
|
response = requests.get(IANABASE, timeout=IANATIMEOUT)
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
raise Exception("Invalid HTTPS return code when trying to get %s: %s" % (IANABASE, response.status_code))
|
raise Exception("Invalid HTTPS return code when trying to get %s: %s" % (IANABASE, response.status_code))
|
||||||
content = response.content
|
content = response.content
|
||||||
|
12
tests.yaml
12
tests.yaml
@ -33,7 +33,7 @@ tests:
|
|||||||
args:
|
args:
|
||||||
- '-H'
|
- '-H'
|
||||||
- 'bie.re'
|
- 'bie.re'
|
||||||
retcode: 2
|
retcode: 3
|
||||||
partstdout: 'No RDAP server'
|
partstdout: 'No RDAP server'
|
||||||
|
|
||||||
# 2021-07-05: no expiration in RDAP for this TLD (but there is one
|
# 2021-07-05: no expiration in RDAP for this TLD (but there is one
|
||||||
@ -45,6 +45,16 @@ tests:
|
|||||||
retcode: 2
|
retcode: 2
|
||||||
partstdout: 'No expiration found'
|
partstdout: 'No expiration found'
|
||||||
|
|
||||||
|
# Far away and slow, timeout is expected
|
||||||
|
- exe: './check_expire'
|
||||||
|
args:
|
||||||
|
- '-t'
|
||||||
|
- '1'
|
||||||
|
- '-H'
|
||||||
|
- 'nic.ar'
|
||||||
|
retcode: 3
|
||||||
|
partstdout: 'Timeout'
|
||||||
|
|
||||||
- exe: './check_expire'
|
- exe: './check_expire'
|
||||||
args:
|
args:
|
||||||
- '-H'
|
- '-H'
|
||||||
|
Loading…
Reference in New Issue
Block a user