mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
111 lines
3.3 KiB
Python
Executable File
111 lines
3.3 KiB
Python
Executable File
#!/usr/bin/python3
|
|
|
|
import json # noqa
|
|
import re
|
|
from collections.abc import Mapping
|
|
from dataclasses import dataclass
|
|
from typing import Any
|
|
|
|
import click
|
|
|
|
"""Convenience script for setting up silos in a dev environment.
|
|
|
|
Prints devserver commands with the necessary environment variables.
|
|
"""
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class RegionConfig:
|
|
number: int
|
|
port: int
|
|
api_token: str
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
return f"devregion{self.number}"
|
|
|
|
@property
|
|
def bind(self) -> str:
|
|
return f"localhost:{self.port}"
|
|
|
|
def get_env_repr(self) -> Mapping[str, Any]:
|
|
return {
|
|
"name": self.name,
|
|
"id": self.number,
|
|
"address": f"http://{self.bind}/",
|
|
"category": "MULTI_TENANT",
|
|
"api_token": self.api_token,
|
|
}
|
|
|
|
|
|
def format_env_vars(env_vars: Mapping[str, str]) -> str:
|
|
def format_env_var(name: str, value: str) -> str:
|
|
value = re.sub("([\"$'\\\\])", "\\\\\\1", value) # https://xkcd.com/1638/
|
|
return f'{name}="{value}"'
|
|
|
|
return " ".join(format_env_var(name, value) for (name, value) in env_vars.items())
|
|
|
|
|
|
@click.command()
|
|
@click.option(
|
|
"--api-token",
|
|
type=str,
|
|
required=True,
|
|
help=(
|
|
"""An API token to authorize RPC requests between servers.
|
|
|
|
At the time this script is being written, the authentication system for RPCs
|
|
hasn't been developed. An API token is needed to ensure that an incoming
|
|
request hits a REST endpoint, but it doesn't need to have any particular
|
|
permission scope.
|
|
|
|
Because dev instances of the control and region silo will presumably share a
|
|
single database, this script assumes that the same API token will work for both.
|
|
"""
|
|
),
|
|
)
|
|
@click.option("--region-count", type=int, default=2, help="Number of region silos")
|
|
@click.option(
|
|
"--control-port",
|
|
type=int,
|
|
default=8000,
|
|
help=(
|
|
"""Port on which to bind the control silo.
|
|
|
|
Region silos will be bound on ascending numbers after this one in steps of 10.
|
|
"""
|
|
),
|
|
)
|
|
def main(api_token: str, region_count: int, control_port: int) -> None:
|
|
sender_credentials = {
|
|
"is_allowed": True,
|
|
"control_silo_api_token": api_token,
|
|
"control_silo_address": f"http://localhost:{control_port}/",
|
|
}
|
|
|
|
regions = [
|
|
RegionConfig(n, control_port + 10 * n, api_token) for n in range(1, region_count + 1)
|
|
]
|
|
region_config = json.dumps([r.get_env_repr() for r in regions])
|
|
|
|
common_env_vars = {}
|
|
common_env_vars["SENTRY_REGION_CONFIG"] = region_config
|
|
common_env_vars["SENTRY_DEV_HYBRID_CLOUD_RPC_SENDER"] = json.dumps(sender_credentials)
|
|
|
|
control_env_vars = common_env_vars.copy()
|
|
control_env_vars["SENTRY_SILO_MODE"] = "CONTROL"
|
|
control_env_vars["SENTRY_DEVSERVER_BIND"] = f"localhost:{control_port}"
|
|
|
|
print(f"# Control silo\n{format_env_vars(control_env_vars)} sentry devserver") # noqa
|
|
|
|
for region in regions:
|
|
region_env_vars = common_env_vars.copy()
|
|
region_env_vars["SENTRY_SILO_MODE"] = "REGION"
|
|
region_env_vars["SENTRY_REGION"] = region.name
|
|
region_env_vars["SENTRY_DEVSERVER_BIND"] = region.bind
|
|
|
|
print(f"\n# {region.name}\n{format_env_vars(region_env_vars)} sentry devserver") # noqa
|
|
|
|
|
|
main()
|