Files
oci-wrap/oci.sh
my99problems 1cea7bec60 usage display
2025-10-26 15:50:16 +01:00

347 lines
11 KiB
Bash
Executable File

#!/bin/bash
################# FUNCTION TO DISPLAY HELP
show_help() {
echo "Usage: oci.sh [OPTION]"
echo "Options:"
echo " -lu List all users in the tenancy"
echo " -lc List all compartments in the tenancy"
echo " -lr List all running instances in the tenancy"
echo " -la List and parse audit events for a specific user (filtered by email)///ONLY WORKS FOR OWN DATA"
echo " --usage Display usage and cost summary for the current month"
echo " -h Show this help message"
}
SEP="echo -------------------------------"
activate_venv() {
$SEP
echo "Activating oci-cli venv..."
source $HOME/oci-cli/oci/bin/activate
sleep 0.5
$SEP
}
test_connection() {
echo "Testing Oci Connection...."
$SEP
oci iam region list > /dev/null
STATUS=$?
if [[ $STATUS -eq 0 ]]; then
echo "Test connection to oci completed succesfully!"
else
echo "Something went wrong, check oci-cli config file"
exit 1
fi
}
################# LIST ALL USERS IN TENANCY
list_users_lite() {
TENANCY_ID=$(oci iam compartment list --query 'data[0]."compartment-id"' --raw-output)
echo "Listing users in tenancy: $TENANCY_ID"
$SEP
oci iam user list --compartment-id $TENANCY_ID | grep email | awk -F '"' '{print $4}' | grep -v '^$' | paste -sd ',' -
$SEP
}
################# LIST ALL COMPARTMENTS IN TENANCY
list_compartments() {
echo "Listing all compartments in the tenancy"
$SEP
#////////////////TABLE HEADER\\\\\\\\\\\\\\\#########
printf " %-25s | %-12s | %-25s | %-s\n" "Name" "State" "Created By" "Description"
echo "$(printf '%.0s-' {1..130})"
#////////////FETCH AND JQ PARSE\\\\\\\\\\\\\\\#
oci iam compartment list --all --compartment-id-in-subtree true 2>/dev/null | \
jq -r '.data[] |
[
(.name // ""),
(.["lifecycle-state"] // ""),
(.["defined-tags"]["Oracle-Tags"]["CreatedBy"] // "" | split("/")[1] // ""),
(.description // "")
] |
@tsv' | \
awk -F'\t' '{printf " %-25s | %-12s | %-25s | %s\n", $1, $2, $3, $4}'
$SEP
}
################# LIST ALL RUNNING INSTANCES IN TENANCY
list_running_instances() {
echo "Listing all running instances in the tenancy"
$SEP
#////////////FETCH ROOT TENANCY ID FROM CONFIG\\\\\\\\\\\\\\\#
TENANCY_ID=$(grep "^tenancy=" "$HOME/.oci/config" | cut -d'=' -f2)
#////////////LIST INSTANCES FROM ROOT TENANCY\\\\\\\\\\\\\\\#
echo "[ROOT TENANCY]"
oci compute instance list --compartment-id "$TENANCY_ID" --lifecycle-state RUNNING \
--query "data[*].{Name:\"display-name\", State:\"lifecycle-state\", Shape:shape, CreatedBy:\"defined-tags\".\"Oracle-Tags\".\"CreatedBy\", CreatedOn:\"defined-tags\".\"Oracle-Tags\".\"CreatedOn\", OCID:id}" \
--output table 2>/dev/null
#////////////FETCH ALL COMPARTMENTS AND LIST INSTANCES\\\\\\\\\\\\\\\#
oci iam compartment list --all --compartment-id-in-subtree true 2>/dev/null | \
jq -r '.data[] | "\(.id)|\(.name)|\(.description // "")|\(.["defined-tags"]["Oracle-Tags"]["CreatedBy"] // "")|\(.["defined-tags"]["Oracle-Tags"]["CreatedOn"] // "")"' | while IFS='|' read -r COMPARTMENT_ID COMPARTMENT_NAME DESCRIPTION CREATEDBY CREATEDON; do
echo ""
printf "┌─ [%s]\n" "$COMPARTMENT_NAME"
printf "│ ID: %s\n" "$COMPARTMENT_ID"
printf "│ Description: %s\n" "$DESCRIPTION"
printf "│ Created By: %s | Created On: %s\n" "$CREATEDBY" "$CREATEDON"
printf "└─ Instances:\n"
oci compute instance list --compartment-id "$COMPARTMENT_ID" --lifecycle-state RUNNING \
--query "data[*].{Name:\"display-name\", State:\"lifecycle-state\", Shape:shape, CreatedBy:\"defined-tags\".\"Oracle-Tags\".\"CreatedBy\", CreatedOn:\"defined-tags\".\"Oracle-Tags\".\"CreatedOn\", OCID:id}" \
--output table 2>/dev/null
done
$SEP
}
################# LIST AUDIT EVENTS FOR USER
list_audit_events() {
TENANCY_ID=$(oci iam compartment list --query 'data[0]."compartment-id"' --raw-output)
echo "Enter email to search audit events:"
read -p "Email: " USER_EMAIL
##### SELECT TIME RANGE
echo "Select time range:"
echo "1) This day"
echo "2) Last 3 days"
echo "3) Last 10 days"
echo "4) Last month"
echo "5) Last 90 days"
read -p "Option (1-5): " TIME_OPTION
##### SET TIME RANGE BASED ON SELECTION
case "$TIME_OPTION" in
1)
START_TIME=$(date -u -d '1 day ago' +"%Y-%m-%dT%H:%M:%S.000Z")
;;
2)
START_TIME=$(date -u -d '3 days ago' +"%Y-%m-%dT%H:%M:%S.000Z")
;;
3)
START_TIME=$(date -u -d '10 days ago' +"%Y-%m-%dT%H:%M:%S.000Z")
;;
4)
START_TIME=$(date -u -d '1 month ago' +"%Y-%m-%dT%H:%M:%S.000Z")
;;
5)
START_TIME=$(date -u -d '90 days ago' +"%Y-%m-%dT%H:%M:%S.000Z")
;;
*)
echo "Invalid option. Using last 90 days."
START_TIME=$(date -u -d '90 days ago' +"%Y-%m-%dT%H:%M:%S.000Z")
;;
esac
END_TIME=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")
echo "Listing audit events for user: $USER_EMAIL"
$SEP
echo "Fetching audit events (this may take a moment)..."
################## FETCH AND PARSE AUDIT EVENTS //// WILL ONLY DISPLAY DATA OF USER MATCHING THE FINGERPRINT IN OCI-CLI CONFIG FILE (OWN DATA)
echo " Timestamp | Event | Service | Action | Status | Description | User | IP Address "
echo "$(printf '%.0s-' {1..130})"
timeout 120 oci audit event list \
--compartment-id $TENANCY_ID \
--start-time "$START_TIME" \
--end-time "$END_TIME" \
--all 2>/dev/null | \
jq --arg email "$USER_EMAIL" \
'.data |
map(select(
((.data."defined-tags"."Oracle-Tags"."CreatedBy" // "") | contains($email)) or
((.data.identity."principal-name" // "") | contains($email)) or
((.data."compartment-name" // "") | contains($email))
)) |
.[] |
{
"Time": (."event-time" | split("+")[0] | split(".")[0]),
"Event": .data."event-name",
"Source": .source,
"Action": .data.request.action,
"Status": .data.response.status,
"Message": .data.response.message,
"Principal": .data.identity."principal-name",
"IP": .data.identity."ip-address"
}' \
2>/dev/null | \
jq -r '[.Time, .Event, .Source, .Action, .Status, .Message, .Principal, .IP] | @tsv' | \
column -t -s $'\t' || echo "No audit events found for: $USER_EMAIL"
$SEP
echo "Audit events retrieval completed for: $USER_EMAIL"
}
################# DISPLAY USAGE AND COST SUMMARY
list_usage_summary() {
echo "Select time window for usage report:"
echo "1) Last 7 days"
echo "2) Last month (30 days)"
echo "3) Last 3 months (90 days)"
echo "4) Last 6 months (180 days)"
echo "5) Last 9 months (270 days)"
echo "6) Custom date range"
read -p "Option (1-6): " TIME_OPTION
$SEP
echo "Select grouping:"
echo "1) By compartment only"
echo "2) By compartment and service"
read -p "Option (1-2): " GROUP_OPTION
$SEP
echo "Displaying usage and cost summary"
$SEP
#////////////FETCH TENANCY ID FROM CONFIG\\\\\\\\\\\\\\\#
TENANCY_ID=$(grep "^tenancy=" "$HOME/.oci/config" | cut -d'=' -f2)
#////////////CALCULATE TIME RANGE BASED ON SELECTION\\\\\\\\\\\\\\\#
case "$TIME_OPTION" in
1)
TIME_STARTED=$(date -u -d '7 days ago' '+%Y-%m-%dT00:00:00Z')
TIME_ENDED=$(date -u '+%Y-%m-%dT00:00:00Z')
;;
2)
TIME_STARTED=$(date -u -d '30 days ago' '+%Y-%m-%dT00:00:00Z')
TIME_ENDED=$(date -u '+%Y-%m-%dT00:00:00Z')
;;
3)
TIME_STARTED=$(date -u -d '90 days ago' '+%Y-%m-%dT00:00:00Z')
TIME_ENDED=$(date -u '+%Y-%m-%dT00:00:00Z')
;;
4)
TIME_STARTED=$(date -u -d '180 days ago' '+%Y-%m-%dT00:00:00Z')
TIME_ENDED=$(date -u '+%Y-%m-%dT00:00:00Z')
;;
5)
TIME_STARTED=$(date -u -d '270 days ago' '+%Y-%m-%dT00:00:00Z')
TIME_ENDED=$(date -u '+%Y-%m-%dT00:00:00Z')
;;
6)
read -p "Start date (YYYY-MM-DD): " START_DATE
read -p "End date (YYYY-MM-DD): " END_DATE
TIME_STARTED="${START_DATE}T00:00:00Z"
TIME_ENDED="${END_DATE}T00:00:00Z"
;;
*)
echo "Invalid option. Using last 7 days."
TIME_STARTED=$(date -u -d '7 days ago' '+%Y-%m-%dT00:00:00Z')
TIME_ENDED=$(date -u '+%Y-%m-%dT00:00:00Z')
;;
esac
#////////////SET GROUP-BY PARAMETER BASED ON SELECTION\\\\\\\\\\\\\\\#
TEMP_FILE=$(mktemp)
if [[ "$GROUP_OPTION" == "2" ]]; then
GROUP_BY='["compartmentName","service"]'
printf "%-25s | %-15s | %-25s | %-20s | %-s\n" "Compartment" "Date" "Service" "Cost (EUR)" "Usage"
echo "$(printf '%.0s-' {1..110})"
oci usage-api usage-summary request-summarized-usages \
--tenant-id "$TENANCY_ID" \
--time-usage-started "$TIME_STARTED" \
--time-usage-ended "$TIME_ENDED" \
--granularity DAILY \
--query-type COST \
--group-by "$GROUP_BY" \
--compartment-depth 7 \
--output json 2>/dev/null | \
jq -r '.data.items[] | [."compartment-name", ."time-usage-started"[0:10], (."service" // "N/A"), (."computed-amount" | tostring | split(".")[0] + "." + (split(".")[1][0:2] // "00")), ."computed-quantity"] | @tsv' | \
sort -k2 -rn | \
while IFS=$'\t' read -r COMP DATE SERVICE COST USAGE; do
printf "%-25s | %-15s | %-25s | %-20s | %-s\n" "$COMP" "$DATE" "$SERVICE" "$COST" "$USAGE"
echo "$COMP|$SERVICE|$COST" >> "$TEMP_FILE"
done
echo ""
printf "%-25s | %-25s | %-s\n" "Compartment" "Service" "Total Cost (EUR)"
echo "$(printf '%.0s-' {1..60})"
awk -F'|' '{key=$1"|"$2; comp_service[key]+=$3} END {for (k in comp_service) {split(k, arr, "|"); printf "%-25s | %-25s | %.2f\n", arr[1], arr[2], comp_service[k]}}' "$TEMP_FILE" | sort
else
GROUP_BY='["compartmentName"]'
printf "%-25s | %-15s | %-20s | %-20s | %-s\n" "Compartment" "Date" "Cost (EUR)" "Service" "Usage"
echo "$(printf '%.0s-' {1..100})"
oci usage-api usage-summary request-summarized-usages \
--tenant-id "$TENANCY_ID" \
--time-usage-started "$TIME_STARTED" \
--time-usage-ended "$TIME_ENDED" \
--granularity DAILY \
--query-type COST \
--group-by "$GROUP_BY" \
--compartment-depth 7 \
--output json 2>/dev/null | \
jq -r '.data.items[] | [."compartment-name", ."time-usage-started"[0:10], (."computed-amount" | tostring | split(".")[0] + "." + (split(".")[1][0:2] // "00")), (."service" // "N/A"), ."computed-quantity"] | @tsv' | \
sort -k2 -rn | \
while IFS=$'\t' read -r COMP DATE COST SERVICE USAGE; do
printf "%-25s | %-15s | %-20s | %-20s | %-s\n" "$COMP" "$DATE" "$COST" "$SERVICE" "$USAGE"
echo "$COMP|$COST" >> "$TEMP_FILE"
done
echo ""
printf "%-25s | %-s\n" "Compartment" "Total Cost (EUR)"
echo "$(printf '%.0s-' {1..42})"
awk -F'|' '{comp[$1]+=$2} END {for (c in comp) printf "%-25s | %.2f\n", c, comp[c]}' "$TEMP_FILE" | sort
fi
rm -f "$TEMP_FILE"
$SEP
}
################# MAIN FUNC
if [[ $# -eq 0 ]]; then
#####ALWAYS ACTIVATE VENV AND TEST CONNECTION TO OCI
activate_venv
test_connection
else
case "$1" in
-lu)
activate_venv
test_connection
list_users_lite
;;
-lc)
activate_venv
test_connection
list_compartments
;;
-lr)
activate_venv
test_connection
list_running_instances
;;
-la)
activate_venv
test_connection
list_audit_events
;;
--usage)
activate_venv
test_connection
list_usage_summary
;;
-h|--help)
show_help
;;
*)
echo "Unknown option: $1"
show_help
exit 1
;;
esac
fi