-
-
Notifications
You must be signed in to change notification settings - Fork 37.6k
Move HTTP integration configuration to the UI #170321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
686a2d3
Move HTTP integration configuration to the UI
MindFreeze e43ddf1
Drop deprecated base_url when persisting HTTP config
MindFreeze 1f371a9
Extend HTTP YAML deprecation window to 12 months
MindFreeze 7f66269
comment
MindFreeze 457d61e
Potential fix for pull request finding
MindFreeze 3cec452
Merge partial updates in HTTP config WS API and drop unreachable impo…
MindFreeze 28e98a9
Apply suggestions from code review
MindFreeze File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| """Repair issues for the HTTP integration.""" | ||
|
|
||
| from homeassistant.core import HomeAssistant, callback | ||
| from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue | ||
|
|
||
| from .const import DOMAIN | ||
|
|
||
| # HTTP touches every installation, so we allow at least a full 12 months for | ||
| # users to migrate. | ||
| BREAKS_IN_HA_VERSION = "2027.6.0" | ||
|
|
||
|
|
||
|
MindFreeze marked this conversation as resolved.
|
||
| @callback | ||
| def async_create_deprecated_yaml_issue(hass: HomeAssistant) -> None: | ||
| """Create a repair issue for deprecated YAML configuration.""" | ||
| async_create_issue( | ||
| hass, | ||
| DOMAIN, | ||
| "deprecated_yaml", | ||
| is_fixable=False, | ||
| breaks_in_ha_version=BREAKS_IN_HA_VERSION, | ||
| severity=IssueSeverity.WARNING, | ||
| translation_key="deprecated_yaml", | ||
| translation_placeholders={"domain": DOMAIN}, | ||
| ) | ||
|
|
||
|
|
||
| @callback | ||
| def async_create_failed_to_start_issue(hass: HomeAssistant, *, error: str) -> None: | ||
| """Surface that HTTP fell back to safe defaults during startup.""" | ||
| async_create_issue( | ||
| hass, | ||
| DOMAIN, | ||
| "http_failed_to_start", | ||
| is_fixable=False, | ||
| severity=IssueSeverity.ERROR, | ||
| translation_key="http_failed_to_start", | ||
| translation_placeholders={"error": error}, | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| """Persistent storage for the user-managed HTTP integration config.""" | ||
|
|
||
| from ipaddress import IPv4Network, IPv6Network | ||
| from typing import Any, TypedDict, cast | ||
|
|
||
| from homeassistant.core import HomeAssistant | ||
| from homeassistant.helpers.storage import Store | ||
|
|
||
| # A separate key from STORAGE_KEY ("http") in __init__.py, which is used for the | ||
| # recovery-mode snapshot of the last successfully resolved config. The two stores | ||
| # must not share a key. | ||
| USER_CONFIG_STORAGE_KEY = "http.config" | ||
| USER_CONFIG_STORAGE_VERSION = 1 | ||
|
|
||
|
|
||
| class HttpUserConfig(TypedDict, total=False): | ||
| """User-managed HTTP config persisted via Store. | ||
|
|
||
| Mirrors the validated output of ``HTTP_SCHEMA`` except ``trusted_proxies`` is | ||
| held as a list of strings for JSON serialization. | ||
| """ | ||
|
|
||
| server_host: list[str] | ||
| server_port: int | ||
|
MindFreeze marked this conversation as resolved.
|
||
| ssl_certificate: str | ||
| ssl_peer_certificate: str | ||
| ssl_key: str | ||
| cors_allowed_origins: list[str] | ||
| use_x_forwarded_for: bool | ||
| trusted_proxies: list[str] | ||
| use_x_frame_options: bool | ||
| ip_ban_enabled: bool | ||
| login_attempts_threshold: int | ||
| ssl_profile: str | ||
|
|
||
|
|
||
| class HttpConfigStore(Store[HttpUserConfig]): | ||
| """Store for user-managed HTTP config.""" | ||
|
|
||
|
|
||
| def async_get_store(hass: HomeAssistant) -> HttpConfigStore: | ||
| """Return the user-config Store, private to the integration.""" | ||
| return HttpConfigStore( | ||
| hass, | ||
| USER_CONFIG_STORAGE_VERSION, | ||
| USER_CONFIG_STORAGE_KEY, | ||
| private=True, | ||
|
MindFreeze marked this conversation as resolved.
|
||
| atomic_writes=True, | ||
| ) | ||
|
Comment on lines
+41
to
+49
|
||
|
|
||
|
|
||
| def to_stored(conf: dict[str, Any]) -> HttpUserConfig: | ||
| """Convert a validated ``HTTP_SCHEMA`` dict into a JSON-serializable form.""" | ||
| out: dict[str, Any] = {k: v for k, v in conf.items() if k != "base_url"} | ||
| if "trusted_proxies" in out: | ||
| out["trusted_proxies"] = [ | ||
| str(cast(IPv4Network | IPv6Network, n)) for n in out["trusted_proxies"] | ||
| ] | ||
|
MindFreeze marked this conversation as resolved.
|
||
| return cast(HttpUserConfig, out) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| """WebSocket API for the HTTP integration user config.""" | ||
|
|
||
| from typing import Any, cast | ||
|
|
||
| import voluptuous as vol | ||
|
|
||
| from homeassistant.core import HomeAssistant | ||
|
|
||
| from .storage import async_get_store, to_stored | ||
|
|
||
|
|
||
| def async_register_websocket_api(hass: HomeAssistant) -> None: | ||
| """Register the HTTP config WebSocket commands. | ||
|
|
||
| The core ``homeassistant.components.websocket_api`` dependency is imported | ||
| lazily because it imports from ``homeassistant.components.http``; using its | ||
| decorators at this module's load time would create a circular import. | ||
| """ | ||
| from homeassistant.components import websocket_api # noqa: PLC0415 | ||
|
|
||
| @websocket_api.require_admin | ||
| @websocket_api.websocket_command({vol.Required("type"): "http/config/get"}) | ||
| @websocket_api.async_response | ||
| async def ws_get_config( | ||
| hass: HomeAssistant, | ||
| connection: websocket_api.ActiveConnection, | ||
| msg: dict[str, Any], | ||
| ) -> None: | ||
| """Return the current user-managed HTTP config.""" | ||
| store = async_get_store(hass) | ||
| stored = await store.async_load() or {} | ||
| connection.send_result(msg["id"], {"config": stored}) | ||
|
|
||
| @websocket_api.require_admin | ||
| @websocket_api.websocket_command( | ||
| { | ||
| vol.Required("type"): "http/config/update", | ||
| vol.Required("config"): dict, | ||
| } | ||
| ) | ||
| @websocket_api.async_response | ||
| async def ws_update_config( | ||
| hass: HomeAssistant, | ||
| connection: websocket_api.ActiveConnection, | ||
| msg: dict[str, Any], | ||
| ) -> None: | ||
| """Merge the incoming patch into the stored HTTP config and save.""" | ||
| # Local import: HTTP_SCHEMA lives in __init__.py, which already imports | ||
| # this module to wire up the commands. | ||
| from . import HTTP_SCHEMA # noqa: PLC0415 | ||
|
|
||
| store = async_get_store(hass) | ||
| existing = await store.async_load() or {} | ||
| merged = {**existing, **msg["config"]} | ||
|
|
||
| try: | ||
| validated = HTTP_SCHEMA(merged) | ||
| except vol.Invalid as err: | ||
| connection.send_error(msg["id"], websocket_api.ERR_INVALID_FORMAT, str(err)) | ||
| return | ||
|
|
||
| stored = to_stored(cast(dict[str, Any], validated)) | ||
| await store.async_save(stored) | ||
| connection.send_result(msg["id"], {"config": stored}) | ||
|
Comment on lines
+52
to
+64
|
||
|
|
||
| websocket_api.async_register_command(hass, ws_get_config) | ||
| websocket_api.async_register_command(hass, ws_update_config) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.