Merge pull request #9649 from hashicorp/clean_up_vsphere_ui
Clean up vsphere ui
This commit is contained in:
commit
3b297f4937
|
@ -48,7 +48,7 @@ func (s *StepExport) generateArgs(c *DriverConfig, displayName string, hidePassw
|
||||||
|
|
||||||
password := c.RemotePassword
|
password := c.RemotePassword
|
||||||
if hidePassword {
|
if hidePassword {
|
||||||
password = "<password_redacted>"
|
password = "<password>"
|
||||||
}
|
}
|
||||||
u.User = url.UserPassword(c.RemoteUser, password)
|
u.User = url.UserPassword(c.RemoteUser, password)
|
||||||
|
|
||||||
|
|
|
@ -6,17 +6,17 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl/v2/hcldec"
|
"github.com/hashicorp/hcl/v2/hcldec"
|
||||||
"github.com/hashicorp/packer/common"
|
"github.com/hashicorp/packer/common"
|
||||||
|
shelllocal "github.com/hashicorp/packer/common/shell-local"
|
||||||
"github.com/hashicorp/packer/helper/config"
|
"github.com/hashicorp/packer/helper/config"
|
||||||
"github.com/hashicorp/packer/packer"
|
"github.com/hashicorp/packer/packer"
|
||||||
"github.com/hashicorp/packer/template/interpolate"
|
"github.com/hashicorp/packer/template/interpolate"
|
||||||
|
@ -144,6 +144,16 @@ func (p *PostProcessor) generateURI() (*url.URL, error) {
|
||||||
return u, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getEncodedPassword(u *url.URL) (string, bool) {
|
||||||
|
// filter password from all logging
|
||||||
|
password, passwordSet := u.User.Password()
|
||||||
|
if passwordSet && password != "" {
|
||||||
|
encodedPassword := strings.Split(u.User.String(), ":")[1]
|
||||||
|
return encodedPassword, true
|
||||||
|
}
|
||||||
|
return password, false
|
||||||
|
}
|
||||||
|
|
||||||
func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, bool, error) {
|
func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, bool, error) {
|
||||||
source := ""
|
source := ""
|
||||||
for _, path := range artifact.Files() {
|
for _, path := range artifact.Files() {
|
||||||
|
@ -161,6 +171,10 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, false, err
|
return nil, false, false, err
|
||||||
}
|
}
|
||||||
|
encodedPassword, isSet := getEncodedPassword(ovftool_uri)
|
||||||
|
if isSet {
|
||||||
|
packer.LogSecretFilter.Set(encodedPassword)
|
||||||
|
}
|
||||||
|
|
||||||
args, err := p.BuildArgs(source, ovftool_uri.String())
|
args, err := p.BuildArgs(source, ovftool_uri.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -169,35 +183,61 @@ func (p *PostProcessor) PostProcess(ctx context.Context, ui packer.Ui, artifact
|
||||||
|
|
||||||
ui.Message(fmt.Sprintf("Uploading %s to vSphere", source))
|
ui.Message(fmt.Sprintf("Uploading %s to vSphere", source))
|
||||||
|
|
||||||
log.Printf("Starting ovftool with parameters: %s",
|
log.Printf("Starting ovftool with parameters: %s", strings.Join(args, " "))
|
||||||
filterLog(strings.Join(args, " "), ovftool_uri))
|
|
||||||
|
|
||||||
var errWriter io.Writer
|
ui.Message("Validating Username and Password with dry-run")
|
||||||
var errOut bytes.Buffer
|
err = p.ValidateOvfTool(args, ovftool)
|
||||||
cmd := exec.Command(ovftool, args...)
|
if err != nil {
|
||||||
errWriter = io.MultiWriter(os.Stderr, &errOut)
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = errWriter
|
|
||||||
|
|
||||||
if err := cmd.Run(); err != nil {
|
|
||||||
err := fmt.Errorf("Error uploading virtual machine: %s\n%s\n", err, filterLog(errOut.String(), ovftool_uri))
|
|
||||||
return nil, false, false, err
|
return nil, false, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.Message(filterLog(errOut.String(), ovftool_uri))
|
// Validation has passed, so run for real.
|
||||||
|
ui.Message("Calling OVFtool to upload vm")
|
||||||
|
commandAndArgs := []string{ovftool}
|
||||||
|
commandAndArgs = append(commandAndArgs, args...)
|
||||||
|
comm := &shelllocal.Communicator{
|
||||||
|
ExecuteCommand: commandAndArgs,
|
||||||
|
}
|
||||||
|
flattenedCmd := strings.Join(commandAndArgs, " ")
|
||||||
|
cmd := &packer.RemoteCmd{Command: flattenedCmd}
|
||||||
|
log.Printf("[INFO] (vsphere): starting ovftool command: %s", flattenedCmd)
|
||||||
|
if err := cmd.RunWithUi(ctx, comm, ui); err != nil {
|
||||||
|
return nil, false, false, fmt.Errorf(
|
||||||
|
"Error uploading virtual machine: Please see output above for more information.")
|
||||||
|
}
|
||||||
|
|
||||||
artifact = NewArtifact(p.config.Datastore, p.config.VMFolder, p.config.VMName, artifact.Files())
|
artifact = NewArtifact(p.config.Datastore, p.config.VMFolder, p.config.VMName, artifact.Files())
|
||||||
|
|
||||||
return artifact, false, false, nil
|
return artifact, false, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterLog(s string, u *url.URL) string {
|
func (p *PostProcessor) ValidateOvfTool(args []string, ofvtool string) error {
|
||||||
password, passwordSet := u.User.Password()
|
args = append([]string{"--verifyOnly"}, args...)
|
||||||
if passwordSet && password != "" {
|
var out bytes.Buffer
|
||||||
return strings.Replace(s, password, "<password>", -1)
|
cmdCtx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||||
}
|
defer cancel()
|
||||||
|
cmd := exec.CommandContext(cmdCtx, ovftool, args...)
|
||||||
|
cmd.Stdout = &out
|
||||||
|
|
||||||
return s
|
// Need to manually close stdin or else the ofvtool call will hang
|
||||||
|
// forever in a situation where the user has provided an invalid
|
||||||
|
// password or username
|
||||||
|
stdin, err := cmd.StdinPipe()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer stdin.Close()
|
||||||
|
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
outString := out.String()
|
||||||
|
if strings.Contains(outString, "Enter login information for") {
|
||||||
|
err = fmt.Errorf("Error performing OVFtool dry run; the username " +
|
||||||
|
"or password you provided to ovftool is likely invalid.")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PostProcessor) BuildArgs(source, ovftool_uri string) ([]string, error) {
|
func (p *PostProcessor) BuildArgs(source, ovftool_uri string) ([]string, error) {
|
||||||
|
|
|
@ -101,3 +101,30 @@ func TestGenerateURI_PasswordEscapes(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetEncodedPassword(t *testing.T) {
|
||||||
|
|
||||||
|
// Password is encoded, and contains a colon
|
||||||
|
ovftool_uri := fmt.Sprintf("vi://hostname/Datacenter/host/cluster")
|
||||||
|
|
||||||
|
u, _ := url.Parse(ovftool_uri)
|
||||||
|
u.User = url.UserPassword("us:ername", "P@ssW:rd")
|
||||||
|
|
||||||
|
encoded, isSet := getEncodedPassword(u)
|
||||||
|
expected := "P%40ssW%3Ard"
|
||||||
|
if !isSet {
|
||||||
|
t.Fatalf("Password is set but test said it is not")
|
||||||
|
}
|
||||||
|
if encoded != expected {
|
||||||
|
t.Fatalf("Should have successfully gotten encoded password. Expected: %s; recieved: %s", expected, encoded)
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is no password
|
||||||
|
u.User = url.UserPassword("us:ername", "")
|
||||||
|
|
||||||
|
_, isSet = getEncodedPassword(u)
|
||||||
|
if isSet {
|
||||||
|
t.Fatalf("Should have determined that password was not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -22,7 +22,9 @@ each category, the available configuration keys are alphabetized.
|
||||||
|
|
||||||
Required:
|
Required:
|
||||||
|
|
||||||
- `cluster` (string) - The cluster to upload the VM to.
|
- `cluster` (string) - The cluster to upload the VM to. If you do not have a
|
||||||
|
cluster defined, you can instead provide the IP address of the esx host
|
||||||
|
that you want to upload to.
|
||||||
|
|
||||||
- `datacenter` (string) - The name of the datacenter within vSphere to add
|
- `datacenter` (string) - The name of the datacenter within vSphere to add
|
||||||
the VM to.
|
the VM to.
|
||||||
|
|
Loading…
Reference in New Issue