udyndns 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
udyndns-0.0.1/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
udyndns-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.1
2
+ Name: udyndns
3
+ Version: 0.0.1
4
+ Summary: A very simple OVH dyndns client to workaround difficulties with Ubiquity unadyn...
5
+ Home-page: https://github.com/KurisuD/udyndns
6
+ Author: KurisuD
7
+ Author-email: KurisuD@pypi.darnand.net
8
+ Classifier: Programming Language :: Python :: 3 :: Only
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: License :: Public Domain
11
+ Classifier: Operating System :: POSIX :: Linux
12
+ Classifier: Topic :: Home Automation
13
+ Classifier: Topic :: Internet :: Name Service (DNS)
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: aiounifi
17
+ Requires-Dist: pap_logger
File without changes
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
udyndns-0.0.1/setup.py ADDED
@@ -0,0 +1,28 @@
1
+ # coding=utf-8
2
+ import setuptools
3
+
4
+ from udyndns.version import __version__
5
+
6
+ with open("README.md") as fh:
7
+ long_description = fh.read()
8
+
9
+ setuptools.setup(
10
+ name="udyndns",
11
+ version=__version__,
12
+ author="KurisuD",
13
+ author_email="KurisuD@pypi.darnand.net",
14
+ description="A very simple OVH dyndns client to workaround difficulties with Ubiquity unadyn...",
15
+ long_description=long_description,
16
+ long_description_content_type="text/markdown",
17
+ url="https://github.com/KurisuD/udyndns",
18
+ packages=setuptools.find_packages(),
19
+ install_requires=['aiounifi', 'pap_logger'],
20
+ classifiers=[
21
+ "Programming Language :: Python :: 3 :: Only",
22
+ "Programming Language :: Python :: 3.10",
23
+ "License :: Public Domain",
24
+ "Operating System :: POSIX :: Linux",
25
+ "Topic :: Home Automation",
26
+ "Topic :: Internet :: Name Service (DNS)"
27
+ ],
28
+ )
@@ -0,0 +1,110 @@
1
+ import asyncio
2
+ import logging
3
+ from typing import Optional
4
+
5
+ import aiounifi
6
+ import requests
7
+ from aiohttp import ClientSession
8
+ from aiounifi.controller import Controller
9
+ from aiounifi.models.configuration import Configuration
10
+ from requests.auth import HTTPBasicAuth
11
+
12
+
13
+ async def get_wan_ip(host: str, port: int, username: str, password: str, timeout: int = 10) -> [Optional[str]]:
14
+ """
15
+ obtains the WAN IP address of the unifi gateway
16
+
17
+ :param host: hostname or ip address of your unifi gateway / dream machine / ...
18
+ :param port: port to your unifi gateway / dream machine / ...
19
+ :param username: username to authenticate on your unifi device.
20
+ :param password: password to authenticate on your unifi device.
21
+ :param timeout: number of seconds to wait for your unifi device to respond.
22
+ :return: the WAN IP address of the unifi gateway / dream machine / ...
23
+ :type host: str
24
+ :type port: int
25
+ :type username: str
26
+ :type password: str
27
+ :type timeout: int
28
+ :rtype: str | None
29
+
30
+ """
31
+ async with ClientSession() as _session:
32
+ _config = Configuration(session=_session, host=host, username=username, port=port, password=password)
33
+ api = Controller(config=_config)
34
+ try:
35
+ async with asyncio.timeout(10):
36
+ await api.login()
37
+ except aiounifi.Unauthorized as err:
38
+ logging.warning(f"Connected to {host}:{port} but user {username} is not registered: {err}")
39
+
40
+ except (
41
+ TimeoutError,
42
+ aiounifi.BadGateway,
43
+ aiounifi.Forbidden,
44
+ aiounifi.ServiceUnavailable,
45
+ aiounifi.RequestError,
46
+ aiounifi.ResponseError,
47
+ ) as err:
48
+ logging.error(f"Error connecting to the UniFi Network at {host}:{port}: {err}")
49
+ return None
50
+ _proxy_network_str = "/proxy/network" if api.connectivity.is_unifi_os else ""
51
+ health_data = await _session.get(
52
+ f"https://{host}:{port}{_proxy_network_str}/api/s/default/stat/health",
53
+ headers={"Accept": "application/json",
54
+ "Content-Type": "application/json"},
55
+ timeout=timeout,
56
+ ssl=_config.ssl_context
57
+ )
58
+ health = await health_data.json()
59
+ wan_ip = [subsystem for subsystem in health['data'] if subsystem["subsystem"] == "wan"][0]["wan_ip"]
60
+ logging.info(f"WAN IP for {host}:{port}: {wan_ip}")
61
+ return wan_ip
62
+
63
+
64
+ def update_ovh_dyn_dns(fqdn: str, ip: str, username: str, password: str) -> bool:
65
+ """
66
+ Updates the OVH Dyndns's registered wan ip address for your domain, if necessary.
67
+ :param fqdn: The fully qualified domain name to be updated.
68
+ :param ip: the wan ip address to be used for the update.
69
+ :param username: your ovh dyndns username for updating this fqdn.
70
+ :param password: your ovh dyndns password for updating this fqdn.
71
+ :return: True on success, False otherwise.
72
+ :type fqdn: str
73
+ :type ip: str
74
+ :type username: str
75
+ :type password: str
76
+ :rtype: bool
77
+ """
78
+ logging.info(f"Checking dynamic DNS for {fqdn}")
79
+ session = requests.Session()
80
+ session.auth = HTTPBasicAuth(username=username, password=password)
81
+ current_ip_url = f"https://www.ovh.com/nic/update?system=dyndns&hostname={fqdn}"
82
+ current_ip_resp = session.get(current_ip_url)
83
+ if current_ip_resp.ok:
84
+ logging.info(current_ip_resp.status_code)
85
+ logging.info(current_ip_resp.text)
86
+ current = current_ip_resp.text.split(" ")[1].strip()
87
+ if current != ip:
88
+ logging.info(f"Need to update IP from '{current}' to '{ip}'")
89
+ new_ip_url = f"{current_ip_url}&myip={ip}"
90
+ logging.info(new_ip_url)
91
+ new_ip_resp = session.get(new_ip_url)
92
+ if new_ip_resp.ok:
93
+ logging.info(f"New IP results: {new_ip_resp.text}")
94
+ return True
95
+ else:
96
+ logging.warning(new_ip_resp.status_code)
97
+ logging.warning(new_ip_resp.reason)
98
+ return False
99
+ else:
100
+ logging.info(f"Our unifi API retrieved IP {ip} is the same as our current IP: {current}")
101
+ return True
102
+ else:
103
+ logging.error(f"Unable to authenticate to the {current_ip_url}")
104
+ logging.error(current_ip_resp.status_code)
105
+ logging.error(current_ip_resp.reason)
106
+ logging.error(current_ip_resp.text)
107
+ return False
108
+
109
+
110
+ __all__ = ["get_wan_ip", "update_ovh_dyn_dns"]
@@ -0,0 +1,35 @@
1
+ import asyncio
2
+ import json
3
+ import logging
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ from __init__ import get_wan_ip, update_ovh_dyn_dns
8
+
9
+
10
+ def main():
11
+ """
12
+ Updates OVH dyndns based on the WAN IP retrieved from the unifi API since unadyn is so stubbornly unable to do so.
13
+ """
14
+ udyndns_config_file = Path("~").expanduser() / ".udyndns.json"
15
+ if not udyndns_config_file.exists():
16
+ raise FileNotFoundError(f"{udyndns_config_file} not found")
17
+ for fqdn, config in json.loads(udyndns_config_file.read_text()).items():
18
+ unifi_config = config["unifi"]
19
+ wan_ip = asyncio.run(get_wan_ip(**unifi_config))
20
+ if wan_ip:
21
+ ovh_config = config["ovh"]
22
+ ovh_config.update({"fqdn": fqdn, "ip": wan_ip})
23
+ logging.info(f"Will check and update {fqdn} with {wan_ip} if necessary")
24
+ update_ovh_dyn_dns(**ovh_config)
25
+
26
+
27
+ if __name__ == '__main__':
28
+ from pap_logger import PaPLogger
29
+
30
+ p = PaPLogger(level=logging.INFO)
31
+ try:
32
+ main()
33
+ except Exception as e:
34
+ logging.error(f"Sorry, we could not proceed: {e}")
35
+ sys.exit(1)
@@ -0,0 +1 @@
1
+ __version__ = '0.0.1'
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.1
2
+ Name: udyndns
3
+ Version: 0.0.1
4
+ Summary: A very simple OVH dyndns client to workaround difficulties with Ubiquity unadyn...
5
+ Home-page: https://github.com/KurisuD/udyndns
6
+ Author: KurisuD
7
+ Author-email: KurisuD@pypi.darnand.net
8
+ Classifier: Programming Language :: Python :: 3 :: Only
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: License :: Public Domain
11
+ Classifier: Operating System :: POSIX :: Linux
12
+ Classifier: Topic :: Home Automation
13
+ Classifier: Topic :: Internet :: Name Service (DNS)
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: aiounifi
17
+ Requires-Dist: pap_logger
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ setup.py
4
+ udyndns/__init__.py
5
+ udyndns/__main__.py
6
+ udyndns/version.py
7
+ udyndns.egg-info/PKG-INFO
8
+ udyndns.egg-info/SOURCES.txt
9
+ udyndns.egg-info/dependency_links.txt
10
+ udyndns.egg-info/requires.txt
11
+ udyndns.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ aiounifi
2
+ pap_logger
@@ -0,0 +1 @@
1
+ udyndns