kopia lustrzana https://github.com/bugout-dev/moonstream
Deployment script for nodebalancer, default vars for dns route
rodzic
21eb896637
commit
416f5dd35e
|
@ -19,7 +19,6 @@ APP_DIR="${APP_DIR:-/home/ubuntu/moonstream}"
|
||||||
APP_NODES_DIR="${APP_DIR}/nodes"
|
APP_NODES_DIR="${APP_DIR}/nodes"
|
||||||
PYTHON_ENV_DIR="${PYTHON_ENV_DIR:-/home/ubuntu/moonstream-env}"
|
PYTHON_ENV_DIR="${PYTHON_ENV_DIR:-/home/ubuntu/moonstream-env}"
|
||||||
PYTHON="${PYTHON_ENV_DIR}/bin/python"
|
PYTHON="${PYTHON_ENV_DIR}/bin/python"
|
||||||
PIP="${PYTHON_ENV_DIR}/bin/pip"
|
|
||||||
SECRETS_DIR="${SECRETS_DIR:-/home/ubuntu/moonstream-secrets}"
|
SECRETS_DIR="${SECRETS_DIR:-/home/ubuntu/moonstream-secrets}"
|
||||||
PARAMETERS_ENV_PATH="${SECRETS_DIR}/app.env"
|
PARAMETERS_ENV_PATH="${SECRETS_DIR}/app.env"
|
||||||
AWS_SSM_PARAMETER_PATH="${AWS_SSM_PARAMETER_PATH:-/moonstream/prod}"
|
AWS_SSM_PARAMETER_PATH="${AWS_SSM_PARAMETER_PATH:-/moonstream/prod}"
|
||||||
|
@ -27,7 +26,6 @@ SCRIPT_DIR="$(realpath $(dirname $0))"
|
||||||
|
|
||||||
# Parameters scripts
|
# Parameters scripts
|
||||||
PARAMETERS_SCRIPT="${SCRIPT_DIR}/parameters.py"
|
PARAMETERS_SCRIPT="${SCRIPT_DIR}/parameters.py"
|
||||||
CHECKENV_PARAMETERS_SCRIPT="${SCRIPT_DIR}/parameters.bash"
|
|
||||||
CHECKENV_NODES_CONNECTIONS_SCRIPT="${SCRIPT_DIR}/nodes-connections.bash"
|
CHECKENV_NODES_CONNECTIONS_SCRIPT="${SCRIPT_DIR}/nodes-connections.bash"
|
||||||
|
|
||||||
# Service file
|
# Service file
|
||||||
|
@ -35,6 +33,27 @@ NODE_BALANCER_SERVICE_FILE="node-balancer.service"
|
||||||
|
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo -e "${PREFIX_INFO} Retrieving deployment parameters"
|
||||||
|
mkdir -p "${SECRETS_DIR}"
|
||||||
|
AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION}" "${PYTHON}" "${PARAMETERS_SCRIPT}" extract -p "${AWS_SSM_PARAMETER_PATH}" -o "${PARAMETERS_ENV_PATH}"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo -e "${PREFIX_INFO} Install checkenv"
|
||||||
|
HOME=/root /usr/local/go/bin/go install github.com/bugout-dev/checkenv@latest
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo -e "${PREFIX_INFO} Retrieving addition deployment parameters"
|
||||||
|
HOME=/root AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION}" $HOME/go/bin/checkenv show aws_ssm+Product:moonstream >> "${PARAMETERS_ENV_PATH}"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
echo -e "${PREFIX_INFO} Updating nodes connection parameters"
|
||||||
|
bash "${CHECKENV_NODES_CONNECTIONS_SCRIPT}" -v -f "${PARAMETERS_ENV_PATH}"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo
|
echo
|
||||||
echo -e "${PREFIX_INFO} Building executable load balancer for nodes script with Go"
|
echo -e "${PREFIX_INFO} Building executable load balancer for nodes script with Go"
|
||||||
|
@ -43,22 +62,6 @@ cd "${APP_NODES_DIR}/node_balancer"
|
||||||
HOME=/root /usr/local/go/bin/go build -o "${APP_NODES_DIR}/node_balancer/nodebalancer" "${APP_NODES_DIR}/node_balancer/main.go"
|
HOME=/root /usr/local/go/bin/go build -o "${APP_NODES_DIR}/node_balancer/nodebalancer" "${APP_NODES_DIR}/node_balancer/main.go"
|
||||||
cd "${EXEC_DIR}"
|
cd "${EXEC_DIR}"
|
||||||
|
|
||||||
echo
|
|
||||||
echo
|
|
||||||
echo -e "${PREFIX_INFO} Retrieving deployment parameters"
|
|
||||||
mkdir -p "${SECRETS_DIR}"
|
|
||||||
AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION}" "${PYTHON}" "${PARAMETERS_SCRIPT}" extract -p "${AWS_SSM_PARAMETER_PATH}" -o "${PARAMETERS_ENV_PATH}"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo
|
|
||||||
echo -e "${PREFIX_INFO} Retrieving addition deployment parameters"
|
|
||||||
bash "${CHECKENV_PARAMETERS_SCRIPT}" -v -p "moonstream" -o "${PARAMETERS_ENV_PATH}"
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo
|
|
||||||
echo -e "${PREFIX_INFO} Updating nodes connection parameters"
|
|
||||||
bash "${CHECKENV_NODES_CONNECTIONS_SCRIPT}" -v -f "${PARAMETERS_ENV_PATH}"
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo
|
echo
|
||||||
echo -e "${PREFIX_INFO} Replacing existing load balancer for nodes service definition with ${NODE_BALANCER_SERVICE_FILE}"
|
echo -e "${PREFIX_INFO} Replacing existing load balancer for nodes service definition with ${NODE_BALANCER_SERVICE_FILE}"
|
||||||
|
|
|
@ -11,7 +11,7 @@ WorkingDirectory=/home/ubuntu/moonstream/nodes/node_balancer
|
||||||
EnvironmentFile=/home/ubuntu/moonstream-secrets/app.env
|
EnvironmentFile=/home/ubuntu/moonstream-secrets/app.env
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=15s
|
RestartSec=15s
|
||||||
ExecStart=/home/ubuntu/moonstream/nodes/node_balancer/nodebalancer -host 0.0.0.0 -port 8544 -healthcheck
|
ExecStart=/home/ubuntu/moonstream/nodes/node_balancer/nodebalancer -host "$(ec2metadata --local-ipv4)" -port 8544 -healthcheck
|
||||||
SyslogIdentifier=node-balancer
|
SyslogIdentifier=node-balancer
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
"""
|
||||||
|
Collect secrets from AWS SSM Parameter Store and output as environment variable exports.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
from dataclasses import dataclass
|
||||||
|
import sys
|
||||||
|
from typing import Any, Dict, Iterable, List, Optional
|
||||||
|
|
||||||
|
import boto3
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class EnvironmentVariable:
|
||||||
|
name: str
|
||||||
|
value: str
|
||||||
|
|
||||||
|
|
||||||
|
def get_parameters(path: str) -> List[Dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
Retrieve parameters from AWS SSM Parameter Store. Decrypts any encrypted parameters.
|
||||||
|
|
||||||
|
Relies on the appropriate environment variables to authenticate against AWS:
|
||||||
|
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
|
||||||
|
"""
|
||||||
|
ssm = boto3.client("ssm")
|
||||||
|
next_token: Optional[bool] = True
|
||||||
|
parameters: List[Dict[str, Any]] = []
|
||||||
|
while next_token is not None:
|
||||||
|
kwargs = {"Path": path, "Recursive": False, "WithDecryption": True}
|
||||||
|
if next_token is not True:
|
||||||
|
kwargs["NextToken"] = next_token
|
||||||
|
response = ssm.get_parameters_by_path(**kwargs)
|
||||||
|
new_parameters = response.get("Parameters", [])
|
||||||
|
parameters.extend(new_parameters)
|
||||||
|
next_token = response.get("NextToken")
|
||||||
|
|
||||||
|
return parameters
|
||||||
|
|
||||||
|
|
||||||
|
def parameter_to_env(parameter_object: Dict[str, Any]) -> EnvironmentVariable:
|
||||||
|
"""
|
||||||
|
Transforms parameters returned by the AWS SSM API into EnvironmentVariables.
|
||||||
|
"""
|
||||||
|
parameter_path = parameter_object.get("Name")
|
||||||
|
if parameter_path is None:
|
||||||
|
raise ValueError('Did not find "Name" in parameter object')
|
||||||
|
name = parameter_path.split("/")[-1].upper()
|
||||||
|
|
||||||
|
value = parameter_object.get("Value")
|
||||||
|
if value is None:
|
||||||
|
raise ValueError('Did not find "Value" in parameter object')
|
||||||
|
|
||||||
|
return EnvironmentVariable(name, value)
|
||||||
|
|
||||||
|
|
||||||
|
def env_string(env_vars: Iterable[EnvironmentVariable], with_export: bool) -> str:
|
||||||
|
"""
|
||||||
|
Produces a string which, when executed in a shell, exports the desired environment variables as
|
||||||
|
specified by env_vars.
|
||||||
|
"""
|
||||||
|
prefix = "export " if with_export else ""
|
||||||
|
return "\n".join([f'{prefix}{var.name}="{var.value}"' for var in env_vars])
|
||||||
|
|
||||||
|
|
||||||
|
def extract_handler(args: argparse.Namespace) -> None:
|
||||||
|
"""
|
||||||
|
Save environment variables to file.
|
||||||
|
"""
|
||||||
|
result = env_string(map(parameter_to_env, get_parameters(args.path)), args.export)
|
||||||
|
with args.outfile as ofp:
|
||||||
|
print(result, file=ofp)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Materialize environment variables from AWS SSM Parameter Store"
|
||||||
|
)
|
||||||
|
parser.set_defaults(func=lambda _: parser.print_help())
|
||||||
|
subcommands = parser.add_subparsers(description="Parameters commands")
|
||||||
|
|
||||||
|
parser_extract = subcommands.add_parser(
|
||||||
|
"extract", description="Parameters extract commands"
|
||||||
|
)
|
||||||
|
parser_extract.set_defaults(func=lambda _: parser_extract.print_help())
|
||||||
|
parser_extract.add_argument(
|
||||||
|
"-o", "--outfile", type=argparse.FileType("w"), default=sys.stdout
|
||||||
|
)
|
||||||
|
parser_extract.add_argument(
|
||||||
|
"--export",
|
||||||
|
action="store_true",
|
||||||
|
help="Set to output environment strings with export statements",
|
||||||
|
)
|
||||||
|
parser_extract.add_argument(
|
||||||
|
"-p",
|
||||||
|
"--path",
|
||||||
|
default=None,
|
||||||
|
help="SSM path from which to pull environment variables (pull is NOT recursive)",
|
||||||
|
)
|
||||||
|
parser_extract.set_defaults(func=extract_handler)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
args.func(args)
|
|
@ -21,9 +21,9 @@ func pingRoute(w http.ResponseWriter, r *http.Request) {
|
||||||
func lbHandler(w http.ResponseWriter, r *http.Request) {
|
func lbHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var blockchain string
|
var blockchain string
|
||||||
switch {
|
switch {
|
||||||
case strings.HasPrefix(r.URL.Path, "/lb/ethereum"):
|
case strings.HasPrefix(r.URL.Path, "/nb/ethereum"):
|
||||||
blockchain = "ethereum"
|
blockchain = "ethereum"
|
||||||
case strings.HasPrefix(r.URL.Path, "/lb/polygon"):
|
case strings.HasPrefix(r.URL.Path, "/nb/polygon"):
|
||||||
blockchain = "polygon"
|
blockchain = "polygon"
|
||||||
default:
|
default:
|
||||||
http.Error(w, fmt.Sprintf("Unacceptable blockchain provided %s", blockchain), http.StatusBadRequest)
|
http.Error(w, fmt.Sprintf("Unacceptable blockchain provided %s", blockchain), http.StatusBadRequest)
|
||||||
|
@ -41,11 +41,11 @@ func lbHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
r.Header.Add("X-Origin-Path", r.URL.Path)
|
r.Header.Add("X-Origin-Path", r.URL.Path)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case strings.HasPrefix(r.URL.Path, fmt.Sprintf("/lb/%s/ping", blockchain)):
|
case strings.HasPrefix(r.URL.Path, fmt.Sprintf("/nb/%s/ping", blockchain)):
|
||||||
r.URL.Path = "/ping"
|
r.URL.Path = "/ping"
|
||||||
peer.StatusReverseProxy.ServeHTTP(w, r)
|
peer.StatusReverseProxy.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
case strings.HasPrefix(r.URL.Path, fmt.Sprintf("/lb/%s/rpc", blockchain)):
|
case strings.HasPrefix(r.URL.Path, fmt.Sprintf("/nb/%s/rpc", blockchain)):
|
||||||
r.URL.Path = "/"
|
r.URL.Path = "/"
|
||||||
peer.GethReverseProxy.ServeHTTP(w, r)
|
peer.GethReverseProxy.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
|
|
|
@ -36,11 +36,29 @@ var MOONSTREAM_NODE_POLYGON_B_IPC_ADDR = os.Getenv("MOONSTREAM_NODE_POLYGON_B_IP
|
||||||
var MOONSTREAM_NODE_POLYGON_IPC_PORT = os.Getenv("MOONSTREAM_NODE_POLYGON_IPC_PORT")
|
var MOONSTREAM_NODE_POLYGON_IPC_PORT = os.Getenv("MOONSTREAM_NODE_POLYGON_IPC_PORT")
|
||||||
var MOONSTREAM_NODES_SERVER_PORT = os.Getenv("MOONSTREAM_NODES_SERVER_PORT")
|
var MOONSTREAM_NODES_SERVER_PORT = os.Getenv("MOONSTREAM_NODES_SERVER_PORT")
|
||||||
|
|
||||||
// Return list of NodeConfig structures
|
func checkEnvVarSet() {
|
||||||
func (nc *NodeConfigList) InitNodeConfigList() {
|
if MOONSTREAM_NODE_ETHEREUM_A_IPC_ADDR == "" {
|
||||||
if MOONSTREAM_NODES_SERVER_PORT == "" || MOONSTREAM_NODE_ETHEREUM_A_IPC_ADDR == "" || MOONSTREAM_NODE_ETHEREUM_B_IPC_ADDR == "" || MOONSTREAM_NODE_ETHEREUM_IPC_PORT == "" || MOONSTREAM_NODE_POLYGON_A_IPC_ADDR == "" || MOONSTREAM_NODE_POLYGON_B_IPC_ADDR == "" || MOONSTREAM_NODE_POLYGON_IPC_PORT == "" {
|
MOONSTREAM_NODE_ETHEREUM_A_IPC_ADDR = "a.ethereum.moonstream.internal"
|
||||||
|
}
|
||||||
|
if MOONSTREAM_NODE_ETHEREUM_B_IPC_ADDR == "" {
|
||||||
|
MOONSTREAM_NODE_ETHEREUM_B_IPC_ADDR = "b.ethereum.moonstream.internal"
|
||||||
|
}
|
||||||
|
|
||||||
|
if MOONSTREAM_NODE_POLYGON_A_IPC_ADDR == "" {
|
||||||
|
MOONSTREAM_NODE_POLYGON_A_IPC_ADDR = "a.polygon.moonstream.internal"
|
||||||
|
}
|
||||||
|
if MOONSTREAM_NODE_POLYGON_B_IPC_ADDR == "" {
|
||||||
|
MOONSTREAM_NODE_POLYGON_B_IPC_ADDR = "b.polygon.moonstream.internal"
|
||||||
|
}
|
||||||
|
|
||||||
|
if MOONSTREAM_NODES_SERVER_PORT == "" || MOONSTREAM_NODE_ETHEREUM_IPC_PORT == "" || MOONSTREAM_NODE_POLYGON_IPC_PORT == "" {
|
||||||
log.Fatal("Some of environment variables not set")
|
log.Fatal("Some of environment variables not set")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return list of NodeConfig structures
|
||||||
|
func (nc *NodeConfigList) InitNodeConfigList() {
|
||||||
|
checkEnvVarSet()
|
||||||
|
|
||||||
// Define available blockchain nodes
|
// Define available blockchain nodes
|
||||||
blockchainConfigList := make([]BlockchainConfig, 0, 2)
|
blockchainConfigList := make([]BlockchainConfig, 0, 2)
|
||||||
|
|
Ładowanie…
Reference in New Issue