diff --git a/hyperglass/api/fake_output.py b/hyperglass/api/fake_output.py new file mode 100644 index 0000000..e66cdaf --- /dev/null +++ b/hyperglass/api/fake_output.py @@ -0,0 +1,124 @@ +"""Return fake, static data for development purposes.""" + +# Standard Library +from typing import Dict, Union + +PLAIN = r""" # noqa: W291 + _ _ +| |__ _ _ _ __ ___ _ __ __ _ | | __ _ ___ ___ +| '_ \ | | | || '_ \ / _ \| '__|/ _` || | / _` |/ __|/ __| +| | | || |_| || |_) || __/| | | (_| || || (_| |\__ \\__ \ +|_| |_| \__, || .__/ \___||_| \__, ||_| \__,_||___/|___/ + |___/ |_| |___/ + +""" + +ROUTES = [ + { + "prefix": "198.18.1.0/24", + "active": True, + "age": 240, + "weight": 170, + "med": 1, + "local_preference": 100, + "as_path": [65001], + "communities": ["65000:1"], + "next_hop": "198.18.0.1", + "source_as": 65001, + "source_rid": "198.18.0.1", + "peer_rid": "198.18.0.1", + "rpki_state": 1, + }, + { + "prefix": "2001:db8:1::/64", + "active": True, + "age": 240, + "weight": 170, + "med": 1, + "local_preference": 100, + "as_path": [65001], + "communities": ["65000:1"], + "next_hop": "2001:db8::1", + "source_as": 65001, + "source_rid": "198.18.0.1", + "peer_rid": "198.18.0.1", + "rpki_state": 1, + }, + { + "prefix": "198.18.2.0/24", + "active": False, + "age": 480, + "weight": 170, + "med": 2, + "local_preference": 100, + "as_path": [65002], + "communities": ["65000:2"], + "next_hop": "198.18.0.2", + "source_as": 65002, + "source_rid": "198.18.0.2", + "peer_rid": "198.18.0.2", + "rpki_state": 2, + }, + { + "prefix": "2001:db8:2::/64", + "active": False, + "age": 480, + "weight": 170, + "med": 2, + "local_preference": 100, + "as_path": [65002], + "communities": ["65000:2"], + "next_hop": "2001:db8::2", + "source_as": 65002, + "source_rid": "198.18.0.2", + "peer_rid": "198.18.0.2", + "rpki_state": 2, + }, + { + "prefix": "198.18.3.0/24", + "active": False, + "age": 480, + "weight": 170, + "med": 2, + "local_preference": 100, + "as_path": [65003], + "communities": ["65000:3"], + "next_hop": "198.18.0.3", + "source_as": 65003, + "source_rid": "198.18.0.3", + "peer_rid": "198.18.0.3", + "rpki_state": 0, + }, + { + "prefix": "2001:db8:3::/64", + "active": False, + "age": 480, + "weight": 170, + "med": 2, + "local_preference": 100, + "as_path": [65003], + "communities": ["65000:3"], + "next_hop": "2001:db8::3", + "source_as": 65003, + "source_rid": "198.18.0.3", + "peer_rid": "198.18.0.3", + "rpki_state": 0, + }, +] + +STRUCTURED = { + "vrf": "default", + "count": len(ROUTES), + "routes": ROUTES, + "winning_weight": "high", +} + + +async def fake_output(structured: bool) -> Union[str, Dict]: + """Bypass the standard execution process and return static, fake output.""" + output = PLAIN + + if structured: + output = STRUCTURED + + return output diff --git a/hyperglass/api/routes.py b/hyperglass/api/routes.py index 08d76cf..e861da2 100644 --- a/hyperglass/api/routes.py +++ b/hyperglass/api/routes.py @@ -23,6 +23,9 @@ from hyperglass.models.api import Query, EncodedRequest from hyperglass.configuration import REDIS_CONFIG, params, devices from hyperglass.execution.main import execute +# Local +from .fake_output import fake_output + APP_PATH = os.environ["hyperglass_directory"] @@ -115,9 +118,16 @@ async def query(query_data: Query, request: Request, background_tasks: Backgroun ) timestamp = query_data.timestamp - # Pass request to execution module + starttime = time.time() - cache_output = await execute(query_data) + + if params.fake_output: + # Return fake, static data for development purposes, if enabled. + cache_output = await fake_output(query_data.device.structured_output) + else: + # Pass request to execution module + cache_output = await execute(query_data) + endtime = time.time() elapsedtime = round(endtime - starttime, 4) log.debug("Query {} took {} seconds to run.", cache_key, elapsedtime) diff --git a/hyperglass/models/config/params.py b/hyperglass/models/config/params.py index f046471..c6f725b 100644 --- a/hyperglass/models/config/params.py +++ b/hyperglass/models/config/params.py @@ -43,6 +43,11 @@ class Params(HyperglassModel): title="Developer Mode", description='Enable developer mode. If enabled, the hyperglass backend (Python) and frontend (React/Javascript) applications are "unlinked", so that React tools can be used for front end development. A `` convenience component is also displayed in the UI for easier UI development.', ) + fake_output: StrictBool = Field( + False, + title="Fake Output", + description="If enabled, the hyperglass backend will return static fake output for development/testing purposes.", + ) primary_asn: Union[StrictInt, StrictStr] = Field( "65001", title="Primary ASN",