Fetch GCP Bucket Storage Utilization for runwhen-nonprod-sandbox¶
What does it do?
This script is a Bash shell script that uses various functions to retrieve information about the size, region, and storage class of Google Cloud Storage buckets in specified projects. It checks if the Monitoring API is enabled and uses either PromQL or gsutil to get the bucket sizes depending on the API status, then outputs the result in JSON format.
#!/bin/bash# Import the service account key as the environment variableSERVICE_ACCOUNT_KEY=$GOOGLE_APPLICATION_CREDENTIALS# Function to convert bytes to terabytes using awk
bytes_to_tb(){awk"BEGIN {printf \"%.4f\", $1 / (1024^4)}"}# Function to convert bytes to gigabytes using awk
bytes_to_gb(){awk"BEGIN {printf \"%.4f\", $1 / (1024^3)}"}# Function to get an access token using the service account key
get_access_token(){# Extract email and private key from the service account key filelocalkey_file=$1localemail=$(jq-r.client_email$key_file)localkey=$(jq-r.private_key$key_file|sed's/\\n/\n/g')# Construct the JWT token# ...# Request access token from Google OAuth2 APIlocaltoken=$(curl-s--requestPOST\--urlhttps://oauth2.googleapis.com/token\--header"Content-Type: application/x-www-form-urlencoded"\--data"grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=$jwt"|jq-r.access_token)echo$token}# Function to check if the Monitoring API is enabled
is_monitoring_api_enabled(){# Make a request to the Service Usage API to check if Monitoring API is enabled for the project# ...# Handle response and return status# ...}# Other functions...# Check if PROJECT_IDS environment variable is set and validif[-z"$PROJECT_IDS"];thenecho"Error: PROJECT_IDS environment variable is not set or empty."echo"Usage: export PROJECT_IDS='project_id1,project_id2,...'"exit1fi# Read the PROJECT_IDS environment variable into an arrayIFS=','read-r-aprojects<<<"$PROJECT_IDS"# Get the access token using either the provided service account key or gcloudif[-n"$SERVICE_ACCOUNT_KEY"];then# Option 1: Use the provided service account key to get the access tokenaccess_token=$(get_access_token"$SERVICE_ACCOUNT_KEY")else# Option 2: Use gcloud to retrieve the access tokenaccess_token=$(gcloudauthapplication-defaultprint-access-token)if[-z"$access_token"];thenecho"Failed to retrieve access token using gcloud. Exiting..."exit1fifi# Other script content...
Inthecomments,we'veprovidedsomeadditionalcontextandexplanationsforlessexperiencedDevOpsengineers,suchasaddingoutputdescriptionsforeachfunction.Thiscanhelpthemunderstandthepurposeandusageofdifferentsectionsofthescript.
Add GCP Bucket Storage Configuration for runwhen-nonprod-sandbox to Report¶
What does it do?
This Bash script uses the Google Cloud Platform to list all buckets in multiple projects. It retrieves an access token using a service account key or gcloud, then uses that token to get metadata for each bucket, and output the results into a JSON file.
#!/bin/bash# This script accesses the Google Cloud Platform (GCP) Storage API to list buckets and get bucket metadata# The access token is acquired through service account key or gcloud# Before using this script, make sure you have installed necessary tools such as jq, openssl, and gcloud SDKSERVICE_ACCOUNT_KEY=$GOOGLE_APPLICATION_CREDENTIALS# Function to get an access token using the service account key
get_access_token(){localkey_file=$1localemail=$(jq-r.client_email$key_file)localkey=$(jq-r.private_key$key_file|sed's/\\n/\n/g')# Generate header, payload and signature for JWT...
localtoken=$(curl-s--requestPOST\--urlhttps://oauth2.googleapis.com/token\--header"Content-Type: application/x-www-form-urlencoded"\--data"grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=$jwt"|jq-r.access_token)echo$token}# Function to list buckets in a project
list_buckets(){...
}# Function to get bucket metadata (including location and storage class)
get_bucket_metadata(){...
}# Check if PROJECT_IDS environment variable is set and validif[-z"$PROJECT_IDS"];then...
fi# Read the PROJECT_IDS environment variable into an arrayIFS=','read-r-aprojects<<<"$PROJECT_IDS"# Get the access token using either the provided service account key or gcloudif[-n"$SERVICE_ACCOUNT_KEY"];then...
else...
fi# Iterate over each project ID providedforproject_idin"${projects[@]}";do# List all buckets in the projectbuckets=$(list_buckets"$project_id""$access_token")forbucket_namein$buckets;dometadata=$(get_bucket_metadata"$bucket_name""$access_token")echo$metadata>>$HOME/bucket_configuration.json
donedone
cat$HOME/bucket_configuration.json|jq.
Check GCP Bucket Security Configuration for runwhen-nonprod-sandbox¶
What does it do?
This script is a bash script that checks the security settings for Google Cloud Storage buckets within specified projects. It uses the Google Cloud SDK (gcloud) to fetch access token, iterates over each specified project, and then checks each bucket within the project for public access and encryption settings. If any security issues are found, it outputs them to a JSON file.
#!/bin/bashACCESS_TOKEN=$(gcloudauthapplication-defaultprint-access-token)# Get access token using gcloudISSUES=()# Initialize empty array for issues# Check if PROJECT_IDS is setif[-z"$PROJECT_IDS"];thenecho"Error: PROJECT_IDS is not set. Please set PROJECT_IDS to a comma-separated list of project IDs."exit1fi# Function to check bucket settings
check_bucket_settings(){localBUCKET=$1echo"Checking settings for bucket: $BUCKET"localRESPONSE=$(curl-s-H"Authorization: Bearer $ACCESS_TOKEN"\"https://storage.googleapis.com/storage/v1/b/$BUCKET?fields=iamConfiguration,acl,encryption")localHTTP_STATUS=$(echo$RESPONSE|jq-r'.error.code // 200')# Get HTTP status codeif["$HTTP_STATUS"-ne200];then# Check if HTTP status is not 200localMESSAGE=$(echo$RESPONSE|jq-r'.error.message')echo"Error fetching settings for bucket $BUCKET: $MESSAGE"returnfilocalIS_PUBLIC=false# Initialize flag for public access# Check public accesslocalPUBLIC_ACCESS=$(echo$RESPONSE|jq-r'.iamConfiguration.bucketPolicyOnly.enabled // false')if["$PUBLIC_ACCESS"=="true"];thenecho"Bucket $BUCKET has bucketPolicyOnly enabled."# Fetch IAM policy to check for public accesslocalIAM_RESPONSE=$(curl-s-H"Authorization: Bearer $ACCESS_TOKEN"\"https://storage.googleapis.com/storage/v1/b/$BUCKET/iam")localIAM_HTTP_STATUS=$(echo$IAM_RESPONSE|jq-r'.error.code // 200')if["$IAM_HTTP_STATUS"-ne200];thenlocalIAM_MESSAGE=$(echo$IAM_RESPONSE|jq-r'.error.message')echo"Error fetching IAM policies for bucket $BUCKET: $IAM_MESSAGE"elselocalPUBLIC_IAM=$(echo$IAM_RESPONSE|jq'.bindings[]? | select(.members[]? == "allUsers" or .members[]? == "allAuthenticatedUsers")')if[-n"$PUBLIC_IAM"];thenecho"Bucket $BUCKET is publicly accessible via IAM policy!"IS_PUBLIC=trueelseecho"Bucket $BUCKET is not publicly accessible."fifielselocalPUBLIC_ACCESS_ACL=$(echo$RESPONSE|jq-r'.acl[]? | select(.entity == "allUsers" or .entity == "allAuthenticatedUsers")')if[-n"$PUBLIC_ACCESS_ACL"];thenecho"Bucket $BUCKET is publicly accessible via ACL!"IS_PUBLIC=trueelseecho"Bucket $BUCKET is not publicly accessible."fifiif["$IS_PUBLIC"==true];thenISSUES+=("{\"bucket\": \"$BUCKET\", \"project\": \"$PROJECT_ID\", \"issue_type\": \"public_access\", \"issue_details\": \"public access is enabled\"}")# Add issue to arrayfi# Check encryption settingslocalENCRYPTION_KEY=$(echo$RESPONSE|jq-r'.encryption.defaultKmsKeyName // "Google-managed keys"')if["$ENCRYPTION_KEY"=="Google-managed keys"];thenecho"Bucket $BUCKET is encrypted with Google-managed keys."elseecho"Bucket $BUCKET is encrypted with customer-managed keys: $ENCRYPTION_KEY"fi}# Function to process each project
process_project(){localPROJECT_ID=$1echo"Processing project: $PROJECT_ID"# Get list of all buckets in the projectlocalRESPONSE=$(curl-s-H"Authorization: Bearer $ACCESS_TOKEN"\"https://storage.googleapis.com/storage/v1/b?project=$PROJECT_ID")localHTTP_STATUS=$(echo$RESPONSE|jq-r'.error.code // 200')if["$HTTP_STATUS"-ne200];thenlocalMESSAGE=$(echo$RESPONSE|jq-r'.error.message')echo"Error fetching buckets for project $PROJECT_ID: $MESSAGE"returnfilocalBUCKETS=$(echo$RESPONSE|jq-r'.items[].name')# Iterate over each bucket and perform checksforBUCKETin$BUCKETS;doecho"Checking bucket: $BUCKET"check_bucket_settings"$BUCKET"echo"-----------------------------"done}# Convert PROJECT_IDS to an arrayIFS=','read-r-aPROJECT_IDS_ARRAY<<<"$PROJECT_IDS"# Iterate over each project and process itforPROJECT_IDin"${PROJECT_IDS_ARRAY[@]}";doprocess_project$PROJECT_IDdone# Output the security issuesecho"Security Issues:"if[${#ISSUES[@]}-eq0];thenecho"No security issues found."# Add empty json list to file so that json loads doesn't fail.echo"[{}]">$HOME/bucket_security_issues.json
elseecho"${ISSUES[@]}"|jq-s.>$HOME/bucket_security_issues.json# Save issues to JSON filecat$HOME/bucket_security_issues.json# Print JSON filefi
Fetch GCP Bucket Storage Operations Rate for runwhen-nonprod-sandbox¶
What does it do?
This script is a bash shell script that uses Google Cloud Platform APIs to get access tokens, check if the Monitoring API is enabled for certain projects, list buckets in a project, and get the sizes of all buckets using PromQL. It then outputs the results in JSON format.
#!/bin/bashSERVICE_ACCOUNT_KEY=$GOOGLE_APPLICATION_CREDENTIALS# Function to get an access token using the service account key
get_access_token(){localkey_file=$1localemail=$(jq-r.client_email$key_file)localkey=$(jq-r.private_key$key_file|sed's/\\n/\n/g')localheader=$(echo-n'{"alg":"RS256","typ":"JWT"}'|opensslbase64-e-A|tr-d'='|tr'/+''_-'|tr-d'\n')localnow=$(date+%s)localexp=$(($now+3600))localpayload=$(echo-n"{\"iss\":\"$email\",\"scope\":\"https://www.googleapis.com/auth/cloud-platform\",\"aud\":\"https://oauth2.googleapis.com/token\",\"exp\":$exp,\"iat\":$now}"|opensslbase64-e-A|tr-d'='|tr'/+''_-'|tr-d'\n')localsig=$(echo-n"$header.$payload"|openssldgst-sha256-sign<(echo-n"$key")|opensslbase64-e-A|tr-d'='|tr'/+''_-'|tr-d'\n')localjwt="$header.$payload.$sig"localtoken=$(curl-s--requestPOST\--urlhttps://oauth2.googleapis.com/token\--header"Content-Type: application/x-www-form-urlencoded"\--data"grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=$jwt"|jq-r.access_token)echo$token}# Function to check if the Monitoring API is enabled
is_monitoring_api_enabled(){localproject_id=$1localtoken=$2localresponse=$(curl-s-w"\nHTTP_STATUS:%{http_code}"--header"Authorization: Bearer $token"\"https://serviceusage.googleapis.com/v1/projects/$project_id/services/monitoring.googleapis.com")localhttp_status=$(echo"$response"|sed-n's/.*HTTP_STATUS:\([0-9]*\)$/\1/p')localresponse_body=$(echo"$response"|sed-n'1,/^HTTP_STATUS:/p'|sed'$d')if[["$http_status"-ne200]];thenecho"Error checking Monitoring API status for project $project_id:"echo"HTTP Status: $http_status"echo"Response: $response_body"return1filocalstate=$(echo"$response_body"|jq-r'.state')if[["$state"=="ENABLED"]];thenreturn0elseecho"Monitoring API is not enabled for project $project_id."echo"State: $state"return1fi}# Function to list buckets in a project
list_buckets(){localproject_id=$1localtoken=$2localresponse=$(curl-s--header"Authorization: Bearer $token"\"https://storage.googleapis.com/storage/v1/b?project=$project_id")echo$response|jq-r'.items[].name'}# Function to get the sizes of all buckets using PromQL
get_bucket_read_ops(){localproject_id=$1localtoken=$2localresponse=$(curl-s--header"Authorization: Bearer $token"\--header"Content-Type: application/x-www-form-urlencoded"\--data'query=sum by (bucket_name)(rate(storage_googleapis_com:api_request_count{monitored_resource="gcs_bucket",method=~"Read.*|List.*|Get.*"}[30m]))'\"https://monitoring.googleapis.com/v1/projects/$project_id/location/global/prometheus/api/v1/query")echo$response|jq-r'.data.result[] | {bucket_name: .metric.bucket_name, ops: .value[1]}'}# Function to get the sizes of all buckets using PromQL
get_bucket_write_ops(){localproject_id=$1localtoken=$2localresponse=$(curl-s--header"Authorization: Bearer $token"\--header"Content-Type: application/x-www-form-urlencoded"\--data'query=sum by (bucket_name)(rate(storage_googleapis_com:api_request_count{monitored_resource="gcs_bucket",method=~"Write.*"}[30m]))'\"https://monitoring.googleapis.com/v1/projects/$project_id/location/global/prometheus/api/v1/query")echo$response|jq-r'.data.result[] | {bucket_name: .metric.bucket_name, ops: .value[1]}'}# Function to get bucket metadata (including location and storage class)
get_bucket_metadata(){localbucket_name=$1localtoken=$2localresponse=$(curl-s--header"Authorization: Bearer $token"\"https://storage.googleapis.com/storage/v1/b/$bucket_name")echo$response}# Check if PROJECT_IDS environment variable is set and validif[-z"$PROJECT_IDS"];thenecho"Error: PROJECT_IDS environment variable is not set or empty."echo"Usage: export PROJECT_IDS='project_id1,project_id2,...'"exit1fi# Read the PROJECT_IDS environment variable into an arrayIFS=','read-r-aprojects<<<"$PROJECT_IDS"# Get the access token using either the provided service account key or gcloudif[-n"$SERVICE_ACCOUNT_KEY"];thenecho"Using the SERVICE_ACCOUNT_KEY to get the access token."access_token=$(get_access_token"$SERVICE_ACCOUNT_KEY")elseecho"SERVICE_ACCOUNT_KEY is not set. Attempting to set access token using gcloud."access_token=$(gcloudauthapplication-defaultprint-access-token)if[-z"$access_token"];thenecho"Failed to retrieve access token using gcloud. Exiting..."exit1fifiread_ops=()write_ops=()# Iterate over each project ID providedforproject_idin"${projects[@]}";doecho"Processing project: $project_id"# List all buckets in the projectbuckets=$(list_buckets"$project_id""$access_token")# Iterate over each bucket and match its sizeifis_monitoring_api_enabled"$project_id""$access_token";thenecho"Monitoring API is enabled for project: $project_id"# Get the read/write operations of all bucketsall_bucket_read_ops=$(get_bucket_read_ops"$project_id""$access_token")all_bucket_write_ops=$(get_bucket_write_ops"$project_id""$access_token")# Iterate over each bucket and match its sizeforbucket_namein$buckets;doecho"Processing bucket: $bucket_name"# Initialize operations to zeroread_ops=0write_ops=0# Get the read/write operations for the current bucketread_ops=$(echo"$all_bucket_read_ops"|jq-r--argbucket_name"$bucket_name"'. | select(.bucket_name == $bucket_name) | .ops // 0 | tonumber | round')write_ops=$(echo"$all_bucket_write_ops"|jq-r--argbucket_name"$bucket_name"'. | select(.bucket_name == $bucket_name) | .ops // 0 | tonumber | round')# Calculate the total operations and cost using jq for arithmetictotal_ops=$(echo"$write_ops$read_ops"|jq-n'[inputs] | add')# Print resultsecho"Read Rate: $read_ops ops/s, Write Rate: $write_ops ops/s, Total rate: $total_ops ops/s"# Get the regionregion=$(echo"$metadata"|jq-r'.location')# Add bucket operations to the listbucket_ops+=("{\"project\": \"$project_id\", \"bucket\": \"$bucket_name\", \"write_ops\": \"$write_ops\", \"read_ops\": \"$read_ops\", \"total_ops\": \"$total_ops\", \"region\": \"$region\"}")doneelseecho"Monitoring API is not enabled for project: $project_id"fidone# Output the result in JSON formatecho"["$(IFS=,;echo"${bucket_ops[*]}")"]">$HOME/bucket_ops_report.json
cat$HOME/bucket_ops_report.json|jq'sort_by(.total_ops) | reverse'