-
-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/develop' for release 0.1.0-beta1
- Loading branch information
Showing
17 changed files
with
556 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,29 @@ | ||
# warden | ||
Warden is a CLI utility for managing docker powered developer environments on macOS | ||
# Warden | ||
Warden is a CLI utility for working with docker-compose environments, and enables multiple local developer environments to run simultaneously without port conflicts via the use of a few centrally run services for proxying into each environment's containers. | ||
|
||
## Prerequisites | ||
|
||
* [Homebrew](https://brew.sh) package manager (for installing Warden) | ||
* [Docker for Mac](https://hub.docker.com/editions/community/docker-ce-desktop-mac) or [Docker for Linux](https://docs.docker.com/install/linux/docker-ce/fedora/) | ||
* `docker-compose` available in your `$PATH` (included in Docker for Mac, can be installed via brew on Linux hosts) | ||
|
||
## Installing Warden | ||
|
||
brew install davidalger/warden/warden | ||
warden up | ||
|
||
## Features | ||
|
||
* Traefik for SSL termination and routing/proxying requests into the correct containers. | ||
* Portainer for quick visibility into what's running inside the local Docker host. | ||
* Dnsmasq to serve DNS responses for .test domains eliminating manual editing of `/etc/hosts` | ||
* An SSH tunnel for connecting from SequelPro or TablePlus into any one of multiple running database containers. | ||
* Warden wildcard SSl certificate signing for running https on all local development domains. | ||
|
||
## License | ||
|
||
This work is licensed under the MIT license. See LICENSE file for details. | ||
|
||
## Author Information | ||
|
||
This project was started in 2019 by [David Alger](https://davidalger.com/). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#!/usr/bin/env bash | ||
set -e | ||
trap '>&2 printf "\n\e[01;31mError: Command \`%s\` on line $LINENO failed with exit code $?\033[0m\n" "$BASH_COMMAND"' ERR | ||
|
||
## find directory where this script is located following symlinks if neccessary | ||
readonly WARDEN_DIR="$( | ||
cd "$( | ||
dirname "$( | ||
(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}") \ | ||
| sed -e "s#^../#$(dirname "$(dirname "${BASH_SOURCE[0]}")")/#" | ||
)" | ||
)/.." >/dev/null \ | ||
&& pwd | ||
)" | ||
|
||
## define global directory paths by commands | ||
readonly WARDEN_HOME_DIR=~/.warden | ||
readonly WARDEN_SSL_DIR="${WARDEN_HOME_DIR}/ssl" | ||
|
||
## declare variables for flags and arguments | ||
declare WARDEN_HELP= | ||
declare WARDEN_PARAMS=() | ||
declare WARDEN_COMMAND= | ||
|
||
## parse first argument as command and determine validity | ||
if (( "$#" )) && [[ -f "${WARDEN_DIR}/commands/${1}.cmd" ]]; then | ||
WARDEN_COMMAND="$1" | ||
shift | ||
else | ||
WARDEN_COMMAND=usage | ||
fi | ||
|
||
## parse arguments | ||
while (( "$#" )); do | ||
case "$1" in | ||
-h|--help) | ||
WARDEN_HELP=1 | ||
break | ||
;; | ||
--) # end argument parsing | ||
shift | ||
break | ||
;; | ||
-*|--*=) # unsupported flags | ||
>&2 echo "Error: Unsupported flag $1" | ||
exit 1 | ||
;; | ||
*) # preserve positional arguments | ||
WARDEN_PARAMS+=($1) | ||
shift | ||
;; | ||
esac | ||
done | ||
|
||
function assert_installed { | ||
if [[ ! -f "${WARDEN_HOME_DIR}/.installed" ]]; then | ||
"${WARDEN_DIR}/bin/warden" install | ||
date > "${WARDEN_HOME_DIR}/.installed" | ||
fi | ||
} | ||
|
||
## display command specific usage info if help flag is set | ||
if [[ ${WARDEN_HELP} ]]; then | ||
source "${WARDEN_DIR}/commands/usage.cmd" | ||
fi | ||
|
||
## execute sub-command in context of this script | ||
source "${WARDEN_DIR}/commands/${WARDEN_COMMAND}.cmd" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/usr/bin/env bash | ||
[[ ! ${WARDEN_COMMAND} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!" && exit 1 | ||
|
||
pushd "${WARDEN_DIR}" >/dev/null | ||
docker-compose -p warden -f docker/docker-compose.yml down "${WARDEN_PARAMS[@]}" "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#!/usr/bin/env bash | ||
[[ ! ${WARDEN_COMMAND} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!" && exit 1 | ||
|
||
if [[ ! -d "${WARDEN_SSL_DIR}/rootca" ]]; then | ||
mkdir -p "${WARDEN_SSL_DIR}/rootca"/{certs,crl,newcerts,private} | ||
|
||
touch "${WARDEN_SSL_DIR}/rootca/index.txt" | ||
echo 1000 > "${WARDEN_SSL_DIR}/rootca/serial" | ||
fi | ||
|
||
# create CA root certificate if none present | ||
if [[ ! -f "${WARDEN_SSL_DIR}/rootca/private/ca.key.pem" ]]; then | ||
echo "==> Generating private key for local root certificate" | ||
openssl genrsa -out "${WARDEN_SSL_DIR}/rootca/private/ca.key.pem" 2048 | ||
fi | ||
|
||
if [[ ! -f "${WARDEN_SSL_DIR}/rootca/certs/ca.cert.pem" ]]; then | ||
echo "==> Signing root certificate (Warden Proxy Local CA)" | ||
openssl req -new -x509 -days 7300 -sha256 -extensions v3_ca \ | ||
-config "${WARDEN_DIR}/config/openssl/rootca.conf" \ | ||
-key "${WARDEN_SSL_DIR}/rootca/private/ca.key.pem" \ | ||
-out "${WARDEN_SSL_DIR}/rootca/certs/ca.cert.pem" \ | ||
-subj "/C=US/O=Warden Proxy Local CA" | ||
fi | ||
|
||
## trust root ca differently on linux-gnu than on macOS | ||
if [[ "$OSTYPE" == "linux-gnu" ]] && [[ ! -f /etc/pki/ca-trust/source/anchors/warden-proxy-local-ca.cert.pem ]]; then | ||
echo "==> Trusting root certificate (requires sudo privileges)" | ||
sudo cp "${WARDEN_SSL_DIR}/rootca/certs/ca.cert.pem" /etc/pki/ca-trust/source/anchors/warden-proxy-local-ca.cert.pem | ||
sudo update-ca-trust | ||
sudo update-ca-trust enable | ||
elif [[ "$OSTYPE" == "darwin"* ]] && ! security dump-trust-settings -d | grep 'Warden Proxy Local CA' >/dev/null; then | ||
echo "==> Trusting root certificate (requires sudo privileges)" | ||
sudo security add-trusted-cert -d -r trustRoot \ | ||
-k /Library/Keychains/System.keychain "${WARDEN_SSL_DIR}/rootca/certs/ca.cert.pem" | ||
fi | ||
|
||
if [[ ! -f "${WARDEN_SSL_DIR}/certs/warden.test.crt.pem" ]]; then | ||
"${WARDEN_DIR}/bin/warden" sign-certificate warden.test | ||
fi | ||
|
||
## configure resolver for .test domains | ||
if [[ ! -d /etc/resolver ]] || [[ ! -f /etc/resolver/test ]]; then | ||
echo "==> Configuring resolver for .test domains (requires sudo privileges)" | ||
sudo mkdir /etc/resolver | ||
echo "nameserver 127.0.0.1" | sudo tee /etc/resolver/test >/dev/null | ||
fi | ||
|
||
## generate rsa keypair for authenticating to warden sshd service | ||
if [[ ! -f "${WARDEN_HOME_DIR}/tunnel/ssh_key" ]]; then | ||
echo "==> Generating rsa key pair for tunnel into sshd service" | ||
mkdir -p "${WARDEN_HOME_DIR}/tunnel" | ||
ssh-keygen -b 2048 -t rsa -f "${WARDEN_HOME_DIR}/tunnel/ssh_key" -N "" -C "[email protected]" | ||
fi | ||
|
||
if ! grep '## WARDEN START ##' /etc/ssh/ssh_config >/dev/null; then | ||
echo "==> Configuring sshd tunnel in host ssh_config (requires sudo privileges)" | ||
cat <<-EOF | sudo tee -a /etc/ssh/ssh_config >/dev/null | ||
## WARDEN START ## | ||
Host tunnel.warden.test | ||
HostName 127.0.0.1 | ||
User user | ||
Port 2222 | ||
IdentityFile ~/.warden/tunnel/ssh_key | ||
## WARDEN END ## | ||
EOF | ||
fi | ||
|
||
echo "==> Installed successfully" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/usr/bin/env bash | ||
[[ ! ${WARDEN_COMMAND} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!" && exit 1 | ||
|
||
pushd "${WARDEN_DIR}" >/dev/null | ||
docker-compose -p warden -f docker/docker-compose.yml restart "${WARDEN_PARAMS[@]}" "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#!/usr/bin/env bash | ||
[[ ! ${WARDEN_COMMAND} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!" && exit 1 | ||
|
||
mkdir -p "${WARDEN_SSL_DIR}/certs" | ||
|
||
if [[ ! -f "${WARDEN_SSL_DIR}/rootca/certs/ca.cert.pem" ]]; then | ||
echo -e "\033[31mError: Missing the root CA file. Please run 'warden install' and try again." | ||
exit -1 | ||
fi | ||
|
||
if (( ${#WARDEN_PARAMS[@]} == 0 )); then | ||
echo -e "\033[33mCommand '${WARDEN_COMMAND}' requires a hostname as an argument, please use --help for details." | ||
exit -1 | ||
fi | ||
|
||
CERTIFICATE_SAN_LIST= | ||
for (( i = 0; i < ${#WARDEN_PARAMS[@]} * 2; i+=2 )); do | ||
[[ ${CERTIFICATE_SAN_LIST} ]] && CERTIFICATE_SAN_LIST+="," | ||
CERTIFICATE_SAN_LIST+="DNS.$(expr $i + 1):${WARDEN_PARAMS[i/2]}" | ||
CERTIFICATE_SAN_LIST+=",DNS.$(expr $i + 2):*.${WARDEN_PARAMS[i/2]}" | ||
done | ||
|
||
CERTIFICATE_NAME="${WARDEN_PARAMS[0]}" | ||
|
||
if [[ -f "${WARDEN_SSL_DIR}/certs/${CERTIFICATE_NAME}.key.pem" ]]; then | ||
>&2 echo -e "\033[33mWarning: Certificate for ${CERTIFICATE_NAME} already exists! Overwriting...\033[0m\n" | ||
fi | ||
|
||
echo "==> Generating private key ${CERTIFICATE_NAME}.key.pem" | ||
openssl genrsa -out "${WARDEN_SSL_DIR}/certs/${CERTIFICATE_NAME}.key.pem" 2048 | ||
|
||
echo "==> Generating signing req ${CERTIFICATE_NAME}.crt.pem" | ||
openssl req -new -sha256 -config <(cat \ | ||
"${WARDEN_DIR}/config/openssl/certificate.conf" \ | ||
<(printf "subjectAltName = %s" "${CERTIFICATE_SAN_LIST}") \ | ||
) \ | ||
-key "${WARDEN_SSL_DIR}/certs/${CERTIFICATE_NAME}.key.pem" \ | ||
-out "${WARDEN_SSL_DIR}/certs/${CERTIFICATE_NAME}.csr.pem" \ | ||
-subj "/C=US/CN=${CERTIFICATE_NAME}" | ||
|
||
echo "==> Generating certificate ${CERTIFICATE_NAME}.crt.pem" | ||
openssl x509 -req -days 365 -sha256 -extensions v3_req \ | ||
-extfile <(cat \ | ||
"${WARDEN_DIR}/config/openssl/certificate.conf" \ | ||
<(printf "subjectAltName = %s" "${CERTIFICATE_SAN_LIST}") \ | ||
) \ | ||
-CA "${WARDEN_SSL_DIR}/rootca/certs/ca.cert.pem" \ | ||
-CAkey "${WARDEN_SSL_DIR}/rootca/private/ca.key.pem" \ | ||
-CAserial "${WARDEN_SSL_DIR}/rootca/serial" \ | ||
-in "${WARDEN_SSL_DIR}/certs/${CERTIFICATE_NAME}.csr.pem" \ | ||
-out "${WARDEN_SSL_DIR}/certs/${CERTIFICATE_NAME}.crt.pem" | ||
|
||
if [[ "$(cd "${WARDEN_DIR}" && docker-compose -p warden -f docker/docker-compose.yml ps -q traefik)" ]]; then | ||
echo "==> Updating traefik" | ||
"${WARDEN_DIR}/bin/warden" up traefik | ||
"${WARDEN_DIR}/bin/warden" restart traefik | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#!/usr/bin/env bash | ||
[[ ! ${WARDEN_COMMAND} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!" && exit 1 | ||
|
||
WARDEN_USAGE=$(cat <<EOF | ||
\033[33mUsage:\033[0m | ||
sign-certificate <hostname> [hostname2] [hostname3] ... | ||
\033[33mOptions:\033[0m | ||
-h, --help Display this help menu | ||
-v, --verbose Increases verbosity of output | ||
EOF | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/usr/bin/env bash | ||
[[ ! ${WARDEN_COMMAND} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!" && exit 1 | ||
|
||
pushd "${WARDEN_DIR}" >/dev/null | ||
docker-compose -p warden -f docker/docker-compose.yml start "${WARDEN_PARAMS[@]}" "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/usr/bin/env bash | ||
[[ ! ${WARDEN_COMMAND} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!" && exit 1 | ||
|
||
pushd "${WARDEN_DIR}" >/dev/null | ||
docker-compose -p warden -f docker/docker-compose.yml stop "${WARDEN_PARAMS[@]}" "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#!/usr/bin/env bash | ||
[[ ! ${WARDEN_COMMAND} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!" && exit 1 | ||
|
||
assert_installed | ||
|
||
mkdir -p "${WARDEN_HOME_DIR}/etc/traefik" | ||
cp "${WARDEN_DIR}/config/traefik/traefik.toml" "${WARDEN_HOME_DIR}/etc/traefik/traefik.toml" | ||
cp "${WARDEN_DIR}/config/dnsmasq.conf" "${WARDEN_HOME_DIR}/etc/dnsmasq.conf" | ||
|
||
# TODO: Determine if a template loop may work in the config file to do this automatically in traefik | ||
for cert in $(find "${WARDEN_SSL_DIR}/certs" -type f -name "*.crt.pem" | sed -E 's#^.*/ssl/certs/(.*)\.crt\.pem$#\1#'); do | ||
[[ "${cert}" = "warden.test" ]] && continue | ||
|
||
cat >> "${WARDEN_HOME_DIR}/etc/traefik/traefik.toml" <<-EOF | ||
[[entryPoints.https.tls.certificates]] | ||
certFile = "/etc/ssl/certs/${cert}.crt.pem" | ||
keyFile = "/etc/ssl/certs/${cert}.key.pem" | ||
EOF | ||
done | ||
|
||
pushd "${WARDEN_DIR}" >/dev/null | ||
docker-compose -p warden -f docker/docker-compose.yml up -d "${WARDEN_PARAMS[@]}" "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#!/usr/bin/env bash | ||
[[ ! ${WARDEN_COMMAND} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!" && exit 1 | ||
|
||
## load usage info for the given command falling back on default usage text | ||
if [[ -f "${WARDEN_DIR}/commands/${WARDEN_COMMAND}.help" ]]; then | ||
source "${WARDEN_DIR}/commands/${WARDEN_COMMAND}.help" | ||
else | ||
source "${WARDEN_DIR}/commands/usage.help" | ||
fi | ||
|
||
echo -e "${WARDEN_USAGE}" | ||
exit 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#!/usr/bin/env bash | ||
[[ ! ${WARDEN_COMMAND} ]] && >&2 echo -e "\033[31mThis script is not intended to be run directly!" && exit 1 | ||
|
||
WARDEN_HEADER=' | ||
_ __ __ | ||
| | / /___ __________/ /__ ____ | ||
| | /| / / __ `/ ___/ __ / _ \/ __ \ | ||
| |/ |/ / /_/ / / / /_/ / __/ / / / | ||
|__/|__/\__,_/_/ \__,_/\___/_/ /_/ | ||
' | ||
|
||
WARDEN_USAGE=$(cat <<EOF | ||
${WARDEN_HEADER:1} | ||
Warden version 0.1.0-dev | ||
\033[33mUsage:\033[0m | ||
command [options] [arguments] | ||
\033[33mOptions:\033[0m | ||
-h, --help Display this help menu | ||
-v, --verbose Increases verbosity of output | ||
\033[33mCommands:\033[0m | ||
down Stop and remove containers, networks, and services | ||
install Installs local docker environment in the current directory | ||
restart Restarts warden managed containers | ||
sign-certificate Signs a wildcard certificate including all passed hostnames on the SAN list | ||
start Start services | ||
stop Stop services | ||
up Create and start containers, networks, and services | ||
EOF | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#dnsmasq config, for a complete example, see: | ||
# http://oss.segetech.com/intra/srv/dnsmasq.conf | ||
|
||
#log all dns queries | ||
log-queries | ||
|
||
#dont use hosts nameservers | ||
no-resolv | ||
|
||
#use cloudflare as default nameservers, prefer 1^4 | ||
server=1.0.0.1 | ||
server=1.1.1.1 | ||
strict-order | ||
|
||
#explicitly define host-ip mappings | ||
address=/.test/127.0.0.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[req] | ||
distinguished_name = req_distinguished_name | ||
req_extensions = v3_req | ||
|
||
[req_distinguished_name] | ||
countryName = Country Name (2 letter code) | ||
countryName_default = US | ||
stateOrProvinceName = State or Province Name (full name) | ||
stateOrProvinceName_default = | ||
localityName = Locality Name (eg, city) | ||
localityName_default = | ||
organizationalUnitName = Organizational Unit Name (eg, section) | ||
organizationalUnitName_default = Warden Proxy | ||
commonName = Internet Widgits Ltd | ||
commonName_max = 64 | ||
|
||
[ v3_req ] | ||
# Extensions to add to a certificate request | ||
basicConstraints = CA:FALSE | ||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment |
Oops, something went wrong.