can add syncthing public address; refactorings

This commit is contained in:
B.J. Dweck 2021-01-31 11:45:07 +02:00
parent afb1a2f7bd
commit 9f4084fb53
4 changed files with 71 additions and 42 deletions

View File

@ -21,7 +21,9 @@ services:
volumes:
- sync1config:/config
environment:
- SYNCTHING_PUBLIC_HOST=sync1
- SYNCTHING_HOSTNAME=sync1
- SYNCTHING_ADDRESS=tcp4://sync1
- SYNCTHING_DATA_PATH=/data
networks:
- syncnet
@ -45,7 +47,9 @@ services:
volumes:
- sync2config:/config
environment:
- SYNCTHING_PUBLIC_HOST=sync2
- SYNCTHING_HOSTNAME=sync2
- SYNCTHING_ADDRESS=tcp4://sync2
- SYNCTHING_DATA_PATH=/data
networks:
- syncnet

View File

@ -2,27 +2,35 @@ import os
import sys
import time
from retrying import retry
import syncthing_monitor.config_xml as xml
from .etcd_client import EtcdClient
from .syncthing_client import SyncthingClient
SHARED_FOLDER_ID = "data"
SHARED_FOLDER_LABEL = "syncthing_monitor_data"
SYNCTHING_CONFIG_XML_PATH = '/config/config.xml'
SYNCTHING_GUI_PORT = 8384
ETCD_PORT = 2379
def main():
program = Program(os.getenv('SYNCTHING_PUBLIC_HOST'),
syncthing_mon = SyncthingMonitor(os.getenv('SYNCTHING_HOSTNAME'),
os.getenv('SYNCTHING_ADDRESS'),
os.getenv('SYNCTHING_DATA_PATH'),
SYNCTHING_CONFIG_XML_PATH, "sync", SYNCTHING_GUI_PORT,
"etcd", ETCD_PORT)
program.start()
syncthing_mon.start()
class Program:
def __init__(self, syncthing_public_host,
class SyncthingMonitor:
def __init__(self, syncthing_public_host, syncthing_address, syncthing_data_path,
syncthing_config_xml_path, syncthing_hostname, syncthing_gui_port,
etcd_hostname, etcd_port):
self.syncthing_public_host = syncthing_public_host
self.syncthing_hostname = syncthing_public_host
self.syncthing_address = syncthing_address
self.syncthing_data_path = syncthing_data_path
self.my_device_id = None
self.syncthing = None
self.etcd = EtcdClient(etcd_hostname, etcd_port)
@ -30,6 +38,7 @@ class Program:
self.syncthing_hostname = syncthing_hostname
self.syncthing_config_xml_path = syncthing_config_xml_path
@retry
def initialize_syncthing(self):
api_key = xml.parse_api_key(self.syncthing_config_xml_path)
print("Found API Key: {0}".format(api_key))
@ -41,20 +50,20 @@ class Program:
self.syncthing = SyncthingClient(api_key, self.syncthing_hostname, self.syncthing_gui_port)
@retry
def start(self):
self.initialize_syncthing()
self.my_device_id = self.syncthing.get_my_device_id()
print("Found My Device ID: {0}".format(self.my_device_id))
self.syncthing.patch_config()
self.syncthing.create_shared_folder("GXWxf-3zgnU", "SharedFolder", "/data", [{'id': self.my_device_id}])
if not self.syncthing.config_is_in_sync():
self.syncthing.restart()
self.syncthing.disable_announce_discovery_and_relay()
self.syncthing.create_shared_folder(SHARED_FOLDER_ID, SHARED_FOLDER_LABEL, self.syncthing_data_path,
[{'id': self.my_device_id}])
self.syncthing.sync_config()
self.etcd.register_device_update_handler(self.update_devices)
self.etcd.add_device_to_cluster(self.my_device_id, self.syncthing_public_host)
self.etcd.add_device_to_cluster(self.my_device_id, self.syncthing_hostname, self.syncthing_address)
self.loop()
@ -68,12 +77,11 @@ class Program:
def update_devices(self, event):
device_list = self.etcd.get_device_list()
self.syncthing.add_devices(device_list)
self.syncthing.create_shared_folder("GXWxf-3zgnU", "SharedFolder", "/data", device_list)
self.syncthing.create_shared_folder(SHARED_FOLDER_ID, SHARED_FOLDER_LABEL, self.syncthing_data_path,
device_list)
self.syncthing.sync_config()
self.syncthing.print_config()
if not self.syncthing.config_is_in_sync():
self.syncthing.restart()
if __name__ == "__main__":
main()

View File

@ -17,7 +17,7 @@ class EtcdClient:
return json.loads(raw_value)
@retry
def add_device_to_cluster(self, device_id, public_host):
def add_device_to_cluster(self, device_id, hostname, address):
with self.etcd.lock('syncthing_monitor'):
cluster_info = self.load_cluster_info()
@ -26,7 +26,8 @@ class EtcdClient:
new_device = {
'id': device_id,
'hostname': public_host
'hostname': hostname,
'address': address
}
cluster_info['devices'].append(new_device)

View File

@ -11,24 +11,30 @@ class SyncthingClient:
self.host = host
self.port = port
self.headers = {'X-API-Key': self.api_key}
self.myID = None
@retry
def get_my_device_id(self):
response = requests.get(self.make_url("/rest/system/status"), headers=self.headers)
return json.loads(response.content)["myID"]
if self.myID is None:
response = self.get("/rest/system/status")
status = json.loads(response.content)
self.myID = status["myID"]
return self.myID
def add_devices(self, device_list):
for device in device_list:
self.add_device(device)
def add_device(self, device):
device_address = device['address']
if device['id'] == self.myID:
device_address = 'dynamic'
post_data = {
"deviceID": device['id'],
"name": device['hostname'],
"addresses": [
"dynamic",
"tcp://{0}:22000".format(device['hostname'])
],
"addresses": [device_address],
"compression": "metadata",
"certName": "",
"introducer": False,
@ -43,9 +49,7 @@ class SyncthingClient:
"pendingFolders": [],
"maxRequestKiB": 0
}
response = requests.post(self.make_url("/rest/config/devices"),
headers=self.headers, data=json.dumps(post_data))
response = self.post("/rest/config/devices", json.dumps(post_data))
print("Attempt to add device {0} to syncthing: {1}".format(device, response.content))
def create_shared_folder(self, folder_id, label, path, devices):
@ -95,40 +99,52 @@ class SyncthingClient:
}
post_data['devices'].append(folder_device)
response = requests.post(self.make_url("/rest/config/folders"),
headers=self.headers, data=json.dumps(post_data))
response = self.post("/rest/config/folders", json.dumps(post_data))
print("Attempt to add shared folder to syncthing: {0}".format(response.content))
@retry
def print_config(self):
response = requests.get(self.make_url("/rest/config/devices"), headers=self.headers)
response = self.get("/rest/config/devices")
print("/rest/config/devices: {0}".format(response.content))
response = requests.get(self.make_url("/rest/config/folders"), headers=self.headers)
response = self.get("/rest/config/folders")
print("/rest/config/folders: {0}".format(response.content))
response = requests.get(self.make_url("/rest/config/options"), headers=self.headers)
response = self.get("/rest/config/options")
print("/rest/config/options: {0}".format(response.content))
@retry
def config_is_in_sync(self):
response = requests.get(self.make_url("/rest/config/insync"), headers=self.headers)
response = self.get("/rest/config/insync")
return bool(json.loads(response.content)['configInSync'])
@retry
def restart(self):
response = requests.post(self.make_url("/rest/system/restart"), headers=self.headers, data='')
response = self.post("/rest/system/restart", '')
print("System reset: {0}".format(response.content))
def sync_config(self):
if not self.config_is_in_sync():
self.restart()
@retry
def patch_config(self):
def disable_announce_discovery_and_relay(self):
config_patch = {
"globalAnnounceEnabled": False,
"localAnnounceEnabled": False,
"relaysEnabled": False,
"announceLANAddresses": False,
}
response = requests.patch(self.make_url("/rest/config/options"),
headers=self.headers, data=json.dumps(config_patch))
response = self.patch("/rest/config/options", json.dumps(config_patch))
print("Patched syncthing configuration: {0}".format(response.content))
def make_url(self, endpoint):
return "http://{0}:{1}{2}".format(self.host, self.port, endpoint)
def get(self, endpoint):
return requests.get(self.make_url(endpoint), headers=self.headers)
def post(self, endpoint, data):
return requests.post(self.make_url(endpoint), headers=self.headers, data=data)
def patch(self, endpoint, data):
return requests.patch(self.make_url(endpoint), headers=self.headers, data=data)