mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-28 11:36:32 +00:00
Update secrets handling (#1289)
* Update secrets handling * Remove start pre_check * fix lint * remove tasker
This commit is contained in:
parent
64fe190119
commit
a12567d0a8
@ -345,11 +345,14 @@ class Addon(AddonModel):
|
|||||||
"""Save data of add-on."""
|
"""Save data of add-on."""
|
||||||
self.sys_addons.data.save_data()
|
self.sys_addons.data.save_data()
|
||||||
|
|
||||||
def write_options(self):
|
async def write_options(self):
|
||||||
"""Return True if add-on options is written to data."""
|
"""Return True if add-on options is written to data."""
|
||||||
schema = self.schema
|
schema = self.schema
|
||||||
options = self.options
|
options = self.options
|
||||||
|
|
||||||
|
# Update secrets for validation
|
||||||
|
await self.sys_secrets.reload()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
options = schema(options)
|
options = schema(options)
|
||||||
write_json_file(self.path_options, options)
|
write_json_file(self.path_options, options)
|
||||||
@ -467,7 +470,7 @@ class Addon(AddonModel):
|
|||||||
self.save_persist()
|
self.save_persist()
|
||||||
|
|
||||||
# Options
|
# Options
|
||||||
self.write_options()
|
await self.write_options()
|
||||||
|
|
||||||
# Sound
|
# Sound
|
||||||
if self.with_audio:
|
if self.with_audio:
|
||||||
|
@ -5,7 +5,6 @@ from typing import Any, Awaitable, Dict, List
|
|||||||
|
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
from voluptuous.humanize import humanize_error
|
|
||||||
|
|
||||||
from ..addons import AnyAddon
|
from ..addons import AnyAddon
|
||||||
from ..docker.stats import DockerStats
|
from ..docker.stats import DockerStats
|
||||||
@ -266,13 +265,16 @@ class APIAddons(CoreSysAttributes):
|
|||||||
"""Store user options for add-on."""
|
"""Store user options for add-on."""
|
||||||
addon: AnyAddon = self._extract_addon(request)
|
addon: AnyAddon = self._extract_addon(request)
|
||||||
|
|
||||||
|
# Update secrets for validation
|
||||||
|
await self.sys_secrets.reload()
|
||||||
|
|
||||||
|
# Extend schema with add-on specific validation
|
||||||
addon_schema = SCHEMA_OPTIONS.extend(
|
addon_schema = SCHEMA_OPTIONS.extend(
|
||||||
{vol.Optional(ATTR_OPTIONS): vol.Any(None, addon.schema)}
|
{vol.Optional(ATTR_OPTIONS): vol.Any(None, addon.schema)}
|
||||||
)
|
)
|
||||||
body: Dict[str, Any] = await api_validate(
|
|
||||||
addon_schema, request, origin=[ATTR_OPTIONS]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
# Validate/Process Body
|
||||||
|
body = await api_validate(addon_schema, request, origin=[ATTR_OPTIONS])
|
||||||
if ATTR_OPTIONS in body:
|
if ATTR_OPTIONS in body:
|
||||||
addon.options = body[ATTR_OPTIONS]
|
addon.options = body[ATTR_OPTIONS]
|
||||||
if ATTR_BOOT in body:
|
if ATTR_BOOT in body:
|
||||||
@ -336,14 +338,6 @@ class APIAddons(CoreSysAttributes):
|
|||||||
def start(self, request: web.Request) -> Awaitable[None]:
|
def start(self, request: web.Request) -> Awaitable[None]:
|
||||||
"""Start add-on."""
|
"""Start add-on."""
|
||||||
addon: AnyAddon = self._extract_addon(request)
|
addon: AnyAddon = self._extract_addon(request)
|
||||||
|
|
||||||
# check options
|
|
||||||
options = addon.options
|
|
||||||
try:
|
|
||||||
addon.schema(options)
|
|
||||||
except vol.Invalid as ex:
|
|
||||||
raise APIError(humanize_error(options, ex)) from None
|
|
||||||
|
|
||||||
return asyncio.shield(addon.start())
|
return asyncio.shield(addon.start())
|
||||||
|
|
||||||
@api_process
|
@api_process
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
"""Init file for Hass.io util for RESTful API."""
|
"""Init file for Hass.io util for RESTful API."""
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from typing import Optional, List
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
from voluptuous.humanize import humanize_error
|
from voluptuous.humanize import humanize_error
|
||||||
|
|
||||||
from ..const import (
|
from ..const import (
|
||||||
JSON_RESULT,
|
CONTENT_TYPE_BINARY,
|
||||||
JSON_DATA,
|
JSON_DATA,
|
||||||
JSON_MESSAGE,
|
JSON_MESSAGE,
|
||||||
RESULT_OK,
|
JSON_RESULT,
|
||||||
RESULT_ERROR,
|
RESULT_ERROR,
|
||||||
CONTENT_TYPE_BINARY,
|
RESULT_OK,
|
||||||
)
|
)
|
||||||
from ..exceptions import HassioError, APIError, APIForbidden
|
from ..exceptions import APIError, APIForbidden, HassioError
|
||||||
|
|
||||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def json_loads(data):
|
def json_loads(data: Any) -> Dict[str, Any]:
|
||||||
"""Extract json from string with support for '' and None."""
|
"""Extract json from string with support for '' and None."""
|
||||||
if not data:
|
if not data:
|
||||||
return {}
|
return {}
|
||||||
@ -78,23 +78,23 @@ def api_process_raw(content):
|
|||||||
return wrap_method
|
return wrap_method
|
||||||
|
|
||||||
|
|
||||||
def api_return_error(message=None):
|
def api_return_error(message: Optional[str] = None) -> web.Response:
|
||||||
"""Return an API error message."""
|
"""Return an API error message."""
|
||||||
return web.json_response(
|
return web.json_response(
|
||||||
{JSON_RESULT: RESULT_ERROR, JSON_MESSAGE: message}, status=400
|
{JSON_RESULT: RESULT_ERROR, JSON_MESSAGE: message}, status=400
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def api_return_ok(data=None):
|
def api_return_ok(data: Optional[Dict[str, Any]] = None) -> web.Response:
|
||||||
"""Return an API ok answer."""
|
"""Return an API ok answer."""
|
||||||
return web.json_response({JSON_RESULT: RESULT_OK, JSON_DATA: data or {}})
|
return web.json_response({JSON_RESULT: RESULT_OK, JSON_DATA: data or {}})
|
||||||
|
|
||||||
|
|
||||||
async def api_validate(
|
async def api_validate(
|
||||||
schema: vol.Schema, request: web.Request, origin: Optional[List[str]] = None
|
schema: vol.Schema, request: web.Request, origin: Optional[List[str]] = None
|
||||||
):
|
) -> Dict[str, Any]:
|
||||||
"""Validate request data with schema."""
|
"""Validate request data with schema."""
|
||||||
data = await request.json(loads=json_loads)
|
data: Dict[str, Any] = await request.json(loads=json_loads)
|
||||||
try:
|
try:
|
||||||
data_validated = schema(data)
|
data_validated = schema(data)
|
||||||
except vol.Invalid as ex:
|
except vol.Invalid as ex:
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
"""Handle Home Assistant secrets to add-ons."""
|
"""Handle Home Assistant secrets to add-ons."""
|
||||||
from typing import Dict
|
from datetime import timedelta
|
||||||
from pathlib import Path
|
|
||||||
import logging
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
from ruamel.yaml import YAML, YAMLError
|
from ruamel.yaml import YAML, YAMLError
|
||||||
|
|
||||||
from .coresys import CoreSys, CoreSysAttributes
|
from .coresys import CoreSys, CoreSysAttributes
|
||||||
|
from .utils import AsyncThrottle
|
||||||
|
|
||||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -38,6 +40,7 @@ class SecretsManager(CoreSysAttributes):
|
|||||||
"""Reload secrets."""
|
"""Reload secrets."""
|
||||||
await self._read_secrets()
|
await self._read_secrets()
|
||||||
|
|
||||||
|
@AsyncThrottle(timedelta(seconds=60))
|
||||||
async def _read_secrets(self):
|
async def _read_secrets(self):
|
||||||
"""Read secrets.yaml into memory."""
|
"""Read secrets.yaml into memory."""
|
||||||
if not self.path_secrets.exists():
|
if not self.path_secrets.exists():
|
||||||
|
@ -16,10 +16,9 @@ RUN_UPDATE_DNS = 30100
|
|||||||
|
|
||||||
RUN_RELOAD_ADDONS = 10800
|
RUN_RELOAD_ADDONS = 10800
|
||||||
RUN_RELOAD_SNAPSHOTS = 72000
|
RUN_RELOAD_SNAPSHOTS = 72000
|
||||||
RUN_RELOAD_HOST = 72000
|
RUN_RELOAD_HOST = 7600
|
||||||
RUN_RELOAD_UPDATER = 7200
|
RUN_RELOAD_UPDATER = 7200
|
||||||
RUN_RELOAD_INGRESS = 930
|
RUN_RELOAD_INGRESS = 930
|
||||||
RUN_RELOAD_SECRETS = 940
|
|
||||||
|
|
||||||
RUN_WATCHDOG_HOMEASSISTANT_DOCKER = 15
|
RUN_WATCHDOG_HOMEASSISTANT_DOCKER = 15
|
||||||
RUN_WATCHDOG_HOMEASSISTANT_API = 300
|
RUN_WATCHDOG_HOMEASSISTANT_API = 300
|
||||||
@ -78,11 +77,6 @@ class Tasks(CoreSysAttributes):
|
|||||||
self.sys_ingress.reload, RUN_RELOAD_INGRESS
|
self.sys_ingress.reload, RUN_RELOAD_INGRESS
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.jobs.add(
|
|
||||||
self.sys_scheduler.register_task(
|
|
||||||
self.sys_secrets.reload, RUN_RELOAD_SECRETS
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Watchdog
|
# Watchdog
|
||||||
self.jobs.add(
|
self.jobs.add(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user