diff --git a/.idea/dictionaries/Javinator9889.xml b/.idea/dictionaries/Javinator9889.xml index 45a46dd..66b09e2 100644 --- a/.idea/dictionaries/Javinator9889.xml +++ b/.idea/dictionaries/Javinator9889.xml @@ -2,10 +2,12 @@ asctime + cloudflare daemonize fpreferences javinator levelname + proxied \ No newline at end of file diff --git a/LICENSE b/LICENSE index d2daa6e..c9bd668 100644 --- a/LICENSE +++ b/LICENSE @@ -631,7 +631,7 @@ to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - pyGoDaddyAUpdater + pyCloudFlareUpdater Copyright (C) 2019 Javinator9889 This program is free software: you can redistribute it and/or modify @@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: - pyGoDaddyAUpdater Copyright (C) 2019 Javinator9889 + pyCloudFlareUpdater Copyright (C) 2019 Javinator9889 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. diff --git a/README.md b/README.md index 946b1fb..8e98af7 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# GoDaddy 'A' Record Updater +# CloudFlare 'A' Record Updater -*DDNS Service for updating dynamically your GoDaddy 'A' Records when your public IP changes* +*DDNS Service for updating dynamically your CloudFlare 'A' Records when your public IP changes* -[![PyPi](https://img.shields.io/badge/v1.1%20-PyPi-green.svg)](https://pypi.org/project/pyGoDaddyUpdater/) -[![ZIP](https://img.shields.io/badge/Package%20-Zip-green.svg)](https://gitlab.javinator9889.com/Javinator9889/pyGoDaddyAUpdater/repository/master/archive.zip) -[![GIT](https://img.shields.io/badge/Package%20-Git-green.svg)](https://gitlab.javinator9889.com/Javinator9889/pyGoDaddyAUpdater.git) -[![Downloads](https://pepy.tech/badge/pygodaddyupdater)](https://pepy.tech/project/pygodaddyupdater) +[![PyPi](https://img.shields.io/badge/v1.0%20-PyPi-green.svg)](https://pypi.org/project/pyCloudFlareUpdater/) +[![ZIP](https://img.shields.io/badge/Package%20-Zip-green.svg)](https://gitlab.javinator9889.com/ddns-clients/pyCloudFlareUpdater/repository/master/archive.zip) +[![GIT](https://img.shields.io/badge/Package%20-Git-green.svg)](https://gitlab.javinator9889.com/ddns-clients/pyCloudFlareUpdater.git) +[![Downloads](https://pepy.tech/badge/pycloudflareupdater)](https://pepy.tech/project/pycloudflareupdater) ## Index @@ -18,7 +18,11 @@ ### Purpose -If you are a *GoDaddy* user (you have your own domain, CNAMES, etc.) maybe you have noticed that there is no **Dynamic +As a continuation of the [recently created pyGoDaddyUpdater](https://gitlab.javinator9889.com/ddns-clients/pyGoDaddyAUpdater), +here you have *CloudFlare Updater*. This group aims to create *DDNS* OpenSource clients that are available for every +user/sysadmin with the most common DNS providers. + +If you are a *CloudFlare* user (you have your own domain, CNAMES, etc.) maybe you have noticed that there is no **Dynamic DNS** (*DDNS*) update service, so you have to manually put your **public IP** at your domain 'A' Record whenever it changes. @@ -39,7 +43,7 @@ There are two possibilities for installing this script: Start by *cloning* this repository. For that, you will need to have [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) installed. Then, run on Git Bash: ```text - git clone https://gitlab.javinator9889.com/Javinator9889/pyGoDaddyAUpdater.git + git clone https://gitlab.javinator9889.com/ddns-clients/pyCloudFlareUpdater.git ``` There is another possibility so you can *directly download* a compressed file with all the necessary data. Just unzip @@ -48,7 +52,7 @@ There are two possibilities for installing this script: For installing, you will need **administrator** permissions, as the script is creating a new command so you can run it from everywhere: ```text - cd pyGoDaddyAUpdater + cd pyCloudFlareUpdater sudo python3 setup.py install ``` @@ -56,25 +60,26 @@ There are two possibilities for installing this script: I assume you have [**pip** installed](https://www.makeuseof.com/tag/install-pip-for-python/), so for using this package: ```text - sudo pip install pyGoDaddyUpdater + sudo pip install pyCloudFlareUpdater # If you have any error saying that at least Python 3 is needed # try with the following one: - sudo pip3 install pyGoDaddyUpdater + sudo pip3 install pyCloudFlareUpdater ``` ### Usage -First of all, you need to create a [**GoDaddy Developer Account**](https://developer.godaddy.com/getstarted), -and obtaining your *key* and *secret*. The pair you need to create are the **Production** ones, which are hosted at -https://api.godaddy.com (https://api.ote-godaddy.com is not supported). +First of all, go to your *Cloudflare user account* options, and find the section (usually at the bottom of the page) +that says **API Keys**. + +Obtain the *Global API Key* and save it on a safe location, we will use it later. -You can obtain the necessary data here: https://developer.godaddy.com/keys (use the name you want). +![API Keys](api_keys.png) --------- Once you have installed the script, the execution is simple (from your command line): ```text -$ godaddy_ddns [OPTIONS] +$ cloudflare_ddns [OPTIONS] ``` The available options are: @@ -82,22 +87,24 @@ The available options are: + `--domain DOMAIN`: specifies **which domain** will be updated. That is, if your site is hosted at www.example.com, then your domain is *example.com*. - + `--name NAME`: here the 'A' Record name must be included. In most cases, this name usually is `@` (the name pointing to - the host). + + `--name NAME`: here the 'A' Record name must be included. In most cases, this name usually matches the domain. + `--time TIME`: change the *update check interval* time (in minutes). By default, it is 5 minutes. - + `--key KEY`: the *GoDaddy Developer key* you obtained as explained before. + + `--key KEY`: the *Cloudflare key* you obtained as explained before. + + + `--mail MAIL`: the *Cloudflare mail* you use to login into your account. - + `--secret SECRET`: the *GoDaddy Developer secret* you obtained as explained before. + + `--proxied`: use this option for making all the requests to your website **access first** Cloudflare servers (the + same as enabling this option ![Cloudflare proxy](cloud.png)). + `--no_daemonize`: include this option for running this script **only once**. + `--pid PID FILE`: define your own PID file, in which the running daemon PID will be saved. By default, it is: - `/var/run/pygoddady.pid`. + `/var/run/cloudflare.pid`. + `--log LOG FILE`: define your own LOG file, in which the running daemon logs will be saved. By default, it is: - `/var/log/pygoddady.log`. + `/var/log/cloudflare.log`. + `--preferences PREFERENCES FILE`: if you are planning to dynamically update **more than one** domain at the same time, you can define a custom preferences file (if not, each time you run the daemon it will be overwritten). @@ -112,7 +119,8 @@ The first time you execute this script (or for defining a new preferences file), + Domain. + Name. + Key. - + Secret. + + Mail. + + Proxied. Then, each time you execute the script with no *extra arguments* or *providing the preferences file* you will not need to include the options mentioned above. @@ -120,7 +128,7 @@ to include the options mentioned above. ### License ```text - pyGoDaddyAUpdater + pyCloudFlareUpdater Copyright (C) 2019 - Javinator9889 This program is free software: you can redistribute it and/or modify diff --git a/api_keys.png b/api_keys.png new file mode 100644 index 0000000..6a138ba Binary files /dev/null and b/api_keys.png differ diff --git a/cloud.png b/cloud.png new file mode 100644 index 0000000..372821a Binary files /dev/null and b/cloud.png differ diff --git a/pyGoDaddyUpdater/__init__.py b/pyCloudFlareUpdater/__init__.py similarity index 93% rename from pyGoDaddyUpdater/__init__.py rename to pyCloudFlareUpdater/__init__.py index 7d930dc..f0a363b 100644 --- a/pyGoDaddyUpdater/__init__.py +++ b/pyCloudFlareUpdater/__init__.py @@ -1,4 +1,4 @@ -# pyGoDaddyAUpdater +# pyCloudFlareUpdater # Copyright (C) 2019 - Javinator9889 # # This program is free software: you can redistribute it and/or modify diff --git a/pyGoDaddyUpdater/__main__.py b/pyCloudFlareUpdater/__main__.py similarity index 77% rename from pyGoDaddyUpdater/__main__.py rename to pyCloudFlareUpdater/__main__.py index a8256b7..6597f1b 100644 --- a/pyGoDaddyUpdater/__main__.py +++ b/pyCloudFlareUpdater/__main__.py @@ -1,4 +1,4 @@ -# pyGoDaddyAUpdater +# pyCloudFlareUpdater # Copyright (C) 2019 - Javinator9889 # # This program is free software: you can redistribute it and/or modify @@ -13,6 +13,7 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import traceback from argparse import ArgumentParser from argparse import SUPPRESS from logging import getLogger @@ -24,7 +25,7 @@ from .logging_utils import LoggingHandler from .logging_utils import setup_logging -from .network import GoDaddy +from .network import CloudFlare from .network import get_machine_public_ip from .preferences import UserPreferences from .values import description @@ -33,21 +34,25 @@ def main(): + log = LoggingHandler(logs=[getLogger("cloudflareLogger")]) loop_continuation = True - log = LoggingHandler(logs=[getLogger("appLogger")]) - net = GoDaddy(preferences.get_domain(), preferences.get_name(), preferences.get_key(), preferences.get_secret()) try: + net = CloudFlare(domain=preferences.get_domain(), + name=preferences.get_name(), + key=preferences.get_key(), + mail=preferences.get_mail(), + proxied=preferences.is_record_behind_proxy()) while loop_continuation: current_ip = get_machine_public_ip() log.info("Current machine IP: \"{0}\"".format(current_ip)) if preferences.get_latest_ip() == "0.0.0.0": - preferences.set_latest_ip(net.get_godaddy_latest_ip()) - log.warning("User saved latest IP is not up to date - downloading GoDaddy A Record value: \"{0}\"" + preferences.set_latest_ip(net.get_cloudflare_latest_ip()) + log.warning("User saved latest IP is not up to date - downloading CloudFlare A Record value: \"{0}\"" .format(preferences.get_latest_ip())) if preferences.get_latest_ip() != current_ip: log.info("IP needs an upgrade - OLD IP: {0} | NEW IP: {1}" .format(preferences.get_latest_ip(), current_ip)) - result = net.set_goddady_ip(current_ip) + result = net.set_cloudflare_ip(current_ip) log.info("IP updated correctly! - Operation return code: {0}".format(result)) log.debug("Updating saved IP...") preferences.set_latest_ip(current_ip) @@ -63,8 +68,12 @@ def main(): sleep(preferences.get_time()) except KeyboardInterrupt: log.warning("Received SIGINT - exiting...") + except Exception as e: + log.error("Exception registered! - " + str(e)) + log.error("Stacktrace: " + traceback.format_exc()) + finally: preferences.save_preferences() - exit(1) + exit(0) def parser(): @@ -74,24 +83,30 @@ def parser(): args.add_argument("--domain", type=str, required=is_first_execution, - help="GoDaddy domain to be updated.") + help="CloudFlare domain to be updated.") args.add_argument("--name", type=str, required=is_first_execution, - help="GoDaddy 'A' Record name.") + help="CloudFlare 'A' Record name.") args.add_argument("--time", type=int, default=SUPPRESS, - required=is_first_execution, + required=False, help="Time (in minutes) to check for updated IP (defaults: 5 min.) - must be higher than 0.") args.add_argument("--key", type=str, required=is_first_execution, - help="GoDaddy developer key.") - args.add_argument("--secret", + help="CloudFlare API key.") + args.add_argument("--mail", type=str, required=is_first_execution, - help="GoDaddy developer secret.") + help="CloudFlare sign-in mail.") + args.add_argument("--proxied", + action="store_true", + required=is_first_execution, + default=False, + help="Set this value if you want your 'A' Record to be behind the Cloudflare proxy " + "(disabled by default).") args.add_argument("--no_daemonize", action="store_true", required=False, @@ -112,7 +127,7 @@ def parser(): help="Specifies a custom LOG file for storing current daemon logs.") args.add_argument("--preferences", type=str, - default="user.preferences", + default="cloudflare.user.preferences", required=False, metavar="PREFERENCES FILE", help="Provide a custom preferences file - useful for multiple running daemon for different 'A'" @@ -146,8 +161,8 @@ def parser(): if p_args.key: preferences.set_key(p_args.key) should_save_preferences = True - if p_args.secret: - preferences.set_secret(p_args.secret) + if p_args.mail: + preferences.set_mail(p_args.mail) should_save_preferences = True if p_args.no_daemonize: preferences.run_as_daemon(not p_args.no_daemonize) @@ -156,36 +171,39 @@ def parser(): should_save_preferences = True else: if preferences.get_pid_file() is None: - preferences.set_pid_file("/var/run/pygoddady.pid") + preferences.set_pid_file("/var/run/cloudflare.pid") if "log" in p_args: preferences.set_log_file(p_args.log) should_save_preferences = True else: if preferences.get_log_file() is None: - preferences.set_log_file("/var/log/pygoddady.log") + preferences.set_log_file("/var/log/cloudflare.log") user = p_args.user group = p_args.group - if preferences: - if not (p_args.domain and p_args.name and p_args.key and p_args.secret): + if p_args.preferences: + if not (p_args.domain and p_args.name and p_args.key and p_args.mail): print("You must provide the required params for a new preferences file") if should_save_preferences: preferences.save_preferences(p_args.preferences) if not is_first_execution: preferences.load_preferences() - file_handler = setup_logging("appLogger", preferences.get_log_file()) + if preferences.is_record_behind_proxy() != p_args.proxied: + preferences.record_behind_proxy(p_args.proxied) + preferences.save_preferences() + file_handler = setup_logging("cloudflareLogger", preferences.get_log_file()) fds = [file_handler.stream.fileno()] pid_dir = path.dirname(path.abspath(preferences.get_pid_file())) if not path.exists(pid_dir): makedirs(path=pid_dir, exist_ok=True) - daemon = Daemonize(app="pyGoDaddyDaemon", + daemon = Daemonize(app="pyCloudFlareDaemon", pid=preferences.get_pid_file(), action=main, keep_fds=fds, user=user, group=group, - logger=getLogger("appLogger")) + logger=getLogger("cloudflareLogger")) daemon.start() diff --git a/pyGoDaddyUpdater/logging_utils/__init__.py b/pyCloudFlareUpdater/logging_utils/__init__.py similarity index 94% rename from pyGoDaddyUpdater/logging_utils/__init__.py rename to pyCloudFlareUpdater/logging_utils/__init__.py index ae521d9..37f933f 100644 --- a/pyGoDaddyUpdater/logging_utils/__init__.py +++ b/pyCloudFlareUpdater/logging_utils/__init__.py @@ -1,4 +1,4 @@ -# pyGoDaddyAUpdater +# pyCloudFlareUpdater # Copyright (C) 2019 - Javinator9889 # # This program is free software: you can redistribute it and/or modify diff --git a/pyGoDaddyUpdater/logging_utils/utils.py b/pyCloudFlareUpdater/logging_utils/utils.py similarity index 98% rename from pyGoDaddyUpdater/logging_utils/utils.py rename to pyCloudFlareUpdater/logging_utils/utils.py index c5f19b6..4e8c948 100644 --- a/pyGoDaddyUpdater/logging_utils/utils.py +++ b/pyCloudFlareUpdater/logging_utils/utils.py @@ -1,4 +1,4 @@ -# pyGoDaddyAUpdater +# pyCloudFlareUpdater # Copyright (C) 2019 - Javinator9889 # # This program is free software: you can redistribute it and/or modify diff --git a/pyGoDaddyUpdater/network/__init__.py b/pyCloudFlareUpdater/network/__init__.py similarity index 89% rename from pyGoDaddyUpdater/network/__init__.py rename to pyCloudFlareUpdater/network/__init__.py index e087320..e9c73f9 100644 --- a/pyGoDaddyUpdater/network/__init__.py +++ b/pyCloudFlareUpdater/network/__init__.py @@ -1,4 +1,4 @@ -# pyGoDaddyAUpdater +# pyCloudFlareUpdater # Copyright (C) 2019 - Javinator9889 # # This program is free software: you can redistribute it and/or modify @@ -13,5 +13,5 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from ..network.network_utils import GoDaddy +from ..network.network_utils import CloudFlare from ..network.network_utils import get_machine_public_ip diff --git a/pyCloudFlareUpdater/network/network_utils.py b/pyCloudFlareUpdater/network/network_utils.py new file mode 100644 index 0000000..b997aa2 --- /dev/null +++ b/pyCloudFlareUpdater/network/network_utils.py @@ -0,0 +1,97 @@ +# pyCloudFlareUpdater +# Copyright (C) 2019 - Javinator9889 +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +def get_machine_public_ip(): + import urllib.request + + return urllib.request.urlopen('https://ident.me').read().decode('utf8') + + +class CloudFlare(object): + def __init__(self, domain, name, key, mail, proxied): + self.__domain = domain + self.__name = name + self.__headers = {"X-Auth-Email": mail, + "X-Auth-Key": key, + "Content-Type": "application/json"} + self.__proxied = proxied + self.__zone = self._get_zone() + self.__id = self._get_identifier() + + def _get_zone(self): + try: + import ujson as json + except ImportError: + import json + from urllib.request import Request, urlopen + + from ..values import cloudflare_base_url + + url_extra_attrs = "zones?name={0}&status=active&page=1&per_page=1&match=all".format(self.__name) + request = Request(cloudflare_base_url.format(url_extra_attrs), headers=self.__headers) + result = json.loads(urlopen(request).read().decode("utf8")) + if not result["success"]: + raise ValueError("CloudFlare returned error code with the request data - more info: " + result["errors"][0]) + + return result["result"][0]["id"] + + def _get_identifier(self): + try: + import ujson as json + except ImportError: + import json + from urllib.request import Request, urlopen + + from ..values import cloudflare_base_url + + url_extra_attrs = "zones/{0}/dns_records?type=A&name={1}&page=1&per_page=1".format(self.__zone, self.__name) + request = Request(cloudflare_base_url.format(url_extra_attrs), headers=self.__headers) + result = json.loads(urlopen(request).read().decode("utf8")) + if not result["success"]: + raise ValueError("CloudFlare returned error code with the request data - more info: " + result["errors"][0]) + + return result["result"][0]["id"] + + def get_cloudflare_latest_ip(self): + try: + import ujson as json + except ImportError: + import json + from urllib.request import Request, urlopen + from ..values import cloudflare_base_url + + url_extra_attrs = "zones/{0}/dns_records/{1}".format(self.__zone, self.__id) + request = Request(cloudflare_base_url.format(url_extra_attrs), headers=self.__headers) + result = json.loads(urlopen(request).read().decode("utf8")) + + return result["result"]["content"] + + def set_cloudflare_ip(self, ip): + try: + from ujson import dumps + except ImportError: + from json import dumps + from urllib.request import Request, urlopen + from ..values import cloudflare_base_url + + data = dumps({"type": "A", "name": self.__name, "content": ip, "ttl": 600, "proxied": self.__proxied}) + url_extra_attrs = "zones/{0}/dns_records/{1}".format(self.__zone, self.__id) + request = Request(url=cloudflare_base_url.format(url_extra_attrs), + data=data.encode("utf-8"), + headers=self.__headers, + method="PUT") + return urlopen(request).getcode() diff --git a/pyGoDaddyUpdater/preferences/__init__.py b/pyCloudFlareUpdater/preferences/__init__.py similarity index 94% rename from pyGoDaddyUpdater/preferences/__init__.py rename to pyCloudFlareUpdater/preferences/__init__.py index ca3ebbf..5f26955 100644 --- a/pyGoDaddyUpdater/preferences/__init__.py +++ b/pyCloudFlareUpdater/preferences/__init__.py @@ -1,4 +1,4 @@ -# pyGoDaddyAUpdater +# pyCloudFlareUpdater # Copyright (C) 2019 - Javinator9889 # # This program is free software: you can redistribute it and/or modify diff --git a/pyGoDaddyUpdater/preferences/user_preferences.py b/pyCloudFlareUpdater/preferences/user_preferences.py similarity index 79% rename from pyGoDaddyUpdater/preferences/user_preferences.py rename to pyCloudFlareUpdater/preferences/user_preferences.py index ae617c8..9854883 100644 --- a/pyGoDaddyUpdater/preferences/user_preferences.py +++ b/pyCloudFlareUpdater/preferences/user_preferences.py @@ -1,4 +1,4 @@ -# pyGoDaddyAUpdater +# pyCloudFlareUpdater # Copyright (C) 2019 - Javinator9889 # # This program is free software: you can redistribute it and/or modify @@ -23,7 +23,8 @@ def __init__(self, **kwargs): self.__name = kwargs["name"] self.__time = kwargs["time"] self.__key = kwargs["key"] - self.__secret = kwargs["secret"] + self.__mail = kwargs["mail"] + self.__proxy = kwargs["proxy"] self.__pid = kwargs["pid"] self.__log = kwargs["log"] except KeyError: @@ -32,24 +33,24 @@ def __init__(self, **kwargs): " - Domain\n" " - Name (of A Record)\n" " - Time (update time)\n" - " - Key\n" - " - Secret\n") + " - Key\n") else: self.__domain = None self.__name = None self.__time = None self.__key = None - self.__secret = None + self.__mail = None self.__pid = None self.__log = None self.__latest_ip = "0.0.0.0" + self.__proxy = True self.__daemonize = True @staticmethod def get_preferences_file(): import os - return os.path.dirname(os.path.abspath(__file__)) + "/user.preferences" + return os.path.dirname(os.path.abspath(__file__)) + "/cloudflare.user.preferences" def load_preferences(self): import pickle @@ -57,21 +58,22 @@ def load_preferences(self): from base64 import b64decode - if os.path.exists("user.preferences"): - with open("user.preferences", "rb") as fpreferences: + if os.path.exists("cloudflare.user.preferences"): + with open("cloudflare.user.preferences", "rb") as fpreferences: preferences = pickle.load(fpreferences) self.__domain = preferences["domain"] - self.__secret = b64decode(preferences["secret"]).decode("utf-8") self.__time = preferences["time"] self.__key = b64decode(preferences["key"]).decode("utf-8") + self.__mail = b64decode(preferences["mail"]).decode("utf-8") self.__name = preferences["name"] + self.__proxy = preferences["proxy"] self.__latest_ip = preferences["latest_ip"] self.__pid = preferences["pid"] self.__log = preferences["log"] else: raise FileNotFoundError("There are no saved user preferences. Call \"save_preferences\" the first time") - def save_preferences(self, filename="user.preferences"): + def save_preferences(self, filename="cloudflare.user.preferences"): import pickle from base64 import b64encode @@ -82,7 +84,8 @@ def save_preferences(self, filename="user.preferences"): "name": self.__name, "time": self.__time, "key": b64encode(bytes(self.__key, "utf-8")), - "secret": b64encode(bytes(self.__secret, "utf-8")), + "mail": b64encode(bytes(self.__mail, "utf-8")), + "proxy": self.__proxy, "latest_ip": self.__latest_ip, "pid": self.__pid, "log": self.__log} @@ -104,8 +107,11 @@ def get_time(self): def get_key(self): return self.__key - def get_secret(self): - return self.__secret + def get_mail(self): + return self.__mail + + def is_record_behind_proxy(self): + return self.__proxy def get_latest_ip(self): return self.__latest_ip @@ -131,8 +137,8 @@ def set_time(self, time): def set_key(self, key): self.__key = key - def set_secret(self, secret): - self.__secret = secret + def set_mail(self, mail): + self.__mail = mail def set_latest_ip(self, ip): self.__latest_ip = ip @@ -143,6 +149,9 @@ def set_pid_file(self, pid): def set_log_file(self, log): self.__log = log + def record_behind_proxy(self, behind_proxy: bool): + self.__proxy = behind_proxy + def run_as_daemon(self, daemonize: bool): self.__daemonize = daemonize @@ -150,4 +159,4 @@ def run_as_daemon(self, daemonize: bool): def are_preferences_stored(): import os - return os.path.exists("user.preferences") + return os.path.exists("cloudflare.user.preferences") diff --git a/pyGoDaddyUpdater/values/__init__.py b/pyCloudFlareUpdater/values/__init__.py similarity index 88% rename from pyGoDaddyUpdater/values/__init__.py rename to pyCloudFlareUpdater/values/__init__.py index b2b0354..eba6f5f 100644 --- a/pyGoDaddyUpdater/values/__init__.py +++ b/pyCloudFlareUpdater/values/__init__.py @@ -1,4 +1,4 @@ -# pyGoDaddyAUpdater +# pyCloudFlareUpdater # Copyright (C) 2019 - Javinator9889 # # This program is free software: you can redistribute it and/or modify @@ -13,4 +13,5 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from ..values.constants import cloudflare_base_url from ..values.constants import description diff --git a/pyGoDaddyUpdater/values/constants.py b/pyCloudFlareUpdater/values/constants.py similarity index 85% rename from pyGoDaddyUpdater/values/constants.py rename to pyCloudFlareUpdater/values/constants.py index 6850b0f..2788b73 100644 --- a/pyGoDaddyUpdater/values/constants.py +++ b/pyCloudFlareUpdater/values/constants.py @@ -1,4 +1,4 @@ -# pyGoDaddyAUpdater +# pyCloudFlareUpdater # Copyright (C) 2019 - Javinator9889 # # This program is free software: you can redistribute it and/or modify @@ -13,6 +13,7 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -description = """pyGoDaddyUpdater\n\n +description = """pyCloudFlareUpdater\n\n The first time this application is executed, all params must be included in order to save the user preferences and do this process automatically.""" +cloudflare_base_url = "https://api.cloudflare.com/client/v4/{0}" diff --git a/pyGoDaddyUpdater/network/network_utils.py b/pyGoDaddyUpdater/network/network_utils.py deleted file mode 100644 index 0460a58..0000000 --- a/pyGoDaddyUpdater/network/network_utils.py +++ /dev/null @@ -1,53 +0,0 @@ -# pyGoDaddyAUpdater -# Copyright (C) 2019 - Javinator9889 -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - - -def get_machine_public_ip(): - import urllib.request - - return urllib.request.urlopen('https://ident.me').read().decode('utf8') - - -class GoDaddy(object): - def __init__(self, domain, name, key, secret): - self.__domain = domain - self.__name = name - self.__headers = "sso-key {0}:{1}".format(key, secret) - - def get_godaddy_latest_ip(self): - from urllib.request import Request, urlopen - from re import search - - request = Request("https://api.godaddy.com/v1/domains/{0}/records/A/{1}".format(self.__domain, self.__name)) - request.add_header("Authorization", self.__headers) - result = urlopen(request).read().decode('utf8') - - ip = search("([0-9]{1,3}\.){3}[0-9]{1,3}", result) - return ip.group(0) if ip else "0.0.0.0" - - def set_goddady_ip(self, ip): - from urllib.request import Request, urlopen - try: - from ujson import dumps - except ImportError: - from json import dumps - - data = dumps([{"data": ip, "ttl": 600, "name": self.__name, "type": "A"}]) - request = Request(url="https://api.godaddy.com/v1/domains/{0}/records/A/{1}".format(self.__domain, self.__name), - data=data.encode("utf-8"), - headers={"Authorization": self.__headers, "Content-Type": "application/json"}, - method="PUT") - return urlopen(request).getcode() diff --git a/setup.py b/setup.py index 36a7323..9fd726a 100644 --- a/setup.py +++ b/setup.py @@ -11,25 +11,25 @@ long_description = f.read() setup( - name='pyGoDaddyUpdater', - version='1.1', - packages=['pyGoDaddyUpdater', - 'pyGoDaddyUpdater.values', - 'pyGoDaddyUpdater.network', - 'pyGoDaddyUpdater.preferences', - 'pyGoDaddyUpdater.logging_utils'], - url='https://gitlab.javinator9889.com/Javinator9889/pyGoDaddyAUpdater', - license='GPL-3.0', + name='pyCloudFlareUpdater', + version='1.0', + packages=['pyCloudFlareUpdater', + 'pyCloudFlareUpdater.values', + 'pyCloudFlareUpdater.network', + 'pyCloudFlareUpdater.preferences', + 'pyCloudFlareUpdater.logging_utils'], + url='https://gitlab.javinator9889.com/ddns-clients/pyCloudFlareUpdater', + license='GPLv3', author='Javinator9889', author_email='javialonso007@hotmail.es', - description='DDNS service for dynamically update GoDaddy A Records', + description='DDNS service for dynamically update CloudFlare \'A\' Records', long_description=long_description, long_description_content_type='text/markdown', include_package_data=False, zip_safe=True, - download_url="https://gitlab.javinator9889.com/Javinator9889/pyGoDaddyAUpdater/repository/master/archive.zip", + download_url="https://gitlab.javinator9889.com/ddns-clients/pyCloudFlareUpdater/repository/master/archive.zip", entry_points={ - 'console_scripts': ['godaddy_ddns=pyGoDaddyUpdater.__main__:parser'] + 'console_scripts': ['cloudflare_ddns=pyCloudFlareUpdater.__main__:parser'] }, install_requires=['daemonize'], classifiers=[