@@ -313,76 +313,59 @@ private async Task PromptForSubscriptionAsync(CancellationToken cancellationToke
313313
314314 private async Task PromptForLocationAndResourceGroupAsync ( CancellationToken cancellationToken )
315315 {
316- List < KeyValuePair < string , string > > ? locationOptions = null ;
317- List < string > ? resourceGroupOptions = null ;
318- var locationFetchSucceeded = false ;
316+ List < ( string Name , string Location ) > ? resourceGroupOptions = null ;
319317 var resourceGroupFetchSucceeded = false ;
320318
321319 var step = await activityReporter . CreateStepAsync (
322- "fetch-regions-and- resource-groups" ,
320+ "fetch-resource-groups" ,
323321 cancellationToken ) . ConfigureAwait ( false ) ;
324322
325323 await using ( step . ConfigureAwait ( false ) )
326324 {
327325 try
328326 {
329- var task = await step . CreateTaskAsync ( "Fetching supported regions and resource groups" , cancellationToken ) . ConfigureAwait ( false ) ;
327+ var task = await step . CreateTaskAsync ( "Fetching resource groups" , cancellationToken ) . ConfigureAwait ( false ) ;
330328
331329 await using ( task . ConfigureAwait ( false ) )
332330 {
333- ( locationOptions , locationFetchSucceeded ) = await TryGetLocationsAsync ( _options . SubscriptionId ! , cancellationToken ) . ConfigureAwait ( false ) ;
334- ( resourceGroupOptions , resourceGroupFetchSucceeded ) = await TryGetResourceGroupsAsync ( _options . SubscriptionId ! , cancellationToken ) . ConfigureAwait ( false ) ;
331+ ( resourceGroupOptions , resourceGroupFetchSucceeded ) = await TryGetResourceGroupsWithLocationAsync ( _options . SubscriptionId ! , cancellationToken ) . ConfigureAwait ( false ) ;
335332 }
336333
337- if ( locationFetchSucceeded && resourceGroupFetchSucceeded )
334+ if ( resourceGroupFetchSucceeded && resourceGroupOptions is not null )
338335 {
339- await step . SucceedAsync ( $ "Found { locationOptions ! . Count } region(s) and { resourceGroupOptions ! . Count } resource group(s)", cancellationToken ) . ConfigureAwait ( false ) ;
340- }
341- else if ( locationFetchSucceeded )
342- {
343- await step . SucceedAsync ( $ "Found { locationOptions ! . Count } region(s)", cancellationToken ) . ConfigureAwait ( false ) ;
336+ await step . SucceedAsync ( $ "Found { resourceGroupOptions . Count } resource group(s)", cancellationToken ) . ConfigureAwait ( false ) ;
344337 }
345338 else
346339 {
347- await step . WarnAsync ( "Failed to fetch regions, falling back to manual entry " , cancellationToken ) . ConfigureAwait ( false ) ;
340+ await step . WarnAsync ( "Failed to fetch resource groups " , cancellationToken ) . ConfigureAwait ( false ) ;
348341 }
349342 }
350343 catch ( Exception ex )
351344 {
352- _logger . LogError ( ex , "Failed to retrieve Azure region and resource group information." ) ;
353- await step . FailAsync ( $ "Failed to retrieve region and resource group information: { ex . Message } ", cancellationToken ) . ConfigureAwait ( false ) ;
345+ _logger . LogError ( ex , "Failed to retrieve Azure resource group information." ) ;
346+ await step . FailAsync ( $ "Failed to retrieve resource group information: { ex . Message } ", cancellationToken ) . ConfigureAwait ( false ) ;
354347 throw ;
355348 }
356349 }
357350
358- var inputs = new List < InteractionInput >
351+ // First, prompt for resource group selection
352+ var resourceGroupInput = new InteractionInput
359353 {
360- new InteractionInput
361- {
362- Name = LocationName ,
363- InputType = InputType . Choice ,
364- Label = AzureProvisioningStrings . LocationLabel ,
365- Required = true ,
366- Options = [ ..locationOptions ]
367- } ,
368- new InteractionInput
369- {
370- Name = ResourceGroupName ,
371- InputType = InputType . Choice ,
372- Label = AzureProvisioningStrings . ResourceGroupLabel ,
373- Placeholder = AzureProvisioningStrings . ResourceGroupPlaceholder ,
374- Value = GetDefaultResourceGroupName ( ) ,
375- AllowCustomChoice = true ,
376- Options = resourceGroupFetchSucceeded && resourceGroupOptions is not null
377- ? resourceGroupOptions . Select ( rg => KeyValuePair . Create ( rg , rg ) ) . ToList ( )
378- : [ ]
379- }
354+ Name = ResourceGroupName ,
355+ InputType = InputType . Choice ,
356+ Label = AzureProvisioningStrings . ResourceGroupLabel ,
357+ Placeholder = AzureProvisioningStrings . ResourceGroupPlaceholder ,
358+ Value = GetDefaultResourceGroupName ( ) ,
359+ AllowCustomChoice = true ,
360+ Options = resourceGroupFetchSucceeded && resourceGroupOptions is not null
361+ ? resourceGroupOptions . Select ( rg => KeyValuePair . Create ( rg . Name , rg . Name ) ) . ToList ( )
362+ : [ ]
380363 } ;
381364
382- var result = await _interactionService . PromptInputsAsync (
383- AzureProvisioningStrings . LocationDialogTitle ,
384- AzureProvisioningStrings . LocationSelectionMessage ,
385- inputs ,
365+ var resourceGroupResult = await _interactionService . PromptInputsAsync (
366+ AzureProvisioningStrings . ResourceGroupDialogTitle ,
367+ AzureProvisioningStrings . ResourceGroupSelectionMessage ,
368+ [ resourceGroupInput ] ,
386369 new InputsDialogInteractionOptions
387370 {
388371 EnableMessageMarkdown = false ,
@@ -398,11 +381,90 @@ private async Task PromptForLocationAndResourceGroupAsync(CancellationToken canc
398381 } ,
399382 cancellationToken ) . ConfigureAwait ( false ) ;
400383
401- if ( ! result . Canceled )
384+ if ( resourceGroupResult . Canceled )
385+ {
386+ return ;
387+ }
388+
389+ var selectedResourceGroup = resourceGroupResult . Data [ ResourceGroupName ] . Value ;
390+ _options . ResourceGroup = selectedResourceGroup ;
391+ _options . AllowResourceGroupCreation = true ;
392+
393+ // Check if the selected resource group is an existing one
394+ var existingResourceGroup = resourceGroupOptions ? . FirstOrDefault ( rg => rg . Name . Equals ( selectedResourceGroup , StringComparison . OrdinalIgnoreCase ) ) ;
395+
396+ if ( existingResourceGroup != null && ! string . IsNullOrEmpty ( existingResourceGroup . Value . Name ) )
397+ {
398+ // Use the location from the existing resource group
399+ _options . Location = existingResourceGroup . Value . Location ;
400+ _logger . LogInformation ( "Using location {location} from existing resource group {resourceGroup}" , _options . Location , selectedResourceGroup ) ;
401+ }
402+ else
403+ {
404+ // This is a new resource group, prompt for location
405+ await PromptForLocationAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
406+ }
407+ }
408+
409+ private async Task PromptForLocationAsync ( CancellationToken cancellationToken )
410+ {
411+ List < KeyValuePair < string , string > > ? locationOptions = null ;
412+ var locationFetchSucceeded = false ;
413+
414+ var step = await activityReporter . CreateStepAsync (
415+ "fetch-regions" ,
416+ cancellationToken ) . ConfigureAwait ( false ) ;
417+
418+ await using ( step . ConfigureAwait ( false ) )
419+ {
420+ try
421+ {
422+ var task = await step . CreateTaskAsync ( "Fetching supported regions" , cancellationToken ) . ConfigureAwait ( false ) ;
423+
424+ await using ( task . ConfigureAwait ( false ) )
425+ {
426+ ( locationOptions , locationFetchSucceeded ) = await TryGetLocationsAsync ( _options . SubscriptionId ! , cancellationToken ) . ConfigureAwait ( false ) ;
427+ }
428+
429+ if ( locationFetchSucceeded )
430+ {
431+ await step . SucceedAsync ( $ "Found { locationOptions ! . Count } region(s)", cancellationToken ) . ConfigureAwait ( false ) ;
432+ }
433+ else
434+ {
435+ await step . WarnAsync ( "Failed to fetch regions, falling back to manual entry" , cancellationToken ) . ConfigureAwait ( false ) ;
436+ }
437+ }
438+ catch ( Exception ex )
439+ {
440+ _logger . LogError ( ex , "Failed to retrieve Azure region information." ) ;
441+ await step . FailAsync ( $ "Failed to retrieve region information: { ex . Message } ", cancellationToken ) . ConfigureAwait ( false ) ;
442+ throw ;
443+ }
444+ }
445+
446+ var locationResult = await _interactionService . PromptInputsAsync (
447+ AzureProvisioningStrings . LocationDialogTitle ,
448+ AzureProvisioningStrings . LocationSelectionMessage ,
449+ [
450+ new InteractionInput
451+ {
452+ Name = LocationName ,
453+ InputType = InputType . Choice ,
454+ Label = AzureProvisioningStrings . LocationLabel ,
455+ Required = true ,
456+ Options = [ ..locationOptions ]
457+ }
458+ ] ,
459+ new InputsDialogInteractionOptions
460+ {
461+ EnableMessageMarkdown = false
462+ } ,
463+ cancellationToken ) . ConfigureAwait ( false ) ;
464+
465+ if ( ! locationResult . Canceled )
402466 {
403- _options . Location = result . Data [ LocationName ] . Value ;
404- _options . ResourceGroup = result . Data [ ResourceGroupName ] . Value ;
405- _options . AllowResourceGroupCreation = true ;
467+ _options . Location = locationResult . Data [ LocationName ] . Value ;
406468 }
407469 }
408470}
0 commit comments