github.phpd.cn/hashicorp/packer@v1.3.2/builder/azure/arm/step_delete_resource_group.go (about)

     1  package arm
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/hashicorp/packer/builder/azure/common/constants"
     8  	retry "github.com/hashicorp/packer/common"
     9  	"github.com/hashicorp/packer/helper/multistep"
    10  	"github.com/hashicorp/packer/packer"
    11  )
    12  
    13  const (
    14  	maxResourcesToDelete = 50
    15  )
    16  
    17  type StepDeleteResourceGroup struct {
    18  	client *AzureClient
    19  	delete func(ctx context.Context, state multistep.StateBag, resourceGroupName string) error
    20  	say    func(message string)
    21  	error  func(e error)
    22  }
    23  
    24  func NewStepDeleteResourceGroup(client *AzureClient, ui packer.Ui) *StepDeleteResourceGroup {
    25  	var step = &StepDeleteResourceGroup{
    26  		client: client,
    27  		say:    func(message string) { ui.Say(message) },
    28  		error:  func(e error) { ui.Error(e.Error()) },
    29  	}
    30  
    31  	step.delete = step.deleteResourceGroup
    32  	return step
    33  }
    34  
    35  func (s *StepDeleteResourceGroup) deleteResourceGroup(ctx context.Context, state multistep.StateBag, resourceGroupName string) error {
    36  	var err error
    37  	if state.Get(constants.ArmIsExistingResourceGroup).(bool) {
    38  		s.say("\nThe resource group was not created by Packer, only deleting individual resources ...")
    39  		var deploymentName = state.Get(constants.ArmDeploymentName).(string)
    40  		err = s.deleteDeploymentResources(ctx, deploymentName, resourceGroupName)
    41  		if err != nil {
    42  			return err
    43  		}
    44  
    45  		if keyVaultDeploymentName, ok := state.GetOk(constants.ArmKeyVaultDeploymentName); ok {
    46  			err = s.deleteDeploymentResources(ctx, keyVaultDeploymentName.(string), resourceGroupName)
    47  			if err != nil {
    48  				return err
    49  			}
    50  		}
    51  
    52  		return nil
    53  	} else {
    54  		s.say("\nThe resource group was created by Packer, deleting ...")
    55  		f, err := s.client.GroupsClient.Delete(ctx, resourceGroupName)
    56  		if err == nil {
    57  			if state.Get(constants.ArmAsyncResourceGroupDelete).(bool) {
    58  				// No need to wait for the complition for delete if request is Accepted
    59  				s.say(fmt.Sprintf("\nResource Group is being deleted, not waiting for deletion due to config. Resource Group Name '%s'", resourceGroupName))
    60  			} else {
    61  				f.WaitForCompletion(ctx, s.client.GroupsClient.Client)
    62  			}
    63  
    64  		}
    65  
    66  		if err != nil {
    67  			s.say(s.client.LastError.Error())
    68  		}
    69  		return err
    70  	}
    71  }
    72  
    73  func (s *StepDeleteResourceGroup) deleteDeploymentResources(ctx context.Context, deploymentName, resourceGroupName string) error {
    74  	maxResources := int32(maxResourcesToDelete)
    75  
    76  	deploymentOperations, err := s.client.DeploymentOperationsClient.ListComplete(ctx, resourceGroupName, deploymentName, &maxResources)
    77  	if err != nil {
    78  		s.reportIfError(err, resourceGroupName)
    79  		return err
    80  	}
    81  
    82  	for deploymentOperations.NotDone() {
    83  		deploymentOperation := deploymentOperations.Value()
    84  		// Sometimes an empty operation is added to the list by Azure
    85  		if deploymentOperation.Properties.TargetResource == nil {
    86  			deploymentOperations.Next()
    87  			continue
    88  		}
    89  
    90  		resourceName := *deploymentOperation.Properties.TargetResource.ResourceName
    91  		resourceType := *deploymentOperation.Properties.TargetResource.ResourceType
    92  
    93  		s.say(fmt.Sprintf(" -> %s : '%s'",
    94  			resourceType,
    95  			resourceName))
    96  
    97  		err := retry.Retry(10, 600, 10, func(attempt uint) (bool, error) {
    98  			err := deleteResource(ctx, s.client,
    99  				resourceType,
   100  				resourceName,
   101  				resourceGroupName)
   102  			if err != nil {
   103  				s.reportIfError(err, resourceName)
   104  				return false, nil
   105  			}
   106  
   107  			return true, nil
   108  		})
   109  
   110  		if err = deploymentOperations.Next(); err != nil {
   111  			return err
   112  		}
   113  	}
   114  
   115  	return nil
   116  }
   117  
   118  func (s *StepDeleteResourceGroup) reportIfError(err error, resourceName string) {
   119  	if err != nil {
   120  		s.say(fmt.Sprintf("Error deleting resource. Please delete manually.\n\n"+
   121  			"Name: %s\n"+
   122  			"Error: %s", resourceName, err.Error()))
   123  		s.error(err)
   124  	}
   125  }
   126  
   127  func (s *StepDeleteResourceGroup) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
   128  	s.say("Deleting resource group ...")
   129  
   130  	var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string)
   131  	s.say(fmt.Sprintf(" -> ResourceGroupName : '%s'", resourceGroupName))
   132  
   133  	err := s.delete(ctx, state, resourceGroupName)
   134  	if err != nil {
   135  		state.Put(constants.Error, err)
   136  		s.error(err)
   137  
   138  		return multistep.ActionHalt
   139  	}
   140  
   141  	state.Put(constants.ArmIsResourceGroupCreated, false)
   142  
   143  	return multistep.ActionContinue
   144  }
   145  
   146  func (*StepDeleteResourceGroup) Cleanup(multistep.StateBag) {
   147  }