Skip to content

Commit

Permalink
add Option to only get Gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
T0biii committed Apr 3, 2024
1 parent d06f8ea commit c008cca
Showing 1 changed file with 76 additions and 0 deletions.
76 changes: 76 additions & 0 deletions wgkex/broker/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit c008cca

Please sign in to comment.