allow users of AWS to use the dynamically-generated admin password which we use as the winRM password as an elevated password in the Powershell provisioner, as well as an environment variable in same provisoner.

This commit is contained in:
Megan Marsh 2018-03-08 15:14:57 -08:00
parent d2f9fd1afc
commit d689e6b4d3
3 changed files with 32 additions and 16 deletions

View File

@ -12,6 +12,7 @@ import (
"time"
"github.com/aws/aws-sdk-go/service/ec2"
commonhelper "github.com/hashicorp/packer/helper/common"
"github.com/hashicorp/packer/helper/communicator"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
@ -92,11 +93,15 @@ WaitLoop:
ui.Message(fmt.Sprintf(
"Password (since debug is enabled): %s", s.Comm.WinRMPassword))
}
// store so that we can access this later during provisioning
commonhelper.SetSharedState("winrm_password", s.Comm.WinRMPassword)
return multistep.ActionContinue
}
func (s *StepGetPassword) Cleanup(multistep.StateBag) {}
func (s *StepGetPassword) Cleanup(multistep.StateBag) {
commonhelper.RemoveSharedStateFile("winrm_password")
}
func (s *StepGetPassword) waitForPassword(state multistep.StateBag, cancel <-chan struct{}) (string, error) {
ec2conn := state.Get("ec2").(*ec2.EC2)

View File

@ -3,14 +3,12 @@ package common
import (
"context"
"fmt"
"io/ioutil"
"log"
"math/rand"
"net"
"net/http"
"os"
"path/filepath"
"github.com/hashicorp/packer/helper/common"
"github.com/hashicorp/packer/helper/multistep"
"github.com/hashicorp/packer/packer"
)
@ -77,25 +75,21 @@ func (s *StepHTTPServer) Run(_ context.Context, state multistep.StateBag) multis
return multistep.ActionContinue
}
func httpAddrFilename(suffix string) string {
uuid := os.Getenv("PACKER_RUN_UUID")
return filepath.Join(os.TempDir(), fmt.Sprintf("packer-%s-%s", uuid, suffix))
}
func SetHTTPPort(port string) error {
return ioutil.WriteFile(httpAddrFilename("port"), []byte(port), 0644)
return common.SetSharedState("port", port)
}
func SetHTTPIP(ip string) error {
return ioutil.WriteFile(httpAddrFilename("ip"), []byte(ip), 0644)
return common.SetSharedState("ip", ip)
}
func GetHTTPAddr() string {
ip, err := ioutil.ReadFile(httpAddrFilename("ip"))
ip, err := common.RetrieveSharedState("ip")
if err != nil {
return ""
}
port, err := ioutil.ReadFile(httpAddrFilename("port"))
port, err := common.RetrieveSharedState("port")
if err != nil {
return ""
}
@ -107,6 +101,6 @@ func (s *StepHTTPServer) Cleanup(multistep.StateBag) {
// Close the listener so that the HTTP server stops
s.l.Close()
}
os.Remove(httpAddrFilename("port"))
os.Remove(httpAddrFilename("ip"))
common.RemoveSharedStateFile("port")
common.RemoveSharedStateFile("ip")
}

View File

@ -17,6 +17,7 @@ import (
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/common/uuid"
commonhelper "github.com/hashicorp/packer/helper/common"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
@ -114,7 +115,6 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
},
},
}, raws...)
if err != nil {
return err
}
@ -358,10 +358,17 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) {
// Always available Packer provided env vars
envVars["PACKER_BUILD_NAME"] = p.config.PackerBuildName
envVars["PACKER_BUILDER_TYPE"] = p.config.PackerBuilderType
httpAddr := common.GetHTTPAddr()
if httpAddr != "" {
envVars["PACKER_HTTP_ADDR"] = httpAddr
}
winRMPass, err := commonhelper.RetrieveSharedState("winrm_password")
// This shared state is only created by the amazon builder.
if err == nil {
envVars["AUTO_WINRM_PASSWORD"] = psEscape.Replace(winRMPass)
}
// Split vars into key/value components
for _, envVar := range p.config.Vars {
@ -501,6 +508,16 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin
log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell",
p.config.ElevatedUser, escapedElevatedUser)
}
// Replace ElevatedPassword for winrm users who used this feature
if strings.Compare(p.config.ElevatedPassword, ".AUTO_WINRM_PASSWORD") == 0 {
winRMPass, err := commonhelper.RetrieveSharedState("winrm_password")
// This shared state is only created by the amazon builder.
if err != nil {
fmt.Printf("Error reading AUTO_WINRM_PASSWORD from state: %s", err)
return "", err
}
p.config.ElevatedPassword = winRMPass
}
// Escape chars special to PowerShell in the ElevatedPassword string
escapedElevatedPassword := psEscape.Replace(p.config.ElevatedPassword)