From 02457ceddffb3309e7461e1382452d3755517da7 Mon Sep 17 00:00:00 2001 From: Nathan Woodburn Date: Wed, 16 Aug 2023 16:59:57 +1000 Subject: [PATCH] main: Added worker interactions --- .env.example | 3 +- .gitignore | 2 ++ README.md | 6 ++++ main.py | 76 +++++++++++++++++++++++++++++++++++++++------ worker/.env.example | 1 + worker/main.py | 16 +++++++++- 6 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 worker/.env.example diff --git a/.env.example b/.env.example index 77d3541..182e962 100644 --- a/.env.example +++ b/.env.example @@ -1 +1,2 @@ -LICENCE-API=y6X3N9d4nqXYjJ4x \ No newline at end of file +LICENCE-API=y6X3N9d4nqXYjJ4x +WORKER_KEY=N5xKQyt280VBa7wl \ No newline at end of file diff --git a/.gitignore b/.gitignore index d876a56..feaf445 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ sites.txt licence_key.txt + +workers.txt diff --git a/README.md b/README.md index 426b3c8..3309d37 100644 --- a/README.md +++ b/README.md @@ -24,4 +24,10 @@ Install prerequisites: ``` chmod +x install.sh ./install.sh +``` + +Add worker to master server: + +``` +curl -X POST http://master-server-ip:5000/add-worker?worker=worker-name&ip=worker-server-ip -H "key: api-key" ``` \ No newline at end of file diff --git a/main.py b/main.py index 6446735..c276a9c 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,7 @@ from flask import Flask, request, jsonify import dotenv import os +import requests dotenv.load_dotenv() @@ -44,10 +45,37 @@ def new_site(): if site_exists(domain): return jsonify({'error': 'Domain already exists', 'success': 'false'}) + # Check if domain contains http:// or https:// + if domain.startswith("http://") or domain.startswith("https://"): + return jsonify({'error': 'Domain should not contain http:// or https://', 'success': 'false'}) + + + # Check if worker file exists + workers = None + try: + worker_file = open('workers.txt', 'r') + workers = worker_file.readlines() + worker_file.close() + except FileNotFoundError: + return jsonify({'error': 'No workers available', 'success': 'false'}) + + # Get a worker that has available slots + worker = None + for line in workers: + ip = line.split(':')[1].strip('\n') + resp=requests.get("http://"+ip + ":5000/status",timeout=2) + if (resp.status_code == 200): + if resp.json()['availability'] == True: + worker = line + break + + if worker == None: + return jsonify({'error': 'No workers available', 'success': 'false'}) + # Add domain to file sites_file = open('sites.txt', 'a') - sites_file.write(domain + '\n') + sites_file.write(domain + ':' + worker.split(':')[0] + '\n') sites_file.close() # Use key @@ -60,6 +88,9 @@ def new_site(): key_file.write(line) key_file.close() + # Send worker request + requests.post("http://"+ worker.split(':')[1].strip('\n') + ":5000/new-site?domain=" + domain) + return jsonify({'success': 'true', 'domain': domain, 'status': "creating"}) @@ -67,10 +98,11 @@ def new_site(): @app.route('/add-worker', methods=['POST']) def add_worker(): worker=request.args.get('worker') + worker_IP=request.args.get('ip') # Get API header api_key = request.headers.get('key') - if api_key == None or worker == None: - return jsonify({'error': 'Invalid API key or worker', 'success': 'false'}) + if api_key == None or worker == None or worker_IP == None: + return jsonify({'error': 'Invalid API key or worker info', 'success': 'false'}) if api_key != os.getenv('WORKER_KEY'): return jsonify({'error': 'Invalid API key', 'success': 'false'}) @@ -90,9 +122,15 @@ def add_worker(): # Add worker to file workers_file = open('workers.txt', 'a') - workers_file.write(worker + '\n') + workers_file.write(worker + ":" + worker_IP + '\n') workers_file.close() - return jsonify({'success': 'true', 'worker': worker, 'status': "ready to join"}) + + online=True + resp=requests.get("http://"+worker_IP + ":5000/ping",timeout=2) + if (resp.status_code != 200): + online=False + + return jsonify({'success': 'true', 'worker': worker, 'online': online}) def get_sites_count(): @@ -118,13 +156,33 @@ def site_exists(domain): sites_file = open('sites.txt', 'r') contains_site = False - # Check if domain is in file - if domain in sites_file.read(): - contains_site = True + for line in sites_file.readlines(): + if domain == line.split(':')[0]: + contains_site = True + break + sites_file.close() return contains_site + +def site_worker(domain): + # If file doesn't exist, create it + try: + sites_file = open('sites.txt', 'r') + except FileNotFoundError: + sites_file = open('sites.txt', 'w') + sites_file.close() + sites_file = open('sites.txt', 'r') + + worker = None + for line in sites_file.readlines(): + if domain == line.split(':')[0]: + worker = line.split(':')[1].strip('\n') + break + + sites_file.close() + return worker # Start the server if __name__ == '__main__': - app.run(debug=False, port=5000) \ No newline at end of file + app.run(debug=False, port=4000) \ No newline at end of file diff --git a/worker/.env.example b/worker/.env.example new file mode 100644 index 0000000..e7819a4 --- /dev/null +++ b/worker/.env.example @@ -0,0 +1 @@ +MAX_SITES=4 \ No newline at end of file diff --git a/worker/main.py b/worker/main.py index c15d32f..a51293d 100644 --- a/worker/main.py +++ b/worker/main.py @@ -26,6 +26,20 @@ def new_site(): # Return the domain and the number of sites return jsonify({'domain': domain, 'count': count}) +# Return status +@app.route('/status', methods=['GET']) +def status(): + num_Sites = get_sites_count() + + availability=(num_Sites < int(os.getenv('MAX_SITES'))) + return jsonify({'availability': availability, 'num_sites': num_Sites}) + + +# Ping status +@app.route('/ping') +def ping(): + return 'pong' + def get_sites_count(): # If file doesn't exist, create it try: @@ -34,7 +48,7 @@ def get_sites_count(): sites_file = open('sites.txt', 'w') sites_file.close() sites_file = open('sites.txt', 'r') - + print(sites_file.readlines()) # Return number of lines in file return len(sites_file.readlines())