Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}/translator",
"localRoot": "${workspaceFolder}/translator/src/translator",
"remoteRoot": "/app"
}
]
Expand All @@ -59,7 +59,7 @@
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}/translator",
"localRoot": "${workspaceFolder}/translator/src/translator",
"remoteRoot": "/app"
}
]
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ integration-tests: run
## behave-translator
.Phony: behave-translator
behave-translator: compose.override.yml
@docker compose exec -T translator /usr/local/bin/behave /app/tests/acceptance/features
@docker compose exec -T translator /app/.venv/bin/behave /app/tests/acceptance/features

## build: rebuilds all your containers or a single one if CONTAINER is specified
.Phony: build
Expand Down
6 changes: 6 additions & 0 deletions compose.override.local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ services:
replicas: 1

translator:
build:
context: .
dockerfile: ./compose/local/translator/Dockerfile
volumes:
- ./translator/tests/:/app/tests/
env_file:
Expand All @@ -117,6 +120,9 @@ services:
- DEBUG=${DEBUG:-}

translator-secondary:
build:
context: .
dockerfile: ./compose/local/translator/Dockerfile
volumes:
- ./translator/tests/:/app/tests/
env_file:
Expand Down
4 changes: 2 additions & 2 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ services:
translator:
build:
context: .
dockerfile: ./compose/local/translator/Dockerfile
dockerfile: ./compose/production/translator/Dockerfile
depends_on:
redis:
condition: service_healthy
Expand All @@ -119,7 +119,7 @@ services:
translator-secondary:
build:
context: .
dockerfile: ./compose/local/translator/Dockerfile
dockerfile: ./compose/production/translator/Dockerfile
depends_on:
redis:
condition: service_healthy
Expand Down
45 changes: 26 additions & 19 deletions compose/local/translator/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
FROM python:3.13-slim-bookworm
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim

ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED=1

