diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3bbb42e --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +app_name := ucentral-cgw + +all: output/bin/${app_name} + @echo "uCentral CGW build app done" + +clean: + rm -rf ./output/ + +run: output/bin/${app_name} + ./run_cgw.sh + +# TODO: replace this find with actual --out-dir for cargo +# however, as of now it's an unstable flag, hence gotta do it +# in a bash-ish way. +output/bin/${app_name}: + @rm output/bin/${app_name} || true; + @mkdir output/bin || true; + @cargo build --target-dir ./output &&\ + find ./output/ -name "${app_name}" -exec cp {} ./output/bin/ -f \; diff --git a/README.md b/README.md index 035453e..1f6d22d 100644 --- a/README.md +++ b/README.md @@ -1 +1,62 @@ -# openlan-cgw +# openlan-cgw - What is it? +Cloud GateWay (CGW) is a Rust-based implementation of the uCentral-protocol-based Gateway layer (link). +CGW, like OWGW, manages device (Access Points and OpenLan switches) that implement and abide the uCentral protocol. +The main reasoning behind a new implementation of the GW is the horizontal scalability. +# Dependencies (runtime) +CGW requires a set of tools and services to operate and function. Some of them are embedded into the application itself and require no external utilities, +while others are required to be running for the CGW to operate. +## gRPC +CGW utilizes gRPC to communicate with other CGW instances (referred to as Shards). This functionality does not depend on some external thirdparty services. +## Kafka +CGW uses Kafka as a main North-Bound API layer for communication with NB services. CnC topic is used for commands and requests handling, CnC_Res is used to send replies/results back (CGW reads CnC and writes into CnC_Res). +## PSQL +Application utilizes relational DB (PSQL) to store registered Infrastructure Groups as well as registered Infrastructures. +## Redis +fast in-memory DB that CGW uses to store all needed runtime information (InfraGroup assigned CGW id, remote CGW info - IP, gRPC port etc) +# Building +Before building CGW you must put cert+key pair into the src folder, named *localhost.crt* and *localhost.key*. +These steps are not part of the build, and crt+key pair should exist upon running the build command. +Key and certificate will be used by the CGW internally to validate incoming WSS connections. +```console +$ make all +``` +The output (CGW binaries) is then put into the ./output directory. +# Running +The following script can be used to launch the CGW app +```console +$ make run +``` +Running application with default arguments might not be desired behavior. +And thus the run script utilizes the following list of *enviroment* variables that you can define before running it to alternate behavior of the app. +The following list is a list of enviroment variables you can define to configure cgw-app behavior in certain way: +``` +CGW_GRPC_IP - IP to bind gRPC server to (listens for gRPC requests from remote CGWs) +CGW_GRPC_PORT - PORT to bind gRPC server to +CGW_WSS_IP - IP to bind websocket server to (listens for incoming WSS connections from underlying devices - infrastructures) +CGW_WSS_PORT - PORT to bind WSS server to +CGW_KAFKA_IP - IP of remote KAFKA server to connect to (NB API) +CGW_KAFKA_PORT - PORT of remote KAFKA server to connect to +CGW_DB_IP - IP of remote database server to connect to +CGW_DB_PORT - PORT of remote database server to connect to +CGW_REDIS_DB_IP - IP of remote redis-db server to connect to +CGW_REDIS_DB_PORT - PORT of remote redis-db server to connect to +CGW_LOG_LEVEL - log level to start CGW application with (debug, info) +``` + +Example of properly configured list of env variables to start CGW: +```console +$ export | grep CGW +declare -x CGW_DB_IP="172.20.10.136" # PSQL server is at xxx.136 +declare -x CGW_DB_PORT="5432" +declare -x CGW_GRPC_IP="172.20.10.153" # local default subnet is 172.20.10.0/24 +declare -x CGW_GRPC_PORT="50051" +declare -x CGW_ID="1" +declare -x CGW_KAFKA_IP="172.20.10.136" # kafka is located at the xxx.136 host +declare -x CGW_KAFKA_PORT="9092" +declare -x CGW_LOG_LEVEL="debug" +declare -x CGW_REDIS_DB_IP="172.20.10.136" # redis server can be found at the xxx.136 host +declare -x CGW_WSS_IP="0.0.0.0" # accept WSS connections at all interfaces / subnets +declare -x CGW_WSS_PORT="15002" +``` +# Certificates + diff --git a/run_cgw.sh b/run_cgw.sh new file mode 100755 index 0000000..2b9f35a --- /dev/null +++ b/run_cgw.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# By default - use default subnet's SRC ip to listen to gRPC requests +DEFAULT_SRC_IP=`ip route get 1 | grep -o "src\ .*\ " | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"` +DEFAULT_GRPC_PORT=50051 + +# By default - listen to all interfaces +DEFAULT_WSS_IP="0.0.0.0" +DEFAULT_WSS_PORT=15002 + +DEFAULT_KAFKA_IP="127.0.0.1" +DEFAULT_KAFKA_PORT=9092 + +DEFAULT_DB_IP="127.0.0.1" +DEFAULT_DB_PORT=5432 + +DEFAULT_REDIS_DB_IP="127.0.0.1" +DEFAULT_REDIS_DB_PORT=6379 + +ID="${CGW_ID:-1}" + +GRPC_IP="${CGW_GRPC_IP:-$DEFAULT_SRC_IP}" +GRPC_PORT="${CGW_GRPC_PORT:-$DEFAULT_GRPC_PORT}" +WSS_LOCAL_IP="${CGW_WSS_IP:-$DEFAULT_WSS_IP}" +WSS_LOCAL_PORT="${CGW_WSS_PORT:-$DEFAULT_WSS_PORT}" +KAFKA_IP="${CGW_KAFKA_IP:-$DEFAULT_KAFKA_IP}" +KAFKA_PORT="${CGW_KAFKA_PORT:-$DEFAULT_KAFKA_PORT}" +DB_IP="${CGW_DB_IP:-$DEFAULT_DB_IP}" +DB_PORT="${CGW_DB_PORT:-$DEFAULT_DB_PORT}" +REDIS_DB_IP="${CGW_REDIS_DB_IP:-$DEFAULT_REDIS_DB_IP}" +REDIS_DB_PORT="${CGW_REDIS_DB_PORT:-$DEFAULT_REDIS_DB_PORT}" +LOG_LEVEL="${CGW_LOG_LEVEL:-info}" + +echo "Starting CGW..." +echo "CGW ID: $ID" +echo "LOG_LEVEL: $LOG_LEVEL" +echo "GRPC: $GRPC_IP:$GRPC_PORT" +echo "WSS: $WSS_LOCAL_IP:$WSS_LOCAL_PORT" +echo "KAFKA: $KAFKA_IP:$KAFKA_PORT" +echo "DB: $DB_IP:$DB_PORT" +echo "REDIS_DB: $REDIS_DB_IP:$REDIS_DB_PORT" + +# TBD: docker-based run +# TBD 2: add num of thread cfg (start argument) +output/bin/ucentral-cgw -w 4 -c $ID \ + --grpc-ip $GRPC_IP --grpc-port $GRPC_PORT \ + --wss-ip $WSS_LOCAL_IP --wss-port $WSS_LOCAL_PORT \ + --kafka-ip $KAFKA_IP --kafka-port $KAFKA_PORT \ + --db-ip $DB_IP --db-port $DB_PORT \ + --redis-db-ip $REDIS_DB_IP --redis-db-port $REDIS_DB_PORT \ + $LOG_LEVEL