mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
First draft of DNS diagnoser
This commit is contained in:
parent
77b0920dac
commit
85930163a0
2 changed files with 96 additions and 1 deletions
93
data/hooks/diagnosis/12-dns.py
Normal file
93
data/hooks/diagnosis/12-dns.py
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from moulinette import m18n
|
||||||
|
from moulinette.utils.network import download_text
|
||||||
|
from moulinette.core import MoulinetteError, init_authenticator
|
||||||
|
from moulinette.utils.process import check_output
|
||||||
|
|
||||||
|
from yunohost.diagnosis import Diagnoser
|
||||||
|
from yunohost.domain import domain_list, _build_dns_conf, _get_maindomain
|
||||||
|
|
||||||
|
# Instantiate LDAP Authenticator
|
||||||
|
auth_identifier = ('ldap', 'ldap-anonymous')
|
||||||
|
auth_parameters = {'uri': 'ldap://localhost:389', 'base_dn': 'dc=yunohost,dc=org'}
|
||||||
|
auth = init_authenticator(auth_identifier, auth_parameters)
|
||||||
|
|
||||||
|
class DNSDiagnoser(Diagnoser):
|
||||||
|
|
||||||
|
id_ = os.path.splitext(os.path.basename(__file__))[0].split("-")[1]
|
||||||
|
description = "dns_configurations"
|
||||||
|
cache_duration = 3600*24
|
||||||
|
|
||||||
|
def validate_args(self, args):
|
||||||
|
all_domains = domain_list(auth)["domains"]
|
||||||
|
if "domain" not in args.keys():
|
||||||
|
return { "domains" : all_domains }
|
||||||
|
else:
|
||||||
|
if args["domain"] not in all_domains:
|
||||||
|
raise MoulinetteError(errno.EINVAL, m18n.n('domain_unknown'))
|
||||||
|
return { "domains" : [ args["domain"] ] }
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
|
||||||
|
self.resolver = check_output('grep "$nameserver" /etc/resolv.dnsmasq.conf').split("\n")[0].split(" ")[1]
|
||||||
|
|
||||||
|
main_domain = _get_maindomain()
|
||||||
|
|
||||||
|
for domain in self.args["domains"]:
|
||||||
|
self.logger_info("Diagnosing DNS conf for %s" % domain)
|
||||||
|
for report in self.check_domain(domain, domain==main_domain):
|
||||||
|
yield report
|
||||||
|
|
||||||
|
def check_domain(self, domain, is_main_domain):
|
||||||
|
|
||||||
|
expected_configuration = _build_dns_conf(domain)
|
||||||
|
|
||||||
|
# Here if there are no AAAA record, we should add something to expect "no" AAAA record
|
||||||
|
# to properly diagnose situations where people have a AAAA record but no IPv6
|
||||||
|
|
||||||
|
for category, records in expected_configuration.items():
|
||||||
|
|
||||||
|
discrepancies = []
|
||||||
|
|
||||||
|
for r in records:
|
||||||
|
current_value = self.get_current_record(domain, r["name"], r["type"]) or "None"
|
||||||
|
expected_value = r["value"] if r["value"] != "@" else domain+"."
|
||||||
|
|
||||||
|
if current_value != expected_value:
|
||||||
|
discrepancies.append((r, expected_value, current_value))
|
||||||
|
|
||||||
|
if discrepancies:
|
||||||
|
if category == "basic" or is_main_domain:
|
||||||
|
level = "ERROR"
|
||||||
|
else:
|
||||||
|
level = "WARNING"
|
||||||
|
report = (level, "diagnosis_dns_bad_conf", {"domain": domain, "category": category})
|
||||||
|
else:
|
||||||
|
level = "SUCCESS"
|
||||||
|
report = ("SUCCESS", "diagnosis_dns_good_conf", {"domain": domain, "category": category})
|
||||||
|
|
||||||
|
# FIXME : add management of details of what's wrong if there are discrepancies
|
||||||
|
yield dict(meta = {"domain": domain, "category": category},
|
||||||
|
result = level, report = report )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_record(self, domain, name, type_):
|
||||||
|
if name == "@":
|
||||||
|
command = "dig +short @%s %s %s" % (self.resolver, type_, domain)
|
||||||
|
else:
|
||||||
|
command = "dig +short @%s %s %s.%s" % (self.resolver, type_, name, domain)
|
||||||
|
output = check_output(command).strip()
|
||||||
|
output = output.replace("\;",";")
|
||||||
|
if output.startswith('"') and output.endswith('"'):
|
||||||
|
output = '"' + ' '.join(output.replace('"',' ').split()) + '"'
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
def main(args, env, loggers):
|
||||||
|
DNSDiagnoser(args, env, loggers).diagnose()
|
||||||
|
return 0
|
||||||
|
|
|
@ -155,7 +155,9 @@
|
||||||
"diagnosis_no_apps": "No installed application",
|
"diagnosis_no_apps": "No installed application",
|
||||||
"dpkg_is_broken": "You cannot do this right now because dpkg/APT (the system package managers) seems to be in a broken state… You can try to solve this issue by connecting through SSH and running `sudo dpkg --configure -a`.",
|
"dpkg_is_broken": "You cannot do this right now because dpkg/APT (the system package managers) seems to be in a broken state… You can try to solve this issue by connecting through SSH and running `sudo dpkg --configure -a`.",
|
||||||
"dpkg_lock_not_available": "This command can't be ran right now because another program seems to be using the lock of dpkg (the system package manager)",
|
"dpkg_lock_not_available": "This command can't be ran right now because another program seems to be using the lock of dpkg (the system package manager)",
|
||||||
"domain_cannot_remove_main": "Cannot remove main domain. Set one first",
|
"diagnosis_dns_good_conf": "Good DNS configuration for {domain} : {category}.",
|
||||||
|
"diagnosis_dns_bad_conf": "Bad DNS configuration for {domain} : {category}.",
|
||||||
|
"domain_cannot_remove_main": "Cannot remove main domain. Set a new main domain first",
|
||||||
"domain_cert_gen_failed": "Could not generate certificate",
|
"domain_cert_gen_failed": "Could not generate certificate",
|
||||||
"domain_created": "Domain created",
|
"domain_created": "Domain created",
|
||||||
"domain_creation_failed": "Could not create domain {domain}: {error}",
|
"domain_creation_failed": "Could not create domain {domain}: {error}",
|
||||||
|
|
Loading…
Add table
Reference in a new issue