Commit d6b2e404 authored by James Kirk's avatar James Kirk
Browse files

feat: dockerised the app

feat: added docker-compose setup, inc run-compose and .env to handle vars for locally running
refactor: changed rmq to fail when it can't connect, allowing stuff to wait until the MQ is available
refactor: moved from assuming pipenv to just pip
refactor: mounted volumes, so changed interactions with clients.json to match
parent 298299d5
MQ_HOST=rmq
# DATA_DIR=
# SOAR_TOKEN_LIFETIME=
# SOAR_TOKEN_SECRET=
\ No newline at end of file
clients.json
examples/
rmq.log
\ No newline at end of file
rmq.log
Pipfile
Pipfile.lock
\ No newline at end of file
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
pubsubpy = "*"
pika = "*"
pyrabbit = "*"
flask = "*"
flask-restful = "*"
marshmallow = "*"
bson = "*"
flask-cors = "*"
cryptography = "*"
[dev-packages]
[requires]
python_version = "3.8"
This diff is collapsed.
from flask import Flask
from flask_cors import CORS
from flask_restful import Api
from endpoints.clients import Client, ClientList
from endpoints.notify import Notify
from endpoints.receive import Receive
from endpoints.send import Send
from endpoints.notify import Notify
from endpoints.token import Token
from flask_cors import CORS
from models.token import TokenModel
token = TokenModel()
......@@ -23,4 +24,4 @@ api.add_resource(Notify, "/notify")
api.add_resource(Token, "/token")
if __name__ == "__main__":
app.run(debug=True, port=8087)
app.run(debug=False, port=8087, host="0.0.0.0")
FROM python:alpine3.17
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
ENTRYPOINT [ "python" ]
\ No newline at end of file
version: '3.8'
services:
rabbitmq__local:
image: rabbitmq:management
ports:
- "5672:5672"
# - "15672:15672" # Admin web console
expose:
- "5672"
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "-q", "ping"]
interval: 5s
timeout: 20s
retries: 3
container_name: rmq
soar_bus:
build:
context: ..
dockerfile: docker/Dockerfile
restart: on-failure
depends_on:
- rabbitmq__local
environment:
- MQ_HOST=${MQ_HOST}
command: "soar_bus.py"
soar_api:
build:
context: ..
dockerfile: docker/Dockerfile
ports:
- "8087:8087"
expose:
- "8087"
command: "api.py"
environment:
- MQ_HOST=${MQ_HOST}
volumes:
- ${DATA_DIR}/data:/data
\ No newline at end of file
import json
import os
from flask_restful import Resource, abort
from models.token import TokenModel
class AuthResource(Resource):
def __init__(self):
self.token = TokenModel()
with open("clients.json", "r") as clients_file:
data_dir = os.getenv("DATA_DIR")
with open("/data/clients.json", "r") as clients_file:
self.clients = json.load(clients_file)
def auth(self, request):
......
......@@ -13,7 +13,7 @@ class ClientSchema(Schema):
class ClientsFile:
file = "clients.json"
file = "/data/clients.json"
mtime = 0
clients = {}
parser = None
......
......@@ -18,7 +18,7 @@ class Token(Resource):
def __init__(self):
self.schema = TokenQuerySchema()
self.model = TokenModel()
with open("clients.json", "r") as clients_file:
with open("/data/clients.json", "r") as clients_file:
self.clients = json.load(clients_file)
def get(self):
......
-i https://pypi.org/simple
amqp==5.1.1 ; python_version >= '3.6'
aniso8601==9.0.1
bson==0.5.10
cffi==1.15.1
click==8.1.3 ; python_version >= '3.7'
cryptography==38.0.3
flask==2.2.2
flask-cors==3.0.10
flask-restful==0.3.9
future==0.18.2 ; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'
httplib2==0.21.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
importlib-metadata==5.1.0 ; python_version < '3.10'
itsdangerous==2.1.2 ; python_version >= '3.7'
jinja2==3.1.2 ; python_version >= '3.7'
kombu==5.2.4 ; python_version >= '3.7'
markupsafe==2.1.1 ; python_version >= '3.7'
marshmallow==3.19.0
packaging==21.3 ; python_version >= '3.6'
pika==1.3.1
pubsubpy==2.3.0
pycparser==2.21
pyparsing==3.0.9 ; python_full_version >= '3.6.8'
pyrabbit==1.1.0
python-dateutil==2.8.2 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
pytz==2022.6
six==1.16.0 ; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
vine==5.0.0 ; python_version >= '3.6'
werkzeug==2.2.2 ; python_version >= '3.7'
zipp==3.10.0 ; python_version >= '3.7'
import json
import os
import pika
host='localhost' # TODO Handle host being passed in (https://git.noc.ac.uk/communications-backbone-system/communications-backbone/-/issues/17)
host = os.getenv("MQ_HOST", "localhost") # Sets to whatever MQ_HOST is, or defaults to localhost
# -------------------------------------------------------------------------------------------------------------------------------------------------------------
def pika_connect(host):
connection = pika.BlockingConnection(pika.ConnectionParameters(host))
channel = connection.channel()
try:
connection = pika.BlockingConnection(pika.ConnectionParameters(host))
except Exception:
connection = None
if connection is not None:
channel = connection.channel()
else:
print("ERROR: Pika has been unable to connect to host '%s'. Is RabbitMQ running?" % host)
raise Exception("ERROR: Pika has been unable to connect to host '%s'. Is RabbitMQ running?" % host)
return connection, channel
......@@ -154,7 +164,6 @@ def subscribe(queue_name, exchange_name, topic=None):
# setup bindings between queue and exchange,
# exchange_type is either 'fanout' or 'topic' based on if the topic arg is passed
connection, channel = pika_connect(host=host)
setup_queue(channel=channel, queue_name=queue_name)
if topic is None:
......
set -a
source .env
if [[ -z "${DATA_DIR}" ]]; then
DATA_DIR=$(pwd)
fi
docker-compose -f docker/docker-compose.yaml up --build
\ No newline at end of file
......@@ -10,8 +10,9 @@
# soar-broadcast - admin messages forwarded to all client-inboxes regardless of subscriptions
import concurrent.futures
from endpoints.clients import ClientsFile
from rmq import publish, subscribe, broadcast, forward
from rmq import broadcast, forward, publish, subscribe
THREADS = []
EXCHANGES = {
......@@ -21,6 +22,7 @@ EXCHANGES = {
def main():
print("Starting SOAR bus...")
clients_file = ClientsFile()
clients = clients_file.get()
......@@ -45,6 +47,7 @@ def main():
EXCHANGES.get("publish"),
client["subscription"] # topic
)
THREADS.append(thread)
thread = executor.submit(
subscribe,
f"{id}-inbox",
......@@ -55,6 +58,14 @@ def main():
# TODO - add optional webhook target to client and post to webhook target
# if present
# Make sure the threads are actually running, error if not,
# this allows the SOAR Bus to actually wait for RMQ to start running
for thread in THREADS:
thread.result()
try:
print(thread.result())
except Exception as e:
print(e)
if __name__ == "__main__":
main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment