Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
evilsocket committed Nov 19, 2024
2 parents acd1e05 + 8e5004b commit 84fc9ba
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 4 deletions.
2 changes: 1 addition & 1 deletion dreadnode_cli/agent/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def init(

print()
project_name = Prompt.ask("Project name?", default=name or directory.name)
template = Template(Prompt.ask("Template?", choices=[t.value for t in Template], default=template))
template = Template(Prompt.ask("Template?", choices=[t.value for t in Template], default=template.value))

directory.mkdir(exist_ok=True)

Expand Down
27 changes: 24 additions & 3 deletions dreadnode_cli/agent/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,44 @@
from rich.text import Text

from dreadnode_cli.config import ServerConfig
from dreadnode_cli.defaults import DOCKER_REGISTRY_SUBDOMAIN, PLATFORM_BASE_DOMAIN
from dreadnode_cli.defaults import (
DOCKER_REGISTRY_IMAGE_TAG,
DOCKER_REGISTRY_LOCAL_PORT,
DOCKER_REGISTRY_SUBDOMAIN,
PLATFORM_BASE_DOMAIN,
)

try:
client = docker.from_env()
except docker.errors.DockerException:
client = None


def get_local_registry_port() -> int:
if client is None:
raise Exception("Docker not available")

for container in client.containers.list():
if DOCKER_REGISTRY_IMAGE_TAG in container.image.tags:
ports = container.attrs["NetworkSettings"]["Ports"]
assert len(ports) == 1
for _container_port, port_bindings in ports.items():
if port_bindings:
for binding in port_bindings:
return int(binding["HostPort"])

# fallback to the default port if we can't find the running container
return DOCKER_REGISTRY_LOCAL_PORT


def get_registry(config: ServerConfig) -> str:
# fail early if docker is not available
if client is None:
raise Exception("Docker not available")

# localhost is a special case
# TODO: Can we get this port dynamically?
if "localhost" in config.url or "127.0.0.1" in config.url:
return "localhost:5005"
return f"localhost:{get_local_registry_port()}"

prefix = ""
if "staging-" in config.url:
Expand Down
31 changes: 31 additions & 0 deletions dreadnode_cli/agent/tests/test_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,23 @@

import dreadnode_cli.agent.docker as docker
from dreadnode_cli.config import ServerConfig
from dreadnode_cli.defaults import DOCKER_REGISTRY_IMAGE_TAG


class MockImage:
def __init__(self, tags: list[str] | None = None) -> None:
self.tags = tags or []

def tag(self, *args: t.Any, **kwargs: t.Any) -> None:
pass


class MockContainer:
def __init__(self, image_tags: list[str], attrs: dict[str, t.Any]) -> None:
self.image = MockImage(image_tags)
self.attrs = attrs


class MockDockerClient:
"""Simple mock Docker client for testing."""

Expand All @@ -37,6 +47,13 @@ class images:
def get(id: str) -> MockImage:
return MockImage()

class containers:
containers: list[MockContainer] = []

@staticmethod
def list(*args: t.Any, **kwargs: t.Any) -> list[MockContainer]:
return MockDockerClient.containers.containers


def _create_test_server_config(url: str = "https://crucible.dreadnode.io") -> ServerConfig:
return ServerConfig(
Expand Down Expand Up @@ -116,6 +133,20 @@ def test_get_registry() -> None:
assert docker.get_registry(config) == "localhost:5005"


def test_get_local_registry_port_with_running_registry_container() -> None:
with pytest.MonkeyPatch.context() as mp:
mp.setattr(
docker.client.containers,
"containers",
[
MockContainer(
[DOCKER_REGISTRY_IMAGE_TAG], {"NetworkSettings": {"Ports": {"5000/tcp": [{"HostPort": "12345"}]}}}
)
],
)
assert docker.get_registry(_create_test_server_config("http://localhost:8000")) == "localhost:12345"


def test_get_registry_without_schema() -> None:
# Test without schema
config = _create_test_server_config("crucible.dreadnode.io")
Expand Down
5 changes: 5 additions & 0 deletions dreadnode_cli/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
PLATFORM_BASE_URL = os.getenv("DREADNODE_SERVER", f"https://crucible.{PLATFORM_BASE_DOMAIN}")
# default docker registry subdomain
DOCKER_REGISTRY_SUBDOMAIN = "registry"
# default docker registry local port
DOCKER_REGISTRY_LOCAL_PORT = 5005
# default docker registry image tag
DOCKER_REGISTRY_IMAGE_TAG = "registry"

# path to the user configuration file
USER_CONFIG_PATH = pathlib.Path(
# allow overriding the user config file via env variable
Expand Down

0 comments on commit 84fc9ba

Please sign in to comment.