Compare commits
No commits in common. "ae00a81f7998d49e0ae6b07068843d9281620919" and "6b4f5b228eb37582313be748623199ab006706c1" have entirely different histories.
ae00a81f79
...
6b4f5b228e
|
@ -11,7 +11,6 @@ check_expire follows the usual Nagios rules. The options are:
|
||||||
* -w: warning threshold in days
|
* -w: warning threshold in days
|
||||||
* -v: verbose details in output
|
* -v: verbose details in output
|
||||||
* -u: unixtime output
|
* -u: unixtime output
|
||||||
* -t: timeout for RDAP requetss (in seconds)
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
@ -31,7 +30,6 @@ object CheckCommand "expiration" {
|
||||||
"-H" = "$address$",
|
"-H" = "$address$",
|
||||||
"-c" = "$expiration_critical$",
|
"-c" = "$expiration_critical$",
|
||||||
"-w" = "$expiration_warning$",
|
"-w" = "$expiration_warning$",
|
||||||
"-t" = "$expiration_timeout$",
|
|
||||||
"-v" = { set_if = "$expiration_verbose$" }
|
"-v" = { set_if = "$expiration_verbose$" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,8 @@ def usage(msg=None):
|
||||||
|
|
||||||
def details():
|
def details():
|
||||||
if verbose:
|
if verbose:
|
||||||
print(" RDAP database \"%s\", version %s published on %s, retrieved on %s, RDAP server is %s" % \
|
print(" RDAP database \"%s\", version %s published on %s, RDAP server is %s" % \
|
||||||
(database.description, database.version, database.publication, database.retrieved, server))
|
(database.description, database.version, database.publication, server))
|
||||||
else:
|
else:
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
|
|
|
@ -12,14 +12,12 @@ import datetime
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
|
||||||
import fcntl
|
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 # Seconds
|
IANATIMEOUT = 10
|
||||||
MAXTESTS = 3 # Maximum attempts to get the database
|
|
||||||
|
|
||||||
class IanaRDAPDatabase():
|
class IanaRDAPDatabase():
|
||||||
|
|
||||||
|
@ -28,49 +26,22 @@ class IanaRDAPDatabase():
|
||||||
cache_valid = False
|
cache_valid = False
|
||||||
self.cachefile = cachefile
|
self.cachefile = cachefile
|
||||||
self.lockname = self.cachefile + ".lock"
|
self.lockname = self.cachefile + ".lock"
|
||||||
loaded = False
|
self.lock()
|
||||||
tests = 0
|
if os.path.exists(cachefile) and \
|
||||||
errmsg = "No error"
|
datetime.datetime.fromtimestamp(os.path.getmtime(cachefile)) >= \
|
||||||
while not loaded and tests < MAXTESTS:
|
(datetime.datetime.utcnow() - datetime.timedelta(hours = maxage)):
|
||||||
self.lock()
|
cache = open(cachefile, "rb")
|
||||||
if os.path.exists(cachefile) and \
|
content = cache.read()
|
||||||
datetime.datetime.fromtimestamp(os.path.getmtime(cachefile)) > \
|
cache.close()
|
||||||
(datetime.datetime.now() - datetime.timedelta(hours = maxage)):
|
cache_valid = True
|
||||||
cache = open(cachefile, "rb")
|
self.unlock()
|
||||||
content = cache.read()
|
else:
|
||||||
cache.close()
|
self.unlock()
|
||||||
self.unlock()
|
response = requests.get(IANABASE, timeout=IANATIMEOUT)
|
||||||
try:
|
if response.status_code != 200:
|
||||||
database = json.loads(content)
|
raise Exception("Invalid HTTPS return code when trying to get %s: %s" % (IANABASE, response.status_code))
|
||||||
loaded = True
|
content = response.content
|
||||||
self.retrieved = datetime.datetime.fromtimestamp(os.path.getmtime(cachefile))
|
database = json.loads(content)
|
||||||
cache_valid = True
|
|
||||||
except json.decoder.JSONDecodeError:
|
|
||||||
tests += 1
|
|
||||||
errmsg = "Invalid JSON content in %s" % cachefile
|
|
||||||
# Delete it without mercy
|
|
||||||
os.remove(cachefile)
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
self.unlock()
|
|
||||||
response = requests.get(IANABASE, timeout=IANATIMEOUT)
|
|
||||||
if response.status_code != 200:
|
|
||||||
time.sleep(2)
|
|
||||||
tests += 1
|
|
||||||
errmsg = "Invalid HTTPS return code when trying to get %s: %s" % (IANABASE, response.status_code)
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
loaded = True
|
|
||||||
self.retrieved = datetime.datetime.now()
|
|
||||||
try:
|
|
||||||
content = response.content
|
|
||||||
database = json.loads(content)
|
|
||||||
except json.decoder.JSONDecodeError:
|
|
||||||
tests += 1
|
|
||||||
errmsg = "Invalid JSON retrieved from %s" % IANABASE
|
|
||||||
continue
|
|
||||||
if not loaded:
|
|
||||||
raise Exception("Cannot read IANA database: %s" % errmsg)
|
|
||||||
self.description = database["description"]
|
self.description = database["description"]
|
||||||
self.publication = database["publication"]
|
self.publication = database["publication"]
|
||||||
self.version = database["version"]
|
self.version = database["version"]
|
||||||
|
@ -96,8 +67,6 @@ class IanaRDAPDatabase():
|
||||||
|
|
||||||
def find(self, domain):
|
def find(self, domain):
|
||||||
""" Get the RDAP server for a given domain name. None if there is none."""
|
""" Get the RDAP server for a given domain name. None if there is none."""
|
||||||
if domain.endswith("."):
|
|
||||||
domain = domain[:-1]
|
|
||||||
labels = domain.split(".")
|
labels = domain.split(".")
|
||||||
tld = labels[len(labels)-1]
|
tld = labels[len(labels)-1]
|
||||||
if tld in self.services:
|
if tld in self.services:
|
||||||
|
@ -107,8 +76,8 @@ class IanaRDAPDatabase():
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
rdap = IanaRDAPDatabase(maxage=1)
|
rdap = IanaRDAPDatabase(maxage=1)
|
||||||
print("Database \"%s\", version %s published on %s, retrieved on %s, %i services" % \
|
print("Database \"%s\", version %s published on %s, %i services" % \
|
||||||
(rdap.description, rdap.version, rdap.publication, rdap.retrieved, len(rdap.services)))
|
(rdap.description, rdap.version, rdap.publication, len(rdap.services)))
|
||||||
for domain in sys.argv[1:]:
|
for domain in sys.argv[1:]:
|
||||||
print("%s -> %s" % (domain, rdap.find(domain)))
|
print("%s -> %s" % (domain, rdap.find(domain)))
|
||||||
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
"""Test by executing 'pytest' https://docs.pytest.org/
|
|
||||||
|
|
||||||
Don't forget to set PYTHONPATH if you want to test the development
|
|
||||||
tree and not the installed package. """
|
|
||||||
|
|
||||||
import ianardap
|
|
||||||
|
|
||||||
import tempfile
|
|
||||||
import os.path
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
def test_basic():
|
|
||||||
database = ianardap.IanaRDAPDatabase()
|
|
||||||
assert database.description.startswith("RDAP bootstrap file") and database.version == "1.0" and \
|
|
||||||
len(database.services) > 1000
|
|
||||||
|
|
||||||
def test_alternative_cache():
|
|
||||||
tmpfile = tempfile.NamedTemporaryFile(suffix=".testianacache", delete=False)
|
|
||||||
database = ianardap.IanaRDAPDatabase(cachefile=tmpfile.name, maxage=0)
|
|
||||||
assert os.path.exists(tmpfile.name) and \
|
|
||||||
datetime.datetime.fromtimestamp(os.path.getmtime(tmpfile.name)) > \
|
|
||||||
(datetime.datetime.now() - datetime.timedelta(minutes=1))
|
|
||||||
os.remove(tmpfile.name)
|
|
||||||
os.remove(tmpfile.name + ".lock")
|
|
||||||
|
|
||||||
def test_refresh():
|
|
||||||
# Force a resfresh
|
|
||||||
database = ianardap.IanaRDAPDatabase(maxage=0)
|
|
||||||
assert (database.retrieved > (datetime.datetime.now() - datetime.timedelta(minutes=1))) and \
|
|
||||||
(datetime.datetime.fromtimestamp(os.path.getmtime(database.cachefile)) > \
|
|
||||||
(datetime.datetime.now() - datetime.timedelta(minutes=1)))
|
|
||||||
|
|
||||||
def test_find_exists():
|
|
||||||
database = ianardap.IanaRDAPDatabase()
|
|
||||||
server = database.find("www.foobar.ar")
|
|
||||||
assert server == "https://rdap.nic.ar/"
|
|
||||||
|
|
||||||
def test_find_not_exists():
|
|
||||||
database = ianardap.IanaRDAPDatabase()
|
|
||||||
server = database.find("www.foobar.example")
|
|
||||||
assert server is None
|
|
|
@ -72,15 +72,6 @@ tests:
|
||||||
stderr: ''
|
stderr: ''
|
||||||
partstdout: 'RDAP server is'
|
partstdout: 'RDAP server is'
|
||||||
|
|
||||||
- exe: './check_expire'
|
|
||||||
args:
|
|
||||||
- '-u'
|
|
||||||
- '-H'
|
|
||||||
- 'bortzmeyer.org'
|
|
||||||
retcode: 0
|
|
||||||
stderr: ''
|
|
||||||
# TODO how to test we get an integer?
|
|
||||||
|
|
||||||
- exe: './check_expire'
|
- exe: './check_expire'
|
||||||
args:
|
args:
|
||||||
- '-c'
|
- '-c'
|
||||||
|
|
Loading…
Reference in New Issue