mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-28 11:36:32 +00:00
commit
de3edb1654
@ -3,6 +3,9 @@
|
|||||||
"name": "Hass.io dev",
|
"name": "Hass.io dev",
|
||||||
"context": "..",
|
"context": "..",
|
||||||
"dockerFile": "Dockerfile",
|
"dockerFile": "Dockerfile",
|
||||||
|
"runArgs": [
|
||||||
|
"-e", "GIT_EDTIOR='code --wait'"
|
||||||
|
],
|
||||||
"extensions": [
|
"extensions": [
|
||||||
"ms-python.python"
|
"ms-python.python"
|
||||||
],
|
],
|
||||||
@ -13,6 +16,7 @@
|
|||||||
"python.formatting.provider": "black",
|
"python.formatting.provider": "black",
|
||||||
"editor.formatOnPaste": false,
|
"editor.formatOnPaste": false,
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.formatOnType": true
|
"editor.formatOnType": true,
|
||||||
|
"files.trimTrailingWhitespace": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
API.md
3
API.md
@ -730,7 +730,8 @@ return:
|
|||||||
"arch": "arch",
|
"arch": "arch",
|
||||||
"supported_arch": ["arch1", "arch2"],
|
"supported_arch": ["arch1", "arch2"],
|
||||||
"channel": "stable|beta|dev",
|
"channel": "stable|beta|dev",
|
||||||
"logging": "debug|info|warning|error|critical"
|
"logging": "debug|info|warning|error|critical",
|
||||||
|
"timezone": "Europe/Zurich"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ class APIAddons(CoreSysAttributes):
|
|||||||
_LOGGER.warning("Protected flag changing for %s!", addon.slug)
|
_LOGGER.warning("Protected flag changing for %s!", addon.slug)
|
||||||
addon.protected = body[ATTR_PROTECTED]
|
addon.protected = body[ATTR_PROTECTED]
|
||||||
|
|
||||||
addon.save_data()
|
addon.save_persist()
|
||||||
|
|
||||||
@api_process
|
@api_process
|
||||||
async def stats(self, request: web.Request) -> Dict[str, Any]:
|
async def stats(self, request: web.Request) -> Dict[str, Any]:
|
||||||
|
@ -14,6 +14,7 @@ from ..const import (
|
|||||||
ATTR_MACHINE,
|
ATTR_MACHINE,
|
||||||
ATTR_SUPERVISOR,
|
ATTR_SUPERVISOR,
|
||||||
ATTR_SUPPORTED_ARCH,
|
ATTR_SUPPORTED_ARCH,
|
||||||
|
ATTR_TIMEZONE,
|
||||||
)
|
)
|
||||||
from ..coresys import CoreSysAttributes
|
from ..coresys import CoreSysAttributes
|
||||||
from .utils import api_process
|
from .utils import api_process
|
||||||
@ -37,4 +38,5 @@ class APIInfo(CoreSysAttributes):
|
|||||||
ATTR_SUPPORTED_ARCH: self.sys_arch.supported,
|
ATTR_SUPPORTED_ARCH: self.sys_arch.supported,
|
||||||
ATTR_CHANNEL: self.sys_updater.channel,
|
ATTR_CHANNEL: self.sys_updater.channel,
|
||||||
ATTR_LOGGING: self.sys_config.logging,
|
ATTR_LOGGING: self.sys_config.logging,
|
||||||
|
ATTR_TIMEZONE: self.sys_timezone,
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
class APIProxy(CoreSysAttributes):
|
class APIProxy(CoreSysAttributes):
|
||||||
"""API Proxy for Home Assistant."""
|
"""API Proxy for Home Assistant."""
|
||||||
|
|
||||||
def _check_access(self, request):
|
def _check_access(self, request: web.Request):
|
||||||
"""Check the Hass.io token."""
|
"""Check the Hass.io token."""
|
||||||
if AUTHORIZATION in request.headers:
|
if AUTHORIZATION in request.headers:
|
||||||
bearer = request.headers[AUTHORIZATION]
|
bearer = request.headers[AUTHORIZATION]
|
||||||
@ -40,7 +40,7 @@ class APIProxy(CoreSysAttributes):
|
|||||||
raise HTTPUnauthorized()
|
raise HTTPUnauthorized()
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def _api_client(self, request, path, timeout=300):
|
async def _api_client(self, request: web.Request, path: str, timeout: int = 300):
|
||||||
"""Return a client request with proxy origin for Home Assistant."""
|
"""Return a client request with proxy origin for Home Assistant."""
|
||||||
try:
|
try:
|
||||||
# read data
|
# read data
|
||||||
@ -58,6 +58,7 @@ class APIProxy(CoreSysAttributes):
|
|||||||
content_type=content_type,
|
content_type=content_type,
|
||||||
data=data,
|
data=data,
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
|
params=request.query,
|
||||||
) as resp:
|
) as resp:
|
||||||
yield resp
|
yield resp
|
||||||
return
|
return
|
||||||
@ -73,7 +74,7 @@ class APIProxy(CoreSysAttributes):
|
|||||||
|
|
||||||
raise HTTPBadGateway()
|
raise HTTPBadGateway()
|
||||||
|
|
||||||
async def stream(self, request):
|
async def stream(self, request: web.Request):
|
||||||
"""Proxy HomeAssistant EventStream Requests."""
|
"""Proxy HomeAssistant EventStream Requests."""
|
||||||
self._check_access(request)
|
self._check_access(request)
|
||||||
|
|
||||||
@ -92,7 +93,7 @@ class APIProxy(CoreSysAttributes):
|
|||||||
_LOGGER.info("Home Assistant EventStream close")
|
_LOGGER.info("Home Assistant EventStream close")
|
||||||
return response
|
return response
|
||||||
|
|
||||||
async def api(self, request):
|
async def api(self, request: web.Request):
|
||||||
"""Proxy Home Assistant API Requests."""
|
"""Proxy Home Assistant API Requests."""
|
||||||
self._check_access(request)
|
self._check_access(request)
|
||||||
|
|
||||||
@ -162,7 +163,7 @@ class APIProxy(CoreSysAttributes):
|
|||||||
|
|
||||||
raise APIError()
|
raise APIError()
|
||||||
|
|
||||||
async def websocket(self, request):
|
async def websocket(self, request: web.Request):
|
||||||
"""Initialize a WebSocket API connection."""
|
"""Initialize a WebSocket API connection."""
|
||||||
_LOGGER.info("Home Assistant WebSocket API request initialize")
|
_LOGGER.info("Home Assistant WebSocket API request initialize")
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ from pathlib import Path
|
|||||||
from ipaddress import ip_network
|
from ipaddress import ip_network
|
||||||
|
|
||||||
|
|
||||||
HASSIO_VERSION = "167"
|
HASSIO_VERSION = "168"
|
||||||
|
|
||||||
URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons"
|
URL_HASSIO_ADDONS = "https://github.com/home-assistant/hassio-addons"
|
||||||
URL_HASSIO_VERSION = "https://s3.amazonaws.com/hassio-version/{channel}.json"
|
URL_HASSIO_VERSION = "https://s3.amazonaws.com/hassio-version/{channel}.json"
|
||||||
|
@ -460,7 +460,8 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
|
|||||||
json: Optional[Dict[str, Any]] = None,
|
json: Optional[Dict[str, Any]] = None,
|
||||||
content_type: Optional[str] = None,
|
content_type: Optional[str] = None,
|
||||||
data: Optional[bytes] = None,
|
data: Optional[bytes] = None,
|
||||||
timeout=30,
|
timeout: int = 30,
|
||||||
|
params: Optional[Dict[str, str]] = None,
|
||||||
) -> AsyncContextManager[aiohttp.ClientResponse]:
|
) -> AsyncContextManager[aiohttp.ClientResponse]:
|
||||||
"""Async context manager to make a request with right auth."""
|
"""Async context manager to make a request with right auth."""
|
||||||
url = f"{self.api_url}/{path}"
|
url = f"{self.api_url}/{path}"
|
||||||
@ -482,7 +483,12 @@ class HomeAssistant(JsonConfig, CoreSysAttributes):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
async with getattr(self.sys_websession_ssl, method)(
|
async with getattr(self.sys_websession_ssl, method)(
|
||||||
url, data=data, timeout=timeout, json=json, headers=headers
|
url,
|
||||||
|
data=data,
|
||||||
|
timeout=timeout,
|
||||||
|
json=json,
|
||||||
|
headers=headers,
|
||||||
|
params=params,
|
||||||
) as resp:
|
) as resp:
|
||||||
# Access token expired
|
# Access token expired
|
||||||
if resp.status == 401 and self.refresh_token:
|
if resp.status == 401 and self.refresh_token:
|
||||||
|
@ -96,8 +96,6 @@ class Ingress(JsonConfig, CoreSysAttributes):
|
|||||||
valid = utcnow() + timedelta(minutes=15)
|
valid = utcnow() + timedelta(minutes=15)
|
||||||
|
|
||||||
self.sessions[session] = valid.timestamp()
|
self.sessions[session] = valid.timestamp()
|
||||||
self.save_data()
|
|
||||||
|
|
||||||
return session
|
return session
|
||||||
|
|
||||||
def validate_session(self, session: str) -> bool:
|
def validate_session(self, session: str) -> bool:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
flake8==3.7.7
|
flake8==3.7.7
|
||||||
pylint==2.3.1
|
pylint==2.3.1
|
||||||
pytest==4.6.3
|
pytest==5.0.1
|
||||||
pytest-timeout==1.3.3
|
pytest-timeout==1.3.3
|
||||||
pytest-aiohttp==0.3.0
|
pytest-aiohttp==0.3.0
|
||||||
|
@ -9,7 +9,6 @@ def test_session_handling(coresys):
|
|||||||
session = coresys.ingress.create_session()
|
session = coresys.ingress.create_session()
|
||||||
validate = coresys.ingress.sessions[session]
|
validate = coresys.ingress.sessions[session]
|
||||||
|
|
||||||
assert coresys.ingress.save_data.called
|
|
||||||
assert session
|
assert session
|
||||||
assert validate
|
assert validate
|
||||||
|
|
||||||
@ -22,6 +21,14 @@ def test_session_handling(coresys):
|
|||||||
assert not coresys.ingress.validate_session("invalid session")
|
assert not coresys.ingress.validate_session("invalid session")
|
||||||
|
|
||||||
|
|
||||||
|
async def test_save_on_unload(coresys):
|
||||||
|
"""Test called save on unload."""
|
||||||
|
coresys.ingress.create_session()
|
||||||
|
await coresys.ingress.unload()
|
||||||
|
|
||||||
|
assert coresys.ingress.save_data.called
|
||||||
|
|
||||||
|
|
||||||
def test_dynamic_ports(coresys):
|
def test_dynamic_ports(coresys):
|
||||||
"""Test dyanmic port handling."""
|
"""Test dyanmic port handling."""
|
||||||
port_test1 = coresys.ingress.get_dynamic_port("test1")
|
port_test1 = coresys.ingress.get_dynamic_port("test1")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user