Moved all source files to src/

This commit is contained in:
2024-02-12 12:26:09 +01:00
parent 11ceb88f1b
commit 440f31fede
7 changed files with 106 additions and 73 deletions

View File

@@ -29,7 +29,7 @@ virtualenv
source -p $(which python3) env/bin/activate source -p $(which python3) env/bin/activate
pip install -r requirements.txt pip install -r requirements.txt
python main.py python src/main.py
``` ```
## Kubernetes ## Kubernetes
@@ -46,8 +46,14 @@ metadata:
namespace: cloudflare-ddns namespace: cloudflare-ddns
type: Opaque type: Opaque
data: data:
API_KEY: BASE_64_ENCODED_CLOUDFLARE_API_KEY API_KEY: CLOUDFLARE_API_KEY
DDNS_ZONE: BASE64_ENCODED_CLOUDFLARE_ZONE_ID DDNS_ZONE: CLOUDFLARE_ZONE_ID
```
(Optional: receive a SMS from gateway API by appending to secrets data)
```yaml
SMS_API_KEY: GATEWAY_API_API_KEY
SMS_RECIPIENT: PHONE_NUMBER_TO_RECEIVE
``` ```
``` ```

65
main.py
View File

@@ -1,65 +0,0 @@
import os
import re
import requests
from bulk_dns_update import updateAllZones, setAPIKey, getDDNSAddresszoneId
from notify import notify
from dotenv import load_dotenv
from logger import logger
load_dotenv()
currentIP = None
recordedIP = None
DDNS_ZONE = os.getenv('DDNS_ZONE')
def validIP(ipString):
ipRegex = '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
return re.search(ipRegex, ipString)
def publicAddress():
global currentIP
logger.info('Getting public IP from ifconfg.me...')
r = requests.get('https://ifconfig.me')
if r.status_code != 200 or not validIP(r.text):
return
currentIP = r.text
logger.info('Public IP: {}'.format(currentIP))
def cloudflareDDNS():
global recordedIP
logger.info('Checking IP recorded in Cloudflare...')
ddnsRecord = getDDNSAddresszoneId(DDNS_ZONE)
recordedIP = ddnsRecord['content']
logger.info('Found ddns recorded IP: {}'.format(recordedIP))
if currentIP != recordedIP and validIP(recordedIP):
logger.info('Public IP has changed, updating all A records.')
return True
else:
logger.info('is same, exiting')
return False
def main():
apiKey = os.getenv('API_KEY')
if apiKey is None:
raise Exception('In .env file or environment set Cloudflare variable: API_KEY')
if DDNS_ZONE is None:
raise Exception('In .env file or environment; set Cloudflare zone where addr. points to current IP.')
setAPIKey(apiKey)
publicAddress()
changed = cloudflareDDNS()
if changed is True:
notify("IP changed to: {}. Updating all cloudflare zones!".format(currentIP))
updateAllZones(recordedIP, currentIP)
if __name__ == '__main__':
main()

7
src/__init__.py Normal file
View File

@@ -0,0 +1,7 @@
import os
import sys
PROJECT_PATH = os.getcwd()
SOURCE_PATH = os.path.join(
PROJECT_PATH, "src"
)
sys.path.append(SOURCE_PATH)

View File

