Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/LocalDevelopmentSetup.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.bashrc

# Clone and setup
git clone https://github.com/microsoft/Container-Migration-Solution-Acceleratorr.git
git clone https://github.com/microsoft/Container-Migration-Solution-Accelerator.git
cd container-migration-solution-accelerator/src/processor
uv venv .venv
source .venv/bin/activate
Expand Down
24 changes: 12 additions & 12 deletions docs/QuotaCheck.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ o3:500
### 📌 Default Regions:

```
eastus, uksouth, eastus2, northcentralus, swedencentral, westus, westus2, southcentralus, canadacentral
eastus, uksouth, eastus2, northcentralus, swedencentral, westus, westus2, southcentralus, canadacentral, australiaeast, japaneast
```

### Usage Scenarios:
Expand All @@ -37,37 +37,37 @@ eastus, uksouth, eastus2, northcentralus, swedencentral, westus, westus2, southc
✔️ Run without parameters to check default models & regions without verbose logging:

```
./quota_check.sh
./quota_check_params.sh
```

✔️ Enable verbose logging:

```
./quota_check.sh --verbose
./quota_check_params.sh --verbose
```

✔️ Check specific model(s) in default regions:

```
./quota_check.sh --models o3:500
./quota_check_params.sh --models o3:500
```

✔️ Check default models in specific region(s):

```
./quota_check.sh --regions eastus,westus
./quota_check_params.sh --regions eastus,westus
```

✔️ Passing Both models and regions:

```
./quota_check.sh --models o3:500 --regions eastus,westus2
./quota_check_params.sh --models o3:500 --regions eastus,westus2
```

✔️ All parameters combined:

```
./quota_check.sh --models o3:500 --regions eastus,westus --verbose
./quota_check_params.sh --models o3:500 --regions eastus,westus --verbose
```

### **Sample Output**
Expand All @@ -85,9 +85,9 @@ The final table lists regions with available quota. You can select any of these
**To check quota for the deployment**

```sh
curl -L -o quota_check.sh "https://raw.githubusercontent.com/microsoft/Container-Migration-Solution-Accelerator/main/scripts/quota_check.sh"
chmod +x quota_check.sh
./quota_check.sh
curl -L -o quota_check_params.sh "https://raw.githubusercontent.com/microsoft/Container-Migration-Solution-Accelerator/main/scripts/quota_check_params.sh"
chmod +x quota_check_params.sh
./quota_check_params.sh
```

