mirror of
https://github.com/home-assistant/core.git
synced 2026-08-07 05:46:41 +01:00
Add env var SETUP_PORT to change the default port (#174263)
This commit is contained in:
@@ -33,7 +33,6 @@ from homeassistant.const import (
|
||||
EVENT_HOMEASSISTANT_START,
|
||||
EVENT_HOMEASSISTANT_STOP,
|
||||
HASSIO_USER_NAME,
|
||||
SERVER_PORT,
|
||||
)
|
||||
from homeassistant.core import Event, HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
@@ -60,7 +59,7 @@ from homeassistant.util.json import json_loads
|
||||
|
||||
from .auth import async_setup_auth
|
||||
from .ban import setup_bans
|
||||
from .config import async_load_config
|
||||
from .config import async_load_config, default_server_port
|
||||
from .const import ( # noqa: F401
|
||||
CONF_BASE_URL,
|
||||
CONF_CORS_ORIGINS,
|
||||
@@ -109,7 +108,7 @@ HTTP_SCHEMA: Final = vol.All(
|
||||
vol.Optional(CONF_SERVER_HOST): vol.All(
|
||||
cv.ensure_list, vol.Length(min=1), [cv.string]
|
||||
),
|
||||
vol.Optional(CONF_SERVER_PORT, default=SERVER_PORT): cv.port,
|
||||
vol.Optional(CONF_SERVER_PORT, default=default_server_port): cv.port,
|
||||
vol.Optional(CONF_BASE_URL): cv.string,
|
||||
vol.Optional(CONF_SSL_CERTIFICATE): cv.isfile,
|
||||
vol.Optional(CONF_SSL_PEER_CERTIFICATE): cv.isfile,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import asyncio
|
||||
from ipaddress import IPv4Network, IPv6Network, ip_network
|
||||
import logging
|
||||
import os
|
||||
from typing import Any, Final, TypedDict, cast, override
|
||||
|
||||
import voluptuous as vol
|
||||
@@ -31,6 +32,7 @@ from .const import (
|
||||
CONF_USE_X_FRAME_OPTIONS,
|
||||
DEFAULT_CORS,
|
||||
DOMAIN,
|
||||
ENV_SETUP_PORT,
|
||||
NO_LOGIN_ATTEMPT_THRESHOLD,
|
||||
SSL_INTERMEDIATE,
|
||||
SSL_MODERN,
|
||||
@@ -38,6 +40,28 @@ from .const import (
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def default_server_port() -> int:
|
||||
"""Return the default HTTP server port.
|
||||
|
||||
The built-in default port can be overridden via the
|
||||
``SETUP_PORT`` environment variable. An invalid value is ignored in favor
|
||||
of the built-in default.
|
||||
"""
|
||||
if (env_value := os.environ.get(ENV_SETUP_PORT)) is None:
|
||||
return SERVER_PORT
|
||||
try:
|
||||
return cast(int, cv.port(env_value))
|
||||
except vol.Invalid:
|
||||
_LOGGER.warning(
|
||||
"Invalid port %r in %s environment variable; falling back to %s",
|
||||
env_value,
|
||||
ENV_SETUP_PORT,
|
||||
SERVER_PORT,
|
||||
)
|
||||
return SERVER_PORT
|
||||
|
||||
|
||||
STORAGE_KEY: Final = DOMAIN
|
||||
STORAGE_VERSION: Final = 2
|
||||
|
||||
@@ -86,7 +110,7 @@ HTTP_STORAGE_SCHEMA: Final = vol.Schema(
|
||||
vol.Optional(CONF_SERVER_HOST): vol.All(
|
||||
cv.ensure_list, vol.Length(min=1), [cv.string]
|
||||
),
|
||||
vol.Optional(CONF_SERVER_PORT, default=SERVER_PORT): cv.port,
|
||||
vol.Optional(CONF_SERVER_PORT, default=default_server_port): cv.port,
|
||||
vol.Optional(CONF_SSL_CERTIFICATE): cv.isfile,
|
||||
vol.Optional(CONF_SSL_PEER_CERTIFICATE): cv.isfile,
|
||||
vol.Optional(CONF_SSL_KEY): cv.isfile,
|
||||
|
||||
@@ -28,6 +28,8 @@ CONF_SSL_PROFILE: Final = "ssl_profile"
|
||||
SSL_MODERN: Final = "modern"
|
||||
SSL_INTERMEDIATE: Final = "intermediate"
|
||||
|
||||
ENV_SETUP_PORT: Final = "SETUP_PORT"
|
||||
|
||||
# Cast to be able to load custom cards.
|
||||
# My to be able to check url and version info.
|
||||
DEFAULT_CORS: Final[list[str]] = ["https://cast.home-assistant.io"]
|
||||
|
||||
@@ -15,7 +15,12 @@ from homeassistant.auth.providers.homeassistant import HassAuthProvider
|
||||
from homeassistant.components import cloud, http
|
||||
from homeassistant.components.cloud import CloudNotAvailable
|
||||
from homeassistant.components.http import DOMAIN
|
||||
from homeassistant.components.http.config import _DEFAULT_CONFIG, HTTP_STORAGE_SCHEMA
|
||||
from homeassistant.components.http.config import (
|
||||
_DEFAULT_CONFIG,
|
||||
HTTP_STORAGE_SCHEMA,
|
||||
default_server_port,
|
||||
)
|
||||
from homeassistant.components.http.const import ENV_SETUP_PORT
|
||||
from homeassistant.const import HASSIO_USER_NAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import issue_registry as ir
|
||||
@@ -1191,6 +1196,46 @@ async def test_setup_migrates_v1_storage_to_v2(
|
||||
assert data["yaml_migration_done"] is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("env", "expected_port"),
|
||||
[
|
||||
pytest.param({}, 8123, id="unset"),
|
||||
pytest.param({ENV_SETUP_PORT: "80"}, 80, id="valid"),
|
||||
pytest.param({ENV_SETUP_PORT: "0"}, 8123, id="out-of-range"),
|
||||
pytest.param({ENV_SETUP_PORT: "notaport"}, 8123, id="not-a-number"),
|
||||
pytest.param({ENV_SETUP_PORT: ""}, 8123, id="empty"),
|
||||
],
|
||||
)
|
||||
def test_default_server_port(
|
||||
env: dict[str, str],
|
||||
expected_port: int,
|
||||
) -> None:
|
||||
"""Test SETUP_PORT overrides the default port and invalid values fall back."""
|
||||
with patch.dict(os.environ, env, clear=True):
|
||||
assert default_server_port() == expected_port
|
||||
|
||||
|
||||
async def test_setup_port_env_var_used_as_default(
|
||||
hass: HomeAssistant,
|
||||
hass_storage: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test SETUP_PORT is used as the default server port without YAML config."""
|
||||
mock_server = Mock()
|
||||
with (
|
||||
patch.dict(os.environ, {ENV_SETUP_PORT: "80"}),
|
||||
patch(
|
||||
"asyncio.BaseEventLoop.create_server", return_value=mock_server
|
||||
) as mock_create_server,
|
||||
):
|
||||
assert await async_setup_component(hass, "http", {})
|
||||
await hass.async_start()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
args, _ = mock_create_server.call_args
|
||||
assert args[2] == 80
|
||||
assert hass_storage["http"]["data"]["pending"]["server_port"] == 80
|
||||
|
||||
|
||||
async def test_websocket_http_config(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
|
||||
Reference in New Issue
Block a user