#!/usr/bin/env bash # netdata # real-time performance and health monitoring, done right! # (C) 2017 Costa Tsaousis # SPDX-License-Identifier: GPL-3.0-or-later # Exit code: 0 - Success # Exit code: 1 - Unknown argument # Exit code: 2 - Problems with claiming working directory # Exit code: 3 - Missing dependencies # Exit code: 4 - Failure to connect to endpoint # Exit code: 5 - Unknown HTTP error message # # OK: Agent claimed successfully # HTTP Status code: 204 # Exit code: 0 # # Error: The agent id is invalid; it does not fulfill the constraints # HTTP Status code: 422 # Error key: "ErrInvalidNodeID" # Error message: "invalid node id" # Exit code: 6 # Error: The agent hostname is invalid; it does not fulfill the constraints # HTTP Status code: 422 # Error key: "ErrInvalidNodeName" # Error message: "invalid node name" # Exit code: 7 # # Error: At least one of the given rooms ids is invalid; it does not fulfill the constraints # HTTP Status code: 422 # Error key: "ErrInvalidRoomID" # Error message: "invalid room id" # Exit code: 8 # # Error: Invalid public key; the public key is empty or not present # HTTP Status code: 422 # Error key: "ErrInvalidPublicKey" # Error message: "invalid public key" # Exit code: 9 # # Error: Expired, missing or invalid token # HTTP Status code: 403 # Error key: "ErrForbidden" # Error message: "token expired" | "token not found" | "invalid token" # Exit code: 10 # # Error: Duplicate agent id; an agent with the same id is already registered in the cloud # HTTP Status code: 409 # Error key: "ErrAlreadyClaimed" # Error message: "already claimed" # Exit code: 11 # # Error: The node claiming process is still in progress. # HTTP Status code: 102 # Error key: "ErrProcessingClaim" # Error message: "processing claiming" # Exit code: 12 # # Error: Internal server error. Any other unexpected error (DB problems, etc.) # HTTP Status code: 500 # Error key: "ErrInternalServerError" # Error message: "Internal Server Error" # Exit code: 13 # # Error: There was a timout processing the claim. # HTTP Status code: 504 # Error key: "ErrGatewayTimeout" # Error message: "Gateway Timeout" # Exit code: 14 # # Error: The service cannot handle the claiming request at this time. # HTTP Status code: 503 # Error key: "ErrServiceUnavailable" # Error message: "Service Unavailable" # Exit code: 15 if command -v curl >/dev/null 2>&1 ; then URLTOOL="curl" elif command -v wget >/dev/null 2>&1 ; then URLTOOL="wget" else echo >&2 "I need curl or wget to proceed, but neither is available on this system." exit 3 fi if ! command -v openssl >/dev/null 2>&1 ; then echo >&2 "I need openssl to proceed, but neither is available on this system." exit 3 fi # ----------------------------------------------------------------------------- # defaults to allow running this script by hand [ -z "${NETDATA_USER_CONFIG_DIR}" ] && NETDATA_USER_CONFIG_DIR="@configdir_POST@" MACHINE_GUID_FILE="@registrydir_POST@/netdata.public.unique.id" CLAIMING_DIR="${NETDATA_USER_CONFIG_DIR}/claim.d" TOKEN="unknown" URL_BASE="https://netdata.cloud" ID="unknown" ROOMS="" HOSTNAME=$(hostname) CLOUD_CERTIFICATE_FILE="${CLAIMING_DIR}/cloud_fullchain.pem" # get the MACHINE_GUID by default if [ -r "${MACHINE_GUID_FILE}" ]; then ID="$(cat "${MACHINE_GUID_FILE}")" fi # get token from file if [ -r "${CLAIMING_DIR}/token" ]; then TOKEN="$(cat "${CLAIMING_DIR}/token")" fi # get rooms from file if [ -r "${CLAIMING_DIR}/rooms" ]; then ROOMS="$(cat "${CLAIMING_DIR}/rooms")" fi for arg in "$@" do case $arg in -token=*) TOKEN=${arg:7} ;; -url=*) URL_BASE=${arg:5} ;; -id=*) ID=${arg:4} ;; -rooms=*) ROOMS=${arg:7} ;; -hostname=*) HOSTNAME=${arg:10} ;; *) echo >&2 "Unknown argument ${arg}" exit 1 ;; esac shift 1 done echo >&2 "Token: ****************" echo >&2 "Base URL: $URL_BASE" echo >&2 "Id: $ID" echo >&2 "Rooms: $ROOMS" echo >&2 "Hostname: $HOSTNAME" # create the claiming directory for this user if [ ! -d "${CLAIMING_DIR}" ] ; then mkdir -p "${CLAIMING_DIR}" && chmod 0770 "${CLAIMING_DIR}" # shellcheck disable=SC2181 if [ $? -ne 0 ] ; then echo >&2 "Failed to create claiming working directory ${CLAIMING_DIR}" exit 2 fi fi if [ ! -w "${CLAIMING_DIR}" ] ; then echo >&2 "No write permission in claiming working directory ${CLAIMING_DIR}" exit 2 fi if [ ! -f "${CLAIMING_DIR}/private.pem" ] ; then echo >&2 "Generating private/public key for the first time." if ! openssl genrsa -out "${CLAIMING_DIR}/private.pem" 2048 ; then echo >&2 "Failed to generate private/public key pair." exit 2 fi fi if [ ! -f "${CLAIMING_DIR}/public.pem" ] ; then echo >&2 "Extracting public key from private key." if ! openssl rsa -in "${CLAIMING_DIR}/private.pem" -outform PEM -pubout -out "${CLAIMING_DIR}/public.pem" ; then echo >&2 "Failed to extract public key." exit 2 fi fi TARGET_URL="${URL_BASE}/api/v1/spaces/nodes/${ID}" # shellcheck disable=SC2002 KEY=$(cat "${CLAIMING_DIR}/public.pem" | tr '\n' '!' | sed -e 's/!/\\n/g') # shellcheck disable=SC2001 [ -n "$ROOMS" ] && ROOMS=\"$(echo "$ROOMS" | sed s'/,/", "/g')\" cat > "${CLAIMING_DIR}/tmpin.txt" <&2 "Failed to connect to ${URL_BASE}" rm -f "${CLAIMING_DIR}/tmpout.txt" exit 4 fi HTTP_STATUS_CODE=$(grep "HTTP" "${CLAIMING_DIR}/tmpout.txt" | awk -F " " '{print $2}') if [ "${HTTP_STATUS_CODE}" -ne 204 ] ; then ERROR_MESSAGE=$(grep "\"errorMsgKey\":" "${CLAIMING_DIR}/tmpout.txt" | awk -F "errorMsgKey\":\"" '{print $2}' | awk -F "\"" '{print $1}') case ${ERROR_MESSAGE} in "ErrInvalidNodeID") EXIT_CODE=6 ;; "ErrInvalidNodeName") EXIT_CODE=7 ;; "ErrInvalidRoomID") EXIT_CODE=8 ;; "ErrInvalidPublicKey") EXIT_CODE=9 ;; "ErrForbidden") EXIT_CODE=10 ;; "ErrAlreadyClaimed") EXIT_CODE=11 ;; "ErrProcessingClaim") EXIT_CODE=12 ;; "ErrInternalServerError") EXIT_CODE=13 ;; "ErrGatewayTimeout") EXIT_CODE=14 ;; "ErrServiceUnavailable") EXIT_CODE=15 ;; *) EXIT_CODE=5 ;; esac echo >&2 "Failed to claim node." rm -f "${CLAIMING_DIR}/tmpout.txt" exit $EXIT_CODE fi rm -f "${CLAIMING_DIR}/tmpout.txt" echo -n "${ID}" >"${CLAIMING_DIR}/claimed_id" rm -f "${CLAIMING_DIR}/token" echo >&2 "Node was successfully claimed."