From 1cea7bec605cd3eb3f892ebaa84ea8b1deb644fc Mon Sep 17 00:00:00 2001 From: my99problems Date: Sun, 26 Oct 2025 15:50:16 +0100 Subject: [PATCH] usage display --- README.md | 14 ++--- oci.sh | 168 ++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 156 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 26c265c..141df8f 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,14 @@ Oci-cli wrapper in bash # Current available methods -``` +``` Usage: oci.sh [OPTION] Options: - -lu List all users in the tenancy - -lc List all compartments in the tenancy - -lr List all running instances in the tenancy - -la List and parse audit events for a specific user (filtered by email)///ONLY WORKS FOR OWN DATA - -h Show this help message - + -lu List all users in the tenancy + -lc List all compartments in the tenancy + -lr List all running instances in the tenancy + -la List and parse audit events for a specific user (filtered by email)///ONLY WORKS FOR OWN DATA + --usage Display usage and cost summary for the current month + -h Show this help message ``` diff --git a/oci.sh b/oci.sh index f9b3b8d..8d2be92 100755 --- a/oci.sh +++ b/oci.sh @@ -4,11 +4,12 @@ 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 " -h Show this help message" + 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" } @@ -75,24 +76,27 @@ list_running_instances() { echo "Listing all running instances in the tenancy" $SEP - #////////////////TABLE HEADER\\\\\\\\\\\\\\\######### - printf " %-30s | %-20s | %-s\n" "Instance Name" "Compartment" "Instance ID" - echo "$(printf '%.0s-' {1..130})" + #////////////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)"' | while IFS='|' read -r COMPARTMENT_ID COMPARTMENT_NAME; do + 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",ID:id}' 2>/dev/null | \ - jq -r '.[] | - [ - (.Name // ""), - (.ID // "") - ] | - @tsv' | \ - while IFS=$'\t' read -r NAME ID; do - printf " %-30s | %-20s | %s\n" "$NAME" "$COMPARTMENT_NAME" "$ID" - done + --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 @@ -177,6 +181,127 @@ list_audit_events() { 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 @@ -204,6 +329,11 @@ else test_connection list_audit_events ;; + --usage) + activate_venv + test_connection + list_usage_summary + ;; -h|--help) show_help ;;