Files
securityonion/salt/influxdb/tools/sbin/so-influxdb-manage
2023-05-01 15:21:31 -04:00

286 lines
8.2 KiB
Bash

#!/bin/bash
# Copyright Security Onion Solutions LLC and/or licensed to Security Onion Solutions LLC under one
# or more contributor license agreements. Licensed under the Elastic License 2.0 as shown at
# https://securityonion.net/license; you may not use this file except in compliance with the
# Elastic License 2.0.
. /usr/sbin/so-common
usage() {
echo "Usage: $0 <operation> [args]"
echo ""
echo "Supported Operations:"
echo " dashboardpath Returns the URL path for a dashboard, requires: <name-of-dashboard>"
echo " export Exports all templates to stdout"
echo " setup Loads all templates and creates all required buckets"
echo " userlist Lists users"
echo " useradd Adds a new user, requires: <email>"
echo " userdel Removes an existing user, requires: <email>"
echo " userenable Enables a user, requires: <email>"
echo " userdisable Disables a user, requires: <email>"
echo " userpass Updates a user's password, requires: <email>"
echo " userpromote Promotes a user to admin: <email>"
echo " userdemote Demotes a user from admin: <email>"
echo ""
echo "If required, the password will be read from STDIN."
exit 1
}
if [ $# -lt 1 ]; then
usage
fi
COMMAND=$(basename $0)
OP=$1
shift
set -eo pipefail
log() {
echo -e "$(date) | $COMMAND | $@" >&2
}
check_response() {
response=$1
if [[ "$response" =~ "\"code\":" ]]; then
log "Failed. Check the response for more details.\n$response"
exit 1
fi
}
request() {
curl -skK /opt/so/conf/influxdb/curl.config "https://localhost:8086/api/v2/$@"
}
lookup_user_id() {
email=$1
response=$(request users?limit=100)
check_response "$response"
uid=$(echo "$response" | jq -r ".users[] | select(.name == \"$email\").id")
if [[ -z "$uid" ]]; then
log "User not found"
exit 1
fi
echo "$uid"
}
lookup_stack_id() {
oid=$1
response=$(request "stacks?orgID=$oid&name=Security+Onion")
check_response "$response"
stackid=$(echo "$response" | jq -r ".stacks[0].id")
if [[ -z "$stackid" || "$stackid" == null ]]; then
response=$(request stacks -X POST -d "{\"name\":\"Security Onion\",\"orgID\":\"$oid\"}")
check_response "$response"
stackid=$(echo "$response" | jq -r .id)
fi
echo "$stackid"
}
change_password() {
uid=$1
set +e
test -t 0
if [[ $? == 0 ]]; then
echo "Enter new password:"
fi
set -e
read -rs pass
check_password_and_exit "$pass"
response=$(request users/$uid/password -X POST -d "{\"password\":\"$pass\"}")
check_response "$response"
}
apply_templates() {
oid=$1
stackid=$2
template_objects_array=$3
body="{\"orgID\":\"$oid\",\"stackID\":\"$stackid\",\"templates\":$template_objects_array}"
response=$(request templates/apply -X POST -d "$body")
check_response "$response"
}
setup_bucket() {
oid=$1
name=$2
age=$3
shardduration=$4
response=$(request "buckets?orgID=$oid&name=$name")
bucketid=$(echo "$response" | jq -r ".buckets[0].id")
if [[ -z "$bucketid" || "$bucketid" == null ]]; then
response=$(request buckets -X POST -d "{\"name\":\"$name\",\"orgID\":\"$oid\"}")
check_response "$response"
bucketid=$(echo "$response" | jq -r .id)
fi
response=$(request buckets/$bucketid -X PATCH -d "{\"name\":\"$name\",\"retentionRules\":[{\"everySeconds\":$age,\"shardGroupDurationSeconds\":$shardduration,\"type\":\"expire\"}]}")
check_response "$response"
}
lookup_org_id_with_wait() {
max_attempts=30
attempts=0
wait=10
while [[ $attempts -lt $max_attempts ]]; do
response=$(request orgs?org=Security+Onion)
oid=$(echo "$response" | jq -r ".orgs[] | select(.name == \"Security Onion\").id")
if [[ -z $oid ]]; then
attempts=$((attempts+1))
log "Server does not appear to be running or fully initialized - will try again in $wait seconds ($attempts / $max_attempts)"
sleep $wait
else
echo "$oid"
return
fi
done
log "Server has not started after $max_attempts attempts - aborting"
exit 1
}
oid=$(lookup_org_id_with_wait)
case "$OP" in
setup)
log "Ensuring organization is setup correctly"
# Load templates if at least one has been modified since the last setup
newest=$(ls -1t /opt/so/conf/influxdb/templates/ | head -1)
if [ /opt/so/conf/influxdb/templates/$newest -nt /opt/so/conf/influxdb/last_template_setup ]; then
log "Updating templates"
stackid=$(lookup_stack_id "$oid")
for file in /opt/so/conf/influxdb/templates/*; do
if [[ "$templates_array" != "" ]]; then
templates_array="$templates_array,"
fi
template=$(cat "$file")
templates_array="$templates_array{\"contents\":$template}"
done
apply_templates "$oid" "$stackid" "[$templates_array]"
echo $(date) > /opt/so/conf/influxdb/last_template_setup
else
log "Templates have not been modified since last setup"
fi
# Setup buckets and retention periods if at least one has been modified since the last setup
if [ /opt/so/conf/influxdb/buckets.json -nt /opt/so/conf/influxdb/last_bucket_setup ]; then
log "Updating buckets and retention periods"
for rp in so_short_term so_long_term; do
bucket=telegraf/$rp
log "Ensuring bucket is created and configured; bucket=$bucket"
age=$(cat /opt/so/conf/influxdb/buckets.json | jq -r .$rp.duration)
shard_duration=$(cat /opt/so/conf/influxdb/buckets.json | jq -r .$rp.shard_duration)
setup_bucket "$oid" "$bucket" "$age" "$shard_duration"
done
echo $(date) > /opt/so/conf/influxdb/last_bucket_setup
else
log "Buckets have not been modified since last setup"
fi
;;
userlist)
log "Listing existing users"
response=$(request users)
check_response "$response"
echo "$response" | jq -r '.users[] | "\(.id): \(.name) (\(.status))"'
;;
useradd)
[ $# -ne 1 ] && usage
email=$1
log "Adding new user; email=$email"
response=$(request users -X POST -d "{\"name\":\"$email\"}")
check_response "$response"
uid=$(echo "$response" | jq -r .id)
log "Adding new user to organization"
response=$(request orgs/$oid/members -X POST -d "{\"id\":\"$uid\"}")
check_response "$response"
change_password "$uid"
;;
userpass)
[ $# -ne 1 ] && usage
email=$1
log "Updating user password; email=$email"
uid=$(lookup_user_id "$email")
change_password "$uid"
;;
userdel)
[ $# -ne 1 ] && usage
email=$1
log "Deleting user; email=$email"
uid=$(lookup_user_id "$email")
response=$(request users/$uid -X DELETE)
check_response "$response"
;;
userenable)
[ $# -ne 1 ] && usage
email=$1
log "Enabling user; email=$email"
uid=$(lookup_user_id "$email")
response=$(request users/$uid -X PATCH -d "{\"name\":\"$email\",\"status\":\"active\"}")
check_response "$response"
;;
userdisable)
[ $# -ne 1 ] && usage
email=$1
log "Disabling user; email=$email"
uid=$(lookup_user_id "$email")
response=$(request users/$uid -X PATCH -d "{\"name\":\"$email\",\"status\":\"inactive\"}")
check_response "$response"
;;
userpromote)
[ $# -ne 1 ] && usage
email=$1
log "Promoting user to admin; email=$email"
uid=$(lookup_user_id "$email")
response=$(request orgs/$oid/members/$uid -X DELETE)
response=$(request orgs/$oid/owners -X POST -d "{\"id\":\"$uid\"}")
check_response "$response"
;;
userdemote)
[ $# -ne 1 ] && usage
email=$1
log "Demoting user from admin; email=$email"
uid=$(lookup_user_id "$email")
response=$(request orgs/$oid/owners/$uid -X DELETE)
response=$(request orgs/$oid/members -X POST -d "{\"id\":\"$uid\"}")
check_response "$response"
;;
export)
log "Exporting all organization templates"
request templates/export -X POST -d "{\"orgIDs\":[{\"orgID\":\"$oid\"}]}" -H "Content-Type: application/json"
;;
dashboardpath)
[ $# -ne 1 ] && usage
name=$1
response=$(request dashboards?limit=100&orgID=$oid)
check_response "$response"
dbid=$(echo "$response" | jq -r ".dashboards[] | select(.name == \"$name\").id")
if [[ -z "$dbid" ]]; then
log "Dashboard not found"
exit 1
fi
echo -n "/influxdb/orgs/$oid/dashboards/$dbid"
;;
*)
usage
;;
esac