Skip to content

fix(providers/azure): case-insensitive + whitespace-tolerant SKU validation across all services #675

Description

@cristim

Symptom

Azure service clients reject user-supplied SKU identifiers that differ from the API-returned form only by case or surrounding whitespace. For example "premium_p1" or " Premium_P1 " would fail validation even though "Premium_P1" is valid.

Scope

Five Azure service clients implement ValidateOffering with an exact == compare against the live SKU list:

Service File Line
compute providers/azure/services/compute/client.go ~288-300
database providers/azure/services/database/client.go ~293-305
cache providers/azure/services/cache/client.go ~288-300
search providers/azure/services/search/client.go ~288-300
cosmosdb providers/azure/services/cosmosdb/client.go ~294-306

All five share the identical loop shape:

for _, sku := range validSKUs {
    if sku == rec.ResourceType {
        return nil
    }
}
return fmt.Errorf("invalid Azure ... SKU: %s", rec.ResourceType)

Root cause

== is byte-exact. Azure SKU casing isn't necessarily stable across regions / API versions / reservation-vs-resource queries, and operator-supplied SKUs (CLI, override file, etc.) frequently have whitespace or differ in case.

The synapse service (PR #622) just landed strings.EqualFold(sku, strings.TrimSpace(rec.ResourceType)) for the same shape of bug — this issue extends that fix consistently to the other five services so behavior is uniform across Azure providers.

Fix

Replace the exact compare in each of the five services with:

for _, sku := range validSKUs {
    if strings.EqualFold(sku, strings.TrimSpace(rec.ResourceType)) {
        return nil
    }
}

Add the strings import where missing.

Tests

Each service has a Test*Client_ValidateOffering_Valid and _Invalid pair already. Add regression sub-cases to the _Valid test:

  • Lowercase variant of the canonical SKU passes (e.g. premium_p1 for cache).
  • SKU with leading/trailing whitespace passes.

The _Invalid test already covers the truly-invalid case and should continue to pass unchanged.

Why this matters

Operator-driven approves (UI override, CLI, scheduled re-drives via CSV imports) all funnel through ValidateOffering before hitting the purchase API. A case-only mismatch surfaces as "invalid Azure ... SKU: premium_p1" with no obvious remediation path — the user sees their input rejected even though Azure would accept it. EqualFold + TrimSpace removes that whole class of false-negative rejections at minimal cost.

Discovered while reviewing the PR #622 (synapse) round-5 CR findings. The synapse fix is in commit 1313332cc on branch feat/issue-555-azure-synapse; this issue extends the same treatment to the five sibling services.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions