Skip to content

Commit

Permalink
try multiple ipv4 and ipv6 providers
Browse files Browse the repository at this point in the history
  • Loading branch information
mietzen committed Mar 3, 2024
1 parent 7bc9b44 commit b91b52b
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 15 deletions.
34 changes: 20 additions & 14 deletions porkbun_ddns/porkbun_ddns.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,33 +84,39 @@ def get_public_ips(self) -> list:
get_ips_from_fritzbox(self.fritzbox_ip))
else:
if self.ipv4:
urls = ['https://v4.ident.me',
'https://api.ipify.org',
'https://ipv4.icanhazip.com']
try:
response = urllib.request.urlopen('https://v4.ident.me')
if response.getcode() == 200:
public_ips.append(response.read().decode('utf-8'))
else:
logger.warning("Failed to retrieve IPv4 Address! HTTP status code: {}".format(response.code()))
alternative_response = urllib.request.urlopen('https://api.ipify.org/')
if alternative_response.getcode() == 200:
public_ips.append(alternative_response.read().decode('utf-8'))
else:
logger.warning("Failed to retrieve IPv4 Address! HTTP status code: {}".format(response.code()))
for url in urls:
with urllib.request.urlopen(url) as response:
if response.getcode() == 200:
public_ips.append(response.read().decode('utf-8'))
break
logger.warning("Failed to retrieve IPv4 Address from %s! HTTP status code: %s", url, str(response.code()))
except URLError:
logger.warning("Can't reach IPv4 Address! Check IPv4 connectivity!")
if self.ipv6:
urls = ['https://v6.ident.me',
'https://api6.ipify.org',
'https://ipv6.icanhazip.com']
try:
public_ips.append(urllib.request.urlopen(
'https://v6.ident.me').read().decode('utf8'))
for url in urls:
with urllib.request.urlopen(url) as response:
if response.getcode() == 200:
public_ips.append(response.read().decode('utf-8'))
break
logger.warning("Failed to retrieve IPv6 Address from %s! HTTP status code: %s", url, str(response.code()))
except URLError:
logger.warning("Can't reach IPv6 Address! Check IPv6 connectivity!")

public_ips = set(public_ips)

if not public_ips:
raise PorkbunDDNS_Error('Failed to obtain IP Addresses!')

return [ipaddress.ip_address(x) for x in public_ips if not ipaddress.ip_address(x).is_unspecified]

def _api(self, target: str, data: dict = None) -> dict:
"""Send an API request to a specified target.
"""
Expand Down
19 changes: 18 additions & 1 deletion porkbun_ddns/test/test_porkbun_ddns.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def test_record_overwrite_alias_and_cname(self, mocker=None):
'0000:0000:0000:0000:0000:0000:0000:0001, Status: SUCCESS'])

@patch('urllib.request.urlopen')
def test_urlopen_returns_500(self, mock_urlopen):
def test_urlopen_returns_500_ipv4(self, mock_urlopen):
# Set up the mock to return a response with status code 500
mock_response = MagicMock()
mock_response.getcode.return_value = 500
Expand All @@ -176,6 +176,23 @@ def test_urlopen_returns_500(self, mock_urlopen):
# Verify that the exception has the expected error message
self.assertEqual(str(context.exception), 'Failed to obtain IP Addresses!')

@patch('urllib.request.urlopen')
def test_urlopen_returns_500_ipv6(self, mock_urlopen):
# Set up the mock to return a response with status code 500
mock_response = MagicMock()
mock_response.getcode.return_value = 500
mock_urlopen.return_value = mock_response

# Instantiate your class or call the method that uses urllib.request.urlopen()
porkbun_ddns = PorkbunDDNS(valid_config, domain='example.com', ipv4=False, ipv6=True)

# Now when you call the method that uses urllib.request.urlopen(), it will get the mocked response
with self.assertRaises(PorkbunDDNS_Error) as context:
porkbun_ddns.get_public_ips()

# Verify that the exception has the expected error message
self.assertEqual(str(context.exception), 'Failed to obtain IP Addresses!')


if __name__ == '__main__':
unittest.main()

0 comments on commit b91b52b

Please sign in to comment.