-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.py
125 lines (107 loc) · 3.32 KB
/
index.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
115
116
117
118
119
120
121
122
123
124
125
import sys
import os
import yaml
import json
import requests
from time import sleep
from pymemcache.client.base import Client
from designateclient.v2 import client
from keystoneauth1.identity import generic
from keystoneauth1 import session as keystone_session
def json_serializer(key, value):
if type(value) == str:
return value, 1
return json.dumps(value), 2
def json_deserializer(key, value, flags):
if flags == 1:
return value
if flags == 2:
return json.loads(value)
raise Exception("Unknown serialization format")
print("Reading settings...")
config = "settings.yaml"
if os.path.isfile(config):
with open(config) as f:
settings = yaml.load(f, Loader=yaml.Loader)
else:
sys.exit("Can't find settings.")
if settings["sleep"] != 0:
print("\nSleeping...") # allow hosts to save latency information
sleep(settings["sleep"])
try:
mc = Client(
(settings["memcached"]["server"], int(settings["memcached"]["port"])),
serializer=json_serializer,
deserializer=json_deserializer)
except Exception as e:
print(str(e))
sys.exit("Can't connect to Memcached.")
try:
auth = generic.Password(
auth_url=settings["openstack"]["endpoint"],
username=settings["openstack"]["username"],
password=settings["openstack"]["password"],
project_name=settings["openstack"]["project"]["name"],
project_domain_id="default",
user_domain_id="default")
session = keystone_session.Session(auth=auth)
client = client.Client(session=session)
except Exception as e:
print(str(e))
sys.exit("Can't connect to Nectar.")
token = "dns-lb"
print("\nGetting current DNS records...")
records = mc.get(token)
if records is None:
records = []
for ip in records:
print("- {}".format(ip))
hosts = {}
print("\nGetting latency...")
for host in settings["haproxy"]["hosts"]:
try:
rsp = requests.get(
settings["haproxy"]["path"].format(host),
timeout=settings["haproxy"]["timeout"])
if rsp.status_code == 200:
data = rsp.text.split("/")
ping = float(data[1]) # min/avg/max/mdev
if ping < settings["latency"]["threshold"]:
hosts[host] = ping
status = "UP"
else:
status = "DOWN"
print("- {}: {} ({})".format(host, ping, status))
except Exception as e:
print("- {}: {}".format(host, str(e)))
pass
if len(hosts) == 0:
print("\nNo update due to no hosts information available.")
else:
dns = []
for ip in records:
if ip in hosts:
dns.append(ip)
for ip in hosts:
if ip not in dns:
dns.append(ip)
if len(records) != 0 and len(dns) > 1:
dns = dns[1:] + dns[:1]
if dns != records:
print("\nUpdating DNS records...")
for ip in dns:
print("- {}".format(ip))
try:
client.recordsets.update(
settings["dns"]["zone"],
settings["dns"]["name"],
{
"ttl": settings["dns"]["ttl"],
"records": dns
}
)
mc.set(token, dns)
except Exception as e:
print(str(e))
sys.exit("Can't update DNS information.")
print("\nCompleted.")