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"
 | 
			
		||||
PYTHON_ENV_DIR="${PYTHON_ENV_DIR:-/home/ubuntu/moonstream-env}"
 | 
			
		||||
PYTHON="${PYTHON_ENV_DIR}/bin/python"
 | 
			
		||||
PIP="${PYTHON_ENV_DIR}/bin/pip"
 | 
			
		||||
SECRETS_DIR="${SECRETS_DIR:-/home/ubuntu/moonstream-secrets}"
 | 
			
		||||
PARAMETERS_ENV_PATH="${SECRETS_DIR}/app.env"
 | 
			
		||||
AWS_SSM_PARAMETER_PATH="${AWS_SSM_PARAMETER_PATH:-/moonstream/prod}"
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +26,6 @@ SCRIPT_DIR="$(realpath $(dirname $0))"
 | 
			
		|||
 | 
			
		||||
# Parameters scripts
 | 
			
		||||
PARAMETERS_SCRIPT="${SCRIPT_DIR}/parameters.py"
 | 
			
		||||
CHECKENV_PARAMETERS_SCRIPT="${SCRIPT_DIR}/parameters.bash"
 | 
			
		||||
CHECKENV_NODES_CONNECTIONS_SCRIPT="${SCRIPT_DIR}/nodes-connections.bash"
 | 
			
		||||
 | 
			
		||||
# Service file
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +33,27 @@ NODE_BALANCER_SERVICE_FILE="node-balancer.service"
 | 
			
		|||
 | 
			
		||||
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 -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"
 | 
			
		||||
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 -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
 | 
			
		||||
Restart=on-failure
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
[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) {
 | 
			
		||||
	var blockchain string
 | 
			
		||||
	switch {
 | 
			
		||||
	case strings.HasPrefix(r.URL.Path, "/lb/ethereum"):
 | 
			
		||||
	case strings.HasPrefix(r.URL.Path, "/nb/ethereum"):
 | 
			
		||||
		blockchain = "ethereum"
 | 
			
		||||
	case strings.HasPrefix(r.URL.Path, "/lb/polygon"):
 | 
			
		||||
	case strings.HasPrefix(r.URL.Path, "/nb/polygon"):
 | 
			
		||||
		blockchain = "polygon"
 | 
			
		||||
	default:
 | 
			
		||||
		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)
 | 
			
		||||
 | 
			
		||||
	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"
 | 
			
		||||
		peer.StatusReverseProxy.ServeHTTP(w, r)
 | 
			
		||||
		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 = "/"
 | 
			
		||||
		peer.GethReverseProxy.ServeHTTP(w, r)
 | 
			
		||||
		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_NODES_SERVER_PORT = os.Getenv("MOONSTREAM_NODES_SERVER_PORT")
 | 
			
		||||
 | 
			
		||||
// Return list of NodeConfig structures
 | 
			
		||||
func (nc *NodeConfigList) InitNodeConfigList() {
 | 
			
		||||
	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 == "" {
 | 
			
		||||
func checkEnvVarSet() {
 | 
			
		||||
	if MOONSTREAM_NODE_ETHEREUM_A_IPC_ADDR == "" {
 | 
			
		||||
		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")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Return list of NodeConfig structures
 | 
			
		||||
func (nc *NodeConfigList) InitNodeConfigList() {
 | 
			
		||||
	checkEnvVarSet()
 | 
			
		||||
 | 
			
		||||
	// Define available blockchain nodes
 | 
			
		||||
	blockchainConfigList := make([]BlockchainConfig, 0, 2)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue