Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ngrok): Adding ngrok feature #769

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions commands/env.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,21 @@ fi
[[ ${WARDEN_VARNISH} -eq 1 ]] \
&& appendEnvPartialIfExists "varnish"

if [[ ${WARDEN_NGROK} -eq 1 ]]; then
if [[ ! -f "${WARDEN_ENV_PATH}/.warden/ngrok.yml" ]]; then
fatal "Ngrok is not initialized, please run \"warden ngrok init\" or set WARDEN_NGROK=0 in .env file. File ${WARDEN_ENV_PATH}/.warden/ngrok.yml is missing."
fi

if [[ ! -f "${WARDEN_ENV_PATH}/.warden/ngrok.caddy" ]]; then
fatal "Ngrok is not initialized, please run \"warden ngrok init\" or set WARDEN_NGROK=0 in .env file. File ${WARDEN_ENV_PATH}/.warden/ngrok.caddy is missing."
fi

if [[ "$NGROK_AUTHTOKEN" == "" ]]; then
fatal "NGROK_AUTHTOKEN is not defined in the .env, please create an account at https://ngrok.com and set the authtoken in your .env file."
fi
appendEnvPartialIfExists "ngrok"
fi

[[ ${WARDEN_RABBITMQ} -eq 1 ]] \
&& appendEnvPartialIfExists "rabbitmq"

