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

     1  package arm
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources"
     9  	"github.com/hashicorp/packer/builder/azure/common/constants"
    10  	"github.com/hashicorp/packer/helper/multistep"
    11  	"github.com/hashicorp/packer/packer"
    12  )
    13  
    14  type StepCreateResourceGroup struct {
    15  	client *AzureClient
    16  	create func(ctx context.Context, resourceGroupName string, location string, tags map[string]*string) error
    17  	say    func(message string)
    18  	error  func(e error)
    19  	exists func(ctx context.Context, resourceGroupName string) (bool, error)
    20  }
    21  
    22  func NewStepCreateResourceGroup(client *AzureClient, ui packer.Ui) *StepCreateResourceGroup {
    23  	var step = &StepCreateResourceGroup{
    24  		client: client,
    25  		say:    func(message string) { ui.Say(message) },
    26  		error:  func(e error) { ui.Error(e.Error()) },
    27  	}
    28  
    29  	step.create = step.createResourceGroup
    30  	step.exists = step.doesResourceGroupExist
    31  	return step
    32  }
    33  
    34  func (s *StepCreateResourceGroup) createResourceGroup(ctx context.Context, resourceGroupName string, location string, tags map[string]*string) error {
    35  	_, err := s.client.GroupsClient.CreateOrUpdate(ctx, resourceGroupName, resources.Group{
    36  		Location: &location,
    37  		Tags:     tags,
    38  	})
    39  
    40  	if err != nil {
    41  		s.say(s.client.LastError.Error())
    42  	}
    43  	return err
    44  }
    45  
    46  func (s *StepCreateResourceGroup) doesResourceGroupExist(ctx context.Context, resourceGroupName string) (bool, error) {
    47  	exists, err := s.client.GroupsClient.CheckExistence(ctx, resourceGroupName)
    48  	if err != nil {
    49  		s.say(s.client.LastError.Error())
    50  	}
    51  
    52  	return exists.Response.StatusCode != 404, err
    53  }
    54  
    55  func (s *StepCreateResourceGroup) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
    56  	var doubleResource, ok = state.GetOk(constants.ArmDoubleResourceGroupNameSet)
    57  	if ok && doubleResource.(bool) {
    58  		err := errors.New("You have filled in both temp_resource_group_name and build_resource_group_name. Please choose one.")
    59  		return processStepResult(err, s.error, state)
    60  	}
    61  
    62  	var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string)
    63  	var location = state.Get(constants.ArmLocation).(string)
    64  	var tags = state.Get(constants.ArmTags).(map[string]*string)
    65  
    66  	exists, err := s.exists(ctx, resourceGroupName)
    67  	if err != nil {
    68  		return processStepResult(err, s.error, state)
    69  	}
    70  	configThinksExists := state.Get(constants.ArmIsExistingResourceGroup).(bool)
    71  	if exists != configThinksExists {
    72  		if configThinksExists {
    73  			err = errors.New("The resource group you want to use does not exist yet. Please use temp_resource_group_name to create a temporary resource group.")
    74  		} else {
    75  			err = errors.New("A resource group with that name already exists. Please use build_resource_group_name to use an existing resource group.")
    76  		}
    77  		return processStepResult(err, s.error, state)
    78  	}
    79  
    80  	// If the resource group exists, we may not have permissions to update it so we don't.
    81  	if !exists {
    82  		s.say("Creating resource group ...")
    83  
    84  		s.say(fmt.Sprintf(" -> ResourceGroupName : '%s'", resourceGroupName))
    85  		s.say(fmt.Sprintf(" -> Location          : '%s'", location))
    86  		s.say(fmt.Sprintf(" -> Tags              :"))
    87  		for k, v := range tags {
    88  			s.say(fmt.Sprintf(" ->> %s : %s", k, *v))
    89  		}
    90  		err = s.create(ctx, resourceGroupName, location, tags)
    91  		if err == nil {
    92  			state.Put(constants.ArmIsResourceGroupCreated, true)
    93  		}
    94  	} else {
    95  		s.say("Using existing resource group ...")
    96  		s.say(fmt.Sprintf(" -> ResourceGroupName : '%s'", resourceGroupName))
    97  		s.say(fmt.Sprintf(" -> Location          : '%s'", location))
    98  		state.Put(constants.ArmIsResourceGroupCreated, true)
    99  	}
   100  
   101  	return processStepResult(err, s.error, state)
   102  }
   103  
   104  func (s *StepCreateResourceGroup) Cleanup(state multistep.StateBag) {
   105  	isCreated, ok := state.GetOk(constants.ArmIsResourceGroupCreated)
   106  	if !ok || !isCreated.(bool) {
   107  		return
   108  	}
   109  
   110  	ui := state.Get("ui").(packer.Ui)
   111  	if state.Get(constants.ArmIsExistingResourceGroup).(bool) {
   112  		ui.Say("\nThe resource group was not created by Packer, not deleting ...")
   113  		return
   114  	} else {
   115  		ui.Say("\nCleanup requested, deleting resource group ...")
   116  
   117  		var resourceGroupName = state.Get(constants.ArmResourceGroupName).(string)
   118  		ctx := context.TODO()
   119  		f, err := s.client.GroupsClient.Delete(ctx, resourceGroupName)
   120  		if err == nil {
   121  			if state.Get(constants.ArmAsyncResourceGroupDelete).(bool) {
   122  				s.say(fmt.Sprintf("\n Not waiting for Resource Group delete as requested by user. Resource Group Name is %s", resourceGroupName))
   123  			} else {
   124  				err = f.WaitForCompletion(ctx, s.client.GroupsClient.Client)
   125  			}
   126  		}
   127  		if err != nil {
   128  			ui.Error(fmt.Sprintf("Error deleting resource group.  Please delete it manually.\n\n"+
   129  				"Name: %s\n"+
   130  				"Error: %s", resourceGroupName, err))
   131  			return
   132  		}
   133  		if !state.Get(constants.ArmAsyncResourceGroupDelete).(bool) {
   134  			ui.Say("Resource group has been deleted.")
   135  		}
   136  	}
   137  }