diff --git a/.env b/.env index c094305..a1d104b 100644 --- a/.env +++ b/.env @@ -2,6 +2,3 @@ SYNCTHING_VERSION=latest PUID=1001 PGID=1001 TZ=Europe/London -SYNC_LISTEN_PORT=22000 -SYNC1_LISTEN_PORT=22100 -SYNC2_LISTEN_PORT=22101 diff --git a/docker-compose.test.yml b/docker-compose.test.yml index bf363ad..c39472c 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -8,15 +8,19 @@ services: - sync1 - sync2 volumes: - - sync1data:/data1 - - sync2data:/data2 + - sync1data:/data1 + - sync2data:/data2 + networks: + - syncnet sut1: build: . links: - - sync1 + - sync1:sync volumes: - - sync1config:/config:ro + - sync1config:/config + networks: + - syncnet sync1: image: ghcr.io/linuxserver/syncthing:${SYNCTHING_VERSION} @@ -27,15 +31,17 @@ services: volumes: - sync1config:/config - sync1data:/data - ports: - - ${SYNC1_LISTEN_PORT}:22000 + networks: + - syncnet sut2: build: . links: - - sync2 + - sync2:sync volumes: - - sync2config:/config:ro + - sync2config:/config + networks: + - syncnet sync2: image: ghcr.io/linuxserver/syncthing:${SYNCTHING_VERSION} @@ -46,21 +52,23 @@ services: volumes: - sync2config:/config - sync2data:/data - ports: - - ${SYNC2_LISTEN_PORT}:22000 + networks: + - syncnet etcd: image: quay.io/coreos/etcd command: /usr/local/bin/etcd --data-dir=/etcd-data - ports: - - 2379:2379 - - 2380:2380 volumes: - - etcd-data:/etcd-data + - etcd-data:/etcd-data + networks: + - syncnet volumes: sync1data: sync1config: sync2data: sync2config: - etcd-data: \ No newline at end of file + etcd-data: + +networks: + syncnet: \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index e69de29..d5f6187 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,2 @@ +retrying +requests diff --git a/syncthing_monitor/__main__.py b/syncthing_monitor/__main__.py index 43b3950..70c5e3d 100644 --- a/syncthing_monitor/__main__.py +++ b/syncthing_monitor/__main__.py @@ -1,10 +1,17 @@ -from syncthing_monitor.config_xml import parse_api_key +from syncthing_monitor.config_xml import parse_api_key, set_listen_ip_to_any +from syncthing_monitor.syncthing_rest import get_device_id -def loop(): +def loop(gui_port="8384", host="sync"): + api_key = parse_api_key() print("Found API Key: {0}".format(api_key)) + set_listen_ip_to_any() + + device_id = get_device_id(host, gui_port, api_key) + print("Found Device ID: {0}".format(device_id)) + if __name__ == "__main__": loop() diff --git a/syncthing_monitor/config_xml.py b/syncthing_monitor/config_xml.py index 3a48dd3..4ddbd6c 100644 --- a/syncthing_monitor/config_xml.py +++ b/syncthing_monitor/config_xml.py @@ -8,3 +8,13 @@ def parse_api_key(xml_path='/config/config.xml'): # noinspection SpellCheckingInspection api_key = gui.find('apikey').text return api_key + + +def set_listen_ip_to_any(in_xml_path='/config/config.xml', out_xml_path='/config/config.xml', gui_port='8384'): + with open(in_xml_path, 'r') as file: + xml = file.read() + + xml = xml.replace("127.0.0.1:8384", "0.0.0.0:"+gui_port) + + with open(out_xml_path, 'w') as file: + file.write(xml) diff --git a/syncthing_monitor/syncthing_rest.py b/syncthing_monitor/syncthing_rest.py new file mode 100644 index 0000000..561726b --- /dev/null +++ b/syncthing_monitor/syncthing_rest.py @@ -0,0 +1,11 @@ +import json + +import requests +from retrying import retry + + +@retry +def get_device_id(host, gui_port, api_key): + syncthing_headers = {'X-API-Key': api_key} + response = requests.get("http://" + host + ":" + gui_port + "/rest/system/status", headers=syncthing_headers) + return json.loads(response.content)["myID"] diff --git a/test/test-syncthing-config-any-ip.xml b/test/test-syncthing-config-any-ip.xml new file mode 100644 index 0000000..f4d6997 --- /dev/null +++ b/test/test-syncthing-config-any-ip.xml @@ -0,0 +1,114 @@ + + + basic + + + + + + + 1 + + 0 + + 0 + 0 + 0 + random + false + 0 + 0 + 10 + false + false + false + 25 + .stfolder + false + 0 + 2 + false + standard + standard + false + false + + +
dynamic
+ false + 10.122.122.0/24 + false + 0 + 0 + 0 + false + 0 +
+ +
tcp://blackberry
+ false + 10.122.122.0/24 + false + 0 + 0 + 0 + false + 0 +
+ +
0.0.0.0:8384
+ syncadmin + $2a$10$.nzDwmF2w9gWfPFWto1wmOOek4RzEF/MlolVyzOLsOCXL733IleVC + dFoLNEaqEZFSP62EFVGC2Ds5juuTmvH2 + default +
+ + + default + default + false + false + 21027 + [ff12::8384]:21027 + 0 + 0 + 60 + false + 10 + true + false + 60 + 30 + 10 + -1 + 3 + + https://data.syncthing.net/newdata + false + 1800 + true + 12 + false + 24 + false + 5 + false + 1 + https://upgrades.syncthing.net/meta.json + false + 10 + 0 + ~ + true + 0 + https://crash.syncthing.net/newcrash + false + 180 + 20 + default + auto + 0 + false + false + +
diff --git a/test/test_config.py b/test/test_config.py index 602c175..1d5e80c 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -1,10 +1,35 @@ +import io +import os import unittest +from os import path -from syncthing_monitor.config_xml import parse_api_key +from syncthing_monitor.config_xml import parse_api_key, set_listen_ip_to_any + +SYNCTHING_TEST_CONFIG_XML = 'test/test-syncthing-config.xml' + +EXPECTED_API_KEY = "dFoLNEaqEZFSP62EFVGC2Ds5juuTmvH2" +SYNCTHING_EXPECTED_ANY_IP_CONFIG_XML = 'test/test-syncthing-config-any-ip.xml' + +TEST_OUT_XML = 'test/out.xml' + + +def read_file(filename=TEST_OUT_XML): + with open(filename, 'r') as file: + return file.read() class ConfigTests(unittest.TestCase): def test_can_parse_api_key(self): # noinspection SpellCheckingInspection - self.assertEqual(parse_api_key('test/test-syncthing-config.xml'), "dFoLNEaqEZFSP62EFVGC2Ds5juuTmvH2") + self.assertEqual(parse_api_key(SYNCTHING_TEST_CONFIG_XML), EXPECTED_API_KEY) + + def test_can_set_listen_ip_to_any(self): + set_listen_ip_to_any(SYNCTHING_TEST_CONFIG_XML, TEST_OUT_XML) + self.assertListEqual( + list(io.open(TEST_OUT_XML)), + list(io.open(SYNCTHING_EXPECTED_ANY_IP_CONFIG_XML))) + + def tearDown(self): + if path.exists(TEST_OUT_XML): + os.remove(TEST_OUT_XML)