Add speedtest cli to Telegraf config

- Install speedtest CLI on cluster leader
- Install speedtest telegraf config on leader
- cleanup hosts in ping list
- Add custom shell script on leader to output speedtest data to influxdb
- improve version checking of Telegraf binary
- bump telegraf version
- allow ' package-latest' to pass ansible-lint
This commit is contained in:
Nathaniel Landau
2022-04-19 09:17:15 -04:00
parent d0be01b337
commit 73419ec0bd
9 changed files with 802 additions and 15 deletions

View File

@@ -14,6 +14,7 @@ skip_list:
- meta-incorrect - meta-incorrect
- role-name - role-name
- ignore-errors - ignore-errors
- package-latest
warn_list: warn_list:
- experimental - experimental

View File

@@ -18,11 +18,11 @@ rules:
quote-type: any quote-type: any
required: false required: false
extra-required: extra-required:
- '^http://' - "^http://"
- '^https://' - "^https://"
- 'ftp://' - "ftp://"
- 'ssh \w.*' - 'ssh \w.*'
- '{{' - "{{"
extra-allowed: [] extra-allowed: []
truthy: truthy:
level: error level: error

View File

@@ -5,8 +5,9 @@ influxdb_version: 1.8.4
nomad_version: 1.2.5 nomad_version: 1.2.5
prometheus_verssion: 1.1.2 prometheus_verssion: 1.1.2
tdarr_installer_version: 2.00.13 tdarr_installer_version: 2.00.13
telegraf_version: 1.21.4 telegraf_version: 1.22.1
traefik_version: "v2.6.0" traefik_version: "v2.6.0"
speedtest_cli_version: "1.1.1"
# ---------------------------------- SERVICE STATIC PORT MAPPINGS # ---------------------------------- SERVICE STATIC PORT MAPPINGS
authelia_port: "9091" authelia_port: "9091"

View File

