-
Notifications
You must be signed in to change notification settings - Fork 268
Description
Findings are showing that there are unsuccessful provision attempts due to services/providers not available in the region selected for a service that is in the project.
We are already filtering the available regions by subscription, we can add the services in the project as an additional filter to further reduce the list.
There are some of the templates that attempt to do this via the allowed parameter in the bicep files, but this is a manual list and has room for error.
Proposed solution -
Extend Existing Method with Optional Filtering
A backwards-compatible approach would be to add optional parameters:
// ...existing code...
// LocationFilterOptions provides filtering options for location queries
type LocationFilterOptions struct {
ResourceProviders []string // Filter by resource provider availability
ServiceTypes []string // Filter by specific service types
SkipQuotaCheck bool // Skip quota availability checks
}
// ListSubscriptionLocationsWithFilter lists physical locations with optional filtering
func (s *SubscriptionsService) ListSubscriptionLocationsWithFilter(
ctx context.Context,
subscriptionId string,
tenantId string,
options *LocationFilterOptions,
) ([]Location, error) {
client, err := s.createSubscriptionsClient(ctx, tenantId)
if err != nil {
return nil, err
}
locations := []Location{}
pager := client.NewListLocationsPager(subscriptionId, nil)
for pager.More() {
page, err := pager.NextPage(ctx)
if err != nil {
return nil, fmt.Errorf("failed getting next page of locations: %w", err)
}
for _, location := range page.LocationListResult.Value {
// Only include physical locations
if *location.Metadata.RegionType == "Physical" &&
!compare.PtrValueEquals(location.Metadata.PhysicalLocation, "") {
locationName := *location.Name
// Apply filters if specified
if options != nil {
if len(options.ResourceProviders) > 0 {
supported, err := s.checkProviderAvailability(ctx, subscriptionId, tenantId, locationName, options.ResourceProviders)
if err != nil || !supported {
continue
}
}
if len(options.ServiceTypes) > 0 {
supported, err := s.checkServiceAvailability(ctx, subscriptionId, tenantId, locationName, options.ServiceTypes)
if err != nil || !supported {
continue
}
}
}
displayName := convert.ToValueWithDefault(location.DisplayName, locationName)
regionalDisplayName := convert.ToValueWithDefault(location.RegionalDisplayName, displayName)
locations = append(locations, Location{
Name: locationName,
DisplayName: displayName,
RegionalDisplayName: regionalDisplayName,
})
}
}
}
sort.Slice(locations, func(i, j int) bool {
return locations[i].RegionalDisplayName < locations[j].RegionalDisplayName
})
return locations, nil
}Integration with Existing Prompt System
You would also need to update the prompt system to use the filtered locations. This would involve modifying pkg/azureutil/location.go
// Add new function that accepts service filters
func PromptLocationWithServiceFilter(
ctx context.Context,
subscriptionId string,
message string,
help string,
console input.Console,
accountManager account.Manager,
shouldDisplay func(account.Location) bool,
defaultSelectedLocation *string,
serviceTypes []string, // New parameter for service filtering
) (string, error) {
// Get filtered locations instead of all locations
allLocations, err := accountManager.GetLocationsForServices(ctx, subscriptionId, serviceTypes)
if err != nil {
return "", fmt.Errorf("listing locations: %w", err)
}
// Rest of the function remains the same...
}We would have to parse the bicep files for the services.