This commit is contained in:
@@ -4,7 +4,7 @@ on:
|
|||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: woryzen
|
runs-on: hostinger
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout sources
|
- name: Checkout sources
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
from urllib.request import urlopen, Request
|
|
||||||
import argparse
|
import argparse
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from subprocess import check_call
|
from subprocess import check_call
|
||||||
|
from .utils import get_public_ip
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
@@ -19,11 +17,8 @@ def run():
|
|||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
url = "http://v4.ipv6-test.com/api/myip.php"
|
|
||||||
request = Request(url)
|
|
||||||
with urlopen(request) as request:
|
|
||||||
public_ip = request.read().decode()
|
|
||||||
date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
public_ip = get_public_ip()
|
||||||
params = {
|
params = {
|
||||||
'Comment': f'Auto update by awsdyndns on {date}',
|
'Comment': f'Auto update by awsdyndns on {date}',
|
||||||
'Changes': [
|
'Changes': [
|
80
dyndns/cloudflare.py
Normal file
80
dyndns/cloudflare.py
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import json
|
||||||
|
import argparse
|
||||||
|
from os import environ
|
||||||
|
from .utils import get_public_ip
|
||||||
|
from urllib.request import urlopen, Request
|
||||||
|
|
||||||
|
# Define your variables
|
||||||
|
cloudflare_api_key = environ['CLOUDFLARE_API_KEY']
|
||||||
|
|
||||||
|
def update_dns_record(
|
||||||
|
zone_id: str,
|
||||||
|
dns_record_id: str,
|
||||||
|
ip_address: str,
|
||||||
|
domain_name: str,
|
||||||
|
ttl: int,
|
||||||
|
record_type : str,
|
||||||
|
proxied : bool = False,
|
||||||
|
comment : str = None
|
||||||
|
):
|
||||||
|
# Set the URL
|
||||||
|
url = f'https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{dns_record_id}'
|
||||||
|
|
||||||
|
# Set the headers
|
||||||
|
headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': f'Bearer {cloudflare_api_key}'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Define the data to be sent in the PATCH request
|
||||||
|
data = {
|
||||||
|
"comment": comment,
|
||||||
|
"content": ip_address,
|
||||||
|
"name": domain_name,
|
||||||
|
"proxied": proxied,
|
||||||
|
"ttl": ttl,
|
||||||
|
"type": record_type
|
||||||
|
}
|
||||||
|
|
||||||
|
# Make the PATCH request
|
||||||
|
request = Request(url, headers=headers, data=json.dumps(data).encode('UTF-8'), method='PATCH')
|
||||||
|
with urlopen(request) as request:
|
||||||
|
if request.status != 200:
|
||||||
|
response = request.read().decode()
|
||||||
|
msg = f'Failed to update DNS record: {request.status} {response}'
|
||||||
|
raise RuntimeError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('-z', "--hosted-zone", metavar='HOSTED_ZONE_ID', required=True,
|
||||||
|
help="Specify the hosted zone id")
|
||||||
|
parser.add_argument('-d', "--domain", metavar='DOMAIN_NAME', required=True,
|
||||||
|
help="Specify domain name")
|
||||||
|
parser.add_argument('-t', "--type", metavar='DNS_TYPE', default='A',
|
||||||
|
help="Specify DNS type")
|
||||||
|
parser.add_argument('-l', "--ttl", metavar='TTL_S', type=int, default=300,
|
||||||
|
help="Specify time-to-live in seconds")
|
||||||
|
parser.add_argument('-r', "--record-id", metavar='RECORD_ID',
|
||||||
|
help="Cloudflare DNS record id")
|
||||||
|
parser.add_argument('-p', "--proxied", metavar='PROXIED', type=bool, default=False,
|
||||||
|
help="Whether or not the traffic will be proxied through Cloudflare network")
|
||||||
|
parser.add_argument('-c', "--comment", metavar='COMMENT', help="Specify a comment for this entry")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
public_ip = get_public_ip()
|
||||||
|
|
||||||
|
update_dns_record(
|
||||||
|
zone_id=args.hosted_zone,
|
||||||
|
domain_name=args.domain,
|
||||||
|
record_type=args.type,
|
||||||
|
ip_address=public_ip,
|
||||||
|
ttl=args.ttl,
|
||||||
|
dns_record_id=args.record_id,
|
||||||
|
proxied=args.proxied,
|
||||||
|
comment=args.comment
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
7
dyndns/utils.py
Normal file
7
dyndns/utils.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from urllib.request import urlopen, Request
|
||||||
|
|
||||||
|
def get_public_ip() -> str:
|
||||||
|
url = "http://v4.ipv6-test.com/api/myip.php"
|
||||||
|
request = Request(url)
|
||||||
|
with urlopen(request) as request:
|
||||||
|
return request.read().decode()
|
@@ -3,8 +3,8 @@ requires = ["setuptools>=61.0"]
|
|||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "awsdyndns"
|
name = "dyndns"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
authors = [
|
authors = [
|
||||||
{ name="Walter Oggioni", email="oggioni.walter@gmail.com" },
|
{ name="Walter Oggioni", email="oggioni.walter@gmail.com" },
|
||||||
]
|
]
|
||||||
@@ -16,14 +16,25 @@ classifiers = [
|
|||||||
"License :: OSI Approved :: MIT License",
|
"License :: OSI Approved :: MIT License",
|
||||||
"Operating System :: OS Independent",
|
"Operating System :: OS Independent",
|
||||||
]
|
]
|
||||||
dependencies = []
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
dev = [
|
||||||
|
"build", "mypy", "ipdb", "twine"
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.setuptools.package-data]
|
||||||
|
dyndns = ['conf/*']
|
||||||
|
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
"Homepage" = "https://woggioni.net/cgit/awsdyndns.git/"
|
"Homepage" = "https://gitea.woggioni.net/woggioni/dyndns/"
|
||||||
"Bug Tracker" = "https://woggioni.net/cgit/awsdyndns.git/"
|
"Bug Tracker" = "https://gitea.woggioni.net/woggioni/dyndns/"
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
awsdyndns = "awsdyndns.wrapper:run"
|
awsdyndns = "dyndns.aws:run"
|
||||||
|
cloudflaredyndns = "dyndns.cloudflare:run"
|
||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
python_version = "3.11"
|
python_version = "3.11"
|
||||||
@@ -33,4 +44,4 @@ no_implicit_optional = true
|
|||||||
warn_return_any = true
|
warn_return_any = true
|
||||||
warn_unused_ignores = true
|
warn_unused_ignores = true
|
||||||
exclude = ["scripts", "docs", "test"]
|
exclude = ["scripts", "docs", "test"]
|
||||||
strict = true
|
strict = true
|
||||||
|
141
requirements.txt
141
requirements.txt
@@ -1,31 +1,124 @@
|
|||||||
build==1.2.1
|
#
|
||||||
certifi==2024.7.4
|
# This file is autogenerated by pip-compile with Python 3.13
|
||||||
cffi==1.16.0
|
# by the following command:
|
||||||
charset-normalizer==3.3.2
|
#
|
||||||
cryptography==43.0.0
|
# pip-compile --allow-unsafe --extra=dev --output-file=requirements.txt pyproject.toml
|
||||||
|
#
|
||||||
|
--index-url https://gitea.woggioni.net/api/packages/woggioni/pypi/simple
|
||||||
|
--extra-index-url https://pypi.org/simple
|
||||||
|
|
||||||
|
asttokens==3.0.0
|
||||||
|
# via stack-data
|
||||||
|
build==1.2.2.post1
|
||||||
|
# via dyndns (pyproject.toml)
|
||||||
|
certifi==2025.1.31
|
||||||
|
# via requests
|
||||||
|
cffi==1.17.1
|
||||||
|
# via cryptography
|
||||||
|
charset-normalizer==3.4.1
|
||||||
|
# via requests
|
||||||
|
cryptography==44.0.2
|
||||||
|
# via secretstorage
|
||||||
|
decorator==5.2.1
|
||||||
|
# via
|
||||||
|
# ipdb
|
||||||
|
# ipython
|
||||||
docutils==0.21.2
|
docutils==0.21.2
|
||||||
idna==3.7
|
# via readme-renderer
|
||||||
importlib_metadata==8.2.0
|
executing==2.2.0
|
||||||
jaraco.classes==3.4.0
|
# via stack-data
|
||||||
jaraco.context==5.3.0
|
id==1.5.0
|
||||||
jaraco.functools==4.0.1
|
# via twine
|
||||||
jeepney==0.8.0
|
idna==3.10
|
||||||
keyring==25.2.1
|
# via requests
|
||||||
|
ipdb==0.13.13
|
||||||
|
# via dyndns (pyproject.toml)
|
||||||
|
ipython==9.0.2
|
||||||
|
# via ipdb
|
||||||
|
ipython-pygments-lexers==1.1.1
|
||||||
|
# via ipython
|
||||||
|
jaraco-classes==3.4.0
|
||||||
|
# via keyring
|
||||||
|
jaraco-context==6.0.1
|
||||||
|
# via keyring
|
||||||
|
jaraco-functools==4.1.0
|
||||||
|
# via keyring
|
||||||
|
jedi==0.19.2
|
||||||
|
# via ipython
|
||||||
|
jeepney==0.9.0
|
||||||
|
# via
|
||||||
|
# keyring
|
||||||
|
# secretstorage
|
||||||
|
keyring==25.6.0
|
||||||
|
# via twine
|
||||||
markdown-it-py==3.0.0
|
markdown-it-py==3.0.0
|
||||||
|
# via rich
|
||||||
|
matplotlib-inline==0.1.7
|
||||||
|
# via ipython
|
||||||
mdurl==0.1.2
|
mdurl==0.1.2
|
||||||
more-itertools==10.3.0
|
# via markdown-it-py
|
||||||
nh3==0.2.18
|
more-itertools==10.6.0
|
||||||
packaging==24.1
|
# via
|
||||||
pkginfo==1.10.0
|
# jaraco-classes
|
||||||
|
# jaraco-functools
|
||||||
|
mypy==1.15.0
|
||||||
|
# via dyndns (pyproject.toml)
|
||||||
|
mypy-extensions==1.0.0
|
||||||
|
# via mypy
|
||||||
|
nh3==0.2.21
|
||||||
|
# via readme-renderer
|
||||||
|
packaging==24.2
|
||||||
|
# via
|
||||||
|
# build
|
||||||
|
# twine
|
||||||
|
parso==0.8.4
|
||||||
|
# via jedi
|
||||||
|
pexpect==4.9.0
|
||||||
|
# via ipython
|
||||||
|
prompt-toolkit==3.0.50
|
||||||
|
# via ipython
|
||||||
|
ptyprocess==0.7.0
|
||||||
|
# via pexpect
|
||||||
|
pure-eval==0.2.3
|
||||||
|
# via stack-data
|
||||||
pycparser==2.22
|
pycparser==2.22
|
||||||
Pygments==2.18.0
|
# via cffi
|
||||||
pyproject_hooks==1.1.0
|
pygments==2.19.1
|
||||||
readme_renderer==44.0
|
# via
|
||||||
|
# ipython
|
||||||
|
# ipython-pygments-lexers
|
||||||
|
# readme-renderer
|
||||||
|
# rich
|
||||||
|
pyproject-hooks==1.2.0
|
||||||
|
# via build
|
||||||
|
readme-renderer==44.0
|
||||||
|
# via twine
|
||||||
requests==2.32.3
|
requests==2.32.3
|
||||||
|
# via
|
||||||
|
# id
|
||||||
|
# requests-toolbelt
|
||||||
|
# twine
|
||||||
requests-toolbelt==1.0.0
|
requests-toolbelt==1.0.0
|
||||||
|
# via twine
|
||||||
rfc3986==2.0.0
|
rfc3986==2.0.0
|
||||||
rich==13.7.1
|
# via twine
|
||||||
SecretStorage==3.3.3
|
rich==14.0.0
|
||||||
twine==5.1.1
|
# via twine
|
||||||
urllib3==2.2.2
|
secretstorage==3.3.3
|
||||||
zipp==3.19.2
|
# via keyring
|
||||||
|
stack-data==0.6.3
|
||||||
|
# via ipython
|
||||||
|
traitlets==5.14.3
|
||||||
|
# via
|
||||||
|
# ipython
|
||||||
|
# matplotlib-inline
|
||||||
|
twine==6.1.0
|
||||||
|
# via dyndns (pyproject.toml)
|
||||||
|
typing-extensions==4.13.0
|
||||||
|
# via mypy
|
||||||
|
urllib3==2.3.0
|
||||||
|
# via
|
||||||
|
# requests
|
||||||
|
# twine
|
||||||
|
wcwidth==0.2.13
|
||||||
|
# via prompt-toolkit
|
||||||
|
Reference in New Issue
Block a user