|
14 | 14 | from urllib.parse import urlencode
|
15 | 15 |
|
16 | 16 | import pycountry
|
| 17 | +from bs4 import BeautifulSoup # pyright: ignore [reportMissingModuleSource] |
17 | 18 | from docker.errors import APIError
|
18 | 19 | from docker.models.containers import Container, ExecResult
|
19 | 20 | from docker.types import Mount
|
|
32 | 33 | from mirrors_qa_manager.settings import Settings
|
33 | 34 |
|
34 | 35 |
|
| 36 | +def ipme_data_from_html(html_content: str) -> dict[str, Any]: |
| 37 | + try: |
| 38 | + soup = BeautifulSoup(html_content, "html.parser") |
| 39 | + ip_address = soup.select_one( |
| 40 | + "p.ip-address" |
| 41 | + ).text # pyright: ignore [reportOptionalMemberAccess] |
| 42 | + except Exception as exc: |
| 43 | + logger.error(f"Cant parse HTML or find IP: {exc}") |
| 44 | + return {} |
| 45 | + try: |
| 46 | + ( |
| 47 | + _, # country |
| 48 | + city, |
| 49 | + _, # country_code |
| 50 | + _, # latitude |
| 51 | + _, # longitude |
| 52 | + _, # postal_code |
| 53 | + organization, |
| 54 | + _, # asn |
| 55 | + isp_name, |
| 56 | + ) = (code.text for code in soup.select("table tr td code")) |
| 57 | + organization = isp_name or organization |
| 58 | + except Exception as exc: |
| 59 | + logger.error(f"Cant find City/Organization: {exc}") |
| 60 | + city = None |
| 61 | + organization = None |
| 62 | + |
| 63 | + return { |
| 64 | + "ip": ip_address, |
| 65 | + "city": city, |
| 66 | + "organization": organization, |
| 67 | + } |
| 68 | + |
| 69 | + |
35 | 70 | class WgInterfaceStatus(Enum):
|
36 | 71 | """Status of the Wireguard interface."""
|
37 | 72 |
|
@@ -73,10 +108,13 @@ def __init__(self, worker_id: str) -> None:
|
73 | 108 | self.wg_interface = "wg0"
|
74 | 109 | self.wg_healthcheck_cmd = [
|
75 | 110 | "curl",
|
| 111 | + "--header", |
| 112 | + "User-Agent: Mozilla", |
76 | 113 | "--interface",
|
77 | 114 | self.wg_interface,
|
78 | 115 | "-s",
|
79 |
| - "https://am.i.mullvad.net/json", |
| 116 | + # "https://am.i.mullvad.net/json", |
| 117 | + "https://ip.me", |
80 | 118 | ]
|
81 | 119 | self.wg_interface_status = WgInterfaceStatus.DOWN
|
82 | 120 | # commands for bringing down/up the interface whenever a new configuration
|
@@ -438,7 +476,10 @@ def run(self) -> None:
|
438 | 476 | logger.info(
|
439 | 477 | f"Successfully retrieved metrics results for test {test_id}"
|
440 | 478 | )
|
441 |
| - ip_data = json.loads(healthcheck_result.output.decode("utf-8")) |
| 479 | + # ip_data = json.loads(healthcheck_result.output.decode("utf-8")) |
| 480 | + ip_data = ipme_data_from_html( |
| 481 | + healthcheck_result.output.decode("utf-8") |
| 482 | + ) |
442 | 483 | payload = self.merge_data(
|
443 | 484 | ip_data=ip_data,
|
444 | 485 | metrics_data=json.loads(results),
|
|
0 commit comments