Skip to content

Commit

Permalink
Add MOCK_NETWORK env variable
Browse files Browse the repository at this point in the history
  • Loading branch information
pixup1 committed Jan 27, 2025
1 parent f33ff94 commit 65b9698
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 12 deletions.
2 changes: 2 additions & 0 deletions .env.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# 1 is easier to debug, 0 is more secure
DEV=1
# Control whether netcontrol actually interacts with the host's network (for development purposes)
MOCK_NETWORK=1
# `gate.localhost` if you're on your laptop, `gate.insalan.fr` if you're
# deploying the production website
WEBSITE_HOST=gate.localhost
Expand Down
3 changes: 2 additions & 1 deletion backend/langate/modules/netcontrol.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ def __init__(self):
"""
Initialize HOST_IP to the docker's default route, set up REQUEST_URL and check the connection with the netcontrol API.
"""
self.HOST_IP = subprocess.run(["/sbin/ip", "route"], capture_output=True).stdout.decode("utf-8").split()[2]
#self.HOST_IP = subprocess.run(["/sbin/ip", "route"], capture_output=True).stdout.decode("utf-8").split()[2]
self.HOST_IP = "host.docker.internal"
self.REQUEST_URL = f"http://{self.HOST_IP}:6784/"

self.logger = logging.getLogger(__name__)
Expand Down
4 changes: 4 additions & 0 deletions docker-compose-beta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ services:
- 8000
networks:
- backend
extra_hosts:
- "host.docker.internal:host-gateway"
links:
- db
depends_on:
Expand Down Expand Up @@ -102,6 +104,8 @@ services:
context: ./netcontrol
dockerfile: Dockerfile.dev
image: langate/netcontrol
environment:
- MOCK_NETWORK=${MOCK_NETWORK}
cap_add:
- NET_ADMIN
volumes:
Expand Down
4 changes: 4 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ services:
- 8000
networks:
- backend
extra_hosts:
- "host.docker.internal:host-gateway"
links:
- db
depends_on:
Expand Down Expand Up @@ -92,6 +94,8 @@ services:
netcontrol:
build: ./netcontrol
restart: unless-stopped
environment:
- MOCK_NETWORK=${MOCK_NETWORK}
cap_add:
- NET_ADMIN
volumes:
Expand Down
4 changes: 2 additions & 2 deletions netcontrol/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.12-alpine3.19
FROM python:3.12-alpine3.19

WORKDIR /nctl

Expand All @@ -12,4 +12,4 @@ RUN pip install -r /nctl/requirements.txt

COPY . /nctl

CMD ["fastapi", "run", "main.py", "--port", "6784"]
CMD ["fastapi", "run", "main.py", "--host", "0.0.0.0", "--port", "6784"]
2 changes: 1 addition & 1 deletion netcontrol/Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ RUN pip install -r /nctl/requirements.txt

COPY . /nctl

CMD ["fastapi", "dev", "main.py", "--port", "6784"]
CMD ["fastapi", "dev", "main.py", "--host", "0.0.0.0", "--port", "6784"]
25 changes: 22 additions & 3 deletions netcontrol/arp.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def get_mac(self, ip: str):
if line.startswith(ip + " "):
mac = line[41:].split(" ")[0] # 41 is the position of the MAC address in the line
self.logger.info("Found MAC %s for IP %s", mac, ip)
return { "mac" : mac}
return { "mac" : mac }
raise HTTPException(status_code=404, detail="MAC not found")

def get_ip(self, mac: str):
Expand All @@ -39,5 +39,24 @@ def get_ip(self, mac: str):
if line[41:].split(" ")[0] == mac:
ip = line.split(" ")[0] # Extracting IP address
self.logger.info("Found IP %s for MAC %s", ip, mac)
return { "ip" : ip}
raise HTTPException(status_code=404, detail="IP not found")
return { "ip" : ip }
raise HTTPException(status_code=404, detail="IP not found")

class MockedArp(Arp):
"""
Class which *doesn't* interact with the ARP table
"""
def __init__(self, logger: logging.Logger):
self.logger = logger

def get_mac(self, ip: str):
self.logger.info("Querying MAC for IP %s", ip)
mac = "00:00:00:00:00:00"
self.logger.info("Found MAC %s for IP %s", mac, ip)
return { "mac" : mac }

def get_ip(self, mac: str):
self.logger.info("Querying IP for MAC %s", mac)
ip = "127.0.0.1"
self.logger.info("Found IP %s for MAC %s", ip, mac)
return { "ip" : "127.0.0.1" }
18 changes: 13 additions & 5 deletions netcontrol/main.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
from fastapi import FastAPI
from contextlib import asynccontextmanager
import os
import logging
from .nft import Nft
from .arp import Arp
from .nft import Nft, MockedNft
from .arp import Arp, MockedArp

mock = os.getenv("MOCK_NETWORK", "0") == "1"

logger = logging.getLogger('uvicorn.error')
# for some reason, default loggers are not working with FastAPI

logger.info("Checking that nftables is working...")
nft = Nft(logger)
arp = Arp(logger)
if mock:
logger.warning("MOCK_NETWORK is set to 1, Nftables rules will not be applied.")
nft = MockedNft(logger)
arp = MockedArp(logger)
else:
nft = Nft(logger)
arp = Arp(logger)
logger.info("Checking that nftables is working...")
nft.check_nftables()

@asynccontextmanager
Expand Down
13 changes: 13 additions & 0 deletions netcontrol/nft.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,16 @@ def delete_user(self, mac: str) -> None:

class NftablesException(Exception):
pass

class MockedNft(Nft):
"""
Class which mocks the Nft class without actually executing nft commands
"""
def __init__(self, logger: logging.Logger):
self.logger = logger

def check_nftables(self):
return

def _execute_nft_cmd(self, cmd: str) -> dict:
return {}

0 comments on commit 65b9698

Please sign in to comment.