@@ -63,6 +63,11 @@ def getZones():
url = 'https://api.cloudflare.com/client/v4/zones' url = 'https://api.cloudflare.com/client/v4/zones'
data = cloudflareRequest(url) data = cloudflareRequest(url)
if 'success' not in data and 'errors' not in data:
logger.info("Unexpected cloudflare error when getting zones, no response!")
logger.info("data:" + str(data))
raise Exception('Unexpected Cloudflare error, missing response! Check logs.')
if data['success'] is False: if data['success'] is False:
logger.info('Request to cloudflare was unsuccessful, error:') logger.info('Request to cloudflare was unsuccessful, error:')
logger.info(data['errors']) logger.info(data['errors'])
@@ -77,9 +82,15 @@ def getZones():
def getRecordsForZone(zoneId): def getRecordsForZone(zoneId):
url = 'https://api.cloudflare.com/client/v4/zones/{}/dns_records?type=A'.format(zoneId) url = 'https://api.cloudflare.com/client/v4/zones/{}/dns_records?type=A'.format(
zoneId)
data = cloudflareRequest(url) data = cloudflareRequest(url)
if 'success' not in data and 'errors' not in data:
logger.info("Unexpected cloudflare error when getting records, no response!")
logger.info("data:" + str(data))
raise Exception('Unexpected Cloudflare error, missing response! Check logs.')
if data['success'] is False: if data['success'] is False:
logger.info('Request from cloudflare was unsuccessful, error:') logger.info('Request from cloudflare was unsuccessful, error:')
logger.info(data['errors']) logger.info(data['errors'])
@@ -105,7 +116,8 @@ def getDDNSAddresszoneId(ddnsZone):
def updateRecord(zoneId, recordId, name, newIP, ttl, proxied): def updateRecord(zoneId, recordId, name, newIP, ttl, proxied):
url = 'https://api.cloudflare.com/client/v4/zones/{}/dns_records/{}'.format(zoneId, recordId) url = 'https://api.cloudflare.com/client/v4/zones/{}/dns_records/{}'.format(
zoneId, recordId)
data = { data = {
'type': 'A', 'type': 'A',
'name': name, 'name': name,
@@ -115,7 +127,8 @@ def updateRecord(zoneId, recordId, name, newIP, ttl, proxied):
} }
response = cloudflareUpdateRequest(url, data) response = cloudflareUpdateRequest(url, data)
logger.info('\tRecord updated: {}'.format('' if response['success'] is True else '')) logger.info('\tRecord updated: {}'.format(
'' if response['success'] is True else ''))
def getMatchingRecordsForZone(zoneId, oldIP): def getMatchingRecordsForZone(zoneId, oldIP):
@@ -131,8 +144,10 @@ def updateZone(zone, oldIP, newIP):
return return
for record in records: for record in records:
logger.info('\tRecord {}: {} -> {}'.format(record['name'], record['content'], newIP)) logger.info(
updateRecord(zone['id'], record['id'], record['name'], newIP, record['ttl'], record['proxied']) '\tRecord {}: {} -> {}'.format(record['name'], record['content'], newIP))
updateRecord(zone['id'], record['id'], record['name'],
newIP, record['ttl'], record['proxied'])
def updateAllZones(oldIP, newIP): def updateAllZones(oldIP, newIP):

70
src/main.py Normal file
View File

@@ -0,0 +1,70 @@
import os
import re
import requests
from bulk_dns_update import updateAllZones, setAPIKey, getDDNSAddresszoneId
from notify import notify
from dotenv import load_dotenv
from logger import logger
load_dotenv()
DDNS_ZONE = os.getenv('DDNS_ZONE')
def validIP(ipString):
ipRegex = '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
return bool(re.search(ipRegex, str(ipString)))
def publicAddress():
logger.info('Getting public IP from ifconfg.me...')
r = requests.get('https://ifconfig.me')
if r.status_code != 200:
return
ip = r.text
if not validIP(ip):
return
logger.info('Public IP: {}'.format(ip))
return ip
def cloudflareDDNS():
logger.info('Checking IP recorded in Cloudflare...')
ddnsRecord = getDDNSAddresszoneId(DDNS_ZONE)
ip = ddnsRecord['content']
logger.info('Found ddns recorded IP: {}'.format(ip))
if not validIP(ip):
return
return ip
def main():
apiKey = os.getenv('API_KEY')
if apiKey is None:
raise Exception(
'In .env file or environment set Cloudflare variable: API_KEY')
if DDNS_ZONE is None:
raise Exception(
'In .env file or environment; set Cloudflare zone where addr. points to current IP.')
setAPIKey(apiKey)
currentIP = publicAddress()
recordedIP = cloudflareDDNS()
if currentIP == recordedIP or None in [currentIP, recordedIP]:
logger.info('is same, exiting')
return
logger.info('Public IP has changed, updating all A records.')
notify("IP changed to: {}. Updating all cloudflare zones!".format(currentIP))
updateAllZones(recordedIP, currentIP)
if __name__ == '__main__':
main()