Expand Down
63 changes: 63 additions & 0 deletions commands/ngrok.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
[[ ! ${WARDEN_DIR} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!\033[0m" && exit 1

WARDEN_ENV_PATH="$(locateEnvPath)" || exit $?
loadEnvConfig "${WARDEN_ENV_PATH}" || exit $?
assertDockerRunning

if [[ ${WARDEN_NGROK:-0} -eq 0 ]]; then
fatal "Ngrok environment is not used (WARDEN_NGROK=0)."
fi

source "${WARDEN_DIR}/utils/ngrok.sh"

if (( ${#WARDEN_PARAMS[@]} == 0 )) || [[ "${WARDEN_PARAMS[0]}" == "help" ]]; then
warden ngrok --help || exit $? && exit $?
fi

## load connection information for the mysql service

## sub-command execution
case "${WARDEN_PARAMS[0]}" in
init)
if [[ "${WARDEN_PARAMS[1]}" == "" ]]; then
domain="$TRAEFIK_DOMAIN";
if [[ ${TRAEFIK_SUBDOMAIN} != "" ]]; then
domain="${TRAEFIK_SUBDOMAIN}.${domain}"
fi
mkdir -p ${WARDEN_ENV_PATH}/.warden; #create directoy if does not exists
generateNgrokConfigurationFile "${WARDEN_ENV_PATH}/.warden/ngrok.yml" "$domain"
else
mkdir -p ${WARDEN_ENV_PATH}/.warden; #create directoy if does not exists
generateNgrokConfigurationFile "${WARDEN_ENV_PATH}/.warden/ngrok.yml" ${WARDEN_PARAMS[@]:1}
fi
if [ ! -f ${WARDEN_ENV_PATH}/.warden/ngrok.caddy ]; then
touch ${WARDEN_ENV_PATH}/.warden/ngrok.caddy
$WARDEN_DIR/bin/warden ngrok refresh-config
fi

warning "You have to run the command \"warden ngrok refresh-config\" after every ngrok container start. It will generate the config for the reverse proxy allowing correct url rewrites and mapping."

;;
refresh-config)
if [[ ${CADDY_NGROK_TARGET_SERVICE} == "" ]]; then
if [[ ${WARDEN_VARNISH} == "1" ]]; then
CADDY_NGROK_TARGET_SERVICE=varnish;
else
CADDY_NGROK_TARGET_SERVICE=nginx;
fi
fi
if [[ ${CADDY_NGROK_TARGET_PORT} == "" ]]; then
CADDY_NGROK_TARGET_PORT=80;
fi
mkdir -p ${WARDEN_ENV_PATH}/.warden; #create directoy if does not exists
generateCaddyConfigurationFile "${WARDEN_ENV_PATH}/.warden/ngrok.caddy" "$CADDY_NGROK_TARGET_SERVICE" "$CADDY_NGROK_TARGET_PORT"
displayNgrokUrls
;;
ls)
displayNgrokUrls
;;
*)
fatal "The command \"${WARDEN_PARAMS[0]}\" does not exist. Please use --help for usage."
;;
esac
16 changes: 16 additions & 0 deletions commands/ngrok.help
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
[[ ! ${WARDEN_DIR} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!\033[0m" && exit 1

WARDEN_USAGE=$(cat <<EOF
\033[33mUsage:\033[0m
db <sub-command>

\033[33mOptions:\033[0m
-h, --help Display this help menu

\033[33mCommands:\033[0m
init <domain1> <domain2> <...> Initialize the ngrok configuration file with the default TRAEFIK_DOMAIN.
refresh-config Regenerate the caddy configuration to match the urls in ngrok.
ls Show the list of ngrok urls
EOF
)
3 changes: 3 additions & 0 deletions environments/drupal/init.env
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ BLACKFIRE_CLIENT_ID=
BLACKFIRE_CLIENT_TOKEN=
BLACKFIRE_SERVER_ID=
BLACKFIRE_SERVER_TOKEN=

WARDEN_NGROK=0
NGROK_AUTHTOKEN=
26 changes: 26 additions & 0 deletions environments/includes/ngrok.base.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
services:
ngrok:
hostname: "${WARDEN_ENV_NAME}-ngrok"
image: ngrok/ngrok:${NGROK_VERSION:-latest}
environment:
NGROK_AUTHTOKEN: ${NGROK_AUTHTOKEN}
volumes:
- ${WARDEN_ENV_PATH:-.}/.warden/ngrok.yml:/etc/ngrok.yml:ro,cached
command:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bruno-blackbird Reviewing the entrypoint script in the ngrok image, I think all you'd need to do here is just specify the NGROK_CONFIG environment variable to be /etc/ngrok.yml. The entrypoint script will start listening on all tunnels in the config file by default.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bap14 you mean instead of passing the command, yes, maybe it will be cleaner if I add it this way

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bruno-blackbird Yes, that's correct.

- "start"
- "--all"
- "--config"
- "/etc/ngrok.yml"


caddy-ngrok:
hostname: "${WARDEN_ENV_NAME}-caddy-ngrok"
image: ${WARDEN_IMAGE_REPOSITORY}/caddy-ngrok:${CADDY_NGROK_VERSION:-latest}
volumes:
- ${WARDEN_ENV_PATH:-.}/.warden/ngrok.caddy:/etc/caddy/Caddyfile:ro,cached
command:
- "caddy"
- "run"
- "--watch"
- "--config"
- "/etc/caddy/Caddyfile"
3 changes: 3 additions & 0 deletions environments/laravel/init.env
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ REDIS_HOST=redis
REDIS_PORT=6379

MAIL_DRIVER=sendmail

WARDEN_NGROK=0
NGROK_AUTHTOKEN=
3 changes: 3 additions & 0 deletions environments/magento1/init.env
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ BLACKFIRE_CLIENT_TOKEN=
BLACKFIRE_SERVER_ID=
BLACKFIRE_SERVER_TOKEN=

WARDEN_NGROK=0
NGROK_AUTHTOKEN=

2 changes: 2 additions & 0 deletions environments/magento2/init.env
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ BLACKFIRE_CLIENT_TOKEN=
BLACKFIRE_SERVER_ID=
BLACKFIRE_SERVER_TOKEN=

WARDEN_NGROK=0
NGROK_AUTHTOKEN=
2 changes: 2 additions & 0 deletions environments/shopware/init.env
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ RABBITMQ_VERSION=3.8
REDIS_VERSION=5.0
VARNISH_VERSION=6.0

WARDEN_NGROK=0
NGROK_AUTHTOKEN=
2 changes: 2 additions & 0 deletions environments/symfony/init.env
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ RABBITMQ_VERSION=3.8
REDIS_VERSION=5.0
VARNISH_VERSION=6.0

WARDEN_NGROK=0
NGROK_AUTHTOKEN=
3 changes: 3 additions & 0 deletions environments/wordpress/init.env
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ DB_PORT=3306
DB_DATABASE=wordpress
DB_USERNAME=wordpress
DB_PASSWORD=wordpress

WARDEN_NGROK=0
NGROK_AUTHTOKEN=
1 change: 1 addition & 0 deletions utils/env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ function loadEnvConfig () {
eval "$(cat "${WARDEN_ENV_PATH}/.env" | sed 's/\r$//g' | grep "^WARDEN_")"
eval "$(cat "${WARDEN_ENV_PATH}/.env" | sed 's/\r$//g' | grep "^TRAEFIK_")"
eval "$(cat "${WARDEN_ENV_PATH}/.env" | sed 's/\r$//g' | grep "^PHP_")"
eval "$(cat "${WARDEN_ENV_PATH}/.env" | sed 's/\r$//g' | grep "^NGROK_")"

WARDEN_ENV_NAME="${WARDEN_ENV_NAME:-}"
WARDEN_ENV_TYPE="${WARDEN_ENV_TYPE:-}"
Expand Down
109 changes: 109 additions & 0 deletions utils/ngrok.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env bash
[[ ! ${WARDEN_DIR} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!\033[0m" && exit 1

function replaceDots() {
local input_string="$1"
local output_string="${input_string//./\\.}"
echo "$output_string"
}

function displayNgrokUrls() {
# Sample text input
local text=$($WARDEN_DIR/bin/warden env logs ngrok | grep name=)

# Extract name and url using grep and awk
local names=$(echo "$text" | grep -o 'name=[^ ]*' | awk -F'=' '{print $2}')
local urls=$(echo "$text" | grep -o 'url=[^ ]*' | awk -F'=https://' '{print $2}')

local names=($(echo "${names[@]}" | tr '\n' ' '))
local urls=($(echo "${urls[@]}" | tr '\n' ' '))

# Check if the number of names and urls match
if [[ ${#names[@]} -ne ${#urls[@]} ]]; then
echo "Error: The number of names and URLs doesn't match!"
exit 1
fi

# Return only unique urls, latest values in logs are replacing oldest values
declare -A unique_urls
for ((i = 0; i < ${#names[@]}; i++)); do
unique_urls[${names[i]}]=${urls[i]}
done

for name in "${!unique_urls[@]}"; do
echo "Use url: https://${name} for https://${unique_urls[$name]}"
done
}

function generateCaddyConfigurationFile() {
local target_file="$1"
local target_service="$2"
local target_port="$3"

# Sample text input
local text=$($WARDEN_DIR/bin/warden env logs ngrok | grep name=)

# Extract name and url using grep and awk
local names=$(echo "$text" | grep -o 'name=[^ ]*' | awk -F'=' '{print $2}')
local urls=$(echo "$text" | grep -o 'url=[^ ]*' | awk -F'=https://' '{print $2}')

local names=($(echo "${names[@]}" | tr '\n' ' '))
local urls=($(echo "${urls[@]}" | tr '\n' ' '))

# Check if the number of names and urls match
if [[ ${#names[@]} -ne ${#urls[@]} ]]; then
echo "Error: The number of names and URLs doesn't match!"
exit 1
fi

# Return only unique urls, latest values in logs are replacing oldest values
declare -A unique_urls
for ((i = 0; i < ${#names[@]}; i++)); do
unique_urls[${names[i]}]=${urls[i]}
done

echo "{
order replace after encode
}
:2080 {
@get {
method GET
path /*
}
handle @get {
replace {" > $target_file;

# Loop through the urls to get before and after replacement
for name in "${!unique_urls[@]}"; do
echo " ${name} ${unique_urls[$name]}" >> $target_file;
done

echo " }
}

reverse_proxy $target_service:$target_port {
header_up Accept-Encoding identity
header_up X-Forwarded-Proto https" >> $target_file;

# Loop through the arrays and map the headers to be replaced
for name in "${!unique_urls[@]}"; do
echo " header_up * $(replaceDots ${unique_urls[$name]}) ${name}
header_down * $(replaceDots ${name}) ${unique_urls[$name]}" >> $target_file;
done

echo " }
}" >> $target_file;
}

function generateNgrokConfigurationFile() {
local target_file="$1"
local domains="${@:2}"
echo 'version: "2"
log: stdout
tunnels:'> $target_file;
for domain in $domains ; do
echo ' '${domain}':
proto: "http"
addr: "caddy-ngrok:2080"' >> $target_file;
done
}