#!/bin/bash LATEST=$(curl -s https://api.github.com/repos/gravitl/netmaker/releases/latest | grep "tag_name" | cut -d : -f 2,3 | tr -d [:space:],\") print_logo() {( cat << "EOF" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - __ __ ______ ______ __ __ ______ __ __ ______ ______ /\ "-.\ \ /\ ___\ /\__ _\ /\ "-./ \ /\ __ \ /\ \/ / /\ ___\ /\ == \ \ \ \-. \ \ \ __\ \/_/\ \/ \ \ \-./\ \ \ \ __ \ \ \ _"-. \ \ __\ \ \ __< \ \_\\"\_\ \ \_____\ \ \_\ \ \_\ \ \_\ \ \_\ \_\ \ \_\ \_\ \ \_____\ \ \_\ \_\ \/_/ \/_/ \/_____/ \/_/ \/_/ \/_/ \/_/\/_/ \/_/\/_/ \/_____/ \/_/ /_/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EOF )} if [ $(id -u) -ne 0 ]; then echo "This script must be run as root" exit 1 fi unset INSTALL_TYPE unset BUILD_TYPE unset BUILD_TAG unset IMAGE_TAG unset AUTO_BUILD # usage - displays usage instructions usage () { echo "usage: ./nm-quick.sh [-e] [-b buildtype] [-t tag] [-a auto]" echo " -e if specified, will install netmaker EE" echo " -b type of build; options:" echo " \"version\" - will install a specific version of Netmaker using remote git and dockerhub" echo " \"local\": - will install by cloning repo and and building images from git" echo " \"branch\": - will install a specific branch using remote git and dockerhub" echo " -t tag of build; if buildtype=version, tag=version. If builtype=branch or builtype=local, tag=branch" echo " -a auto-build; skip prompts and use defaults, if none provided" echo "examples:" echo " nm-quick.sh -e -b version -t $LATEST" echo " nm-quick.sh -e -b local -t feature_v0.17.2_newfeature" echo " nm-quick.sh -e -b branch -t develop" exit 1 } while getopts evab:t: flag do case "${flag}" in e) INSTALL_TYPE="ee" ;; v) usage exit 0 ;; a) AUTO_BUILD="on" ;; b) BUILD_TYPE=${OPTARG} if [[ ! "$BUILD_TYPE" =~ ^(version|local|branch)$ ]]; then echo "error: $BUILD_TYPE is invalid" echo "valid options: version, local, branch" usage exit 1 fi ;; t) BUILD_TAG=${OPTARG} ;; esac done # print_logo - prints the netmaker logo print_logo() { cat << "EOF" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - __ __ ______ ______ __ __ ______ __ __ ______ ______ /\ "-.\ \ /\ ___\ /\__ _\ /\ "-./ \ /\ __ \ /\ \/ / /\ ___\ /\ == \ \ \ \-. \ \ \ __\ \/_/\ \/ \ \ \-./\ \ \ \ __ \ \ \ _"-. \ \ __\ \ \ __< \ \_\\"\_\ \ \_____\ \ \_\ \ \_\ \ \_\ \ \_\ \_\ \ \_\ \_\ \ \_____\ \ \_\ \_\ \/_/ \/_/ \/_____/ \/_/ \/_/ \/_/ \/_/\/_/ \/_/\/_/ \/_____/ \/_/ /_/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EOF } # set_buildinfo - sets the information based on script input for how the installation should be run set_buildinfo() { if [ -z "$BUILD_TYPE" ]; then BUILD_TYPE="version" BUILD_TAG=$LATEST fi if [ -z "$BUILD_TAG" ] && [ "$BUILD_TYPE" = "version" ]; then BUILD_TAG=$LATEST fi if [ -z "$BUILD_TAG" ] && [ ! -z "$BUILD_TYPE" ]; then echo "error: must specify build tag when build type \"$BUILD_TYPE\" is specified" usage exit 1 fi IMAGE_TAG=$(sed 's/\//-/g' <<< "$BUILD_TAG") if [ "$1" = "ce" ]; then INSTALL_TYPE="ce" elif [ "$1" = "ee" ]; then INSTALL_TYPE="ee" fi if [ "$AUTO_BUILD" = "on" ] && [ -z "$INSTALL_TYPE" ]; then INSTALL_TYPE="ce" elif [ -z "$INSTALL_TYPE" ]; then echo "-----------------------------------------------------" echo "Would you like to install Netmaker Community Edition (CE), or Netmaker Enterprise Edition (EE)?" echo "EE will require you to create an account at https://dashboard.license.netmaker.io" echo "-----------------------------------------------------" select install_option in "Community Edition" "Enterprise Edition"; do case $REPLY in 1) echo "installing Netmaker CE" INSTALL_TYPE="ce" break ;; 2) echo "installing Netmaker EE" INSTALL_TYPE="ee" break ;; *) echo "invalid option $REPLY";; esac done fi echo "-----------Build Options-----------------------------" echo " EE or CE: $INSTALL_TYPE"; echo " Build Type: $BUILD_TYPE"; echo " Build Tag: $BUILD_TAG"; echo " Image Tag: $IMAGE_TAG"; echo "-----------------------------------------------------" } # install_yq - install yq if not present install_yq() { if ! command -v yq &> /dev/null; then wget -O /usr/bin/yq https://github.com/mikefarah/yq/releases/download/v4.31.1/yq_linux_$(dpkg --print-architecture) chmod +x /usr/bin/yq fi set +e if ! command -v yq &> /dev/null; then set -e wget -O /usr/bin/yq https://github.com/mikefarah/yq/releases/download/v4.31.1/yq_linux_amd64 chmod +x /usr/bin/yq fi set -e if ! command -v yq &> /dev/null; then echo "failed to install yq. Please install yq and try again." echo "https://github.com/mikefarah/yq/#install" exit 1 fi } # setup_netclient - adds netclient to docker-compose setup_netclient() { set +e netclient uninstall set -e wget -O netclient https://github.com/gravitl/netclient/releases/download/$LATEST/netclient-linux-amd64 chmod +x netclient ./netclient install netclient register -t $TOKEN echo "waiting for client to become available" wait_seconds 10 } # configure_netclient - configures server's netclient as a default host and an ingress gateway configure_netclient() { NODE_ID=$(sudo cat /etc/netclient/nodes.yml | yq -r .netmaker.commonnode.id) echo "register complete. New node ID: $NODE_ID" HOST_ID=$(sudo cat /etc/netclient/netclient.yml | yq -r .host.id) echo "making host a default" echo "Host ID: $HOST_ID" # set as a default host set +e nmctl host update $HOST_ID --default sleep 5 nmctl node create_ingress netmaker $NODE_ID set -e } # setup_nmctl - pulls nmctl and makes it executable setup_nmctl() { wget -O /usr/bin/nmctl https://github.com/gravitl/netmaker/releases/download/$LATEST/nmctl-linux-amd64 chmod +x /usr/bin/nmctl echo "using server api.$NETMAKER_BASE_DOMAIN" echo "using master key $MASTER_KEY" nmctl context set default --endpoint="https://api.$NETMAKER_BASE_DOMAIN" --master_key="$MASTER_KEY" nmctl context use default RESP=$(nmctl network list) if [[ $RESP == *"unauthorized"* ]]; then echo "Unable to properly configure NMCTL, exiting..." exit 1 fi } # wait_seconds - wait for the specified period of time wait_seconds() {( for ((a=1; a <= $1; a++)) do echo ". . ." sleep 1 done )} # confirm - get user input to confirm that they want to perform the next step confirm() {( if [ "$AUTO_BUILD" = "on" ]; then return 0 fi while true; do read -p 'Does everything look right? [y/n]: ' yn case $yn in [Yy]* ) override="true"; break;; [Nn]* ) echo "exiting..."; exit 1;; * ) echo "Please answer yes or no.";; esac done )} # local_install_setup - builds artifacts based on specified branch locally to use in install local_install_setup() {( rm -rf netmaker-tmp mkdir netmaker-tmp cd netmaker-tmp git clone https://www.github.com/gravitl/netmaker cd netmaker git checkout $BUILD_TAG git pull origin $BUILD_TAG docker build --no-cache --build-arg version=$IMAGE_TAG -t gravitl/netmaker:$IMAGE_TAG . if [ "$INSTALL_TYPE" = "ee" ]; then cp compose/docker-compose.ee.yml /root/docker-compose.yml cp docker/Caddyfile-EE /root/Caddyfile else cp compose/docker-compose.yml /root/docker-compose.yml cp docker/Caddyfile /root/Caddyfile fi cp docker/mosquitto.conf /root/mosquitto.conf cp docker/wait.sh /root/wait.sh cd ../../ rm -rf netmaker-tmp )} # install_dependencies - install necessary packages to run netmaker install_dependencies() { echo "checking dependencies..." OS=$(uname) if [ -f /etc/debian_version ]; then dependencies="git wireguard wireguard-tools dnsutils jq docker.io docker-compose" update_cmd='apt update' install_cmd='apt-get install -y' elif [ -f /etc/alpine-release ]; then dependencies="git wireguard jq docker.io docker-compose" update_cmd='apk update' install_cmd='apk --update add' elif [ -f /etc/centos-release ]; then dependencies="git wireguard jq bind-utils docker.io docker-compose" update_cmd='yum update' install_cmd='yum install -y' elif [ -f /etc/fedora-release ]; then dependencies="git wireguard bind-utils jq docker.io docker-compose" update_cmd='dnf update' install_cmd='dnf install -y' elif [ -f /etc/redhat-release ]; then dependencies="git wireguard jq docker.io bind-utils docker-compose" update_cmd='yum update' install_cmd='yum install -y' elif [ -f /etc/arch-release ]; then dependecies="git wireguard-tools dnsutils jq docker.io docker-compose" update_cmd='pacman -Sy' install_cmd='pacman -S --noconfirm' elif [ "${OS}" = "FreeBSD" ]; then dependencies="git wireguard wget jq docker.io docker-compose" update_cmd='pkg update' install_cmd='pkg install -y' elif [ -f /etc/turris-version ]; then dependencies="git wireguard-tools bash jq docker.io docker-compose" OS="TurrisOS" update_cmd='opkg update' install_cmd='opkg install' elif [ -f /etc/openwrt_release ]; then dependencies="git wireguard-tools bash jq docker.io docker-compose" OS="OpenWRT" update_cmd='opkg update' install_cmd='opkg install' else install_cmd='' fi if [ -z "${install_cmd}" ]; then echo "OS unsupported for automatic dependency install" exit 1 fi set -- $dependencies ${update_cmd} while [ -n "$1" ]; do if [ "${OS}" = "FreeBSD" ]; then is_installed=$(pkg check -d $1 | grep "Checking" | grep "done") if [ "$is_installed" != "" ]; then echo " " $1 is installed else echo " " $1 is not installed. Attempting install. ${install_cmd} $1 sleep 5 is_installed=$(pkg check -d $1 | grep "Checking" | grep "done") if [ "$is_installed" != "" ]; then echo " " $1 is installed elif [ -x "$(command -v $1)" ]; then echo " " $1 is installed else echo " " FAILED TO INSTALL $1 echo " " This may break functionality. fi fi else if [ "${OS}" = "OpenWRT" ] || [ "${OS}" = "TurrisOS" ]; then is_installed=$(opkg list-installed $1 | grep $1) else is_installed=$(dpkg-query -W --showformat='${Status}\n' $1 | grep "install ok installed") fi if [ "${is_installed}" != "" ]; then echo " " $1 is installed else echo " " $1 is not installed. Attempting install. ${install_cmd} $1 sleep 5 if [ "${OS}" = "OpenWRT" ] || [ "${OS}" = "TurrisOS" ]; then is_installed=$(opkg list-installed $1 | grep $1) else is_installed=$(dpkg-query -W --showformat='${Status}\n' $1 | grep "install ok installed") fi if [ "${is_installed}" != "" ]; then echo " " $1 is installed elif [ -x "$(command -v $1)" ]; then echo " " $1 is installed else echo " " FAILED TO INSTALL $1 echo " " This may break functionality. fi fi fi shift done echo "-----------------------------------------------------" echo "dependency check complete" echo "-----------------------------------------------------" } set -e # set_install_vars - sets the variables that will be used throughout installation set_install_vars() { IP_ADDR=$(dig -4 myip.opendns.com @resolver1.opendns.com +short) if [ "$IP_ADDR" = "" ]; then IP_ADDR=$(curl -s ifconfig.me) fi NETMAKER_BASE_DOMAIN=nm.$(echo $IP_ADDR | tr . -).nip.io COREDNS_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p') SERVER_PUBLIC_IP=$IP_ADDR MASTER_KEY=$(tr -dc A-Za-z0-9 &1) if [[ "$i" == 8 ]]; then echo " Caddy is having an issue setting up certificates, please investigate (docker logs caddy)" echo " Exiting..." exit 1 elif [[ "$curlresponse" == *"failed to verify the legitimacy of the server"* ]]; then echo " Certificates not yet configured, retrying..." elif [[ "$curlresponse" == *"left intact"* ]]; then echo " Certificates ok" break else secs=$(($i*5+10)) echo " Issue establishing connection...retrying in $secs seconds..." fi sleep $secs done } # setup_mesh - sets up a default mesh network on the server setup_mesh() { wait_seconds 5 echo "Creating netmaker network (10.101.0.0/16)" nmctl network create --name netmaker --ipv4_addr 10.101.0.0/16 wait_seconds 5 echo "Creating netmaker enrollment key" tokenJson=$(nmctl enrollment_key create --unlimited --networks netmaker) TOKEN=$(jq -r '.token' <<< ${tokenJson}) wait_seconds 3 } # print_success - prints a success message upon completion print_success() { echo "-----------------------------------------------------------------" echo "-----------------------------------------------------------------" echo "Netmaker setup is now complete. You are ready to begin using Netmaker." echo "Visit dashboard.$NETMAKER_BASE_DOMAIN to log in" echo "-----------------------------------------------------------------" echo "-----------------------------------------------------------------" } # 1. print netmaker logo print_logo # 2. setup the build instructions set_buildinfo set +e # 3. install necessary packages install_dependencies # 4. install yq if necessary install_yq # 5. if running a local build, clone git and build artifacts if [ "$BUILD_TYPE" = "local" ]; then local_install_setup fi set -e # 6. get user input for variables set_install_vars # 7. get and set config files, startup docker-compose install_netmaker set +e # 8. make sure Caddy certs are working test_connection # 9. install the netmaker CLI setup_nmctl # 10. create a default mesh network for netmaker setup_mesh set -e # 11. add netclient to docker-compose and start it up setup_netclient # 12. make the netclient a default host and ingress gw configure_netclient # 13. print success message print_success # cp -f /etc/skel/.bashrc /root/.bashrc