From a8fb8654cb3de0918d3a64d9fa86da2eb3fd2378 Mon Sep 17 00:00:00 2001 From: Wallace Breza Date: Wed, 14 Aug 2024 14:57:07 -0700 Subject: [PATCH] Fixes normalization of provisioning state between deployment providers --- cli/azd/pkg/azapi/deployments.go | 7 +- cli/azd/pkg/azapi/stack_deployments.go | 94 ++++++++++++++++++++++- cli/azd/pkg/azapi/standard_deployments.go | 31 +++++++- 3 files changed, 126 insertions(+), 6 deletions(-) diff --git a/cli/azd/pkg/azapi/deployments.go b/cli/azd/pkg/azapi/deployments.go index 2c4fee1045c..1a166e15aaf 100644 --- a/cli/azd/pkg/azapi/deployments.go +++ b/cli/azd/pkg/azapi/deployments.go @@ -66,18 +66,23 @@ type ResourceDeployment struct { type DeploymentProvisioningState string const ( + DeploymentProvisioningStateAccepted DeploymentProvisioningState = "Accepted" DeploymentProvisioningStateCanceled DeploymentProvisioningState = "Canceled" DeploymentProvisioningStateCanceling DeploymentProvisioningState = "Canceling" DeploymentProvisioningStateCreating DeploymentProvisioningState = "Creating" - DeploymentProvisioningStateRunning DeploymentProvisioningState = "Running" + DeploymentProvisioningStateDeleted DeploymentProvisioningState = "Deleted" DeploymentProvisioningStateDeleting DeploymentProvisioningState = "Deleting" DeploymentProvisioningStateDeletingResources DeploymentProvisioningState = "DeletingResources" DeploymentProvisioningStateDeploying DeploymentProvisioningState = "Deploying" DeploymentProvisioningStateFailed DeploymentProvisioningState = "Failed" + DeploymentProvisioningStateNotSpecified DeploymentProvisioningState = "NotSpecified" + DeploymentProvisioningStateReady DeploymentProvisioningState = "Ready" + DeploymentProvisioningStateRunning DeploymentProvisioningState = "Running" DeploymentProvisioningStateSucceeded DeploymentProvisioningState = "Succeeded" DeploymentProvisioningStateUpdatingDenyAssignments DeploymentProvisioningState = "UpdatingDenyAssignments" DeploymentProvisioningStateValidating DeploymentProvisioningState = "Validating" DeploymentProvisioningStateWaiting DeploymentProvisioningState = "Waiting" + DeploymentProvisioningStateUpdating DeploymentProvisioningState = "Updating" ) type DeploymentService interface { diff --git a/cli/azd/pkg/azapi/stack_deployments.go b/cli/azd/pkg/azapi/stack_deployments.go index 2afafdf3d89..7b1082063db 100644 --- a/cli/azd/pkg/azapi/stack_deployments.go +++ b/cli/azd/pkg/azapi/stack_deployments.go @@ -316,7 +316,7 @@ func (d *StackDeployments) ListSubscriptionDeploymentOperations( deploymentName string, ) ([]*armresources.DeploymentOperation, error) { deployment, err := d.GetSubscriptionDeployment(ctx, subscriptionId, deploymentName) - if !errors.Is(err, ErrDeploymentNotFound) { + if err != nil && !errors.Is(err, ErrDeploymentNotFound) { return nil, err } @@ -337,7 +337,7 @@ func (d *StackDeployments) ListResourceGroupDeploymentOperations( // If this is the case continue on checking if there is a stack deployment // If a deployment stack is found then use the deployment id of the stack deployment, err := d.GetResourceGroupDeployment(ctx, subscriptionId, resourceGroupName, deploymentName) - if !errors.Is(err, ErrDeploymentNotFound) { + if err != nil && !errors.Is(err, ErrDeploymentNotFound) { return nil, err } @@ -361,6 +361,15 @@ func (d *StackDeployments) WhatIfDeployToSubscription( armTemplate azure.RawArmTemplate, parameters azure.ArmParameters, ) (*armresources.WhatIfOperationResult, error) { + deployment, err := d.GetSubscriptionDeployment(ctx, subscriptionId, deploymentName) + if err != nil && !errors.Is(err, ErrDeploymentNotFound) { + return nil, err + } + + if deployment != nil && deployment.DeploymentId != "" { + deploymentName = filepath.Base(deployment.DeploymentId) + } + return d.standardDeployments.WhatIfDeployToSubscription( ctx, subscriptionId, @@ -379,6 +388,15 @@ func (d *StackDeployments) WhatIfDeployToResourceGroup( armTemplate azure.RawArmTemplate, parameters azure.ArmParameters, ) (*armresources.WhatIfOperationResult, error) { + deployment, err := d.GetResourceGroupDeployment(ctx, subscriptionId, resourceGroup, deploymentName) + if err != nil && !errors.Is(err, ErrDeploymentNotFound) { + return nil, err + } + + if deployment != nil && deployment.DeploymentId != "" { + deploymentName = filepath.Base(deployment.DeploymentId) + } + return d.standardDeployments.WhatIfDeployToResourceGroup( ctx, subscriptionId, @@ -488,16 +506,53 @@ func (d *StackDeployments) DeleteResourceGroupDeployment( return err } - poller, err := client.BeginDeleteAtResourceGroup(ctx, resourceGroupName, deploymentName, nil) + // Delete all resource groups & resources within the deployment stack + options := armdeploymentstacks.ClientBeginDeleteAtResourceGroupOptions{ + UnmanageActionManagementGroups: to.Ptr(armdeploymentstacks.UnmanageActionManagementGroupModeDelete), + UnmanageActionResourceGroups: to.Ptr(armdeploymentstacks.UnmanageActionResourceGroupModeDelete), + UnmanageActionResources: to.Ptr(armdeploymentstacks.UnmanageActionResourceModeDelete), + } + + progress.SetProgress(DeleteDeploymentProgress{ + Name: deploymentName, + Message: fmt.Sprintf("Deleting resource group deployment stack %s", output.WithHighLightFormat(deploymentName)), + State: DeleteResourceStateInProgress, + }) + + poller, err := client.BeginDeleteAtResourceGroup(ctx, resourceGroupName, deploymentName, &options) if err != nil { + progress.SetProgress(DeleteDeploymentProgress{ + Name: deploymentName, + Message: fmt.Sprintf( + "Failed deleting resource group deployment stack %s", + output.WithHighLightFormat(deploymentName), + ), + State: DeleteResourceStateFailed, + }) + return err } _, err = poller.PollUntilDone(ctx, nil) if err != nil { + progress.SetProgress(DeleteDeploymentProgress{ + Name: deploymentName, + Message: fmt.Sprintf( + "Failed deleting resource group deployment stack %s", + output.WithHighLightFormat(deploymentName), + ), + State: DeleteResourceStateFailed, + }) + return err } + progress.SetProgress(DeleteDeploymentProgress{ + Name: deploymentName, + Message: fmt.Sprintf("Deleted resource group deployment stack %s", output.WithHighLightFormat(deploymentName)), + State: DeleteResourceStateSucceeded, + }) + return nil } @@ -537,7 +592,7 @@ func (d *StackDeployments) convertFromStackDeployment(deployment *armdeployments Name: *deployment.Name, Type: *deployment.Type, Tags: deployment.Tags, - ProvisioningState: DeploymentProvisioningState(*deployment.Properties.ProvisioningState), + ProvisioningState: convertFromStacksProvisioningState(*deployment.Properties.ProvisioningState), Timestamp: *deployment.SystemData.LastModifiedAt, TemplateHash: nil, Outputs: deployment.Properties.Outputs, @@ -563,3 +618,34 @@ func (d *StackDeployments) convertFromStackDeployment(deployment *armdeployments ), } } + +func convertFromStacksProvisioningState( + state armdeploymentstacks.DeploymentStackProvisioningState, +) DeploymentProvisioningState { + switch state { + case armdeploymentstacks.DeploymentStackProvisioningStateCanceled: + return DeploymentProvisioningStateCanceled + case armdeploymentstacks.DeploymentStackProvisioningStateCanceling: + return DeploymentProvisioningStateCanceling + case armdeploymentstacks.DeploymentStackProvisioningStateCreating: + return DeploymentProvisioningStateCreating + case armdeploymentstacks.DeploymentStackProvisioningStateDeleting: + return DeploymentProvisioningStateDeleting + case armdeploymentstacks.DeploymentStackProvisioningStateDeletingResources: + return DeploymentProvisioningStateDeletingResources + case armdeploymentstacks.DeploymentStackProvisioningStateDeploying: + return DeploymentProvisioningStateDeploying + case armdeploymentstacks.DeploymentStackProvisioningStateFailed: + return DeploymentProvisioningStateFailed + case armdeploymentstacks.DeploymentStackProvisioningStateSucceeded: + return DeploymentProvisioningStateSucceeded + case armdeploymentstacks.DeploymentStackProvisioningStateUpdatingDenyAssignments: + return DeploymentProvisioningStateUpdatingDenyAssignments + case armdeploymentstacks.DeploymentStackProvisioningStateValidating: + return DeploymentProvisioningStateValidating + case armdeploymentstacks.DeploymentStackProvisioningStateWaiting: + return DeploymentProvisioningStateWaiting + } + + return DeploymentProvisioningState("") +} diff --git a/cli/azd/pkg/azapi/standard_deployments.go b/cli/azd/pkg/azapi/standard_deployments.go index 8693f7a4459..c74ec387994 100644 --- a/cli/azd/pkg/azapi/standard_deployments.go +++ b/cli/azd/pkg/azapi/standard_deployments.go @@ -585,7 +585,7 @@ func (ds *StandardDeployments) convertFromArmDeployment(deployment *armresources Name: *deployment.Name, Type: *deployment.Type, Tags: deployment.Tags, - ProvisioningState: DeploymentProvisioningState(*deployment.Properties.ProvisioningState), + ProvisioningState: convertFromStandardProvisioningState(*deployment.Properties.ProvisioningState), Timestamp: *deployment.Properties.Timestamp, TemplateHash: deployment.Properties.TemplateHash, Outputs: deployment.Properties.Outputs, @@ -611,3 +611,32 @@ func (ds *StandardDeployments) convertFromArmDeployment(deployment *armresources ), } } + +func convertFromStandardProvisioningState(state armresources.ProvisioningState) DeploymentProvisioningState { + switch state { + case armresources.ProvisioningStateAccepted: + return DeploymentProvisioningStateAccepted + case armresources.ProvisioningStateCanceled: + return DeploymentProvisioningStateCanceled + case armresources.ProvisioningStateCreating: + return DeploymentProvisioningStateCreating + case armresources.ProvisioningStateDeleted: + return DeploymentProvisioningStateDeleted + case armresources.ProvisioningStateDeleting: + return DeploymentProvisioningStateDeleting + case armresources.ProvisioningStateFailed: + return DeploymentProvisioningStateFailed + case armresources.ProvisioningStateNotSpecified: + return DeploymentProvisioningStateNotSpecified + case armresources.ProvisioningStateReady: + return DeploymentProvisioningStateReady + case armresources.ProvisioningStateRunning: + return DeploymentProvisioningStateRunning + case armresources.ProvisioningStateSucceeded: + return DeploymentProvisioningStateSucceeded + case armresources.ProvisioningStateUpdating: + return DeploymentProvisioningStateUpdating + } + + return DeploymentProvisioningState("") +}