From c008ccad14083d238c8eb8c9012e5260d14b5e5c Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 3 Apr 2024 09:28:57 +0000 Subject: [PATCH 1/8] add Option to only get Gateway --- wgkex/broker/app.py | 76 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/wgkex/broker/app.py b/wgkex/broker/app.py index e8122cc..80612f3 100644 --- a/wgkex/broker/app.py +++ b/wgkex/broker/app.py @@ -51,6 +51,30 @@ def from_dict(cls, msg: dict) -> "KeyExchange": raise ValueError(f"Domain {domain} not in configured domains.") return cls(public_key=public_key, domain=domain) +@dataclasses.dataclass +class Gateway: + """A best Gateway message. + + Attributes: + domain: The domain for the best Gateway. + """ + + domain: str + + @classmethod + def from_dict(cls, msg: dict) -> "Gateway": + """Creates a new Gateway message from dict. + + Arguments: + msg: The message to convert. + Returns: + A Gateway object. + """ + domain = str(msg.get("domain")) + if not is_valid_domain(domain): + raise ValueError(f"Domain {domain} not in configured domains.") + return cls(domain=domain) + def _fetch_app_config() -> Flask_app: """Creates the Flask app from configuration. @@ -160,6 +184,58 @@ def wg_api_v2_key_exchange() -> Tuple[Response | Dict, int]: return {"Endpoint": endpoint}, 200 +@app.route("/api/v2/wg/gateway/best", methods=["POST"]) +def wg_api_v2_gateway_best() -> Tuple[Response | Dict, int]: + """Retrieves a site, validates it and responds with a worker/gateway the client should connect to. + + Returns: + Status message, Endpoint with address/domain, port. + """ + try: + data = Gateway.from_dict(request.get_json(force=True)) + except Exception as ex: + return {"error": {"message": str(ex)}}, 400 + + domain = data.domain + # in case we want to decide here later we want to publish it only to dedicated gateways + gateway = "all" + logger.info(f"wg_api_v2_gateway_best: Domain: {domain}") + + + best_worker, diff, current_peers = worker_metrics.get_best_worker(domain) + if best_worker is None: + logger.warning(f"No worker online for domain {domain}") + return { + "error": { + "message": "no gateway online for this domain, please check the domain value and try again later" + } + }, 400 + + # Update number of peers locally to interpolate data between MQTT updates from the worker + # TODO fix data race + current_peers_domain = ( + worker_metrics.get(best_worker) + .get_domain_metrics(domain) + .get(CONNECTED_PEERS_METRIC, 0) + ) + + logger.debug( + f"Chose worker {best_worker} with {current_peers} connected clients ({diff})" + ) + + w_data = worker_data.get((best_worker, domain), None) + if w_data is None: + logger.error(f"Couldn't get worker endpoint data for {best_worker}/{domain}") + return {"error": {"message": "could not get gateway data"}}, 500 + + endpoint = { + "Address": w_data.get("ExternalAddress"), + "Port": str(w_data.get("Port")), + } + + return {"Endpoint": endpoint}, 200 + + @mqtt.on_connect() def handle_mqtt_connect( client: mqtt_client.Client, userdata: bytes, flags: Any, rc: Any From c1026f65d61a99b89b43303199dc21250133f59e Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 3 Apr 2024 09:36:35 +0000 Subject: [PATCH 2/8] update logging and remove code --- wgkex/broker/app.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/wgkex/broker/app.py b/wgkex/broker/app.py index 80612f3..f74d3f0 100644 --- a/wgkex/broker/app.py +++ b/wgkex/broker/app.py @@ -201,7 +201,6 @@ def wg_api_v2_gateway_best() -> Tuple[Response | Dict, int]: gateway = "all" logger.info(f"wg_api_v2_gateway_best: Domain: {domain}") - best_worker, diff, current_peers = worker_metrics.get_best_worker(domain) if best_worker is None: logger.warning(f"No worker online for domain {domain}") @@ -211,16 +210,8 @@ def wg_api_v2_gateway_best() -> Tuple[Response | Dict, int]: } }, 400 - # Update number of peers locally to interpolate data between MQTT updates from the worker - # TODO fix data race - current_peers_domain = ( - worker_metrics.get(best_worker) - .get_domain_metrics(domain) - .get(CONNECTED_PEERS_METRIC, 0) - ) - logger.debug( - f"Chose worker {best_worker} with {current_peers} connected clients ({diff})" + f"Should Chose worker {best_worker} with {current_peers} connected clients ({diff})" ) w_data = worker_data.get((best_worker, domain), None) From cc48a5ecf293232c356f51345dc9540524a20928 Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 3 Apr 2024 09:37:43 +0000 Subject: [PATCH 3/8] remove code --- wgkex/broker/app.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/wgkex/broker/app.py b/wgkex/broker/app.py index f74d3f0..9981e63 100644 --- a/wgkex/broker/app.py +++ b/wgkex/broker/app.py @@ -197,8 +197,6 @@ def wg_api_v2_gateway_best() -> Tuple[Response | Dict, int]: return {"error": {"message": str(ex)}}, 400 domain = data.domain - # in case we want to decide here later we want to publish it only to dedicated gateways - gateway = "all" logger.info(f"wg_api_v2_gateway_best: Domain: {domain}") best_worker, diff, current_peers = worker_metrics.get_best_worker(domain) From cfe5b8c8e7e10cdde81696d419f59187d9d38fdd Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 3 Apr 2024 09:38:37 +0000 Subject: [PATCH 4/8] fix linter --- wgkex/broker/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wgkex/broker/app.py b/wgkex/broker/app.py index 9981e63..0d313cb 100644 --- a/wgkex/broker/app.py +++ b/wgkex/broker/app.py @@ -51,6 +51,7 @@ def from_dict(cls, msg: dict) -> "KeyExchange": raise ValueError(f"Domain {domain} not in configured domains.") return cls(public_key=public_key, domain=domain) + @dataclasses.dataclass class Gateway: """A best Gateway message. From 8aab326219241dd788e71682a6938f891a2c98ab Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 3 Apr 2024 10:08:29 +0000 Subject: [PATCH 5/8] add switch bool --- wgkex/broker/app.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wgkex/broker/app.py b/wgkex/broker/app.py index 0d313cb..6151634 100644 --- a/wgkex/broker/app.py +++ b/wgkex/broker/app.py @@ -218,9 +218,14 @@ def wg_api_v2_gateway_best() -> Tuple[Response | Dict, int]: logger.error(f"Couldn't get worker endpoint data for {best_worker}/{domain}") return {"error": {"message": "could not get gateway data"}}, 500 + #Add Code to check if we should Switch (check if Gateways are Loadbalaced in a specefiy trashhold) + shouldSwitch = True endpoint = { "Address": w_data.get("ExternalAddress"), "Port": str(w_data.get("Port")), + "AllowedIPs": [w_data.get("LinkAddress")], + "PublicKey": w_data.get("PublicKey"), + "Switch:" shouldSwitch } return {"Endpoint": endpoint}, 200 From a3994ceab6d4be25b65221f9b359a0e5d623d4b0 Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 3 Apr 2024 10:16:05 +0000 Subject: [PATCH 6/8] fix error --- wgkex/broker/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgkex/broker/app.py b/wgkex/broker/app.py index 6151634..5bbe01a 100644 --- a/wgkex/broker/app.py +++ b/wgkex/broker/app.py @@ -225,7 +225,7 @@ def wg_api_v2_gateway_best() -> Tuple[Response | Dict, int]: "Port": str(w_data.get("Port")), "AllowedIPs": [w_data.get("LinkAddress")], "PublicKey": w_data.get("PublicKey"), - "Switch:" shouldSwitch + "Switch": shouldSwitch, } return {"Endpoint": endpoint}, 200 From 240825c097c09c2a057f5926a71a9da03ef6db7d Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 3 Apr 2024 10:19:26 +0000 Subject: [PATCH 7/8] fix linter --- wgkex/broker/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgkex/broker/app.py b/wgkex/broker/app.py index 5bbe01a..865c9e9 100644 --- a/wgkex/broker/app.py +++ b/wgkex/broker/app.py @@ -218,7 +218,7 @@ def wg_api_v2_gateway_best() -> Tuple[Response | Dict, int]: logger.error(f"Couldn't get worker endpoint data for {best_worker}/{domain}") return {"error": {"message": "could not get gateway data"}}, 500 - #Add Code to check if we should Switch (check if Gateways are Loadbalaced in a specefiy trashhold) + # Add Code to check if we should Switch (check if Gateways are Loadbalaced in a specefiy trashhold) shouldSwitch = True endpoint = { "Address": w_data.get("ExternalAddress"), From 7cc2b8f17a21f1f60d3c0361ff795e0e73556750 Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 3 Apr 2024 10:21:16 +0000 Subject: [PATCH 8/8] fix linter --- wgkex/broker/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgkex/broker/app.py b/wgkex/broker/app.py index 865c9e9..84366d1 100644 --- a/wgkex/broker/app.py +++ b/wgkex/broker/app.py @@ -218,7 +218,7 @@ def wg_api_v2_gateway_best() -> Tuple[Response | Dict, int]: logger.error(f"Couldn't get worker endpoint data for {best_worker}/{domain}") return {"error": {"message": "could not get gateway data"}}, 500 - # Add Code to check if we should Switch (check if Gateways are Loadbalaced in a specefiy trashhold) + # Add Code to check if we should Switch (check if Gateways are Loadbalaced in a specefiy trashhold) shouldSwitch = True endpoint = { "Address": w_data.get("ExternalAddress"),