@@ -43,6 +43,13 @@
- not mac_arm - not mac_arm
fail_msg: "Unable to install Telegraf on this host" fail_msg: "Unable to install Telegraf on this host"
- name: "set variable: Set speedtest download Binary (armv7l)"
ansible.builtin.set_fact:
speedtest_download_file_uri: "https://install.speedtest.net/app/cli/ookla-speedtest-{{ speedtest_cli_version }}-linux-armhf.tgz"
when:
- ansible_os_family == 'Debian'
- ansible_architecture == 'armv7l'
- name: "Install/upgrade Telegraf" - name: "Install/upgrade Telegraf"
block: block:
- name: "set fact: Need telegraf install?" - name: "set fact: Need telegraf install?"
@@ -70,7 +77,7 @@
ignore_errors: true ignore_errors: true
register: current_telegraf_version register: current_telegraf_version
check_mode: false check_mode: false
changed_when: current_telegraf_version.stdout != telegraf_version changed_when: false
when: when:
- telegraph_binary_location is defined - telegraph_binary_location is defined
- not need_telegraf_install - not need_telegraf_install
@@ -81,7 +88,13 @@
when: when:
- telegraph_binary_location is defined - telegraph_binary_location is defined
- not need_telegraf_install - not need_telegraf_install
- current_telegraf_version.stdout != telegraf_version - current_telegraf_version.stdout is version(telegraf_version, '<')
- ansible.builtin.debug:
msg: "Current telegraf version {{ current_telegraf_version.stdout }} is lower than specified {{ telegraf_version }}"
when:
- telegraph_binary_location is defined
- current_telegraf_version.stdout is version(telegraf_version, '<')
- name: install telegraf (MacOS) - name: install telegraf (MacOS)
community.general.homebrew: community.general.homebrew:
@@ -124,7 +137,9 @@
become: true become: true
ansible.builtin.apt: ansible.builtin.apt:
pkg: telegraf pkg: telegraf
state: latest
update_cache: true update_cache: true
only_upgrade: true
notify: restart_telegraf notify: restart_telegraf
when: when:
- ansible_os_family == 'Debian' - ansible_os_family == 'Debian'
@@ -143,6 +158,51 @@
# - need_telegraf_install # - need_telegraf_install
# -------------------------------------------------- Add Telegraf Configs # -------------------------------------------------- Add Telegraf Configs
- name: "Install speedtest"
when: "'pis' in group_names"
block:
- name: "set fact: do we need speedtest installed?"
ansible.builtin.set_fact:
need_speedtest_install: false
- name: Check if speedtest is installed
ansible.builtin.stat:
path: /usr/local/bin/speedtest
register: speedtest_binary_file_location
- name: "set fact: do we need a speedtest install"
ansible.builtin.set_fact:
need_speedtest_install: true
when:
- not speedtest_binary_file_location.stat.exists
- name: Check current version of speedtest
ansible.builtin.shell: /usr/local/bin/speedtest --version | head -n1 | awk '{print $4}' | grep -oE '[0-9]+\.[0-9]+\.[0-9]+'
ignore_errors: true
register: current_speedtest_version
check_mode: false
changed_when: false
when:
- not need_speedtest_install
- name: "set fact: do we need a speedtest install"
ansible.builtin.set_fact:
need_speedtest_install: true
when:
- not need_speedtest_install
- current_speedtest_version.stdout is version(speedtest_cli_version, '<')
- name: "Install speedtest (pi)"
become: true
ansible.builtin.unarchive:
src: "{{ speedtest_download_file_uri }}"
dest: /usr/local/bin
remote_src: true
when:
- need_speedtest_install
- ansible_os_family == 'Debian'
- ansible_architecture == 'armv7l'
- name: "Configure Telegraf" - name: "Configure Telegraf"
block: block:
- name: "Ensure {{ telegraph_config_location }} exists" - name: "Ensure {{ telegraph_config_location }} exists"
@@ -176,6 +236,7 @@
mode: "644" mode: "644"
loop: loop:
- { src: "telegraf/leader.conf.j2", dest: "{{ telegraph_config_location }}/telegraf.d/leader.conf" } - { src: "telegraf/leader.conf.j2", dest: "{{ telegraph_config_location }}/telegraf.d/leader.conf" }
- { src: "telegraf/speedtest.conf.j2", dest: "{{ telegraph_config_location }}/telegraf.d/speedtest.conf" }
- { src: "telegraf/pingHosts.conf.j2", dest: "{{ telegraph_config_location }}/telegraf.d/pingHosts.conf" } - { src: "telegraf/pingHosts.conf.j2", dest: "{{ telegraph_config_location }}/telegraf.d/pingHosts.conf" }
when: when:
- is_cluster_leader - is_cluster_leader
@@ -192,6 +253,17 @@
when: when:
- inventory_hostname != 'synology' - inventory_hostname != 'synology'
- name: Copy speedtest script
become: true
ansible.builtin.template:
src: "scripts/telegraf_speedtest.sh.j2"
dest: "/usr/local/bin/telegraf_speedtest.sh"
mode: 0755
owner: "{{ ansible_user_uid }}"
group: "{{ ansible_user_gid }}"
when:
- is_cluster_leader
- name: Reset file ownership - name: Reset file ownership
become: true become: true
ansible.builtin.file: ansible.builtin.file:

View File

@@ -17,4 +17,4 @@ if _uname=$(command -v uname); then
fi fi
# Print output # Print output
printf "exec ip_external=%s,cpu_temp=%s" "\"${EXTERNAL_IP}\"" "${TEMP}" printf 'exec ip_external="%s",cpu_temp=%s' "${EXTERNAL_IP}" "${TEMP}"

View File

