>(tee -a "$LOGFILE") 2>&1 echo "=== Floating IP Report generated at $(date) ===" echo "Logfile: $LOGFILE" echo # --- Helper caches --- declare -A NET_NAME_CACHE get_network_name() { local net_id="$1" if [[ -z "${NET_NAME_CACHE[$net_id]+x}" ]]; then NET_NAME_CACHE["$net_id"]="$(openstack network show "$net_id" -c name -f value 2>/dev/null || echo "")" fi printf '%s' "${NET_NAME_CACHE[$net_id]}" } # --- Step 1: collect unique Project IDs that have at least one Floating IP --- readarray -t PROJECT_IDS < <(openstack floating ip list -f json \ | jq -r '.[].Project' | sort -u) # --- Iterate per Project --- for PROJECT_ID in "${PROJECT_IDS[@]}"; do PROJECT_NAME="$(openstack project show "$PROJECT_ID" -c name -f value 2>/dev/null || echo "")" FIP_JSON=""> >(tee -a "$LOGFILE") 2>&1 echo "=== Floating IP Report generated at $(date) ===" echo "Logfile: $LOGFILE" echo # --- Helper caches --- declare -A NET_NAME_CACHE get_network_name() { local net_id="$1" if [[ -z "${NET_NAME_CACHE[$net_id]+x}" ]]; then NET_NAME_CACHE["$net_id"]="$(openstack network show "$net_id" -c name -f value 2>/dev/null || echo "")" fi printf '%s' "${NET_NAME_CACHE[$net_id]}" } # --- Step 1: collect unique Project IDs that have at least one Floating IP --- readarray -t PROJECT_IDS < <(openstack floating ip list -f json \ | jq -r '.[].Project' | sort -u) # --- Iterate per Project --- for PROJECT_ID in "${PROJECT_IDS[@]}"; do PROJECT_NAME="$(openstack project show "$PROJECT_ID" -c name -f value 2>/dev/null || echo "")" FIP_JSON=""> >(tee -a "$LOGFILE") 2>&1 echo "=== Floating IP Report generated at $(date) ===" echo "Logfile: $LOGFILE" echo # --- Helper caches --- declare -A NET_NAME_CACHE get_network_name() { local net_id="$1" if [[ -z "${NET_NAME_CACHE[$net_id]+x}" ]]; then NET_NAME_CACHE["$net_id"]="$(openstack network show "$net_id" -c name -f value 2>/dev/null || echo "")" fi printf '%s' "${NET_NAME_CACHE[$net_id]}" } # --- Step 1: collect unique Project IDs that have at least one Floating IP --- readarray -t PROJECT_IDS < <(openstack floating ip list -f json \ | jq -r '.[].Project' | sort -u) # --- Iterate per Project --- for PROJECT_ID in "${PROJECT_IDS[@]}"; do PROJECT_NAME="$(openstack project show "$PROJECT_ID" -c name -f value 2>/dev/null || echo "")" FIP_JSON="">
#!/usr/bin/env bash
set -euo pipefail
# --- Timestamped log file ---
LOGDIR="/var/log"
LOGFILE="$LOGDIR/support-fip-list-$(date +%Y%m%d-%H%M%S).log"

# Redirect all stdout + stderr to the logfile
exec > >(tee -a "$LOGFILE") 2>&1

echo "=== Floating IP Report generated at $(date) ==="
echo "Logfile: $LOGFILE"
echo

# --- Helper caches ---
declare -A NET_NAME_CACHE

get_network_name() {
  local net_id="$1"
  if [[ -z "${NET_NAME_CACHE[$net_id]+x}" ]]; then
    NET_NAME_CACHE["$net_id"]="$(openstack network show "$net_id" -c name -f value 2>/dev/null || echo "<unknown>")"
  fi
  printf '%s' "${NET_NAME_CACHE[$net_id]}"
}

# --- Step 1: collect unique Project IDs that have at least one Floating IP ---
readarray -t PROJECT_IDS < <(openstack floating ip list -f json \\
  | jq -r '.[].Project' | sort -u)

# --- Iterate per Project ---
for PROJECT_ID in "${PROJECT_IDS[@]}"; do
  PROJECT_NAME="$(openstack project show "$PROJECT_ID" -c name -f value 2>/dev/null || echo "<unknown>")"

  FIP_JSON="$(openstack floating ip list --project="$PROJECT_ID" -f json)"
  TOTAL_FIPS="$(jq 'length' <<<"$FIP_JSON")"

  printf 'Project: %s (%s) Total Floating IPs allocated: %s\\n' "$PROJECT_NAME" "$PROJECT_ID" "$TOTAL_FIPS"

  readarray -t NET_IDS < <(jq -r '.[]."Floating Network"' <<<"$FIP_JSON" | sort -u | awk 'NF')

  if [[ "${#NET_IDS[@]}" -eq 0 ]]; then
    echo "  (No Floating IPs)"
    echo
    continue
  fi

  for NET_ID in "${NET_IDS[@]}"; do
    COUNT_IN_NET="$(jq --arg net "$NET_ID" '[.[] | select(."Floating Network"==$net)] | length' <<<"$FIP_JSON")"
    NET_NAME="$(get_network_name "$NET_ID")"

    printf '  Network: %s (%s) Floating IPs allocated: %s\\n' "$NET_NAME" "$NET_ID" "$COUNT_IN_NET"

    IFS=$'\\n' read -r -d '' -a FIP_LINES < <(jq -r --arg net "$NET_ID" \\
      '.[] | select(."Floating Network"==$net)
       | "\\(.["Floating IP Address"] // "")|\\(.ID // "")|\\(.["Fixed IP Address"] // "")"' \\
      <<<"$FIP_JSON" && printf '\\0')

    idx=1
    for line in "${FIP_LINES[@]}"; do
      IFS='|' read -r FIP_ADDR FIP_ID FIXED_IP <<<"$line"
      if [[ -n "${FIXED_IP// }" ]]; then
        printf '    %d. %s (%s) attached to %s\\n' "$idx" "$FIP_ADDR" "$FIP_ID" "$FIXED_IP"
      else
        printf '    %d. %s (%s) detached\\n' "$idx" "$FIP_ADDR" "$FIP_ID"
      fi
      idx=$((idx+1))
    done
  done

  echo
done

result

=== Floating IP Report generated at Tue Sep  2 10:51:57 AM CST 2025 ===
Logfile: /var/log/support-fip-list-20250902-105157.log

Project: app-framework (2a75b1b104254f94acaf99d42cf066b5) Total Floating IPs allocated: 3
  Network: public (ab2777f8-ec5c-46bf-9354-317b6e86d054) Floating IPs allocated: 3
    1. 10.32.19.100 (0ec6bb10-0de5-4d23-9bd4-7398e000e04c) attached to 192.168.1.115
    2. 10.32.19.134 (60ca0db2-d23e-40d3-9eee-2e6a75db0fcd) attached to 192.168.1.21
    3. 10.32.19.95 (fcbac361-44ad-441a-b47f-af7c255b9029) attached to 192.168.1.208

Project: vdi (376ca768c2a14e4f81fcd1e8957f7e42) Total Floating IPs allocated: 3
  Network: public (ab2777f8-ec5c-46bf-9354-317b6e86d054) Floating IPs allocated: 3
    1. 10.32.19.19 (c298b58e-c9b8-42c8-af32-725c7b2b8663) attached to 192.168.0.115
    2. 10.32.19.239 (fba580a2-0646-40d7-8951-60a240e2204a) attached to 192.168.0.229
    3. 10.32.19.20 (fea5c901-2794-484c-81a4-29b9f4e3827f) attached to 192.168.0.242

Project: proj001 (919bfad4b8fc426ba7650aed33d00825) Total Floating IPs allocated: 6
  Network: public (ab2777f8-ec5c-46bf-9354-317b6e86d054) Floating IPs allocated: 6
    1. 10.32.19.243 (16b8af67-200e-40f0-88ef-7d95e390e670) attached to 192.168.1.40
    2. 10.32.19.185 (28cbc9ad-d478-4934-8335-67e1e9b5d9be) attached to 192.168.1.80
    3. 10.32.19.169 (35be66b4-d392-407a-b762-19e1d2c93a14) attached to 192.168.0.151
    4. 10.32.19.225 (86e9398c-72e0-4099-81c1-b6d6b4a59ed6) attached to 192.168.1.178
    5. 10.32.19.171 (c7b1ca86-50ee-49ec-a5bb-528fe0035b7e) attached to 192.168.0.213
    6. 10.32.19.129 (f12ff4d1-11c9-4f52-8b95-7d723fb50c53) attached to 192.168.0.101

Project: demo (b5f1291a5591450bbc753315b2c9635e) Total Floating IPs allocated: 2
  Network: public (ab2777f8-ec5c-46bf-9354-317b6e86d054) Floating IPs allocated: 2
    1. 10.32.19.203 (08dabca7-8f26-4bc9-9634-f51c07bcdae4) attached to 192.168.0.188
    2. 10.32.19.38 (57bfdbe4-30ff-4550-8536-b5da5f70257a) attached to 192.168.0.155

Project: ws6 (d5adda2bc1604f4f8273b63849f1790a) Total Floating IPs allocated: 2
  Network: public (ab2777f8-ec5c-46bf-9354-317b6e86d054) Floating IPs allocated: 2
    1. 10.32.19.105 (5778adb3-7662-4389-85a6-2bb480528662) attached to 192.168.0.221
    2. 10.32.19.168 (accc0093-d901-4dc8-8305-bc0eaf89a41f) attached to 192.168.0.70