From 6dd8cfc9ff2633611c5634fa3118aab789ede9b6 Mon Sep 17 00:00:00 2001 From: checktheroads Date: Mon, 13 Jul 2020 01:55:42 -0700 Subject: [PATCH] cache RPKI responses --- hyperglass/external/rpki.py | 49 ++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/hyperglass/external/rpki.py b/hyperglass/external/rpki.py index 691ce90..78b1985 100644 --- a/hyperglass/external/rpki.py +++ b/hyperglass/external/rpki.py @@ -2,10 +2,15 @@ # Project from hyperglass.log import log +from hyperglass.cache import SyncCache +from hyperglass.configuration import REDIS_CONFIG, params from hyperglass.external._base import BaseExternal RPKI_STATE_MAP = {"Invalid": 0, "Valid": 1, "NotFound": 2, "DEFAULT": 3} RPKI_NAME_MAP = {v: k for k, v in RPKI_STATE_MAP.items()} +CACHE_KEY = "hyperglass.external.rpki" + +cache = SyncCache(db=params.cache.database, **REDIS_CONFIG) def rpki_state(prefix, asn): @@ -13,24 +18,34 @@ def rpki_state(prefix, asn): log.debug("Validating RPKI State for {p} via AS{a}", p=prefix, a=asn) state = 3 - query = 'query GetValidation {{ validation(prefix: "{prefix}", asn: {asn}) {{ state }} }}'.format( # noqa: E501 - prefix=prefix, asn=asn - ) + ro = f"{prefix}@{asn}" - try: - with BaseExternal(base_url="https://rpki.cloudflare.com") as client: - response = client._post("/api/graphql", data={"query": query}) - validation_state = ( - response.get("data", {}).get("validation", {}).get("state", "DEFAULT") - ) - state = RPKI_STATE_MAP[validation_state] - except Exception: - state = 3 + cached = cache.get_dict(CACHE_KEY, ro) - log.debug( - "RPKI Validation State for {p} via AS{a} is {s}", - p=prefix, - a=asn, - s=RPKI_NAME_MAP[state], + if cached is not None: + state = cached + else: + + ql = 'query GetValidation {{ validation(prefix: "{}", asn: {}) {{ state }} }}' + query = ql.format(prefix, asn) + + try: + with BaseExternal(base_url="https://rpki.cloudflare.com") as client: + response = client._post("/api/graphql", data={"query": query}) + validation_state = ( + response.get("data", {}).get("validation", {}).get("state", "DEFAULT") + ) + state = RPKI_STATE_MAP[validation_state] + cache.set_dict(CACHE_KEY, ro, state) + except Exception as err: + log.error(str(err)) + state = 3 + + msg = "RPKI Validation State for {} via AS{} is {}".format( + prefix, asn, RPKI_NAME_MAP[state] ) + if cached is not None: + msg += " [CACHED]" + + log.debug(msg) return state