2017-03-30 16:01:52 +02:00
|
|
|
"""Init file for HassIO rest api."""
|
|
|
|
import logging
|
2017-05-13 17:41:46 +02:00
|
|
|
from pathlib import Path
|
2017-03-30 16:01:52 +02:00
|
|
|
|
|
|
|
from aiohttp import web
|
|
|
|
|
2017-04-12 22:59:40 +02:00
|
|
|
from .addons import APIAddons
|
2018-02-08 17:19:47 +01:00
|
|
|
from .discovery import APIDiscovery
|
2017-04-12 00:06:17 +02:00
|
|
|
from .homeassistant import APIHomeAssistant
|
2018-04-12 22:15:08 +02:00
|
|
|
from .hardware import APIHardware
|
2017-03-30 16:01:52 +02:00
|
|
|
from .host import APIHost
|
2018-06-22 22:54:03 +02:00
|
|
|
from .hassos import APIHassOS
|
2017-12-26 00:51:07 +01:00
|
|
|
from .proxy import APIProxy
|
2017-03-30 16:54:13 +02:00
|
|
|
from .supervisor import APISupervisor
|
2017-07-05 18:16:14 +02:00
|
|
|
from .snapshots import APISnapshots
|
2018-02-08 17:19:47 +01:00
|
|
|
from .services import APIServices
|
2018-03-12 23:40:06 +01:00
|
|
|
from .security import SecurityMiddleware
|
2018-01-02 21:21:29 +01:00
|
|
|
from ..coresys import CoreSysAttributes
|
2017-03-30 16:01:52 +02:00
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
2018-01-02 21:21:29 +01:00
|
|
|
class RestAPI(CoreSysAttributes):
|
2017-03-30 16:01:52 +02:00
|
|
|
"""Handle rest api for hassio."""
|
|
|
|
|
2018-01-02 21:21:29 +01:00
|
|
|
def __init__(self, coresys):
|
2017-03-30 16:01:52 +02:00
|
|
|
"""Initialize docker base wrapper."""
|
2018-01-02 21:21:29 +01:00
|
|
|
self.coresys = coresys
|
2018-03-12 23:40:06 +01:00
|
|
|
self.security = SecurityMiddleware(coresys)
|
2018-02-08 17:19:47 +01:00
|
|
|
self.webapp = web.Application(
|
2018-04-21 16:30:31 +02:00
|
|
|
middlewares=[self.security.token_validation], loop=coresys.loop)
|
2017-03-30 16:01:52 +02:00
|
|
|
|
2017-03-30 23:26:26 +02:00
|
|
|
# service stuff
|
2018-06-20 12:17:33 +02:00
|
|
|
self._runner = web.AppRunner(self.webapp)
|
2018-06-20 15:32:55 +02:00
|
|
|
self._site = None
|
2017-03-30 16:01:52 +02:00
|
|
|
|
2018-01-02 21:21:29 +01:00
|
|
|
async def load(self):
|
|
|
|
"""Register REST API Calls."""
|
|
|
|
self._register_supervisor()
|
|
|
|
self._register_host()
|
2018-06-22 22:54:03 +02:00
|
|
|
self._register_hassos()
|
2018-04-12 22:15:08 +02:00
|
|
|
self._register_hardware()
|
2018-01-02 21:21:29 +01:00
|
|
|
self._register_homeassistant()
|
|
|
|
self._register_proxy()
|
|
|
|
self._register_panel()
|
|
|
|
self._register_addons()
|
|
|
|
self._register_snapshots()
|
2018-02-08 17:19:47 +01:00
|
|
|
self._register_discovery()
|
|
|
|
self._register_services()
|
2018-01-02 21:21:29 +01:00
|
|
|
|
|
|
|
def _register_host(self):
|
2017-04-26 11:15:56 +02:00
|
|
|
"""Register hostcontrol function."""
|
2018-01-02 21:21:29 +01:00
|
|
|
api_host = APIHost()
|
|
|
|
api_host.coresys = self.coresys
|
2017-03-30 16:01:52 +02:00
|
|
|
|
2018-04-09 21:01:06 +02:00
|
|
|
self.webapp.add_routes([
|
|
|
|
web.get('/host/info', api_host.info),
|
|
|
|
web.post('/host/reboot', api_host.reboot),
|
|
|
|
web.post('/host/shutdown', api_host.shutdown),
|
|
|
|
web.post('/host/reload', api_host.reload),
|
2018-06-17 02:07:12 +02:00
|
|
|
web.get('/host/services', api_host.services),
|
|
|
|
web.post('/host/services/{service}/stop', api_host.service_stop),
|
|
|
|
web.post('/host/services/{service}/start', api_host.service_start),
|
|
|
|
web.post(
|
|
|
|
'/host/services/{service}/restart', api_host.service_restart),
|
|
|
|
web.post(
|
|
|
|
'/host/services/{service}/reload', api_host.service_reload),
|
2018-04-09 21:01:06 +02:00
|
|
|
])
|
2017-04-05 08:55:19 +02:00
|
|
|
|
2018-06-22 22:54:03 +02:00
|
|
|
def _register_hassos(self):
|
|
|
|
"""Register hassos function."""
|
|
|
|
api_hassos = APIHassOS()
|
|
|
|
api_hassos.coresys = self.coresys
|
|
|
|
|
|
|
|
self.webapp.add_routes([
|
|
|
|
web.get('/hassos/info', api_hassos.info),
|
2018-06-30 01:48:58 +02:00
|
|
|
web.post('/hassos/update', api_hassos.update),
|
2018-06-22 22:54:03 +02:00
|
|
|
web.post('/hassos/config/sync', api_hassos.config_sync),
|
|
|
|
])
|
|
|
|
|
2018-04-12 22:15:08 +02:00
|
|
|
def _register_hardware(self):
|
|
|
|
"""Register hardware function."""
|
|
|
|
api_hardware = APIHardware()
|
|
|
|
api_hardware.coresys = self.coresys
|
|
|
|
|
|
|
|
self.webapp.add_routes([
|
2018-04-12 23:00:42 +02:00
|
|
|
web.get('/hardware/info', api_hardware.info),
|
|
|
|
web.get('/hardware/audio', api_hardware.audio),
|
2018-04-12 22:15:08 +02:00
|
|
|
])
|
|
|
|
|
2018-01-02 21:21:29 +01:00
|
|
|
def _register_supervisor(self):
|
2017-03-30 16:54:13 +02:00
|
|
|
"""Register supervisor function."""
|
2018-01-02 21:21:29 +01:00
|
|
|
api_supervisor = APISupervisor()
|
|
|
|
api_supervisor.coresys = self.coresys
|
2017-03-30 16:54:13 +02:00
|
|
|
|
2018-04-09 21:01:06 +02:00
|
|
|
self.webapp.add_routes([
|
|
|
|
web.get('/supervisor/ping', api_supervisor.ping),
|
|
|
|
web.get('/supervisor/info', api_supervisor.info),
|
|
|
|
web.get('/supervisor/stats', api_supervisor.stats),
|
2018-04-09 22:50:21 +02:00
|
|
|
web.get('/supervisor/logs', api_supervisor.logs),
|
2018-04-09 21:01:06 +02:00
|
|
|
web.post('/supervisor/update', api_supervisor.update),
|
|
|
|
web.post('/supervisor/reload', api_supervisor.reload),
|
|
|
|
web.post('/supervisor/options', api_supervisor.options),
|
|
|
|
])
|
2017-03-30 16:54:13 +02:00
|
|
|
|
2018-01-02 21:21:29 +01:00
|
|
|
def _register_homeassistant(self):
|
2017-03-30 16:01:52 +02:00
|
|
|
"""Register homeassistant function."""
|
2018-01-02 21:21:29 +01:00
|
|
|
api_hass = APIHomeAssistant()
|
|
|
|
api_hass.coresys = self.coresys
|
2017-03-30 16:01:52 +02:00
|
|
|
|
2018-04-09 21:01:06 +02:00
|
|
|
self.webapp.add_routes([
|
|
|
|
web.get('/homeassistant/info', api_hass.info),
|
|
|
|
web.get('/homeassistant/logs', api_hass.logs),
|
|
|
|
web.get('/homeassistant/stats', api_hass.stats),
|
|
|
|
web.post('/homeassistant/options', api_hass.options),
|
|
|
|
web.post('/homeassistant/update', api_hass.update),
|
|
|
|
web.post('/homeassistant/restart', api_hass.restart),
|
|
|
|
web.post('/homeassistant/stop', api_hass.stop),
|
|
|
|
web.post('/homeassistant/start', api_hass.start),
|
|
|
|
web.post('/homeassistant/check', api_hass.check),
|
|
|
|
])
|
2017-12-26 00:51:07 +01:00
|
|
|
|
2018-01-02 21:21:29 +01:00
|
|
|
def _register_proxy(self):
|
2017-12-26 00:51:07 +01:00
|
|
|
"""Register HomeAssistant API Proxy."""
|
2018-01-02 21:21:29 +01:00
|
|
|
api_proxy = APIProxy()
|
|
|
|
api_proxy.coresys = self.coresys
|
2017-12-26 00:51:07 +01:00
|
|
|
|
2018-04-09 21:01:06 +02:00
|
|
|
self.webapp.add_routes([
|
|
|
|
web.get('/homeassistant/api/websocket', api_proxy.websocket),
|
|
|
|
web.get('/homeassistant/websocket', api_proxy.websocket),
|
|
|
|
web.get('/homeassistant/api/stream', api_proxy.stream),
|
|
|
|
web.post('/homeassistant/api/{path:.+}', api_proxy.api),
|
|
|
|
web.get('/homeassistant/api/{path:.+}', api_proxy.api),
|
|
|
|
web.get('/homeassistant/api/', api_proxy.api),
|
|
|
|
])
|
2017-03-30 16:01:52 +02:00
|
|
|
|
2018-01-02 21:21:29 +01:00
|
|
|
def _register_addons(self):
|
2017-04-12 00:06:17 +02:00
|
|
|
"""Register homeassistant function."""
|
2018-01-02 21:21:29 +01:00
|
|
|
api_addons = APIAddons()
|
|
|
|
api_addons.coresys = self.coresys
|
2017-04-12 00:06:17 +02:00
|
|
|
|
2018-04-09 21:01:06 +02:00
|
|
|
self.webapp.add_routes([
|
|
|
|
web.get('/addons', api_addons.list),
|
|
|
|
web.post('/addons/reload', api_addons.reload),
|
|
|
|
web.get('/addons/{addon}/info', api_addons.info),
|
|
|
|
web.post('/addons/{addon}/install', api_addons.install),
|
|
|
|
web.post('/addons/{addon}/uninstall', api_addons.uninstall),
|
|
|
|
web.post('/addons/{addon}/start', api_addons.start),
|
|
|
|
web.post('/addons/{addon}/stop', api_addons.stop),
|
|
|
|
web.post('/addons/{addon}/restart', api_addons.restart),
|
|
|
|
web.post('/addons/{addon}/update', api_addons.update),
|
|
|
|
web.post('/addons/{addon}/options', api_addons.options),
|
|
|
|
web.post('/addons/{addon}/rebuild', api_addons.rebuild),
|
|
|
|
web.get('/addons/{addon}/logs', api_addons.logs),
|
|
|
|
web.get('/addons/{addon}/icon', api_addons.icon),
|
|
|
|
web.get('/addons/{addon}/logo', api_addons.logo),
|
|
|
|
web.get('/addons/{addon}/changelog', api_addons.changelog),
|
|
|
|
web.post('/addons/{addon}/stdin', api_addons.stdin),
|
|
|
|
web.get('/addons/{addon}/stats', api_addons.stats),
|
|
|
|
])
|
2017-04-12 00:06:17 +02:00
|
|
|
|
2018-01-02 21:21:29 +01:00
|
|
|
def _register_snapshots(self):
|
2017-07-05 18:16:14 +02:00
|
|
|
"""Register snapshots function."""
|
2018-01-02 21:21:29 +01:00
|
|
|
api_snapshots = APISnapshots()
|
|
|
|
api_snapshots.coresys = self.coresys
|
2017-07-05 18:16:14 +02:00
|
|
|
|
2018-04-09 21:01:06 +02:00
|
|
|
self.webapp.add_routes([
|
|
|
|
web.get('/snapshots', api_snapshots.list),
|
|
|
|
web.post('/snapshots/reload', api_snapshots.reload),
|
|
|
|
web.post('/snapshots/new/full', api_snapshots.snapshot_full),
|
|
|
|
web.post('/snapshots/new/partial', api_snapshots.snapshot_partial),
|
|
|
|
web.post('/snapshots/new/upload', api_snapshots.upload),
|
|
|
|
web.get('/snapshots/{snapshot}/info', api_snapshots.info),
|
|
|
|
web.post('/snapshots/{snapshot}/remove', api_snapshots.remove),
|
|
|
|
web.post('/snapshots/{snapshot}/restore/full',
|
|
|
|
api_snapshots.restore_full),
|
|
|
|
web.post('/snapshots/{snapshot}/restore/partial',
|
|
|
|
api_snapshots.restore_partial),
|
|
|
|
web.get('/snapshots/{snapshot}/download', api_snapshots.download),
|
|
|
|
])
|
2017-07-05 18:16:14 +02:00
|
|
|
|
2018-02-08 17:19:47 +01:00
|
|
|
def _register_services(self):
|
|
|
|
api_services = APIServices()
|
|
|
|
api_services.coresys = self.coresys
|
|
|
|
|
2018-04-09 21:01:06 +02:00
|
|
|
self.webapp.add_routes([
|
|
|
|
web.get('/services', api_services.list),
|
|
|
|
web.get('/services/{service}', api_services.get_service),
|
|
|
|
web.post('/services/{service}', api_services.set_service),
|
|
|
|
web.delete('/services/{service}', api_services.del_service),
|
|
|
|
])
|
2018-02-08 17:19:47 +01:00
|
|
|
|
|
|
|
def _register_discovery(self):
|
|
|
|
api_discovery = APIDiscovery()
|
|
|
|
api_discovery.coresys = self.coresys
|
|
|
|
|
2018-04-09 21:01:06 +02:00
|
|
|
self.webapp.add_routes([
|
|
|
|
web.get('/services/discovery', api_discovery.list),
|
|
|
|
web.get('/services/discovery/{uuid}', api_discovery.get_discovery),
|
|
|
|
web.delete('/services/discovery/{uuid}',
|
|
|
|
api_discovery.del_discovery),
|
|
|
|
web.post('/services/discovery', api_discovery.set_discovery),
|
|
|
|
])
|
2018-02-08 17:19:47 +01:00
|
|
|
|
2018-01-02 21:21:29 +01:00
|
|
|
def _register_panel(self):
|
2017-05-13 17:41:46 +02:00
|
|
|
"""Register panel for homeassistant."""
|
2018-05-28 23:16:03 +02:00
|
|
|
panel_dir = Path(__file__).parent.joinpath("panel")
|
|
|
|
|
|
|
|
def create_response(panel_file):
|
2017-11-20 13:44:04 +01:00
|
|
|
"""Create a function to generate a response."""
|
2018-05-28 23:16:03 +02:00
|
|
|
path = panel_dir.joinpath(f"{panel_file!s}.html")
|
2017-11-20 13:44:04 +01:00
|
|
|
return lambda request: web.FileResponse(path)
|
2017-05-13 17:41:46 +02:00
|
|
|
|
2017-11-20 13:44:04 +01:00
|
|
|
# This route is for backwards compatibility with HA < 0.58
|
2018-04-09 21:01:06 +02:00
|
|
|
self.webapp.add_routes([
|
|
|
|
web.get('/panel', create_response('hassio-main-es5'))])
|
2018-01-23 13:54:11 +01:00
|
|
|
|
|
|
|
# This route is for backwards compatibility with HA 0.58 - 0.61
|
2018-04-09 21:01:06 +02:00
|
|
|
self.webapp.add_routes([
|
|
|
|
web.get('/panel_es5', create_response('hassio-main-es5')),
|
|
|
|
web.get('/panel_latest', create_response('hassio-main-latest')),
|
|
|
|
])
|
2018-01-23 13:54:11 +01:00
|
|
|
|
2018-05-29 17:53:09 +02:00
|
|
|
# This route is for backwards compatibility with HA 0.62 - 0.70
|
|
|
|
self.webapp.add_routes([
|
|
|
|
web.get('/app-es5/index.html', create_response('index')),
|
|
|
|
web.get('/app-es5/hassio-app.html', create_response('hassio-app')),
|
|
|
|
])
|
|
|
|
|
|
|
|
# This route is for HA > 0.70
|
|
|
|
self.webapp.add_routes([web.static('/app', panel_dir)])
|
2017-05-13 17:41:46 +02:00
|
|
|
|
2017-03-30 16:01:52 +02:00
|
|
|
async def start(self):
|
|
|
|
"""Run rest api webserver."""
|
2018-06-20 12:17:33 +02:00
|
|
|
await self._runner.setup()
|
2018-06-20 15:32:55 +02:00
|
|
|
self._site = web.TCPSite(self._runner, "0.0.0.0", 80)
|
2017-03-30 16:01:52 +02:00
|
|
|
|
|
|
|
try:
|
2018-06-20 12:17:33 +02:00
|
|
|
await self._site.start()
|
2017-03-30 16:01:52 +02:00
|
|
|
except OSError as err:
|
2017-03-30 18:02:32 +02:00
|
|
|
_LOGGER.fatal(
|
|
|
|
"Failed to create HTTP server at 0.0.0.0:80 -> %s", err)
|
2017-03-30 16:01:52 +02:00
|
|
|
|
|
|
|
async def stop(self):
|
|
|
|
"""Stop rest api webserver."""
|
2018-06-20 12:17:33 +02:00
|
|
|
await self._site.stop()
|
|
|
|
await self._runner.cleanup()
|