- Refer to [Input Formats](#input-formats) for detailed commands.
Expand All @@ -100,14 +100,14 @@ The final table lists regions with available quota. You can select any of these
3. Navigate to the `scripts` folder where the script files are located and make the script as executable:
```sh
cd scripts
chmod +x quota_check.sh
chmod +x quota_check_params.sh
```
4. Run the appropriate script based on your requirement:

**To check quota for the deployment**

```sh
./quota_check.sh
./quota_check_params.sh
```

- Refer to [Input Formats](#input-formats) for detailed commands.
Expand Down
8 changes: 8 additions & 0 deletions infra/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,14 @@ module appConfiguration 'br/public:avm/res/app-configuration/configuration-store
name: 'APP_LOGGING_LEVEL'
value: 'INFO'
}
{
name: 'AZURE_PACKAGE_LOGGING_LEVEL'
value: 'INFO'
}
{
name: 'AZURE_LOGGING_PACKAGES'
value: ''
}
{
name: 'AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME'
value: ''
Expand Down
8 changes: 8 additions & 0 deletions infra/main_custom.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,14 @@ module appConfiguration 'br/public:avm/res/app-configuration/configuration-store
name: 'APP_LOGGING_LEVEL'
value: 'INFO'
}
{
name: 'AZURE_PACKAGE_LOGGING_LEVEL'
value: 'INFO'
}
{
name: 'AZURE_LOGGING_PACKAGES'
value: ''
}
{
name: 'AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME'
value: ''
Expand Down
245 changes: 245 additions & 0 deletions scripts/quota_check_params.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
#!/bin/bash
# VERBOSE=false

MODELS=""
REGIONS=""
VERBOSE=false

while [[ $# -gt 0 ]]; do
case "$1" in
--models)
MODELS="$2"
shift 2
;;
--regions)
REGIONS="$2"
shift 2
;;
--verbose)
VERBOSE=true
shift
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done

# Fallback to defaults if not provided
[[ -z "$MODELS" ]]
[[ -z "$REGIONS" ]]

echo "Models: $MODELS"
echo "Regions: $REGIONS"
echo "Verbose: $VERBOSE"

for arg in "$@"; do
if [ "$arg" = "--verbose" ]; then
VERBOSE=true
fi
done

log_verbose() {
if [ "$VERBOSE" = true ]; then
echo "$1"
fi
}

# Default Models and Capacities (Comma-separated in "model:capacity" format)
DEFAULT_MODEL_CAPACITY="o3:500"
# Convert the comma-separated string into an array
IFS=',' read -r -a MODEL_CAPACITY_PAIRS <<< "$DEFAULT_MODEL_CAPACITY"

echo "🔄 Fetching available Azure subscriptions..."
SUBSCRIPTIONS=$(az account list --query "[?state=='Enabled'].{Name:name, ID:id}" --output tsv)
SUB_COUNT=$(echo "$SUBSCRIPTIONS" | wc -l)

if [ "$SUB_COUNT" -eq 0 ]; then
echo "❌ ERROR: No active Azure subscriptions found. Please log in using 'az login' and ensure you have an active subscription."
exit 1
elif [ "$SUB_COUNT" -eq 1 ]; then
# If only one subscription, automatically select it
AZURE_SUBSCRIPTION_ID=$(echo "$SUBSCRIPTIONS" | awk '{print $2}')
if [ -z "$AZURE_SUBSCRIPTION_ID" ]; then
echo "❌ ERROR: No active Azure subscriptions found. Please log in using 'az login' and ensure you have an active subscription."
exit 1
fi
echo "✅ Using the only available subscription: $AZURE_SUBSCRIPTION_ID"
else
# If multiple subscriptions exist, prompt the user to choose one
echo "Multiple subscriptions found:"
echo "$SUBSCRIPTIONS" | awk '{print NR")", $1, "-", $2}'

while true; do
echo "Enter the number of the subscription to use:"
read SUB_INDEX

# Validate user input
if [[ "$SUB_INDEX" =~ ^[0-9]+$ ]] && [ "$SUB_INDEX" -ge 1 ] && [ "$SUB_INDEX" -le "$SUB_COUNT" ]; then
AZURE_SUBSCRIPTION_ID=$(echo "$SUBSCRIPTIONS" | awk -v idx="$SUB_INDEX" 'NR==idx {print $2}')
echo "✅ Selected Subscription: $AZURE_SUBSCRIPTION_ID"
break
else
echo "❌ Invalid selection. Please enter a valid number from the list."
fi
done
fi


# Set the selected subscription
az account set --subscription "$AZURE_SUBSCRIPTION_ID"
echo "🎯 Active Subscription: $(az account show --query '[name, id]' --output tsv)"

# Default Regions to check (Comma-separated, now configurable)
DEFAULT_REGIONS="australiaeast,japaneast,eastus,uksouth,eastus2,northcentralus,swedencentral,westus,westus2,southcentralus,canadacentral"
IFS=',' read -r -a DEFAULT_REGION_ARRAY <<< "$DEFAULT_REGIONS"

# Read parameters (if any)
IFS=',' read -r -a USER_PROVIDED_PAIRS <<< "$MODELS"
USER_REGION="$REGIONS"

IS_USER_PROVIDED_PAIRS=false

if [ ${#USER_PROVIDED_PAIRS[@]} -lt 1 ]; then
echo "No parameters provided, using default model-capacity pairs: ${MODEL_CAPACITY_PAIRS[*]}"
else
echo "Using provided model and capacity pairs: ${USER_PROVIDED_PAIRS[*]}"
IS_USER_PROVIDED_PAIRS=true
MODEL_CAPACITY_PAIRS=("${USER_PROVIDED_PAIRS[@]}")
fi

declare -a FINAL_MODEL_NAMES
declare -a FINAL_CAPACITIES
declare -a TABLE_ROWS

for PAIR in "${MODEL_CAPACITY_PAIRS[@]}"; do
MODEL_NAME=$(echo "$PAIR" | cut -d':' -f1 | tr '[:upper:]' '[:lower:]')
CAPACITY=$(echo "$PAIR" | cut -d':' -f2)

if [ -z "$MODEL_NAME" ] || [ -z "$CAPACITY" ]; then
echo "❌ ERROR: Invalid model and capacity pair '$PAIR'. Both model and capacity must be specified."
exit 1
fi

FINAL_MODEL_NAMES+=("$MODEL_NAME")
FINAL_CAPACITIES+=("$CAPACITY")

done

echo "🔄 Using Models: ${FINAL_MODEL_NAMES[*]} with respective Capacities: ${FINAL_CAPACITIES[*]}"
echo "----------------------------------------"

# Check if the user provided a region, if not, use the default regions
if [ -n "$USER_REGION" ]; then
echo "🔍 User provided region: $USER_REGION"
IFS=',' read -r -a REGIONS <<< "$USER_REGION"
else
echo "No region specified, using default regions: ${DEFAULT_REGION_ARRAY[*]}"
REGIONS=("${DEFAULT_REGION_ARRAY[@]}")
APPLY_OR_CONDITION=true
fi

echo "✅ Retrieved Azure regions. Checking availability..."
INDEX=1

VALID_REGIONS=()
for REGION in "${REGIONS[@]}"; do
log_verbose "----------------------------------------"
log_verbose "🔍 Checking region: $REGION"

QUOTA_INFO=$(az cognitiveservices usage list --location "$REGION" --output json | tr '[:upper:]' '[:lower:]')
if [ -z "$QUOTA_INFO" ]; then
log_verbose "⚠️ WARNING: Failed to retrieve quota for region $REGION. Skipping."
continue
fi

TEXT_EMBEDDING_AVAILABLE=false
AT_LEAST_ONE_MODEL_AVAILABLE=false
TEMP_TABLE_ROWS=()

for index in "${!FINAL_MODEL_NAMES[@]}"; do
MODEL_NAME="${FINAL_MODEL_NAMES[$index]}"
REQUIRED_CAPACITY="${FINAL_CAPACITIES[$index]}"
FOUND=false
INSUFFICIENT_QUOTA=false

MODEL_TYPES=("openai.standard.$MODEL_NAME" "openai.globalstandard.$MODEL_NAME")

for MODEL_TYPE in "${MODEL_TYPES[@]}"; do
FOUND=false
INSUFFICIENT_QUOTA=false
log_verbose "🔍 Checking model: $MODEL_NAME with required capacity: $REQUIRED_CAPACITY ($MODEL_TYPE)"

MODEL_INFO=$(echo "$QUOTA_INFO" | awk -v model="\"value\": \"$MODEL_TYPE\"" '
BEGIN { RS="},"; FS="," }
$0 ~ model { print $0 }
')

if [ -z "$MODEL_INFO" ]; then
FOUND=false
log_verbose "⚠️ WARNING: No quota information found for model: $MODEL_NAME in region: $REGION for model type: $MODEL_TYPE."
continue
fi

if [ -n "$MODEL_INFO" ]; then
FOUND=true
CURRENT_VALUE=$(echo "$MODEL_INFO" | awk -F': ' '/"currentvalue"/ {print $2}' | tr -d ',' | tr -d ' ')
LIMIT=$(echo "$MODEL_INFO" | awk -F': ' '/"limit"/ {print $2}' | tr -d ',' | tr -d ' ')

CURRENT_VALUE=${CURRENT_VALUE:-0}
LIMIT=${LIMIT:-0}

CURRENT_VALUE=$(echo "$CURRENT_VALUE" | cut -d'.' -f1)
LIMIT=$(echo "$LIMIT" | cut -d'.' -f1)

AVAILABLE=$((LIMIT - CURRENT_VALUE))
log_verbose "✅ Model: $MODEL_TYPE | Used: $CURRENT_VALUE | Limit: $LIMIT | Available: $AVAILABLE"

if [ "$AVAILABLE" -ge "$REQUIRED_CAPACITY" ]; then
FOUND=true
if [ "$MODEL_NAME" = "text-embedding-ada-002" ]; then
TEXT_EMBEDDING_AVAILABLE=true
fi
AT_LEAST_ONE_MODEL_AVAILABLE=true
TEMP_TABLE_ROWS+=("$(printf "| %-4s | %-20s | %-43s | %-10s | %-10s | %-10s |" "$INDEX" "$REGION" "$MODEL_TYPE" "$LIMIT" "$CURRENT_VALUE" "$AVAILABLE")")
else
INSUFFICIENT_QUOTA=true
fi
fi

if [ "$FOUND" = false ]; then
log_verbose "❌ No models found for model: $MODEL_NAME in region: $REGION (${MODEL_TYPES[*]})"

elif [ "$INSUFFICIENT_QUOTA" = true ]; then
log_verbose "⚠️ Model $MODEL_NAME in region: $REGION has insufficient quota (${MODEL_TYPES[*]})."
fi
done
done

if { [ "$IS_USER_PROVIDED_PAIRS" = true ] && [ "$INSUFFICIENT_QUOTA" = false ] && [ "$FOUND" = true ]; } || { [ "$APPLY_OR_CONDITION" != true ] || [ "$AT_LEAST_ONE_MODEL_AVAILABLE" = true ]; }; then
VALID_REGIONS+=("$REGION")
TABLE_ROWS+=("${TEMP_TABLE_ROWS[@]}")
INDEX=$((INDEX + 1))
elif [ ${#USER_PROVIDED_PAIRS[@]} -eq 0 ]; then
echo "🚫 Skipping $REGION as it does not meet quota requirements."
fi

done

if [ ${#TABLE_ROWS[@]} -eq 0 ]; then
echo "--------------------------------------------------------------------------------------------------------------------"

echo "❌ No regions have sufficient quota for all required models. Please request a quota increase: https://aka.ms/oai/stuquotarequest"
else
echo "---------------------------------------------------------------------------------------------------------------------"
printf "| %-4s | %-20s | %-43s | %-10s | %-10s | %-10s |\n" "No." "Region" "Model Name" "Limit" "Used" "Available"
echo "---------------------------------------------------------------------------------------------------------------------"
for ROW in "${TABLE_ROWS[@]}"; do
echo "$ROW"
done
echo "---------------------------------------------------------------------------------------------------------------------"
echo "➡️ To request a quota increase, visit: https://aka.ms/oai/stuquotarequest"
fi

echo "✅ Script completed."
4 changes: 4 additions & 0 deletions src/backend-api/src/app/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ APP_CONFIGURATION_URL=""
# APP_LOGGING_ENABLE=true
# APP_LOGGING_LEVEL="INFO"

# Azure Logging Configuration
# AZURE_PACKAGE_LOGGING_LEVEL="WARNING" # Options: DEBUG, INFO, WARNING, ERROR, CRITICAL
# AZURE_LOGGING_PACKAGES="azure.core.pipeline.policies.http_logging_policy,azure.storage.blob,azure.storage.queue,azure.core,azure.identity,azure.storage,azure.core.pipeline,azure.core.pipeline.policies,azure.core.pipeline.transport,openai,openai._client,httpx,httpcore,semantic_kernel,urllib3,msal"

Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ class Configuration(_configuration_base, KernelBaseSettings):
app_logging_level: str = Field(default="INFO")
app_sample_variable: str = Field(default="Hello World!")

# Azure logging configuration
azure_package_logging_level: str = Field(default="WARNING", alias="AZURE_PACKAGE_LOGGING_LEVEL")
azure_logging_packages: str | None = Field(default=None, alias="AZURE_LOGGING_PACKAGES")

global_llm_service: str | None = "AzureOpenAI"
cosmos_db_process_log_container: str | None = Field(
default=None, env="COSMOS_DB_PROCESS_LOG_CONTAINER"
Expand Down
Loading