commit da99902e9962e38a01201095d98713a7e6e3ca02 Author: cooler Date: Mon Jun 19 10:12:07 2023 +0300 init diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..572ec40 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +# start by pulling the python image +FROM python:3.8-alpine + +# copy the requirements file into the image +COPY ./requirements.txt /app/requirements.txt + +# switch working directory +WORKDIR /app + +# install the dependencies and packages in the requirements file +RUN pip install -r requirements.txt + +# copy every content from the local file to the image +COPY . /app + +# configure the container to run in an executed manner +ENTRYPOINT [ "python" ] + +CMD ["main.py" ] \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..81d27a6 --- /dev/null +++ b/main.py @@ -0,0 +1,156 @@ +import json +import random +from time import sleep +import uuid +import atexit +import os +import socket, struct +import requests +from flask import Flask + +import consul + +from logging.config import dictConfig + +dictConfig({ + 'version': 1, + 'formatters': {'default': { + 'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s', + }}, + 'handlers': {'wsgi': { + 'class': 'logging.StreamHandler', + 'stream': 'ext://sys.stdout', + 'formatter': 'default' + }}, + 'root': { + 'level': 'INFO', + 'handlers': ['wsgi'] + } +}) + + +def get_ip(): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.settimeout(0) + try: + # doesn't even have to be reachable + s.connect(('10.254.254.254', 1)) + IP = s.getsockname()[0] + except Exception: + IP = '127.0.0.1' + finally: + s.close() + return IP + +def get_default_gateway_linux(): + with open("/proc/net/route") as fh: + for line in fh: + fields = line.strip().split() + if fields[1] != '00000000' or not int(fields[3], 16) & 2: + continue + return socket.inet_ntoa(struct.pack("configuration changed. new configuration: {config} | prev config: {prev_config}' + if config != {}: + prev_config = config + changed = 0 + else: + ad = f'configuration NOT changed: {config}' + return f"Hello World,
I`m {HOSTNAME} from {SERVICE_ADDRESS} {PORT} {UUID}
my config: {config} | {ad}" + + +@app.route('/health') +def hello_world(): + data = { + 'status': 'healthy' + } + global config + global prev_config + global changed + try: + _, resp = c.kv.get('PythonApp/config', wait='2s') + resp_config = resp['Value'] + if resp_config != prev_config: + changed = 1 + config = resp_config + except Exception as e: + # config = {} + app.logger.debug(f'Get config from consul failed: {e}') + return json.dumps(data) + +@app.route('/register') +def register(): + url = BASE_CONSUL_URL + '/v1/agent/service/register' + data = { + 'Name': 'PythonApp', + 'ID': UUID, + 'Tags': ['flask'], + 'Address': SERVICE_ADDRESS, + 'Port': PORT, + 'Check': { + 'http': 'http://{address}:{port}/health'.format(address=SERVICE_ADDRESS, port=PORT), + 'interval': '10s' + } + } + res = requests.put( + url, + data=json.dumps(data) + ) + return res + +def cleanup(): + try: + sleep(int(random.randrange(1,5))) + url = BASE_CONSUL_URL + '/v1/agent/service/deregister/' + UUID + data = { + 'service_id': UUID, + } + + res = requests.put( + url, + data=json.dumps(data) + ) + app.logger.debug(f'Service registration parameters: {data} | {res.status_code} : {res.text}') + return f'Response: {res.text} | status_code: {res.status_code}' + except Exception as e: + app.logger.debug(f'{e}') +atexit.register(cleanup) + +if __name__ == '__main__': + sleep(1) + status = "" + while status != 200: + try: + app.logger.debug(f'Registering on consul') + status = register().status_code + sleep(int(random.randrange(1,5))) + except Exception as e: + app.logger.debug(f'ERROR::::: {e}') + app.run(debug=True, host="0.0.0.0", port=PORT) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4341bf3 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +flask +python-consul +requests \ No newline at end of file