github.phpd.cn/hashicorp/packer@v1.3.2/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 packer.LogSecretFilter.Set(c.Comm.WinRMPassword) 37 return multistep.ActionContinue 38 } 39 40 create, ok := state.GetOk("create_windows_password") 41 42 if !ok || !create.(bool) { 43 return multistep.ActionContinue 44 45 } 46 ui.Say("Creating windows user for instance...") 47 priv, err := rsa.GenerateKey(rand.Reader, 2048) 48 if err != nil { 49 err := fmt.Errorf("Error creating temporary key: %s", err) 50 state.Put("error", err) 51 ui.Error(err.Error()) 52 return multistep.ActionHalt 53 } 54 55 buf := make([]byte, 4) 56 binary.BigEndian.PutUint32(buf, uint32(priv.E)) 57 58 data := WindowsPasswordConfig{ 59 key: priv, 60 UserName: c.Comm.WinRMUser, 61 Modulus: base64.StdEncoding.EncodeToString(priv.N.Bytes()), 62 Exponent: base64.StdEncoding.EncodeToString(buf[1:]), 63 Email: c.Account.ClientEmail, 64 ExpireOn: time.Now().Add(time.Minute * 5), 65 } 66 67 if s.Debug { 68 69 priv_blk := pem.Block{ 70 Type: "RSA PRIVATE KEY", 71 Headers: nil, 72 Bytes: x509.MarshalPKCS1PrivateKey(priv), 73 } 74 75 ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath)) 76 f, err := os.Create(s.DebugKeyPath) 77 if err != nil { 78 state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) 79 return multistep.ActionHalt 80 } 81 82 // Write out the key 83 err = pem.Encode(f, &priv_blk) 84 f.Close() 85 if err != nil { 86 state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) 87 return multistep.ActionHalt 88 } 89 } 90 91 errCh, err := d.CreateOrResetWindowsPassword(name, c.Zone, &data) 92 93 if err == nil { 94 ui.Message("Waiting for windows password to complete...") 95 select { 96 case err = <-errCh: 97 case <-time.After(c.stateTimeout): 98 err = errors.New("time out while waiting for the password to be created") 99 } 100 } 101 102 if err != nil { 103 err := fmt.Errorf("Error creating windows password: %s", err) 104 state.Put("error", err) 105 ui.Error(err.Error()) 106 return multistep.ActionHalt 107 } 108 109 ui.Message("Created password.") 110 111 if s.Debug { 112 ui.Message(fmt.Sprintf( 113 "Password (since debug is enabled): %s", data.password)) 114 } 115 116 state.Put("winrm_password", data.password) 117 commonhelper.SetSharedState("winrm_password", data.password, c.PackerConfig.PackerBuildName) 118 packer.LogSecretFilter.Set(data.password) 119 120 return multistep.ActionContinue 121 } 122 123 // Nothing to clean up. The windows password is only created on the single instance. 124 func (s *StepCreateWindowsPassword) Cleanup(state multistep.StateBag) {}