github.com/StackPointCloud/packer@v0.10.2-0.20180716202532-b28098e0f79b/builder/googlecompute/step_create_windows_password.go (about) 1 package googlecompute 2 3 import ( 4 "context" 5 "crypto/rand" 6 "crypto/rsa" 7 "crypto/x509" 8 "encoding/base64" 9 "encoding/binary" 10 "encoding/pem" 11 "errors" 12 "fmt" 13 "os" 14 "time" 15 16 commonhelper "github.com/hashicorp/packer/helper/common" 17 "github.com/hashicorp/packer/helper/multistep" 18 "github.com/hashicorp/packer/packer" 19 ) 20 21 // StepCreateWindowsPassword represents a Packer build step that sets the windows password on a Windows GCE instance. 22 type StepCreateWindowsPassword struct { 23 Debug bool 24 DebugKeyPath string 25 } 26 27 // Run executes the Packer build step that sets the windows password on a Windows GCE instance. 28 func (s *StepCreateWindowsPassword) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { 29 ui := state.Get("ui").(packer.Ui) 30 d := state.Get("driver").(Driver) 31 c := state.Get("config").(*Config) 32 name := state.Get("instance_name").(string) 33 34 if c.Comm.WinRMPassword != "" { 35 state.Put("winrm_password", c.Comm.WinRMPassword) 36 return multistep.ActionContinue 37 } 38 39 create, ok := state.GetOk("create_windows_password") 40 41 if !ok || !create.(bool) { 42 return multistep.ActionContinue 43 44 } 45 ui.Say("Creating windows user for instance...") 46 priv, err := rsa.GenerateKey(rand.Reader, 2048) 47 if err != nil { 48 err := fmt.Errorf("Error creating temporary key: %s", err) 49 state.Put("error", err) 50 ui.Error(err.Error()) 51 return multistep.ActionHalt 52 } 53 54 buf := make([]byte, 4) 55 binary.BigEndian.PutUint32(buf, uint32(priv.E)) 56 57 data := WindowsPasswordConfig{ 58 key: priv, 59 UserName: c.Comm.WinRMUser, 60 Modulus: base64.StdEncoding.EncodeToString(priv.N.Bytes()), 61 Exponent: base64.StdEncoding.EncodeToString(buf[1:]), 62 Email: c.Account.ClientEmail, 63 ExpireOn: time.Now().Add(time.Minute * 5), 64 } 65 66 if s.Debug { 67 68 priv_blk := pem.Block{ 69 Type: "RSA PRIVATE KEY", 70 Headers: nil, 71 Bytes: x509.MarshalPKCS1PrivateKey(priv), 72 } 73 74 ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath)) 75 f, err := os.Create(s.DebugKeyPath) 76 if err != nil { 77 state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) 78 return multistep.ActionHalt 79 } 80 81 // Write out the key 82 err = pem.Encode(f, &priv_blk) 83 f.Close() 84 if err != nil { 85 state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) 86 return multistep.ActionHalt 87 } 88 } 89 90 errCh, err := d.CreateOrResetWindowsPassword(name, c.Zone, &data) 91 92 if err == nil { 93 ui.Message("Waiting for windows password to complete...") 94 select { 95 case err = <-errCh: 96 case <-time.After(c.stateTimeout): 97 err = errors.New("time out while waiting for the password to be created") 98 } 99 } 100 101 if err != nil { 102 err := fmt.Errorf("Error creating windows password: %s", err) 103 state.Put("error", err) 104 ui.Error(err.Error()) 105 return multistep.ActionHalt 106 } 107 108 ui.Message("Created password.") 109 110 if s.Debug { 111 ui.Message(fmt.Sprintf( 112 "Password (since debug is enabled): %s", data.password)) 113 } 114 115 state.Put("winrm_password", data.password) 116 commonhelper.SetSharedState("winrm_password", data.password, c.PackerConfig.PackerBuildName) 117 118 return multistep.ActionContinue 119 } 120 121 // Nothing to clean up. The windows password is only created on the single instance. 122 func (s *StepCreateWindowsPassword) Cleanup(state multistep.StateBag) {}