addons/info returns info on all addons (#3762)

* Change to legacy routing approach

* Revert launch.json changes
This commit is contained in:
Mike Degatano 2022-08-03 09:44:18 -04:00 committed by GitHub
parent 2b4f46f6b3
commit 4f8f28b9f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 5 deletions

View File

@ -356,6 +356,9 @@ class Addon(AddonModel):
@property
def ingress_panel(self) -> Optional[bool]:
"""Return True if the add-on access support ingress."""
if not self.with_ingress:
return None
return self.persist[ATTR_INGRESS_PANEL]
@ingress_panel.setter

View File

@ -1,10 +1,13 @@
"""Init file for Supervisor RESTful API."""
import logging
from pathlib import Path
from typing import Optional
from typing import Any, Optional
from aiohttp import web
from supervisor.api.utils import api_process
from supervisor.exceptions import APIAddonNotInstalled
from ..coresys import CoreSys, CoreSysAttributes
from .addons import APIAddons
from .audio import APIAudio
@ -383,7 +386,6 @@ class RestAPI(CoreSysAttributes):
self.webapp.add_routes(
[
web.get("/addons", api_addons.list),
web.get("/addons/{addon}/info", api_addons.info),
web.post("/addons/{addon}/uninstall", api_addons.uninstall),
web.post("/addons/{addon}/start", api_addons.start),
web.post("/addons/{addon}/stop", api_addons.stop),
@ -401,6 +403,20 @@ class RestAPI(CoreSysAttributes):
]
)
# Legacy routing to support requests for not installed addons
api_store = APIStore()
api_store.coresys = self.coresys
@api_process
async def addons_addon_info(request: web.Request) -> dict[str, Any]:
"""Route to store if info requested for not installed addon."""
try:
return await api_addons.info(request)
except APIAddonNotInstalled:
return await api_store.addons_addon_info(request)
self.webapp.add_routes([web.get("/addons/{addon}/info", addons_addon_info)])
def _register_ingress(self) -> None:
"""Register Ingress functions."""
api_ingress = APIIngress()

View File

@ -96,7 +96,13 @@ from ..const import (
)
from ..coresys import CoreSysAttributes
from ..docker.stats import DockerStats
from ..exceptions import APIError, APIForbidden, PwnedError, PwnedSecret
from ..exceptions import (
APIAddonNotInstalled,
APIError,
APIForbidden,
PwnedError,
PwnedSecret,
)
from ..validate import docker_ports
from .const import ATTR_SIGNED, CONTENT_TYPE_BINARY
from .utils import api_process, api_process_raw, api_validate, json_loads
@ -140,7 +146,7 @@ class APIAddons(CoreSysAttributes):
if not addon:
raise APIError(f"Addon {addon_slug} does not exist")
if not isinstance(addon, Addon) or not addon.is_installed:
raise APIError("Addon is not installed")
raise APIAddonNotInstalled("Addon is not installed")
return addon
@ -177,7 +183,6 @@ class APIAddons(CoreSysAttributes):
"""Reload all add-on data from store."""
await asyncio.shield(self.sys_store.reload())
@api_process
async def info(self, request: web.Request) -> dict[str, Any]:
"""Return add-on information."""
addon: AnyAddon = self._extract_addon(request)

View File

@ -263,6 +263,10 @@ class APIForbidden(APIError):
"""API forbidden error."""
class APIAddonNotInstalled(APIError):
"""Not installed addon requested at addons API."""
# Service / Discovery

36
tests/api/test_addons.py Normal file
View File

@ -0,0 +1,36 @@
"""Test addons api."""
from supervisor.addons.addon import Addon
from supervisor.const import AddonState
from supervisor.coresys import CoreSys
from supervisor.store.repository import Repository
from ..const import TEST_ADDON_SLUG
async def test_addons_info(api_client, coresys: CoreSys, install_addon_ssh: Addon):
"""Test getting addon info."""
install_addon_ssh.state = AddonState.STOPPED
install_addon_ssh.ingress_panel = True
install_addon_ssh.protected = True
install_addon_ssh.watchdog = False
resp = await api_client.get(f"/addons/{TEST_ADDON_SLUG}/info")
result = await resp.json()
assert result["data"]["version_latest"] == "9.2.1"
assert result["data"]["version"] == "9.2.1"
assert result["data"]["state"] == "stopped"
assert result["data"]["ingress_panel"] is True
assert result["data"]["protected"] is True
assert result["data"]["watchdog"] is False
# DEPRECATED - Remove with legacy routing logic on 1/2023
async def test_addons_info_not_installed(
api_client, coresys: CoreSys, repository: Repository
):
"""Test getting addon info for not installed addon."""
resp = await api_client.get(f"/addons/{TEST_ADDON_SLUG}/info")
result = await resp.json()
assert result["data"]["version_latest"] == "9.2.1"
assert result["data"]["version"] is None