Skip to content

Commit

Permalink
add configs and debug options for aws-replicator proxy container (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
whummer authored Feb 12, 2024
1 parent 4d30218 commit 58d07a1
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 5 deletions.
10 changes: 10 additions & 0 deletions aws-replicator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ make_bucket: test123

A more comprehensive sample, involving local Lambda functions combined with remote SQS queues and S3 buckets, can be found in the `example` folder of this repo.

### Configuration

In addition to the proxy services configuration shown above, the following configs can be used to customize the behavior of the extension itself (simply pass them as environment variables to the main LocalStack container):
* `REPLICATOR_CLEANUP_PROXY_CONTAINERS`: whether to clean up (remove) the proxy Docker containers once they shut down (default `1`). Can be set to `0` to help debug issues, e.g., if a proxy container starts up and exits immediately.
* `REPLICATOR_LOCALSTACK_HOST`: the target host to use when the proxy container connects to the LocalStack main container (automatically determined by default)
* `REPLICATOR_PROXY_DOCKER_FLAGS`: additional flags that should be passed when creating the proxy Docker containers

## Resource Replicator CLI

The figure below illustrates how the extension can be used to replicate the state, e.g., an SQS queue and the messages contained in it, from AWS into your LocalStack instance.
Expand Down Expand Up @@ -143,6 +150,9 @@ localstack extensions install "git+https://github.com/localstack/localstack-exte

## Change Log

* `0.1.10`: Add `REPLICATOR_PROXY_DOCKER_FLAGS` option to pass custom flags to proxy Docker containers
* `0.1.9`: Enhance proxy networking and add `REPLICATOR_LOCALSTACK_HOST` config option
* `0.1.8`: Add `REPLICATOR_CLEANUP_PROXY_CONTAINERS` option to skip removing proxy containers for debugging
* `0.1.7`: Add rolo dependency to tests
* `0.1.6`: Adjust config to support `LOCALSTACK_AUTH_TOKEN` in addition to legacy API keys
* `0.1.5`: Minor fix to accommodate recent upstream changes
Expand Down
16 changes: 13 additions & 3 deletions aws-replicator/aws_replicator/client/auth_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@
from localstack.utils.docker_utils import DOCKER_CLIENT, reserve_available_container_port
from localstack.utils.files import new_tmp_file, save_file
from localstack.utils.functions import run_safe
from localstack.utils.net import get_free_tcp_port
from localstack.utils.net import get_docker_host_from_container, get_free_tcp_port
from localstack.utils.server.http2_server import run_server
from localstack.utils.serving import Server
from localstack.utils.strings import short_uid, to_bytes, to_str, truncate
from localstack_ext.bootstrap.licensingv2 import ENV_LOCALSTACK_API_KEY, ENV_LOCALSTACK_AUTH_TOKEN
from requests import Response

from aws_replicator import config as repl_config
from aws_replicator.client.utils import truncate_content
from aws_replicator.config import HANDLER_PATH_PROXIES
from aws_replicator.shared.models import AddProxyRequest, ProxyConfig
Expand Down Expand Up @@ -142,6 +143,7 @@ def register_in_instance(self):
raise Exception("Proxy currently not running")
url = f"{external_service_url()}{HANDLER_PATH_PROXIES}"
data = AddProxyRequest(port=port, config=self.config)
LOG.debug("Registering new proxy in main container via: %s", url)
try:
response = requests.post(url, json=data)
assert response.ok
Expand Down Expand Up @@ -313,6 +315,7 @@ def start_aws_auth_proxy_in_container(
entrypoint="",
command=["bash", "-c", f"touch {CONTAINER_LOG_FILE}; tail -f {CONTAINER_LOG_FILE}"],
ports=ports,
additional_flags=repl_config.PROXY_DOCKER_FLAGS,
)

# start container in detached mode
Expand Down Expand Up @@ -346,7 +349,13 @@ def start_aws_auth_proxy_in_container(
]
env_vars = env_vars or os.environ
env_vars = select_attributes(dict(env_vars), env_var_names)
env_vars["LOCALSTACK_HOST"] = "host.docker.internal"

# Determine target hostname - we make the host configurable via PROXY_LOCALSTACK_HOST,
# and if not configured then use get_docker_host_from_container() as a fallback.
target_host = repl_config.PROXY_LOCALSTACK_HOST
if not repl_config.PROXY_LOCALSTACK_HOST:
target_host = get_docker_host_from_container()
env_vars["LOCALSTACK_HOST"] = target_host

try:
print("Proxy container is ready.")
Expand Down Expand Up @@ -379,7 +388,8 @@ def start_aws_auth_proxy_in_container(
LOG.info("Error in called process - output: %s\n%s", e.stdout, e.stderr)
finally:
try:
DOCKER_CLIENT.remove_container(container_name, force=True)
if repl_config.CLEANUP_PROXY_CONTAINERS:
DOCKER_CLIENT.remove_container(container_name, force=True)
except Exception as e:
if "already in progress" not in str(e):
raise
12 changes: 12 additions & 0 deletions aws-replicator/aws_replicator/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import os

from localstack.config import is_env_not_false
from localstack.constants import INTERNAL_RESOURCE_PATH

# handler path within the internal /_localstack endpoint
HANDLER_PATH_REPLICATE = f"{INTERNAL_RESOURCE_PATH}/aws/replicate"
HANDLER_PATH_PROXIES = f"{INTERNAL_RESOURCE_PATH}/aws/proxies"

# whether to clean up proxy containers (set to "0" to investigate startup issues)
CLEANUP_PROXY_CONTAINERS = is_env_not_false("REPLICATOR_CLEANUP_PROXY_CONTAINERS")

# additional Docker flags to pass to the proxy containers
PROXY_DOCKER_FLAGS = (os.getenv("REPLICATOR_PROXY_DOCKER_FLAGS") or "").strip()

# LS hostname to use for proxy Docker container to register itself at the main container
PROXY_LOCALSTACK_HOST = (os.getenv("REPLICATOR_LOCALSTACK_HOST") or "").strip()
5 changes: 4 additions & 1 deletion aws-replicator/aws_replicator/server/request_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from localstack.utils.strings import to_str
from localstack.utils.threads import start_worker_thread

from aws_replicator import config as repl_config
from aws_replicator.client.auth_proxy import (
CONTAINER_CONFIG_FILE,
CONTAINER_NAME_PREFIX,
Expand Down Expand Up @@ -145,7 +146,9 @@ def get_proxy_containers() -> List[Dict]:
def stop_proxy_containers():
for container in get_proxy_containers():
try:
DOCKER_CLIENT.remove_container(container["name"], force=True)
DOCKER_CLIENT.stop_container(container["name"])
if repl_config.CLEANUP_PROXY_CONTAINERS:
DOCKER_CLIENT.remove_container(container["name"], force=True)
except Exception as e:
LOG.debug("Unable to remove container %s: %s", container["name"], e)

Expand Down
2 changes: 1 addition & 1 deletion aws-replicator/setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = localstack-extension-aws-replicator
version = 0.1.7
version = 0.1.10
summary = LocalStack Extension: AWS replicator
description = Replicate AWS resources into your LocalStack instance
long_description = file: README.md
Expand Down

0 comments on commit 58d07a1

Please sign in to comment.