From 439a999c02c172fe1d0299bc3a7f779d719e8a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Sun, 26 Aug 2018 12:47:15 +0200 Subject: [PATCH 1/8] Add hook support in domain_dns_conf --- src/yunohost/domain.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index 560a6fda5..644b233d2 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -188,6 +188,7 @@ def domain_dns_conf(domain, ttl=None): ttl -- Time to live """ + from yunohost.hook import hook_callback ttl = 3600 if ttl is None else ttl @@ -209,6 +210,11 @@ def domain_dns_conf(domain, ttl=None): for record in dns_conf["mail"]: result += "\n{name} {ttl} IN {type} {value}".format(**record) + result += "\n\n" + result += "; Custom\n" + + result += ''.join(hook_callback('custom_dns_rules', args=[])['stdreturn']) + is_cli = True if msettings.get('interface') == 'cli' else False if is_cli: logger.info(m18n.n("domain_dns_conf_is_just_a_recommendation")) From 5a27e314ff78fbc29b8c9849a555732977e9b223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Sun, 26 Aug 2018 14:59:52 +0200 Subject: [PATCH 2/8] Get custom dns conf in _build_dns_conf --- src/yunohost/domain.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index 644b233d2..475b23223 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -38,6 +38,7 @@ import yunohost.certificate from yunohost.service import service_regen_conf from yunohost.utils.network import get_public_ip from yunohost.log import is_unit_operation +from yunohost.hook import hook_callback logger = getActionLogger('yunohost.domain') @@ -188,7 +189,6 @@ def domain_dns_conf(domain, ttl=None): ttl -- Time to live """ - from yunohost.hook import hook_callback ttl = 3600 if ttl is None else ttl @@ -212,8 +212,8 @@ def domain_dns_conf(domain, ttl=None): result += "\n\n" result += "; Custom\n" - - result += ''.join(hook_callback('custom_dns_rules', args=[])['stdreturn']) + for record in dns_conf["custom"]: + result += "\n{name} {ttl} IN {type} {value}".format(**record) is_cli = True if msettings.get('interface') == 'cli' else False if is_cli: @@ -393,12 +393,22 @@ def _build_dns_conf(domain, ttl=3600): ["_dmarc", ttl, "TXT", '"v=DMARC1; p=none"'], ] - return { + # Custom + hookres = hook_callback('custom_dns_rules', args=[domain]) + print(hookres) + custom = [] + for h in hookres.values() : + custom.extend(h['stdreturn']) + + res = { "basic": [{"name": name, "ttl": ttl, "type": type_, "value": value} for name, ttl, type_, value in basic], "xmpp": [{"name": name, "ttl": ttl, "type": type_, "value": value} for name, ttl, type_, value in xmpp], "mail": [{"name": name, "ttl": ttl, "type": type_, "value": value} for name, ttl, type_, value in mail], + "custom": custom, } + return res + def _get_DKIM(domain): DKIM_file = '/etc/dkim/{domain}.mail.txt'.format(domain=domain) From f83e9cae7d24ec8e3ca6c80ce71e7e5503444093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Wed, 29 Aug 2018 21:49:35 +0200 Subject: [PATCH 3/8] Dns hook : add specific comment for each hook --- src/yunohost/domain.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index 475b23223..6c094e80b 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -210,10 +210,12 @@ def domain_dns_conf(domain, ttl=None): for record in dns_conf["mail"]: result += "\n{name} {ttl} IN {type} {value}".format(**record) - result += "\n\n" - result += "; Custom\n" - for record in dns_conf["custom"]: - result += "\n{name} {ttl} IN {type} {value}".format(**record) + for name, record_list in dns_conf.items(): + if name not in ("basic", "xmpp", "mail"): + result += "\n\n" + result += "; " + name + "\n" + for record in record_list: + result += "\n{name} {ttl} IN {type} {value}".format(**record) is_cli = True if msettings.get('interface') == 'cli' else False if is_cli: @@ -393,20 +395,18 @@ def _build_dns_conf(domain, ttl=3600): ["_dmarc", ttl, "TXT", '"v=DMARC1; p=none"'], ] - # Custom - hookres = hook_callback('custom_dns_rules', args=[domain]) - print(hookres) - custom = [] - for h in hookres.values() : - custom.extend(h['stdreturn']) - + # Official record res = { "basic": [{"name": name, "ttl": ttl, "type": type_, "value": value} for name, ttl, type_, value in basic], "xmpp": [{"name": name, "ttl": ttl, "type": type_, "value": value} for name, ttl, type_, value in xmpp], "mail": [{"name": name, "ttl": ttl, "type": type_, "value": value} for name, ttl, type_, value in mail], - "custom": custom, } + # Custom record + hookres = hook_callback('custom_dns_rules', args=[domain]) + for n,v in hookres.items() : + res[n] = v['stdreturn'] + return res From a20b72c2dd26db2721a6d9d9b61fcc3ea116abb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Tue, 4 Sep 2018 22:50:45 +0200 Subject: [PATCH 4/8] Add comment about DNS datastructure returned --- src/yunohost/domain.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index 6c094e80b..a9df20026 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -342,6 +342,9 @@ def _build_dns_conf(domain, ttl=3600): {"type": "TXT", "name": "mail._domainkey", "value": "\"v=DKIM1; k=rsa; p=some-super-long-key\"", "ttl": 3600}, {"type": "TXT", "name": "_dmarc", "value": "\"v=DMARC1; p=none\"", "ttl": 3600} ], + "example_of_a_custom_rule": [ + {"type": "SRV", "name": "_matrix", "value": "domain.tld.", "ttl": 3600} + ], } """ From f266cceb265559e8bf3d272b1b4837bb2206c08e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Mon, 7 Jan 2019 20:23:41 +0100 Subject: [PATCH 5/8] Fix typo --- src/yunohost/domain.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index 280f8a9c3..088f7724f 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -4,8 +4,7 @@ Copyright (C) 2013 YunoHost - This progra - m is free software; you can redistribute it and/or modify + This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. From d15092a7401001ffbe8fcceec168bab0657ea439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josu=C3=A9=20Tille?= Date: Mon, 11 Feb 2019 20:22:42 +0100 Subject: [PATCH 6/8] Fix result from hook_callback --- src/yunohost/domain.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index 088f7724f..66f17c491 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -206,16 +206,16 @@ def domain_dns_conf(domain, ttl=None): result += "; Mail" for record in dns_conf["mail"]: result += "\n{name} {ttl} IN {type} {value}".format(**record) - result += "\n\n + result += "\n\n" result += "; Extra" for record in dns_conf["extra"]: result += "\n{name} {ttl} IN {type} {value}".format(**record) for name, record_list in dns_conf.items(): - if name not in ("basic", "xmpp", "mail"): + if name not in ("basic", "xmpp", "mail", "extra") and record_list: result += "\n\n" - result += "; " + name + "\n" + result += "; " + name for record in record_list: result += "\n{name} {ttl} IN {type} {value}".format(**record) @@ -418,8 +418,10 @@ def _build_dns_conf(domain, ttl=3600): # Custom record hookres = hook_callback('custom_dns_rules', args=[domain]) - for n,v in hookres.items() : - res[n] = v['stdreturn'] + for n, val in hookres.items() : + res[n] = [] + for v in [v['stdreturn'] for p, v in val.items() if v and v['stdreturn']]: + res[n].extend(v) return res From dd87b9192aefde56175f54aa5aa20cdf98baa9b8 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 23 Mar 2019 16:50:44 +0100 Subject: [PATCH 7/8] Improve naming / semantic / add comments --- src/yunohost/domain.py | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index e604b54f0..a7141e0b8 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -408,21 +408,38 @@ def _build_dns_conf(domain, ttl=3600): ] # Official record - res = { + records = { "basic": [{"name": name, "ttl": ttl, "type": type_, "value": value} for name, ttl, type_, value in basic], "xmpp": [{"name": name, "ttl": ttl, "type": type_, "value": value} for name, ttl, type_, value in xmpp], "mail": [{"name": name, "ttl": ttl, "type": type_, "value": value} for name, ttl, type_, value in mail], "extra": [{"name": name, "ttl": ttl, "type": type_, "value": value} for name, ttl, type_, value in extra], } - # Custom record - hookres = hook_callback('custom_dns_rules', args=[domain]) - for n, val in hookres.items() : - res[n] = [] - for v in [v['stdreturn'] for p, v in val.items() if v and v['stdreturn']]: - res[n].extend(v) + # Custom records + hook_results = hook_callback('custom_dns_rules', args=[domain]) + for hook_name, results in hook_results.items(): + # + # There can be multiple results per hook name, so results look like + # {'/some/path/to/hook1': + # { 'state': 'succeed', + # 'stdreturn': [{'type': 'SRV', + # 'name': 'stuff.foo.bar.', + # 'value': 'yoloswag', + # 'ttl': 3600}] + # }, + # '/some/path/to/hook2': + # { ... }, + # [...] + # + # Loop over the sub-results + custom_records = [v['stdreturn'] for v in results.values() + if v and v['stdreturn']] - return res + records[hook_name] = [] + for record_list in custom_records: + records[hook_name].extend(record_list) + + return records def _get_DKIM(domain): From 5ac5cc93107efea4a5855afb686d4f4640d244bf Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 23 Mar 2019 17:31:56 +0100 Subject: [PATCH 8/8] Check format of data retrieved from hook stdreturn --- src/yunohost/domain.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index a7141e0b8..70a4ef5c9 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -437,6 +437,15 @@ def _build_dns_conf(domain, ttl=3600): records[hook_name] = [] for record_list in custom_records: + # Check that record_list is indeed a list of dict + # with the required keys + if not isinstance(record_list, list) \ + or any(not isinstance(record, dict) for record in record_list) \ + or any(key not in record for record in record_list for key in ["name", "ttl", "type", "value"]): + # Display an error, mainly for app packagers trying to implement a hook + logger.warning("Ignored custom record from hook '%s' because the data is not a *list* of dict with keys name, ttl, type and value. Raw data : %s" % (hook_name, record_list)) + continue + records[hook_name].extend(record_list) return records