From 8cf82c3f1a220555b06fdd4ddc520f2e6ac48f5e Mon Sep 17 00:00:00 2001 From: lauren Date: Thu, 22 Dec 2022 20:19:38 -0500 Subject: [PATCH 1/2] initial configuration --- Dockerfile | 2 +- README.rst | 1 + docker-compose.yml | 17 ++++++++++++ etc/batfish-agent.json | 4 +++ setup.cfg | 1 + src/alto/agent/batfish.py | 54 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 etc/batfish-agent.json create mode 100644 src/alto/agent/batfish.py diff --git a/Dockerfile b/Dockerfile index 1ef248e..8c1a853 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM python:3.10.7 COPY / /tmp/alto RUN rm -rf /tmp/alto/.git && \ - pip install redis geoip2 && \ + pip install redis geoip2 pybatfish && \ pip install /tmp/alto && \ rm -rf /tmp/alto diff --git a/README.rst b/README.rst index eaa0c85..d688a92 100644 --- a/README.rst +++ b/README.rst @@ -77,6 +77,7 @@ required packages: $ pip3 install . $ pip3 install redis $ gunicorn -b 0.0.0.0:8000 --reload --preload --capture-output --error-logfile /tmp/openalto-error.log --access-logfile /tmp/openalto-access.log alto.server.northbound.wsgi -D + $ python3 -m alto.agent.manage --pid /tmp start -c etc/batfish.json -D batfish $ python3 -m alto.agent.manage --pid /tmp start -c etc/lg-agent.json -D cernlg $ python3 -m alto.agent.manage --pid /tmp start -c etc/cric-agent.json -D cric $ python3 -m alto.agent.manage --pid /tmp start -c etc/geoip-delegate-agent.json -D geoip diff --git a/docker-compose.yml b/docker-compose.yml index 283a45e..6fd29ce 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -31,6 +31,23 @@ services: entrypoint: python command: ["-m", "alto.agent.manage", "--pid", "/tmp", "start", "-c", "/etc/cric-agent.json", "-D", "cric"] network_mode: "service:alto-frontend" + alto-batfish-agent: + image: openalto/alto + volumes: + - ./etc/batfish-agent.json:/etc/batfish-agent.json + - ./etc/alto.conf:/opt/alto/etc/alto.conf + entrypoint: python + command: ["-m", "alto.agent.manage", "--pid", "/tmp", "start", "-c", "/etc/batfish-agent.json", "-D", "batfish"] + network_mode: "service:alto-frontend" + alto-batfish-server: + image: batfish/allinone + volumes: + - batfish-data:/data + ports: + - 8888:8888 + - 9996:9996 + - 9997:9997 + network_mode: "service:alto-frontend" alto-db: image: redis network_mode: "service:alto-frontend" diff --git a/etc/batfish-agent.json b/etc/batfish-agent.json new file mode 100644 index 0000000..bf61e19 --- /dev/null +++ b/etc/batfish-agent.json @@ -0,0 +1,4 @@ +{ + "namespace": "default", + "agent_class": "alto.agent.cernlg.BatfishAgent" +} \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index a551c0f..0d8cc84 100644 --- a/setup.cfg +++ b/setup.cfg @@ -51,6 +51,7 @@ install_requires = dataclasses; python_version<="3.6" importlib-metadata; python_version<"3.8" requests + pybatfish pytricia Django djangorestframework diff --git a/src/alto/agent/batfish.py b/src/alto/agent/batfish.py new file mode 100644 index 0000000..09dfd48 --- /dev/null +++ b/src/alto/agent/batfish.py @@ -0,0 +1,54 @@ +import logging +import pandas as pd +from pybatfish.client.session import Session +from pybatfish.datamodel import * +from pybatfish.datamodel.answer import * +from pybatfish.datamodel.flow import * +import time + +from alto.server.components.datasource import DBInfo, DataSourceAgent +from alto.server.components.db import ForwardingRule, Match, Action + +class BatfishAgent(DataSourceAgent): + """ + Class of data source agent for looking glass server. + """ + + def __init__(self, dbinfo: DBInfo, name: str, namespace='default', **cfg): + super().__init__(dbinfo, name, namespace) + + self.uri = self.ensure_field(cfg, 'uri') + self.router = cfg.get('default_router', None) + self.proxies = cfg.get('proxies', None) + self.refresh_interval = cfg.get('refresh_interval', None) + self.listened_routers = cfg.get('listened_routers', set()) + self.default_router = cfg.get('default_router', None) + + logging.info("Loading databases") + self.db = [ self.request_db(t) for t in ['forwarding', 'endpoint']] + + self.bf = Session(host="alto-batfish-server") + + # TODO: initialize snapshot + SNAPSHOT_DIR = '../../networks/example' + self.bf.init_snapshot(SNAPSHOT_DIR, name='snapshot-2020-01-01', overwrite=True) + self.bf.set_network('example_dc') + self.bf.set_snapshot('snapshot-2020-01-01') + self.bf.q.initIssues().answer() + + def update(self): + fib_trans = self.db[0].new_transaction() + results = self.bf.q.routes().answer().frame() + for row in results: + pkt_match = Match("network") + action = Action("next_hop") + rule = ForwardingRule(pkt_match, action) + fib_trans.add_rule(row["node"], rule) + fib_trans.commit() + + def run(self): + if self.refresh_interval is None: + self.refresh_interval = 60 + while True: + self.update() + time.sleep(self.refresh_interval) From 0c44cadc4bf5661dff7ed4f8146c82b6d4bcc960 Mon Sep 17 00:00:00 2001 From: lauren Date: Mon, 26 Dec 2022 12:33:08 -0500 Subject: [PATCH 2/2] update docker deployment --- .gitignore | 2 ++ docker-batfish/Dockerfile | 14 ++++++++++++++ docker-batfish/start.sh | 13 +++++++++++++ docker-compose.yml | 19 ++++++------------- etc/batfish-agent.json | 3 ++- src/alto/agent/batfish.py | 23 +++++++---------------- 6 files changed, 44 insertions(+), 30 deletions(-) create mode 100644 docker-batfish/Dockerfile create mode 100644 docker-batfish/start.sh diff --git a/.gitignore b/.gitignore index 4fbcd09..d96acf3 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,5 @@ MANIFEST .venv*/ .conda*/ .python-version + +batfish-data/ diff --git a/docker-batfish/Dockerfile b/docker-batfish/Dockerfile new file mode 100644 index 0000000..a464dd6 --- /dev/null +++ b/docker-batfish/Dockerfile @@ -0,0 +1,14 @@ +FROM batfish/allinone:latest + +COPY . /tmp/alto +COPY ./docker-batfish/start.sh start.sh +RUN chmod +x start.sh +RUN apt-get install -y python3 python3-pip +RUN rm -rf /tmp/alto/.git && \ + pip install redis geoip2 pybatfish && \ + pip install /tmp/alto && \ + rm -rf /tmp/alto + +EXPOSE 8000 + +ENTRYPOINT [ "./start.sh" ] diff --git a/docker-batfish/start.sh b/docker-batfish/start.sh new file mode 100644 index 0000000..1d7eb9e --- /dev/null +++ b/docker-batfish/start.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Start batfish-agent +python3 -m alto.agent.manage --pid /tmp start -c /etc/batfish-agent.json -D batfish & + +# Start batfish-server +./wrapper.sh & + +# Wait for any process to exit +wait -n + +# Exit with status of process that exited first +exit $? diff --git a/docker-compose.yml b/docker-compose.yml index 6fd29ce..7f7230e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,3 +1,4 @@ +version: '2.2' services: gateway: image: nginx @@ -31,22 +32,14 @@ services: entrypoint: python command: ["-m", "alto.agent.manage", "--pid", "/tmp", "start", "-c", "/etc/cric-agent.json", "-D", "cric"] network_mode: "service:alto-frontend" - alto-batfish-agent: - image: openalto/alto + alto-batfish-server-agent: + build: + context: . + dockerfile: docker-batfish/Dockerfile volumes: + - ./etc/batfish-data:/data - ./etc/batfish-agent.json:/etc/batfish-agent.json - ./etc/alto.conf:/opt/alto/etc/alto.conf - entrypoint: python - command: ["-m", "alto.agent.manage", "--pid", "/tmp", "start", "-c", "/etc/batfish-agent.json", "-D", "batfish"] - network_mode: "service:alto-frontend" - alto-batfish-server: - image: batfish/allinone - volumes: - - batfish-data:/data - ports: - - 8888:8888 - - 9996:9996 - - 9997:9997 network_mode: "service:alto-frontend" alto-db: image: redis diff --git a/etc/batfish-agent.json b/etc/batfish-agent.json index bf61e19..6777a91 100644 --- a/etc/batfish-agent.json +++ b/etc/batfish-agent.json @@ -1,4 +1,5 @@ { "namespace": "default", - "agent_class": "alto.agent.cernlg.BatfishAgent" + "agent_class": "alto.agent.batfish.BatfishAgent", + "refresh_interval": 300 } \ No newline at end of file diff --git a/src/alto/agent/batfish.py b/src/alto/agent/batfish.py index 09dfd48..fb34cd5 100644 --- a/src/alto/agent/batfish.py +++ b/src/alto/agent/batfish.py @@ -1,5 +1,4 @@ import logging -import pandas as pd from pybatfish.client.session import Session from pybatfish.datamodel import * from pybatfish.datamodel.answer import * @@ -17,33 +16,25 @@ class BatfishAgent(DataSourceAgent): def __init__(self, dbinfo: DBInfo, name: str, namespace='default', **cfg): super().__init__(dbinfo, name, namespace) - self.uri = self.ensure_field(cfg, 'uri') - self.router = cfg.get('default_router', None) - self.proxies = cfg.get('proxies', None) self.refresh_interval = cfg.get('refresh_interval', None) - self.listened_routers = cfg.get('listened_routers', set()) - self.default_router = cfg.get('default_router', None) logging.info("Loading databases") self.db = [ self.request_db(t) for t in ['forwarding', 'endpoint']] - self.bf = Session(host="alto-batfish-server") + self.bf = Session(host="localhost") - # TODO: initialize snapshot - SNAPSHOT_DIR = '../../networks/example' - self.bf.init_snapshot(SNAPSHOT_DIR, name='snapshot-2020-01-01', overwrite=True) - self.bf.set_network('example_dc') - self.bf.set_snapshot('snapshot-2020-01-01') + self.bf.init_snapshot('/data/live', name='live', overwrite=True) self.bf.q.initIssues().answer() def update(self): fib_trans = self.db[0].new_transaction() results = self.bf.q.routes().answer().frame() - for row in results: - pkt_match = Match("network") - action = Action("next_hop") + logging.info("RESULTS*****************************************" + str(results)) + for index in results.index: + pkt_match = Match(results["Network"][index]) + action = Action(results["Next_Hop_IP"][index]) rule = ForwardingRule(pkt_match, action) - fib_trans.add_rule(row["node"], rule) + fib_trans.add_rule(results["Node"][index], rule) fib_trans.commit() def run(self):