From b5e20cadf4df595d1217668fdd6d38b817ad51e2 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 19 Sep 2021 00:32:42 +0200 Subject: [PATCH] autodns: Various fixes, improvement for edge case handling --- locales/en.json | 6 +++--- src/yunohost/dns.py | 46 ++++++++++++++++++++++++++++++--------------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/locales/en.json b/locales/en.json index c4413380a..fb755c08b 100644 --- a/locales/en.json +++ b/locales/en.json @@ -318,9 +318,9 @@ "domain_remove_confirm_apps_removal": "Removing this domain will remove those applications:\n{apps}\n\nAre you sure you want to do that? [{answers}]", "domain_uninstall_app_first": "Those applications are still installed on your domain:\n{apps}\n\nPlease uninstall them using 'yunohost app remove the_app_id' or move them to another domain using 'yunohost app change-url the_app_id' before proceeding to domain removal", "domain_registrar_is_not_configured": "The registrar is not yet configured for domain {domain}.", - "domain_dns_push_not_applicable": "The DNS push feature is not applicable to domain {domain}. You should manually configure your DNS records following the documentation at https://yunohost.org/dns_config.", - "domain_dns_push_managed_in_parent_domain": "The DNS push feature is managed in the parent domain {parent_domain}.", - "domain_dns_push_failed_to_authenticate": "Failed to authenticate on registrar's API. Most probably the credentials are incorrect? (Error: {error})", + "domain_dns_push_not_applicable": "The automatic DNS configuration feature is not applicable to domain {domain}. You should manually configure your DNS records following the documentation at https://yunohost.org/dns_config.", + "domain_dns_push_managed_in_parent_domain": "The automatic DNS configuration feature is managed in the parent domain {parent_domain}.", + "domain_dns_push_failed_to_authenticate": "Failed to authenticate on registrar's API for domain '{domain}'. Most probably the credentials are incorrect? (Error: {error})", "domain_config_mail_in": "Incoming emails", "domain_config_mail_out": "Outgoing emails", "domain_config_xmpp": "XMPP", diff --git a/src/yunohost/dns.py b/src/yunohost/dns.py index dfec7ceb9..daeae0c7f 100644 --- a/src/yunohost/dns.py +++ b/src/yunohost/dns.py @@ -490,7 +490,7 @@ def _get_registrar_config_section(domain): registrar_infos["registrar"] = OrderedDict({ "type": "alert", "style": "success", - "ask": "This domain is a nohost.me / nohost.st / ynh.fr and its DNS configuration is therefore automatically handled by Yunohost.", # FIXME: i18n + "ask": "This domain is a nohost.me / nohost.st / ynh.fr and its DNS configuration is therefore automatically handled by Yunohost without any further configuration.", # FIXME: i18n "value": "yunohost" }) return OrderedDict(registrar_infos) @@ -532,6 +532,20 @@ def _get_registrar_config_section(domain): return OrderedDict(registrar_infos) +def _get_registar_settings(domain): + + _assert_domain_exists(domain) + + settings = domain_config_get(domain, key='dns.registrar', export=True) + + registrar = settings.pop("registrar") + + if "experimental_disclaimer" in settings: + settings.pop("experimental_disclaimer") + + return registrar, settings + + @is_unit_operation() def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=False): """ @@ -541,29 +555,31 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge= from lexicon.client import Client as LexiconClient from lexicon.config import ConfigResolver as LexiconConfigResolver + registrar, registrar_credentials = _get_registar_settings(domain) + _assert_domain_exists(domain) - settings = domain_config_get(domain, key='dns.registrar', export=True) - - registrar = settings.get("registrar") - - if not registrar or registrar in ["None", "yunohost"]: + if not registrar or registrar == "None": # yes it's None as a string raise YunohostValidationError("domain_dns_push_not_applicable", domain=domain) + # FIXME: in the future, properly unify this with yunohost dyndns update + if registrar == "yunohost": + logger.info("This domain is a nohost.me / nohost.st / ynh.fr and its DNS configuration is therefore already automatically handled by Yunohost without any further configuration.") # FIXME: i18n + return {} + if registrar == "parent_domain": parent_domain = domain.split(".", 1)[1] - raise YunohostValidationError("domain_dns_push_managed_in_parent_domain", domain=domain, parent_domain=parent_domain) - - base_dns_zone = _get_dns_zone_for_domain(domain) - - registrar_credentials = settings - registrar_credentials.pop("registrar") - if "experimental_disclaimer" in registrar_credentials: - registrar_credentials.pop("experimental_disclaimer") + registar, registrar_credentials = _get_registar_settings(parent_domain) + if any(registrar_credentials.values()): + raise YunohostValidationError("domain_dns_push_managed_in_parent_domain", domain=domain, parent_domain=parent_domain) + else: + raise YunohostValidationError("domain_registrar_is_not_configured", domain=domain) if not all(registrar_credentials.values()): raise YunohostValidationError("domain_registrar_is_not_configured", domain=domain) + base_dns_zone = _get_dns_zone_for_domain(domain) + # Convert the generated conf into a format that matches what we'll fetch using the API # Makes it easier to compare "wanted records" with "current records on remote" wanted_records = [] @@ -619,7 +635,7 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge= try: client.provider.authenticate() except Exception as e: - raise YunohostValidationError("domain_dns_push_failed_to_authenticate", error=str(e)) + raise YunohostValidationError("domain_dns_push_failed_to_authenticate", domain=domain, error=str(e)) try: current_records = client.provider.list_records()