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