@@ -0,0 +1,710 @@
#!/usr/bin/env bash
_mainScript_() {
if ! command -v /usr/local/bin/speedtest &>/dev/null; then
error "Speedtest is not installed"
_safeExit_ 1
elif ! command -v /usr/bin/jq &>/dev/null; then
error "JQ is not installed"
_safeExit_ 1
fi
declare -a RESPONSE=()
mapfile -t RESPONSE < <(/usr/local/bin/speedtest -f json | /usr/bin/jq -r '.isp, .server.host, .ping.latency, .download.bandwidth, .upload.bandwidth')
ISP="$(printf "%s" "${RESPONSE[0]}" | sed -E 's/ /_/g')"
SERVER="$(printf "%s" "${RESPONSE[1]}" | sed -E 's/ /_/g')"
PING="${RESPONSE[2]}"
DOWNLOAD="${RESPONSE[3]}"
UPLOAD="${RESPONSE[4]}"
# Print output
printf 'exec,speedtest-server=%s speedtest-isp="%s",ping=%s,download=%s,upload=%s' \
"${SERVER}" \
"${ISP}" \
"${PING}" \
"${DOWNLOAD}" \
"${UPLOAD}"
}
# end _mainScript_
# ################################## Flags and defaults
# Required variables
LOGFILE="${HOME}/logs/$(basename "$0").log"
QUIET=false
LOGLEVEL=ERROR
VERBOSE=false
FORCE=false
DRYRUN=false
declare -a ARGS=()
# Script specific
QUIET=true
if [ -d "/mnt/pi-cluster/logs" ]; then
LOGFILE="/mnt/pi-cluster/logs/$(basename "$0").log"
else
LOGFILE="${HOME}/logs/$(basename "$0").log"
fi
# ################################## Custom utility functions (Pasted from repository)
# ################################## Functions required for this template to work
_setColors_() {
# DESC:
# Sets colors use for alerts.
# ARGS:
# None
# OUTS:
# None
# USAGE:
# printf "%s\n" "${blue}Some text${reset}"
if tput setaf 1 >/dev/null 2>&1; then
bold=$(tput bold)
underline=$(tput smul)
reverse=$(tput rev)
reset=$(tput sgr0)
if [[ $(tput colors) -ge 256 ]] >/dev/null 2>&1; then
white=$(tput setaf 231)
blue=$(tput setaf 38)
yellow=$(tput setaf 11)
green=$(tput setaf 82)
red=$(tput setaf 9)
purple=$(tput setaf 171)
gray=$(tput setaf 250)
else
white=$(tput setaf 7)
blue=$(tput setaf 38)
yellow=$(tput setaf 3)
green=$(tput setaf 2)
red=$(tput setaf 9)
purple=$(tput setaf 13)
gray=$(tput setaf 7)
fi
else
bold="\033[4;37m"
reset="\033[0m"
underline="\033[4;37m"
# shellcheck disable=SC2034
reverse=""
white="\033[0;37m"
blue="\033[0;34m"
yellow="\033[0;33m"
green="\033[1;32m"
red="\033[0;31m"
purple="\033[0;35m"
gray="\033[0;37m"
fi
}
_alert_() {
# DESC:
# Controls all printing of messages to log files and stdout.
# ARGS:
# $1 (required) - The type of alert to print
# (success, header, notice, dryrun, debug, warning, error,
# fatal, info, input)
# $2 (required) - The message to be printed to stdout and/or a log file
# $3 (optional) - Pass '${LINENO}' to print the line number where the _alert_ was triggered
# OUTS:
# stdout: The message is printed to stdout
# log file: The message is printed to a log file
# USAGE:
# [_alertType] "[MESSAGE]" "${LINENO}"
# NOTES:
# - The colors of each alert type are set in this function
# - For specified alert types, the funcstac will be printed
local _color
local _alertType="${1}"
local _message="${2}"
local _line="${3:-}" # Optional line number
[[ $# -lt 2 ]] && fatal 'Missing required argument to _alert_'
if [[ -n ${_line} && ${_alertType} =~ ^(fatal|error) && ${FUNCNAME[2]} != "_trapCleanup_" ]]; then
_message="${_message} ${gray}(line: ${_line}) $(_printFuncStack_)"
elif [[ -n ${_line} && ${FUNCNAME[2]} != "_trapCleanup_" ]]; then
_message="${_message} ${gray}(line: ${_line})"
elif [[ -z ${_line} && ${_alertType} =~ ^(fatal|error) && ${FUNCNAME[2]} != "_trapCleanup_" ]]; then
_message="${_message} ${gray}$(_printFuncStack_)"
fi
if [[ ${_alertType} =~ ^(error|fatal) ]]; then
_color="${bold}${red}"
elif [ "${_alertType}" == "info" ]; then
_color="${gray}"
elif [ "${_alertType}" == "warning" ]; then
_color="${red}"
elif [ "${_alertType}" == "success" ]; then
_color="${green}"
elif [ "${_alertType}" == "debug" ]; then
_color="${purple}"
elif [ "${_alertType}" == "header" ]; then
_color="${bold}${white}${underline}"
elif [ "${_alertType}" == "notice" ]; then
_color="${bold}"
elif [ "${_alertType}" == "input" ]; then
_color="${bold}${underline}"
elif [ "${_alertType}" = "dryrun" ]; then
_color="${blue}"
else
_color=""
fi
_writeToScreen_() {
("${QUIET}") && return 0 # Print to console when script is not 'quiet'
[[ ${VERBOSE} == false && ${_alertType} =~ ^(debug|verbose) ]] && return 0
if ! [[ -t 1 || -z ${TERM:-} ]]; then # Don't use colors on non-recognized terminals
_color=""
reset=""
fi
if [[ ${_alertType} == header ]]; then
printf "${_color}%s${reset}\n" "${_message}"
else
printf "${_color}[%7s] %s${reset}\n" "${_alertType}" "${_message}"
fi
}
_writeToScreen_
_writeToLog_() {
[[ ${_alertType} == "input" ]] && return 0
[[ ${LOGLEVEL} =~ (off|OFF|Off) ]] && return 0
if [ -z "${LOGFILE:-}" ]; then
LOGFILE="$(pwd)/$(basename "$0").log"
fi
[ ! -d "$(dirname "${LOGFILE}")" ] && mkdir -p "$(dirname "${LOGFILE}")"
[[ ! -f ${LOGFILE} ]] && touch "${LOGFILE}"
# Don't use colors in logs
local _cleanmessage
_cleanmessage="$(printf "%s" "${_message}" | sed -E 's/(\x1b)?\[(([0-9]{1,2})(;[0-9]{1,3}){0,2})?[mGK]//g')"
# Print message to log file
printf "%s [%7s] %s %s\n" "$(date +"%b %d %R:%S")" "${_alertType}" "[$(/bin/hostname)]" "${_cleanmessage}" >>"${LOGFILE}"
}
# Write specified log level data to logfile
case "${LOGLEVEL:-ERROR}" in
ALL | all | All)
_writeToLog_
;;
DEBUG | debug | Debug)
_writeToLog_
;;
INFO | info | Info)
if [[ ${_alertType} =~ ^(error|fatal|warning|info|notice|success) ]]; then
_writeToLog_
fi
;;
NOTICE | notice | Notice)
if [[ ${_alertType} =~ ^(error|fatal|warning|notice|success) ]]; then
_writeToLog_
fi
;;
WARN | warn | Warn)
if [[ ${_alertType} =~ ^(error|fatal|warning) ]]; then
_writeToLog_
fi
;;
ERROR | error | Error)
if [[ ${_alertType} =~ ^(error|fatal) ]]; then
_writeToLog_
fi
;;
FATAL | fatal | Fatal)
if [[ ${_alertType} =~ ^fatal ]]; then
_writeToLog_
fi
;;
OFF | off)
return 0
;;
*)
if [[ ${_alertType} =~ ^(error|fatal) ]]; then
_writeToLog_
fi
;;
esac
} # /_alert_
error() { _alert_ error "${1}" "${2:-}"; }
warning() { _alert_ warning "${1}" "${2:-}"; }
notice() { _alert_ notice "${1}" "${2:-}"; }
info() { _alert_ info "${1}" "${2:-}"; }
success() { _alert_ success "${1}" "${2:-}"; }
dryrun() { _alert_ dryrun "${1}" "${2:-}"; }
input() { _alert_ input "${1}" "${2:-}"; }
header() { _alert_ header "${1}" "${2:-}"; }
debug() { _alert_ debug "${1}" "${2:-}"; }
fatal() {
_alert_ fatal "${1}" "${2:-}"
_safeExit_ "1"
}
# shellcheck disable=SC1009,SC1054,SC1056,SC1072,SC1073,SC1083
{% raw %}
_printFuncStack_() {
# DESC:
# Prints the function stack in use. Used for debugging, and error reporting.
# ARGS:
# None
# OUTS:
# stdout: Prints [function]:[file]:[line]
# NOTE:
# Does not print functions from the alert class
local _i
declare -a _funcStackResponse=()
for ((_i = 1; _i < ${#BASH_SOURCE[@]}; _i++)); do
case "${FUNCNAME[${_i}]}" in
_alert_ | _trapCleanup_ | fatal | error | warning | notice | info | debug | dryrun | header | success)
continue
;;
*)
_funcStackResponse+=("${FUNCNAME[${_i}]}:$(basename "${BASH_SOURCE[${_i}]}"):${BASH_LINENO[_i - 1]}")
;;
esac
done
printf "( "
printf %s "${_funcStackResponse[0]}"
printf ' < %s' "${_funcStackResponse[@]:1}"
printf ' )\n'
}
{% endraw %}
_safeExit_() {
# DESC:
# Cleanup and exit from a script
# ARGS:
# $1 (optional) - Exit code (defaults to 0)
# OUTS:
# None
if [[ -d ${SCRIPT_LOCK:-} ]]; then
if command rm -rf "${SCRIPT_LOCK}"; then
debug "Removing script lock"
else
warning "Script lock could not be removed. Try manually deleting ${yellow}'${SCRIPT_LOCK}'"
fi
fi
if [[ -n ${TMP_DIR:-} && -d ${TMP_DIR:-} ]]; then
if [[ ${1:-} == 1 && -n "$(ls "${TMP_DIR}")" ]]; then
command rm -r "${TMP_DIR}"
else
command rm -r "${TMP_DIR}"
debug "Removing temp directory"
fi
fi
trap - INT TERM EXIT
exit "${1:-0}"
}
_trapCleanup_() {
# DESC:
# Log errors and cleanup from script when an error is trapped. Called by 'trap'
# ARGS:
# $1: Line number where error was trapped
# $2: Line number in function
# $3: Command executing at the time of the trap
# $4: Names of all shell functions currently in the execution call stack
# $5: Scriptname
# $6: $BASH_SOURCE
# USAGE:
# trap '_trapCleanup_ ${LINENO} ${BASH_LINENO} "${BASH_COMMAND}" "${FUNCNAME[*]}" "${0}" "${BASH_SOURCE[0]}"' EXIT INT TERM SIGINT SIGQUIT SIGTERM ERR
# OUTS:
# Exits script with error code 1
local _line=${1:-} # LINENO
local _linecallfunc=${2:-}
local _command="${3:-}"
local _funcstack="${4:-}"
local _script="${5:-}"
local _sourced="${6:-}"
# Replace the cursor in-case 'tput civis' has been used
tput cnorm
if declare -f "fatal" &>/dev/null && declare -f "_printFuncStack_" &>/dev/null; then
_funcstack="'$(printf "%s" "${_funcstack}" | sed -E 's/ / < /g')'"
if [[ ${_script##*/} == "${_sourced##*/}" ]]; then
fatal "${7:-} command: '${_command}' (line: ${_line}) [func: $(_printFuncStack_)]"
else
fatal "${7:-} command: '${_command}' (func: ${_funcstack} called at line ${_linecallfunc} of '${_script##*/}') (line: ${_line} of '${_sourced##*/}') "
fi
else
printf "%s\n" "Fatal error trapped. Exiting..."
fi
if declare -f _safeExit_ &>/dev/null; then
_safeExit_ 1
else
exit 1
fi
}
_makeTempDir_() {
# DESC:
# Creates a temp directory to house temporary files
# ARGS:
# $1 (Optional) - First characters/word of directory name
# OUTS:
# Sets $TMP_DIR variable to the path of the temp directory
# USAGE:
# _makeTempDir_ "$(basename "$0")"
[ -d "${TMP_DIR:-}" ] && return 0
if [ -n "${1:-}" ]; then
TMP_DIR="${TMPDIR:-/tmp/}${1}.${RANDOM}.${RANDOM}.$$"
else
TMP_DIR="${TMPDIR:-/tmp/}$(basename "$0").${RANDOM}.${RANDOM}.${RANDOM}.$$"
fi
(umask 077 && mkdir "${TMP_DIR}") || {
fatal "Could not create temporary directory! Exiting."
}
debug "\$TMP_DIR=${TMP_DIR}"
}
# shellcheck disable=SC2120
_acquireScriptLock_() {
# DESC:
# Acquire script lock to prevent running the same script a second time before the
# first instance exits
# ARGS:
# $1 (optional) - Scope of script execution lock (system or user)
# OUTS:
# exports $SCRIPT_LOCK - Path to the directory indicating we have the script lock
# Exits script if lock cannot be acquired
# NOTE:
# If the lock was acquired it's automatically released in _safeExit_()
local _lockDir
if [[ ${1:-} == 'system' ]]; then
_lockDir="${TMPDIR:-/tmp/}$(basename "$0").lock"
else
_lockDir="${TMPDIR:-/tmp/}$(basename "$0").${UID}.lock"
fi
if command mkdir "${_lockDir}" 2>/dev/null; then
readonly SCRIPT_LOCK="${_lockDir}"
debug "Acquired script lock: ${yellow}${SCRIPT_LOCK}${purple}"
else
if declare -f "_safeExit_" &>/dev/null; then
error "Unable to acquire script lock: ${yellow}${_lockDir}${red}"
fatal "If you trust the script isn't running, delete the lock dir"
else
printf "%s\n" "ERROR: Could not acquire script lock. If you trust the script isn't running, delete: ${_lockDir}"
exit 1
fi
fi
}
_setPATH_() {
# DESC:
# Add directories to $PATH so script can find executables
# ARGS:
# $@ - One or more paths
# OPTS:
# -x - Fail if directories are not found
# OUTS:
# 0: Success
# 1: Failure
# Adds items to $PATH
# USAGE:
# _setPATH_ "/usr/local/bin" "${HOME}/bin" "$(npm bin)"
[[ $# == 0 ]] && fatal "Missing required argument to ${FUNCNAME[0]}"
local opt
local OPTIND=1
local _failIfNotFound=false
while getopts ":xX" opt; do
case ${opt} in
x | X) _failIfNotFound=true ;;
*)
{
error "Unrecognized option '${1}' passed to _backupFile_" "${LINENO}"
return 1
}
;;
esac
done
shift $((OPTIND - 1))
local _newPath
for _newPath in "$@"; do
if [ -d "${_newPath}" ]; then
if ! printf "%s" "${PATH}" | grep -Eq "(^|:)${_newPath}($|:)"; then
if PATH="${_newPath}:${PATH}"; then
debug "Added '${_newPath}' to PATH"
else
debug "'${_newPath}' already in PATH"
fi
else
debug "_setPATH_: '${_newPath}' already exists in PATH"
fi
else
debug "_setPATH_: can not find: ${_newPath}"
if [[ ${_failIfNotFound} == true ]]; then
return 1
fi
continue
fi
done
return 0
}
_useGNUutils_() {
# DESC:
# Add GNU utilities to PATH to allow consistent use of sed/grep/tar/etc. on MacOS
# ARGS:
# None
# OUTS:
# 0 if successful
# 1 if unsuccessful
# PATH: Adds GNU utilities to the path
# USAGE:
# # if ! _useGNUUtils_; then exit 1; fi
# NOTES:
# GNU utilities can be added to MacOS using Homebrew
! declare -f "_setPATH_" &>/dev/null && fatal "${FUNCNAME[0]} needs function _setPATH_"
if _setPATH_ \
"/usr/local/opt/gnu-tar/libexec/gnubin" \
"/usr/local/opt/coreutils/libexec/gnubin" \
"/usr/local/opt/gnu-sed/libexec/gnubin" \
"/usr/local/opt/grep/libexec/gnubin" \
"/usr/local/opt/findutils/libexec/gnubin" \
"/opt/homebrew/opt/findutils/libexec/gnubin" \
"/opt/homebrew/opt/gnu-sed/libexec/gnubin" \
"/opt/homebrew/opt/grep/libexec/gnubin" \
"/opt/homebrew/opt/coreutils/libexec/gnubin" \
"/opt/homebrew/opt/gnu-tar/libexec/gnubin"; then
return 0
else
return 1
fi
}
_homebrewPath_() {
# DESC:
# Add homebrew bin dir to PATH
# ARGS:
# None
# OUTS:
# 0 if successful
# 1 if unsuccessful
# PATH: Adds homebrew bin directory to PATH
# USAGE:
# # if ! _homebrewPath_; then exit 1; fi
! declare -f "_setPATH_" &>/dev/null && fatal "${FUNCNAME[0]} needs function _setPATH_"
if _uname=$(command -v uname); then
if "${_uname}" | tr '[:upper:]' '[:lower:]' | grep -q 'darwin'; then
if _setPATH_ "/usr/local/bin" "/opt/homebrew/bin"; then
return 0
else
return 1
fi
fi
else
if _setPATH_ "/usr/local/bin" "/opt/homebrew/bin"; then
return 0
else
return 1
fi
fi
}
# shellcheck disable=SC1009,SC1054,SC1056,SC1072,SC1073,SC1083
{% raw %}
_parseOptions_() {
# DESC:
# Iterates through options passed to script and sets variables. Will break -ab into -a -b
# when needed and --foo=bar into --foo bar
# ARGS:
# $@ from command line
# OUTS:
# Sets array 'ARGS' containing all arguments passed to script that were not parsed as options
# USAGE:
# _parseOptions_ "$@"
# Iterate over options
local _optstring=h
declare -a _options
local _c
local i
while (($#)); do
case $1 in
# If option is of type -ab
-[!-]?*)
# Loop over each character starting with the second
for ((i = 1; i < ${#1}; i++)); do
_c=${1:i:1}
_options+=("-${_c}") # Add current char to options
# If option takes a required argument, and it's not the last char make
# the rest of the string its argument
if [[ ${_optstring} == *"${_c}:"* && -n ${1:i+1} ]]; then
_options+=("${1:i+1}")
break
fi
done
;;
# If option is of type --foo=bar
--?*=*) _options+=("${1%%=*}" "${1#*=}") ;;
# add --endopts for --
--) _options+=(--endopts) ;;
# Otherwise, nothing special
*) _options+=("$1") ;;
esac
shift
done
set -- "${_options[@]:-}"
unset _options
# Read the options and set stuff
# shellcheck disable=SC2034
while [[ ${1:-} == -?* ]]; do
case $1 in
# Custom options
# Common options
-h | --help)
_usage_
_safeExit_
;;
--loglevel)
shift
LOGLEVEL=${1}
;;
--logfile)
shift
LOGFILE="${1}"
;;
-n | --dryrun) DRYRUN=true ;;
-v | --verbose) VERBOSE=true ;;
-q | --quiet) QUIET=true ;;
--force) FORCE=true ;;
--endopts)
shift
break
;;
*)
if declare -f _safeExit_ &>/dev/null; then
fatal "invalid option: $1"
else
printf "%s\n" "ERROR: Invalid option: $1"
exit 1
fi
;;
esac
shift
done
if [[ -z ${*} || ${*} == null ]]; then
ARGS=()
else
ARGS+=("$@") # Store the remaining user input as arguments.
fi
}
{% endraw %}
_usage_() {
cat <<USAGE_TEXT
${bold}$(basename "$0") [OPTION]... [FILE]...${reset}
This is a script template. Edit this description to print help to users.
${bold}Options:${reset}
-h, --help Display this help and exit
--loglevel [LEVEL] One of: FATAL, ERROR, WARN, INFO, NOTICE, DEBUG, ALL, OFF
(Default is 'ERROR')
--logfile [FILE] Full PATH to logfile. (Default is '${HOME}/logs/$(basename "$0").log')
-n, --dryrun Non-destructive. Makes no permanent changes.
-q, --quiet Quiet (no output)
-v, --verbose Output more information. (Items echoed to 'verbose')
--force Skip all user interaction. Implied 'Yes' to all actions.
${bold}Example Usage:${reset}
${gray}# Run the script and specify log level and log file.${reset}
$(basename "$0") -vn --logfile "/path/to/file.log" --loglevel 'WARN'
USAGE_TEXT
}
# ################################## INITIALIZE AND RUN THE SCRIPT
# (Comment or uncomment the lines below to customize script behavior)
trap '_trapCleanup_ ${LINENO} ${BASH_LINENO} "${BASH_COMMAND}" "${FUNCNAME[*]}" "${0}" "${BASH_SOURCE[0]}"' EXIT INT TERM SIGINT SIGQUIT SIGTERM
# Trap errors in subshells and functions
set -o errtrace
# Exit on error. Append '||true' if you expect an error
set -o errexit
# Use last non-zero exit code in a pipeline
set -o pipefail
# Confirm we have BASH greater than v4
[ "${BASH_VERSINFO:-0}" -ge 4 ] || {
printf "%s\n" "ERROR: BASH_VERSINFO is '${BASH_VERSINFO:-0}'. This script requires BASH v4 or greater."
exit 1
}
# Make `for f in *.txt` work when `*.txt` matches zero files
shopt -s nullglob globstar
# Set IFS to preferred implementation
IFS=$' \n\t'
# Run in debug mode
# set -o xtrace
# Initialize color constants
_setColors_
# Disallow expansion of unset variables
set -o nounset
# Force arguments when invoking the script
# [[ $# -eq 0 ]] && _parseOptions_ "-h"
# Parse arguments passed to script
_parseOptions_ "$@"
# Create a temp directory '$TMP_DIR'
# _makeTempDir_ "$(basename "$0")"
# Acquire script lock
# _acquireScriptLock_
# Add Homebrew bin directory to PATH (MacOS)
# _homebrewPath_
# Source GNU utilities from Homebrew (MacOS)
# _useGNUutils_
# Run the main logic script
_mainScript_
# Exit cleanly
_safeExit_

