diff --git a/hyperglass/api/events.py b/hyperglass/api/events.py index 27bd587..32cf24b 100644 --- a/hyperglass/api/events.py +++ b/hyperglass/api/events.py @@ -39,7 +39,7 @@ async def check_redis_instance(): {bool} -- True if Redis is running. """ try: - await check_redis(db=params.features.cache.redis_id, config=REDIS_CONFIG) + await check_redis(db=params.cache.database, config=REDIS_CONFIG) except RuntimeError as e: raise HyperglassError(str(e), level="danger") from None @@ -71,7 +71,7 @@ async def build_ui(): async def clear_cache(): """Clear the Redis cache on shutdown.""" try: - await clear_redis_cache(db=params.features.cache.redis_id, config=REDIS_CONFIG) + await clear_redis_cache(db=params.cache.database, config=REDIS_CONFIG) except RuntimeError as e: log.error(str(e)) pass diff --git a/hyperglass/api/routes.py b/hyperglass/api/routes.py index aff6091..f321e64 100644 --- a/hyperglass/api/routes.py +++ b/hyperglass/api/routes.py @@ -18,7 +18,7 @@ from hyperglass.execution.execute import Execute from hyperglass.models.query import Query from hyperglass.util import log -Cache = aredis.StrictRedis(db=params.features.cache.redis_id, **REDIS_CONFIG) +Cache = aredis.StrictRedis(db=params.cache.database, **REDIS_CONFIG) async def query(query_data: Query, request: Request): @@ -29,7 +29,7 @@ async def query(query_data: Query, request: Request): cache_key = query_data.digest() # Define cache entry expiry time - cache_timeout = params.features.cache.timeout + cache_timeout = params.cache.timeout log.debug(f"Cache Timeout: {cache_timeout}") # Check if cached entry exists diff --git a/hyperglass/configuration/__init__.py b/hyperglass/configuration/__init__.py index 2137870..7c37e34 100644 --- a/hyperglass/configuration/__init__.py +++ b/hyperglass/configuration/__init__.py @@ -3,6 +3,7 @@ # Standard Library Imports import asyncio import copy +import math from pathlib import Path # Third Party Imports @@ -143,12 +144,6 @@ try: params = _params.Params(**user_config) elif not user_config: params = _params.Params() - try: - params.web.text.subtitle = params.web.text.subtitle.format( - **params.dict(exclude={"branding", "features", "messages"}) - ) - except KeyError: - pass if user_commands: commands = _commands.Commands.import_params(user_commands) @@ -166,6 +161,29 @@ except ValidationError as validation_errors: error_msg=error["msg"], ) +""" +Perform post-config initialization string formatting or other +functions that require access to other config levels. E.g., +something in 'params.web.text' needs to be formatted with a value +from params. +""" +try: + params.web.text.subtitle = params.web.text.subtitle.format( + **params.dict(exclude={"web", "features", "messages"}) + ) + if params.cache.timeout >= 60: + _cache_timeout = math.ceil(params.cache.timeout / 60) + _cache_period = "minutes" + elif params.cache.timeout < 60: + _cache_timeout = params.cache.timeout + _cache_period = "seconds" + params.web.text.cache = params.web.text.cache.format( + timeout=_cache_timeout, period=_cache_period + ) +except KeyError: + pass + + # Re-evaluate debug state after config is validated _set_log_level(params.debug, params.log_file) @@ -396,16 +414,13 @@ networks = _build_networks() frontend_networks = _build_frontend_networks() frontend_devices = _build_frontend_devices() _frontend_fields = { - "general": { - "debug", - "primary_asn", - "request_timeout", - "org_name", - "google_analytics", - "opengraph", - "site_description", - }, - "branding": ..., + "debug": ..., + "primary_asn": ..., + "request_timeout": ..., + "org_name": ..., + "google_analytics": ..., + "site_description": ..., + "web": ..., "features": { "bgp_route": {"enable", "display_name"}, "bgp_community": {"enable", "display_name"}, @@ -436,7 +451,7 @@ URL_DEV = f"http://localhost:{str(params.listen_port)}/api/" URL_PROD = "/api/" REDIS_CONFIG = { - "host": str(params.redis_host), - "port": params.redis_port, + "host": str(params.cache.host), + "port": params.cache.port, "decode_responses": True, } diff --git a/hyperglass/configuration/models/cache.py b/hyperglass/configuration/models/cache.py new file mode 100644 index 0000000..79317c2 --- /dev/null +++ b/hyperglass/configuration/models/cache.py @@ -0,0 +1,19 @@ +"""Validation model for Redis cache config.""" + +# Third Party Imports +from pydantic import StrictBool +from pydantic import StrictInt +from pydantic import StrictStr + +# Project Imports +from hyperglass.configuration.models._utils import HyperglassModel + + +class Cache(HyperglassModel): + """Validation model for params.cache.""" + + host: StrictStr = "localhost" + port: StrictInt = 6379 + database: StrictInt = 0 + timeout: StrictInt = 120 + show_text: StrictBool = True diff --git a/hyperglass/configuration/models/features.py b/hyperglass/configuration/models/features.py index 67dbe58..6aa43be 100644 --- a/hyperglass/configuration/models/features.py +++ b/hyperglass/configuration/models/features.py @@ -1,8 +1,5 @@ """Validate feature configuration variables.""" -# Standard Library Imports -from math import ceil - # Third Party Imports from pydantic import StrictBool from pydantic import StrictInt @@ -66,16 +63,6 @@ class Features(HyperglassModel): enable: StrictBool = True display_name: StrictStr = "Traceroute" - class Cache(HyperglassModel): - """Validation model for params.features.cache.""" - - redis_id: StrictInt = 0 - timeout: StrictInt = 120 - show_text: StrictBool = True - text: StrictStr = "Results will be cached for {timeout} minutes.".format( - timeout=ceil(timeout / 60) - ) - class MaxPrefix(HyperglassModel): """Validation model for params.features.max_prefix.""" @@ -91,5 +78,4 @@ class Features(HyperglassModel): bgp_aspath: BgpAsPath = BgpAsPath() ping: Ping = Ping() traceroute: Traceroute = Traceroute() - cache: Cache = Cache() max_prefix: MaxPrefix = MaxPrefix() diff --git a/hyperglass/configuration/models/params.py b/hyperglass/configuration/models/params.py index 4070198..338b1b4 100644 --- a/hyperglass/configuration/models/params.py +++ b/hyperglass/configuration/models/params.py @@ -18,10 +18,10 @@ from pydantic import validator # Project Imports from hyperglass.configuration.models._utils import HyperglassModel +from hyperglass.configuration.models.cache import Cache from hyperglass.configuration.models.docs import Docs from hyperglass.configuration.models.features import Features from hyperglass.configuration.models.messages import Messages -from hyperglass.configuration.models.opengraph import OpenGraph from hyperglass.configuration.models.web import Web @@ -52,8 +52,6 @@ class Params(HyperglassModel): "isp", ] google_analytics: StrictStr = "" - redis_host: StrictStr = "localhost" - redis_port: StrictInt = 6379 requires_ipv6_cidr: List[StrictStr] = ["cisco_ios", "cisco_nxos"] request_timeout: StrictInt = 30 listen_address: Optional[Union[IPvAnyAddress, StrictStr]] @@ -62,10 +60,10 @@ class Params(HyperglassModel): cors_origins: List[StrictStr] = [] # Sub Level Params + cache: Cache = Cache() docs: Docs = Docs() features: Features = Features() messages: Messages = Messages() - opengraph: OpenGraph = OpenGraph() web: Web = Web() @validator("listen_address", pre=True, always=True)