diff --git a/hassio/addons/addon.py b/hassio/addons/addon.py index 582c12b9b..6b25b03f0 100644 --- a/hassio/addons/addon.py +++ b/hassio/addons/addon.py @@ -351,7 +351,7 @@ class Addon(AddonModel): options = self.options try: - schema(options) + options = schema(options) write_json_file(self.path_options, options) except vol.Invalid as ex: _LOGGER.error( diff --git a/hassio/addons/validate.py b/hassio/addons/validate.py index bbc46bcc8..687eadfca 100644 --- a/hassio/addons/validate.py +++ b/hassio/addons/validate.py @@ -356,6 +356,8 @@ def _single_validate(coresys, typ, value, key): if str(value).startswith("!secret "): secret: str = value.partition(" ")[2] value = coresys.secrets.get(secret) + if value is None: + raise vol.Invalid(f"Unknown secret {secret}") # parse extend data from type match = RE_SCHEMA_ELEMENT.match(typ) diff --git a/hassio/api/addons.py b/hassio/api/addons.py index 6ee425192..701dc3e39 100644 --- a/hassio/api/addons.py +++ b/hassio/api/addons.py @@ -269,7 +269,9 @@ class APIAddons(CoreSysAttributes): addon_schema = SCHEMA_OPTIONS.extend( {vol.Optional(ATTR_OPTIONS): vol.Any(None, addon.schema)} ) - body: Dict[str, Any] = await api_validate(addon_schema, request) + body: Dict[str, Any] = await api_validate( + addon_schema, request, origin=[ATTR_OPTIONS] + ) if ATTR_OPTIONS in body: addon.options = body[ATTR_OPTIONS] diff --git a/hassio/api/supervisor.py b/hassio/api/supervisor.py index d266f4b2b..0bde1bcf0 100644 --- a/hassio/api/supervisor.py +++ b/hassio/api/supervisor.py @@ -161,7 +161,9 @@ class APISupervisor(CoreSysAttributes): @api_process def reload(self, request: web.Request) -> Awaitable[None]: """Reload add-ons, configuration, etc.""" - return asyncio.shield(self.sys_updater.reload()) + return asyncio.shield( + asyncio.wait([self.sys_updater.reload(), self.sys_secrets.reload()]) + ) @api_process def repair(self, request: web.Request) -> Awaitable[None]: diff --git a/hassio/api/utils.py b/hassio/api/utils.py index 9cbd3fb99..126c2f40d 100644 --- a/hassio/api/utils.py +++ b/hassio/api/utils.py @@ -1,6 +1,7 @@ """Init file for Hass.io util for RESTful API.""" import json import logging +from typing import Optional, List from aiohttp import web import voluptuous as vol @@ -89,12 +90,22 @@ def api_return_ok(data=None): return web.json_response({JSON_RESULT: RESULT_OK, JSON_DATA: data or {}}) -async def api_validate(schema, request): +async def api_validate( + schema: vol.Schema, request: web.Request, origin: Optional[List[str]] = None +): """Validate request data with schema.""" data = await request.json(loads=json_loads) try: - data = schema(data) + data_validated = schema(data) except vol.Invalid as ex: raise APIError(humanize_error(data, ex)) from None - return data + if not origin: + return data_validated + + for origin_value in origin: + if origin_value not in data_validated: + continue + data_validated[origin_value] = data[origin_value] + + return data_validated diff --git a/hassio/tasks.py b/hassio/tasks.py index 36bc8e3ca..aabec5fcd 100644 --- a/hassio/tasks.py +++ b/hassio/tasks.py @@ -19,7 +19,7 @@ RUN_RELOAD_SNAPSHOTS = 72000 RUN_RELOAD_HOST = 72000 RUN_RELOAD_UPDATER = 7200 RUN_RELOAD_INGRESS = 930 -RUN_RELOAD_SECRETS = 900 +RUN_RELOAD_SECRETS = 630 RUN_WATCHDOG_HOMEASSISTANT_DOCKER = 15 RUN_WATCHDOG_HOMEASSISTANT_API = 300