forked from simonpainter/pyflare
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pyflare.py
114 lines (100 loc) · 3.74 KB
/
pyflare.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#! /usr/bin/env python3
import json
import logging
import os
import requests
import sys
# Logging setup
log = logging.getLogger() # 'root' Logger
console = logging.StreamHandler()
format_str = "%(levelname)s: %(filename)s:%(lineno)s -- %(message)s"
console.setFormatter(logging.Formatter(format_str))
log.addHandler(console)
acceptable_log_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
class Cloudflare:
def __init__(self, email, key):
self.endpoint = "https://api.cloudflare.com/client/v4"
self.headers = {
"X-Auth-Email": email,
"X-Auth-Key": key,
"Content-Type": "application/json",
}
def getmyip(self):
""" Get public IP """
pub_ip = requests.get("https://api.ipify.org/")
return pub_ip.text
def user(self):
""" Get the user """
user = requests.get(self.endpoint + "/user", headers=self.headers)
return user.json()
def zones(self, zone):
""" Get the zones """
payload = {"name": zone}
zones = requests.get(
self.endpoint + "/zones", headers=self.headers, params=payload
)
return zones.json()
def dns_records(self, zone_id, record):
""" Get the dns records for the zones """
payload = {"name": record}
records = requests.get(
self.endpoint + "/zones/" + zone_id + "/dns_records",
headers=self.headers,
params=payload,
)
return records.json()
def update_record(self, zone_id, record_id, record, ip_address):
""" Update the record to use the new public IP """
payload = {"type": "A", "name": record, "content": ip_address}
record = requests.put(
self.endpoint + "/zones/" + zone_id + "/dns_records/" + record_id,
headers=self.headers,
data=json.dumps(payload),
)
return record.json()
def __call__(self, zone, record):
""" If public IP has changed, call update_record method """
zone_id = cf.zones(zone)["result"][0]["id"]
record_id = cf.dns_records(zone_id, record)["result"][0]["id"]
ip_address = cf.getmyip()
if ip_address != cf.dns_records(zone_id, record)["result"][0]["content"]:
return cf.update_record(zone_id, record_id, record, ip_address)
else:
return
if __name__ == "__main__":
__location__ = os.path.realpath(
os.path.join(os.getcwd(), os.path.dirname(__file__))
)
config_file = os.path.join(__location__, "config.json")
try:
with open(config_file, "r") as json_data_file:
config = json.load(json_data_file)
if "PYFLARE_LOG_LEVEL" in os.environ:
log_level = os.environ["PYFLARE_LOG_LEVEL"]
else:
log_level = config["log_level"]
email = config["email"]
key = config["key"]
zone = config["zone"]
record = config["record"]
ll = log_level.upper()
if ll not in acceptable_log_levels:
log.critical("Please choose an accepted python logging level")
sys.exit()
elif ll == "CRITICAL":
log.setLevel(logging.CRITICAL)
elif ll == "ERROR":
log.setLevel(logging.ERROR)
elif ll == "WARNING":
log.setLevel(logging.WARNING)
elif ll == "DEBUG":
log.setLevel(logging.DEBUG)
else:
log.setLevel(logging.INFO)
cf = Cloudflare(email, key)
log.info("Using config file: {}".format(config_file))
log.info("Zone: {}".format(zone))
log.info("Record: {}".format(record))
log.debug(cf(zone, record))
except IOError:
log.critical("Unable to find or read config file.")