mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
update domain.py to new config panel
This commit is contained in:
parent
807f5956ea
commit
0778cf3ffe
4 changed files with 79 additions and 105 deletions
|
@ -5,10 +5,10 @@ i18n = "domain_config"
|
||||||
name = "Features"
|
name = "Features"
|
||||||
|
|
||||||
[feature.app]
|
[feature.app]
|
||||||
|
|
||||||
[feature.app.default_app]
|
[feature.app.default_app]
|
||||||
type = "app"
|
type = "app"
|
||||||
filter = "is_webapp"
|
filter = "is_webapp"
|
||||||
default = "_none"
|
|
||||||
|
|
||||||
[feature.mail]
|
[feature.mail]
|
||||||
|
|
||||||
|
@ -44,28 +44,30 @@ name = "Certificate"
|
||||||
[cert.cert.cert_validity]
|
[cert.cert.cert_validity]
|
||||||
type = "number"
|
type = "number"
|
||||||
readonly = true
|
readonly = true
|
||||||
visible = "false"
|
visible = false
|
||||||
# Automatically filled by DomainConfigPanel
|
# Automatically filled by DomainConfigPanel
|
||||||
|
|
||||||
[cert.cert.cert_issuer]
|
[cert.cert.cert_issuer]
|
||||||
type = "string"
|
type = "string"
|
||||||
|
readonly = true
|
||||||
visible = false
|
visible = false
|
||||||
# Automatically filled by DomainConfigPanel
|
# Automatically filled by DomainConfigPanel
|
||||||
|
|
||||||
[cert.cert.acme_eligible]
|
[cert.cert.acme_eligible]
|
||||||
type = "boolean"
|
type = "boolean"
|
||||||
|
readonly = true
|
||||||
visible = false
|
visible = false
|
||||||
# Automatically filled by DomainConfigPanel
|
# Automatically filled by DomainConfigPanel
|
||||||
|
|
||||||
[cert.cert.acme_eligible_explain]
|
[cert.cert.acme_eligible_explain]
|
||||||
type = "alert"
|
type = "alert"
|
||||||
style = "warning"
|
style = "warning"
|
||||||
visible = "acme_eligible == false || acme_eligible == null"
|
visible = "!acme_eligible"
|
||||||
|
|
||||||
[cert.cert.cert_no_checks]
|
[cert.cert.cert_no_checks]
|
||||||
type = "boolean"
|
type = "boolean"
|
||||||
default = false
|
default = false
|
||||||
visible = "acme_eligible == false || acme_eligible == null"
|
visible = "!acme_eligible"
|
||||||
|
|
||||||
[cert.cert.cert_install]
|
[cert.cert.cert_install]
|
||||||
type = "button"
|
type = "button"
|
||||||
|
|
|
@ -1411,7 +1411,7 @@ def app_remove(operation_logger, app, purge=False, force_workdir=None):
|
||||||
|
|
||||||
for domain in domain_list()["domains"]:
|
for domain in domain_list()["domains"]:
|
||||||
if domain_config_get(domain, "feature.app.default_app") == app:
|
if domain_config_get(domain, "feature.app.default_app") == app:
|
||||||
domain_config_set(domain, "feature.app.default_app", "_none")
|
domain_config_set(domain, "feature.app.default_app", None)
|
||||||
|
|
||||||
if ret == 0:
|
if ret == 0:
|
||||||
logger.success(m18n.n("app_removed", app=app))
|
logger.success(m18n.n("app_removed", app=app))
|
||||||
|
@ -1448,7 +1448,7 @@ def app_makedefault(operation_logger, app, domain=None, undo=False):
|
||||||
operation_logger.start()
|
operation_logger.start()
|
||||||
|
|
||||||
if undo:
|
if undo:
|
||||||
domain_config_set(domain, "feature.app.default_app", "_none")
|
domain_config_set(domain, "feature.app.default_app", None)
|
||||||
else:
|
else:
|
||||||
domain_config_set(domain, "feature.app.default_app", app)
|
domain_config_set(domain, "feature.app.default_app", app)
|
||||||
|
|
||||||
|
@ -1701,7 +1701,7 @@ def app_ssowatconf():
|
||||||
|
|
||||||
for domain in domains:
|
for domain in domains:
|
||||||
default_app = domain_config_get(domain, "feature.app.default_app")
|
default_app = domain_config_get(domain, "feature.app.default_app")
|
||||||
if default_app != "_none" and _is_installed(default_app):
|
if default_app and _is_installed(default_app):
|
||||||
app_settings = _get_app_settings(default_app)
|
app_settings = _get_app_settings(default_app)
|
||||||
app_domain = app_settings["domain"]
|
app_domain = app_settings["domain"]
|
||||||
app_path = app_settings["path"]
|
app_path = app_settings["path"]
|
||||||
|
|
10
src/dns.py
10
src/dns.py
|
@ -529,7 +529,7 @@ def _get_registrar_config_section(domain):
|
||||||
parent_domain=parent_domain,
|
parent_domain=parent_domain,
|
||||||
parent_domain_link=parent_domain_link,
|
parent_domain_link=parent_domain_link,
|
||||||
),
|
),
|
||||||
"value": "parent_domain",
|
"default": "parent_domain",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return OrderedDict(registrar_infos)
|
return OrderedDict(registrar_infos)
|
||||||
|
@ -542,7 +542,7 @@ def _get_registrar_config_section(domain):
|
||||||
"type": "alert",
|
"type": "alert",
|
||||||
"style": "success",
|
"style": "success",
|
||||||
"ask": m18n.n("domain_dns_registrar_yunohost"),
|
"ask": m18n.n("domain_dns_registrar_yunohost"),
|
||||||
"value": "yunohost",
|
"default": "yunohost",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return OrderedDict(registrar_infos)
|
return OrderedDict(registrar_infos)
|
||||||
|
@ -552,7 +552,7 @@ def _get_registrar_config_section(domain):
|
||||||
"type": "alert",
|
"type": "alert",
|
||||||
"style": "info",
|
"style": "info",
|
||||||
"ask": m18n.n("domain_dns_conf_special_use_tld"),
|
"ask": m18n.n("domain_dns_conf_special_use_tld"),
|
||||||
"value": None,
|
"default": None,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -564,7 +564,7 @@ def _get_registrar_config_section(domain):
|
||||||
"type": "alert",
|
"type": "alert",
|
||||||
"style": "warning",
|
"style": "warning",
|
||||||
"ask": m18n.n("domain_dns_registrar_not_supported"),
|
"ask": m18n.n("domain_dns_registrar_not_supported"),
|
||||||
"value": None,
|
"default": None,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -573,7 +573,7 @@ def _get_registrar_config_section(domain):
|
||||||
"type": "alert",
|
"type": "alert",
|
||||||
"style": "info",
|
"style": "info",
|
||||||
"ask": m18n.n("domain_dns_registrar_supported", registrar=registrar),
|
"ask": m18n.n("domain_dns_registrar_supported", registrar=registrar),
|
||||||
"value": registrar,
|
"default": registrar,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
158
src/domain.py
158
src/domain.py
|
@ -18,7 +18,7 @@
|
||||||
#
|
#
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from typing import List, Optional
|
from typing import List, Optional, TYPE_CHECKING, Union, Any
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from moulinette import m18n, Moulinette
|
from moulinette import m18n, Moulinette
|
||||||
|
@ -33,10 +33,14 @@ from yunohost.app import (
|
||||||
_get_conflicting_apps,
|
_get_conflicting_apps,
|
||||||
)
|
)
|
||||||
from yunohost.regenconf import regen_conf, _force_clear_hashes, _process_regen_conf
|
from yunohost.regenconf import regen_conf, _force_clear_hashes, _process_regen_conf
|
||||||
from yunohost.utils.config import ConfigPanel, Question
|
from yunohost.utils.configpanel import Config
|
||||||
|
from yunohost.utils.config import 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
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from yunohost.utils.configpanel import YunoForm
|
||||||
|
|
||||||
logger = getActionLogger("yunohost.domain")
|
logger = getActionLogger("yunohost.domain")
|
||||||
|
|
||||||
DOMAIN_SETTINGS_DIR = "/etc/yunohost/domains"
|
DOMAIN_SETTINGS_DIR = "/etc/yunohost/domains"
|
||||||
|
@ -532,135 +536,103 @@ def domain_config_set(
|
||||||
return config.set(key, value, args, args_file, operation_logger=operation_logger)
|
return config.set(key, value, args, args_file, operation_logger=operation_logger)
|
||||||
|
|
||||||
|
|
||||||
class DomainConfigPanel(ConfigPanel):
|
class DomainConfigPanel(Config):
|
||||||
entity_type = "domain"
|
entity_type = "domain"
|
||||||
save_path_tpl = f"{DOMAIN_SETTINGS_DIR}/{{entity}}.yml"
|
save_path_tpl = f"{DOMAIN_SETTINGS_DIR}/{{entity}}.yml"
|
||||||
save_mode = "diff"
|
save_mode = "diff"
|
||||||
|
|
||||||
def _apply(self):
|
# TODO add mechanism to share some settings with other domains on the same zone
|
||||||
if (
|
|
||||||
"default_app" in self.future_values
|
|
||||||
and self.future_values["default_app"] != self.values["default_app"]
|
|
||||||
):
|
|
||||||
from yunohost.app import app_ssowatconf, app_map
|
|
||||||
|
|
||||||
if "/" in app_map(raw=True).get(self.entity, {}):
|
def _get_config_data(
|
||||||
raise YunohostValidationError(
|
self,
|
||||||
"app_make_default_location_already_used",
|
panel_id: Union[str, None] = None,
|
||||||
app=self.future_values["default_app"],
|
section_id: Union[str, None] = None,
|
||||||
domain=self.entity,
|
option_id: Union[str, None] = None,
|
||||||
other_app=app_map(raw=True)[self.entity]["/"]["id"],
|
) -> dict[str, Any]:
|
||||||
)
|
any_filter = all([panel_id, section_id, option_id])
|
||||||
|
config_data = super()._get_config_data(panel_id, section_id, option_id)
|
||||||
|
|
||||||
super()._apply()
|
config_data["feature"]["xmpp"]["xmpp"]["default"] = (
|
||||||
|
|
||||||
# Reload ssowat if default app changed
|
|
||||||
if (
|
|
||||||
"default_app" in self.future_values
|
|
||||||
and self.future_values["default_app"] != self.values["default_app"]
|
|
||||||
):
|
|
||||||
app_ssowatconf()
|
|
||||||
|
|
||||||
stuff_to_regen_conf = []
|
|
||||||
if (
|
|
||||||
"xmpp" in self.future_values
|
|
||||||
and self.future_values["xmpp"] != self.values["xmpp"]
|
|
||||||
):
|
|
||||||
stuff_to_regen_conf.append("nginx")
|
|
||||||
stuff_to_regen_conf.append("metronome")
|
|
||||||
|
|
||||||
if (
|
|
||||||
"mail_in" in self.future_values
|
|
||||||
and self.future_values["mail_in"] != self.values["mail_in"]
|
|
||||||
) or (
|
|
||||||
"mail_out" in self.future_values
|
|
||||||
and self.future_values["mail_out"] != self.values["mail_out"]
|
|
||||||
):
|
|
||||||
if "nginx" not in stuff_to_regen_conf:
|
|
||||||
stuff_to_regen_conf.append("nginx")
|
|
||||||
stuff_to_regen_conf.append("postfix")
|
|
||||||
stuff_to_regen_conf.append("dovecot")
|
|
||||||
stuff_to_regen_conf.append("rspamd")
|
|
||||||
|
|
||||||
if stuff_to_regen_conf:
|
|
||||||
regen_conf(names=stuff_to_regen_conf)
|
|
||||||
|
|
||||||
def _get_toml(self):
|
|
||||||
toml = super()._get_toml()
|
|
||||||
|
|
||||||
toml["feature"]["xmpp"]["xmpp"]["default"] = (
|
|
||||||
1 if self.entity == _get_maindomain() else 0
|
1 if self.entity == _get_maindomain() else 0
|
||||||
)
|
)
|
||||||
|
|
||||||
# Optimize wether or not to load the DNS section,
|
# Optimize wether or not to load the DNS section,
|
||||||
# e.g. we don't want to trigger the whole _get_registary_config_section
|
# e.g. we don't want to trigger the whole _get_registary_config_section
|
||||||
# when just getting the current value from the feature section
|
# when just getting the current value from the feature section
|
||||||
filter_key = self.filter_key.split(".") if self.filter_key != "" else []
|
if not any_filter or panel_id == "dns":
|
||||||
if not filter_key or filter_key[0] == "dns":
|
|
||||||
from yunohost.dns import _get_registrar_config_section
|
from yunohost.dns import _get_registrar_config_section
|
||||||
|
|
||||||
toml["dns"]["registrar"] = _get_registrar_config_section(self.entity)
|
config_data["dns"]["registrar"] = _get_registrar_config_section(self.entity)
|
||||||
|
|
||||||
# FIXME: Ugly hack to save the registar id/value and reinject it in _load_current_values ...
|
|
||||||
self.registar_id = toml["dns"]["registrar"]["registrar"]["value"]
|
|
||||||
del toml["dns"]["registrar"]["registrar"]["value"]
|
|
||||||
|
|
||||||
# Cert stuff
|
# Cert stuff
|
||||||
if not filter_key or filter_key[0] == "cert":
|
if not any_filter or panel_id == "cert":
|
||||||
from yunohost.certificate import certificate_status
|
from yunohost.certificate import certificate_status
|
||||||
|
|
||||||
status = certificate_status([self.entity], full=True)["certificates"][
|
status = certificate_status([self.entity], full=True)["certificates"][
|
||||||
self.entity
|
self.entity
|
||||||
]
|
]
|
||||||
|
|
||||||
toml["cert"]["cert"]["cert_summary"]["style"] = status["style"]
|
config_data["cert"]["cert"]["cert_summary"]["style"] = status["style"]
|
||||||
|
|
||||||
# i18n: domain_config_cert_summary_expired
|
# i18n: domain_config_cert_summary_expired
|
||||||
# i18n: domain_config_cert_summary_selfsigned
|
# i18n: domain_config_cert_summary_selfsigned
|
||||||
# i18n: domain_config_cert_summary_abouttoexpire
|
# i18n: domain_config_cert_summary_abouttoexpire
|
||||||
# i18n: domain_config_cert_summary_ok
|
# i18n: domain_config_cert_summary_ok
|
||||||
# i18n: domain_config_cert_summary_letsencrypt
|
# i18n: domain_config_cert_summary_letsencrypt
|
||||||
toml["cert"]["cert"]["cert_summary"]["ask"] = m18n.n(
|
config_data["cert"]["cert"]["cert_summary"]["ask"] = m18n.n(
|
||||||
f"domain_config_cert_summary_{status['summary']}"
|
f"domain_config_cert_summary_{status['summary']}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# FIXME: Ugly hack to save the cert status and reinject it in _load_current_values ...
|
for option_id, status_key in [
|
||||||
self.cert_status = status
|
("cert_validity", "validity"),
|
||||||
|
("cert_issuer", "CA_type"),
|
||||||
|
("acme_eligible", "ACME_eligible"),
|
||||||
|
# FIXME not sure why "summary" was injected in settings values
|
||||||
|
# ("summary", "summary")
|
||||||
|
]:
|
||||||
|
config_data["cert"]["cert"][option_id]["default"] = status[status_key]
|
||||||
|
|
||||||
return toml
|
# Other specific strings used in config panels
|
||||||
|
# i18n: domain_config_cert_renew_help
|
||||||
|
|
||||||
def get(self, key="", mode="classic"):
|
return config_data
|
||||||
result = super().get(key=key, mode=mode)
|
|
||||||
|
|
||||||
if mode == "full":
|
def _apply(self, settings: "YunoForm", exclude=None):
|
||||||
for panel, section, option in self._iterate():
|
# Do not rely on super `_apply` to get new values since it excludes
|
||||||
# This injects:
|
# values that are default values.
|
||||||
# i18n: domain_config_cert_renew_help
|
new_values = settings.dict(exclude_unset=True)
|
||||||
# i18n: domain_config_default_app_help
|
|
||||||
# i18n: domain_config_xmpp_help
|
|
||||||
if m18n.key_exists(self.config["i18n"] + "_" + option["id"] + "_help"):
|
|
||||||
option["help"] = m18n.n(
|
|
||||||
self.config["i18n"] + "_" + option["id"] + "_help"
|
|
||||||
)
|
|
||||||
return self.config
|
|
||||||
|
|
||||||
return result
|
# Check if another app is already the default one
|
||||||
|
# FIXME could be a custom pydantic.validator() instead
|
||||||
|
if "default_app" in new_values:
|
||||||
|
from yunohost.app import app_ssowatconf, app_map
|
||||||
|
|
||||||
def _load_current_values(self):
|
app_map_ = app_map(raw=True).get(self.entity, {})
|
||||||
# TODO add mechanism to share some settings with other domains on the same zone
|
if "/" in app_map_:
|
||||||
super()._load_current_values()
|
raise YunohostValidationError(
|
||||||
|
"app_make_default_location_already_used",
|
||||||
|
app=new_values["default_app"],
|
||||||
|
domain=self.entity,
|
||||||
|
other_app=app_map_["/"]["id"],
|
||||||
|
)
|
||||||
|
|
||||||
# FIXME: Ugly hack to save the registar id/value and reinject it in _load_current_values ...
|
# Save settings (without default values)
|
||||||
filter_key = self.filter_key.split(".") if self.filter_key != "" else []
|
super()._apply(settings)
|
||||||
if not filter_key or filter_key[0] == "dns":
|
|
||||||
self.values["registrar"] = self.registar_id
|
|
||||||
|
|
||||||
# FIXME: Ugly hack to save the cert status and reinject it in _load_current_values ...
|
# Reload ssowat if default app changed
|
||||||
if not filter_key or filter_key[0] == "cert":
|
if "default_app" in new_values:
|
||||||
self.values["cert_validity"] = self.cert_status["validity"]
|
app_ssowatconf()
|
||||||
self.values["cert_issuer"] = self.cert_status["CA_type"]
|
|
||||||
self.values["acme_eligible"] = self.cert_status["ACME_eligible"]
|
stuff_to_regen_conf = set()
|
||||||
self.values["summary"] = self.cert_status["summary"]
|
if "xmpp" in new_values:
|
||||||
|
stuff_to_regen_conf.update({"nginx", "metronome"})
|
||||||
|
|
||||||
|
if "mail_in" in new_values or "mail_out" in new_values:
|
||||||
|
stuff_to_regen_conf.update({"nginx", "postfix", "dovecot", "rspamd"})
|
||||||
|
|
||||||
|
if stuff_to_regen_conf:
|
||||||
|
# TODO `regen_conf` could (only?) accept a set() as "names"
|
||||||
|
regen_conf(names=list(stuff_to_regen_conf))
|
||||||
|
|
||||||
|
|
||||||
def domain_action_run(domain, action, args=None):
|
def domain_action_run(domain, action, args=None):
|
||||||
|
|
Loading…
Add table
Reference in a new issue