mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Black
This commit is contained in:
parent
d1ad7f83d1
commit
4d3692a70b
14 changed files with 219 additions and 121 deletions
|
@ -86,7 +86,11 @@ class DNSRecordsDiagnoser(Diagnoser):
|
||||||
|
|
||||||
# Ugly hack to not check mail records for subdomains stuff, otherwise will end up in a shitstorm of errors for people with many subdomains...
|
# Ugly hack to not check mail records for subdomains stuff, otherwise will end up in a shitstorm of errors for people with many subdomains...
|
||||||
# Should find a cleaner solution in the suggested conf...
|
# Should find a cleaner solution in the suggested conf...
|
||||||
if r["type"] in ["MX", "TXT"] and fqdn not in [domain, f'mail._domainkey.{domain}', f'_dmarc.{domain}']:
|
if r["type"] in ["MX", "TXT"] and fqdn not in [
|
||||||
|
domain,
|
||||||
|
f"mail._domainkey.{domain}",
|
||||||
|
f"_dmarc.{domain}",
|
||||||
|
]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
r["current"] = self.get_current_record(fqdn, r["type"])
|
r["current"] = self.get_current_record(fqdn, r["type"])
|
||||||
|
@ -112,7 +116,10 @@ class DNSRecordsDiagnoser(Diagnoser):
|
||||||
# A bad or missing A record is critical ...
|
# A bad or missing A record is critical ...
|
||||||
# And so is a wrong AAAA record
|
# And so is a wrong AAAA record
|
||||||
# (However, a missing AAAA record is acceptable)
|
# (However, a missing AAAA record is acceptable)
|
||||||
if results[f"A:{basename}"] != "OK" or results[f"AAAA:{basename}"] == "WRONG":
|
if (
|
||||||
|
results[f"A:{basename}"] != "OK"
|
||||||
|
or results[f"AAAA:{basename}"] == "WRONG"
|
||||||
|
):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
@ -175,7 +182,7 @@ class DNSRecordsDiagnoser(Diagnoser):
|
||||||
)
|
)
|
||||||
|
|
||||||
# For SPF, ignore parts starting by ip4: or ip6:
|
# For SPF, ignore parts starting by ip4: or ip6:
|
||||||
if 'v=spf1' in r["value"]:
|
if "v=spf1" in r["value"]:
|
||||||
current = {
|
current = {
|
||||||
part
|
part
|
||||||
for part in current
|
for part in current
|
||||||
|
|
|
@ -35,11 +35,11 @@ class MailDiagnoser(Diagnoser):
|
||||||
# TODO check that the recent mail logs are not filled with thousand of email sending (unusual number of mail sent)
|
# TODO check that the recent mail logs are not filled with thousand of email sending (unusual number of mail sent)
|
||||||
# TODO check for unusual failed sending attempt being refused in the logs ?
|
# TODO check for unusual failed sending attempt being refused in the logs ?
|
||||||
checks = [
|
checks = [
|
||||||
"check_outgoing_port_25", # i18n: diagnosis_mail_outgoing_port_25_ok
|
"check_outgoing_port_25", # i18n: diagnosis_mail_outgoing_port_25_ok
|
||||||
"check_ehlo", # i18n: diagnosis_mail_ehlo_ok
|
"check_ehlo", # i18n: diagnosis_mail_ehlo_ok
|
||||||
"check_fcrdns", # i18n: diagnosis_mail_fcrdns_ok
|
"check_fcrdns", # i18n: diagnosis_mail_fcrdns_ok
|
||||||
"check_blacklist", # i18n: diagnosis_mail_blacklist_ok
|
"check_blacklist", # i18n: diagnosis_mail_blacklist_ok
|
||||||
"check_queue", # i18n: diagnosis_mail_queue_ok
|
"check_queue", # i18n: diagnosis_mail_queue_ok
|
||||||
]
|
]
|
||||||
for check in checks:
|
for check in checks:
|
||||||
self.logger_debug("Running " + check)
|
self.logger_debug("Running " + check)
|
||||||
|
|
|
@ -708,7 +708,9 @@ class BackupManager:
|
||||||
|
|
||||||
# Prepare environment
|
# Prepare environment
|
||||||
env_dict = self._get_env_var(app)
|
env_dict = self._get_env_var(app)
|
||||||
env_dict["YNH_APP_BASEDIR"] = os.path.join(self.work_dir, "apps", app, "settings")
|
env_dict["YNH_APP_BASEDIR"] = os.path.join(
|
||||||
|
self.work_dir, "apps", app, "settings"
|
||||||
|
)
|
||||||
tmp_app_bkp_dir = env_dict["YNH_APP_BACKUP_DIR"]
|
tmp_app_bkp_dir = env_dict["YNH_APP_BACKUP_DIR"]
|
||||||
settings_dir = os.path.join(self.work_dir, "apps", app, "settings")
|
settings_dir = os.path.join(self.work_dir, "apps", app, "settings")
|
||||||
|
|
||||||
|
@ -1491,7 +1493,9 @@ class RestoreManager:
|
||||||
"YNH_APP_BACKUP_DIR": os.path.join(
|
"YNH_APP_BACKUP_DIR": os.path.join(
|
||||||
self.work_dir, "apps", app_instance_name, "backup"
|
self.work_dir, "apps", app_instance_name, "backup"
|
||||||
),
|
),
|
||||||
"YNH_APP_BASEDIR": os.path.join(self.work_dir, "apps", app_instance_name, "settings"),
|
"YNH_APP_BASEDIR": os.path.join(
|
||||||
|
self.work_dir, "apps", app_instance_name, "settings"
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1529,7 +1533,9 @@ class RestoreManager:
|
||||||
|
|
||||||
# Setup environment for remove script
|
# Setup environment for remove script
|
||||||
env_dict_remove = _make_environment_for_app_script(app_instance_name)
|
env_dict_remove = _make_environment_for_app_script(app_instance_name)
|
||||||
env_dict_remove["YNH_APP_BASEDIR"] = os.path.join(self.work_dir, "apps", app_instance_name, "settings")
|
env_dict_remove["YNH_APP_BASEDIR"] = os.path.join(
|
||||||
|
self.work_dir, "apps", app_instance_name, "settings"
|
||||||
|
)
|
||||||
|
|
||||||
remove_operation_logger = OperationLogger(
|
remove_operation_logger = OperationLogger(
|
||||||
"remove_on_failed_restore",
|
"remove_on_failed_restore",
|
||||||
|
|
|
@ -34,7 +34,13 @@ from moulinette import m18n, Moulinette
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.filesystem import read_file, write_to_file, read_toml
|
from moulinette.utils.filesystem import read_file, write_to_file, read_toml
|
||||||
|
|
||||||
from yunohost.domain import domain_list, _assert_domain_exists, domain_config_get, _get_domain_settings, _set_domain_settings
|
from yunohost.domain import (
|
||||||
|
domain_list,
|
||||||
|
_assert_domain_exists,
|
||||||
|
domain_config_get,
|
||||||
|
_get_domain_settings,
|
||||||
|
_set_domain_settings,
|
||||||
|
)
|
||||||
from yunohost.utils.dns import dig, YNH_DYNDNS_DOMAINS
|
from yunohost.utils.dns import dig, YNH_DYNDNS_DOMAINS
|
||||||
from yunohost.utils.error import YunohostValidationError, YunohostError
|
from yunohost.utils.error import YunohostValidationError, YunohostError
|
||||||
from yunohost.utils.network import get_public_ip
|
from yunohost.utils.network import get_public_ip
|
||||||
|
@ -163,13 +169,18 @@ def _build_dns_conf(base_domain, include_empty_AAAA_if_no_ipv6=False):
|
||||||
# If this is a ynh_dyndns_domain, we're not gonna include all the subdomains in the conf
|
# If this is a ynh_dyndns_domain, we're not gonna include all the subdomains in the conf
|
||||||
# Because dynette only accept a specific list of name/type
|
# Because dynette only accept a specific list of name/type
|
||||||
# And the wildcard */A already covers the bulk of use cases
|
# And the wildcard */A already covers the bulk of use cases
|
||||||
if any(base_domain.endswith("." + ynh_dyndns_domain) for ynh_dyndns_domain in YNH_DYNDNS_DOMAINS):
|
if any(
|
||||||
|
base_domain.endswith("." + ynh_dyndns_domain)
|
||||||
|
for ynh_dyndns_domain in YNH_DYNDNS_DOMAINS
|
||||||
|
):
|
||||||
subdomains = []
|
subdomains = []
|
||||||
else:
|
else:
|
||||||
subdomains = _list_subdomains_of(base_domain)
|
subdomains = _list_subdomains_of(base_domain)
|
||||||
|
|
||||||
domains_settings = {domain: domain_config_get(domain, export=True)
|
domains_settings = {
|
||||||
for domain in [base_domain] + subdomains}
|
domain: domain_config_get(domain, export=True)
|
||||||
|
for domain in [base_domain] + subdomains
|
||||||
|
}
|
||||||
|
|
||||||
base_dns_zone = _get_dns_zone_for_domain(base_domain)
|
base_dns_zone = _get_dns_zone_for_domain(base_domain)
|
||||||
|
|
||||||
|
@ -186,7 +197,7 @@ def _build_dns_conf(base_domain, include_empty_AAAA_if_no_ipv6=False):
|
||||||
basename = domain.replace(base_dns_zone, "").rstrip(".") or "@"
|
basename = domain.replace(base_dns_zone, "").rstrip(".") or "@"
|
||||||
suffix = f".{basename}" if basename != "@" else ""
|
suffix = f".{basename}" if basename != "@" else ""
|
||||||
|
|
||||||
#ttl = settings["ttl"]
|
# ttl = settings["ttl"]
|
||||||
ttl = 3600
|
ttl = 3600
|
||||||
|
|
||||||
###########################
|
###########################
|
||||||
|
@ -416,7 +427,7 @@ def _get_dns_zone_for_domain(domain):
|
||||||
# This is mainly meant to speed up things for "dyndns update"
|
# This is mainly meant to speed up things for "dyndns update"
|
||||||
# ... otherwise we end up constantly doing a bunch of dig requests
|
# ... otherwise we end up constantly doing a bunch of dig requests
|
||||||
for ynh_dyndns_domain in YNH_DYNDNS_DOMAINS:
|
for ynh_dyndns_domain in YNH_DYNDNS_DOMAINS:
|
||||||
if domain.endswith('.' + ynh_dyndns_domain):
|
if domain.endswith("." + ynh_dyndns_domain):
|
||||||
return ynh_dyndns_domain
|
return ynh_dyndns_domain
|
||||||
|
|
||||||
# Check cache
|
# Check cache
|
||||||
|
@ -453,8 +464,7 @@ def _get_dns_zone_for_domain(domain):
|
||||||
# baz.gni
|
# baz.gni
|
||||||
# gni
|
# gni
|
||||||
# Until we find the first one that has a NS record
|
# Until we find the first one that has a NS record
|
||||||
parent_list = [domain.split(".", i)[-1]
|
parent_list = [domain.split(".", i)[-1] for i, _ in enumerate(domain.split("."))]
|
||||||
for i, _ in enumerate(domain.split("."))]
|
|
||||||
|
|
||||||
for parent in parent_list:
|
for parent in parent_list:
|
||||||
|
|
||||||
|
@ -470,7 +480,9 @@ def _get_dns_zone_for_domain(domain):
|
||||||
else:
|
else:
|
||||||
zone = parent_list[-1]
|
zone = parent_list[-1]
|
||||||
|
|
||||||
logger.warning(f"Could not identify the dns zone for domain {domain}, returning {zone}")
|
logger.warning(
|
||||||
|
f"Could not identify the dns zone for domain {domain}, returning {zone}"
|
||||||
|
)
|
||||||
return zone
|
return zone
|
||||||
|
|
||||||
|
|
||||||
|
@ -492,50 +504,66 @@ def _get_registrar_config_section(domain):
|
||||||
else:
|
else:
|
||||||
parent_domain_link = parent_domain
|
parent_domain_link = parent_domain
|
||||||
|
|
||||||
registrar_infos["registrar"] = OrderedDict({
|
registrar_infos["registrar"] = OrderedDict(
|
||||||
"type": "alert",
|
{
|
||||||
"style": "info",
|
"type": "alert",
|
||||||
"ask": m18n.n("domain_dns_registrar_managed_in_parent_domain", parent_domain=domain, parent_domain_link=parent_domain_link),
|
"style": "info",
|
||||||
"value": "parent_domain"
|
"ask": m18n.n(
|
||||||
})
|
"domain_dns_registrar_managed_in_parent_domain",
|
||||||
|
parent_domain=domain,
|
||||||
|
parent_domain_link=parent_domain_link,
|
||||||
|
),
|
||||||
|
"value": "parent_domain",
|
||||||
|
}
|
||||||
|
)
|
||||||
return OrderedDict(registrar_infos)
|
return OrderedDict(registrar_infos)
|
||||||
|
|
||||||
# TODO big project, integrate yunohost's dynette as a registrar-like provider
|
# TODO big project, integrate yunohost's dynette as a registrar-like provider
|
||||||
# TODO big project, integrate other dyndns providers such as netlib.re, or cf the list of dyndns providers supported by cloudron...
|
# TODO big project, integrate other dyndns providers such as netlib.re, or cf the list of dyndns providers supported by cloudron...
|
||||||
if dns_zone in YNH_DYNDNS_DOMAINS:
|
if dns_zone in YNH_DYNDNS_DOMAINS:
|
||||||
registrar_infos["registrar"] = OrderedDict({
|
registrar_infos["registrar"] = OrderedDict(
|
||||||
"type": "alert",
|
{
|
||||||
"style": "success",
|
"type": "alert",
|
||||||
"ask": m18n.n("domain_dns_registrar_yunohost"),
|
"style": "success",
|
||||||
"value": "yunohost"
|
"ask": m18n.n("domain_dns_registrar_yunohost"),
|
||||||
})
|
"value": "yunohost",
|
||||||
|
}
|
||||||
|
)
|
||||||
return OrderedDict(registrar_infos)
|
return OrderedDict(registrar_infos)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
registrar = _relevant_provider_for_domain(dns_zone)[0]
|
registrar = _relevant_provider_for_domain(dns_zone)[0]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
registrar_infos["registrar"] = OrderedDict({
|
registrar_infos["registrar"] = OrderedDict(
|
||||||
"type": "alert",
|
{
|
||||||
"style": "warning",
|
"type": "alert",
|
||||||
"ask": m18n.n("domain_dns_registrar_not_supported"),
|
"style": "warning",
|
||||||
"value": None
|
"ask": m18n.n("domain_dns_registrar_not_supported"),
|
||||||
})
|
"value": None,
|
||||||
|
}
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
registrar_infos["registrar"] = OrderedDict({
|
registrar_infos["registrar"] = OrderedDict(
|
||||||
"type": "alert",
|
{
|
||||||
"style": "info",
|
"type": "alert",
|
||||||
"ask": m18n.n("domain_dns_registrar_supported", registrar=registrar),
|
"style": "info",
|
||||||
"value": registrar
|
"ask": m18n.n("domain_dns_registrar_supported", registrar=registrar),
|
||||||
})
|
"value": registrar,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
TESTED_REGISTRARS = ["ovh", "gandi"]
|
TESTED_REGISTRARS = ["ovh", "gandi"]
|
||||||
if registrar not in TESTED_REGISTRARS:
|
if registrar not in TESTED_REGISTRARS:
|
||||||
registrar_infos["experimental_disclaimer"] = OrderedDict({
|
registrar_infos["experimental_disclaimer"] = OrderedDict(
|
||||||
"type": "alert",
|
{
|
||||||
"style": "danger",
|
"type": "alert",
|
||||||
"ask": m18n.n("domain_dns_registrar_experimental", registrar=registrar),
|
"style": "danger",
|
||||||
})
|
"ask": m18n.n(
|
||||||
|
"domain_dns_registrar_experimental", registrar=registrar
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# TODO : add a help tip with the link to the registar's API doc (c.f. Lexicon's README)
|
# TODO : add a help tip with the link to the registar's API doc (c.f. Lexicon's README)
|
||||||
registrar_list = read_toml(DOMAIN_REGISTRAR_LIST_PATH)
|
registrar_list = read_toml(DOMAIN_REGISTRAR_LIST_PATH)
|
||||||
|
@ -552,7 +580,7 @@ def _get_registar_settings(domain):
|
||||||
|
|
||||||
_assert_domain_exists(domain)
|
_assert_domain_exists(domain)
|
||||||
|
|
||||||
settings = domain_config_get(domain, key='dns.registrar', export=True)
|
settings = domain_config_get(domain, key="dns.registrar", export=True)
|
||||||
|
|
||||||
registrar = settings.pop("registrar")
|
registrar = settings.pop("registrar")
|
||||||
|
|
||||||
|
@ -587,12 +615,20 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
parent_domain = domain.split(".", 1)[1]
|
parent_domain = domain.split(".", 1)[1]
|
||||||
registar, registrar_credentials = _get_registar_settings(parent_domain)
|
registar, registrar_credentials = _get_registar_settings(parent_domain)
|
||||||
if any(registrar_credentials.values()):
|
if any(registrar_credentials.values()):
|
||||||
raise YunohostValidationError("domain_dns_push_managed_in_parent_domain", domain=domain, parent_domain=parent_domain)
|
raise YunohostValidationError(
|
||||||
|
"domain_dns_push_managed_in_parent_domain",
|
||||||
|
domain=domain,
|
||||||
|
parent_domain=parent_domain,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise YunohostValidationError("domain_registrar_is_not_configured", domain=parent_domain)
|
raise YunohostValidationError(
|
||||||
|
"domain_registrar_is_not_configured", domain=parent_domain
|
||||||
|
)
|
||||||
|
|
||||||
if not all(registrar_credentials.values()):
|
if not all(registrar_credentials.values()):
|
||||||
raise YunohostValidationError("domain_registrar_is_not_configured", domain=domain)
|
raise YunohostValidationError(
|
||||||
|
"domain_registrar_is_not_configured", domain=domain
|
||||||
|
)
|
||||||
|
|
||||||
base_dns_zone = _get_dns_zone_for_domain(domain)
|
base_dns_zone = _get_dns_zone_for_domain(domain)
|
||||||
|
|
||||||
|
@ -603,7 +639,11 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
for record in records:
|
for record in records:
|
||||||
|
|
||||||
# Make sure the name is a FQDN
|
# Make sure the name is a FQDN
|
||||||
name = f"{record['name']}.{base_dns_zone}" if record["name"] != "@" else base_dns_zone
|
name = (
|
||||||
|
f"{record['name']}.{base_dns_zone}"
|
||||||
|
if record["name"] != "@"
|
||||||
|
else base_dns_zone
|
||||||
|
)
|
||||||
type_ = record["type"]
|
type_ = record["type"]
|
||||||
content = record["value"]
|
content = record["value"]
|
||||||
|
|
||||||
|
@ -611,19 +651,16 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
if content == "@" and record["type"] == "CNAME":
|
if content == "@" and record["type"] == "CNAME":
|
||||||
content = base_dns_zone + "."
|
content = base_dns_zone + "."
|
||||||
|
|
||||||
wanted_records.append({
|
wanted_records.append(
|
||||||
"name": name,
|
{"name": name, "type": type_, "ttl": record["ttl"], "content": content}
|
||||||
"type": type_,
|
)
|
||||||
"ttl": record["ttl"],
|
|
||||||
"content": content
|
|
||||||
})
|
|
||||||
|
|
||||||
# FIXME Lexicon does not support CAA records
|
# FIXME Lexicon does not support CAA records
|
||||||
# See https://github.com/AnalogJ/lexicon/issues/282 and https://github.com/AnalogJ/lexicon/pull/371
|
# See https://github.com/AnalogJ/lexicon/issues/282 and https://github.com/AnalogJ/lexicon/pull/371
|
||||||
# They say it's trivial to implement it!
|
# They say it's trivial to implement it!
|
||||||
# And yet, it is still not done/merged
|
# And yet, it is still not done/merged
|
||||||
# Update by Aleks: it works - at least with Gandi ?!
|
# Update by Aleks: it works - at least with Gandi ?!
|
||||||
#wanted_records = [record for record in wanted_records if record["type"] != "CAA"]
|
# wanted_records = [record for record in wanted_records if record["type"] != "CAA"]
|
||||||
|
|
||||||
if purge:
|
if purge:
|
||||||
wanted_records = []
|
wanted_records = []
|
||||||
|
@ -634,7 +671,7 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
base_config = {
|
base_config = {
|
||||||
"provider_name": registrar,
|
"provider_name": registrar,
|
||||||
"domain": base_dns_zone,
|
"domain": base_dns_zone,
|
||||||
registrar: registrar_credentials
|
registrar: registrar_credentials,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Ugly hack to be able to fetch all record types at once:
|
# Ugly hack to be able to fetch all record types at once:
|
||||||
|
@ -643,15 +680,17 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
# then trigger ourselves the authentication + list_records
|
# then trigger ourselves the authentication + list_records
|
||||||
# instead of calling .execute()
|
# instead of calling .execute()
|
||||||
query = (
|
query = (
|
||||||
LexiconConfigResolver()
|
LexiconConfigResolver()
|
||||||
.with_dict(dict_object=base_config)
|
.with_dict(dict_object=base_config)
|
||||||
.with_dict(dict_object={"action": "list", "type": "all"})
|
.with_dict(dict_object={"action": "list", "type": "all"})
|
||||||
)
|
)
|
||||||
client = LexiconClient(query)
|
client = LexiconClient(query)
|
||||||
try:
|
try:
|
||||||
client.provider.authenticate()
|
client.provider.authenticate()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise YunohostValidationError("domain_dns_push_failed_to_authenticate", domain=domain, error=str(e))
|
raise YunohostValidationError(
|
||||||
|
"domain_dns_push_failed_to_authenticate", domain=domain, error=str(e)
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
current_records = client.provider.list_records()
|
current_records = client.provider.list_records()
|
||||||
|
@ -666,7 +705,11 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
|
|
||||||
# Ignore records which are for a higher-level domain
|
# Ignore records which are for a higher-level domain
|
||||||
# i.e. we don't care about the records for domain.tld when pushing yuno.domain.tld
|
# i.e. we don't care about the records for domain.tld when pushing yuno.domain.tld
|
||||||
current_records = [r for r in current_records if r['name'].endswith(f'.{domain}') or r['name'] == domain]
|
current_records = [
|
||||||
|
r
|
||||||
|
for r in current_records
|
||||||
|
if r["name"].endswith(f".{domain}") or r["name"] == domain
|
||||||
|
]
|
||||||
|
|
||||||
for record in current_records:
|
for record in current_records:
|
||||||
|
|
||||||
|
@ -674,7 +717,11 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
record["name"] = record["name"].strip("@").strip(".")
|
record["name"] = record["name"].strip("@").strip(".")
|
||||||
|
|
||||||
# Some API return '@' in content and we shall convert it to absolute/fqdn
|
# Some API return '@' in content and we shall convert it to absolute/fqdn
|
||||||
record["content"] = record["content"].replace('@.', base_dns_zone + ".").replace('@', base_dns_zone + ".")
|
record["content"] = (
|
||||||
|
record["content"]
|
||||||
|
.replace("@.", base_dns_zone + ".")
|
||||||
|
.replace("@", base_dns_zone + ".")
|
||||||
|
)
|
||||||
|
|
||||||
if record["type"] == "TXT":
|
if record["type"] == "TXT":
|
||||||
if not record["content"].startswith('"'):
|
if not record["content"].startswith('"'):
|
||||||
|
@ -683,7 +730,9 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
record["content"] = record["content"] + '"'
|
record["content"] = record["content"] + '"'
|
||||||
|
|
||||||
# Check if this record was previously set by YunoHost
|
# Check if this record was previously set by YunoHost
|
||||||
record["managed_by_yunohost"] = _hash_dns_record(record) in managed_dns_records_hashes
|
record["managed_by_yunohost"] = (
|
||||||
|
_hash_dns_record(record) in managed_dns_records_hashes
|
||||||
|
)
|
||||||
|
|
||||||
# Step 0 : Get the list of unique (type, name)
|
# Step 0 : Get the list of unique (type, name)
|
||||||
# And compare the current and wanted records
|
# And compare the current and wanted records
|
||||||
|
@ -699,8 +748,12 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
# (SRV, .domain.tld) 0 5 5269 domain.tld
|
# (SRV, .domain.tld) 0 5 5269 domain.tld
|
||||||
changes = {"delete": [], "update": [], "create": [], "unchanged": []}
|
changes = {"delete": [], "update": [], "create": [], "unchanged": []}
|
||||||
|
|
||||||
type_and_names = sorted(set([(r["type"], r["name"]) for r in current_records + wanted_records]))
|
type_and_names = sorted(
|
||||||
comparison = {type_and_name: {"current": [], "wanted": []} for type_and_name in type_and_names}
|
set([(r["type"], r["name"]) for r in current_records + wanted_records])
|
||||||
|
)
|
||||||
|
comparison = {
|
||||||
|
type_and_name: {"current": [], "wanted": []} for type_and_name in type_and_names
|
||||||
|
}
|
||||||
|
|
||||||
for record in current_records:
|
for record in current_records:
|
||||||
comparison[(record["type"], record["name"])]["current"].append(record)
|
comparison[(record["type"], record["name"])]["current"].append(record)
|
||||||
|
@ -748,7 +801,9 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
|
|
||||||
def likeliness(r):
|
def likeliness(r):
|
||||||
# We compute this only on the first 100 chars, to have a high value even for completely different DKIM keys
|
# We compute this only on the first 100 chars, to have a high value even for completely different DKIM keys
|
||||||
return SequenceMatcher(None, r["content"][:100], record["content"][:100]).ratio()
|
return SequenceMatcher(
|
||||||
|
None, r["content"][:100], record["content"][:100]
|
||||||
|
).ratio()
|
||||||
|
|
||||||
matches = sorted(current, key=lambda r: likeliness(r), reverse=True)
|
matches = sorted(current, key=lambda r: likeliness(r), reverse=True)
|
||||||
if matches and likeliness(matches[0]) > 0.50:
|
if matches and likeliness(matches[0]) > 0.50:
|
||||||
|
@ -770,7 +825,7 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
|
|
||||||
def relative_name(name):
|
def relative_name(name):
|
||||||
name = name.strip(".")
|
name = name.strip(".")
|
||||||
name = name.replace('.' + base_dns_zone, "")
|
name = name.replace("." + base_dns_zone, "")
|
||||||
name = name.replace(base_dns_zone, "@")
|
name = name.replace(base_dns_zone, "@")
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
@ -780,24 +835,30 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
t = record["type"]
|
t = record["type"]
|
||||||
|
|
||||||
if not force and action in ["update", "delete"]:
|
if not force and action in ["update", "delete"]:
|
||||||
ignored = "" if record["managed_by_yunohost"] else "(ignored, won't be changed by Yunohost unless forced)"
|
ignored = (
|
||||||
|
""
|
||||||
|
if record["managed_by_yunohost"]
|
||||||
|
else "(ignored, won't be changed by Yunohost unless forced)"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
ignored = ""
|
ignored = ""
|
||||||
|
|
||||||
if action == "create":
|
if action == "create":
|
||||||
old_content = record.get("old_content", "(None)")[:30]
|
old_content = record.get("old_content", "(None)")[:30]
|
||||||
new_content = record.get("content", "(None)")[:30]
|
new_content = record.get("content", "(None)")[:30]
|
||||||
return f'{name:>20} [{t:^5}] {new_content:^30} {ignored}'
|
return f"{name:>20} [{t:^5}] {new_content:^30} {ignored}"
|
||||||
elif action == "update":
|
elif action == "update":
|
||||||
old_content = record.get("old_content", "(None)")[:30]
|
old_content = record.get("old_content", "(None)")[:30]
|
||||||
new_content = record.get("content", "(None)")[:30]
|
new_content = record.get("content", "(None)")[:30]
|
||||||
return f'{name:>20} [{t:^5}] {old_content:^30} -> {new_content:^30} {ignored}'
|
return (
|
||||||
|
f"{name:>20} [{t:^5}] {old_content:^30} -> {new_content:^30} {ignored}"
|
||||||
|
)
|
||||||
elif action == "unchanged":
|
elif action == "unchanged":
|
||||||
old_content = new_content = record.get("content", "(None)")[:30]
|
old_content = new_content = record.get("content", "(None)")[:30]
|
||||||
return f'{name:>20} [{t:^5}] {old_content:^30}'
|
return f"{name:>20} [{t:^5}] {old_content:^30}"
|
||||||
else:
|
else:
|
||||||
old_content = record.get("content", "(None)")[:30]
|
old_content = record.get("content", "(None)")[:30]
|
||||||
return f'{name:>20} [{t:^5}] {old_content:^30} {ignored}'
|
return f"{name:>20} [{t:^5}] {old_content:^30} {ignored}"
|
||||||
|
|
||||||
if dry_run:
|
if dry_run:
|
||||||
if Moulinette.interface.type == "api":
|
if Moulinette.interface.type == "api":
|
||||||
|
@ -852,8 +913,10 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
|
|
||||||
for record in changes[action]:
|
for record in changes[action]:
|
||||||
|
|
||||||
relative_name = record['name'].replace(base_dns_zone, '').rstrip('.') or '@'
|
relative_name = record["name"].replace(base_dns_zone, "").rstrip(".") or "@"
|
||||||
progress(f"{action} {record['type']:^5} / {relative_name}") # FIXME: i18n but meh
|
progress(
|
||||||
|
f"{action} {record['type']:^5} / {relative_name}"
|
||||||
|
) # FIXME: i18n but meh
|
||||||
|
|
||||||
# Apparently Lexicon yields us some 'id' during fetch
|
# Apparently Lexicon yields us some 'id' during fetch
|
||||||
# But wants 'identifier' during push ...
|
# But wants 'identifier' during push ...
|
||||||
|
@ -865,8 +928,12 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
if record["name"] == base_dns_zone:
|
if record["name"] == base_dns_zone:
|
||||||
record["name"] = "@." + record["name"]
|
record["name"] = "@." + record["name"]
|
||||||
if record["type"] in ["MX", "SRV", "CAA"]:
|
if record["type"] in ["MX", "SRV", "CAA"]:
|
||||||
logger.warning(f"Pushing {record['type']} records is not properly supported by Lexicon/Godaddy.")
|
logger.warning(
|
||||||
results["warnings"].append(f"Pushing {record['type']} records is not properly supported by Lexicon/Godaddy.")
|
f"Pushing {record['type']} records is not properly supported by Lexicon/Godaddy."
|
||||||
|
)
|
||||||
|
results["warnings"].append(
|
||||||
|
f"Pushing {record['type']} records is not properly supported by Lexicon/Godaddy."
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
record["action"] = action
|
record["action"] = action
|
||||||
|
@ -879,14 +946,26 @@ def domain_dns_push(operation_logger, domain, dry_run=False, force=False, purge=
|
||||||
try:
|
try:
|
||||||
result = LexiconClient(query).execute()
|
result = LexiconClient(query).execute()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = m18n.n("domain_dns_push_record_failed", action=action, type=record['type'], name=record['name'], error=str(e))
|
msg = m18n.n(
|
||||||
|
"domain_dns_push_record_failed",
|
||||||
|
action=action,
|
||||||
|
type=record["type"],
|
||||||
|
name=record["name"],
|
||||||
|
error=str(e),
|
||||||
|
)
|
||||||
logger.error(msg)
|
logger.error(msg)
|
||||||
results["errors"].append(msg)
|
results["errors"].append(msg)
|
||||||
else:
|
else:
|
||||||
if result:
|
if result:
|
||||||
new_managed_dns_records_hashes.append(_hash_dns_record(record))
|
new_managed_dns_records_hashes.append(_hash_dns_record(record))
|
||||||
else:
|
else:
|
||||||
msg = m18n.n("domain_dns_push_record_failed", action=action, type=record['type'], name=record['name'], error="unkonwn error?")
|
msg = m18n.n(
|
||||||
|
"domain_dns_push_record_failed",
|
||||||
|
action=action,
|
||||||
|
type=record["type"],
|
||||||
|
name=record["name"],
|
||||||
|
error="unkonwn error?",
|
||||||
|
)
|
||||||
logger.error(msg)
|
logger.error(msg)
|
||||||
results["errors"].append(msg)
|
results["errors"].append(msg)
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,7 @@ from yunohost.app import (
|
||||||
_get_app_settings,
|
_get_app_settings,
|
||||||
_get_conflicting_apps,
|
_get_conflicting_apps,
|
||||||
)
|
)
|
||||||
from yunohost.regenconf import (
|
from yunohost.regenconf import regen_conf, _force_clear_hashes, _process_regen_conf
|
||||||
regen_conf, _force_clear_hashes, _process_regen_conf
|
|
||||||
)
|
|
||||||
from yunohost.utils.config import ConfigPanel, Question
|
from yunohost.utils.config import ConfigPanel, Question
|
||||||
from yunohost.utils.error import YunohostError, YunohostValidationError
|
from yunohost.utils.error import YunohostError, YunohostValidationError
|
||||||
from yunohost.log import is_unit_operation
|
from yunohost.log import is_unit_operation
|
||||||
|
@ -392,13 +390,15 @@ def _get_maindomain():
|
||||||
return maindomain
|
return maindomain
|
||||||
|
|
||||||
|
|
||||||
def domain_config_get(domain, key='', full=False, export=False):
|
def domain_config_get(domain, key="", full=False, export=False):
|
||||||
"""
|
"""
|
||||||
Display a domain configuration
|
Display a domain configuration
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if full and export:
|
if full and export:
|
||||||
raise YunohostValidationError("You can't use --full and --export together.", raw_msg=True)
|
raise YunohostValidationError(
|
||||||
|
"You can't use --full and --export together.", raw_msg=True
|
||||||
|
)
|
||||||
|
|
||||||
if full:
|
if full:
|
||||||
mode = "full"
|
mode = "full"
|
||||||
|
@ -412,7 +412,9 @@ def domain_config_get(domain, key='', full=False, export=False):
|
||||||
|
|
||||||
|
|
||||||
@is_unit_operation()
|
@is_unit_operation()
|
||||||
def domain_config_set(operation_logger, domain, key=None, value=None, args=None, args_file=None):
|
def domain_config_set(
|
||||||
|
operation_logger, domain, key=None, value=None, args=None, args_file=None
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Apply a new domain configuration
|
Apply a new domain configuration
|
||||||
"""
|
"""
|
||||||
|
@ -422,14 +424,13 @@ def domain_config_set(operation_logger, domain, key=None, value=None, args=None,
|
||||||
|
|
||||||
|
|
||||||
class DomainConfigPanel(ConfigPanel):
|
class DomainConfigPanel(ConfigPanel):
|
||||||
|
|
||||||
def __init__(self, domain):
|
def __init__(self, domain):
|
||||||
_assert_domain_exists(domain)
|
_assert_domain_exists(domain)
|
||||||
self.domain = domain
|
self.domain = domain
|
||||||
self.save_mode = "diff"
|
self.save_mode = "diff"
|
||||||
super().__init__(
|
super().__init__(
|
||||||
config_path=DOMAIN_CONFIG_PATH,
|
config_path=DOMAIN_CONFIG_PATH,
|
||||||
save_path=f"{DOMAIN_SETTINGS_DIR}/{domain}.yml"
|
save_path=f"{DOMAIN_SETTINGS_DIR}/{domain}.yml",
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_toml(self):
|
def _get_toml(self):
|
||||||
|
@ -437,12 +438,14 @@ class DomainConfigPanel(ConfigPanel):
|
||||||
|
|
||||||
toml = super()._get_toml()
|
toml = super()._get_toml()
|
||||||
|
|
||||||
toml['feature']['xmpp']['xmpp']['default'] = 1 if self.domain == _get_maindomain() else 0
|
toml["feature"]["xmpp"]["xmpp"]["default"] = (
|
||||||
toml['dns']['registrar'] = _get_registrar_config_section(self.domain)
|
1 if self.domain == _get_maindomain() else 0
|
||||||
|
)
|
||||||
|
toml["dns"]["registrar"] = _get_registrar_config_section(self.domain)
|
||||||
|
|
||||||
# FIXME: Ugly hack to save the registar id/value and reinject it in _load_current_values ...
|
# FIXME: Ugly hack to save the registar id/value and reinject it in _load_current_values ...
|
||||||
self.registar_id = toml['dns']['registrar']['registrar']['value']
|
self.registar_id = toml["dns"]["registrar"]["registrar"]["value"]
|
||||||
del toml['dns']['registrar']['registrar']['value']
|
del toml["dns"]["registrar"]["registrar"]["value"]
|
||||||
|
|
||||||
return toml
|
return toml
|
||||||
|
|
||||||
|
@ -511,9 +514,11 @@ def domain_dns_conf(domain):
|
||||||
|
|
||||||
def domain_dns_suggest(domain):
|
def domain_dns_suggest(domain):
|
||||||
import yunohost.dns
|
import yunohost.dns
|
||||||
|
|
||||||
return yunohost.dns.domain_dns_suggest(domain)
|
return yunohost.dns.domain_dns_suggest(domain)
|
||||||
|
|
||||||
|
|
||||||
def domain_dns_push(domain, dry_run, force, purge):
|
def domain_dns_push(domain, dry_run, force, purge):
|
||||||
import yunohost.dns
|
import yunohost.dns
|
||||||
|
|
||||||
return yunohost.dns.domain_dns_push(domain, dry_run, force, purge)
|
return yunohost.dns.domain_dns_push(domain, dry_run, force, purge)
|
||||||
|
|
|
@ -308,7 +308,9 @@ def dyndns_update(
|
||||||
logger.debug("Requested IPv4/v6 are (%s, %s)" % (ipv4, ipv6))
|
logger.debug("Requested IPv4/v6 are (%s, %s)" % (ipv4, ipv6))
|
||||||
|
|
||||||
if ipv4 is None and ipv6 is None:
|
if ipv4 is None and ipv6 is None:
|
||||||
logger.debug("No ipv4 nor ipv6 ?! Sounds like the server is not connected to the internet, or the ip.yunohost.org infrastructure is down somehow")
|
logger.debug(
|
||||||
|
"No ipv4 nor ipv6 ?! Sounds like the server is not connected to the internet, or the ip.yunohost.org infrastructure is down somehow"
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# no need to update
|
# no need to update
|
||||||
|
|
|
@ -75,6 +75,7 @@ moulinette.core.Moulinette18n.n = new_m18nn
|
||||||
def pytest_cmdline_main(config):
|
def pytest_cmdline_main(config):
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.path.insert(0, "/usr/lib/moulinette/")
|
sys.path.insert(0, "/usr/lib/moulinette/")
|
||||||
import yunohost
|
import yunohost
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,9 @@ def test_get_dns_zone_from_domain_existing():
|
||||||
assert _get_dns_zone_for_domain("donate.yunohost.org") == "yunohost.org"
|
assert _get_dns_zone_for_domain("donate.yunohost.org") == "yunohost.org"
|
||||||
assert _get_dns_zone_for_domain("fr.wikipedia.org") == "wikipedia.org"
|
assert _get_dns_zone_for_domain("fr.wikipedia.org") == "wikipedia.org"
|
||||||
assert _get_dns_zone_for_domain("www.fr.wikipedia.org") == "wikipedia.org"
|
assert _get_dns_zone_for_domain("www.fr.wikipedia.org") == "wikipedia.org"
|
||||||
assert _get_dns_zone_for_domain("non-existing-domain.yunohost.org") == "yunohost.org"
|
assert (
|
||||||
|
_get_dns_zone_for_domain("non-existing-domain.yunohost.org") == "yunohost.org"
|
||||||
|
)
|
||||||
assert _get_dns_zone_for_domain("yolo.nohost.me") == "nohost.me"
|
assert _get_dns_zone_for_domain("yolo.nohost.me") == "nohost.me"
|
||||||
assert _get_dns_zone_for_domain("foo.yolo.nohost.me") == "nohost.me"
|
assert _get_dns_zone_for_domain("foo.yolo.nohost.me") == "nohost.me"
|
||||||
assert _get_dns_zone_for_domain("yolo.test") == "yolo.test"
|
assert _get_dns_zone_for_domain("yolo.test") == "yolo.test"
|
||||||
|
@ -48,11 +50,17 @@ def test_magic_guess_registrar_weird_domain():
|
||||||
|
|
||||||
|
|
||||||
def test_magic_guess_registrar_ovh():
|
def test_magic_guess_registrar_ovh():
|
||||||
assert _get_registrar_config_section("yolo.yunohost.org")["registrar"]["value"] == "ovh"
|
assert (
|
||||||
|
_get_registrar_config_section("yolo.yunohost.org")["registrar"]["value"]
|
||||||
|
== "ovh"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_magic_guess_registrar_yunodyndns():
|
def test_magic_guess_registrar_yunodyndns():
|
||||||
assert _get_registrar_config_section("yolo.nohost.me")["registrar"]["value"] == "yunohost"
|
assert (
|
||||||
|
_get_registrar_config_section("yolo.nohost.me")["registrar"]["value"]
|
||||||
|
== "yunohost"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -66,6 +74,7 @@ def test_domain_dns_suggest(example_domain):
|
||||||
|
|
||||||
assert _build_dns_conf(example_domain)
|
assert _build_dns_conf(example_domain)
|
||||||
|
|
||||||
#def domain_dns_push(domain, dry_run):
|
|
||||||
|
# def domain_dns_push(domain, dry_run):
|
||||||
# import yunohost.dns
|
# import yunohost.dns
|
||||||
# return yunohost.dns.domain_registrar_push(domain, dry_run)
|
# return yunohost.dns.domain_registrar_push(domain, dry_run)
|
||||||
|
|
|
@ -15,11 +15,7 @@ from yunohost.domain import (
|
||||||
domain_config_set,
|
domain_config_set,
|
||||||
)
|
)
|
||||||
|
|
||||||
TEST_DOMAINS = [
|
TEST_DOMAINS = ["example.tld", "sub.example.tld", "other-example.com"]
|
||||||
"example.tld",
|
|
||||||
"sub.example.tld",
|
|
||||||
"other-example.com"
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def setup_function(function):
|
def setup_function(function):
|
||||||
|
|
|
@ -518,9 +518,7 @@ def test_question_password_input_test_ask():
|
||||||
|
|
||||||
with patch.object(
|
with patch.object(
|
||||||
Moulinette, "prompt", return_value="some_value"
|
Moulinette, "prompt", return_value="some_value"
|
||||||
) as prompt, patch.object(
|
) as prompt, patch.object(os, "isatty", return_value=True):
|
||||||
os, "isatty", return_value=True
|
|
||||||
):
|
|
||||||
parse_args_in_yunohost_format(answers, questions)
|
parse_args_in_yunohost_format(answers, questions)
|
||||||
prompt.assert_called_with(
|
prompt.assert_called_with(
|
||||||
message=ask_text,
|
message=ask_text,
|
||||||
|
@ -547,9 +545,7 @@ def test_question_password_input_test_ask_with_example():
|
||||||
|
|
||||||
with patch.object(
|
with patch.object(
|
||||||
Moulinette, "prompt", return_value="some_value"
|
Moulinette, "prompt", return_value="some_value"
|
||||||
) as prompt, patch.object(
|
) as prompt, patch.object(os, "isatty", return_value=True):
|
||||||
os, "isatty", return_value=True
|
|
||||||
):
|
|
||||||
parse_args_in_yunohost_format(answers, questions)
|
parse_args_in_yunohost_format(answers, questions)
|
||||||
assert ask_text in prompt.call_args[1]["message"]
|
assert ask_text in prompt.call_args[1]["message"]
|
||||||
assert example_text in prompt.call_args[1]["message"]
|
assert example_text in prompt.call_args[1]["message"]
|
||||||
|
@ -571,9 +567,7 @@ def test_question_password_input_test_ask_with_help():
|
||||||
|
|
||||||
with patch.object(
|
with patch.object(
|
||||||
Moulinette, "prompt", return_value="some_value"
|
Moulinette, "prompt", return_value="some_value"
|
||||||
) as prompt, patch.object(
|
) as prompt, patch.object(os, "isatty", return_value=True):
|
||||||
os, "isatty", return_value=True
|
|
||||||
):
|
|
||||||
parse_args_in_yunohost_format(answers, questions)
|
parse_args_in_yunohost_format(answers, questions)
|
||||||
assert ask_text in prompt.call_args[1]["message"]
|
assert ask_text in prompt.call_args[1]["message"]
|
||||||
assert help_text in prompt.call_args[1]["message"]
|
assert help_text in prompt.call_args[1]["message"]
|
||||||
|
|
|
@ -53,8 +53,8 @@ class ConfigPanel:
|
||||||
self.values = {}
|
self.values = {}
|
||||||
self.new_values = {}
|
self.new_values = {}
|
||||||
|
|
||||||
def get(self, key='', mode='classic'):
|
def get(self, key="", mode="classic"):
|
||||||
self.filter_key = key or ''
|
self.filter_key = key or ""
|
||||||
|
|
||||||
# Read config panel toml
|
# Read config panel toml
|
||||||
self._get_config_panel()
|
self._get_config_panel()
|
||||||
|
|
|
@ -91,4 +91,3 @@ def dig(
|
||||||
answers = [answer.to_text() for answer in answers]
|
answers = [answer.to_text() for answer in answers]
|
||||||
|
|
||||||
return ("ok", answers)
|
return ("ok", answers)
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ class LDAPInterface:
|
||||||
raise YunohostError(
|
raise YunohostError(
|
||||||
"Service slapd is not running but is required to perform this action ... "
|
"Service slapd is not running but is required to perform this action ... "
|
||||||
"You can try to investigate what's happening with 'systemctl status slapd'",
|
"You can try to investigate what's happening with 'systemctl status slapd'",
|
||||||
raw_msg=True
|
raw_msg=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check that we are indeed logged in with the right identity
|
# Check that we are indeed logged in with the right identity
|
||||||
|
|
|
@ -130,13 +130,13 @@ def find_expected_string_keys():
|
||||||
yield "backup_applying_method_%s" % method
|
yield "backup_applying_method_%s" % method
|
||||||
yield "backup_method_%s_finished" % method
|
yield "backup_method_%s_finished" % method
|
||||||
|
|
||||||
registrars = toml.load(open('data/other/registrar_list.toml'))
|
registrars = toml.load(open("data/other/registrar_list.toml"))
|
||||||
supported_registrars = ["ovh", "gandi", "godaddy"]
|
supported_registrars = ["ovh", "gandi", "godaddy"]
|
||||||
for registrar in supported_registrars:
|
for registrar in supported_registrars:
|
||||||
for key in registrars[registrar].keys():
|
for key in registrars[registrar].keys():
|
||||||
yield f"domain_config_{key}"
|
yield f"domain_config_{key}"
|
||||||
|
|
||||||
domain_config = toml.load(open('data/other/config_domain.toml'))
|
domain_config = toml.load(open("data/other/config_domain.toml"))
|
||||||
for panel in domain_config.values():
|
for panel in domain_config.values():
|
||||||
if not isinstance(panel, dict):
|
if not isinstance(panel, dict):
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Add table
Reference in a new issue