addons/info returns info on all addons (#3762)
* Change to legacy routing approach * Revert launch.json changes
This commit is contained in:
parent
2b4f46f6b3
commit
4f8f28b9f6
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -263,6 +263,10 @@ class APIForbidden(APIError):
|
|||
"""API forbidden error."""
|
||||
|
||||
|
||||
class APIAddonNotInstalled(APIError):
|
||||
"""Not installed addon requested at addons API."""
|
||||
|
||||
|
||||
# Service / Discovery
|
||||
|
||||
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue