Last active
April 25, 2024 18:43
-
-
Save bahamat/b77284bc08d772308ae7d1c49c53cecb to your computer and use it in GitHub Desktop.
Shell script to pull CMON metrics from Joyent Triton (https://www.joyent.com/triton)
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
#!/bin/bash | |
# shellcheck disable=SC2154 | |
if [[ -n "$TRACE" ]]; then | |
export PS4='[\D{%FT%TZ}] ${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' | |
set -o xtrace | |
fi | |
export PATH=/opt/pkg/bin:/opt/local/bin:/opt/custom/bin:$PATH | |
call() { | |
curl --connect-timeout 10 $insecure "${header:--i}" -s --compressed --cert "$cert" --key "$key" "https://${1}/${2}" | |
exit $? | |
} | |
do_genconfig() { | |
local datacenters | |
local dc_names | |
if [[ -n $gz ]]; then | |
printf 'Prometheus does not support discovery of CNs.\n' | |
# shellcheck disable=SC2016 | |
printf 'Use file_sd and `cmon -g targets` instead.\n' | |
exit 1 | |
fi | |
datacenters=$(get_datacenters) | |
# shellcheck disable=SC2207 | |
dc_names=( $(get_dcnames) ) | |
cat << EOF | |
global: | |
scrape_interval: 10s | |
evaluation_interval: 8s | |
# scrape_timeout is set to the global default 10s | |
scrape_configs: | |
- job_name: prometheus | |
scrape_interval: 5s | |
static_configs: | |
- targets: ['localhost:9090'] | |
EOF | |
for dc in "${dc_names[@]}"; do | |
dc_url="$(json -Ma -c "this.key==\"$dc\"" value <<< "$datacenters")" | |
print_prom_job "$dc" "$dc_url" | |
done | |
} | |
do_keys() { | |
keydir=$(get_cmonkeydir) | |
mkdir -p ~/.triton/cmon/"${keydir}" | |
cd ~/.triton/cmon/"${keydir}" || return | |
export SDC_ACCOUNT="$user" | |
triton -p "${profile}" -a "$SDC_ACCOUNT" profile cmon-certgen -y | |
} | |
do_targets() { | |
local dcname | |
local kind='cns' | |
local objs | |
dcname="$(get_dcname)" | |
if [[ -z $gz ]]; then | |
printf 'Prometheus supports triton_sd for containers directly.\n' | |
# shellcheck disable=2016 | |
printf 'Use `cmon genconfig` instead.\n' | |
exit 1 | |
fi | |
# shellcheck disable=2207 | |
objs=( $(call "${socket:?}" "v1/${gz}discover" | json -Ha "$kind" | json -a -o jsony-0) ) | |
# shellcheck disable=2207 | |
targets=( | |
$(for o in "${objs[@]}"; do | |
read -r -a u <<< "$(json -ga server_uuid server_hostname <<< "$o")" | |
printf '{"targets":' | |
printf '["%s.%s"],' "${u[0]}" "$socket" | |
printf '"labels":' | |
printf '{"server_uuid":"%s","hostname":"%s","datacenter":"%s"' "${u[0]}" "${u[1]}" "$dcname" | |
printf '}}\n' | |
done) | |
) | |
t=$(join , "${targets[@]}") | |
printf '[%s]' "$t" | json | |
} | |
get_cmonkeydir () { | |
local url | |
profile_j=$(triton -p "$profile" profile get -j) | |
url=$(json url <<< "$profile_j" | sed -E 's/^https?//g' | tr -d :/ | tr '.' _) | |
echo "${user}@${url}" | |
} | |
get_datacenters() { | |
triton -p "$profile" datacenters -j | |
} | |
get_dcname() { | |
cut -d '.' -f 2 <<< "$socket" | |
} | |
get_dcnames() { | |
local datacenters | |
datacenters="$(get_datacenters)" | |
json -Ma key <<< "$datacenters" | |
} | |
get_profile() { | |
triton -p "$profile" profile get -j | |
} | |
function join { | |
local IFS="$1"; shift; echo "$*"; | |
} | |
parse_cmon_url () { | |
# shellcheck disable=2207 | |
parts=( $(tr -d '/' <<< "$1" | tr ':' ' ') ) | |
echo "${parts[@]}" | |
} | |
print_prom_job () { | |
local dc="$1" | |
local url="$2" | |
# shellcheck disable=2207 | |
local cmon=($(parse_cmon_url "$(triton -a "$user" -p "$profile" -U "$url" services -j | json cmon)")) | |
local scheme="${cmon[0]}" | |
local endpoint="${cmon[1]}" | |
# Not used | |
#local port="${cmon[2]}" | |
cat << EOF | |
- job_name: ${user}_${dc} | |
scheme: ${scheme} | |
tls_config: | |
cert_file: ${cert} | |
key_file: ${key} | |
${config_insecure} | |
triton_sd_configs: | |
- account: ${user} | |
dns_suffix: ${endpoint} | |
endpoint: ${endpoint} | |
version: 1 | |
tls_config: | |
cert_file: ${cert} | |
key_file: ${key} | |
${config_insecure} | |
relabel_configs: | |
- source_labels: [__meta_triton_machine_alias] | |
target_label: alias | |
- source_labels: [__meta_triton_machine_id] | |
target_label: zonename | |
- source_labels: [__param_datacenter_name] | |
target_label: datacenter_name | |
replacement: ${dc} | |
- source_labels: [__param_account] | |
target_label: account_name | |
replacement: ${user} | |
EOF | |
} | |
strip_proto() { | |
#sed 's#https://##' <<< "$1" | |
echo "${1/*:\/\/}" | |
} | |
usage () { | |
printf '%s [ -g ] [ -p profile ] [ -c certficate ] [ -k key ] targets\n' "${0##*/}" | |
printf '%s [ -g ] [ -p profile ] [ -c certficate ] [ -k key ] [ -G groups ] discover\n' "${0##*/}" | |
printf '%s [ -p profile ] [ -c certficate ] [ -k key ] metrics vm_uuid|server_uuid\n' "${0##*/}" | |
printf '%s [ -p profile ] -u username keysetup\n' "${0##*/}" | |
printf '%s [ -p profile ] -u username genconfig\n' "${0##*/}" | |
printf '\n -g\tDiscover Compute Nodes (gz metrics)\n' | |
exit "$1" | |
} | |
while getopts "e:c:k:p:u:G:ghiH" options; do | |
case $options in | |
H) header=' ';; | |
c) cert="${OPTARG}";; | |
e) socket="${OPTARG}";; | |
g) gz="gz/";; | |
G) groups="?groups=${OPTARG}" ;; | |
i) | |
insecure="-k"; | |
config_insecure="insecure_skip_verify: true"; | |
;; | |
k) key="${OPTARG}";; | |
p) profile="${OPTARG}";; | |
u) user="${OPTARG}";; | |
h) usage 0;; | |
*) usage 1;; | |
esac | |
done | |
shift $(( OPTIND - 1 )) | |
if [[ -z $user ]] || [[ -z $socket ]]; then | |
# Default profile | |
profile_json=$(get_profile) | |
fi | |
if [[ -n $profile ]]; then | |
profile=$(json name <<< "$profile_json") | |
fi | |
if [[ -z $user ]]; then | |
user=$(json account <<< "$profile_json") | |
fi | |
if [[ -z $socket ]]; then | |
socket=$(triton -p "$profile" services -j | json cmon) | |
fi | |
socket=$(strip_proto "$socket") | |
action="$1" | |
inst="$2" | |
if [[ -z $cert ]] || [[ -z $key ]]; then | |
keydir=$(get_cmonkeydir) | |
fi | |
# Use certs generated by triton profile cmon-certgen | |
if [[ -z $cert ]]; then | |
cert=~/.triton/cmon/"${keydir}"/cmon-${user}-cert.pem | |
fi | |
if [[ -z $key ]]; then | |
key=~/.triton/cmon/"${keydir}"/cmon-${user}-key.pem | |
fi | |
if [[ -z $socket ]]; then | |
printf 'Profile "%s" does not list a cmon endpoint\n' "$profile" | |
exit 1 | |
fi | |
case $action in | |
disco|discover) | |
call "${socket:?}" "v1/${gz}discover${groups}" | |
;; | |
metrics) | |
call "${inst:?}.${socket}" metrics | |
;; | |
certgen|keysetup) | |
do_keys | |
;; | |
targets) | |
do_targets | |
;; | |
genconfig) | |
if [[ -z $user ]]; then | |
printf 'user is required for config generation\n' | |
usage 1 | |
fi | |
do_genconfig; | |
;; | |
*) | |
printf 'Not implemented\n' | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
All options