RUN apt-get update \
# dependencies for building Python packages
Expand All @@ -10,24 +9,32 @@ RUN apt-get update \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& rm -rf /var/lib/apt/lists/*

# Requirements are installed here to ensure they will be cached.
COPY ./translator/requirements /requirements
RUN pip install uv
RUN uv pip install --system -r /requirements/base.txt
WORKDIR /app

RUN mkdir /app \
&& cd /app \
&& git clone -b v3.33.0 https://github.com/osrg/gobgp.git \
&& cd gobgp/api \
&& python3 -m grpc_tools.protoc -I./ --python_out=/app/ --pyi_out=/app/ --grpc_python_out=/app/ *.proto
COPY ./translator/pyproject.toml ./translator/uv.lock* ./

COPY ./translator/translator.py /app
COPY ./translator/gobgp.py /app
COPY ./translator/exceptions.py /app
COPY ./translator/shared.py /app
# Install deps only (as protobuf stuff doesn't exist yet but we need deps to setup protobufs)
RUN uv sync --locked --no-install-project

RUN chmod +x /app/translator.py
# put the venv into PATH
ENV PATH="/app/.venv/bin:$PATH"

WORKDIR /app
COPY ./translator/src /app/

# Generate protobuf files
# TODO: Make this less jank and don't do the git clone crap?
# Protos don't work well in packages so we generate them in /app/ outside the package so that bare
# `import gobgp_pb2` style imports work.
RUN git clone -b v3.33.0 https://github.com/osrg/gobgp.git gobgp \
&& cd gobgp/api \
&& python3 -m grpc_tools.protoc -I./ \
--python_out=/app/ \
--pyi_out=/app/ \
--grpc_python_out=/app/ \
*.proto \
&& cd /app && rm -rf gobgp

# Install the project itself (including the protobuff stuff)
RUN uv sync --locked

ENTRYPOINT ["/app/translator.py"]
ENTRYPOINT ["python", "-m", "translator.translator"]
41 changes: 41 additions & 0 deletions compose/production/translator/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim

ENV PYTHONUNBUFFERED=1
ENV UV_NO_DEV=1

RUN apt-get update \
# dependencies for building Python packages
&& apt-get install -y build-essential git \
# cleaning up unused files
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY ./translator/pyproject.toml ./translator/uv.lock* ./

# Install deps only (as protobuf stuff doesn't exist yet but we need deps to setup protobufs)
RUN uv sync --locked --no-install-project

# put the venv into PATH
ENV PATH="/app/.venv/bin:$PATH"

COPY ./translator/src /app/

# Generate protobuf files
# TODO: Make this less jank and don't do the git clone crap?
# Protos don't work well in packages so we generate them in /app/ outside the package so that bare
# `import gobgp_pb2` style imports work.
RUN git clone -b v3.33.0 https://github.com/osrg/gobgp.git gobgp \
&& cd gobgp/api \
&& python3 -m grpc_tools.protoc -I./ \
--python_out=/app/ \
--pyi_out=/app/ \
--grpc_python_out=/app/ \
*.proto \
&& cd /app && rm -rf gobgp

# Install the project itself (including the protobuff stuff)
RUN uv sync --locked

ENTRYPOINT ["python", "-m", "translator.translator"]
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,4 @@ django_settings_module = "config.settings.test"


[tool.uv.workspace]
exclude = ["scheduler"]
exclude = ["scheduler", "translator"]
2 changes: 1 addition & 1 deletion requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ django-environ==0.9.0 # https://github.com/joke2k/django-environ
django-eventstream==4.5.1 # https://github.com/fanout/django-eventstream
django-model-utils==4.2.0 # https://github.com/jazzband/django-model-utils
django-redis==5.3.0
django-simple-history~=3.1.1
django-simple-history>=3.4.0 # 3.4.0+ dropped the pkg_resources dependency

# Django REST Framework
djangorestframework~=3.15 # https://github.com/encode/django-rest-framework
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 4.2.28 on 2026-02-25 16:43

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("route_manager", "0034_alter_entry_originating_scram_instance_and_more"),
]

operations = [
migrations.RenameIndex(
model_name="historicalactiontype",
new_name="route_manag_history_ee6aeb_idx",
old_fields=("history_date", "id"),
),
migrations.RenameIndex(
model_name="historicalentry",
new_name="route_manag_history_0a19f0_idx",
old_fields=("history_date", "id"),
),
migrations.RenameIndex(
model_name="historicalignoreentry",
new_name="route_manag_history_6909c5_idx",
old_fields=("history_date", "id"),
),
]
21 changes: 21 additions & 0 deletions translator/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[project]
name = "translator"
dependencies = [
"aiohttp-sse-client>=0.2.1",
"behave>=1.2.6",
"coverage>=5.5",
"grpcio-tools>=1.69.0",
"websockets>=10.3",
]
requires-python = ">=3.13"
version = "0.1.0"

[dependency-groups]
dev = [
"debugpy",
"pydevd-pycharm",
]

[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
5 changes: 0 additions & 5 deletions translator/requirements/base.txt

This file was deleted.

5 changes: 0 additions & 5 deletions translator/requirements/local.txt

This file was deleted.

1 change: 1 addition & 0 deletions translator/src/translator/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Translator package for SCRAM."""
File renamed without changes.
5 changes: 3 additions & 2 deletions translator/gobgp.py → translator/src/translator/gobgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
import gobgp_pb2
import gobgp_pb2_grpc
import grpc
from exceptions import ASNError
from google.protobuf.any_pb2 import Any
from shared import asn_is_valid

from .exceptions import ASNError
from .shared import asn_is_valid

_TIMEOUT_SECONDS = 1000
DEFAULT_ASN = 65400
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Provide a location for code that we want to share between all translators."""

from exceptions import ASNError
from .exceptions import ASNError

MAX_ASN_VAL = 2**32 - 1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
from os import getenv

import websockets
from gobgp import GoBGP
from grpc import RpcError

from .gobgp import GoBGP

LOG_LEVEL = getenv("LOG_LEVEL", "INFO")
GOBGP_HOST = getenv("GOBGP_HOST", "gobgp")
GOBGP_PORT = getenv("GOBGP_PORT", "50051")
Expand All @@ -31,32 +32,12 @@
# Here we setup a debugger if this is desired. This obviously should not be run in production.
debug_mode = os.environ.get("DEBUG")
if debug_mode:

def install_deps():
"""Install necessary dependencies for debuggers.

Because of how we build translator currently, we don't have a great way to selectively
install things at build, so we just do it here! Right now this also includes base.txt,
which is unecessary, but in the future when we build a little better, it'll already be
setup.
"""
logger.info("Installing dependencies for debuggers")

import subprocess # noqa: S404, PLC0415
import sys # noqa: PLC0415

subprocess.check_call([sys.executable, "-m", "pip", "install", "-r", "/requirements/local.txt"]) # noqa: S603 TODO: add this to the container build

logger.info("Done installing dependencies for debuggers")

logger.info("Translator is set to use a debugger. Provided debug mode: %s", debug_mode)
# We have to setup the debugger appropriately for various IDEs. It'd be nice if they all used the same thing but
# sadly, we live in a fallen world.
if debug_mode == "pycharm-pydevd":
logger.info("Entering debug mode for pycharm, make sure the debug server is running in PyCharm!")

install_deps()

import pydevd_pycharm

pydevd_pycharm.settrace("host.docker.internal", port=56782, stdoutToServer=True, stderrToServer=True)
Expand All @@ -65,8 +46,6 @@ def install_deps():
elif debug_mode == "debugpy":
logger.info("Entering debug mode for debugpy (VSCode)")

install_deps()

import debugpy

debugpy.listen(("0.0.0.0", 56781)) # noqa S104 (doesn't like binding to all interfaces)
Expand Down
Loading
Loading