From d34136b42f9548132bb6ff4d2b164edd3ab840de Mon Sep 17 00:00:00 2001 From: lare Date: Sun, 29 Sep 2024 20:09:45 +0200 Subject: [PATCH] [backend] longer timeout for node communication and retrying with other if add/update fails with 409/404 --- nodes/main.py | 3 +-- web/backend/peering_manager.py | 42 +++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/nodes/main.py b/nodes/main.py index 95f9685..4de9e68 100644 --- a/nodes/main.py +++ b/nodes/main.py @@ -227,8 +227,7 @@ class PeeringManager: else: return False, ret_code - def update_peering(self, ASN, wg_key, MNT=NotSpecified, node=NotSpecified, endpoint=NotSpecified, ipv6ll=NotSpecified, ipv4=NotSpecified, ipv6=NotSpecified, bgp_mp=NotSpecified, bgp_enh=NotSpecified): - asn = ASN + def update_peering(self, asn, wg_key, MNT=NotSpecified, node=NotSpecified, endpoint=NotSpecified, ipv6ll=NotSpecified, ipv4=NotSpecified, ipv6=NotSpecified, bgp_mp=NotSpecified, bgp_enh=NotSpecified): try: if not asn in self.peerings: diff --git a/web/backend/peering_manager.py b/web/backend/peering_manager.py index c878223..2249563 100644 --- a/web/backend/peering_manager.py +++ b/web/backend/peering_manager.py @@ -17,11 +17,11 @@ class NodeCommunicator: def update(self, action: str, peering: dict): try: if action == "add": - req = requests.post(f"{self.__api_addr}peerings", json=peering, timeout=6) + req = requests.post(f"{self.__api_addr}peerings", json=peering, timeout=10) elif action == "update": - req = requests.put(f"{self.__api_addr}peerings", json=peering, timeout=6) + req = requests.put(f"{self.__api_addr}peerings", json=peering, timeout=10) elif action == "delete": - req = requests.delete(f"{self.__api_addr}peerings", json=peering, timeout=6) + req = requests.delete(f"{self.__api_addr}peerings", json=peering, timeout=10) else: return 400 @@ -158,7 +158,7 @@ class PeeringManager: except KeyError: return {} - def add_peering(self, asn, node, mnt, wg_key, endpoint=None, ipv6ll=None, ipv4=None, ipv6=None, bgp_mp=True, bgp_enh=True): + def add_peering(self, asn, node, mnt, wg_key, endpoint=None, ipv6ll=None, ipv4=None, ipv6=None, bgp_mp=True, bgp_enh=True)-> tuple[bool,int]: # check if this MNT already has a/this asn try: if asn not in self.peerings["mntner"][mnt]: @@ -181,10 +181,14 @@ class PeeringManager: peering = {"MNT": mnt, "ASN": asn, "node": node, "wg_key": wg_key, "endpoint": endpoint, "ipv6ll": ipv6ll, "ipv4": ipv4, "ipv6": ipv6, "bgp_mp": bgp_mp, "bgp_enh": bgp_enh} success, code = self._update_nodes("add", peering=peering) - if not success: - # if ssomething failed notify user and don't add it to the list + if not success and code != 409: + # if something failed notify user and don't add it to the list return False, code - # + elif code == 409: + # apparently this peering already exists in a similar way, so we'll try updating it + success, code = self._update_nodes("update", peering=peering) + if not success: + return False, code self.peerings["asn"][asn].append(peering) self._save_peerings() return True, code @@ -206,27 +210,33 @@ class PeeringManager: # this should only happen if "asn" not in self.peerings return False, 404 - success = False + found = False for pNr in range(len(self.peerings["asn"][asn])): if self.peerings["asn"][asn][pNr]["node"] == node: old_peering = self.peerings["asn"][asn][pNr] new_peering = self.peerings["asn"][asn][pNr] = {"MNT": mnt, "ASN": asn, "node": node, "wg_key": wg_key, "endpoint": endpoint, "ipv6ll": ipv6ll, "ipv4": ipv4, "ipv6": ipv6, "bgp_mp": bgp_mp, "bgp_enh": bgp_enh} - success = True + found = True peering_number = pNr - if not success: - return False + if not found: + return False, 404 # notify the node success, code = self._update_nodes("update", old_peering, new_peering=new_peering) - if not success: + if not success and code != 404: # revert updating peering self.peerings["asn"][asn][peering_number] = old_peering return False, code - else: - - self._save_peerings() - return True, code + elif code == 404: + # for some reason the node doesn't yet know about this peering, we'l try adding it + success, code = self._update_nodes("add", old_peering, new_peering=new_peering) + if not success: + # revert updating peering + self.peerings["asn"][asn][peering_number] = old_peering + return False, code + + self._save_peerings() + return True, code def delete_peering(self, asn, node, mnt, wg_key=None): if not self.exists(asn, node, mnt=mnt, wg_key=wg_key):