View File

@@ -35,7 +35,7 @@
{% if 'pis' in group_names %} {% if 'pis' in group_names %}
logtarget = "file" ## destination logs can be one of "file" or "stderr" logtarget = "file" ## destination logs can be one of "file" or "stderr"
logfile = "/var/log/telegraf/telegraf.log" logfile = "/var/log/telegraf/telegraf.log"
logfile_rotation_interval = "1d" logfile_rotation_interval = "24h"
# logfile_rotation_max_size = "0MB" # logfile_rotation_max_size = "0MB"
logfile_rotation_max_archives = 2 logfile_rotation_max_archives = 2
{% elif 'macs' in group_names %} {% elif 'macs' in group_names %}

View File

@@ -29,14 +29,13 @@
urls = [{% for i in groups['pis'] %}'{{ hostvars[i].ansible_host }}'{% if not loop.last %}, {% endif %}{% endfor %}, urls = [{% for i in groups['pis'] %}'{{ hostvars[i].ansible_host }}'{% if not loop.last %}, {% endif %}{% endfor %},
'10.0.30.6', '10.0.30.6',
'core1.bos1.he.net', 'core1.bos1.he.net',
'core1.lax1.he.net', 'core2.lax1.he.net',
'core1.nyc4.he.net', 'core1.nyc4.he.net',
'core1.oma1.he.net', 'core2.oma1.he.net',
'core1.chi1.he.net', 'core1.chi1.he.net',
'core1.dal1.he.net', 'core1.dal1.he.net',
'core1.den1.he.net', 'core1.den1.he.net',
'core1.mia1.he.net', 'core2.mia1.he.net',
'core1.bna1.he.net',
'core1.phx1.he.net', 'core1.phx1.he.net',
'core1.sea1.he.net', 'core1.sea1.he.net',
'core1.blp1.he.net', 'core1.blp1.he.net',
@@ -49,10 +48,8 @@
'core1.zrh3.he.net', 'core1.zrh3.he.net',
'core2.sao1.he.net', 'core2.sao1.he.net',
'core1.sin1.he.net', 'core1.sin1.he.net',
'core1.kpb1.he.net',
'core1.nbo1.he.net', 'core1.nbo1.he.net',
'core1.tpe1.he.net', 'core1.tpe1.he.net',
'core1.sto1.he.net',
'core1.ymq1.he.net', 'core1.ymq1.he.net',
'core2.syd1.he.net' 'core2.syd1.he.net'
] ]

View File

@@ -0,0 +1,6 @@
[[inputs.exec]]
commands = ["/usr/local/bin/telegraf_speedtest.sh"]
interval = "10m"
timeout = "1m"
name_suffix = "_speedtest"
data_format = "influx"