github.phpd.cn/hashicorp/packer@v1.3.2/builder/oracle/classic/step_security.go (about)

     1  package classic
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/hashicorp/go-oracle-terraform/compute"
     9  	"github.com/hashicorp/packer/common/uuid"
    10  	"github.com/hashicorp/packer/helper/multistep"
    11  	"github.com/hashicorp/packer/packer"
    12  )
    13  
    14  type stepSecurity struct{}
    15  
    16  func (s *stepSecurity) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
    17  	ui := state.Get("ui").(packer.Ui)
    18  	config := state.Get("config").(*Config)
    19  
    20  	commType := ""
    21  	if config.Comm.Type == "ssh" {
    22  		commType = "SSH"
    23  	} else if config.Comm.Type == "winrm" {
    24  		commType = "WINRM"
    25  	}
    26  
    27  	ui.Say(fmt.Sprintf("Configuring security lists and rules to enable %s access...", commType))
    28  
    29  	client := state.Get("client").(*compute.ComputeClient)
    30  	runUUID := uuid.TimeOrderedUUID()
    31  
    32  	namePrefix := fmt.Sprintf("/Compute-%s/%s/", config.IdentityDomain, config.Username)
    33  	secListName := fmt.Sprintf("Packer_%s_Allow_%s_%s", commType, config.ImageName, runUUID)
    34  	secListClient := client.SecurityLists()
    35  	secListInput := compute.CreateSecurityListInput{
    36  		Description: fmt.Sprintf("Packer-generated security list to give packer %s access", commType),
    37  		Name:        namePrefix + secListName,
    38  	}
    39  	_, err := secListClient.CreateSecurityList(&secListInput)
    40  	if err != nil {
    41  		if !strings.Contains(err.Error(), "already exists") {
    42  			err = fmt.Errorf("Error creating security List to"+
    43  				" allow Packer to connect to Oracle instance via %s: %s", commType, err)
    44  			ui.Error(err.Error())
    45  			state.Put("error", err)
    46  			return multistep.ActionHalt
    47  		}
    48  	}
    49  	// DOCS NOTE: user must have Compute_Operations role
    50  	// Create security rule that allows Packer to connect via SSH or winRM
    51  	var application string
    52  	if commType == "SSH" {
    53  		application = "/oracle/public/ssh"
    54  	} else if commType == "WINRM" {
    55  		// Check to see whether a winRM security application is already defined
    56  		applicationClient := client.SecurityApplications()
    57  		application = fmt.Sprintf("packer_winRM_%s", runUUID)
    58  		applicationInput := compute.CreateSecurityApplicationInput{
    59  			Description: "Allows Packer to connect to instance via winRM",
    60  			DPort:       "5985-5986",
    61  			Name:        application,
    62  			Protocol:    "TCP",
    63  		}
    64  		_, err = applicationClient.CreateSecurityApplication(&applicationInput)
    65  		if err != nil {
    66  			err = fmt.Errorf("Error creating security application to"+
    67  				" allow Packer to connect to Oracle instance via %s: %s", commType, err)
    68  			ui.Error(err.Error())
    69  			state.Put("error", err)
    70  			return multistep.ActionHalt
    71  		}
    72  		state.Put("winrm_application", application)
    73  	}
    74  	secRulesClient := client.SecRules()
    75  	secRuleName := fmt.Sprintf("Packer-allow-%s-Rule_%s_%s", commType,
    76  		config.ImageName, runUUID)
    77  	secRulesInput := compute.CreateSecRuleInput{
    78  		Action:          "PERMIT",
    79  		Application:     application,
    80  		Description:     "Packer-generated security rule to allow ssh/winrm",
    81  		DestinationList: "seclist:" + namePrefix + secListName,
    82  		Name:            namePrefix + secRuleName,
    83  		SourceList:      config.SSHSourceList,
    84  	}
    85  
    86  	_, err = secRulesClient.CreateSecRule(&secRulesInput)
    87  	if err != nil {
    88  		err = fmt.Errorf("Error creating security rule to"+
    89  			" allow Packer to connect to Oracle instance: %s", err)
    90  		ui.Error(err.Error())
    91  		state.Put("error", err)
    92  		return multistep.ActionHalt
    93  	}
    94  	state.Put("security_rule_name", secRuleName)
    95  	state.Put("security_list", secListName)
    96  	return multistep.ActionContinue
    97  }
    98  
    99  func (s *stepSecurity) Cleanup(state multistep.StateBag) {
   100  	secRuleName, ok := state.GetOk("security_rule_name")
   101  	if !ok {
   102  		return
   103  	}
   104  	secListName, ok := state.GetOk("security_list")
   105  	if !ok {
   106  		return
   107  	}
   108  
   109  	client := state.Get("client").(*compute.ComputeClient)
   110  	ui := state.Get("ui").(packer.Ui)
   111  	config := state.Get("config").(*Config)
   112  
   113  	ui.Say("Deleting temporary rules and lists...")
   114  
   115  	namePrefix := fmt.Sprintf("/Compute-%s/%s/", config.IdentityDomain, config.Username)
   116  	// delete security rules that Packer generated
   117  	secRulesClient := client.SecRules()
   118  	ruleInput := compute.DeleteSecRuleInput{Name: namePrefix + secRuleName.(string)}
   119  	err := secRulesClient.DeleteSecRule(&ruleInput)
   120  	if err != nil {
   121  		ui.Say(fmt.Sprintf("Error deleting the packer-generated security rule %s; "+
   122  			"please delete manually. (error: %s)", secRuleName.(string), err.Error()))
   123  	}
   124  
   125  	// delete security list that Packer generated
   126  	secListClient := client.SecurityLists()
   127  	input := compute.DeleteSecurityListInput{Name: namePrefix + secListName.(string)}
   128  	err = secListClient.DeleteSecurityList(&input)
   129  	if err != nil {
   130  		ui.Say(fmt.Sprintf("Error deleting the packer-generated security list %s; "+
   131  			"please delete manually. (error : %s)", secListName.(string), err.Error()))
   132  	}
   133  
   134  	// Some extra cleanup if we used the winRM communicator
   135  	if config.Comm.Type == "winrm" {
   136  		// Delete the packer-generated application
   137  		application, ok := state.GetOk("winrm_application")
   138  		if !ok {
   139  			return
   140  		}
   141  		applicationClient := client.SecurityApplications()
   142  		deleteApplicationInput := compute.DeleteSecurityApplicationInput{
   143  			Name: namePrefix + application.(string),
   144  		}
   145  		err = applicationClient.DeleteSecurityApplication(&deleteApplicationInput)
   146  		if err != nil {
   147  			ui.Say(fmt.Sprintf("Error deleting the packer-generated winrm security application %s; "+
   148  				"please delete manually. (error : %s)", application.(string), err.Error()))
   149  		}
   150  	}
   151  
   152  }