github.com/rothwerx/packer@v0.9.0/builder/amazon/common/step_key_pair.go (about)

     1  package common
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"runtime"
     8  
     9  	"github.com/aws/aws-sdk-go/service/ec2"
    10  	"github.com/mitchellh/multistep"
    11  	"github.com/mitchellh/packer/packer"
    12  )
    13  
    14  type StepKeyPair struct {
    15  	Debug                bool
    16  	DebugKeyPath         string
    17  	TemporaryKeyPairName string
    18  	KeyPairName          string
    19  	PrivateKeyFile       string
    20  
    21  	keyName string
    22  }
    23  
    24  func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction {
    25  	if s.PrivateKeyFile != "" {
    26  		privateKeyBytes, err := ioutil.ReadFile(s.PrivateKeyFile)
    27  		if err != nil {
    28  			state.Put("error", fmt.Errorf(
    29  				"Error loading configured private key file: %s", err))
    30  			return multistep.ActionHalt
    31  		}
    32  
    33  		state.Put("keyPair", s.KeyPairName)
    34  		state.Put("privateKey", string(privateKeyBytes))
    35  
    36  		return multistep.ActionContinue
    37  	}
    38  
    39  	ec2conn := state.Get("ec2").(*ec2.EC2)
    40  	ui := state.Get("ui").(packer.Ui)
    41  
    42  	ui.Say(fmt.Sprintf("Creating temporary keypair: %s", s.TemporaryKeyPairName))
    43  	keyResp, err := ec2conn.CreateKeyPair(&ec2.CreateKeyPairInput{
    44  		KeyName: &s.TemporaryKeyPairName})
    45  	if err != nil {
    46  		state.Put("error", fmt.Errorf("Error creating temporary keypair: %s", err))
    47  		return multistep.ActionHalt
    48  	}
    49  
    50  	// Set the keyname so we know to delete it later
    51  	s.keyName = s.TemporaryKeyPairName
    52  
    53  	// Set some state data for use in future steps
    54  	state.Put("keyPair", s.keyName)
    55  	state.Put("privateKey", *keyResp.KeyMaterial)
    56  
    57  	// If we're in debug mode, output the private key to the working
    58  	// directory.
    59  	if s.Debug {
    60  		ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath))
    61  		f, err := os.Create(s.DebugKeyPath)
    62  		if err != nil {
    63  			state.Put("error", fmt.Errorf("Error saving debug key: %s", err))
    64  			return multistep.ActionHalt
    65  		}
    66  		defer f.Close()
    67  
    68  		// Write the key out
    69  		if _, err := f.Write([]byte(*keyResp.KeyMaterial)); err != nil {
    70  			state.Put("error", fmt.Errorf("Error saving debug key: %s", err))
    71  			return multistep.ActionHalt
    72  		}
    73  
    74  		// Chmod it so that it is SSH ready
    75  		if runtime.GOOS != "windows" {
    76  			if err := f.Chmod(0600); err != nil {
    77  				state.Put("error", fmt.Errorf("Error setting permissions of debug key: %s", err))
    78  				return multistep.ActionHalt
    79  			}
    80  		}
    81  	}
    82  
    83  	return multistep.ActionContinue
    84  }
    85  
    86  func (s *StepKeyPair) Cleanup(state multistep.StateBag) {
    87  	// If no key name is set, then we never created it, so just return
    88  	// If we used an SSH private key file, do not go about deleting
    89  	// keypairs
    90  	if s.PrivateKeyFile != "" {
    91  		return
    92  	}
    93  
    94  	ec2conn := state.Get("ec2").(*ec2.EC2)
    95  	ui := state.Get("ui").(packer.Ui)
    96  
    97  	// Remove the keypair
    98  	ui.Say("Deleting temporary keypair...")
    99  	_, err := ec2conn.DeleteKeyPair(&ec2.DeleteKeyPairInput{KeyName: &s.keyName})
   100  	if err != nil {
   101  		ui.Error(fmt.Sprintf(
   102  			"Error cleaning up keypair. Please delete the key manually: %s", s.keyName))
   103  	}
   104  
   105  	// Also remove the physical key if we're debugging.
   106  	if s.Debug {
   107  		if err := os.Remove(s.DebugKeyPath); err != nil {
   108  			ui.Error(fmt.Sprintf(
   109  				"Error removing debug key '%s': %s", s.DebugKeyPath, err))
   110  		}
   111  	}
   112  }